@illuma-ai/agents 1.3.2 → 1.4.0-alpha.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 (353) hide show
  1. package/dist/cjs/graphs/Graph.cjs +3 -18
  2. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  3. package/dist/cjs/llm/openai/index.cjs +3 -0
  4. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  5. package/dist/cjs/main.cjs +58 -0
  6. package/dist/cjs/main.cjs.map +1 -1
  7. package/dist/cjs/providers/a2a/A2ACapabilityProvider.cjs +288 -0
  8. package/dist/cjs/providers/a2a/A2ACapabilityProvider.cjs.map +1 -0
  9. package/dist/cjs/providers/a2a/client.cjs +92 -0
  10. package/dist/cjs/providers/a2a/client.cjs.map +1 -0
  11. package/dist/cjs/providers/a2a/config.cjs +38 -0
  12. package/dist/cjs/providers/a2a/config.cjs.map +1 -0
  13. package/dist/cjs/providers/capabilityNaming.cjs +43 -0
  14. package/dist/cjs/providers/capabilityNaming.cjs.map +1 -0
  15. package/dist/cjs/providers/composite/CompositeCapabilityProvider.cjs +80 -0
  16. package/dist/cjs/providers/composite/CompositeCapabilityProvider.cjs.map +1 -0
  17. package/dist/cjs/providers/mcp/MCPCapabilityProvider.cjs +244 -0
  18. package/dist/cjs/providers/mcp/MCPCapabilityProvider.cjs.map +1 -0
  19. package/dist/cjs/providers/mcp/config.cjs +42 -0
  20. package/dist/cjs/providers/mcp/config.cjs.map +1 -0
  21. package/dist/cjs/providers/mcp/transport.cjs +65 -0
  22. package/dist/cjs/providers/mcp/transport.cjs.map +1 -0
  23. package/dist/cjs/providers/tools-server/ToolsServerCapabilityProvider.cjs +121 -0
  24. package/dist/cjs/providers/tools-server/ToolsServerCapabilityProvider.cjs.map +1 -0
  25. package/dist/cjs/providers/types.cjs +51 -0
  26. package/dist/cjs/providers/types.cjs.map +1 -0
  27. package/dist/cjs/tools/ToolNode.cjs +3 -0
  28. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  29. package/dist/cjs/tools/proxyTool.cjs +100 -0
  30. package/dist/cjs/tools/proxyTool.cjs.map +1 -0
  31. package/dist/cjs/utils/credentials.cjs +142 -0
  32. package/dist/cjs/utils/credentials.cjs.map +1 -0
  33. package/dist/cjs/utils/httpClient.cjs +74 -0
  34. package/dist/cjs/utils/httpClient.cjs.map +1 -0
  35. package/dist/cjs/utils/toolManifest.cjs +100 -0
  36. package/dist/cjs/utils/toolManifest.cjs.map +1 -0
  37. package/dist/esm/graphs/Graph.mjs +3 -18
  38. package/dist/esm/graphs/Graph.mjs.map +1 -1
  39. package/dist/esm/llm/openai/index.mjs +3 -0
  40. package/dist/esm/llm/openai/index.mjs.map +1 -1
  41. package/dist/esm/main.mjs +14 -0
  42. package/dist/esm/main.mjs.map +1 -1
  43. package/dist/esm/providers/a2a/A2ACapabilityProvider.mjs +281 -0
  44. package/dist/esm/providers/a2a/A2ACapabilityProvider.mjs.map +1 -0
  45. package/dist/esm/providers/a2a/client.mjs +88 -0
  46. package/dist/esm/providers/a2a/client.mjs.map +1 -0
  47. package/dist/esm/providers/a2a/config.mjs +35 -0
  48. package/dist/esm/providers/a2a/config.mjs.map +1 -0
  49. package/dist/esm/providers/capabilityNaming.mjs +39 -0
  50. package/dist/esm/providers/capabilityNaming.mjs.map +1 -0
  51. package/dist/esm/providers/composite/CompositeCapabilityProvider.mjs +78 -0
  52. package/dist/esm/providers/composite/CompositeCapabilityProvider.mjs.map +1 -0
  53. package/dist/esm/providers/mcp/MCPCapabilityProvider.mjs +240 -0
  54. package/dist/esm/providers/mcp/MCPCapabilityProvider.mjs.map +1 -0
  55. package/dist/esm/providers/mcp/config.mjs +39 -0
  56. package/dist/esm/providers/mcp/config.mjs.map +1 -0
  57. package/dist/esm/providers/mcp/transport.mjs +63 -0
  58. package/dist/esm/providers/mcp/transport.mjs.map +1 -0
  59. package/dist/esm/providers/tools-server/ToolsServerCapabilityProvider.mjs +119 -0
  60. package/dist/esm/providers/tools-server/ToolsServerCapabilityProvider.mjs.map +1 -0
  61. package/dist/esm/providers/types.mjs +51 -0
  62. package/dist/esm/providers/types.mjs.map +1 -0
  63. package/dist/esm/tools/ToolNode.mjs +3 -0
  64. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  65. package/dist/esm/tools/proxyTool.mjs +98 -0
  66. package/dist/esm/tools/proxyTool.mjs.map +1 -0
  67. package/dist/esm/utils/credentials.mjs +135 -0
  68. package/dist/esm/utils/credentials.mjs.map +1 -0
  69. package/dist/esm/utils/httpClient.mjs +70 -0
  70. package/dist/esm/utils/httpClient.mjs.map +1 -0
  71. package/dist/esm/utils/toolManifest.mjs +96 -0
  72. package/dist/esm/utils/toolManifest.mjs.map +1 -0
  73. package/dist/types/index.d.ts +2 -0
  74. package/dist/types/providers/a2a/A2ACapabilityProvider.d.ts +89 -0
  75. package/dist/types/providers/a2a/client.d.ts +47 -0
  76. package/dist/types/providers/a2a/config.d.ts +18 -0
  77. package/dist/types/providers/a2a/index.d.ts +6 -0
  78. package/dist/types/providers/a2a/types.d.ts +173 -0
  79. package/dist/types/providers/capabilityNaming.d.ts +25 -0
  80. package/dist/types/providers/composite/CompositeCapabilityProvider.d.ts +22 -0
  81. package/dist/types/providers/composite/index.d.ts +1 -0
  82. package/dist/types/providers/index.d.ts +13 -0
  83. package/dist/types/providers/mcp/MCPCapabilityProvider.d.ts +54 -0
  84. package/dist/types/providers/mcp/config.d.ts +20 -0
  85. package/dist/types/providers/mcp/index.d.ts +5 -0
  86. package/dist/types/providers/mcp/transport.d.ts +18 -0
  87. package/dist/types/providers/mcp/types.d.ts +112 -0
  88. package/dist/types/providers/tools-server/ToolsServerCapabilityProvider.d.ts +45 -0
  89. package/dist/types/providers/tools-server/index.d.ts +1 -0
  90. package/dist/types/providers/types.d.ts +170 -0
  91. package/dist/types/tools/proxyTool.d.ts +55 -0
  92. package/dist/types/utils/credentials.d.ts +77 -0
  93. package/dist/types/utils/httpClient.d.ts +46 -0
  94. package/dist/types/utils/index.d.ts +3 -0
  95. package/dist/types/utils/toolManifest.d.ts +49 -0
  96. package/package.json +21 -1
  97. package/src/graphs/Graph.ts +0 -23
  98. package/src/index.ts +4 -0
  99. package/src/providers/__tests__/CompositeCapabilityProvider.test.ts +93 -0
  100. package/src/providers/__tests__/ToolsServerCapabilityProvider.integration.spec.ts +79 -0
  101. package/src/providers/__tests__/ToolsServerCapabilityProvider.test.ts +206 -0
  102. package/src/providers/__tests__/types.test.ts +64 -0
  103. package/src/providers/a2a/A2ACapabilityProvider.ts +384 -0
  104. package/src/providers/a2a/__tests__/A2ACapabilityProvider.integration.spec.ts +345 -0
  105. package/src/providers/a2a/__tests__/A2ACapabilityProvider.test.ts +460 -0
  106. package/src/providers/a2a/client.ts +115 -0
  107. package/src/providers/a2a/config.ts +40 -0
  108. package/src/providers/a2a/index.ts +29 -0
  109. package/src/providers/a2a/types.ts +191 -0
  110. package/src/providers/capabilityNaming.ts +42 -0
  111. package/src/providers/composite/CompositeCapabilityProvider.ts +112 -0
  112. package/src/providers/composite/index.ts +1 -0
  113. package/src/providers/index.ts +65 -0
  114. package/src/providers/mcp/MCPCapabilityProvider.ts +345 -0
  115. package/src/providers/mcp/__tests__/MCPCapabilityProvider.integration.spec.ts +386 -0
  116. package/src/providers/mcp/__tests__/MCPCapabilityProvider.test.ts +371 -0
  117. package/src/providers/mcp/config.ts +45 -0
  118. package/src/providers/mcp/index.ts +21 -0
  119. package/src/providers/mcp/transport.ts +76 -0
  120. package/src/providers/mcp/types.ts +139 -0
  121. package/src/providers/tools-server/ToolsServerCapabilityProvider.ts +220 -0
  122. package/src/providers/tools-server/index.ts +1 -0
  123. package/src/providers/types.ts +187 -0
  124. package/src/tools/proxyTool.ts +146 -0
  125. package/src/utils/__tests__/credentials.test.ts +130 -0
  126. package/src/utils/__tests__/httpClient.test.ts +75 -0
  127. package/src/utils/__tests__/toolManifest.test.ts +116 -0
  128. package/src/utils/credentials.ts +157 -0
  129. package/src/utils/httpClient.ts +92 -0
  130. package/src/utils/index.ts +3 -0
  131. package/src/utils/toolManifest.ts +109 -0
  132. package/src/agents/AgentContext.js.map +0 -1
  133. package/src/agents/AgentContext.test.js.map +0 -1
  134. package/src/agents/__tests__/AgentContext.test.js.map +0 -1
  135. package/src/agents/__tests__/resolveStructuredOutputMode.test.js.map +0 -1
  136. package/src/common/enum.js.map +0 -1
  137. package/src/common/index.js.map +0 -1
  138. package/src/events.js.map +0 -1
  139. package/src/graphs/Graph.js.map +0 -1
  140. package/src/graphs/MultiAgentGraph.js.map +0 -1
  141. package/src/graphs/__tests__/structured-output.integration.test.js.map +0 -1
  142. package/src/graphs/__tests__/structured-output.test.js.map +0 -1
  143. package/src/graphs/contextManagement.e2e.test.js.map +0 -1
  144. package/src/graphs/contextManagement.test.js.map +0 -1
  145. package/src/graphs/handoffValidation.test.js.map +0 -1
  146. package/src/graphs/index.js.map +0 -1
  147. package/src/index.js.map +0 -1
  148. package/src/instrumentation.js.map +0 -1
  149. package/src/llm/anthropic/index.js.map +0 -1
  150. package/src/llm/anthropic/types.js.map +0 -1
  151. package/src/llm/anthropic/utils/message_inputs.js.map +0 -1
  152. package/src/llm/anthropic/utils/message_outputs.js.map +0 -1
  153. package/src/llm/anthropic/utils/output_parsers.js.map +0 -1
  154. package/src/llm/anthropic/utils/tools.js.map +0 -1
  155. package/src/llm/bedrock/__tests__/bedrock-caching.test.js.map +0 -1
  156. package/src/llm/bedrock/index.js.map +0 -1
  157. package/src/llm/bedrock/types.js.map +0 -1
  158. package/src/llm/bedrock/utils/index.js.map +0 -1
  159. package/src/llm/bedrock/utils/message_inputs.js.map +0 -1
  160. package/src/llm/bedrock/utils/message_outputs.js.map +0 -1
  161. package/src/llm/fake.js.map +0 -1
  162. package/src/llm/google/index.js.map +0 -1
  163. package/src/llm/google/types.js.map +0 -1
  164. package/src/llm/google/utils/common.js.map +0 -1
  165. package/src/llm/google/utils/tools.js.map +0 -1
  166. package/src/llm/google/utils/zod_to_genai_parameters.js.map +0 -1
  167. package/src/llm/openai/index.js.map +0 -1
  168. package/src/llm/openai/types.js.map +0 -1
  169. package/src/llm/openai/utils/index.js.map +0 -1
  170. package/src/llm/openai/utils/isReasoningModel.test.js.map +0 -1
  171. package/src/llm/openrouter/index.js.map +0 -1
  172. package/src/llm/openrouter/reasoning.test.js.map +0 -1
  173. package/src/llm/providers.js.map +0 -1
  174. package/src/llm/text.js.map +0 -1
  175. package/src/llm/vertexai/index.js.map +0 -1
  176. package/src/messages/__tests__/tools.test.js.map +0 -1
  177. package/src/messages/cache.js.map +0 -1
  178. package/src/messages/cache.test.js.map +0 -1
  179. package/src/messages/content.js.map +0 -1
  180. package/src/messages/content.test.js.map +0 -1
  181. package/src/messages/core.js.map +0 -1
  182. package/src/messages/ensureThinkingBlock.test.js.map +0 -1
  183. package/src/messages/format.js.map +0 -1
  184. package/src/messages/formatAgentMessages.test.js.map +0 -1
  185. package/src/messages/formatAgentMessages.tools.test.js.map +0 -1
  186. package/src/messages/formatMessage.test.js.map +0 -1
  187. package/src/messages/ids.js.map +0 -1
  188. package/src/messages/index.js.map +0 -1
  189. package/src/messages/labelContentByAgent.test.js.map +0 -1
  190. package/src/messages/prune.js.map +0 -1
  191. package/src/messages/reducer.js.map +0 -1
  192. package/src/messages/shiftIndexTokenCountMap.test.js.map +0 -1
  193. package/src/messages/summarize.js.map +0 -1
  194. package/src/messages/summarize.test.js.map +0 -1
  195. package/src/messages/tools.js.map +0 -1
  196. package/src/mockStream.js.map +0 -1
  197. package/src/prompts/collab.js.map +0 -1
  198. package/src/prompts/index.js.map +0 -1
  199. package/src/prompts/taskmanager.js.map +0 -1
  200. package/src/run.js.map +0 -1
  201. package/src/schemas/index.js.map +0 -1
  202. package/src/schemas/schema-preparation.test.js.map +0 -1
  203. package/src/schemas/validate.js.map +0 -1
  204. package/src/schemas/validate.test.js.map +0 -1
  205. package/src/scripts/abort.js.map +0 -1
  206. package/src/scripts/ant_web_search.js.map +0 -1
  207. package/src/scripts/ant_web_search_edge_case.js.map +0 -1
  208. package/src/scripts/ant_web_search_error_edge_case.js.map +0 -1
  209. package/src/scripts/args.js.map +0 -1
  210. package/src/scripts/bedrock-cache-debug.js.map +0 -1
  211. package/src/scripts/bedrock-content-aggregation-test.js.map +0 -1
  212. package/src/scripts/bedrock-merge-test.js.map +0 -1
  213. package/src/scripts/bedrock-parallel-tools-test.js.map +0 -1
  214. package/src/scripts/caching.js.map +0 -1
  215. package/src/scripts/cli.js.map +0 -1
  216. package/src/scripts/cli2.js.map +0 -1
  217. package/src/scripts/cli3.js.map +0 -1
  218. package/src/scripts/cli4.js.map +0 -1
  219. package/src/scripts/cli5.js.map +0 -1
  220. package/src/scripts/code_exec.js.map +0 -1
  221. package/src/scripts/code_exec_files.js.map +0 -1
  222. package/src/scripts/code_exec_multi_session.js.map +0 -1
  223. package/src/scripts/code_exec_ptc.js.map +0 -1
  224. package/src/scripts/code_exec_session.js.map +0 -1
  225. package/src/scripts/code_exec_simple.js.map +0 -1
  226. package/src/scripts/content.js.map +0 -1
  227. package/src/scripts/empty_input.js.map +0 -1
  228. package/src/scripts/handoff-test.js.map +0 -1
  229. package/src/scripts/image.js.map +0 -1
  230. package/src/scripts/memory.js.map +0 -1
  231. package/src/scripts/multi-agent-chain.js.map +0 -1
  232. package/src/scripts/multi-agent-conditional.js.map +0 -1
  233. package/src/scripts/multi-agent-document-review-chain.js.map +0 -1
  234. package/src/scripts/multi-agent-hybrid-flow.js.map +0 -1
  235. package/src/scripts/multi-agent-parallel-start.js.map +0 -1
  236. package/src/scripts/multi-agent-parallel.js.map +0 -1
  237. package/src/scripts/multi-agent-sequence.js.map +0 -1
  238. package/src/scripts/multi-agent-supervisor.js.map +0 -1
  239. package/src/scripts/multi-agent-test.js.map +0 -1
  240. package/src/scripts/parallel-asymmetric-tools-test.js.map +0 -1
  241. package/src/scripts/parallel-full-metadata-test.js.map +0 -1
  242. package/src/scripts/parallel-tools-test.js.map +0 -1
  243. package/src/scripts/programmatic_exec.js.map +0 -1
  244. package/src/scripts/programmatic_exec_agent.js.map +0 -1
  245. package/src/scripts/search.js.map +0 -1
  246. package/src/scripts/sequential-full-metadata-test.js.map +0 -1
  247. package/src/scripts/simple.js.map +0 -1
  248. package/src/scripts/single-agent-metadata-test.js.map +0 -1
  249. package/src/scripts/stream.js.map +0 -1
  250. package/src/scripts/test-custom-prompt-key.js.map +0 -1
  251. package/src/scripts/test-handoff-input.js.map +0 -1
  252. package/src/scripts/test-handoff-preamble.js.map +0 -1
  253. package/src/scripts/test-handoff-steering.js.map +0 -1
  254. package/src/scripts/test-multi-agent-list-handoff.js.map +0 -1
  255. package/src/scripts/test-parallel-agent-labeling.js.map +0 -1
  256. package/src/scripts/test-parallel-handoffs.js.map +0 -1
  257. package/src/scripts/test-thinking-handoff-bedrock.js.map +0 -1
  258. package/src/scripts/test-thinking-handoff.js.map +0 -1
  259. package/src/scripts/test-thinking-to-thinking-handoff-bedrock.js.map +0 -1
  260. package/src/scripts/test-tool-before-handoff-role-order.js.map +0 -1
  261. package/src/scripts/test-tools-before-handoff.js.map +0 -1
  262. package/src/scripts/test_code_api.js.map +0 -1
  263. package/src/scripts/thinking-bedrock.js.map +0 -1
  264. package/src/scripts/thinking-vertexai.js.map +0 -1
  265. package/src/scripts/thinking.js.map +0 -1
  266. package/src/scripts/tool_search.js.map +0 -1
  267. package/src/scripts/tools.js.map +0 -1
  268. package/src/specs/agent-handoffs-bedrock.integration.test.js.map +0 -1
  269. package/src/specs/agent-handoffs.test.js.map +0 -1
  270. package/src/specs/anthropic.simple.test.js.map +0 -1
  271. package/src/specs/azure.simple.test.js.map +0 -1
  272. package/src/specs/cache.simple.test.js.map +0 -1
  273. package/src/specs/custom-event-await.test.js.map +0 -1
  274. package/src/specs/deepseek.simple.test.js.map +0 -1
  275. package/src/specs/emergency-prune.test.js.map +0 -1
  276. package/src/specs/moonshot.simple.test.js.map +0 -1
  277. package/src/specs/observability.integration.test.js.map +0 -1
  278. package/src/specs/openai.simple.test.js.map +0 -1
  279. package/src/specs/openrouter.simple.test.js.map +0 -1
  280. package/src/specs/prune.test.js.map +0 -1
  281. package/src/specs/reasoning.test.js.map +0 -1
  282. package/src/specs/spec.utils.js.map +0 -1
  283. package/src/specs/thinking-handoff.test.js.map +0 -1
  284. package/src/specs/thinking-prune.test.js.map +0 -1
  285. package/src/specs/token-distribution-edge-case.test.js.map +0 -1
  286. package/src/specs/token-memoization.test.js.map +0 -1
  287. package/src/specs/tokens.test.js.map +0 -1
  288. package/src/specs/tool-error.test.js.map +0 -1
  289. package/src/splitStream.js.map +0 -1
  290. package/src/splitStream.test.js.map +0 -1
  291. package/src/stream.js.map +0 -1
  292. package/src/stream.test.js.map +0 -1
  293. package/src/test/mockTools.js.map +0 -1
  294. package/src/tools/BrowserTools.js.map +0 -1
  295. package/src/tools/Calculator.js.map +0 -1
  296. package/src/tools/Calculator.test.js.map +0 -1
  297. package/src/tools/CodeExecutor.js.map +0 -1
  298. package/src/tools/ProgrammaticToolCalling.js.map +0 -1
  299. package/src/tools/StreamingToolCallBuffer.js.map +0 -1
  300. package/src/tools/ToolNode.js.map +0 -1
  301. package/src/tools/ToolSearch.js.map +0 -1
  302. package/src/tools/__tests__/BrowserTools.test.js.map +0 -1
  303. package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.js.map +0 -1
  304. package/src/tools/__tests__/ProgrammaticToolCalling.test.js.map +0 -1
  305. package/src/tools/__tests__/StreamingToolCallBuffer.test.js.map +0 -1
  306. package/src/tools/__tests__/ToolApproval.test.js.map +0 -1
  307. package/src/tools/__tests__/ToolNode.recovery.test.js.map +0 -1
  308. package/src/tools/__tests__/ToolNode.session.test.js.map +0 -1
  309. package/src/tools/__tests__/ToolSearch.integration.test.js.map +0 -1
  310. package/src/tools/__tests__/ToolSearch.test.js.map +0 -1
  311. package/src/tools/__tests__/handlers.test.js.map +0 -1
  312. package/src/tools/__tests__/truncation-recovery.integration.test.js.map +0 -1
  313. package/src/tools/handlers.js.map +0 -1
  314. package/src/tools/schema.js.map +0 -1
  315. package/src/tools/search/anthropic.js.map +0 -1
  316. package/src/tools/search/content.js.map +0 -1
  317. package/src/tools/search/content.test.js.map +0 -1
  318. package/src/tools/search/firecrawl.js.map +0 -1
  319. package/src/tools/search/format.js.map +0 -1
  320. package/src/tools/search/highlights.js.map +0 -1
  321. package/src/tools/search/index.js.map +0 -1
  322. package/src/tools/search/jina-reranker.test.js.map +0 -1
  323. package/src/tools/search/rerankers.js.map +0 -1
  324. package/src/tools/search/schema.js.map +0 -1
  325. package/src/tools/search/search.js.map +0 -1
  326. package/src/tools/search/serper-scraper.js.map +0 -1
  327. package/src/tools/search/test.js.map +0 -1
  328. package/src/tools/search/tool.js.map +0 -1
  329. package/src/tools/search/types.js.map +0 -1
  330. package/src/tools/search/utils.js.map +0 -1
  331. package/src/types/graph.js.map +0 -1
  332. package/src/types/graph.test.js.map +0 -1
  333. package/src/types/index.js.map +0 -1
  334. package/src/types/llm.js.map +0 -1
  335. package/src/types/messages.js.map +0 -1
  336. package/src/types/run.js.map +0 -1
  337. package/src/types/stream.js.map +0 -1
  338. package/src/types/tools.js.map +0 -1
  339. package/src/utils/contextAnalytics.js.map +0 -1
  340. package/src/utils/contextAnalytics.test.js.map +0 -1
  341. package/src/utils/events.js.map +0 -1
  342. package/src/utils/graph.js.map +0 -1
  343. package/src/utils/handlers.js.map +0 -1
  344. package/src/utils/index.js.map +0 -1
  345. package/src/utils/llm.js.map +0 -1
  346. package/src/utils/llmConfig.js.map +0 -1
  347. package/src/utils/logging.js.map +0 -1
  348. package/src/utils/misc.js.map +0 -1
  349. package/src/utils/run.js.map +0 -1
  350. package/src/utils/schema.js.map +0 -1
  351. package/src/utils/title.js.map +0 -1
  352. package/src/utils/tokens.js.map +0 -1
  353. package/src/utils/toonFormat.js.map +0 -1
@@ -0,0 +1,345 @@
1
+ /**
2
+ * Integration test — exercises A2ACapabilityProvider against a local HTTP
3
+ * server that implements the A2A protocol.
4
+ *
5
+ * The harness is a minimal pure-http A2A-compliant server:
6
+ * - GET /.well-known/agent.json → agent card
7
+ * - POST / → JSON-RPC dispatcher (tasks/send)
8
+ *
9
+ * Validates the same surface a real A2A-served agent exposes, without
10
+ * needing to boot the full CLI runner.
11
+ */
12
+
13
+ import { createServer, type Server as HttpServer } from 'node:http';
14
+ import type { AddressInfo } from 'node:net';
15
+
16
+ import {
17
+ A2ACapabilityProvider,
18
+ formatCapabilityName,
19
+ } from '../A2ACapabilityProvider';
20
+ import { CapabilityKind } from '../../types';
21
+ import type { A2AAgentCard, A2ATaskParams } from '../types';
22
+
23
+ // ---------------------------------------------------------------------------
24
+ // Minimal A2A HTTP harness
25
+ // ---------------------------------------------------------------------------
26
+
27
+ interface Harness {
28
+ url: string;
29
+ httpServer: HttpServer;
30
+ lastHeaders: Record<string, string>;
31
+ lastTaskMessage: string | undefined;
32
+ close: () => Promise<void>;
33
+ }
34
+
35
+ const CARD_FIXTURE: A2AAgentCard = {
36
+ name: 'research-assistant',
37
+ description: 'A test agent that echoes inbound messages.',
38
+ url: 'http://placeholder/', // overwritten after listen()
39
+ version: '1.0.0',
40
+ capabilities: { streaming: true },
41
+ defaultInputModes: ['text/plain'],
42
+ defaultOutputModes: ['text/plain'],
43
+ skills: [
44
+ {
45
+ id: 'echo',
46
+ name: 'Echo',
47
+ description: 'Return the inbound message as the response.',
48
+ tags: ['echo'],
49
+ },
50
+ {
51
+ id: 'upper',
52
+ name: 'Uppercase',
53
+ description: 'Return the inbound message in uppercase.',
54
+ tags: ['transform'],
55
+ },
56
+ ],
57
+ };
58
+
59
+ async function startLocalA2AServer(
60
+ opts: { requireAuth?: boolean } = {}
61
+ ): Promise<Harness> {
62
+ const lastHeaders: Record<string, string> = {};
63
+ let lastTaskMessage: string | undefined;
64
+
65
+ const httpServer = createServer(async (req, res) => {
66
+ for (const [k, v] of Object.entries(req.headers)) {
67
+ if (typeof v === 'string') lastHeaders[k.toLowerCase()] = v;
68
+ }
69
+
70
+ if (opts.requireAuth) {
71
+ const auth = req.headers['authorization'];
72
+ if (typeof auth !== 'string' || !auth.startsWith('Bearer ')) {
73
+ res.writeHead(401, { 'content-type': 'application/json' });
74
+ res.end(JSON.stringify({ error: 'unauthorized' }));
75
+ return;
76
+ }
77
+ }
78
+
79
+ const url = req.url ?? '';
80
+
81
+ // Agent card endpoint
82
+ if (req.method === 'GET' && url === '/.well-known/agent.json') {
83
+ res.writeHead(200, { 'content-type': 'application/json' });
84
+ res.end(
85
+ JSON.stringify({
86
+ ...CARD_FIXTURE,
87
+ url: `http://127.0.0.1:${(req.socket.localPort ?? 0).toString()}/`,
88
+ })
89
+ );
90
+ return;
91
+ }
92
+
93
+ // JSON-RPC endpoint
94
+ if (req.method === 'POST' && (url === '/' || url === '')) {
95
+ const chunks: Buffer[] = [];
96
+ for await (const chunk of req) chunks.push(chunk as Buffer);
97
+ const body = Buffer.concat(chunks).toString('utf8');
98
+
99
+ let parsed: {
100
+ jsonrpc: '2.0';
101
+ id: string | number | null;
102
+ method: string;
103
+ params: A2ATaskParams;
104
+ };
105
+ try {
106
+ parsed = JSON.parse(body);
107
+ } catch {
108
+ res.writeHead(400, { 'content-type': 'application/json' });
109
+ res.end(JSON.stringify({ error: 'invalid JSON' }));
110
+ return;
111
+ }
112
+
113
+ if (parsed.method !== 'tasks/send') {
114
+ res.writeHead(200, { 'content-type': 'application/json' });
115
+ res.end(
116
+ JSON.stringify({
117
+ jsonrpc: '2.0',
118
+ id: parsed.id,
119
+ error: {
120
+ code: -32601,
121
+ message: `Method not found: ${parsed.method}`,
122
+ },
123
+ })
124
+ );
125
+ return;
126
+ }
127
+
128
+ const text = parsed.params.message.parts[0]?.text ?? '';
129
+ lastTaskMessage = text;
130
+
131
+ const isUpper = text.includes('[skill: upper]');
132
+ // Strip the leading `[skill: xxx]\n` prefix before echoing.
133
+ const cleanText = text.replace(/^\[skill: [^\]]+\]\n?/, '');
134
+ const responseText = isUpper ? cleanText.toUpperCase() : cleanText;
135
+
136
+ const isFailSignal = cleanText === '__FAIL__';
137
+ if (isFailSignal) {
138
+ res.writeHead(200, { 'content-type': 'application/json' });
139
+ res.end(
140
+ JSON.stringify({
141
+ jsonrpc: '2.0',
142
+ id: parsed.id,
143
+ result: {
144
+ id: parsed.params.id,
145
+ status: { state: 'failed', timestamp: new Date().toISOString() },
146
+ error: { code: 500, message: 'intentional failure' },
147
+ },
148
+ })
149
+ );
150
+ return;
151
+ }
152
+
153
+ res.writeHead(200, { 'content-type': 'application/json' });
154
+ res.end(
155
+ JSON.stringify({
156
+ jsonrpc: '2.0',
157
+ id: parsed.id,
158
+ result: {
159
+ id: parsed.params.id,
160
+ status: { state: 'completed', timestamp: new Date().toISOString() },
161
+ artifacts: [{ parts: [{ type: 'text', text: responseText }] }],
162
+ },
163
+ })
164
+ );
165
+ return;
166
+ }
167
+
168
+ res.writeHead(404);
169
+ res.end();
170
+ });
171
+
172
+ await new Promise<void>((resolve) =>
173
+ httpServer.listen(0, '127.0.0.1', resolve)
174
+ );
175
+ const port = (httpServer.address() as AddressInfo).port;
176
+ const url = `http://127.0.0.1:${port}/`;
177
+
178
+ return {
179
+ url,
180
+ httpServer,
181
+ lastHeaders,
182
+ get lastTaskMessage() {
183
+ return lastTaskMessage;
184
+ },
185
+ close: () =>
186
+ new Promise<void>((resolve, reject) => {
187
+ httpServer.close((err) => (err ? reject(err) : resolve()));
188
+ }),
189
+ } as unknown as Harness;
190
+ }
191
+
192
+ // ---------------------------------------------------------------------------
193
+ // Tests
194
+ // ---------------------------------------------------------------------------
195
+
196
+ describe('A2ACapabilityProvider (live HTTP)', () => {
197
+ let harness: Harness;
198
+ let provider: A2ACapabilityProvider;
199
+
200
+ beforeAll(async () => {
201
+ harness = await startLocalA2AServer();
202
+ });
203
+
204
+ afterAll(async () => {
205
+ await provider?.close();
206
+ await harness.close();
207
+ });
208
+
209
+ it('fetches agent card and exposes one Capability per skill', async () => {
210
+ provider = new A2ACapabilityProvider({
211
+ remotes: { research: { url: harness.url } },
212
+ });
213
+
214
+ const caps = await provider.fetchManifest();
215
+ const names = caps.map((c) => c.name).sort();
216
+ expect(names).toEqual([
217
+ formatCapabilityName('research', 'echo'),
218
+ formatCapabilityName('research', 'upper'),
219
+ ]);
220
+ expect(caps[0].kind).toBe(CapabilityKind.A2A);
221
+ });
222
+
223
+ it('invokes a skill end-to-end and returns the remote response', async () => {
224
+ const caps = await provider.fetchManifest({
225
+ names: [formatCapabilityName('research', 'echo')],
226
+ });
227
+ expect(caps).toHaveLength(1);
228
+
229
+ const [runnable] = await provider.createRunnables(caps, {});
230
+ const result = await runnable.invoke({ message: 'hello world' });
231
+ expect(result).toBe('hello world');
232
+ });
233
+
234
+ it('routes skill-specific behavior via the skillId marker', async () => {
235
+ const caps = await provider.fetchManifest({
236
+ names: [formatCapabilityName('research', 'upper')],
237
+ });
238
+ const [runnable] = await provider.createRunnables(caps, {});
239
+ const result = await runnable.invoke({ message: 'hi' });
240
+ expect(result).toBe('HI');
241
+ });
242
+
243
+ it('surfaces a failed task as a thrown error', async () => {
244
+ const caps = await provider.fetchManifest({
245
+ names: [formatCapabilityName('research', 'echo')],
246
+ });
247
+ const [runnable] = await provider.createRunnables(caps, {});
248
+ await expect(runnable.invoke({ message: '__FAIL__' })).rejects.toThrow(
249
+ /intentional failure/
250
+ );
251
+ });
252
+ });
253
+
254
+ describe('A2ACapabilityProvider — auth header forwarding', () => {
255
+ let harness: Harness;
256
+ let provider: A2ACapabilityProvider;
257
+
258
+ beforeAll(async () => {
259
+ harness = await startLocalA2AServer({ requireAuth: true });
260
+ });
261
+
262
+ afterAll(async () => {
263
+ await provider?.close();
264
+ await harness.close();
265
+ });
266
+
267
+ it('rejects without auth (server 401 → empty manifest)', async () => {
268
+ provider = new A2ACapabilityProvider({
269
+ remotes: { secure: { url: harness.url } },
270
+ });
271
+ const caps = await provider.fetchManifest();
272
+ expect(caps).toEqual([]);
273
+ });
274
+
275
+ it('succeeds when getAuthHeaders supplies a Bearer token', async () => {
276
+ provider = new A2ACapabilityProvider({
277
+ remotes: { secure: { url: harness.url } },
278
+ getAuthHeaders: () => ({ Authorization: 'Bearer a2a-test-token' }),
279
+ });
280
+ const caps = await provider.fetchManifest();
281
+ expect(caps.length).toBeGreaterThan(0);
282
+ expect(harness.lastHeaders['authorization']).toBe('Bearer a2a-test-token');
283
+ });
284
+ });
285
+
286
+ describe('A2ACapabilityProvider — config-source patterns', () => {
287
+ let harness: Harness;
288
+
289
+ beforeAll(async () => {
290
+ harness = await startLocalA2AServer();
291
+ });
292
+
293
+ afterAll(async () => {
294
+ await harness.close();
295
+ });
296
+
297
+ const verifyRemote = async (p: A2ACapabilityProvider): Promise<void> => {
298
+ const caps = await p.fetchManifest();
299
+ expect(caps.length).toBeGreaterThan(0);
300
+ const echoCap = caps.find((c) => c.name.endsWith('__echo'));
301
+ expect(echoCap).toBeDefined();
302
+ const [runnable] = await p.createRunnables([echoCap!], {});
303
+ const result = await runnable.invoke({ message: 'ok' });
304
+ expect(result).toBe('ok');
305
+ await p.close();
306
+ };
307
+
308
+ it('direct programmatic spec', async () => {
309
+ const p = new A2ACapabilityProvider({
310
+ remotes: { mine: { url: harness.url } },
311
+ });
312
+ await verifyRemote(p);
313
+ });
314
+
315
+ it('YAML-derived spec (simulated)', async () => {
316
+ const yamlLike = {
317
+ remote_agents: [{ name: 'from-yaml', url: harness.url }],
318
+ };
319
+ const remotes: Record<string, { url: string }> = {};
320
+ for (const entry of yamlLike.remote_agents) {
321
+ remotes[entry.name] = { url: entry.url };
322
+ }
323
+ const p = new A2ACapabilityProvider({ remotes });
324
+ await verifyRemote(p);
325
+ });
326
+
327
+ it('marketplace-catalog-derived spec (simulated)', async () => {
328
+ const marketplaceEntry = {
329
+ id: 'market-agent',
330
+ name: 'Market Agent',
331
+ transport: 'a2a' as const,
332
+ url: harness.url,
333
+ authConfig: [{ authField: 'A2A_MARKET_TOKEN', required: false }],
334
+ };
335
+ const p = new A2ACapabilityProvider({
336
+ remotes: {
337
+ [marketplaceEntry.id]: { url: marketplaceEntry.url },
338
+ },
339
+ getAuthHeaders: () => ({
340
+ 'x-market-token': 'resolved-by-host',
341
+ }),
342
+ });
343
+ await verifyRemote(p);
344
+ });
345
+ });