@xopcai/xopc 0.0.187 → 0.0.188
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/browser-ext/manifest.json +1 -1
- package/dist/extensions/demo-memory/src/index.js +1 -0
- package/dist/extensions/feishu/src/streaming/streaming-adapter.js +1 -3
- package/dist/extensions/telegram/src/adapters/streaming-adapter.js +0 -2
- package/dist/extensions/telegram/src/draft-stream.d.ts +0 -4
- package/dist/extensions/telegram/src/draft-stream.js +1 -53
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-WlR2zEvA.js → activity-store--QoUGhiS.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-RedDszrG.js → agent-avatar-dicebear-B0yweLNQ.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-Df9mTa-K.js → agents-C6OV-gMm.js} +1 -1
- package/dist/gateway/static/root/assets/{api-tVOllncq.js → api-5laWqfiE.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-C9hKBzaF.js → app-management-settings-panel-BXJ8Jiv_.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-5cQvq7hd.js → appearance-settings-DG9n9D1M.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-Bd3tN-k2.js → apps-page-Ci14lDeO.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-Ct-shK4n.js → archive-plugin-Ceh5qrZf.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-CpPj3m-q.js → attachment-load-jFW7uYf7.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-Q1xmb4Rh.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-BpSXZBle.js → binary-plugins-XDlkI1r4.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-B8hR2tXc.js → block-editor-kyKc2IhE.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-jb5Hf-hm.js → browser-settings-page-DbowrHXD.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-D_LAXUrh.js → browser-workflow-inputs-BJa5Iz_v.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-CPAs7-6s.js → browser-workflows-page-CTQQOsn5.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-BjUe4raq.js → capabilities-settings-panel-DoZPFdKF.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-presets-api-CKklVY2p.js → capability-presets-api-Dn-7MMEo.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-presets-settings-panel-DiWIMYRr.js → capability-presets-settings-panel-Bt8Hnx0h.js} +1 -1
- package/dist/gateway/static/root/assets/{channel-recipient-api-WWN-nbFL.js → channel-recipient-api-BgIkWq01.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-D8IkjMuX.js → channels-settings-Bpsebsru.js} +1 -1
- package/dist/gateway/static/root/assets/channels-status-swr-DFmdYRE5.js +1 -0
- package/dist/gateway/static/root/assets/{connector-logo-CdNkVFdB.js → connector-logo-TRr9ybf6.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-BT2ahw52.js → connectors-page-Tg5kl22i.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-Bm_IEAf3.js → desktop-pet-CSwd00CV.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-C0Ve04-G.js → desktop-pet-settings-CuNQvHGu.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-B2cvhvAI.js → directory-picker-path-field-ct0n5Rje.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DNashgGu.js → extension-debug-page-BeRBuMUU.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-Bvo-5htX.js → extension-page-DbK-Cwao.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BBESdISV.js → extension-settings-page-C9ag5tb5.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-ClQvokMo.js → gateway-config-api-CC7EvEFp.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-CIRs2QVy.js → gateway-settings-9g8uIry9.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-CntXJF6W.js → gateway-startup-retry-B2DmdlwO.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-CWKcZuvc.js → heartbeat-settings-fl1oC_-5.js} +1 -1
- package/dist/gateway/static/root/assets/{home-page-C59f8UJw.js → home-page-Bao9jq_z.js} +1 -1
- package/dist/gateway/static/root/assets/{image-generation-api-DjSAQwGy.js → image-generation-api-GMTaS6eI.js} +1 -1
- package/dist/gateway/static/root/assets/index-Cl5n1f_U.css +1 -0
- package/dist/gateway/static/root/assets/index-OJgiMh07.js +223 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-ahKHpjoW.js → keyboard-shortcuts-settings-DhGYddbI.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-DRB4UQBE.js → local-app-workbench-page-B69NvtvH.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-B6GKdgza.js → local-apps-page-CmnrBmWi.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-Bff30u5V.js → locale-store-D6hs74o5.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-CNp4XiBN.js → logs-page-Cq3cABqg.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-BeNMJm_i.js → markdown-split-CZaBPOVn.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-Bdzrj_-6.js → media-plugins-CiKvSgCv.js} +1 -1
- package/dist/gateway/static/root/assets/messages-D02NNLCZ.js +3 -0
- package/dist/gateway/static/root/assets/{notes-page-MYIi-9S9.js → notes-page-Bisbzqlz.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-workbench-DqSkeDXX.js → notes-workbench-BOZfJFhE.js} +2 -2
- package/dist/gateway/static/root/assets/{page-tabs-3t88bbGx.js → page-tabs-BxlwhAbH.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-Cf_BWbeE.js → preview-open-alternatives-RM8wXxfT.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-CKq73c98.js → product-open-page-DdBlibek.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-BrbHs4Wp.js → project-detail-page-TSKFb2tN.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-B80rtkj6.js → projects-page-BokeBrTT.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-_Q3GEznb.js → remote-access-hub-C56anxCX.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-NqOm-OG1.js → schema-form-BDKbpmXv.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-55dJOUVg.js → sessions-page-C7TQADrD.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-BDOPKeAX.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-DYAS8p8z.js → settings-form-section-zxo5ZGOu.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-DZFhxihA.js → settings-loading-skeleton-DgIp8_S6.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-BSIiMLi-.js → settings-page-BUPSIa9P.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-DfFfkdED.js → settings-page-layout-97LmwrzC.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-q_yE6-H1.js → setup-status-panel-BRg766eW.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-CYtrQaZN.js → share-preview-page-BH7i3g1S.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-gYkRX9Ik.js → shares-settings-DhEAviQ_.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-Ct7AV8ls.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-GZHKDFSb.js → skills-page-DoVuprZm.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-BBXirAjc.js → skills-page.utils-s-a5WV9j.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-DLf5YvFl.js → system-settings-panel-BxjeMT5k.js} +1 -1
- package/dist/gateway/static/root/assets/{task-detail-page-DFGkuYfl.js → task-detail-page-BahycnfW.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-y7e_tvYi.js → theme-store-BRxdsmic.js} +1 -1
- package/dist/gateway/static/root/assets/{time-picker-5sHEZ5w5.js → time-picker-BGk_Tbsj.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-DR12j_dr.js → typed-models-lib-39MjwPSq.js} +1 -1
- package/dist/gateway/static/root/assets/{use-save-bar-registration-BsvcJgZl.js → use-save-bar-registration-5aVSjTjO.js} +1 -1
- package/dist/gateway/static/root/assets/{user-context-page-q5dr8JFG.js → user-context-page-B9K41qmy.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-DKADXFWD.js → voice-api-key-field-XU-7sBSg.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BC1nExf8.js → work-discovery-overlay-CJqu8UHq.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-page-fNvSg40M.js → work-discovery-page-BBVnRHju.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-C8X5W-8k.js → workflow-run-setup-panel-DXtg8Qxl.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-YJBKmPYK.js → workflows-page-Bs_tYfst.js} +1 -1
- package/dist/gateway/static/root/index.html +7 -7
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/tool-activity.js +223 -0
- package/dist/src/agent/agent-manager.js +2 -8
- package/dist/src/agent/code-intelligence/binary.js +1 -1
- package/dist/src/agent/embedded/run-for-session.d.ts +0 -2
- package/dist/src/agent/embedded/run-for-session.js +99 -112
- package/dist/src/agent/external-tools/composio-provider.d.ts +29 -0
- package/dist/src/agent/external-tools/composio-provider.js +307 -0
- package/dist/src/agent/external-tools/extension-provider.d.ts +20 -0
- package/dist/src/agent/external-tools/extension-provider.js +68 -0
- package/dist/src/agent/external-tools/gateway-tools.d.ts +8 -0
- package/dist/src/agent/external-tools/gateway-tools.js +89 -0
- package/dist/src/agent/external-tools/index.d.ts +24 -0
- package/dist/src/agent/external-tools/index.js +40 -0
- package/dist/src/agent/external-tools/mcp-provider.d.ts +29 -0
- package/dist/src/agent/external-tools/mcp-provider.js +118 -0
- package/dist/src/agent/external-tools/memory-provider.d.ts +21 -0
- package/dist/src/agent/external-tools/memory-provider.js +56 -0
- package/dist/src/agent/external-tools/refs.d.ts +5 -0
- package/dist/src/agent/external-tools/refs.js +18 -0
- package/dist/src/agent/external-tools/service.d.ts +26 -0
- package/dist/src/agent/external-tools/service.js +117 -0
- package/dist/src/agent/external-tools/types.d.ts +28 -0
- package/dist/src/agent/external-tools/types.js +9 -0
- package/dist/src/agent/inbound/inbound-loop.d.ts +0 -2
- package/dist/src/agent/inbound/inbound-loop.js +0 -3
- package/dist/src/agent/mcp/{bundle-mcp-materialize.d.ts → bundle-mcp-gateway.d.ts} +1 -19
- package/dist/src/agent/mcp/bundle-mcp-gateway.js +60 -0
- package/dist/src/agent/mcp/bundle-mcp-names.d.ts +0 -8
- package/dist/src/agent/mcp/bundle-mcp-names.js +2 -29
- package/dist/src/agent/mcp/bundle-mcp-policy.d.ts +4 -7
- package/dist/src/agent/mcp/bundle-mcp-policy.js +6 -20
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +2 -2
- package/dist/src/agent/mcp/bundle-mcp-tools.d.ts +1 -2
- package/dist/src/agent/mcp/bundle-mcp-tools.js +1 -2
- package/dist/src/agent/mcp/bundle-mcp-types.d.ts +0 -5
- package/dist/src/agent/mcp/index.d.ts +0 -2
- package/dist/src/agent/mcp/index.js +2 -5
- package/dist/src/agent/mcp/mcp-stdio-transport.js +1 -1
- package/dist/src/agent/mcp/mcp-transport.js +1 -1
- package/dist/src/agent/memory/context/planner.d.ts +1 -0
- package/dist/src/agent/memory/context/planner.js +22 -7
- package/dist/src/agent/memory/manager.d.ts +4 -1
- package/dist/src/agent/memory/manager.js +5 -2
- package/dist/src/agent/memory/types.d.ts +2 -0
- package/dist/src/agent/messaging/stream-manager.d.ts +2 -14
- package/dist/src/agent/messaging/stream-manager.js +0 -12
- package/dist/src/agent/orchestration/agent-event-handler.d.ts +1 -3
- package/dist/src/agent/orchestration/agent-event-handler.js +0 -36
- package/dist/src/agent/orchestration/agent-orchestrator.d.ts +0 -5
- package/dist/src/agent/orchestration/agent-orchestrator.js +0 -5
- package/dist/src/agent/prompt/sections/behavior.js +6 -4
- package/dist/src/agent/service.d.ts +0 -3
- package/dist/src/agent/service.js +0 -28
- package/dist/src/agent/service.types.d.ts +0 -3
- package/dist/src/agent/skills/hub-pull.js +1 -1
- package/dist/src/agent/starter-agents.js +2 -2
- package/dist/src/agent/tools/delegate-tool.js +5 -1
- package/dist/src/agent/tools/executor.js +1 -1
- package/dist/src/agent/tools/factory.d.ts +2 -1
- package/dist/src/agent/tools/factory.js +16 -22
- package/dist/src/agent/tools/index.d.ts +0 -1
- package/dist/src/agent/tools/index.js +1 -2
- package/dist/src/agent/workflow/workflow-child-tools.js +7 -1
- package/dist/src/browser/providers/cloakbrowser.js +1 -1
- package/dist/src/channels/channel-domain.d.ts +0 -4
- package/dist/src/channels/plugin-types.d.ts +0 -2
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/connectors/health.js +1 -1
- package/dist/src/extensions/extension-registry-impl.d.ts +3 -1
- package/dist/src/extensions/extension-registry-impl.js +7 -1
- package/dist/src/extensions/loader.js +1 -1
- package/dist/src/extensions/types/core.d.ts +2 -1
- package/dist/src/extensions/update.js +1 -1
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/agent-builtin-tools.js +5 -2
- package/dist/src/gateway/chat-stream/mapper.js +16 -1
- package/dist/src/gateway/chat-stream/protocol.d.ts +4 -0
- package/dist/src/gateway/file-reference-errors.d.ts +6 -0
- package/dist/src/gateway/file-reference-errors.js +21 -0
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/mcp.js +1 -1
- package/dist/src/gateway/hono/routes/projects.js +34 -13
- package/dist/src/gateway/hono/routes/workflows.js +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +34 -13
- package/dist/src/gateway/hono/routes/you.js +3 -3
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service/run-gateway-agent.js +4 -1
- package/dist/src/gateway/service.js +6 -6
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/share/share-zip.js +1 -1
- package/dist/src/storage/sqlite/memory-records-repository.js +3 -1
- package/dist/src/storage/sqlite/migrations/108_repair_user_memory_provider.sql +18 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/tui/tool-summary.d.ts +1 -2
- package/dist/src/tui/tool-summary.js +2 -18
- package/dist/src/tunnel/frpc-binary.js +1 -1
- package/dist/src/user-context/projection.d.ts +1 -0
- package/dist/src/user-context/projection.js +2 -1
- package/dist/src/voice/local/model-files.js +1 -1
- package/dist/src/work-discovery/service.js +1 -1
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/automations-page-w6K9GZQ7.js +0 -6
- package/dist/gateway/static/root/assets/channels-status-swr-CySs1GQX.js +0 -1
- package/dist/gateway/static/root/assets/index-D-YfWVyS.css +0 -1
- package/dist/gateway/static/root/assets/index-vi5KlR5_.js +0 -222
- package/dist/gateway/static/root/assets/messages-CPxz48hr.js +0 -3
- package/dist/gateway/static/root/assets/settings-advanced-gate-CSFCZj14.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BoNBMKW6.js +0 -1
- package/dist/src/agent/feedback/feedback-coordinator.d.ts +0 -73
- package/dist/src/agent/feedback/feedback-coordinator.js +0 -156
- package/dist/src/agent/feedback/index.d.ts +0 -4
- package/dist/src/agent/feedback/index.js +0 -2
- package/dist/src/agent/lifecycle/progress.d.ts +0 -90
- package/dist/src/agent/lifecycle/progress.js +0 -339
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +0 -183
- package/dist/src/agent/mcp/mcp-tool-meta.d.ts +0 -8
- package/dist/src/agent/mcp/mcp-tool-meta.js +0 -13
- package/dist/src/agent/mcp/resolve-embedded-mcp-tools.d.ts +0 -14
- package/dist/src/agent/mcp/resolve-embedded-mcp-tools.js +0 -48
- package/dist/src/agent/tools/composio-tool.d.ts +0 -21
- package/dist/src/agent/tools/composio-tool.js +0 -261
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
|
|
2
|
+
import { externalToolRef, parseExternalToolRef } from "./refs.js";
|
|
3
|
+
import { isMcpCatalogToolDenied, mcpToolPolicyId } from "../mcp/bundle-mcp-policy.js";
|
|
4
|
+
import { getOrCreateSessionMcpRuntime } from "../mcp/bundle-mcp-runtime.js";
|
|
5
|
+
//#region src/agent/external-tools/mcp-provider.ts
|
|
6
|
+
function policyToolId(tool) {
|
|
7
|
+
return mcpToolPolicyId(tool.safeServerName, tool.toolName);
|
|
8
|
+
}
|
|
9
|
+
function toAgentToolResult(params) {
|
|
10
|
+
const content = Array.isArray(params.result.content) ? params.result.content : [];
|
|
11
|
+
return {
|
|
12
|
+
content: content.length > 0 ? content : [{
|
|
13
|
+
type: "text",
|
|
14
|
+
text: JSON.stringify(params.result.structuredContent ?? {
|
|
15
|
+
status: params.result.isError === true ? "error" : "ok",
|
|
16
|
+
server: params.serverName,
|
|
17
|
+
tool: params.toolName
|
|
18
|
+
}, null, 2)
|
|
19
|
+
}],
|
|
20
|
+
details: {
|
|
21
|
+
mcpServer: params.serverName,
|
|
22
|
+
mcpTool: params.toolName,
|
|
23
|
+
...params.result.structuredContent !== void 0 ? { structuredContent: params.result.structuredContent } : {},
|
|
24
|
+
...params.result.isError === true ? { status: "error" } : {}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
var McpToolProvider = class {
|
|
29
|
+
source = "mcp";
|
|
30
|
+
constructor(deps) {
|
|
31
|
+
this.deps = deps;
|
|
32
|
+
}
|
|
33
|
+
async search(_query) {
|
|
34
|
+
return this.withRuntime(async (runtime) => {
|
|
35
|
+
return (await runtime.getCatalog()).tools.filter((tool) => this.isAllowed(tool)).map((tool) => ({
|
|
36
|
+
toolRef: externalToolRef(this.source, tool.serverName, tool.toolName),
|
|
37
|
+
source: this.source,
|
|
38
|
+
namespace: tool.serverName,
|
|
39
|
+
title: tool.title || tool.toolName,
|
|
40
|
+
summary: tool.description || tool.fallbackDescription
|
|
41
|
+
}));
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
async describe(toolRef) {
|
|
45
|
+
return this.withRuntime(async (runtime) => {
|
|
46
|
+
const tool = await this.resolve(runtime, toolRef);
|
|
47
|
+
if (!tool) return void 0;
|
|
48
|
+
const summary = tool.description || tool.fallbackDescription;
|
|
49
|
+
return {
|
|
50
|
+
toolRef,
|
|
51
|
+
source: this.source,
|
|
52
|
+
namespace: tool.serverName,
|
|
53
|
+
title: tool.title || tool.toolName,
|
|
54
|
+
summary,
|
|
55
|
+
description: summary,
|
|
56
|
+
inputSchema: tool.inputSchema
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async execute(toolRef, args, _approvalId, context) {
|
|
61
|
+
return this.withRuntime(async (runtime) => {
|
|
62
|
+
const tool = await this.resolve(runtime, toolRef);
|
|
63
|
+
if (!tool) throw new Error(`MCP tool is unavailable or denied: ${toolRef}`);
|
|
64
|
+
let executionArgs = args;
|
|
65
|
+
if (this.deps.hookRunner) {
|
|
66
|
+
const hook = await this.deps.hookRunner.runBeforeToolCall(policyToolId(tool), args, {
|
|
67
|
+
sessionKey: this.deps.getSessionKey(),
|
|
68
|
+
isMcpTool: true,
|
|
69
|
+
mcpServerId: tool.serverName
|
|
70
|
+
});
|
|
71
|
+
if (!hook.allowed) throw new Error(hook.reason ?? "MCP tool call blocked by policy hook.");
|
|
72
|
+
executionArgs = hook.params ?? args;
|
|
73
|
+
}
|
|
74
|
+
const result = await runtime.callTool(tool.serverName, tool.toolName, executionArgs, context.signal);
|
|
75
|
+
return toAgentToolResult({
|
|
76
|
+
serverName: tool.serverName,
|
|
77
|
+
toolName: tool.toolName,
|
|
78
|
+
result
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async resolve(runtime, toolRef) {
|
|
83
|
+
const parsed = parseExternalToolRef(toolRef, this.source);
|
|
84
|
+
if (!parsed) return void 0;
|
|
85
|
+
const tool = (await runtime.getCatalog()).tools.find((candidate) => candidate.serverName === parsed.namespace && candidate.toolName === parsed.toolName);
|
|
86
|
+
return tool && this.isAllowed(tool) ? tool : void 0;
|
|
87
|
+
}
|
|
88
|
+
isAllowed(tool) {
|
|
89
|
+
const cfg = this.deps.getConfig();
|
|
90
|
+
const sessionKey = this.deps.getSessionKey();
|
|
91
|
+
const profile = cfg && sessionKey ? resolveEffectiveAgentProfileForSession(cfg, sessionKey) : void 0;
|
|
92
|
+
const policyName = policyToolId(tool);
|
|
93
|
+
return !profile?.tools.denied.has(policyName) && !isMcpCatalogToolDenied({
|
|
94
|
+
serverId: tool.safeServerName,
|
|
95
|
+
policyToolId: policyName
|
|
96
|
+
}, profile?.manifest.tools.mcp);
|
|
97
|
+
}
|
|
98
|
+
async withRuntime(run) {
|
|
99
|
+
const cfg = this.deps.getConfig();
|
|
100
|
+
const sessionKey = this.deps.getSessionKey();
|
|
101
|
+
const sessionId = sessionKey ?? `agent:${this.deps.agentId ?? "main"}`;
|
|
102
|
+
const runtime = await (this.deps.getRuntime ?? getOrCreateSessionMcpRuntime)({
|
|
103
|
+
sessionId,
|
|
104
|
+
sessionKey,
|
|
105
|
+
workspaceDir: this.deps.workspace,
|
|
106
|
+
cfg
|
|
107
|
+
});
|
|
108
|
+
const releaseLease = runtime.acquireLease?.();
|
|
109
|
+
runtime.markUsed();
|
|
110
|
+
try {
|
|
111
|
+
return await run(runtime);
|
|
112
|
+
} finally {
|
|
113
|
+
releaseLease?.();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
//#endregion
|
|
118
|
+
export { McpToolProvider };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ExtensionHookRunner } from '../../extensions/index.js';
|
|
2
|
+
import type { MemoryManager } from '../memory/manager.js';
|
|
3
|
+
import { type ToolExecutorConfig } from '../tools/executor.js';
|
|
4
|
+
import type { ExternalToolDescriptor, ExternalToolExecutionContext, ExternalToolProvider, ExternalToolSearchHit } from './types.js';
|
|
5
|
+
export interface MemoryToolProviderDeps {
|
|
6
|
+
getMemoryManager?: () => MemoryManager;
|
|
7
|
+
disabledTools?: Set<string>;
|
|
8
|
+
getSessionKey: () => string | undefined;
|
|
9
|
+
hookRunner?: ExtensionHookRunner;
|
|
10
|
+
toolExecutorConfig?: Partial<ToolExecutorConfig>;
|
|
11
|
+
}
|
|
12
|
+
export declare class MemoryToolProvider implements ExternalToolProvider {
|
|
13
|
+
private readonly deps;
|
|
14
|
+
readonly source: "memory";
|
|
15
|
+
constructor(deps: MemoryToolProviderDeps);
|
|
16
|
+
search(_query: string): Promise<ExternalToolSearchHit[]>;
|
|
17
|
+
describe(toolRef: string): Promise<ExternalToolDescriptor | undefined>;
|
|
18
|
+
execute(toolRef: string, args: Record<string, unknown>, _approvalId: string | undefined, context: ExternalToolExecutionContext): Promise<import("@earendil-works/pi-agent-core").AgentToolResult<any>>;
|
|
19
|
+
private entries;
|
|
20
|
+
private resolve;
|
|
21
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { externalToolRef, parseExternalToolRef } from "./refs.js";
|
|
2
|
+
import { executeToolWithProtection } from "../tools/executor.js";
|
|
3
|
+
//#region src/agent/external-tools/memory-provider.ts
|
|
4
|
+
function toolSummary(tool) {
|
|
5
|
+
return tool.description || tool.label || tool.name;
|
|
6
|
+
}
|
|
7
|
+
var MemoryToolProvider = class {
|
|
8
|
+
source = "memory";
|
|
9
|
+
constructor(deps) {
|
|
10
|
+
this.deps = deps;
|
|
11
|
+
}
|
|
12
|
+
async search(_query) {
|
|
13
|
+
return this.entries().map(({ providerId, tool }) => ({
|
|
14
|
+
toolRef: externalToolRef(this.source, providerId, tool.name),
|
|
15
|
+
source: this.source,
|
|
16
|
+
namespace: providerId,
|
|
17
|
+
title: tool.label || tool.name,
|
|
18
|
+
summary: toolSummary(tool)
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
async describe(toolRef) {
|
|
22
|
+
const resolved = this.resolve(toolRef);
|
|
23
|
+
if (!resolved) return void 0;
|
|
24
|
+
const summary = toolSummary(resolved.tool);
|
|
25
|
+
return {
|
|
26
|
+
toolRef,
|
|
27
|
+
source: this.source,
|
|
28
|
+
namespace: resolved.providerId,
|
|
29
|
+
title: resolved.tool.label || resolved.tool.name,
|
|
30
|
+
summary,
|
|
31
|
+
description: summary,
|
|
32
|
+
inputSchema: resolved.tool.parameters
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
async execute(toolRef, args, _approvalId, context) {
|
|
36
|
+
const resolved = this.resolve(toolRef);
|
|
37
|
+
if (!resolved) throw new Error(`Memory provider tool is unavailable: ${toolRef}`);
|
|
38
|
+
let executionArgs = args;
|
|
39
|
+
if (this.deps.hookRunner) {
|
|
40
|
+
const hook = await this.deps.hookRunner.runBeforeToolCall(resolved.tool.name, args, { sessionKey: this.deps.getSessionKey() });
|
|
41
|
+
if (!hook.allowed) throw new Error(hook.reason ?? "Memory provider tool call blocked by policy hook.");
|
|
42
|
+
executionArgs = hook.params ?? args;
|
|
43
|
+
}
|
|
44
|
+
return executeToolWithProtection(resolved.tool, context.toolCallId, executionArgs, context.signal, context.onUpdate, this.deps.toolExecutorConfig);
|
|
45
|
+
}
|
|
46
|
+
entries() {
|
|
47
|
+
return (this.deps.getMemoryManager?.().getExternalToolEntries() ?? []).filter(({ tool }) => !this.deps.disabledTools?.has(tool.name));
|
|
48
|
+
}
|
|
49
|
+
resolve(toolRef) {
|
|
50
|
+
const parsed = parseExternalToolRef(toolRef, this.source);
|
|
51
|
+
if (!parsed) return void 0;
|
|
52
|
+
return this.entries().find(({ providerId, tool }) => providerId === parsed.namespace && tool.name === parsed.toolName);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
//#endregion
|
|
56
|
+
export { MemoryToolProvider };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/agent/external-tools/refs.ts
|
|
2
|
+
function externalToolRef(source, namespace, toolName) {
|
|
3
|
+
return `${source}:${encodeURIComponent(namespace)}:${encodeURIComponent(toolName)}`;
|
|
4
|
+
}
|
|
5
|
+
function parseExternalToolRef(toolRef, expectedSource) {
|
|
6
|
+
const parts = toolRef.split(":");
|
|
7
|
+
if (parts.length !== 3 || parts[0] !== expectedSource) return void 0;
|
|
8
|
+
try {
|
|
9
|
+
return {
|
|
10
|
+
namespace: decodeURIComponent(parts[1]),
|
|
11
|
+
toolName: decodeURIComponent(parts[2])
|
|
12
|
+
};
|
|
13
|
+
} catch {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { externalToolRef, parseExternalToolRef };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ExternalToolExecutionContext, ExternalToolProvider, ExternalToolSearchHit, ExternalToolSource, VersionedExternalToolDescriptor } from './types.js';
|
|
2
|
+
export declare class ExternalToolService {
|
|
3
|
+
private readonly providerBySource;
|
|
4
|
+
private readonly ajv;
|
|
5
|
+
constructor(providers: ExternalToolProvider[]);
|
|
6
|
+
search(params: {
|
|
7
|
+
query: string;
|
|
8
|
+
sources?: ExternalToolSource[];
|
|
9
|
+
limit?: number;
|
|
10
|
+
}): Promise<{
|
|
11
|
+
tools: ExternalToolSearchHit[];
|
|
12
|
+
unavailableSources: ExternalToolSource[];
|
|
13
|
+
}>;
|
|
14
|
+
describe(toolRefs: string[]): Promise<{
|
|
15
|
+
tools: VersionedExternalToolDescriptor[];
|
|
16
|
+
notFound: string[];
|
|
17
|
+
}>;
|
|
18
|
+
execute(params: {
|
|
19
|
+
toolRef: string;
|
|
20
|
+
revision: string;
|
|
21
|
+
arguments?: Record<string, unknown>;
|
|
22
|
+
approvalId?: string;
|
|
23
|
+
context: ExternalToolExecutionContext;
|
|
24
|
+
}): Promise<import("@earendil-works/pi-agent-core").AgentToolResult<Record<string, unknown>>>;
|
|
25
|
+
private providerForRef;
|
|
26
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import Ajv2020 from "ajv/dist/2020.js";
|
|
3
|
+
//#region src/agent/external-tools/service.ts
|
|
4
|
+
const DEFAULT_SEARCH_LIMIT = 8;
|
|
5
|
+
const MAX_SEARCH_LIMIT = 20;
|
|
6
|
+
const MAX_DESCRIBE_COUNT = 3;
|
|
7
|
+
const MAX_DESCRIPTOR_BYTES = 64 * 1024;
|
|
8
|
+
function normalizedTokens(value) {
|
|
9
|
+
return value.toLowerCase().split(/[^\p{L}\p{N}_-]+/u).filter(Boolean);
|
|
10
|
+
}
|
|
11
|
+
function relevanceScore(hit, query) {
|
|
12
|
+
const haystack = `${hit.title} ${hit.summary} ${hit.namespace}`.toLowerCase();
|
|
13
|
+
const tokens = normalizedTokens(query);
|
|
14
|
+
if (tokens.length === 0) return 0;
|
|
15
|
+
return tokens.reduce((score, token) => {
|
|
16
|
+
if (hit.title.toLowerCase() === token) return score + 8;
|
|
17
|
+
if (hit.title.toLowerCase().includes(token)) return score + 4;
|
|
18
|
+
return haystack.includes(token) ? score + 1 : score;
|
|
19
|
+
}, 0);
|
|
20
|
+
}
|
|
21
|
+
function descriptorRevision(descriptor) {
|
|
22
|
+
return crypto.createHash("sha256").update(JSON.stringify({
|
|
23
|
+
toolRef: descriptor.toolRef,
|
|
24
|
+
description: descriptor.description,
|
|
25
|
+
inputSchema: descriptor.inputSchema
|
|
26
|
+
})).digest("hex").slice(0, 16);
|
|
27
|
+
}
|
|
28
|
+
function versionDescriptor(descriptor) {
|
|
29
|
+
return {
|
|
30
|
+
...descriptor,
|
|
31
|
+
revision: descriptorRevision(descriptor)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
var ExternalToolService = class {
|
|
35
|
+
providerBySource;
|
|
36
|
+
ajv = new Ajv2020({
|
|
37
|
+
allErrors: true,
|
|
38
|
+
strict: false,
|
|
39
|
+
validateFormats: false,
|
|
40
|
+
validateSchema: false
|
|
41
|
+
});
|
|
42
|
+
constructor(providers) {
|
|
43
|
+
this.providerBySource = new Map(providers.map((provider) => [provider.source, provider]));
|
|
44
|
+
}
|
|
45
|
+
async search(params) {
|
|
46
|
+
const selected = params.sources?.length ? params.sources.map((source) => this.providerBySource.get(source)).filter((provider) => provider !== void 0) : [...this.providerBySource.values()];
|
|
47
|
+
const settled = await Promise.allSettled(selected.map(async (provider) => ({
|
|
48
|
+
provider,
|
|
49
|
+
hits: await provider.search(params.query)
|
|
50
|
+
})));
|
|
51
|
+
const unavailableSources = [];
|
|
52
|
+
const hits = [];
|
|
53
|
+
for (const [index, result] of settled.entries()) if (result.status === "fulfilled") hits.push(...result.value.hits);
|
|
54
|
+
else {
|
|
55
|
+
const provider = selected[index];
|
|
56
|
+
if (provider) unavailableSources.push(provider.source);
|
|
57
|
+
}
|
|
58
|
+
const limit = Math.min(MAX_SEARCH_LIMIT, Math.max(1, params.limit ?? DEFAULT_SEARCH_LIMIT));
|
|
59
|
+
return {
|
|
60
|
+
tools: hits.map((hit) => ({
|
|
61
|
+
hit,
|
|
62
|
+
score: relevanceScore(hit, params.query)
|
|
63
|
+
})).filter((entry) => entry.score > 0 || normalizedTokens(params.query).length === 0).toSorted((left, right) => right.score - left.score || left.hit.toolRef.localeCompare(right.hit.toolRef)).slice(0, limit).map(({ hit }) => ({
|
|
64
|
+
toolRef: hit.toolRef,
|
|
65
|
+
source: hit.source,
|
|
66
|
+
namespace: hit.namespace,
|
|
67
|
+
title: hit.title,
|
|
68
|
+
summary: hit.summary.slice(0, 300)
|
|
69
|
+
})),
|
|
70
|
+
unavailableSources
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
async describe(toolRefs) {
|
|
74
|
+
if (toolRefs.length === 0 || toolRefs.length > MAX_DESCRIBE_COUNT) throw new Error(`Describe between 1 and ${MAX_DESCRIBE_COUNT} tools per call.`);
|
|
75
|
+
const tools = [];
|
|
76
|
+
const notFound = [];
|
|
77
|
+
for (const toolRef of toolRefs) {
|
|
78
|
+
const provider = this.providerForRef(toolRef);
|
|
79
|
+
const descriptor = provider ? await provider.describe(toolRef) : void 0;
|
|
80
|
+
if (!descriptor) {
|
|
81
|
+
notFound.push(toolRef);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const versioned = versionDescriptor(descriptor);
|
|
85
|
+
if (Buffer.byteLength(JSON.stringify(versioned), "utf8") > MAX_DESCRIPTOR_BYTES) throw new Error(`Tool contract is too large to expose safely: ${toolRef}`);
|
|
86
|
+
tools.push(versioned);
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
tools,
|
|
90
|
+
notFound
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
async execute(params) {
|
|
94
|
+
const provider = this.providerForRef(params.toolRef);
|
|
95
|
+
if (!provider) throw new Error(`Unknown external tool source: ${params.toolRef}`);
|
|
96
|
+
const descriptor = await provider.describe(params.toolRef);
|
|
97
|
+
if (!descriptor) throw new Error(`External tool is unavailable: ${params.toolRef}`);
|
|
98
|
+
const current = versionDescriptor(descriptor);
|
|
99
|
+
if (current.revision !== params.revision) throw new Error(`Tool contract changed. Describe ${params.toolRef} again before executing it.`);
|
|
100
|
+
const args = params.arguments ?? {};
|
|
101
|
+
let validate;
|
|
102
|
+
try {
|
|
103
|
+
validate = this.ajv.compile(current.inputSchema);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
throw new Error(`Tool contract is invalid: ${params.toolRef}`, { cause: error });
|
|
106
|
+
}
|
|
107
|
+
if (!validate(args)) throw new Error(`Arguments do not match ${params.toolRef}: ${this.ajv.errorsText(validate.errors)}`);
|
|
108
|
+
return provider.execute(params.toolRef, args, params.approvalId, params.context);
|
|
109
|
+
}
|
|
110
|
+
providerForRef(toolRef) {
|
|
111
|
+
const separator = toolRef.indexOf(":");
|
|
112
|
+
if (separator <= 0) return void 0;
|
|
113
|
+
return this.providerBySource.get(toolRef.slice(0, separator));
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
//#endregion
|
|
117
|
+
export { ExternalToolService };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AgentToolResult, AgentToolUpdateCallback } from '@earendil-works/pi-agent-core';
|
|
2
|
+
export declare const EXTERNAL_TOOL_SOURCES: readonly ["mcp", "composio", "extension", "memory"];
|
|
3
|
+
export type ExternalToolSource = (typeof EXTERNAL_TOOL_SOURCES)[number];
|
|
4
|
+
export interface ExternalToolSearchHit {
|
|
5
|
+
toolRef: string;
|
|
6
|
+
source: ExternalToolSource;
|
|
7
|
+
namespace: string;
|
|
8
|
+
title: string;
|
|
9
|
+
summary: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ExternalToolDescriptor extends ExternalToolSearchHit {
|
|
12
|
+
description: string;
|
|
13
|
+
inputSchema: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
export interface VersionedExternalToolDescriptor extends ExternalToolDescriptor {
|
|
16
|
+
revision: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ExternalToolExecutionContext {
|
|
19
|
+
toolCallId: string;
|
|
20
|
+
signal?: AbortSignal;
|
|
21
|
+
onUpdate?: AgentToolUpdateCallback<Record<string, unknown>>;
|
|
22
|
+
}
|
|
23
|
+
export interface ExternalToolProvider {
|
|
24
|
+
readonly source: ExternalToolSource;
|
|
25
|
+
search(query: string): Promise<ExternalToolSearchHit[]>;
|
|
26
|
+
describe(toolRef: string): Promise<ExternalToolDescriptor | undefined>;
|
|
27
|
+
execute(toolRef: string, args: Record<string, unknown>, approvalId: string | undefined, context: ExternalToolExecutionContext): Promise<AgentToolResult<Record<string, unknown>>>;
|
|
28
|
+
}
|
|
@@ -23,7 +23,6 @@ import type { CommandHandler, OutboundCoordinator, StreamManager } from '../mess
|
|
|
23
23
|
import type { MessageRouter } from '../messaging/message-router.js';
|
|
24
24
|
import type { ModelManager } from '../models/index.js';
|
|
25
25
|
import type { SessionContextManager, SessionHydrator, SessionLifecycleManager, SessionStateBag } from '../session/index.js';
|
|
26
|
-
import type { FeedbackCoordinator } from '../feedback/index.js';
|
|
27
26
|
import type { HookHandler } from '../lifecycle/hook-handler.js';
|
|
28
27
|
import type { SessionStore } from '../../session/store.js';
|
|
29
28
|
import type { StreamHandle } from '../service.types.js';
|
|
@@ -35,7 +34,6 @@ export interface InboundLoopConfig {
|
|
|
35
34
|
messageRouter: MessageRouter;
|
|
36
35
|
commandHandler: CommandHandler;
|
|
37
36
|
sessionContextManager: SessionContextManager;
|
|
38
|
-
feedbackCoordinator: FeedbackCoordinator;
|
|
39
37
|
agentManager: AgentManager;
|
|
40
38
|
sessionLifecycleManager: SessionLifecycleManager;
|
|
41
39
|
agentOrchestrator: AgentOrchestrator;
|
|
@@ -91,7 +91,6 @@ var InboundLoop = class {
|
|
|
91
91
|
...sessionMetadata?.sessionId ? { sessionId: sessionMetadata.sessionId } : {}
|
|
92
92
|
});
|
|
93
93
|
await this.cfg.sessionContextManager.runWith(sessionContext, async () => {
|
|
94
|
-
this.cfg.feedbackCoordinator.setContext(sessionContext);
|
|
95
94
|
this.cfg.agentManager.getOrCreateAgent(sessionContext.sessionKey);
|
|
96
95
|
this.cfg.setupSessionEventHandling(sessionContext.sessionKey);
|
|
97
96
|
await this.cfg.sessionLifecycleManager.startSession(sessionContext);
|
|
@@ -196,8 +195,6 @@ var InboundLoop = class {
|
|
|
196
195
|
}
|
|
197
196
|
this.cfg.sessionState.endInboundTurn(sessionContext.sessionKey);
|
|
198
197
|
}
|
|
199
|
-
this.cfg.feedbackCoordinator.endTask();
|
|
200
|
-
this.cfg.feedbackCoordinator.clearContext();
|
|
201
198
|
}
|
|
202
199
|
});
|
|
203
200
|
});
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { Config } from "../../config/schema.js";
|
|
3
|
-
import type { BundleMcpToolRuntime, SessionMcpRuntime } from "./bundle-mcp-types.js";
|
|
1
|
+
import type { Config } from '../../config/schema.js';
|
|
4
2
|
export type McpGatewayToolEntry = {
|
|
5
3
|
name: string;
|
|
6
4
|
shortName: string;
|
|
@@ -28,7 +26,6 @@ export type McpGatewayCapabilitySummary = {
|
|
|
28
26
|
resources: McpGatewayResourceEntry[];
|
|
29
27
|
prompts: McpGatewayPromptEntry[];
|
|
30
28
|
};
|
|
31
|
-
export declare function mapBundleMcpToolsForGateway(tools: AnyAgentTool[], serverId: string): McpGatewayToolEntry[];
|
|
32
29
|
export declare function listBundleMcpServerToolsForGateway(params: {
|
|
33
30
|
workspaceDir: string;
|
|
34
31
|
cfg?: Config;
|
|
@@ -39,18 +36,3 @@ export declare function listBundleMcpServerCapabilitiesForGateway(params: {
|
|
|
39
36
|
cfg?: Config;
|
|
40
37
|
serverId: string;
|
|
41
38
|
}): Promise<McpGatewayCapabilitySummary>;
|
|
42
|
-
export declare function materializeBundleMcpToolsForRun(params: {
|
|
43
|
-
runtime: SessionMcpRuntime;
|
|
44
|
-
reservedToolNames?: Iterable<string>;
|
|
45
|
-
disposeRuntime?: () => Promise<void>;
|
|
46
|
-
}): Promise<BundleMcpToolRuntime>;
|
|
47
|
-
export declare function createBundleMcpToolRuntime(params: {
|
|
48
|
-
workspaceDir: string;
|
|
49
|
-
cfg?: Config;
|
|
50
|
-
reservedToolNames?: Iterable<string>;
|
|
51
|
-
createRuntime?: (params: {
|
|
52
|
-
sessionId: string;
|
|
53
|
-
workspaceDir: string;
|
|
54
|
-
cfg?: Config;
|
|
55
|
-
}) => SessionMcpRuntime;
|
|
56
|
-
}): Promise<BundleMcpToolRuntime>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { mcpToolPolicyId } from "./bundle-mcp-policy.js";
|
|
2
|
+
import { createSessionMcpRuntime } from "./bundle-mcp-runtime.js";
|
|
3
|
+
import crypto from "node:crypto";
|
|
4
|
+
//#region src/agent/mcp/bundle-mcp-gateway.ts
|
|
5
|
+
function mapTools(tools, serverId) {
|
|
6
|
+
return tools.filter((tool) => tool.serverName === serverId).map((tool) => ({
|
|
7
|
+
name: mcpToolPolicyId(tool.safeServerName, tool.toolName),
|
|
8
|
+
shortName: tool.toolName,
|
|
9
|
+
description: tool.description || tool.title || tool.fallbackDescription
|
|
10
|
+
}));
|
|
11
|
+
}
|
|
12
|
+
function mapResources(resources, serverId) {
|
|
13
|
+
return resources.filter((resource) => resource.serverName === serverId).map((resource) => ({
|
|
14
|
+
uri: resource.uri,
|
|
15
|
+
name: resource.name,
|
|
16
|
+
title: resource.title,
|
|
17
|
+
description: resource.description,
|
|
18
|
+
mimeType: resource.mimeType
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
function mapPrompts(prompts, serverId) {
|
|
22
|
+
return prompts.filter((prompt) => prompt.serverName === serverId).map((prompt) => ({
|
|
23
|
+
name: prompt.name,
|
|
24
|
+
title: prompt.title,
|
|
25
|
+
description: prompt.description,
|
|
26
|
+
argumentCount: prompt.argumentCount
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
async function loadCatalog(params) {
|
|
30
|
+
const runtime = createSessionMcpRuntime({
|
|
31
|
+
sessionId: `mcp-gateway:${crypto.randomUUID()}`,
|
|
32
|
+
workspaceDir: params.workspaceDir,
|
|
33
|
+
cfg: params.cfg
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
return await runtime.getCatalog();
|
|
37
|
+
} finally {
|
|
38
|
+
await runtime.dispose();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function listBundleMcpServerToolsForGateway(params) {
|
|
42
|
+
return mapTools((await loadCatalog(params)).tools, params.serverId);
|
|
43
|
+
}
|
|
44
|
+
async function listBundleMcpServerCapabilitiesForGateway(params) {
|
|
45
|
+
const catalog = await loadCatalog(params);
|
|
46
|
+
const tools = mapTools(catalog.tools, params.serverId);
|
|
47
|
+
const resources = mapResources(catalog.resources, params.serverId);
|
|
48
|
+
const prompts = mapPrompts(catalog.prompts, params.serverId);
|
|
49
|
+
return {
|
|
50
|
+
serverId: params.serverId,
|
|
51
|
+
toolCount: tools.length,
|
|
52
|
+
resourceCount: resources.length,
|
|
53
|
+
promptCount: prompts.length,
|
|
54
|
+
tools,
|
|
55
|
+
resources,
|
|
56
|
+
prompts
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { listBundleMcpServerCapabilitiesForGateway, listBundleMcpServerToolsForGateway };
|
|
@@ -1,9 +1 @@
|
|
|
1
|
-
export declare const TOOL_NAME_SEPARATOR = "__";
|
|
2
1
|
export declare function sanitizeServerName(raw: string, usedNames: Set<string>): string;
|
|
3
|
-
export declare function sanitizeToolName(raw: string): string;
|
|
4
|
-
export declare function normalizeReservedToolNames(names?: Iterable<string>): Set<string>;
|
|
5
|
-
export declare function buildSafeToolName(params: {
|
|
6
|
-
serverName: string;
|
|
7
|
-
toolName: string;
|
|
8
|
-
reservedNames: Set<string>;
|
|
9
|
-
}): string;
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import { init_string_coerce, normalizeLowercaseStringOrEmpty
|
|
1
|
+
import { init_string_coerce, normalizeLowercaseStringOrEmpty } from "../../utils/string-coerce.js";
|
|
2
2
|
//#region src/agent/mcp/bundle-mcp-names.ts
|
|
3
3
|
init_string_coerce();
|
|
4
|
-
function normalizeOptionalLowercaseString(value) {
|
|
5
|
-
const s = normalizeOptionalString(value);
|
|
6
|
-
return s ? s.toLowerCase() : void 0;
|
|
7
|
-
}
|
|
8
4
|
const TOOL_NAME_SAFE_RE = /[^A-Za-z0-9_-]/g;
|
|
9
|
-
const TOOL_NAME_SEPARATOR = "__";
|
|
10
5
|
const TOOL_NAME_MAX_PREFIX = 30;
|
|
11
|
-
const TOOL_NAME_MAX_TOTAL = 64;
|
|
12
6
|
function sanitizeToolFragment(raw, fallback, maxChars) {
|
|
13
7
|
const normalized = raw.trim().replace(TOOL_NAME_SAFE_RE, "-") || fallback;
|
|
14
8
|
if (!maxChars) return normalized;
|
|
@@ -26,26 +20,5 @@ function sanitizeServerName(raw, usedNames) {
|
|
|
26
20
|
usedNames.add(normalizeLowercaseStringOrEmpty(candidate));
|
|
27
21
|
return candidate;
|
|
28
22
|
}
|
|
29
|
-
function sanitizeToolName(raw) {
|
|
30
|
-
return sanitizeToolFragment(raw, "tool");
|
|
31
|
-
}
|
|
32
|
-
function normalizeReservedToolNames(names) {
|
|
33
|
-
return new Set(Array.from(names ?? [], (name) => normalizeOptionalLowercaseString(name)).filter((name) => Boolean(name)));
|
|
34
|
-
}
|
|
35
|
-
function buildSafeToolName(params) {
|
|
36
|
-
const cleanedToolName = sanitizeToolName(params.toolName);
|
|
37
|
-
const maxToolChars = Math.max(1, TOOL_NAME_MAX_TOTAL - params.serverName.length - 2);
|
|
38
|
-
const truncatedToolName = cleanedToolName.slice(0, maxToolChars);
|
|
39
|
-
let candidateToolName = truncatedToolName || "tool";
|
|
40
|
-
let candidate = `${params.serverName}__${candidateToolName}`;
|
|
41
|
-
let n = 2;
|
|
42
|
-
while (params.reservedNames.has(normalizeLowercaseStringOrEmpty(candidate))) {
|
|
43
|
-
const suffix = `-${n}`;
|
|
44
|
-
candidateToolName = `${(truncatedToolName || "tool").slice(0, Math.max(1, maxToolChars - suffix.length))}${suffix}`;
|
|
45
|
-
candidate = `${params.serverName}__${candidateToolName}`;
|
|
46
|
-
n += 1;
|
|
47
|
-
}
|
|
48
|
-
return candidate;
|
|
49
|
-
}
|
|
50
23
|
//#endregion
|
|
51
|
-
export {
|
|
24
|
+
export { sanitizeServerName };
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import type { AgentManifest } from '../../agent-manifest/schema.js';
|
|
2
|
-
|
|
3
|
-
export declare function
|
|
4
|
-
export declare function isMcpToolName(toolName: string): boolean;
|
|
5
|
-
export declare function parseMcpToolName(toolName: string): {
|
|
2
|
+
export declare function mcpToolPolicyId(serverId: string, toolName: string): string;
|
|
3
|
+
export declare function isMcpCatalogToolDenied(identity: {
|
|
6
4
|
serverId: string;
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
export declare function isMcpToolDenied(toolName: string, policy: AgentManifest['tools']['mcp']): boolean;
|
|
5
|
+
policyToolId: string;
|
|
6
|
+
}, policy: AgentManifest['tools']['mcp']): boolean;
|
|
@@ -1,24 +1,10 @@
|
|
|
1
|
-
import "./bundle-mcp-names.js";
|
|
2
|
-
import { hasAnyMcpServers } from "../../extensions/bundle-mcp.js";
|
|
3
1
|
//#region src/agent/mcp/bundle-mcp-policy.ts
|
|
4
|
-
function
|
|
5
|
-
return
|
|
2
|
+
function mcpToolPolicyId(serverId, toolName) {
|
|
3
|
+
return `mcp:${encodeURIComponent(serverId)}:${encodeURIComponent(toolName)}`;
|
|
6
4
|
}
|
|
7
|
-
function
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
function parseMcpToolName(toolName) {
|
|
11
|
-
const idx = toolName.indexOf("__");
|
|
12
|
-
if (idx <= 0) return null;
|
|
13
|
-
return {
|
|
14
|
-
serverId: toolName.slice(0, idx),
|
|
15
|
-
toolId: toolName.slice(idx + 2)
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
function isMcpToolDenied(toolName, policy) {
|
|
19
|
-
const parsed = parseMcpToolName(toolName);
|
|
20
|
-
if (!parsed || !policy) return false;
|
|
21
|
-
return policy.servers?.[parsed.serverId]?.mode === "deny" || policy.tools?.[toolName]?.mode === "deny";
|
|
5
|
+
function isMcpCatalogToolDenied(identity, policy) {
|
|
6
|
+
if (!policy) return false;
|
|
7
|
+
return policy.servers?.[identity.serverId]?.mode === "deny" || policy.tools?.[identity.policyToolId]?.mode === "deny";
|
|
22
8
|
}
|
|
23
9
|
//#endregion
|
|
24
|
-
export {
|
|
10
|
+
export { isMcpCatalogToolDenied, mcpToolPolicyId };
|
|
@@ -2,12 +2,12 @@ import { createLogger } from "../../utils/logger/index.js";
|
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { resolveGlobalSingleton } from "../../utils/global-singleton.js";
|
|
4
4
|
import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
|
|
5
|
-
import { sanitizeServerName } from "./bundle-mcp-names.js";
|
|
6
5
|
import { redactSensitiveUrlLikeString } from "../../utils/redact-sensitive-url.js";
|
|
7
6
|
import { loadEmbeddedMcpConfig } from "./embedded-mcp.js";
|
|
8
7
|
import { resolveConnectorSecretReferences } from "../../connectors/secret-store.js";
|
|
9
8
|
import { isMcpConfigRecord } from "./mcp-config-shared.js";
|
|
10
9
|
import { resolveMcpTransport } from "./mcp-transport.js";
|
|
10
|
+
import { sanitizeServerName } from "./bundle-mcp-names.js";
|
|
11
11
|
import crypto from "node:crypto";
|
|
12
12
|
import Ajv2020 from "ajv/dist/2020.js";
|
|
13
13
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
@@ -182,7 +182,7 @@ function createSessionMcpRuntime(params) {
|
|
|
182
182
|
phase: "agent.mcp_connect",
|
|
183
183
|
serverName,
|
|
184
184
|
safeServerName
|
|
185
|
-
}, `bundle-mcp: server key "${serverName}"
|
|
185
|
+
}, `bundle-mcp: server key "${serverName}" uses policy namespace "${safeServerName}"`);
|
|
186
186
|
const client = new Client({
|
|
187
187
|
name: "xopc-bundle-mcp",
|
|
188
188
|
version: "0.0.0"
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
export type {
|
|
1
|
+
export type { McpCatalogTool, McpServerCatalog, McpToolCatalog, SessionMcpRuntime, SessionMcpRuntimeManager, } from "./bundle-mcp-types.js";
|
|
2
2
|
export { __testing, createSessionMcpRuntime, disposeAllSessionMcpRuntimes, disposeSessionMcpRuntime, getOrCreateSessionMcpRuntime, getSessionMcpRuntimeManager, retireSessionMcpRuntime, retireSessionMcpRuntimeForSessionKey, } from "./bundle-mcp-runtime.js";
|
|
3
|
-
export { createBundleMcpToolRuntime, materializeBundleMcpToolsForRun, } from "./bundle-mcp-materialize.js";
|