@loopingai/core 0.1.1 → 0.2.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 (75) hide show
  1. package/README.md +131 -15
  2. package/dist/a2a/card.d.ts +35 -0
  3. package/dist/a2a/card.d.ts.map +1 -1
  4. package/dist/a2a/card.js +41 -3
  5. package/dist/a2a/card.js.map +1 -1
  6. package/dist/a2a/context.d.ts +9 -3
  7. package/dist/a2a/context.d.ts.map +1 -1
  8. package/dist/a2a/context.js +11 -4
  9. package/dist/a2a/context.js.map +1 -1
  10. package/dist/a2a/index.d.ts +1 -1
  11. package/dist/a2a/index.d.ts.map +1 -1
  12. package/dist/a2a/index.js +1 -1
  13. package/dist/a2a/index.js.map +1 -1
  14. package/dist/a2a/notify.d.ts +11 -2
  15. package/dist/a2a/notify.d.ts.map +1 -1
  16. package/dist/a2a/notify.js +12 -3
  17. package/dist/a2a/notify.js.map +1 -1
  18. package/dist/a2a/verify.d.ts +23 -2
  19. package/dist/a2a/verify.d.ts.map +1 -1
  20. package/dist/a2a/verify.js +26 -3
  21. package/dist/a2a/verify.js.map +1 -1
  22. package/dist/agent/history.d.ts +15 -0
  23. package/dist/agent/history.d.ts.map +1 -1
  24. package/dist/agent/history.js +17 -0
  25. package/dist/agent/history.js.map +1 -1
  26. package/dist/agent/index.d.ts +1 -1
  27. package/dist/agent/index.d.ts.map +1 -1
  28. package/dist/agent/index.js +1 -1
  29. package/dist/agent/index.js.map +1 -1
  30. package/dist/contract/index.d.ts +1 -1
  31. package/dist/contract/index.d.ts.map +1 -1
  32. package/dist/contract/index.js.map +1 -1
  33. package/dist/contract/plugin.d.ts +86 -3
  34. package/dist/contract/plugin.d.ts.map +1 -1
  35. package/dist/contract/plugin.js.map +1 -1
  36. package/dist/db/db.d.ts +32 -14
  37. package/dist/db/db.d.ts.map +1 -1
  38. package/dist/db/db.js.map +1 -1
  39. package/dist/env.d.ts +10 -2
  40. package/dist/env.d.ts.map +1 -1
  41. package/dist/env.js +10 -2
  42. package/dist/env.js.map +1 -1
  43. package/dist/index.d.ts +2 -2
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +1 -1
  46. package/dist/index.js.map +1 -1
  47. package/dist/runtime/index.d.ts +28 -3
  48. package/dist/runtime/index.d.ts.map +1 -1
  49. package/dist/runtime/index.js +39 -3
  50. package/dist/runtime/index.js.map +1 -1
  51. package/dist/subagent/workspace.d.ts +21 -0
  52. package/dist/subagent/workspace.d.ts.map +1 -1
  53. package/dist/subagent/workspace.js +80 -5
  54. package/dist/subagent/workspace.js.map +1 -1
  55. package/dist/testing/auth.d.ts +23 -0
  56. package/dist/testing/auth.d.ts.map +1 -1
  57. package/dist/testing/auth.js +11 -3
  58. package/dist/testing/auth.js.map +1 -1
  59. package/dist/testing/fixtures.d.ts +21 -0
  60. package/dist/testing/fixtures.d.ts.map +1 -1
  61. package/dist/testing/fixtures.js +21 -0
  62. package/dist/testing/fixtures.js.map +1 -1
  63. package/dist/testing/node.d.ts +23 -0
  64. package/dist/testing/node.d.ts.map +1 -1
  65. package/dist/testing/node.js +23 -0
  66. package/dist/testing/node.js.map +1 -1
  67. package/dist/testing/vcr-spec.d.ts +4 -4
  68. package/dist/testing/vcr-spec.d.ts.map +1 -1
  69. package/dist/testing/vcr-spec.js +32 -11
  70. package/dist/testing/vcr-spec.js.map +1 -1
  71. package/dist/worker/index.d.ts +142 -3
  72. package/dist/worker/index.d.ts.map +1 -1
  73. package/dist/worker/index.js +152 -29
  74. package/dist/worker/index.js.map +1 -1
  75. package/package.json +12 -4
package/README.md CHANGED
@@ -68,22 +68,84 @@ const manifest = {
68
68
 
69
69
  export default {
70
70
  fetch: createA2AWorker({
71
- manifest,
72
- // One DO instance per verified caller this is what makes a task
73
- // unreachable from any other caller by construction.
74
- resolveAgent: (identity) =>
75
- env.MY_AGENT.get(env.MY_AGENT.idFromName(identity.key!)),
76
- // Must be idempotent: the gateway retries dispatch.
77
- startTurn: async (turn) => {
78
- await env.TURN_WORKFLOW.create({ id: turn.messageId, params: turn });
71
+ // The stub card at /.well-known/agent-card.json. It describes the origin,
72
+ // not an agentsee below.
73
+ manifest: hostManifest,
74
+ tenants: {
75
+ "my-agent": {
76
+ manifest,
77
+ // One DO instance per verified caller — this is what makes a task
78
+ // unreachable from any other caller by construction.
79
+ resolveAgent: (identity) =>
80
+ env.MY_AGENT.get(env.MY_AGENT.idFromName(identity.key!)),
81
+ // Must be idempotent: the gateway retries dispatch.
82
+ startTurn: async (turn) => {
83
+ await env.TURN_WORKFLOW.create({ id: turn.messageId, params: turn });
84
+ }
85
+ }
79
86
  }
80
87
  })
81
88
  } satisfies ExportedHandler<Env>;
82
89
  ```
83
90
 
84
- That handler serves three routes: the public JWKS, a **signed** AgentCard at
85
- `/.well-known/agent-card.json`, and gateway-authenticated JSON-RPC. Every POST is
86
- verified before a Durable Object is ever addressed.
91
+ That handler serves three routes: the public JWKS, a **signed** stub AgentCard at
92
+ `/.well-known/agent-card.json`, and gateway-authenticated JSON-RPC. Every POST is verified
93
+ before a Durable Object is ever addressed.
94
+
95
+ #### Agents are tenants
96
+
97
+ Agents are keyed by **tenant id**, and one is required on every request — there is no
98
+ default agent and no implicit routing. This is the A2A mechanism for exactly this case:
99
+ `AgentInterface.tenant` is _"an opaque string used for routing requests to a specific agent
100
+ or tenant when multiple agents are served behind a single A2A endpoint"_, and §8.3.2
101
+ requires a client to send the value the interface it selected declared.
102
+
103
+ So one origin serves any number of agents over **one endpoint, one signing key and one
104
+ card** at the well-known path. It works the same for one agent as for twenty; nothing about
105
+ the shape changes.
106
+
107
+ The card is the reason it has to be this way rather than a path prefix per agent. Its
108
+ location is a **well-known URI**, which RFC 8615 defines per-authority, so exactly one card
109
+ per origin is discoverable at the path A2A registered with IANA. A gateway resolving
110
+ `/.well-known/agent-card.json` against the origin finds that one card whatever prefix an
111
+ agent is mounted behind — and pins its key for all of them.
112
+
113
+ Which is why the card served there is a **stub**: it describes the deployment, advertises
114
+ the endpoint and `extendedAgentCard`, and names no tenant. A tenant's real card — its name,
115
+ skills and signature — comes from `GetExtendedAgentCard`, the spec's own tenant-aware card
116
+ method:
117
+
118
+ ```jsonc
119
+ // POST /a2a
120
+ {
121
+ "jsonrpc": "2.0",
122
+ "id": 1,
123
+ "method": "GetExtendedAgentCard",
124
+ "params": { "tenant": "my-agent" }
125
+ }
126
+ ```
127
+
128
+ A card carries one interface entry and clients take the first, so the stub cannot list its
129
+ siblings — put their names in `description` for a human, and register them out of band.
130
+
131
+ Two independent checks keep one tenant's traffic out of another's:
132
+
133
+ | check | proves |
134
+ | ------------ | -------------------------------------------- |
135
+ | `aud` | the token was minted for **this deployment** |
136
+ | tenant claim | …and for **this agent on it** |
137
+
138
+ The second is load-bearing. Every tenant shares one endpoint and therefore one audience, so
139
+ the audience cannot distinguish them: without the claim, `tenant` would be an
140
+ unauthenticated field in the request body and a token minted for one agent could be replayed
141
+ against any sibling. A token carrying no tenant claim is rejected rather than treated as a
142
+ wildcard.
143
+
144
+ > **Breaking.** Requires a gateway that mints both the endpoint audience and the tenant
145
+ > claim, and registers agents with a tenant id — looping-gateway
146
+ > [#62](https://github.com/Looping-AI/looping-gateway/pull/62). The two sides do not
147
+ > interoperate across this change in either direction, so they deploy together and
148
+ > registered agents are re-registered.
87
149
 
88
150
  ### 3. Build the runtime in your Durable Object
89
151
 
@@ -207,10 +269,40 @@ its cause.
207
269
  The contract is **additive-only within a major**: new capabilities arrive as optional
208
270
  fields on `AgentPlugin`.
209
271
 
210
- The one session hook core offers is `onMessagesDisplaced` — the raw messages a compaction
211
- is about to fold into a summary. Core performs the compaction, so core announces the loss;
212
- it neither stores the messages nor knows who wants them. An episodic-memory plugin, an
213
- audit log, and a cold-storage dump all want exactly this callback, and each gets it:
272
+ ### Plugin-owned tables
273
+
274
+ A plugin owns its tables outright, through `store: PluginStore` but it must stay out of
275
+ core's migration journal. `drizzle-orm/durable-sqlite/migrator` keeps one flat integer
276
+ journal and one global `__drizzle_migrations` table, and two independently-versioned
277
+ packages cannot share that index space.
278
+
279
+ That is a prohibition on exactly **one import**, not on drizzle. The query builder holds
280
+ no journal and no connection state, so a plugin declares its tables with `sqliteTable`,
281
+ writes idempotent DDL in `ensureTables`, and queries through its own handle:
282
+
283
+ ```ts
284
+ export const scrapes = sqliteTable("scraper_scrapes", { url: text("url").primaryKey() });
285
+
286
+ store: {
287
+ plugin: "scraper",
288
+ version: 1,
289
+ // Re-run on every hibernation wake-up, so it must be idempotent.
290
+ ensureTables: (sql) => sql.exec(`CREATE TABLE IF NOT EXISTS scraper_scrapes (…)`)
291
+ }
292
+
293
+ // …and anywhere the plugin queries:
294
+ const db = drizzle(storage, { schema: { scrapes } });
295
+ ```
296
+
297
+ Core records each store's version in a `plugin_migrations` row, so `ensureTables` receives
298
+ the version last seen on disk and an upgrade path can branch on it.
299
+
300
+ ### Session hooks
301
+
302
+ `onMessagesDisplaced` hands over the raw messages a compaction is about to fold into a
303
+ summary. Core performs the compaction, so core announces the loss; it neither stores the
304
+ messages nor knows who wants them. An episodic-memory plugin, an audit log, and a
305
+ cold-storage dump all want exactly this callback, and each gets it:
214
306
 
215
307
  ```ts
216
308
  // in your DO, wiring the runtime's fan-out into the session
@@ -224,6 +316,30 @@ Best-effort in both directions — a listener that throws never aborts compactio
224
316
  must still shorten when a side store is down), and the fan-out is `Promise.allSettled`, so
225
317
  one plugin's outage cannot cost another its notification.
226
318
 
319
+ `shouldHandleTurn` is the other side of the session: a gate that decides whether a turn
320
+ runs at all, before the loop builds or calls anything. An agent that sees every message in
321
+ its channels is mostly seeing messages that are not for it, and asking a model already
322
+ trying to be helpful to stay quiet degrades _invisibly_ — failing to call a decline-tool
323
+ looks identical to deciding not to. Every declaring plugin is consulted and the answers are
324
+ AND-ed, so any one gate may decline.
325
+
326
+ ```ts
327
+ if (!(await this.runtime.shouldHandleTurn({ history }))) return; // declined
328
+ ```
329
+
330
+ It **fails open**: a gate that throws is counted as `true`. The two mistakes are not
331
+ symmetric — a wrong reply is noise the user can see and ignore, while a wrong silence is
332
+ invisible to the person who needed an answer.
333
+
334
+ ### The workspace backend
335
+
336
+ Core declares the `WorkspaceBacking` shape and enforces the caps, but ships no backend —
337
+ the predecessor's was `@cloudflare/shell`, which is experimental, and an agent that never
338
+ delegates file work should not carry it. A plugin supplies one via `workspaceBacking`; at
339
+ most one may, and an agent that installs none gets `memoryWorkspaceBacking`. So
340
+ `runtime.workspaceBacking` is always defined and your `SubagentRuntime` never needs a null
341
+ check.
342
+
227
343
  ---
228
344
 
229
345
  ## Testing
@@ -33,6 +33,18 @@ export interface BuildCardOptions {
33
33
  origin: string;
34
34
  /** Path this agent answers JSON-RPC on. Defaults to {@link A2A_RPC_PATH}. */
35
35
  rpcPath?: string;
36
+ /**
37
+ * The tenant this card describes, advertised on its interface entry.
38
+ *
39
+ * Several agents share one endpoint here, so `tenant` is what says *which*
40
+ * one — A2A spec §8.3.2 requires a client to echo the declared value on every
41
+ * request, and this Worker refuses a request that does not.
42
+ *
43
+ * Omitted for the **root stub card**, which describes the origin rather than
44
+ * any agent: it advertises the endpoint and `extendedAgentCard`, and a caller
45
+ * reaches a real agent by asking for its tenant.
46
+ */
47
+ tenant?: string;
36
48
  /**
37
49
  * Advertise the gateway's Bearer-JWT scheme in `securitySchemes`.
38
50
  *
@@ -93,6 +105,29 @@ export declare function buildBaseCard(manifest: AgentManifest, opts: BuildCardOp
93
105
  * (Trust-On-First-Use).
94
106
  */
95
107
  export declare function signCard(card: AgentCard, cfg: CardSigningConfig): Promise<WireAgentCard>;
108
+ /**
109
+ * The same signature, attached to the **in-memory** card instead of the wire
110
+ * one — for a caller that hands the card to something which will encode it
111
+ * itself.
112
+ *
113
+ * That caller is `GetExtendedAgentCard`. The SDK's JSON-RPC transport runs
114
+ * `AgentCard.toJSON()` over whatever the extended-card provider returns, so
115
+ * returning {@link signCard}'s wire card means `toJSON` runs over a document
116
+ * that has already been encoded. For most cards that is a no-op and looks fine
117
+ * — which is the trap. `securitySchemes` is a protobuf *oneof*: encoding it
118
+ * twice collapses `{ gatewayJwt: { httpAuthSecurityScheme: … } }` to
119
+ * `{ gatewayJwt: {} }`, the served document stops matching the one that was
120
+ * signed, and every signature verification fails.
121
+ *
122
+ * So the double encode is latent today only because
123
+ * {@link BuildCardOptions.advertiseSecuritySchemes} defaults to `false`; it
124
+ * would surface the day that flag is flipped, as a signature failure with
125
+ * nothing pointing back here. Returning the in-memory card lets the SDK do the
126
+ * single encode the signature was computed over, and is correct either way.
127
+ *
128
+ * `card.spec.ts` pins both halves.
129
+ */
130
+ export declare function signCardInPlace(card: AgentCard, cfg: CardSigningConfig): Promise<AgentCard>;
96
131
  /**
97
132
  * The card's protobuf-JSON encoding. Typed back as `AgentCard` for the SDK
98
133
  * signer, which is generic over "the document to canonicalize" rather than over
@@ -1 +1 @@
1
- {"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../src/a2a/card.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,EAEL,SAAS,EAEV,MAAM,aAAa,CAAC;AAKrB,iFAAiF;AACjF,eAAO,MAAM,YAAY,SAAS,CAAC;AAEnC;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG,IAAI,CAC9B,SAAS,EACP,MAAM,GACN,aAAa,GACb,SAAS,GACT,cAAc,GACd,mBAAmB,GACnB,oBAAoB,GACpB,QAAQ,CACX,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpD,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,UAAU,EAAE,GAAG,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,wEAAwE;IACxE,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC;AAUD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,aAAa,EACvB,IAAI,EAAE,gBAAgB,GACrB,SAAS,CAiCX;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,SAAS,EACf,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,aAAa,CAAC,CASxB;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAI5E;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,UAAU,EAAE,GAAG,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IACjE,IAAI,EAAE,GAAG,EAAE,CAAC;CACb,CAIA"}
1
+ {"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../src/a2a/card.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,EAEL,SAAS,EAEV,MAAM,aAAa,CAAC;AAKrB,iFAAiF;AACjF,eAAO,MAAM,YAAY,SAAS,CAAC;AAEnC;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG,IAAI,CAC9B,SAAS,EACP,MAAM,GACN,aAAa,GACb,SAAS,GACT,cAAc,GACd,mBAAmB,GACnB,oBAAoB,GACpB,QAAQ,CACX,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpD,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,UAAU,EAAE,GAAG,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,wEAAwE;IACxE,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC;AAUD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,aAAa,EACvB,IAAI,EAAE,gBAAgB,GACrB,SAAS,CA6CX;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,SAAS,EACf,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,aAAa,CAAC,CASxB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,SAAS,EACf,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,SAAS,CAAC,CAGpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAI5E;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,UAAU,EAAE,GAAG,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IACjE,IAAI,EAAE,GAAG,EAAE,CAAC;CACb,CAIA"}
package/dist/a2a/card.js CHANGED
@@ -24,14 +24,26 @@ export function buildBaseCard(manifest, opts) {
24
24
  const rpcPath = opts.rpcPath ?? A2A_RPC_PATH;
25
25
  return {
26
26
  ...manifest,
27
+ capabilities: {
28
+ // `extensions` is required on the proto type but absent from most
29
+ // hand-written manifests, so it is defaulted before the spread rather
30
+ // than after — a manifest that declares extensions keeps them.
31
+ extensions: [],
32
+ ...manifest.capabilities,
33
+ // Forced on, not inherited from the manifest: an agent here is *only*
34
+ // reachable as a tenant, and its card *only* through
35
+ // `GetExtendedAgentCard`. The SDK gates that method on this flag, reading
36
+ // it off whichever card the request handler was built with (spec §3.3.4 —
37
+ // it MUST return `UnsupportedOperationError` when unset), so every card
38
+ // this Worker serves has to carry it, the stub and the tenants alike.
39
+ extendedAgentCard: true
40
+ },
27
41
  supportedInterfaces: [
28
42
  {
29
43
  url: `${opts.origin}${rpcPath}`,
30
44
  protocolBinding: "JSONRPC",
31
45
  protocolVersion: A2A_PROTOCOL_VERSION,
32
- // Single-tenant agent: one DO per verified gateway identity, so the
33
- // protocol-level tenant slot goes unused.
34
- tenant: ""
46
+ tenant: opts.tenant ?? ""
35
47
  }
36
48
  ],
37
49
  provider: undefined,
@@ -82,6 +94,32 @@ export async function signCard(card, cfg) {
82
94
  const signed = await sign(wireCard(card));
83
95
  return signed;
84
96
  }
97
+ /**
98
+ * The same signature, attached to the **in-memory** card instead of the wire
99
+ * one — for a caller that hands the card to something which will encode it
100
+ * itself.
101
+ *
102
+ * That caller is `GetExtendedAgentCard`. The SDK's JSON-RPC transport runs
103
+ * `AgentCard.toJSON()` over whatever the extended-card provider returns, so
104
+ * returning {@link signCard}'s wire card means `toJSON` runs over a document
105
+ * that has already been encoded. For most cards that is a no-op and looks fine
106
+ * — which is the trap. `securitySchemes` is a protobuf *oneof*: encoding it
107
+ * twice collapses `{ gatewayJwt: { httpAuthSecurityScheme: … } }` to
108
+ * `{ gatewayJwt: {} }`, the served document stops matching the one that was
109
+ * signed, and every signature verification fails.
110
+ *
111
+ * So the double encode is latent today only because
112
+ * {@link BuildCardOptions.advertiseSecuritySchemes} defaults to `false`; it
113
+ * would surface the day that flag is flipped, as a signature failure with
114
+ * nothing pointing back here. Returning the in-memory card lets the SDK do the
115
+ * single encode the signature was computed over, and is correct either way.
116
+ *
117
+ * `card.spec.ts` pins both halves.
118
+ */
119
+ export async function signCardInPlace(card, cfg) {
120
+ const signed = await signCard(card, cfg);
121
+ return { ...card, signatures: signed.signatures };
122
+ }
85
123
  /**
86
124
  * The card's protobuf-JSON encoding. Typed back as `AgentCard` for the SDK
87
125
  * signer, which is generic over "the document to canonicalize" rather than over
@@ -1 +1 @@
1
- {"version":3,"file":"card.js","sourceRoot":"","sources":["../../src/a2a/card.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,SAAS,EACT,0BAA0B,EAC3B,MAAM,aAAa,CAAC;AAErB,+EAA+E;AAC/E,MAAM,GAAG,GAAG,OAAO,CAAC;AAEpB,iFAAiF;AACjF,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC;AA0EnC;;;;;GAKG;AACH,MAAM,iBAAiB,GAAG,YAAY,CAAC;AAEvC;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAC3B,QAAuB,EACvB,IAAsB;IAEtB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,YAAY,CAAC;IAC7C,OAAO;QACL,GAAG,QAAQ;QACX,mBAAmB,EAAE;YACnB;gBACE,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE;gBAC/B,eAAe,EAAE,SAAS;gBAC1B,eAAe,EAAE,oBAAoB;gBACrC,oEAAoE;gBACpE,0CAA0C;gBAC1C,MAAM,EAAE,EAAE;aACX;SACF;QACD,QAAQ,EAAE,SAAS;QACnB,gBAAgB,EAAE,SAAS;QAC3B,OAAO,EAAE,SAAS;QAClB,eAAe,EAAE,IAAI,CAAC,wBAAwB;YAC5C,CAAC,CAAC;gBACE,CAAC,iBAAiB,CAAC,EAAE;oBACnB,MAAM,EAAE;wBACN,KAAK,EAAE,wBAAwB;wBAC/B,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE;qBAClE;iBACF;aACF;YACH,CAAC,CAAC,EAAE;QACN,6EAA6E;QAC7E,6EAA6E;QAC7E,6EAA6E;QAC7E,oBAAoB,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;QAC1E,UAAU,EAAE,EAAE;KACf,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAAe,EACf,GAAsB;IAEtB,MAAM,IAAI,GAAG,0BAA0B,CAAC,GAAG,CAAC,UAAU,EAAE;QACtD,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG;QACvB,GAAG,EAAE,MAAM;QACX,GAAG,EAAE,GAAG,CAAC,GAAG;KACb,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1C,OAAO,MAAkC,CAAC;AAC5C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAe;IACtC,OAAO,SAAS,CAAC,MAAM,CAAC,IAAI,CAAc,CAAC;AAC7C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC;IAChD,IAAI,CAAC,GAAG,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACtE,OAAO,GAAsC,CAAC;AAChD,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,UAAiC;IAG9D,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,GAAG,UAAU,CAAC;IACrC,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AACtD,CAAC"}
1
+ {"version":3,"file":"card.js","sourceRoot":"","sources":["../../src/a2a/card.ts"],"names":[],"mappings":"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"}
@@ -5,10 +5,16 @@ import type { GatewayIdentity } from "./verify.js";
5
5
  * stashes the raw headers in the context's state bag, so an executor can reach
6
6
  * them the same way it would under the Express binding.
7
7
  *
8
- * `tenant` is deliberately unset: one agent DO instance *is* the tenant, keyed
9
- * by the verified caller, so there is no second axis to scope on.
8
+ * `tenant` names which agent on this origin the call is for. The SDK's
9
+ * `JsonRpcTransportHandler` would also lift it off `params.tenant` on its own,
10
+ * but only when the context arrives without one — so passing it here is not
11
+ * redundant: this Worker has already parsed, authorized and routed on the
12
+ * tenant before a handler exists to receive the context, and setting it keeps
13
+ * the value the executor and task store see identical to the one that chose
14
+ * them. It is also what reaches the extended-card provider, which the SDK calls
15
+ * with the context alone.
10
16
  */
11
- export declare function buildCallContext(request: Request, identity: GatewayIdentity): ServerCallContext;
17
+ export declare function buildCallContext(request: Request, identity: GatewayIdentity, tenant: string): ServerCallContext;
12
18
  /** Echo back the extensions the handler actually activated (spec §14.2.2). */
13
19
  export declare function extensionHeaders(context: ServerCallContext): HeadersInit;
14
20
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/a2a/context.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,iBAAiB,EAEvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA6BnD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,eAAe,GACxB,iBAAiB,CAYnB;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,WAAW,CAIxE"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/a2a/context.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,iBAAiB,EAEvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA6BnD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,MAAM,GACb,iBAAiB,CAanB;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,WAAW,CAIxE"}
@@ -31,10 +31,16 @@ class GatewayUser {
31
31
  * stashes the raw headers in the context's state bag, so an executor can reach
32
32
  * them the same way it would under the Express binding.
33
33
  *
34
- * `tenant` is deliberately unset: one agent DO instance *is* the tenant, keyed
35
- * by the verified caller, so there is no second axis to scope on.
34
+ * `tenant` names which agent on this origin the call is for. The SDK's
35
+ * `JsonRpcTransportHandler` would also lift it off `params.tenant` on its own,
36
+ * but only when the context arrives without one — so passing it here is not
37
+ * redundant: this Worker has already parsed, authorized and routed on the
38
+ * tenant before a handler exists to receive the context, and setting it keeps
39
+ * the value the executor and task store see identical to the one that chose
40
+ * them. It is also what reaches the extended-card provider, which the SDK calls
41
+ * with the context alone.
36
42
  */
37
- export function buildCallContext(request, identity) {
43
+ export function buildCallContext(request, identity, tenant) {
38
44
  const headers = {};
39
45
  for (const [name, value] of request.headers)
40
46
  headers[name] = value;
@@ -42,7 +48,8 @@ export function buildCallContext(request, identity) {
42
48
  extensions: Extensions.parseServiceParameter(request.headers.get(HTTP_EXTENSION_HEADER) ?? undefined),
43
49
  user: new GatewayUser(identity),
44
50
  headers,
45
- requestedVersion: request.headers.get(A2A_VERSION_HEADER) ?? undefined
51
+ requestedVersion: request.headers.get(A2A_VERSION_HEADER) ?? undefined,
52
+ tenant
46
53
  });
47
54
  }
48
55
  /** Echo back the extensions the handler actually activated (spec §14.2.2). */
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/a2a/context.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,qBAAqB,EACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,+BAA+B,EAIhC,MAAM,oBAAoB,CAAC;AAG5B;;;;;;GAMG;AAEH;;;;;GAKG;AACH,MAAM,WAAW;IACc;IAA7B,YAA6B,QAAyB;QAAzB,aAAQ,GAAR,QAAQ,CAAiB;IAAG,CAAC;IAE1D,IAAI,eAAe;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,QAAQ;QACV,yEAAyE;QACzE,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,EAAE,CAAC;IACjC,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAgB,EAChB,QAAyB;IAEzB,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IAEnE,OAAO,+BAA+B,CAAC;QACrC,UAAU,EAAE,UAAU,CAAC,qBAAqB,CAC1C,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,SAAS,CACxD;QACD,IAAI,EAAE,IAAI,WAAW,CAAC,QAAQ,CAAC;QAC/B,OAAO;QACP,gBAAgB,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,SAAS;KACvE,CAAC,CAAC;AACL,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,gBAAgB,CAAC,OAA0B;IACzD,MAAM,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAC9C,IAAI,CAAC,SAAS,EAAE,MAAM;QAAE,OAAO,EAAE,CAAC;IAClC,OAAO,EAAE,CAAC,qBAAqB,CAAC,EAAE,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC;AAC/E,CAAC"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/a2a/context.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,qBAAqB,EACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,+BAA+B,EAIhC,MAAM,oBAAoB,CAAC;AAG5B;;;;;;GAMG;AAEH;;;;;GAKG;AACH,MAAM,WAAW;IACc;IAA7B,YAA6B,QAAyB;QAAzB,aAAQ,GAAR,QAAQ,CAAiB;IAAG,CAAC;IAE1D,IAAI,eAAe;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,QAAQ;QACV,yEAAyE;QACzE,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,EAAE,CAAC;IACjC,CAAC;CACF;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAgB,EAChB,QAAyB,EACzB,MAAc;IAEd,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IAEnE,OAAO,+BAA+B,CAAC;QACrC,UAAU,EAAE,UAAU,CAAC,qBAAqB,CAC1C,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,SAAS,CACxD;QACD,IAAI,EAAE,IAAI,WAAW,CAAC,QAAQ,CAAC;QAC/B,OAAO;QACP,gBAAgB,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,SAAS;QACtE,MAAM;KACP,CAAC,CAAC;AACL,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,gBAAgB,CAAC,OAA0B;IACzD,MAAM,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAC9C,IAAI,CAAC,SAAS,EAAE,MAAM;QAAE,OAAO,EAAE,CAAC;IAClC,OAAO,EAAE,CAAC,qBAAqB,CAAC,EAAE,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC;AAC/E,CAAC"}
@@ -6,7 +6,7 @@
6
6
  * narrowed task types that survive Durable Object RPC. Nothing here knows what an
7
7
  * agent *does* — past {@link A2AExecutor} everything is plain strings.
8
8
  */
9
- export { IDENTITY_CLAIM, GatewayAuthError, bearerToken, normalizeGatewayOrigins, verifyGatewayToken, type GatewayIdentity, type VerifyOptions } from "./verify.js";
9
+ export { IDENTITY_CLAIM, TENANT_CLAIM, GatewayAuthError, bearerToken, normalizeGatewayOrigins, verifyGatewayToken, type GatewayIdentity, type VerifyOptions } from "./verify.js";
10
10
  export { A2A_RPC_PATH, buildBaseCard, signCard, wireCard, parsePrivateJwk, publicCardJwks, type AgentManifest, type BuildCardOptions, type CardSigningConfig, type WireAgentCard } from "./card.js";
11
11
  export { NOTIFICATION_TOKEN_HEADER, buildSubmittedTask, buildWorkingTask, buildCompletedTask, buildFailedTask, buildNoReplyCompletedTask, signCallbackJwt, postNotification } from "./notify.js";
12
12
  export { taskStateLabel, type PlainArtifact, type PlainMessage, type PlainPart, type PlainStatus, type PlainTask } from "./task.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/a2a/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,uBAAuB,EACvB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,yBAAyB,EACzB,eAAe,EACf,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,SAAS,EACf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,QAAQ,EACR,SAAS,EACT,MAAM,EACN,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAElE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,mBAAmB,EACnB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,WAAW,EACjB,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,aAAa,EACb,SAAS,EACT,YAAY,EACZ,aAAa,EACd,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/a2a/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,uBAAuB,EACvB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,yBAAyB,EACzB,eAAe,EACf,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,SAAS,EACf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,QAAQ,EACR,SAAS,EACT,MAAM,EACN,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAElE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,mBAAmB,EACnB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,WAAW,EACjB,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,aAAa,EACb,SAAS,EACT,YAAY,EACZ,aAAa,EACd,MAAM,iBAAiB,CAAC"}
package/dist/a2a/index.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * narrowed task types that survive Durable Object RPC. Nothing here knows what an
7
7
  * agent *does* — past {@link A2AExecutor} everything is plain strings.
8
8
  */
9
- export { IDENTITY_CLAIM, GatewayAuthError, bearerToken, normalizeGatewayOrigins, verifyGatewayToken } from "./verify.js";
9
+ export { IDENTITY_CLAIM, TENANT_CLAIM, GatewayAuthError, bearerToken, normalizeGatewayOrigins, verifyGatewayToken } from "./verify.js";
10
10
  export { A2A_RPC_PATH, buildBaseCard, signCard, wireCard, parsePrivateJwk, publicCardJwks } from "./card.js";
11
11
  export { NOTIFICATION_TOKEN_HEADER, buildSubmittedTask, buildWorkingTask, buildCompletedTask, buildFailedTask, buildNoReplyCompletedTask, signCallbackJwt, postNotification } from "./notify.js";
12
12
  export { taskStateLabel } from "./task.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/a2a/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,uBAAuB,EACvB,kBAAkB,EAGnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,cAAc,EAKf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,yBAAyB,EACzB,eAAe,EACf,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,EAMf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,QAAQ,EACR,SAAS,EACT,MAAM,EACN,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAElE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,mBAAmB,EAIpB,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/a2a/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,uBAAuB,EACvB,kBAAkB,EAGnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,cAAc,EAKf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,yBAAyB,EACzB,eAAe,EACf,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,EAMf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,QAAQ,EACR,SAAS,EACT,MAAM,EACN,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAElE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,mBAAmB,EAIpB,MAAM,eAAe,CAAC"}
@@ -29,10 +29,19 @@ export declare function buildNoReplyCompletedTask(taskId: string, contextId: str
29
29
  /**
30
30
  * A non-terminal `working` Task snapshot carrying an intermediate content message.
31
31
  * Streamed live from the DO as the tool loop emits content before the final reply.
32
- * `messageId` is derived from `${taskId}:${stepIndex}` — stable across re-runs (see
32
+ *
33
+ * `messageId` is derived from `${taskId}:${key}` — stable across re-runs (see
33
34
  * {@link agentTextMessage}) so the gateway dedupes correctly on workflow replay.
35
+ *
36
+ * `key` is a **semantic** string, not a step counter, and the distinction is
37
+ * load-bearing: an agent that runs several rounds per task emits progress from
38
+ * each, so a bare index makes round 0's third step and round 1's third step the
39
+ * same message to the gateway — it dedupes the second away and the user watches
40
+ * a task go quiet. A caller that genuinely has one flat sequence can pass
41
+ * `String(i)`; one with rounds should key on both (`r1:step:3`), and milestones
42
+ * on what they are (`ack:1`).
34
43
  */
35
- export declare function buildWorkingTask(taskId: string, contextId: string, text: string, stepIndex: number): PlainTask;
44
+ export declare function buildWorkingTask(taskId: string, contextId: string, text: string, key: string): PlainTask;
36
45
  /**
37
46
  * The terminal `completed` Task POSTed to the gateway callback. The `messageId` is
38
47
  * deterministic (`${taskId}:final`, not a fresh UUID) because this is built in the
@@ -1 +1 @@
1
- {"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../src/a2a/notify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,EAAa,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAGnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAqB3C;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,6BAA6B,CAAC;AAqCpE;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,SAAS,CAEX;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,SAAS,CAEX;AAwBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,SAAS,CAQX;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,SAAS,CAQX;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,SAAS,CAQX;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,GAAG,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,EACjC,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACjC,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,QAAQ,CAAC,CAanB"}
1
+ {"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../src/a2a/notify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,EAAa,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAGnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAqB3C;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,6BAA6B,CAAC;AAqCpE;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,SAAS,CAEX;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,SAAS,CAEX;AAwBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACV,SAAS,CAQX;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,SAAS,CAQX;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,SAAS,CAQX;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,GAAG,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,EACjC,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACjC,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,QAAQ,CAAC,CAanB"}
@@ -94,11 +94,20 @@ function buildTaskUpdate(taskId, contextId, state, text, messageId) {
94
94
  /**
95
95
  * A non-terminal `working` Task snapshot carrying an intermediate content message.
96
96
  * Streamed live from the DO as the tool loop emits content before the final reply.
97
- * `messageId` is derived from `${taskId}:${stepIndex}` — stable across re-runs (see
97
+ *
98
+ * `messageId` is derived from `${taskId}:${key}` — stable across re-runs (see
98
99
  * {@link agentTextMessage}) so the gateway dedupes correctly on workflow replay.
100
+ *
101
+ * `key` is a **semantic** string, not a step counter, and the distinction is
102
+ * load-bearing: an agent that runs several rounds per task emits progress from
103
+ * each, so a bare index makes round 0's third step and round 1's third step the
104
+ * same message to the gateway — it dedupes the second away and the user watches
105
+ * a task go quiet. A caller that genuinely has one flat sequence can pass
106
+ * `String(i)`; one with rounds should key on both (`r1:step:3`), and milestones
107
+ * on what they are (`ack:1`).
99
108
  */
100
- export function buildWorkingTask(taskId, contextId, text, stepIndex) {
101
- return buildTaskUpdate(taskId, contextId, TaskState.TASK_STATE_WORKING, text, `${taskId}:${stepIndex}`);
109
+ export function buildWorkingTask(taskId, contextId, text, key) {
110
+ return buildTaskUpdate(taskId, contextId, TaskState.TASK_STATE_WORKING, text, `${taskId}:${key}`);
102
111
  }
103
112
  /**
104
113
  * The terminal `completed` Task POSTed to the gateway callback. The `messageId` is
@@ -1 +1 @@
1
- {"version":3,"file":"notify.js","sourceRoot":"","sources":["../../src/a2a/notify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"notify.js","sourceRoot":"","sources":["../../src/a2a/notify.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,20 @@ import { type JWTPayload } from "jose";
6
6
  * isn't behind looping-gateway; the default is the Looping namespace so an
7
7
  * agent built on this package needs no configuration to interoperate.
8
8
  */
9
- export declare const IDENTITY_CLAIM = "https://looping.ai/identity";
9
+ export declare const IDENTITY_CLAIM = "https://loopingai.org/identity";
10
+ /**
11
+ * Default namespaced claim naming the **tenant** the gateway minted this token
12
+ * for — which of the agents on this origin it authorizes the call to reach.
13
+ *
14
+ * Several agents share one endpoint, so they also share an `aud`: the audience
15
+ * proves the token was minted for *this deployment*, and can say nothing about
16
+ * which agent on it. This claim is the only thing that can, which is why the
17
+ * Worker refuses a token that omits it rather than falling back to a default.
18
+ * Without it `tenant` would be an unauthenticated field in the request body,
19
+ * and a token legitimately issued for one agent could be replayed against any
20
+ * of its siblings.
21
+ */
22
+ export declare const TENANT_CLAIM = "https://loopingai.org/tenant";
10
23
  /**
11
24
  * The gateway-agent instance identity forwarded by the gateway — i.e. which
12
25
  * registered agent instance dispatched this call, not the human end user.
@@ -41,6 +54,8 @@ export interface VerifyOptions {
41
54
  audience: string;
42
55
  /** Claim carrying the caller identity. Defaults to {@link IDENTITY_CLAIM}. */
43
56
  identityClaim?: string;
57
+ /** Claim carrying the authorized tenant. Defaults to {@link TENANT_CLAIM}. */
58
+ tenantClaim?: string;
44
59
  }
45
60
  /**
46
61
  * Normalize configured gateway origins to the HTTPS origins emitted in gateway
@@ -49,16 +64,22 @@ export interface VerifyOptions {
49
64
  */
50
65
  export declare function normalizeGatewayOrigins(origins: string[]): string[];
51
66
  /**
52
- * Verify a gateway JWT and return its payload + parsed identity.
67
+ * Verify a gateway JWT and return its payload, parsed identity and authorized
68
+ * tenant.
53
69
  *
54
70
  * The `jku` JWK Set URL is read directly from the token's protected header
55
71
  * (RFC 7515 §4.1.2) and validated against the allowlist before fetching, so no
56
72
  * separate JWKS URL configuration is needed on the remote side.
57
73
  *
74
+ * `tenant` is returned rather than enforced: this function stays a pure
75
+ * signature/origin question, and only the caller knows which tenant the request
76
+ * actually addressed. {@link createA2AWorker} compares the two.
77
+ *
58
78
  * Throws {@link GatewayAuthError} on any failure.
59
79
  */
60
80
  export declare function verifyGatewayToken(token: string, opts: VerifyOptions): Promise<{
61
81
  payload: JWTPayload;
62
82
  identity: GatewayIdentity;
83
+ tenant: string;
63
84
  }>;
64
85
  //# sourceMappingURL=verify.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/a2a/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,MAAM,CAAC;AAyBd;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,gCAAgC,CAAC;AAE5D;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B,yDAAyD;IACzD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,oEAAoE;AACpE,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAcD,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAI3D;AAED,MAAM,WAAW,aAAa;IAC5B,iFAAiF;IACjF,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAenE;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,eAAe,CAAA;CAAE,CAAC,CAyC7D"}
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/a2a/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,MAAM,CAAC;AAyBd;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,mCAAmC,CAAC;AAE/D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,iCAAiC,CAAC;AAE3D;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B,yDAAyD;IACzD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,oEAAoE;AACpE,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAcD,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAI3D;AAED,MAAM,WAAW,aAAa;IAC5B,iFAAiF;IACjF,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAenE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC;IACT,OAAO,EAAE,UAAU,CAAC;IACpB,QAAQ,EAAE,eAAe,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CA8CD"}
@@ -27,7 +27,20 @@ const ALG = "EdDSA";
27
27
  * isn't behind looping-gateway; the default is the Looping namespace so an
28
28
  * agent built on this package needs no configuration to interoperate.
29
29
  */
30
- export const IDENTITY_CLAIM = "https://looping.ai/identity";
30
+ export const IDENTITY_CLAIM = "https://loopingai.org/identity";
31
+ /**
32
+ * Default namespaced claim naming the **tenant** the gateway minted this token
33
+ * for — which of the agents on this origin it authorizes the call to reach.
34
+ *
35
+ * Several agents share one endpoint, so they also share an `aud`: the audience
36
+ * proves the token was minted for *this deployment*, and can say nothing about
37
+ * which agent on it. This claim is the only thing that can, which is why the
38
+ * Worker refuses a token that omits it rather than falling back to a default.
39
+ * Without it `tenant` would be an unauthenticated field in the request body,
40
+ * and a token legitimately issued for one agent could be replayed against any
41
+ * of its siblings.
42
+ */
43
+ export const TENANT_CLAIM = "https://loopingai.org/tenant";
31
44
  /** Thrown when a gateway token is missing or fails verification. */
32
45
  export class GatewayAuthError extends Error {
33
46
  constructor(message) {
@@ -73,12 +86,17 @@ export function normalizeGatewayOrigins(origins) {
73
86
  });
74
87
  }
75
88
  /**
76
- * Verify a gateway JWT and return its payload + parsed identity.
89
+ * Verify a gateway JWT and return its payload, parsed identity and authorized
90
+ * tenant.
77
91
  *
78
92
  * The `jku` JWK Set URL is read directly from the token's protected header
79
93
  * (RFC 7515 §4.1.2) and validated against the allowlist before fetching, so no
80
94
  * separate JWKS URL configuration is needed on the remote side.
81
95
  *
96
+ * `tenant` is returned rather than enforced: this function stays a pure
97
+ * signature/origin question, and only the caller knows which tenant the request
98
+ * actually addressed. {@link createA2AWorker} compares the two.
99
+ *
82
100
  * Throws {@link GatewayAuthError} on any failure.
83
101
  */
84
102
  export async function verifyGatewayToken(token, opts) {
@@ -111,7 +129,12 @@ export async function verifyGatewayToken(token, opts) {
111
129
  });
112
130
  const claim = opts.identityClaim ?? IDENTITY_CLAIM;
113
131
  const identity = payload[claim] ?? {};
114
- return { payload, identity };
132
+ const tenant = payload[opts.tenantClaim ?? TENANT_CLAIM];
133
+ return {
134
+ payload,
135
+ identity,
136
+ tenant: typeof tenant === "string" ? tenant : ""
137
+ };
115
138
  }
116
139
  catch (err) {
117
140
  if (err instanceof GatewayAuthError)
@@ -1 +1 @@
1
- {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/a2a/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,SAAS,EACT,qBAAqB,EACrB,SAAS,EAEV,MAAM,MAAM,CAAC;AAEd;;;;;;;;;;;;;;;;;;GAkBG;AAEH,+DAA+D;AAC/D,MAAM,GAAG,GAAG,OAAO,CAAC;AAEpB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,6BAA6B,CAAC;AAyB5D,oEAAoE;AACpE,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED,8EAA8E;AAC9E,oDAAoD;AACpD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAiD,CAAC;AAC3E,SAAS,OAAO,CAAC,GAAW;IAC1B,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,GAAG,GAAG,kBAAkB,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACvC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;IAC1D,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACrD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAUD;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAiB;IACvD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,gBAAgB,CAAC,wCAAwC,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,CAAC;YACH,OAAO,IAAI,GAAG,CAAC,WAAW,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;QAC3E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,MAAM,IAAI,gBAAgB,CACxB,mCAAmC,MAAM,MAAM,OAAO,EAAE,CACzD,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAa,EACb,IAAmB;IAEnB,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,uBAAuB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACpE,uEAAuE;QACvE,sEAAsE;QACtE,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,CAAqB,CAAC;QAChE,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,gBAAgB,CACxB,kDAAkD,CACnD,CAAC;QACJ,CAAC;QACD,qEAAqE;QACrE,oEAAoE;QACpE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QACtC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,gBAAgB,CACxB,eAAe,SAAS,yCAAyC,CAClE,CAAC;QACJ,CAAC;QACD,0EAA0E;QAC1E,gEAAgE;QAChE,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;QAC1C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;QACzC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,IAAI,gBAAgB,CACxB,eAAe,SAAS,gCAAgC,SAAS,GAAG,CACrE,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE;YACvD,MAAM,EAAE,cAAc;YACtB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,UAAU,EAAE,CAAC,GAAG,CAAC;SAClB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,IAAI,cAAc,CAAC;QACnD,MAAM,QAAQ,GAAI,OAAO,CAAC,KAAK,CAAiC,IAAI,EAAE,CAAC;QACvE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,gBAAgB;YAAE,MAAM,GAAG,CAAC;QAC/C,MAAM,IAAI,gBAAgB,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;IACrD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/a2a/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,SAAS,EACT,qBAAqB,EACrB,SAAS,EAEV,MAAM,MAAM,CAAC;AAEd;;;;;;;;;;;;;;;;;;GAkBG;AAEH,+DAA+D;AAC/D,MAAM,GAAG,GAAG,OAAO,CAAC;AAEpB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,gCAAgC,CAAC;AAE/D;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,8BAA8B,CAAC;AAyB3D,oEAAoE;AACpE,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED,8EAA8E;AAC9E,oDAAoD;AACpD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAiD,CAAC;AAC3E,SAAS,OAAO,CAAC,GAAW;IAC1B,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,GAAG,GAAG,kBAAkB,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACvC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;IAC1D,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACrD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAYD;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAiB;IACvD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,gBAAgB,CAAC,wCAAwC,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,CAAC;YACH,OAAO,IAAI,GAAG,CAAC,WAAW,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;QAC3E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,MAAM,IAAI,gBAAgB,CACxB,mCAAmC,MAAM,MAAM,OAAO,EAAE,CACzD,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAa,EACb,IAAmB;IAMnB,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,uBAAuB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACpE,uEAAuE;QACvE,sEAAsE;QACtE,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,CAAqB,CAAC;QAChE,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,gBAAgB,CACxB,kDAAkD,CACnD,CAAC;QACJ,CAAC;QACD,qEAAqE;QACrE,oEAAoE;QACpE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QACtC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,gBAAgB,CACxB,eAAe,SAAS,yCAAyC,CAClE,CAAC;QACJ,CAAC;QACD,0EAA0E;QAC1E,gEAAgE;QAChE,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;QAC1C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;QACzC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,IAAI,gBAAgB,CACxB,eAAe,SAAS,gCAAgC,SAAS,GAAG,CACrE,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE;YACvD,MAAM,EAAE,cAAc;YACtB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,UAAU,EAAE,CAAC,GAAG,CAAC;SAClB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,IAAI,cAAc,CAAC;QACnD,MAAM,QAAQ,GAAI,OAAO,CAAC,KAAK,CAAiC,IAAI,EAAE,CAAC;QACvE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,IAAI,YAAY,CAAC,CAAC;QACzD,OAAO;YACL,OAAO;YACP,QAAQ;YACR,MAAM,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;SACjD,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,gBAAgB;YAAE,MAAM,GAAG,CAAC;QAC/C,MAAM,IAAI,gBAAgB,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;IACrD,CAAC;AACH,CAAC"}