@axiom-lattice/gateway 2.1.116 → 3.0.0

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 (34) hide show
  1. package/.turbo/turbo-build.log +15 -15
  2. package/CHANGELOG.md +37 -0
  3. package/dist/{a2a-ERG5RMUW.mjs → a2a-QMHEH3ZT.mjs} +77 -29
  4. package/dist/a2a-QMHEH3ZT.mjs.map +1 -0
  5. package/dist/index.js +1144 -177
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +1013 -92
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +6 -5
  10. package/src/__tests__/a2a.test.ts +82 -0
  11. package/src/__tests__/workspace.test.ts +13 -3
  12. package/src/config/local-a2a-templates.ts +59 -0
  13. package/src/controllers/__tests__/assistant-local-a2a.test.ts +147 -0
  14. package/src/controllers/__tests__/local-a2a-templates.test.ts +112 -0
  15. package/src/controllers/assistant.ts +126 -4
  16. package/src/controllers/local-a2a-templates.ts +18 -0
  17. package/src/controllers/local-a2a.ts +149 -0
  18. package/src/controllers/tasks.ts +2 -3
  19. package/src/controllers/workspace.ts +144 -17
  20. package/src/index.ts +2 -10
  21. package/src/routes/__tests__/a2a-test-connection.test.ts +177 -0
  22. package/src/routes/a2a-test-connection.ts +126 -0
  23. package/src/routes/a2a.ts +100 -28
  24. package/src/routes/index.ts +27 -0
  25. package/src/routes/stt.ts +102 -0
  26. package/src/services/__tests__/local-a2a.test.ts +124 -0
  27. package/src/services/eval-runner.ts +6 -0
  28. package/src/services/local-a2a.ts +352 -0
  29. package/src/utils/__tests__/local-a2a-runtime.test.ts +77 -0
  30. package/src/utils/__tests__/path-containment.test.ts +35 -0
  31. package/src/utils/a2a-url.ts +20 -0
  32. package/src/utils/local-a2a-runtime.ts +107 -0
  33. package/src/utils/path-containment.ts +38 -0
  34. package/dist/a2a-ERG5RMUW.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
 
2
- > @axiom-lattice/gateway@2.1.116 build /home/runner/work/agentic/agentic/packages/gateway
2
+ > @axiom-lattice/gateway@3.0.0 build /home/runner/work/agentic/agentic/packages/gateway
3
3
  > tsup src/index.ts --format cjs,esm --dts --clean --sourcemap
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -11,36 +11,36 @@
11
11
  ESM Build start
12
12
  [warn] ▲ [WARNING] "import.meta" is not available with the "cjs" output format and will be empty [empty-import-meta]
13
13
 
14
- src/index.ts:201:33:
15
-  201 │ const __filename = fileURLToPath(import.meta.url);
14
+ src/index.ts:200:33:
15
+  200 │ const __filename = fileURLToPath(import.meta.url);
16
16
  ╵ ~~~~~~~~~~~
17
17
 
18
18
  You need to set the output format to "esm" for "import.meta" to work correctly.
19
19
 
20
20
 
21
- CJS dist/index.js 410.19 KB
22
- CJS dist/index.js.map 833.87 KB
23
- CJS ⚡️ Build success in 551ms
21
+ CJS dist/index.js 443.07 KB
22
+ CJS dist/index.js.map 895.92 KB
23
+ CJS ⚡️ Build success in 659ms
24
+ ESM dist/index.mjs 370.08 KB
25
+ ESM dist/mcp-configs-SHRMQHIL.mjs 685.00 B
24
26
  ESM dist/chunk-K4XELOSO.mjs 12.52 KB
25
27
  ESM dist/sender-PX32VSHB.mjs 873.00 B
26
28
  ESM dist/WechatChannelAdapter-WSDKR4OA.mjs 8.27 KB
27
- ESM dist/index.mjs 339.48 KB
28
- ESM dist/mcp-configs-SHRMQHIL.mjs 685.00 B
29
29
  ESM dist/chunk-6CUQGDJI.mjs 6.42 KB
30
+ ESM dist/a2a-QMHEH3ZT.mjs 17.78 KB
30
31
  ESM dist/resources-VA7LSDKN.mjs 15.81 KB
31
- ESM dist/a2a-ERG5RMUW.mjs 15.95 KB
32
32
  ESM dist/chunk-LHQY46YB.mjs 1.46 KB
33
- ESM dist/sender-PX32VSHB.mjs.map 2.07 KB
33
+ ESM dist/mcp-configs-SHRMQHIL.mjs.map 71.00 B
34
34
  ESM dist/chunk-K4XELOSO.mjs.map 25.53 KB
35
+ ESM dist/sender-PX32VSHB.mjs.map 2.07 KB
35
36
  ESM dist/WechatChannelAdapter-WSDKR4OA.mjs.map 16.28 KB
36
- ESM dist/mcp-configs-SHRMQHIL.mjs.map 71.00 B
37
37
  ESM dist/chunk-6CUQGDJI.mjs.map 14.04 KB
38
+ ESM dist/a2a-QMHEH3ZT.mjs.map 35.64 KB
38
39
  ESM dist/resources-VA7LSDKN.mjs.map 29.34 KB
39
- ESM dist/a2a-ERG5RMUW.mjs.map 32.14 KB
40
40
  ESM dist/chunk-LHQY46YB.mjs.map 2.39 KB
41
- ESM dist/index.mjs.map 711.66 KB
42
- ESM ⚡️ Build success in 551ms
41
+ ESM dist/index.mjs.map 770.22 KB
42
+ ESM ⚡️ Build success in 658ms
43
43
  DTS Build start
44
- DTS ⚡️ Build success in 20289ms
44
+ DTS ⚡️ Build success in 20073ms
45
45
  DTS dist/index.d.ts 7.57 KB
46
46
  DTS dist/index.d.mts 7.57 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # @axiom-lattice/gateway
2
2
 
3
+ ## 3.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 3a124ab: **BREAKING**: Remove `LocalA2ATemplateStore` from store lattice, replacing it with static template config.
8
+
9
+ - Deleted `LocalA2ATemplateStoreProtocol` and all implementations (InMemory, PostgreSQL, SQLite)
10
+ - Removed `localA2ATemplate` entry from `StoreTypeMap` and store lattice default registrations
11
+ - Removed obsolete PostgreSQL Local A2A template migration source; existing database tables are not dropped
12
+ - Removed `LocalA2ATemplateEntry`, `CreateLocalA2ATemplateRequest`, `UpdateLocalA2ATemplateRequest` types
13
+ - `client.assistants.localA2A.templates` now only supports `.list()` (returns `LocalA2ATemplateDefinition[]`)
14
+ - Templates are now defined in `packages/gateway/src/config/local-a2a-templates.ts`
15
+ - Gateway resolves the managed CLI through the installed `@axiom-lattice/cli-a2a/cli-path` export and declares the CLI package as a runtime dependency
16
+ - Templates no longer contain port or agentCardUrl; those are user-supplied at creation time
17
+ - `CreateAssistantModal` appends the Agent Card URL port to template commands as `--port <port>` when the template does not already declare a port
18
+ - CLI session files are isolated by provider and server port when no explicit store path is configured
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies [3a124ab]
23
+ - @axiom-lattice/protocols@3.0.0
24
+ - @axiom-lattice/core@3.0.0
25
+ - @axiom-lattice/pg-stores@2.0.0
26
+ - @axiom-lattice/cli-a2a@0.1.6
27
+ - @axiom-lattice/queue-redis@1.0.54
28
+
29
+ ## 2.1.117
30
+
31
+ ### Patch Changes
32
+
33
+ - 5e1486e: add voice input
34
+ - Updated dependencies [5e1486e]
35
+ - @axiom-lattice/core@2.1.103
36
+ - @axiom-lattice/pg-stores@1.0.94
37
+ - @axiom-lattice/protocols@2.1.54
38
+ - @axiom-lattice/queue-redis@1.0.53
39
+
3
40
  ## 2.1.116
4
41
 
5
42
  ### Patch Changes
@@ -5,6 +5,7 @@ import {
5
5
  } from "@axiom-lattice/core";
6
6
  import { MessageChunkTypes } from "@axiom-lattice/protocols";
7
7
  var taskStore = /* @__PURE__ */ new Map();
8
+ var contextThreadMap = /* @__PURE__ */ new Map();
8
9
  var _a2aKeyStore = null;
9
10
  var _storeKeyMap = /* @__PURE__ */ new Map();
10
11
  function setA2AKeyStore(store) {
@@ -118,14 +119,16 @@ function buildTextPart(text) {
118
119
  function isoNow() {
119
120
  return (/* @__PURE__ */ new Date()).toISOString();
120
121
  }
121
- async function streamChunksAsA2A(stream, taskId, sendEvent, onInterrupt) {
122
+ async function streamChunksAsA2A(stream, taskId, contextId, sendEvent, onInterrupt) {
122
123
  let accumulatedText = "";
124
+ let interrupted = false;
123
125
  for await (const chunk of stream) {
124
126
  const chunkText = chunk.data?.content || "";
125
127
  const chunkType = chunk.type;
126
128
  if (chunkType === MessageChunkTypes.INTERRUPT) {
127
129
  sendEvent("status-update", {
128
130
  id: taskId,
131
+ contextId,
129
132
  status: {
130
133
  state: "input-required",
131
134
  message: {
@@ -137,13 +140,15 @@ async function streamChunksAsA2A(stream, taskId, sendEvent, onInterrupt) {
137
140
  final: false
138
141
  });
139
142
  onInterrupt?.();
140
- continue;
143
+ interrupted = true;
144
+ break;
141
145
  }
142
146
  if (chunkType === MessageChunkTypes.AI || chunkType === MessageChunkTypes.TOOL) {
143
147
  if (chunkText) {
144
148
  accumulatedText += chunkText;
145
149
  sendEvent("status-update", {
146
150
  id: taskId,
151
+ contextId,
147
152
  status: {
148
153
  state: "working",
149
154
  message: {
@@ -157,7 +162,7 @@ async function streamChunksAsA2A(stream, taskId, sendEvent, onInterrupt) {
157
162
  }
158
163
  }
159
164
  }
160
- return accumulatedText;
165
+ return { text: accumulatedText, interrupted };
161
166
  }
162
167
  async function getTaskStatus(taskId) {
163
168
  const record = taskStore.get(taskId);
@@ -211,13 +216,48 @@ async function handleTasksSend(request, reply) {
211
216
  });
212
217
  return;
213
218
  }
219
+ const contextId = body.message.contextId;
220
+ const referenceTaskIds = body.message.referenceTaskIds;
214
221
  const taskId = body.id || v4();
215
- const threadId = v4();
222
+ let threadId;
223
+ let resolvedReferenceTaskIds;
224
+ if (body.id) {
225
+ const existingTask = taskStore.get(body.id);
226
+ if (existingTask) {
227
+ if (existingTask.status === "input-required") {
228
+ threadId = existingTask.threadId;
229
+ resolvedReferenceTaskIds = referenceTaskIds;
230
+ } else if (existingTask.status === "completed" || existingTask.status === "failed" || existingTask.status === "canceled") {
231
+ threadId = v4();
232
+ resolvedReferenceTaskIds = referenceTaskIds ? [...referenceTaskIds, body.id] : [body.id];
233
+ } else {
234
+ threadId = v4();
235
+ resolvedReferenceTaskIds = referenceTaskIds;
236
+ }
237
+ } else {
238
+ threadId = v4();
239
+ resolvedReferenceTaskIds = referenceTaskIds ? [...referenceTaskIds, body.id] : [body.id];
240
+ }
241
+ } else if (contextId && contextThreadMap.has(contextId)) {
242
+ threadId = contextThreadMap.get(contextId);
243
+ console.warn({
244
+ event: "a2a:deprecated:contextId_thread_reuse",
245
+ message: "contextId-based thread reuse is deprecated; use referenceTaskIds and application-layer conversation state instead",
246
+ contextId,
247
+ threadId
248
+ });
249
+ resolvedReferenceTaskIds = referenceTaskIds;
250
+ } else {
251
+ threadId = v4();
252
+ resolvedReferenceTaskIds = referenceTaskIds;
253
+ }
216
254
  const tenantId = auth.tenantId || config.defaultTenantId;
217
255
  const now = isoNow();
218
256
  const record = {
219
257
  id: taskId,
220
258
  threadId,
259
+ contextId,
260
+ referenceTaskIds: resolvedReferenceTaskIds,
221
261
  assistantId,
222
262
  tenantId,
223
263
  projectId: auth.projectId || void 0,
@@ -273,24 +313,27 @@ data: ${JSON.stringify(data)}
273
313
  const stream = agent.chunkStream(result.messageId, [
274
314
  MessageChunkTypes.MESSAGE_COMPLETED
275
315
  ]);
276
- const accumulatedText = await streamChunksAsA2A(stream, taskId, sendEvent, () => {
316
+ const { text: accumulatedText, interrupted } = await streamChunksAsA2A(stream, taskId, contextId, sendEvent, () => {
277
317
  record.status = "input-required";
278
318
  record.updatedAt = isoNow();
279
319
  });
280
- record.status = "completed";
281
- record.updatedAt = isoNow();
282
- record.history.push({
283
- role: "agent",
284
- parts: [buildTextPart(accumulatedText)]
285
- });
286
- sendEvent("status-update", {
287
- id: taskId,
288
- status: {
289
- state: "completed",
290
- timestamp: isoNow()
291
- },
292
- final: true
293
- });
320
+ if (!interrupted) {
321
+ record.status = "completed";
322
+ record.updatedAt = isoNow();
323
+ record.history.push({
324
+ role: "agent",
325
+ parts: [buildTextPart(accumulatedText)]
326
+ });
327
+ sendEvent("status-update", {
328
+ id: taskId,
329
+ contextId,
330
+ status: {
331
+ state: "completed",
332
+ timestamp: isoNow()
333
+ },
334
+ final: true
335
+ });
336
+ }
294
337
  } catch (err) {
295
338
  record.status = "failed";
296
339
  record.updatedAt = isoNow();
@@ -300,6 +343,7 @@ data: ${JSON.stringify(data)}
300
343
  });
301
344
  sendEvent("status-update", {
302
345
  id: taskId,
346
+ contextId,
303
347
  status: {
304
348
  state: "failed",
305
349
  timestamp: isoNow()
@@ -393,6 +437,7 @@ data: ${JSON.stringify(data)}
393
437
  if (!record.messageId) {
394
438
  sendEvent("status-update", {
395
439
  id: taskId,
440
+ contextId: record.contextId,
396
441
  status: {
397
442
  state: record.status,
398
443
  timestamp: record.updatedAt
@@ -406,15 +451,18 @@ data: ${JSON.stringify(data)}
406
451
  const stream = agent.chunkStream(record.messageId, [
407
452
  MessageChunkTypes.MESSAGE_COMPLETED
408
453
  ]);
409
- await streamChunksAsA2A(stream, taskId, sendEvent);
410
- sendEvent("status-update", {
411
- id: taskId,
412
- status: {
413
- state: record.status,
414
- timestamp: record.updatedAt
415
- },
416
- final: true
417
- });
454
+ const { interrupted } = await streamChunksAsA2A(stream, taskId, record.contextId, sendEvent);
455
+ if (!interrupted) {
456
+ sendEvent("status-update", {
457
+ id: taskId,
458
+ contextId: record.contextId,
459
+ status: {
460
+ state: record.status,
461
+ timestamp: record.updatedAt
462
+ },
463
+ final: true
464
+ });
465
+ }
418
466
  } catch (err) {
419
467
  sendEvent("error", {
420
468
  code: "STREAM_ERROR",
@@ -564,4 +612,4 @@ export {
564
612
  registerA2ARoutes,
565
613
  setA2AKeyStore
566
614
  };
567
- //# sourceMappingURL=a2a-ERG5RMUW.mjs.map
615
+ //# sourceMappingURL=a2a-QMHEH3ZT.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/routes/a2a.ts"],"sourcesContent":["import type { FastifyInstance, FastifyRequest, FastifyReply } from \"fastify\";\nimport { v4 } from \"uuid\";\nimport {\n agentInstanceManager,\n} from \"@axiom-lattice/core\";\nimport { MessageChunkTypes } from \"@axiom-lattice/protocols\";\nimport type {\n AgentCard,\n A2ATask,\n A2ATaskState,\n A2ATaskSendRequest,\n A2AMessage,\n A2APart,\n A2AAuthContext,\n A2AApiKeyStore,\n A2AApiKeyRecord,\n CreateA2AApiKeyInput,\n A2AApiKeyEntry,\n} from \"@axiom-lattice/protocols\";\n\n// ─── Task Tracking ────────────────────────────────────────────────────────\n\ninterface TaskRecord {\n id: string;\n threadId: string;\n contextId?: string;\n referenceTaskIds?: string[];\n messageId?: string;\n assistantId: string;\n tenantId: string;\n projectId?: string;\n workspaceId?: string;\n status: A2ATaskState;\n createdAt: string;\n updatedAt: string;\n history: A2AMessage[];\n}\n\nconst taskStore = new Map<string, TaskRecord>();\n\nconst MAX_CONTEXT_THREADS = 100;\nconst contextThreadMap = new Map<string, string>();\n\nfunction cacheContextThread(contextId: string, threadId: string): void {\n if (contextThreadMap.size >= MAX_CONTEXT_THREADS) {\n const oldest = contextThreadMap.keys().next().value;\n if (oldest !== undefined) contextThreadMap.delete(oldest);\n }\n contextThreadMap.set(contextId, threadId);\n}\n\n// ─── Key Store ────────────────────────────────────────────────────────────\n\nlet _a2aKeyStore: A2AApiKeyStore | null = null;\nlet _storeKeyMap: Map<string, A2AApiKeyEntry> = new Map();\n\nexport function setA2AKeyStore(store: A2AApiKeyStore): void {\n _a2aKeyStore = store;\n}\n\n/**\n * Reload the cached key map from the store.\n * Call after any CRUD mutation or at startup.\n */\nexport async function refreshStoreKeyMap(): Promise<void> {\n if (!_a2aKeyStore) return;\n _storeKeyMap = await _a2aKeyStore.loadIntoMap();\n}\n\n// ─── Config ───────────────────────────────────────────────────────────────\n\nfunction parseEnvKeyMap(): Map<string, A2AApiKeyEntry> {\n const keysEnv = process.env.A2A_API_KEYS || \"\";\n const defaultTenantId = process.env.A2A_DEFAULT_TENANT_ID || \"a2a-default-tenant\";\n const defaultProjectId = process.env.A2A_DEFAULT_PROJECT_ID || \"\";\n const defaultWorkspaceId = process.env.A2A_DEFAULT_WORKSPACE_ID || \"\";\n const map = new Map<string, A2AApiKeyEntry>();\n\n if (keysEnv) {\n keysEnv.split(\",\").forEach((entry) => {\n const trimmed = entry.trim();\n if (!trimmed) return;\n const parts = trimmed.split(\":\");\n const key = parts[0];\n if (!key) return;\n map.set(key, {\n key,\n tenantId: parts[1]?.trim() || defaultTenantId,\n projectId: parts[2]?.trim() || defaultProjectId || undefined,\n workspaceId: parts[3]?.trim() || defaultWorkspaceId || undefined,\n });\n });\n }\n\n return map;\n}\n\nfunction getA2AConfig() {\n const envMap = parseEnvKeyMap();\n // Store keys take priority; env keys serve as fallback\n const apiKeyMap = new Map([..._storeKeyMap, ...envMap]);\n\n return {\n agentName: process.env.A2A_AGENT_NAME || \"Axiom Lattice Agent\",\n agentDescription:\n process.env.A2A_AGENT_DESCRIPTION ||\n \"AI agent powered by Axiom Lattice framework\",\n organization: process.env.A2A_ORGANIZATION || \"Axiom Lattice\",\n organizationUrl: process.env.A2A_ORGANIZATION_URL || \"https://axiom-lattice.ai\",\n version: process.env.A2A_VERSION || \"1.0.0\",\n defaultAssistantId: process.env.A2A_DEFAULT_AGENT_ID || \"\",\n defaultTenantId: process.env.A2A_DEFAULT_TENANT_ID || \"a2a-default-tenant\",\n defaultProjectId: process.env.A2A_DEFAULT_PROJECT_ID || \"\",\n defaultWorkspaceId: process.env.A2A_DEFAULT_WORKSPACE_ID || \"\",\n apiKeyMap,\n };\n}\n\n// ─── Auth ─────────────────────────────────────────────────────────────────\n\nfunction authenticateA2A(\n request: FastifyRequest,\n): A2AAuthContext {\n const config = getA2AConfig();\n const noAuthRequired = config.apiKeyMap.size === 0;\n\n const token =\n request.headers.authorization?.startsWith(\"Bearer \")\n ? request.headers.authorization.substring(7)\n : (request.headers[\"x-api-key\"] as string | undefined);\n\n if (!token) {\n return {\n authenticated: noAuthRequired,\n tenantId: config.defaultTenantId,\n projectId: config.defaultProjectId || undefined,\n workspaceId: config.defaultWorkspaceId || undefined,\n };\n }\n\n const entry = config.apiKeyMap.get(token);\n if (entry) {\n return {\n authenticated: true,\n apiKey: token,\n tenantId: entry.tenantId,\n projectId: entry.projectId,\n workspaceId: entry.workspaceId,\n source: request.headers.authorization?.startsWith(\"Bearer \") ? \"bearer\" : \"x-api-key\",\n };\n }\n\n return { authenticated: false };\n}\n\nfunction requireAuth(\n request: FastifyRequest,\n reply: FastifyReply,\n): A2AAuthContext {\n const auth = authenticateA2A(request);\n if (!auth.authenticated) {\n reply.status(401).send({\n error: \"Unauthorized\",\n message: \"Valid API key required via Bearer token or X-API-Key header\",\n });\n }\n return auth;\n}\n\n// ─── Agent Card ───────────────────────────────────────────────────────────\n\nfunction buildAgentCard(baseUrl: string): AgentCard {\n const config = getA2AConfig();\n return {\n name: config.agentName,\n description: config.agentDescription,\n url: `${baseUrl}/api/a2a`,\n provider: {\n organization: config.organization,\n url: config.organizationUrl,\n },\n version: config.version,\n capabilities: {\n streaming: true,\n pushNotifications: false,\n stateTransitionHistory: false,\n },\n defaultInputModes: [\"text\", \"text/plain\"],\n defaultOutputModes: [\"text\", \"text/plain\", \"text/markdown\"],\n skills: [],\n };\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────\n\nfunction extractTextFromParts(parts: A2APart[]): string {\n return parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\\n\");\n}\n\nfunction buildTextPart(text: string): A2APart {\n return { type: \"text\", text };\n}\n\nfunction isoNow(): string {\n return new Date().toISOString();\n}\n\ntype SendEventFn = (event: string, data: Record<string, unknown>) => void;\n\nasync function streamChunksAsA2A(\n stream: AsyncIterable<{ type: unknown; data?: { content?: string } }>,\n taskId: string,\n contextId: string | undefined,\n sendEvent: SendEventFn,\n onInterrupt?: () => void,\n): Promise<{ text: string; interrupted: boolean }> {\n let accumulatedText = \"\";\n let interrupted = false;\n\n for await (const chunk of stream) {\n const chunkText = (chunk as { data?: { content?: string } }).data?.content || \"\";\n const chunkType = (chunk as { type: string }).type;\n\n if (chunkType === MessageChunkTypes.INTERRUPT) {\n sendEvent(\"status-update\", {\n id: taskId,\n contextId,\n status: {\n state: \"input-required\",\n message: {\n role: \"agent\",\n parts: [buildTextPart(accumulatedText)],\n },\n timestamp: isoNow(),\n },\n final: false,\n });\n onInterrupt?.();\n interrupted = true;\n break;\n }\n\n if (\n chunkType === MessageChunkTypes.AI ||\n chunkType === MessageChunkTypes.TOOL\n ) {\n if (chunkText) {\n accumulatedText += chunkText;\n sendEvent(\"status-update\", {\n id: taskId,\n contextId,\n status: {\n state: \"working\",\n message: {\n role: \"agent\",\n parts: [buildTextPart(chunkText)],\n },\n timestamp: isoNow(),\n },\n final: false,\n });\n }\n }\n }\n\n return { text: accumulatedText, interrupted };\n}\n\n// ─── Task Status ──────────────────────────────────────────────────────────\n\nasync function getTaskStatus(taskId: string): Promise<A2ATask | null> {\n const record = taskStore.get(taskId);\n if (!record) return null;\n\n return {\n id: record.id,\n status: {\n state: record.status,\n timestamp: record.updatedAt,\n },\n artifacts: [],\n history: record.history,\n };\n}\n\n// ─── Handlers ─────────────────────────────────────────────────────────────\n\nasync function handleAgentCard(\n request: FastifyRequest,\n reply: FastifyReply,\n): Promise<void> {\n const protocol =\n (request.headers[\"x-forwarded-proto\"] as string) ||\n request.protocol;\n const host = request.hostname;\n const baseUrl = `${protocol}://${host}`;\n const card = buildAgentCard(baseUrl);\n reply.status(200).send(card);\n}\n\nasync function handleTasksGet(\n request: FastifyRequest<{ Params: { taskId: string } }>,\n reply: FastifyReply,\n): Promise<void> {\n const auth = requireAuth(request, reply);\n if (!auth.authenticated) return;\n const task = await getTaskStatus(request.params.taskId);\n if (!task) {\n reply.status(404).send({ error: \"Task not found\" });\n return;\n }\n reply.status(200).send(task);\n}\n\nasync function handleTasksSend(\n request: FastifyRequest<{ Body: A2ATaskSendRequest }>,\n reply: FastifyReply,\n): Promise<void> {\n const auth = requireAuth(request, reply);\n if (!auth.authenticated) return;\n\n const config = getA2AConfig();\n const body = request.body as A2ATaskSendRequest;\n\n if (!body.message || !body.message.parts || body.message.parts.length === 0) {\n reply.status(400).send({ error: \"message.parts is required\" });\n return;\n }\n\n const text = extractTextFromParts(body.message.parts);\n if (!text.trim()) {\n reply.status(400).send({ error: \"message must contain text content\" });\n return;\n }\n\n const assistantId =\n (request.headers[\"x-a2a-agent-id\"] as string) ||\n config.defaultAssistantId;\n\n if (!assistantId) {\n reply.status(500).send({\n error: \"No agent configured\",\n message:\n \"Set A2A_DEFAULT_AGENT_ID env var or provide x-a2a-agent-id header\",\n });\n return;\n }\n\n const contextId = body.message.contextId;\n const referenceTaskIds = body.message.referenceTaskIds;\n const taskId = body.id || v4();\n\n let threadId: string;\n let resolvedReferenceTaskIds: string[] | undefined;\n\n // Explicit task continuation: if body.id matches a stored task\n if (body.id) {\n const existingTask = taskStore.get(body.id);\n if (existingTask) {\n if (existingTask.status === \"input-required\") {\n threadId = existingTask.threadId;\n resolvedReferenceTaskIds = referenceTaskIds;\n } else if (\n existingTask.status === \"completed\" ||\n existingTask.status === \"failed\" ||\n existingTask.status === \"canceled\"\n ) {\n threadId = v4();\n resolvedReferenceTaskIds = referenceTaskIds\n ? [...referenceTaskIds, body.id]\n : [body.id];\n } else {\n threadId = v4();\n resolvedReferenceTaskIds = referenceTaskIds;\n }\n } else {\n threadId = v4();\n resolvedReferenceTaskIds = referenceTaskIds\n ? [...referenceTaskIds, body.id]\n : [body.id];\n }\n } else if (contextId && contextThreadMap.has(contextId)) {\n threadId = contextThreadMap.get(contextId)!;\n console.warn({\n event: \"a2a:deprecated:contextId_thread_reuse\",\n message: \"contextId-based thread reuse is deprecated; use referenceTaskIds and application-layer conversation state instead\",\n contextId,\n threadId,\n });\n resolvedReferenceTaskIds = referenceTaskIds;\n } else {\n threadId = v4();\n resolvedReferenceTaskIds = referenceTaskIds;\n }\n\n const tenantId = auth.tenantId || config.defaultTenantId;\n\n const now = isoNow();\n\n const record: TaskRecord = {\n id: taskId,\n threadId,\n contextId,\n referenceTaskIds: resolvedReferenceTaskIds,\n assistantId,\n tenantId,\n projectId: auth.projectId || undefined,\n workspaceId: auth.workspaceId || undefined,\n status: \"working\",\n createdAt: now,\n updatedAt: now,\n history: [\n {\n role: \"user\",\n parts: body.message.parts,\n },\n ],\n };\n\n taskStore.set(taskId, record);\n\n let agent;\n try {\n agent = agentInstanceManager.getAgent({\n assistant_id: assistantId,\n thread_id: threadId,\n tenant_id: tenantId,\n workspace_id: auth.workspaceId || undefined,\n project_id: auth.projectId || undefined,\n });\n } catch (err) {\n record.status = \"failed\";\n record.updatedAt = isoNow();\n reply.status(500).send({\n id: taskId,\n error: \"Failed to initialize agent\",\n message: err instanceof Error ? err.message : String(err),\n });\n return;\n }\n\n reply.hijack();\n reply.raw.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n\n const sendEvent = (event: string, data: Record<string, unknown>): void => {\n reply.raw.write(`event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`);\n };\n\n try {\n const result = await agent.addMessage({\n input: { message: text },\n });\n\n record.messageId = result.messageId;\n\n const stream = agent.chunkStream(result.messageId, [\n MessageChunkTypes.MESSAGE_COMPLETED,\n ]);\n\n const { text: accumulatedText, interrupted } = await streamChunksAsA2A(stream, taskId, contextId, sendEvent, () => {\n record.status = \"input-required\";\n record.updatedAt = isoNow();\n });\n\n if (!interrupted) {\n record.status = \"completed\";\n record.updatedAt = isoNow();\n record.history.push({\n role: \"agent\",\n parts: [buildTextPart(accumulatedText)],\n });\n\n sendEvent(\"status-update\", {\n id: taskId,\n contextId,\n status: {\n state: \"completed\",\n timestamp: isoNow(),\n },\n final: true,\n });\n }\n } catch (err) {\n record.status = \"failed\";\n record.updatedAt = isoNow();\n\n sendEvent(\"error\", {\n code: \"EXECUTION_ERROR\",\n message: err instanceof Error ? err.message : String(err),\n });\n\n sendEvent(\"status-update\", {\n id: taskId,\n contextId,\n status: {\n state: \"failed\",\n timestamp: isoNow(),\n },\n final: true,\n });\n } finally {\n reply.raw.end();\n }\n}\n\nasync function handleTasksCancel(\n request: FastifyRequest<{ Params: { taskId: string } }>,\n reply: FastifyReply,\n): Promise<void> {\n const auth = requireAuth(request, reply);\n if (!auth.authenticated) return;\n const { taskId } = request.params;\n const record = taskStore.get(taskId);\n\n if (!record) {\n reply.status(404).send({ error: \"Task not found\" });\n return;\n }\n\n if (record.status === \"completed\" || record.status === \"failed\" || record.status === \"canceled\") {\n reply.status(409).send({\n error: \"Task is already in a terminal state\",\n task: { id: record.id, status: record.status },\n });\n return;\n }\n\n try {\n const agent = agentInstanceManager.getAgent({\n assistant_id: record.assistantId,\n thread_id: record.threadId,\n tenant_id: record.tenantId,\n workspace_id: record.workspaceId,\n project_id: record.projectId,\n });\n await agent.abort();\n } catch (err) {\n // Agent session may have already been cleaned up\n console.warn({\n event: \"a2a:cancel:no_agent\",\n taskId,\n threadId: record.threadId,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n\n record.status = \"canceled\";\n record.updatedAt = isoNow();\n\n reply.status(200).send({\n id: taskId,\n status: {\n state: \"canceled\",\n timestamp: record.updatedAt,\n },\n });\n}\n\nasync function handleTasksStream(\n request: FastifyRequest<{ Params: { taskId: string } }>,\n reply: FastifyReply,\n): Promise<void> {\n const auth = requireAuth(request, reply);\n if (!auth.authenticated) return;\n\n const { taskId } = request.params;\n const record = taskStore.get(taskId);\n\n if (!record) {\n reply.status(404).send({ error: \"Task not found\" });\n return;\n }\n\n let agent;\n try {\n agent = agentInstanceManager.getAgent({\n assistant_id: record.assistantId,\n thread_id: record.threadId,\n tenant_id: record.tenantId,\n workspace_id: record.workspaceId,\n project_id: record.projectId,\n });\n } catch {\n reply.status(404).send({\n error: \"Agent session not found. The task may have already completed.\",\n });\n return;\n }\n\n reply.hijack();\n reply.raw.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n\n const sendEvent = (event: string, data: Record<string, unknown>): void => {\n reply.raw.write(`event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`);\n };\n\n if (!record.messageId) {\n sendEvent(\"status-update\", {\n id: taskId,\n contextId: record.contextId,\n status: {\n state: record.status,\n timestamp: record.updatedAt,\n },\n final: true,\n });\n reply.raw.end();\n return;\n }\n\n try {\n const stream = agent.chunkStream(record.messageId, [\n MessageChunkTypes.MESSAGE_COMPLETED,\n ]);\n\n const { interrupted } = await streamChunksAsA2A(stream, taskId, record.contextId, sendEvent);\n\n if (!interrupted) {\n sendEvent(\"status-update\", {\n id: taskId,\n contextId: record.contextId,\n status: {\n state: record.status,\n timestamp: record.updatedAt,\n },\n final: true,\n });\n }\n } catch (err) {\n sendEvent(\"error\", {\n code: \"STREAM_ERROR\",\n message: err instanceof Error ? err.message : String(err),\n });\n } finally {\n reply.raw.end();\n }\n}\n\n// ─── API Key Management Handlers ─────────────────────────────────────────\n\nasync function handleApiKeyList(\n request: FastifyRequest<{ Querystring: { tenantId?: string; limit?: string; offset?: string } }>,\n reply: FastifyReply,\n): Promise<void> {\n const auth = requireAuth(request, reply);\n if (!auth.authenticated) return;\n\n if (!_a2aKeyStore) {\n reply.status(501).send({ error: \"Key store not configured\" });\n return;\n }\n\n const records = await _a2aKeyStore.list({\n tenantId: request.query.tenantId,\n limit: request.query.limit ? parseInt(request.query.limit, 10) : undefined,\n offset: request.query.offset ? parseInt(request.query.offset, 10) : undefined,\n });\n\n reply.status(200).send({\n success: true,\n data: {\n records: records.map((r) => ({ ...r, key: r.key.slice(0, 8) + \"...\" })),\n total: records.length,\n },\n });\n}\n\nasync function handleApiKeyCreate(\n request: FastifyRequest<{ Body: Partial<CreateA2AApiKeyInput> }>,\n reply: FastifyReply,\n): Promise<void> {\n const auth = requireAuth(request, reply);\n if (!auth.authenticated) return;\n\n if (!_a2aKeyStore) {\n reply.status(501).send({ error: \"Key store not configured\" });\n return;\n }\n\n const body = request.body as Partial<CreateA2AApiKeyInput>;\n // Scope from request body / headers; fallback to auth context\n const tenantId =\n body.tenantId ||\n (request.headers[\"x-tenant-id\"] as string) ||\n auth.tenantId;\n const projectId =\n body.projectId || (request.headers[\"x-project-id\"] as string) || auth.projectId || \"default\";\n const workspaceId =\n body.workspaceId || (request.headers[\"x-workspace-id\"] as string) || auth.workspaceId;\n\n if (!tenantId) {\n reply.status(400).send({\n error: \"tenantId is required\",\n message: \"Provide via body.tenantId, x-tenant-id header, or authenticate with a scoped API key\",\n });\n return;\n }\n\n const record = await _a2aKeyStore.create({\n tenantId,\n projectId,\n workspaceId,\n label: body.label,\n });\n await refreshStoreKeyMap();\n\n reply.status(201).send({ success: true, data: record });\n}\n\nasync function handleApiKeyDelete(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply,\n): Promise<void> {\n const auth = requireAuth(request, reply);\n if (!auth.authenticated) return;\n\n if (!_a2aKeyStore) {\n reply.status(501).send({ error: \"Key store not configured\" });\n return;\n }\n\n await _a2aKeyStore.delete(request.params.id);\n await refreshStoreKeyMap();\n\n reply.status(200).send({ success: true });\n}\n\nasync function handleApiKeyDisable(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply,\n): Promise<void> {\n const auth = requireAuth(request, reply);\n if (!auth.authenticated) return;\n\n if (!_a2aKeyStore) {\n reply.status(501).send({ error: \"Key store not configured\" });\n return;\n }\n\n await _a2aKeyStore.disable(request.params.id);\n await refreshStoreKeyMap();\n\n reply.status(200).send({ success: true });\n}\n\nasync function handleApiKeyEnable(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply,\n): Promise<void> {\n const auth = requireAuth(request, reply);\n if (!auth.authenticated) return;\n\n if (!_a2aKeyStore) {\n reply.status(501).send({ error: \"Key store not configured\" });\n return;\n }\n\n await _a2aKeyStore.enable(request.params.id);\n await refreshStoreKeyMap();\n\n reply.status(200).send({ success: true });\n}\n\nasync function handleApiKeyRotate(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply,\n): Promise<void> {\n const auth = requireAuth(request, reply);\n if (!auth.authenticated) return;\n\n if (!_a2aKeyStore) {\n reply.status(501).send({ error: \"Key store not configured\" });\n return;\n }\n\n const record = await _a2aKeyStore.rotate(request.params.id);\n await refreshStoreKeyMap();\n\n reply.status(200).send({ success: true, data: record });\n}\n\n// ─── Route Registration ───────────────────────────────────────────────────\n\nexport function registerA2ARoutes(app: FastifyInstance): void {\n app.get(\"/api/a2a/.well-known/agent.json\", handleAgentCard);\n app.get(\"/api/a2a/.well-known/agent-card.json\", handleAgentCard);\n\n app.post<{ Body: A2ATaskSendRequest }>(\n \"/api/a2a/tasks/send\",\n handleTasksSend,\n );\n\n app.get<{ Params: { taskId: string } }>(\n \"/api/a2a/tasks/:taskId\",\n handleTasksGet,\n );\n\n app.get<{ Params: { taskId: string } }>(\n \"/api/a2a/tasks/:taskId/stream\",\n handleTasksStream,\n );\n\n app.post<{ Params: { taskId: string } }>(\n \"/api/a2a/tasks/:taskId/cancel\",\n handleTasksCancel,\n );\n\n // A2A API Key management\n app.get<{ Querystring: { tenantId?: string; limit?: string; offset?: string } }>(\n \"/api/a2a/keys\",\n handleApiKeyList,\n );\n\n app.post<{ Body: Partial<CreateA2AApiKeyInput> }>(\n \"/api/a2a/keys\",\n handleApiKeyCreate,\n );\n\n app.delete<{ Params: { id: string } }>(\n \"/api/a2a/keys/:id\",\n handleApiKeyDelete,\n );\n\n app.post<{ Params: { id: string } }>(\n \"/api/a2a/keys/:id/disable\",\n handleApiKeyDisable,\n );\n\n app.post<{ Params: { id: string } }>(\n \"/api/a2a/keys/:id/enable\",\n handleApiKeyEnable,\n );\n\n app.post<{ Params: { id: string } }>(\n \"/api/a2a/keys/:id/rotate\",\n handleApiKeyRotate,\n );\n}\n"],"mappings":"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","names":[]}