@illuma-ai/agents 1.3.1 → 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.
- package/dist/cjs/graphs/Graph.cjs +3 -18
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +3 -0
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +58 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/providers/a2a/A2ACapabilityProvider.cjs +288 -0
- package/dist/cjs/providers/a2a/A2ACapabilityProvider.cjs.map +1 -0
- package/dist/cjs/providers/a2a/client.cjs +92 -0
- package/dist/cjs/providers/a2a/client.cjs.map +1 -0
- package/dist/cjs/providers/a2a/config.cjs +38 -0
- package/dist/cjs/providers/a2a/config.cjs.map +1 -0
- package/dist/cjs/providers/capabilityNaming.cjs +43 -0
- package/dist/cjs/providers/capabilityNaming.cjs.map +1 -0
- package/dist/cjs/providers/composite/CompositeCapabilityProvider.cjs +80 -0
- package/dist/cjs/providers/composite/CompositeCapabilityProvider.cjs.map +1 -0
- package/dist/cjs/providers/mcp/MCPCapabilityProvider.cjs +244 -0
- package/dist/cjs/providers/mcp/MCPCapabilityProvider.cjs.map +1 -0
- package/dist/cjs/providers/mcp/config.cjs +42 -0
- package/dist/cjs/providers/mcp/config.cjs.map +1 -0
- package/dist/cjs/providers/mcp/transport.cjs +65 -0
- package/dist/cjs/providers/mcp/transport.cjs.map +1 -0
- package/dist/cjs/providers/tools-server/ToolsServerCapabilityProvider.cjs +121 -0
- package/dist/cjs/providers/tools-server/ToolsServerCapabilityProvider.cjs.map +1 -0
- package/dist/cjs/providers/types.cjs +51 -0
- package/dist/cjs/providers/types.cjs.map +1 -0
- package/dist/cjs/tools/ToolNode.cjs +3 -0
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/proxyTool.cjs +100 -0
- package/dist/cjs/tools/proxyTool.cjs.map +1 -0
- package/dist/cjs/utils/credentials.cjs +142 -0
- package/dist/cjs/utils/credentials.cjs.map +1 -0
- package/dist/cjs/utils/httpClient.cjs +74 -0
- package/dist/cjs/utils/httpClient.cjs.map +1 -0
- package/dist/cjs/utils/toolManifest.cjs +100 -0
- package/dist/cjs/utils/toolManifest.cjs.map +1 -0
- package/dist/esm/graphs/Graph.mjs +3 -18
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +3 -0
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +14 -0
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/providers/a2a/A2ACapabilityProvider.mjs +281 -0
- package/dist/esm/providers/a2a/A2ACapabilityProvider.mjs.map +1 -0
- package/dist/esm/providers/a2a/client.mjs +88 -0
- package/dist/esm/providers/a2a/client.mjs.map +1 -0
- package/dist/esm/providers/a2a/config.mjs +35 -0
- package/dist/esm/providers/a2a/config.mjs.map +1 -0
- package/dist/esm/providers/capabilityNaming.mjs +39 -0
- package/dist/esm/providers/capabilityNaming.mjs.map +1 -0
- package/dist/esm/providers/composite/CompositeCapabilityProvider.mjs +78 -0
- package/dist/esm/providers/composite/CompositeCapabilityProvider.mjs.map +1 -0
- package/dist/esm/providers/mcp/MCPCapabilityProvider.mjs +240 -0
- package/dist/esm/providers/mcp/MCPCapabilityProvider.mjs.map +1 -0
- package/dist/esm/providers/mcp/config.mjs +39 -0
- package/dist/esm/providers/mcp/config.mjs.map +1 -0
- package/dist/esm/providers/mcp/transport.mjs +63 -0
- package/dist/esm/providers/mcp/transport.mjs.map +1 -0
- package/dist/esm/providers/tools-server/ToolsServerCapabilityProvider.mjs +119 -0
- package/dist/esm/providers/tools-server/ToolsServerCapabilityProvider.mjs.map +1 -0
- package/dist/esm/providers/types.mjs +51 -0
- package/dist/esm/providers/types.mjs.map +1 -0
- package/dist/esm/tools/ToolNode.mjs +3 -0
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/proxyTool.mjs +98 -0
- package/dist/esm/tools/proxyTool.mjs.map +1 -0
- package/dist/esm/utils/credentials.mjs +135 -0
- package/dist/esm/utils/credentials.mjs.map +1 -0
- package/dist/esm/utils/httpClient.mjs +70 -0
- package/dist/esm/utils/httpClient.mjs.map +1 -0
- package/dist/esm/utils/toolManifest.mjs +96 -0
- package/dist/esm/utils/toolManifest.mjs.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/providers/a2a/A2ACapabilityProvider.d.ts +89 -0
- package/dist/types/providers/a2a/client.d.ts +47 -0
- package/dist/types/providers/a2a/config.d.ts +18 -0
- package/dist/types/providers/a2a/index.d.ts +6 -0
- package/dist/types/providers/a2a/types.d.ts +173 -0
- package/dist/types/providers/capabilityNaming.d.ts +25 -0
- package/dist/types/providers/composite/CompositeCapabilityProvider.d.ts +22 -0
- package/dist/types/providers/composite/index.d.ts +1 -0
- package/dist/types/providers/index.d.ts +13 -0
- package/dist/types/providers/mcp/MCPCapabilityProvider.d.ts +54 -0
- package/dist/types/providers/mcp/config.d.ts +20 -0
- package/dist/types/providers/mcp/index.d.ts +5 -0
- package/dist/types/providers/mcp/transport.d.ts +18 -0
- package/dist/types/providers/mcp/types.d.ts +112 -0
- package/dist/types/providers/tools-server/ToolsServerCapabilityProvider.d.ts +45 -0
- package/dist/types/providers/tools-server/index.d.ts +1 -0
- package/dist/types/providers/types.d.ts +170 -0
- package/dist/types/tools/proxyTool.d.ts +55 -0
- package/dist/types/types/stream.d.ts +10 -0
- package/dist/types/utils/credentials.d.ts +77 -0
- package/dist/types/utils/httpClient.d.ts +46 -0
- package/dist/types/utils/index.d.ts +3 -0
- package/dist/types/utils/toolManifest.d.ts +49 -0
- package/package.json +21 -1
- package/src/graphs/Graph.ts +0 -23
- package/src/index.ts +4 -0
- package/src/providers/__tests__/CompositeCapabilityProvider.test.ts +93 -0
- package/src/providers/__tests__/ToolsServerCapabilityProvider.integration.spec.ts +79 -0
- package/src/providers/__tests__/ToolsServerCapabilityProvider.test.ts +206 -0
- package/src/providers/__tests__/types.test.ts +64 -0
- package/src/providers/a2a/A2ACapabilityProvider.ts +384 -0
- package/src/providers/a2a/__tests__/A2ACapabilityProvider.integration.spec.ts +345 -0
- package/src/providers/a2a/__tests__/A2ACapabilityProvider.test.ts +460 -0
- package/src/providers/a2a/client.ts +115 -0
- package/src/providers/a2a/config.ts +40 -0
- package/src/providers/a2a/index.ts +29 -0
- package/src/providers/a2a/types.ts +191 -0
- package/src/providers/capabilityNaming.ts +42 -0
- package/src/providers/composite/CompositeCapabilityProvider.ts +112 -0
- package/src/providers/composite/index.ts +1 -0
- package/src/providers/index.ts +65 -0
- package/src/providers/mcp/MCPCapabilityProvider.ts +345 -0
- package/src/providers/mcp/__tests__/MCPCapabilityProvider.integration.spec.ts +386 -0
- package/src/providers/mcp/__tests__/MCPCapabilityProvider.test.ts +371 -0
- package/src/providers/mcp/config.ts +45 -0
- package/src/providers/mcp/index.ts +21 -0
- package/src/providers/mcp/transport.ts +76 -0
- package/src/providers/mcp/types.ts +139 -0
- package/src/providers/tools-server/ToolsServerCapabilityProvider.ts +220 -0
- package/src/providers/tools-server/index.ts +1 -0
- package/src/providers/types.ts +187 -0
- package/src/tools/proxyTool.ts +146 -0
- package/src/types/stream.ts +10 -0
- package/src/utils/__tests__/credentials.test.ts +130 -0
- package/src/utils/__tests__/errors.test.ts +6 -4
- package/src/utils/__tests__/httpClient.test.ts +75 -0
- package/src/utils/__tests__/toolManifest.test.ts +116 -0
- package/src/utils/credentials.ts +157 -0
- package/src/utils/httpClient.ts +92 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/toolManifest.ts +109 -0
- package/src/agents/AgentContext.js.map +0 -1
- package/src/agents/AgentContext.test.js.map +0 -1
- package/src/agents/__tests__/AgentContext.test.js.map +0 -1
- package/src/agents/__tests__/resolveStructuredOutputMode.test.js.map +0 -1
- package/src/common/enum.js.map +0 -1
- package/src/common/index.js.map +0 -1
- package/src/events.js.map +0 -1
- package/src/graphs/Graph.js.map +0 -1
- package/src/graphs/MultiAgentGraph.js.map +0 -1
- package/src/graphs/__tests__/structured-output.integration.test.js.map +0 -1
- package/src/graphs/__tests__/structured-output.test.js.map +0 -1
- package/src/graphs/contextManagement.e2e.test.js.map +0 -1
- package/src/graphs/contextManagement.test.js.map +0 -1
- package/src/graphs/handoffValidation.test.js.map +0 -1
- package/src/graphs/index.js.map +0 -1
- package/src/index.js.map +0 -1
- package/src/instrumentation.js.map +0 -1
- package/src/llm/anthropic/index.js.map +0 -1
- package/src/llm/anthropic/types.js.map +0 -1
- package/src/llm/anthropic/utils/message_inputs.js.map +0 -1
- package/src/llm/anthropic/utils/message_outputs.js.map +0 -1
- package/src/llm/anthropic/utils/output_parsers.js.map +0 -1
- package/src/llm/anthropic/utils/tools.js.map +0 -1
- package/src/llm/bedrock/__tests__/bedrock-caching.test.js.map +0 -1
- package/src/llm/bedrock/index.js.map +0 -1
- package/src/llm/bedrock/types.js.map +0 -1
- package/src/llm/bedrock/utils/index.js.map +0 -1
- package/src/llm/bedrock/utils/message_inputs.js.map +0 -1
- package/src/llm/bedrock/utils/message_outputs.js.map +0 -1
- package/src/llm/fake.js.map +0 -1
- package/src/llm/google/index.js.map +0 -1
- package/src/llm/google/types.js.map +0 -1
- package/src/llm/google/utils/common.js.map +0 -1
- package/src/llm/google/utils/tools.js.map +0 -1
- package/src/llm/google/utils/zod_to_genai_parameters.js.map +0 -1
- package/src/llm/openai/index.js.map +0 -1
- package/src/llm/openai/types.js.map +0 -1
- package/src/llm/openai/utils/index.js.map +0 -1
- package/src/llm/openai/utils/isReasoningModel.test.js.map +0 -1
- package/src/llm/openrouter/index.js.map +0 -1
- package/src/llm/openrouter/reasoning.test.js.map +0 -1
- package/src/llm/providers.js.map +0 -1
- package/src/llm/text.js.map +0 -1
- package/src/llm/vertexai/index.js.map +0 -1
- package/src/messages/__tests__/tools.test.js.map +0 -1
- package/src/messages/cache.js.map +0 -1
- package/src/messages/cache.test.js.map +0 -1
- package/src/messages/content.js.map +0 -1
- package/src/messages/content.test.js.map +0 -1
- package/src/messages/core.js.map +0 -1
- package/src/messages/ensureThinkingBlock.test.js.map +0 -1
- package/src/messages/format.js.map +0 -1
- package/src/messages/formatAgentMessages.test.js.map +0 -1
- package/src/messages/formatAgentMessages.tools.test.js.map +0 -1
- package/src/messages/formatMessage.test.js.map +0 -1
- package/src/messages/ids.js.map +0 -1
- package/src/messages/index.js.map +0 -1
- package/src/messages/labelContentByAgent.test.js.map +0 -1
- package/src/messages/prune.js.map +0 -1
- package/src/messages/reducer.js.map +0 -1
- package/src/messages/shiftIndexTokenCountMap.test.js.map +0 -1
- package/src/messages/summarize.js.map +0 -1
- package/src/messages/summarize.test.js.map +0 -1
- package/src/messages/tools.js.map +0 -1
- package/src/mockStream.js.map +0 -1
- package/src/prompts/collab.js.map +0 -1
- package/src/prompts/index.js.map +0 -1
- package/src/prompts/taskmanager.js.map +0 -1
- package/src/run.js.map +0 -1
- package/src/schemas/index.js.map +0 -1
- package/src/schemas/schema-preparation.test.js.map +0 -1
- package/src/schemas/validate.js.map +0 -1
- package/src/schemas/validate.test.js.map +0 -1
- package/src/scripts/abort.js.map +0 -1
- package/src/scripts/ant_web_search.js.map +0 -1
- package/src/scripts/ant_web_search_edge_case.js.map +0 -1
- package/src/scripts/ant_web_search_error_edge_case.js.map +0 -1
- package/src/scripts/args.js.map +0 -1
- package/src/scripts/bedrock-cache-debug.js.map +0 -1
- package/src/scripts/bedrock-content-aggregation-test.js.map +0 -1
- package/src/scripts/bedrock-merge-test.js.map +0 -1
- package/src/scripts/bedrock-parallel-tools-test.js.map +0 -1
- package/src/scripts/caching.js.map +0 -1
- package/src/scripts/cli.js.map +0 -1
- package/src/scripts/cli2.js.map +0 -1
- package/src/scripts/cli3.js.map +0 -1
- package/src/scripts/cli4.js.map +0 -1
- package/src/scripts/cli5.js.map +0 -1
- package/src/scripts/code_exec.js.map +0 -1
- package/src/scripts/code_exec_files.js.map +0 -1
- package/src/scripts/code_exec_multi_session.js.map +0 -1
- package/src/scripts/code_exec_ptc.js.map +0 -1
- package/src/scripts/code_exec_session.js.map +0 -1
- package/src/scripts/code_exec_simple.js.map +0 -1
- package/src/scripts/content.js.map +0 -1
- package/src/scripts/empty_input.js.map +0 -1
- package/src/scripts/handoff-test.js.map +0 -1
- package/src/scripts/image.js.map +0 -1
- package/src/scripts/memory.js.map +0 -1
- package/src/scripts/multi-agent-chain.js.map +0 -1
- package/src/scripts/multi-agent-conditional.js.map +0 -1
- package/src/scripts/multi-agent-document-review-chain.js.map +0 -1
- package/src/scripts/multi-agent-hybrid-flow.js.map +0 -1
- package/src/scripts/multi-agent-parallel-start.js.map +0 -1
- package/src/scripts/multi-agent-parallel.js.map +0 -1
- package/src/scripts/multi-agent-sequence.js.map +0 -1
- package/src/scripts/multi-agent-supervisor.js.map +0 -1
- package/src/scripts/multi-agent-test.js.map +0 -1
- package/src/scripts/parallel-asymmetric-tools-test.js.map +0 -1
- package/src/scripts/parallel-full-metadata-test.js.map +0 -1
- package/src/scripts/parallel-tools-test.js.map +0 -1
- package/src/scripts/programmatic_exec.js.map +0 -1
- package/src/scripts/programmatic_exec_agent.js.map +0 -1
- package/src/scripts/search.js.map +0 -1
- package/src/scripts/sequential-full-metadata-test.js.map +0 -1
- package/src/scripts/simple.js.map +0 -1
- package/src/scripts/single-agent-metadata-test.js.map +0 -1
- package/src/scripts/stream.js.map +0 -1
- package/src/scripts/test-custom-prompt-key.js.map +0 -1
- package/src/scripts/test-handoff-input.js.map +0 -1
- package/src/scripts/test-handoff-preamble.js.map +0 -1
- package/src/scripts/test-handoff-steering.js.map +0 -1
- package/src/scripts/test-multi-agent-list-handoff.js.map +0 -1
- package/src/scripts/test-parallel-agent-labeling.js.map +0 -1
- package/src/scripts/test-parallel-handoffs.js.map +0 -1
- package/src/scripts/test-thinking-handoff-bedrock.js.map +0 -1
- package/src/scripts/test-thinking-handoff.js.map +0 -1
- package/src/scripts/test-thinking-to-thinking-handoff-bedrock.js.map +0 -1
- package/src/scripts/test-tool-before-handoff-role-order.js.map +0 -1
- package/src/scripts/test-tools-before-handoff.js.map +0 -1
- package/src/scripts/test_code_api.js.map +0 -1
- package/src/scripts/thinking-bedrock.js.map +0 -1
- package/src/scripts/thinking-vertexai.js.map +0 -1
- package/src/scripts/thinking.js.map +0 -1
- package/src/scripts/tool_search.js.map +0 -1
- package/src/scripts/tools.js.map +0 -1
- package/src/specs/agent-handoffs-bedrock.integration.test.js.map +0 -1
- package/src/specs/agent-handoffs.test.js.map +0 -1
- package/src/specs/anthropic.simple.test.js.map +0 -1
- package/src/specs/azure.simple.test.js.map +0 -1
- package/src/specs/cache.simple.test.js.map +0 -1
- package/src/specs/custom-event-await.test.js.map +0 -1
- package/src/specs/deepseek.simple.test.js.map +0 -1
- package/src/specs/emergency-prune.test.js.map +0 -1
- package/src/specs/moonshot.simple.test.js.map +0 -1
- package/src/specs/observability.integration.test.js.map +0 -1
- package/src/specs/openai.simple.test.js.map +0 -1
- package/src/specs/openrouter.simple.test.js.map +0 -1
- package/src/specs/prune.test.js.map +0 -1
- package/src/specs/reasoning.test.js.map +0 -1
- package/src/specs/spec.utils.js.map +0 -1
- package/src/specs/thinking-handoff.test.js.map +0 -1
- package/src/specs/thinking-prune.test.js.map +0 -1
- package/src/specs/token-distribution-edge-case.test.js.map +0 -1
- package/src/specs/token-memoization.test.js.map +0 -1
- package/src/specs/tokens.test.js.map +0 -1
- package/src/specs/tool-error.test.js.map +0 -1
- package/src/splitStream.js.map +0 -1
- package/src/splitStream.test.js.map +0 -1
- package/src/stream.js.map +0 -1
- package/src/stream.test.js.map +0 -1
- package/src/test/mockTools.js.map +0 -1
- package/src/tools/BrowserTools.js.map +0 -1
- package/src/tools/Calculator.js.map +0 -1
- package/src/tools/Calculator.test.js.map +0 -1
- package/src/tools/CodeExecutor.js.map +0 -1
- package/src/tools/ProgrammaticToolCalling.js.map +0 -1
- package/src/tools/StreamingToolCallBuffer.js.map +0 -1
- package/src/tools/ToolNode.js.map +0 -1
- package/src/tools/ToolSearch.js.map +0 -1
- package/src/tools/__tests__/BrowserTools.test.js.map +0 -1
- package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.js.map +0 -1
- package/src/tools/__tests__/ProgrammaticToolCalling.test.js.map +0 -1
- package/src/tools/__tests__/StreamingToolCallBuffer.test.js.map +0 -1
- package/src/tools/__tests__/ToolApproval.test.js.map +0 -1
- package/src/tools/__tests__/ToolNode.recovery.test.js.map +0 -1
- package/src/tools/__tests__/ToolNode.session.test.js.map +0 -1
- package/src/tools/__tests__/ToolSearch.integration.test.js.map +0 -1
- package/src/tools/__tests__/ToolSearch.test.js.map +0 -1
- package/src/tools/__tests__/handlers.test.js.map +0 -1
- package/src/tools/__tests__/truncation-recovery.integration.test.js.map +0 -1
- package/src/tools/handlers.js.map +0 -1
- package/src/tools/schema.js.map +0 -1
- package/src/tools/search/anthropic.js.map +0 -1
- package/src/tools/search/content.js.map +0 -1
- package/src/tools/search/content.test.js.map +0 -1
- package/src/tools/search/firecrawl.js.map +0 -1
- package/src/tools/search/format.js.map +0 -1
- package/src/tools/search/highlights.js.map +0 -1
- package/src/tools/search/index.js.map +0 -1
- package/src/tools/search/jina-reranker.test.js.map +0 -1
- package/src/tools/search/rerankers.js.map +0 -1
- package/src/tools/search/schema.js.map +0 -1
- package/src/tools/search/search.js.map +0 -1
- package/src/tools/search/serper-scraper.js.map +0 -1
- package/src/tools/search/test.js.map +0 -1
- package/src/tools/search/tool.js.map +0 -1
- package/src/tools/search/types.js.map +0 -1
- package/src/tools/search/utils.js.map +0 -1
- package/src/types/graph.js.map +0 -1
- package/src/types/graph.test.js.map +0 -1
- package/src/types/index.js.map +0 -1
- package/src/types/llm.js.map +0 -1
- package/src/types/messages.js.map +0 -1
- package/src/types/run.js.map +0 -1
- package/src/types/stream.js.map +0 -1
- package/src/types/tools.js.map +0 -1
- package/src/utils/contextAnalytics.js.map +0 -1
- package/src/utils/contextAnalytics.test.js.map +0 -1
- package/src/utils/events.js.map +0 -1
- package/src/utils/graph.js.map +0 -1
- package/src/utils/handlers.js.map +0 -1
- package/src/utils/index.js.map +0 -1
- package/src/utils/llm.js.map +0 -1
- package/src/utils/llmConfig.js.map +0 -1
- package/src/utils/logging.js.map +0 -1
- package/src/utils/misc.js.map +0 -1
- package/src/utils/run.js.map +0 -1
- package/src/utils/schema.js.map +0 -1
- package/src/utils/title.js.map +0 -1
- package/src/utils/tokens.js.map +0 -1
- package/src/utils/toonFormat.js.map +0 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* proxyTool — wraps a Capability into a LangChain StructuredTool that
|
|
3
|
+
* dispatches execution to a remote backend (e.g., tools-server) over HTTP.
|
|
4
|
+
*
|
|
5
|
+
* The LLM sees this tool identically to a locally-implemented tool:
|
|
6
|
+
* - same name
|
|
7
|
+
* - same description
|
|
8
|
+
* - same input schema (JSON Schema)
|
|
9
|
+
* - same invoke(input) contract
|
|
10
|
+
*
|
|
11
|
+
* Under the hood, invoke() POSTs to the backend's execute endpoint with
|
|
12
|
+
* the input and a caller-supplied credential map. The backend returns
|
|
13
|
+
* { success, result, error, timing } which this wrapper unpacks.
|
|
14
|
+
*/
|
|
15
|
+
import type { AxiosInstance } from 'axios';
|
|
16
|
+
import { type StructuredToolInterface } from '@langchain/core/tools';
|
|
17
|
+
import type { Capability, CredentialMap } from '@/providers/types';
|
|
18
|
+
/** Shape of the backend's execute response. Matches tools-server. */
|
|
19
|
+
export interface ExecuteResponse {
|
|
20
|
+
success: boolean;
|
|
21
|
+
result?: unknown;
|
|
22
|
+
error?: string;
|
|
23
|
+
timing?: {
|
|
24
|
+
durationMs: number;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** Options passed to buildProxyTool. */
|
|
28
|
+
export interface ProxyToolOptions {
|
|
29
|
+
/** HTTP client configured with backend base URL + auth. */
|
|
30
|
+
client: AxiosInstance;
|
|
31
|
+
/**
|
|
32
|
+
* Path template for execution. The literal `:name` is replaced with the
|
|
33
|
+
* capability's name. Defaults to `/execute/:name` (tools-server convention).
|
|
34
|
+
*/
|
|
35
|
+
executePath?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Optional callback invoked on every execution — used for metrics,
|
|
38
|
+
* telemetry, debug logging. Errors in the hook are swallowed.
|
|
39
|
+
*/
|
|
40
|
+
onExecute?: (ctx: ExecuteCallbackContext) => void;
|
|
41
|
+
}
|
|
42
|
+
export interface ExecuteCallbackContext {
|
|
43
|
+
capabilityName: string;
|
|
44
|
+
input: unknown;
|
|
45
|
+
response?: ExecuteResponse;
|
|
46
|
+
error?: Error;
|
|
47
|
+
durationMs: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Build a StructuredTool that proxies to a remote backend.
|
|
51
|
+
*
|
|
52
|
+
* The credentialMap is baked into the closure — callers that need
|
|
53
|
+
* per-invocation credential rotation should rebuild the tool.
|
|
54
|
+
*/
|
|
55
|
+
export declare function buildProxyTool(capability: Capability, credentials: CredentialMap, options: ProxyToolOptions): StructuredToolInterface;
|
|
@@ -116,6 +116,16 @@ export type ToolCallsDetails = {
|
|
|
116
116
|
export type ToolCallDelta = {
|
|
117
117
|
type: StepTypes;
|
|
118
118
|
tool_calls?: ToolCallChunk[];
|
|
119
|
+
/**
|
|
120
|
+
* Auth URL for tool calls that require interactive authentication
|
|
121
|
+
* (typically OAuth-gated MCP tools). Hosts populate this on a delta
|
|
122
|
+
* dispatch when a tool invocation surfaces an auth challenge so the
|
|
123
|
+
* client can render an approval prompt without waiting for the call
|
|
124
|
+
* to complete.
|
|
125
|
+
*/
|
|
126
|
+
auth?: string;
|
|
127
|
+
/** Auth challenge expiration (UNIX seconds). Pairs with `auth`. */
|
|
128
|
+
expires_at?: number;
|
|
119
129
|
};
|
|
120
130
|
export type AgentToolCall = {
|
|
121
131
|
id: string;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential merging utility for capability providers.
|
|
3
|
+
*
|
|
4
|
+
* The host is the source of truth for credential values. It resolves them
|
|
5
|
+
* from env vars, user settings, or active OAuth sessions, then passes a
|
|
6
|
+
* flat CredentialMap to the provider.
|
|
7
|
+
*
|
|
8
|
+
* This utility helps hosts build that map from multiple sources with clear
|
|
9
|
+
* precedence rules. Providers themselves do NOT use this — they just receive
|
|
10
|
+
* the finished map.
|
|
11
|
+
*/
|
|
12
|
+
import type { AuthConfigEntry, Capability, CredentialMap } from '@/providers/types';
|
|
13
|
+
/**
|
|
14
|
+
* Source of a credential value in the merged result. Useful for logging
|
|
15
|
+
* and debugging which layer won a given authField.
|
|
16
|
+
*/
|
|
17
|
+
export declare enum CredentialOrigin {
|
|
18
|
+
/** From the caller's process env (typically the CLI). */
|
|
19
|
+
ENV = "env",
|
|
20
|
+
/** From the agent definition's tool_credentials block. */
|
|
21
|
+
AGENT = "agent",
|
|
22
|
+
/** From the user's stored credentials in the host's credential store. */
|
|
23
|
+
USER = "user",
|
|
24
|
+
/** From an active OAuth session forwarded by the host. */
|
|
25
|
+
SESSION = "session",
|
|
26
|
+
/** Injected by the host at runtime for another reason. */
|
|
27
|
+
RUNTIME = "runtime"
|
|
28
|
+
}
|
|
29
|
+
/** One layer of credentials with its origin. */
|
|
30
|
+
export interface CredentialLayer {
|
|
31
|
+
origin: CredentialOrigin;
|
|
32
|
+
values: CredentialMap;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Merge credential layers with earlier layers overriding later ones.
|
|
36
|
+
*
|
|
37
|
+
* Typical host flow (in order of precedence):
|
|
38
|
+
* 1. runtime overrides (e.g., test injection) → RUNTIME
|
|
39
|
+
* 2. active OAuth session tokens → SESSION
|
|
40
|
+
* 3. agent-defined tool_credentials → AGENT
|
|
41
|
+
* 4. user's stored credentials → USER
|
|
42
|
+
* 5. process env → ENV
|
|
43
|
+
*
|
|
44
|
+
* Caller passes layers in precedence order (highest first).
|
|
45
|
+
*/
|
|
46
|
+
export declare function mergeCredentials(...layers: CredentialLayer[]): CredentialMap;
|
|
47
|
+
/**
|
|
48
|
+
* Given a set of capabilities, return the union of authField names they
|
|
49
|
+
* require. Useful for hosts that want to pre-resolve credentials before
|
|
50
|
+
* calling createRunnables.
|
|
51
|
+
*/
|
|
52
|
+
export declare function collectRequiredAuthFields(capabilities: Capability[]): string[];
|
|
53
|
+
/**
|
|
54
|
+
* Filter out credentials that the provider is expected to resolve itself
|
|
55
|
+
* (source === SERVER). Hosts call this before forwarding — these values
|
|
56
|
+
* live in the provider's own environment and shouldn't be sent.
|
|
57
|
+
*
|
|
58
|
+
* Precedence: entries without `source` default to USER (must be forwarded).
|
|
59
|
+
*/
|
|
60
|
+
export declare function filterForwardableCredentials(credentials: CredentialMap, capabilities: Capability[]): CredentialMap;
|
|
61
|
+
/**
|
|
62
|
+
* Validate that all required credentials for a capability are present in
|
|
63
|
+
* the provided map. Returns the list of missing authFields (empty array
|
|
64
|
+
* if all satisfied). Credentials with `source === SERVER` are excluded
|
|
65
|
+
* from the check since the provider resolves them.
|
|
66
|
+
*/
|
|
67
|
+
export declare function findMissingCredentials(capability: Capability, credentials: CredentialMap): string[];
|
|
68
|
+
/**
|
|
69
|
+
* Build a CredentialLayer from process env given a list of authField names.
|
|
70
|
+
* Values that aren't set in env are omitted (not set to empty string).
|
|
71
|
+
*/
|
|
72
|
+
export declare function credentialsFromEnv(authFields: readonly string[], env?: NodeJS.ProcessEnv): CredentialLayer;
|
|
73
|
+
/**
|
|
74
|
+
* Type guard: check whether an auth config entry should be forwarded by
|
|
75
|
+
* the host (vs resolved by the provider itself).
|
|
76
|
+
*/
|
|
77
|
+
export declare function isForwardable(entry: AuthConfigEntry): boolean;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client utility for capability providers.
|
|
3
|
+
*
|
|
4
|
+
* Wraps axios with proxy support, default headers, and consistent retry
|
|
5
|
+
* behavior so every provider doesn't reinvent the wheel. Used by
|
|
6
|
+
* ToolsServerCapabilityProvider and (future) any HTTP-backed provider.
|
|
7
|
+
*
|
|
8
|
+
* Proxy resolution follows the existing pattern in this codebase:
|
|
9
|
+
* the PROXY env var is read and an HttpsProxyAgent is attached if present.
|
|
10
|
+
*/
|
|
11
|
+
import { type AxiosInstance } from 'axios';
|
|
12
|
+
/** Configuration for creating an HTTP client. */
|
|
13
|
+
export interface HttpClientConfig {
|
|
14
|
+
/** Base URL prepended to all requests. */
|
|
15
|
+
baseURL: string;
|
|
16
|
+
/** Optional API key — if present, sent as `x-api-key` header. */
|
|
17
|
+
apiKey?: string;
|
|
18
|
+
/** Custom header map merged into every request. */
|
|
19
|
+
headers?: Record<string, string>;
|
|
20
|
+
/** Request timeout in milliseconds. Defaults to 30_000. */
|
|
21
|
+
timeoutMs?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Override for the PROXY env var. Useful for tests. If undefined,
|
|
24
|
+
* falls back to process.env.PROXY.
|
|
25
|
+
*/
|
|
26
|
+
proxy?: string | null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Build an axios instance configured per HttpClientConfig.
|
|
30
|
+
*
|
|
31
|
+
* The returned instance should be retained (not recreated per request) so
|
|
32
|
+
* keepalive connections can be reused.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createHttpClient(config: HttpClientConfig): AxiosInstance;
|
|
35
|
+
/**
|
|
36
|
+
* Thin wrapper around an axios response that throws with a structured error
|
|
37
|
+
* on non-2xx status codes. Providers use this to get uniform error surface.
|
|
38
|
+
*/
|
|
39
|
+
export declare class HttpError extends Error {
|
|
40
|
+
readonly status: number;
|
|
41
|
+
readonly body: unknown;
|
|
42
|
+
readonly url: string;
|
|
43
|
+
constructor(status: number, url: string, body: unknown);
|
|
44
|
+
}
|
|
45
|
+
/** Assert that an axios response is a 2xx; throw HttpError otherwise. */
|
|
46
|
+
export declare function assertOk(status: number, url: string, body: unknown): void;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool manifest cache.
|
|
3
|
+
*
|
|
4
|
+
* Providers fetch a manifest at init and potentially on refresh. This
|
|
5
|
+
* utility provides a minimal TTL cache so repeated fetchManifest() calls
|
|
6
|
+
* don't hammer the backing server.
|
|
7
|
+
*
|
|
8
|
+
* Caching is opt-in — providers that want fresh data every time (e.g.,
|
|
9
|
+
* MCP with dynamic tool lists) can skip this entirely.
|
|
10
|
+
*/
|
|
11
|
+
import type { Capability, CapabilityFilter } from '@/providers/types';
|
|
12
|
+
export interface ManifestCacheConfig {
|
|
13
|
+
/** Time-to-live in milliseconds. 0 disables caching. Defaults to 60_000 (1 min). */
|
|
14
|
+
ttlMs?: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Simple in-memory TTL cache for manifests, keyed by a caller-supplied
|
|
18
|
+
* cache key (e.g., the filter hash or a fixed constant for unfiltered).
|
|
19
|
+
*
|
|
20
|
+
* Thread-safety: the cache uses a plain Map. Node's single-threaded event
|
|
21
|
+
* loop makes this safe for typical use. Not safe across workers — each
|
|
22
|
+
* worker keeps its own cache (fine, since manifests are small).
|
|
23
|
+
*/
|
|
24
|
+
export declare class ManifestCache {
|
|
25
|
+
private readonly ttlMs;
|
|
26
|
+
private readonly store;
|
|
27
|
+
constructor(config?: ManifestCacheConfig);
|
|
28
|
+
/** Retrieve cached capabilities, or undefined on miss / expiry. */
|
|
29
|
+
get(key: string): Capability[] | undefined;
|
|
30
|
+
/** Insert or replace cached capabilities for the given key. */
|
|
31
|
+
set(key: string, capabilities: Capability[]): void;
|
|
32
|
+
/** Remove all cached entries. */
|
|
33
|
+
clear(): void;
|
|
34
|
+
/** For tests / diagnostics. */
|
|
35
|
+
get size(): number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build a deterministic cache key from a CapabilityFilter.
|
|
39
|
+
*
|
|
40
|
+
* Two identical filters always produce the same key. Providers use this
|
|
41
|
+
* so `fetchManifest(filter)` and `fetchManifest(sameFilter)` hit the
|
|
42
|
+
* same cache entry.
|
|
43
|
+
*/
|
|
44
|
+
export declare function filterToCacheKey(filter?: CapabilityFilter): string;
|
|
45
|
+
/**
|
|
46
|
+
* Apply a CapabilityFilter to a pre-fetched manifest. Used by providers
|
|
47
|
+
* that fetch the full manifest once and filter in memory.
|
|
48
|
+
*/
|
|
49
|
+
export declare function applyFilter(capabilities: Capability[], filter?: CapabilityFilter): Capability[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@illuma-ai/agents",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0-alpha.0",
|
|
4
4
|
"main": "./dist/cjs/main.cjs",
|
|
5
5
|
"module": "./dist/esm/main.mjs",
|
|
6
6
|
"types": "./dist/types/index.d.ts",
|
|
@@ -9,6 +9,26 @@
|
|
|
9
9
|
"import": "./dist/esm/main.mjs",
|
|
10
10
|
"require": "./dist/cjs/main.cjs",
|
|
11
11
|
"types": "./dist/types/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./providers/tools-server": {
|
|
14
|
+
"import": "./dist/esm/providers/tools-server/ToolsServerCapabilityProvider.mjs",
|
|
15
|
+
"require": "./dist/cjs/providers/tools-server/ToolsServerCapabilityProvider.cjs",
|
|
16
|
+
"types": "./dist/types/providers/tools-server/ToolsServerCapabilityProvider.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./providers/mcp": {
|
|
19
|
+
"import": "./dist/esm/providers/mcp/MCPCapabilityProvider.mjs",
|
|
20
|
+
"require": "./dist/cjs/providers/mcp/MCPCapabilityProvider.cjs",
|
|
21
|
+
"types": "./dist/types/providers/mcp/MCPCapabilityProvider.d.ts"
|
|
22
|
+
},
|
|
23
|
+
"./providers/a2a": {
|
|
24
|
+
"import": "./dist/esm/providers/a2a/A2ACapabilityProvider.mjs",
|
|
25
|
+
"require": "./dist/cjs/providers/a2a/A2ACapabilityProvider.cjs",
|
|
26
|
+
"types": "./dist/types/providers/a2a/A2ACapabilityProvider.d.ts"
|
|
27
|
+
},
|
|
28
|
+
"./providers/composite": {
|
|
29
|
+
"import": "./dist/esm/providers/composite/CompositeCapabilityProvider.mjs",
|
|
30
|
+
"require": "./dist/cjs/providers/composite/CompositeCapabilityProvider.cjs",
|
|
31
|
+
"types": "./dist/types/providers/composite/CompositeCapabilityProvider.d.ts"
|
|
12
32
|
}
|
|
13
33
|
},
|
|
14
34
|
"type": "module",
|
package/src/graphs/Graph.ts
CHANGED
|
@@ -1498,14 +1498,6 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
1498
1498
|
clientOptions: effectiveClientOptions,
|
|
1499
1499
|
});
|
|
1500
1500
|
|
|
1501
|
-
// DEBUG: Log which model and tools each agent uses during handoff
|
|
1502
|
-
mlog(
|
|
1503
|
-
`[createCallModel] Agent "${agentId}" invoking LLM | provider=${agentContext.provider} | ` +
|
|
1504
|
-
`model=${(effectiveClientOptions as Record<string, unknown>).model ?? 'default'} | ` +
|
|
1505
|
-
`toolsForBinding=${toolsForBinding?.length ?? 0} | ` +
|
|
1506
|
-
`toolNames=[${(toolsForBinding ?? []).map((t) => (t as { name?: string }).name ?? 'unknown').join(', ')}]`
|
|
1507
|
-
);
|
|
1508
|
-
|
|
1509
1501
|
if (agentContext.systemRunnable) {
|
|
1510
1502
|
model = agentContext.systemRunnable.pipe(model as Runnable);
|
|
1511
1503
|
}
|
|
@@ -1680,27 +1672,21 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
1680
1672
|
|
|
1681
1673
|
// Step 1: Resolve best available summary
|
|
1682
1674
|
let summary: string | undefined;
|
|
1683
|
-
let summarySource: string;
|
|
1684
1675
|
|
|
1685
1676
|
if (this._cachedRunSummary != null) {
|
|
1686
1677
|
summary = this._cachedRunSummary;
|
|
1687
|
-
summarySource = 'cached';
|
|
1688
1678
|
} else if (
|
|
1689
1679
|
agentContext.persistedSummary != null &&
|
|
1690
1680
|
agentContext.persistedSummary !== ''
|
|
1691
1681
|
) {
|
|
1692
1682
|
summary = agentContext.persistedSummary;
|
|
1693
1683
|
this._cachedRunSummary = summary;
|
|
1694
|
-
summarySource = 'persisted';
|
|
1695
1684
|
} else if (
|
|
1696
1685
|
sumConfig?.initialSummary != null &&
|
|
1697
1686
|
sumConfig.initialSummary !== ''
|
|
1698
1687
|
) {
|
|
1699
1688
|
summary = sumConfig.initialSummary;
|
|
1700
1689
|
this._cachedRunSummary = summary;
|
|
1701
|
-
summarySource = 'initial-seed';
|
|
1702
|
-
} else {
|
|
1703
|
-
summarySource = 'none';
|
|
1704
1690
|
}
|
|
1705
1691
|
|
|
1706
1692
|
// Step 2: Calculate token budget
|
|
@@ -1847,15 +1833,6 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
1847
1833
|
}
|
|
1848
1834
|
agentContext.indexTokenCountMap = viewTokenMap;
|
|
1849
1835
|
|
|
1850
|
-
mlog(
|
|
1851
|
-
`[Graph:Compaction] ${messages.length}→${viewParts.length} msgs | ` +
|
|
1852
|
-
`compacted=${compactedMessages.length} window=${recentMessages.length} | ` +
|
|
1853
|
-
`summary=${summarySource} | budget=${usedTokens}/${recentBudget}` +
|
|
1854
|
-
(fileManifestTokens > 0
|
|
1855
|
-
? ` | manifest=${fileManifest?.length ?? 0} files (${fileManifestTokens}tok)`
|
|
1856
|
-
: '')
|
|
1857
|
-
);
|
|
1858
|
-
|
|
1859
1836
|
// Step 5: Fire background summary update (non-blocking)
|
|
1860
1837
|
// Summarize messages outside the window so next iteration has a fresh summary.
|
|
1861
1838
|
// Only trigger if there are compacted messages worth summarizing.
|
package/src/index.ts
CHANGED
|
@@ -26,6 +26,10 @@ export * from './tools/schema';
|
|
|
26
26
|
export * from './tools/handlers';
|
|
27
27
|
export * from './tools/search';
|
|
28
28
|
export * from './tools/memory';
|
|
29
|
+
export * from './tools/proxyTool';
|
|
30
|
+
|
|
31
|
+
/* Capability Providers */
|
|
32
|
+
export * from './providers';
|
|
29
33
|
|
|
30
34
|
/* Memory (storage + factory) */
|
|
31
35
|
export * from './memory';
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { CompositeCapabilityProvider } from '../composite/CompositeCapabilityProvider';
|
|
2
|
+
import {
|
|
3
|
+
CapabilityKind,
|
|
4
|
+
type Capability,
|
|
5
|
+
type CapabilityProvider,
|
|
6
|
+
type CredentialMap,
|
|
7
|
+
} from '../types';
|
|
8
|
+
|
|
9
|
+
const makeCap = (
|
|
10
|
+
name: string,
|
|
11
|
+
kind: CapabilityKind = CapabilityKind.TOOL
|
|
12
|
+
): Capability => ({
|
|
13
|
+
kind,
|
|
14
|
+
name,
|
|
15
|
+
description: `${name} cap`,
|
|
16
|
+
authConfig: [],
|
|
17
|
+
metadata: {},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
class FakeProvider implements CapabilityProvider {
|
|
21
|
+
readonly providerId: string;
|
|
22
|
+
manifestCallCount = 0;
|
|
23
|
+
createCallCount = 0;
|
|
24
|
+
|
|
25
|
+
constructor(
|
|
26
|
+
id: string,
|
|
27
|
+
private readonly manifest: Capability[],
|
|
28
|
+
private readonly failOnFetch = false
|
|
29
|
+
) {
|
|
30
|
+
this.providerId = id;
|
|
31
|
+
}
|
|
32
|
+
async fetchManifest(): Promise<Capability[]> {
|
|
33
|
+
this.manifestCallCount++;
|
|
34
|
+
if (this.failOnFetch) throw new Error('simulated failure');
|
|
35
|
+
return this.manifest;
|
|
36
|
+
}
|
|
37
|
+
async createRunnables(capabilities: Capability[], _creds: CredentialMap) {
|
|
38
|
+
this.createCallCount++;
|
|
39
|
+
// Return one fake tool per capability name — we can't import StructuredToolInterface here cleanly,
|
|
40
|
+
// so cast. The test only checks length + name.
|
|
41
|
+
return capabilities.map((c) => ({ name: c.name }) as unknown as never);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
describe('CompositeCapabilityProvider', () => {
|
|
46
|
+
it('throws on empty provider list', () => {
|
|
47
|
+
expect(() => new CompositeCapabilityProvider([])).toThrow(/at least one/);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('providerId reflects composed providers', () => {
|
|
51
|
+
const composite = new CompositeCapabilityProvider([
|
|
52
|
+
new FakeProvider('p1', []),
|
|
53
|
+
new FakeProvider('p2', []),
|
|
54
|
+
]);
|
|
55
|
+
expect(composite.providerId).toBe('composite:p1,p2');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('merges manifests from all providers', async () => {
|
|
59
|
+
const p1 = new FakeProvider('p1', [makeCap('a'), makeCap('b')]);
|
|
60
|
+
const p2 = new FakeProvider('p2', [makeCap('c')]);
|
|
61
|
+
const composite = new CompositeCapabilityProvider([p1, p2]);
|
|
62
|
+
const caps = await composite.fetchManifest();
|
|
63
|
+
expect(caps.map((c) => c.name).sort()).toEqual(['a', 'b', 'c']);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('deduplicates on name collision, first provider wins', async () => {
|
|
67
|
+
const p1 = new FakeProvider('p1', [makeCap('dup'), makeCap('a')]);
|
|
68
|
+
const p2 = new FakeProvider('p2', [makeCap('dup'), makeCap('b')]);
|
|
69
|
+
const composite = new CompositeCapabilityProvider([p1, p2]);
|
|
70
|
+
const caps = await composite.fetchManifest();
|
|
71
|
+
expect(caps.map((c) => c.name).sort()).toEqual(['a', 'b', 'dup']);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('continues when one provider fails', async () => {
|
|
75
|
+
const p1 = new FakeProvider('p1', [], true);
|
|
76
|
+
const p2 = new FakeProvider('p2', [makeCap('x')]);
|
|
77
|
+
const composite = new CompositeCapabilityProvider([p1, p2]);
|
|
78
|
+
const caps = await composite.fetchManifest();
|
|
79
|
+
expect(caps).toHaveLength(1);
|
|
80
|
+
expect(caps[0].name).toBe('x');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('createRunnables routes each capability to its owning provider', async () => {
|
|
84
|
+
const p1 = new FakeProvider('p1', [makeCap('a'), makeCap('b')]);
|
|
85
|
+
const p2 = new FakeProvider('p2', [makeCap('c')]);
|
|
86
|
+
const composite = new CompositeCapabilityProvider([p1, p2]);
|
|
87
|
+
const manifest = await composite.fetchManifest();
|
|
88
|
+
const runnables = await composite.createRunnables(manifest, {});
|
|
89
|
+
expect(runnables).toHaveLength(3);
|
|
90
|
+
expect(p1.createCallCount).toBe(1);
|
|
91
|
+
expect(p2.createCallCount).toBe(1);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration test — exercises ToolsServerCapabilityProvider against a live
|
|
3
|
+
* tools-server instance.
|
|
4
|
+
*
|
|
5
|
+
* RUN REQUIREMENTS:
|
|
6
|
+
* 1. tools-server must be running locally at TOOLS_SERVER_URL
|
|
7
|
+
* 2. TOOLS_SERVER_API_KEY must match the server's configured key
|
|
8
|
+
*
|
|
9
|
+
* The suite is skipped when TOOLS_SERVER_URL is not set so unit CI passes.
|
|
10
|
+
* To run: TOOLS_SERVER_URL=http://localhost:3500 TOOLS_SERVER_API_KEY=test \
|
|
11
|
+
* npx jest --testPathPatterns=integration
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { ToolsServerCapabilityProvider } from '../tools-server/ToolsServerCapabilityProvider';
|
|
15
|
+
import { CapabilityKind } from '../types';
|
|
16
|
+
|
|
17
|
+
const baseUrl = process.env.TOOLS_SERVER_URL;
|
|
18
|
+
const apiKey = process.env.TOOLS_SERVER_API_KEY;
|
|
19
|
+
|
|
20
|
+
const describeIfLive = baseUrl && apiKey ? describe : describe.skip;
|
|
21
|
+
|
|
22
|
+
describeIfLive('ToolsServerCapabilityProvider (live integration)', () => {
|
|
23
|
+
let provider: ToolsServerCapabilityProvider;
|
|
24
|
+
|
|
25
|
+
beforeAll(() => {
|
|
26
|
+
provider = new ToolsServerCapabilityProvider({
|
|
27
|
+
baseUrl: baseUrl as string,
|
|
28
|
+
apiKey: apiKey as string,
|
|
29
|
+
manifestTtlMs: 0, // always fresh for tests
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('fetches manifest from live server', async () => {
|
|
34
|
+
const caps = await provider.fetchManifest();
|
|
35
|
+
expect(caps.length).toBeGreaterThan(0);
|
|
36
|
+
for (const cap of caps) {
|
|
37
|
+
expect(cap.kind).toBe(CapabilityKind.TOOL);
|
|
38
|
+
expect(typeof cap.name).toBe('string');
|
|
39
|
+
expect(typeof cap.description).toBe('string');
|
|
40
|
+
expect(Array.isArray(cap.authConfig)).toBe(true);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('live manifest contains wikipedia', async () => {
|
|
45
|
+
const caps = await provider.fetchManifest();
|
|
46
|
+
const wikipedia = caps.find((c) => c.name === 'wikipedia');
|
|
47
|
+
expect(wikipedia).toBeDefined();
|
|
48
|
+
expect(wikipedia?.schema).toBeDefined();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('builds runnables that invoke wikipedia end-to-end', async () => {
|
|
52
|
+
const caps = await provider.fetchManifest({ names: ['wikipedia'] });
|
|
53
|
+
expect(caps).toHaveLength(1);
|
|
54
|
+
|
|
55
|
+
const [tool] = await provider.createRunnables(caps, {});
|
|
56
|
+
const result = await tool.invoke({ action: 'search', query: 'TypeScript' });
|
|
57
|
+
|
|
58
|
+
// Wikipedia returns JSON-serialized results; just check it's non-empty
|
|
59
|
+
expect(typeof result).toBe('string');
|
|
60
|
+
expect((result as string).length).toBeGreaterThan(0);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('surfaces backend failure as thrown error', async () => {
|
|
64
|
+
// Invoke wikipedia with missing required field → backend returns success:false
|
|
65
|
+
const caps = await provider.fetchManifest({ names: ['wikipedia'] });
|
|
66
|
+
const [tool] = await provider.createRunnables(caps, {});
|
|
67
|
+
await expect(tool.invoke({})).rejects.toThrow();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('filters manifest by names correctly', async () => {
|
|
71
|
+
const caps = await provider.fetchManifest({
|
|
72
|
+
names: ['wikipedia', 'arxiv_search'],
|
|
73
|
+
});
|
|
74
|
+
expect(caps.length).toBeLessThanOrEqual(2);
|
|
75
|
+
for (const cap of caps) {
|
|
76
|
+
expect(['wikipedia', 'arxiv_search']).toContain(cap.name);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
});
|