Skip to main content

路径

POST /task 公网入口 https://agentapi.kira.art/task。浏览器直连,不经 kira-be 透传。

认证

eitherAuth() 中间件,二选一:
模式Header说明
客户端Authorization: Bearer <Supabase JWT>hono/jwk 验 ES256,userId = jwtPayload.sub
服务器到服务器X-Internal-Key: <INTERNAL_KEY>内部调用方(user 归因走 W3C Baggage)

请求 Body

StreamingRequestSchemasrc/hono/agent/models.ts)校验:
字段类型必填默认说明
messageResponseMessageSchema本轮用户消息:{ id, role: "user"|"assistant", parts?: any[] }
threadIdstring目标线程 ID
model"lite" | "nova" | "ultra""lite"期望的 KiraModel tier
anchorMessageIdstringrewind 锚点:删除该消息之后的所有 message / version / 资源
// KiraModelSchema = z.enum(["lite", "nova", "ultra"])
{
  message: { id: string, role: "user" | "assistant", parts?: any[] },
  threadId: string,
  model?: "lite" | "nova" | "ultra",   // default "lite"
  anchorMessageId?: string
}

响应

成功启动后台 agent run,返回新 taskId。客户端随后用它打开 GET /stream/:taskId
{ "taskId": "<uuid>" }

状态码

含义
201启动成功,返回 { taskId }
409thread 已在跑,返回 { taskId, reason: "running" }
401缺少有效 JWT / jwtPayload.sub
404user_profiles 查不到该用户
500拉取 user profile 失败
503实例正在 graceful drain(instance draining

处理流程

1

Drain 检查

isDraining() 为 true 直接抛 503 instance draining
2

抢 dedup 锁

acquireLock(threadId, "<instanceId>:<newTaskId>")SET NX agent:lock:{threadId} EX 60)。抢不到 → 读现役锁值解析出 taskId,返回 409 { taskId, reason: "running" }
3

Plan 校验与 model 降级

user_profiles.plan,按下表把请求的 model 收敛成 effectiveModel
const isMaxPlan = profile.plan?.startsWith("max");
const isPremium = profile.plan?.startsWith("pro") || isMaxPlan;
if (model === "ultra") {
  effectiveModel = isMaxPlan ? "ultra" : "lite";
} else {
  effectiveModel = isPremium ? model : "lite";
}
Plan可用 tier
free / basiclite
pro / pro_yearlite, nova
max / max_yearlite, nova, ultra
4

anchorMessageId rewind(可选)

若带 anchorMessageId,调用 rewindAfter():删除锚点 created_at 之后messages + thread_version 行,并清理对应 CDN assets(图片/视频/缩略图 + 用户上传 ref)与 video task(purgeVideoTasks + cdn.deleteTask)。
5

装配上下文

从 DB 取该 thread 最近 10 条 message(仅 parts 非空),按时间升序拼为 v5 UIMessage 列表;若本轮 message.id 不在其中则追加到末尾。
6

起后台 run

createTask(...) 写 Redis task HASH + stream,然后 fire-and-forget 启动 agent run(createAgentUIStream),run 内:每 20s heartbeat 续锁、每 2s poll abort key、chunk 经 ChunkBatcher XADD 到 stream。register(...) 进 in-memory registry 供 graceful drain。
用户消息在 run 期间立即 upsert DB;只有 onFinish(非 aborted、有内容)才写回 messages + thread_version,并对生成的 video 通过 tasks.trigger@trigger.dev/sdk/v3)在 kira-video-worker 上触发对应的 Trigger.dev task(publishVideoTask,按 toolName[:provider] 路由到 video-* task id)。

示例

curl -X POST https://agentapi.kira.art/task \
  -H "Authorization: Bearer $SUPABASE_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "message": {
      "id": "11111111-1111-1111-1111-111111111111",
      "role": "user",
      "parts": [{ "type": "text", "text": "画一只赛博朋克猫" }]
    },
    "threadId": "22222222-2222-2222-2222-222222222222",
    "model": "nova"
  }'
# → 201 { "taskId": "33333333-3333-3333-3333-333333333333" }

src/hono/agent/index.ts:85(handler)、rewindAfter at :658src/hono/agent/models.ts:65StreamingRequestSchema

相关