@agentproto/adapter-mastra-agent 0.5.5 → 0.6.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/{chunk-6ILIPWNM.mjs → chunk-BOEMDDBC.mjs} +109 -17
- package/dist/chunk-BOEMDDBC.mjs.map +1 -0
- package/dist/cli.mjs +1 -1
- package/dist/index.d.ts +194 -178
- package/dist/index.mjs +1 -1
- package/package.json +6 -5
- package/dist/chunk-6ILIPWNM.mjs.map +0 -1
|
@@ -17,6 +17,8 @@ import { ProviderHistoryCompat } from '@mastra/core/processors';
|
|
|
17
17
|
import { AgentController } from '@mastra/core/agent-controller';
|
|
18
18
|
import { Workspace } from '@mastra/core/workspace';
|
|
19
19
|
import { createNotificationInboxTool } from '@mastra/core/notifications';
|
|
20
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
21
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
20
22
|
import { SignalProvider } from '@mastra/core/signals';
|
|
21
23
|
import { PROTOCOL_VERSION, ndJsonStream, AgentSideConnection } from '@agentclientprotocol/sdk';
|
|
22
24
|
import { Writable, Readable } from 'stream';
|
|
@@ -787,6 +789,61 @@ function resolveMastraModel(ref, env = process.env) {
|
|
|
787
789
|
}
|
|
788
790
|
return modelId;
|
|
789
791
|
}
|
|
792
|
+
async function connectDaemonMcpClient(opts = {}) {
|
|
793
|
+
const endpoint = await discoverDaemonEndpoint(opts);
|
|
794
|
+
if (!endpoint) throw new DaemonNotFoundError();
|
|
795
|
+
const env = opts.env ?? process.env;
|
|
796
|
+
const url = new URL(`${endpoint.url}/mcp`);
|
|
797
|
+
if (env.AGENTPROTO_SESSION_ID) url.searchParams.set("callerSessionId", env.AGENTPROTO_SESSION_ID);
|
|
798
|
+
const client = new Client({ name: "agentproto-mastra-agent", version: "0.1.0" }, { capabilities: {} });
|
|
799
|
+
const transport = new StreamableHTTPClientTransport(url, {
|
|
800
|
+
...endpoint.token ? { requestInit: { headers: { authorization: `Bearer ${endpoint.token}` } } } : {}
|
|
801
|
+
});
|
|
802
|
+
await client.connect(transport);
|
|
803
|
+
return client;
|
|
804
|
+
}
|
|
805
|
+
async function listDaemonMcpTools(client) {
|
|
806
|
+
const { tools } = await client.listTools();
|
|
807
|
+
return tools.map((t) => ({
|
|
808
|
+
name: t.name,
|
|
809
|
+
...t.description !== void 0 ? { description: t.description } : {},
|
|
810
|
+
inputSchema: t.inputSchema ?? { type: "object" }
|
|
811
|
+
}));
|
|
812
|
+
}
|
|
813
|
+
function injectAppId(toolName, args, appId) {
|
|
814
|
+
if (!appId) return args;
|
|
815
|
+
if (!toolName.startsWith("app_")) return args;
|
|
816
|
+
if (args.appId !== void 0) return args;
|
|
817
|
+
return { ...args, appId };
|
|
818
|
+
}
|
|
819
|
+
function relaxAppIdRequirement(inputSchema, toolName, appId) {
|
|
820
|
+
if (!appId || !toolName.startsWith("app_")) return inputSchema;
|
|
821
|
+
if (!Array.isArray(inputSchema.required) || !inputSchema.required.includes("appId")) return inputSchema;
|
|
822
|
+
return { ...inputSchema, required: inputSchema.required.filter((id) => id !== "appId") };
|
|
823
|
+
}
|
|
824
|
+
function extractText(content) {
|
|
825
|
+
if (!Array.isArray(content)) return "";
|
|
826
|
+
return content.filter(
|
|
827
|
+
(block) => !!block && typeof block === "object" && block.type === "text" && typeof block.text === "string"
|
|
828
|
+
).map((block) => block.text).join("\n");
|
|
829
|
+
}
|
|
830
|
+
function makeDaemonMcpProxyTool(def, opts) {
|
|
831
|
+
const config = {
|
|
832
|
+
id: def.name,
|
|
833
|
+
description: def.description ?? `Daemon tool "${def.name}", proxied via the daemon's MCP gateway.`,
|
|
834
|
+
inputSchema: relaxAppIdRequirement(def.inputSchema, def.name, opts.appId),
|
|
835
|
+
execute: async (input) => {
|
|
836
|
+
const client = await opts.getClient();
|
|
837
|
+
const args = injectAppId(def.name, input ?? {}, opts.appId);
|
|
838
|
+
const result = await client.callTool({ name: def.name, arguments: args });
|
|
839
|
+
if (result.isError) {
|
|
840
|
+
throw new Error(`daemon tool "${def.name}" failed: ${extractText(result.content) || "(no error detail)"}`);
|
|
841
|
+
}
|
|
842
|
+
return result.structuredContent ?? extractText(result.content);
|
|
843
|
+
}
|
|
844
|
+
};
|
|
845
|
+
return createTool(config);
|
|
846
|
+
}
|
|
790
847
|
var WATCHED_EVENT_KINDS = [
|
|
791
848
|
"turn-end",
|
|
792
849
|
"error",
|
|
@@ -1431,6 +1488,26 @@ function makeAgentFactory(opts = {}) {
|
|
|
1431
1488
|
allowExec: opts.allowExec,
|
|
1432
1489
|
extraTools: opts.extraTools
|
|
1433
1490
|
});
|
|
1491
|
+
const modesEnabled = opts.modes !== false && !envFlag(process.env.AGENTPROTO_MASTRA_NO_MODES);
|
|
1492
|
+
const daemonClient = new DaemonClient({ cwd });
|
|
1493
|
+
const daemonSubAgentTools = modesEnabled ? makeDaemonTools({ client: daemonClient }) : {};
|
|
1494
|
+
let daemonMcpClient;
|
|
1495
|
+
let daemonMcpToolDefsPromise;
|
|
1496
|
+
const resolvedDaemonMcpTools = {};
|
|
1497
|
+
const appId = opts.appId ?? process.env.AGENTPROTO_APP_ID;
|
|
1498
|
+
async function getDaemonMcpToolDefs() {
|
|
1499
|
+
if (!daemonMcpToolDefsPromise) {
|
|
1500
|
+
daemonMcpToolDefsPromise = (async () => {
|
|
1501
|
+
try {
|
|
1502
|
+
daemonMcpClient = opts.daemonMcp?.client ?? await connectDaemonMcpClient({ cwd, ...opts.daemonMcp?.discoverOptions });
|
|
1503
|
+
return await listDaemonMcpTools(daemonMcpClient);
|
|
1504
|
+
} catch {
|
|
1505
|
+
return [];
|
|
1506
|
+
}
|
|
1507
|
+
})();
|
|
1508
|
+
}
|
|
1509
|
+
return daemonMcpToolDefsPromise;
|
|
1510
|
+
}
|
|
1434
1511
|
const store = buildSqliteStore();
|
|
1435
1512
|
let memory;
|
|
1436
1513
|
const historyCompat = new ProviderHistoryCompat({
|
|
@@ -1439,21 +1516,38 @@ function makeAgentFactory(opts = {}) {
|
|
|
1439
1516
|
const { agent } = await buildMastraAgent(handle, {
|
|
1440
1517
|
inputProcessors: [historyCompat],
|
|
1441
1518
|
resolveModel: (ref) => resolveMastraModel(ref),
|
|
1442
|
-
// Match each declared tool ref
|
|
1443
|
-
//
|
|
1444
|
-
//
|
|
1445
|
-
//
|
|
1446
|
-
//
|
|
1447
|
-
//
|
|
1448
|
-
//
|
|
1449
|
-
//
|
|
1450
|
-
|
|
1519
|
+
// Match each declared tool ref, in order: the workspace toolset, the
|
|
1520
|
+
// curated daemon sub-agent tools, then (modes-on only) the generic
|
|
1521
|
+
// daemon MCP proxy — ONLY for a ref an AGENT.md actually declares,
|
|
1522
|
+
// which is what keeps the proxy an allowlist rather than a blanket
|
|
1523
|
+
// grant of the daemon's whole toolset. A ref matching none of those
|
|
1524
|
+
// still resolves — to a stub that fails fast and clearly on call —
|
|
1525
|
+
// rather than being dropped: a dropped ref leaves the model unable to
|
|
1526
|
+
// see it at all, and (if the model still tries the name from AGENT.md
|
|
1527
|
+
// prose) surfaces as an opaque provider NoSuchToolError this adapter's
|
|
1528
|
+
// ACP layer silently swallows (see tool-call-map.ts), which is how a
|
|
1529
|
+
// declared-but-unwired tool used to hang a turn with zero recorded
|
|
1530
|
+
// tool calls instead of failing fast.
|
|
1531
|
+
resolveTool: async (ref) => {
|
|
1451
1532
|
const id = toolRefId(ref);
|
|
1452
1533
|
if (!id) return void 0;
|
|
1453
|
-
const
|
|
1454
|
-
if (
|
|
1534
|
+
const workspaceTool = workspaceTools[id];
|
|
1535
|
+
if (workspaceTool) return { name: id, tool: workspaceTool };
|
|
1536
|
+
const daemonSubAgentTool = daemonSubAgentTools[id];
|
|
1537
|
+
if (daemonSubAgentTool) return { name: id, tool: daemonSubAgentTool };
|
|
1538
|
+
if (modesEnabled) {
|
|
1539
|
+
const def = (await getDaemonMcpToolDefs()).find((d) => d.name === id);
|
|
1540
|
+
if (def) {
|
|
1541
|
+
const tool = makeDaemonMcpProxyTool(def, {
|
|
1542
|
+
getClient: async () => daemonMcpClient,
|
|
1543
|
+
...appId !== void 0 ? { appId } : {}
|
|
1544
|
+
});
|
|
1545
|
+
resolvedDaemonMcpTools[id] = tool;
|
|
1546
|
+
return { name: id, tool };
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1455
1549
|
console.warn(
|
|
1456
|
-
`[@agentproto/adapter-mastra-agent] agent '${handle.id}' declares tool '${id}' but no executor is wired for it in
|
|
1550
|
+
`[@agentproto/adapter-mastra-agent] agent '${handle.id}' declares tool '${id}' but no executor is wired for it (not in the workspace toolset, the daemon sub-agent tools, or the daemon's own MCP tool list) \u2014 calls to it will fail immediately instead of hanging. Wire it in workspace-tools.ts, pass it via extraTools, or expose it from the daemon.`
|
|
1457
1551
|
);
|
|
1458
1552
|
return { name: id, tool: makeUnwiredToolStub(id) };
|
|
1459
1553
|
},
|
|
@@ -1461,12 +1555,10 @@ function makeAgentFactory(opts = {}) {
|
|
|
1461
1555
|
// The markdown body is the agent's primary system prompt (AIP-42).
|
|
1462
1556
|
body
|
|
1463
1557
|
});
|
|
1464
|
-
const modesEnabled = opts.modes !== false && !envFlag(process.env.AGENTPROTO_MASTRA_NO_MODES);
|
|
1465
1558
|
const { modes, defaultModeId } = modesEnabled ? resolveModes(body) : { modes: [{ id: "main", metadata: { default: true } }], defaultModeId: "main" };
|
|
1466
1559
|
let tools = workspaceTools;
|
|
1467
1560
|
if (modesEnabled) {
|
|
1468
|
-
|
|
1469
|
-
tools = { ...workspaceTools, ...makeDaemonTools({ client: daemonClient }) };
|
|
1561
|
+
tools = { ...workspaceTools, ...daemonSubAgentTools, ...resolvedDaemonMcpTools };
|
|
1470
1562
|
const signalProvider = new AgentprotoSignalProvider({
|
|
1471
1563
|
client: daemonClient,
|
|
1472
1564
|
stateEmitter: new DaemonStateEmitter({ client: daemonClient, cwd })
|
|
@@ -2091,5 +2183,5 @@ function runAcpOverStdio(buildController) {
|
|
|
2091
2183
|
}
|
|
2092
2184
|
|
|
2093
2185
|
export { DEFAULT_MODEL, DEFAULT_MODEL_CATALOG, DEFAULT_TOOL_IDS, DISABLED_BUILTIN_TOOL_IDS, DaemonClient, DaemonHttpError, DaemonNotFoundError, MastraAcpAgent, buildSqliteMemory, buildSqliteStore, createEventMapper, defaultAgentManifest, discoverDaemonEndpoint, makeAgentFactory, makeDaemonTools, makeWorkspaceTools, messageText, modelRefToString, promptContent, promptText, providerOf, resolveInCwd, resolveMastraModel, resolveMemoryDbPath, runAcpOverStdio, toolCallTitle, toolKindFor };
|
|
2094
|
-
//# sourceMappingURL=chunk-
|
|
2095
|
-
//# sourceMappingURL=chunk-
|
|
2186
|
+
//# sourceMappingURL=chunk-BOEMDDBC.mjs.map
|
|
2187
|
+
//# sourceMappingURL=chunk-BOEMDDBC.mjs.map
|