@illuma-ai/agents 1.4.0-alpha.0 → 1.4.0-alpha.1
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/main.cjs +0 -2
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/esm/main.mjs +0 -1
- package/dist/esm/main.mjs.map +1 -1
- package/dist/types/providers/index.d.ts +0 -1
- package/package.json +1 -6
- package/src/providers/index.ts +4 -1
- package/dist/cjs/providers/composite/CompositeCapabilityProvider.cjs +0 -80
- package/dist/cjs/providers/composite/CompositeCapabilityProvider.cjs.map +0 -1
- package/dist/esm/providers/composite/CompositeCapabilityProvider.mjs +0 -78
- package/dist/esm/providers/composite/CompositeCapabilityProvider.mjs.map +0 -1
- package/dist/types/providers/composite/CompositeCapabilityProvider.d.ts +0 -22
- package/dist/types/providers/composite/index.d.ts +0 -1
- package/src/providers/__tests__/CompositeCapabilityProvider.test.ts +0 -93
- package/src/providers/composite/CompositeCapabilityProvider.ts +0 -112
- package/src/providers/composite/index.ts +0 -1
package/dist/cjs/main.cjs
CHANGED
|
@@ -32,7 +32,6 @@ var proxyTool = require('./tools/proxyTool.cjs');
|
|
|
32
32
|
var types = require('./providers/types.cjs');
|
|
33
33
|
var capabilityNaming = require('./providers/capabilityNaming.cjs');
|
|
34
34
|
var ToolsServerCapabilityProvider = require('./providers/tools-server/ToolsServerCapabilityProvider.cjs');
|
|
35
|
-
var CompositeCapabilityProvider = require('./providers/composite/CompositeCapabilityProvider.cjs');
|
|
36
35
|
var MCPCapabilityProvider = require('./providers/mcp/MCPCapabilityProvider.cjs');
|
|
37
36
|
var transport = require('./providers/mcp/transport.cjs');
|
|
38
37
|
var config$1 = require('./providers/mcp/config.cjs');
|
|
@@ -233,7 +232,6 @@ exports.CAPABILITY_NAME_SEPARATOR = capabilityNaming.CAPABILITY_NAME_SEPARATOR;
|
|
|
233
232
|
exports.formatCapabilityName = capabilityNaming.formatCapabilityName;
|
|
234
233
|
exports.parseCapabilityName = capabilityNaming.parseCapabilityName;
|
|
235
234
|
exports.ToolsServerCapabilityProvider = ToolsServerCapabilityProvider.ToolsServerCapabilityProvider;
|
|
236
|
-
exports.CompositeCapabilityProvider = CompositeCapabilityProvider.CompositeCapabilityProvider;
|
|
237
235
|
exports.MCPCapabilityProvider = MCPCapabilityProvider.MCPCapabilityProvider;
|
|
238
236
|
exports.flattenToolCallResponse = MCPCapabilityProvider.flattenToolCallResponse;
|
|
239
237
|
exports.createTransport = transport.createTransport;
|
package/dist/cjs/main.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"main.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/esm/main.mjs
CHANGED
|
@@ -30,7 +30,6 @@ export { buildProxyTool } from './tools/proxyTool.mjs';
|
|
|
30
30
|
export { AuthSource, CapabilityKind } from './providers/types.mjs';
|
|
31
31
|
export { CAPABILITY_NAME_SEPARATOR, formatCapabilityName, parseCapabilityName } from './providers/capabilityNaming.mjs';
|
|
32
32
|
export { ToolsServerCapabilityProvider } from './providers/tools-server/ToolsServerCapabilityProvider.mjs';
|
|
33
|
-
export { CompositeCapabilityProvider } from './providers/composite/CompositeCapabilityProvider.mjs';
|
|
34
33
|
export { MCPCapabilityProvider, flattenToolCallResponse } from './providers/mcp/MCPCapabilityProvider.mjs';
|
|
35
34
|
export { createTransport } from './providers/mcp/transport.mjs';
|
|
36
35
|
export { getMCPEnvDefaults, consoleLogger as mcpConsoleLogger } from './providers/mcp/config.mjs';
|
package/dist/esm/main.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"main.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
export * from './types';
|
|
7
7
|
export * from './capabilityNaming';
|
|
8
8
|
export * from './tools-server';
|
|
9
|
-
export * from './composite';
|
|
10
9
|
export { MCPCapabilityProvider, flattenToolCallResponse, createTransport, mcpConsoleLogger, getMCPEnvDefaults, } from './mcp';
|
|
11
10
|
export type { MCPLogger, MCPProviderConfig, MCPServerSpec, MCPTransportKind, StdioSpec, SSESpec, StreamableHTTPSpec, WebSocketSpec, MCPToolDescriptor, MCPToolCallResult, MCPStructuredTool, } from './mcp';
|
|
12
11
|
export { A2ACapabilityProvider, A2AClient, extractTaskText, generateRpcId, skillToCapability, coerceInputToA2AMessage, MESSAGE_INPUT_SCHEMA, a2aConsoleLogger, getA2AEnvDefaults, } from './a2a';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@illuma-ai/agents",
|
|
3
|
-
"version": "1.4.0-alpha.
|
|
3
|
+
"version": "1.4.0-alpha.1",
|
|
4
4
|
"main": "./dist/cjs/main.cjs",
|
|
5
5
|
"module": "./dist/esm/main.mjs",
|
|
6
6
|
"types": "./dist/types/index.d.ts",
|
|
@@ -24,11 +24,6 @@
|
|
|
24
24
|
"import": "./dist/esm/providers/a2a/A2ACapabilityProvider.mjs",
|
|
25
25
|
"require": "./dist/cjs/providers/a2a/A2ACapabilityProvider.cjs",
|
|
26
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"
|
|
32
27
|
}
|
|
33
28
|
},
|
|
34
29
|
"type": "module",
|
package/src/providers/index.ts
CHANGED
|
@@ -9,7 +9,10 @@ export * from './types';
|
|
|
9
9
|
// A2A consumers get the same encoding without re-export duplication.
|
|
10
10
|
export * from './capabilityNaming';
|
|
11
11
|
export * from './tools-server';
|
|
12
|
-
|
|
12
|
+
// Hosts compose multiple providers by iterating a plain array and
|
|
13
|
+
// concatenating tools — see docs/capability-providers.md. No wrapper
|
|
14
|
+
// class is provided because the loop is trivial and keeps host code
|
|
15
|
+
// transparent.
|
|
13
16
|
// MCP + A2A barrels intentionally namespaced to avoid re-exporting
|
|
14
17
|
// `CAPABILITY_NAME_SEPARATOR` / `formatCapabilityName` twice (each
|
|
15
18
|
// provider module re-exports them internally; the canonical export
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* CompositeCapabilityProvider — fans out to multiple CapabilityProviders
|
|
5
|
-
* and merges their manifests + runnables into one.
|
|
6
|
-
*
|
|
7
|
-
* Use case: an agent that consumes tools from tools-server AND MCP servers
|
|
8
|
-
* AND (future) skills. The composite exposes a single CapabilityProvider
|
|
9
|
-
* interface to the agent runtime so it doesn't know or care how many
|
|
10
|
-
* backing sources exist.
|
|
11
|
-
*
|
|
12
|
-
* Precedence: later providers do NOT override earlier ones on name
|
|
13
|
-
* collision — collisions are logged and the first-registered capability
|
|
14
|
-
* wins. Callers should ensure providers expose disjoint name spaces.
|
|
15
|
-
*/
|
|
16
|
-
class CompositeCapabilityProvider {
|
|
17
|
-
providerId;
|
|
18
|
-
providers;
|
|
19
|
-
constructor(providers) {
|
|
20
|
-
if (!providers.length) {
|
|
21
|
-
throw new Error('CompositeCapabilityProvider: at least one provider is required');
|
|
22
|
-
}
|
|
23
|
-
this.providers = providers;
|
|
24
|
-
this.providerId = `composite:${providers.map((p) => p.providerId).join(',')}`;
|
|
25
|
-
}
|
|
26
|
-
async fetchManifest(filter) {
|
|
27
|
-
// Fetch all providers in parallel. One provider failing should not
|
|
28
|
-
// prevent others from contributing — log and continue.
|
|
29
|
-
const results = await Promise.allSettled(this.providers.map((p) => p.fetchManifest(filter)));
|
|
30
|
-
const merged = [];
|
|
31
|
-
const seen = new Set();
|
|
32
|
-
for (let i = 0; i < results.length; i++) {
|
|
33
|
-
const result = results[i];
|
|
34
|
-
const provider = this.providers[i];
|
|
35
|
-
if (result.status === 'rejected') {
|
|
36
|
-
// DEBUG
|
|
37
|
-
// eslint-disable-next-line no-console
|
|
38
|
-
console.debug(`[composite] provider ${provider.providerId} fetchManifest failed — ${String(result.reason)}`);
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
for (const cap of result.value) {
|
|
42
|
-
if (seen.has(cap.name)) {
|
|
43
|
-
// DEBUG
|
|
44
|
-
// eslint-disable-next-line no-console
|
|
45
|
-
console.debug(`[composite] name collision on "${cap.name}" from ${provider.providerId} — keeping first`);
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
seen.add(cap.name);
|
|
49
|
-
merged.push(cap);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
// DEBUG
|
|
53
|
-
// eslint-disable-next-line no-console
|
|
54
|
-
console.debug(`[composite] merged manifest: ${merged.length} caps from ${this.providers.length} providers`);
|
|
55
|
-
return merged;
|
|
56
|
-
}
|
|
57
|
-
async createRunnables(capabilities, credentials) {
|
|
58
|
-
// Determine which capabilities belong to which provider by refetching
|
|
59
|
-
// each provider's manifest and intersecting with the requested set.
|
|
60
|
-
// This keeps providers stateless — we don't require Capability to
|
|
61
|
-
// carry a back-reference to its provider.
|
|
62
|
-
const capabilityNames = new Set(capabilities.map((c) => c.name));
|
|
63
|
-
const perProviderCaps = await Promise.all(this.providers.map(async (p) => {
|
|
64
|
-
const manifest = await p.fetchManifest();
|
|
65
|
-
return manifest.filter((c) => capabilityNames.has(c.name));
|
|
66
|
-
}));
|
|
67
|
-
const allRunnables = [];
|
|
68
|
-
for (let i = 0; i < this.providers.length; i++) {
|
|
69
|
-
const providerCaps = perProviderCaps[i];
|
|
70
|
-
if (!providerCaps.length)
|
|
71
|
-
continue;
|
|
72
|
-
const runnables = await this.providers[i].createRunnables(providerCaps, credentials);
|
|
73
|
-
allRunnables.push(...runnables);
|
|
74
|
-
}
|
|
75
|
-
return allRunnables;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
exports.CompositeCapabilityProvider = CompositeCapabilityProvider;
|
|
80
|
-
//# sourceMappingURL=CompositeCapabilityProvider.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CompositeCapabilityProvider.cjs","sources":["../../../../src/providers/composite/CompositeCapabilityProvider.ts"],"sourcesContent":["/**\n * CompositeCapabilityProvider — fans out to multiple CapabilityProviders\n * and merges their manifests + runnables into one.\n *\n * Use case: an agent that consumes tools from tools-server AND MCP servers\n * AND (future) skills. The composite exposes a single CapabilityProvider\n * interface to the agent runtime so it doesn't know or care how many\n * backing sources exist.\n *\n * Precedence: later providers do NOT override earlier ones on name\n * collision — collisions are logged and the first-registered capability\n * wins. Callers should ensure providers expose disjoint name spaces.\n */\n\nimport type { StructuredToolInterface } from '@langchain/core/tools';\nimport type {\n Capability,\n CapabilityFilter,\n CapabilityProvider,\n CredentialMap,\n} from '@/providers/types';\n\nexport class CompositeCapabilityProvider implements CapabilityProvider {\n readonly providerId: string;\n private readonly providers: CapabilityProvider[];\n\n constructor(providers: CapabilityProvider[]) {\n if (!providers.length) {\n throw new Error(\n 'CompositeCapabilityProvider: at least one provider is required'\n );\n }\n this.providers = providers;\n this.providerId = `composite:${providers.map((p) => p.providerId).join(',')}`;\n }\n\n async fetchManifest(filter?: CapabilityFilter): Promise<Capability[]> {\n // Fetch all providers in parallel. One provider failing should not\n // prevent others from contributing — log and continue.\n const results = await Promise.allSettled(\n this.providers.map((p) => p.fetchManifest(filter))\n );\n\n const merged: Capability[] = [];\n const seen = new Set<string>();\n\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n const provider = this.providers[i];\n\n if (result.status === 'rejected') {\n // DEBUG\n // eslint-disable-next-line no-console\n console.debug(\n `[composite] provider ${provider.providerId} fetchManifest failed — ${String(result.reason)}`\n );\n continue;\n }\n\n for (const cap of result.value) {\n if (seen.has(cap.name)) {\n // DEBUG\n // eslint-disable-next-line no-console\n console.debug(\n `[composite] name collision on \"${cap.name}\" from ${provider.providerId} — keeping first`\n );\n continue;\n }\n seen.add(cap.name);\n merged.push(cap);\n }\n }\n\n // DEBUG\n // eslint-disable-next-line no-console\n console.debug(\n `[composite] merged manifest: ${merged.length} caps from ${this.providers.length} providers`\n );\n\n return merged;\n }\n\n async createRunnables(\n capabilities: Capability[],\n credentials: CredentialMap\n ): Promise<StructuredToolInterface[]> {\n // Determine which capabilities belong to which provider by refetching\n // each provider's manifest and intersecting with the requested set.\n // This keeps providers stateless — we don't require Capability to\n // carry a back-reference to its provider.\n const capabilityNames = new Set(capabilities.map((c) => c.name));\n const perProviderCaps = await Promise.all(\n this.providers.map(async (p) => {\n const manifest = await p.fetchManifest();\n return manifest.filter((c) => capabilityNames.has(c.name));\n })\n );\n\n const allRunnables: StructuredToolInterface[] = [];\n for (let i = 0; i < this.providers.length; i++) {\n const providerCaps = perProviderCaps[i];\n if (!providerCaps.length) continue;\n const runnables = await this.providers[i].createRunnables(\n providerCaps,\n credentials\n );\n allRunnables.push(...runnables);\n }\n\n return allRunnables;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CompositeCapabilityProvider — fans out to multiple CapabilityProviders
|
|
3
|
-
* and merges their manifests + runnables into one.
|
|
4
|
-
*
|
|
5
|
-
* Use case: an agent that consumes tools from tools-server AND MCP servers
|
|
6
|
-
* AND (future) skills. The composite exposes a single CapabilityProvider
|
|
7
|
-
* interface to the agent runtime so it doesn't know or care how many
|
|
8
|
-
* backing sources exist.
|
|
9
|
-
*
|
|
10
|
-
* Precedence: later providers do NOT override earlier ones on name
|
|
11
|
-
* collision — collisions are logged and the first-registered capability
|
|
12
|
-
* wins. Callers should ensure providers expose disjoint name spaces.
|
|
13
|
-
*/
|
|
14
|
-
class CompositeCapabilityProvider {
|
|
15
|
-
providerId;
|
|
16
|
-
providers;
|
|
17
|
-
constructor(providers) {
|
|
18
|
-
if (!providers.length) {
|
|
19
|
-
throw new Error('CompositeCapabilityProvider: at least one provider is required');
|
|
20
|
-
}
|
|
21
|
-
this.providers = providers;
|
|
22
|
-
this.providerId = `composite:${providers.map((p) => p.providerId).join(',')}`;
|
|
23
|
-
}
|
|
24
|
-
async fetchManifest(filter) {
|
|
25
|
-
// Fetch all providers in parallel. One provider failing should not
|
|
26
|
-
// prevent others from contributing — log and continue.
|
|
27
|
-
const results = await Promise.allSettled(this.providers.map((p) => p.fetchManifest(filter)));
|
|
28
|
-
const merged = [];
|
|
29
|
-
const seen = new Set();
|
|
30
|
-
for (let i = 0; i < results.length; i++) {
|
|
31
|
-
const result = results[i];
|
|
32
|
-
const provider = this.providers[i];
|
|
33
|
-
if (result.status === 'rejected') {
|
|
34
|
-
// DEBUG
|
|
35
|
-
// eslint-disable-next-line no-console
|
|
36
|
-
console.debug(`[composite] provider ${provider.providerId} fetchManifest failed — ${String(result.reason)}`);
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
for (const cap of result.value) {
|
|
40
|
-
if (seen.has(cap.name)) {
|
|
41
|
-
// DEBUG
|
|
42
|
-
// eslint-disable-next-line no-console
|
|
43
|
-
console.debug(`[composite] name collision on "${cap.name}" from ${provider.providerId} — keeping first`);
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
seen.add(cap.name);
|
|
47
|
-
merged.push(cap);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
// DEBUG
|
|
51
|
-
// eslint-disable-next-line no-console
|
|
52
|
-
console.debug(`[composite] merged manifest: ${merged.length} caps from ${this.providers.length} providers`);
|
|
53
|
-
return merged;
|
|
54
|
-
}
|
|
55
|
-
async createRunnables(capabilities, credentials) {
|
|
56
|
-
// Determine which capabilities belong to which provider by refetching
|
|
57
|
-
// each provider's manifest and intersecting with the requested set.
|
|
58
|
-
// This keeps providers stateless — we don't require Capability to
|
|
59
|
-
// carry a back-reference to its provider.
|
|
60
|
-
const capabilityNames = new Set(capabilities.map((c) => c.name));
|
|
61
|
-
const perProviderCaps = await Promise.all(this.providers.map(async (p) => {
|
|
62
|
-
const manifest = await p.fetchManifest();
|
|
63
|
-
return manifest.filter((c) => capabilityNames.has(c.name));
|
|
64
|
-
}));
|
|
65
|
-
const allRunnables = [];
|
|
66
|
-
for (let i = 0; i < this.providers.length; i++) {
|
|
67
|
-
const providerCaps = perProviderCaps[i];
|
|
68
|
-
if (!providerCaps.length)
|
|
69
|
-
continue;
|
|
70
|
-
const runnables = await this.providers[i].createRunnables(providerCaps, credentials);
|
|
71
|
-
allRunnables.push(...runnables);
|
|
72
|
-
}
|
|
73
|
-
return allRunnables;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export { CompositeCapabilityProvider };
|
|
78
|
-
//# sourceMappingURL=CompositeCapabilityProvider.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CompositeCapabilityProvider.mjs","sources":["../../../../src/providers/composite/CompositeCapabilityProvider.ts"],"sourcesContent":["/**\n * CompositeCapabilityProvider — fans out to multiple CapabilityProviders\n * and merges their manifests + runnables into one.\n *\n * Use case: an agent that consumes tools from tools-server AND MCP servers\n * AND (future) skills. The composite exposes a single CapabilityProvider\n * interface to the agent runtime so it doesn't know or care how many\n * backing sources exist.\n *\n * Precedence: later providers do NOT override earlier ones on name\n * collision — collisions are logged and the first-registered capability\n * wins. Callers should ensure providers expose disjoint name spaces.\n */\n\nimport type { StructuredToolInterface } from '@langchain/core/tools';\nimport type {\n Capability,\n CapabilityFilter,\n CapabilityProvider,\n CredentialMap,\n} from '@/providers/types';\n\nexport class CompositeCapabilityProvider implements CapabilityProvider {\n readonly providerId: string;\n private readonly providers: CapabilityProvider[];\n\n constructor(providers: CapabilityProvider[]) {\n if (!providers.length) {\n throw new Error(\n 'CompositeCapabilityProvider: at least one provider is required'\n );\n }\n this.providers = providers;\n this.providerId = `composite:${providers.map((p) => p.providerId).join(',')}`;\n }\n\n async fetchManifest(filter?: CapabilityFilter): Promise<Capability[]> {\n // Fetch all providers in parallel. One provider failing should not\n // prevent others from contributing — log and continue.\n const results = await Promise.allSettled(\n this.providers.map((p) => p.fetchManifest(filter))\n );\n\n const merged: Capability[] = [];\n const seen = new Set<string>();\n\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n const provider = this.providers[i];\n\n if (result.status === 'rejected') {\n // DEBUG\n // eslint-disable-next-line no-console\n console.debug(\n `[composite] provider ${provider.providerId} fetchManifest failed — ${String(result.reason)}`\n );\n continue;\n }\n\n for (const cap of result.value) {\n if (seen.has(cap.name)) {\n // DEBUG\n // eslint-disable-next-line no-console\n console.debug(\n `[composite] name collision on \"${cap.name}\" from ${provider.providerId} — keeping first`\n );\n continue;\n }\n seen.add(cap.name);\n merged.push(cap);\n }\n }\n\n // DEBUG\n // eslint-disable-next-line no-console\n console.debug(\n `[composite] merged manifest: ${merged.length} caps from ${this.providers.length} providers`\n );\n\n return merged;\n }\n\n async createRunnables(\n capabilities: Capability[],\n credentials: CredentialMap\n ): Promise<StructuredToolInterface[]> {\n // Determine which capabilities belong to which provider by refetching\n // each provider's manifest and intersecting with the requested set.\n // This keeps providers stateless — we don't require Capability to\n // carry a back-reference to its provider.\n const capabilityNames = new Set(capabilities.map((c) => c.name));\n const perProviderCaps = await Promise.all(\n this.providers.map(async (p) => {\n const manifest = await p.fetchManifest();\n return manifest.filter((c) => capabilityNames.has(c.name));\n })\n );\n\n const allRunnables: StructuredToolInterface[] = [];\n for (let i = 0; i < this.providers.length; i++) {\n const providerCaps = perProviderCaps[i];\n if (!providerCaps.length) continue;\n const runnables = await this.providers[i].createRunnables(\n providerCaps,\n credentials\n );\n allRunnables.push(...runnables);\n }\n\n return allRunnables;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CompositeCapabilityProvider — fans out to multiple CapabilityProviders
|
|
3
|
-
* and merges their manifests + runnables into one.
|
|
4
|
-
*
|
|
5
|
-
* Use case: an agent that consumes tools from tools-server AND MCP servers
|
|
6
|
-
* AND (future) skills. The composite exposes a single CapabilityProvider
|
|
7
|
-
* interface to the agent runtime so it doesn't know or care how many
|
|
8
|
-
* backing sources exist.
|
|
9
|
-
*
|
|
10
|
-
* Precedence: later providers do NOT override earlier ones on name
|
|
11
|
-
* collision — collisions are logged and the first-registered capability
|
|
12
|
-
* wins. Callers should ensure providers expose disjoint name spaces.
|
|
13
|
-
*/
|
|
14
|
-
import type { StructuredToolInterface } from '@langchain/core/tools';
|
|
15
|
-
import type { Capability, CapabilityFilter, CapabilityProvider, CredentialMap } from '@/providers/types';
|
|
16
|
-
export declare class CompositeCapabilityProvider implements CapabilityProvider {
|
|
17
|
-
readonly providerId: string;
|
|
18
|
-
private readonly providers;
|
|
19
|
-
constructor(providers: CapabilityProvider[]);
|
|
20
|
-
fetchManifest(filter?: CapabilityFilter): Promise<Capability[]>;
|
|
21
|
-
createRunnables(capabilities: Capability[], credentials: CredentialMap): Promise<StructuredToolInterface[]>;
|
|
22
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './CompositeCapabilityProvider';
|
|
@@ -1,93 +0,0 @@
|
|
|
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
|
-
});
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CompositeCapabilityProvider — fans out to multiple CapabilityProviders
|
|
3
|
-
* and merges their manifests + runnables into one.
|
|
4
|
-
*
|
|
5
|
-
* Use case: an agent that consumes tools from tools-server AND MCP servers
|
|
6
|
-
* AND (future) skills. The composite exposes a single CapabilityProvider
|
|
7
|
-
* interface to the agent runtime so it doesn't know or care how many
|
|
8
|
-
* backing sources exist.
|
|
9
|
-
*
|
|
10
|
-
* Precedence: later providers do NOT override earlier ones on name
|
|
11
|
-
* collision — collisions are logged and the first-registered capability
|
|
12
|
-
* wins. Callers should ensure providers expose disjoint name spaces.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import type { StructuredToolInterface } from '@langchain/core/tools';
|
|
16
|
-
import type {
|
|
17
|
-
Capability,
|
|
18
|
-
CapabilityFilter,
|
|
19
|
-
CapabilityProvider,
|
|
20
|
-
CredentialMap,
|
|
21
|
-
} from '@/providers/types';
|
|
22
|
-
|
|
23
|
-
export class CompositeCapabilityProvider implements CapabilityProvider {
|
|
24
|
-
readonly providerId: string;
|
|
25
|
-
private readonly providers: CapabilityProvider[];
|
|
26
|
-
|
|
27
|
-
constructor(providers: CapabilityProvider[]) {
|
|
28
|
-
if (!providers.length) {
|
|
29
|
-
throw new Error(
|
|
30
|
-
'CompositeCapabilityProvider: at least one provider is required'
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
this.providers = providers;
|
|
34
|
-
this.providerId = `composite:${providers.map((p) => p.providerId).join(',')}`;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async fetchManifest(filter?: CapabilityFilter): Promise<Capability[]> {
|
|
38
|
-
// Fetch all providers in parallel. One provider failing should not
|
|
39
|
-
// prevent others from contributing — log and continue.
|
|
40
|
-
const results = await Promise.allSettled(
|
|
41
|
-
this.providers.map((p) => p.fetchManifest(filter))
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
const merged: Capability[] = [];
|
|
45
|
-
const seen = new Set<string>();
|
|
46
|
-
|
|
47
|
-
for (let i = 0; i < results.length; i++) {
|
|
48
|
-
const result = results[i];
|
|
49
|
-
const provider = this.providers[i];
|
|
50
|
-
|
|
51
|
-
if (result.status === 'rejected') {
|
|
52
|
-
// DEBUG
|
|
53
|
-
// eslint-disable-next-line no-console
|
|
54
|
-
console.debug(
|
|
55
|
-
`[composite] provider ${provider.providerId} fetchManifest failed — ${String(result.reason)}`
|
|
56
|
-
);
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
for (const cap of result.value) {
|
|
61
|
-
if (seen.has(cap.name)) {
|
|
62
|
-
// DEBUG
|
|
63
|
-
// eslint-disable-next-line no-console
|
|
64
|
-
console.debug(
|
|
65
|
-
`[composite] name collision on "${cap.name}" from ${provider.providerId} — keeping first`
|
|
66
|
-
);
|
|
67
|
-
continue;
|
|
68
|
-
}
|
|
69
|
-
seen.add(cap.name);
|
|
70
|
-
merged.push(cap);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// DEBUG
|
|
75
|
-
// eslint-disable-next-line no-console
|
|
76
|
-
console.debug(
|
|
77
|
-
`[composite] merged manifest: ${merged.length} caps from ${this.providers.length} providers`
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
return merged;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
async createRunnables(
|
|
84
|
-
capabilities: Capability[],
|
|
85
|
-
credentials: CredentialMap
|
|
86
|
-
): Promise<StructuredToolInterface[]> {
|
|
87
|
-
// Determine which capabilities belong to which provider by refetching
|
|
88
|
-
// each provider's manifest and intersecting with the requested set.
|
|
89
|
-
// This keeps providers stateless — we don't require Capability to
|
|
90
|
-
// carry a back-reference to its provider.
|
|
91
|
-
const capabilityNames = new Set(capabilities.map((c) => c.name));
|
|
92
|
-
const perProviderCaps = await Promise.all(
|
|
93
|
-
this.providers.map(async (p) => {
|
|
94
|
-
const manifest = await p.fetchManifest();
|
|
95
|
-
return manifest.filter((c) => capabilityNames.has(c.name));
|
|
96
|
-
})
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
const allRunnables: StructuredToolInterface[] = [];
|
|
100
|
-
for (let i = 0; i < this.providers.length; i++) {
|
|
101
|
-
const providerCaps = perProviderCaps[i];
|
|
102
|
-
if (!providerCaps.length) continue;
|
|
103
|
-
const runnables = await this.providers[i].createRunnables(
|
|
104
|
-
providerCaps,
|
|
105
|
-
credentials
|
|
106
|
-
);
|
|
107
|
-
allRunnables.push(...runnables);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return allRunnables;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './CompositeCapabilityProvider';
|