@mappies/miniwat-mcp-core 0.10.0 → 0.11.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/index.cjs +61 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -9
- package/dist/index.d.ts +12 -9
- package/dist/index.js +62 -31
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -26,6 +26,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
26
26
|
|
|
27
27
|
// src/entities/toolDispatcher.ts
|
|
28
28
|
var import_miniwat_agent_core = require("@mappies/miniwat-agent-core");
|
|
29
|
+
var import_crypto = require("crypto");
|
|
29
30
|
var ToolDispatcher = class {
|
|
30
31
|
constructor(mcp) {
|
|
31
32
|
this.mcp = mcp;
|
|
@@ -45,6 +46,7 @@ var ToolDispatcher = class {
|
|
|
45
46
|
let definition = pck[t.import];
|
|
46
47
|
let tool = new import_miniwat_agent_core.Tool({
|
|
47
48
|
name: definition.name,
|
|
49
|
+
displayName: definition.displayName,
|
|
48
50
|
description: definition.description,
|
|
49
51
|
schema: definition.inputSchema,
|
|
50
52
|
func: pck[definition.name],
|
|
@@ -52,57 +54,57 @@ var ToolDispatcher = class {
|
|
|
52
54
|
getInputText: pck[`${definition.name}InputText`],
|
|
53
55
|
readOnly: definition.readOnly === true,
|
|
54
56
|
requiresApproval: definition.requiresApproval === true,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
inputGuardrail: this.resolveInputGuardrail(server, definition, pck),
|
|
58
|
+
outputGuardrail: this.resolveOutputGuardrail(server, definition, pck)
|
|
57
59
|
});
|
|
58
60
|
this.tools.push(tool);
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
|
-
// Resolves a tool definition's named
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
const name = definition.
|
|
64
|
+
// Resolves a tool definition's named inputGuardrail from the OWNING package's INPUT_GUARDRAILS
|
|
65
|
+
// factory export. Validation is loud and happens at init — never deferred to tool invocation —
|
|
66
|
+
// so the app cannot reach agent.stream() with a partially resolved tool.
|
|
67
|
+
resolveInputGuardrail(server, definition, pck) {
|
|
68
|
+
const name = definition.inputGuardrail;
|
|
67
69
|
if (name === void 0) return void 0;
|
|
68
|
-
const factories = pck.
|
|
70
|
+
const factories = pck.INPUT_GUARDRAILS;
|
|
69
71
|
if (factories === void 0 || typeof factories !== "object") {
|
|
70
|
-
throw new Error(`Tool '${definition.name}' on server '${server}' names
|
|
72
|
+
throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' but its package exports no INPUT_GUARDRAILS.`);
|
|
71
73
|
}
|
|
72
74
|
const factory = factories[name];
|
|
73
75
|
if (factory === void 0) {
|
|
74
|
-
throw new Error(`Tool '${definition.name}' on server '${server}' names
|
|
76
|
+
throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' not found in the package's INPUT_GUARDRAILS.`);
|
|
75
77
|
}
|
|
76
78
|
if (typeof factory !== "function") {
|
|
77
|
-
throw new Error(`
|
|
79
|
+
throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);
|
|
78
80
|
}
|
|
79
|
-
const
|
|
80
|
-
if (
|
|
81
|
-
throw new Error(`
|
|
81
|
+
const guardrail = factory();
|
|
82
|
+
if (guardrail === void 0 || typeof guardrail.evaluate !== "function") {
|
|
83
|
+
throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolInputGuardrail.`);
|
|
82
84
|
}
|
|
83
|
-
return
|
|
85
|
+
return guardrail;
|
|
84
86
|
}
|
|
85
|
-
// Resolves a tool definition's named
|
|
86
|
-
// factory export. Validated loudly at init, mirroring
|
|
87
|
-
|
|
88
|
-
const name = definition.
|
|
87
|
+
// Resolves a tool definition's named outputGuardrail from the OWNING package's OUTPUT_GUARDRAILS
|
|
88
|
+
// factory export. Validated loudly at init, mirroring resolveInputGuardrail.
|
|
89
|
+
resolveOutputGuardrail(server, definition, pck) {
|
|
90
|
+
const name = definition.outputGuardrail;
|
|
89
91
|
if (name === void 0) return void 0;
|
|
90
|
-
const factories = pck.
|
|
92
|
+
const factories = pck.OUTPUT_GUARDRAILS;
|
|
91
93
|
if (factories === void 0 || typeof factories !== "object") {
|
|
92
|
-
throw new Error(`Tool '${definition.name}' on server '${server}' names
|
|
94
|
+
throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' but its package exports no OUTPUT_GUARDRAILS.`);
|
|
93
95
|
}
|
|
94
96
|
const factory = factories[name];
|
|
95
97
|
if (factory === void 0) {
|
|
96
|
-
throw new Error(`Tool '${definition.name}' on server '${server}' names
|
|
98
|
+
throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' not found in the package's OUTPUT_GUARDRAILS.`);
|
|
97
99
|
}
|
|
98
100
|
if (typeof factory !== "function") {
|
|
99
|
-
throw new Error(`
|
|
101
|
+
throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);
|
|
100
102
|
}
|
|
101
|
-
const
|
|
102
|
-
if (
|
|
103
|
-
throw new Error(`
|
|
103
|
+
const guardrail = factory();
|
|
104
|
+
if (guardrail === void 0 || typeof guardrail.evaluate !== "function") {
|
|
105
|
+
throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolOutputGuardrail.`);
|
|
104
106
|
}
|
|
105
|
-
return
|
|
107
|
+
return guardrail;
|
|
106
108
|
}
|
|
107
109
|
async list() {
|
|
108
110
|
await this.init();
|
|
@@ -120,7 +122,30 @@ var ToolDispatcher = class {
|
|
|
120
122
|
const tool = await this.get(name);
|
|
121
123
|
return tool?.getInputText?.(input) || "";
|
|
122
124
|
}
|
|
123
|
-
|
|
125
|
+
// Evaluates the dispatch-boundary input guardrail against the concrete invocation. Returns
|
|
126
|
+
// undefined when execution may proceed; a ToolAuthorizationResult (defer/deny) when it is
|
|
127
|
+
// blocked. On defer the pending call is recorded via the awaited onDeferred sink BEFORE the
|
|
128
|
+
// deferred result is returned (persist-before-respond); if a tool can defer but no sink is
|
|
129
|
+
// supplied, it FAILS CLOSED (denied) — a deferral must never be reported as unrecoverable.
|
|
130
|
+
async authorize(name, input, tool, auth) {
|
|
131
|
+
if (!auth) {
|
|
132
|
+
return void 0;
|
|
133
|
+
}
|
|
134
|
+
const decision = auth.guardrail.evaluate({ toolName: name, arguments: input }, auth.context);
|
|
135
|
+
if (decision.status === "allow") {
|
|
136
|
+
return void 0;
|
|
137
|
+
}
|
|
138
|
+
if (decision.status === "deny") {
|
|
139
|
+
return { authorization: "deny", succeeded: false, text: decision.reason };
|
|
140
|
+
}
|
|
141
|
+
const pending = { id: (0, import_crypto.randomUUID)(), name, arguments: input ?? {}, status: "pending" };
|
|
142
|
+
if (!auth.onDeferred) {
|
|
143
|
+
return { authorization: "deny", succeeded: false, text: "Authorization is unavailable for this operation." };
|
|
144
|
+
}
|
|
145
|
+
await auth.onDeferred(pending);
|
|
146
|
+
return { authorization: "defer", succeeded: false, text: decision.reason, pending };
|
|
147
|
+
}
|
|
148
|
+
async execute(name, input, auth) {
|
|
124
149
|
const tool = await this.get(name);
|
|
125
150
|
if (!tool) {
|
|
126
151
|
throw new Error(`Tool ${name} could not be found.`);
|
|
@@ -128,12 +153,18 @@ var ToolDispatcher = class {
|
|
|
128
153
|
if (!tool.func) {
|
|
129
154
|
throw new Error(`Tool ${name} does not have a function.`);
|
|
130
155
|
}
|
|
156
|
+
const authorization = await this.authorize(name, input, tool, auth);
|
|
157
|
+
if (authorization) {
|
|
158
|
+
return authorization;
|
|
159
|
+
}
|
|
160
|
+
let result;
|
|
131
161
|
try {
|
|
132
|
-
|
|
133
|
-
return result;
|
|
162
|
+
result = await tool.func(input);
|
|
134
163
|
} catch (e) {
|
|
135
164
|
throw new Error(`Failed to run ${name} tool: ${e?.message}`);
|
|
136
165
|
}
|
|
166
|
+
const guardrail = tool.outputGuardrail ?? new import_miniwat_agent_core.DefaultOutputGuardrail();
|
|
167
|
+
return guardrail.evaluate(result);
|
|
137
168
|
}
|
|
138
169
|
};
|
|
139
170
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/entities/toolDispatcher.ts"],"sourcesContent":["export { ToolDispatcher } from './entities/toolDispatcher';\nexport { McpConfig, McpServer, McpToolImport } from './interfaces/mcpConfig';","import { Tool, McpServer, ExecutionPolicy, ExecutionPolicyFactory, ToolOutcomeMapper, ToolOutcomeMapperFactory } from \"@mappies/miniwat-agent-core\";\nimport { McpConfig } from \"../interfaces/mcpConfig\";\n\nexport class ToolDispatcher\n{\n private tools:Tool[]\n private servers:McpServer[]\n\n constructor(private mcp?:McpConfig)\n {\n this.tools = []\n this.servers = []\n }\n\n async init()\n {\n if(this.tools.length !== 0) return;\n\n this.tools = [];\n\n if(this.mcp === undefined) return;\n\n for(let server of Object.keys(this.mcp.mcpServers))\n {\n let service = this.mcp.mcpServers[server]\n\n this.servers.push(new McpServer({name: server, ...service}))\n \n const pck = await import(service.package);\n for(let t of service.tools)\n {\n // Host intent: a tool explicitly disabled in config is excluded here, during\n // discovery, so the planner never sees it.\n if(t.enabled === false) continue;\n\n let definition = pck[t.import];\n let tool = new Tool({ \n name: definition.name, \n description: definition.description, \n schema: definition.inputSchema, \n func: pck[definition.name],\n service: server,\n getInputText: pck[`${definition.name}InputText`],\n readOnly: definition.readOnly === true,\n requiresApproval: definition.requiresApproval === true,\n executionPolicy: this.resolveExecutionPolicy(server, definition, pck),\n outcomeMapper: this.resolveOutcomeMapper(server, definition, pck)\n })\n \n this.tools.push(tool)\n }\n }\n }\n\n // Resolves a tool definition's named executionPolicy from the OWNING package's\n // EXECUTION_POLICIES factory export. Validation is loud and happens at init — never deferred to\n // tool invocation — so the app cannot reach agent.stream() with a partially resolved tool.\n private resolveExecutionPolicy(server:string, definition:any, pck:any): ExecutionPolicy | undefined\n {\n const name:string | undefined = definition.executionPolicy;\n\n if(name === undefined) return undefined;\n\n const factories = pck.EXECUTION_POLICIES;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names executionPolicy '${name}' but its package exports no EXECUTION_POLICIES.`);\n }\n\n const factory:ExecutionPolicyFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names executionPolicy '${name}' not found in the package's EXECUTION_POLICIES.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`EXECUTION_POLICIES['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const policy = factory();\n\n if(policy === undefined || typeof policy.evaluate !== \"function\")\n {\n throw new Error(`EXECUTION_POLICIES['${name}'] on server '${server}' did not produce a valid ExecutionPolicy.`);\n }\n\n return policy;\n }\n\n // Resolves a tool definition's named outcomeMapper from the OWNING package's OUTCOME_MAPPERS\n // factory export. Validated loudly at init, mirroring resolveExecutionPolicy.\n private resolveOutcomeMapper(server:string, definition:any, pck:any): ToolOutcomeMapper | undefined\n {\n const name:string | undefined = definition.outcomeMapper;\n\n if(name === undefined) return undefined;\n\n const factories = pck.OUTCOME_MAPPERS;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outcomeMapper '${name}' but its package exports no OUTCOME_MAPPERS.`);\n }\n\n const factory:ToolOutcomeMapperFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outcomeMapper '${name}' not found in the package's OUTCOME_MAPPERS.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`OUTCOME_MAPPERS['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const mapper = factory();\n\n if(mapper === undefined || typeof mapper.map !== \"function\")\n {\n throw new Error(`OUTCOME_MAPPERS['${name}'] on server '${server}' did not produce a valid ToolOutcomeMapper.`);\n }\n\n return mapper;\n }\n\n async list(): Promise<Tool[]>\n {\n await this.init()\n return this.tools;\n }\n\n async listServers(): Promise<McpServer[]>\n {\n await this.init()\n return this.servers;\n }\n\n async get(name:string): Promise<Tool|undefined>\n {\n await this.init()\n return this.tools.find(tool => tool.name === name);\n }\n\n async getInputText(name:string, input?:object): Promise<string>\n {\n const tool = await this.get(name);\n\n return tool?.getInputText?.(input) || '';\n }\n\n async execute(name:string, input?:object): Promise<string>\n {\n const tool = await this.get(name);\n \n if(!tool)\n {\n throw new Error(`Tool ${name} could not be found.`);\n }\n\n if(!tool.func)\n {\n throw new Error(`Tool ${name} does not have a function.`);\n }\n\n try\n {\n let result = await tool.func(input);\n return result;\n }\n catch(e:any)\n {\n throw new Error(`Failed to run ${name} tool: ${e?.message}`);\n }\n }\n}"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/entities/toolDispatcher.ts"],"sourcesContent":["export { ToolDispatcher } from './entities/toolDispatcher';\nexport { McpConfig } from './interfaces/mcpConfig';\nexport { McpServer } from './interfaces/mcpServer';\nexport { McpToolImport } from './interfaces/mcpToolImport';","import { Tool, McpServer, ToolInputGuardrail, ToolInputGuardrailFactory, ToolOutputGuardrail, ToolOutputGuardrailFactory, ToolOutputGuardrailResult, DefaultOutputGuardrail, ToolAuthorizationOptions, ToolAuthorizationResult, PendingToolCall } from \"@mappies/miniwat-agent-core\";\nimport { randomUUID } from \"crypto\";\nimport { McpConfig } from \"../interfaces/mcpConfig\";\n\nexport class ToolDispatcher\n{\n private tools:Tool[]\n private servers:McpServer[]\n\n constructor(private mcp?:McpConfig)\n {\n this.tools = []\n this.servers = []\n }\n\n async init()\n {\n if(this.tools.length !== 0) return;\n\n this.tools = [];\n\n if(this.mcp === undefined) return;\n\n for(let server of Object.keys(this.mcp.mcpServers))\n {\n let service = this.mcp.mcpServers[server]\n\n this.servers.push(new McpServer({name: server, ...service}))\n \n const pck = await import(service.package);\n for(let t of service.tools)\n {\n // Host intent: a tool explicitly disabled in config is excluded here, during\n // discovery, so the planner never sees it.\n if(t.enabled === false) continue;\n\n let definition = pck[t.import];\n let tool = new Tool({ \n name: definition.name, \n displayName: definition.displayName,\n description: definition.description, \n schema: definition.inputSchema, \n func: pck[definition.name],\n service: server,\n getInputText: pck[`${definition.name}InputText`],\n readOnly: definition.readOnly === true,\n requiresApproval: definition.requiresApproval === true,\n inputGuardrail: this.resolveInputGuardrail(server, definition, pck),\n outputGuardrail: this.resolveOutputGuardrail(server, definition, pck)\n })\n \n this.tools.push(tool)\n }\n }\n }\n\n // Resolves a tool definition's named inputGuardrail from the OWNING package's INPUT_GUARDRAILS\n // factory export. Validation is loud and happens at init — never deferred to tool invocation —\n // so the app cannot reach agent.stream() with a partially resolved tool.\n private resolveInputGuardrail(server:string, definition:any, pck:any): ToolInputGuardrail | undefined\n {\n const name:string | undefined = definition.inputGuardrail;\n\n if(name === undefined) return undefined;\n\n const factories = pck.INPUT_GUARDRAILS;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' but its package exports no INPUT_GUARDRAILS.`);\n }\n\n const factory:ToolInputGuardrailFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' not found in the package's INPUT_GUARDRAILS.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const guardrail = factory();\n\n if(guardrail === undefined || typeof guardrail.evaluate !== \"function\")\n {\n throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolInputGuardrail.`);\n }\n\n return guardrail;\n }\n\n // Resolves a tool definition's named outputGuardrail from the OWNING package's OUTPUT_GUARDRAILS\n // factory export. Validated loudly at init, mirroring resolveInputGuardrail.\n private resolveOutputGuardrail(server:string, definition:any, pck:any): ToolOutputGuardrail | undefined\n {\n const name:string | undefined = definition.outputGuardrail;\n\n if(name === undefined) return undefined;\n\n const factories = pck.OUTPUT_GUARDRAILS;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' but its package exports no OUTPUT_GUARDRAILS.`);\n }\n\n const factory:ToolOutputGuardrailFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' not found in the package's OUTPUT_GUARDRAILS.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const guardrail = factory();\n\n if(guardrail === undefined || typeof guardrail.evaluate !== \"function\")\n {\n throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolOutputGuardrail.`);\n }\n\n return guardrail;\n }\n\n async list(): Promise<Tool[]>\n {\n await this.init()\n return this.tools;\n }\n\n async listServers(): Promise<McpServer[]>\n {\n await this.init()\n return this.servers;\n }\n\n async get(name:string): Promise<Tool|undefined>\n {\n await this.init()\n return this.tools.find(tool => tool.name === name);\n }\n\n async getInputText(name:string, input?:object): Promise<string>\n {\n const tool = await this.get(name);\n\n return tool?.getInputText?.(input) || '';\n }\n\n // Evaluates the dispatch-boundary input guardrail against the concrete invocation. Returns\n // undefined when execution may proceed; a ToolAuthorizationResult (defer/deny) when it is\n // blocked. On defer the pending call is recorded via the awaited onDeferred sink BEFORE the\n // deferred result is returned (persist-before-respond); if a tool can defer but no sink is\n // supplied, it FAILS CLOSED (denied) — a deferral must never be reported as unrecoverable.\n private async authorize(name:string, input:object | undefined, tool:Tool, auth?:ToolAuthorizationOptions): Promise<ToolAuthorizationResult | undefined>\n {\n if(!auth)\n {\n return undefined;\n }\n\n const decision = auth.guardrail.evaluate({ toolName: name, arguments: input }, auth.context);\n\n if(decision.status === \"allow\")\n {\n return undefined;\n }\n\n if(decision.status === \"deny\")\n {\n return { authorization: \"deny\", succeeded: false, text: decision.reason };\n }\n\n // defer: preserve the invocation for a later approval turn.\n const pending:PendingToolCall = { id: randomUUID(), name, arguments: (input ?? {}) as Record<string, unknown>, status: \"pending\" };\n\n if(!auth.onDeferred)\n {\n // Fail closed: a deferral we cannot durably record must not surface as a usable\n // approval-required result.\n return { authorization: \"deny\", succeeded: false, text: \"Authorization is unavailable for this operation.\" };\n }\n\n // Persist-before-respond: the pending call is durably recorded before the deferred result\n // (and the approval request derived from it) can reach the user. A rejection propagates.\n await auth.onDeferred(pending);\n\n return { authorization: \"defer\", succeeded: false, text: decision.reason, pending };\n }\n\n async execute(name:string, input?:object, auth?:ToolAuthorizationOptions): Promise<ToolOutputGuardrailResult | ToolAuthorizationResult>\n {\n const tool = await this.get(name);\n \n if(!tool)\n {\n throw new Error(`Tool ${name} could not be found.`);\n }\n\n if(!tool.func)\n {\n throw new Error(`Tool ${name} does not have a function.`);\n }\n\n // Dispatch-boundary authorization runs BEFORE the tool, so an unauthorized side effect never\n // executes — regardless of which planner (or no planner) proposed it. The guardrail is the\n // existing allow/defer/deny input guardrail evaluated against the CONCRETE invocation.\n const authorization = await this.authorize(name, input, tool, auth);\n\n if(authorization)\n {\n return authorization;\n }\n\n let result;\n\n try\n {\n result = await tool.func(input);\n }\n catch(e:any)\n {\n throw new Error(`Failed to run ${name} tool: ${e?.message}`);\n }\n\n // The output guardrail is the SINGLE post-execution authority. It runs here, at the\n // provider-agnostic chokepoint, so the real result is classified BEFORE any provider relays\n // it. Its verdict carries both the user-facing text and the semantic status to the caller;\n // a `blocked` verdict withholds the real result in favor of a replacement. A tool without an\n // explicit guardrail gets the framework default (a normal return is a success).\n const guardrail = tool.outputGuardrail ?? new DefaultOutputGuardrail();\n\n return guardrail.evaluate(result);\n }\n}"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import { Tool, McpServer as McpServer$1 } from '@mappies/miniwat-agent-core';
|
|
1
|
+
import { Tool, McpServer as McpServer$1, ToolAuthorizationOptions, ToolOutputGuardrailResult, ToolAuthorizationResult } from '@mappies/miniwat-agent-core';
|
|
2
2
|
|
|
3
|
-
interface
|
|
4
|
-
|
|
3
|
+
interface McpToolImport {
|
|
4
|
+
import: string;
|
|
5
|
+
enabled?: boolean;
|
|
5
6
|
}
|
|
7
|
+
|
|
6
8
|
interface McpServer {
|
|
7
9
|
package: string;
|
|
8
10
|
description?: string;
|
|
9
11
|
secrets?: string[];
|
|
10
12
|
tools: McpToolImport[];
|
|
11
13
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
interface McpConfig {
|
|
16
|
+
mcpServers: Record<string, McpServer>;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
declare class ToolDispatcher {
|
|
@@ -20,13 +22,14 @@ declare class ToolDispatcher {
|
|
|
20
22
|
private servers;
|
|
21
23
|
constructor(mcp?: McpConfig | undefined);
|
|
22
24
|
init(): Promise<void>;
|
|
23
|
-
private
|
|
24
|
-
private
|
|
25
|
+
private resolveInputGuardrail;
|
|
26
|
+
private resolveOutputGuardrail;
|
|
25
27
|
list(): Promise<Tool[]>;
|
|
26
28
|
listServers(): Promise<McpServer$1[]>;
|
|
27
29
|
get(name: string): Promise<Tool | undefined>;
|
|
28
30
|
getInputText(name: string, input?: object): Promise<string>;
|
|
29
|
-
|
|
31
|
+
private authorize;
|
|
32
|
+
execute(name: string, input?: object, auth?: ToolAuthorizationOptions): Promise<ToolOutputGuardrailResult | ToolAuthorizationResult>;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
export { type McpConfig, type McpServer, type McpToolImport, ToolDispatcher };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import { Tool, McpServer as McpServer$1 } from '@mappies/miniwat-agent-core';
|
|
1
|
+
import { Tool, McpServer as McpServer$1, ToolAuthorizationOptions, ToolOutputGuardrailResult, ToolAuthorizationResult } from '@mappies/miniwat-agent-core';
|
|
2
2
|
|
|
3
|
-
interface
|
|
4
|
-
|
|
3
|
+
interface McpToolImport {
|
|
4
|
+
import: string;
|
|
5
|
+
enabled?: boolean;
|
|
5
6
|
}
|
|
7
|
+
|
|
6
8
|
interface McpServer {
|
|
7
9
|
package: string;
|
|
8
10
|
description?: string;
|
|
9
11
|
secrets?: string[];
|
|
10
12
|
tools: McpToolImport[];
|
|
11
13
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
interface McpConfig {
|
|
16
|
+
mcpServers: Record<string, McpServer>;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
declare class ToolDispatcher {
|
|
@@ -20,13 +22,14 @@ declare class ToolDispatcher {
|
|
|
20
22
|
private servers;
|
|
21
23
|
constructor(mcp?: McpConfig | undefined);
|
|
22
24
|
init(): Promise<void>;
|
|
23
|
-
private
|
|
24
|
-
private
|
|
25
|
+
private resolveInputGuardrail;
|
|
26
|
+
private resolveOutputGuardrail;
|
|
25
27
|
list(): Promise<Tool[]>;
|
|
26
28
|
listServers(): Promise<McpServer$1[]>;
|
|
27
29
|
get(name: string): Promise<Tool | undefined>;
|
|
28
30
|
getInputText(name: string, input?: object): Promise<string>;
|
|
29
|
-
|
|
31
|
+
private authorize;
|
|
32
|
+
execute(name: string, input?: object, auth?: ToolAuthorizationOptions): Promise<ToolOutputGuardrailResult | ToolAuthorizationResult>;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
export { type McpConfig, type McpServer, type McpToolImport, ToolDispatcher };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/entities/toolDispatcher.ts
|
|
2
|
-
import { Tool, McpServer } from "@mappies/miniwat-agent-core";
|
|
2
|
+
import { Tool, McpServer, DefaultOutputGuardrail } from "@mappies/miniwat-agent-core";
|
|
3
|
+
import { randomUUID } from "crypto";
|
|
3
4
|
var ToolDispatcher = class {
|
|
4
5
|
constructor(mcp) {
|
|
5
6
|
this.mcp = mcp;
|
|
@@ -19,6 +20,7 @@ var ToolDispatcher = class {
|
|
|
19
20
|
let definition = pck[t.import];
|
|
20
21
|
let tool = new Tool({
|
|
21
22
|
name: definition.name,
|
|
23
|
+
displayName: definition.displayName,
|
|
22
24
|
description: definition.description,
|
|
23
25
|
schema: definition.inputSchema,
|
|
24
26
|
func: pck[definition.name],
|
|
@@ -26,57 +28,57 @@ var ToolDispatcher = class {
|
|
|
26
28
|
getInputText: pck[`${definition.name}InputText`],
|
|
27
29
|
readOnly: definition.readOnly === true,
|
|
28
30
|
requiresApproval: definition.requiresApproval === true,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
inputGuardrail: this.resolveInputGuardrail(server, definition, pck),
|
|
32
|
+
outputGuardrail: this.resolveOutputGuardrail(server, definition, pck)
|
|
31
33
|
});
|
|
32
34
|
this.tools.push(tool);
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
|
-
// Resolves a tool definition's named
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
const name = definition.
|
|
38
|
+
// Resolves a tool definition's named inputGuardrail from the OWNING package's INPUT_GUARDRAILS
|
|
39
|
+
// factory export. Validation is loud and happens at init — never deferred to tool invocation —
|
|
40
|
+
// so the app cannot reach agent.stream() with a partially resolved tool.
|
|
41
|
+
resolveInputGuardrail(server, definition, pck) {
|
|
42
|
+
const name = definition.inputGuardrail;
|
|
41
43
|
if (name === void 0) return void 0;
|
|
42
|
-
const factories = pck.
|
|
44
|
+
const factories = pck.INPUT_GUARDRAILS;
|
|
43
45
|
if (factories === void 0 || typeof factories !== "object") {
|
|
44
|
-
throw new Error(`Tool '${definition.name}' on server '${server}' names
|
|
46
|
+
throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' but its package exports no INPUT_GUARDRAILS.`);
|
|
45
47
|
}
|
|
46
48
|
const factory = factories[name];
|
|
47
49
|
if (factory === void 0) {
|
|
48
|
-
throw new Error(`Tool '${definition.name}' on server '${server}' names
|
|
50
|
+
throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' not found in the package's INPUT_GUARDRAILS.`);
|
|
49
51
|
}
|
|
50
52
|
if (typeof factory !== "function") {
|
|
51
|
-
throw new Error(`
|
|
53
|
+
throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);
|
|
52
54
|
}
|
|
53
|
-
const
|
|
54
|
-
if (
|
|
55
|
-
throw new Error(`
|
|
55
|
+
const guardrail = factory();
|
|
56
|
+
if (guardrail === void 0 || typeof guardrail.evaluate !== "function") {
|
|
57
|
+
throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolInputGuardrail.`);
|
|
56
58
|
}
|
|
57
|
-
return
|
|
59
|
+
return guardrail;
|
|
58
60
|
}
|
|
59
|
-
// Resolves a tool definition's named
|
|
60
|
-
// factory export. Validated loudly at init, mirroring
|
|
61
|
-
|
|
62
|
-
const name = definition.
|
|
61
|
+
// Resolves a tool definition's named outputGuardrail from the OWNING package's OUTPUT_GUARDRAILS
|
|
62
|
+
// factory export. Validated loudly at init, mirroring resolveInputGuardrail.
|
|
63
|
+
resolveOutputGuardrail(server, definition, pck) {
|
|
64
|
+
const name = definition.outputGuardrail;
|
|
63
65
|
if (name === void 0) return void 0;
|
|
64
|
-
const factories = pck.
|
|
66
|
+
const factories = pck.OUTPUT_GUARDRAILS;
|
|
65
67
|
if (factories === void 0 || typeof factories !== "object") {
|
|
66
|
-
throw new Error(`Tool '${definition.name}' on server '${server}' names
|
|
68
|
+
throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' but its package exports no OUTPUT_GUARDRAILS.`);
|
|
67
69
|
}
|
|
68
70
|
const factory = factories[name];
|
|
69
71
|
if (factory === void 0) {
|
|
70
|
-
throw new Error(`Tool '${definition.name}' on server '${server}' names
|
|
72
|
+
throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' not found in the package's OUTPUT_GUARDRAILS.`);
|
|
71
73
|
}
|
|
72
74
|
if (typeof factory !== "function") {
|
|
73
|
-
throw new Error(`
|
|
75
|
+
throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);
|
|
74
76
|
}
|
|
75
|
-
const
|
|
76
|
-
if (
|
|
77
|
-
throw new Error(`
|
|
77
|
+
const guardrail = factory();
|
|
78
|
+
if (guardrail === void 0 || typeof guardrail.evaluate !== "function") {
|
|
79
|
+
throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolOutputGuardrail.`);
|
|
78
80
|
}
|
|
79
|
-
return
|
|
81
|
+
return guardrail;
|
|
80
82
|
}
|
|
81
83
|
async list() {
|
|
82
84
|
await this.init();
|
|
@@ -94,7 +96,30 @@ var ToolDispatcher = class {
|
|
|
94
96
|
const tool = await this.get(name);
|
|
95
97
|
return tool?.getInputText?.(input) || "";
|
|
96
98
|
}
|
|
97
|
-
|
|
99
|
+
// Evaluates the dispatch-boundary input guardrail against the concrete invocation. Returns
|
|
100
|
+
// undefined when execution may proceed; a ToolAuthorizationResult (defer/deny) when it is
|
|
101
|
+
// blocked. On defer the pending call is recorded via the awaited onDeferred sink BEFORE the
|
|
102
|
+
// deferred result is returned (persist-before-respond); if a tool can defer but no sink is
|
|
103
|
+
// supplied, it FAILS CLOSED (denied) — a deferral must never be reported as unrecoverable.
|
|
104
|
+
async authorize(name, input, tool, auth) {
|
|
105
|
+
if (!auth) {
|
|
106
|
+
return void 0;
|
|
107
|
+
}
|
|
108
|
+
const decision = auth.guardrail.evaluate({ toolName: name, arguments: input }, auth.context);
|
|
109
|
+
if (decision.status === "allow") {
|
|
110
|
+
return void 0;
|
|
111
|
+
}
|
|
112
|
+
if (decision.status === "deny") {
|
|
113
|
+
return { authorization: "deny", succeeded: false, text: decision.reason };
|
|
114
|
+
}
|
|
115
|
+
const pending = { id: randomUUID(), name, arguments: input ?? {}, status: "pending" };
|
|
116
|
+
if (!auth.onDeferred) {
|
|
117
|
+
return { authorization: "deny", succeeded: false, text: "Authorization is unavailable for this operation." };
|
|
118
|
+
}
|
|
119
|
+
await auth.onDeferred(pending);
|
|
120
|
+
return { authorization: "defer", succeeded: false, text: decision.reason, pending };
|
|
121
|
+
}
|
|
122
|
+
async execute(name, input, auth) {
|
|
98
123
|
const tool = await this.get(name);
|
|
99
124
|
if (!tool) {
|
|
100
125
|
throw new Error(`Tool ${name} could not be found.`);
|
|
@@ -102,12 +127,18 @@ var ToolDispatcher = class {
|
|
|
102
127
|
if (!tool.func) {
|
|
103
128
|
throw new Error(`Tool ${name} does not have a function.`);
|
|
104
129
|
}
|
|
130
|
+
const authorization = await this.authorize(name, input, tool, auth);
|
|
131
|
+
if (authorization) {
|
|
132
|
+
return authorization;
|
|
133
|
+
}
|
|
134
|
+
let result;
|
|
105
135
|
try {
|
|
106
|
-
|
|
107
|
-
return result;
|
|
136
|
+
result = await tool.func(input);
|
|
108
137
|
} catch (e) {
|
|
109
138
|
throw new Error(`Failed to run ${name} tool: ${e?.message}`);
|
|
110
139
|
}
|
|
140
|
+
const guardrail = tool.outputGuardrail ?? new DefaultOutputGuardrail();
|
|
141
|
+
return guardrail.evaluate(result);
|
|
111
142
|
}
|
|
112
143
|
};
|
|
113
144
|
export {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/entities/toolDispatcher.ts"],"sourcesContent":["import { Tool, McpServer, ExecutionPolicy, ExecutionPolicyFactory, ToolOutcomeMapper, ToolOutcomeMapperFactory } from \"@mappies/miniwat-agent-core\";\nimport { McpConfig } from \"../interfaces/mcpConfig\";\n\nexport class ToolDispatcher\n{\n private tools:Tool[]\n private servers:McpServer[]\n\n constructor(private mcp?:McpConfig)\n {\n this.tools = []\n this.servers = []\n }\n\n async init()\n {\n if(this.tools.length !== 0) return;\n\n this.tools = [];\n\n if(this.mcp === undefined) return;\n\n for(let server of Object.keys(this.mcp.mcpServers))\n {\n let service = this.mcp.mcpServers[server]\n\n this.servers.push(new McpServer({name: server, ...service}))\n \n const pck = await import(service.package);\n for(let t of service.tools)\n {\n // Host intent: a tool explicitly disabled in config is excluded here, during\n // discovery, so the planner never sees it.\n if(t.enabled === false) continue;\n\n let definition = pck[t.import];\n let tool = new Tool({ \n name: definition.name, \n description: definition.description, \n schema: definition.inputSchema, \n func: pck[definition.name],\n service: server,\n getInputText: pck[`${definition.name}InputText`],\n readOnly: definition.readOnly === true,\n requiresApproval: definition.requiresApproval === true,\n executionPolicy: this.resolveExecutionPolicy(server, definition, pck),\n outcomeMapper: this.resolveOutcomeMapper(server, definition, pck)\n })\n \n this.tools.push(tool)\n }\n }\n }\n\n // Resolves a tool definition's named executionPolicy from the OWNING package's\n // EXECUTION_POLICIES factory export. Validation is loud and happens at init — never deferred to\n // tool invocation — so the app cannot reach agent.stream() with a partially resolved tool.\n private resolveExecutionPolicy(server:string, definition:any, pck:any): ExecutionPolicy | undefined\n {\n const name:string | undefined = definition.executionPolicy;\n\n if(name === undefined) return undefined;\n\n const factories = pck.EXECUTION_POLICIES;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names executionPolicy '${name}' but its package exports no EXECUTION_POLICIES.`);\n }\n\n const factory:ExecutionPolicyFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names executionPolicy '${name}' not found in the package's EXECUTION_POLICIES.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`EXECUTION_POLICIES['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const policy = factory();\n\n if(policy === undefined || typeof policy.evaluate !== \"function\")\n {\n throw new Error(`EXECUTION_POLICIES['${name}'] on server '${server}' did not produce a valid ExecutionPolicy.`);\n }\n\n return policy;\n }\n\n // Resolves a tool definition's named outcomeMapper from the OWNING package's OUTCOME_MAPPERS\n // factory export. Validated loudly at init, mirroring resolveExecutionPolicy.\n private resolveOutcomeMapper(server:string, definition:any, pck:any): ToolOutcomeMapper | undefined\n {\n const name:string | undefined = definition.outcomeMapper;\n\n if(name === undefined) return undefined;\n\n const factories = pck.OUTCOME_MAPPERS;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outcomeMapper '${name}' but its package exports no OUTCOME_MAPPERS.`);\n }\n\n const factory:ToolOutcomeMapperFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outcomeMapper '${name}' not found in the package's OUTCOME_MAPPERS.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`OUTCOME_MAPPERS['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const mapper = factory();\n\n if(mapper === undefined || typeof mapper.map !== \"function\")\n {\n throw new Error(`OUTCOME_MAPPERS['${name}'] on server '${server}' did not produce a valid ToolOutcomeMapper.`);\n }\n\n return mapper;\n }\n\n async list(): Promise<Tool[]>\n {\n await this.init()\n return this.tools;\n }\n\n async listServers(): Promise<McpServer[]>\n {\n await this.init()\n return this.servers;\n }\n\n async get(name:string): Promise<Tool|undefined>\n {\n await this.init()\n return this.tools.find(tool => tool.name === name);\n }\n\n async getInputText(name:string, input?:object): Promise<string>\n {\n const tool = await this.get(name);\n\n return tool?.getInputText?.(input) || '';\n }\n\n async execute(name:string, input?:object): Promise<string>\n {\n const tool = await this.get(name);\n \n if(!tool)\n {\n throw new Error(`Tool ${name} could not be found.`);\n }\n\n if(!tool.func)\n {\n throw new Error(`Tool ${name} does not have a function.`);\n }\n\n try\n {\n let result = await tool.func(input);\n return result;\n }\n catch(e:any)\n {\n throw new Error(`Failed to run ${name} tool: ${e?.message}`);\n }\n }\n}"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/entities/toolDispatcher.ts"],"sourcesContent":["import { Tool, McpServer, ToolInputGuardrail, ToolInputGuardrailFactory, ToolOutputGuardrail, ToolOutputGuardrailFactory, ToolOutputGuardrailResult, DefaultOutputGuardrail, ToolAuthorizationOptions, ToolAuthorizationResult, PendingToolCall } from \"@mappies/miniwat-agent-core\";\nimport { randomUUID } from \"crypto\";\nimport { McpConfig } from \"../interfaces/mcpConfig\";\n\nexport class ToolDispatcher\n{\n private tools:Tool[]\n private servers:McpServer[]\n\n constructor(private mcp?:McpConfig)\n {\n this.tools = []\n this.servers = []\n }\n\n async init()\n {\n if(this.tools.length !== 0) return;\n\n this.tools = [];\n\n if(this.mcp === undefined) return;\n\n for(let server of Object.keys(this.mcp.mcpServers))\n {\n let service = this.mcp.mcpServers[server]\n\n this.servers.push(new McpServer({name: server, ...service}))\n \n const pck = await import(service.package);\n for(let t of service.tools)\n {\n // Host intent: a tool explicitly disabled in config is excluded here, during\n // discovery, so the planner never sees it.\n if(t.enabled === false) continue;\n\n let definition = pck[t.import];\n let tool = new Tool({ \n name: definition.name, \n displayName: definition.displayName,\n description: definition.description, \n schema: definition.inputSchema, \n func: pck[definition.name],\n service: server,\n getInputText: pck[`${definition.name}InputText`],\n readOnly: definition.readOnly === true,\n requiresApproval: definition.requiresApproval === true,\n inputGuardrail: this.resolveInputGuardrail(server, definition, pck),\n outputGuardrail: this.resolveOutputGuardrail(server, definition, pck)\n })\n \n this.tools.push(tool)\n }\n }\n }\n\n // Resolves a tool definition's named inputGuardrail from the OWNING package's INPUT_GUARDRAILS\n // factory export. Validation is loud and happens at init — never deferred to tool invocation —\n // so the app cannot reach agent.stream() with a partially resolved tool.\n private resolveInputGuardrail(server:string, definition:any, pck:any): ToolInputGuardrail | undefined\n {\n const name:string | undefined = definition.inputGuardrail;\n\n if(name === undefined) return undefined;\n\n const factories = pck.INPUT_GUARDRAILS;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' but its package exports no INPUT_GUARDRAILS.`);\n }\n\n const factory:ToolInputGuardrailFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names inputGuardrail '${name}' not found in the package's INPUT_GUARDRAILS.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const guardrail = factory();\n\n if(guardrail === undefined || typeof guardrail.evaluate !== \"function\")\n {\n throw new Error(`INPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolInputGuardrail.`);\n }\n\n return guardrail;\n }\n\n // Resolves a tool definition's named outputGuardrail from the OWNING package's OUTPUT_GUARDRAILS\n // factory export. Validated loudly at init, mirroring resolveInputGuardrail.\n private resolveOutputGuardrail(server:string, definition:any, pck:any): ToolOutputGuardrail | undefined\n {\n const name:string | undefined = definition.outputGuardrail;\n\n if(name === undefined) return undefined;\n\n const factories = pck.OUTPUT_GUARDRAILS;\n\n if(factories === undefined || typeof factories !== \"object\")\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' but its package exports no OUTPUT_GUARDRAILS.`);\n }\n\n const factory:ToolOutputGuardrailFactory | undefined = factories[name];\n\n if(factory === undefined)\n {\n throw new Error(`Tool '${definition.name}' on server '${server}' names outputGuardrail '${name}' not found in the package's OUTPUT_GUARDRAILS.`);\n }\n\n if(typeof factory !== \"function\")\n {\n throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' is not a factory function.`);\n }\n\n const guardrail = factory();\n\n if(guardrail === undefined || typeof guardrail.evaluate !== \"function\")\n {\n throw new Error(`OUTPUT_GUARDRAILS['${name}'] on server '${server}' did not produce a valid ToolOutputGuardrail.`);\n }\n\n return guardrail;\n }\n\n async list(): Promise<Tool[]>\n {\n await this.init()\n return this.tools;\n }\n\n async listServers(): Promise<McpServer[]>\n {\n await this.init()\n return this.servers;\n }\n\n async get(name:string): Promise<Tool|undefined>\n {\n await this.init()\n return this.tools.find(tool => tool.name === name);\n }\n\n async getInputText(name:string, input?:object): Promise<string>\n {\n const tool = await this.get(name);\n\n return tool?.getInputText?.(input) || '';\n }\n\n // Evaluates the dispatch-boundary input guardrail against the concrete invocation. Returns\n // undefined when execution may proceed; a ToolAuthorizationResult (defer/deny) when it is\n // blocked. On defer the pending call is recorded via the awaited onDeferred sink BEFORE the\n // deferred result is returned (persist-before-respond); if a tool can defer but no sink is\n // supplied, it FAILS CLOSED (denied) — a deferral must never be reported as unrecoverable.\n private async authorize(name:string, input:object | undefined, tool:Tool, auth?:ToolAuthorizationOptions): Promise<ToolAuthorizationResult | undefined>\n {\n if(!auth)\n {\n return undefined;\n }\n\n const decision = auth.guardrail.evaluate({ toolName: name, arguments: input }, auth.context);\n\n if(decision.status === \"allow\")\n {\n return undefined;\n }\n\n if(decision.status === \"deny\")\n {\n return { authorization: \"deny\", succeeded: false, text: decision.reason };\n }\n\n // defer: preserve the invocation for a later approval turn.\n const pending:PendingToolCall = { id: randomUUID(), name, arguments: (input ?? {}) as Record<string, unknown>, status: \"pending\" };\n\n if(!auth.onDeferred)\n {\n // Fail closed: a deferral we cannot durably record must not surface as a usable\n // approval-required result.\n return { authorization: \"deny\", succeeded: false, text: \"Authorization is unavailable for this operation.\" };\n }\n\n // Persist-before-respond: the pending call is durably recorded before the deferred result\n // (and the approval request derived from it) can reach the user. A rejection propagates.\n await auth.onDeferred(pending);\n\n return { authorization: \"defer\", succeeded: false, text: decision.reason, pending };\n }\n\n async execute(name:string, input?:object, auth?:ToolAuthorizationOptions): Promise<ToolOutputGuardrailResult | ToolAuthorizationResult>\n {\n const tool = await this.get(name);\n \n if(!tool)\n {\n throw new Error(`Tool ${name} could not be found.`);\n }\n\n if(!tool.func)\n {\n throw new Error(`Tool ${name} does not have a function.`);\n }\n\n // Dispatch-boundary authorization runs BEFORE the tool, so an unauthorized side effect never\n // executes — regardless of which planner (or no planner) proposed it. The guardrail is the\n // existing allow/defer/deny input guardrail evaluated against the CONCRETE invocation.\n const authorization = await this.authorize(name, input, tool, auth);\n\n if(authorization)\n {\n return authorization;\n }\n\n let result;\n\n try\n {\n result = await tool.func(input);\n }\n catch(e:any)\n {\n throw new Error(`Failed to run ${name} tool: ${e?.message}`);\n }\n\n // The output guardrail is the SINGLE post-execution authority. It runs here, at the\n // provider-agnostic chokepoint, so the real result is classified BEFORE any provider relays\n // it. Its verdict carries both the user-facing text and the semantic status to the caller;\n // a `blocked` verdict withholds the real result in favor of a replacement. A tool without an\n // explicit guardrail gets the framework default (a normal return is a success).\n const guardrail = tool.outputGuardrail ?? new DefaultOutputGuardrail();\n\n return guardrail.evaluate(result);\n }\n}"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mappies/miniwat-mcp-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Shared entities and executor for Miniwat MCP",
|
|
5
5
|
"homepage": "https://gitlab.com/mappies/miniwat-mcp-core#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -43,6 +43,6 @@
|
|
|
43
43
|
"vitest": "^5.0.0"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@mappies/miniwat-agent-core": "^0.
|
|
46
|
+
"@mappies/miniwat-agent-core": "^0.21.0"
|
|
47
47
|
}
|
|
48
48
|
}
|