@spinabot/brigade 1.19.4 → 1.21.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 +4 -3
- package/convex/config.d.ts +2 -2
- package/convex/schema.d.ts +4 -4
- package/dist/agents/agent-loop.d.ts.map +1 -1
- package/dist/agents/agent-loop.js +92 -22
- package/dist/agents/agent-loop.js.map +1 -1
- package/dist/agents/content-quality-retry.d.ts.map +1 -1
- package/dist/agents/content-quality-retry.js +3 -22
- package/dist/agents/content-quality-retry.js.map +1 -1
- package/dist/agents/error-classifier.d.ts.map +1 -1
- package/dist/agents/error-classifier.js +2 -0
- package/dist/agents/error-classifier.js.map +1 -1
- package/dist/agents/memory/extract.d.ts.map +1 -1
- package/dist/agents/memory/extract.js +11 -44
- package/dist/agents/memory/extract.js.map +1 -1
- package/dist/agents/model-resolution.d.ts.map +1 -1
- package/dist/agents/model-resolution.js +9 -3
- package/dist/agents/model-resolution.js.map +1 -1
- package/dist/agents/ollama-native/ollama-json.d.ts +6 -0
- package/dist/agents/ollama-native/ollama-json.d.ts.map +1 -0
- package/dist/agents/ollama-native/ollama-json.js +126 -0
- package/dist/agents/ollama-native/ollama-json.js.map +1 -0
- package/dist/agents/ollama-native/register.d.ts +12 -0
- package/dist/agents/ollama-native/register.d.ts.map +1 -0
- package/dist/agents/ollama-native/register.js +37 -0
- package/dist/agents/ollama-native/register.js.map +1 -0
- package/dist/agents/ollama-native/stream.d.ts +59 -0
- package/dist/agents/ollama-native/stream.d.ts.map +1 -0
- package/dist/agents/ollama-native/stream.js +532 -0
- package/dist/agents/ollama-native/stream.js.map +1 -0
- package/dist/agents/payload-mutators.d.ts +0 -21
- package/dist/agents/payload-mutators.d.ts.map +1 -1
- package/dist/agents/payload-mutators.js +0 -58
- package/dist/agents/payload-mutators.js.map +1 -1
- package/dist/agents/thinking-fallback.d.ts.map +1 -1
- package/dist/agents/thinking-fallback.js +32 -10
- package/dist/agents/thinking-fallback.js.map +1 -1
- package/dist/buildstamp.json +1 -1
- package/dist/cli/commands/connect.d.ts.map +1 -1
- package/dist/cli/commands/connect.js +31 -43
- package/dist/cli/commands/connect.js.map +1 -1
- package/dist/cli/commands/update.d.ts +0 -6
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +9 -124
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/program/build-program.d.ts.map +1 -1
- package/dist/cli/program/build-program.js +1 -5
- package/dist/cli/program/build-program.js.map +1 -1
- package/dist/core/server.d.ts.map +1 -1
- package/dist/core/server.js +43 -25
- package/dist/core/server.js.map +1 -1
- package/dist/integrations/antigravity/transport.d.ts +29 -0
- package/dist/integrations/antigravity/transport.d.ts.map +1 -0
- package/dist/integrations/antigravity/transport.js +498 -0
- package/dist/integrations/antigravity/transport.js.map +1 -0
- package/dist/integrations/cli-login.d.ts +13 -0
- package/dist/integrations/cli-login.d.ts.map +1 -1
- package/dist/integrations/cli-login.js +29 -0
- package/dist/integrations/cli-login.js.map +1 -1
- package/dist/integrations/ollama.d.ts +29 -36
- package/dist/integrations/ollama.d.ts.map +1 -1
- package/dist/integrations/ollama.js +213 -78
- package/dist/integrations/ollama.js.map +1 -1
- package/dist/integrations/provider-discovery.d.ts +37 -0
- package/dist/integrations/provider-discovery.d.ts.map +1 -1
- package/dist/integrations/provider-discovery.js +102 -0
- package/dist/integrations/provider-discovery.js.map +1 -1
- package/dist/providers/catalog.d.ts +8 -1
- package/dist/providers/catalog.d.ts.map +1 -1
- package/dist/providers/catalog.js +29 -1
- package/dist/providers/catalog.js.map +1 -1
- package/dist/providers/validate-key.js +1 -1
- package/dist/storage/boot.d.ts.map +1 -1
- package/dist/storage/boot.js +2 -1
- package/dist/storage/boot.js.map +1 -1
- package/dist/storage/convex/index.d.ts.map +1 -1
- package/dist/storage/convex/index.js +15 -4
- package/dist/storage/convex/index.js.map +1 -1
- package/dist/system-prompt/guidance.d.ts.map +1 -1
- package/dist/system-prompt/guidance.js +2 -9
- package/dist/system-prompt/guidance.js.map +1 -1
- package/dist/ui/onboard-storage-mode.js +30 -4
- package/dist/ui/onboard-storage-mode.js.map +1 -1
- package/dist/ui/onboarding.d.ts.map +1 -1
- package/dist/ui/onboarding.js +150 -32
- package/dist/ui/onboarding.js.map +1 -1
- package/package.json +5 -2
- package/scripts/convex-push.mjs +47 -29
- package/dist/agents/tool-name-repair.d.ts +0 -28
- package/dist/agents/tool-name-repair.d.ts.map +0 -1
- package/dist/agents/tool-name-repair.js +0 -168
- package/dist/agents/tool-name-repair.js.map +0 -1
- package/dist/shared/reasoning-tags.d.ts +0 -14
- package/dist/shared/reasoning-tags.d.ts.map +0 -1
- package/dist/shared/reasoning-tags.js +0 -71
- package/dist/shared/reasoning-tags.js.map +0 -1
package/scripts/convex-push.mjs
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// scripts/convex-push.mjs — deploy convex/ functions to the
|
|
2
|
+
// scripts/convex-push.mjs — deploy convex/ functions to the target backend.
|
|
3
3
|
//
|
|
4
4
|
// npm run convex:push
|
|
5
5
|
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
6
|
+
// TWO targets, auto-detected:
|
|
7
|
+
// • CLOUD — when CONVEX_DEPLOY_KEY is set (Convex dashboard → deployment →
|
|
8
|
+
// Settings → "Deploy key"). Runs `convex deploy` against the cloud
|
|
9
|
+
// deployment the key belongs to. No admin key, no self-hosted env.
|
|
10
|
+
// • SELF-HOSTED (default) — reads the admin key minted by convex-dev.mjs and
|
|
11
|
+
// deploys to the local backend (default http://127.0.0.1:3210).
|
|
12
|
+
//
|
|
13
|
+
// Idempotent — run any time the functions or schema change. `npm run convex:dev`
|
|
14
|
+
// runs the self-hosted path automatically once the backend is up. WITHOUT a push,
|
|
15
|
+
// a fresh deployment has NO functions and every call fails with "Could not find
|
|
16
|
+
// public function 'health:ping'" — which the runtime otherwise surfaces as the
|
|
17
|
+
// misleading "backend unreachable". This is exactly why pointing Brigade at a
|
|
18
|
+
// *.convex.cloud URL "didn't work": the cloud deployment was empty.
|
|
13
19
|
|
|
14
20
|
import { spawnSync } from "node:child_process";
|
|
15
21
|
import { existsSync, readFileSync, readdirSync, rmSync } from "node:fs";
|
|
@@ -21,12 +27,9 @@ const DATA_DIR = join(ROOT, ".convex-data");
|
|
|
21
27
|
|
|
22
28
|
// Pre-clean: compiled .js/.js.map artifacts INSIDE convex/ make the bundler
|
|
23
29
|
// fail with "Two output files share the same path" (it treats both the .ts
|
|
24
|
-
// and the stray .js as entry points).
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
// the NEXT push. Sweep them before every deploy as a belt-and-suspenders so
|
|
28
|
-
// no future emitter can re-break deploys. `_generated/` is the CLI's own
|
|
29
|
-
// output and is exempt.
|
|
30
|
+
// and the stray .js as entry points). Sweep them before every deploy so no
|
|
31
|
+
// future emitter can re-break deploys. `_generated/` is the CLI's own output
|
|
32
|
+
// and is exempt (readdir is non-recursive).
|
|
30
33
|
const convexDir = join(ROOT, "convex");
|
|
31
34
|
let cleaned = 0;
|
|
32
35
|
for (const name of readdirSync(convexDir)) {
|
|
@@ -38,28 +41,43 @@ for (const name of readdirSync(convexDir)) {
|
|
|
38
41
|
if (cleaned > 0) {
|
|
39
42
|
console.log(`▌ Removed ${cleaned} stray compiled artifact(s) from convex/ (deploy-breaking).`);
|
|
40
43
|
}
|
|
41
|
-
const keyFile = join(DATA_DIR, "admin-key.txt");
|
|
42
|
-
const url = process.env.CONVEX_SELF_HOSTED_URL?.trim() || "http://127.0.0.1:3210";
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
const deployKey = process.env.CONVEX_DEPLOY_KEY?.trim();
|
|
46
|
+
|
|
47
|
+
let env;
|
|
48
|
+
let target;
|
|
49
|
+
if (deployKey) {
|
|
50
|
+
// CLOUD: the deploy key encodes the deployment, so `convex deploy` resolves
|
|
51
|
+
// the URL from it. Crucially, DO NOT pass CONVEX_SELF_HOSTED_* — setting them
|
|
52
|
+
// forces the CLI into self-hosted mode and it would ignore the deploy key.
|
|
53
|
+
env = { ...process.env, CONVEX_DEPLOY_KEY: deployKey };
|
|
54
|
+
delete env.CONVEX_SELF_HOSTED_URL;
|
|
55
|
+
delete env.CONVEX_SELF_HOSTED_ADMIN_KEY;
|
|
56
|
+
target = "Convex Cloud (via deploy key)";
|
|
57
|
+
} else {
|
|
58
|
+
// SELF-HOSTED (local backend).
|
|
59
|
+
const keyFile = join(DATA_DIR, "admin-key.txt");
|
|
60
|
+
const url = process.env.CONVEX_SELF_HOSTED_URL?.trim() || "http://127.0.0.1:3210";
|
|
61
|
+
if (!existsSync(keyFile) && !process.env.CONVEX_SELF_HOSTED_ADMIN_KEY) {
|
|
62
|
+
console.error(
|
|
63
|
+
"✖ No Convex target. Either:\n" +
|
|
64
|
+
" • CLOUD — set CONVEX_DEPLOY_KEY (Convex dashboard → deployment → Settings → Deploy key), or\n" +
|
|
65
|
+
" • SELF-HOSTED — start the local backend once: npm run convex:dev",
|
|
66
|
+
);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
const adminKey =
|
|
70
|
+
process.env.CONVEX_SELF_HOSTED_ADMIN_KEY?.trim() || readFileSync(keyFile, "utf8").trim();
|
|
71
|
+
env = { ...process.env, CONVEX_SELF_HOSTED_URL: url, CONVEX_SELF_HOSTED_ADMIN_KEY: adminKey };
|
|
72
|
+
target = url;
|
|
49
73
|
}
|
|
50
|
-
const adminKey =
|
|
51
|
-
process.env.CONVEX_SELF_HOSTED_ADMIN_KEY?.trim() || readFileSync(keyFile, "utf8").trim();
|
|
52
74
|
|
|
53
|
-
console.log(`▌ Pushing convex/ functions → ${
|
|
75
|
+
console.log(`▌ Pushing convex/ functions → ${target}`);
|
|
54
76
|
const res = spawnSync("npx", ["convex", "deploy", "--yes"], {
|
|
55
77
|
cwd: ROOT,
|
|
56
78
|
stdio: "inherit",
|
|
57
79
|
shell: true, // resolves npx.cmd on Windows
|
|
58
|
-
env
|
|
59
|
-
...process.env,
|
|
60
|
-
CONVEX_SELF_HOSTED_URL: url,
|
|
61
|
-
CONVEX_SELF_HOSTED_ADMIN_KEY: adminKey,
|
|
62
|
-
},
|
|
80
|
+
env,
|
|
63
81
|
});
|
|
64
82
|
if (res.status === 0) {
|
|
65
83
|
console.log("✓ Convex functions are up to date.");
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { BrigadeStreamFn } from "./stream-wrappers.js";
|
|
2
|
-
export interface ResolvedToolName {
|
|
3
|
-
/** The real registered tool name to dispatch. */
|
|
4
|
-
name: string;
|
|
5
|
-
/** When the raw name was a multiplexed-tool ACTION value, the action to inject into args. */
|
|
6
|
-
action?: string;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Resolve a model-emitted tool name to a REAL registered tool. Returns null
|
|
10
|
-
* when no change is needed (already valid) or nothing plausibly matches (leave
|
|
11
|
-
* it for Pi to reject). Order: exact → trim → case-insensitive-unique → static
|
|
12
|
-
* alias → browser-action-value → segmented/prefixed name.
|
|
13
|
-
*/
|
|
14
|
-
export declare function resolveToolName(rawName: unknown, allowed: ReadonlySet<string>): ResolvedToolName | null;
|
|
15
|
-
/** Rewrite one `toolCall` content block; returns null when unchanged. */
|
|
16
|
-
export declare function rewriteToolCallBlock(block: unknown, allowed: ReadonlySet<string>): unknown | null;
|
|
17
|
-
/** Rewrite every `toolCall` block in an assistant message. Same ref if unchanged. */
|
|
18
|
-
export declare function rewriteMessageToolNames<M>(message: M, allowed: ReadonlySet<string>): M;
|
|
19
|
-
/**
|
|
20
|
-
* Wrap Pi's streamFn to reconcile misnamed tool calls against the live
|
|
21
|
-
* allowed-tool set — rewriting the name on BOTH the final assistant message
|
|
22
|
-
* (`.result()`, which Pi dispatches from) and the streamed toolcall events (so
|
|
23
|
-
* the TUI shows the corrected name). `getAllowedNames` is read per call so
|
|
24
|
-
* per-turn tool changes are honoured. Composes on top of Pi's auth-aware
|
|
25
|
-
* streamFn — never replaces it.
|
|
26
|
-
*/
|
|
27
|
-
export declare function wrapStreamFnWithToolNameRepair<F extends BrigadeStreamFn>(base: F, getAllowedNames: () => Iterable<string> | undefined): F;
|
|
28
|
-
//# sourceMappingURL=tool-name-repair.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool-name-repair.d.ts","sourceRoot":"","sources":["../../src/agents/tool-name-repair.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAa5D,MAAM,WAAW,gBAAgB;IAChC,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,gBAAgB,GAAG,IAAI,CAuCvG;AASD,yEAAyE;AACzE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,GAAG,IAAI,CAejG;AAED,qFAAqF;AACrF,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAatF;AAqCD;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAAC,CAAC,SAAS,eAAe,EACvE,IAAI,EAAE,CAAC,EACP,eAAe,EAAE,MAAM,QAAQ,CAAC,MAAM,CAAC,GAAG,SAAS,GACjD,CAAC,CAgBH"}
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
// Tool-name reconciliation for misnamed tool calls.
|
|
2
|
-
//
|
|
3
|
-
// Pi's agent-loop dispatches tool calls by EXACT string match
|
|
4
|
-
// (`tools.find(t => t.name === toolCall.name)`) and, on a miss, hard-returns a
|
|
5
|
-
// `Tool <name> not found` error tool-result BEFORE any Brigade guard / hook can
|
|
6
|
-
// run. Weak local models (Ollama forks) routinely misname a call:
|
|
7
|
-
// • wrong case / stray whitespace (`Browser`, `" read "`),
|
|
8
|
-
// • a provider/namespace prefix (`functions.browser`, `browser.navigate`),
|
|
9
|
-
// • — most commonly — the `browser` tool's `action` DISCRIMINATOR used AS the
|
|
10
|
-
// tool name: it emits a tool literally named `action` (with
|
|
11
|
-
// `{action:"navigate", url}`), or names the tool after an action VALUE like
|
|
12
|
-
// `navigate`. There is no tool called `action`/`navigate`, so dispatch
|
|
13
|
-
// fails and the turn stalls.
|
|
14
|
-
//
|
|
15
|
-
// This module reconciles the emitted name against the LIVE allowed-tool set and
|
|
16
|
-
// rewrites it (on both the streamed events and the final assistant message Pi
|
|
17
|
-
// dispatches from) so a recoverable call lands instead of erroring. Nothing is
|
|
18
|
-
// invented: if no real tool plausibly matches, the name is left for Pi to
|
|
19
|
-
// reject as before.
|
|
20
|
-
import { BROWSER_ACTIONS } from "./tools/browser.js";
|
|
21
|
-
const BROWSER_ACTION_SET = new Set(BROWSER_ACTIONS.map((a) => a.toLowerCase()));
|
|
22
|
-
// Unknown-name → real-tool aliases. Seeded from the observed failure: the
|
|
23
|
-
// browser tool multiplexes on an `action` param, and models mistake that
|
|
24
|
-
// discriminator (or the verbs "browse"/"web") for the tool name.
|
|
25
|
-
const STATIC_ALIASES = {
|
|
26
|
-
action: "browser",
|
|
27
|
-
browse: "browser",
|
|
28
|
-
web: "browser",
|
|
29
|
-
};
|
|
30
|
-
/**
|
|
31
|
-
* Resolve a model-emitted tool name to a REAL registered tool. Returns null
|
|
32
|
-
* when no change is needed (already valid) or nothing plausibly matches (leave
|
|
33
|
-
* it for Pi to reject). Order: exact → trim → case-insensitive-unique → static
|
|
34
|
-
* alias → browser-action-value → segmented/prefixed name.
|
|
35
|
-
*/
|
|
36
|
-
export function resolveToolName(rawName, allowed) {
|
|
37
|
-
if (typeof rawName !== "string" || rawName.length === 0)
|
|
38
|
-
return null;
|
|
39
|
-
if (allowed.has(rawName))
|
|
40
|
-
return null; // already a valid tool name
|
|
41
|
-
const trimmed = rawName.trim();
|
|
42
|
-
if (trimmed !== rawName && allowed.has(trimmed))
|
|
43
|
-
return { name: trimmed };
|
|
44
|
-
const lower = trimmed.toLowerCase();
|
|
45
|
-
// Case-insensitive UNIQUE match (`Browser`/`READ` → the real name).
|
|
46
|
-
const ciMatches = [...allowed].filter((n) => n.toLowerCase() === lower);
|
|
47
|
-
if (ciMatches.length === 1)
|
|
48
|
-
return { name: ciMatches[0] };
|
|
49
|
-
// Static alias (action/browse/web → browser).
|
|
50
|
-
const alias = STATIC_ALIASES[lower];
|
|
51
|
-
if (alias && allowed.has(alias))
|
|
52
|
-
return { name: alias };
|
|
53
|
-
// A browser ACTION value used as the tool name (navigate/click/…) → route to
|
|
54
|
-
// `browser` and carry the action along.
|
|
55
|
-
if (BROWSER_ACTION_SET.has(lower) && allowed.has("browser")) {
|
|
56
|
-
return { name: "browser", action: lower };
|
|
57
|
-
}
|
|
58
|
-
// Provider-prefixed / segmented name: `functions.browser`, `browser.navigate`.
|
|
59
|
-
const segments = trimmed.split(/[.:/]+/).filter(Boolean);
|
|
60
|
-
if (segments.length > 1) {
|
|
61
|
-
for (const seg of segments) {
|
|
62
|
-
if (allowed.has(seg))
|
|
63
|
-
return { name: seg };
|
|
64
|
-
const s = seg.toLowerCase();
|
|
65
|
-
if (allowed.has(s))
|
|
66
|
-
return { name: s };
|
|
67
|
-
}
|
|
68
|
-
for (const seg of segments) {
|
|
69
|
-
if (BROWSER_ACTION_SET.has(seg.toLowerCase()) && allowed.has("browser")) {
|
|
70
|
-
return { name: "browser", action: seg.toLowerCase() };
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
/** Rewrite one `toolCall` content block; returns null when unchanged. */
|
|
77
|
-
export function rewriteToolCallBlock(block, allowed) {
|
|
78
|
-
if (!block || typeof block !== "object")
|
|
79
|
-
return null;
|
|
80
|
-
const b = block;
|
|
81
|
-
if (b.type !== "toolCall" || typeof b.name !== "string")
|
|
82
|
-
return null;
|
|
83
|
-
const res = resolveToolName(b.name, allowed);
|
|
84
|
-
if (!res)
|
|
85
|
-
return null;
|
|
86
|
-
let args = b.arguments;
|
|
87
|
-
if (res.action) {
|
|
88
|
-
const obj = args && typeof args === "object" && !Array.isArray(args)
|
|
89
|
-
? args
|
|
90
|
-
: {};
|
|
91
|
-
if (obj.action === undefined)
|
|
92
|
-
args = { ...obj, action: res.action };
|
|
93
|
-
}
|
|
94
|
-
return { ...b, name: res.name, arguments: args };
|
|
95
|
-
}
|
|
96
|
-
/** Rewrite every `toolCall` block in an assistant message. Same ref if unchanged. */
|
|
97
|
-
export function rewriteMessageToolNames(message, allowed) {
|
|
98
|
-
const m = message;
|
|
99
|
-
if (!m || !Array.isArray(m.content))
|
|
100
|
-
return message;
|
|
101
|
-
let changed = false;
|
|
102
|
-
const content = m.content.map((block) => {
|
|
103
|
-
const rewritten = rewriteToolCallBlock(block, allowed);
|
|
104
|
-
if (rewritten) {
|
|
105
|
-
changed = true;
|
|
106
|
-
return rewritten;
|
|
107
|
-
}
|
|
108
|
-
return block;
|
|
109
|
-
});
|
|
110
|
-
return changed ? { ...m, content } : message;
|
|
111
|
-
}
|
|
112
|
-
function isEventStreamLike(v) {
|
|
113
|
-
if (!v || (typeof v !== "object" && typeof v !== "function"))
|
|
114
|
-
return false;
|
|
115
|
-
const s = v;
|
|
116
|
-
return typeof s[Symbol.asyncIterator] === "function" && typeof s.result === "function";
|
|
117
|
-
}
|
|
118
|
-
function rewriteEventToolNames(ev, allowed) {
|
|
119
|
-
if (!ev || typeof ev !== "object")
|
|
120
|
-
return ev;
|
|
121
|
-
const e = ev;
|
|
122
|
-
let next = ev;
|
|
123
|
-
if (e.type === "toolcall_end" && e.toolCall) {
|
|
124
|
-
const rewritten = rewriteToolCallBlock(e.toolCall, allowed);
|
|
125
|
-
if (rewritten)
|
|
126
|
-
next = { ...next, toolCall: rewritten };
|
|
127
|
-
}
|
|
128
|
-
if (e.partial && typeof e.partial === "object") {
|
|
129
|
-
const rewrittenPartial = rewriteMessageToolNames(e.partial, allowed);
|
|
130
|
-
if (rewrittenPartial !== e.partial)
|
|
131
|
-
next = { ...next, partial: rewrittenPartial };
|
|
132
|
-
}
|
|
133
|
-
return next;
|
|
134
|
-
}
|
|
135
|
-
async function* toolNameIterator(inner, allowed) {
|
|
136
|
-
for await (const ev of inner) {
|
|
137
|
-
yield rewriteEventToolNames(ev, allowed);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Wrap Pi's streamFn to reconcile misnamed tool calls against the live
|
|
142
|
-
* allowed-tool set — rewriting the name on BOTH the final assistant message
|
|
143
|
-
* (`.result()`, which Pi dispatches from) and the streamed toolcall events (so
|
|
144
|
-
* the TUI shows the corrected name). `getAllowedNames` is read per call so
|
|
145
|
-
* per-turn tool changes are honoured. Composes on top of Pi's auth-aware
|
|
146
|
-
* streamFn — never replaces it.
|
|
147
|
-
*/
|
|
148
|
-
export function wrapStreamFnWithToolNameRepair(base, getAllowedNames) {
|
|
149
|
-
const wrapped = async function (...args) {
|
|
150
|
-
const stream = await Promise.resolve(base.apply(this, args));
|
|
151
|
-
if (!isEventStreamLike(stream))
|
|
152
|
-
return stream;
|
|
153
|
-
const allowed = new Set();
|
|
154
|
-
for (const n of getAllowedNames() ?? []) {
|
|
155
|
-
if (typeof n === "string" && n)
|
|
156
|
-
allowed.add(n);
|
|
157
|
-
}
|
|
158
|
-
if (allowed.size === 0)
|
|
159
|
-
return stream;
|
|
160
|
-
const inner = stream;
|
|
161
|
-
return {
|
|
162
|
-
[Symbol.asyncIterator]: () => toolNameIterator(inner, allowed),
|
|
163
|
-
result: async () => rewriteMessageToolNames(await inner.result(), allowed),
|
|
164
|
-
};
|
|
165
|
-
};
|
|
166
|
-
return wrapped;
|
|
167
|
-
}
|
|
168
|
-
//# sourceMappingURL=tool-name-repair.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool-name-repair.js","sourceRoot":"","sources":["../../src/agents/tool-name-repair.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Split `text` into the visible answer and the concatenated reasoning trace.
|
|
3
|
-
* `reasoning` is "" when there was none. Never throws.
|
|
4
|
-
*/
|
|
5
|
-
export declare function splitReasoning(text: string): {
|
|
6
|
-
visible: string;
|
|
7
|
-
reasoning: string;
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* Return `text` with all reasoning removed — only the model's actual answer
|
|
11
|
-
* (or the JSON it was asked for) remains. Never throws.
|
|
12
|
-
*/
|
|
13
|
-
export declare function stripReasoningTags(text: string): string;
|
|
14
|
-
//# sourceMappingURL=reasoning-tags.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reasoning-tags.d.ts","sourceRoot":"","sources":["../../src/shared/reasoning-tags.ts"],"names":[],"mappings":"AAwCA;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CA2BnF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD"}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
// Reasoning-tag handling for models that emit chain-of-thought as literal text.
|
|
2
|
-
//
|
|
3
|
-
// Many local models (Ollama qwen3 / deepseek-r1 / qwq / "thinking" forks, and
|
|
4
|
-
// assorted fine-tunes) emit their reasoning INLINE as `<think>…</think>`,
|
|
5
|
-
// `<thinking>…</thinking>`, `<thought>…</thought>`, sometimes wrapped in a
|
|
6
|
-
// `<final>…</final>` around the real answer — as plain TEXT, not as a typed
|
|
7
|
-
// reasoning content block. Left in place this reasoning:
|
|
8
|
-
// • leaks the raw tags into the visible reply (bad UX), and
|
|
9
|
-
// • defeats JSON extraction (the chain-of-thought surrounds/pollutes the
|
|
10
|
-
// JSON the memory extractor asks for).
|
|
11
|
-
//
|
|
12
|
-
// This module is the single source of truth for stripping/splitting that
|
|
13
|
-
// reasoning. Two entry points:
|
|
14
|
-
// • stripReasoningTags(text) — drop reasoning, return only the answer text.
|
|
15
|
-
// • splitReasoning(text) — split into { visible, reasoning } so callers
|
|
16
|
-
// that want to SHOW the trace (e.g. the TUI's
|
|
17
|
-
// /show-thinking) can keep it.
|
|
18
|
-
// Fast pre-check: bail immediately when there's no reasoning tag at all so the
|
|
19
|
-
// common (no-tag) path allocates nothing.
|
|
20
|
-
const REASONING_QUICK_RE = /<\s*\/?\s*(?:think(?:ing)?|thought|final)\b/i;
|
|
21
|
-
// A complete paired reasoning block. Group 1 captures the tag word so the
|
|
22
|
-
// backreference (\1) forces the closing tag to match the opener
|
|
23
|
-
// (`<thinking>…</thinking>`, not `<thinking>…</think>`); group 2 is the inner
|
|
24
|
-
// reasoning. Case-insensitive; tolerant of attributes/whitespace.
|
|
25
|
-
const REASONING_BLOCK_RE = /<\s*(think(?:ing)?|thought)\b[^>]*>([\s\S]*?)<\/\s*\1\s*>/gi;
|
|
26
|
-
// A reasoning block that was OPENED but never closed — e.g. a stream cut off
|
|
27
|
-
// mid-thought. Everything from the open tag to end-of-text is reasoning.
|
|
28
|
-
const REASONING_OPEN_TO_END_RE = /<\s*(?:think(?:ing)?|thought)\b[^>]*>([\s\S]*)$/i;
|
|
29
|
-
// `<final>` / `</final>` wrapper tags — the INNER content is the real answer,
|
|
30
|
-
// so we only remove the tags, never the content.
|
|
31
|
-
const FINAL_TAG_RE = /<\s*\/?\s*final\b[^>]*>/gi;
|
|
32
|
-
// Any stray/leftover reasoning tag (unpaired open or close) after the passes
|
|
33
|
-
// above.
|
|
34
|
-
const REASONING_STRAY_TAG_RE = /<\s*\/?\s*(?:think(?:ing)?|thought)\b[^>]*>/gi;
|
|
35
|
-
/**
|
|
36
|
-
* Split `text` into the visible answer and the concatenated reasoning trace.
|
|
37
|
-
* `reasoning` is "" when there was none. Never throws.
|
|
38
|
-
*/
|
|
39
|
-
export function splitReasoning(text) {
|
|
40
|
-
if (!text || !REASONING_QUICK_RE.test(text))
|
|
41
|
-
return { visible: text, reasoning: "" };
|
|
42
|
-
const reasoning = [];
|
|
43
|
-
// 1. Complete paired blocks → collect inner, drop from visible.
|
|
44
|
-
let visible = text.replace(REASONING_BLOCK_RE, (_m, _word, inner) => {
|
|
45
|
-
const t = (inner ?? "").trim();
|
|
46
|
-
if (t)
|
|
47
|
-
reasoning.push(t);
|
|
48
|
-
return "";
|
|
49
|
-
});
|
|
50
|
-
// 2. An unclosed reasoning block (opened, never closed) → collect the tail.
|
|
51
|
-
const open = REASONING_OPEN_TO_END_RE.exec(visible);
|
|
52
|
-
if (open) {
|
|
53
|
-
const t = (open[1] ?? "").trim();
|
|
54
|
-
if (t)
|
|
55
|
-
reasoning.push(t);
|
|
56
|
-
visible = visible.slice(0, open.index);
|
|
57
|
-
}
|
|
58
|
-
// 3. Unwrap <final>…</final> (keep the answer, drop the tags).
|
|
59
|
-
visible = visible.replace(FINAL_TAG_RE, "");
|
|
60
|
-
// 4. Remove any stray leftover reasoning tags.
|
|
61
|
-
visible = visible.replace(REASONING_STRAY_TAG_RE, "");
|
|
62
|
-
return { visible, reasoning: reasoning.join("\n").trim() };
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Return `text` with all reasoning removed — only the model's actual answer
|
|
66
|
-
* (or the JSON it was asked for) remains. Never throws.
|
|
67
|
-
*/
|
|
68
|
-
export function stripReasoningTags(text) {
|
|
69
|
-
return splitReasoning(text).visible;
|
|
70
|
-
}
|
|
71
|
-
//# sourceMappingURL=reasoning-tags.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reasoning-tags.js","sourceRoot":"","sources":["../../src/shared/reasoning-tags.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,EAAE;AACF,8EAA8E;AAC9E,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,yDAAyD;AACzD,8DAA8D;AAC9D,2EAA2E;AAC3E,2CAA2C;AAC3C,EAAE;AACF,yEAAyE;AACzE,+BAA+B;AAC/B,+EAA+E;AAC/E,+EAA+E;AAC/E,8EAA8E;AAC9E,+DAA+D;AAE/D,+EAA+E;AAC/E,0CAA0C;AAC1C,MAAM,kBAAkB,GAAG,8CAA8C,CAAC;AAE1E,0EAA0E;AAC1E,gEAAgE;AAChE,8EAA8E;AAC9E,kEAAkE;AAClE,MAAM,kBAAkB,GAAG,6DAA6D,CAAC;AAEzF,6EAA6E;AAC7E,yEAAyE;AACzE,MAAM,wBAAwB,GAAG,kDAAkD,CAAC;AAEpF,8EAA8E;AAC9E,iDAAiD;AACjD,MAAM,YAAY,GAAG,2BAA2B,CAAC;AAEjD,6EAA6E;AAC7E,SAAS;AACT,MAAM,sBAAsB,GAAG,+CAA+C,CAAC;AAE/E;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IAC1C,IAAI,CAAC,IAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IAErF,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,gEAAgE;IAChE,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,EAAE,EAAE,KAAa,EAAE,KAAa,EAAE,EAAE;QACnF,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB,OAAO,EAAE,CAAC;IACX,CAAC,CAAC,CAAC;IAEH,4EAA4E;IAC5E,MAAM,IAAI,GAAG,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpD,IAAI,IAAI,EAAE,CAAC;QACV,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAED,+DAA+D;IAC/D,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAE5C,+CAA+C;IAC/C,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC;IAEtD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;AAC5D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC9C,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;AACrC,CAAC"}
|