@msm-core/mini 0.1.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/README.md +297 -0
- package/dist/adapters/index.d.ts +9 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +7 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/redis-control.d.ts +25 -0
- package/dist/adapters/redis-control.d.ts.map +1 -0
- package/dist/adapters/redis-control.js +48 -0
- package/dist/adapters/redis-control.js.map +1 -0
- package/dist/adapters/redis-lock.d.ts +31 -0
- package/dist/adapters/redis-lock.d.ts.map +1 -0
- package/dist/adapters/redis-lock.js +73 -0
- package/dist/adapters/redis-lock.js.map +1 -0
- package/dist/adapters/redis-memory.d.ts +42 -0
- package/dist/adapters/redis-memory.d.ts.map +1 -0
- package/dist/adapters/redis-memory.js +87 -0
- package/dist/adapters/redis-memory.js.map +1 -0
- package/dist/adapters/redis-types.d.ts +17 -0
- package/dist/adapters/redis-types.d.ts.map +1 -0
- package/dist/adapters/redis-types.js +2 -0
- package/dist/adapters/redis-types.js.map +1 -0
- package/dist/brain/anthropic.d.ts +10 -0
- package/dist/brain/anthropic.d.ts.map +1 -0
- package/dist/brain/anthropic.js +73 -0
- package/dist/brain/anthropic.js.map +1 -0
- package/dist/brain/factory.d.ts +7 -0
- package/dist/brain/factory.d.ts.map +1 -0
- package/dist/brain/factory.js +24 -0
- package/dist/brain/factory.js.map +1 -0
- package/dist/brain/gemini.d.ts +10 -0
- package/dist/brain/gemini.d.ts.map +1 -0
- package/dist/brain/gemini.js +113 -0
- package/dist/brain/gemini.js.map +1 -0
- package/dist/brain/ollama.d.ts +10 -0
- package/dist/brain/ollama.d.ts.map +1 -0
- package/dist/brain/ollama.js +38 -0
- package/dist/brain/ollama.js.map +1 -0
- package/dist/brain/openai.d.ts +11 -0
- package/dist/brain/openai.d.ts.map +1 -0
- package/dist/brain/openai.js +96 -0
- package/dist/brain/openai.js.map +1 -0
- package/dist/brain/types.d.ts +6 -0
- package/dist/brain/types.d.ts.map +1 -0
- package/dist/brain/types.js +2 -0
- package/dist/brain/types.js.map +1 -0
- package/dist/core/context-builder.d.ts +25 -0
- package/dist/core/context-builder.d.ts.map +1 -0
- package/dist/core/context-builder.js +107 -0
- package/dist/core/context-builder.js.map +1 -0
- package/dist/core/gates.d.ts +16 -0
- package/dist/core/gates.d.ts.map +1 -0
- package/dist/core/gates.js +70 -0
- package/dist/core/gates.js.map +1 -0
- package/dist/core/guards.d.ts +22 -0
- package/dist/core/guards.d.ts.map +1 -0
- package/dist/core/guards.js +119 -0
- package/dist/core/guards.js.map +1 -0
- package/dist/core/hooks.d.ts +13 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +61 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/core/loop.d.ts +16 -0
- package/dist/core/loop.d.ts.map +1 -0
- package/dist/core/loop.js +255 -0
- package/dist/core/loop.js.map +1 -0
- package/dist/core/types.d.ts +310 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +8 -0
- package/dist/core/types.js.map +1 -0
- package/dist/definition/parser.d.ts +12 -0
- package/dist/definition/parser.d.ts.map +1 -0
- package/dist/definition/parser.js +117 -0
- package/dist/definition/parser.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/quality/scorer.d.ts +18 -0
- package/dist/quality/scorer.d.ts.map +1 -0
- package/dist/quality/scorer.js +22 -0
- package/dist/quality/scorer.js.map +1 -0
- package/dist/server.d.ts +27 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +118 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/dedup.d.ts +20 -0
- package/dist/tools/dedup.d.ts.map +1 -0
- package/dist/tools/dedup.js +47 -0
- package/dist/tools/dedup.js.map +1 -0
- package/dist/tools/executor.d.ts +32 -0
- package/dist/tools/executor.d.ts.map +1 -0
- package/dist/tools/executor.js +75 -0
- package/dist/tools/executor.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Builder — Assembles brain input from session state + injected context.
|
|
3
|
+
*
|
|
4
|
+
* Priority order (highest first):
|
|
5
|
+
* 1. neverTruncate memories (from msm-context tiers marked protected)
|
|
6
|
+
* 2. normal memories, sorted by score
|
|
7
|
+
* 3. session history (last N messages)
|
|
8
|
+
* 4. tool catalog
|
|
9
|
+
*
|
|
10
|
+
* Token budget is enforced by dropping lowest-priority memories first.
|
|
11
|
+
* The agent never queries external stores — context arrives pre-assembled.
|
|
12
|
+
*/
|
|
13
|
+
const DEFAULT_BUDGET = {
|
|
14
|
+
maxTokens: 32_000,
|
|
15
|
+
maxHistoryMessages: 20,
|
|
16
|
+
};
|
|
17
|
+
/** Rough token estimator — accurate enough for budget enforcement */
|
|
18
|
+
function countTokens(text) {
|
|
19
|
+
return Math.ceil(text.length / 4);
|
|
20
|
+
}
|
|
21
|
+
function memoriesBlock(memories) {
|
|
22
|
+
if (memories.length === 0)
|
|
23
|
+
return "";
|
|
24
|
+
const lines = memories.map((m) => `[${m.source}] ${m.content.trimEnd()}`);
|
|
25
|
+
return `\n\n## Retrieved Context\n\n${lines.join("\n\n")}`;
|
|
26
|
+
}
|
|
27
|
+
function userProfileBlock(profile) {
|
|
28
|
+
const lines = Object.entries(profile)
|
|
29
|
+
.filter(([, v]) => v != null)
|
|
30
|
+
.map(([k, v]) => `- ${k}: ${JSON.stringify(v)}`);
|
|
31
|
+
if (lines.length === 0)
|
|
32
|
+
return "";
|
|
33
|
+
return `\n\n## User Profile\n\n${lines.join("\n")}`;
|
|
34
|
+
}
|
|
35
|
+
function toolsBlock(tools) {
|
|
36
|
+
if (tools.length === 0)
|
|
37
|
+
return "\n\n## Tools\n\nNo tools available.";
|
|
38
|
+
const defs = tools
|
|
39
|
+
.map((t) => {
|
|
40
|
+
const params = Object.entries(t.parameters)
|
|
41
|
+
.map(([name, p]) => ` - ${name} (${p.type}${p.required ? ", required" : ""}): ${p.description}`)
|
|
42
|
+
.join("\n");
|
|
43
|
+
return `### ${t.name}\n${t.description}\n${params}`;
|
|
44
|
+
})
|
|
45
|
+
.join("\n\n");
|
|
46
|
+
return `\n\n## Available Tools\n\n${defs}`;
|
|
47
|
+
}
|
|
48
|
+
function personaBlock(def) {
|
|
49
|
+
const lines = [
|
|
50
|
+
`You are ${def.persona.name ?? def.name}, an AI agent for ${def.domain ?? "general assistance"}.`,
|
|
51
|
+
def.persona.style ? `Style: ${def.persona.style}.` : "",
|
|
52
|
+
"",
|
|
53
|
+
"## Capabilities",
|
|
54
|
+
...def.capabilities.map((c) => `- ${c}`),
|
|
55
|
+
].filter((l) => l !== undefined);
|
|
56
|
+
return lines.join("\n");
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Build the full system context string for the brain.
|
|
60
|
+
* Enforces token budget by truncating memories from the bottom.
|
|
61
|
+
*/
|
|
62
|
+
export function buildContext(def, history, tools, context, budget = DEFAULT_BUDGET) {
|
|
63
|
+
// 1. Persona
|
|
64
|
+
let system = personaBlock(def);
|
|
65
|
+
// 2. Caller-provided system prompt extension
|
|
66
|
+
if (context?.systemPrompt) {
|
|
67
|
+
system += `\n\n${context.systemPrompt}`;
|
|
68
|
+
}
|
|
69
|
+
// 3. User profile
|
|
70
|
+
if (context?.userProfile && Object.keys(context.userProfile).length > 0) {
|
|
71
|
+
system += userProfileBlock(context.userProfile);
|
|
72
|
+
}
|
|
73
|
+
// 4. Budget-aware memories
|
|
74
|
+
const rawMemories = context?.memories ?? [];
|
|
75
|
+
const budgetUsed = countTokens(system) + countTokens(toolsBlock(tools));
|
|
76
|
+
const remaining = budget.maxTokens - budgetUsed;
|
|
77
|
+
const fittedMemories = fitMemoriesToBudget(rawMemories, remaining);
|
|
78
|
+
system += memoriesBlock(fittedMemories);
|
|
79
|
+
// 5. Tools
|
|
80
|
+
system += toolsBlock(tools);
|
|
81
|
+
// 6. History (last N)
|
|
82
|
+
const trimmedHistory = history.slice(-budget.maxHistoryMessages);
|
|
83
|
+
return { system_context: system, history: trimmedHistory };
|
|
84
|
+
}
|
|
85
|
+
/** Fit memories into token budget: protected entries first, then by score */
|
|
86
|
+
function fitMemoriesToBudget(memories, budgetTokens) {
|
|
87
|
+
if (memories.length === 0 || budgetTokens <= 0)
|
|
88
|
+
return [];
|
|
89
|
+
// Annotate with token counts
|
|
90
|
+
const annotated = memories.map((m) => ({
|
|
91
|
+
...m,
|
|
92
|
+
tokenCount: m.tokenCount ?? countTokens(m.content),
|
|
93
|
+
}));
|
|
94
|
+
const result = [];
|
|
95
|
+
let used = 0;
|
|
96
|
+
// Pass 1: entries explicitly marked as never-truncatable (no metadata flag needed —
|
|
97
|
+
// we treat score >= 1 as the signal, or rely on msm-context having sorted them first)
|
|
98
|
+
// Pass 2: remaining by score descending
|
|
99
|
+
for (const entry of annotated) {
|
|
100
|
+
if (used + entry.tokenCount > budgetTokens)
|
|
101
|
+
continue;
|
|
102
|
+
result.push(entry);
|
|
103
|
+
used += entry.tokenCount;
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=context-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-builder.js","sourceRoot":"","sources":["../../src/core/context-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-processing gates — zero-LLM message filters.
|
|
3
|
+
*
|
|
4
|
+
* Gate 1 — Acknowledgement: suppress "ok / thanks / تمام" with no brain call.
|
|
5
|
+
* Gate 2 — Business hours: return canned closed message outside working hours.
|
|
6
|
+
*
|
|
7
|
+
* Both gates are optional. Configure via AgentConfig.gates.
|
|
8
|
+
*/
|
|
9
|
+
import type { GateConfig, LoopOutcome } from "./types.js";
|
|
10
|
+
export declare function isAcknowledgement(text: string): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Run pre-processing gates. Returns a suppressed LoopOutcome if a gate fires,
|
|
13
|
+
* or null if the message should proceed to the brain loop.
|
|
14
|
+
*/
|
|
15
|
+
export declare function runGates(sessionId: string, taskId: string, message: string, gates?: GateConfig): LoopOutcome | null;
|
|
16
|
+
//# sourceMappingURL=gates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gates.d.ts","sourceRoot":"","sources":["../../src/core/gates.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAe1D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIvD;AA6BD;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,UAAU,GACjB,WAAW,GAAG,IAAI,CA2BpB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-processing gates — zero-LLM message filters.
|
|
3
|
+
*
|
|
4
|
+
* Gate 1 — Acknowledgement: suppress "ok / thanks / تمام" with no brain call.
|
|
5
|
+
* Gate 2 — Business hours: return canned closed message outside working hours.
|
|
6
|
+
*
|
|
7
|
+
* Both gates are optional. Configure via AgentConfig.gates.
|
|
8
|
+
*/
|
|
9
|
+
// ─── Acknowledgement Gate ─────────────────────────────────────
|
|
10
|
+
const ACK_PATTERNS = [
|
|
11
|
+
/^\s*(ok|okay|o+k+|alright|got it|got that|understood|noted|i see|ic)\s*[.!]?\s*$/i,
|
|
12
|
+
/^\s*(thanks|thank you|thx|ty|thank u|many thanks|cheers)\s*[.!]?\s*$/i,
|
|
13
|
+
/^\s*(sure|yep|yup|yes|yeah|no worries|no problem|np)\s*[.!]?\s*$/i,
|
|
14
|
+
/^\s*(great|perfect|awesome|nice|cool|sounds good|sounds great)\s*[.!]?\s*$/i,
|
|
15
|
+
/^\s*(تمام|اوكي|أوكي|حسنا|حسناً|مفهوم|موافق|شكرا|شكراً|ممتاز|رائع)\s*[.!]?\s*$/u,
|
|
16
|
+
/^\s*(👍|👌|🙏|✅|💯|🫡)\s*$/u,
|
|
17
|
+
];
|
|
18
|
+
const ACK_MAX_LENGTH = 60;
|
|
19
|
+
export function isAcknowledgement(text) {
|
|
20
|
+
const trimmed = text.trim();
|
|
21
|
+
if (!trimmed || trimmed.length > ACK_MAX_LENGTH)
|
|
22
|
+
return false;
|
|
23
|
+
return ACK_PATTERNS.some((re) => re.test(trimmed));
|
|
24
|
+
}
|
|
25
|
+
const DAY_INDEX = {
|
|
26
|
+
sun: 0, mon: 1, tue: 2, wed: 3, thu: 4, fri: 5, sat: 6,
|
|
27
|
+
};
|
|
28
|
+
function isWithinBusinessHours(config) {
|
|
29
|
+
const now = new Date(new Date().toLocaleString("en-US", { timeZone: config.timezone }));
|
|
30
|
+
const dayCode = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"][now.getDay()];
|
|
31
|
+
if (!config.days.includes(dayCode))
|
|
32
|
+
return false;
|
|
33
|
+
const [fromH = 9, fromM = 0] = config.from.split(":").map(Number);
|
|
34
|
+
const [toH = 17, toM = 0] = config.to.split(":").map(Number);
|
|
35
|
+
const currentMinutes = now.getHours() * 60 + now.getMinutes();
|
|
36
|
+
const fromMinutes = (fromH) * 60 + (fromM);
|
|
37
|
+
const toMinutes = (toH) * 60 + (toM);
|
|
38
|
+
return currentMinutes >= fromMinutes && currentMinutes < toMinutes;
|
|
39
|
+
}
|
|
40
|
+
// ─── Gate Runner ──────────────────────────────────────────────
|
|
41
|
+
/**
|
|
42
|
+
* Run pre-processing gates. Returns a suppressed LoopOutcome if a gate fires,
|
|
43
|
+
* or null if the message should proceed to the brain loop.
|
|
44
|
+
*/
|
|
45
|
+
export function runGates(sessionId, taskId, message, gates) {
|
|
46
|
+
const started = Date.now();
|
|
47
|
+
// Gate 1 — Acknowledgement
|
|
48
|
+
if (gates?.acknowledgement !== false && isAcknowledgement(message)) {
|
|
49
|
+
return {
|
|
50
|
+
type: "suppressed",
|
|
51
|
+
sessionId,
|
|
52
|
+
taskId,
|
|
53
|
+
metrics: { iterations: 0, totalCostUsd: 0, durationMs: Date.now() - started, totalToolCalls: 0 },
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// Gate 2 — Business hours
|
|
57
|
+
if (gates?.businessHours) {
|
|
58
|
+
if (!isWithinBusinessHours(gates.businessHours)) {
|
|
59
|
+
return {
|
|
60
|
+
type: "response",
|
|
61
|
+
sessionId,
|
|
62
|
+
taskId,
|
|
63
|
+
text: gates.businessHours.closedMessage ?? "We are currently closed. Please contact us during business hours.",
|
|
64
|
+
metrics: { iterations: 0, totalCostUsd: 0, durationMs: Date.now() - started, totalToolCalls: 0 },
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=gates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gates.js","sourceRoot":"","sources":["../../src/core/gates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guards — Hard and soft safety checks for the execution loop.
|
|
3
|
+
*
|
|
4
|
+
* Hard guards abort execution and force a response.
|
|
5
|
+
* Soft guards are removed from msm-mini (repetition / dead-end).
|
|
6
|
+
* New guard: consecutive tool failures (hard abort after N failures).
|
|
7
|
+
*/
|
|
8
|
+
import type { GuardConfig, GuardSignal, RunState } from "./types.js";
|
|
9
|
+
export declare const DEFAULT_GUARDS: Required<GuardConfig>;
|
|
10
|
+
/**
|
|
11
|
+
* Check all guards against the current run state.
|
|
12
|
+
* Returns an array of fired signals (may be empty).
|
|
13
|
+
* Hard guards: iteration, cost, timeout, kill, consecutive failures.
|
|
14
|
+
*/
|
|
15
|
+
export declare function checkGuards(state: RunState, config: Required<GuardConfig>, action: string, confidence: number, controlCommand: string | null): GuardSignal[];
|
|
16
|
+
/** True if any signal in the list is a hard blocker */
|
|
17
|
+
export declare function hasHardBlock(signals: GuardSignal[]): boolean;
|
|
18
|
+
/** Returns the first hard signal's action, or undefined */
|
|
19
|
+
export declare function hardAction(signals: GuardSignal[]): GuardSignal["action"] | undefined;
|
|
20
|
+
/** Merge user guard config with defaults */
|
|
21
|
+
export declare function resolveGuards(config?: GuardConfig): Required<GuardConfig>;
|
|
22
|
+
//# sourceMappingURL=guards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../src/core/guards.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAErE,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,WAAW,CAOhD,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,QAAQ,EACf,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,EAC7B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,GAAG,IAAI,GAC5B,WAAW,EAAE,CAyFf;AAED,uDAAuD;AACvD,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,OAAO,CAE5D;AAED,2DAA2D;AAC3D,wBAAgB,UAAU,CACxB,OAAO,EAAE,WAAW,EAAE,GACrB,WAAW,CAAC,QAAQ,CAAC,GAAG,SAAS,CAEnC;AAED,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC,CASzE"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guards — Hard and soft safety checks for the execution loop.
|
|
3
|
+
*
|
|
4
|
+
* Hard guards abort execution and force a response.
|
|
5
|
+
* Soft guards are removed from msm-mini (repetition / dead-end).
|
|
6
|
+
* New guard: consecutive tool failures (hard abort after N failures).
|
|
7
|
+
*/
|
|
8
|
+
export const DEFAULT_GUARDS = {
|
|
9
|
+
maxIterations: 60,
|
|
10
|
+
costCapPerTask: 2.5,
|
|
11
|
+
timeoutMs: 900_000, // 15 min
|
|
12
|
+
confidenceThreshold: 0.75,
|
|
13
|
+
maxToolCallsPerTask: 200,
|
|
14
|
+
maxConsecutiveFailures: 3,
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Check all guards against the current run state.
|
|
18
|
+
* Returns an array of fired signals (may be empty).
|
|
19
|
+
* Hard guards: iteration, cost, timeout, kill, consecutive failures.
|
|
20
|
+
*/
|
|
21
|
+
export function checkGuards(state, config, action, confidence, controlCommand) {
|
|
22
|
+
const signals = [];
|
|
23
|
+
// ─── Hard: task killed via control bus ───────────────────
|
|
24
|
+
if (controlCommand === "kill") {
|
|
25
|
+
signals.push({
|
|
26
|
+
type: "task_killed",
|
|
27
|
+
hard: true,
|
|
28
|
+
message: "Task killed via control bus",
|
|
29
|
+
action: "abort",
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (controlCommand === "pause") {
|
|
33
|
+
signals.push({
|
|
34
|
+
type: "tenant_paused",
|
|
35
|
+
hard: true,
|
|
36
|
+
message: "Tenant paused via control bus",
|
|
37
|
+
action: "abort",
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
// ─── Hard: iteration budget ───────────────────────────────
|
|
41
|
+
if (state.iteration >= config.maxIterations) {
|
|
42
|
+
signals.push({
|
|
43
|
+
type: "budget_iterations",
|
|
44
|
+
hard: true,
|
|
45
|
+
message: `Iteration limit reached (${state.iteration}/${config.maxIterations})`,
|
|
46
|
+
action: "force_respond",
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
// ─── Hard: cost cap ───────────────────────────────────────
|
|
50
|
+
if (config.costCapPerTask > 0 && state.totalCostUsd >= config.costCapPerTask) {
|
|
51
|
+
signals.push({
|
|
52
|
+
type: "budget_cost",
|
|
53
|
+
hard: true,
|
|
54
|
+
message: `Cost cap reached ($${state.totalCostUsd.toFixed(4)}/$${config.costCapPerTask})`,
|
|
55
|
+
action: "force_respond",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
// ─── Hard: timeout ────────────────────────────────────────
|
|
59
|
+
if (config.timeoutMs > 0) {
|
|
60
|
+
const elapsed = Date.now() - state.startedAt;
|
|
61
|
+
if (elapsed >= config.timeoutMs) {
|
|
62
|
+
signals.push({
|
|
63
|
+
type: "budget_timeout",
|
|
64
|
+
hard: true,
|
|
65
|
+
message: `Timeout exceeded (${elapsed}ms/${config.timeoutMs}ms)`,
|
|
66
|
+
action: "force_respond",
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// ─── Hard: total tool call budget ────────────────────────
|
|
71
|
+
if (config.maxToolCallsPerTask > 0 && state.totalToolCalls >= config.maxToolCallsPerTask) {
|
|
72
|
+
signals.push({
|
|
73
|
+
type: "budget_tool_calls",
|
|
74
|
+
hard: true,
|
|
75
|
+
message: `Tool call budget exhausted (${state.totalToolCalls}/${config.maxToolCallsPerTask})`,
|
|
76
|
+
action: "force_respond",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
// ─── Hard: consecutive tool failures ─────────────────────
|
|
80
|
+
if (config.maxConsecutiveFailures > 0 &&
|
|
81
|
+
state.consecutiveToolFailures >= config.maxConsecutiveFailures) {
|
|
82
|
+
signals.push({
|
|
83
|
+
type: "consecutive_failures",
|
|
84
|
+
hard: true,
|
|
85
|
+
message: `${state.consecutiveToolFailures} consecutive tool failures — aborting`,
|
|
86
|
+
action: "escalate",
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
// ─── Soft: confidence gate ────────────────────────────────
|
|
90
|
+
if (action === "use_tool" && confidence < config.confidenceThreshold) {
|
|
91
|
+
signals.push({
|
|
92
|
+
type: "confidence_low",
|
|
93
|
+
hard: false,
|
|
94
|
+
message: `Confidence ${confidence} below threshold ${config.confidenceThreshold}`,
|
|
95
|
+
action: "clarify",
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return signals;
|
|
99
|
+
}
|
|
100
|
+
/** True if any signal in the list is a hard blocker */
|
|
101
|
+
export function hasHardBlock(signals) {
|
|
102
|
+
return signals.some((s) => s.hard);
|
|
103
|
+
}
|
|
104
|
+
/** Returns the first hard signal's action, or undefined */
|
|
105
|
+
export function hardAction(signals) {
|
|
106
|
+
return signals.find((s) => s.hard)?.action;
|
|
107
|
+
}
|
|
108
|
+
/** Merge user guard config with defaults */
|
|
109
|
+
export function resolveGuards(config) {
|
|
110
|
+
return {
|
|
111
|
+
maxIterations: config?.maxIterations ?? DEFAULT_GUARDS.maxIterations,
|
|
112
|
+
costCapPerTask: config?.costCapPerTask ?? DEFAULT_GUARDS.costCapPerTask,
|
|
113
|
+
timeoutMs: config?.timeoutMs ?? DEFAULT_GUARDS.timeoutMs,
|
|
114
|
+
confidenceThreshold: config?.confidenceThreshold ?? DEFAULT_GUARDS.confidenceThreshold,
|
|
115
|
+
maxToolCallsPerTask: config?.maxToolCallsPerTask ?? DEFAULT_GUARDS.maxToolCallsPerTask,
|
|
116
|
+
maxConsecutiveFailures: config?.maxConsecutiveFailures ?? DEFAULT_GUARDS.maxConsecutiveFailures,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=guards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.js","sourceRoot":"","sources":["../../src/core/guards.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hooks — Observability callbacks for the execution loop.
|
|
3
|
+
*
|
|
4
|
+
* Wire to SSE channels, loggers, or dashboards.
|
|
5
|
+
* All hooks are optional and fire-and-forget (errors do not affect the loop).
|
|
6
|
+
*/
|
|
7
|
+
import type { AgentHooks, GuardSignal, ToolResult, RunState } from "./types.js";
|
|
8
|
+
export declare function fireIteration(hooks: AgentHooks | undefined, state: RunState, maxIterations: number, currentSection?: string): void;
|
|
9
|
+
export declare function fireSectionComplete(hooks: AgentHooks | undefined, sessionId: string, sectionName: string, sectionIndex: number, totalSections: number): void;
|
|
10
|
+
export declare function fireToolCall(hooks: AgentHooks | undefined, sessionId: string, result: ToolResult, iteration: number, cached: boolean, durationMs: number): void;
|
|
11
|
+
export declare function fireGuard(hooks: AgentHooks | undefined, sessionId: string, signal: GuardSignal, iteration: number): void;
|
|
12
|
+
export declare function fireFatalError(hooks: AgentHooks | undefined, error: Error, sessionId: string): void;
|
|
13
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/core/hooks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAWhF,wBAAgB,aAAa,CAC3B,KAAK,EAAE,UAAU,GAAG,SAAS,EAC7B,KAAK,EAAE,QAAQ,EACf,aAAa,EAAE,MAAM,EACrB,cAAc,CAAC,EAAE,MAAM,GACtB,IAAI,CAYN;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,UAAU,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,GACpB,IAAI,CAWN;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,UAAU,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,MAAM,GACjB,IAAI,CAYN;AAED,wBAAgB,SAAS,CACvB,KAAK,EAAE,UAAU,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,GAChB,IAAI,CAGN;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,UAAU,GAAG,SAAS,EAC7B,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,MAAM,GAChB,IAAI,CAGN"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hooks — Observability callbacks for the execution loop.
|
|
3
|
+
*
|
|
4
|
+
* Wire to SSE channels, loggers, or dashboards.
|
|
5
|
+
* All hooks are optional and fire-and-forget (errors do not affect the loop).
|
|
6
|
+
*/
|
|
7
|
+
/** Safely call a hook — never throw into the loop */
|
|
8
|
+
function safely(fn) {
|
|
9
|
+
try {
|
|
10
|
+
fn();
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
// hook errors must not affect the agent loop
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function fireIteration(hooks, state, maxIterations, currentSection) {
|
|
17
|
+
if (!hooks?.onIteration)
|
|
18
|
+
return;
|
|
19
|
+
safely(() => hooks.onIteration({
|
|
20
|
+
sessionId: state.sessionId,
|
|
21
|
+
iteration: state.iteration,
|
|
22
|
+
maxIterations,
|
|
23
|
+
...(currentSection !== undefined ? { currentSection } : {}),
|
|
24
|
+
totalCostUsd: state.totalCostUsd,
|
|
25
|
+
elapsedMs: Date.now() - state.startedAt,
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
export function fireSectionComplete(hooks, sessionId, sectionName, sectionIndex, totalSections) {
|
|
29
|
+
if (!hooks?.onSectionComplete)
|
|
30
|
+
return;
|
|
31
|
+
safely(() => hooks.onSectionComplete({
|
|
32
|
+
sessionId,
|
|
33
|
+
sectionName,
|
|
34
|
+
sectionIndex,
|
|
35
|
+
totalSections,
|
|
36
|
+
completedAt: Date.now(),
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
export function fireToolCall(hooks, sessionId, result, iteration, cached, durationMs) {
|
|
40
|
+
if (!hooks?.onToolCall)
|
|
41
|
+
return;
|
|
42
|
+
safely(() => hooks.onToolCall({
|
|
43
|
+
sessionId,
|
|
44
|
+
toolName: result.tool,
|
|
45
|
+
iteration,
|
|
46
|
+
cached,
|
|
47
|
+
durationMs,
|
|
48
|
+
status: result.status,
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
export function fireGuard(hooks, sessionId, signal, iteration) {
|
|
52
|
+
if (!hooks?.onGuard)
|
|
53
|
+
return;
|
|
54
|
+
safely(() => hooks.onGuard({ sessionId, signal, iteration }));
|
|
55
|
+
}
|
|
56
|
+
export function fireFatalError(hooks, error, sessionId) {
|
|
57
|
+
if (!hooks?.onFatalError)
|
|
58
|
+
return;
|
|
59
|
+
safely(() => hooks.onFatalError(error, sessionId));
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/core/hooks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,qDAAqD;AACrD,SAAS,MAAM,CAAC,EAAc;IAC5B,IAAI,CAAC;QACH,EAAE,EAAE,CAAC;IACP,CAAC;IAAC,MAAM,CAAC;QACP,6CAA6C;IAC/C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,KAA6B,EAC7B,KAAe,EACf,aAAqB,EACrB,cAAuB;IAEvB,IAAI,CAAC,KAAK,EAAE,WAAW;QAAE,OAAO;IAChC,MAAM,CAAC,GAAG,EAAE,CACV,KAAK,CAAC,WAAY,CAAC;QACjB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,aAAa;QACb,GAAG,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS;KACxC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,KAA6B,EAC7B,SAAiB,EACjB,WAAmB,EACnB,YAAoB,EACpB,aAAqB;IAErB,IAAI,CAAC,KAAK,EAAE,iBAAiB;QAAE,OAAO;IACtC,MAAM,CAAC,GAAG,EAAE,CACV,KAAK,CAAC,iBAAkB,CAAC;QACvB,SAAS;QACT,WAAW;QACX,YAAY;QACZ,aAAa;QACb,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;KACxB,CAAC,CACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,KAA6B,EAC7B,SAAiB,EACjB,MAAkB,EAClB,SAAiB,EACjB,MAAe,EACf,UAAkB;IAElB,IAAI,CAAC,KAAK,EAAE,UAAU;QAAE,OAAO;IAC/B,MAAM,CAAC,GAAG,EAAE,CACV,KAAK,CAAC,UAAW,CAAC;QAChB,SAAS;QACT,QAAQ,EAAE,MAAM,CAAC,IAAI;QACrB,SAAS;QACT,MAAM;QACN,UAAU;QACV,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,CACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,KAA6B,EAC7B,SAAiB,EACjB,MAAmB,EACnB,SAAiB;IAEjB,IAAI,CAAC,KAAK,EAAE,OAAO;QAAE,OAAO;IAC5B,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,OAAQ,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,KAA6B,EAC7B,KAAY,EACZ,SAAiB;IAEjB,IAAI,CAAC,KAAK,EAAE,YAAY;QAAE,OAAO;IACjC,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,YAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution Loop — The core of msm-mini.
|
|
3
|
+
*
|
|
4
|
+
* event → gates → lock → control bus → context build → brain call →
|
|
5
|
+
* guards → dispatch:
|
|
6
|
+
* use_tool → validate/dedup/execute → record → loop
|
|
7
|
+
* respond/clarify/escalate → deliver → done
|
|
8
|
+
* budget exhausted → force_respond → done
|
|
9
|
+
*/
|
|
10
|
+
import type { AgentConfig } from "./types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Create a stateful agent from config.
|
|
13
|
+
* Returns an Agent object — call .handle() on every incoming event.
|
|
14
|
+
*/
|
|
15
|
+
export declare function createAgent(config: AgentConfig): import("./types.js").Agent;
|
|
16
|
+
//# sourceMappingURL=loop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/core/loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EACV,WAAW,EAQZ,MAAM,YAAY,CAAC;AA2BpB;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,YAAY,EAAE,KAAK,CAoS3E"}
|