@agent-native/core 0.31.0 → 0.31.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/dist/a2a/client.js +1 -1
  2. package/dist/a2a/client.js.map +1 -1
  3. package/dist/a2a/task-store.d.ts.map +1 -1
  4. package/dist/a2a/task-store.js +5 -1
  5. package/dist/a2a/task-store.js.map +1 -1
  6. package/dist/action.js +22 -4
  7. package/dist/action.js.map +1 -1
  8. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  9. package/dist/agent/engine/ai-sdk-engine.js +5 -0
  10. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  11. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  12. package/dist/agent/engine/builder-engine.js +4 -0
  13. package/dist/agent/engine/builder-engine.js.map +1 -1
  14. package/dist/agent/production-agent.d.ts.map +1 -1
  15. package/dist/agent/production-agent.js +24 -1
  16. package/dist/agent/production-agent.js.map +1 -1
  17. package/dist/agent/run-manager.d.ts.map +1 -1
  18. package/dist/agent/run-manager.js +7 -2
  19. package/dist/agent/run-manager.js.map +1 -1
  20. package/dist/agent/run-store.d.ts.map +1 -1
  21. package/dist/agent/run-store.js +5 -1
  22. package/dist/agent/run-store.js.map +1 -1
  23. package/dist/agent/tool-search.js.map +1 -1
  24. package/dist/application-state/store.d.ts.map +1 -1
  25. package/dist/application-state/store.js +18 -7
  26. package/dist/application-state/store.js.map +1 -1
  27. package/dist/browser-sessions/store.d.ts.map +1 -1
  28. package/dist/browser-sessions/store.js +6 -1
  29. package/dist/browser-sessions/store.js.map +1 -1
  30. package/dist/chat-threads/store.d.ts.map +1 -1
  31. package/dist/chat-threads/store.js +6 -2
  32. package/dist/chat-threads/store.js.map +1 -1
  33. package/dist/checkpoints/store.d.ts.map +1 -1
  34. package/dist/checkpoints/store.js +5 -1
  35. package/dist/checkpoints/store.js.map +1 -1
  36. package/dist/client/AgentPanel.js +18 -18
  37. package/dist/client/AgentPanel.js.map +1 -1
  38. package/dist/client/agent-chat.d.ts +0 -3
  39. package/dist/client/agent-chat.d.ts.map +1 -1
  40. package/dist/client/agent-chat.js +0 -3
  41. package/dist/client/agent-chat.js.map +1 -1
  42. package/dist/client/components/CodeRequiredDialog.js +0 -7
  43. package/dist/client/components/CodeRequiredDialog.js.map +1 -1
  44. package/dist/client/composer/use-file-search.d.ts.map +1 -1
  45. package/dist/client/composer/use-file-search.js +14 -3
  46. package/dist/client/composer/use-file-search.js.map +1 -1
  47. package/dist/client/db-admin/EditableCell.js +1 -1
  48. package/dist/client/db-admin/EditableCell.js.map +1 -1
  49. package/dist/client/dev-overlay/DevOverlay.d.ts +0 -2
  50. package/dist/client/dev-overlay/DevOverlay.d.ts.map +1 -1
  51. package/dist/client/dev-overlay/DevOverlay.js +1 -1
  52. package/dist/client/dev-overlay/DevOverlay.js.map +1 -1
  53. package/dist/client/mcp-app-host.d.ts.map +1 -1
  54. package/dist/client/mcp-app-host.js +19 -2
  55. package/dist/client/mcp-app-host.js.map +1 -1
  56. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  57. package/dist/client/resources/ResourcesPanel.js +0 -1
  58. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  59. package/dist/client/settings/SettingsPanel.js +2 -2
  60. package/dist/client/settings/SettingsPanel.js.map +1 -1
  61. package/dist/client/sse-event-processor.d.ts.map +1 -1
  62. package/dist/client/sse-event-processor.js +13 -3
  63. package/dist/client/sse-event-processor.js.map +1 -1
  64. package/dist/client/use-db-sync.d.ts.map +1 -1
  65. package/dist/client/use-db-sync.js +16 -0
  66. package/dist/client/use-db-sync.js.map +1 -1
  67. package/dist/client/use-run-stuck-detection.d.ts.map +1 -1
  68. package/dist/client/use-run-stuck-detection.js +7 -1
  69. package/dist/client/use-run-stuck-detection.js.map +1 -1
  70. package/dist/collab/agent-presence.d.ts +0 -3
  71. package/dist/collab/agent-presence.d.ts.map +1 -1
  72. package/dist/collab/agent-presence.js +2 -4
  73. package/dist/collab/agent-presence.js.map +1 -1
  74. package/dist/collab/awareness.d.ts.map +1 -1
  75. package/dist/collab/awareness.js +3 -1
  76. package/dist/collab/awareness.js.map +1 -1
  77. package/dist/collab/storage.d.ts.map +1 -1
  78. package/dist/collab/storage.js +5 -1
  79. package/dist/collab/storage.js.map +1 -1
  80. package/dist/collab/ydoc-manager.d.ts.map +1 -1
  81. package/dist/collab/ydoc-manager.js +35 -8
  82. package/dist/collab/ydoc-manager.js.map +1 -1
  83. package/dist/extensions/content-patch.js +1 -1
  84. package/dist/extensions/content-patch.js.map +1 -1
  85. package/dist/extensions/routes.js +12 -12
  86. package/dist/extensions/routes.js.map +1 -1
  87. package/dist/extensions/slots/store.d.ts.map +1 -1
  88. package/dist/extensions/slots/store.js +5 -1
  89. package/dist/extensions/slots/store.js.map +1 -1
  90. package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
  91. package/dist/integrations/a2a-continuations-store.js +5 -1
  92. package/dist/integrations/a2a-continuations-store.js.map +1 -1
  93. package/dist/integrations/adapters/email.d.ts.map +1 -1
  94. package/dist/integrations/adapters/email.js +5 -2
  95. package/dist/integrations/adapters/email.js.map +1 -1
  96. package/dist/integrations/google-docs-poller.d.ts.map +1 -1
  97. package/dist/integrations/google-docs-poller.js +2 -4
  98. package/dist/integrations/google-docs-poller.js.map +1 -1
  99. package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -1
  100. package/dist/integrations/pending-tasks-retry-job.js +6 -2
  101. package/dist/integrations/pending-tasks-retry-job.js.map +1 -1
  102. package/dist/integrations/pending-tasks-store.d.ts.map +1 -1
  103. package/dist/integrations/pending-tasks-store.js +5 -1
  104. package/dist/integrations/pending-tasks-store.js.map +1 -1
  105. package/dist/integrations/plugin.d.ts.map +1 -1
  106. package/dist/integrations/plugin.js +14 -3
  107. package/dist/integrations/plugin.js.map +1 -1
  108. package/dist/integrations/remote-commands-store.d.ts.map +1 -1
  109. package/dist/integrations/remote-commands-store.js +5 -1
  110. package/dist/integrations/remote-commands-store.js.map +1 -1
  111. package/dist/integrations/remote-devices-store.d.ts.map +1 -1
  112. package/dist/integrations/remote-devices-store.js +5 -1
  113. package/dist/integrations/remote-devices-store.js.map +1 -1
  114. package/dist/integrations/remote-push-store.d.ts.map +1 -1
  115. package/dist/integrations/remote-push-store.js +5 -1
  116. package/dist/integrations/remote-push-store.js.map +1 -1
  117. package/dist/integrations/remote-retry-job.js +1 -1
  118. package/dist/integrations/remote-retry-job.js.map +1 -1
  119. package/dist/integrations/remote-run-events-store.d.ts.map +1 -1
  120. package/dist/integrations/remote-run-events-store.js +5 -1
  121. package/dist/integrations/remote-run-events-store.js.map +1 -1
  122. package/dist/integrations/thread-mapping-store.d.ts.map +1 -1
  123. package/dist/integrations/thread-mapping-store.js +5 -1
  124. package/dist/integrations/thread-mapping-store.js.map +1 -1
  125. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  126. package/dist/integrations/webhook-handler.js.map +1 -1
  127. package/dist/jobs/scheduler.d.ts.map +1 -1
  128. package/dist/jobs/scheduler.js +31 -15
  129. package/dist/jobs/scheduler.js.map +1 -1
  130. package/dist/jobs/tools.d.ts.map +1 -1
  131. package/dist/jobs/tools.js +4 -1
  132. package/dist/jobs/tools.js.map +1 -1
  133. package/dist/mcp/build-server.d.ts.map +1 -1
  134. package/dist/mcp/build-server.js +4 -1
  135. package/dist/mcp/build-server.js.map +1 -1
  136. package/dist/mcp/connect-store.d.ts +3 -4
  137. package/dist/mcp/connect-store.d.ts.map +1 -1
  138. package/dist/mcp/connect-store.js +4 -4
  139. package/dist/mcp/connect-store.js.map +1 -1
  140. package/dist/mcp-client/routes.js +6 -1
  141. package/dist/mcp-client/routes.js.map +1 -1
  142. package/dist/oauth-tokens/store.d.ts.map +1 -1
  143. package/dist/oauth-tokens/store.js +5 -1
  144. package/dist/oauth-tokens/store.js.map +1 -1
  145. package/dist/org/accept-pending.js +1 -1
  146. package/dist/org/accept-pending.js.map +1 -1
  147. package/dist/progress/store.d.ts.map +1 -1
  148. package/dist/progress/store.js +11 -1
  149. package/dist/progress/store.js.map +1 -1
  150. package/dist/resources/handlers.d.ts.map +1 -1
  151. package/dist/resources/handlers.js +0 -2
  152. package/dist/resources/handlers.js.map +1 -1
  153. package/dist/resources/store.d.ts.map +1 -1
  154. package/dist/resources/store.js +23 -13
  155. package/dist/resources/store.js.map +1 -1
  156. package/dist/scripts/db/query.d.ts.map +1 -1
  157. package/dist/scripts/db/query.js +1 -2
  158. package/dist/scripts/db/query.js.map +1 -1
  159. package/dist/server/action-discovery.d.ts.map +1 -1
  160. package/dist/server/action-discovery.js +10 -3
  161. package/dist/server/action-discovery.js.map +1 -1
  162. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  163. package/dist/server/agent-chat-plugin.js +3 -0
  164. package/dist/server/agent-chat-plugin.js.map +1 -1
  165. package/dist/server/auth.d.ts.map +1 -1
  166. package/dist/server/auth.js +13 -9
  167. package/dist/server/auth.js.map +1 -1
  168. package/dist/server/identity-sso-store.d.ts.map +1 -1
  169. package/dist/server/identity-sso-store.js +14 -3
  170. package/dist/server/identity-sso-store.js.map +1 -1
  171. package/dist/server/poll.d.ts.map +1 -1
  172. package/dist/server/poll.js +18 -0
  173. package/dist/server/poll.js.map +1 -1
  174. package/dist/server/schema-prompt.js +1 -1
  175. package/dist/server/schema-prompt.js.map +1 -1
  176. package/dist/server/security-headers.d.ts +5 -4
  177. package/dist/server/security-headers.d.ts.map +1 -1
  178. package/dist/server/security-headers.js +5 -4
  179. package/dist/server/security-headers.js.map +1 -1
  180. package/dist/settings/store.d.ts.map +1 -1
  181. package/dist/settings/store.js +5 -1
  182. package/dist/settings/store.js.map +1 -1
  183. package/dist/sharing/actions/set-resource-visibility.d.ts.map +1 -1
  184. package/dist/sharing/actions/set-resource-visibility.js +8 -1
  185. package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
  186. package/dist/triggers/actions.d.ts.map +1 -1
  187. package/dist/triggers/actions.js +1 -2
  188. package/dist/triggers/actions.js.map +1 -1
  189. package/dist/triggers/dispatcher.d.ts.map +1 -1
  190. package/dist/triggers/dispatcher.js +36 -8
  191. package/dist/triggers/dispatcher.js.map +1 -1
  192. package/dist/usage/store.d.ts.map +1 -1
  193. package/dist/usage/store.js +5 -1
  194. package/dist/usage/store.js.map +1 -1
  195. package/dist/vite/client.js +5 -5
  196. package/dist/vite/client.js.map +1 -1
  197. package/package.json +1 -1
@@ -180,7 +180,7 @@ export class A2AClient {
180
180
  current = await this.getTask(submitted.id);
181
181
  opts?.onUpdate?.(current);
182
182
  }
183
- catch (err) {
183
+ catch {
184
184
  // Transient fetch failure — keep polling until the deadline.
185
185
  continue;
186
186
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"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","sourcesContent":["import * as jose from \"jose\";\nimport { ssrfSafeFetch } from \"../extensions/url-safety.js\";\nimport type {\n AgentCard,\n JsonRpcRequest,\n JsonRpcResponse,\n Message,\n Task,\n} from \"./types.js\";\n\nexport class A2ATaskTimeoutError extends Error {\n readonly taskId: string;\n readonly lastTask: Task;\n readonly lastState: string;\n readonly timeoutMs: number;\n\n constructor(taskId: string, lastTask: Task, timeoutMs: number) {\n const lastState = lastTask.status.state;\n super(\n `A2A task ${taskId} did not complete within ${timeoutMs}ms (last state: ${lastState})`,\n );\n this.name = \"A2ATaskTimeoutError\";\n this.taskId = taskId;\n this.lastTask = lastTask;\n this.lastState = lastState;\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Sign a JWT for A2A cross-app identity verification.\n *\n * Uses an org-level secret by default for direct org-secret workflows. Callers\n * that are doing ordinary hosted cross-app delegation can set\n * `preferGlobalSecret` so deployments with a shared A2A_SECRET don't depend on\n * every app database having an identical org row. The token contains the\n * caller's email as `sub`, so the receiving app can verify who's calling.\n */\nexport async function signA2AToken(\n email: string,\n orgDomain?: string,\n orgSecret?: string,\n options?: {\n expiresIn?: string | number;\n preferGlobalSecret?: boolean;\n /**\n * Extra JWT claims to merge alongside `sub` / `org_domain`. Used by the\n * MCP connect flow to add a revocable `jti` and a `scope: \"mcp-connect\"`\n * marker. Reserved claims (`sub`, `org_domain`) cannot be overridden —\n * they are spread last so a caller can never spoof identity via this map.\n */\n extraClaims?: Record<string, unknown>;\n },\n): Promise<string> {\n const secret = options?.preferGlobalSecret\n ? process.env.A2A_SECRET || orgSecret\n : orgSecret || process.env.A2A_SECRET;\n if (!secret) {\n throw new Error(\n \"No A2A secret available. Set an org-level A2A secret in Team settings, \" +\n \"or set A2A_SECRET as an environment variable on all apps that need to verify identity.\",\n );\n }\n\n const appUrl =\n process.env.APP_URL ||\n process.env.BETTER_AUTH_URL ||\n \"http://localhost:3000\";\n\n return new jose.SignJWT({\n ...(options?.extraClaims ?? {}),\n // `sub` / `org_domain` are spread AFTER extraClaims so a caller-supplied\n // map can never override the verified identity claims.\n sub: email,\n ...(orgDomain ? { org_domain: orgDomain } : {}),\n })\n .setProtectedHeader({ alg: \"HS256\" })\n .setIssuer(appUrl)\n .setIssuedAt()\n .setExpirationTime(options?.expiresIn ?? \"15m\")\n .sign(new TextEncoder().encode(secret));\n}\n\nexport class A2AClient {\n private baseUrl: string;\n private apiKey?: string;\n private endpointCandidates: string[] = [];\n private endpointResolved = false;\n private requestTimeoutMs?: number;\n\n constructor(\n baseUrl: string,\n apiKey?: string,\n options?: { requestTimeoutMs?: number },\n ) {\n const normalized = baseUrl.replace(/\\/$/, \"\");\n const explicitEndpoint = splitExplicitA2AEndpoint(normalized);\n this.baseUrl = explicitEndpoint?.baseUrl ?? normalized;\n if (explicitEndpoint) {\n this.endpointCandidates = [explicitEndpoint.endpointUrl];\n this.endpointResolved = true;\n }\n this.apiKey = apiKey;\n this.requestTimeoutMs = options?.requestTimeoutMs;\n }\n\n /**\n * Detect which A2A path the target agent uses.\n * Agent-native apps use /_agent-native/a2a, external agents may use /a2a.\n */\n async resolveEndpoint(): Promise<void> {\n await this.ensureEndpointCandidates();\n if (this.endpointCandidates.length <= 1) return;\n\n for (const endpoint of this.endpointCandidates) {\n try {\n const res = await ssrfSafeFetch(\n endpoint,\n { method: \"OPTIONS\" },\n { maxRedirects: 3 },\n );\n if (res.status !== 404 && res.status !== 405) {\n this.endpointCandidates = [endpoint];\n return;\n }\n if (res.status === 405) {\n this.endpointCandidates = [endpoint];\n return;\n }\n } catch {\n // Try the next candidate.\n }\n }\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (this.apiKey) {\n h[\"Authorization\"] = `Bearer ${this.apiKey}`;\n }\n return h;\n }\n\n private async rpc(\n method: string,\n params: Record<string, unknown>,\n ): Promise<JsonRpcResponse> {\n const body: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id: Date.now(),\n method,\n params,\n };\n\n await this.ensureEndpointCandidates();\n let lastError: Error | null = null;\n\n for (const url of this.endpointCandidates) {\n console.log(`[A2A Client] POST ${url} method=${method}`);\n const startTime = Date.now();\n const res = await this.postJson(url, body);\n console.log(\n `[A2A Client] Response: ${res.status} in ${Date.now() - startTime}ms`,\n );\n\n if (res.ok) {\n this.endpointCandidates = [url];\n return res.json() as Promise<JsonRpcResponse>;\n }\n\n const text = await res.text();\n lastError = new Error(`A2A request failed (${res.status}): ${text}`);\n if (!shouldTryNextEndpoint(res.status)) {\n throw lastError;\n }\n }\n\n throw lastError ?? new Error(\"No A2A endpoint candidates available\");\n }\n\n async getAgentCard(): Promise<AgentCard> {\n const res = await ssrfSafeFetch(\n `${this.baseUrl}/.well-known/agent-card.json`,\n {},\n { maxRedirects: 3 },\n );\n if (!res.ok) {\n throw new Error(`Failed to fetch agent card (${res.status})`);\n }\n return res.json() as Promise<AgentCard>;\n }\n\n async send(\n message: Message,\n opts?: {\n contextId?: string;\n metadata?: Record<string, unknown>;\n /**\n * If true, ask the server to return the task immediately in `working`\n * state and process the handler in the background. The caller should\n * then poll `getTask(taskId)` until `completed` / `failed` / `canceled`.\n *\n * Use this when you expect the handler may exceed a synchronous\n * serverless request budget.\n */\n async?: boolean;\n },\n ): Promise<Task> {\n const response = await this.rpc(\"message/send\", {\n message,\n contextId: opts?.contextId,\n metadata: opts?.metadata,\n ...(opts?.async ? { async: true } : {}),\n });\n\n if (response.error) {\n throw new Error(\n `A2A error (${response.error.code}): ${response.error.message}`,\n );\n }\n\n return response.result as Task;\n }\n\n /**\n * Poll for a task by id. Used in async mode after `send({ async: true })`.\n */\n async getTask(taskId: string): Promise<Task> {\n const response = await this.rpc(\"tasks/get\", { id: taskId });\n if (response.error) {\n throw new Error(\n `A2A error (${response.error.code}): ${response.error.message}`,\n );\n }\n return response.result as Task;\n }\n\n /**\n * Send a message in async mode and poll until the task reaches a terminal\n * state. This is the recommended path on serverless hosts with short\n * function timeouts (Netlify, Vercel) where a synchronous LLM-driven A2A\n * call can exceed the gateway limit.\n *\n * Each individual fetch returns quickly; long-running work happens on the\n * receiving side and is checked via `tasks/get`.\n */\n async sendAndWait(\n message: Message,\n opts?: {\n contextId?: string;\n metadata?: Record<string, unknown>;\n /** Total time to wait for completion. Default 5 min. */\n timeoutMs?: number;\n /** Poll interval. Default 2s. */\n pollIntervalMs?: number;\n /** Called with each polled task — useful for surfacing progress. */\n onUpdate?: (task: Task) => void;\n },\n ): Promise<Task> {\n const submitted = await this.send(message, {\n contextId: opts?.contextId,\n metadata: opts?.metadata,\n async: true,\n });\n\n const terminalStates = new Set([\"completed\", \"failed\", \"canceled\"]);\n if (terminalStates.has(submitted.status.state)) return submitted;\n\n const timeoutMs = opts?.timeoutMs ?? 5 * 60_000;\n const pollMs = opts?.pollIntervalMs ?? 2_000;\n const deadline = Date.now() + timeoutMs;\n\n let current = submitted;\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, pollMs));\n try {\n current = await this.getTask(submitted.id);\n opts?.onUpdate?.(current);\n } catch (err) {\n // Transient fetch failure — keep polling until the deadline.\n continue;\n }\n if (terminalStates.has(current.status.state)) return current;\n }\n throw new A2ATaskTimeoutError(submitted.id, current, timeoutMs);\n }\n\n async *stream(\n message: Message,\n opts?: { contextId?: string; metadata?: Record<string, unknown> },\n ): AsyncGenerator<Task> {\n const body: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id: Date.now(),\n method: \"message/stream\",\n params: {\n message,\n contextId: opts?.contextId,\n metadata: opts?.metadata,\n },\n };\n\n await this.ensureEndpointCandidates();\n let res: Response | null = null;\n let lastError: Error | null = null;\n for (const candidate of this.endpointCandidates) {\n res = await this.postJson(candidate, body);\n if (res.ok) {\n this.endpointCandidates = [candidate];\n break;\n }\n const text = await res.text();\n lastError = new Error(`A2A stream failed (${res.status}): ${text}`);\n if (!shouldTryNextEndpoint(res.status)) throw lastError;\n }\n if (!res?.ok) {\n throw lastError ?? new Error(\"No A2A endpoint candidates available\");\n }\n\n const reader = res.body?.getReader();\n if (!reader) throw new Error(\"No response body\");\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const json = line.slice(6).trim();\n if (!json) continue;\n\n const response: JsonRpcResponse = JSON.parse(json);\n if (response.error) {\n throw new Error(\n `A2A error (${response.error.code}): ${response.error.message}`,\n );\n }\n if (response.result) {\n yield response.result as Task;\n }\n }\n }\n }\n\n private async ensureEndpointCandidates(): Promise<void> {\n if (this.endpointResolved) return;\n this.endpointResolved = true;\n\n const candidates: string[] = [];\n addDefaultEndpointCandidates(candidates, this.baseUrl);\n\n try {\n const card = await this.getAgentCard();\n const cardUrl = normalizeUrl(card.url, this.baseUrl);\n if (cardUrl) {\n const explicitEndpoint = splitExplicitA2AEndpoint(cardUrl);\n if (explicitEndpoint) {\n candidates.unshift(explicitEndpoint.endpointUrl);\n } else {\n addDefaultEndpointCandidates(candidates, cardUrl);\n }\n }\n } catch {\n // Agent cards are discovery hints. Fall back to conventional endpoints.\n }\n\n this.endpointCandidates = unique(candidates);\n }\n\n private async postJson(url: string, body: JsonRpcRequest): Promise<Response> {\n const controller = this.requestTimeoutMs\n ? new AbortController()\n : undefined;\n const timer =\n controller && this.requestTimeoutMs\n ? setTimeout(() => controller.abort(), this.requestTimeoutMs)\n : undefined;\n try {\n return await ssrfSafeFetch(\n url,\n {\n method: \"POST\",\n headers: this.headers(),\n body: JSON.stringify(body),\n signal: controller?.signal,\n },\n { maxRedirects: 3 },\n );\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n}\n\nfunction splitExplicitA2AEndpoint(\n url: string,\n): { baseUrl: string; endpointUrl: string } | null {\n try {\n const parsed = new URL(url);\n const pathname = parsed.pathname.replace(/\\/$/, \"\");\n if (pathname.endsWith(\"/_agent-native/a2a\")) {\n parsed.pathname = pathname.slice(0, -\"/_agent-native/a2a\".length) || \"/\";\n parsed.search = \"\";\n parsed.hash = \"\";\n return {\n baseUrl: parsed.toString().replace(/\\/$/, \"\"),\n endpointUrl: url,\n };\n }\n if (pathname.endsWith(\"/a2a\")) {\n parsed.pathname = pathname.slice(0, -\"/a2a\".length) || \"/\";\n parsed.search = \"\";\n parsed.hash = \"\";\n return {\n baseUrl: parsed.toString().replace(/\\/$/, \"\"),\n endpointUrl: url,\n };\n }\n } catch {\n // Relative or invalid URLs are handled by the caller's normal fetch path.\n }\n return null;\n}\n\nfunction addDefaultEndpointCandidates(candidates: string[], baseUrl: string) {\n const base = baseUrl.replace(/\\/$/, \"\");\n candidates.push(`${base}/_agent-native/a2a`, `${base}/a2a`);\n}\n\nfunction normalizeUrl(\n value: string | undefined,\n baseUrl: string,\n): string | null {\n if (!value) return null;\n try {\n return new URL(value, `${baseUrl.replace(/\\/$/, \"\")}/`)\n .toString()\n .replace(/\\/$/, \"\");\n } catch {\n return null;\n }\n}\n\nfunction shouldTryNextEndpoint(status: number): boolean {\n return status === 404 || status === 405;\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n\n/**\n * One-shot convenience function: send a text message and get a text response.\n *\n * When A2A_SECRET is set and userEmail is provided, outbound calls are signed\n * with a JWT so the receiving app can cryptographically verify the caller's\n * identity (instead of blindly trusting metadata).\n */\nexport async function callAgent(\n url: string,\n text: string,\n opts?: {\n apiKey?: string;\n contextId?: string;\n userEmail?: string;\n orgDomain?: string;\n orgSecret?: string;\n /**\n * Use async/poll instead of a single blocking POST. Recommended for\n * cross-app calls that may exceed a synchronous serverless request budget.\n * Defaults to true so callers get safe behavior out of the box.\n */\n async?: boolean;\n /** Total time to wait for the polled task (default 5 min). */\n timeoutMs?: number;\n /** Poll interval for async calls. Primarily useful for tests/retries. */\n pollIntervalMs?: number;\n },\n): Promise<string> {\n let apiKey = opts?.apiKey;\n\n // Auto-sign with JWT when an A2A secret (org or global) is available and we have a user email\n if (\n !apiKey &&\n opts?.userEmail &&\n (opts?.orgSecret || process.env.A2A_SECRET)\n ) {\n try {\n apiKey = await signA2AToken(\n opts.userEmail,\n opts.orgDomain,\n opts.orgSecret,\n { preferGlobalSecret: !opts.orgSecret },\n );\n } catch {\n // Fall back to unsigned call\n }\n }\n\n const client = new A2AClient(url, apiKey);\n const metadata: Record<string, unknown> = {};\n if (opts?.userEmail) metadata.userEmail = opts.userEmail;\n if (opts?.orgDomain) metadata.orgDomain = opts.orgDomain;\n\n // Default to async + poll. The receiving A2A server's `_process-task` route\n // runs the handler in a fresh function execution (cross-platform queue\n // pattern), so async mode now works on every host instead of relying on\n // detached promises that get killed on Netlify/Vercel. Callers that\n // explicitly want a single-shot blocking POST can pass `async: false`.\n const useAsync = opts?.async ?? true;\n const message: Message = {\n role: \"user\",\n parts: [{ type: \"text\", text }],\n };\n\n let task: Task;\n if (useAsync) {\n try {\n task = await client.sendAndWait(message, {\n contextId: opts?.contextId,\n metadata,\n timeoutMs: opts?.timeoutMs,\n pollIntervalMs: opts?.pollIntervalMs,\n });\n } catch (err) {\n if (err instanceof A2ATaskTimeoutError) {\n const recoverableText = extractRecoverableArtifactText(err.lastTask);\n if (recoverableText) return recoverableText;\n }\n throw err;\n }\n } else {\n task = await client.send(message, {\n contextId: opts?.contextId,\n metadata,\n });\n }\n\n // Extract text from the response\n const responseMessage = task.status.message;\n if (responseMessage) {\n const textParts = responseMessage.parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text);\n return textParts.join(\"\\n\");\n }\n\n return \"\";\n}\n\nfunction extractRecoverableArtifactText(task: Task): string {\n if (!task.status.message?.metadata?.agentNativeRecoverableArtifacts) {\n return \"\";\n }\n return extractMessageText(task.status.message);\n}\n\nfunction extractMessageText(message: Message): string {\n return message.parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\\n\");\n}\n"]}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"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","sourcesContent":["import * as jose from \"jose\";\nimport { ssrfSafeFetch } from \"../extensions/url-safety.js\";\nimport type {\n AgentCard,\n JsonRpcRequest,\n JsonRpcResponse,\n Message,\n Task,\n} from \"./types.js\";\n\nexport class A2ATaskTimeoutError extends Error {\n readonly taskId: string;\n readonly lastTask: Task;\n readonly lastState: string;\n readonly timeoutMs: number;\n\n constructor(taskId: string, lastTask: Task, timeoutMs: number) {\n const lastState = lastTask.status.state;\n super(\n `A2A task ${taskId} did not complete within ${timeoutMs}ms (last state: ${lastState})`,\n );\n this.name = \"A2ATaskTimeoutError\";\n this.taskId = taskId;\n this.lastTask = lastTask;\n this.lastState = lastState;\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Sign a JWT for A2A cross-app identity verification.\n *\n * Uses an org-level secret by default for direct org-secret workflows. Callers\n * that are doing ordinary hosted cross-app delegation can set\n * `preferGlobalSecret` so deployments with a shared A2A_SECRET don't depend on\n * every app database having an identical org row. The token contains the\n * caller's email as `sub`, so the receiving app can verify who's calling.\n */\nexport async function signA2AToken(\n email: string,\n orgDomain?: string,\n orgSecret?: string,\n options?: {\n expiresIn?: string | number;\n preferGlobalSecret?: boolean;\n /**\n * Extra JWT claims to merge alongside `sub` / `org_domain`. Used by the\n * MCP connect flow to add a revocable `jti` and a `scope: \"mcp-connect\"`\n * marker. Reserved claims (`sub`, `org_domain`) cannot be overridden —\n * they are spread last so a caller can never spoof identity via this map.\n */\n extraClaims?: Record<string, unknown>;\n },\n): Promise<string> {\n const secret = options?.preferGlobalSecret\n ? process.env.A2A_SECRET || orgSecret\n : orgSecret || process.env.A2A_SECRET;\n if (!secret) {\n throw new Error(\n \"No A2A secret available. Set an org-level A2A secret in Team settings, \" +\n \"or set A2A_SECRET as an environment variable on all apps that need to verify identity.\",\n );\n }\n\n const appUrl =\n process.env.APP_URL ||\n process.env.BETTER_AUTH_URL ||\n \"http://localhost:3000\";\n\n return new jose.SignJWT({\n ...(options?.extraClaims ?? {}),\n // `sub` / `org_domain` are spread AFTER extraClaims so a caller-supplied\n // map can never override the verified identity claims.\n sub: email,\n ...(orgDomain ? { org_domain: orgDomain } : {}),\n })\n .setProtectedHeader({ alg: \"HS256\" })\n .setIssuer(appUrl)\n .setIssuedAt()\n .setExpirationTime(options?.expiresIn ?? \"15m\")\n .sign(new TextEncoder().encode(secret));\n}\n\nexport class A2AClient {\n private baseUrl: string;\n private apiKey?: string;\n private endpointCandidates: string[] = [];\n private endpointResolved = false;\n private requestTimeoutMs?: number;\n\n constructor(\n baseUrl: string,\n apiKey?: string,\n options?: { requestTimeoutMs?: number },\n ) {\n const normalized = baseUrl.replace(/\\/$/, \"\");\n const explicitEndpoint = splitExplicitA2AEndpoint(normalized);\n this.baseUrl = explicitEndpoint?.baseUrl ?? normalized;\n if (explicitEndpoint) {\n this.endpointCandidates = [explicitEndpoint.endpointUrl];\n this.endpointResolved = true;\n }\n this.apiKey = apiKey;\n this.requestTimeoutMs = options?.requestTimeoutMs;\n }\n\n /**\n * Detect which A2A path the target agent uses.\n * Agent-native apps use /_agent-native/a2a, external agents may use /a2a.\n */\n async resolveEndpoint(): Promise<void> {\n await this.ensureEndpointCandidates();\n if (this.endpointCandidates.length <= 1) return;\n\n for (const endpoint of this.endpointCandidates) {\n try {\n const res = await ssrfSafeFetch(\n endpoint,\n { method: \"OPTIONS\" },\n { maxRedirects: 3 },\n );\n if (res.status !== 404 && res.status !== 405) {\n this.endpointCandidates = [endpoint];\n return;\n }\n if (res.status === 405) {\n this.endpointCandidates = [endpoint];\n return;\n }\n } catch {\n // Try the next candidate.\n }\n }\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (this.apiKey) {\n h[\"Authorization\"] = `Bearer ${this.apiKey}`;\n }\n return h;\n }\n\n private async rpc(\n method: string,\n params: Record<string, unknown>,\n ): Promise<JsonRpcResponse> {\n const body: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id: Date.now(),\n method,\n params,\n };\n\n await this.ensureEndpointCandidates();\n let lastError: Error | null = null;\n\n for (const url of this.endpointCandidates) {\n console.log(`[A2A Client] POST ${url} method=${method}`);\n const startTime = Date.now();\n const res = await this.postJson(url, body);\n console.log(\n `[A2A Client] Response: ${res.status} in ${Date.now() - startTime}ms`,\n );\n\n if (res.ok) {\n this.endpointCandidates = [url];\n return res.json() as Promise<JsonRpcResponse>;\n }\n\n const text = await res.text();\n lastError = new Error(`A2A request failed (${res.status}): ${text}`);\n if (!shouldTryNextEndpoint(res.status)) {\n throw lastError;\n }\n }\n\n throw lastError ?? new Error(\"No A2A endpoint candidates available\");\n }\n\n async getAgentCard(): Promise<AgentCard> {\n const res = await ssrfSafeFetch(\n `${this.baseUrl}/.well-known/agent-card.json`,\n {},\n { maxRedirects: 3 },\n );\n if (!res.ok) {\n throw new Error(`Failed to fetch agent card (${res.status})`);\n }\n return res.json() as Promise<AgentCard>;\n }\n\n async send(\n message: Message,\n opts?: {\n contextId?: string;\n metadata?: Record<string, unknown>;\n /**\n * If true, ask the server to return the task immediately in `working`\n * state and process the handler in the background. The caller should\n * then poll `getTask(taskId)` until `completed` / `failed` / `canceled`.\n *\n * Use this when you expect the handler may exceed a synchronous\n * serverless request budget.\n */\n async?: boolean;\n },\n ): Promise<Task> {\n const response = await this.rpc(\"message/send\", {\n message,\n contextId: opts?.contextId,\n metadata: opts?.metadata,\n ...(opts?.async ? { async: true } : {}),\n });\n\n if (response.error) {\n throw new Error(\n `A2A error (${response.error.code}): ${response.error.message}`,\n );\n }\n\n return response.result as Task;\n }\n\n /**\n * Poll for a task by id. Used in async mode after `send({ async: true })`.\n */\n async getTask(taskId: string): Promise<Task> {\n const response = await this.rpc(\"tasks/get\", { id: taskId });\n if (response.error) {\n throw new Error(\n `A2A error (${response.error.code}): ${response.error.message}`,\n );\n }\n return response.result as Task;\n }\n\n /**\n * Send a message in async mode and poll until the task reaches a terminal\n * state. This is the recommended path on serverless hosts with short\n * function timeouts (Netlify, Vercel) where a synchronous LLM-driven A2A\n * call can exceed the gateway limit.\n *\n * Each individual fetch returns quickly; long-running work happens on the\n * receiving side and is checked via `tasks/get`.\n */\n async sendAndWait(\n message: Message,\n opts?: {\n contextId?: string;\n metadata?: Record<string, unknown>;\n /** Total time to wait for completion. Default 5 min. */\n timeoutMs?: number;\n /** Poll interval. Default 2s. */\n pollIntervalMs?: number;\n /** Called with each polled task — useful for surfacing progress. */\n onUpdate?: (task: Task) => void;\n },\n ): Promise<Task> {\n const submitted = await this.send(message, {\n contextId: opts?.contextId,\n metadata: opts?.metadata,\n async: true,\n });\n\n const terminalStates = new Set([\"completed\", \"failed\", \"canceled\"]);\n if (terminalStates.has(submitted.status.state)) return submitted;\n\n const timeoutMs = opts?.timeoutMs ?? 5 * 60_000;\n const pollMs = opts?.pollIntervalMs ?? 2_000;\n const deadline = Date.now() + timeoutMs;\n\n let current = submitted;\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, pollMs));\n try {\n current = await this.getTask(submitted.id);\n opts?.onUpdate?.(current);\n } catch {\n // Transient fetch failure — keep polling until the deadline.\n continue;\n }\n if (terminalStates.has(current.status.state)) return current;\n }\n throw new A2ATaskTimeoutError(submitted.id, current, timeoutMs);\n }\n\n async *stream(\n message: Message,\n opts?: { contextId?: string; metadata?: Record<string, unknown> },\n ): AsyncGenerator<Task> {\n const body: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id: Date.now(),\n method: \"message/stream\",\n params: {\n message,\n contextId: opts?.contextId,\n metadata: opts?.metadata,\n },\n };\n\n await this.ensureEndpointCandidates();\n let res: Response | null = null;\n let lastError: Error | null = null;\n for (const candidate of this.endpointCandidates) {\n res = await this.postJson(candidate, body);\n if (res.ok) {\n this.endpointCandidates = [candidate];\n break;\n }\n const text = await res.text();\n lastError = new Error(`A2A stream failed (${res.status}): ${text}`);\n if (!shouldTryNextEndpoint(res.status)) throw lastError;\n }\n if (!res?.ok) {\n throw lastError ?? new Error(\"No A2A endpoint candidates available\");\n }\n\n const reader = res.body?.getReader();\n if (!reader) throw new Error(\"No response body\");\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const json = line.slice(6).trim();\n if (!json) continue;\n\n const response: JsonRpcResponse = JSON.parse(json);\n if (response.error) {\n throw new Error(\n `A2A error (${response.error.code}): ${response.error.message}`,\n );\n }\n if (response.result) {\n yield response.result as Task;\n }\n }\n }\n }\n\n private async ensureEndpointCandidates(): Promise<void> {\n if (this.endpointResolved) return;\n this.endpointResolved = true;\n\n const candidates: string[] = [];\n addDefaultEndpointCandidates(candidates, this.baseUrl);\n\n try {\n const card = await this.getAgentCard();\n const cardUrl = normalizeUrl(card.url, this.baseUrl);\n if (cardUrl) {\n const explicitEndpoint = splitExplicitA2AEndpoint(cardUrl);\n if (explicitEndpoint) {\n candidates.unshift(explicitEndpoint.endpointUrl);\n } else {\n addDefaultEndpointCandidates(candidates, cardUrl);\n }\n }\n } catch {\n // Agent cards are discovery hints. Fall back to conventional endpoints.\n }\n\n this.endpointCandidates = unique(candidates);\n }\n\n private async postJson(url: string, body: JsonRpcRequest): Promise<Response> {\n const controller = this.requestTimeoutMs\n ? new AbortController()\n : undefined;\n const timer =\n controller && this.requestTimeoutMs\n ? setTimeout(() => controller.abort(), this.requestTimeoutMs)\n : undefined;\n try {\n return await ssrfSafeFetch(\n url,\n {\n method: \"POST\",\n headers: this.headers(),\n body: JSON.stringify(body),\n signal: controller?.signal,\n },\n { maxRedirects: 3 },\n );\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n}\n\nfunction splitExplicitA2AEndpoint(\n url: string,\n): { baseUrl: string; endpointUrl: string } | null {\n try {\n const parsed = new URL(url);\n const pathname = parsed.pathname.replace(/\\/$/, \"\");\n if (pathname.endsWith(\"/_agent-native/a2a\")) {\n parsed.pathname = pathname.slice(0, -\"/_agent-native/a2a\".length) || \"/\";\n parsed.search = \"\";\n parsed.hash = \"\";\n return {\n baseUrl: parsed.toString().replace(/\\/$/, \"\"),\n endpointUrl: url,\n };\n }\n if (pathname.endsWith(\"/a2a\")) {\n parsed.pathname = pathname.slice(0, -\"/a2a\".length) || \"/\";\n parsed.search = \"\";\n parsed.hash = \"\";\n return {\n baseUrl: parsed.toString().replace(/\\/$/, \"\"),\n endpointUrl: url,\n };\n }\n } catch {\n // Relative or invalid URLs are handled by the caller's normal fetch path.\n }\n return null;\n}\n\nfunction addDefaultEndpointCandidates(candidates: string[], baseUrl: string) {\n const base = baseUrl.replace(/\\/$/, \"\");\n candidates.push(`${base}/_agent-native/a2a`, `${base}/a2a`);\n}\n\nfunction normalizeUrl(\n value: string | undefined,\n baseUrl: string,\n): string | null {\n if (!value) return null;\n try {\n return new URL(value, `${baseUrl.replace(/\\/$/, \"\")}/`)\n .toString()\n .replace(/\\/$/, \"\");\n } catch {\n return null;\n }\n}\n\nfunction shouldTryNextEndpoint(status: number): boolean {\n return status === 404 || status === 405;\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n\n/**\n * One-shot convenience function: send a text message and get a text response.\n *\n * When A2A_SECRET is set and userEmail is provided, outbound calls are signed\n * with a JWT so the receiving app can cryptographically verify the caller's\n * identity (instead of blindly trusting metadata).\n */\nexport async function callAgent(\n url: string,\n text: string,\n opts?: {\n apiKey?: string;\n contextId?: string;\n userEmail?: string;\n orgDomain?: string;\n orgSecret?: string;\n /**\n * Use async/poll instead of a single blocking POST. Recommended for\n * cross-app calls that may exceed a synchronous serverless request budget.\n * Defaults to true so callers get safe behavior out of the box.\n */\n async?: boolean;\n /** Total time to wait for the polled task (default 5 min). */\n timeoutMs?: number;\n /** Poll interval for async calls. Primarily useful for tests/retries. */\n pollIntervalMs?: number;\n },\n): Promise<string> {\n let apiKey = opts?.apiKey;\n\n // Auto-sign with JWT when an A2A secret (org or global) is available and we have a user email\n if (\n !apiKey &&\n opts?.userEmail &&\n (opts?.orgSecret || process.env.A2A_SECRET)\n ) {\n try {\n apiKey = await signA2AToken(\n opts.userEmail,\n opts.orgDomain,\n opts.orgSecret,\n { preferGlobalSecret: !opts.orgSecret },\n );\n } catch {\n // Fall back to unsigned call\n }\n }\n\n const client = new A2AClient(url, apiKey);\n const metadata: Record<string, unknown> = {};\n if (opts?.userEmail) metadata.userEmail = opts.userEmail;\n if (opts?.orgDomain) metadata.orgDomain = opts.orgDomain;\n\n // Default to async + poll. The receiving A2A server's `_process-task` route\n // runs the handler in a fresh function execution (cross-platform queue\n // pattern), so async mode now works on every host instead of relying on\n // detached promises that get killed on Netlify/Vercel. Callers that\n // explicitly want a single-shot blocking POST can pass `async: false`.\n const useAsync = opts?.async ?? true;\n const message: Message = {\n role: \"user\",\n parts: [{ type: \"text\", text }],\n };\n\n let task: Task;\n if (useAsync) {\n try {\n task = await client.sendAndWait(message, {\n contextId: opts?.contextId,\n metadata,\n timeoutMs: opts?.timeoutMs,\n pollIntervalMs: opts?.pollIntervalMs,\n });\n } catch (err) {\n if (err instanceof A2ATaskTimeoutError) {\n const recoverableText = extractRecoverableArtifactText(err.lastTask);\n if (recoverableText) return recoverableText;\n }\n throw err;\n }\n } else {\n task = await client.send(message, {\n contextId: opts?.contextId,\n metadata,\n });\n }\n\n // Extract text from the response\n const responseMessage = task.status.message;\n if (responseMessage) {\n const textParts = responseMessage.parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text);\n return textParts.join(\"\\n\");\n }\n\n return \"\";\n}\n\nfunction extractRecoverableArtifactText(task: Task): string {\n if (!task.status.message?.metadata?.agentNativeRecoverableArtifacts) {\n return \"\";\n }\n return extractMessageText(task.status.message);\n}\n\nfunction extractMessageText(message: Message): string {\n return message.parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\\n\");\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../../src/a2a/task-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAuErE,wBAAsB,UAAU,CAC9B,OAAO,EAAE,OAAO,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GACzB,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUrE;AAED;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAC7C,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAwBtB;AAED,wBAAsB,uBAAuB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IACjE,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC9C,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,IAAI,CAAC,CAeR;AAED,wBAAsB,0BAA0B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAa7E;AAED,wBAAsB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAazE;AAED,wBAAsB,yBAAyB,CAC7C,EAAE,EAAE,MAAM,EACV,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,OAAO,CAAC,CAiBlB;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,MAAM,EACV,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CAsBlB;AAED,wBAAsB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAS9D;AAED,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,EACV,MAAM,EAAE;IACN,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;CACxB,GACA,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CA4CtB;AAED,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAgBnE"}
1
+ {"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../../src/a2a/task-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AA2ErE,wBAAsB,UAAU,CAC9B,OAAO,EAAE,OAAO,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GACzB,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUrE;AAED;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAC7C,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAwBtB;AAED,wBAAsB,uBAAuB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IACjE,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC9C,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,IAAI,CAAC,CAeR;AAED,wBAAsB,0BAA0B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAa7E;AAED,wBAAsB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAazE;AAED,wBAAsB,yBAAyB,CAC7C,EAAE,EAAE,MAAM,EACV,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,OAAO,CAAC,CAiBlB;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,MAAM,EACV,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CAsBlB;AAED,wBAAsB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAS9D;AAED,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,EACV,MAAM,EAAE;IACN,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;CACxB,GACA,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CA4CtB;AAED,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAgBnE"}
@@ -31,7 +31,11 @@ async function ensureTable() {
31
31
  catch {
32
32
  // Column already exists — expected on every restart after first run.
33
33
  }
34
- })();
34
+ })().catch((err) => {
35
+ // Retry init on the next call after a failed startup.
36
+ _initPromise = undefined;
37
+ throw err;
38
+ });
35
39
  }
36
40
  return _initPromise;
37
41
  }
@@ -1 +1 @@
1
- {"version":3,"file":"task-store.js","sourceRoot":"","sources":["../../src/a2a/task-store.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"crypto\";\nimport { getDbExec, intType } from \"../db/client.js\";\nimport type { Task, Message, TaskState, Artifact } from \"./types.js\";\n\nlet _initPromise: Promise<void> | undefined;\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n await client.execute(`\n CREATE TABLE IF NOT EXISTS a2a_tasks (\n id TEXT PRIMARY KEY,\n context_id TEXT,\n status_state TEXT NOT NULL DEFAULT 'submitted',\n status_message TEXT,\n status_timestamp TEXT NOT NULL,\n history TEXT NOT NULL DEFAULT '[]',\n artifacts TEXT NOT NULL DEFAULT '[]',\n metadata TEXT,\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )\n `);\n // Additive migration: owner_email column. Bound to the JWT-verified\n // caller at task-creation time so handleGet / handleCancel can reject\n // mismatched callers (the IDOR class fixed in PR #369). Existing rows\n // have NULL owner_email and remain accessible to legacy callers via\n // the legacy-token apiKeyEnv path; new rows are scoped from this point\n // forward.\n try {\n await client.execute(\n `ALTER TABLE a2a_tasks ADD COLUMN owner_email TEXT`,\n );\n } catch {\n // Column already exists — expected on every restart after first run.\n }\n })();\n }\n return _initPromise;\n}\n\nfunction taskFromRow(row: any): Task & { ownerEmail?: string | null } {\n return {\n id: row.id as string,\n contextId: (row.context_id as string) || undefined,\n status: {\n state: row.status_state as TaskState,\n message: row.status_message\n ? JSON.parse(row.status_message as string)\n : undefined,\n timestamp: row.status_timestamp as string,\n },\n history: JSON.parse(row.history as string),\n artifacts: JSON.parse(row.artifacts as string),\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,\n ownerEmail: (row.owner_email as string | null) ?? null,\n };\n}\n\nfunction getAffectedRowCount(result: unknown): number | undefined {\n const resultRecord = result as\n | {\n rowsAffected?: number;\n rowCount?: number;\n count?: number;\n }\n | undefined;\n return (\n resultRecord?.rowsAffected ?? resultRecord?.rowCount ?? resultRecord?.count\n );\n}\n\nexport async function createTask(\n message: Message,\n contextId?: string,\n metadata?: Record<string, unknown>,\n ownerEmail?: string | null,\n): Promise<Task> {\n await ensureTable();\n const client = getDbExec();\n const id = crypto.randomUUID();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n\n const task: Task = {\n id,\n contextId,\n status: { state: \"submitted\", timestamp },\n history: [message],\n artifacts: [],\n metadata,\n };\n\n await client.execute({\n sql: `INSERT INTO a2a_tasks (id, context_id, status_state, status_timestamp, history, artifacts, metadata, owner_email, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n id,\n contextId ?? null,\n \"submitted\",\n timestamp,\n JSON.stringify([message]),\n \"[]\",\n metadata ? JSON.stringify(metadata) : null,\n ownerEmail ?? null,\n now,\n now,\n ],\n });\n\n return task;\n}\n\n/**\n * Fetch the verified owner email recorded against a task at creation time.\n * Returns null when the task has no owner (legacy rows or unauthenticated\n * deployments) or when the task is missing.\n *\n * Used by `handleGet` / `handleCancel` to reject IDOR access — the JWT-\n * verified caller's email must match `owner_email` to read or cancel.\n */\nexport async function getTaskOwner(id: string): Promise<string | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT owner_email FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n const ownerEmail = (rows[0] as any).owner_email;\n return typeof ownerEmail === \"string\" && ownerEmail ? ownerEmail : null;\n}\n\n/**\n * Atomically claim a task for processing. Only succeeds when the task is in\n * state 'submitted' or 'working' — flipping it to 'processing' so concurrent\n * processors can't pick it up twice. Returns the task if claimed, null if it\n * was already claimed/completed/missing.\n *\n * Used by the cross-platform async processor (`_process-task` route) to avoid\n * duplicate handler runs when retries fire.\n */\nexport async function claimA2ATaskForProcessing(\n id: string,\n): Promise<Task | null> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_state = 'processing',\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state IN ('submitted', 'working')`,\n args: [timestamp, now, id],\n });\n const affected = getAffectedRowCount(result);\n if (affected === 0) return null;\n\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n return taskFromRow(rows[0]);\n}\n\nexport async function getA2ATaskDispatchState(id: string): Promise<{\n id: string;\n statusState: string;\n metadata: Record<string, unknown> | undefined;\n updatedAt: number;\n} | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT id, status_state, metadata, updated_at FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n const row = rows[0] as any;\n if (!row) return null;\n return {\n id: row.id as string,\n statusState: row.status_state as string,\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,\n updatedAt: Number(row.updated_at ?? 0),\n };\n}\n\nexport async function touchQueuedA2ATaskDispatch(id: string): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET updated_at = ?\n WHERE id = ?\n AND status_state IN ('submitted', 'working')`,\n args: [now, id],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\nexport async function touchProcessingA2ATask(id: string): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET updated_at = ?\n WHERE id = ?\n AND status_state = 'processing'`,\n args: [now, id],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\nexport async function resetStuckA2ATaskForRetry(\n id: string,\n processingCutoff: number,\n): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_state = 'working',\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state = 'processing'\n AND updated_at <= ?`,\n args: [timestamp, now, id, processingCutoff],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\nexport async function failStuckA2ATask(\n id: string,\n processingCutoff: number,\n reason: string,\n): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n const message: Message = {\n role: \"agent\",\n parts: [{ type: \"text\", text: reason }],\n };\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_state = 'failed',\n status_message = ?,\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state = 'processing'\n AND updated_at <= ?`,\n args: [JSON.stringify(message), timestamp, now, id, processingCutoff],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\nexport async function getTask(id: string): Promise<Task | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n return taskFromRow(rows[0]);\n}\n\nexport async function updateTask(\n id: string,\n update: {\n state?: TaskState;\n message?: Message;\n artifacts?: Artifact[];\n },\n): Promise<Task | null> {\n await ensureTable();\n const client = getDbExec();\n\n // Read current task\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n\n const task = taskFromRow(rows[0]);\n const now = Date.now();\n\n if (update.state) {\n task.status = {\n state: update.state,\n message: update.message ?? task.status.message,\n timestamp: new Date().toISOString(),\n };\n }\n\n if (update.message && task.history) {\n task.history.push(update.message);\n }\n\n if (update.artifacts) {\n task.artifacts = [...(task.artifacts ?? []), ...update.artifacts];\n }\n\n await client.execute({\n sql: `UPDATE a2a_tasks SET status_state = ?, status_message = ?, status_timestamp = ?, history = ?, artifacts = ?, updated_at = ? WHERE id = ?`,\n args: [\n task.status.state,\n task.status.message ? JSON.stringify(task.status.message) : null,\n task.status.timestamp,\n JSON.stringify(task.history),\n JSON.stringify(task.artifacts),\n now,\n id,\n ],\n });\n\n return task;\n}\n\nexport async function updateTaskStatusMessage(\n id: string,\n message: Message,\n): Promise<void> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_message = ?,\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state IN ('submitted', 'working', 'processing')`,\n args: [JSON.stringify(message), timestamp, now, id],\n });\n}\n\nexport async function listTasks(contextId?: string): Promise<Task[]> {\n await ensureTable();\n const client = getDbExec();\n\n if (contextId) {\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE context_id = ? ORDER BY created_at DESC`,\n args: [contextId],\n });\n return rows.map(taskFromRow);\n }\n\n const { rows } = await client.execute(\n `SELECT * FROM a2a_tasks ORDER BY created_at DESC`,\n );\n return rows.map(taskFromRow);\n}\n"]}
1
+ {"version":3,"file":"task-store.js","sourceRoot":"","sources":["../../src/a2a/task-store.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"crypto\";\nimport { getDbExec, intType } from \"../db/client.js\";\nimport type { Task, Message, TaskState, Artifact } from \"./types.js\";\n\nlet _initPromise: Promise<void> | undefined;\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n await client.execute(`\n CREATE TABLE IF NOT EXISTS a2a_tasks (\n id TEXT PRIMARY KEY,\n context_id TEXT,\n status_state TEXT NOT NULL DEFAULT 'submitted',\n status_message TEXT,\n status_timestamp TEXT NOT NULL,\n history TEXT NOT NULL DEFAULT '[]',\n artifacts TEXT NOT NULL DEFAULT '[]',\n metadata TEXT,\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )\n `);\n // Additive migration: owner_email column. Bound to the JWT-verified\n // caller at task-creation time so handleGet / handleCancel can reject\n // mismatched callers (the IDOR class fixed in PR #369). Existing rows\n // have NULL owner_email and remain accessible to legacy callers via\n // the legacy-token apiKeyEnv path; new rows are scoped from this point\n // forward.\n try {\n await client.execute(\n `ALTER TABLE a2a_tasks ADD COLUMN owner_email TEXT`,\n );\n } catch {\n // Column already exists — expected on every restart after first run.\n }\n })().catch((err) => {\n // Retry init on the next call after a failed startup.\n _initPromise = undefined;\n throw err;\n });\n }\n return _initPromise;\n}\n\nfunction taskFromRow(row: any): Task & { ownerEmail?: string | null } {\n return {\n id: row.id as string,\n contextId: (row.context_id as string) || undefined,\n status: {\n state: row.status_state as TaskState,\n message: row.status_message\n ? JSON.parse(row.status_message as string)\n : undefined,\n timestamp: row.status_timestamp as string,\n },\n history: JSON.parse(row.history as string),\n artifacts: JSON.parse(row.artifacts as string),\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,\n ownerEmail: (row.owner_email as string | null) ?? null,\n };\n}\n\nfunction getAffectedRowCount(result: unknown): number | undefined {\n const resultRecord = result as\n | {\n rowsAffected?: number;\n rowCount?: number;\n count?: number;\n }\n | undefined;\n return (\n resultRecord?.rowsAffected ?? resultRecord?.rowCount ?? resultRecord?.count\n );\n}\n\nexport async function createTask(\n message: Message,\n contextId?: string,\n metadata?: Record<string, unknown>,\n ownerEmail?: string | null,\n): Promise<Task> {\n await ensureTable();\n const client = getDbExec();\n const id = crypto.randomUUID();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n\n const task: Task = {\n id,\n contextId,\n status: { state: \"submitted\", timestamp },\n history: [message],\n artifacts: [],\n metadata,\n };\n\n await client.execute({\n sql: `INSERT INTO a2a_tasks (id, context_id, status_state, status_timestamp, history, artifacts, metadata, owner_email, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n id,\n contextId ?? null,\n \"submitted\",\n timestamp,\n JSON.stringify([message]),\n \"[]\",\n metadata ? JSON.stringify(metadata) : null,\n ownerEmail ?? null,\n now,\n now,\n ],\n });\n\n return task;\n}\n\n/**\n * Fetch the verified owner email recorded against a task at creation time.\n * Returns null when the task has no owner (legacy rows or unauthenticated\n * deployments) or when the task is missing.\n *\n * Used by `handleGet` / `handleCancel` to reject IDOR access — the JWT-\n * verified caller's email must match `owner_email` to read or cancel.\n */\nexport async function getTaskOwner(id: string): Promise<string | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT owner_email FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n const ownerEmail = (rows[0] as any).owner_email;\n return typeof ownerEmail === \"string\" && ownerEmail ? ownerEmail : null;\n}\n\n/**\n * Atomically claim a task for processing. Only succeeds when the task is in\n * state 'submitted' or 'working' — flipping it to 'processing' so concurrent\n * processors can't pick it up twice. Returns the task if claimed, null if it\n * was already claimed/completed/missing.\n *\n * Used by the cross-platform async processor (`_process-task` route) to avoid\n * duplicate handler runs when retries fire.\n */\nexport async function claimA2ATaskForProcessing(\n id: string,\n): Promise<Task | null> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_state = 'processing',\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state IN ('submitted', 'working')`,\n args: [timestamp, now, id],\n });\n const affected = getAffectedRowCount(result);\n if (affected === 0) return null;\n\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n return taskFromRow(rows[0]);\n}\n\nexport async function getA2ATaskDispatchState(id: string): Promise<{\n id: string;\n statusState: string;\n metadata: Record<string, unknown> | undefined;\n updatedAt: number;\n} | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT id, status_state, metadata, updated_at FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n const row = rows[0] as any;\n if (!row) return null;\n return {\n id: row.id as string,\n statusState: row.status_state as string,\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,\n updatedAt: Number(row.updated_at ?? 0),\n };\n}\n\nexport async function touchQueuedA2ATaskDispatch(id: string): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET updated_at = ?\n WHERE id = ?\n AND status_state IN ('submitted', 'working')`,\n args: [now, id],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\nexport async function touchProcessingA2ATask(id: string): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET updated_at = ?\n WHERE id = ?\n AND status_state = 'processing'`,\n args: [now, id],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\nexport async function resetStuckA2ATaskForRetry(\n id: string,\n processingCutoff: number,\n): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_state = 'working',\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state = 'processing'\n AND updated_at <= ?`,\n args: [timestamp, now, id, processingCutoff],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\nexport async function failStuckA2ATask(\n id: string,\n processingCutoff: number,\n reason: string,\n): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n const message: Message = {\n role: \"agent\",\n parts: [{ type: \"text\", text: reason }],\n };\n const result = await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_state = 'failed',\n status_message = ?,\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state = 'processing'\n AND updated_at <= ?`,\n args: [JSON.stringify(message), timestamp, now, id, processingCutoff],\n });\n const affected = getAffectedRowCount(result);\n return affected !== 0;\n}\n\nexport async function getTask(id: string): Promise<Task | null> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n return taskFromRow(rows[0]);\n}\n\nexport async function updateTask(\n id: string,\n update: {\n state?: TaskState;\n message?: Message;\n artifacts?: Artifact[];\n },\n): Promise<Task | null> {\n await ensureTable();\n const client = getDbExec();\n\n // Read current task\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE id = ?`,\n args: [id],\n });\n if (rows.length === 0) return null;\n\n const task = taskFromRow(rows[0]);\n const now = Date.now();\n\n if (update.state) {\n task.status = {\n state: update.state,\n message: update.message ?? task.status.message,\n timestamp: new Date().toISOString(),\n };\n }\n\n if (update.message && task.history) {\n task.history.push(update.message);\n }\n\n if (update.artifacts) {\n task.artifacts = [...(task.artifacts ?? []), ...update.artifacts];\n }\n\n await client.execute({\n sql: `UPDATE a2a_tasks SET status_state = ?, status_message = ?, status_timestamp = ?, history = ?, artifacts = ?, updated_at = ? WHERE id = ?`,\n args: [\n task.status.state,\n task.status.message ? JSON.stringify(task.status.message) : null,\n task.status.timestamp,\n JSON.stringify(task.history),\n JSON.stringify(task.artifacts),\n now,\n id,\n ],\n });\n\n return task;\n}\n\nexport async function updateTaskStatusMessage(\n id: string,\n message: Message,\n): Promise<void> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const timestamp = new Date().toISOString();\n await client.execute({\n sql: `UPDATE a2a_tasks\n SET status_message = ?,\n status_timestamp = ?,\n updated_at = ?\n WHERE id = ?\n AND status_state IN ('submitted', 'working', 'processing')`,\n args: [JSON.stringify(message), timestamp, now, id],\n });\n}\n\nexport async function listTasks(contextId?: string): Promise<Task[]> {\n await ensureTable();\n const client = getDbExec();\n\n if (contextId) {\n const { rows } = await client.execute({\n sql: `SELECT * FROM a2a_tasks WHERE context_id = ? ORDER BY created_at DESC`,\n args: [contextId],\n });\n return rows.map(taskFromRow);\n }\n\n const { rows } = await client.execute(\n `SELECT * FROM a2a_tasks ORDER BY created_at DESC`,\n );\n return rows.map(taskFromRow);\n}\n"]}
package/dist/action.js CHANGED
@@ -160,7 +160,9 @@ function zodDefToJsonSchema(def) {
160
160
  if (desc && !prop.description)
161
161
  prop.description = desc;
162
162
  properties[key] = prop;
163
- if (fieldDef.type !== "optional" && fieldDef.type !== "default") {
163
+ if (fieldDef.type !== "optional" &&
164
+ fieldDef.type !== "default" &&
165
+ fieldDef.type !== "nullable") {
164
166
  required.push(key);
165
167
  }
166
168
  }
@@ -232,7 +234,10 @@ function zodDefToJsonSchema(def) {
232
234
  }
233
235
  if (type === "nullable") {
234
236
  if (def.innerType?._zod?.def) {
235
- return zodDefToJsonSchema(def.innerType._zod.def);
237
+ const inner = zodDefToJsonSchema(def.innerType._zod.def);
238
+ // Surface null as a valid value so the model knows it may pass null
239
+ // (and doesn't treat the field as a non-nullable required string).
240
+ return { anyOf: [inner, { type: "null" }] };
236
241
  }
237
242
  }
238
243
  if (type === "union") {
@@ -240,9 +245,22 @@ function zodDefToJsonSchema(def) {
240
245
  // Check if it's a simple enum-like union of literals
241
246
  const allLiterals = def.options.every((o) => o?._zod?.def?.type === "literal");
242
247
  if (allLiterals) {
248
+ const values = def.options.map((o) => o._zod.def.value);
249
+ const jsonTypeOf = (v) => typeof v === "number"
250
+ ? "number"
251
+ : typeof v === "boolean"
252
+ ? "boolean"
253
+ : "string";
254
+ const uniqueTypes = [...new Set(values.map(jsonTypeOf))];
255
+ if (uniqueTypes.length === 1) {
256
+ // Homogeneous literal union (e.g. all numbers) — derive the JSON
257
+ // type instead of hardcoding "string", which would contradict the
258
+ // enum values and make the model coerce/round-trip them wrongly.
259
+ return { type: uniqueTypes[0], enum: values };
260
+ }
261
+ // Mixed literal types: emit anyOf so each branch stays self-consistent.
243
262
  return {
244
- type: "string",
245
- enum: def.options.map((o) => o._zod.def.value),
263
+ anyOf: values.map((v) => ({ type: jsonTypeOf(v), enum: [v] })),
246
264
  };
247
265
  }
248
266
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"action.js","sourceRoot":"","sources":["../src/action.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ActionTool } from \"./agent/types.js\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\nexport interface AgentActionStopOptions {\n /** Optional stable code surfaced in run metadata and tests. */\n errorCode?: string;\n /** Optional short tool-result text. Defaults to the user-facing message. */\n toolResult?: string;\n}\n\n/**\n * Throw from an action when the agent should stop the current turn instead of\n * feeding the failure back to the model for another retry.\n */\nexport class AgentActionStopError extends Error {\n readonly agentNativeStop = true;\n readonly errorCode?: string;\n readonly toolResult?: string;\n\n constructor(message: string, options: AgentActionStopOptions = {}) {\n super(message);\n this.name = \"AgentActionStopError\";\n this.errorCode = options.errorCode;\n this.toolResult = options.toolResult;\n }\n}\n\nexport function isAgentActionStopError(\n err: unknown,\n): err is AgentActionStopError {\n return (\n err instanceof AgentActionStopError ||\n Boolean(\n err &&\n typeof err === \"object\" &&\n \"agentNativeStop\" in err &&\n (err as { agentNativeStop?: unknown }).agentNativeStop === true,\n )\n );\n}\n\n/** HTTP exposure config for an action. */\nexport interface ActionHttpConfig {\n /** HTTP method. Default: \"POST\". Use \"GET\" for read-only actions. */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n /** Override route path under /_agent-native/actions/. Default: action filename. */\n path?: string;\n}\n\n/** Explicit opt-in metadata for public agent protocols such as MCP or A2A. */\nexport interface PublicAgentActionConfig {\n expose: boolean;\n readOnly: boolean;\n requiresAuth?: boolean;\n isConsequential?: boolean;\n title?: string;\n description?: string;\n}\n\n/** A deep link an external agent (MCP / A2A) can surface to the user so they\n * can open the produced/listed resource in the running app UI. */\nexport interface ActionDeepLink {\n /** App-relative path (e.g. `/_agent-native/open?app=mail&view=inbox&...`)\n * or an absolute URL. The MCP layer prefixes the request origin when this\n * is relative, and may rewrite it to the `agentnative://` desktop scheme. */\n url: string;\n /** Human-readable label, e.g. \"Open draft in Mail\". */\n label: string;\n /** Optional view hint (matches the `navigate` command `view`). */\n view?: string;\n}\n\n/** Builds a deep link from an action's args + result so external agents can\n * surface an \"Open in <app> →\" link. MUST be pure and synchronous — no I/O,\n * no awaits. Best-effort: a throw or null is swallowed and never fails the\n * tool call. See the `external-agents` skill. */\nexport type ActionLinkBuilder = (ctx: {\n args: Record<string, any>;\n result: any;\n}) => ActionDeepLink | null | undefined;\n\nexport const MCP_APP_EXTENSION_ID = \"io.modelcontextprotocol/ui\" as const;\nexport const MCP_APP_MIME_TYPE = \"text/html;profile=mcp-app\" as const;\nexport const MCP_APP_RESOURCE_URI_META_KEY = \"ui/resourceUri\" as const;\n\nexport interface ActionMcpAppCsp {\n connectDomains?: string[];\n resourceDomains?: string[];\n frameDomains?: string[];\n baseUriDomains?: string[];\n}\n\nexport type ActionMcpAppCspBuilder = (ctx: {\n actionName: string;\n appId?: string;\n requestOrigin?: string;\n}) => ActionMcpAppCsp | Promise<ActionMcpAppCsp>;\n\nexport interface ActionMcpAppPermissions {\n camera?: Record<string, never>;\n microphone?: Record<string, never>;\n geolocation?: Record<string, never>;\n clipboardWrite?: Record<string, never>;\n}\n\nexport interface ActionMcpAppResourceMeta {\n csp?: ActionMcpAppCsp | ActionMcpAppCspBuilder;\n permissions?: ActionMcpAppPermissions;\n /**\n * Host-specific sandbox domain hint. Do not set this to the app's normal\n * production URL; app origins belong in CSP/open-link metadata. ChatGPT uses\n * the separate `openai/widgetDomain` compatibility field.\n */\n domain?: string;\n prefersBorder?: boolean;\n}\n\nexport type ActionMcpAppHtmlBuilder = (ctx: {\n actionName: string;\n appId?: string;\n requestOrigin?: string;\n}) => string;\n\nexport interface ActionMcpAppResourceConfig {\n /** `ui://` URI. Defaults to `ui://<app>/<action-name>`. */\n uri?: string;\n /** MCP resource name. Defaults to the action name. */\n name?: string;\n title?: string;\n description?: string;\n /**\n * HTML5 document content for the MCP App resource. Keep this self-contained\n * or declare any external origins in `csp`.\n */\n html: string | ActionMcpAppHtmlBuilder;\n /** Defaults to the MCP Apps HTML MIME type. */\n mimeType?: typeof MCP_APP_MIME_TYPE;\n /** Extra resource/content metadata. `ui` is merged with the fields below. */\n _meta?: Record<string, unknown>;\n csp?: ActionMcpAppCsp | ActionMcpAppCspBuilder;\n permissions?: ActionMcpAppPermissions;\n /**\n * Host-specific sandbox domain hint. Do not set this to the app's normal\n * production URL; app origins belong in CSP/open-link metadata. ChatGPT uses\n * the separate `openai/widgetDomain` compatibility field.\n */\n domain?: string;\n prefersBorder?: boolean;\n}\n\nexport interface ActionMcpAppConfig {\n resource: ActionMcpAppResourceConfig;\n /**\n * MCP Apps tool visibility. Defaults to model + app so the LLM can call the\n * action and the app iframe can call it back through the host bridge.\n */\n visibility?: Array<\"model\" | \"app\">;\n /**\n * Rare escape hatch for MCP Apps chat hosts. By default OAuth callers with\n * `mcp:apps` see the generic app tools (`open_app`, `list_apps`, etc.) so\n * hosts do not ingest every action-specific UI resource. Set this only when\n * this specific action must stay visible in that compact catalog.\n */\n compactCatalog?: boolean;\n}\n\n/** Schema definition for a single action parameter (legacy JSON schema style). */\nexport interface ParameterSchema {\n type: string;\n description?: string;\n enum?: string[];\n}\n\n/** Infer runtime parameter types from a legacy parameter schema map. */\ntype InferParams<T extends Record<string, ParameterSchema> | undefined> =\n T extends Record<string, ParameterSchema>\n ? { [K in keyof T]?: string }\n : Record<string, string>;\n\n// ---------------------------------------------------------------------------\n// Schema-based action options (new: Zod / Valibot / ArkType via Standard Schema)\n// ---------------------------------------------------------------------------\n\ninterface DefineActionWithSchema<\n TSchema extends StandardSchemaV1,\n TReturn = any,\n> {\n description: string;\n /** Standard Schema-compatible schema (Zod, Valibot, ArkType). Provides runtime\n * validation and full TypeScript type inference for `run()` args. The schema is\n * also converted to JSON Schema for the Claude API tool definition. */\n schema: TSchema;\n /** Legacy parameters — ignored when `schema` is provided. */\n parameters?: never;\n run: (\n args: StandardSchemaV1.InferOutput<TSchema>,\n ) => Promise<TReturn> | TReturn;\n http?: ActionHttpConfig | false;\n /** If true, the framework will NOT emit a screen-refresh change event after a\n * successful call. Auto-inferred as `true` when `http.method === \"GET\"`.\n * Only set this manually when you need to override the inference — e.g. a\n * POST action that only reads data but can't use GET for a protocol reason. */\n readOnly?: boolean;\n /** If true, the agent may execute this action concurrently with other\n * read-only or parallel-safe tool calls emitted in the same model turn.\n * Only set this for mutating actions that are internally concurrency-safe\n * and order-independent for same-turn execution. */\n parallelSafe?: boolean;\n /** Whether this action may be invoked from the tools (Alpine iframe) bridge\n * via `appAction(name, params)` — see `packages/core/docs/content/actions.md`\n * (\"Tools Callability\"). **Default-allow opt-out**: undefined / `true` both\n * allow tool-iframe calls; only an explicit `false` returns 403. Set to\n * `false` for high-blast-radius admin operations (account deletion, org\n * membership changes, anything that modifies auth state) — used by the\n * framework's `share-resource`, `unshare-resource`, and\n * `set-resource-visibility` for defense-in-depth. Regular UI/agent/CLI/MCP/A2A\n * calls are unaffected. Enforced by the action HTTP route layer — see\n * `packages/core/src/server/action-routes.ts`. Audit reference: H5 in\n * `security-audit/05-tools-sandbox.md`. */\n toolCallable?: boolean;\n /** Explicit public-agent exposure metadata. Public web routes never imply\n * public MCP/A2A/OpenAPI tool exposure. Actions must opt in here and public\n * protocol mounts must still filter for safe, route-appropriate tools. */\n publicAgent?: PublicAgentActionConfig;\n /** Optional deep-link builder. When set, MCP/A2A surfaces append an\n * \"Open in <app> →\" link built from the call's args + result so the\n * external agent can drop the user into the running app at the right\n * view/record. Pure + sync + best-effort. See the `external-agents` skill. */\n link?: ActionLinkBuilder;\n /** Optional MCP Apps UI resource for hosts that can render inline\n * interactive app iframes. Text/deep-link tool results remain the fallback\n * for CLI and non-UI hosts. */\n mcpApp?: ActionMcpAppConfig;\n}\n\n// ---------------------------------------------------------------------------\n// Legacy parameter-based action options\n// ---------------------------------------------------------------------------\n\ninterface DefineActionWithParams<\n TParams extends Record<string, ParameterSchema> | undefined =\n | Record<string, ParameterSchema>\n | undefined,\n TReturn = any,\n> {\n description: string;\n /** Flat map of parameter names to their schema. Automatically wrapped in\n * `{ type: \"object\", properties: ... }` for the Claude API. */\n parameters?: TParams;\n /** Standard Schema — not used in this overload. */\n schema?: never;\n run: (args: InferParams<TParams>) => Promise<TReturn> | TReturn;\n http?: ActionHttpConfig | false;\n /** If true, the framework will NOT emit a screen-refresh change event after a\n * successful call. Auto-inferred as `true` when `http.method === \"GET\"`. */\n readOnly?: boolean;\n /** If true, the agent may execute this action concurrently with other\n * read-only or parallel-safe tool calls emitted in the same model turn. */\n parallelSafe?: boolean;\n /** Whether this action may be invoked from the tools (Alpine iframe) bridge\n * via `appAction(name, params)`. See the schema overload above for details\n * and the `toolCallable` section in actions.md. */\n toolCallable?: boolean;\n /** Explicit public-agent exposure metadata. See schema overload above. */\n publicAgent?: PublicAgentActionConfig;\n /** Optional deep-link builder. See schema overload above. */\n link?: ActionLinkBuilder;\n /** Optional MCP Apps UI resource. See schema overload above. */\n mcpApp?: ActionMcpAppConfig;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Define an agent action. Place in `actions/` directory — auto-discovered by the framework.\n *\n * Supports two modes:\n *\n * **Schema mode (recommended)** — pass a Standard Schema-compatible schema (Zod, Valibot,\n * ArkType) for runtime validation and full type inference:\n *\n * ```ts\n * import { defineAction } from \"@agent-native/core\";\n * import { z } from \"zod\";\n *\n * export default defineAction({\n * description: \"Create a form\",\n * schema: z.object({\n * title: z.string().describe(\"Form title\"),\n * status: z.enum([\"draft\", \"published\", \"closed\"]).default(\"draft\"),\n * }),\n * run: async (args) => {\n * // args is { title: string; status: \"draft\" | \"published\" | \"closed\" }\n * // Already validated — invalid inputs never reach here\n * },\n * });\n * ```\n *\n * **Parameters mode (legacy)** — pass raw JSON schema-like parameter definitions:\n *\n * ```ts\n * export default defineAction({\n * description: \"List events\",\n * parameters: {\n * from: { type: \"string\", description: \"Start date\" },\n * },\n * run: async (args) => { ... },\n * });\n * ```\n */\nexport function defineAction<TSchema extends StandardSchemaV1, TReturn>(\n options: DefineActionWithSchema<TSchema, TReturn>,\n): any;\nexport function defineAction<\n TParams extends Record<string, ParameterSchema> | undefined,\n TReturn,\n>(options: DefineActionWithParams<TParams, TReturn>): any;\nexport function defineAction(options: any) {\n const hasSchema = options.schema && \"~standard\" in options.schema;\n\n // Build tool definition for the Claude API\n let toolParameters: ActionTool[\"parameters\"];\n if (hasSchema) {\n // Convert Standard Schema to JSON Schema for Claude\n toolParameters = schemaToJsonSchema(options.schema, options.description);\n } else if (options.parameters) {\n toolParameters = {\n type: \"object\" as const,\n properties: options.parameters,\n };\n }\n\n // Wrap run() with validation when schema is provided.\n // Pass toolParameters so the validation error can echo the expected signature\n // (required vs optional fields) and help the caller self-correct.\n const run = hasSchema\n ? wrapWithValidation(options.schema, options.run, toolParameters)\n : options.run;\n\n // Auto-infer readOnly from http.method === \"GET\" unless explicitly set.\n // GET actions are idempotent reads; their completion should NOT trigger a\n // screen refresh. Everything else is assumed to mutate — the dispatcher\n // emits a change event on success so the UI auto-refetches its queries.\n const httpConfig = options.http as ActionHttpConfig | false | undefined;\n const inferredReadOnly =\n httpConfig !== false &&\n httpConfig !== undefined &&\n httpConfig.method === \"GET\";\n // Explicit `readOnly` (true OR false) wins. Otherwise infer from http.method.\n // We store the resolved boolean so downstream checks can trust entry.readOnly\n // without re-running method inference — including when a caller explicitly\n // passes readOnly:false to override a GET (rare but valid).\n const readOnly: boolean | undefined =\n typeof options.readOnly === \"boolean\"\n ? options.readOnly\n : inferredReadOnly\n ? true\n : undefined;\n\n // toolCallable: thread through whatever the caller declared. We DO NOT\n // default to `true` here — the absence of an explicit field is meaningful\n // to the tools bridge: it lets us emit a one-shot warning when an action\n // without a declared `toolCallable` flag is invoked from a tool, so the\n // ecosystem can migrate over time. The bridge treats `undefined` as\n // \"implicit allow with a deprecation warning\"; only an explicit `false`\n // refuses the call. See `extensions/routes.ts` and audit H5.\n const toolCallable: boolean | undefined =\n typeof options.toolCallable === \"boolean\"\n ? options.toolCallable\n : undefined;\n const parallelSafe: boolean | undefined =\n typeof options.parallelSafe === \"boolean\"\n ? options.parallelSafe\n : undefined;\n const publicAgent: PublicAgentActionConfig | undefined =\n options.publicAgent &&\n typeof options.publicAgent === \"object\" &&\n !Array.isArray(options.publicAgent)\n ? options.publicAgent\n : undefined;\n const link: ActionLinkBuilder | undefined =\n typeof options.link === \"function\" ? options.link : undefined;\n const mcpApp: ActionMcpAppConfig | undefined =\n options.mcpApp &&\n typeof options.mcpApp === \"object\" &&\n !Array.isArray(options.mcpApp) &&\n options.mcpApp.resource &&\n typeof options.mcpApp.resource === \"object\" &&\n !Array.isArray(options.mcpApp.resource) &&\n (typeof options.mcpApp.resource.html === \"string\" ||\n typeof options.mcpApp.resource.html === \"function\")\n ? options.mcpApp\n : undefined;\n\n return {\n tool: {\n description: options.description,\n parameters: toolParameters,\n },\n run,\n ...(hasSchema ? { schema: options.schema } : {}),\n ...(options.http !== undefined ? { http: options.http } : {}),\n ...(typeof readOnly === \"boolean\" ? { readOnly } : {}),\n ...(typeof parallelSafe === \"boolean\" ? { parallelSafe } : {}),\n ...(typeof toolCallable === \"boolean\" ? { toolCallable } : {}),\n ...(publicAgent ? { publicAgent } : {}),\n ...(link ? { link } : {}),\n ...(mcpApp ? { mcpApp } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Schema → JSON Schema conversion\n// ---------------------------------------------------------------------------\n\n/**\n * Convert a Standard Schema to JSON Schema for the Claude API.\n * Tries vendor-specific toJSONSchema first (Zod v4), then falls back\n * to a basic introspection of the schema shape.\n */\nfunction schemaToJsonSchema(\n schema: StandardSchemaV1,\n _description?: string,\n): ActionTool[\"parameters\"] {\n const s = schema as any;\n\n // Prefer Zod's own JSON Schema output — it handles descriptions,\n // enums, coerce, and all type wrappers correctly.\n if (s[\"~standard\"]?.jsonSchema?.input) {\n try {\n const result = s[\"~standard\"].jsonSchema.input({\n target: \"draft-07\",\n }) as any;\n // Strip $schema — the Claude API validates against draft 2020-12\n // and a mismatched $schema declaration can cause rejections.\n if (result && typeof result === \"object\") {\n delete result.$schema;\n }\n return result as ActionTool[\"parameters\"];\n } catch {\n // Fall through to manual converter\n }\n }\n\n // Fallback: manual conversion from Zod v4 internal defs\n if (s._zod?.def) {\n return zodDefToJsonSchema(s._zod.def);\n }\n\n // Last resort: empty object schema\n return { type: \"object\" as const, properties: {} };\n}\n\n/**\n * Convert a Zod v4 internal def to JSON Schema.\n * Handles the common types used in action parameters.\n */\nfunction zodDefToJsonSchema(def: any): any {\n const type = def.type;\n\n if (type === \"object\") {\n const properties: Record<string, any> = {};\n const required: string[] = [];\n const shape = def.shape;\n if (shape) {\n for (const [key, fieldSchema] of Object.entries(shape) as any[]) {\n const fieldDef = fieldSchema?._zod?.def;\n if (fieldDef) {\n const prop = zodDefToJsonSchema(fieldDef);\n // Zod v4 stores .describe() on the schema object, not in the def\n const desc = fieldSchema?.description;\n if (desc && !prop.description) prop.description = desc;\n properties[key] = prop;\n if (fieldDef.type !== \"optional\" && fieldDef.type !== \"default\") {\n required.push(key);\n }\n }\n }\n }\n const result: any = { type: \"object\", properties };\n if (required.length > 0) result.required = required;\n return result;\n }\n\n if (type === \"string\") {\n const result: any = { type: \"string\" };\n if (def.description) result.description = def.description;\n return result;\n }\n\n if (type === \"number\" || type === \"float\" || type === \"int\") {\n const result: any = { type: type === \"int\" ? \"integer\" : \"number\" };\n if (def.description) result.description = def.description;\n return result;\n }\n\n if (type === \"boolean\") {\n const result: any = { type: \"boolean\" };\n if (def.description) result.description = def.description;\n return result;\n }\n\n if (type === \"enum\") {\n // Zod v4 stores enum entries as an object {a: \"a\", b: \"b\"};\n // JSON Schema requires an array.\n const entries = def.entries;\n const enumValues = Array.isArray(entries)\n ? entries\n : typeof entries === \"object\" && entries !== null\n ? Object.values(entries)\n : entries;\n const result: any = { type: \"string\", enum: enumValues };\n if (def.description) result.description = def.description;\n return result;\n }\n\n if (type === \"literal\") {\n return { type: typeof def.value, enum: [def.value] };\n }\n\n if (type === \"array\") {\n const result: any = { type: \"array\" };\n if (def.element?._zod?.def) {\n result.items = zodDefToJsonSchema(def.element._zod.def);\n }\n if (def.description) result.description = def.description;\n return result;\n }\n\n if (type === \"optional\") {\n if (def.innerType?._zod?.def) {\n return zodDefToJsonSchema(def.innerType._zod.def);\n }\n }\n\n if (type === \"default\") {\n if (def.innerType?._zod?.def) {\n const inner = zodDefToJsonSchema(def.innerType._zod.def);\n inner.default =\n typeof def.defaultValue === \"function\"\n ? def.defaultValue()\n : def.defaultValue;\n return inner;\n }\n }\n\n if (type === \"nullable\") {\n if (def.innerType?._zod?.def) {\n return zodDefToJsonSchema(def.innerType._zod.def);\n }\n }\n\n if (type === \"union\") {\n if (def.options?.length) {\n // Check if it's a simple enum-like union of literals\n const allLiterals = def.options.every(\n (o: any) => o?._zod?.def?.type === \"literal\",\n );\n if (allLiterals) {\n return {\n type: \"string\",\n enum: def.options.map((o: any) => o._zod.def.value),\n };\n }\n return {\n anyOf: def.options.map((o: any) =>\n zodDefToJsonSchema(o._zod?.def ?? {}),\n ),\n };\n }\n }\n\n // Fallback\n return { type: \"string\" };\n}\n\n// ---------------------------------------------------------------------------\n// Runtime validation wrapper\n// ---------------------------------------------------------------------------\n\n/**\n * Wrap an action's run function with schema validation.\n * Invalid inputs get a clear error message (including what was actually passed)\n * so the agent can see its own mistake and correct it on the next turn.\n */\nfunction wrapWithValidation(\n schema: StandardSchemaV1,\n run: Function,\n toolParameters?: ActionTool[\"parameters\"],\n): (args: any) => any {\n return async (args: any) => {\n const result = await schema[\"~standard\"].validate(args);\n if (result.issues) {\n // Split issues into \"missing required field\" vs other validation errors\n // so the error message reads naturally rather than as \"fieldName: Required\".\n const missing: string[] = [];\n const other: string[] = [];\n for (const issue of result.issues) {\n const pathStr = issue.path\n ? issue.path.map((p) => (typeof p === \"object\" ? p.key : p)).join(\".\")\n : \"\";\n const msg = String(issue.message ?? \"\");\n // Zod emits \"Required\" for missing fields; other libraries may use\n // similar wording. Treat any variant as \"missing\".\n if (\n pathStr &&\n (msg === \"Required\" ||\n /invalid.*undefined/i.test(msg) ||\n /expected.*received undefined/i.test(msg))\n ) {\n missing.push(pathStr);\n } else {\n other.push(pathStr ? `${pathStr}: ${msg}` : msg);\n }\n }\n\n const parts: string[] = [];\n if (missing.length > 0) {\n parts.push(\n `Missing required parameter${missing.length === 1 ? \"\" : \"s\"}: ${missing.join(\", \")}`,\n );\n }\n if (other.length > 0) {\n parts.push(other.join(\"; \"));\n }\n\n // Echo the args that were actually passed so the caller (usually an\n // agent) can see exactly what it sent and fix its next call.\n let received: string;\n try {\n received = JSON.stringify(args);\n if (received.length > 500) received = received.slice(0, 500) + \"…\";\n } catch {\n received = String(args);\n }\n\n // Also show the EXPECTED signature so the agent doesn't have to guess.\n // Format: `{ deckId*: string, content*: string, slideId?: string, ... }`\n // where `*` = required, `?` = optional.\n let expected = \"\";\n if (toolParameters?.properties) {\n const required = new Set(toolParameters.required ?? []);\n const sig = Object.entries(toolParameters.properties)\n .map(([k, v]) => {\n const mark = required.has(k) ? \"*\" : \"?\";\n const type = (v as { type?: string }).type ?? \"any\";\n return `${k}${mark}: ${type}`;\n })\n .join(\", \");\n if (sig)\n expected = ` Expected: { ${sig} } (where * = required, ? = optional).`;\n }\n\n throw new Error(\n `Invalid action parameters — ${parts.join(\". \")}. Received: ${received}.${expected}`,\n );\n }\n return run((result as StandardSchemaV1.SuccessResult<any>).value);\n };\n}\n"]}
1
+ {"version":3,"file":"action.js","sourceRoot":"","sources":["../src/action.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,eAAe,GAAG,IAAI,CAAC;IACvB,SAAS,CAAU;IACnB,UAAU,CAAU;IAE7B,YAAY,OAAe,EAAE,UAAkC,EAAE;QAC/D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACvC,CAAC;CACF;AAED,MAAM,UAAU,sBAAsB,CACpC,GAAY;IAEZ,OAAO,CACL,GAAG,YAAY,oBAAoB;QACnC,OAAO,CACL,GAAG;YACH,OAAO,GAAG,KAAK,QAAQ;YACvB,iBAAiB,IAAI,GAAG;YACvB,GAAqC,CAAC,eAAe,KAAK,IAAI,CAChE,CACF,CAAC;AACJ,CAAC;AA0CD,MAAM,CAAC,MAAM,oBAAoB,GAAG,4BAAqC,CAAC;AAC1E,MAAM,CAAC,MAAM,iBAAiB,GAAG,2BAAoC,CAAC;AACtE,MAAM,CAAC,MAAM,6BAA6B,GAAG,gBAAyB,CAAC;AA4OvE,MAAM,UAAU,YAAY,CAAC,OAAY;IACvC,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,IAAI,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAElE,2CAA2C;IAC3C,IAAI,cAAwC,CAAC;IAC7C,IAAI,SAAS,EAAE,CAAC;QACd,oDAAoD;QACpD,cAAc,GAAG,kBAAkB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC3E,CAAC;SAAM,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QAC9B,cAAc,GAAG;YACf,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC;IACJ,CAAC;IAED,sDAAsD;IACtD,8EAA8E;IAC9E,kEAAkE;IAClE,MAAM,GAAG,GAAG,SAAS;QACnB,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC;QACjE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;IAEhB,wEAAwE;IACxE,0EAA0E;IAC1E,wEAAwE;IACxE,wEAAwE;IACxE,MAAM,UAAU,GAAG,OAAO,CAAC,IAA4C,CAAC;IACxE,MAAM,gBAAgB,GACpB,UAAU,KAAK,KAAK;QACpB,UAAU,KAAK,SAAS;QACxB,UAAU,CAAC,MAAM,KAAK,KAAK,CAAC;IAC9B,8EAA8E;IAC9E,8EAA8E;IAC9E,2EAA2E;IAC3E,4DAA4D;IAC5D,MAAM,QAAQ,GACZ,OAAO,OAAO,CAAC,QAAQ,KAAK,SAAS;QACnC,CAAC,CAAC,OAAO,CAAC,QAAQ;QAClB,CAAC,CAAC,gBAAgB;YAChB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,SAAS,CAAC;IAElB,uEAAuE;IACvE,0EAA0E;IAC1E,yEAAyE;IACzE,wEAAwE;IACxE,oEAAoE;IACpE,wEAAwE;IACxE,6DAA6D;IAC7D,MAAM,YAAY,GAChB,OAAO,OAAO,CAAC,YAAY,KAAK,SAAS;QACvC,CAAC,CAAC,OAAO,CAAC,YAAY;QACtB,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,YAAY,GAChB,OAAO,OAAO,CAAC,YAAY,KAAK,SAAS;QACvC,CAAC,CAAC,OAAO,CAAC,YAAY;QACtB,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,WAAW,GACf,OAAO,CAAC,WAAW;QACnB,OAAO,OAAO,CAAC,WAAW,KAAK,QAAQ;QACvC,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC;QACjC,CAAC,CAAC,OAAO,CAAC,WAAW;QACrB,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,IAAI,GACR,OAAO,OAAO,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAChE,MAAM,MAAM,GACV,OAAO,CAAC,MAAM;QACd,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ;QAClC,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ;QACvB,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,KAAK,QAAQ;QAC3C,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;QACvC,CAAC,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ;YAC/C,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,CAAC;QACnD,CAAC,CAAC,OAAO,CAAC,MAAM;QAChB,CAAC,CAAC,SAAS,CAAC;IAEhB,OAAO;QACL,IAAI,EAAE;YACJ,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,UAAU,EAAE,cAAc;SAC3B;QACD,GAAG;QACH,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,GAAG,CAAC,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,GAAG,CAAC,OAAO,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,OAAO,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9B,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,kCAAkC;AAClC,8EAA8E;AAE9E;;;;GAIG;AACH,SAAS,kBAAkB,CACzB,MAAwB,EACxB,YAAqB;IAErB,MAAM,CAAC,GAAG,MAAa,CAAC;IAExB,iEAAiE;IACjE,kDAAkD;IAClD,IAAI,CAAC,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;QACtC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;gBAC7C,MAAM,EAAE,UAAU;aACnB,CAAQ,CAAC;YACV,iEAAiE;YACjE,6DAA6D;YAC7D,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACzC,OAAO,MAAM,CAAC,OAAO,CAAC;YACxB,CAAC;YACD,OAAO,MAAkC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;QACrC,CAAC;IACH,CAAC;IAED,wDAAwD;IACxD,IAAI,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;QAChB,OAAO,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxC,CAAC;IAED,mCAAmC;IACnC,OAAO,EAAE,IAAI,EAAE,QAAiB,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CAAC,GAAQ;IAClC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IAEtB,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,UAAU,GAAwB,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;QACxB,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAU,EAAE,CAAC;gBAChE,MAAM,QAAQ,GAAG,WAAW,EAAE,IAAI,EAAE,GAAG,CAAC;gBACxC,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,IAAI,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;oBAC1C,iEAAiE;oBACjE,MAAM,IAAI,GAAG,WAAW,EAAE,WAAW,CAAC;oBACtC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW;wBAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;oBACvD,UAAU,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;oBACvB,IACE,QAAQ,CAAC,IAAI,KAAK,UAAU;wBAC5B,QAAQ,CAAC,IAAI,KAAK,SAAS;wBAC3B,QAAQ,CAAC,IAAI,KAAK,UAAU,EAC5B,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACrB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;QACnD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACpD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,MAAM,GAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QACvC,IAAI,GAAG,CAAC,WAAW;YAAE,MAAM,CAAC,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC;QAC1D,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QAC5D,MAAM,MAAM,GAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QACpE,IAAI,GAAG,CAAC,WAAW;YAAE,MAAM,CAAC,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC;QAC1D,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,MAAM,GAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACxC,IAAI,GAAG,CAAC,WAAW;YAAE,MAAM,CAAC,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC;QAC1D,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,4DAA4D;QAC5D,iCAAiC;QACjC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAC5B,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YACvC,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI;gBAC/C,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;gBACxB,CAAC,CAAC,OAAO,CAAC;QACd,MAAM,MAAM,GAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QACzD,IAAI,GAAG,CAAC,WAAW;YAAE,MAAM,CAAC,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC;QAC1D,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;IACvD,CAAC;IAED,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,MAAM,MAAM,GAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QACtC,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;YAC3B,MAAM,CAAC,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,GAAG,CAAC,WAAW;YAAE,MAAM,CAAC,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC;QAC1D,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,IAAI,GAAG,CAAC,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;YAC7B,OAAO,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzD,KAAK,CAAC,OAAO;gBACX,OAAO,GAAG,CAAC,YAAY,KAAK,UAAU;oBACpC,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE;oBACpB,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC;YACvB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,IAAI,GAAG,CAAC,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzD,oEAAoE;YACpE,mEAAmE;YACnE,OAAO,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,IAAI,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;YACxB,qDAAqD;YACrD,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CACnC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,SAAS,CAC7C,CAAC;YACF,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAC7D,MAAM,UAAU,GAAG,CAAC,CAAM,EAAE,EAAE,CAC5B,OAAO,CAAC,KAAK,QAAQ;oBACnB,CAAC,CAAC,QAAQ;oBACV,CAAC,CAAC,OAAO,CAAC,KAAK,SAAS;wBACtB,CAAC,CAAC,SAAS;wBACX,CAAC,CAAC,QAAQ,CAAC;gBACjB,MAAM,WAAW,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBACzD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC7B,iEAAiE;oBACjE,kEAAkE;oBAClE,iEAAiE;oBACjE,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gBAChD,CAAC;gBACD,wEAAwE;gBACxE,OAAO;oBACL,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;iBACpE,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAChC,kBAAkB,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC,CACtC;aACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,WAAW;IACX,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,8EAA8E;AAC9E,6BAA6B;AAC7B,8EAA8E;AAE9E;;;;GAIG;AACH,SAAS,kBAAkB,CACzB,MAAwB,EACxB,GAAa,EACb,cAAyC;IAEzC,OAAO,KAAK,EAAE,IAAS,EAAE,EAAE;QACzB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,wEAAwE;YACxE,6EAA6E;YAC7E,MAAM,OAAO,GAAa,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI;oBACxB,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;oBACtE,CAAC,CAAC,EAAE,CAAC;gBACP,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;gBACxC,mEAAmE;gBACnE,mDAAmD;gBACnD,IACE,OAAO;oBACP,CAAC,GAAG,KAAK,UAAU;wBACjB,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC;wBAC/B,+BAA+B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAC5C,CAAC;oBACD,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACxB,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;YAED,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,KAAK,CAAC,IAAI,CACR,6BAA6B,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtF,CAAC;YACJ,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAC/B,CAAC;YAED,oEAAoE;YACpE,6DAA6D;YAC7D,IAAI,QAAgB,CAAC;YACrB,IAAI,CAAC;gBACH,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBAChC,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG;oBAAE,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;YACrE,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;YAED,uEAAuE;YACvE,yEAAyE;YACzE,wCAAwC;YACxC,IAAI,QAAQ,GAAG,EAAE,CAAC;YAClB,IAAI,cAAc,EAAE,UAAU,EAAE,CAAC;gBAC/B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;gBACxD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC;qBAClD,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE;oBACd,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;oBACzC,MAAM,IAAI,GAAI,CAAuB,CAAC,IAAI,IAAI,KAAK,CAAC;oBACpD,OAAO,GAAG,CAAC,GAAG,IAAI,KAAK,IAAI,EAAE,CAAC;gBAChC,CAAC,CAAC;qBACD,IAAI,CAAC,IAAI,CAAC,CAAC;gBACd,IAAI,GAAG;oBACL,QAAQ,GAAG,gBAAgB,GAAG,wCAAwC,CAAC;YAC3E,CAAC;YAED,MAAM,IAAI,KAAK,CACb,+BAA+B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,QAAQ,IAAI,QAAQ,EAAE,CACrF,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,CAAE,MAA8C,CAAC,KAAK,CAAC,CAAC;IACpE,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { ActionTool } from \"./agent/types.js\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\nexport interface AgentActionStopOptions {\n /** Optional stable code surfaced in run metadata and tests. */\n errorCode?: string;\n /** Optional short tool-result text. Defaults to the user-facing message. */\n toolResult?: string;\n}\n\n/**\n * Throw from an action when the agent should stop the current turn instead of\n * feeding the failure back to the model for another retry.\n */\nexport class AgentActionStopError extends Error {\n readonly agentNativeStop = true;\n readonly errorCode?: string;\n readonly toolResult?: string;\n\n constructor(message: string, options: AgentActionStopOptions = {}) {\n super(message);\n this.name = \"AgentActionStopError\";\n this.errorCode = options.errorCode;\n this.toolResult = options.toolResult;\n }\n}\n\nexport function isAgentActionStopError(\n err: unknown,\n): err is AgentActionStopError {\n return (\n err instanceof AgentActionStopError ||\n Boolean(\n err &&\n typeof err === \"object\" &&\n \"agentNativeStop\" in err &&\n (err as { agentNativeStop?: unknown }).agentNativeStop === true,\n )\n );\n}\n\n/** HTTP exposure config for an action. */\nexport interface ActionHttpConfig {\n /** HTTP method. Default: \"POST\". Use \"GET\" for read-only actions. */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n /** Override route path under /_agent-native/actions/. Default: action filename. */\n path?: string;\n}\n\n/** Explicit opt-in metadata for public agent protocols such as MCP or A2A. */\nexport interface PublicAgentActionConfig {\n expose: boolean;\n readOnly: boolean;\n requiresAuth?: boolean;\n isConsequential?: boolean;\n title?: string;\n description?: string;\n}\n\n/** A deep link an external agent (MCP / A2A) can surface to the user so they\n * can open the produced/listed resource in the running app UI. */\nexport interface ActionDeepLink {\n /** App-relative path (e.g. `/_agent-native/open?app=mail&view=inbox&...`)\n * or an absolute URL. The MCP layer prefixes the request origin when this\n * is relative, and may rewrite it to the `agentnative://` desktop scheme. */\n url: string;\n /** Human-readable label, e.g. \"Open draft in Mail\". */\n label: string;\n /** Optional view hint (matches the `navigate` command `view`). */\n view?: string;\n}\n\n/** Builds a deep link from an action's args + result so external agents can\n * surface an \"Open in <app> →\" link. MUST be pure and synchronous — no I/O,\n * no awaits. Best-effort: a throw or null is swallowed and never fails the\n * tool call. See the `external-agents` skill. */\nexport type ActionLinkBuilder = (ctx: {\n args: Record<string, any>;\n result: any;\n}) => ActionDeepLink | null | undefined;\n\nexport const MCP_APP_EXTENSION_ID = \"io.modelcontextprotocol/ui\" as const;\nexport const MCP_APP_MIME_TYPE = \"text/html;profile=mcp-app\" as const;\nexport const MCP_APP_RESOURCE_URI_META_KEY = \"ui/resourceUri\" as const;\n\nexport interface ActionMcpAppCsp {\n connectDomains?: string[];\n resourceDomains?: string[];\n frameDomains?: string[];\n baseUriDomains?: string[];\n}\n\nexport type ActionMcpAppCspBuilder = (ctx: {\n actionName: string;\n appId?: string;\n requestOrigin?: string;\n}) => ActionMcpAppCsp | Promise<ActionMcpAppCsp>;\n\nexport interface ActionMcpAppPermissions {\n camera?: Record<string, never>;\n microphone?: Record<string, never>;\n geolocation?: Record<string, never>;\n clipboardWrite?: Record<string, never>;\n}\n\nexport interface ActionMcpAppResourceMeta {\n csp?: ActionMcpAppCsp | ActionMcpAppCspBuilder;\n permissions?: ActionMcpAppPermissions;\n /**\n * Host-specific sandbox domain hint. Do not set this to the app's normal\n * production URL; app origins belong in CSP/open-link metadata. ChatGPT uses\n * the separate `openai/widgetDomain` compatibility field.\n */\n domain?: string;\n prefersBorder?: boolean;\n}\n\nexport type ActionMcpAppHtmlBuilder = (ctx: {\n actionName: string;\n appId?: string;\n requestOrigin?: string;\n}) => string;\n\nexport interface ActionMcpAppResourceConfig {\n /** `ui://` URI. Defaults to `ui://<app>/<action-name>`. */\n uri?: string;\n /** MCP resource name. Defaults to the action name. */\n name?: string;\n title?: string;\n description?: string;\n /**\n * HTML5 document content for the MCP App resource. Keep this self-contained\n * or declare any external origins in `csp`.\n */\n html: string | ActionMcpAppHtmlBuilder;\n /** Defaults to the MCP Apps HTML MIME type. */\n mimeType?: typeof MCP_APP_MIME_TYPE;\n /** Extra resource/content metadata. `ui` is merged with the fields below. */\n _meta?: Record<string, unknown>;\n csp?: ActionMcpAppCsp | ActionMcpAppCspBuilder;\n permissions?: ActionMcpAppPermissions;\n /**\n * Host-specific sandbox domain hint. Do not set this to the app's normal\n * production URL; app origins belong in CSP/open-link metadata. ChatGPT uses\n * the separate `openai/widgetDomain` compatibility field.\n */\n domain?: string;\n prefersBorder?: boolean;\n}\n\nexport interface ActionMcpAppConfig {\n resource: ActionMcpAppResourceConfig;\n /**\n * MCP Apps tool visibility. Defaults to model + app so the LLM can call the\n * action and the app iframe can call it back through the host bridge.\n */\n visibility?: Array<\"model\" | \"app\">;\n /**\n * Rare escape hatch for MCP Apps chat hosts. By default OAuth callers with\n * `mcp:apps` see the generic app tools (`open_app`, `list_apps`, etc.) so\n * hosts do not ingest every action-specific UI resource. Set this only when\n * this specific action must stay visible in that compact catalog.\n */\n compactCatalog?: boolean;\n}\n\n/** Schema definition for a single action parameter (legacy JSON schema style). */\nexport interface ParameterSchema {\n type: string;\n description?: string;\n enum?: string[];\n}\n\n/** Infer runtime parameter types from a legacy parameter schema map. */\ntype InferParams<T extends Record<string, ParameterSchema> | undefined> =\n T extends Record<string, ParameterSchema>\n ? { [K in keyof T]?: string }\n : Record<string, string>;\n\n// ---------------------------------------------------------------------------\n// Schema-based action options (new: Zod / Valibot / ArkType via Standard Schema)\n// ---------------------------------------------------------------------------\n\ninterface DefineActionWithSchema<\n TSchema extends StandardSchemaV1,\n TReturn = any,\n> {\n description: string;\n /** Standard Schema-compatible schema (Zod, Valibot, ArkType). Provides runtime\n * validation and full TypeScript type inference for `run()` args. The schema is\n * also converted to JSON Schema for the Claude API tool definition. */\n schema: TSchema;\n /** Legacy parameters — ignored when `schema` is provided. */\n parameters?: never;\n run: (\n args: StandardSchemaV1.InferOutput<TSchema>,\n ) => Promise<TReturn> | TReturn;\n http?: ActionHttpConfig | false;\n /** If true, the framework will NOT emit a screen-refresh change event after a\n * successful call. Auto-inferred as `true` when `http.method === \"GET\"`.\n * Only set this manually when you need to override the inference — e.g. a\n * POST action that only reads data but can't use GET for a protocol reason. */\n readOnly?: boolean;\n /** If true, the agent may execute this action concurrently with other\n * read-only or parallel-safe tool calls emitted in the same model turn.\n * Only set this for mutating actions that are internally concurrency-safe\n * and order-independent for same-turn execution. */\n parallelSafe?: boolean;\n /** Whether this action may be invoked from the tools (Alpine iframe) bridge\n * via `appAction(name, params)` — see `packages/core/docs/content/actions.md`\n * (\"Tools Callability\"). **Default-allow opt-out**: undefined / `true` both\n * allow tool-iframe calls; only an explicit `false` returns 403. Set to\n * `false` for high-blast-radius admin operations (account deletion, org\n * membership changes, anything that modifies auth state) — used by the\n * framework's `share-resource`, `unshare-resource`, and\n * `set-resource-visibility` for defense-in-depth. Regular UI/agent/CLI/MCP/A2A\n * calls are unaffected. Enforced by the action HTTP route layer — see\n * `packages/core/src/server/action-routes.ts`. Audit reference: H5 in\n * `security-audit/05-tools-sandbox.md`. */\n toolCallable?: boolean;\n /** Explicit public-agent exposure metadata. Public web routes never imply\n * public MCP/A2A/OpenAPI tool exposure. Actions must opt in here and public\n * protocol mounts must still filter for safe, route-appropriate tools. */\n publicAgent?: PublicAgentActionConfig;\n /** Optional deep-link builder. When set, MCP/A2A surfaces append an\n * \"Open in <app> →\" link built from the call's args + result so the\n * external agent can drop the user into the running app at the right\n * view/record. Pure + sync + best-effort. See the `external-agents` skill. */\n link?: ActionLinkBuilder;\n /** Optional MCP Apps UI resource for hosts that can render inline\n * interactive app iframes. Text/deep-link tool results remain the fallback\n * for CLI and non-UI hosts. */\n mcpApp?: ActionMcpAppConfig;\n}\n\n// ---------------------------------------------------------------------------\n// Legacy parameter-based action options\n// ---------------------------------------------------------------------------\n\ninterface DefineActionWithParams<\n TParams extends Record<string, ParameterSchema> | undefined =\n | Record<string, ParameterSchema>\n | undefined,\n TReturn = any,\n> {\n description: string;\n /** Flat map of parameter names to their schema. Automatically wrapped in\n * `{ type: \"object\", properties: ... }` for the Claude API. */\n parameters?: TParams;\n /** Standard Schema — not used in this overload. */\n schema?: never;\n run: (args: InferParams<TParams>) => Promise<TReturn> | TReturn;\n http?: ActionHttpConfig | false;\n /** If true, the framework will NOT emit a screen-refresh change event after a\n * successful call. Auto-inferred as `true` when `http.method === \"GET\"`. */\n readOnly?: boolean;\n /** If true, the agent may execute this action concurrently with other\n * read-only or parallel-safe tool calls emitted in the same model turn. */\n parallelSafe?: boolean;\n /** Whether this action may be invoked from the tools (Alpine iframe) bridge\n * via `appAction(name, params)`. See the schema overload above for details\n * and the `toolCallable` section in actions.md. */\n toolCallable?: boolean;\n /** Explicit public-agent exposure metadata. See schema overload above. */\n publicAgent?: PublicAgentActionConfig;\n /** Optional deep-link builder. See schema overload above. */\n link?: ActionLinkBuilder;\n /** Optional MCP Apps UI resource. See schema overload above. */\n mcpApp?: ActionMcpAppConfig;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Define an agent action. Place in `actions/` directory — auto-discovered by the framework.\n *\n * Supports two modes:\n *\n * **Schema mode (recommended)** — pass a Standard Schema-compatible schema (Zod, Valibot,\n * ArkType) for runtime validation and full type inference:\n *\n * ```ts\n * import { defineAction } from \"@agent-native/core\";\n * import { z } from \"zod\";\n *\n * export default defineAction({\n * description: \"Create a form\",\n * schema: z.object({\n * title: z.string().describe(\"Form title\"),\n * status: z.enum([\"draft\", \"published\", \"closed\"]).default(\"draft\"),\n * }),\n * run: async (args) => {\n * // args is { title: string; status: \"draft\" | \"published\" | \"closed\" }\n * // Already validated — invalid inputs never reach here\n * },\n * });\n * ```\n *\n * **Parameters mode (legacy)** — pass raw JSON schema-like parameter definitions:\n *\n * ```ts\n * export default defineAction({\n * description: \"List events\",\n * parameters: {\n * from: { type: \"string\", description: \"Start date\" },\n * },\n * run: async (args) => { ... },\n * });\n * ```\n */\nexport function defineAction<TSchema extends StandardSchemaV1, TReturn>(\n options: DefineActionWithSchema<TSchema, TReturn>,\n): any;\nexport function defineAction<\n TParams extends Record<string, ParameterSchema> | undefined,\n TReturn,\n>(options: DefineActionWithParams<TParams, TReturn>): any;\nexport function defineAction(options: any) {\n const hasSchema = options.schema && \"~standard\" in options.schema;\n\n // Build tool definition for the Claude API\n let toolParameters: ActionTool[\"parameters\"];\n if (hasSchema) {\n // Convert Standard Schema to JSON Schema for Claude\n toolParameters = schemaToJsonSchema(options.schema, options.description);\n } else if (options.parameters) {\n toolParameters = {\n type: \"object\" as const,\n properties: options.parameters,\n };\n }\n\n // Wrap run() with validation when schema is provided.\n // Pass toolParameters so the validation error can echo the expected signature\n // (required vs optional fields) and help the caller self-correct.\n const run = hasSchema\n ? wrapWithValidation(options.schema, options.run, toolParameters)\n : options.run;\n\n // Auto-infer readOnly from http.method === \"GET\" unless explicitly set.\n // GET actions are idempotent reads; their completion should NOT trigger a\n // screen refresh. Everything else is assumed to mutate — the dispatcher\n // emits a change event on success so the UI auto-refetches its queries.\n const httpConfig = options.http as ActionHttpConfig | false | undefined;\n const inferredReadOnly =\n httpConfig !== false &&\n httpConfig !== undefined &&\n httpConfig.method === \"GET\";\n // Explicit `readOnly` (true OR false) wins. Otherwise infer from http.method.\n // We store the resolved boolean so downstream checks can trust entry.readOnly\n // without re-running method inference — including when a caller explicitly\n // passes readOnly:false to override a GET (rare but valid).\n const readOnly: boolean | undefined =\n typeof options.readOnly === \"boolean\"\n ? options.readOnly\n : inferredReadOnly\n ? true\n : undefined;\n\n // toolCallable: thread through whatever the caller declared. We DO NOT\n // default to `true` here — the absence of an explicit field is meaningful\n // to the tools bridge: it lets us emit a one-shot warning when an action\n // without a declared `toolCallable` flag is invoked from a tool, so the\n // ecosystem can migrate over time. The bridge treats `undefined` as\n // \"implicit allow with a deprecation warning\"; only an explicit `false`\n // refuses the call. See `extensions/routes.ts` and audit H5.\n const toolCallable: boolean | undefined =\n typeof options.toolCallable === \"boolean\"\n ? options.toolCallable\n : undefined;\n const parallelSafe: boolean | undefined =\n typeof options.parallelSafe === \"boolean\"\n ? options.parallelSafe\n : undefined;\n const publicAgent: PublicAgentActionConfig | undefined =\n options.publicAgent &&\n typeof options.publicAgent === \"object\" &&\n !Array.isArray(options.publicAgent)\n ? options.publicAgent\n : undefined;\n const link: ActionLinkBuilder | undefined =\n typeof options.link === \"function\" ? options.link : undefined;\n const mcpApp: ActionMcpAppConfig | undefined =\n options.mcpApp &&\n typeof options.mcpApp === \"object\" &&\n !Array.isArray(options.mcpApp) &&\n options.mcpApp.resource &&\n typeof options.mcpApp.resource === \"object\" &&\n !Array.isArray(options.mcpApp.resource) &&\n (typeof options.mcpApp.resource.html === \"string\" ||\n typeof options.mcpApp.resource.html === \"function\")\n ? options.mcpApp\n : undefined;\n\n return {\n tool: {\n description: options.description,\n parameters: toolParameters,\n },\n run,\n ...(hasSchema ? { schema: options.schema } : {}),\n ...(options.http !== undefined ? { http: options.http } : {}),\n ...(typeof readOnly === \"boolean\" ? { readOnly } : {}),\n ...(typeof parallelSafe === \"boolean\" ? { parallelSafe } : {}),\n ...(typeof toolCallable === \"boolean\" ? { toolCallable } : {}),\n ...(publicAgent ? { publicAgent } : {}),\n ...(link ? { link } : {}),\n ...(mcpApp ? { mcpApp } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Schema → JSON Schema conversion\n// ---------------------------------------------------------------------------\n\n/**\n * Convert a Standard Schema to JSON Schema for the Claude API.\n * Tries vendor-specific toJSONSchema first (Zod v4), then falls back\n * to a basic introspection of the schema shape.\n */\nfunction schemaToJsonSchema(\n schema: StandardSchemaV1,\n _description?: string,\n): ActionTool[\"parameters\"] {\n const s = schema as any;\n\n // Prefer Zod's own JSON Schema output — it handles descriptions,\n // enums, coerce, and all type wrappers correctly.\n if (s[\"~standard\"]?.jsonSchema?.input) {\n try {\n const result = s[\"~standard\"].jsonSchema.input({\n target: \"draft-07\",\n }) as any;\n // Strip $schema — the Claude API validates against draft 2020-12\n // and a mismatched $schema declaration can cause rejections.\n if (result && typeof result === \"object\") {\n delete result.$schema;\n }\n return result as ActionTool[\"parameters\"];\n } catch {\n // Fall through to manual converter\n }\n }\n\n // Fallback: manual conversion from Zod v4 internal defs\n if (s._zod?.def) {\n return zodDefToJsonSchema(s._zod.def);\n }\n\n // Last resort: empty object schema\n return { type: \"object\" as const, properties: {} };\n}\n\n/**\n * Convert a Zod v4 internal def to JSON Schema.\n * Handles the common types used in action parameters.\n */\nfunction zodDefToJsonSchema(def: any): any {\n const type = def.type;\n\n if (type === \"object\") {\n const properties: Record<string, any> = {};\n const required: string[] = [];\n const shape = def.shape;\n if (shape) {\n for (const [key, fieldSchema] of Object.entries(shape) as any[]) {\n const fieldDef = fieldSchema?._zod?.def;\n if (fieldDef) {\n const prop = zodDefToJsonSchema(fieldDef);\n // Zod v4 stores .describe() on the schema object, not in the def\n const desc = fieldSchema?.description;\n if (desc && !prop.description) prop.description = desc;\n properties[key] = prop;\n if (\n fieldDef.type !== \"optional\" &&\n fieldDef.type !== \"default\" &&\n fieldDef.type !== \"nullable\"\n ) {\n required.push(key);\n }\n }\n }\n }\n const result: any = { type: \"object\", properties };\n if (required.length > 0) result.required = required;\n return result;\n }\n\n if (type === \"string\") {\n const result: any = { type: \"string\" };\n if (def.description) result.description = def.description;\n return result;\n }\n\n if (type === \"number\" || type === \"float\" || type === \"int\") {\n const result: any = { type: type === \"int\" ? \"integer\" : \"number\" };\n if (def.description) result.description = def.description;\n return result;\n }\n\n if (type === \"boolean\") {\n const result: any = { type: \"boolean\" };\n if (def.description) result.description = def.description;\n return result;\n }\n\n if (type === \"enum\") {\n // Zod v4 stores enum entries as an object {a: \"a\", b: \"b\"};\n // JSON Schema requires an array.\n const entries = def.entries;\n const enumValues = Array.isArray(entries)\n ? entries\n : typeof entries === \"object\" && entries !== null\n ? Object.values(entries)\n : entries;\n const result: any = { type: \"string\", enum: enumValues };\n if (def.description) result.description = def.description;\n return result;\n }\n\n if (type === \"literal\") {\n return { type: typeof def.value, enum: [def.value] };\n }\n\n if (type === \"array\") {\n const result: any = { type: \"array\" };\n if (def.element?._zod?.def) {\n result.items = zodDefToJsonSchema(def.element._zod.def);\n }\n if (def.description) result.description = def.description;\n return result;\n }\n\n if (type === \"optional\") {\n if (def.innerType?._zod?.def) {\n return zodDefToJsonSchema(def.innerType._zod.def);\n }\n }\n\n if (type === \"default\") {\n if (def.innerType?._zod?.def) {\n const inner = zodDefToJsonSchema(def.innerType._zod.def);\n inner.default =\n typeof def.defaultValue === \"function\"\n ? def.defaultValue()\n : def.defaultValue;\n return inner;\n }\n }\n\n if (type === \"nullable\") {\n if (def.innerType?._zod?.def) {\n const inner = zodDefToJsonSchema(def.innerType._zod.def);\n // Surface null as a valid value so the model knows it may pass null\n // (and doesn't treat the field as a non-nullable required string).\n return { anyOf: [inner, { type: \"null\" }] };\n }\n }\n\n if (type === \"union\") {\n if (def.options?.length) {\n // Check if it's a simple enum-like union of literals\n const allLiterals = def.options.every(\n (o: any) => o?._zod?.def?.type === \"literal\",\n );\n if (allLiterals) {\n const values = def.options.map((o: any) => o._zod.def.value);\n const jsonTypeOf = (v: any) =>\n typeof v === \"number\"\n ? \"number\"\n : typeof v === \"boolean\"\n ? \"boolean\"\n : \"string\";\n const uniqueTypes = [...new Set(values.map(jsonTypeOf))];\n if (uniqueTypes.length === 1) {\n // Homogeneous literal union (e.g. all numbers) — derive the JSON\n // type instead of hardcoding \"string\", which would contradict the\n // enum values and make the model coerce/round-trip them wrongly.\n return { type: uniqueTypes[0], enum: values };\n }\n // Mixed literal types: emit anyOf so each branch stays self-consistent.\n return {\n anyOf: values.map((v: any) => ({ type: jsonTypeOf(v), enum: [v] })),\n };\n }\n return {\n anyOf: def.options.map((o: any) =>\n zodDefToJsonSchema(o._zod?.def ?? {}),\n ),\n };\n }\n }\n\n // Fallback\n return { type: \"string\" };\n}\n\n// ---------------------------------------------------------------------------\n// Runtime validation wrapper\n// ---------------------------------------------------------------------------\n\n/**\n * Wrap an action's run function with schema validation.\n * Invalid inputs get a clear error message (including what was actually passed)\n * so the agent can see its own mistake and correct it on the next turn.\n */\nfunction wrapWithValidation(\n schema: StandardSchemaV1,\n run: Function,\n toolParameters?: ActionTool[\"parameters\"],\n): (args: any) => any {\n return async (args: any) => {\n const result = await schema[\"~standard\"].validate(args);\n if (result.issues) {\n // Split issues into \"missing required field\" vs other validation errors\n // so the error message reads naturally rather than as \"fieldName: Required\".\n const missing: string[] = [];\n const other: string[] = [];\n for (const issue of result.issues) {\n const pathStr = issue.path\n ? issue.path.map((p) => (typeof p === \"object\" ? p.key : p)).join(\".\")\n : \"\";\n const msg = String(issue.message ?? \"\");\n // Zod emits \"Required\" for missing fields; other libraries may use\n // similar wording. Treat any variant as \"missing\".\n if (\n pathStr &&\n (msg === \"Required\" ||\n /invalid.*undefined/i.test(msg) ||\n /expected.*received undefined/i.test(msg))\n ) {\n missing.push(pathStr);\n } else {\n other.push(pathStr ? `${pathStr}: ${msg}` : msg);\n }\n }\n\n const parts: string[] = [];\n if (missing.length > 0) {\n parts.push(\n `Missing required parameter${missing.length === 1 ? \"\" : \"s\"}: ${missing.join(\", \")}`,\n );\n }\n if (other.length > 0) {\n parts.push(other.join(\"; \"));\n }\n\n // Echo the args that were actually passed so the caller (usually an\n // agent) can see exactly what it sent and fix its next call.\n let received: string;\n try {\n received = JSON.stringify(args);\n if (received.length > 500) received = received.slice(0, 500) + \"…\";\n } catch {\n received = String(args);\n }\n\n // Also show the EXPECTED signature so the agent doesn't have to guess.\n // Format: `{ deckId*: string, content*: string, slideId?: string, ... }`\n // where `*` = required, `?` = optional.\n let expected = \"\";\n if (toolParameters?.properties) {\n const required = new Set(toolParameters.required ?? []);\n const sig = Object.entries(toolParameters.properties)\n .map(([k, v]) => {\n const mark = required.has(k) ? \"*\" : \"?\";\n const type = (v as { type?: string }).type ?? \"any\";\n return `${k}${mark}: ${type}`;\n })\n .join(\", \");\n if (sig)\n expected = ` Expected: { ${sig} } (where * = required, ? = optional).`;\n }\n\n throw new Error(\n `Invalid action parameters — ${parts.join(\". \")}. Received: ${received}.${expected}`,\n );\n }\n return run((result as StandardSchemaV1.SuccessResult<any>).value);\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ai-sdk-engine.d.ts","sourceRoot":"","sources":["../../../src/agent/engine/ai-sdk-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAInB,MAAM,YAAY,CAAC;AAOpB,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAK7E,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMxD,QAAA,MAAM,qBAAqB,EAAE,MAAM,CAAC,aAAa,EAAE,kBAAkB,CAyDpE,CAAC;AAMF,QAAA,MAAM,uBAAuB,EAKxB,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;AAEnC,QAAA,MAAM,yBAAyB,EAKf,MAAM,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;AAEzD,QAAA,MAAM,iBAAiB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,EAAE,CAStD,CAAC;AAEF,QAAA,MAAM,iBAAiB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CASpD,CAAC;AA0BF,kDAAkD;AAClD,MAAM,WAAW,iBAAiB;IAChC,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0GAA0G;IAC1G,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yFAAyF;IACzF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA+MD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,aAAa,EACvB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,WAAW,CAEb;AA8CD,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,GAClB,CAAC"}
1
+ {"version":3,"file":"ai-sdk-engine.d.ts","sourceRoot":"","sources":["../../../src/agent/engine/ai-sdk-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAInB,MAAM,YAAY,CAAC;AAOpB,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAK7E,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMxD,QAAA,MAAM,qBAAqB,EAAE,MAAM,CAAC,aAAa,EAAE,kBAAkB,CAyDpE,CAAC;AAMF,QAAA,MAAM,uBAAuB,EAKxB,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;AAEnC,QAAA,MAAM,yBAAyB,EAKf,MAAM,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;AAEzD,QAAA,MAAM,iBAAiB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,EAAE,CAStD,CAAC;AAEF,QAAA,MAAM,iBAAiB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CASpD,CAAC;AA8BF,kDAAkD;AAClD,MAAM,WAAW,iBAAiB;IAChC,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0GAA0G;IAC1G,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yFAAyF;IACzF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA+MD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,aAAa,EACvB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,WAAW,CAEb;AA8CD,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,GAClB,CAAC"}
@@ -120,6 +120,11 @@ const PROVIDER_FACTORIES = {
120
120
  function googleThinkingBudget(effort) {
121
121
  if (effort === "low")
122
122
  return 1024;
123
+ // "medium" is a normalized effort for Gemini models; without this case it
124
+ // fell through to the -1 ("dynamic/unlimited") fallback, so selecting
125
+ // medium effort silently uncapped the thinking budget.
126
+ if (effort === "medium")
127
+ return 4096;
123
128
  if (effort === "high")
124
129
  return 8000;
125
130
  if (effort === "xhigh")