import { sqliteTable, text, integer, index, uniqueIndex } from "drizzle-orm/sqlite-core"; import { agents } from "./agent"; import { agentSessions } from "./agent"; /** * A2A Task ↔ Session 映射表 * * 记录 A2A task ID 与内部 agentSession ID 的对应关系, * 以及调用链信息(caller / callee agent)、task 状态。 * * 设计说明: * - 不改动现有 agentSessions schema,通过映射表关联 * - taskId 为 A2A 协议层生成的 UUID,对调用方暴露 * - sessionId 为内部 session ID,不直接暴露给 A2A 调用方 */ export const a2aTaskSessions = sqliteTable( "a2a_task_sessions", { id: integer("id").primaryKey({ autoIncrement: true }), taskId: text("task_id", { length: 64 }).notNull().unique(), sessionId: text("session_id") .notNull() .references(() => agentSessions.id, { onDelete: "cascade" }), callerAgentId: integer("caller_agent_id").references(() => agents.id, { onDelete: "set null" }), calleeAgentId: integer("callee_agent_id") .notNull() .references(() => agents.id, { onDelete: "cascade" }), state: text("state", { length: 20 }).notNull().default("submitted"), callerContext: text("caller_context"), createdAt: integer("created_at", { mode: "timestamp_ms" }).defaultNow().notNull(), updatedAt: integer("updated_at", { mode: "timestamp_ms" }) .defaultNow() .$onUpdate(() => new Date()) .notNull(), completedAt: integer("completed_at", { mode: "timestamp_ms" }), }, (table) => [ uniqueIndex("a2a_task_sessions_task_id_uniq").on(table.taskId), index("a2a_task_sessions_session_idx").on(table.sessionId), index("a2a_task_sessions_callee_idx").on(table.calleeAgentId), index("a2a_task_sessions_state_idx").on(table.state), ], ); export type A2aTaskSessionRow = typeof a2aTaskSessions.$inferSelect;