@wrongstack/core 0.306.4 → 0.307.1
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/dist/chronicle/index.js +957 -953
- package/dist/chronicle/metrics-ingest.d.ts +55 -0
- package/dist/chronicle/metrics-schema.d.ts +86 -0
- package/dist/chronicle/metrics-store.d.ts +5 -120
- package/dist/chronicle/project-server.js +1083 -1084
- package/dist/chronicle/sqlite-journal-quota.d.ts +39 -0
- package/dist/chronicle/sqlite-journal-schema.d.ts +25 -0
- package/dist/chronicle/sqlite-journal.d.ts +12 -177
- package/dist/coordination/agents/index.js +1803 -1701
- package/dist/coordination/agents/project-agent-capture.d.ts +48 -0
- package/dist/coordination/agents/project-agent-identity.d.ts +3 -129
- package/dist/coordination/agents/project-agent-roster.d.ts +17 -0
- package/dist/coordination/agents/types.d.ts +6 -9
- package/dist/coordination/index.js +6051 -5880
- package/dist/coordination/mail-tools.d.ts +1 -1
- package/dist/coordination/mailbox-http-actor-query.d.ts +16 -0
- package/dist/coordination/mailbox-http-router.d.ts +0 -48
- package/dist/coordination/mailbox-http-sse.d.ts +12 -0
- package/dist/coordination/mailbox-message-types.d.ts +71 -0
- package/dist/coordination/mailbox-predicates.d.ts +13 -0
- package/dist/coordination/mailbox-project-server.js +1 -1
- package/dist/coordination/mailbox-session-sync.d.ts +8 -0
- package/dist/coordination/mailbox-types.d.ts +6 -793
- package/dist/core/agent-loop-context.d.ts +28 -0
- package/dist/core/agent-loop-detector.d.ts +25 -0
- package/dist/core/fallback-doctor.d.ts +72 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1859 -1335
- package/dist/defaults/index.js +3647 -3559
- package/dist/execution/autonomy-brain-llm.d.ts +55 -0
- package/dist/execution/autonomy-brain.d.ts +3 -156
- package/dist/execution/compaction-budget.d.ts +38 -0
- package/dist/execution/compaction-core.d.ts +3 -170
- package/dist/execution/compaction-elision.d.ts +58 -0
- package/dist/execution/council-orchestrator-helpers.d.ts +39 -0
- package/dist/execution/council-orchestrator.d.ts +3 -42
- package/dist/execution/council-response-parser.d.ts +56 -0
- package/dist/execution/index.js +2475 -2449
- package/dist/execution/prompt-enhancer.js +11 -3
- package/dist/execution/tool-executor-guard.d.ts +18 -0
- package/dist/execution/tool-executor-runner.d.ts +12 -0
- package/dist/execution/tool-executor.d.ts +0 -75
- package/dist/goal/index.js +19 -6
- package/dist/hq/index.js +8 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +8021 -7405
- package/dist/infrastructure/index.js +3 -1
- package/dist/kernel/events/agent-events.d.ts +2 -0
- package/dist/kernel/events/provider-events.d.ts +13 -0
- package/dist/plugin/index.js +2590 -2561
- package/dist/plugins/auto-review-config.d.ts +53 -0
- package/dist/plugins/auto-review-git.d.ts +19 -0
- package/dist/plugins/auto-review-plugin.d.ts +2 -140
- package/dist/plugins/review-finding-verification.d.ts +7 -0
- package/dist/prompts/index.d.ts +1 -0
- package/dist/prompts/index.js +601 -0
- package/dist/prompts/prompt-journal.d.ts +103 -0
- package/dist/security/index.js +627 -652
- package/dist/security/permission-explain.d.ts +19 -0
- package/dist/security/permission-policy.d.ts +0 -101
- package/dist/security/yolo-risk.d.ts +5 -4
- package/dist/session-catalog/index.js +220 -212
- package/dist/session-catalog/project-server.js +227 -219
- package/dist/session-catalog/store-rebuild.d.ts +9 -0
- package/dist/session-catalog/store-schema.d.ts +48 -0
- package/dist/session-catalog/store.d.ts +0 -17
- package/dist/storage/director-state.d.ts +6 -0
- package/dist/storage/file-session-writer.d.ts +2 -58
- package/dist/storage/index.d.ts +2 -1
- package/dist/storage/index.js +2057 -1925
- package/dist/storage/orphan-lock-cleaner.d.ts +15 -0
- package/dist/storage/queue-store.d.ts +6 -0
- package/dist/storage/session-recovery.d.ts +9 -0
- package/dist/storage/session-store/rename-session.d.ts +16 -0
- package/dist/storage/session-store/resume-session.d.ts +26 -0
- package/dist/storage/session-store/session-store-clear.d.ts +11 -0
- package/dist/storage/session-store/session-store-index.d.ts +13 -0
- package/dist/storage/session-store.d.ts +1 -129
- package/dist/storage/session-summary-tracker.d.ts +39 -0
- package/dist/storage/session-write-buffer.d.ts +43 -0
- package/dist/storage/session-writer/session-writer-flush.d.ts +4 -0
- package/dist/storage/session-writer/session-writer-summary-tracker.d.ts +28 -0
- package/dist/tools/fallback-agent-model-assign-tool.d.ts +18 -0
- package/dist/tools/fallback-leader-model-set-tool.d.ts +18 -0
- package/dist/tools/fallback-manage-tools.d.ts +8 -45
- package/dist/tools/fallback-profile-manage-tool.d.ts +16 -0
- package/dist/tools/fallback-provider-key-set-tool.d.ts +17 -0
- package/dist/tools/fallback-provider-manage-tool.d.ts +26 -0
- package/dist/tools/index.js +5124 -5071
- package/dist/types/config/root.d.ts +7 -2
- package/dist/types/default-config.d.ts +1 -1
- package/dist/types/index.d.ts +54 -55
- package/dist/types/index.js +953 -932
- package/dist/types/runtime-capability-manifest.d.ts +5 -5
- package/dist/types/session-markers.d.ts +12 -0
- package/dist/types/session-markers.js +19 -0
- package/dist/worktree/worktree-manager.d.ts +1 -1
- package/instructions/agents/architect.md +2 -0
- package/instructions/agents/code-reviewer.md +1 -0
- package/instructions/agents/debugger.md +2 -0
- package/instructions/agents/executor.md +2 -0
- package/instructions/agents/explore.md +3 -1
- package/instructions/agents/refactor.md +2 -0
- package/instructions/agents/reviewer.md +1 -0
- package/instructions/coordination/subagent-baseline.md +68 -7
- package/instructions/llm/prompt-enhancer.md +2 -1
- package/instructions/sections/tool/common-patterns.md +30 -0
- package/instructions/sections/tool/delegation-compact.md +3 -1
- package/instructions/sections/tool/delegation-full.md +5 -1
- package/instructions/system-lite.md +32 -4
- package/instructions/system-pro.md +63 -9
- package/instructions/system.md +56 -11
- package/package.json +9 -5
package/dist/types/index.js
CHANGED
|
@@ -12,146 +12,385 @@ function isImageBlock(b) {
|
|
|
12
12
|
return b.type === "image";
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
// src/types/
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return
|
|
23
|
-
})(ToolErrorCategory || {});
|
|
24
|
-
|
|
25
|
-
// src/types/tool-executor.ts
|
|
26
|
-
var GOVERNED_TOOL_EXECUTOR_META_KEY = "toolExecutor.executeGoverned";
|
|
27
|
-
|
|
28
|
-
// src/types/tool-markers.ts
|
|
29
|
-
var MALFORMED_ARG_MARKERS = ["__raw", "__raw_arguments", "_raw"];
|
|
30
|
-
|
|
31
|
-
// src/utils/string.ts
|
|
32
|
-
function truncate(s, max) {
|
|
33
|
-
return s.length <= max ? s : `${s.slice(0, max - 1)}\u2026`;
|
|
15
|
+
// src/types/config/fleet-chat.ts
|
|
16
|
+
var FLEET_CHAT_VERBOSITY_VALUES = ["off", "full"];
|
|
17
|
+
function resolveFleetChatVerbosity(autonomy) {
|
|
18
|
+
const explicit = autonomy?.fleetChatVerbosity;
|
|
19
|
+
if (explicit && FLEET_CHAT_VERBOSITY_VALUES.includes(explicit)) {
|
|
20
|
+
return explicit;
|
|
21
|
+
}
|
|
22
|
+
return "off";
|
|
34
23
|
}
|
|
35
24
|
|
|
36
|
-
// src/
|
|
37
|
-
function
|
|
38
|
-
|
|
25
|
+
// src/types/config/runtime.ts
|
|
26
|
+
function normalizeTokenSavingTier(val) {
|
|
27
|
+
if (val === void 0) return "off";
|
|
28
|
+
if (typeof val === "boolean") return val ? "medium" : "off";
|
|
29
|
+
if (val === "auto") return "medium";
|
|
30
|
+
const validTiers = /* @__PURE__ */ new Set([
|
|
31
|
+
"off",
|
|
32
|
+
"minimal",
|
|
33
|
+
"light",
|
|
34
|
+
"medium",
|
|
35
|
+
"aggressive"
|
|
36
|
+
]);
|
|
37
|
+
return validTiers.has(val) ? val : "off";
|
|
39
38
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
|
|
49
|
-
PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR",
|
|
50
|
-
PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW",
|
|
51
|
-
// Tool
|
|
52
|
-
TOOL_NOT_FOUND: "TOOL_NOT_FOUND",
|
|
53
|
-
TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED",
|
|
54
|
-
TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED",
|
|
55
|
-
TOOL_TIMEOUT: "TOOL_TIMEOUT",
|
|
56
|
-
TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
|
|
57
|
-
// Config
|
|
58
|
-
CONFIG_INVALID: "CONFIG_INVALID",
|
|
59
|
-
CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND",
|
|
60
|
-
CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED",
|
|
61
|
-
CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED",
|
|
62
|
-
// Plugin
|
|
63
|
-
PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED",
|
|
64
|
-
PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH",
|
|
65
|
-
PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY",
|
|
66
|
-
// Agent
|
|
67
|
-
AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT",
|
|
68
|
-
AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW",
|
|
69
|
-
AGENT_ABORTED: "AGENT_ABORTED",
|
|
70
|
-
AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
|
|
71
|
-
// Session
|
|
72
|
-
SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
|
|
73
|
-
SESSION_CORRUPTED: "SESSION_CORRUPTED",
|
|
74
|
-
SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED",
|
|
75
|
-
// Container / Registry
|
|
76
|
-
CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
|
|
77
|
-
CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
|
|
78
|
-
CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY",
|
|
79
|
-
REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE",
|
|
80
|
-
REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND",
|
|
81
|
-
REGISTRY_INVALID: "REGISTRY_INVALID",
|
|
82
|
-
// File system
|
|
83
|
-
FS_READ_FAILED: "FS_READ_FAILED",
|
|
84
|
-
FS_WRITE_FAILED: "FS_WRITE_FAILED",
|
|
85
|
-
FS_MKDIR_FAILED: "FS_MKDIR_FAILED",
|
|
86
|
-
FS_DELETE_FAILED: "FS_DELETE_FAILED",
|
|
87
|
-
FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED",
|
|
88
|
-
// SDD (Spec-Driven Development)
|
|
89
|
-
SDD_VALIDATION_FAILED: "SDD_VALIDATION_FAILED",
|
|
90
|
-
SDD_PARSE_FAILED: "SDD_PARSE_FAILED",
|
|
91
|
-
SDD_INVALID_STATE: "SDD_INVALID_STATE",
|
|
92
|
-
SDD_NOT_READY: "SDD_NOT_READY",
|
|
93
|
-
// General
|
|
94
|
-
VALIDATION_ERROR: "VALIDATION_ERROR",
|
|
95
|
-
PARSE_FAILED: "PARSE_FAILED",
|
|
96
|
-
UNKNOWN: "UNKNOWN"
|
|
97
|
-
};
|
|
98
|
-
var WrongStackError = class extends Error {
|
|
99
|
-
code;
|
|
100
|
-
subsystem;
|
|
101
|
-
severity;
|
|
102
|
-
recoverable;
|
|
103
|
-
context;
|
|
104
|
-
constructor(opts) {
|
|
105
|
-
super(opts.message, { cause: opts.cause });
|
|
106
|
-
this.name = "WrongStackError";
|
|
107
|
-
this.code = opts.code;
|
|
108
|
-
this.subsystem = opts.subsystem;
|
|
109
|
-
this.severity = opts.severity ?? "error";
|
|
110
|
-
this.recoverable = opts.recoverable ?? false;
|
|
111
|
-
this.context = opts.context;
|
|
39
|
+
function resolveTokenSavingTier(val, maxContext) {
|
|
40
|
+
if (val === "auto") {
|
|
41
|
+
if (typeof maxContext !== "number" || !Number.isFinite(maxContext) || maxContext <= 0) {
|
|
42
|
+
return "off";
|
|
43
|
+
}
|
|
44
|
+
if (maxContext < 32e3) return "medium";
|
|
45
|
+
if (maxContext < 128e3) return "light";
|
|
46
|
+
return "minimal";
|
|
112
47
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
48
|
+
return normalizeTokenSavingTier(val);
|
|
49
|
+
}
|
|
50
|
+
var DEFAULT_TUI_THINKING_WORD = "thinking";
|
|
51
|
+
var MAX_TUI_THINKING_WORD_LENGTH = 16;
|
|
52
|
+
function normalizeTuiThinkingWord(value) {
|
|
53
|
+
if (typeof value !== "string") return DEFAULT_TUI_THINKING_WORD;
|
|
54
|
+
const word = value.trim();
|
|
55
|
+
if (word.length === 0 || word.length > MAX_TUI_THINKING_WORD_LENGTH) {
|
|
56
|
+
return DEFAULT_TUI_THINKING_WORD;
|
|
120
57
|
}
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
|
|
124
|
-
return parts.length > 0 ? `[${parts.join(" ")}]` : "";
|
|
58
|
+
if (!/^[\p{L}\p{N}_-]+$/u.test(word)) return DEFAULT_TUI_THINKING_WORD;
|
|
59
|
+
return word;
|
|
125
60
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
61
|
+
|
|
62
|
+
// src/types/config/ui.ts
|
|
63
|
+
var THEME_PRESET_IDS = [
|
|
64
|
+
"catppuccin",
|
|
65
|
+
"tokyo-night",
|
|
66
|
+
"nord",
|
|
67
|
+
"cyberpunk",
|
|
68
|
+
"dracula",
|
|
69
|
+
"gruvbox-dark",
|
|
70
|
+
"solarized-dark",
|
|
71
|
+
"one-dark",
|
|
72
|
+
"monokai",
|
|
73
|
+
"rose-pine",
|
|
74
|
+
"kanagawa",
|
|
75
|
+
"ayu-dark",
|
|
76
|
+
"everforest",
|
|
77
|
+
"night-owl",
|
|
78
|
+
"synthwave",
|
|
79
|
+
"github-dark",
|
|
80
|
+
"material-ocean",
|
|
81
|
+
"nightfox",
|
|
82
|
+
"oxocarbon",
|
|
83
|
+
"catppuccin-macchiato",
|
|
84
|
+
"catppuccin-frappe",
|
|
85
|
+
"gruvbox-material",
|
|
86
|
+
"tokyo-night-storm",
|
|
87
|
+
"rose-pine-moon",
|
|
88
|
+
"zenburn",
|
|
89
|
+
"palenight",
|
|
90
|
+
"horizon",
|
|
91
|
+
"sonokai",
|
|
92
|
+
"edge-dark",
|
|
93
|
+
"moonfly",
|
|
94
|
+
"melange",
|
|
95
|
+
"poimandres",
|
|
96
|
+
"vitesse-dark",
|
|
97
|
+
"aura",
|
|
98
|
+
"dark-plus"
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
// src/utils/expect-defined.ts
|
|
102
|
+
function expectDefined(value, label) {
|
|
103
|
+
if (value === null || value === void 0) {
|
|
104
|
+
const err = new Error(label ? `Expected ${label} to be defined` : "Expected value to be defined");
|
|
105
|
+
err.name = "ExpectDefinedError";
|
|
106
|
+
throw err;
|
|
139
107
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
108
|
+
return value;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// src/types/context-window.ts
|
|
112
|
+
var DEFAULT_CONTEXT_WINDOW_MODE_ID = "balanced";
|
|
113
|
+
var DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES = Object.freeze({
|
|
114
|
+
archival: "balanced"
|
|
115
|
+
});
|
|
116
|
+
var CONTEXT_WINDOW_MODES = Object.freeze([
|
|
117
|
+
{
|
|
118
|
+
id: "balanced",
|
|
119
|
+
name: "Balanced",
|
|
120
|
+
description: "Default rolling compaction: recent work stays verbatim, old tool output is trimmed.",
|
|
121
|
+
thresholds: { warn: 0.55, soft: 0.7, hard: 0.85 },
|
|
122
|
+
aggressiveOn: "soft",
|
|
123
|
+
preserveK: 8,
|
|
124
|
+
eliseThreshold: 1200,
|
|
125
|
+
targetLoad: 0.65
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: "frugal",
|
|
129
|
+
name: "Frugal",
|
|
130
|
+
description: "Token-saver mode: compacts early and keeps a tight verbatim tail.",
|
|
131
|
+
thresholds: { warn: 0.4, soft: 0.55, hard: 0.7 },
|
|
132
|
+
aggressiveOn: "warn",
|
|
133
|
+
preserveK: 4,
|
|
134
|
+
eliseThreshold: 500,
|
|
135
|
+
targetLoad: 0.45
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
id: "deep",
|
|
139
|
+
name: "Deep",
|
|
140
|
+
description: "Long-reasoning mode: delays compaction and keeps more recent turns intact.",
|
|
141
|
+
thresholds: { warn: 0.72, soft: 0.86, hard: 0.96 },
|
|
142
|
+
aggressiveOn: "hard",
|
|
143
|
+
preserveK: 18,
|
|
144
|
+
eliseThreshold: 5e3,
|
|
145
|
+
targetLoad: 0.82
|
|
153
146
|
}
|
|
154
|
-
|
|
147
|
+
]);
|
|
148
|
+
function listContextWindowModes() {
|
|
149
|
+
return CONTEXT_WINDOW_MODES.map((m) => ({ ...m, thresholds: { ...m.thresholds } }));
|
|
150
|
+
}
|
|
151
|
+
function normalizeContextWindowModeId(id) {
|
|
152
|
+
if (!id) return null;
|
|
153
|
+
if (isContextWindowModeId(id)) return id;
|
|
154
|
+
return DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES[id] ?? null;
|
|
155
|
+
}
|
|
156
|
+
function isDeprecatedContextWindowModeId(id) {
|
|
157
|
+
return Object.hasOwn(DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES, id);
|
|
158
|
+
}
|
|
159
|
+
function isContextWindowModeSelectionId(id) {
|
|
160
|
+
return isContextWindowModeId(id) || isDeprecatedContextWindowModeId(id);
|
|
161
|
+
}
|
|
162
|
+
function getContextWindowMode(id) {
|
|
163
|
+
const normalized = normalizeContextWindowModeId(id);
|
|
164
|
+
if (!normalized) return null;
|
|
165
|
+
const mode = CONTEXT_WINDOW_MODES.find((m) => m.id === normalized);
|
|
166
|
+
return mode ? { ...mode, thresholds: { ...mode.thresholds } } : null;
|
|
167
|
+
}
|
|
168
|
+
function isContextWindowModeId(id) {
|
|
169
|
+
return CONTEXT_WINDOW_MODES.some((m) => m.id === id);
|
|
170
|
+
}
|
|
171
|
+
function resolveContextWindowPolicy(config = {}, overrideMode) {
|
|
172
|
+
const requested = overrideMode ?? config.mode ?? DEFAULT_CONTEXT_WINDOW_MODE_ID;
|
|
173
|
+
const mode = getContextWindowMode(requested) ?? expectDefined(getContextWindowMode(DEFAULT_CONTEXT_WINDOW_MODE_ID));
|
|
174
|
+
return {
|
|
175
|
+
...mode,
|
|
176
|
+
thresholds: {
|
|
177
|
+
warn: config.warnThreshold ?? mode.thresholds.warn,
|
|
178
|
+
soft: config.softThreshold ?? mode.thresholds.soft,
|
|
179
|
+
hard: config.hardThreshold ?? mode.thresholds.hard
|
|
180
|
+
},
|
|
181
|
+
preserveK: config.preserveK ?? mode.preserveK,
|
|
182
|
+
eliseThreshold: config.eliseThreshold ?? mode.eliseThreshold,
|
|
183
|
+
targetLoad: config.targetLoad ?? mode.targetLoad
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function formatContextWindowModeList(activeId) {
|
|
187
|
+
const active = normalizeContextWindowModeId(activeId);
|
|
188
|
+
return CONTEXT_WINDOW_MODES.map((m) => {
|
|
189
|
+
const marker = m.id === active ? "*" : " ";
|
|
190
|
+
return `${marker} ${m.id.padEnd(9)} ${m.name} - ${m.description}`;
|
|
191
|
+
}).join("\n");
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// src/types/default-config.ts
|
|
195
|
+
var DEFAULT_TOOLS_CONFIG = Object.freeze({
|
|
196
|
+
defaultExecutionStrategy: "smart",
|
|
197
|
+
maxIterations: 100,
|
|
198
|
+
iterationTimeoutMs: 3e5,
|
|
199
|
+
maxToolTimeoutMs: 3e5,
|
|
200
|
+
sessionTimeoutMs: 18e5,
|
|
201
|
+
perIterationOutputCapBytes: 1e5,
|
|
202
|
+
descriptionMode: Object.freeze({}),
|
|
203
|
+
disabledTools: Object.freeze([]),
|
|
204
|
+
// Extension requires an explicit host/user policy. Without that boundary a
|
|
205
|
+
// nominal maxIterations cap can grow forever in autonomous sessions.
|
|
206
|
+
autoExtendLimit: false,
|
|
207
|
+
restrictToProjectRoot: true,
|
|
208
|
+
// Off by default: the board is a record of the work, not a permit for it.
|
|
209
|
+
// See ToolsConfig.kanbanGovernance for what turning it on costs and gates.
|
|
210
|
+
kanbanGovernance: false,
|
|
211
|
+
loopDetection: Object.freeze({
|
|
212
|
+
mode: "steer-then-cut",
|
|
213
|
+
steerThreshold: 3,
|
|
214
|
+
cutThreshold: 5,
|
|
215
|
+
windowSize: 12,
|
|
216
|
+
callRepeatThreshold: 4
|
|
217
|
+
})
|
|
218
|
+
});
|
|
219
|
+
var DEFAULT_CONTEXT_CONFIG = Object.freeze({
|
|
220
|
+
warnThreshold: 0.55,
|
|
221
|
+
softThreshold: 0.7,
|
|
222
|
+
hardThreshold: 0.85,
|
|
223
|
+
targetLoad: 0.65,
|
|
224
|
+
preserveK: 8,
|
|
225
|
+
eliseThreshold: 1200
|
|
226
|
+
});
|
|
227
|
+
var DEFAULT_AUTONOMY_CONFIG = Object.freeze({
|
|
228
|
+
autoProceedDelayMs: 45e3
|
|
229
|
+
});
|
|
230
|
+
var DEFAULT_CIRCUIT_BREAKER_CONFIG = Object.freeze({
|
|
231
|
+
enabled: false,
|
|
232
|
+
autoKillResetMs: 6e4
|
|
233
|
+
});
|
|
234
|
+
var DEFAULT_SESSION_LOGGING_CONFIG = Object.freeze({
|
|
235
|
+
auditLevel: "standard",
|
|
236
|
+
sampling: {
|
|
237
|
+
toolProgress: {
|
|
238
|
+
sampleRate: 8
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
var DEFAULT_SESSION_PRUNE_DAYS = 30;
|
|
243
|
+
|
|
244
|
+
// src/types/design-kit.ts
|
|
245
|
+
var DESIGN_STACKS = ["web", "react-native", "flutter", "swiftui", "compose"];
|
|
246
|
+
function isDesignStack(v) {
|
|
247
|
+
return DESIGN_STACKS.includes(v);
|
|
248
|
+
}
|
|
249
|
+
var KNOWN_TOKEN_GROUPS = {
|
|
250
|
+
/** Corner radii. */
|
|
251
|
+
radius: ["radius-none", "radius-sm", "radius-md", "radius-lg", "radius-xl", "radius-full"],
|
|
252
|
+
/** Spacing scale (4/8px rhythm). */
|
|
253
|
+
space: ["space-1", "space-2", "space-3", "space-4", "space-6", "space-8", "space-12"],
|
|
254
|
+
/** Type sizes. */
|
|
255
|
+
text: ["text-xs", "text-sm", "text-base", "text-lg", "text-xl", "text-2xl", "text-3xl"],
|
|
256
|
+
/** Line-heights (unitless). */
|
|
257
|
+
leading: ["leading-tight", "leading-normal", "leading-relaxed"],
|
|
258
|
+
/** Font weights (unitless). */
|
|
259
|
+
weight: ["weight-normal", "weight-medium", "weight-semibold", "weight-bold"],
|
|
260
|
+
/** Letter-spacing. */
|
|
261
|
+
tracking: ["tracking-tight", "tracking-normal", "tracking-wide"],
|
|
262
|
+
/** Elevation / shadow ramp. */
|
|
263
|
+
shadow: ["shadow-1", "shadow-2", "shadow-3", "shadow-4"],
|
|
264
|
+
/** Border widths. */
|
|
265
|
+
border: ["border-hairline", "border-thin", "border-thick"],
|
|
266
|
+
/** Motion durations. */
|
|
267
|
+
duration: ["duration-fast", "duration-base", "duration-slow"],
|
|
268
|
+
/** Motion easings. */
|
|
269
|
+
ease: ["ease-standard", "ease-emphasized"],
|
|
270
|
+
/** Font families. */
|
|
271
|
+
font: ["font-sans", "font-mono", "font-display"]
|
|
272
|
+
};
|
|
273
|
+
var KNOWN_TOKEN_NAMES = Object.values(KNOWN_TOKEN_GROUPS).flat();
|
|
274
|
+
|
|
275
|
+
// src/utils/error.ts
|
|
276
|
+
function toErrorMessage(err) {
|
|
277
|
+
return err instanceof Error ? err.message : String(err);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// src/types/errors.ts
|
|
281
|
+
var ERROR_CODES = {
|
|
282
|
+
// Provider
|
|
283
|
+
PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
|
|
284
|
+
PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
|
|
285
|
+
PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
|
|
286
|
+
PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
|
|
287
|
+
PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
|
|
288
|
+
PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR",
|
|
289
|
+
PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW",
|
|
290
|
+
// Tool
|
|
291
|
+
TOOL_NOT_FOUND: "TOOL_NOT_FOUND",
|
|
292
|
+
TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED",
|
|
293
|
+
TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED",
|
|
294
|
+
TOOL_TIMEOUT: "TOOL_TIMEOUT",
|
|
295
|
+
TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
|
|
296
|
+
// Config
|
|
297
|
+
CONFIG_INVALID: "CONFIG_INVALID",
|
|
298
|
+
CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND",
|
|
299
|
+
CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED",
|
|
300
|
+
CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED",
|
|
301
|
+
// Plugin
|
|
302
|
+
PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED",
|
|
303
|
+
PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH",
|
|
304
|
+
PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY",
|
|
305
|
+
// Agent
|
|
306
|
+
AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT",
|
|
307
|
+
AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW",
|
|
308
|
+
AGENT_ABORTED: "AGENT_ABORTED",
|
|
309
|
+
AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
|
|
310
|
+
// Session
|
|
311
|
+
SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
|
|
312
|
+
SESSION_CORRUPTED: "SESSION_CORRUPTED",
|
|
313
|
+
SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED",
|
|
314
|
+
// Container / Registry
|
|
315
|
+
CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
|
|
316
|
+
CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
|
|
317
|
+
CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY",
|
|
318
|
+
REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE",
|
|
319
|
+
REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND",
|
|
320
|
+
REGISTRY_INVALID: "REGISTRY_INVALID",
|
|
321
|
+
// File system
|
|
322
|
+
FS_READ_FAILED: "FS_READ_FAILED",
|
|
323
|
+
FS_WRITE_FAILED: "FS_WRITE_FAILED",
|
|
324
|
+
FS_MKDIR_FAILED: "FS_MKDIR_FAILED",
|
|
325
|
+
FS_DELETE_FAILED: "FS_DELETE_FAILED",
|
|
326
|
+
FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED",
|
|
327
|
+
// SDD (Spec-Driven Development)
|
|
328
|
+
SDD_VALIDATION_FAILED: "SDD_VALIDATION_FAILED",
|
|
329
|
+
SDD_PARSE_FAILED: "SDD_PARSE_FAILED",
|
|
330
|
+
SDD_INVALID_STATE: "SDD_INVALID_STATE",
|
|
331
|
+
SDD_NOT_READY: "SDD_NOT_READY",
|
|
332
|
+
// General
|
|
333
|
+
VALIDATION_ERROR: "VALIDATION_ERROR",
|
|
334
|
+
PARSE_FAILED: "PARSE_FAILED",
|
|
335
|
+
UNKNOWN: "UNKNOWN"
|
|
336
|
+
};
|
|
337
|
+
var WrongStackError = class extends Error {
|
|
338
|
+
code;
|
|
339
|
+
subsystem;
|
|
340
|
+
severity;
|
|
341
|
+
recoverable;
|
|
342
|
+
context;
|
|
343
|
+
constructor(opts) {
|
|
344
|
+
super(opts.message, { cause: opts.cause });
|
|
345
|
+
this.name = "WrongStackError";
|
|
346
|
+
this.code = opts.code;
|
|
347
|
+
this.subsystem = opts.subsystem;
|
|
348
|
+
this.severity = opts.severity ?? "error";
|
|
349
|
+
this.recoverable = opts.recoverable ?? false;
|
|
350
|
+
this.context = opts.context;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Render a one-line user-facing description.
|
|
354
|
+
* Subclasses should override for domain-specific formatting.
|
|
355
|
+
*/
|
|
356
|
+
describe() {
|
|
357
|
+
const ctx = this.context ? ` ${formatContext(this.context)}` : "";
|
|
358
|
+
return `${this.code}: ${this.message}${ctx}`;
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
function formatContext(ctx) {
|
|
362
|
+
const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
|
|
363
|
+
return parts.length > 0 ? `[${parts.join(" ")}]` : "";
|
|
364
|
+
}
|
|
365
|
+
var ToolError = class extends WrongStackError {
|
|
366
|
+
toolName;
|
|
367
|
+
constructor(opts) {
|
|
368
|
+
super({
|
|
369
|
+
message: opts.message,
|
|
370
|
+
code: opts.code,
|
|
371
|
+
subsystem: "tool",
|
|
372
|
+
recoverable: opts.recoverable,
|
|
373
|
+
context: { tool: opts.toolName, ...opts.context },
|
|
374
|
+
cause: opts.cause
|
|
375
|
+
});
|
|
376
|
+
this.name = "ToolError";
|
|
377
|
+
this.toolName = opts.toolName;
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
var ConfigError = class extends WrongStackError {
|
|
381
|
+
constructor(opts) {
|
|
382
|
+
super({
|
|
383
|
+
message: opts.message,
|
|
384
|
+
code: opts.code,
|
|
385
|
+
subsystem: "config",
|
|
386
|
+
severity: "fatal",
|
|
387
|
+
recoverable: false,
|
|
388
|
+
context: opts.context,
|
|
389
|
+
cause: opts.cause
|
|
390
|
+
});
|
|
391
|
+
this.name = "ConfigError";
|
|
392
|
+
}
|
|
393
|
+
};
|
|
155
394
|
var PluginError = class extends WrongStackError {
|
|
156
395
|
pluginName;
|
|
157
396
|
constructor(opts) {
|
|
@@ -317,499 +556,229 @@ function isSddError(err) {
|
|
|
317
556
|
return err instanceof SddError;
|
|
318
557
|
}
|
|
319
558
|
|
|
320
|
-
// src/types/
|
|
321
|
-
var
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
var CONTENT_FILTER_RE = /content.(filter|policy|moderation)|safety (system|filter)/i;
|
|
329
|
-
var RATE_LIMIT_EXCEEDED_RE = /rate[-_\s]*limit[-_\s]*exceeded/i;
|
|
330
|
-
function classifyProviderError(status, body, message) {
|
|
331
|
-
const type = body?.type;
|
|
332
|
-
const text = [message, body?.message, type, body?.raw].filter(Boolean).join("\n");
|
|
333
|
-
if (status === 0) return "network";
|
|
334
|
-
if (status === 408) return "timeout";
|
|
335
|
-
if (status === 599) return "stream_hang";
|
|
336
|
-
if (status === 402 || QUOTA_EXHAUSTED_RE.test(text)) return "quota_exhausted";
|
|
337
|
-
if (status === 429 && body?.message && body.type !== "rate_limit_exceeded" && RATE_LIMIT_EXCEEDED_RE.test(body.message)) {
|
|
338
|
-
return "quota_exhausted";
|
|
339
|
-
}
|
|
340
|
-
if (type === "rate_limit_error" || status === 429) return "rate_limit";
|
|
341
|
-
if (type === "overloaded_error" || status === 529) return "overloaded";
|
|
342
|
-
if (status >= 500) return "server";
|
|
343
|
-
if (type === "authentication_error" || type === "permission_error" || status === 401 || status === 403) {
|
|
344
|
-
return "auth";
|
|
345
|
-
}
|
|
346
|
-
if (type === "content_filter" || CONTENT_FILTER_RE.test(text)) return "content_filter";
|
|
347
|
-
if (status === 413 || status >= 400 && CONTEXT_OVERFLOW_RE.test(text)) {
|
|
348
|
-
return "context_overflow";
|
|
349
|
-
}
|
|
350
|
-
if (status >= 400) return "invalid_request";
|
|
351
|
-
return "unknown";
|
|
352
|
-
}
|
|
353
|
-
var MAX_RESET_HINT_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
354
|
-
function isRetryableKind(kind) {
|
|
355
|
-
return RETRYABLE_BY_KIND[kind];
|
|
356
|
-
}
|
|
357
|
-
var RETRYABLE_BY_KIND = {
|
|
358
|
-
rate_limit: true,
|
|
359
|
-
quota_exhausted: false,
|
|
360
|
-
overloaded: true,
|
|
361
|
-
server: true,
|
|
362
|
-
timeout: true,
|
|
363
|
-
network: true,
|
|
364
|
-
stream_hang: true,
|
|
365
|
-
auth: false,
|
|
366
|
-
context_overflow: false,
|
|
367
|
-
content_filter: false,
|
|
368
|
-
invalid_request: false,
|
|
369
|
-
unknown: false
|
|
559
|
+
// src/types/memory.ts
|
|
560
|
+
var MEMORY_TYPE_LABELS = {
|
|
561
|
+
fact: "Fact",
|
|
562
|
+
decision: "Decision",
|
|
563
|
+
convention: "Convention",
|
|
564
|
+
preference: "Preference",
|
|
565
|
+
reference: "Reference",
|
|
566
|
+
anti_pattern: "Anti-pattern"
|
|
370
567
|
};
|
|
371
|
-
function
|
|
372
|
-
return
|
|
568
|
+
function defineMemoryCapability(id) {
|
|
569
|
+
return Object.freeze({
|
|
570
|
+
id,
|
|
571
|
+
/** Identity function that makes the brand a real runtime value so
|
|
572
|
+
* `defineMemoryCapability<A>('x')` and `defineMemoryCapability<B>('x')`
|
|
573
|
+
* produce structurally distinct objects. Capability lookup is still
|
|
574
|
+
* keyed by `id` only — the brand prevents accidental cross-type casts
|
|
575
|
+
* at the type level. */
|
|
576
|
+
__memoryCapabilityType: (v) => v
|
|
577
|
+
});
|
|
373
578
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
content_filter: false,
|
|
385
|
-
invalid_request: false,
|
|
386
|
-
unknown: false
|
|
387
|
-
};
|
|
388
|
-
var ProviderError = class extends WrongStackError {
|
|
389
|
-
status;
|
|
390
|
-
retryable;
|
|
391
|
-
providerId;
|
|
392
|
-
/** Canonical failure classification — see {@link ProviderErrorKind}. */
|
|
393
|
-
kind;
|
|
394
|
-
body;
|
|
395
|
-
/**
|
|
396
|
-
* Duck-type guard: checks whether an unknown value *looks like* a
|
|
397
|
-
* ProviderError by probing for its structural properties. Use this
|
|
398
|
-
* anywhere the constructor identity might cross a package boundary
|
|
399
|
-
* (e.g. `@wrongstack/providers` creates the error, but the runner in
|
|
400
|
-
* `@wrongstack/core` checks it). A plain `instanceof ProviderError`
|
|
401
|
-
* can fail when npm hoists duplicate copies of `@wrongstack/core`,
|
|
402
|
-
* each with its own class identity.
|
|
403
|
-
*
|
|
404
|
-
* The check tests for the four invariant properties defined in the
|
|
405
|
-
* constructor: `name === 'ProviderError'`, `status` (number),
|
|
406
|
-
* `retryable` (boolean), and `kind` (string). This tolerates both
|
|
407
|
-
* true `ProviderError` instances and cross-boundary copies.
|
|
408
|
-
*/
|
|
409
|
-
static isProviderError(err) {
|
|
410
|
-
if (!err || typeof err !== "object") return false;
|
|
411
|
-
const e = err;
|
|
412
|
-
const name = e.name;
|
|
413
|
-
if (typeof name !== "string" || !name.endsWith("Error")) return false;
|
|
414
|
-
return typeof e.status === "number" && typeof e.retryable === "boolean" && typeof e.kind === "string" && typeof e.describe === "function";
|
|
415
|
-
}
|
|
416
|
-
constructor(message, status, retryable, providerId, opts = {}) {
|
|
417
|
-
const kind = opts.kind ?? classifyProviderError(status, opts.body, message);
|
|
418
|
-
super({
|
|
419
|
-
message,
|
|
420
|
-
code: kindToCode(kind),
|
|
421
|
-
subsystem: "provider",
|
|
422
|
-
severity: status >= 500 ? "error" : "warning",
|
|
423
|
-
recoverable: retryable,
|
|
424
|
-
context: { providerId, status },
|
|
425
|
-
cause: opts.cause
|
|
426
|
-
});
|
|
427
|
-
this.name = "ProviderError";
|
|
428
|
-
this.status = status;
|
|
429
|
-
this.retryable = retryable;
|
|
430
|
-
this.providerId = providerId;
|
|
431
|
-
this.kind = kind;
|
|
432
|
-
this.body = opts.body;
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
|
-
* Render a one-line, user-facing description. Designed for the CLI/TUI
|
|
436
|
-
* status line and the agent's retry warning. Avoids dumping raw JSON
|
|
437
|
-
* (which is what users see today when a 529 lands and the log message
|
|
438
|
-
* includes the full `{"type":"error",...}` body).
|
|
439
|
-
*
|
|
440
|
-
* Examples:
|
|
441
|
-
* "minimax-coding-plan overloaded (529): High traffic detected. Upgrade for highspeed model. [req 06534785201de9c0…]"
|
|
442
|
-
* "openai rate limited (429): Retry after 12s"
|
|
443
|
-
* "anthropic invalid request (400): messages.0.role must be one of 'user'|'assistant'"
|
|
444
|
-
* "groq HTTP 500 (server error)"
|
|
445
|
-
*/
|
|
446
|
-
describe() {
|
|
447
|
-
const kind = describeStatus(this.status, this.body?.type);
|
|
448
|
-
const head = `${this.providerId} ${kind}`;
|
|
449
|
-
const detail = this.body?.message?.trim();
|
|
450
|
-
const reqId = this.body?.requestId ? ` [req ${this.body.requestId.slice(0, 16)}${this.body.requestId.length > 16 ? "\u2026" : ""}]` : "";
|
|
451
|
-
if (detail && detail.length > 0) {
|
|
452
|
-
return `${head}: ${truncate(detail, 240)}${reqId}`;
|
|
579
|
+
|
|
580
|
+
// src/types/mode-prompts.ts
|
|
581
|
+
import { readFileSync, statSync } from "node:fs";
|
|
582
|
+
import * as path from "node:path";
|
|
583
|
+
import { fileURLToPath } from "node:url";
|
|
584
|
+
function modePrompt(id) {
|
|
585
|
+
for (const dir of modePromptDirCandidates()) {
|
|
586
|
+
try {
|
|
587
|
+
return readFileSync(path.join(dir, `${id}.md`), "utf8").trimEnd();
|
|
588
|
+
} catch {
|
|
453
589
|
}
|
|
454
|
-
return `${head}${reqId}`;
|
|
455
590
|
}
|
|
456
|
-
|
|
457
|
-
function isContextOverflowShaped(err) {
|
|
458
|
-
if (!(err instanceof ProviderError) && !ProviderError.isProviderError(err)) return false;
|
|
459
|
-
const providerErr = err;
|
|
460
|
-
if (providerErr.kind === "context_overflow" || providerErr.status === 413) return true;
|
|
461
|
-
if (providerErr.status < 400) return false;
|
|
462
|
-
const text = [providerErr.message, providerErr.body?.message, providerErr.body?.type, providerErr.body?.raw].filter(Boolean).join("\n");
|
|
463
|
-
return CONTEXT_OVERFLOW_RE.test(text);
|
|
464
|
-
}
|
|
465
|
-
function describeStatus(status, type) {
|
|
466
|
-
if (status === 0) return "network error";
|
|
467
|
-
if (status === 599) return `stream hang (${status})`;
|
|
468
|
-
if (type === "overloaded_error" || status === 529) return `overloaded (${status})`;
|
|
469
|
-
if (type === "rate_limit_error" || status === 429) return `rate limited (${status})`;
|
|
470
|
-
if (type === "authentication_error" || status === 401) return `auth failed (${status})`;
|
|
471
|
-
if (type === "permission_error" || status === 403) return `forbidden (${status})`;
|
|
472
|
-
if (type === "not_found_error" || status === 404) return `not found (${status})`;
|
|
473
|
-
if (type === "content_filter") return `content filtered (${status})`;
|
|
474
|
-
if (type === "invalid_request_error" || status === 400) return `invalid request (${status})`;
|
|
475
|
-
if (status === 408) return `timeout (${status})`;
|
|
476
|
-
if (status >= 500 && status < 600) return `HTTP ${status} (server error)`;
|
|
477
|
-
if (type) return `${type} (${status})`;
|
|
478
|
-
return `HTTP ${status}`;
|
|
591
|
+
return "";
|
|
479
592
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
bytesReceived;
|
|
489
|
-
/** Elapsed time (ms) from the start of the stream until the hang. */
|
|
490
|
-
elapsedMs;
|
|
491
|
-
constructor(opts) {
|
|
492
|
-
super(
|
|
493
|
-
`Stream hang: ${opts.providerId}/${opts.model} \u2014 no data for ${opts.hangTimeoutMs}ms after ${opts.bytesReceived} bytes (${opts.elapsedMs}ms elapsed)`,
|
|
494
|
-
599,
|
|
495
|
-
true,
|
|
496
|
-
// always retryable
|
|
497
|
-
opts.providerId,
|
|
498
|
-
{
|
|
499
|
-
body: {
|
|
500
|
-
message: `Stream stalled after ${opts.elapsedMs}ms, ${opts.bytesReceived} bytes received`
|
|
501
|
-
},
|
|
502
|
-
cause: opts.cause
|
|
503
|
-
}
|
|
504
|
-
);
|
|
505
|
-
this.name = "StreamHangError";
|
|
506
|
-
this.hungProviderId = opts.providerId;
|
|
507
|
-
this.hungModel = opts.model;
|
|
508
|
-
this.hangTimeoutMs = opts.hangTimeoutMs;
|
|
509
|
-
this.bytesReceived = opts.bytesReceived;
|
|
510
|
-
this.elapsedMs = opts.elapsedMs;
|
|
511
|
-
}
|
|
512
|
-
};
|
|
513
|
-
var KIND_TO_CODE = {
|
|
514
|
-
network: ERROR_CODES.PROVIDER_NETWORK_ERROR,
|
|
515
|
-
timeout: ERROR_CODES.PROVIDER_NETWORK_ERROR,
|
|
516
|
-
rate_limit: ERROR_CODES.PROVIDER_RATE_LIMITED,
|
|
517
|
-
quota_exhausted: ERROR_CODES.PROVIDER_RATE_LIMITED,
|
|
518
|
-
auth: ERROR_CODES.PROVIDER_AUTH_FAILED,
|
|
519
|
-
overloaded: ERROR_CODES.PROVIDER_OVERLOADED,
|
|
520
|
-
context_overflow: ERROR_CODES.PROVIDER_CONTEXT_OVERFLOW,
|
|
521
|
-
server: ERROR_CODES.PROVIDER_SERVER_ERROR,
|
|
522
|
-
stream_hang: ERROR_CODES.PROVIDER_SERVER_ERROR,
|
|
523
|
-
content_filter: ERROR_CODES.PROVIDER_INVALID_REQUEST,
|
|
524
|
-
invalid_request: ERROR_CODES.PROVIDER_INVALID_REQUEST,
|
|
525
|
-
unknown: ERROR_CODES.PROVIDER_INVALID_REQUEST
|
|
526
|
-
};
|
|
527
|
-
function kindToCode(kind) {
|
|
528
|
-
return KIND_TO_CODE[kind];
|
|
593
|
+
function modePromptDirCandidates() {
|
|
594
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
595
|
+
const candidates = [
|
|
596
|
+
path.resolve(here, "../../instructions/modes"),
|
|
597
|
+
path.resolve(here, "../instructions/modes"),
|
|
598
|
+
path.resolve(here, "instructions/modes")
|
|
599
|
+
];
|
|
600
|
+
return candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));
|
|
529
601
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
if (explicit && FLEET_CHAT_VERBOSITY_VALUES.includes(explicit)) {
|
|
536
|
-
return explicit;
|
|
602
|
+
function isDirectory(candidate) {
|
|
603
|
+
try {
|
|
604
|
+
return statSync(candidate).isDirectory();
|
|
605
|
+
} catch {
|
|
606
|
+
return false;
|
|
537
607
|
}
|
|
538
|
-
return "off";
|
|
539
608
|
}
|
|
540
609
|
|
|
541
|
-
// src/types/
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
"
|
|
548
|
-
"
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
"
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
return {
|
|
712
|
-
ts: ev.ts,
|
|
713
|
-
source: ev.type,
|
|
714
|
-
level: "info",
|
|
715
|
-
text: `skill activated: ${ev.skillName}`
|
|
716
|
-
};
|
|
717
|
-
case "skill_deactivated":
|
|
718
|
-
return {
|
|
719
|
-
ts: ev.ts,
|
|
720
|
-
source: ev.type,
|
|
721
|
-
level: "info",
|
|
722
|
-
text: `skill deactivated: ${ev.skillName}`
|
|
723
|
-
};
|
|
724
|
-
case "message_truncated":
|
|
725
|
-
return {
|
|
726
|
-
ts: ev.ts,
|
|
727
|
-
source: ev.type,
|
|
728
|
-
level: "warn",
|
|
729
|
-
text: ev.after < ev.before ? `message truncated: ${ev.before} \u2192 ${ev.after} tokens` : `message truncated at ${ev.after} tokens`
|
|
730
|
-
};
|
|
731
|
-
default:
|
|
732
|
-
return null;
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
function projectSessionMarkers(events, sources = SESSION_MARKER_EVENT_TYPES) {
|
|
736
|
-
const markers = [];
|
|
737
|
-
for (const ev of events) {
|
|
738
|
-
if (!sources.has(ev.type)) continue;
|
|
739
|
-
const marker = sessionEventToMarker(ev);
|
|
740
|
-
if (marker) markers.push(marker);
|
|
741
|
-
}
|
|
742
|
-
return markers;
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
// src/types/default-config.ts
|
|
746
|
-
var DEFAULT_TOOLS_CONFIG = Object.freeze({
|
|
747
|
-
defaultExecutionStrategy: "smart",
|
|
748
|
-
maxIterations: 100,
|
|
749
|
-
iterationTimeoutMs: 3e5,
|
|
750
|
-
maxToolTimeoutMs: 3e5,
|
|
751
|
-
sessionTimeoutMs: 18e5,
|
|
752
|
-
perIterationOutputCapBytes: 1e5,
|
|
753
|
-
descriptionMode: Object.freeze({}),
|
|
754
|
-
disabledTools: Object.freeze([]),
|
|
755
|
-
autoExtendLimit: true,
|
|
756
|
-
restrictToProjectRoot: true,
|
|
757
|
-
// Off by default: the board is a record of the work, not a permit for it.
|
|
758
|
-
// See ToolsConfig.kanbanGovernance for what turning it on costs and gates.
|
|
759
|
-
kanbanGovernance: false,
|
|
760
|
-
loopDetection: Object.freeze({
|
|
761
|
-
mode: "steer-then-cut",
|
|
762
|
-
steerThreshold: 3,
|
|
763
|
-
cutThreshold: 5,
|
|
764
|
-
windowSize: 12,
|
|
765
|
-
callRepeatThreshold: 4
|
|
766
|
-
})
|
|
767
|
-
});
|
|
768
|
-
var DEFAULT_CONTEXT_CONFIG = Object.freeze({
|
|
769
|
-
warnThreshold: 0.55,
|
|
770
|
-
softThreshold: 0.7,
|
|
771
|
-
hardThreshold: 0.85,
|
|
772
|
-
targetLoad: 0.65,
|
|
773
|
-
preserveK: 8,
|
|
774
|
-
eliseThreshold: 1200
|
|
775
|
-
});
|
|
776
|
-
var DEFAULT_AUTONOMY_CONFIG = Object.freeze({
|
|
777
|
-
autoProceedDelayMs: 45e3
|
|
778
|
-
});
|
|
779
|
-
var DEFAULT_CIRCUIT_BREAKER_CONFIG = Object.freeze({
|
|
780
|
-
enabled: false,
|
|
781
|
-
autoKillResetMs: 6e4
|
|
782
|
-
});
|
|
783
|
-
var DEFAULT_SESSION_LOGGING_CONFIG = Object.freeze({
|
|
784
|
-
auditLevel: "standard",
|
|
785
|
-
sampling: {
|
|
786
|
-
toolProgress: {
|
|
787
|
-
sampleRate: 8
|
|
788
|
-
}
|
|
610
|
+
// src/types/mode.ts
|
|
611
|
+
var DEFAULT_MODES = [
|
|
612
|
+
{
|
|
613
|
+
id: "default",
|
|
614
|
+
name: "Default",
|
|
615
|
+
description: "Balanced general-purpose mode; use when no special token/coverage trade-off is needed",
|
|
616
|
+
prompt: "",
|
|
617
|
+
tags: ["general", "balanced"]
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
id: "brief",
|
|
621
|
+
name: "Brief",
|
|
622
|
+
description: "Ultra-compact responses for low-context, high-speed work",
|
|
623
|
+
prompt: modePrompt("brief"),
|
|
624
|
+
tags: ["lite", "fast", "concise", "token-saving"],
|
|
625
|
+
toolPreferences: ["read", "edit", "bash"],
|
|
626
|
+
suggestedSkills: []
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
id: "review-lite",
|
|
630
|
+
name: "Review Lite",
|
|
631
|
+
description: "Token-saving code review: changed files only, top correctness/security risks",
|
|
632
|
+
prompt: modePrompt("review-lite"),
|
|
633
|
+
tags: ["lite", "review", "quality", "token-saving"],
|
|
634
|
+
toolPreferences: ["git", "diff", "read", "grep"],
|
|
635
|
+
suggestedSkills: ["bug-hunter", "typescript-strict"]
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
id: "audit-lite",
|
|
639
|
+
name: "Audit Lite",
|
|
640
|
+
description: "Token-saving security triage for a small diff or named file",
|
|
641
|
+
prompt: modePrompt("audit-lite"),
|
|
642
|
+
tags: ["lite", "security", "audit", "token-saving"],
|
|
643
|
+
toolPreferences: ["grep", "read", "git"],
|
|
644
|
+
suggestedSkills: ["security-scanner"]
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
id: "plan-lite",
|
|
648
|
+
name: "Plan Lite",
|
|
649
|
+
description: "Token-saving planning: 3-6 actionable steps, minimal design debate",
|
|
650
|
+
prompt: modePrompt("plan-lite"),
|
|
651
|
+
tags: ["lite", "planning", "architecture", "token-saving"],
|
|
652
|
+
toolPreferences: ["tree", "glob", "read", "grep"],
|
|
653
|
+
suggestedSkills: ["refactor-planner"]
|
|
654
|
+
},
|
|
655
|
+
{
|
|
656
|
+
id: "debug-lite",
|
|
657
|
+
name: "Debug Lite",
|
|
658
|
+
description: "Token-saving bug triage: one hypothesis, nearest evidence, narrow check",
|
|
659
|
+
prompt: modePrompt("debug-lite"),
|
|
660
|
+
tags: ["lite", "debug", "triage", "token-saving"],
|
|
661
|
+
toolPreferences: ["read", "grep", "test", "logs"],
|
|
662
|
+
suggestedSkills: ["bug-hunter"]
|
|
663
|
+
},
|
|
664
|
+
{
|
|
665
|
+
id: "test-lite",
|
|
666
|
+
name: "Test Lite",
|
|
667
|
+
description: "Token-saving tests: one focused regression or narrow verification target",
|
|
668
|
+
prompt: modePrompt("test-lite"),
|
|
669
|
+
tags: ["lite", "testing", "qa", "token-saving"],
|
|
670
|
+
toolPreferences: ["test", "read", "grep"],
|
|
671
|
+
suggestedSkills: ["testing"]
|
|
672
|
+
},
|
|
673
|
+
{
|
|
674
|
+
id: "refactor-lite",
|
|
675
|
+
name: "Refactor Lite",
|
|
676
|
+
description: "Token-saving cleanup: small scoped behavior-preserving changes",
|
|
677
|
+
prompt: modePrompt("refactor-lite"),
|
|
678
|
+
tags: ["lite", "refactor", "token-saving"],
|
|
679
|
+
toolPreferences: ["read", "edit", "test"],
|
|
680
|
+
suggestedSkills: ["typescript-strict"]
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
id: "research-lite",
|
|
684
|
+
name: "Research Lite",
|
|
685
|
+
description: "Token-saving web research: one search, one authoritative fetch, short answer",
|
|
686
|
+
prompt: modePrompt("research-lite"),
|
|
687
|
+
tags: ["lite", "research", "web", "token-saving"],
|
|
688
|
+
toolPreferences: ["search", "fetch"],
|
|
689
|
+
suggestedSkills: ["research-web"]
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
id: "code-reviewer",
|
|
693
|
+
name: "Review Deep",
|
|
694
|
+
description: "Comprehensive code review across contracts, edge cases, lifecycle, errors, concurrency",
|
|
695
|
+
prompt: modePrompt("code-reviewer"),
|
|
696
|
+
tags: ["deep", "review", "quality", "security"],
|
|
697
|
+
toolPreferences: ["read", "grep", "git", "diff", "test"],
|
|
698
|
+
suggestedSkills: ["bug-hunter", "security-scanner", "typescript-strict", "testing"]
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
id: "code-auditor",
|
|
702
|
+
name: "Audit Deep",
|
|
703
|
+
description: "Comprehensive security audit with category coverage and exploitability notes",
|
|
704
|
+
prompt: modePrompt("code-auditor"),
|
|
705
|
+
tags: ["deep", "security", "audit", "compliance"],
|
|
706
|
+
toolPreferences: ["grep", "read", "audit", "bash"],
|
|
707
|
+
suggestedSkills: ["security-scanner", "bug-hunter", "audit-log"]
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
id: "architect",
|
|
711
|
+
name: "Architecture Deep",
|
|
712
|
+
description: "Comprehensive architecture and cross-module contract analysis",
|
|
713
|
+
prompt: modePrompt("architect"),
|
|
714
|
+
tags: ["deep", "architecture", "design", "scalability"],
|
|
715
|
+
toolPreferences: ["read", "glob", "tree", "diff"],
|
|
716
|
+
suggestedSkills: ["api-design", "refactor-planner", "node-modern", "docker-deploy"]
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
id: "debugger",
|
|
720
|
+
name: "Debug Deep",
|
|
721
|
+
description: "Comprehensive root-cause analysis with traces, logs, assumptions, and verification",
|
|
722
|
+
prompt: modePrompt("debugger"),
|
|
723
|
+
tags: ["deep", "debug", "investigation", "error-resolution"],
|
|
724
|
+
toolPreferences: ["read", "grep", "bash", "logs", "test"],
|
|
725
|
+
suggestedSkills: ["bug-hunter", "audit-log", "observability"]
|
|
726
|
+
},
|
|
727
|
+
{
|
|
728
|
+
id: "tester",
|
|
729
|
+
name: "Test Deep",
|
|
730
|
+
description: "Comprehensive QA mode for coverage, boundaries, isolation, and integration gaps",
|
|
731
|
+
prompt: modePrompt("tester"),
|
|
732
|
+
tags: ["deep", "testing", "qa", "quality"],
|
|
733
|
+
toolPreferences: ["read", "grep", "test", "bash"],
|
|
734
|
+
suggestedSkills: ["testing", "bug-hunter", "typescript-strict"]
|
|
735
|
+
},
|
|
736
|
+
{
|
|
737
|
+
id: "devops",
|
|
738
|
+
name: "DevOps Deep",
|
|
739
|
+
description: "Comprehensive infrastructure, deployment, observability, and operations review",
|
|
740
|
+
prompt: modePrompt("devops"),
|
|
741
|
+
tags: ["deep", "devops", "infrastructure", "operations"],
|
|
742
|
+
toolPreferences: ["read", "bash", "grep", "logs", "git"],
|
|
743
|
+
suggestedSkills: ["docker-deploy", "observability", "security-scanner"]
|
|
744
|
+
},
|
|
745
|
+
{
|
|
746
|
+
id: "refactorer",
|
|
747
|
+
name: "Refactor Deep",
|
|
748
|
+
description: "Comprehensive modernization/refactor mode with contracts and verification discipline",
|
|
749
|
+
prompt: modePrompt("refactorer"),
|
|
750
|
+
tags: ["deep", "refactor", "modernization", "improvement"],
|
|
751
|
+
toolPreferences: ["read", "edit", "test", "git", "grep"],
|
|
752
|
+
suggestedSkills: ["refactor-planner", "typescript-strict", "node-modern", "testing"]
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
id: "ui-design",
|
|
756
|
+
name: "UI Design Deep",
|
|
757
|
+
description: "Comprehensive design-first frontend/mobile UI work with kit, tokens, and accessibility",
|
|
758
|
+
prompt: modePrompt("ui-design"),
|
|
759
|
+
tags: ["deep", "ui", "frontend", "mobile", "design"],
|
|
760
|
+
toolPreferences: ["design", "write", "edit", "read", "scaffold"],
|
|
761
|
+
suggestedSkills: ["react-modern"]
|
|
762
|
+
},
|
|
763
|
+
{
|
|
764
|
+
id: "teach",
|
|
765
|
+
name: "Teach Deep",
|
|
766
|
+
description: "Mentor mode with explanations, mental models, trade-offs, and takeaways",
|
|
767
|
+
prompt: modePrompt("teach"),
|
|
768
|
+
tags: ["deep", "teaching", "mentor", "learning"],
|
|
769
|
+
toolPreferences: ["read", "edit", "explain"],
|
|
770
|
+
suggestedSkills: ["prompt-engineering", "skill-creator", "node-modern", "typescript-strict"]
|
|
771
|
+
},
|
|
772
|
+
{
|
|
773
|
+
id: "research-web",
|
|
774
|
+
name: "Research Deep",
|
|
775
|
+
description: "Comprehensive current-data research with cross-checking and reusable findings",
|
|
776
|
+
prompt: modePrompt("research-web"),
|
|
777
|
+
tags: ["deep", "research", "web", "current-data", "up-to-date"],
|
|
778
|
+
toolPreferences: ["search", "fetch", "context_manager"],
|
|
779
|
+
suggestedSkills: ["research-web", "tech-stack", "node-modern", "security-scanner", "react-modern"]
|
|
789
780
|
}
|
|
790
|
-
|
|
791
|
-
var DEFAULT_SESSION_PRUNE_DAYS = 30;
|
|
792
|
-
|
|
793
|
-
// src/types/memory.ts
|
|
794
|
-
var MEMORY_TYPE_LABELS = {
|
|
795
|
-
fact: "Fact",
|
|
796
|
-
decision: "Decision",
|
|
797
|
-
convention: "Convention",
|
|
798
|
-
preference: "Preference",
|
|
799
|
-
reference: "Reference",
|
|
800
|
-
anti_pattern: "Anti-pattern"
|
|
801
|
-
};
|
|
802
|
-
function defineMemoryCapability(id) {
|
|
803
|
-
return Object.freeze({
|
|
804
|
-
id,
|
|
805
|
-
/** Identity function that makes the brand a real runtime value so
|
|
806
|
-
* `defineMemoryCapability<A>('x')` and `defineMemoryCapability<B>('x')`
|
|
807
|
-
* produce structurally distinct objects. Capability lookup is still
|
|
808
|
-
* keyed by `id` only — the brand prevents accidental cross-type casts
|
|
809
|
-
* at the type level. */
|
|
810
|
-
__memoryCapabilityType: (v) => v
|
|
811
|
-
});
|
|
812
|
-
}
|
|
781
|
+
];
|
|
813
782
|
|
|
814
783
|
// src/types/prompt.ts
|
|
815
784
|
var BUILTIN_PROMPT_CATEGORIES = [
|
|
@@ -931,336 +900,365 @@ function diffRegistry(local, manifest) {
|
|
|
931
900
|
return diff;
|
|
932
901
|
}
|
|
933
902
|
|
|
934
|
-
// src/
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
return DESIGN_STACKS.includes(v);
|
|
903
|
+
// src/utils/string.ts
|
|
904
|
+
function truncate(s, max) {
|
|
905
|
+
return s.length <= max ? s : `${s.slice(0, max - 1)}\u2026`;
|
|
938
906
|
}
|
|
939
|
-
var KNOWN_TOKEN_GROUPS = {
|
|
940
|
-
/** Corner radii. */
|
|
941
|
-
radius: ["radius-none", "radius-sm", "radius-md", "radius-lg", "radius-xl", "radius-full"],
|
|
942
|
-
/** Spacing scale (4/8px rhythm). */
|
|
943
|
-
space: ["space-1", "space-2", "space-3", "space-4", "space-6", "space-8", "space-12"],
|
|
944
|
-
/** Type sizes. */
|
|
945
|
-
text: ["text-xs", "text-sm", "text-base", "text-lg", "text-xl", "text-2xl", "text-3xl"],
|
|
946
|
-
/** Line-heights (unitless). */
|
|
947
|
-
leading: ["leading-tight", "leading-normal", "leading-relaxed"],
|
|
948
|
-
/** Font weights (unitless). */
|
|
949
|
-
weight: ["weight-normal", "weight-medium", "weight-semibold", "weight-bold"],
|
|
950
|
-
/** Letter-spacing. */
|
|
951
|
-
tracking: ["tracking-tight", "tracking-normal", "tracking-wide"],
|
|
952
|
-
/** Elevation / shadow ramp. */
|
|
953
|
-
shadow: ["shadow-1", "shadow-2", "shadow-3", "shadow-4"],
|
|
954
|
-
/** Border widths. */
|
|
955
|
-
border: ["border-hairline", "border-thin", "border-thick"],
|
|
956
|
-
/** Motion durations. */
|
|
957
|
-
duration: ["duration-fast", "duration-base", "duration-slow"],
|
|
958
|
-
/** Motion easings. */
|
|
959
|
-
ease: ["ease-standard", "ease-emphasized"],
|
|
960
|
-
/** Font families. */
|
|
961
|
-
font: ["font-sans", "font-mono", "font-display"]
|
|
962
|
-
};
|
|
963
|
-
var KNOWN_TOKEN_NAMES = Object.values(KNOWN_TOKEN_GROUPS).flat();
|
|
964
907
|
|
|
965
|
-
// src/types/
|
|
966
|
-
|
|
967
|
-
return [...regions.core, ...regions.session, ...regions.volatile];
|
|
968
|
-
}
|
|
908
|
+
// src/types/quota-regex.ts
|
|
909
|
+
var QUOTA_EXHAUSTED_RE = /(?:insufficient|exhausted|depleted|exceeded|no|not enough)[-_\s]*(?:quota|credit|balance)|(?:quota|credit|balance)(?:\s+(?:has|have))?(?:\s+been)?[-_\s]*(?:exhausted|depleted|exceeded|insufficient)|billing[_\s-]*(?:hard[_\s-]*)?limit|payment required|spending limit|plan limit|usage[-_\s]*limit[-_\s]*(?:reached|exceeded)/i;
|
|
969
910
|
|
|
970
|
-
// src/types/
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
911
|
+
// src/types/provider.ts
|
|
912
|
+
function effectiveInputTokens(usage) {
|
|
913
|
+
return usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
|
|
914
|
+
}
|
|
915
|
+
var CONTEXT_OVERFLOW_RE = /context.length|context.window|maximum context|max.*tokens?.*exceeded|(?:prompt|request|input|messages?).{0,12}too (?:large|long)|exceeds the context|\btokens\b.*exceed|too many tokens|reduce the length|resulted in \d+ tokens|context_length_exceeded/i;
|
|
916
|
+
var CONTENT_FILTER_RE = /content.(filter|policy|moderation)|safety (system|filter)/i;
|
|
917
|
+
var RATE_LIMIT_EXCEEDED_RE = /rate[-_\s]*limit[-_\s]*exceeded/i;
|
|
918
|
+
function classifyProviderError(status, body, message) {
|
|
919
|
+
const type = body?.type;
|
|
920
|
+
const text = [message, body?.message, type, body?.raw].filter(Boolean).join("\n");
|
|
921
|
+
if (status === 0) return "network";
|
|
922
|
+
if (status === 408) return "timeout";
|
|
923
|
+
if (status === 599) return "stream_hang";
|
|
924
|
+
if (status === 402 || QUOTA_EXHAUSTED_RE.test(text)) return "quota_exhausted";
|
|
925
|
+
if (status === 429 && body?.message && body.type !== "rate_limit_exceeded" && RATE_LIMIT_EXCEEDED_RE.test(body.message)) {
|
|
926
|
+
return "quota_exhausted";
|
|
927
|
+
}
|
|
928
|
+
if (type === "rate_limit_error" || status === 429) return "rate_limit";
|
|
929
|
+
if (type === "overloaded_error" || status === 529) return "overloaded";
|
|
930
|
+
if (status >= 500) return "server";
|
|
931
|
+
if (type === "authentication_error" || type === "permission_error" || status === 401 || status === 403) {
|
|
932
|
+
return "auth";
|
|
933
|
+
}
|
|
934
|
+
if (type === "content_filter" || CONTENT_FILTER_RE.test(text)) return "content_filter";
|
|
935
|
+
if (status === 413 || status >= 400 && CONTEXT_OVERFLOW_RE.test(text)) {
|
|
936
|
+
return "context_overflow";
|
|
937
|
+
}
|
|
938
|
+
if (status >= 400) return "invalid_request";
|
|
939
|
+
return "unknown";
|
|
940
|
+
}
|
|
941
|
+
var MAX_RESET_HINT_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
942
|
+
function isRetryableKind(kind) {
|
|
943
|
+
return RETRYABLE_BY_KIND[kind];
|
|
944
|
+
}
|
|
945
|
+
var RETRYABLE_BY_KIND = {
|
|
946
|
+
rate_limit: true,
|
|
947
|
+
quota_exhausted: false,
|
|
948
|
+
overloaded: true,
|
|
949
|
+
server: true,
|
|
950
|
+
timeout: true,
|
|
951
|
+
network: true,
|
|
952
|
+
stream_hang: true,
|
|
953
|
+
auth: false,
|
|
954
|
+
context_overflow: false,
|
|
955
|
+
content_filter: false,
|
|
956
|
+
invalid_request: false,
|
|
957
|
+
unknown: false
|
|
958
|
+
};
|
|
959
|
+
function isFallbackWorthy(kind) {
|
|
960
|
+
return FALLBACK_WORTHY_BY_KIND[kind];
|
|
961
|
+
}
|
|
962
|
+
var FALLBACK_WORTHY_BY_KIND = {
|
|
963
|
+
rate_limit: true,
|
|
964
|
+
quota_exhausted: true,
|
|
965
|
+
overloaded: true,
|
|
966
|
+
server: true,
|
|
967
|
+
timeout: true,
|
|
968
|
+
network: true,
|
|
969
|
+
stream_hang: true,
|
|
970
|
+
auth: false,
|
|
971
|
+
context_overflow: false,
|
|
972
|
+
content_filter: false,
|
|
973
|
+
invalid_request: false,
|
|
974
|
+
unknown: false
|
|
975
|
+
};
|
|
976
|
+
var ProviderError = class extends WrongStackError {
|
|
977
|
+
status;
|
|
978
|
+
retryable;
|
|
979
|
+
providerId;
|
|
980
|
+
/** Canonical failure classification — see {@link ProviderErrorKind}. */
|
|
981
|
+
kind;
|
|
982
|
+
body;
|
|
983
|
+
/**
|
|
984
|
+
* Duck-type guard: checks whether an unknown value *looks like* a
|
|
985
|
+
* ProviderError by probing for its structural properties. Use this
|
|
986
|
+
* anywhere the constructor identity might cross a package boundary
|
|
987
|
+
* (e.g. `@wrongstack/providers` creates the error, but the runner in
|
|
988
|
+
* `@wrongstack/core` checks it). A plain `instanceof ProviderError`
|
|
989
|
+
* can fail when npm hoists duplicate copies of `@wrongstack/core`,
|
|
990
|
+
* each with its own class identity.
|
|
991
|
+
*
|
|
992
|
+
* The check tests for the four invariant properties defined in the
|
|
993
|
+
* constructor: `name === 'ProviderError'`, `status` (number),
|
|
994
|
+
* `retryable` (boolean), and `kind` (string). This tolerates both
|
|
995
|
+
* true `ProviderError` instances and cross-boundary copies.
|
|
996
|
+
*/
|
|
997
|
+
static isProviderError(err) {
|
|
998
|
+
if (!err || typeof err !== "object") return false;
|
|
999
|
+
const e = err;
|
|
1000
|
+
const name = e.name;
|
|
1001
|
+
if (typeof name !== "string" || !name.endsWith("Error")) return false;
|
|
1002
|
+
return typeof e.status === "number" && typeof e.retryable === "boolean" && typeof e.kind === "string" && typeof e.describe === "function";
|
|
1003
|
+
}
|
|
1004
|
+
constructor(message, status, retryable, providerId, opts = {}) {
|
|
1005
|
+
const kind = opts.kind ?? classifyProviderError(status, opts.body, message);
|
|
1006
|
+
super({
|
|
1007
|
+
message,
|
|
1008
|
+
code: kindToCode(kind),
|
|
1009
|
+
subsystem: "provider",
|
|
1010
|
+
severity: status >= 500 ? "error" : "warning",
|
|
1011
|
+
recoverable: retryable,
|
|
1012
|
+
context: { providerId, status },
|
|
1013
|
+
cause: opts.cause
|
|
1014
|
+
});
|
|
1015
|
+
this.name = "ProviderError";
|
|
1016
|
+
this.status = status;
|
|
1017
|
+
this.retryable = retryable;
|
|
1018
|
+
this.providerId = providerId;
|
|
1019
|
+
this.kind = kind;
|
|
1020
|
+
this.body = opts.body;
|
|
1021
|
+
}
|
|
1022
|
+
/**
|
|
1023
|
+
* Render a one-line, user-facing description. Designed for the CLI/TUI
|
|
1024
|
+
* status line and the agent's retry warning. Avoids dumping raw JSON
|
|
1025
|
+
* (which is what users see today when a 529 lands and the log message
|
|
1026
|
+
* includes the full `{"type":"error",...}` body).
|
|
1027
|
+
*
|
|
1028
|
+
* Examples:
|
|
1029
|
+
* "minimax-coding-plan overloaded (529): High traffic detected. Upgrade for highspeed model. [req 06534785201de9c0…]"
|
|
1030
|
+
* "openai rate limited (429): Retry after 12s"
|
|
1031
|
+
* "anthropic invalid request (400): messages.0.role must be one of 'user'|'assistant'"
|
|
1032
|
+
* "groq HTTP 500 (server error)"
|
|
1033
|
+
*/
|
|
1034
|
+
describe() {
|
|
1035
|
+
const kind = describeStatus(this.status, this.body?.type);
|
|
1036
|
+
const head = `${this.providerId} ${kind}`;
|
|
1037
|
+
const detail = this.body?.message?.trim();
|
|
1038
|
+
const reqId = this.body?.requestId ? ` [req ${this.body.requestId.slice(0, 16)}${this.body.requestId.length > 16 ? "\u2026" : ""}]` : "";
|
|
1039
|
+
if (detail && detail.length > 0) {
|
|
1040
|
+
return `${head}: ${truncate(detail, 240)}${reqId}`;
|
|
979
1041
|
}
|
|
1042
|
+
return `${head}${reqId}`;
|
|
980
1043
|
}
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
const
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
];
|
|
990
|
-
return candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));
|
|
1044
|
+
};
|
|
1045
|
+
function isContextOverflowShaped(err) {
|
|
1046
|
+
if (!(err instanceof ProviderError) && !ProviderError.isProviderError(err)) return false;
|
|
1047
|
+
const providerErr = err;
|
|
1048
|
+
if (providerErr.kind === "context_overflow" || providerErr.status === 413) return true;
|
|
1049
|
+
if (providerErr.status < 400) return false;
|
|
1050
|
+
const text = [providerErr.message, providerErr.body?.message, providerErr.body?.type, providerErr.body?.raw].filter(Boolean).join("\n");
|
|
1051
|
+
return CONTEXT_OVERFLOW_RE.test(text);
|
|
991
1052
|
}
|
|
992
|
-
function
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
}
|
|
1053
|
+
function describeStatus(status, type) {
|
|
1054
|
+
if (status === 0) return "network error";
|
|
1055
|
+
if (status === 599) return `stream hang (${status})`;
|
|
1056
|
+
if (type === "overloaded_error" || status === 529) return `overloaded (${status})`;
|
|
1057
|
+
if (type === "rate_limit_error" || status === 429) return `rate limited (${status})`;
|
|
1058
|
+
if (type === "authentication_error" || status === 401) return `auth failed (${status})`;
|
|
1059
|
+
if (type === "permission_error" || status === 403) return `forbidden (${status})`;
|
|
1060
|
+
if (type === "not_found_error" || status === 404) return `not found (${status})`;
|
|
1061
|
+
if (type === "content_filter") return `content filtered (${status})`;
|
|
1062
|
+
if (type === "invalid_request_error" || status === 400) return `invalid request (${status})`;
|
|
1063
|
+
if (status === 408) return `timeout (${status})`;
|
|
1064
|
+
if (status >= 500 && status < 600) return `HTTP ${status} (server error)`;
|
|
1065
|
+
if (type) return `${type} (${status})`;
|
|
1066
|
+
return `HTTP ${status}`;
|
|
998
1067
|
}
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
description: "Token-saving security triage for a small diff or named file",
|
|
1031
|
-
prompt: modePrompt("audit-lite"),
|
|
1032
|
-
tags: ["lite", "security", "audit", "token-saving"],
|
|
1033
|
-
toolPreferences: ["grep", "read", "git"],
|
|
1034
|
-
suggestedSkills: ["security-scanner"]
|
|
1035
|
-
},
|
|
1036
|
-
{
|
|
1037
|
-
id: "plan-lite",
|
|
1038
|
-
name: "Plan Lite",
|
|
1039
|
-
description: "Token-saving planning: 3-6 actionable steps, minimal design debate",
|
|
1040
|
-
prompt: modePrompt("plan-lite"),
|
|
1041
|
-
tags: ["lite", "planning", "architecture", "token-saving"],
|
|
1042
|
-
toolPreferences: ["tree", "glob", "read", "grep"],
|
|
1043
|
-
suggestedSkills: ["refactor-planner"]
|
|
1044
|
-
},
|
|
1045
|
-
{
|
|
1046
|
-
id: "debug-lite",
|
|
1047
|
-
name: "Debug Lite",
|
|
1048
|
-
description: "Token-saving bug triage: one hypothesis, nearest evidence, narrow check",
|
|
1049
|
-
prompt: modePrompt("debug-lite"),
|
|
1050
|
-
tags: ["lite", "debug", "triage", "token-saving"],
|
|
1051
|
-
toolPreferences: ["read", "grep", "test", "logs"],
|
|
1052
|
-
suggestedSkills: ["bug-hunter"]
|
|
1053
|
-
},
|
|
1054
|
-
{
|
|
1055
|
-
id: "test-lite",
|
|
1056
|
-
name: "Test Lite",
|
|
1057
|
-
description: "Token-saving tests: one focused regression or narrow verification target",
|
|
1058
|
-
prompt: modePrompt("test-lite"),
|
|
1059
|
-
tags: ["lite", "testing", "qa", "token-saving"],
|
|
1060
|
-
toolPreferences: ["test", "read", "grep"],
|
|
1061
|
-
suggestedSkills: ["testing"]
|
|
1062
|
-
},
|
|
1063
|
-
{
|
|
1064
|
-
id: "refactor-lite",
|
|
1065
|
-
name: "Refactor Lite",
|
|
1066
|
-
description: "Token-saving cleanup: small scoped behavior-preserving changes",
|
|
1067
|
-
prompt: modePrompt("refactor-lite"),
|
|
1068
|
-
tags: ["lite", "refactor", "token-saving"],
|
|
1069
|
-
toolPreferences: ["read", "edit", "test"],
|
|
1070
|
-
suggestedSkills: ["typescript-strict"]
|
|
1071
|
-
},
|
|
1072
|
-
{
|
|
1073
|
-
id: "research-lite",
|
|
1074
|
-
name: "Research Lite",
|
|
1075
|
-
description: "Token-saving web research: one search, one authoritative fetch, short answer",
|
|
1076
|
-
prompt: modePrompt("research-lite"),
|
|
1077
|
-
tags: ["lite", "research", "web", "token-saving"],
|
|
1078
|
-
toolPreferences: ["search", "fetch"],
|
|
1079
|
-
suggestedSkills: ["research-web"]
|
|
1080
|
-
},
|
|
1081
|
-
{
|
|
1082
|
-
id: "code-reviewer",
|
|
1083
|
-
name: "Review Deep",
|
|
1084
|
-
description: "Comprehensive code review across contracts, edge cases, lifecycle, errors, concurrency",
|
|
1085
|
-
prompt: modePrompt("code-reviewer"),
|
|
1086
|
-
tags: ["deep", "review", "quality", "security"],
|
|
1087
|
-
toolPreferences: ["read", "grep", "git", "diff", "test"],
|
|
1088
|
-
suggestedSkills: ["bug-hunter", "security-scanner", "typescript-strict", "testing"]
|
|
1089
|
-
},
|
|
1090
|
-
{
|
|
1091
|
-
id: "code-auditor",
|
|
1092
|
-
name: "Audit Deep",
|
|
1093
|
-
description: "Comprehensive security audit with category coverage and exploitability notes",
|
|
1094
|
-
prompt: modePrompt("code-auditor"),
|
|
1095
|
-
tags: ["deep", "security", "audit", "compliance"],
|
|
1096
|
-
toolPreferences: ["grep", "read", "audit", "bash"],
|
|
1097
|
-
suggestedSkills: ["security-scanner", "bug-hunter", "audit-log"]
|
|
1098
|
-
},
|
|
1099
|
-
{
|
|
1100
|
-
id: "architect",
|
|
1101
|
-
name: "Architecture Deep",
|
|
1102
|
-
description: "Comprehensive architecture and cross-module contract analysis",
|
|
1103
|
-
prompt: modePrompt("architect"),
|
|
1104
|
-
tags: ["deep", "architecture", "design", "scalability"],
|
|
1105
|
-
toolPreferences: ["read", "glob", "tree", "diff"],
|
|
1106
|
-
suggestedSkills: ["api-design", "refactor-planner", "node-modern", "docker-deploy"]
|
|
1107
|
-
},
|
|
1108
|
-
{
|
|
1109
|
-
id: "debugger",
|
|
1110
|
-
name: "Debug Deep",
|
|
1111
|
-
description: "Comprehensive root-cause analysis with traces, logs, assumptions, and verification",
|
|
1112
|
-
prompt: modePrompt("debugger"),
|
|
1113
|
-
tags: ["deep", "debug", "investigation", "error-resolution"],
|
|
1114
|
-
toolPreferences: ["read", "grep", "bash", "logs", "test"],
|
|
1115
|
-
suggestedSkills: ["bug-hunter", "audit-log", "observability"]
|
|
1116
|
-
},
|
|
1117
|
-
{
|
|
1118
|
-
id: "tester",
|
|
1119
|
-
name: "Test Deep",
|
|
1120
|
-
description: "Comprehensive QA mode for coverage, boundaries, isolation, and integration gaps",
|
|
1121
|
-
prompt: modePrompt("tester"),
|
|
1122
|
-
tags: ["deep", "testing", "qa", "quality"],
|
|
1123
|
-
toolPreferences: ["read", "grep", "test", "bash"],
|
|
1124
|
-
suggestedSkills: ["testing", "bug-hunter", "typescript-strict"]
|
|
1125
|
-
},
|
|
1126
|
-
{
|
|
1127
|
-
id: "devops",
|
|
1128
|
-
name: "DevOps Deep",
|
|
1129
|
-
description: "Comprehensive infrastructure, deployment, observability, and operations review",
|
|
1130
|
-
prompt: modePrompt("devops"),
|
|
1131
|
-
tags: ["deep", "devops", "infrastructure", "operations"],
|
|
1132
|
-
toolPreferences: ["read", "bash", "grep", "logs", "git"],
|
|
1133
|
-
suggestedSkills: ["docker-deploy", "observability", "security-scanner"]
|
|
1134
|
-
},
|
|
1135
|
-
{
|
|
1136
|
-
id: "refactorer",
|
|
1137
|
-
name: "Refactor Deep",
|
|
1138
|
-
description: "Comprehensive modernization/refactor mode with contracts and verification discipline",
|
|
1139
|
-
prompt: modePrompt("refactorer"),
|
|
1140
|
-
tags: ["deep", "refactor", "modernization", "improvement"],
|
|
1141
|
-
toolPreferences: ["read", "edit", "test", "git", "grep"],
|
|
1142
|
-
suggestedSkills: ["refactor-planner", "typescript-strict", "node-modern", "testing"]
|
|
1143
|
-
},
|
|
1144
|
-
{
|
|
1145
|
-
id: "ui-design",
|
|
1146
|
-
name: "UI Design Deep",
|
|
1147
|
-
description: "Comprehensive design-first frontend/mobile UI work with kit, tokens, and accessibility",
|
|
1148
|
-
prompt: modePrompt("ui-design"),
|
|
1149
|
-
tags: ["deep", "ui", "frontend", "mobile", "design"],
|
|
1150
|
-
toolPreferences: ["design", "write", "edit", "read", "scaffold"],
|
|
1151
|
-
suggestedSkills: ["react-modern"]
|
|
1152
|
-
},
|
|
1153
|
-
{
|
|
1154
|
-
id: "teach",
|
|
1155
|
-
name: "Teach Deep",
|
|
1156
|
-
description: "Mentor mode with explanations, mental models, trade-offs, and takeaways",
|
|
1157
|
-
prompt: modePrompt("teach"),
|
|
1158
|
-
tags: ["deep", "teaching", "mentor", "learning"],
|
|
1159
|
-
toolPreferences: ["read", "edit", "explain"],
|
|
1160
|
-
suggestedSkills: ["prompt-engineering", "skill-creator", "node-modern", "typescript-strict"]
|
|
1161
|
-
},
|
|
1162
|
-
{
|
|
1163
|
-
id: "research-web",
|
|
1164
|
-
name: "Research Deep",
|
|
1165
|
-
description: "Comprehensive current-data research with cross-checking and reusable findings",
|
|
1166
|
-
prompt: modePrompt("research-web"),
|
|
1167
|
-
tags: ["deep", "research", "web", "current-data", "up-to-date"],
|
|
1168
|
-
toolPreferences: ["search", "fetch", "context_manager"],
|
|
1169
|
-
suggestedSkills: ["research-web", "tech-stack", "node-modern", "security-scanner", "react-modern"]
|
|
1170
|
-
}
|
|
1171
|
-
];
|
|
1172
|
-
|
|
1173
|
-
// src/utils/expect-defined.ts
|
|
1174
|
-
function expectDefined(value, label) {
|
|
1175
|
-
if (value === null || value === void 0) {
|
|
1176
|
-
const err = new Error(label ? `Expected ${label} to be defined` : "Expected value to be defined");
|
|
1177
|
-
err.name = "ExpectDefinedError";
|
|
1178
|
-
throw err;
|
|
1068
|
+
var StreamHangError = class extends ProviderError {
|
|
1069
|
+
/** Name of the provider that hung, e.g. "zai", "anthropic". */
|
|
1070
|
+
hungProviderId;
|
|
1071
|
+
/** Model that was being called when the hang occurred. */
|
|
1072
|
+
hungModel;
|
|
1073
|
+
/** How long (ms) we waited for the next chunk before declaring a hang. */
|
|
1074
|
+
hangTimeoutMs;
|
|
1075
|
+
/** How many bytes were received before the hang. */
|
|
1076
|
+
bytesReceived;
|
|
1077
|
+
/** Elapsed time (ms) from the start of the stream until the hang. */
|
|
1078
|
+
elapsedMs;
|
|
1079
|
+
constructor(opts) {
|
|
1080
|
+
super(
|
|
1081
|
+
`Stream hang: ${opts.providerId}/${opts.model} \u2014 no data for ${opts.hangTimeoutMs}ms after ${opts.bytesReceived} bytes (${opts.elapsedMs}ms elapsed)`,
|
|
1082
|
+
599,
|
|
1083
|
+
true,
|
|
1084
|
+
// always retryable
|
|
1085
|
+
opts.providerId,
|
|
1086
|
+
{
|
|
1087
|
+
body: {
|
|
1088
|
+
message: `Stream stalled after ${opts.elapsedMs}ms, ${opts.bytesReceived} bytes received`
|
|
1089
|
+
},
|
|
1090
|
+
cause: opts.cause
|
|
1091
|
+
}
|
|
1092
|
+
);
|
|
1093
|
+
this.name = "StreamHangError";
|
|
1094
|
+
this.hungProviderId = opts.providerId;
|
|
1095
|
+
this.hungModel = opts.model;
|
|
1096
|
+
this.hangTimeoutMs = opts.hangTimeoutMs;
|
|
1097
|
+
this.bytesReceived = opts.bytesReceived;
|
|
1098
|
+
this.elapsedMs = opts.elapsedMs;
|
|
1179
1099
|
}
|
|
1180
|
-
|
|
1100
|
+
};
|
|
1101
|
+
var KIND_TO_CODE = {
|
|
1102
|
+
network: ERROR_CODES.PROVIDER_NETWORK_ERROR,
|
|
1103
|
+
timeout: ERROR_CODES.PROVIDER_NETWORK_ERROR,
|
|
1104
|
+
rate_limit: ERROR_CODES.PROVIDER_RATE_LIMITED,
|
|
1105
|
+
quota_exhausted: ERROR_CODES.PROVIDER_RATE_LIMITED,
|
|
1106
|
+
auth: ERROR_CODES.PROVIDER_AUTH_FAILED,
|
|
1107
|
+
overloaded: ERROR_CODES.PROVIDER_OVERLOADED,
|
|
1108
|
+
context_overflow: ERROR_CODES.PROVIDER_CONTEXT_OVERFLOW,
|
|
1109
|
+
server: ERROR_CODES.PROVIDER_SERVER_ERROR,
|
|
1110
|
+
stream_hang: ERROR_CODES.PROVIDER_SERVER_ERROR,
|
|
1111
|
+
content_filter: ERROR_CODES.PROVIDER_INVALID_REQUEST,
|
|
1112
|
+
invalid_request: ERROR_CODES.PROVIDER_INVALID_REQUEST,
|
|
1113
|
+
unknown: ERROR_CODES.PROVIDER_INVALID_REQUEST
|
|
1114
|
+
};
|
|
1115
|
+
function kindToCode(kind) {
|
|
1116
|
+
return KIND_TO_CODE[kind];
|
|
1181
1117
|
}
|
|
1182
1118
|
|
|
1183
|
-
// src/types/
|
|
1184
|
-
var
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
targetLoad: 0.65
|
|
1198
|
-
},
|
|
1199
|
-
{
|
|
1200
|
-
id: "frugal",
|
|
1201
|
-
name: "Frugal",
|
|
1202
|
-
description: "Token-saver mode: compacts early and keeps a tight verbatim tail.",
|
|
1203
|
-
thresholds: { warn: 0.4, soft: 0.55, hard: 0.7 },
|
|
1204
|
-
aggressiveOn: "warn",
|
|
1205
|
-
preserveK: 4,
|
|
1206
|
-
eliseThreshold: 500,
|
|
1207
|
-
targetLoad: 0.45
|
|
1208
|
-
},
|
|
1209
|
-
{
|
|
1210
|
-
id: "deep",
|
|
1211
|
-
name: "Deep",
|
|
1212
|
-
description: "Long-reasoning mode: delays compaction and keeps more recent turns intact.",
|
|
1213
|
-
thresholds: { warn: 0.72, soft: 0.86, hard: 0.96 },
|
|
1214
|
-
aggressiveOn: "hard",
|
|
1215
|
-
preserveK: 18,
|
|
1216
|
-
eliseThreshold: 5e3,
|
|
1217
|
-
targetLoad: 0.82
|
|
1218
|
-
}
|
|
1119
|
+
// src/types/session-markers.ts
|
|
1120
|
+
var SESSION_MARKER_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
1121
|
+
"mode_changed",
|
|
1122
|
+
"compaction",
|
|
1123
|
+
"checkpoint",
|
|
1124
|
+
"skill_activated",
|
|
1125
|
+
"skill_deactivated",
|
|
1126
|
+
"agent_spawned",
|
|
1127
|
+
"agent_stopped",
|
|
1128
|
+
"agent_error",
|
|
1129
|
+
"error",
|
|
1130
|
+
"provider_retry",
|
|
1131
|
+
"provider_error",
|
|
1132
|
+
"message_truncated"
|
|
1219
1133
|
]);
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
function
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1134
|
+
var CHAT_MARKER_SOURCES = new Set(
|
|
1135
|
+
[...SESSION_MARKER_EVENT_TYPES].filter((type) => type !== "checkpoint")
|
|
1136
|
+
);
|
|
1137
|
+
function sessionEventToMarker(ev) {
|
|
1138
|
+
switch (ev.type) {
|
|
1139
|
+
case "compaction": {
|
|
1140
|
+
const before = (ev.before / 1e3).toFixed(0);
|
|
1141
|
+
const after = (ev.after / 1e3).toFixed(0);
|
|
1142
|
+
const level = ev.level ? ` (${ev.level})` : "";
|
|
1143
|
+
const reductions = ev.reductions && ev.reductions.length > 0 ? ` [${ev.reductions.map((r) => `${r.phase}: \u2212${r.saved}`).join(", ")}]` : "";
|
|
1144
|
+
return {
|
|
1145
|
+
ts: ev.ts,
|
|
1146
|
+
source: ev.type,
|
|
1147
|
+
level: "info",
|
|
1148
|
+
text: `\u27F2 context compacted${level}: ${before}K \u2192 ${after}K tokens${reductions}`
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
case "error":
|
|
1152
|
+
return {
|
|
1153
|
+
ts: ev.ts,
|
|
1154
|
+
source: ev.type,
|
|
1155
|
+
level: "error",
|
|
1156
|
+
text: ev.phase ? `[${ev.phase}] ${ev.message}` : ev.message
|
|
1157
|
+
};
|
|
1158
|
+
case "provider_retry": {
|
|
1159
|
+
const secs = (ev.delayMs / 1e3).toFixed(ev.delayMs >= 1e3 ? 1 : 2);
|
|
1160
|
+
return {
|
|
1161
|
+
ts: ev.ts,
|
|
1162
|
+
source: ev.type,
|
|
1163
|
+
level: "warn",
|
|
1164
|
+
text: ev.status ? `\u27F3 retry ${ev.attempt} (HTTP ${ev.status}) after ${secs}s \u2014 ${ev.description}` : `\u27F3 retry ${ev.attempt} after ${secs}s \u2014 ${ev.description}`
|
|
1165
|
+
};
|
|
1166
|
+
}
|
|
1167
|
+
case "provider_error":
|
|
1168
|
+
return {
|
|
1169
|
+
ts: ev.ts,
|
|
1170
|
+
source: ev.type,
|
|
1171
|
+
level: "error",
|
|
1172
|
+
text: ev.status ? `provider error (HTTP ${ev.status}, ${ev.retryable ? "retryable" : "fatal"}): ${ev.description}` : `provider error (${ev.retryable ? "retryable" : "fatal"}): ${ev.description}`
|
|
1173
|
+
};
|
|
1174
|
+
case "checkpoint":
|
|
1175
|
+
return {
|
|
1176
|
+
ts: ev.ts,
|
|
1177
|
+
source: ev.type,
|
|
1178
|
+
level: "info",
|
|
1179
|
+
text: `\u2713 checkpoint #${ev.promptIndex}: "${ev.promptPreview.slice(0, 60)}"`
|
|
1180
|
+
};
|
|
1181
|
+
case "agent_spawned":
|
|
1182
|
+
return {
|
|
1183
|
+
ts: ev.ts,
|
|
1184
|
+
source: ev.type,
|
|
1185
|
+
level: "info",
|
|
1186
|
+
text: `spawned as ${ev.role}`,
|
|
1187
|
+
agentId: ev.agentId
|
|
1188
|
+
};
|
|
1189
|
+
case "agent_stopped":
|
|
1190
|
+
return {
|
|
1191
|
+
ts: ev.ts,
|
|
1192
|
+
source: ev.type,
|
|
1193
|
+
level: "info",
|
|
1194
|
+
text: "stopped",
|
|
1195
|
+
agentId: ev.agentId
|
|
1196
|
+
};
|
|
1197
|
+
case "agent_error":
|
|
1198
|
+
return {
|
|
1199
|
+
ts: ev.ts,
|
|
1200
|
+
source: ev.type,
|
|
1201
|
+
level: "error",
|
|
1202
|
+
text: `error: ${ev.error.slice(0, 80)}`,
|
|
1203
|
+
agentId: ev.agentId
|
|
1204
|
+
};
|
|
1205
|
+
case "mode_changed":
|
|
1206
|
+
return {
|
|
1207
|
+
ts: ev.ts,
|
|
1208
|
+
source: ev.type,
|
|
1209
|
+
level: "info",
|
|
1210
|
+
text: `mode: ${ev.from} \u2192 ${ev.to}`
|
|
1211
|
+
};
|
|
1212
|
+
case "skill_activated":
|
|
1213
|
+
return {
|
|
1214
|
+
ts: ev.ts,
|
|
1215
|
+
source: ev.type,
|
|
1216
|
+
level: "info",
|
|
1217
|
+
text: `skill activated: ${ev.skillName}`
|
|
1218
|
+
};
|
|
1219
|
+
case "skill_deactivated":
|
|
1220
|
+
return {
|
|
1221
|
+
ts: ev.ts,
|
|
1222
|
+
source: ev.type,
|
|
1223
|
+
level: "info",
|
|
1224
|
+
text: `skill deactivated: ${ev.skillName}`
|
|
1225
|
+
};
|
|
1226
|
+
case "message_truncated":
|
|
1227
|
+
return {
|
|
1228
|
+
ts: ev.ts,
|
|
1229
|
+
source: ev.type,
|
|
1230
|
+
level: "warn",
|
|
1231
|
+
text: ev.after < ev.before ? `message truncated: ${ev.before} \u2192 ${ev.after} tokens` : `message truncated at ${ev.after} tokens`
|
|
1232
|
+
};
|
|
1233
|
+
default:
|
|
1234
|
+
return null;
|
|
1235
|
+
}
|
|
1242
1236
|
}
|
|
1243
|
-
function
|
|
1244
|
-
const
|
|
1245
|
-
const
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
hard: config.hardThreshold ?? mode.thresholds.hard
|
|
1252
|
-
},
|
|
1253
|
-
preserveK: config.preserveK ?? mode.preserveK,
|
|
1254
|
-
eliseThreshold: config.eliseThreshold ?? mode.eliseThreshold,
|
|
1255
|
-
targetLoad: config.targetLoad ?? mode.targetLoad
|
|
1256
|
-
};
|
|
1237
|
+
function projectSessionMarkers(events, sources = SESSION_MARKER_EVENT_TYPES) {
|
|
1238
|
+
const markers = [];
|
|
1239
|
+
for (const ev of events) {
|
|
1240
|
+
if (!sources.has(ev.type)) continue;
|
|
1241
|
+
const marker = sessionEventToMarker(ev);
|
|
1242
|
+
if (marker) markers.push(marker);
|
|
1243
|
+
}
|
|
1244
|
+
return markers;
|
|
1257
1245
|
}
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1246
|
+
var SYSTEM_INJECTION_PREFIXES = [
|
|
1247
|
+
"[MAILBOX]",
|
|
1248
|
+
"[MAILBOX BTW]",
|
|
1249
|
+
"[BY THE WAY \u2014",
|
|
1250
|
+
"[QUEUED MESSAGES \u2014",
|
|
1251
|
+
"[FLEET PULSE]",
|
|
1252
|
+
"[loop-detector]",
|
|
1253
|
+
"[SESSION RESUME FILE VALIDATION]",
|
|
1254
|
+
"[SESSION RESUME INTERRUPTED WORK]"
|
|
1255
|
+
];
|
|
1256
|
+
function isSystemInjectedMessage(text) {
|
|
1257
|
+
const trimmed = text.trimStart();
|
|
1258
|
+
for (const prefix of SYSTEM_INJECTION_PREFIXES) {
|
|
1259
|
+
if (trimmed.startsWith(prefix)) return true;
|
|
1260
|
+
}
|
|
1261
|
+
return false;
|
|
1264
1262
|
}
|
|
1265
1263
|
|
|
1266
1264
|
// src/types/spec.ts
|
|
@@ -1288,6 +1286,27 @@ var DEFAULT_SPEC_TEMPLATE = {
|
|
|
1288
1286
|
}
|
|
1289
1287
|
]
|
|
1290
1288
|
};
|
|
1289
|
+
|
|
1290
|
+
// src/types/system-prompt.ts
|
|
1291
|
+
function flattenSystemPromptRegions(regions) {
|
|
1292
|
+
return [...regions.core, ...regions.session, ...regions.volatile];
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
// src/types/tool.ts
|
|
1296
|
+
var ToolErrorCategory = /* @__PURE__ */ ((ToolErrorCategory2) => {
|
|
1297
|
+
ToolErrorCategory2["TRANSIENT"] = "transient";
|
|
1298
|
+
ToolErrorCategory2["NOT_FOUND"] = "not_found";
|
|
1299
|
+
ToolErrorCategory2["PERMISSION"] = "permission";
|
|
1300
|
+
ToolErrorCategory2["VALIDATION"] = "validation";
|
|
1301
|
+
ToolErrorCategory2["FATAL"] = "fatal";
|
|
1302
|
+
return ToolErrorCategory2;
|
|
1303
|
+
})(ToolErrorCategory || {});
|
|
1304
|
+
|
|
1305
|
+
// src/types/tool-executor.ts
|
|
1306
|
+
var GOVERNED_TOOL_EXECUTOR_META_KEY = "toolExecutor.executeGoverned";
|
|
1307
|
+
|
|
1308
|
+
// src/types/tool-markers.ts
|
|
1309
|
+
var MALFORMED_ARG_MARKERS = ["__raw", "__raw_arguments", "_raw"];
|
|
1291
1310
|
export {
|
|
1292
1311
|
AgentError,
|
|
1293
1312
|
BUILTIN_PROMPT_CATEGORIES,
|
|
@@ -1321,6 +1340,7 @@ export {
|
|
|
1321
1340
|
PluginError,
|
|
1322
1341
|
ProviderError,
|
|
1323
1342
|
SESSION_MARKER_EVENT_TYPES,
|
|
1343
|
+
SYSTEM_INJECTION_PREFIXES,
|
|
1324
1344
|
SddError,
|
|
1325
1345
|
SessionError,
|
|
1326
1346
|
StreamHangError,
|
|
@@ -1353,6 +1373,7 @@ export {
|
|
|
1353
1373
|
isRetryableKind,
|
|
1354
1374
|
isSddError,
|
|
1355
1375
|
isSessionError,
|
|
1376
|
+
isSystemInjectedMessage,
|
|
1356
1377
|
isTextBlock,
|
|
1357
1378
|
isToolError,
|
|
1358
1379
|
isToolResultBlock,
|