@msm-core/mini 0.3.1 → 0.4.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.
Files changed (47) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/dist/adapters/redis-memory.d.ts +3 -0
  3. package/dist/adapters/redis-memory.d.ts.map +1 -1
  4. package/dist/adapters/redis-memory.js +6 -0
  5. package/dist/adapters/redis-memory.js.map +1 -1
  6. package/dist/adapters/redis-types.d.ts +2 -0
  7. package/dist/adapters/redis-types.d.ts.map +1 -1
  8. package/dist/brain/anthropic.d.ts.map +1 -1
  9. package/dist/brain/anthropic.js +3 -2
  10. package/dist/brain/anthropic.js.map +1 -1
  11. package/dist/brain/gemini.d.ts.map +1 -1
  12. package/dist/brain/gemini.js +2 -1
  13. package/dist/brain/gemini.js.map +1 -1
  14. package/dist/brain/ollama.d.ts.map +1 -1
  15. package/dist/brain/ollama.js +3 -2
  16. package/dist/brain/ollama.js.map +1 -1
  17. package/dist/brain/openai.d.ts.map +1 -1
  18. package/dist/brain/openai.js +2 -1
  19. package/dist/brain/openai.js.map +1 -1
  20. package/dist/brain/retry.d.ts +21 -0
  21. package/dist/brain/retry.d.ts.map +1 -0
  22. package/dist/brain/retry.js +63 -0
  23. package/dist/brain/retry.js.map +1 -0
  24. package/dist/core/loop.d.ts.map +1 -1
  25. package/dist/core/loop.js +101 -36
  26. package/dist/core/loop.js.map +1 -1
  27. package/dist/core/types.d.ts +26 -0
  28. package/dist/core/types.d.ts.map +1 -1
  29. package/dist/definition/parser.d.ts.map +1 -1
  30. package/dist/definition/parser.js +5 -2
  31. package/dist/definition/parser.js.map +1 -1
  32. package/dist/index.d.ts +1 -1
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js.map +1 -1
  35. package/dist/server.d.ts +24 -1
  36. package/dist/server.d.ts.map +1 -1
  37. package/dist/server.js +90 -25
  38. package/dist/server.js.map +1 -1
  39. package/dist/tools/dedup.d.ts +7 -2
  40. package/dist/tools/dedup.d.ts.map +1 -1
  41. package/dist/tools/dedup.js +9 -9
  42. package/dist/tools/dedup.js.map +1 -1
  43. package/dist/tools/executor.d.ts +8 -4
  44. package/dist/tools/executor.d.ts.map +1 -1
  45. package/dist/tools/executor.js +62 -6
  46. package/dist/tools/executor.js.map +1 -1
  47. package/package.json +1 -1
package/dist/server.js CHANGED
@@ -8,6 +8,11 @@
8
8
  * The UTS api/server.ts proxies /chat → /v1/event on this server.
9
9
  * All other msm-agent HTTP surface (dashboard etc.) is NOT replicated — keep it slim.
10
10
  *
11
+ * Security posture: this server is designed to sit on localhost behind a
12
+ * trusted gateway. It still hard-validates its inputs: request bodies are
13
+ * size-capped and `guardsOverride` is whitelisted + type-checked so a caller
14
+ * can never disable the loop's safety guards with malformed values.
15
+ *
11
16
  * @example
12
17
  * const agentServer = createAgentServer(agent, { port: PORT + 1 });
13
18
  * await agentServer.start();
@@ -15,10 +20,24 @@
15
20
  * await agentServer.stop();
16
21
  */
17
22
  import { createServer, } from "node:http";
18
- function readBody(req) {
23
+ class BodyTooLargeError extends Error {
24
+ constructor() {
25
+ super("Request body too large");
26
+ }
27
+ }
28
+ function readBody(req, maxBytes) {
19
29
  return new Promise((resolve, reject) => {
20
30
  const chunks = [];
21
- req.on("data", (c) => chunks.push(c));
31
+ let received = 0;
32
+ req.on("data", (c) => {
33
+ received += c.length;
34
+ if (received > maxBytes) {
35
+ req.destroy();
36
+ reject(new BodyTooLargeError());
37
+ return;
38
+ }
39
+ chunks.push(c);
40
+ });
22
41
  req.on("end", () => {
23
42
  try {
24
43
  resolve(JSON.parse(Buffer.concat(chunks).toString("utf8")));
@@ -30,27 +49,66 @@ function readBody(req) {
30
49
  req.on("error", reject);
31
50
  });
32
51
  }
33
- function json(res, status, body) {
34
- const payload = JSON.stringify(body);
35
- res.writeHead(status, {
36
- "Content-Type": "application/json",
37
- "Content-Length": Buffer.byteLength(payload),
38
- });
39
- res.end(payload);
52
+ /**
53
+ * Whitelist + type-check a guards override coming from the network.
54
+ *
55
+ * Without this, a malformed value silently DISABLES guards: resolveGuards
56
+ * merges with `??` (any non-nullish survives), and every guard comparison
57
+ * against a non-number is false — `5 >= "x"` never trips the iteration cap,
58
+ * `"x" > 0` turns the cost cap and timeout off entirely.
59
+ *
60
+ * Only known numeric keys with finite, non-negative values pass through.
61
+ */
62
+ export function sanitizeGuardsOverride(raw) {
63
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
64
+ return undefined;
65
+ }
66
+ const NUMERIC_KEYS = [
67
+ "maxIterations",
68
+ "costCapPerTask",
69
+ "timeoutMs",
70
+ "confidenceThreshold",
71
+ "maxToolCallsPerTask",
72
+ "maxConsecutiveFailures",
73
+ ];
74
+ const out = {};
75
+ for (const key of NUMERIC_KEYS) {
76
+ const v = raw[key];
77
+ if (typeof v === "number" && Number.isFinite(v) && v >= 0) {
78
+ out[key] = v;
79
+ }
80
+ }
81
+ return Object.keys(out).length > 0 ? out : undefined;
40
82
  }
41
83
  const START_TIME = Date.now();
42
84
  export function createAgentServer(agent, opts) {
43
85
  const host = opts.host ?? "127.0.0.1";
44
86
  const port = opts.port;
87
+ const maxBodyBytes = opts.maxBodyBytes ?? 262_144;
88
+ const corsOrigin = opts.corsOrigin;
89
+ function json(res, status, body) {
90
+ const payload = JSON.stringify(body);
91
+ res.writeHead(status, {
92
+ "Content-Type": "application/json",
93
+ "Content-Length": Buffer.byteLength(payload),
94
+ ...(corsOrigin ? { "Access-Control-Allow-Origin": corsOrigin } : {}),
95
+ });
96
+ res.end(payload);
97
+ }
45
98
  const server = createServer(async (req, res) => {
46
99
  const path = (req.url ?? "/").split("?")[0];
47
- // CORS preflight
100
+ // CORS preflight — only when CORS is enabled
48
101
  if (req.method === "OPTIONS") {
49
- res.writeHead(204, {
50
- "Access-Control-Allow-Origin": "*",
51
- "Access-Control-Allow-Methods": "POST, GET, OPTIONS",
52
- "Access-Control-Allow-Headers": "Content-Type, Authorization",
53
- });
102
+ if (corsOrigin) {
103
+ res.writeHead(204, {
104
+ "Access-Control-Allow-Origin": corsOrigin,
105
+ "Access-Control-Allow-Methods": "POST, GET, OPTIONS",
106
+ "Access-Control-Allow-Headers": "Content-Type, Authorization",
107
+ });
108
+ }
109
+ else {
110
+ res.writeHead(405);
111
+ }
54
112
  res.end();
55
113
  return;
56
114
  }
@@ -64,10 +122,15 @@ export function createAgentServer(agent, opts) {
64
122
  if (path === "/v1/event" && req.method === "POST") {
65
123
  let body;
66
124
  try {
67
- body = (await readBody(req));
125
+ body = (await readBody(req, maxBodyBytes));
68
126
  }
69
- catch {
70
- json(res, 400, { error: "Invalid JSON body" });
127
+ catch (err) {
128
+ if (err instanceof BodyTooLargeError) {
129
+ json(res, 413, { error: "Request body too large" });
130
+ }
131
+ else {
132
+ json(res, 400, { error: "Invalid JSON body" });
133
+ }
71
134
  return;
72
135
  }
73
136
  const sessionId = typeof body["sessionId"] === "string" ? body["sessionId"] : "";
@@ -87,12 +150,9 @@ export function createAgentServer(agent, opts) {
87
150
  const agentType = (typeof bodyTenant?.["agentType"] === "string" ? bodyTenant["agentType"] : undefined) ??
88
151
  (typeof req.headers["x-agent-type"] === "string" ? req.headers["x-agent-type"] : undefined);
89
152
  const tenantContext = companyId && agentType ? { companyId, agentType } : undefined;
90
- // Per-tenant guard overrides (cost cap, rate limits) from body.
91
- const guardsOverride = body["guardsOverride"] !== undefined &&
92
- typeof body["guardsOverride"] === "object" &&
93
- body["guardsOverride"] !== null
94
- ? body["guardsOverride"]
95
- : undefined;
153
+ // Per-tenant guard overrides whitelisted + type-checked, so malformed
154
+ // values can't silently disable the loop's safety guards.
155
+ const guardsOverride = sanitizeGuardsOverride(body["guardsOverride"]);
96
156
  const outcome = await agent.handle({
97
157
  sessionId,
98
158
  message: text,
@@ -113,8 +173,13 @@ export function createAgentServer(agent, opts) {
113
173
  });
114
174
  return {
115
175
  start() {
116
- return new Promise((resolve) => {
176
+ return new Promise((resolve, reject) => {
177
+ // Surface listen failures (EADDRINUSE etc.) as a rejected promise
178
+ // instead of an unhandled 'error' event crash.
179
+ const onError = (err) => reject(err);
180
+ server.once("error", onError);
117
181
  server.listen(port, host, () => {
182
+ server.removeListener("error", onError);
118
183
  console.log(`[AgentServer] listening on http://${host}:${port}`);
119
184
  resolve();
120
185
  });
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Tool Dedup — Hash-based idempotency for tool calls.
3
3
  *
4
- * Deduplication key: SHA-256(toolName + JSON.stringify(sortedArgs))
4
+ * Deduplication key: SHA-256(toolName + "::" + JSON.stringify(sortedArgs))
5
5
  * Stored in Redis as: {prefix}:session:{id}:tools:dedup hash field
6
6
  * TTL: 5 minutes (configurable)
7
7
  */
@@ -14,7 +14,12 @@ type RedisLike = {
14
14
  export declare function toolDedupKey(prefix: string, sessionId: string): string;
15
15
  export declare function checkDedup(redis: RedisLike, dedupKey: string, hash: string): Promise<ToolResult | null>;
16
16
  export declare function storeDedup(redis: RedisLike, dedupKey: string, hash: string, result: ToolResult, ttlSeconds: number): Promise<void>;
17
- /** Deterministic hash of a tool call — pure function, no crypto dependency */
17
+ /**
18
+ * Deterministic hash of a tool call (SHA-256, key-sorted args).
19
+ *
20
+ * Previously FNV-1a 32-bit — at 32 bits a same-session collision silently
21
+ * returns the WRONG cached tool result. node:crypto is dependency-free.
22
+ */
18
23
  export declare function hashToolCall(toolName: string, args: Record<string, unknown>): string;
19
24
  export {};
20
25
  //# sourceMappingURL=dedup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dedup.d.ts","sourceRoot":"","sources":["../../src/tools/dedup.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,KAAK,SAAS,GAAG;IACf,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxD,CAAC;AAEF,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED,wBAAsB,UAAU,CAC9B,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAQ5B;AAED,wBAAsB,UAAU,CAC9B,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAUpF"}
1
+ {"version":3,"file":"dedup.d.ts","sourceRoot":"","sources":["../../src/tools/dedup.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,KAAK,SAAS,GAAG;IACf,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxD,CAAC;AAEF,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED,wBAAsB,UAAU,CAC9B,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAQ5B;AAED,wBAAsB,UAAU,CAC9B,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAIpF"}
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * Tool Dedup — Hash-based idempotency for tool calls.
3
3
  *
4
- * Deduplication key: SHA-256(toolName + JSON.stringify(sortedArgs))
4
+ * Deduplication key: SHA-256(toolName + "::" + JSON.stringify(sortedArgs))
5
5
  * Stored in Redis as: {prefix}:session:{id}:tools:dedup hash field
6
6
  * TTL: 5 minutes (configurable)
7
7
  */
8
+ import { createHash } from "node:crypto";
8
9
  export function toolDedupKey(prefix, sessionId) {
9
10
  return `${prefix}:session:${sessionId}:tools:dedup`;
10
11
  }
@@ -23,17 +24,16 @@ export async function storeDedup(redis, dedupKey, hash, result, ttlSeconds) {
23
24
  await redis.hset(dedupKey, hash, JSON.stringify(result));
24
25
  await redis.expire(dedupKey, ttlSeconds);
25
26
  }
26
- /** Deterministic hash of a tool call — pure function, no crypto dependency */
27
+ /**
28
+ * Deterministic hash of a tool call (SHA-256, key-sorted args).
29
+ *
30
+ * Previously FNV-1a 32-bit — at 32 bits a same-session collision silently
31
+ * returns the WRONG cached tool result. node:crypto is dependency-free.
32
+ */
27
33
  export function hashToolCall(toolName, args) {
28
34
  const sorted = sortKeys(args);
29
35
  const str = toolName + "::" + JSON.stringify(sorted);
30
- // FNV-1a 32-bit hash — fast, deterministic, no external dep
31
- let h = 2166136261;
32
- for (let i = 0; i < str.length; i++) {
33
- h ^= str.charCodeAt(i);
34
- h = (h * 16777619) >>> 0;
35
- }
36
- return h.toString(16).padStart(8, "0");
36
+ return createHash("sha256").update(str).digest("hex");
37
37
  }
38
38
  function sortKeys(obj) {
39
39
  if (obj === null || typeof obj !== "object")
@@ -1 +1 @@
1
- {"version":3,"file":"dedup.js","sourceRoot":"","sources":["../../src/tools/dedup.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,SAAiB;IAC5D,OAAO,GAAG,MAAM,YAAY,SAAS,cAAc,CAAC;AACtD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAgB,EAChB,QAAgB,EAChB,IAAY;IAEZ,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAe,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAgB,EAChB,QAAgB,EAChB,IAAY,EACZ,MAAkB,EAClB,UAAkB;IAElB,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACzD,MAAM,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;AAC3C,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,IAA6B;IAC1E,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACrD,4DAA4D;IAC5D,IAAI,CAAC,GAAG,UAAU,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,QAAQ,CAAC,GAAY;IAC5B,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACxD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjD,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,GAA8B,CAAC;SAC3C,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CACrC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"dedup.js","sourceRoot":"","sources":["../../src/tools/dedup.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AASzC,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,SAAiB;IAC5D,OAAO,GAAG,MAAM,YAAY,SAAS,cAAc,CAAC;AACtD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAgB,EAChB,QAAgB,EAChB,IAAY;IAEZ,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAe,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAgB,EAChB,QAAgB,EAChB,IAAY,EACZ,MAAkB,EAClB,UAAkB;IAElB,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACzD,MAAM,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,IAA6B;IAC1E,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACrD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,QAAQ,CAAC,GAAY;IAC5B,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACxD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjD,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,GAA8B,CAAC;SAC3C,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CACrC,CAAC;AACJ,CAAC"}
@@ -2,13 +2,15 @@
2
2
  * Tool Executor — Validation, dedup, and execution pipeline.
3
3
  *
4
4
  * Pipeline per tool call:
5
- * 1. Control bus — check if tool is disabled
6
- * 2. Dedupreturn cached result if same args seen in last 5 min
7
- * 3. Validate check required parameters are present and typed
5
+ * 1. Validate — check required parameters are present and typed
6
+ * 2. onBeforeTool hook approval gate / audit / substitute / skip.
7
+ * Runs BEFORE dedup so cached results can never bypass the gate.
8
+ * requiresApproval tools fail closed (hook error or no hook → blocked).
9
+ * 3. Dedup — return cached result if same args seen in last 5 min
8
10
  * 4. Execute — call tool.execute()
9
11
  * 5. Cache — store result in dedup hash
10
12
  */
11
- import type { Tool, ToolResult, ToolMeta } from "../core/types.js";
13
+ import type { Tool, ToolResult, ToolMeta, AgentHooks } from "../core/types.js";
12
14
  type RedisLike = {
13
15
  hget(key: string, field: string): Promise<string | null>;
14
16
  hset(key: string, field: string, value: string): Promise<unknown>;
@@ -19,6 +21,8 @@ export interface ExecutorOptions {
19
21
  redis: RedisLike;
20
22
  redisPrefix: string;
21
23
  dedupTtlSeconds: number;
24
+ /** Optional hooks — only onBeforeTool is used at this layer */
25
+ hooks?: Pick<AgentHooks, "onBeforeTool">;
22
26
  }
23
27
  export interface ExecutionResult {
24
28
  result: ToolResult;
@@ -1 +1 @@
1
- {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/tools/executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGnE,KAAK,SAAS,GAAG;IACf,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,eAAe,CAAC,CAuC1B;AAqBD,oFAAoF;AACpF,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,EAAE,GACZ,OAAO,kBAAkB,EAAE,cAAc,EAAE,CAS7C"}
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/tools/executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG/E,KAAK,SAAS,GAAG;IACf,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,eAAe,CAAC,CAgG1B;AAqBD,oFAAoF;AACpF,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,EAAE,GACZ,OAAO,kBAAkB,EAAE,cAAc,EAAE,CAS7C"}
@@ -2,9 +2,11 @@
2
2
  * Tool Executor — Validation, dedup, and execution pipeline.
3
3
  *
4
4
  * Pipeline per tool call:
5
- * 1. Control bus — check if tool is disabled
6
- * 2. Dedupreturn cached result if same args seen in last 5 min
7
- * 3. Validate check required parameters are present and typed
5
+ * 1. Validate — check required parameters are present and typed
6
+ * 2. onBeforeTool hook approval gate / audit / substitute / skip.
7
+ * Runs BEFORE dedup so cached results can never bypass the gate.
8
+ * requiresApproval tools fail closed (hook error or no hook → blocked).
9
+ * 3. Dedup — return cached result if same args seen in last 5 min
8
10
  * 4. Execute — call tool.execute()
9
11
  * 5. Cache — store result in dedup hash
10
12
  */
@@ -20,14 +22,68 @@ export async function executeTool(tool, params, meta, opts) {
20
22
  durationMs: Date.now() - start,
21
23
  };
22
24
  }
23
- // Step 2: Dedup check
25
+ // Step 2: onBeforeTool hook — approval gate, audit, dry-run, etc.
26
+ // Runs BEFORE the dedup check so every call (including ones that would be
27
+ // served from cache) passes the gate — an approval/audit hook must never be
28
+ // bypassed by a cached result.
29
+ //
30
+ // Failure semantics: a throwing hook is "proceed" for ordinary tools, but
31
+ // FAIL-CLOSED for tools marked requiresApproval — if the approval system
32
+ // errors, a destructive tool must not run.
33
+ if (opts.hooks?.onBeforeTool) {
34
+ const directive = await opts.hooks
35
+ .onBeforeTool(tool.name, params, meta)
36
+ .catch(() => tool.requiresApproval
37
+ ? { approvalFailed: true }
38
+ : "proceed");
39
+ if (typeof directive === "object" && "approvalFailed" in directive) {
40
+ return {
41
+ result: {
42
+ tool: tool.name,
43
+ status: "failed",
44
+ error: `Tool "${tool.name}" requires approval and the approval hook failed — execution blocked`,
45
+ },
46
+ cached: false,
47
+ durationMs: Date.now() - start,
48
+ };
49
+ }
50
+ if (directive === "skip") {
51
+ return {
52
+ result: { tool: tool.name, status: "ok", result: { skipped: true } },
53
+ cached: false,
54
+ durationMs: Date.now() - start,
55
+ };
56
+ }
57
+ if (typeof directive === "object" && "substituteResult" in directive) {
58
+ return {
59
+ result: directive.substituteResult,
60
+ cached: false,
61
+ durationMs: Date.now() - start,
62
+ };
63
+ }
64
+ // "proceed" — fall through
65
+ }
66
+ else if (tool.requiresApproval) {
67
+ // requiresApproval is a contract, not decoration: with no approval hook
68
+ // configured the tool must not execute.
69
+ return {
70
+ result: {
71
+ tool: tool.name,
72
+ status: "failed",
73
+ error: `Tool "${tool.name}" requires approval but no onBeforeTool hook is configured`,
74
+ },
75
+ cached: false,
76
+ durationMs: Date.now() - start,
77
+ };
78
+ }
79
+ // Step 3: Dedup check
24
80
  const hash = hashToolCall(tool.name, params);
25
81
  const dedupKey = toolDedupKey(opts.redisPrefix, meta.sessionId);
26
82
  const cached = await checkDedup(opts.redis, dedupKey, hash);
27
83
  if (cached) {
28
84
  return { result: cached, cached: true, durationMs: Date.now() - start };
29
85
  }
30
- // Step 3: Execute
86
+ // Step 4: Execute
31
87
  let result;
32
88
  try {
33
89
  result = await tool.execute(params, meta);
@@ -39,7 +95,7 @@ export async function executeTool(tool, params, meta, opts) {
39
95
  error: err instanceof Error ? err.message : String(err),
40
96
  };
41
97
  }
42
- // Step 4: Cache successful results only
98
+ // Step 5: Cache successful results only
43
99
  if (result.status === "ok") {
44
100
  await storeDedup(opts.redis, dedupKey, hash, result, opts.dedupTtlSeconds);
45
101
  }
@@ -1 +1 @@
1
- {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/tools/executor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/tools/executor.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@msm-core/mini",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Portable AI agent execution loop — brain-agnostic, zero embedded databases",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",