Skip to main content

路径

POST /video/submit/:taskId 公网入口 https://agentapi.kira.art/video/submit/:taskId
这是 /video 子路由下唯一搬到 kira-agent 的端点(从 kira-be 整段挪过来,kira-be 那个会删)。其余 video 路由(initialize / task / info / upload DELETE)仍在 kira-cdn,在本服务。

认证

supabaseAuth() —— 仅 JWT,不接受 X-Internal-Key
Authorization: Bearer <Supabase JWT>
/video 子应用挂的是 supabaseAuth()(hono/jwk 验 ES256),跟 agent 端点的 eitherAuth() 不同 —— 这是面向终端用户的 retry 动作,没有服务器到服务器的调用方。userId 取自 jwtPayload.sub

请求

无 body。taskId 走路径参数。
taskId
string
required
失败视频 task 的 taskId(对应 thread_version.videos[].taskId)。

响应

body含义
200{ "success": true }已通过校验并重新触发 Trigger.dev 视频 task
200{ "error": "insufficient_credits" | "insufficient_plan" }billing 复核仍不够格 —— 不重发,记一条 0 credit 的 tool_usage(c.json({error}) 无显式状态码 = 200)
400{ "error": "invalid_status", "message": "Video is not in an insufficient state" }task 当前不是 insufficient_* 状态(其余状态 retry 无意义);代码 c.json({...}, 400)
400{ "message": "Task ID is required" }taskId 路径参数
401{ "message": "Unauthorized" }缺/无效 JWT,jwtPayload.sub 为空
404{ "message": "Video task not found" }在该用户的 thread_version.videos 里找不到这个 taskId
500{ "message": "Failed to update video status" | "Failed to submit video task" }写 JSONB 失败 / 触发 Trigger.dev task 失败
两个 error 分支的状态码不同(以代码为准):
  • billing 不够格(insufficient_*)→ 200 {error: reason}(c.json({error}) 不带显式状态)。
  • invalid_status(task 不在 insufficient_* 状态)→ 400 {error, message}(c.json({...}, 400))。
其余入参/鉴权/找不到/内部错误用 400 / 401 / 404 / 500

机制

仅对处于 insufficient_credits / insufficient_plan 状态的视频生效 —— 用户在前端点 “Start” 重试时调用。
1

定位 video

thread_version 表里按 resource_id = userId + videos @> [{taskId}] 查出那一行,VideoSchema.parse 后用 taskId 找到数组下标。找不到 → 404
2

校验状态

video.status 必须是 insufficient_creditsinsufficient_plan,否则返 400 {error:"invalid_status", message}
3

billing 复核(只读)

cost = getVideoCreditsCost(video.toolName, duration ?? 5)(duration 取 input.duration ?? output.duration),再 checkVideoEligibility(userId, cost)。不够格 → 记 0 credit tool_usage 并返 200 {error: reason}这里不扣 credits,真扣在 worker 里。
4

改状态回 pending

把该下标的 video status 改成 pending,UPDATE thread_version.videos。失败 → 500
5

重新触发 Trigger.dev task

publishVideoTask({ taskId, userId, threadId, toolName, provider: video.provider ?? "seedance", input }) —— 内部 tasks.trigger(taskId, payload, { tags, priority }),按 toolName[:provider] 路由到对应 task id(如 generateVideo:seedancevideo-generation-seedance),并打上 videoTask:<taskId> tag。失败 → 500
6

记 analytics + 返回

trackToolUsage(userId, threadId, "generateVideo", true, 0, { creditsConsumed: cost }),返 200 {success:true}

示例

curl -X POST https://agentapi.kira.art/video/submit/44444444-4444-4444-4444-444444444444 \
  -H "Authorization: Bearer $SUPABASE_JWT"
# → 200 {"success":true}

src/hono/video/index.ts(handler + supabaseAuth() 挂载)、checkVideoEligibility / getVideoCreditsCost at src/ai/libs/billing.tspublishVideoTask at src/lib/tasks.ts

相关