@agent-native/core 0.101.10 → 0.101.11
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +6 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/client.ts +23 -1
- package/corpus/core/src/a2a/handlers.ts +65 -1
- package/corpus/core/src/a2a/server.ts +124 -0
- package/corpus/core/src/a2a/task-store.ts +253 -0
- package/corpus/core/src/a2a/types.ts +26 -0
- package/corpus/core/src/agent/production-agent.ts +5 -2
- package/corpus/core/src/mcp/builtin-tools.ts +25 -1
- package/corpus/core/src/scripts/call-agent.ts +22 -3
- package/corpus/core/src/server/agent-chat-plugin.ts +86 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +25 -0
- package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +23 -0
- package/corpus/templates/content/app/components/editor/MathRenderer.tsx +43 -0
- package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +260 -4
- package/corpus/templates/content/app/components/editor/extensions/NotionExtensions.tsx +78 -0
- package/corpus/templates/content/app/global.css +53 -0
- package/corpus/templates/content/app/i18n/zh-TW.ts +13 -0
- package/corpus/templates/content/app/i18n-data.ts +163 -0
- package/corpus/templates/content/app/root.tsx +2 -0
- package/corpus/templates/content/changelog/2026-07-14-latex-equations-render-in-documents-public-pages-and-exports.md +6 -0
- package/corpus/templates/content/package.json +1 -0
- package/corpus/templates/content/shared/document-export.ts +296 -25
- package/corpus/templates/content/shared/inline-math.ts +128 -0
- package/corpus/templates/content/shared/math-rendering.ts +50 -0
- package/corpus/templates/content/shared/nfm.ts +17 -14
- package/corpus/templates/content/vite.config.ts +0 -1
- package/corpus/templates/mail/.agents/skills/email-drafts/SKILL.md +17 -0
- package/corpus/templates/mail/AGENTS.md +21 -19
- package/corpus/templates/mail/actions/create-attachment-upload.ts +49 -0
- package/corpus/templates/mail/changelog/2026-07-14-connected-agents-can-now-securely-upload-local-files-for-mai.md +6 -0
- package/corpus/templates/mail/server/handlers/media.ts +84 -61
- package/corpus/templates/mail/server/lib/attachment-upload-ticket.ts +234 -0
- package/corpus/templates/mail/server/lib/mail-connector-catalog.ts +8 -4
- package/corpus/templates/mail/server/lib/media-upload.ts +114 -0
- package/corpus/templates/mail/server/plugins/auth.ts +9 -1
- package/corpus/templates/mail/server/routes/api/media/attachment-upload/[uploadId].put.ts +1 -0
- package/dist/a2a/client.d.ts +5 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +18 -1
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +57 -8
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +87 -1
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/task-store.d.ts +27 -0
- package/dist/a2a/task-store.d.ts.map +1 -1
- package/dist/a2a/task-store.js +216 -0
- package/dist/a2a/task-store.js.map +1 -1
- package/dist/a2a/types.d.ts +24 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/agent/production-agent.d.ts +1 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +5 -2
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/mcp/builtin-tools.d.ts.map +1 -1
- package/dist/mcp/builtin-tools.js +22 -3
- package/dist/mcp/builtin-tools.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +5 -5
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/scripts/call-agent.d.ts +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +19 -1
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +71 -2
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +25 -0
- package/package.json +1 -1
- package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +25 -0
package/dist/a2a/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAS5D,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACnC,MAAM,CAAS;IACf,QAAQ,CAAO;IACf,SAAS,CAAS;IAClB,SAAS,CAAS;IAE3B,YAAY,MAAc,EAAE,QAAc,EAAE,SAAiB;QAC3D,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC;QACxC,KAAK,CACH,YAAY,MAAM,4BAA4B,SAAS,mBAAmB,SAAS,GAAG,CACvF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAa,EACb,SAAkB,EAClB,SAAkB,EAClB,OAWC;IAED,MAAM,MAAM,GAAG,OAAO,EAAE,kBAAkB;QACxC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,SAAS;QACrC,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;IACxC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,yEAAyE;YACvE,wFAAwF,CAC3F,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GACV,OAAO,CAAC,GAAG,CAAC,OAAO;QACnB,OAAO,CAAC,GAAG,CAAC,eAAe;QAC3B,uBAAuB,CAAC;IAE1B,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC;QAC3B,GAAG,CAAC,OAAO,EAAE,WAAW,IAAI,EAAE,CAAC;QAC/B,yEAAyE;QACzE,uDAAuD;QACvD,GAAG,EAAE,KAAK;QACV,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAC;SACC,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;SACpC,SAAS,CAAC,MAAM,CAAC;SACjB,WAAW,EAAE;SACb,iBAAiB,CAAC,OAAO,EAAE,SAAS,IAAI,KAAK,CAAC,CAAC;IAElD,IAAI,OAAO,EAAE,QAAQ;QAAE,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEzD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,SAAkB;IAC5D,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;AACxD,CAAC;AAED,MAAM,OAAO,SAAS;IACZ,OAAO,CAAS;IAChB,MAAM,CAAU;IAChB,cAAc,CAA4B;IAC1C,kBAAkB,GAAa,EAAE,CAAC;IAClC,gBAAgB,GAAG,KAAK,CAAC;IACzB,gBAAgB,CAAU;IAElC,YACE,OAAe,EACf,MAAe,EACf,OAAmE;QAEnE,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC9C,MAAM,gBAAgB,GAAG,wBAAwB,CAAC,UAAU,CAAC,CAAC;QAC9D,IAAI,CAAC,OAAO,GAAG,gBAAgB,EAAE,OAAO,IAAI,UAAU,CAAC;QACvD,IAAI,gBAAgB,EAAE,CAAC;YACrB,IAAI,CAAC,kBAAkB,GAAG,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;YACzD,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,cAAc,GAAG,gBAAgB,CAAC;YACrC,MAAM;YACN,GAAG,CAAC,OAAO,EAAE,eAAe,IAAI,EAAE,CAAC;SACpC,CAAC,CAAC;QACH,IAAI,CAAC,gBAAgB,GAAG,OAAO,EAAE,gBAAgB,CAAC;IACpD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe;QACnB,MAAM,IAAI,CAAC,wBAAwB,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,kBAAkB,CAAC,MAAM,IAAI,CAAC;YAAE,OAAO;QAEhD,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC/C,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,aAAa,CAC7B,QAAQ,EACR,EAAE,MAAM,EAAE,SAAS,EAAE,EACrB,EAAE,YAAY,EAAE,CAAC,EAAE,CACpB,CAAC;gBACF,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC7C,IAAI,CAAC,kBAAkB,GAAG,CAAC,QAAQ,CAAC,CAAC;oBACrC,OAAO;gBACT,CAAC;gBACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBACvB,IAAI,CAAC,kBAAkB,GAAG,CAAC,QAAQ,CAAC,CAAC;oBACrC,OAAO;gBACT,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,0BAA0B;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;IAEO,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM;QAClC,MAAM,CAAC,GAA2B,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;QACzE,IAAI,MAAM,EAAE,CAAC;YACX,CAAC,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,EAAE,CAAC;QAC1C,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAEO,mBAAmB,CAAC,MAA0B;QACpD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,cAAc,GAAG,gBAAgB,CAAC;YACrC,MAAM;YACN,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,MAAM,CAAC;SAC3D,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,GAAG,CACf,MAAc,EACd,MAA+B;QAE/B,MAAM,IAAI,GAAmB;YAC3B,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;YACd,MAAM;YACN,MAAM;SACP,CAAC;QAEF,MAAM,IAAI,CAAC,wBAAwB,EAAE,CAAC;QACtC,IAAI,SAAS,GAAiB,IAAI,CAAC;QAEnC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpD,OAAO,CAAC,GAAG,CAAC,qBAAqB,GAAG,WAAW,MAAM,EAAE,CAAC,CAAC;gBACzD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC7B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnE,OAAO,CAAC,GAAG,CACT,0BAA0B,GAAG,CAAC,MAAM,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,CACtE,CAAC;gBAEF,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;oBACX,IAAI,CAAC,kBAAkB,GAAG,CAAC,GAAG,CAAC,CAAC;oBAChC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;oBACjD,OAAO,GAAG,CAAC,IAAI,EAA8B,CAAC;gBAChD,CAAC;gBAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;gBAC9B,SAAS,GAAG,IAAI,KAAK,CAAC,uBAAuB,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;gBACrE,IACE,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;oBAClC,0BAA0B,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,EAC5C,CAAC;oBACD,SAAS;gBACX,CAAC;gBACD,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;oBACvC,MAAM,SAAS,CAAC;gBAClB,CAAC;gBACD,MAAM;YACR,CAAC;QACH,CAAC;QAED,MAAM,SAAS,IAAI,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,GAAG,GAAG,MAAM,aAAa,CAC7B,GAAG,IAAI,CAAC,OAAO,8BAA8B,EAC7C,EAAE,EACF,EAAE,YAAY,EAAE,CAAC,EAAE,CACpB,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,EAAwB,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,IAAI,CACR,OAAgB,EAChB,IAYC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE;YAC9C,OAAO;YACP,SAAS,EAAE,IAAI,EAAE,SAAS;YAC1B,QAAQ,EAAE,IAAI,EAAE,QAAQ;YACxB,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxC,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,cAAc,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,CAChE,CAAC;QACJ,CAAC;QAED,OAAO,QAAQ,CAAC,MAAc,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,MAAc;QAC1B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7D,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,cAAc,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,CAChE,CAAC;QACJ,CAAC;QACD,OAAO,QAAQ,CAAC,MAAc,CAAC;IACjC,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,WAAW,CACf,OAAgB,EAChB,IASC;QAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACzC,SAAS,EAAE,IAAI,EAAE,SAAS;YAC1B,QAAQ,EAAE,IAAI,EAAE,QAAQ;YACxB,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;QACpE,IAAI,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAEjE,MAAM,SAAS,GAAG,IAAI,EAAE,SAAS,IAAI,CAAC,GAAG,MAAM,CAAC;QAChD,MAAM,MAAM,GAAG,IAAI,EAAE,cAAc,IAAI,KAAK,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAExC,IAAI,OAAO,GAAG,SAAS,CAAC;QACxB,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;YAC7B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;YAChD,IAAI,CAAC;gBACH,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBAC3C,IAAI,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,6DAA6D;gBAC7D,SAAS;YACX,CAAC;YACD,IAAI,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;gBAAE,OAAO,OAAO,CAAC;QAC/D,CAAC;QACD,MAAM,IAAI,mBAAmB,CAAC,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAClE,CAAC;IAED,KAAK,CAAC,CAAC,MAAM,CACX,OAAgB,EAChB,IAAiE;QAEjE,MAAM,IAAI,GAAmB;YAC3B,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;YACd,MAAM,EAAE,gBAAgB;YACxB,MAAM,EAAE;gBACN,OAAO;gBACP,SAAS,EAAE,IAAI,EAAE,SAAS;gBAC1B,QAAQ,EAAE,IAAI,EAAE,QAAQ;aACzB;SACF,CAAC;QAEF,MAAM,IAAI,CAAC,wBAAwB,EAAE,CAAC;QACtC,IAAI,GAAG,GAAoB,IAAI,CAAC;QAChC,IAAI,SAAS,GAAiB,IAAI,CAAC;QACnC,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAChD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpD,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnE,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;oBACX,IAAI,CAAC,kBAAkB,GAAG,CAAC,SAAS,CAAC,CAAC;oBACtC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;oBACjD,MAAM;gBACR,CAAC;gBACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;gBAC9B,SAAS,GAAG,IAAI,KAAK,CAAC,sBAAsB,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;gBACpE,IACE,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;oBAClC,0BAA0B,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,EAC5C,CAAC;oBACD,SAAS;gBACX,CAAC;gBACD,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC;oBAAE,MAAM,SAAS,CAAC;gBACxD,MAAM;YACR,CAAC;YACD,IAAI,GAAG,EAAE,EAAE;gBAAE,MAAM;QACrB,CAAC;QACD,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC;YACb,MAAM,SAAS,IAAI,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACvE,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;QACrC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAEjD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,IAAI;gBAAE,MAAM;YAEhB,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACjC,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;YAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;oBAAE,SAAS;gBACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAClC,IAAI,CAAC,IAAI;oBAAE,SAAS;gBAEpB,MAAM,QAAQ,GAAoB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACnD,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;oBACnB,MAAM,IAAI,KAAK,CACb,cAAc,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,CAChE,CAAC;gBACJ,CAAC;gBACD,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;oBACpB,MAAM,QAAQ,CAAC,MAAc,CAAC;gBAChC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,wBAAwB;QACpC,IAAI,IAAI,CAAC,gBAAgB;YAAE,OAAO;QAClC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAE7B,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,4BAA4B,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAEvD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YACrD,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,gBAAgB,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;gBAC3D,IAAI,gBAAgB,EAAE,CAAC;oBACrB,UAAU,CAAC,OAAO,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;gBACnD,CAAC;qBAAM,CAAC;oBACN,4BAA4B,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBACpD,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,wEAAwE;QAC1E,CAAC;QAED,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC;IAEO,KAAK,CAAC,QAAQ,CACpB,GAAW,EACX,IAAoB,EACpB,MAAM,GAAG,IAAI,CAAC,MAAM;QAEpB,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB;YACtC,CAAC,CAAC,IAAI,eAAe,EAAE;YACvB,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,KAAK,GACT,UAAU,IAAI,IAAI,CAAC,gBAAgB;YACjC,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,gBAAgB,CAAC;YAC7D,CAAC,CAAC,SAAS,CAAC;QAChB,IAAI,CAAC;YACH,OAAO,MAAM,aAAa,CACxB,GAAG,EACH;gBACE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;gBAC7B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC1B,MAAM,EAAE,UAAU,EAAE,MAAM;aAC3B,EACD,EAAE,YAAY,EAAE,CAAC,EAAE,CACpB,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,IAAI,KAAK;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;CACF;AAED,SAAS,wBAAwB,CAC/B,GAAW;IAEX,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACpD,IAAI,QAAQ,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAC5C,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,oBAAoB,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;YACzE,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;YACnB,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;YACjB,OAAO;gBACL,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;gBAC7C,WAAW,EAAE,GAAG;aACjB,CAAC;QACJ,CAAC;QACD,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;YAC3D,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;YACnB,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;YACjB,OAAO;gBACL,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;gBAC7C,WAAW,EAAE,GAAG;aACjB,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0EAA0E;IAC5E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,4BAA4B,CAAC,UAAoB,EAAE,OAAe;IACzE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACxC,UAAU,CAAC,IAAI,CAAC,GAAG,IAAI,oBAAoB,EAAE,GAAG,IAAI,MAAM,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,YAAY,CACnB,KAAyB,EACzB,OAAe;IAEf,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,KAAK,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC;aACpD,QAAQ,EAAE;aACV,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAc;IAC3C,OAAO,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,CAAC;AAC1C,CAAC;AAED,SAAS,MAAM,CAAC,MAAgB;IAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,gBAAgB,CACvB,MAAiC;IAEjC,MAAM,MAAM,GAA8B,EAAE,CAAC;IAC7C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAS;QACrC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAChD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,0BAA0B,CAAC,MAAc,EAAE,IAAY;IAC9D,OAAO,CACL,MAAM,KAAK,GAAG;QACd,sKAAsK,CAAC,IAAI,CACzK,IAAI,CACL,CACF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,GAAW,EACX,IAAY,EACZ,IAkCC;IAED,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAC7C,IAAI,IAAI,EAAE,SAAS;QAAE,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IACzD,IAAI,IAAI,EAAE,SAAS;QAAE,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IACzD,IAAI,IAAI,EAAE,aAAa;QAAE,QAAQ,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;IAErE,4EAA4E;IAC5E,uEAAuE;IACvE,wEAAwE;IACxE,oEAAoE;IACpE,uEAAuE;IACvE,MAAM,QAAQ,GAAG,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC;IACrC,MAAM,OAAO,GAAY;QACvB,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;KAChC,CAAC;IAEF,MAAM,cAAc,GAAG,MAAM,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAC1D,IAAI,aAAsB,CAAC;IAE3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,IAAI,CAAC;YACH,MAAM,eAAe,GAAG,cAAc;iBACnC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;iBACZ,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;YAC3D,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE;gBACnD,eAAe;aAChB,CAAC,CAAC;YACH,IAAI,IAAU,CAAC;YACf,IAAI,QAAQ,EAAE,CAAC;gBACb,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE;oBACvC,SAAS,EAAE,IAAI,EAAE,SAAS;oBAC1B,QAAQ;oBACR,SAAS,EAAE,IAAI,EAAE,SAAS;oBAC1B,cAAc,EAAE,IAAI,EAAE,cAAc;oBACpC,QAAQ,EAAE,IAAI,EAAE,QAAQ;iBACzB,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE;oBAChC,SAAS,EAAE,IAAI,EAAE,SAAS;oBAC1B,QAAQ;iBACT,CAAC,CAAC;YACL,CAAC;YAED,iCAAiC;YACjC,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;YAC5C,IAAI,eAAe,EAAE,CAAC;gBACpB,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK;qBACpC,MAAM,CAAC,CAAC,CAAC,EAAuC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;qBACrE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBACtB,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;YAED,OAAO,EAAE,CAAC;QACZ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IACE,IAAI,EAAE,mCAAmC,KAAK,KAAK;gBACnD,GAAG,YAAY,mBAAmB,EAClC,CAAC;gBACD,MAAM,eAAe,GAAG,8BAA8B,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBACrE,IAAI,eAAe;oBAAE,OAAO,eAAe,CAAC;YAC9C,CAAC;YACD,IAAI,CAAC,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7D,aAAa,GAAG,GAAG,CAAC;gBACpB,SAAS;YACX,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,IAAI,aAAa;QAAE,MAAM,aAAa,CAAC;IACvC,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,IAKrC;IACC,MAAM,QAAQ,GAA8B,EAAE,CAAC;IAC/C,MAAM,GAAG,GAAG,CAAC,KAAyB,EAAE,EAAE;QACxC,IAAI,KAAK,KAAK,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO;QAC5D,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC,CAAC;IAEF,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAElB,IAAI,IAAI,EAAE,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QAClE,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,CAAC;YACnC,IAAI,CAAC;gBACH,GAAG,CACD,MAAM,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE;oBACjE,kBAAkB,EAAE,IAAI;iBACzB,CAAC,CACH,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,yDAAyD;YAC3D,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,IAAI,CAAC;gBACH,GAAG,CACD,MAAM,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE;oBACjE,kBAAkB,EAAE,KAAK;iBAC1B,CAAC,CACH,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,gDAAgD;YAClD,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACpD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAY;IACtC,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IACvE,OAAO,iMAAiM,CAAC,IAAI,CAC3M,OAAO,CACR,CAAC;AACJ,CAAC;AAED,SAAS,8BAA8B,CAAC,IAAU;IAChD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,+BAA+B,EAAE,CAAC;QACpE,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAgB;IAC1C,OAAO,OAAO,CAAC,KAAK;SACjB,MAAM,CAAC,CAAC,CAAC,EAAuC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;SACrE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAClB,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC","sourcesContent":["import * as jose from \"jose\";\n\nimport { ssrfSafeFetch } from \"../extensions/url-safety.js\";\nimport type {\n AgentCard,\n JsonRpcRequest,\n JsonRpcResponse,\n Message,\n Task,\n} from \"./types.js\";\n\nexport class A2ATaskTimeoutError extends Error {\n readonly taskId: string;\n readonly lastTask: Task;\n readonly lastState: string;\n readonly timeoutMs: number;\n\n constructor(taskId: string, lastTask: Task, timeoutMs: number) {\n const lastState = lastTask.status.state;\n super(\n `A2A task ${taskId} did not complete within ${timeoutMs}ms (last state: ${lastState})`,\n );\n this.name = \"A2ATaskTimeoutError\";\n this.taskId = taskId;\n this.lastTask = lastTask;\n this.lastState = lastState;\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Sign a JWT for A2A cross-app identity verification.\n *\n * Uses an org-level secret by default for direct org-secret workflows. Callers\n * that are doing ordinary hosted cross-app delegation can set\n * `preferGlobalSecret` so deployments with a shared A2A_SECRET don't depend on\n * every app database having an identical org row. The token contains the\n * caller's email as `sub`, so the receiving app can verify who's calling.\n */\nexport async function signA2AToken(\n email: string,\n orgDomain?: string,\n orgSecret?: string,\n options?: {\n expiresIn?: string | number;\n preferGlobalSecret?: boolean;\n audience?: string | string[];\n /**\n * Extra JWT claims to merge alongside `sub` / `org_domain`. Used by the\n * MCP connect flow to add a revocable `jti` and a `scope: \"mcp-connect\"`\n * marker. Reserved claims (`sub`, `org_domain`) cannot be overridden —\n * they are spread last so a caller can never spoof identity via this map.\n */\n extraClaims?: Record<string, unknown>;\n },\n): Promise<string> {\n const secret = options?.preferGlobalSecret\n ? process.env.A2A_SECRET || orgSecret\n : orgSecret || process.env.A2A_SECRET;\n if (!secret) {\n throw new Error(\n \"No A2A secret available. Set an org-level A2A secret in Team settings, \" +\n \"or set A2A_SECRET as an environment variable on all apps that need to verify identity.\",\n );\n }\n\n const appUrl =\n process.env.APP_URL ||\n process.env.BETTER_AUTH_URL ||\n \"http://localhost:3000\";\n\n const jwt = new jose.SignJWT({\n ...(options?.extraClaims ?? {}),\n // `sub` / `org_domain` are spread AFTER extraClaims so a caller-supplied\n // map can never override the verified identity claims.\n sub: email,\n ...(orgDomain ? { org_domain: orgDomain } : {}),\n })\n .setProtectedHeader({ alg: \"HS256\" })\n .setIssuer(appUrl)\n .setIssuedAt()\n .setExpirationTime(options?.expiresIn ?? \"15m\");\n\n if (options?.audience) jwt.setAudience(options.audience);\n\n return jwt.sign(new TextEncoder().encode(secret));\n}\n\nexport function shouldPreferGlobalA2ASecret(orgSecret?: string): boolean {\n return !!process.env.A2A_SECRET?.trim() || !orgSecret;\n}\n\nexport class A2AClient {\n private baseUrl: string;\n private apiKey?: string;\n private apiKeyAttempts: Array<string | undefined>;\n private endpointCandidates: string[] = [];\n private endpointResolved = false;\n private requestTimeoutMs?: number;\n\n constructor(\n baseUrl: string,\n apiKey?: string,\n options?: { requestTimeoutMs?: number; fallbackApiKeys?: string[] },\n ) {\n const normalized = baseUrl.replace(/\\/$/, \"\");\n const explicitEndpoint = splitExplicitA2AEndpoint(normalized);\n this.baseUrl = explicitEndpoint?.baseUrl ?? normalized;\n if (explicitEndpoint) {\n this.endpointCandidates = [explicitEndpoint.endpointUrl];\n this.endpointResolved = true;\n }\n this.apiKey = apiKey;\n this.apiKeyAttempts = uniqueAuthTokens([\n apiKey,\n ...(options?.fallbackApiKeys ?? []),\n ]);\n this.requestTimeoutMs = options?.requestTimeoutMs;\n }\n\n /**\n * Detect which A2A path the target agent uses.\n * Agent-native apps use /_agent-native/a2a, external agents may use /a2a.\n */\n async resolveEndpoint(): Promise<void> {\n await this.ensureEndpointCandidates();\n if (this.endpointCandidates.length <= 1) return;\n\n for (const endpoint of this.endpointCandidates) {\n try {\n const res = await ssrfSafeFetch(\n endpoint,\n { method: \"OPTIONS\" },\n { maxRedirects: 3 },\n );\n if (res.status !== 404 && res.status !== 405) {\n this.endpointCandidates = [endpoint];\n return;\n }\n if (res.status === 405) {\n this.endpointCandidates = [endpoint];\n return;\n }\n } catch {\n // Try the next candidate.\n }\n }\n }\n\n private headers(apiKey = this.apiKey): Record<string, string> {\n const h: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (apiKey) {\n h[\"Authorization\"] = `Bearer ${apiKey}`;\n }\n return h;\n }\n\n private markApiKeySucceeded(apiKey: string | undefined) {\n this.apiKey = apiKey;\n this.apiKeyAttempts = uniqueAuthTokens([\n apiKey,\n ...this.apiKeyAttempts.filter((token) => token !== apiKey),\n ]);\n }\n\n private async rpc(\n method: string,\n params: Record<string, unknown>,\n ): Promise<JsonRpcResponse> {\n const body: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id: Date.now(),\n method,\n params,\n };\n\n await this.ensureEndpointCandidates();\n let lastError: Error | null = null;\n\n for (const url of this.endpointCandidates) {\n for (let i = 0; i < this.apiKeyAttempts.length; i++) {\n console.log(`[A2A Client] POST ${url} method=${method}`);\n const startTime = Date.now();\n const res = await this.postJson(url, body, this.apiKeyAttempts[i]);\n console.log(\n `[A2A Client] Response: ${res.status} in ${Date.now() - startTime}ms`,\n );\n\n if (res.ok) {\n this.endpointCandidates = [url];\n this.markApiKeySucceeded(this.apiKeyAttempts[i]);\n return res.json() as Promise<JsonRpcResponse>;\n }\n\n const text = await res.text();\n lastError = new Error(`A2A request failed (${res.status}): ${text}`);\n if (\n i < this.apiKeyAttempts.length - 1 &&\n isA2AAuthRejectionResponse(res.status, text)\n ) {\n continue;\n }\n if (!shouldTryNextEndpoint(res.status)) {\n throw lastError;\n }\n break;\n }\n }\n\n throw lastError ?? new Error(\"No A2A endpoint candidates available\");\n }\n\n async getAgentCard(): Promise<AgentCard> {\n const res = await ssrfSafeFetch(\n `${this.baseUrl}/.well-known/agent-card.json`,\n {},\n { maxRedirects: 3 },\n );\n if (!res.ok) {\n throw new Error(`Failed to fetch agent card (${res.status})`);\n }\n return res.json() as Promise<AgentCard>;\n }\n\n async send(\n message: Message,\n opts?: {\n contextId?: string;\n metadata?: Record<string, unknown>;\n /**\n * If true, ask the server to return the task immediately in `working`\n * state and process the handler in the background. The caller should\n * then poll `getTask(taskId)` until `completed` / `failed` / `canceled`.\n *\n * Use this when you expect the handler may exceed a synchronous\n * serverless request budget.\n */\n async?: boolean;\n },\n ): Promise<Task> {\n const response = await this.rpc(\"message/send\", {\n message,\n contextId: opts?.contextId,\n metadata: opts?.metadata,\n ...(opts?.async ? { async: true } : {}),\n });\n\n if (response.error) {\n throw new Error(\n `A2A error (${response.error.code}): ${response.error.message}`,\n );\n }\n\n return response.result as Task;\n }\n\n /**\n * Poll for a task by id. Used in async mode after `send({ async: true })`.\n */\n async getTask(taskId: string): Promise<Task> {\n const response = await this.rpc(\"tasks/get\", { id: taskId });\n if (response.error) {\n throw new Error(\n `A2A error (${response.error.code}): ${response.error.message}`,\n );\n }\n return response.result as Task;\n }\n\n /**\n * Send a message in async mode and poll until the task reaches a terminal\n * state. This is the recommended path on serverless hosts with short\n * function timeouts (Netlify, Vercel) where a synchronous LLM-driven A2A\n * call can exceed the gateway limit.\n *\n * Each individual fetch returns quickly; long-running work happens on the\n * receiving side and is checked via `tasks/get`.\n */\n async sendAndWait(\n message: Message,\n opts?: {\n contextId?: string;\n metadata?: Record<string, unknown>;\n /** Total time to wait for completion. Default 5 min. */\n timeoutMs?: number;\n /** Poll interval. Default 2s. */\n pollIntervalMs?: number;\n /** Called with each polled task — useful for surfacing progress. */\n onUpdate?: (task: Task) => void;\n },\n ): Promise<Task> {\n const submitted = await this.send(message, {\n contextId: opts?.contextId,\n metadata: opts?.metadata,\n async: true,\n });\n\n const terminalStates = new Set([\"completed\", \"failed\", \"canceled\"]);\n if (terminalStates.has(submitted.status.state)) return submitted;\n\n const timeoutMs = opts?.timeoutMs ?? 5 * 60_000;\n const pollMs = opts?.pollIntervalMs ?? 2_000;\n const deadline = Date.now() + timeoutMs;\n\n let current = submitted;\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, pollMs));\n try {\n current = await this.getTask(submitted.id);\n opts?.onUpdate?.(current);\n } catch {\n // Transient fetch failure — keep polling until the deadline.\n continue;\n }\n if (terminalStates.has(current.status.state)) return current;\n }\n throw new A2ATaskTimeoutError(submitted.id, current, timeoutMs);\n }\n\n async *stream(\n message: Message,\n opts?: { contextId?: string; metadata?: Record<string, unknown> },\n ): AsyncGenerator<Task> {\n const body: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id: Date.now(),\n method: \"message/stream\",\n params: {\n message,\n contextId: opts?.contextId,\n metadata: opts?.metadata,\n },\n };\n\n await this.ensureEndpointCandidates();\n let res: Response | null = null;\n let lastError: Error | null = null;\n for (const candidate of this.endpointCandidates) {\n for (let i = 0; i < this.apiKeyAttempts.length; i++) {\n res = await this.postJson(candidate, body, this.apiKeyAttempts[i]);\n if (res.ok) {\n this.endpointCandidates = [candidate];\n this.markApiKeySucceeded(this.apiKeyAttempts[i]);\n break;\n }\n const text = await res.text();\n lastError = new Error(`A2A stream failed (${res.status}): ${text}`);\n if (\n i < this.apiKeyAttempts.length - 1 &&\n isA2AAuthRejectionResponse(res.status, text)\n ) {\n continue;\n }\n if (!shouldTryNextEndpoint(res.status)) throw lastError;\n break;\n }\n if (res?.ok) break;\n }\n if (!res?.ok) {\n throw lastError ?? new Error(\"No A2A endpoint candidates available\");\n }\n\n const reader = res.body?.getReader();\n if (!reader) throw new Error(\"No response body\");\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const json = line.slice(6).trim();\n if (!json) continue;\n\n const response: JsonRpcResponse = JSON.parse(json);\n if (response.error) {\n throw new Error(\n `A2A error (${response.error.code}): ${response.error.message}`,\n );\n }\n if (response.result) {\n yield response.result as Task;\n }\n }\n }\n }\n\n private async ensureEndpointCandidates(): Promise<void> {\n if (this.endpointResolved) return;\n this.endpointResolved = true;\n\n const candidates: string[] = [];\n addDefaultEndpointCandidates(candidates, this.baseUrl);\n\n try {\n const card = await this.getAgentCard();\n const cardUrl = normalizeUrl(card.url, this.baseUrl);\n if (cardUrl) {\n const explicitEndpoint = splitExplicitA2AEndpoint(cardUrl);\n if (explicitEndpoint) {\n candidates.unshift(explicitEndpoint.endpointUrl);\n } else {\n addDefaultEndpointCandidates(candidates, cardUrl);\n }\n }\n } catch {\n // Agent cards are discovery hints. Fall back to conventional endpoints.\n }\n\n this.endpointCandidates = unique(candidates);\n }\n\n private async postJson(\n url: string,\n body: JsonRpcRequest,\n apiKey = this.apiKey,\n ): Promise<Response> {\n const controller = this.requestTimeoutMs\n ? new AbortController()\n : undefined;\n const timer =\n controller && this.requestTimeoutMs\n ? setTimeout(() => controller.abort(), this.requestTimeoutMs)\n : undefined;\n try {\n return await ssrfSafeFetch(\n url,\n {\n method: \"POST\",\n headers: this.headers(apiKey),\n body: JSON.stringify(body),\n signal: controller?.signal,\n },\n { maxRedirects: 3 },\n );\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n}\n\nfunction splitExplicitA2AEndpoint(\n url: string,\n): { baseUrl: string; endpointUrl: string } | null {\n try {\n const parsed = new URL(url);\n const pathname = parsed.pathname.replace(/\\/$/, \"\");\n if (pathname.endsWith(\"/_agent-native/a2a\")) {\n parsed.pathname = pathname.slice(0, -\"/_agent-native/a2a\".length) || \"/\";\n parsed.search = \"\";\n parsed.hash = \"\";\n return {\n baseUrl: parsed.toString().replace(/\\/$/, \"\"),\n endpointUrl: url,\n };\n }\n if (pathname.endsWith(\"/a2a\")) {\n parsed.pathname = pathname.slice(0, -\"/a2a\".length) || \"/\";\n parsed.search = \"\";\n parsed.hash = \"\";\n return {\n baseUrl: parsed.toString().replace(/\\/$/, \"\"),\n endpointUrl: url,\n };\n }\n } catch {\n // Relative or invalid URLs are handled by the caller's normal fetch path.\n }\n return null;\n}\n\nfunction addDefaultEndpointCandidates(candidates: string[], baseUrl: string) {\n const base = baseUrl.replace(/\\/$/, \"\");\n candidates.push(`${base}/_agent-native/a2a`, `${base}/a2a`);\n}\n\nfunction normalizeUrl(\n value: string | undefined,\n baseUrl: string,\n): string | null {\n if (!value) return null;\n try {\n return new URL(value, `${baseUrl.replace(/\\/$/, \"\")}/`)\n .toString()\n .replace(/\\/$/, \"\");\n } catch {\n return null;\n }\n}\n\nfunction shouldTryNextEndpoint(status: number): boolean {\n return status === 404 || status === 405;\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n\nfunction uniqueAuthTokens(\n values: Array<string | undefined>,\n): Array<string | undefined> {\n const result: Array<string | undefined> = [];\n for (const value of values) {\n if (result.includes(value)) continue;\n result.push(value);\n }\n if (result.length === 0) result.push(undefined);\n return result;\n}\n\nfunction isA2AAuthRejectionResponse(status: number, text: string): boolean {\n return (\n status === 401 ||\n /A2A error \\(-32001\\): (?:Invalid or expired A2A token|Invalid API key|Authentication required)|Invalid or expired A2A token|Invalid API key|Authentication required/i.test(\n text,\n )\n );\n}\n\n/**\n * One-shot convenience function: send a text message and get a text response.\n *\n * When A2A_SECRET is set and userEmail is provided, outbound calls are signed\n * with a JWT so the receiving app can cryptographically verify the caller's\n * identity (instead of blindly trusting metadata).\n */\nexport async function callAgent(\n url: string,\n text: string,\n opts?: {\n apiKey?: string;\n contextId?: string;\n userEmail?: string;\n orgDomain?: string;\n orgSecret?: string;\n /** Origin used to build links back to the receiving app. */\n requestOrigin?: string;\n /**\n * Use async/poll instead of a single blocking POST. Recommended for\n * cross-app calls that may exceed a synchronous serverless request budget.\n * Defaults to true so callers get safe behavior out of the box.\n */\n async?: boolean;\n /** Total time to wait for the polled task (default 5 min). */\n timeoutMs?: number;\n /** Poll interval for async calls. Primarily useful for tests/retries. */\n pollIntervalMs?: number;\n /**\n * Return receiver-verified artifact text from the last polled task when\n * the call times out. Defaults to true for backwards compatibility.\n * Callers that can continue polling the remote task separately should set\n * this to false so the A2ATaskTimeoutError (and its taskId) is preserved.\n */\n returnRecoverableArtifactsOnTimeout?: boolean;\n /**\n * Called with each successfully polled task while an async call is still\n * in flight (see `A2AClient.sendAndWait`). Fires once per real poll\n * round-trip that returns a task — including the terminal poll — so\n * callers can surface genuine remote liveness/progress. Not called when a\n * poll fetch throws (remote unresponsive) or when the task completes\n * synchronously on submit. Only threaded through for async calls.\n */\n onUpdate?: (task: Task) => void;\n },\n): Promise<string> {\n const metadata: Record<string, unknown> = {};\n if (opts?.userEmail) metadata.userEmail = opts.userEmail;\n if (opts?.orgDomain) metadata.orgDomain = opts.orgDomain;\n if (opts?.requestOrigin) metadata.requestOrigin = opts.requestOrigin;\n\n // Default to async + poll. The receiving A2A server's `_process-task` route\n // runs the handler in a fresh function execution (cross-platform queue\n // pattern), so async mode now works on every host instead of relying on\n // detached promises that get killed on Netlify/Vercel. Callers that\n // explicitly want a single-shot blocking POST can pass `async: false`.\n const useAsync = opts?.async ?? true;\n const message: Message = {\n role: \"user\",\n parts: [{ type: \"text\", text }],\n };\n\n const apiKeyAttempts = await buildA2AApiKeyAttempts(opts);\n let lastAuthError: unknown;\n\n for (let i = 0; i < apiKeyAttempts.length; i++) {\n try {\n const fallbackApiKeys = apiKeyAttempts\n .slice(i + 1)\n .filter((token): token is string => token !== undefined);\n const client = new A2AClient(url, apiKeyAttempts[i], {\n fallbackApiKeys,\n });\n let task: Task;\n if (useAsync) {\n task = await client.sendAndWait(message, {\n contextId: opts?.contextId,\n metadata,\n timeoutMs: opts?.timeoutMs,\n pollIntervalMs: opts?.pollIntervalMs,\n onUpdate: opts?.onUpdate,\n });\n } else {\n task = await client.send(message, {\n contextId: opts?.contextId,\n metadata,\n });\n }\n\n // Extract text from the response\n const responseMessage = task.status.message;\n if (responseMessage) {\n const textParts = responseMessage.parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text);\n return textParts.join(\"\\n\");\n }\n\n return \"\";\n } catch (err) {\n if (\n opts?.returnRecoverableArtifactsOnTimeout !== false &&\n err instanceof A2ATaskTimeoutError\n ) {\n const recoverableText = extractRecoverableArtifactText(err.lastTask);\n if (recoverableText) return recoverableText;\n }\n if (i < apiKeyAttempts.length - 1 && isA2AAuthRejection(err)) {\n lastAuthError = err;\n continue;\n }\n throw err;\n }\n }\n\n if (lastAuthError) throw lastAuthError;\n return \"\";\n}\n\nasync function buildA2AApiKeyAttempts(opts?: {\n apiKey?: string;\n userEmail?: string;\n orgDomain?: string;\n orgSecret?: string;\n}): Promise<Array<string | undefined>> {\n const attempts: Array<string | undefined> = [];\n const add = (token: string | undefined) => {\n if (token === undefined || attempts.includes(token)) return;\n attempts.push(token);\n };\n\n add(opts?.apiKey);\n\n if (opts?.userEmail && (opts.orgSecret || process.env.A2A_SECRET)) {\n if (process.env.A2A_SECRET?.trim()) {\n try {\n add(\n await signA2AToken(opts.userEmail, opts.orgDomain, opts.orgSecret, {\n preferGlobalSecret: true,\n }),\n );\n } catch {\n // Keep any explicit token attempt, then fall back below.\n }\n }\n\n if (opts.orgSecret) {\n try {\n add(\n await signA2AToken(opts.userEmail, opts.orgDomain, opts.orgSecret, {\n preferGlobalSecret: false,\n }),\n );\n } catch {\n // Fall through to the attempts we already have.\n }\n }\n }\n\n if (attempts.length === 0) attempts.push(undefined);\n return attempts;\n}\n\nfunction isA2AAuthRejection(err: unknown): boolean {\n const message = err instanceof Error ? err.message : String(err ?? \"\");\n return /A2A request failed \\(401\\)|A2A error \\(-32001\\): (?:Invalid or expired A2A token|Invalid API key|Authentication required)|Invalid or expired A2A token|Invalid API key|Authentication required/i.test(\n message,\n );\n}\n\nfunction extractRecoverableArtifactText(task: Task): string {\n if (!task.status.message?.metadata?.agentNativeRecoverableArtifacts) {\n return \"\";\n }\n return extractMessageText(task.status.message);\n}\n\nfunction extractMessageText(message: Message): string {\n return message.parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\\n\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"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","sourcesContent":["import * as jose from \"jose\";\n\nimport { ssrfSafeFetch } from \"../extensions/url-safety.js\";\nimport type {\n A2AApprovedAction,\n AgentCard,\n JsonRpcRequest,\n JsonRpcResponse,\n Message,\n Task,\n} from \"./types.js\";\n\nexport class A2ATaskTimeoutError extends Error {\n readonly taskId: string;\n readonly lastTask: Task;\n readonly lastState: string;\n readonly timeoutMs: number;\n\n constructor(taskId: string, lastTask: Task, timeoutMs: number) {\n const lastState = lastTask.status.state;\n super(\n `A2A task ${taskId} did not complete within ${timeoutMs}ms (last state: ${lastState})`,\n );\n this.name = \"A2ATaskTimeoutError\";\n this.taskId = taskId;\n this.lastTask = lastTask;\n this.lastState = lastState;\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Sign a JWT for A2A cross-app identity verification.\n *\n * Uses an org-level secret by default for direct org-secret workflows. Callers\n * that are doing ordinary hosted cross-app delegation can set\n * `preferGlobalSecret` so deployments with a shared A2A_SECRET don't depend on\n * every app database having an identical org row. The token contains the\n * caller's email as `sub`, so the receiving app can verify who's calling.\n */\nexport async function signA2AToken(\n email: string,\n orgDomain?: string,\n orgSecret?: string,\n options?: {\n expiresIn?: string | number;\n preferGlobalSecret?: boolean;\n audience?: string | string[];\n /**\n * Extra JWT claims to merge alongside `sub` / `org_domain`. Used by the\n * MCP connect flow to add a revocable `jti` and a `scope: \"mcp-connect\"`\n * marker. Reserved claims (`sub`, `org_domain`) cannot be overridden —\n * they are spread last so a caller can never spoof identity via this map.\n */\n extraClaims?: Record<string, unknown>;\n },\n): Promise<string> {\n const secret = options?.preferGlobalSecret\n ? process.env.A2A_SECRET || orgSecret\n : orgSecret || process.env.A2A_SECRET;\n if (!secret) {\n throw new Error(\n \"No A2A secret available. Set an org-level A2A secret in Team settings, \" +\n \"or set A2A_SECRET as an environment variable on all apps that need to verify identity.\",\n );\n }\n\n const appUrl =\n process.env.APP_URL ||\n process.env.BETTER_AUTH_URL ||\n \"http://localhost:3000\";\n\n const jwt = new jose.SignJWT({\n ...(options?.extraClaims ?? {}),\n // `sub` / `org_domain` are spread AFTER extraClaims so a caller-supplied\n // map can never override the verified identity claims.\n sub: email,\n ...(orgDomain ? { org_domain: orgDomain } : {}),\n })\n .setProtectedHeader({ alg: \"HS256\" })\n .setIssuer(appUrl)\n .setIssuedAt()\n .setExpirationTime(options?.expiresIn ?? \"15m\");\n\n if (options?.audience) jwt.setAudience(options.audience);\n\n return jwt.sign(new TextEncoder().encode(secret));\n}\n\nexport function shouldPreferGlobalA2ASecret(orgSecret?: string): boolean {\n return !!process.env.A2A_SECRET?.trim() || !orgSecret;\n}\n\nexport class A2AClient {\n private baseUrl: string;\n private apiKey?: string;\n private apiKeyAttempts: Array<string | undefined>;\n private endpointCandidates: string[] = [];\n private endpointResolved = false;\n private requestTimeoutMs?: number;\n\n constructor(\n baseUrl: string,\n apiKey?: string,\n options?: { requestTimeoutMs?: number; fallbackApiKeys?: string[] },\n ) {\n const normalized = baseUrl.replace(/\\/$/, \"\");\n const explicitEndpoint = splitExplicitA2AEndpoint(normalized);\n this.baseUrl = explicitEndpoint?.baseUrl ?? normalized;\n if (explicitEndpoint) {\n this.endpointCandidates = [explicitEndpoint.endpointUrl];\n this.endpointResolved = true;\n }\n this.apiKey = apiKey;\n this.apiKeyAttempts = uniqueAuthTokens([\n apiKey,\n ...(options?.fallbackApiKeys ?? []),\n ]);\n this.requestTimeoutMs = options?.requestTimeoutMs;\n }\n\n /**\n * Detect which A2A path the target agent uses.\n * Agent-native apps use /_agent-native/a2a, external agents may use /a2a.\n */\n async resolveEndpoint(): Promise<void> {\n await this.ensureEndpointCandidates();\n if (this.endpointCandidates.length <= 1) return;\n\n for (const endpoint of this.endpointCandidates) {\n try {\n const res = await ssrfSafeFetch(\n endpoint,\n { method: \"OPTIONS\" },\n { maxRedirects: 3 },\n );\n if (res.status !== 404 && res.status !== 405) {\n this.endpointCandidates = [endpoint];\n return;\n }\n if (res.status === 405) {\n this.endpointCandidates = [endpoint];\n return;\n }\n } catch {\n // Try the next candidate.\n }\n }\n }\n\n private headers(apiKey = this.apiKey): Record<string, string> {\n const h: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (apiKey) {\n h[\"Authorization\"] = `Bearer ${apiKey}`;\n }\n return h;\n }\n\n private markApiKeySucceeded(apiKey: string | undefined) {\n this.apiKey = apiKey;\n this.apiKeyAttempts = uniqueAuthTokens([\n apiKey,\n ...this.apiKeyAttempts.filter((token) => token !== apiKey),\n ]);\n }\n\n private async rpc(\n method: string,\n params: Record<string, unknown>,\n ): Promise<JsonRpcResponse> {\n const body: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id: Date.now(),\n method,\n params,\n };\n\n await this.ensureEndpointCandidates();\n let lastError: Error | null = null;\n\n for (const url of this.endpointCandidates) {\n for (let i = 0; i < this.apiKeyAttempts.length; i++) {\n console.log(`[A2A Client] POST ${url} method=${method}`);\n const startTime = Date.now();\n const res = await this.postJson(url, body, this.apiKeyAttempts[i]);\n console.log(\n `[A2A Client] Response: ${res.status} in ${Date.now() - startTime}ms`,\n );\n\n if (res.ok) {\n this.endpointCandidates = [url];\n this.markApiKeySucceeded(this.apiKeyAttempts[i]);\n return res.json() as Promise<JsonRpcResponse>;\n }\n\n const text = await res.text();\n lastError = new Error(`A2A request failed (${res.status}): ${text}`);\n if (\n i < this.apiKeyAttempts.length - 1 &&\n isA2AAuthRejectionResponse(res.status, text)\n ) {\n continue;\n }\n if (!shouldTryNextEndpoint(res.status)) {\n throw lastError;\n }\n break;\n }\n }\n\n throw lastError ?? new Error(\"No A2A endpoint candidates available\");\n }\n\n async getAgentCard(): Promise<AgentCard> {\n const res = await ssrfSafeFetch(\n `${this.baseUrl}/.well-known/agent-card.json`,\n {},\n { maxRedirects: 3 },\n );\n if (!res.ok) {\n throw new Error(`Failed to fetch agent card (${res.status})`);\n }\n return res.json() as Promise<AgentCard>;\n }\n\n async send(\n message: Message,\n opts?: {\n contextId?: string;\n metadata?: Record<string, unknown>;\n approvedActions?: A2AApprovedAction[];\n /**\n * If true, ask the server to return the task immediately in `working`\n * state and process the handler in the background. The caller should\n * then poll `getTask(taskId)` until `completed` / `failed` / `canceled`.\n *\n * Use this when you expect the handler may exceed a synchronous\n * serverless request budget.\n */\n async?: boolean;\n },\n ): Promise<Task> {\n const response = await this.rpc(\"message/send\", {\n message,\n contextId: opts?.contextId,\n metadata: opts?.metadata,\n ...(opts?.approvedActions?.length\n ? { approvedActions: opts.approvedActions }\n : {}),\n ...(opts?.async ? { async: true } : {}),\n });\n\n if (response.error) {\n throw new Error(\n `A2A error (${response.error.code}): ${response.error.message}`,\n );\n }\n\n return response.result as Task;\n }\n\n /**\n * Poll for a task by id. Used in async mode after `send({ async: true })`.\n */\n async getTask(taskId: string): Promise<Task> {\n const response = await this.rpc(\"tasks/get\", { id: taskId });\n if (response.error) {\n throw new Error(\n `A2A error (${response.error.code}): ${response.error.message}`,\n );\n }\n return response.result as Task;\n }\n\n /**\n * Send a message in async mode and poll until the task reaches a terminal\n * state. This is the recommended path on serverless hosts with short\n * function timeouts (Netlify, Vercel) where a synchronous LLM-driven A2A\n * call can exceed the gateway limit.\n *\n * Each individual fetch returns quickly; long-running work happens on the\n * receiving side and is checked via `tasks/get`.\n */\n async sendAndWait(\n message: Message,\n opts?: {\n contextId?: string;\n metadata?: Record<string, unknown>;\n approvedActions?: A2AApprovedAction[];\n /** Total time to wait for completion. Default 5 min. */\n timeoutMs?: number;\n /** Poll interval. Default 2s. */\n pollIntervalMs?: number;\n /** Called with each polled task — useful for surfacing progress. */\n onUpdate?: (task: Task) => void;\n },\n ): Promise<Task> {\n const submitted = await this.send(message, {\n contextId: opts?.contextId,\n metadata: opts?.metadata,\n ...(opts?.approvedActions?.length\n ? { approvedActions: opts.approvedActions }\n : {}),\n async: true,\n });\n\n const terminalStates = new Set([\n \"completed\",\n \"failed\",\n \"canceled\",\n \"input-required\",\n ]);\n if (terminalStates.has(submitted.status.state)) return submitted;\n\n const timeoutMs = opts?.timeoutMs ?? 5 * 60_000;\n const pollMs = opts?.pollIntervalMs ?? 2_000;\n const deadline = Date.now() + timeoutMs;\n\n let current = submitted;\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, pollMs));\n try {\n current = await this.getTask(submitted.id);\n opts?.onUpdate?.(current);\n } catch {\n // Transient fetch failure — keep polling until the deadline.\n continue;\n }\n if (terminalStates.has(current.status.state)) return current;\n }\n throw new A2ATaskTimeoutError(submitted.id, current, timeoutMs);\n }\n\n async *stream(\n message: Message,\n opts?: { contextId?: string; metadata?: Record<string, unknown> },\n ): AsyncGenerator<Task> {\n const body: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id: Date.now(),\n method: \"message/stream\",\n params: {\n message,\n contextId: opts?.contextId,\n metadata: opts?.metadata,\n },\n };\n\n await this.ensureEndpointCandidates();\n let res: Response | null = null;\n let lastError: Error | null = null;\n for (const candidate of this.endpointCandidates) {\n for (let i = 0; i < this.apiKeyAttempts.length; i++) {\n res = await this.postJson(candidate, body, this.apiKeyAttempts[i]);\n if (res.ok) {\n this.endpointCandidates = [candidate];\n this.markApiKeySucceeded(this.apiKeyAttempts[i]);\n break;\n }\n const text = await res.text();\n lastError = new Error(`A2A stream failed (${res.status}): ${text}`);\n if (\n i < this.apiKeyAttempts.length - 1 &&\n isA2AAuthRejectionResponse(res.status, text)\n ) {\n continue;\n }\n if (!shouldTryNextEndpoint(res.status)) throw lastError;\n break;\n }\n if (res?.ok) break;\n }\n if (!res?.ok) {\n throw lastError ?? new Error(\"No A2A endpoint candidates available\");\n }\n\n const reader = res.body?.getReader();\n if (!reader) throw new Error(\"No response body\");\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const json = line.slice(6).trim();\n if (!json) continue;\n\n const response: JsonRpcResponse = JSON.parse(json);\n if (response.error) {\n throw new Error(\n `A2A error (${response.error.code}): ${response.error.message}`,\n );\n }\n if (response.result) {\n yield response.result as Task;\n }\n }\n }\n }\n\n private async ensureEndpointCandidates(): Promise<void> {\n if (this.endpointResolved) return;\n this.endpointResolved = true;\n\n const candidates: string[] = [];\n addDefaultEndpointCandidates(candidates, this.baseUrl);\n\n try {\n const card = await this.getAgentCard();\n const cardUrl = normalizeUrl(card.url, this.baseUrl);\n if (cardUrl) {\n const explicitEndpoint = splitExplicitA2AEndpoint(cardUrl);\n if (explicitEndpoint) {\n candidates.unshift(explicitEndpoint.endpointUrl);\n } else {\n addDefaultEndpointCandidates(candidates, cardUrl);\n }\n }\n } catch {\n // Agent cards are discovery hints. Fall back to conventional endpoints.\n }\n\n this.endpointCandidates = unique(candidates);\n }\n\n private async postJson(\n url: string,\n body: JsonRpcRequest,\n apiKey = this.apiKey,\n ): Promise<Response> {\n const controller = this.requestTimeoutMs\n ? new AbortController()\n : undefined;\n const timer =\n controller && this.requestTimeoutMs\n ? setTimeout(() => controller.abort(), this.requestTimeoutMs)\n : undefined;\n try {\n return await ssrfSafeFetch(\n url,\n {\n method: \"POST\",\n headers: this.headers(apiKey),\n body: JSON.stringify(body),\n signal: controller?.signal,\n },\n { maxRedirects: 3 },\n );\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n}\n\nfunction splitExplicitA2AEndpoint(\n url: string,\n): { baseUrl: string; endpointUrl: string } | null {\n try {\n const parsed = new URL(url);\n const pathname = parsed.pathname.replace(/\\/$/, \"\");\n if (pathname.endsWith(\"/_agent-native/a2a\")) {\n parsed.pathname = pathname.slice(0, -\"/_agent-native/a2a\".length) || \"/\";\n parsed.search = \"\";\n parsed.hash = \"\";\n return {\n baseUrl: parsed.toString().replace(/\\/$/, \"\"),\n endpointUrl: url,\n };\n }\n if (pathname.endsWith(\"/a2a\")) {\n parsed.pathname = pathname.slice(0, -\"/a2a\".length) || \"/\";\n parsed.search = \"\";\n parsed.hash = \"\";\n return {\n baseUrl: parsed.toString().replace(/\\/$/, \"\"),\n endpointUrl: url,\n };\n }\n } catch {\n // Relative or invalid URLs are handled by the caller's normal fetch path.\n }\n return null;\n}\n\nfunction addDefaultEndpointCandidates(candidates: string[], baseUrl: string) {\n const base = baseUrl.replace(/\\/$/, \"\");\n candidates.push(`${base}/_agent-native/a2a`, `${base}/a2a`);\n}\n\nfunction normalizeUrl(\n value: string | undefined,\n baseUrl: string,\n): string | null {\n if (!value) return null;\n try {\n return new URL(value, `${baseUrl.replace(/\\/$/, \"\")}/`)\n .toString()\n .replace(/\\/$/, \"\");\n } catch {\n return null;\n }\n}\n\nfunction shouldTryNextEndpoint(status: number): boolean {\n return status === 404 || status === 405;\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n\nfunction uniqueAuthTokens(\n values: Array<string | undefined>,\n): Array<string | undefined> {\n const result: Array<string | undefined> = [];\n for (const value of values) {\n if (result.includes(value)) continue;\n result.push(value);\n }\n if (result.length === 0) result.push(undefined);\n return result;\n}\n\nfunction isA2AAuthRejectionResponse(status: number, text: string): boolean {\n return (\n status === 401 ||\n /A2A error \\(-32001\\): (?:Invalid or expired A2A token|Invalid API key|Authentication required)|Invalid or expired A2A token|Invalid API key|Authentication required/i.test(\n text,\n )\n );\n}\n\n/**\n * One-shot convenience function: send a text message and get a text response.\n *\n * When A2A_SECRET is set and userEmail is provided, outbound calls are signed\n * with a JWT so the receiving app can cryptographically verify the caller's\n * identity (instead of blindly trusting metadata).\n */\nexport async function callAgent(\n url: string,\n text: string,\n opts?: {\n apiKey?: string;\n contextId?: string;\n userEmail?: string;\n orgDomain?: string;\n orgSecret?: string;\n /** Origin used to build links back to the receiving app. */\n requestOrigin?: string;\n /** Exact downstream actions explicitly authorized in the caller's chat. */\n approvedActions?: A2AApprovedAction[];\n /**\n * Use async/poll instead of a single blocking POST. Recommended for\n * cross-app calls that may exceed a synchronous serverless request budget.\n * Defaults to true so callers get safe behavior out of the box.\n */\n async?: boolean;\n /** Total time to wait for the polled task (default 5 min). */\n timeoutMs?: number;\n /** Poll interval for async calls. Primarily useful for tests/retries. */\n pollIntervalMs?: number;\n /**\n * Return receiver-verified artifact text from the last polled task when\n * the call times out. Defaults to true for backwards compatibility.\n * Callers that can continue polling the remote task separately should set\n * this to false so the A2ATaskTimeoutError (and its taskId) is preserved.\n */\n returnRecoverableArtifactsOnTimeout?: boolean;\n /**\n * Called with each successfully polled task while an async call is still\n * in flight (see `A2AClient.sendAndWait`). Fires once per real poll\n * round-trip that returns a task — including the terminal poll — so\n * callers can surface genuine remote liveness/progress. Not called when a\n * poll fetch throws (remote unresponsive) or when the task completes\n * synchronously on submit. Only threaded through for async calls.\n */\n onUpdate?: (task: Task) => void;\n },\n): Promise<string> {\n const metadata: Record<string, unknown> = {};\n if (opts?.userEmail) metadata.userEmail = opts.userEmail;\n if (opts?.orgDomain) metadata.orgDomain = opts.orgDomain;\n if (opts?.requestOrigin) metadata.requestOrigin = opts.requestOrigin;\n\n // Default to async + poll. The receiving A2A server's `_process-task` route\n // runs the handler in a fresh function execution (cross-platform queue\n // pattern), so async mode now works on every host instead of relying on\n // detached promises that get killed on Netlify/Vercel. Callers that\n // explicitly want a single-shot blocking POST can pass `async: false`.\n const useAsync = opts?.async ?? true;\n const message: Message = {\n role: \"user\",\n parts: [{ type: \"text\", text }],\n };\n\n const apiKeyAttempts = await buildA2AApiKeyAttempts(opts);\n let lastAuthError: unknown;\n\n for (let i = 0; i < apiKeyAttempts.length; i++) {\n try {\n const fallbackApiKeys = apiKeyAttempts\n .slice(i + 1)\n .filter((token): token is string => token !== undefined);\n const client = new A2AClient(url, apiKeyAttempts[i], {\n fallbackApiKeys,\n });\n let task: Task;\n if (useAsync) {\n task = await client.sendAndWait(message, {\n contextId: opts?.contextId,\n metadata,\n ...(opts?.approvedActions?.length\n ? { approvedActions: opts.approvedActions }\n : {}),\n timeoutMs: opts?.timeoutMs,\n pollIntervalMs: opts?.pollIntervalMs,\n onUpdate: opts?.onUpdate,\n });\n } else {\n task = await client.send(message, {\n contextId: opts?.contextId,\n metadata,\n ...(opts?.approvedActions?.length\n ? { approvedActions: opts.approvedActions }\n : {}),\n });\n }\n\n // Extract text from the response\n const responseMessage = task.status.message;\n if (responseMessage) {\n const textParts = responseMessage.parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text);\n return textParts.join(\"\\n\");\n }\n\n return \"\";\n } catch (err) {\n if (\n opts?.returnRecoverableArtifactsOnTimeout !== false &&\n err instanceof A2ATaskTimeoutError\n ) {\n const recoverableText = extractRecoverableArtifactText(err.lastTask);\n if (recoverableText) return recoverableText;\n }\n if (i < apiKeyAttempts.length - 1 && isA2AAuthRejection(err)) {\n lastAuthError = err;\n continue;\n }\n throw err;\n }\n }\n\n if (lastAuthError) throw lastAuthError;\n return \"\";\n}\n\nasync function buildA2AApiKeyAttempts(opts?: {\n apiKey?: string;\n userEmail?: string;\n orgDomain?: string;\n orgSecret?: string;\n}): Promise<Array<string | undefined>> {\n const attempts: Array<string | undefined> = [];\n const add = (token: string | undefined) => {\n if (token === undefined || attempts.includes(token)) return;\n attempts.push(token);\n };\n\n add(opts?.apiKey);\n\n if (opts?.userEmail && (opts.orgSecret || process.env.A2A_SECRET)) {\n if (process.env.A2A_SECRET?.trim()) {\n try {\n add(\n await signA2AToken(opts.userEmail, opts.orgDomain, opts.orgSecret, {\n preferGlobalSecret: true,\n }),\n );\n } catch {\n // Keep any explicit token attempt, then fall back below.\n }\n }\n\n if (opts.orgSecret) {\n try {\n add(\n await signA2AToken(opts.userEmail, opts.orgDomain, opts.orgSecret, {\n preferGlobalSecret: false,\n }),\n );\n } catch {\n // Fall through to the attempts we already have.\n }\n }\n }\n\n if (attempts.length === 0) attempts.push(undefined);\n return attempts;\n}\n\nfunction isA2AAuthRejection(err: unknown): boolean {\n const message = err instanceof Error ? err.message : String(err ?? \"\");\n return /A2A request failed \\(401\\)|A2A error \\(-32001\\): (?:Invalid or expired A2A token|Invalid API key|Authentication required)|Invalid or expired A2A token|Invalid API key|Authentication required/i.test(\n message,\n );\n}\n\nfunction extractRecoverableArtifactText(task: Task): string {\n if (!task.status.message?.metadata?.agentNativeRecoverableArtifacts) {\n return \"\";\n }\n return extractMessageText(task.status.message);\n}\n\nfunction extractMessageText(message: Message): string {\n return message.parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\\n\");\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/a2a/handlers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/a2a/handlers.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAEV,SAAS,EAIT,eAAe,EAGhB,MAAM,YAAY,CAAC;AA6LpB;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,EACjB,KAAK,CAAC,EAAE,GAAG,GACV,OAAO,CAAC,IAAI,CAAC,CAsFf;AAitBD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,GAAG,EACT,KAAK,EAAE,GAAG,EACV,MAAM,EAAE,SAAS,GAChB,OAAO,CAAC,eAAe,CAAC,CAyC1B"}
|
package/dist/a2a/handlers.js
CHANGED
|
@@ -5,7 +5,7 @@ import { getOrigin, isConfiguredAppOrigin } from "../server/google-oauth.js";
|
|
|
5
5
|
import { fireInternalDispatch } from "../server/self-dispatch.js";
|
|
6
6
|
import { agentChat } from "../shared/agent-chat.js";
|
|
7
7
|
import { hasConfiguredA2ASecret, isA2AProductionRuntime, } from "./auth-policy.js";
|
|
8
|
-
import { createTask, getTask, getTaskOwner, updateTask, claimA2ATaskForProcessing, getA2ATaskDispatchState, failStuckA2ATask, failStuckQueuedA2ATask, settleProcessingA2ATask, touchQueuedA2ATaskDispatch, touchProcessingA2ATask, } from "./task-store.js";
|
|
8
|
+
import { createTask, getTask, getTaskOwner, updateTask, claimA2ATaskForProcessing, getA2ATaskDispatchState, failStuckA2ATask, failStuckQueuedA2ATask, settleProcessingA2ATask, touchQueuedA2ATaskDispatch, touchProcessingA2ATask, pauseProcessingA2ATask, } from "./task-store.js";
|
|
9
9
|
// Inlined to avoid pulling the entire core-routes-plugin (and its h3
|
|
10
10
|
// transitive deps) into the a2a/handlers test boundary. Must stay in sync
|
|
11
11
|
// with FRAMEWORK_ROUTE_PREFIX in `server/core-routes-plugin.ts`.
|
|
@@ -14,6 +14,23 @@ const PORTABLE_FALLBACK_HANDOFF_TIMEOUT_MS = 1_000;
|
|
|
14
14
|
const A2A_QUEUED_DISPATCH_STUCK_AFTER_MS = 10_000;
|
|
15
15
|
const A2A_PROCESSING_STUCK_AFTER_MS = 5 * 60 * 1000;
|
|
16
16
|
const A2A_PROCESSING_HEARTBEAT_MS = 30_000;
|
|
17
|
+
const MAX_A2A_APPROVED_ACTIONS = 10;
|
|
18
|
+
function trustedApprovedActions(value, event) {
|
|
19
|
+
// Static API keys and unsigned requests do not prove which user authorized
|
|
20
|
+
// a consequential action. Only a verified identity-bearing JWT may carry
|
|
21
|
+
// chat authorization across the A2A boundary.
|
|
22
|
+
if (!event?.context?.__a2aVerifiedEmail || !Array.isArray(value)) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
const approved = value
|
|
26
|
+
.slice(0, MAX_A2A_APPROVED_ACTIONS)
|
|
27
|
+
.filter((candidate) => !!candidate &&
|
|
28
|
+
typeof candidate === "object" &&
|
|
29
|
+
typeof candidate.tool === "string" &&
|
|
30
|
+
!!candidate.tool)
|
|
31
|
+
.map((candidate) => ({ tool: candidate.tool, input: candidate.input }));
|
|
32
|
+
return approved.length > 0 ? approved : undefined;
|
|
33
|
+
}
|
|
17
34
|
/**
|
|
18
35
|
* Request origin is routing/link context, not an identity signal. Accept only
|
|
19
36
|
* an absolute HTTP(S) origin from caller metadata so queued runs can preserve
|
|
@@ -190,6 +207,9 @@ export async function processA2ATaskFromQueue(taskId, config, event) {
|
|
|
190
207
|
const requestOrigin = requestOriginFromMetadata(processorMeta) ?? requestOriginFromEvent(event);
|
|
191
208
|
const contextId = processorMeta.contextId ?? undefined;
|
|
192
209
|
const callerMetadata = processorMeta.callerMetadata ?? undefined;
|
|
210
|
+
const approvedActions = Array.isArray(processorMeta.approvedActions)
|
|
211
|
+
? processorMeta.approvedActions
|
|
212
|
+
: undefined;
|
|
193
213
|
const resolvedOrgId = await resolveVerifiedA2AOrgId(verifiedEmail, orgDomainHint);
|
|
194
214
|
const { runWithRequestContext } = await import("../server/request-context.js");
|
|
195
215
|
const heartbeat = setInterval(() => {
|
|
@@ -201,7 +221,7 @@ export async function processA2ATaskFromQueue(taskId, config, event) {
|
|
|
201
221
|
userEmail: verifiedEmail,
|
|
202
222
|
orgId: resolvedOrgId,
|
|
203
223
|
...(requestOrigin ? { requestOrigin } : {}),
|
|
204
|
-
}, () => runHandlerAndPersist(taskId, message, config, contextId, callerMetadata, event));
|
|
224
|
+
}, () => runHandlerAndPersist(taskId, message, config, contextId, callerMetadata, event, approvedActions));
|
|
205
225
|
}
|
|
206
226
|
catch (err) {
|
|
207
227
|
try {
|
|
@@ -286,13 +306,14 @@ function jsonRpcError(id, code, message) {
|
|
|
286
306
|
function jsonRpcResult(id, result) {
|
|
287
307
|
return { jsonrpc: "2.0", id, result };
|
|
288
308
|
}
|
|
289
|
-
function makeHandlerContext(taskId, contextId, metadata, event) {
|
|
309
|
+
function makeHandlerContext(taskId, contextId, metadata, event, approvedActions) {
|
|
290
310
|
const artifacts = [];
|
|
291
311
|
const context = {
|
|
292
312
|
taskId,
|
|
293
313
|
contextId,
|
|
294
314
|
metadata,
|
|
295
315
|
event,
|
|
316
|
+
approvedActions,
|
|
296
317
|
writeArtifact(name, content, mimeType) {
|
|
297
318
|
const artifact = {
|
|
298
319
|
name,
|
|
@@ -363,8 +384,8 @@ async function resolveVerifiedA2AOrgId(verifiedEmail, verifiedOrgDomain) {
|
|
|
363
384
|
* Used in sync mode (awaited inline) and in async mode (called by the
|
|
364
385
|
* `_process-task` processor route in a fresh function execution).
|
|
365
386
|
*/
|
|
366
|
-
async function runHandlerAndPersist(taskId, message, config, contextId, metadata, event) {
|
|
367
|
-
const { context, artifacts } = makeHandlerContext(taskId, contextId, metadata, event);
|
|
387
|
+
async function runHandlerAndPersist(taskId, message, config, contextId, metadata, event, approvedActions) {
|
|
388
|
+
const { context, artifacts } = makeHandlerContext(taskId, contextId, metadata, event, approvedActions);
|
|
368
389
|
try {
|
|
369
390
|
const result = getHandler(config)(message, context);
|
|
370
391
|
if (result &&
|
|
@@ -374,6 +395,10 @@ async function runHandlerAndPersist(taskId, message, config, contextId, metadata
|
|
|
374
395
|
for await (const msg of result) {
|
|
375
396
|
lastMessage = msg;
|
|
376
397
|
}
|
|
398
|
+
if (lastMessage?.metadata?.agentNativeTaskState === "input-required") {
|
|
399
|
+
await pauseProcessingA2ATask(taskId, lastMessage);
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
377
402
|
await settleProcessingA2ATask(taskId, {
|
|
378
403
|
state: "completed",
|
|
379
404
|
message: lastMessage,
|
|
@@ -383,6 +408,10 @@ async function runHandlerAndPersist(taskId, message, config, contextId, metadata
|
|
|
383
408
|
}
|
|
384
409
|
const handlerResult = await result;
|
|
385
410
|
const allArtifacts = [...artifacts, ...(handlerResult.artifacts ?? [])];
|
|
411
|
+
if (handlerResult.taskState === "input-required") {
|
|
412
|
+
await pauseProcessingA2ATask(taskId, handlerResult.message);
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
386
415
|
await settleProcessingA2ATask(taskId, {
|
|
387
416
|
state: "completed",
|
|
388
417
|
message: handlerResult.message,
|
|
@@ -409,6 +438,7 @@ async function handleSend(params, config, event) {
|
|
|
409
438
|
}
|
|
410
439
|
const contextId = params.contextId;
|
|
411
440
|
const metadata = params.metadata;
|
|
441
|
+
const approvedActions = trustedApprovedActions(params.approvedActions, event);
|
|
412
442
|
// The JWT-verified caller email (set by mountA2A in server.ts) is the
|
|
413
443
|
// single source of truth for task ownership — bound at creation, checked
|
|
414
444
|
// on every subsequent tasks/get and tasks/cancel call. Caller-supplied
|
|
@@ -461,6 +491,7 @@ async function handleSend(params, config, event) {
|
|
|
461
491
|
...(requestOrigin ? { requestOrigin } : {}),
|
|
462
492
|
contextId: contextId ?? null,
|
|
463
493
|
callerMetadata: safeMetadata ?? null,
|
|
494
|
+
approvedActions: approvedActions ?? null,
|
|
464
495
|
},
|
|
465
496
|
};
|
|
466
497
|
const task = await createTask(message, contextId, taskMetadata, ownerEmailForTask);
|
|
@@ -478,12 +509,15 @@ async function handleSend(params, config, event) {
|
|
|
478
509
|
catch (err) {
|
|
479
510
|
console.error("[a2a] Failed to dispatch process-task:", err);
|
|
480
511
|
}
|
|
481
|
-
return {
|
|
512
|
+
return {
|
|
513
|
+
...jsonRpcResult(0, sanitizeTaskForResponse(working ?? task)),
|
|
514
|
+
_id: 0,
|
|
515
|
+
};
|
|
482
516
|
}
|
|
483
517
|
return withA2ARequestContext(metadata, event, async () => {
|
|
484
518
|
const task = await createTask(message, contextId, undefined, ownerEmailForTask);
|
|
485
519
|
await updateTask(task.id, { state: "working" });
|
|
486
|
-
const ctx = makeHandlerContext(task.id, contextId, trustedA2AMetadata(metadata, event), event);
|
|
520
|
+
const ctx = makeHandlerContext(task.id, contextId, trustedA2AMetadata(metadata, event), event, approvedActions);
|
|
487
521
|
try {
|
|
488
522
|
const result = getHandler(config)(message, ctx.context);
|
|
489
523
|
if (result &&
|
|
@@ -493,6 +527,13 @@ async function handleSend(params, config, event) {
|
|
|
493
527
|
for await (const msg of result) {
|
|
494
528
|
lastMessage = msg;
|
|
495
529
|
}
|
|
530
|
+
if (lastMessage?.metadata?.agentNativeTaskState === "input-required") {
|
|
531
|
+
const updated = await updateTask(task.id, {
|
|
532
|
+
state: "input-required",
|
|
533
|
+
message: lastMessage,
|
|
534
|
+
});
|
|
535
|
+
return { ...jsonRpcResult(0, updated), _id: 0 };
|
|
536
|
+
}
|
|
496
537
|
const updated = await updateTask(task.id, {
|
|
497
538
|
state: "completed",
|
|
498
539
|
message: lastMessage,
|
|
@@ -505,6 +546,13 @@ async function handleSend(params, config, event) {
|
|
|
505
546
|
...ctx.artifacts,
|
|
506
547
|
...(handlerResult.artifacts ?? []),
|
|
507
548
|
];
|
|
549
|
+
if (handlerResult.taskState === "input-required") {
|
|
550
|
+
const updated = await updateTask(task.id, {
|
|
551
|
+
state: "input-required",
|
|
552
|
+
message: handlerResult.message,
|
|
553
|
+
});
|
|
554
|
+
return { ...jsonRpcResult(0, updated), _id: 0 };
|
|
555
|
+
}
|
|
508
556
|
const updated = await updateTask(task.id, {
|
|
509
557
|
state: "completed",
|
|
510
558
|
message: handlerResult.message,
|
|
@@ -536,11 +584,12 @@ async function handleStream(params, config, res, event) {
|
|
|
536
584
|
}
|
|
537
585
|
const contextId = params.contextId;
|
|
538
586
|
const metadata = params.metadata;
|
|
587
|
+
const approvedActions = trustedApprovedActions(params.approvedActions, event);
|
|
539
588
|
const ownerEmailForTask = event?.context?.__a2aVerifiedEmail ?? null;
|
|
540
589
|
await withA2ARequestContext(metadata, event, async () => {
|
|
541
590
|
const task = await createTask(message, contextId, undefined, ownerEmailForTask);
|
|
542
591
|
await updateTask(task.id, { state: "working" });
|
|
543
|
-
const { context, artifacts } = makeHandlerContext(task.id, contextId, trustedA2AMetadata(metadata, event), event);
|
|
592
|
+
const { context, artifacts } = makeHandlerContext(task.id, contextId, trustedA2AMetadata(metadata, event), event, approvedActions);
|
|
544
593
|
try {
|
|
545
594
|
const result = getHandler(config)(message, context);
|
|
546
595
|
if (result &&
|