feat: add parameter preprocessing audit trail
This commit is contained in:
@@ -836,8 +836,10 @@ WHERE reference_type = 'gateway_task'
|
||||
}
|
||||
var imageToVideoTask struct {
|
||||
Task struct {
|
||||
Status string `json:"status"`
|
||||
ModelType string `json:"modelType"`
|
||||
ID string `json:"id"`
|
||||
Status string `json:"status"`
|
||||
ModelType string `json:"modelType"`
|
||||
Metrics map[string]any `json:"metrics"`
|
||||
} `json:"task"`
|
||||
}
|
||||
doJSON(t, server.URL, http.MethodPost, "/api/v1/videos/generations", apiKeyResponse.Secret, map[string]any{
|
||||
@@ -851,6 +853,29 @@ WHERE reference_type = 'gateway_task'
|
||||
if imageToVideoTask.Task.Status != "succeeded" || imageToVideoTask.Task.ModelType != "image_to_video" {
|
||||
t.Fatalf("image-to-video request should use image_to_video model_type: %+v", imageToVideoTask.Task)
|
||||
}
|
||||
if _, ok := imageToVideoTask.Task.Metrics["parameterPreprocessing"]; ok {
|
||||
t.Fatalf("task metrics should not embed full parameter preprocessing log: %+v", imageToVideoTask.Task.Metrics)
|
||||
}
|
||||
if imageToVideoTask.Task.Metrics["parameterPreprocessingSummary"] == nil {
|
||||
t.Fatalf("task metrics should keep lightweight preprocessing summary: %+v", imageToVideoTask.Task.Metrics)
|
||||
}
|
||||
var preprocessingDetail struct {
|
||||
Items []map[string]any `json:"items"`
|
||||
}
|
||||
doJSON(t, server.URL, http.MethodGet, "/api/v1/tasks/"+imageToVideoTask.Task.ID+"/param-preprocessing", apiKeyResponse.Secret, nil, http.StatusOK, &preprocessingDetail)
|
||||
if len(preprocessingDetail.Items) == 0 {
|
||||
t.Fatalf("task preprocessing endpoint should expose persisted preprocessing logs: %+v", preprocessingDetail)
|
||||
}
|
||||
if preprocessingDetail.Items[0]["actualInput"] == nil || preprocessingDetail.Items[0]["convertedOutput"] == nil {
|
||||
t.Fatalf("preprocessing log should store actual input and converted output: %+v", preprocessingDetail.Items)
|
||||
}
|
||||
var preprocessingRows int
|
||||
if err := testPool.QueryRow(ctx, `SELECT count(*) FROM gateway_task_param_preprocessing_logs WHERE task_id = $1::uuid`, imageToVideoTask.Task.ID).Scan(&preprocessingRows); err != nil {
|
||||
t.Fatalf("count preprocessing logs: %v", err)
|
||||
}
|
||||
if preprocessingRows == 0 {
|
||||
t.Fatalf("expected preprocessing logs in dedicated table for task %s", imageToVideoTask.Task.ID)
|
||||
}
|
||||
|
||||
failoverModel := "phase1-failover-" + suffixText
|
||||
var failedPlatform struct {
|
||||
|
||||
@@ -795,6 +795,26 @@ func (s *Server) getTask(w http.ResponseWriter, r *http.Request) {
|
||||
writeError(w, http.StatusInternalServerError, "get task failed")
|
||||
}
|
||||
|
||||
func (s *Server) taskParamPreprocessing(w http.ResponseWriter, r *http.Request) {
|
||||
task, err := s.store.GetTask(r.Context(), r.PathValue("taskID"))
|
||||
if err != nil {
|
||||
if store.IsNotFound(err) {
|
||||
writeError(w, http.StatusNotFound, "task not found")
|
||||
return
|
||||
}
|
||||
s.logger.Error("get task failed", "error", err)
|
||||
writeError(w, http.StatusInternalServerError, "get task failed")
|
||||
return
|
||||
}
|
||||
logs, err := s.store.ListTaskParamPreprocessingLogs(r.Context(), task.ID)
|
||||
if err != nil {
|
||||
s.logger.Error("list task parameter preprocessing logs failed", "taskID", task.ID, "error", err)
|
||||
writeError(w, http.StatusInternalServerError, "list task parameter preprocessing logs failed")
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, map[string]any{"items": logs})
|
||||
}
|
||||
|
||||
func (s *Server) taskEvents(w http.ResponseWriter, r *http.Request) {
|
||||
task, err := s.store.GetTask(r.Context(), r.PathValue("taskID"))
|
||||
if err != nil {
|
||||
|
||||
@@ -87,6 +87,7 @@ func NewServerWithContext(ctx context.Context, cfg config.Config, db *store.Stor
|
||||
mux.Handle("GET /api/workspace/wallet/transactions", server.auth.Require(auth.PermissionBasic, http.HandlerFunc(server.listWalletTransactions)))
|
||||
mux.Handle("GET /api/workspace/tasks", server.auth.Require(auth.PermissionBasic, http.HandlerFunc(server.listTasks)))
|
||||
mux.Handle("GET /api/workspace/tasks/{taskID}", server.auth.Require(auth.PermissionBasic, http.HandlerFunc(server.getTask)))
|
||||
mux.Handle("GET /api/workspace/tasks/{taskID}/param-preprocessing", server.auth.Require(auth.PermissionBasic, http.HandlerFunc(server.taskParamPreprocessing)))
|
||||
mux.Handle("GET /api/workspace/tasks/{taskID}/events", server.auth.Require(auth.PermissionBasic, http.HandlerFunc(server.taskEvents)))
|
||||
mux.Handle("GET /api/admin/pricing/rules", server.requireAdmin(auth.PermissionPower, http.HandlerFunc(server.listPricingRules)))
|
||||
mux.Handle("GET /api/admin/pricing/rule-sets", server.requireAdmin(auth.PermissionPower, http.HandlerFunc(server.listPricingRuleSets)))
|
||||
@@ -123,6 +124,7 @@ func NewServerWithContext(ctx context.Context, cfg config.Config, db *store.Stor
|
||||
mux.Handle("POST /api/v1/videos/generations", server.auth.Require(auth.PermissionBasic, server.createTask("videos.generations", false)))
|
||||
mux.Handle("GET /api/v1/tasks", server.auth.Require(auth.PermissionBasic, http.HandlerFunc(server.listTasks)))
|
||||
mux.Handle("GET /api/v1/tasks/{taskID}", server.auth.Require(auth.PermissionBasic, http.HandlerFunc(server.getTask)))
|
||||
mux.Handle("GET /api/v1/tasks/{taskID}/param-preprocessing", server.auth.Require(auth.PermissionBasic, http.HandlerFunc(server.taskParamPreprocessing)))
|
||||
mux.Handle("GET /api/v1/tasks/{taskID}/events", server.auth.Require(auth.PermissionBasic, http.HandlerFunc(server.taskEvents)))
|
||||
mux.Handle("POST /chat/completions", server.auth.Require(auth.PermissionBasic, server.createTask("chat.completions", true)))
|
||||
mux.Handle("POST /v1/chat/completions", server.auth.Require(auth.PermissionBasic, server.createTask("chat.completions", true)))
|
||||
|
||||
Reference in New Issue
Block a user