@msm-core/mini 0.3.2 → 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.
- package/CHANGELOG.md +49 -0
- package/dist/adapters/redis-memory.d.ts +3 -0
- package/dist/adapters/redis-memory.d.ts.map +1 -1
- package/dist/adapters/redis-memory.js +6 -0
- package/dist/adapters/redis-memory.js.map +1 -1
- package/dist/adapters/redis-types.d.ts +2 -0
- package/dist/adapters/redis-types.d.ts.map +1 -1
- package/dist/brain/anthropic.d.ts.map +1 -1
- package/dist/brain/anthropic.js +3 -2
- package/dist/brain/anthropic.js.map +1 -1
- package/dist/brain/gemini.d.ts.map +1 -1
- package/dist/brain/gemini.js +2 -1
- package/dist/brain/gemini.js.map +1 -1
- package/dist/brain/ollama.d.ts.map +1 -1
- package/dist/brain/ollama.js +3 -2
- package/dist/brain/ollama.js.map +1 -1
- package/dist/brain/openai.d.ts.map +1 -1
- package/dist/brain/openai.js +2 -1
- package/dist/brain/openai.js.map +1 -1
- package/dist/brain/retry.d.ts +21 -0
- package/dist/brain/retry.d.ts.map +1 -0
- package/dist/brain/retry.js +63 -0
- package/dist/brain/retry.js.map +1 -0
- package/dist/core/loop.d.ts.map +1 -1
- package/dist/core/loop.js +98 -36
- package/dist/core/loop.js.map +1 -1
- package/dist/core/types.d.ts +8 -4
- package/dist/core/types.d.ts.map +1 -1
- package/dist/definition/parser.d.ts.map +1 -1
- package/dist/definition/parser.js +5 -2
- package/dist/definition/parser.js.map +1 -1
- package/dist/server.d.ts +24 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +90 -25
- package/dist/server.js.map +1 -1
- package/dist/tools/dedup.d.ts +7 -2
- package/dist/tools/dedup.d.ts.map +1 -1
- package/dist/tools/dedup.js +9 -9
- package/dist/tools/dedup.js.map +1 -1
- package/dist/tools/executor.d.ts +4 -2
- package/dist/tools/executor.d.ts.map +1 -1
- package/dist/tools/executor.js +47 -13
- package/dist/tools/executor.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,55 @@ Follows [Semantic Versioning](https://semver.org/).
|
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
## [0.4.0] — 2026-06-10
|
|
9
|
+
|
|
10
|
+
Production-hardening release — the sdk is now the default in-house agent runtime.
|
|
11
|
+
|
|
12
|
+
### Security / correctness
|
|
13
|
+
|
|
14
|
+
- **Output gate now covers EVERY exit path.** Guard-terminated responses
|
|
15
|
+
(force-finalize, force_respond, escalate) previously bypassed the validator —
|
|
16
|
+
exactly where a model under budget pressure is most likely to leak something
|
|
17
|
+
the gate should catch. All terminal text now passes `applyOutputGate`.
|
|
18
|
+
- **`requiresApproval` is enforced.** Tools marked requiresApproval are blocked
|
|
19
|
+
unless an onBeforeTool hook approves; a throwing approval hook FAILS CLOSED.
|
|
20
|
+
(Previously the flag was decorative.)
|
|
21
|
+
- **onBeforeTool runs BEFORE the dedup check** — cached results can no longer
|
|
22
|
+
bypass an approval/audit gate.
|
|
23
|
+
- **Server: `guardsOverride` is whitelisted + type-checked** (exported as
|
|
24
|
+
`sanitizeGuardsOverride`). Malformed values previously disabled guards
|
|
25
|
+
silently (`5 >= "x"` is false → iteration/cost/timeout caps off).
|
|
26
|
+
- **Server: request bodies are size-capped** (256 KB default, configurable via
|
|
27
|
+
`maxBodyBytes`) — was unbounded.
|
|
28
|
+
- **Distributed-lock TTL now uses the effective (per-request) timeout** — an
|
|
29
|
+
override raising timeoutMs could previously outlive the lock and allow a
|
|
30
|
+
concurrent run on the same session.
|
|
31
|
+
- **Dedup hash upgraded FNV-1a-32 → SHA-256** (node:crypto, no new deps) — a
|
|
32
|
+
32-bit collision silently returned the wrong cached tool result.
|
|
33
|
+
|
|
34
|
+
### Reliability
|
|
35
|
+
|
|
36
|
+
- **Transient-error retry in all four brains** (`withRetry`): one bounded,
|
|
37
|
+
abort-aware retry on 429/5xx/network errors — a single provider flake no
|
|
38
|
+
longer kills the whole run.
|
|
39
|
+
- **Guard exits record both turn sides** — the user message was previously
|
|
40
|
+
dropped from history, leaving orphaned assistant turns.
|
|
41
|
+
- **`SessionMetadata` is now written** after every run (status / iterations /
|
|
42
|
+
cost) — was dead code; gives ops a per-session status surface.
|
|
43
|
+
- History storage capped via LTRIM (default 500 entries, configurable) when the
|
|
44
|
+
Redis client supports it.
|
|
45
|
+
|
|
46
|
+
### Changed
|
|
47
|
+
|
|
48
|
+
- Server CORS: preflight is now answered only when `corsOrigin` is configured
|
|
49
|
+
(default: no CORS headers — server-to-server). Previously preflight
|
|
50
|
+
advertised `*` while actual responses sent no CORS headers at all.
|
|
51
|
+
- `server.start()` rejects on listen errors (EADDRINUSE) instead of crashing.
|
|
52
|
+
- `parseDefinition` treats multiline input as markdown (no more confusing
|
|
53
|
+
ENOENT for definitions whose first line is metadata).
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
8
57
|
## [0.3.2] — 2026-06-11
|
|
9
58
|
|
|
10
59
|
### Added
|
|
@@ -22,10 +22,13 @@ export declare class RedisMemory {
|
|
|
22
22
|
private readonly prefix;
|
|
23
23
|
private readonly historyTtl;
|
|
24
24
|
private readonly documentTtl;
|
|
25
|
+
private readonly maxHistoryEntries;
|
|
25
26
|
constructor(redis: RedisLike, opts?: {
|
|
26
27
|
prefix?: string;
|
|
27
28
|
historyTtl?: number;
|
|
28
29
|
documentTtl?: number;
|
|
30
|
+
/** Hard cap on stored history entries per session (default: 500). */
|
|
31
|
+
maxHistoryEntries?: number;
|
|
29
32
|
});
|
|
30
33
|
private historyKey;
|
|
31
34
|
private metaKey;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-memory.d.ts","sourceRoot":"","sources":["../../src/adapters/redis-memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;CACvD;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;
|
|
1
|
+
{"version":3,"file":"redis-memory.d.ts","sourceRoot":"","sources":["../../src/adapters/redis-memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;CACvD;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;gBAGzC,KAAK,EAAE,SAAS,EAChB,IAAI,GAAE;QACJ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,qEAAqE;QACrE,iBAAiB,CAAC,EAAE,MAAM,CAAC;KACvB;IASR,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,WAAW;IAMb,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAU/D,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAc7D,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAU/D,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpE,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAUlE,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,IAAI,CAAC;CAOjB;AAED,uDAAuD;AACvD,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAMlE"}
|
|
@@ -14,11 +14,13 @@ export class RedisMemory {
|
|
|
14
14
|
prefix;
|
|
15
15
|
historyTtl;
|
|
16
16
|
documentTtl;
|
|
17
|
+
maxHistoryEntries;
|
|
17
18
|
constructor(redis, opts = {}) {
|
|
18
19
|
this.redis = redis;
|
|
19
20
|
this.prefix = opts.prefix ?? "msm";
|
|
20
21
|
this.historyTtl = opts.historyTtl ?? 86_400;
|
|
21
22
|
this.documentTtl = opts.documentTtl ?? 14_400;
|
|
23
|
+
this.maxHistoryEntries = opts.maxHistoryEntries ?? 500;
|
|
22
24
|
}
|
|
23
25
|
historyKey(sessionId) {
|
|
24
26
|
return `${this.prefix}:session:${sessionId}:history`;
|
|
@@ -33,6 +35,10 @@ export class RedisMemory {
|
|
|
33
35
|
async appendHistory(sessionId, entry) {
|
|
34
36
|
const key = this.historyKey(sessionId);
|
|
35
37
|
await this.redis.rpush(key, JSON.stringify(entry));
|
|
38
|
+
// Cap storage growth for chatty sessions (lrange caps reads, not writes).
|
|
39
|
+
if (this.redis.ltrim) {
|
|
40
|
+
await this.redis.ltrim(key, -this.maxHistoryEntries, -1);
|
|
41
|
+
}
|
|
36
42
|
await this.redis.expire(key, this.historyTtl);
|
|
37
43
|
}
|
|
38
44
|
async getHistory(sessionId, limit = 50) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-memory.js","sourceRoot":"","sources":["../../src/adapters/redis-memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAYH,MAAM,OAAO,WAAW;IACL,KAAK,CAAY;IACjB,MAAM,CAAS;IACf,UAAU,CAAS;IACnB,WAAW,CAAS;
|
|
1
|
+
{"version":3,"file":"redis-memory.js","sourceRoot":"","sources":["../../src/adapters/redis-memory.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,8 @@ export interface RedisLike {
|
|
|
9
9
|
del(key: string | string[]): Promise<unknown>;
|
|
10
10
|
rpush(key: string, ...values: string[]): Promise<unknown>;
|
|
11
11
|
lrange(key: string, start: number, stop: number): Promise<string[]>;
|
|
12
|
+
/** Optional — used to cap history length; safely skipped when absent. */
|
|
13
|
+
ltrim?(key: string, start: number, stop: number): Promise<unknown>;
|
|
12
14
|
expire(key: string, seconds: number): Promise<unknown>;
|
|
13
15
|
hget(key: string, field: string): Promise<string | null>;
|
|
14
16
|
hset(key: string, field: string, value: string): Promise<unknown>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-types.d.ts","sourceRoot":"","sources":["../../src/adapters/redis-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEzC,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAClC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1D,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACpE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,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;IAElE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACzE"}
|
|
1
|
+
{"version":3,"file":"redis-types.d.ts","sourceRoot":"","sources":["../../src/adapters/redis-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEzC,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAClC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1D,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACpE,yEAAyE;IACzE,KAAK,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,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;IAElE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACzE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/brain/anthropic.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,KAAK,EAIN,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/brain/anthropic.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,KAAK,EAIN,MAAM,YAAY,CAAC;AAKpB,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,KAAK,CA4FR"}
|
package/dist/brain/anthropic.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Peer dependency: @anthropic-ai/sdk >= 0.20.0
|
|
4
4
|
*/
|
|
5
5
|
import { computeCostUsd } from "./pricing.js";
|
|
6
|
+
import { withRetry } from "./retry.js";
|
|
6
7
|
export function createAnthropicBrain(opts) {
|
|
7
8
|
// claude-3-5-sonnet-20241022 was retired (2025-10-28); claude-sonnet-4-6 is
|
|
8
9
|
// its current drop-in replacement.
|
|
@@ -42,12 +43,12 @@ export function createAnthropicBrain(opts) {
|
|
|
42
43
|
system: input.system_context,
|
|
43
44
|
messages: messages,
|
|
44
45
|
};
|
|
45
|
-
const response = await client.messages.create(tools
|
|
46
|
+
const response = await withRetry(() => client.messages.create(tools
|
|
46
47
|
? {
|
|
47
48
|
...baseParams,
|
|
48
49
|
tools: tools,
|
|
49
50
|
}
|
|
50
|
-
: baseParams, input.signal ? { signal: input.signal } : {});
|
|
51
|
+
: baseParams, input.signal ? { signal: input.signal } : {}), input.signal ? { signal: input.signal } : {});
|
|
51
52
|
const content = response.content;
|
|
52
53
|
const inputTokens = response.usage.input_tokens;
|
|
53
54
|
const outputTokens = response.usage.output_tokens;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/brain/anthropic.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/brain/anthropic.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/brain/gemini.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,KAAK,EAIN,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/brain/gemini.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,KAAK,EAIN,MAAM,YAAY,CAAC;AAKpB,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,KAAK,CAsHR"}
|
package/dist/brain/gemini.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Gemini Brain — Google Gemini 2.5 Flash (primary brain for UTS).
|
|
3
3
|
* Peer dependency: @google/generative-ai >= 0.14.0
|
|
4
4
|
*/
|
|
5
|
+
import { withRetry } from "./retry.js";
|
|
5
6
|
import { GoogleGenerativeAI } from "@google/generative-ai";
|
|
6
7
|
export function createGeminiBrain(opts) {
|
|
7
8
|
const model = opts.model ?? "gemini-2.5-flash";
|
|
@@ -49,7 +50,7 @@ export function createGeminiBrain(opts) {
|
|
|
49
50
|
tools: tools,
|
|
50
51
|
}
|
|
51
52
|
: { systemInstruction: input.system_context, contents };
|
|
52
|
-
const result = await geminiModel.generateContent(request, input.signal ? { signal: input.signal } : {});
|
|
53
|
+
const result = await withRetry(() => geminiModel.generateContent(request, input.signal ? { signal: input.signal } : {}), input.signal ? { signal: input.signal } : {});
|
|
53
54
|
const response = result.response;
|
|
54
55
|
const parts = response?.candidates?.[0]?.content?.parts ?? [];
|
|
55
56
|
// Check for function call
|
package/dist/brain/gemini.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/brain/gemini.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAG3D,MAAM,UAAU,iBAAiB,CAAC,IAGjC;IACC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,kBAAkB,CAAC;IAE/C,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,KAAK,CAAC,GAAG,CAAC,KAAoB;YAC5B,MAAM,MAAM,GACV,IAAI,CAAC,MAAM;gBACX,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;gBAC7B,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YAChC,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;YAEjE,MAAM,KAAK,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,WAAW,GAAG,KAAK,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAExD,uDAAuD;YACvD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAE5C,8BAA8B;YAC9B,MAAM,KAAK,GACT,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;gBACpB,CAAC,CAAC;oBACE;wBACE,oBAAoB,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BAC5C,IAAI,EAAE,CAAC,CAAC,IAAI;4BACZ,WAAW,EAAE,CAAC,CAAC,WAAW;4BAC1B,UAAU,EAAE;gCACV,IAAI,EAAE,QAAiB;gCACvB,UAAU,EAAE,MAAM,CAAC,WAAW,CAC5B,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;oCAC3C,CAAC;oCACD;wCACE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE;wCAC1B,WAAW,EAAE,CAAC,CAAC,WAAW;wCAC1B,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qCACpC;iCACF,CAAC,CACH;gCACD,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;qCACnC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;qCAC7B,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;6BACnB;yBACF,CAAC,CAAC;qBACJ;iBACF;gBACH,CAAC,CAAC,SAAS,CAAC;YAEhB,MAAM,OAAO,GAA2B,KAAK;gBAC3C,CAAC,CAAC;oBACE,iBAAiB,EAAE,KAAK,CAAC,cAAc;oBACvC,QAAQ;oBACR,KAAK,EAAE,KAEN;iBACF;gBACH,CAAC,CAAC,EAAE,iBAAiB,EAAE,KAAK,CAAC,cAAc,EAAE,QAAQ,EAAE,CAAC;YAC1D,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/brain/gemini.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../src/brain/ollama.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAmD,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../src/brain/ollama.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAmD,MAAM,YAAY,CAAC;AAGzF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,KAAK,CA8CR"}
|
package/dist/brain/ollama.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Ollama Brain — local model via Ollama REST API.
|
|
3
3
|
* No peer dependencies — plain HTTP fetch.
|
|
4
4
|
*/
|
|
5
|
+
import { withRetry } from "./retry.js";
|
|
5
6
|
export function createOllamaBrain(opts) {
|
|
6
7
|
const endpoint = opts.endpoint ?? process.env["OLLAMA_ENDPOINT"] ?? "http://localhost:11434";
|
|
7
8
|
const model = opts.model ?? "llama3.2";
|
|
@@ -13,12 +14,12 @@ export function createOllamaBrain(opts) {
|
|
|
13
14
|
...input.history.map((m) => ({ role: m.role, content: m.content })),
|
|
14
15
|
{ role: "user", content: input.raw },
|
|
15
16
|
];
|
|
16
|
-
const response = await fetch(`${endpoint}/api/chat`, {
|
|
17
|
+
const response = await withRetry(() => fetch(`${endpoint}/api/chat`, {
|
|
17
18
|
method: "POST",
|
|
18
19
|
headers: { "Content-Type": "application/json" },
|
|
19
20
|
body: JSON.stringify({ model, messages, stream: false }),
|
|
20
21
|
...(input.signal ? { signal: input.signal } : {}),
|
|
21
|
-
});
|
|
22
|
+
}), input.signal ? { signal: input.signal } : {});
|
|
22
23
|
if (!response.ok) {
|
|
23
24
|
throw new Error(`Ollama error: ${response.status} ${response.statusText}`);
|
|
24
25
|
}
|
package/dist/brain/ollama.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../src/brain/ollama.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../src/brain/ollama.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,UAAU,iBAAiB,CAAC,IAGjC;IACC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,wBAAwB,CAAC;IAC7F,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC;IAEvC,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,KAAK,CAAC,GAAG,CAAC,KAAoB;YAC5B,MAAM,QAAQ,GAAG;gBACf,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,cAAc,EAAE;gBACjD,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;gBACnE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE;aACrC,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,SAAS,CAC9B,GAAG,EAAE,CACH,KAAK,CAAC,GAAG,QAAQ,WAAW,EAAE;gBAC5B,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;gBACxD,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAClD,CAAC,EACJ,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAC7C,CAAC;YAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,iBAAiB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;YAC7E,CAAC;YAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAIlC,CAAC;YAEF,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;YACzC,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC;YAC3C,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC;YACrC,OAAO;gBACL,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;gBACnC,aAAa,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAwB;gBAC5E,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS;oBACzD,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;oBAC/H,CAAC,CAAC,EAAE,CAAC;aACR,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/brain/openai.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,KAAK,EAIN,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/brain/openai.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,KAAK,EAIN,MAAM,YAAY,CAAC;AAKpB,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,KAAK,CAkIR"}
|
package/dist/brain/openai.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Peer dependency: openai >= 4.0.0
|
|
4
4
|
*/
|
|
5
5
|
import { computeCostUsd } from "./pricing.js";
|
|
6
|
+
import { withRetry } from "./retry.js";
|
|
6
7
|
export function createOpenAIBrain(opts) {
|
|
7
8
|
const model = opts.model ?? "gpt-4o-mini";
|
|
8
9
|
return {
|
|
@@ -66,7 +67,7 @@ export function createOpenAIBrain(opts) {
|
|
|
66
67
|
tool_choice: "auto",
|
|
67
68
|
}
|
|
68
69
|
: { model, messages: messages };
|
|
69
|
-
const response = await client.chat.completions.create(body, input.signal ? { signal: input.signal } : {});
|
|
70
|
+
const response = await withRetry(() => client.chat.completions.create(body, input.signal ? { signal: input.signal } : {}), input.signal ? { signal: input.signal } : {});
|
|
70
71
|
const choice = response.choices[0];
|
|
71
72
|
if (!choice)
|
|
72
73
|
return {};
|
package/dist/brain/openai.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/brain/openai.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/brain/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transient-error retry for brain provider calls.
|
|
3
|
+
*
|
|
4
|
+
* One flaky 429/5xx/network error from a provider previously killed the whole
|
|
5
|
+
* run with an error outcome. Every built-in brain now wraps its provider call
|
|
6
|
+
* in withRetry(): a single bounded retry on transient failures, abort-aware
|
|
7
|
+
* (never retries a cancelled call — that's the loop's time budget firing).
|
|
8
|
+
*/
|
|
9
|
+
export interface RetryOpts {
|
|
10
|
+
/** Total attempts including the first (default: 2 = one retry). */
|
|
11
|
+
attempts?: number;
|
|
12
|
+
/** Base backoff delay in ms (default: 500, with ±25% jitter). */
|
|
13
|
+
baseDelayMs?: number;
|
|
14
|
+
/** Loop abort signal — aborted calls are never retried. */
|
|
15
|
+
signal?: AbortSignal;
|
|
16
|
+
}
|
|
17
|
+
/** True for errors worth one retry: 429, 5xx, or low-level network failures. */
|
|
18
|
+
export declare function isTransientError(err: unknown): boolean;
|
|
19
|
+
/** Run `fn`, retrying once (by default) on transient provider errors. */
|
|
20
|
+
export declare function withRetry<T>(fn: () => Promise<T>, opts?: RetryOpts): Promise<T>;
|
|
21
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/brain/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,SAAS;IACxB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAYD,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CActD;AAMD,yEAAyE;AACzE,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,IAAI,GAAE,SAAc,GACnB,OAAO,CAAC,CAAC,CAAC,CAoBZ"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transient-error retry for brain provider calls.
|
|
3
|
+
*
|
|
4
|
+
* One flaky 429/5xx/network error from a provider previously killed the whole
|
|
5
|
+
* run with an error outcome. Every built-in brain now wraps its provider call
|
|
6
|
+
* in withRetry(): a single bounded retry on transient failures, abort-aware
|
|
7
|
+
* (never retries a cancelled call — that's the loop's time budget firing).
|
|
8
|
+
*/
|
|
9
|
+
const TRANSIENT_CODES = new Set([
|
|
10
|
+
"ECONNRESET",
|
|
11
|
+
"ECONNREFUSED",
|
|
12
|
+
"ETIMEDOUT",
|
|
13
|
+
"EAI_AGAIN",
|
|
14
|
+
"EPIPE",
|
|
15
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
16
|
+
"UND_ERR_SOCKET",
|
|
17
|
+
]);
|
|
18
|
+
/** True for errors worth one retry: 429, 5xx, or low-level network failures. */
|
|
19
|
+
export function isTransientError(err) {
|
|
20
|
+
if (err === null || typeof err !== "object")
|
|
21
|
+
return false;
|
|
22
|
+
const e = err;
|
|
23
|
+
// Never retry an intentional abort (the loop's time budget fired).
|
|
24
|
+
if (e["name"] === "AbortError")
|
|
25
|
+
return false;
|
|
26
|
+
const status = Number(e["status"] ?? e["statusCode"] ?? NaN);
|
|
27
|
+
if (status === 429 || (status >= 500 && status < 600))
|
|
28
|
+
return true;
|
|
29
|
+
const code = String(e["code"] ?? "");
|
|
30
|
+
if (TRANSIENT_CODES.has(code))
|
|
31
|
+
return true;
|
|
32
|
+
// undici/fetch network failures surface as TypeError("fetch failed") with a cause
|
|
33
|
+
if (e["cause"] && typeof e["cause"] === "object") {
|
|
34
|
+
return isTransientError(e["cause"]);
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
function sleep(ms) {
|
|
39
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
40
|
+
}
|
|
41
|
+
/** Run `fn`, retrying once (by default) on transient provider errors. */
|
|
42
|
+
export async function withRetry(fn, opts = {}) {
|
|
43
|
+
const attempts = Math.max(1, opts.attempts ?? 2);
|
|
44
|
+
const baseDelayMs = opts.baseDelayMs ?? 500;
|
|
45
|
+
let lastErr;
|
|
46
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
47
|
+
try {
|
|
48
|
+
return await fn();
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
lastErr = err;
|
|
52
|
+
const canRetry = attempt < attempts &&
|
|
53
|
+
!opts.signal?.aborted &&
|
|
54
|
+
isTransientError(err);
|
|
55
|
+
if (!canRetry)
|
|
56
|
+
throw err;
|
|
57
|
+
const jitter = baseDelayMs * 0.25 * (Math.random() * 2 - 1);
|
|
58
|
+
await sleep(baseDelayMs * attempt + jitter);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
throw lastErr;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/brain/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,YAAY;IACZ,cAAc;IACd,WAAW;IACX,WAAW;IACX,OAAO;IACP,yBAAyB;IACzB,gBAAgB;CACjB,CAAC,CAAC;AAEH,gFAAgF;AAChF,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC1D,MAAM,CAAC,GAAG,GAA8B,CAAC;IACzC,mEAAmE;IACnE,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,YAAY;QAAE,OAAO,KAAK,CAAC;IAC7C,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,CAAC;IAC7D,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACnE,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,kFAAkF;IAClF,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QACjD,OAAO,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,EAAoB,EACpB,OAAkB,EAAE;IAEpB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;IACjD,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,GAAG,CAAC;IAE5C,IAAI,OAAgB,CAAC;IACrB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC;QACrD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,GAAG,GAAG,CAAC;YACd,MAAM,QAAQ,GACZ,OAAO,GAAG,QAAQ;gBAClB,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO;gBACrB,gBAAgB,CAAC,GAAG,CAAC,CAAC;YACxB,IAAI,CAAC,QAAQ;gBAAE,MAAM,GAAG,CAAC;YACzB,MAAM,MAAM,GAAG,WAAW,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5D,MAAM,KAAK,CAAC,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IACD,MAAM,OAAO,CAAC;AAChB,CAAC"}
|
package/dist/core/loop.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/core/loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EACV,WAAW,EAUZ,MAAM,YAAY,CAAC;AA2BpB;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,YAAY,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/core/loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EACV,WAAW,EAUZ,MAAM,YAAY,CAAC;AA2BpB;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,YAAY,EAAE,KAAK,CA+e3E"}
|
package/dist/core/loop.js
CHANGED
|
@@ -47,15 +47,76 @@ export function createAgent(config) {
|
|
|
47
47
|
}
|
|
48
48
|
return _redis;
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Run the optional output gate on a terminal response. Used by EVERY exit
|
|
52
|
+
* path that delivers model text (normal respond, force-finalize, guard
|
|
53
|
+
* force_respond/escalate) — guard-terminated text is exactly where a model
|
|
54
|
+
* under budget pressure is most likely to emit something the gate should
|
|
55
|
+
* catch. A throwing validator must never drop a valid response: fails safe
|
|
56
|
+
* to "review".
|
|
57
|
+
*/
|
|
58
|
+
async function applyOutputGate(text) {
|
|
59
|
+
if (!config.validator || !text)
|
|
60
|
+
return { finalText: text };
|
|
61
|
+
let validation;
|
|
62
|
+
try {
|
|
63
|
+
validation = await config.validator.validate(text);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
validation = {
|
|
67
|
+
passed: false,
|
|
68
|
+
score: 0,
|
|
69
|
+
violations: ["validator_error"],
|
|
70
|
+
action: "review",
|
|
71
|
+
strategy: "error",
|
|
72
|
+
latency_ms: 0,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const finalText = validation.action === "block"
|
|
76
|
+
? "I'm not able to share that response. Could you rephrase your request?"
|
|
77
|
+
: text;
|
|
78
|
+
return { finalText, validation };
|
|
79
|
+
}
|
|
80
|
+
/** Tenant-scoped Redis prefix: {base}:{companyId}:{agentType} when present. */
|
|
81
|
+
function tenantPrefixFor(event) {
|
|
82
|
+
return event.tenantContext
|
|
83
|
+
? `${prefix}:${event.tenantContext.companyId}:${event.tenantContext.agentType}`
|
|
84
|
+
: prefix;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Public entry point — runs the loop, then persists final run metadata
|
|
88
|
+
* (status / iterations / cost) for ops dashboards. Metadata is best-effort:
|
|
89
|
+
* it never blocks or fails the response.
|
|
90
|
+
*/
|
|
50
91
|
async function handle(event) {
|
|
92
|
+
const outcome = await handleCore(event);
|
|
93
|
+
try {
|
|
94
|
+
const redis = await getRedis();
|
|
95
|
+
const memory = new RedisMemory(redis, {
|
|
96
|
+
prefix: tenantPrefixFor(event),
|
|
97
|
+
...(ttl.history !== undefined ? { historyTtl: ttl.history } : {}),
|
|
98
|
+
});
|
|
99
|
+
await memory.setMetadata(event.sessionId, {
|
|
100
|
+
iterationCount: outcome.metrics.iterations,
|
|
101
|
+
startedAt: Date.now() - outcome.metrics.durationMs,
|
|
102
|
+
totalCostUsd: outcome.metrics.totalCostUsd,
|
|
103
|
+
status: outcome.type === "error"
|
|
104
|
+
? outcome.terminatedBy === "task_killed"
|
|
105
|
+
? "killed"
|
|
106
|
+
: "failed"
|
|
107
|
+
: "completed",
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// best-effort — a metadata write failure must not affect the response
|
|
112
|
+
}
|
|
113
|
+
return outcome;
|
|
114
|
+
}
|
|
115
|
+
async function handleCore(event) {
|
|
51
116
|
const sessionId = event.sessionId;
|
|
52
117
|
const taskId = makeTaskId();
|
|
53
118
|
const started = Date.now();
|
|
54
|
-
|
|
55
|
-
// Format: {base}:{companyId}:{agentType}:session:{sessionId}:...
|
|
56
|
-
const tenantPrefix = event.tenantContext
|
|
57
|
-
? `${prefix}:${event.tenantContext.companyId}:${event.tenantContext.agentType}`
|
|
58
|
-
: prefix;
|
|
119
|
+
const tenantPrefix = tenantPrefixFor(event);
|
|
59
120
|
// Per-event guard overrides (e.g. per-company cost caps from config_json).
|
|
60
121
|
const effectiveGuards = event.guardsOverride
|
|
61
122
|
? resolveGuards({ ...guards, ...event.guardsOverride })
|
|
@@ -73,7 +134,10 @@ export function createAgent(config) {
|
|
|
73
134
|
if (gated)
|
|
74
135
|
return gated;
|
|
75
136
|
// ── Distributed lock ─────────────────────────────────────
|
|
76
|
-
|
|
137
|
+
// TTL must cover the EFFECTIVE timeout (incl. per-request overrides) —
|
|
138
|
+
// otherwise an override raising timeoutMs lets the lock expire mid-run
|
|
139
|
+
// and a second worker can enter the same session concurrently.
|
|
140
|
+
const lockHandle = await lock.acquireWithRetry(sessionId, effectiveGuards.timeoutMs + 30_000);
|
|
77
141
|
const state = {
|
|
78
142
|
sessionId,
|
|
79
143
|
taskId,
|
|
@@ -140,16 +204,23 @@ export function createAgent(config) {
|
|
|
140
204
|
if (process.env["MINI_DEBUG"])
|
|
141
205
|
console.error(`[mini] finalize fired; forced.len=${forced.length} orch=${finalPayload.orchestration?.action}`);
|
|
142
206
|
if (forced) {
|
|
207
|
+
const gated = await applyOutputGate(forced);
|
|
208
|
+
await memory.appendHistory(sessionId, {
|
|
209
|
+
role: "user",
|
|
210
|
+
content: event.message,
|
|
211
|
+
timestamp: started,
|
|
212
|
+
});
|
|
143
213
|
await memory.appendHistory(sessionId, {
|
|
144
214
|
role: "assistant",
|
|
145
|
-
content:
|
|
215
|
+
content: gated.finalText,
|
|
146
216
|
timestamp: Date.now(),
|
|
147
217
|
});
|
|
148
218
|
await lockHandle.release();
|
|
149
|
-
return makeOutcome("response", sessionId, taskId, state, started, {
|
|
150
|
-
text:
|
|
219
|
+
return makeOutcome(gated.validation?.action === "block" ? "suppressed" : "response", sessionId, taskId, state, started, {
|
|
220
|
+
text: gated.finalText,
|
|
151
221
|
terminatedBy: hardSignal.type,
|
|
152
222
|
toolCalls: toolResults,
|
|
223
|
+
...(gated.validation ? { validation: gated.validation } : {}),
|
|
153
224
|
});
|
|
154
225
|
}
|
|
155
226
|
}
|
|
@@ -161,17 +232,30 @@ export function createAgent(config) {
|
|
|
161
232
|
const lastText = state.lastPayload?.generation?.response_text ??
|
|
162
233
|
state.lastPayload?.final_output?.text ??
|
|
163
234
|
"I was unable to complete this request within the allowed limits. Please try a more specific question.";
|
|
164
|
-
const
|
|
235
|
+
const gatedLast = await applyOutputGate(lastText);
|
|
236
|
+
const outcomeType = gatedLast.validation?.action === "block"
|
|
237
|
+
? "suppressed"
|
|
238
|
+
: ha === "escalate"
|
|
239
|
+
? "escalate"
|
|
240
|
+
: "response";
|
|
241
|
+
// Record BOTH sides of the turn — assistant-only history leaves
|
|
242
|
+
// orphaned turns that misalign the conversation on the next call.
|
|
243
|
+
await memory.appendHistory(sessionId, {
|
|
244
|
+
role: "user",
|
|
245
|
+
content: event.message,
|
|
246
|
+
timestamp: started,
|
|
247
|
+
});
|
|
165
248
|
await memory.appendHistory(sessionId, {
|
|
166
249
|
role: "assistant",
|
|
167
|
-
content:
|
|
250
|
+
content: gatedLast.finalText,
|
|
168
251
|
timestamp: Date.now(),
|
|
169
252
|
});
|
|
170
253
|
await lockHandle.release();
|
|
171
254
|
return makeOutcome(outcomeType, sessionId, taskId, state, started, {
|
|
172
|
-
text:
|
|
255
|
+
text: gatedLast.finalText,
|
|
173
256
|
terminatedBy: hardSignal.type,
|
|
174
257
|
toolCalls: toolResults,
|
|
258
|
+
...(gatedLast.validation ? { validation: gatedLast.validation } : {}),
|
|
175
259
|
});
|
|
176
260
|
}
|
|
177
261
|
// ── Context build ─────────────────────────────────────
|
|
@@ -265,30 +349,8 @@ export function createAgent(config) {
|
|
|
265
349
|
fireSectionComplete(config.hooks, sessionId, currentSection, idx, documentState.sections.length);
|
|
266
350
|
}
|
|
267
351
|
}
|
|
268
|
-
// ── Optional output gate
|
|
269
|
-
|
|
270
|
-
// never drop a valid response, so it fails safe to "review".
|
|
271
|
-
let finalText = text;
|
|
272
|
-
let validation;
|
|
273
|
-
if (config.validator && text) {
|
|
274
|
-
try {
|
|
275
|
-
validation = await config.validator.validate(text);
|
|
276
|
-
}
|
|
277
|
-
catch {
|
|
278
|
-
validation = {
|
|
279
|
-
passed: false,
|
|
280
|
-
score: 0,
|
|
281
|
-
violations: ["validator_error"],
|
|
282
|
-
action: "review",
|
|
283
|
-
strategy: "error",
|
|
284
|
-
latency_ms: 0,
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
if (validation.action === "block") {
|
|
288
|
-
finalText =
|
|
289
|
-
"I'm not able to share that response. Could you rephrase your request?";
|
|
290
|
-
}
|
|
291
|
-
}
|
|
352
|
+
// ── Optional output gate (shared with all guard exits) ─
|
|
353
|
+
const { finalText, validation } = await applyOutputGate(text);
|
|
292
354
|
// Record to history (the delivered text, post-gate)
|
|
293
355
|
await memory.appendHistory(sessionId, {
|
|
294
356
|
role: "user",
|