feat(ai-proxy): add video-related API paths and capabilities (#3108)

This commit is contained in:
woody
2025-11-11 19:39:49 +08:00
committed by GitHub
parent 1300e09e28
commit 8a3c0bb342
4 changed files with 35 additions and 4 deletions

View File

@@ -60,6 +60,7 @@ var (
{provider.PathOpenAIModels, provider.ApiNameModels},
{provider.PathOpenAIFineTuningJobs, provider.ApiNameFineTuningJobs},
{provider.PathOpenAIResponses, provider.ApiNameResponses},
{provider.PathOpenAIVideos, provider.ApiNameVideos},
// Anthropic style
{provider.PathAnthropicMessages, provider.ApiNameAnthropicMessages},
{provider.PathAnthropicComplete, provider.ApiNameAnthropicComplete},
@@ -72,6 +73,9 @@ var (
{util.RegCancelBatchPath, provider.ApiNameCancelBatch},
{util.RegRetrieveFilePath, provider.ApiNameRetrieveFile},
{util.RegRetrieveFileContentPath, provider.ApiNameRetrieveFileContent},
{util.RegRetrieveVideoPath, provider.ApiNameRetrieveVideo},
{util.RegRetrieveVideoContentPath, provider.ApiNameRetrieveVideoContent},
{util.RegVideoRemixPath, provider.ApiNameVideoRemix},
{util.RegRetrieveFineTuningJobPath, provider.ApiNameRetrieveFineTuningJob},
{util.RegRetrieveFineTuningJobEventsPath, provider.ApiNameFineTuningJobEvents},
{util.RegRetrieveFineTuningJobCheckpointsPath, provider.ApiNameFineTuningJobCheckpoints},

View File

@@ -7,9 +7,9 @@ import (
"strings"
"github.com/alibaba/higress/plugins/wasm-go/extensions/ai-proxy/util"
"github.com/higress-group/proxy-wasm-go-sdk/proxywasm/types"
"github.com/higress-group/wasm-go/pkg/log"
"github.com/higress-group/wasm-go/pkg/wrapper"
"github.com/higress-group/proxy-wasm-go-sdk/proxywasm/types"
)
// openaiProvider is the provider for OpenAI service.
@@ -50,6 +50,10 @@ func (m *openaiProviderInitializer) DefaultCapabilities() map[string]string {
string(ApiNamePauseFineTuningJob): PathOpenAIPauseFineTuningJob,
string(ApiNameFineTuningCheckpointPermissions): PathOpenAIFineTuningCheckpointPermissions,
string(ApiNameDeleteFineTuningCheckpointPermission): PathOpenAIFineDeleteTuningCheckpointPermission,
string(ApiNameVideos): PathOpenAIVideos,
string(ApiNameRetrieveVideo): PathOpenAIRetrieveVideo,
string(ApiNameVideoRemix): PathOpenAIVideoRemix,
string(ApiNameRetrieveVideoContent): PathOpenAIRetrieveVideoContent,
}
}
@@ -64,7 +68,8 @@ func isDirectPath(path string) bool {
strings.HasSuffix(path, "/models") ||
strings.HasSuffix(path, "/responses") ||
strings.HasSuffix(path, "/fine_tuning/jobs") ||
strings.HasSuffix(path, "/fine_tuning/checkpoints")
strings.HasSuffix(path, "/fine_tuning/checkpoints") ||
strings.HasSuffix(path, "/videos")
}
func (m *openaiProviderInitializer) CreateProvider(config ProviderConfig) (Provider, error) {

View File

@@ -56,6 +56,10 @@ const (
ApiNamePauseFineTuningJob ApiName = "openai/v1/pausefine-tuningjob"
ApiNameFineTuningCheckpointPermissions ApiName = "openai/v1/fine-tuningjobcheckpointpermissions"
ApiNameDeleteFineTuningCheckpointPermission ApiName = "openai/v1/deletefine-tuningjobcheckpointpermission"
ApiNameVideos ApiName = "openai/v1/videos"
ApiNameRetrieveVideo ApiName = "openai/v1/retrievevideo"
ApiNameVideoRemix ApiName = "openai/v1/videoremix"
ApiNameRetrieveVideoContent ApiName = "openai/v1/retrievevideocontent"
// TODO: 以下是一些非标准的API名称需要进一步确认是否支持
ApiNameCohereV1Rerank ApiName = "cohere/v1/rerank"
@@ -93,6 +97,10 @@ const (
PathOpenAIPauseFineTuningJob = "/v1/fine_tuning/jobs/{fine_tuning_job_id}/pause"
PathOpenAIFineTuningCheckpointPermissions = "/v1/fine_tuning/checkpoints/{fine_tuned_model_checkpoint}/permissions"
PathOpenAIFineDeleteTuningCheckpointPermission = "/v1/fine_tuning/checkpoints/{fine_tuned_model_checkpoint}/permissions/{permission_id}"
PathOpenAIVideos = "/v1/videos"
PathOpenAIRetrieveVideo = "/v1/videos/{video_id}"
PathOpenAIVideoRemix = "/v1/videos/{video_id}/remix"
PathOpenAIRetrieveVideoContent = "/v1/videos/{video_id}/content"
// Anthropic
PathAnthropicMessages = "/v1/messages"
@@ -598,7 +606,11 @@ func (c *ProviderConfig) FromJson(json gjson.Result) {
string(ApiNameImageVariation),
string(ApiNameImageEdit),
string(ApiNameAudioSpeech),
string(ApiNameCohereV1Rerank):
string(ApiNameCohereV1Rerank),
string(ApiNameVideos),
string(ApiNameRetrieveVideo),
string(ApiNameRetrieveVideoContent),
string(ApiNameVideoRemix):
c.capabilities[capability] = pathJson.String()
}
}
@@ -966,7 +978,9 @@ func (c *ProviderConfig) handleRequestHeaders(provider Provider, ctx wrapper.Htt
// defaultTransformRequestBody 默认的请求体转换方法只做模型映射用slog替换模型名称不用序列化和反序列化提高性能
func (c *ProviderConfig) defaultTransformRequestBody(ctx wrapper.HttpContext, apiName ApiName, body []byte) ([]byte, error) {
switch apiName {
case ApiNameChatCompletion:
case ApiNameChatCompletion,
ApiNameVideos,
ApiNameVideoRemix:
stream := gjson.GetBytes(body, "stream").Bool()
if stream {
_ = proxywasm.ReplaceHttpRequestHeader("Accept", "text/event-stream")
@@ -1011,6 +1025,8 @@ func (c *ProviderConfig) isStreamingAPI(apiName ApiName, body []byte) bool {
func (c *ProviderConfig) needToProcessRequestBody(apiName ApiName) bool {
switch apiName {
case ApiNameChatCompletion,
ApiNameVideos,
ApiNameVideoRemix,
ApiNameCompletion,
ApiNameEmbeddings,
ApiNameImageGeneration,

View File

@@ -28,6 +28,9 @@ var (
RegCancelBatchPath = regexp.MustCompile(`^.*/v1/batches/(?P<batch_id>[^/]+)/cancel$`)
RegRetrieveFilePath = regexp.MustCompile(`^.*/v1/files/(?P<file_id>[^/]+)$`)
RegRetrieveFileContentPath = regexp.MustCompile(`^.*/v1/files/(?P<file_id>[^/]+)/content$`)
RegRetrieveVideoPath = regexp.MustCompile(`^.*/v1/videos/(?P<video_id>[^/]+)$`)
RegRetrieveVideoContentPath = regexp.MustCompile(`^.*/v1/videos/(?P<video_id>[^/]+)/content$`)
RegVideoRemixPath = regexp.MustCompile(`^.*/v1/videos/(?P<video_id>[^/]+)/remix$`)
RegRetrieveFineTuningJobPath = regexp.MustCompile(`^.*/v1/fine_tuning/jobs/(?P<fine_tuning_job_id>[^/]+)$`)
RegRetrieveFineTuningJobEventsPath = regexp.MustCompile(`^.*/v1/fine_tuning/jobs/(?P<fine_tuning_job_id>[^/]+)/events$`)
RegRetrieveFineTuningJobCheckpointsPath = regexp.MustCompile(`^.*/v1/fine_tuning/jobs/(?P<fine_tuning_job_id>[^/]+)/checkpoints$`)
@@ -99,6 +102,9 @@ func MapRequestPathByCapability(apiName string, originPath string, mapping map[s
{RegRetrieveFileContentPath, "file_id"},
{RegRetrieveBatchPath, "batch_id"},
{RegCancelBatchPath, "batch_id"},
{RegRetrieveVideoPath, "video_id"},
{RegRetrieveVideoContentPath, "video_id"},
{RegVideoRemixPath, "video_id"},
}
for _, r := range replacements {