@axiom-lattice/gateway 2.1.117 → 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.
- package/.turbo/turbo-build.log +12 -12
- package/CHANGELOG.md +26 -0
- package/dist/{a2a-ERG5RMUW.mjs → a2a-QMHEH3ZT.mjs} +77 -29
- package/dist/a2a-QMHEH3ZT.mjs.map +1 -0
- package/dist/index.js +1064 -176
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +933 -91
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -5
- package/src/__tests__/a2a.test.ts +82 -0
- package/src/__tests__/workspace.test.ts +13 -3
- package/src/config/local-a2a-templates.ts +59 -0
- package/src/controllers/__tests__/assistant-local-a2a.test.ts +147 -0
- package/src/controllers/__tests__/local-a2a-templates.test.ts +112 -0
- package/src/controllers/assistant.ts +126 -4
- package/src/controllers/local-a2a-templates.ts +18 -0
- package/src/controllers/local-a2a.ts +149 -0
- package/src/controllers/tasks.ts +2 -3
- package/src/controllers/workspace.ts +144 -17
- package/src/index.ts +1 -9
- package/src/routes/__tests__/a2a-test-connection.test.ts +177 -0
- package/src/routes/a2a-test-connection.ts +126 -0
- package/src/routes/a2a.ts +100 -28
- package/src/routes/index.ts +23 -0
- package/src/services/__tests__/local-a2a.test.ts +124 -0
- package/src/services/eval-runner.ts +6 -0
- package/src/services/local-a2a.ts +352 -0
- package/src/utils/__tests__/local-a2a-runtime.test.ts +77 -0
- package/src/utils/__tests__/path-containment.test.ts +35 -0
- package/src/utils/a2a-url.ts +20 -0
- package/src/utils/local-a2a-runtime.ts +107 -0
- package/src/utils/path-containment.ts +38 -0
- package/dist/a2a-ERG5RMUW.mjs.map +0 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @axiom-lattice/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
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -11,23 +11,23 @@
|
|
|
11
11
|
[34mESM[39m Build start
|
|
12
12
|
[warn] [33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1m"import.meta" is not available with the "cjs" output format and will be empty[0m [empty-import-meta]
|
|
13
13
|
|
|
14
|
-
src/index.ts:
|
|
15
|
-
[37m
|
|
14
|
+
src/index.ts:200:33:
|
|
15
|
+
[37m 200 │ const __filename = fileURLToPath([32mimport.meta[37m.url);
|
|
16
16
|
╵ [32m~~~~~~~~~~~[0m
|
|
17
17
|
|
|
18
18
|
You need to set the output format to "esm" for "import.meta" to work correctly.
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
[32mCJS[39m [1mdist/index.js [22m[
|
|
22
|
-
[32mCJS[39m [1mdist/index.js.map [22m[
|
|
23
|
-
[32mCJS[39m ⚡️ Build success in
|
|
24
|
-
[32mESM[39m [1mdist/index.mjs [22m[
|
|
21
|
+
[32mCJS[39m [1mdist/index.js [22m[32m443.07 KB[39m
|
|
22
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m895.92 KB[39m
|
|
23
|
+
[32mCJS[39m ⚡️ Build success in 659ms
|
|
24
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m370.08 KB[39m
|
|
25
25
|
[32mESM[39m [1mdist/mcp-configs-SHRMQHIL.mjs [22m[32m685.00 B[39m
|
|
26
26
|
[32mESM[39m [1mdist/chunk-K4XELOSO.mjs [22m[32m12.52 KB[39m
|
|
27
27
|
[32mESM[39m [1mdist/sender-PX32VSHB.mjs [22m[32m873.00 B[39m
|
|
28
28
|
[32mESM[39m [1mdist/WechatChannelAdapter-WSDKR4OA.mjs [22m[32m8.27 KB[39m
|
|
29
29
|
[32mESM[39m [1mdist/chunk-6CUQGDJI.mjs [22m[32m6.42 KB[39m
|
|
30
|
-
[32mESM[39m [1mdist/a2a-
|
|
30
|
+
[32mESM[39m [1mdist/a2a-QMHEH3ZT.mjs [22m[32m17.78 KB[39m
|
|
31
31
|
[32mESM[39m [1mdist/resources-VA7LSDKN.mjs [22m[32m15.81 KB[39m
|
|
32
32
|
[32mESM[39m [1mdist/chunk-LHQY46YB.mjs [22m[32m1.46 KB[39m
|
|
33
33
|
[32mESM[39m [1mdist/mcp-configs-SHRMQHIL.mjs.map [22m[32m71.00 B[39m
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
[32mESM[39m [1mdist/sender-PX32VSHB.mjs.map [22m[32m2.07 KB[39m
|
|
36
36
|
[32mESM[39m [1mdist/WechatChannelAdapter-WSDKR4OA.mjs.map [22m[32m16.28 KB[39m
|
|
37
37
|
[32mESM[39m [1mdist/chunk-6CUQGDJI.mjs.map [22m[32m14.04 KB[39m
|
|
38
|
-
[32mESM[39m [1mdist/a2a-
|
|
38
|
+
[32mESM[39m [1mdist/a2a-QMHEH3ZT.mjs.map [22m[32m35.64 KB[39m
|
|
39
39
|
[32mESM[39m [1mdist/resources-VA7LSDKN.mjs.map [22m[32m29.34 KB[39m
|
|
40
40
|
[32mESM[39m [1mdist/chunk-LHQY46YB.mjs.map [22m[32m2.39 KB[39m
|
|
41
|
-
[32mESM[39m [1mdist/index.mjs.map [22m[
|
|
42
|
-
[32mESM[39m ⚡️ Build success in
|
|
41
|
+
[32mESM[39m [1mdist/index.mjs.map [22m[32m770.22 KB[39m
|
|
42
|
+
[32mESM[39m ⚡️ Build success in 658ms
|
|
43
43
|
[34mDTS[39m Build start
|
|
44
|
-
[32mDTS[39m ⚡️ Build success in
|
|
44
|
+
[32mDTS[39m ⚡️ Build success in 20073ms
|
|
45
45
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m7.57 KB[39m
|
|
46
46
|
[32mDTS[39m [1mdist/index.d.mts [22m[32m7.57 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
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
|
+
|
|
3
29
|
## 2.1.117
|
|
4
30
|
|
|
5
31
|
### 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
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
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
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-
|
|
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":[]}
|