完善文档页文本向量与重排序调用支持
This commit is contained in:
@@ -31,6 +31,33 @@ func TestPlanTaskResponseTreatsAPIV1ChatCompletionsAsSynchronousCompatibleRespon
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlanTaskResponseTreatsAPIV1EmbeddingAndRerankAsSynchronousCompatibleResponse(t *testing.T) {
|
||||
for _, item := range []struct {
|
||||
kind string
|
||||
path string
|
||||
}{
|
||||
{kind: "embeddings", path: "/api/v1/embeddings"},
|
||||
{kind: "reranks", path: "/api/v1/reranks"},
|
||||
} {
|
||||
t.Run(item.kind, func(t *testing.T) {
|
||||
req := httptest.NewRequest(http.MethodPost, item.path, nil)
|
||||
req.Header.Set("X-Async", "true")
|
||||
|
||||
plan := planTaskResponse(item.kind, false, map[string]any{"stream": true}, req)
|
||||
|
||||
if plan.asyncMode {
|
||||
t.Fatalf("%s must not enter async task mode", item.path)
|
||||
}
|
||||
if !plan.compatibleMode {
|
||||
t.Fatalf("%s should return compatible response payloads", item.path)
|
||||
}
|
||||
if plan.streamMode {
|
||||
t.Fatal("embedding and rerank endpoints should stay JSON-only even when stream=true is present")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlanTaskResponseKeepsAsyncTaskModeForOtherAPIV1Tasks(t *testing.T) {
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/images/generations", nil)
|
||||
req.Header.Set("X-Async", "true")
|
||||
|
||||
@@ -876,6 +876,8 @@ func (s *Server) listModelRateLimitStatuses(w http.ResponseWriter, r *http.Reque
|
||||
// @Failure 429 {object} ErrorEnvelope
|
||||
// @Failure 502 {object} ErrorEnvelope
|
||||
// @Router /api/v1/responses [post]
|
||||
// @Router /api/v1/embeddings [post]
|
||||
// @Router /api/v1/reranks [post]
|
||||
// @Router /api/v1/images/generations [post]
|
||||
// @Router /api/v1/images/edits [post]
|
||||
// @Router /api/v1/videos/generations [post]
|
||||
@@ -883,6 +885,10 @@ func (s *Server) listModelRateLimitStatuses(w http.ResponseWriter, r *http.Reque
|
||||
// @Router /v1/chat/completions [post]
|
||||
// @Router /responses [post]
|
||||
// @Router /v1/responses [post]
|
||||
// @Router /embeddings [post]
|
||||
// @Router /v1/embeddings [post]
|
||||
// @Router /reranks [post]
|
||||
// @Router /v1/reranks [post]
|
||||
// @Router /images/generations [post]
|
||||
// @Router /v1/images/generations [post]
|
||||
// @Router /images/edits [post]
|
||||
@@ -1085,17 +1091,25 @@ type taskResponsePlan struct {
|
||||
func planTaskResponse(kind string, compatible bool, body map[string]any, r *http.Request) taskResponsePlan {
|
||||
asyncMode := asyncRequest(r)
|
||||
compatibleMode := compatible
|
||||
if kind == "chat.completions" && !compatible {
|
||||
if synchronousCompatibleKind(kind) && !compatible {
|
||||
asyncMode = false
|
||||
compatibleMode = true
|
||||
}
|
||||
return taskResponsePlan{
|
||||
asyncMode: asyncMode,
|
||||
compatibleMode: compatibleMode,
|
||||
streamMode: boolValue(body, "stream"),
|
||||
streamMode: streamCompatibleKind(kind) && boolValue(body, "stream"),
|
||||
}
|
||||
}
|
||||
|
||||
func synchronousCompatibleKind(kind string) bool {
|
||||
return kind == "chat.completions" || kind == "embeddings" || kind == "reranks"
|
||||
}
|
||||
|
||||
func streamCompatibleKind(kind string) bool {
|
||||
return kind == "chat.completions" || kind == "responses"
|
||||
}
|
||||
|
||||
func writeTaskAccepted(w http.ResponseWriter, task store.GatewayTask) {
|
||||
writeJSON(w, http.StatusAccepted, map[string]any{
|
||||
"taskId": task.ID,
|
||||
@@ -1120,6 +1134,12 @@ func apiKeyScopeAllowed(user *auth.User, kind string) bool {
|
||||
if required == "chat" && (scope == "text" || scope == "text_generate") {
|
||||
return true
|
||||
}
|
||||
if required == "embedding" && scope == "text_embedding" {
|
||||
return true
|
||||
}
|
||||
if required == "rerank" && scope == "text_rerank" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -1128,6 +1148,10 @@ func scopeForTaskKind(kind string) string {
|
||||
switch kind {
|
||||
case "chat.completions", "responses":
|
||||
return "chat"
|
||||
case "embeddings":
|
||||
return "embedding"
|
||||
case "reranks":
|
||||
return "rerank"
|
||||
case "images.generations", "images.edits":
|
||||
return "image"
|
||||
case "videos.generations":
|
||||
|
||||
@@ -1025,6 +1025,7 @@ func modelCatalogCapabilityDefinitions() []ModelCatalogFilterOption {
|
||||
{Value: "text_to_speech", Label: "语音合成"},
|
||||
{Value: "audio_understanding", Label: "音频理解"},
|
||||
{Value: "text_embedding", Label: "Embedding"},
|
||||
{Value: "text_rerank", Label: "重排序"},
|
||||
{Value: "omni", Label: "全模态"},
|
||||
{Value: "omni_video", Label: "全模态视频"},
|
||||
{Value: "multimodal", Label: "多模态"},
|
||||
@@ -1120,6 +1121,8 @@ func canonicalCapabilityFilterValue(value string) string {
|
||||
switch normalized {
|
||||
case "embedding":
|
||||
return "text_embedding"
|
||||
case "rerank", "reranks":
|
||||
return "text_rerank"
|
||||
case "model":
|
||||
return "model_3d"
|
||||
default:
|
||||
@@ -1143,6 +1146,8 @@ func capabilityFilterValueForTag(tag string) string {
|
||||
return "structured_output"
|
||||
case "数字人":
|
||||
return "digital_human"
|
||||
case "重排序":
|
||||
return "text_rerank"
|
||||
case "3D 模型":
|
||||
return "model_3d"
|
||||
case "文生 3D":
|
||||
@@ -1165,6 +1170,9 @@ func capabilityLabel(value string) string {
|
||||
"responses": "Responses",
|
||||
"text_embedding": "Embedding",
|
||||
"embedding": "Embedding",
|
||||
"text_rerank": "重排序",
|
||||
"rerank": "重排序",
|
||||
"reranks": "重排序",
|
||||
"image_generate": "图像生成",
|
||||
"image_edit": "图像编辑",
|
||||
"image_analysis": "图像分析",
|
||||
|
||||
@@ -128,6 +128,8 @@ func NewServerWithContext(ctx context.Context, cfg config.Config, db *store.Stor
|
||||
mux.Handle("GET /api/admin/runtime/model-rate-limits", server.requireAdmin(auth.PermissionPower, http.HandlerFunc(server.listModelRateLimitStatuses)))
|
||||
mux.Handle("POST /api/v1/chat/completions", server.auth.Require(auth.PermissionBasic, server.createAPIV1ChatCompletions()))
|
||||
mux.Handle("POST /api/v1/responses", server.auth.Require(auth.PermissionBasic, server.createTask("responses", false)))
|
||||
mux.Handle("POST /api/v1/embeddings", server.auth.Require(auth.PermissionBasic, server.createTask("embeddings", false)))
|
||||
mux.Handle("POST /api/v1/reranks", server.auth.Require(auth.PermissionBasic, server.createTask("reranks", false)))
|
||||
mux.Handle("POST /api/v1/images/generations", server.auth.Require(auth.PermissionBasic, server.createTask("images.generations", false)))
|
||||
mux.Handle("POST /api/v1/images/edits", server.auth.Require(auth.PermissionBasic, server.createTask("images.edits", false)))
|
||||
mux.Handle("POST /api/v1/videos/generations", server.auth.Require(auth.PermissionBasic, server.createTask("videos.generations", false)))
|
||||
@@ -140,6 +142,10 @@ func NewServerWithContext(ctx context.Context, cfg config.Config, db *store.Stor
|
||||
mux.Handle("POST /v1/chat/completions", server.auth.Require(auth.PermissionBasic, server.createTask("chat.completions", true)))
|
||||
mux.Handle("POST /responses", server.auth.Require(auth.PermissionBasic, server.createTask("responses", true)))
|
||||
mux.Handle("POST /v1/responses", server.auth.Require(auth.PermissionBasic, server.createTask("responses", true)))
|
||||
mux.Handle("POST /embeddings", server.auth.Require(auth.PermissionBasic, server.createTask("embeddings", true)))
|
||||
mux.Handle("POST /v1/embeddings", server.auth.Require(auth.PermissionBasic, server.createTask("embeddings", true)))
|
||||
mux.Handle("POST /reranks", server.auth.Require(auth.PermissionBasic, server.createTask("reranks", true)))
|
||||
mux.Handle("POST /v1/reranks", server.auth.Require(auth.PermissionBasic, server.createTask("reranks", true)))
|
||||
mux.Handle("POST /images/generations", server.auth.Require(auth.PermissionBasic, server.createTask("images.generations", true)))
|
||||
mux.Handle("POST /v1/images/generations", server.auth.Require(auth.PermissionBasic, server.createTask("images.generations", true)))
|
||||
mux.Handle("POST /images/edits", server.auth.Require(auth.PermissionBasic, server.createTask("images.edits", true)))
|
||||
|
||||
Reference in New Issue
Block a user