zidane 6.0.1 → 6.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 +27 -0
- package/dist/{acp-Irby04Us.js → acp-cfR8T19u.js} +8 -8
- package/dist/{acp-Irby04Us.js.map → acp-cfR8T19u.js.map} +1 -1
- package/dist/acp-cli.js +7 -7
- package/dist/acp-cli.js.map +1 -1
- package/dist/acp.d.ts +1 -1
- package/dist/acp.js +1 -1
- package/dist/{agent-DkSmGkDM.js → agent-DZRA7wip.js} +377 -61
- package/dist/agent-DZRA7wip.js.map +1 -0
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +1 -1
- package/dist/{anthropic-CTHsdFG9.js → anthropic-DNJbRMUK.js} +7 -7
- package/dist/anthropic-DNJbRMUK.js.map +1 -0
- package/dist/atomic-write-B7zr1ddF.js.map +1 -1
- package/dist/{auth-BDSu_0t3.js → auth-B3cB5K6d.js} +7 -7
- package/dist/auth-B3cB5K6d.js.map +1 -0
- package/dist/cache-telemetry-BKAwsNxm.js.map +1 -1
- package/dist/chat/pure.d.ts +4 -4
- package/dist/chat/pure.js +3 -3
- package/dist/chat.d.ts +44 -21
- package/dist/chat.d.ts.map +1 -1
- package/dist/chat.js +7 -7
- package/dist/chat.js.map +1 -1
- package/dist/completion-core-CXYSVhZo.js.map +1 -1
- package/dist/context-breakdown-Dzo25N45.js.map +1 -1
- package/dist/contexts/daytona.d.ts +3 -1
- package/dist/contexts/daytona.d.ts.map +1 -1
- package/dist/contexts/daytona.js +2 -2
- package/dist/contexts/daytona.js.map +1 -1
- package/dist/contexts/docker.d.ts.map +1 -1
- package/dist/contexts/docker.js +2 -2
- package/dist/contexts/docker.js.map +1 -1
- package/dist/contexts/e2b.d.ts +3 -1
- package/dist/contexts/e2b.d.ts.map +1 -1
- package/dist/contexts/e2b.js +1 -1
- package/dist/contexts/e2b.js.map +1 -1
- package/dist/{contexts-Vone3qQQ.js → contexts-BIbcfBFH.js} +2 -2
- package/dist/contexts-BIbcfBFH.js.map +1 -0
- package/dist/contexts.js +1 -1
- package/dist/edit-utils-EGosADZq.js.map +1 -1
- package/dist/eval.d.ts +1 -1
- package/dist/eval.js +4 -3
- package/dist/eval.js.map +1 -1
- package/dist/exec-file-size-PXkr-MGA.js.map +1 -1
- package/dist/extensions.d.ts +1 -1
- package/dist/extensions.js +1 -1
- package/dist/{fetch-url-CWE8X5OD.js → fetch-url-_5WKWpbQ.js} +2 -2
- package/dist/{fetch-url-CWE8X5OD.js.map → fetch-url-_5WKWpbQ.js.map} +1 -1
- package/dist/{format-BNOXpl-1.js → format-BF745pLL.js} +9 -2
- package/dist/format-BF745pLL.js.map +1 -0
- package/dist/generate-data-WL_yGVL6.js.map +1 -1
- package/dist/hash-DJRzmcPI.js.map +1 -1
- package/dist/headless.d.ts +1 -1
- package/dist/headless.js +4 -4
- package/dist/headless.js.map +1 -1
- package/dist/{index-B8UtiZy7.d.ts → index-BGpM2YaU.d.ts} +378 -5
- package/dist/index-BGpM2YaU.d.ts.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +11 -11
- package/dist/index.js.map +1 -1
- package/dist/logger-DBX9uYOw.js.map +1 -1
- package/dist/{login-DOF8pMVM.js → login-DZLG__2f.js} +4 -3
- package/dist/{login-DOF8pMVM.js.map → login-DZLG__2f.js.map} +1 -1
- package/dist/mcp-CcvuVXB9.js.map +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/media-sniff-Bn76JxAu.js.map +1 -1
- package/dist/{messages-CwujiS74.js → messages-C5BDOjUG.js} +2 -2
- package/dist/{messages-CwujiS74.js.map → messages-C5BDOjUG.js.map} +1 -1
- package/dist/oauth-8LqbeI_Q.js.map +1 -1
- package/dist/{openai-compat-BvgYGSR1.js → openai-compat-B0kqvZqN.js} +2 -2
- package/dist/openai-compat-B0kqvZqN.js.map +1 -0
- package/dist/output/stream-json.d.ts +1 -1
- package/dist/output/terminal.d.ts +1 -1
- package/dist/output/terminal.js +1 -1
- package/dist/output/terminal.js.map +1 -1
- package/dist/output-cap-kBUHBlnq.js.map +1 -1
- package/dist/presets.d.ts +1 -1
- package/dist/presets.js +1 -1
- package/dist/providers/anthropic.d.ts +1 -1
- package/dist/providers/anthropic.js +1 -1
- package/dist/providers/arcee.d.ts +1 -1
- package/dist/providers/arcee.js +1 -1
- package/dist/providers/baseten.d.ts +1 -1
- package/dist/providers/baseten.js +2 -2
- package/dist/providers/baseten.js.map +1 -1
- package/dist/providers/cerebras.d.ts +1 -1
- package/dist/providers/cerebras.js +1 -1
- package/dist/providers/local.d.ts +1 -1
- package/dist/providers/local.js +1 -1
- package/dist/providers/openai-compat.d.ts +1 -1
- package/dist/providers/openai-compat.js +1 -1
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openai.js +8 -8
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.d.ts +1 -1
- package/dist/providers/openrouter.js +1 -1
- package/dist/providers/xai.d.ts +1 -1
- package/dist/providers/xai.js +1 -1
- package/dist/{providers-z6LDMAr3.js → providers-BMlrTr6a.js} +3 -3
- package/dist/{providers-z6LDMAr3.js.map → providers-BMlrTr6a.js.map} +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +4 -4
- package/dist/read-state-Dq_TXUX1.js.map +1 -1
- package/dist/{resolve-Cr8JSL_O.js → resolve-CC8Lmwcj.js} +3 -3
- package/dist/{resolve-Cr8JSL_O.js.map → resolve-CC8Lmwcj.js.map} +1 -1
- package/dist/restate.d.ts +1 -1
- package/dist/restate.d.ts.map +1 -1
- package/dist/restate.js.map +1 -1
- package/dist/session/sqlite.d.ts +1 -1
- package/dist/session/sqlite.d.ts.map +1 -1
- package/dist/session/sqlite.js +75 -20
- package/dist/session/sqlite.js.map +1 -1
- package/dist/{session-CsdDIPY8.js → session-CsKzK8-P.js} +3 -3
- package/dist/session-CsKzK8-P.js.map +1 -0
- package/dist/session.d.ts +2 -2
- package/dist/session.js +2 -2
- package/dist/{skills-Bsb0rvWI.js → skills-BjeXSRlQ.js} +2 -2
- package/dist/{skills-Bsb0rvWI.js.map → skills-BjeXSRlQ.js.map} +1 -1
- package/dist/skills.d.ts +1 -1
- package/dist/skills.js +2 -2
- package/dist/stdio-loader-Ce68wUmM.js.map +1 -1
- package/dist/{tool-formatters-DY0TDb1r.d.ts → tool-formatters-CMwjDvkp.d.ts} +2 -2
- package/dist/tool-formatters-CMwjDvkp.d.ts.map +1 -0
- package/dist/tools/fetch-url.d.ts +1 -1
- package/dist/tools/fetch-url.d.ts.map +1 -1
- package/dist/tools/fetch-url.js +1 -1
- package/dist/tools/web-search.d.ts +1 -1
- package/dist/tools/web-search.js +1 -1
- package/dist/tools/web-search.js.map +1 -1
- package/dist/tools.d.ts +2 -2
- package/dist/tools.js +2 -2
- package/dist/{transcript-anchors-DSRPWjiH.js → transcript-anchors-BTNe1OJi.js} +346 -89
- package/dist/transcript-anchors-BTNe1OJi.js.map +1 -0
- package/dist/{transcript-anchors-Cb-bDbNH.d.ts → transcript-anchors-D5wvdKQQ.d.ts} +37 -3
- package/dist/transcript-anchors-D5wvdKQQ.d.ts.map +1 -0
- package/dist/tui.d.ts +21 -6
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +497 -83
- package/dist/tui.js.map +1 -1
- package/dist/{turn-operations-Dq9Kx7m2.js → turn-operations-CEt_l3fy.js} +23 -8
- package/dist/turn-operations-CEt_l3fy.js.map +1 -0
- package/dist/{turn-operations-CgMROLsr.d.ts → turn-operations-JO5MYM9_.d.ts} +27 -9
- package/dist/turn-operations-JO5MYM9_.d.ts.map +1 -0
- package/dist/types-BIarq1qE.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/{xai-B_e6TOA8.js → xai-C_aq671K.js} +3 -3
- package/dist/{xai-B_e6TOA8.js.map → xai-C_aq671K.js.map} +1 -1
- package/docs/ARCHITECTURE.md +4 -0
- package/docs/CHAT.md +12 -10
- package/docs/SKILL.md +1 -1
- package/docs/TUI.md +3 -3
- package/package.json +2 -2
- package/dist/agent-DkSmGkDM.js.map +0 -1
- package/dist/anthropic-CTHsdFG9.js.map +0 -1
- package/dist/auth-BDSu_0t3.js.map +0 -1
- package/dist/contexts-Vone3qQQ.js.map +0 -1
- package/dist/format-BNOXpl-1.js.map +0 -1
- package/dist/index-B8UtiZy7.d.ts.map +0 -1
- package/dist/openai-compat-BvgYGSR1.js.map +0 -1
- package/dist/session-CsdDIPY8.js.map +0 -1
- package/dist/tool-formatters-DY0TDb1r.d.ts.map +0 -1
- package/dist/transcript-anchors-Cb-bDbNH.d.ts.map +0 -1
- package/dist/transcript-anchors-DSRPWjiH.js.map +0 -1
- package/dist/turn-operations-CgMROLsr.d.ts.map +0 -1
- package/dist/turn-operations-Dq9Kx7m2.js.map +0 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { l as toolResultToText } from "./types-BIarq1qE.js";
|
|
2
|
-
import {
|
|
3
|
-
import { c as
|
|
2
|
+
import { At as grep, Ct as readFile$1, Jt as resolveExtensionKeybindings, Mt as edit, Ot as listFiles, Pt as resolveStorageDirs, R as EMPTY_EXTENSION_REGISTRY, Wt as mergeKeybindings, Z as buildExtensionPreset, ft as waitTask, jt as glob, mt as createSpawnTool, ot as composePresets, qt as readKeybindingsRaw, st as definePreset, ut as writeFile$1, wt as multiEdit, xt as shell, yt as shellKill } from "./agent-DZRA7wip.js";
|
|
3
|
+
import { c as previewLine, i as fmtTokens, l as shortId } from "./format-BF745pLL.js";
|
|
4
4
|
import { l as errorMessage } from "./errors-DJUxZg9b.js";
|
|
5
|
-
import { M as findGitRoot$1, i as discoverSkills, j as projectUserPaths } from "./resolve-
|
|
5
|
+
import { M as findGitRoot$1, i as discoverSkills, j as projectUserPaths } from "./resolve-CC8Lmwcj.js";
|
|
6
6
|
import { t as writeFileAtomic } from "./atomic-write-B7zr1ddF.js";
|
|
7
7
|
import { r as formatTokenUsage } from "./stats-DAKBEKjc.js";
|
|
8
8
|
import { joinSystemPrompt } from "./prompt.js";
|
|
9
9
|
import { a as normalizeMcpServers, n as connectMcpServers } from "./mcp-CcvuVXB9.js";
|
|
10
10
|
import { i as findActiveTriggers, n as collectReferences, o as mergeSuggestions, t as applyInsert } from "./completion-core-CXYSVhZo.js";
|
|
11
|
-
import { r as fetchUrl } from "./fetch-url-
|
|
11
|
+
import { r as fetchUrl } from "./fetch-url-_5WKWpbQ.js";
|
|
12
12
|
import { webSearch } from "./tools/web-search.js";
|
|
13
|
-
import { C as restoreModelOptions, l as BUILTIN_PROVIDERS, n as applyApiKeyEnv, r as credentialsPath, t as detectAuth, v as modelSupportsReasoning, y as modelsForDescriptor } from "./auth-
|
|
14
|
-
import { H as extractEditPayload, Z as parseEditOutcomesFromResult, p as ownerOf, rt as chatReferenceTokensFromText, u as capTranscriptEvents } from "./turn-operations-
|
|
13
|
+
import { C as restoreModelOptions, l as BUILTIN_PROVIDERS, n as applyApiKeyEnv, r as credentialsPath, t as detectAuth, v as modelSupportsReasoning, y as modelsForDescriptor } from "./auth-B3cB5K6d.js";
|
|
14
|
+
import { H as extractEditPayload, Z as parseEditOutcomesFromResult, p as ownerOf, rt as chatReferenceTokensFromText, u as capTranscriptEvents } from "./turn-operations-CEt_l3fy.js";
|
|
15
15
|
import { createRequire } from "node:module";
|
|
16
16
|
import { dirname, isAbsolute, join, posix, relative, resolve, sep } from "node:path";
|
|
17
17
|
import { Buffer as Buffer$1 } from "node:buffer";
|
|
@@ -24,7 +24,7 @@ import { createGunzip } from "node:zlib";
|
|
|
24
24
|
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
25
25
|
import { jsx } from "react/jsx-runtime";
|
|
26
26
|
//#region \0rolldown/runtime.js
|
|
27
|
-
var __require = /*
|
|
27
|
+
var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
|
|
28
28
|
//#endregion
|
|
29
29
|
//#region src/chat/store.ts
|
|
30
30
|
function ensureStateDir(path) {
|
|
@@ -65,6 +65,22 @@ function saveState(path, state) {
|
|
|
65
65
|
* a stderr line is emitted under `ZIDANE_DEBUG` for diagnosis.
|
|
66
66
|
*/
|
|
67
67
|
async function listSessionMeta(store, filter) {
|
|
68
|
+
if (store.listMeta) try {
|
|
69
|
+
return (await store.listMeta(filter)).map((row) => ({
|
|
70
|
+
id: row.id,
|
|
71
|
+
title: deriveSessionTitle(row.firstUserTurn ? [row.firstUserTurn] : [], row.metadata),
|
|
72
|
+
turnCount: row.turnCount,
|
|
73
|
+
userMessageCount: row.userMessageCount,
|
|
74
|
+
runCount: row.runCount,
|
|
75
|
+
...row.projectRoot ? { projectRoot: row.projectRoot } : {},
|
|
76
|
+
updatedAt: row.updatedAt
|
|
77
|
+
}));
|
|
78
|
+
} catch (err) {
|
|
79
|
+
if (process.env.ZIDANE_DEBUG) {
|
|
80
|
+
const cause = err instanceof Error ? err.message : String(err);
|
|
81
|
+
process.stderr.write(`[zidane/chat] store.listMeta failed, falling back to full loads: ${cause}\n`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
68
84
|
const ids = await store.list(filter);
|
|
69
85
|
const settled = await Promise.allSettled(ids.map(async (id) => {
|
|
70
86
|
const data = await store.load(id);
|
|
@@ -252,11 +268,13 @@ function eventsFromTurns(turns, runs = []) {
|
|
|
252
268
|
};
|
|
253
269
|
const pushSpawnStart = (run) => {
|
|
254
270
|
const taskPreview = previewLine(run.prompt, 80);
|
|
271
|
+
const model = run.turnUsage?.find((u) => u.modelId)?.modelId;
|
|
255
272
|
events.push({
|
|
256
273
|
kind: "spawn-start",
|
|
257
274
|
text: taskPreview,
|
|
258
275
|
childId: labelFor(run.id),
|
|
259
|
-
depth: run.depth ?? 1
|
|
276
|
+
depth: run.depth ?? 1,
|
|
277
|
+
...model ? { model } : {}
|
|
260
278
|
});
|
|
261
279
|
};
|
|
262
280
|
for (let i = 0; i < turns.length; i++) {
|
|
@@ -621,7 +639,7 @@ const MARGIN_TOP = {
|
|
|
621
639
|
"task-notification": 1,
|
|
622
640
|
"custom": 1
|
|
623
641
|
};
|
|
624
|
-
const TOOL_KINDS = new Set(["tool", "tool-result"]);
|
|
642
|
+
const TOOL_KINDS = /* @__PURE__ */ new Set(["tool", "tool-result"]);
|
|
625
643
|
/**
|
|
626
644
|
* Resolve the top margin (in rows) for an event given the one rendered
|
|
627
645
|
* just before it. Context-aware rules:
|
|
@@ -699,6 +717,42 @@ function sumRunCosts(runs) {
|
|
|
699
717
|
for (const run of runs) if (run.cost) total += run.cost;
|
|
700
718
|
return total;
|
|
701
719
|
}
|
|
720
|
+
/**
|
|
721
|
+
* Aggregate per-model token + spend totals across every run in a session.
|
|
722
|
+
* Parent and subagent runs alike: each turn carries its own `modelId`, so
|
|
723
|
+
* cost-tiered delegation (cheap spawn workers) shows up as separate rows
|
|
724
|
+
* priced at their own rates. Sorted by cost (desc), then total tokens, so
|
|
725
|
+
* the biggest spender reads first.
|
|
726
|
+
*/
|
|
727
|
+
function usageByModel(runs) {
|
|
728
|
+
const byModel = /* @__PURE__ */ new Map();
|
|
729
|
+
for (const run of runs) for (const u of run.turnUsage ?? []) {
|
|
730
|
+
const key = u.modelId ?? "unknown";
|
|
731
|
+
let row = byModel.get(key);
|
|
732
|
+
if (!row) {
|
|
733
|
+
row = {
|
|
734
|
+
modelId: key,
|
|
735
|
+
turns: 0,
|
|
736
|
+
input: 0,
|
|
737
|
+
output: 0,
|
|
738
|
+
cacheRead: 0,
|
|
739
|
+
cacheCreation: 0,
|
|
740
|
+
cost: 0,
|
|
741
|
+
costComplete: true
|
|
742
|
+
};
|
|
743
|
+
byModel.set(key, row);
|
|
744
|
+
}
|
|
745
|
+
row.turns += 1;
|
|
746
|
+
row.input += u.input;
|
|
747
|
+
row.output += u.output;
|
|
748
|
+
row.cacheRead += u.cacheRead ?? 0;
|
|
749
|
+
row.cacheCreation += u.cacheCreation ?? 0;
|
|
750
|
+
if (u.cost !== void 0) row.cost += u.cost;
|
|
751
|
+
else row.costComplete = false;
|
|
752
|
+
}
|
|
753
|
+
const totalTokens = (r) => r.input + r.output + r.cacheRead + r.cacheCreation;
|
|
754
|
+
return [...byModel.values()].sort((a, b) => b.cost - a.cost || totalTokens(b) - totalTokens(a));
|
|
755
|
+
}
|
|
702
756
|
//#endregion
|
|
703
757
|
//#region src/tools/read-chat-turns.ts
|
|
704
758
|
const DEFAULT_TURN_LIMIT = 12;
|
|
@@ -858,11 +912,12 @@ function escapeAttr(value) {
|
|
|
858
912
|
* for the lifetime of the run.
|
|
859
913
|
*/
|
|
860
914
|
/**
|
|
861
|
-
* Lead line — short, version-stable
|
|
862
|
-
* identity prefix (
|
|
863
|
-
*
|
|
915
|
+
* Lead line — short, version-stable. The first sentence matches the key of
|
|
916
|
+
* Claude Code's identity prefix (models anchor faster on familiar shapes);
|
|
917
|
+
* the second sets the action bias every other fragment leans on. Keep
|
|
918
|
+
* changes rare — each one costs a cache miss across active sessions.
|
|
864
919
|
*/
|
|
865
|
-
const IDENTITY_PREFIX = "You are zidane, a terminal-based coding agent that helps the user with software-engineering tasks.";
|
|
920
|
+
const IDENTITY_PREFIX = "You are zidane, a terminal-based coding agent that helps the user with software-engineering tasks. Bias to action: get to the task immediately, no filler or hedging, keep every response token-lean.";
|
|
866
921
|
/**
|
|
867
922
|
* Render the env anchor block. Plain text — XML tags only because models
|
|
868
923
|
* lean on them as structural cues, not because we parse them anywhere.
|
|
@@ -897,12 +952,33 @@ function envSection(opts) {
|
|
|
897
952
|
* - Verify before claiming done — prevents false-positive reports that force a follow-up turn.
|
|
898
953
|
*/
|
|
899
954
|
const DOING_TASKS_DOCTRINE = `# Doing tasks
|
|
900
|
-
-
|
|
901
|
-
- Don't add comments, docstrings, or type annotations to code you didn't change.
|
|
902
|
-
-
|
|
903
|
-
-
|
|
904
|
-
-
|
|
905
|
-
- If you spot
|
|
955
|
+
- Do exactly what was asked — no unrequested features, refactors, or cleanup.
|
|
956
|
+
- Don't add comments, docstrings, or type annotations to code you didn't change. Comment only non-obvious WHY, never WHAT.
|
|
957
|
+
- Validate at system boundaries (user input, external APIs), not everywhere; trust internal code. No backwards-compat shims unless asked.
|
|
958
|
+
- No helpers or abstractions for one-time operations — three similar lines beat a premature abstraction.
|
|
959
|
+
- Verify before reporting done: run the test or script and report the real outcome, including failures.
|
|
960
|
+
- If you spot an adjacent bug or a flawed assumption in the request, say so.`;
|
|
961
|
+
/**
|
|
962
|
+
* Codebase-conventions doctrine. Mirrors claude-code's "following
|
|
963
|
+
* conventions" section — the single most common quality failure in build
|
|
964
|
+
* agents is inventing a dependency or style the repo doesn't use. Kept
|
|
965
|
+
* separate from {@link DOING_TASKS_DOCTRINE} so read-only profiles can
|
|
966
|
+
* drop it (plan mode proposes but doesn't write).
|
|
967
|
+
*/
|
|
968
|
+
const CONVENTIONS_DOCTRINE = `# Codebase conventions
|
|
969
|
+
- Mimic the surrounding code: style, naming, error handling, test framework.
|
|
970
|
+
- Never assume a library is available — confirm it's already used (manifest, sibling imports) before importing it.
|
|
971
|
+
- Model new components and modules on an existing one in the repo.`;
|
|
972
|
+
/**
|
|
973
|
+
* Git doctrine. {@link ACTIONS_WITH_CARE_DOCTRINE} covers force-push as a
|
|
974
|
+
* destructive action; this fragment covers the everyday cases — users ask
|
|
975
|
+
* TUI agents to commit constantly and unguided models over-stage, commit
|
|
976
|
+
* unprompted, or rewrite shared history.
|
|
977
|
+
*/
|
|
978
|
+
const GIT_DOCTRINE = `# Git
|
|
979
|
+
- Never commit, push, branch, or open PRs unless explicitly asked.
|
|
980
|
+
- When committing: stage only files relevant to the change (no blanket \`git add -A\`); write a concise message focused on the WHY.
|
|
981
|
+
- Never rewrite history you didn't author this session (amend / rebase / force-push) without confirmation. Don't modify the git config.`;
|
|
906
982
|
/**
|
|
907
983
|
* zidane-specific token-economy doctrine. No claude-code analog — this is
|
|
908
984
|
* the prose half of the `behavior.{compactStrategy, elideStaleReads,
|
|
@@ -911,27 +987,35 @@ const DOING_TASKS_DOCTRINE = `# Doing tasks
|
|
|
911
987
|
* the access patterns that defeat them.
|
|
912
988
|
*/
|
|
913
989
|
const TOKEN_DISCIPLINE_DOCTRINE = `# Working efficiently
|
|
914
|
-
-
|
|
915
|
-
-
|
|
916
|
-
- Prefer \`edit\` / \`multi_edit\` over \`write_file\` for
|
|
917
|
-
-
|
|
918
|
-
-
|
|
919
|
-
|
|
920
|
-
|
|
990
|
+
- Search first (\`grep\` / \`glob\`), then \`read_file\` the specific file — don't open a 2000-line file for one function.
|
|
991
|
+
- Don't re-read files, re-list directories, or re-run commands whose output is still visible above. When earlier output shows an \`[…elided…]\` stub, just read it again — you'll get the full content back.
|
|
992
|
+
- Prefer \`edit\` / \`multi_edit\` over \`write_file\` for changes to existing files.
|
|
993
|
+
- Use \`spawn\` for self-contained research or codegen that doesn't need your context; only its final report comes back.
|
|
994
|
+
- Large outputs may be replaced inline by a \`<persisted-output … path="…">\` block with a short preview — \`read_file\` that path when the preview isn't enough. Copy load-bearing data into your response text before it can scroll away.`;
|
|
995
|
+
/**
|
|
996
|
+
* Read-only variant of {@link TOKEN_DISCIPLINE_DOCTRINE} for plan-mode
|
|
997
|
+
* profiles. Drops the \`edit\`/\`multi_edit\`/\`write_file\` bullet and the
|
|
998
|
+
* \`spawn\` bullet — none of those tools exist in the read-only tool set,
|
|
999
|
+
* and recommending \`spawn\` directly contradicted PLAN_MODE_DOCTRINE's
|
|
1000
|
+
* "you CANNOT … spawn subagents". Retained bullets mirror the Build
|
|
1001
|
+
* fragment ("re-run searches" instead of "re-run commands" — plan mode
|
|
1002
|
+
* has no shell) so the two profiles stay consistent in tone.
|
|
1003
|
+
*/
|
|
1004
|
+
const TOKEN_DISCIPLINE_DOCTRINE_READ_ONLY = `# Working efficiently
|
|
1005
|
+
- Search first (\`grep\` / \`glob\`), then \`read_file\` the specific file — don't open a 2000-line file for one function.
|
|
1006
|
+
- Don't re-read files, re-list directories, or re-run searches whose output is still visible above. When earlier output shows an \`[…elided…]\` stub, just read it again — you'll get the full content back.
|
|
1007
|
+
- Large outputs may be replaced inline by a \`<persisted-output … path="…">\` block with a short preview — \`read_file\` that path when the preview isn't enough. Copy load-bearing data into your response text before it can scroll away.`;
|
|
921
1008
|
/**
|
|
922
1009
|
* User-facing communication style. Lifted from claude-code's
|
|
923
1010
|
* `# Communicating with the user` + `# Tone and style` sections (~404-442).
|
|
924
|
-
* The "no colon before tool calls" rule matters because
|
|
925
|
-
*
|
|
926
|
-
*
|
|
1011
|
+
* The "no colon before tool calls" rule matters because the TUI renders
|
|
1012
|
+
* the model's text and the tool call as separate blocks — a trailing
|
|
1013
|
+
* colon reads as a broken sentence.
|
|
927
1014
|
*/
|
|
928
1015
|
const COMMUNICATION_DOCTRINE = `# Communicating with the user
|
|
929
|
-
-
|
|
930
|
-
-
|
|
931
|
-
-
|
|
932
|
-
- Don't use a colon before tool calls. "Let me read the file:" + tool call reads as broken — write "Let me read the file." with a period.
|
|
933
|
-
- Reference code as \`file:line\` so the user can navigate (e.g. \`src/agent.ts:1213\`).
|
|
934
|
-
- No emojis unless the user explicitly asks.`;
|
|
1016
|
+
- Your text output is what the user reads; your reasoning and full tool payloads are not shown. Briefly state what you're doing before the first tool call, then update only at load-bearing moments — root cause found, direction change, real progress. No play-by-play.
|
|
1017
|
+
- Keep responses short and concrete, in flowing prose — not em-dash-chained fragments or notation. Reference code as \`file:line\` (e.g. \`src/agent.ts:1213\`). Tables only when they help. No emojis unless asked.
|
|
1018
|
+
- End the sentence before a tool call with a period, not a colon.`;
|
|
935
1019
|
/**
|
|
936
1020
|
* Reversibility / blast-radius doctrine. Mirrors claude-code's `# Executing
|
|
937
1021
|
* actions with care` (255-267). The TUI's safe-mode already gates risky
|
|
@@ -940,9 +1024,7 @@ const COMMUNICATION_DOCTRINE = `# Communicating with the user
|
|
|
940
1024
|
* before reaching for destructive shortcuts.
|
|
941
1025
|
*/
|
|
942
1026
|
const ACTIONS_WITH_CARE_DOCTRINE = `# Executing actions with care
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
When you hit an obstacle, do not use destructive actions as a shortcut to make it go away. Measure twice, cut once.`;
|
|
1027
|
+
Local edits, tests, and reads are free to take. Destructive or shared-state actions (\`rm -rf\`, dropping tables, force-pushing, modifying CI, posting to external services) need explicit user confirmation each time — prior approval doesn't carry over. Never use a destructive action as a shortcut around an obstacle.`;
|
|
946
1028
|
/**
|
|
947
1029
|
* How to brief a subagent. Spawning a child agent is the highest-leverage
|
|
948
1030
|
* token move in zidane — a 5k-token research dive becomes a 200-token
|
|
@@ -953,14 +1035,8 @@ When you hit an obstacle, do not use destructive actions as a shortcut to make i
|
|
|
953
1035
|
* (`tools/AgentTool/prompt.ts:99-113`).
|
|
954
1036
|
*/
|
|
955
1037
|
const SUBAGENT_GUIDANCE = `# When spawning subagents
|
|
956
|
-
|
|
957
|
-
-
|
|
958
|
-
- Describe what you've already learned or ruled out.
|
|
959
|
-
- Give enough context that the child can make judgment calls, not just follow narrow steps.
|
|
960
|
-
- For investigations, hand over the question. For lookups, hand over the exact command.
|
|
961
|
-
- Never delegate understanding ("based on your findings, fix the bug"). Synthesize yourself — include file paths, line numbers, and the specific change you want.
|
|
962
|
-
|
|
963
|
-
Terse command-style prompts produce shallow, generic work.`;
|
|
1038
|
+
The child has not seen this conversation. Brief it like a colleague who just walked in: the goal and why, what you've learned or ruled out, and enough context for judgment calls. Never delegate understanding — synthesize yourself and hand over file paths, line numbers, and the specific change you want. Terse prompts produce shallow work.
|
|
1039
|
+
When spawn offers a \`model\` field, cost-tier your delegation: mechanical, parallelizable, or high-volume search work belongs on cheaper/faster models; keep synthesis and final judgment on your own model.`;
|
|
964
1040
|
/**
|
|
965
1041
|
* Plan-mode framing. Replaces the previous one-liner with explicit phases
|
|
966
1042
|
* (explore → propose → submit), drawing on claude-code's iterative-plan
|
|
@@ -968,19 +1044,13 @@ Terse command-style prompts produce shallow, generic work.`;
|
|
|
968
1044
|
* tool set in {@link PLAN_AGENT}.
|
|
969
1045
|
*/
|
|
970
1046
|
const PLAN_MODE_DOCTRINE = `# Plan mode — read-only
|
|
971
|
-
You are in PLAN mode. You can read files,
|
|
972
|
-
|
|
973
|
-
## Loop
|
|
974
|
-
1. **Explore** — Read code. Look for existing functions, utilities, and patterns to reuse.
|
|
975
|
-
2. **Ask** — When you hit an ambiguity only the user can resolve (requirements, preferences, tradeoffs), call \`ask_user\` with the full batch of questions.
|
|
976
|
-
3. **Propose** — When the plan is ready, submit it via \`present_plan\` with a concrete title, the markdown body, and optional structured steps. The user approves, rejects, or asks for revisions.
|
|
1047
|
+
You are in PLAN mode: investigate and design a proposal. You can read files, search the codebase, and search the web — you CANNOT modify files, run shell commands, or spawn subagents.
|
|
977
1048
|
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
- Surface only your recommended approach, not every alternative.
|
|
1049
|
+
1. **Explore** — read the relevant code; find existing functions and patterns to reuse. Check current docs via web search when the plan depends on external libraries.
|
|
1050
|
+
2. **Ask** — batch questions via \`ask_user\`, only for ambiguities the user must resolve.
|
|
1051
|
+
3. **Propose** — submit via \`present_plan\`: what to change, which files, what to reuse (real paths, symbols, line numbers), how to verify end-to-end. Recommend one approach, not every alternative.
|
|
982
1052
|
|
|
983
|
-
The user
|
|
1053
|
+
The user switches to Build mode to execute an approved plan.`;
|
|
984
1054
|
/**
|
|
985
1055
|
* How to use `present_plan` / `ask_user`. Kept short — the tool descriptions
|
|
986
1056
|
* carry the schema details; this prompt covers the cross-cutting *when*.
|
|
@@ -989,9 +1059,9 @@ The user will switch to Build mode to execute an approved plan.`;
|
|
|
989
1059
|
* Moved here so a custom profile can pull it in independently.
|
|
990
1060
|
*/
|
|
991
1061
|
const INTERACTION_GUIDANCE = `# Interacting with the user
|
|
992
|
-
-
|
|
993
|
-
-
|
|
994
|
-
-
|
|
1062
|
+
- \`present_plan\`: only for a concrete proposal that materially changes the workspace and needs sign-off before executing.
|
|
1063
|
+
- \`ask_user\`: only when the answer materially changes next steps; batch related questions into one call.
|
|
1064
|
+
- Don't ask what you can find out by reading the code.`;
|
|
995
1065
|
/**
|
|
996
1066
|
* Variant of {@link INTERACTION_GUIDANCE} for the no-interactive-prompts
|
|
997
1067
|
* configuration (`Settings.allowInteraction = false`). The two tools are
|
|
@@ -1000,7 +1070,7 @@ const INTERACTION_GUIDANCE = `# Interacting with the user
|
|
|
1000
1070
|
* final prose message rather than via tool calls.
|
|
1001
1071
|
*/
|
|
1002
1072
|
const INTERACTION_GUIDANCE_NO_PROMPTS = `# No interactive prompts
|
|
1003
|
-
|
|
1073
|
+
\`ask_user\` / \`present_plan\` are unavailable. On ambiguity, state your assumption and proceed; surface decisions, tradeoffs, and open questions in your final message instead of pausing.`;
|
|
1004
1074
|
/**
|
|
1005
1075
|
* Variant of {@link PLAN_MODE_DOCTRINE} for the no-interactive-prompts
|
|
1006
1076
|
* configuration. The "Ask" step is removed; "Propose" no longer calls
|
|
@@ -1008,19 +1078,12 @@ You don't have \`ask_user\` or \`present_plan\` available — interactive prompt
|
|
|
1008
1078
|
* directly in its final message.
|
|
1009
1079
|
*/
|
|
1010
1080
|
const PLAN_MODE_DOCTRINE_NO_PROMPTS = `# Plan mode — read-only
|
|
1011
|
-
You are in PLAN mode. You can read files,
|
|
1081
|
+
You are in PLAN mode: investigate and design a proposal. You can read files, search the codebase, and search the web — you CANNOT modify files, run shell commands, or spawn subagents.
|
|
1012
1082
|
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
2. **Propose** — When the plan is ready, write it directly in your final response. Cover what to change, which files to modify, what existing code to reuse (with file paths), and how to verify the change end-to-end.
|
|
1083
|
+
1. **Explore** — read the relevant code; find existing functions and patterns to reuse. Check current docs via web search when the plan depends on external libraries.
|
|
1084
|
+
2. **Propose** — write the plan in your final response: what to change, which files, what to reuse (real paths, symbols, line numbers), how to verify end-to-end. Recommend one approach, not every alternative. Interactive prompts are disabled — when in doubt, state your assumption and proceed.
|
|
1016
1085
|
|
|
1017
|
-
|
|
1018
|
-
- Cover what to change, which files to modify, what existing code to reuse (with file paths), and how to verify the change end-to-end.
|
|
1019
|
-
- Reference real symbols and line numbers from your exploration.
|
|
1020
|
-
- Surface only your recommended approach, not every alternative.
|
|
1021
|
-
- Don't pause for clarification — interactive prompts are disabled. When in doubt, state your assumption and proceed.
|
|
1022
|
-
|
|
1023
|
-
The user will switch to Build mode to execute the plan.`;
|
|
1086
|
+
The user switches to Build mode to execute the plan.`;
|
|
1024
1087
|
function buildEnvSectionFromOpts(opts) {
|
|
1025
1088
|
if (!opts.cwd) return null;
|
|
1026
1089
|
return envSection({
|
|
@@ -1054,7 +1117,9 @@ function buildBuildSystem(opts = {}) {
|
|
|
1054
1117
|
static: [
|
|
1055
1118
|
IDENTITY_PREFIX,
|
|
1056
1119
|
DOING_TASKS_DOCTRINE,
|
|
1120
|
+
CONVENTIONS_DOCTRINE,
|
|
1057
1121
|
ACTIONS_WITH_CARE_DOCTRINE,
|
|
1122
|
+
GIT_DOCTRINE,
|
|
1058
1123
|
TOKEN_DISCIPLINE_DOCTRINE,
|
|
1059
1124
|
SUBAGENT_GUIDANCE,
|
|
1060
1125
|
COMMUNICATION_DOCTRINE,
|
|
@@ -1076,7 +1141,7 @@ function buildPlanSystem(opts = {}) {
|
|
|
1076
1141
|
static: [
|
|
1077
1142
|
IDENTITY_PREFIX,
|
|
1078
1143
|
noPrompts ? PLAN_MODE_DOCTRINE_NO_PROMPTS : PLAN_MODE_DOCTRINE,
|
|
1079
|
-
|
|
1144
|
+
TOKEN_DISCIPLINE_DOCTRINE_READ_ONLY,
|
|
1080
1145
|
COMMUNICATION_DOCTRINE,
|
|
1081
1146
|
noPrompts ? INTERACTION_GUIDANCE_NO_PROMPTS : INTERACTION_GUIDANCE,
|
|
1082
1147
|
opts.userInstructions || null
|
|
@@ -1749,9 +1814,19 @@ const READ_ONLY_TOOLS = {
|
|
|
1749
1814
|
webSearch,
|
|
1750
1815
|
fetchUrl
|
|
1751
1816
|
};
|
|
1752
|
-
/**
|
|
1817
|
+
/**
|
|
1818
|
+
* Full build-mode tool slice — read + write + shell + spawn.
|
|
1819
|
+
*
|
|
1820
|
+
* `shellKill` / `waitTask` ride along with `shell`: the shell tool's
|
|
1821
|
+
* description (and the `<task-notification>` stall hint in the agent
|
|
1822
|
+
* loop) instruct the model to call `shell_kill` / `wait_task` for
|
|
1823
|
+
* background tasks, so omitting them produces tool-not-found loops the
|
|
1824
|
+
* moment a `run_in_background` task needs terminating or blocking on.
|
|
1825
|
+
*/
|
|
1753
1826
|
const BUILD_TOOLS = {
|
|
1754
1827
|
shell,
|
|
1828
|
+
shellKill,
|
|
1829
|
+
waitTask,
|
|
1755
1830
|
readFile: readFile$1,
|
|
1756
1831
|
writeFile: writeFile$1,
|
|
1757
1832
|
listFiles,
|
|
@@ -3180,6 +3255,139 @@ function useCompletion(input, providers, options = {}) {
|
|
|
3180
3255
|
]);
|
|
3181
3256
|
}
|
|
3182
3257
|
//#endregion
|
|
3258
|
+
//#region src/chat/model-chain.ts
|
|
3259
|
+
/**
|
|
3260
|
+
* Toggle `entry` in `chain`: absent → appended (it takes the next
|
|
3261
|
+
* position number), present → removed (later entries renumber by
|
|
3262
|
+
* shifting down). Pure — returns a new array.
|
|
3263
|
+
*/
|
|
3264
|
+
function toggleChainEntry(chain, entry) {
|
|
3265
|
+
const idx = chain.findIndex((e) => e.provider === entry.provider && e.model === entry.model);
|
|
3266
|
+
if (idx === -1) return [...chain, entry];
|
|
3267
|
+
return [...chain.slice(0, idx), ...chain.slice(idx + 1)];
|
|
3268
|
+
}
|
|
3269
|
+
/**
|
|
3270
|
+
* 1-based position of a pair in the chain, or `null` when absent.
|
|
3271
|
+
* Drives the numbered markers in the picker rows.
|
|
3272
|
+
*/
|
|
3273
|
+
function chainPositionOf(chain, provider, model) {
|
|
3274
|
+
const idx = chain.findIndex((e) => e.provider === provider && e.model === model);
|
|
3275
|
+
return idx === -1 ? null : idx + 1;
|
|
3276
|
+
}
|
|
3277
|
+
/** Order-sensitive equality — a reordered chain is a different chain. */
|
|
3278
|
+
function chainsEqual(a, b) {
|
|
3279
|
+
if (a.length !== b.length) return false;
|
|
3280
|
+
return a.every((e, i) => e.provider === b[i].provider && e.model === b[i].model);
|
|
3281
|
+
}
|
|
3282
|
+
/**
|
|
3283
|
+
* Did the SET of provider keys change between two chains? The agent is
|
|
3284
|
+
* built with one provider instance per distinct chain key, so a set
|
|
3285
|
+
* change requires a session re-activation (rebuild); a pure model /
|
|
3286
|
+
* order change within the same providers does not.
|
|
3287
|
+
*/
|
|
3288
|
+
function providerKeySetChanged(prev, next) {
|
|
3289
|
+
const prevKeys = new Set(prev.map((e) => e.provider));
|
|
3290
|
+
const nextKeys = new Set(next.map((e) => e.provider));
|
|
3291
|
+
if (prevKeys.size !== nextKeys.size) return true;
|
|
3292
|
+
for (const k of nextKeys) if (!prevKeys.has(k)) return true;
|
|
3293
|
+
return false;
|
|
3294
|
+
}
|
|
3295
|
+
/**
|
|
3296
|
+
* Assemble the `agent.run` `model` option from a chain.
|
|
3297
|
+
*
|
|
3298
|
+
* - Single-entry chain → the bare model id string (byte-identical to the
|
|
3299
|
+
* pre-chain behavior).
|
|
3300
|
+
* - Multi-entry chain → pinned `{ provider, model }` targets, where
|
|
3301
|
+
* `provider` is the runtime `Provider.name` resolved via
|
|
3302
|
+
* `providerNameFor` (chain entries carry chat-level `ProviderKey`s,
|
|
3303
|
+
* which need not equal the instance names the agent loop matches on).
|
|
3304
|
+
*
|
|
3305
|
+
* Throws only on an empty chain — a programmer error, since chains
|
|
3306
|
+
* always carry a primary. Stale or unresolvable entries degrade
|
|
3307
|
+
* defensively instead (never throw, never produce an entry the agent
|
|
3308
|
+
* would reject):
|
|
3309
|
+
* - Entries whose key has no resolvable name (provider not constructed
|
|
3310
|
+
* into the current agent) are dropped.
|
|
3311
|
+
* - If the PRIMARY itself doesn't resolve, or fewer than two entries
|
|
3312
|
+
* survive, fall back to the bare primary model string.
|
|
3313
|
+
*
|
|
3314
|
+
* `contextWindowFor` (optional) stamps each target with its model's
|
|
3315
|
+
* context window from the host catalog, so the loop re-bases the
|
|
3316
|
+
* auto-compact trigger when a fallback advances onto it (the host's
|
|
3317
|
+
* explicit window is sized for the PRIMARY otherwise).
|
|
3318
|
+
*/
|
|
3319
|
+
function buildRunModel(chain, providerNameFor, contextWindowFor) {
|
|
3320
|
+
const primary = chain[0];
|
|
3321
|
+
if (!primary) throw new Error("buildRunModel: chain must not be empty");
|
|
3322
|
+
if (chain.length === 1 || providerNameFor(primary.provider) === void 0) return primary.model;
|
|
3323
|
+
const resolved = [];
|
|
3324
|
+
for (const entry of chain) {
|
|
3325
|
+
const name = providerNameFor(entry.provider);
|
|
3326
|
+
if (name === void 0) continue;
|
|
3327
|
+
const contextWindow = contextWindowFor?.(entry);
|
|
3328
|
+
resolved.push({
|
|
3329
|
+
provider: name,
|
|
3330
|
+
model: entry.model,
|
|
3331
|
+
...typeof contextWindow === "number" && contextWindow > 0 ? { contextWindow } : {}
|
|
3332
|
+
});
|
|
3333
|
+
}
|
|
3334
|
+
return resolved.length > 1 ? resolved : primary.model;
|
|
3335
|
+
}
|
|
3336
|
+
/**
|
|
3337
|
+
* Validate a persisted chain read back from `state.json`. The state file
|
|
3338
|
+
* is user-editable JSON, so the value can be arbitrarily malformed —
|
|
3339
|
+
* return only the well-shaped `{ provider, model }` entries (both
|
|
3340
|
+
* non-empty strings), or `[]` for anything else. Never throws.
|
|
3341
|
+
*/
|
|
3342
|
+
function sanitizeModelChain(value) {
|
|
3343
|
+
if (!Array.isArray(value)) return [];
|
|
3344
|
+
const entries = [];
|
|
3345
|
+
for (const item of value) {
|
|
3346
|
+
if (typeof item !== "object" || item === null || !("provider" in item) || !("model" in item)) continue;
|
|
3347
|
+
const { provider, model } = item;
|
|
3348
|
+
if (typeof provider === "string" && provider.length > 0 && typeof model === "string" && model.length > 0) entries.push({
|
|
3349
|
+
provider,
|
|
3350
|
+
model
|
|
3351
|
+
});
|
|
3352
|
+
}
|
|
3353
|
+
return entries;
|
|
3354
|
+
}
|
|
3355
|
+
/**
|
|
3356
|
+
* Restore the fallback tail of a persisted chain for a resolved primary
|
|
3357
|
+
* pair. Returns entries 1+ only when the persisted chain's entry 0
|
|
3358
|
+
* matches `primary` — a divergent chain belongs to a different selection
|
|
3359
|
+
* (e.g. a `--model` launch override) and silently attaching it would
|
|
3360
|
+
* surprise. Entries whose provider isn't registered, entries equal to
|
|
3361
|
+
* the primary, and exact duplicates drop. Accepts the raw persisted
|
|
3362
|
+
* value (`state.json` is user-editable) — shape validation included.
|
|
3363
|
+
*/
|
|
3364
|
+
function restoreChainFallbacks(saved, primary, isRegistered) {
|
|
3365
|
+
const chain = sanitizeModelChain(saved);
|
|
3366
|
+
const head = chain[0];
|
|
3367
|
+
if (chain.length < 2 || !head || head.provider !== primary.provider || head.model !== primary.model) return [];
|
|
3368
|
+
return filterChainFallbacks(chain.slice(1), primary, isRegistered);
|
|
3369
|
+
}
|
|
3370
|
+
/**
|
|
3371
|
+
* Filter candidate fallback entries against a primary pair, preserving
|
|
3372
|
+
* picked order: entries whose provider `isAvailable` rejects, entries
|
|
3373
|
+
* equal to the primary, and exact duplicates drop. Shared by the
|
|
3374
|
+
* picker's apply path (live-auth availability) and persisted-chain
|
|
3375
|
+
* restore (registry availability).
|
|
3376
|
+
*/
|
|
3377
|
+
function filterChainFallbacks(entries, primary, isAvailable) {
|
|
3378
|
+
const fallbacks = [];
|
|
3379
|
+
for (const entry of entries) {
|
|
3380
|
+
if (!isAvailable(entry.provider)) continue;
|
|
3381
|
+
if (entry.provider === primary.provider && entry.model === primary.model) continue;
|
|
3382
|
+
if (fallbacks.some((f) => f.provider === entry.provider && f.model === entry.model)) continue;
|
|
3383
|
+
fallbacks.push({
|
|
3384
|
+
provider: entry.provider,
|
|
3385
|
+
model: entry.model
|
|
3386
|
+
});
|
|
3387
|
+
}
|
|
3388
|
+
return fallbacks;
|
|
3389
|
+
}
|
|
3390
|
+
//#endregion
|
|
3183
3391
|
//#region src/chat/user-config.ts
|
|
3184
3392
|
/**
|
|
3185
3393
|
* User-level config at `~/.{prefix}/config.json`. Holds global flags
|
|
@@ -3486,9 +3694,14 @@ function pickInitial(auth, providers, state, overrides = {}) {
|
|
|
3486
3694
|
if (!model) return null;
|
|
3487
3695
|
const effort = overrides.thinking ?? (modelSupportsReasoning(descriptor, model) ? state.lastEffortByModel?.[model] ?? "medium" : void 0);
|
|
3488
3696
|
const modelOptions = restoreModelOptions(descriptor, model, state.lastModelOptionsByModel);
|
|
3697
|
+
const fallbacks = restoreChainFallbacks(state.lastModelChain, {
|
|
3698
|
+
provider: auth.key,
|
|
3699
|
+
model
|
|
3700
|
+
}, (k) => providers[k] !== void 0);
|
|
3489
3701
|
return {
|
|
3490
3702
|
provider: auth,
|
|
3491
3703
|
model,
|
|
3704
|
+
...fallbacks.length > 0 ? { fallbacks } : {},
|
|
3492
3705
|
...effort ? { effort } : {},
|
|
3493
3706
|
...modelOptions ? { modelOptions } : {}
|
|
3494
3707
|
};
|
|
@@ -4815,6 +5028,7 @@ const DEFAULT_SETTINGS = {
|
|
|
4815
5028
|
safeMode: true,
|
|
4816
5029
|
loadProjectExtensions: false,
|
|
4817
5030
|
hideSubagentOutput: true,
|
|
5031
|
+
subagentModels: true,
|
|
4818
5032
|
theme: DEFAULT_THEME.id,
|
|
4819
5033
|
showAllProjects: false,
|
|
4820
5034
|
resumeLastSession: true,
|
|
@@ -4843,6 +5057,7 @@ const DEFAULT_SETTINGS = {
|
|
|
4843
5057
|
ctrlCBehavior: "quit",
|
|
4844
5058
|
terminalTitle: "off",
|
|
4845
5059
|
sessionIcon: "",
|
|
5060
|
+
attentionIcon: "",
|
|
4846
5061
|
attachmentsEnabled: true,
|
|
4847
5062
|
externalEditor: true
|
|
4848
5063
|
};
|
|
@@ -4967,6 +5182,12 @@ const SETTINGS_TOGGLES = [
|
|
|
4967
5182
|
label: "Auto-compact",
|
|
4968
5183
|
description: "summarize the conversation when context fills past the threshold below"
|
|
4969
5184
|
},
|
|
5185
|
+
{
|
|
5186
|
+
category: "agent",
|
|
5187
|
+
key: "subagentModels",
|
|
5188
|
+
label: "Allow subagents to use different models",
|
|
5189
|
+
description: "spawn gains a `model` field + `model_search` so the agent can delegate to cheaper models (off = children inherit your model)"
|
|
5190
|
+
},
|
|
4970
5191
|
{
|
|
4971
5192
|
category: "agent",
|
|
4972
5193
|
key: "resumeOnMaxTokens",
|
|
@@ -5356,6 +5577,12 @@ const SETTINGS_INPUTS = [{
|
|
|
5356
5577
|
label: "Session icon",
|
|
5357
5578
|
description: "icon prefixed before the session title when \"Terminal title\" is set to icon + session (empty = ⚽)",
|
|
5358
5579
|
placeholder: "⚽"
|
|
5580
|
+
}, {
|
|
5581
|
+
category: "ui",
|
|
5582
|
+
key: "attentionIcon",
|
|
5583
|
+
label: "Attention icon",
|
|
5584
|
+
description: "replaces the session icon while zidane waits on your input — tool approvals and question forms (empty = ⚠️)",
|
|
5585
|
+
placeholder: "⚠️"
|
|
5359
5586
|
}];
|
|
5360
5587
|
//#endregion
|
|
5361
5588
|
//#region src/chat/enabled-toggle-set.ts
|
|
@@ -5410,7 +5637,8 @@ function useEnabledToggleSet(opts) {
|
|
|
5410
5637
|
const next = new Set(enabledSet);
|
|
5411
5638
|
if (next.has(name)) next.delete(name);
|
|
5412
5639
|
else next.add(name);
|
|
5413
|
-
|
|
5640
|
+
const persisted = [...next].filter((n) => catalogKeys.has(n)).sort();
|
|
5641
|
+
setSetting(settingKey, persisted);
|
|
5414
5642
|
}, [
|
|
5415
5643
|
enabledSet,
|
|
5416
5644
|
catalogKeys,
|
|
@@ -5434,7 +5662,7 @@ const DEFAULT_MAX_FILES = 1e4;
|
|
|
5434
5662
|
* `node_modules`, `dist`, build caches — plus the `.git` dir itself.
|
|
5435
5663
|
* Best-effort; the git path is the authoritative one.
|
|
5436
5664
|
*/
|
|
5437
|
-
const FS_WALK_SKIP = new Set([
|
|
5665
|
+
const FS_WALK_SKIP = /* @__PURE__ */ new Set([
|
|
5438
5666
|
".git",
|
|
5439
5667
|
".hg",
|
|
5440
5668
|
".svn",
|
|
@@ -5461,9 +5689,10 @@ const FS_WALK_SKIP = new Set([
|
|
|
5461
5689
|
".vscode-test"
|
|
5462
5690
|
]);
|
|
5463
5691
|
/**
|
|
5464
|
-
* Discover every non-ignored file under `cwd
|
|
5465
|
-
*
|
|
5466
|
-
*
|
|
5692
|
+
* Discover every non-ignored file under `cwd`, plus the directories that
|
|
5693
|
+
* contain them (derived from the file paths, `kind: 'dir'`). Tries
|
|
5694
|
+
* `git ls-files` first; on failure (no git, not a repo, abort) walks the
|
|
5695
|
+
* fs with a hand-rolled skip list.
|
|
5467
5696
|
*
|
|
5468
5697
|
* Errors are not thrown — the function always returns an array (possibly
|
|
5469
5698
|
* empty). Callers wanting failure diagnostics can opt into them via
|
|
@@ -5601,10 +5830,32 @@ function toEntries(paths, source, maxFiles) {
|
|
|
5601
5830
|
out.push({
|
|
5602
5831
|
path,
|
|
5603
5832
|
name,
|
|
5604
|
-
source
|
|
5833
|
+
source,
|
|
5834
|
+
kind: "file"
|
|
5605
5835
|
});
|
|
5606
5836
|
if (out.length >= maxFiles) break;
|
|
5607
5837
|
}
|
|
5838
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
5839
|
+
for (const entry of out) {
|
|
5840
|
+
let p = entry.path;
|
|
5841
|
+
for (let idx = p.lastIndexOf("/"); idx > 0; idx = p.lastIndexOf("/")) {
|
|
5842
|
+
p = p.slice(0, idx);
|
|
5843
|
+
if (dirs.has(p)) break;
|
|
5844
|
+
dirs.add(p);
|
|
5845
|
+
}
|
|
5846
|
+
}
|
|
5847
|
+
let dirCount = 0;
|
|
5848
|
+
for (const path of dirs) {
|
|
5849
|
+
const lastSlash = path.lastIndexOf("/");
|
|
5850
|
+
const name = lastSlash >= 0 ? path.slice(lastSlash + 1) : path;
|
|
5851
|
+
out.push({
|
|
5852
|
+
path,
|
|
5853
|
+
name,
|
|
5854
|
+
source,
|
|
5855
|
+
kind: "dir"
|
|
5856
|
+
});
|
|
5857
|
+
if (++dirCount >= maxFiles) break;
|
|
5858
|
+
}
|
|
5608
5859
|
return out;
|
|
5609
5860
|
}
|
|
5610
5861
|
//#endregion
|
|
@@ -6197,7 +6448,7 @@ function createQuestionTool({ requestInteraction }) {
|
|
|
6197
6448
|
},
|
|
6198
6449
|
choices: {
|
|
6199
6450
|
type: "array",
|
|
6200
|
-
description: "
|
|
6451
|
+
description: "The available choices. Required when `type` is `select`; omit for other types.",
|
|
6201
6452
|
items: {
|
|
6202
6453
|
type: "object",
|
|
6203
6454
|
properties: {
|
|
@@ -6608,7 +6859,8 @@ function buildToolToggle(args) {
|
|
|
6608
6859
|
const nextMap = { ...persistedDenyAll ?? {} };
|
|
6609
6860
|
if (nextForServer.length === 0) delete nextMap[serverName];
|
|
6610
6861
|
else nextMap[serverName] = nextForServer;
|
|
6611
|
-
|
|
6862
|
+
const next = Object.keys(nextMap).length === 0 ? void 0 : nextMap;
|
|
6863
|
+
setDisabledMcpTools(next);
|
|
6612
6864
|
};
|
|
6613
6865
|
return {
|
|
6614
6866
|
enabledSet,
|
|
@@ -6876,7 +7128,7 @@ function parseMcpsFile(text) {
|
|
|
6876
7128
|
* a single space). Replacements happen ONLY outside string literals so a
|
|
6877
7129
|
* user's intentional NBSP inside a `url` or display name is left alone.
|
|
6878
7130
|
*/
|
|
6879
|
-
const PROBLEMATIC_WHITESPACE = new Set([
|
|
7131
|
+
const PROBLEMATIC_WHITESPACE = /* @__PURE__ */ new Set([
|
|
6880
7132
|
65279,
|
|
6881
7133
|
160,
|
|
6882
7134
|
8203,
|
|
@@ -7106,7 +7358,7 @@ async function runOAuthLogin(descriptor, options) {
|
|
|
7106
7358
|
* an arbitrary user-pasted URL from inside the agent process would be a
|
|
7107
7359
|
* trivial SSRF.
|
|
7108
7360
|
*/
|
|
7109
|
-
const LOOPBACK_HOSTS = new Set([
|
|
7361
|
+
const LOOPBACK_HOSTS = /* @__PURE__ */ new Set([
|
|
7110
7362
|
"127.0.0.1",
|
|
7111
7363
|
"localhost",
|
|
7112
7364
|
"::1",
|
|
@@ -7389,7 +7641,8 @@ var ShellParser = class ShellParser {
|
|
|
7389
7641
|
btick() {
|
|
7390
7642
|
this.i++;
|
|
7391
7643
|
const close = this.s.indexOf("`", this.i);
|
|
7392
|
-
const
|
|
7644
|
+
const inner = close < 0 ? this.s.slice(this.i) : this.s.slice(this.i, close);
|
|
7645
|
+
const sub = new ShellParser(inner);
|
|
7393
7646
|
sub.list();
|
|
7394
7647
|
this.heads.push(...sub.heads);
|
|
7395
7648
|
this.i = close < 0 ? this.s.length : close + 1;
|
|
@@ -8202,8 +8455,12 @@ function tagEvent(evt, owner, depth, turnId) {
|
|
|
8202
8455
|
function smoothCpsForBacklog(backlog) {
|
|
8203
8456
|
if (backlog <= 0) return 0;
|
|
8204
8457
|
if (backlog >= SMOOTH_MAX_BACKLOG_CHARS) return SMOOTH_MAX_CPS;
|
|
8205
|
-
if (backlog <= SMOOTH_BURST_BACKLOG_CHARS)
|
|
8206
|
-
|
|
8458
|
+
if (backlog <= SMOOTH_BURST_BACKLOG_CHARS) {
|
|
8459
|
+
const t = backlog / SMOOTH_BURST_BACKLOG_CHARS;
|
|
8460
|
+
return SMOOTH_BASE_CPS + t * (SMOOTH_BURST_CPS - SMOOTH_BASE_CPS);
|
|
8461
|
+
}
|
|
8462
|
+
const t = (backlog - SMOOTH_BURST_BACKLOG_CHARS) / (SMOOTH_MAX_BACKLOG_CHARS - SMOOTH_BURST_BACKLOG_CHARS);
|
|
8463
|
+
return SMOOTH_BURST_CPS + t * (SMOOTH_MAX_CPS - SMOOTH_BURST_CPS);
|
|
8207
8464
|
}
|
|
8208
8465
|
/**
|
|
8209
8466
|
* Number of characters to drain on the next smooth-mode tick + the
|
|
@@ -8514,6 +8771,6 @@ function computeTurnAnchors(items) {
|
|
|
8514
8771
|
};
|
|
8515
8772
|
}
|
|
8516
8773
|
//#endregion
|
|
8517
|
-
export { useMcpAuthState as $,
|
|
8774
|
+
export { useMcpAuthState as $, buildPlanSystem as $n, restoreChainFallbacks as $t, runOAuthLogin as A, TODOWRITE_TOOL as An, DEFAULT_THEME as At, saveMcpToolsCache as B, setTodosForRun as Bn, createDiscoverySlot as Bt, projectsFilePath as C, DEFAULT_PERSIST_EXCLUDE_TOOLS as Cn, SETTINGS_CHOICES as Ct, formatPathForCwd as D, singleAgentRegistry as Dn, clampFps as Dt, writeProjects as E, resolveAgentId as En, SettingsProvider as Et, parseMcpsFile as F, getTodosForRun as Fn, GRUVBOX_LIGHT as Ft, buildVisibleMcpRows as G, IDENTITY_PREFIX as Gn, useConfig as Gt, buildToolToggle as H, ACTIONS_WITH_CARE_DOCTRINE as Hn, useDiscovery as Ht, clearMcpToolsCache as I, isTodoTool as In, CATPPUCCIN_FRAPPE as It, createFileMcpCredentialStore as J, PLAN_MODE_DOCTRINE as Jn, buildRunModel as Jt, indexOfServerRow as K, INTERACTION_GUIDANCE as Kn, resolveConfig as Kt, loadMcpToolsCache as L, pickActiveRunId as Ln, CATPPUCCIN_LATTE as Lt, buildMcpServers as M, TODO_WRITE_COUNTS_METADATA_KEY as Mn, resolveTheme as Mt, defaultMcpsConfigPaths as N, createTodoTools as Nn, VAPORWAVE_THEME as Nt, fetchOAuthRedirect as O, TODOREAD_TOOL as On, useSettings as Ot, discoverProjectMcps as P, getArchivedTodosForRun as Pn, GRUVBOX_DARK as Pt, useMcpAuthDispatch as Q, buildBuildSystem as Qn, providerKeySetChanged as Qt, mcpToolsCachePath as R, pruneTodosByRun as Rn, CATPPUCCIN_MACCHIATO as Rt, matchesSafelistEntry as S, DEFAULT_BUDGET_EXCLUDE_TOOLS as Sn, SETTINGS_CATEGORIES as St, suggestSafelistEntries as T, accentColor as Tn, SETTINGS_TOGGLES as Tt, useMcpToolToggleMap as U, COMMUNICATION_DOCTRINE as Un, useDiscoveryOptional as Ut, subscribeMcpToolsCache as V, useActiveTodos as Vn, DiscoveryProvider as Vt, useMcpToolToggleSet as W, DOING_TASKS_DOCTRINE as Wn, ConfigProvider as Wt, patchMcpCredential as X, SUBAGENT_GUIDANCE as Xn, chainsEqual as Xt, mcpCredentialsPath as Y, PLAN_MODE_DOCTRINE_NO_PROMPTS as Yn, chainPositionOf as Yt, McpAuthProvider as Z, TOKEN_DISCIPLINE_DOCTRINE as Zn, filterChainFallbacks as Zt, useSafeModeQueue as _, discoverAgentsMd as _n, toolCallPreview as _r, buildHints as _t, useSurfaces as a, bootTick as an, createStateStore as ar, buildResumedToolResultsTurn as at, getSafelist as b, BUILTIN_AGENTS as bn, usageByModel as br, useEnabledToggleSet as bt, useStreamBuffer as c, checkForUpdate as cn, lastContextSizeFromTurns as cr, makeRequestInteraction as ct, discoverProjectSkills as d, detectPackageManager as dn, marginTopFor as dr, useInteractionsActions as dt, sanitizeModelChain as en, envSection as er, getMcpAuthStatus as et, renderSession as f, parseSemver as fn, saveState as fr, useInteractionsQueue as ft, useSafeModeActions as g, chatAutoCompactBehavior as gn, titleFromTurns as gr, truncateTrailing as gt, SafeModeProvider as h, resolvePlatformPackage as hn, sumRunCosts as hr, hintsLength as ht, useSelectStyle as i, bootProfileEnabled as in, compactSummaryEvent as ir, PRESENT_PLAN_TOOL as it, supportsOAuth as j, TODO_STATUS_GLYPHS as jn, resolveChipColor as jt, oauthUsesManualCodePaste as k, TODOS_METADATA_KEY as kn, BUILTIN_THEMES as kt, buildSkillsConfig as l, compareSemver as ln, listSessionMeta as lr, pendingInteractionsFromTurns as lt, writeSessionExport as m, performSelfUpdate as mn, stripSpawnTokensLine as mr, clipHintsToWidth as mt, ThemeProvider as n, useCompletion as nn, createChatTurnsReadTool as nr, ASK_USER_TOOL as nt, useSyntaxStyles as o, buildUpdateHint as on, deriveSessionTitle as or, createInteractionTools as ot, resolveSessionExportTarget as p, performInPlaceSelfUpdate as pn, serverToolResultSummary as pr, EMPTY_HINTS as pt, parentServerName as q, INTERACTION_GUIDANCE_NO_PROMPTS as qn, resolveStoragePaths as qt, useColors as r, tryOpenBrowser as rn, DEFAULT_SESSION_TITLE as rr, InteractionsProvider as rt, useTheme as s, useUpdateCheck as sn, eventsFromTurns as sr, isInteractionTool as st, computeTurnAnchors as t, toggleChainEntry as tn, chatReferenceTokensForPrompt as tr, reduceMcpAuth as tt, defaultSkillScanPaths as u, detectLibc as un, loadState as ur, serializeInteractionResponse as ut, IMPLICITLY_SAFE_TOOLS as v, renderAgentsMdBlock as vn, toolResultText as vr, shortChord as vt, readProjects as w, PLAN_AGENT as wn, SETTINGS_INPUTS as wt, isOnSafelist as x, DEFAULT_AGENT_ID as xn, DEFAULT_SETTINGS as xt, addToSafelist as y, BUILD_AGENT as yn, updateToolEventOutcomes as yr, listProjectFiles as yt, refreshMcpToolsCatalog as z, selectActiveTodos as zn, CATPPUCCIN_MOCHA as zt };
|
|
8518
8775
|
|
|
8519
|
-
//# sourceMappingURL=transcript-anchors-
|
|
8776
|
+
//# sourceMappingURL=transcript-anchors-BTNe1OJi.js.map
|