@pentoshi/clai 3.8.19 → 3.8.21
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 +8 -5
- package/dist/agent/compaction-summary.d.ts +1 -1
- package/dist/agent/compaction-summary.js +3 -2
- package/dist/agent/compaction-summary.js.map +1 -1
- package/dist/agent/context-breakdown.d.ts +37 -0
- package/dist/agent/context-breakdown.js +145 -0
- package/dist/agent/context-breakdown.js.map +1 -0
- package/dist/agent/context-manager.d.ts +29 -2
- package/dist/agent/context-manager.js +125 -17
- package/dist/agent/context-manager.js.map +1 -1
- package/dist/agent/continue-orient.d.ts +39 -0
- package/dist/agent/continue-orient.js +152 -0
- package/dist/agent/continue-orient.js.map +1 -0
- package/dist/agent/reliability-policy.d.ts +85 -0
- package/dist/agent/reliability-policy.js +158 -0
- package/dist/agent/reliability-policy.js.map +1 -0
- package/dist/agent/runner.js +280 -141
- package/dist/agent/runner.js.map +1 -1
- package/dist/agent/session-state.d.ts +13 -1
- package/dist/agent/session-state.js +30 -17
- package/dist/agent/session-state.js.map +1 -1
- package/dist/agent/stop-summary.d.ts +2 -2
- package/dist/agent/stop-summary.js +23 -4
- package/dist/agent/stop-summary.js.map +1 -1
- package/dist/agent/task-evidence.js +13 -0
- package/dist/agent/task-evidence.js.map +1 -1
- package/dist/agent/tool-history.d.ts +12 -0
- package/dist/agent/tool-history.js +159 -0
- package/dist/agent/tool-history.js.map +1 -1
- package/dist/agent/tool-output-formatting.d.ts +4 -0
- package/dist/agent/tool-output-formatting.js +21 -8
- package/dist/agent/tool-output-formatting.js.map +1 -1
- package/dist/app/controllers/session-compact-helper.d.ts +2 -0
- package/dist/app/controllers/session-compact-helper.js +14 -5
- package/dist/app/controllers/session-compact-helper.js.map +1 -1
- package/dist/app/controllers/session-controller.d.ts +6 -0
- package/dist/app/controllers/session-controller.js +27 -2
- package/dist/app/controllers/session-controller.js.map +1 -1
- package/dist/commands/providers.js +57 -26
- package/dist/commands/providers.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/llm/gemini.js +4 -1
- package/dist/llm/gemini.js.map +1 -1
- package/dist/llm/http.js +22 -12
- package/dist/llm/http.js.map +1 -1
- package/dist/llm/key-rotation.d.ts +52 -0
- package/dist/llm/key-rotation.js +122 -0
- package/dist/llm/key-rotation.js.map +1 -0
- package/dist/llm/provider.d.ts +2 -0
- package/dist/llm/provider.js +8 -0
- package/dist/llm/provider.js.map +1 -1
- package/dist/llm/router.d.ts +15 -2
- package/dist/llm/router.js +318 -125
- package/dist/llm/router.js.map +1 -1
- package/dist/prompts/embedded.js +1 -1
- package/dist/prompts/embedded.js.map +1 -1
- package/dist/prompts/index.d.ts +25 -0
- package/dist/prompts/index.js +55 -7
- package/dist/prompts/index.js.map +1 -1
- package/dist/prompts/system.agent.md +4 -3
- package/dist/repl/slash-commands.js +14 -8
- package/dist/repl/slash-commands.js.map +1 -1
- package/dist/repl.d.ts +4 -1
- package/dist/repl.js +12 -2
- package/dist/repl.js.map +1 -1
- package/dist/store/config.d.ts +18 -0
- package/dist/store/config.js +9 -0
- package/dist/store/config.js.map +1 -1
- package/dist/store/history.d.ts +8 -0
- package/dist/store/history.js +38 -0
- package/dist/store/history.js.map +1 -1
- package/dist/store/keys.d.ts +55 -0
- package/dist/store/keys.js +226 -21
- package/dist/store/keys.js.map +1 -1
- package/dist/store/logs.js +35 -12
- package/dist/store/logs.js.map +1 -1
- package/dist/store/paths.d.ts +13 -0
- package/dist/store/paths.js +23 -1
- package/dist/store/paths.js.map +1 -1
- package/dist/store/session-workspace.d.ts +79 -0
- package/dist/store/session-workspace.js +199 -0
- package/dist/store/session-workspace.js.map +1 -0
- package/dist/tools/definitions.js +17 -2
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/http.d.ts +10 -0
- package/dist/tools/http.js +293 -58
- package/dist/tools/http.js.map +1 -1
- package/dist/tools/pentest-workflows.js +38 -19
- package/dist/tools/pentest-workflows.js.map +1 -1
- package/dist/tools/registry.js +26 -2
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/shell.d.ts +1 -1
- package/dist/tui/format-keys.js +29 -6
- package/dist/tui/format-keys.js.map +1 -1
- package/dist/tui-v2/app/App.js +39 -1
- package/dist/tui-v2/app/App.js.map +1 -1
- package/dist/tui-v2/app/command-handlers.js +1 -2
- package/dist/tui-v2/app/command-handlers.js.map +1 -1
- package/dist/tui-v2/app/commands/config-commands.d.ts +1 -2
- package/dist/tui-v2/app/commands/config-commands.js +1 -11
- package/dist/tui-v2/app/commands/config-commands.js.map +1 -1
- package/dist/tui-v2/app/commands/key-commands.d.ts +1 -1
- package/dist/tui-v2/app/commands/key-commands.js +148 -63
- package/dist/tui-v2/app/commands/key-commands.js.map +1 -1
- package/dist/tui-v2/app/commands/picker-commands.js +13 -7
- package/dist/tui-v2/app/commands/picker-commands.js.map +1 -1
- package/dist/tui-v2/bootstrap/composition-root.js +8 -5
- package/dist/tui-v2/bootstrap/composition-root.js.map +1 -1
- package/dist/tui-v2/bootstrap/start-tui-v2.js +10 -4
- package/dist/tui-v2/bootstrap/start-tui-v2.js.map +1 -1
- package/dist/tui-v2/components/modal/keys-modal.d.ts +19 -0
- package/dist/tui-v2/components/modal/keys-modal.js +203 -0
- package/dist/tui-v2/components/modal/keys-modal.js.map +1 -0
- package/dist/tui-v2/components/modal/secret-modal.d.ts +3 -1
- package/dist/tui-v2/components/modal/secret-modal.js +110 -18
- package/dist/tui-v2/components/modal/secret-modal.js.map +1 -1
- package/dist/tui-v2/components/overlay/overlay-host.js +6 -2
- package/dist/tui-v2/components/overlay/overlay-host.js.map +1 -1
- package/dist/tui-v2/components/pager/pager-line.js +5 -2
- package/dist/tui-v2/components/pager/pager-line.js.map +1 -1
- package/dist/tui-v2/components/pager/pager.js +6 -3
- package/dist/tui-v2/components/pager/pager.js.map +1 -1
- package/dist/tui-v2/components/plan/use-pane-presence.d.ts +6 -4
- package/dist/tui-v2/components/plan/use-pane-presence.js +8 -45
- package/dist/tui-v2/components/plan/use-pane-presence.js.map +1 -1
- package/dist/tui-v2/components/toast/toast-anim.d.ts +5 -4
- package/dist/tui-v2/components/toast/toast-anim.js +10 -7
- package/dist/tui-v2/components/toast/toast-anim.js.map +1 -1
- package/dist/tui-v2/components/toast/toast-host.d.ts +9 -3
- package/dist/tui-v2/components/toast/toast-host.js +124 -26
- package/dist/tui-v2/components/toast/toast-host.js.map +1 -1
- package/dist/tui-v2/components/transcript/assistant-message.js +4 -1
- package/dist/tui-v2/components/transcript/assistant-message.js.map +1 -1
- package/dist/tui-v2/components/transcript/compacted-row.js +1 -1
- package/dist/tui-v2/components/transcript/compacted-row.js.map +1 -1
- package/dist/tui-v2/components/transcript/file-diff-card.js +3 -23
- package/dist/tui-v2/components/transcript/file-diff-card.js.map +1 -1
- package/dist/tui-v2/components/transcript/linkable-text.js +9 -2
- package/dist/tui-v2/components/transcript/linkable-text.js.map +1 -1
- package/dist/tui-v2/components/transcript/selectable-line.d.ts +22 -0
- package/dist/tui-v2/components/transcript/selectable-line.js +24 -0
- package/dist/tui-v2/components/transcript/selectable-line.js.map +1 -0
- package/dist/tui-v2/components/transcript/thinking-block.js +3 -1
- package/dist/tui-v2/components/transcript/thinking-block.js.map +1 -1
- package/dist/tui-v2/components/transcript/tool-card.d.ts +5 -3
- package/dist/tui-v2/components/transcript/tool-card.js +39 -33
- package/dist/tui-v2/components/transcript/tool-card.js.map +1 -1
- package/dist/tui-v2/components/transcript/use-click-without-drag.js +4 -1
- package/dist/tui-v2/components/transcript/use-click-without-drag.js.map +1 -1
- package/dist/tui-v2/components/transcript/user-message.js +1 -1
- package/dist/tui-v2/components/transcript/user-message.js.map +1 -1
- package/dist/tui-v2/controllers/overlay-controller.d.ts +42 -0
- package/dist/tui-v2/controllers/overlay-controller.js +53 -0
- package/dist/tui-v2/controllers/overlay-controller.js.map +1 -1
- package/dist/tui-v2/rendering/batch-sections.d.ts +15 -4
- package/dist/tui-v2/rendering/batch-sections.js +157 -64
- package/dist/tui-v2/rendering/batch-sections.js.map +1 -1
- package/dist/tui-v2/rendering/format-help.js +1 -1
- package/dist/tui-v2/rendering/format-help.js.map +1 -1
- package/dist/tui-v2/rendering/open-tool-output.js +10 -7
- package/dist/tui-v2/rendering/open-tool-output.js.map +1 -1
- package/dist/tui-v2/rendering/pager-markdown.d.ts +9 -0
- package/dist/tui-v2/rendering/pager-markdown.js +46 -0
- package/dist/tui-v2/rendering/pager-markdown.js.map +1 -1
- package/dist/tui-v2/rendering/pager-view-policy.d.ts +6 -3
- package/dist/tui-v2/rendering/pager-view-policy.js +9 -13
- package/dist/tui-v2/rendering/pager-view-policy.js.map +1 -1
- package/dist/tui-v2/rendering/sanitize-display.js +3 -1
- package/dist/tui-v2/rendering/sanitize-display.js.map +1 -1
- package/dist/tui-v2/state/transcript-reducer.js +70 -30
- package/dist/tui-v2/state/transcript-reducer.js.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/version.generated.d.ts +2 -2
- package/dist/version.generated.js +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Soft orientation for continue / mid-work recovery after interruptions.
|
|
3
|
+
*
|
|
4
|
+
* Professional agents (Claude Code, Cursor, etc.) re-attach to interrupted
|
|
5
|
+
* work: live jobs, open tasks, last tools — they do not skip ahead and mark
|
|
6
|
+
* plan items done. This is guidance + facts, not a hard gate.
|
|
7
|
+
*/
|
|
8
|
+
export const CONTINUE_ORIENT_PREFIX = "CONTINUE / RECOVER MID-WORK";
|
|
9
|
+
/** User is asking to pick up after a pause, error, or short nudge. */
|
|
10
|
+
export function looksLikeContinueOrResumePrompt(prompt) {
|
|
11
|
+
const t = prompt.replace(/\s+/g, " ").trim();
|
|
12
|
+
if (!t)
|
|
13
|
+
return false;
|
|
14
|
+
// Bare or short continue-family prompts
|
|
15
|
+
if (/^(?:continue|resume|proceed|keep\s+going|go\s+on|finish(?:\s+it)?|next|try\s+again|retry|pick\s+up)(?:\s+please)?[.!]?$/i.test(t)) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
// Slightly longer but clearly recovery-oriented
|
|
19
|
+
if (/^(?:continue|resume|proceed|keep\s+going|go\s+on|finish|retry|try\s+again)\b.{0,80}$/i.test(t) &&
|
|
20
|
+
t.length < 100) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
if (/\b(?:continue\s+(?:from|where|the)|resume\s+(?:from|where|the)|pick\s+up\s+where|where\s+you\s+left\s+off|after\s+(?:the\s+)?(?:error|failure|timeout|interrupt))\b/i.test(t)) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
/** Last few tool results from history (newest last), high-signal one-liners. */
|
|
29
|
+
export function extractRecentToolHints(history, limit = 6) {
|
|
30
|
+
if (!history?.length)
|
|
31
|
+
return [];
|
|
32
|
+
const out = [];
|
|
33
|
+
for (let i = history.length - 1; i >= 0 && out.length < limit; i -= 1) {
|
|
34
|
+
const m = history[i];
|
|
35
|
+
if (m.role !== "tool")
|
|
36
|
+
continue;
|
|
37
|
+
const name = m.name?.trim() || guessToolName(m.content) || "tool";
|
|
38
|
+
const first = m.content
|
|
39
|
+
.split(/\r?\n/)
|
|
40
|
+
.map((l) => l.trim())
|
|
41
|
+
.find((l) => l.length > 0) ?? "";
|
|
42
|
+
out.push({
|
|
43
|
+
name,
|
|
44
|
+
...(typeof m.ok === "boolean" ? { ok: m.ok } : {}),
|
|
45
|
+
head: oneLine(first, 140),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return out.reverse();
|
|
49
|
+
}
|
|
50
|
+
function guessToolName(content) {
|
|
51
|
+
const m = content.match(/^Tool\s+(\S+)\s+result/i);
|
|
52
|
+
return m?.[1];
|
|
53
|
+
}
|
|
54
|
+
function oneLine(s, max) {
|
|
55
|
+
const t = s.replace(/\s+/g, " ").trim();
|
|
56
|
+
return t.length <= max ? t : `${t.slice(0, max - 1)}…`;
|
|
57
|
+
}
|
|
58
|
+
function jobLine(job) {
|
|
59
|
+
const cmd = oneLine(job.commandDisplay || job.command, 70);
|
|
60
|
+
const exit = job.exitCode !== undefined && job.exitCode !== null
|
|
61
|
+
? ` exit=${job.exitCode}`
|
|
62
|
+
: "";
|
|
63
|
+
return `[${job.id}] ${job.status}${exit} — ${cmd}`;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Whether this turn should receive mid-work recovery orientation.
|
|
67
|
+
* Soft: continue phrasing, or open plan work / live jobs with prior history.
|
|
68
|
+
*/
|
|
69
|
+
export function shouldInjectContinueOrientation(input) {
|
|
70
|
+
if (input.informationalQuery || input.idleOrSocial)
|
|
71
|
+
return false;
|
|
72
|
+
if (looksLikeContinueOrResumePrompt(input.prompt))
|
|
73
|
+
return true;
|
|
74
|
+
const hasHistory = (input.history?.length ?? 0) >= 2;
|
|
75
|
+
if (!hasHistory)
|
|
76
|
+
return false;
|
|
77
|
+
const openTask = input.plan?.tasks.some((t) => t.state === "in_progress" || t.state === "failed");
|
|
78
|
+
const liveJobs = (input.runningJobs?.length ?? 0) > 0;
|
|
79
|
+
// Recovery after provider/tool failure often looks like a short follow-up
|
|
80
|
+
// while work is still open (not necessarily the word "continue").
|
|
81
|
+
if ((openTask || liveJobs) && input.prompt.trim().length < 160) {
|
|
82
|
+
// Avoid hijacking a brand-new concrete request mid-session.
|
|
83
|
+
if (/\b(?:new\s+(?:task|plan|feature)|start\s+over|from\s+scratch|ignore\s+(?:the\s+)?(?:plan|previous)|different\s+(?:target|project))\b/i.test(input.prompt)) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
// Short nudges with open work → re-attach
|
|
87
|
+
if (/^(?:ok|okay|yes|y|go|do\s+it|keep\s+going|and\s+then|what\s+next|now\s+what)[.!]?$/i.test(input.prompt.trim()) ||
|
|
88
|
+
looksLikeContinueOrResumePrompt(input.prompt)) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Factual briefing + soft procedure. Empty string if nothing useful to say.
|
|
96
|
+
*/
|
|
97
|
+
export function buildContinueOrientation(input) {
|
|
98
|
+
if (!shouldInjectContinueOrientation(input))
|
|
99
|
+
return "";
|
|
100
|
+
const lines = [
|
|
101
|
+
CONTINUE_ORIENT_PREFIX,
|
|
102
|
+
"The prior turn may have been interrupted (provider error, timeout, user cancel, or a long job still running).",
|
|
103
|
+
"Re-attach to real work before advancing the plan. Do not mark tasks done or skip ahead without fresh evidence from tools this turn.",
|
|
104
|
+
];
|
|
105
|
+
const plan = input.plan;
|
|
106
|
+
if (plan) {
|
|
107
|
+
const open = plan.tasks.filter((t) => t.state === "in_progress");
|
|
108
|
+
const failed = plan.tasks.filter((t) => t.state === "failed");
|
|
109
|
+
const pending = plan.tasks.filter((t) => t.state === "pending");
|
|
110
|
+
lines.push(`Plan goal: ${oneLine(plan.goal, 120)} (status=${plan.status}, kind=${plan.kind ?? "?"})`);
|
|
111
|
+
if (open.length) {
|
|
112
|
+
lines.push(`In progress: ${open.map((t) => `[${t.id}] ${oneLine(t.title, 60)}`).join("; ")}`);
|
|
113
|
+
}
|
|
114
|
+
if (failed.length) {
|
|
115
|
+
lines.push(`Failed (retry with evidence, do not skip): ${failed.map((t) => `[${t.id}] ${oneLine(t.title, 50)}`).join("; ")}`);
|
|
116
|
+
}
|
|
117
|
+
if (pending.length) {
|
|
118
|
+
lines.push(`Pending (only after current open work is honestly finished): ${pending
|
|
119
|
+
.slice(0, 6)
|
|
120
|
+
.map((t) => `[${t.id}] ${oneLine(t.title, 40)}`)
|
|
121
|
+
.join("; ")}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const running = input.runningJobs ?? [];
|
|
125
|
+
const recent = input.recentJobs ?? [];
|
|
126
|
+
if (running.length) {
|
|
127
|
+
lines.push("Live background jobs (check before starting the same work again):");
|
|
128
|
+
for (const j of running.slice(0, 8))
|
|
129
|
+
lines.push(` ${jobLine(j)}`);
|
|
130
|
+
}
|
|
131
|
+
else if (recent.length) {
|
|
132
|
+
const interesting = recent
|
|
133
|
+
.filter((j) => /ffuf|nmap|nuclei|gobuster|ferox|masscan|hydra|sqlmap|cargo|npm|vite|next|pytest|jest|docker|make|build/i.test(j.commandDisplay || j.command))
|
|
134
|
+
.slice(0, 6);
|
|
135
|
+
if (interesting.length) {
|
|
136
|
+
lines.push("Recent jobs (may have finished while offline — tail before re-running):");
|
|
137
|
+
for (const j of interesting)
|
|
138
|
+
lines.push(` ${jobLine(j)}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const tools = extractRecentToolHints(input.history, 6);
|
|
142
|
+
if (tools.length) {
|
|
143
|
+
lines.push("Last tool results in context (do not invent outcomes):");
|
|
144
|
+
for (const t of tools) {
|
|
145
|
+
const ok = t.ok === true ? "ok" : t.ok === false ? "fail" : "?";
|
|
146
|
+
lines.push(` ${t.name} [${ok}]: ${t.head}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
lines.push("Suggested order (adapt to evidence):", "1) shell.jobs — see what is still running or just finished.", "2) shell.tail on relevant job ids (or read saved artifacts) — harvest results before new work.", "3) Resume the in_progress / failed task with real tools; only then task.update done with proof.", "4) Start the next pending task only after the current one is honestly complete.", "Avoid busy-wait loops (sleep/poll with no progress). Prefer background long jobs + other useful work, then tail.");
|
|
150
|
+
return lines.join("\n");
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=continue-orient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"continue-orient.js","sourceRoot":"","sources":["../../src/agent/continue-orient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reliability experiments from the architecture audit (E1–E6).
|
|
3
|
+
*
|
|
4
|
+
* Defaults are capability-preserving: they reduce unnecessary context / fragile
|
|
5
|
+
* free-tier overload without hard-truncating critical evidence or blocking free
|
|
6
|
+
* users. Every knob is config-backed and can be disabled independently.
|
|
7
|
+
*/
|
|
8
|
+
import type { ProviderId } from "../types.js";
|
|
9
|
+
/** Hard auto-compact ceiling — never raise soft past this. */
|
|
10
|
+
export declare const HARD_COMPACT_TOKEN_BUDGET = 100000;
|
|
11
|
+
/** E1 default: start compact earlier than the hard ceiling. */
|
|
12
|
+
export declare const DEFAULT_SOFT_COMPACT_TOKEN_BUDGET = 70000;
|
|
13
|
+
/** E2 default fs passthrough (was 400k). Full body always on disk when truncated. */
|
|
14
|
+
export declare const DEFAULT_FS_PASSTHROUGH_CAP_CHARS = 64000;
|
|
15
|
+
/** E4: warn when free-cloud context is this large. */
|
|
16
|
+
export declare const DEFAULT_FREE_TIER_WARN_TOKENS = 40000;
|
|
17
|
+
/** E4: stronger notice after this many consecutive free-tier stream failures. */
|
|
18
|
+
export declare const DEFAULT_FREE_TIER_FAIL_THRESHOLD = 2;
|
|
19
|
+
/** E3 floors — large enough for fs.write / salvage, lower than prior 32k default. */
|
|
20
|
+
export declare const ADAPTIVE_MAX_TOKENS_TOOL_STEP = 24576;
|
|
21
|
+
export declare const ADAPTIVE_MAX_TOKENS_LIGHT = 12288;
|
|
22
|
+
export declare const ADAPTIVE_MAX_TOKENS_FLOOR = 8192;
|
|
23
|
+
export declare const LEGACY_MAX_TOKENS = 32768;
|
|
24
|
+
export interface ReliabilityPolicy {
|
|
25
|
+
readonly softEarlyCompact: boolean;
|
|
26
|
+
readonly softCompactTokenBudget: number;
|
|
27
|
+
readonly hardCompactTokenBudget: number;
|
|
28
|
+
readonly fsPassthroughCapChars: number;
|
|
29
|
+
readonly adaptiveMaxTokens: boolean;
|
|
30
|
+
readonly freeTierContextGuard: boolean;
|
|
31
|
+
readonly freeTierWarnTokens: number;
|
|
32
|
+
readonly freeTierFailThreshold: number;
|
|
33
|
+
readonly toolResultDedup: boolean;
|
|
34
|
+
readonly slimNativePrompt: boolean;
|
|
35
|
+
}
|
|
36
|
+
/** Resolve effective policy from config + optional env overrides. */
|
|
37
|
+
export declare function getReliabilityPolicy(): ReliabilityPolicy;
|
|
38
|
+
/**
|
|
39
|
+
* E1: token threshold that triggers auto-compact.
|
|
40
|
+
* Soft path fires earlier; hard budget is always the ceiling used when soft is off.
|
|
41
|
+
*/
|
|
42
|
+
export declare function autoCompactTriggerTokens(policy?: ReliabilityPolicy): number;
|
|
43
|
+
/**
|
|
44
|
+
* E3: max completion tokens for a model step.
|
|
45
|
+
* Tool-heavy steps keep room for large writes; light steps use a lower cap.
|
|
46
|
+
* Never goes below {@link ADAPTIVE_MAX_TOKENS_FLOOR}.
|
|
47
|
+
*/
|
|
48
|
+
export declare function resolveStepMaxTokens(input: {
|
|
49
|
+
nativeToolsActive: boolean;
|
|
50
|
+
toolsAttached: boolean;
|
|
51
|
+
recoveryNudge?: boolean | undefined;
|
|
52
|
+
policy?: ReliabilityPolicy | undefined;
|
|
53
|
+
}): number;
|
|
54
|
+
export declare function isFreeCloudProvider(provider: ProviderId): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* E4: advisory notices for free-tier + large context / repeated failures.
|
|
57
|
+
* Never blocks the request.
|
|
58
|
+
*/
|
|
59
|
+
export declare function freeTierGuardNotices(input: {
|
|
60
|
+
provider: ProviderId;
|
|
61
|
+
estimatedInputTokens: number;
|
|
62
|
+
consecutiveFailures: number;
|
|
63
|
+
policy?: ReliabilityPolicy | undefined;
|
|
64
|
+
}): string[];
|
|
65
|
+
/** Stable hash for E5 tool-result dedup (content only). */
|
|
66
|
+
export declare function hashToolResultContent(content: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* E5: if identical tool output already appeared this turn, replace with a
|
|
69
|
+
* pointer so history does not grow with duplicate dumps. Full text remains
|
|
70
|
+
* available via artifact path when present.
|
|
71
|
+
*/
|
|
72
|
+
export declare function dedupeToolContextOutput(input: {
|
|
73
|
+
content: string;
|
|
74
|
+
toolName: string;
|
|
75
|
+
artifactPath?: string | undefined;
|
|
76
|
+
seenHashes: Map<string, {
|
|
77
|
+
toolName: string;
|
|
78
|
+
count: number;
|
|
79
|
+
}>;
|
|
80
|
+
policy?: ReliabilityPolicy | undefined;
|
|
81
|
+
}): {
|
|
82
|
+
content: string;
|
|
83
|
+
deduped: boolean;
|
|
84
|
+
hash: string;
|
|
85
|
+
};
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reliability experiments from the architecture audit (E1–E6).
|
|
3
|
+
*
|
|
4
|
+
* Defaults are capability-preserving: they reduce unnecessary context / fragile
|
|
5
|
+
* free-tier overload without hard-truncating critical evidence or blocking free
|
|
6
|
+
* users. Every knob is config-backed and can be disabled independently.
|
|
7
|
+
*/
|
|
8
|
+
import { createHash } from "node:crypto";
|
|
9
|
+
import { getConfig, providerCategory } from "../store/config.js";
|
|
10
|
+
import { AUTO_COMPACT_TOKEN_BUDGET } from "./context-manager.js";
|
|
11
|
+
/** Hard auto-compact ceiling — never raise soft past this. */
|
|
12
|
+
export const HARD_COMPACT_TOKEN_BUDGET = AUTO_COMPACT_TOKEN_BUDGET;
|
|
13
|
+
/** E1 default: start compact earlier than the hard ceiling. */
|
|
14
|
+
export const DEFAULT_SOFT_COMPACT_TOKEN_BUDGET = 70_000;
|
|
15
|
+
/** E2 default fs passthrough (was 400k). Full body always on disk when truncated. */
|
|
16
|
+
export const DEFAULT_FS_PASSTHROUGH_CAP_CHARS = 64_000;
|
|
17
|
+
/** E4: warn when free-cloud context is this large. */
|
|
18
|
+
export const DEFAULT_FREE_TIER_WARN_TOKENS = 40_000;
|
|
19
|
+
/** E4: stronger notice after this many consecutive free-tier stream failures. */
|
|
20
|
+
export const DEFAULT_FREE_TIER_FAIL_THRESHOLD = 2;
|
|
21
|
+
/** E3 floors — large enough for fs.write / salvage, lower than prior 32k default. */
|
|
22
|
+
export const ADAPTIVE_MAX_TOKENS_TOOL_STEP = 24_576;
|
|
23
|
+
export const ADAPTIVE_MAX_TOKENS_LIGHT = 12_288;
|
|
24
|
+
export const ADAPTIVE_MAX_TOKENS_FLOOR = 8_192;
|
|
25
|
+
export const LEGACY_MAX_TOKENS = 32_768;
|
|
26
|
+
function boolEnv(name) {
|
|
27
|
+
const v = process.env[name]?.trim().toLowerCase();
|
|
28
|
+
if (v === undefined || v === "")
|
|
29
|
+
return undefined;
|
|
30
|
+
if (v === "1" || v === "true" || v === "yes" || v === "on")
|
|
31
|
+
return true;
|
|
32
|
+
if (v === "0" || v === "false" || v === "no" || v === "off")
|
|
33
|
+
return false;
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
function intEnv(name) {
|
|
37
|
+
const v = process.env[name]?.trim();
|
|
38
|
+
if (!v)
|
|
39
|
+
return undefined;
|
|
40
|
+
const n = Number.parseInt(v, 10);
|
|
41
|
+
return Number.isFinite(n) ? n : undefined;
|
|
42
|
+
}
|
|
43
|
+
/** Resolve effective policy from config + optional env overrides. */
|
|
44
|
+
export function getReliabilityPolicy() {
|
|
45
|
+
const cfg = getConfig();
|
|
46
|
+
const softEarly = boolEnv("CLAI_SOFT_EARLY_COMPACT") ?? cfg.softEarlyCompact ?? true;
|
|
47
|
+
let softBudget = intEnv("CLAI_SOFT_COMPACT_TOKENS") ??
|
|
48
|
+
cfg.softCompactTokenBudget ??
|
|
49
|
+
DEFAULT_SOFT_COMPACT_TOKEN_BUDGET;
|
|
50
|
+
softBudget = Math.max(20_000, Math.min(softBudget, HARD_COMPACT_TOKEN_BUDGET));
|
|
51
|
+
let fsCap = intEnv("CLAI_FS_PASSTHROUGH_CHARS") ??
|
|
52
|
+
cfg.fsPassthroughCapChars ??
|
|
53
|
+
DEFAULT_FS_PASSTHROUGH_CAP_CHARS;
|
|
54
|
+
fsCap = Math.max(8_000, Math.min(fsCap, 400_000));
|
|
55
|
+
return {
|
|
56
|
+
softEarlyCompact: softEarly,
|
|
57
|
+
softCompactTokenBudget: softBudget,
|
|
58
|
+
hardCompactTokenBudget: HARD_COMPACT_TOKEN_BUDGET,
|
|
59
|
+
fsPassthroughCapChars: fsCap,
|
|
60
|
+
adaptiveMaxTokens: boolEnv("CLAI_ADAPTIVE_MAX_TOKENS") ?? cfg.adaptiveMaxTokens ?? true,
|
|
61
|
+
freeTierContextGuard: boolEnv("CLAI_FREE_TIER_GUARD") ?? cfg.freeTierContextGuard ?? true,
|
|
62
|
+
freeTierWarnTokens: intEnv("CLAI_FREE_TIER_WARN_TOKENS") ??
|
|
63
|
+
cfg.freeTierWarnTokens ??
|
|
64
|
+
DEFAULT_FREE_TIER_WARN_TOKENS,
|
|
65
|
+
freeTierFailThreshold: intEnv("CLAI_FREE_TIER_FAIL_THRESHOLD") ??
|
|
66
|
+
cfg.freeTierFailThreshold ??
|
|
67
|
+
DEFAULT_FREE_TIER_FAIL_THRESHOLD,
|
|
68
|
+
toolResultDedup: boolEnv("CLAI_TOOL_RESULT_DEDUP") ?? cfg.toolResultDedup ?? true,
|
|
69
|
+
slimNativePrompt: boolEnv("CLAI_SLIM_NATIVE_PROMPT") ?? cfg.slimNativePrompt ?? true,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* E1: token threshold that triggers auto-compact.
|
|
74
|
+
* Soft path fires earlier; hard budget is always the ceiling used when soft is off.
|
|
75
|
+
*/
|
|
76
|
+
export function autoCompactTriggerTokens(policy = getReliabilityPolicy()) {
|
|
77
|
+
if (!policy.softEarlyCompact)
|
|
78
|
+
return policy.hardCompactTokenBudget;
|
|
79
|
+
return Math.min(policy.softCompactTokenBudget, policy.hardCompactTokenBudget);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* E3: max completion tokens for a model step.
|
|
83
|
+
* Tool-heavy steps keep room for large writes; light steps use a lower cap.
|
|
84
|
+
* Never goes below {@link ADAPTIVE_MAX_TOKENS_FLOOR}.
|
|
85
|
+
*/
|
|
86
|
+
export function resolveStepMaxTokens(input) {
|
|
87
|
+
const policy = input.policy ?? getReliabilityPolicy();
|
|
88
|
+
if (!policy.adaptiveMaxTokens)
|
|
89
|
+
return LEGACY_MAX_TOKENS;
|
|
90
|
+
if (input.recoveryNudge) {
|
|
91
|
+
return Math.max(ADAPTIVE_MAX_TOKENS_FLOOR, ADAPTIVE_MAX_TOKENS_LIGHT);
|
|
92
|
+
}
|
|
93
|
+
if (input.toolsAttached || input.nativeToolsActive) {
|
|
94
|
+
return ADAPTIVE_MAX_TOKENS_TOOL_STEP;
|
|
95
|
+
}
|
|
96
|
+
return ADAPTIVE_MAX_TOKENS_LIGHT;
|
|
97
|
+
}
|
|
98
|
+
export function isFreeCloudProvider(provider) {
|
|
99
|
+
return providerCategory[provider] === "free-cloud";
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* E4: advisory notices for free-tier + large context / repeated failures.
|
|
103
|
+
* Never blocks the request.
|
|
104
|
+
*/
|
|
105
|
+
export function freeTierGuardNotices(input) {
|
|
106
|
+
const policy = input.policy ?? getReliabilityPolicy();
|
|
107
|
+
if (!policy.freeTierContextGuard)
|
|
108
|
+
return [];
|
|
109
|
+
if (!isFreeCloudProvider(input.provider))
|
|
110
|
+
return [];
|
|
111
|
+
const notices = [];
|
|
112
|
+
if (input.estimatedInputTokens >= policy.freeTierWarnTokens) {
|
|
113
|
+
notices.push(`Large context (~${input.estimatedInputTokens.toLocaleString()} tokens) on free-cloud model — disconnects and empty admissions are more common. Prefer /compact, a paid/local model, or shorter turns if this fails.`);
|
|
114
|
+
}
|
|
115
|
+
if (input.consecutiveFailures >= policy.freeTierFailThreshold) {
|
|
116
|
+
notices.push(`Free-cloud model failed ${input.consecutiveFailures} time(s) this turn. Switch with /model or /provider, or enable providerFallback for automatic recovery.`);
|
|
117
|
+
}
|
|
118
|
+
return notices;
|
|
119
|
+
}
|
|
120
|
+
/** Stable hash for E5 tool-result dedup (content only). */
|
|
121
|
+
export function hashToolResultContent(content) {
|
|
122
|
+
return createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* E5: if identical tool output already appeared this turn, replace with a
|
|
126
|
+
* pointer so history does not grow with duplicate dumps. Full text remains
|
|
127
|
+
* available via artifact path when present.
|
|
128
|
+
*/
|
|
129
|
+
export function dedupeToolContextOutput(input) {
|
|
130
|
+
const policy = input.policy ?? getReliabilityPolicy();
|
|
131
|
+
const hash = hashToolResultContent(input.content);
|
|
132
|
+
if (!policy.toolResultDedup) {
|
|
133
|
+
return { content: input.content, deduped: false, hash };
|
|
134
|
+
}
|
|
135
|
+
// Tiny results are not worth pointer indirection.
|
|
136
|
+
if (input.content.length < 400) {
|
|
137
|
+
input.seenHashes.set(hash, {
|
|
138
|
+
toolName: input.toolName,
|
|
139
|
+
count: (input.seenHashes.get(hash)?.count ?? 0) + 1,
|
|
140
|
+
});
|
|
141
|
+
return { content: input.content, deduped: false, hash };
|
|
142
|
+
}
|
|
143
|
+
const prior = input.seenHashes.get(hash);
|
|
144
|
+
if (!prior) {
|
|
145
|
+
input.seenHashes.set(hash, { toolName: input.toolName, count: 1 });
|
|
146
|
+
return { content: input.content, deduped: false, hash };
|
|
147
|
+
}
|
|
148
|
+
prior.count += 1;
|
|
149
|
+
const artifact = input.artifactPath
|
|
150
|
+
? ` Full output: ${input.artifactPath}`
|
|
151
|
+
: "";
|
|
152
|
+
const head = input.content.slice(0, 200).replace(/\s+/g, " ").trim();
|
|
153
|
+
const content = `[duplicate tool output — identical to earlier ${prior.toolName} this turn; hash=${hash}]${artifact}\n` +
|
|
154
|
+
`Preview: ${head}${input.content.length > 200 ? "…" : ""}\n` +
|
|
155
|
+
`Re-read the prior tool result or artifact if you need the full body; do not assume it changed.`;
|
|
156
|
+
return { content, deduped: true, hash };
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=reliability-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reliability-policy.js","sourceRoot":"","sources":["../../src/agent/reliability-policy.ts"],"names":[],"mappings":"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"}
|