@wrongstack/core 0.275.0 → 0.276.2
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/{agent-bridge-D9JkPvJ0.d.ts → agent-bridge-D7A-eu3C.d.ts} +1 -1
- package/dist/{agent-subagent-runner-CArSFKFl.d.ts → agent-subagent-runner-CEuw4ATz.d.ts} +16 -10
- package/dist/{brain-DCkB5_e7.d.ts → brain-BLOyN5ZP.d.ts} +127 -1
- package/dist/{compactor-CzSvxM1g.d.ts → compactor-DcBpaJsI.d.ts} +1 -1
- package/dist/{config-BzFRKkg7.d.ts → config-Bf5mj-ad.d.ts} +20 -2
- package/dist/{context-BrLe8pJy.d.ts → context-CLnUMW5g.d.ts} +40 -2
- package/dist/coordination/index.d.ts +43 -24
- package/dist/coordination/index.js +849 -648
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +28 -28
- package/dist/defaults/index.js +1636 -845
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +16 -16
- package/dist/execution/index.js +218 -49
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +1 -1
- package/dist/extension/index.d.ts +7 -7
- package/dist/extension/index.js.map +1 -1
- package/dist/{global-mailbox-CXkugtNQ.d.ts → global-mailbox-Iqfkgmwu.d.ts} +3 -3
- package/dist/{goal-store-DUwdbdoY.d.ts → goal-store-DGb6b5Ed.d.ts} +1 -1
- package/dist/hq/index.d.ts +6 -6
- package/dist/hq/index.js +178 -75
- package/dist/hq/index.js.map +1 -1
- package/dist/{index-CtlizLTK.d.ts → index-Cn0NOshr.d.ts} +10 -5
- package/dist/{index-neOCEy6q.d.ts → index-L4RZN9jJ.d.ts} +2 -2
- package/dist/index.d.ts +56 -48
- package/dist/index.js +2789 -1546
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/infrastructure/index.js +26 -7
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +20 -12
- package/dist/kernel/index.js +55 -9
- package/dist/kernel/index.js.map +1 -1
- package/dist/{mailbox-types-_7gaY0Rl.d.ts → mailbox-types-DTl7bRH3.d.ts} +3 -1
- package/dist/{mcp-servers-MLL6bMlv.d.ts → mcp-servers-CuZGf9fI.d.ts} +4 -4
- package/dist/models/index.d.ts +5 -5
- package/dist/models/index.js +223 -139
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-CrkcxQ-g.d.ts → models-registry-8XOdxWQu.d.ts} +16 -1
- package/dist/{multi-agent-coordinator-Dc_HuG9p.d.ts → multi-agent-coordinator-CiRtKVTk.d.ts} +8 -1
- package/dist/{null-fleet-bus-BMZwMin7.d.ts → null-fleet-bus-d9G-bVy9.d.ts} +26 -22
- package/dist/observability/index.d.ts +2 -2
- package/dist/{path-resolver-uVK4BatM.d.ts → path-resolver-BhIb6mtd.d.ts} +8 -3
- package/dist/{permission-CJR1qfOi.d.ts → permission-BCbQDR2s.d.ts} +1 -1
- package/dist/{permission-policy-DLVKKk4w.d.ts → permission-policy-C0ikndX_.d.ts} +2 -18
- package/dist/{pipeline-BYR-Vdau.d.ts → pipeline-Dl6XbfE7.d.ts} +10 -6
- package/dist/{provider-model-resolve-iREK_1lG.d.ts → provider-model-resolve-B70epO19.d.ts} +3 -3
- package/dist/{provider-runner-i7SQXZuC.d.ts → provider-runner-DZ808MSM.d.ts} +3 -3
- package/dist/{retry-policy-BmY5ooh3.d.ts → retry-policy-Dt3_z8Aj.d.ts} +1 -1
- package/dist/sdd/index.d.ts +19 -10
- package/dist/sdd/index.js +411 -240
- package/dist/sdd/index.js.map +1 -1
- package/dist/{secret-vault-C9leEMzr.d.ts → secret-vault-BUJ2d1gB.d.ts} +1 -1
- package/dist/security/index.d.ts +5 -5
- package/dist/security/index.js +30 -6
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-qjpee9BF.d.ts → selector-BCkWgdwy.d.ts} +1 -1
- package/dist/{session-event-bridge-m7y--I-H.d.ts → session-event-bridge-CMvIO59_.d.ts} +1 -1
- package/dist/{session-reader-BjLH4V9n.d.ts → session-reader-C8aiChUu.d.ts} +1 -1
- package/dist/skills/index.js +1 -0
- package/dist/skills/index.js.map +1 -1
- package/dist/storage/index.d.ts +68 -30
- package/dist/storage/index.js +839 -528
- package/dist/storage/index.js.map +1 -1
- package/dist/{strategy-compactor-C2bmlWYg.d.ts → strategy-compactor-DI1OHVbB.d.ts} +10 -10
- package/dist/{todos-checkpoint-oDS9IBNS.d.ts → todos-checkpoint-Ddd2CGr0.d.ts} +56 -9
- package/dist/{tool-executor-D4YdaJ-M.d.ts → tool-executor-Bmd5Ygoo.d.ts} +45 -10
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/types/index.d.ts +20 -20
- package/dist/types/index.js +331 -98
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +16 -3
- package/dist/utils/index.js +159 -83
- package/dist/utils/index.js.map +1 -1
- package/dist/{worktree-manager-A1Efnvs0.d.ts → worktree-manager-DBdl_5rs.d.ts} +4 -1
- package/instructions/agents/shadow-agent.md +3 -3
- package/instructions/coordination/director-preamble.md +3 -3
- package/instructions/modes/research-web.md +4 -4
- package/package.json +1 -1
- package/skills/research-web/SKILL.md +26 -26
- package/skills/research-web/SKILL.save.md +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { C as Compactor } from './compactor-
|
|
2
|
-
import { M as Message, T as Tool } from './context-
|
|
3
|
-
import { c as MCPServerConfig } from './config-
|
|
1
|
+
import { C as Compactor } from './compactor-DcBpaJsI.js';
|
|
2
|
+
import { M as Message, T as Tool } from './context-CLnUMW5g.js';
|
|
3
|
+
import { c as MCPServerConfig } from './config-Bf5mj-ad.js';
|
|
4
4
|
|
|
5
5
|
type ContextManagerAction = 'check' | 'summary' | 'prune' | 'add_note' | 'compact' | 'repair';
|
|
6
6
|
interface ContextManagerInput {
|
|
@@ -149,7 +149,7 @@ declare const zaiVisionServer: () => MCPServerConfig;
|
|
|
149
149
|
*/
|
|
150
150
|
declare const playwrightServer: () => MCPServerConfig;
|
|
151
151
|
/**
|
|
152
|
-
* MiniMax Token Plan MCP —
|
|
152
|
+
* MiniMax Token Plan MCP — search + understand_image.
|
|
153
153
|
* This preset exposes only the read-only image understanding tool by default.
|
|
154
154
|
* Requires MINIMAX_API_KEY and uvx on PATH.
|
|
155
155
|
*/
|
package/dist/models/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { D as DefaultModelsRegistry, a as DefaultModelsRegistryOptions, c as classifyFamily } from '../models-registry-
|
|
2
|
-
export { C as CODEX_MODELS, a as CodexModelMeta, D as DefaultModeStore, L as LLMSelector, b as LLMSelectorOptions, M as ModeLoaderOptions, P as ProviderModelDescriptor, c as codexModelMeta, d as describeCatalogModel, l as loadProjectModes, e as loadUserModes, r as resolveProviderModelList } from '../provider-model-resolve-
|
|
3
|
-
import { d as ModelMatrixEntry, P as ProviderConfig } from '../config-
|
|
4
|
-
import '../context-
|
|
5
|
-
import '../selector-
|
|
1
|
+
export { D as DefaultModelsRegistry, a as DefaultModelsRegistryOptions, c as classifyFamily } from '../models-registry-8XOdxWQu.js';
|
|
2
|
+
export { C as CODEX_MODELS, a as CodexModelMeta, D as DefaultModeStore, L as LLMSelector, b as LLMSelectorOptions, M as ModeLoaderOptions, P as ProviderModelDescriptor, c as codexModelMeta, d as describeCatalogModel, l as loadProjectModes, e as loadUserModes, r as resolveProviderModelList } from '../provider-model-resolve-B70epO19.js';
|
|
3
|
+
import { d as ModelMatrixEntry, P as ProviderConfig } from '../config-Bf5mj-ad.js';
|
|
4
|
+
import '../context-CLnUMW5g.js';
|
|
5
|
+
import '../selector-BCkWgdwy.js';
|
|
6
6
|
import '../mode-CZlO9iU1.js';
|
|
7
7
|
|
|
8
8
|
/**
|
package/dist/models/index.js
CHANGED
|
@@ -5,79 +5,22 @@ import { readFileSync, statSync } from 'fs';
|
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
|
|
7
7
|
// src/models/models-registry.ts
|
|
8
|
-
async function atomicWrite(targetPath, content, opts = {}) {
|
|
9
|
-
const dir = path4.dirname(targetPath);
|
|
10
|
-
await fs.mkdir(dir, { recursive: true });
|
|
11
|
-
const tmp = path4.join(dir, `.${path4.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
|
|
12
|
-
try {
|
|
13
|
-
if (typeof content === "string") {
|
|
14
|
-
await fs.writeFile(tmp, content, { flag: "wx", encoding: opts.encoding ?? "utf8" });
|
|
15
|
-
} else {
|
|
16
|
-
await fs.writeFile(tmp, content, { flag: "wx" });
|
|
17
|
-
}
|
|
18
|
-
try {
|
|
19
|
-
const fh = await fs.open(tmp, "r+");
|
|
20
|
-
try {
|
|
21
|
-
await fh.sync();
|
|
22
|
-
} finally {
|
|
23
|
-
await fh.close();
|
|
24
|
-
}
|
|
25
|
-
} catch {
|
|
26
|
-
}
|
|
27
|
-
let mode;
|
|
28
|
-
try {
|
|
29
|
-
const stat3 = await fs.stat(targetPath);
|
|
30
|
-
mode = stat3.mode & 511;
|
|
31
|
-
} catch {
|
|
32
|
-
mode = opts.mode;
|
|
33
|
-
}
|
|
34
|
-
if (mode !== void 0) {
|
|
35
|
-
await fs.chmod(tmp, mode);
|
|
36
|
-
}
|
|
37
|
-
await renameWithRetry(tmp, targetPath);
|
|
38
|
-
if (mode !== void 0 && process.platform === "win32") {
|
|
39
|
-
try {
|
|
40
|
-
await fs.chmod(targetPath, mode);
|
|
41
|
-
} catch {
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
} catch (err) {
|
|
45
|
-
try {
|
|
46
|
-
await fs.unlink(tmp);
|
|
47
|
-
} catch {
|
|
48
|
-
}
|
|
49
|
-
throw err;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
var TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EBUSY", "EACCES", "ENOTEMPTY"]);
|
|
53
|
-
async function renameWithRetry(from, to) {
|
|
54
|
-
if (process.platform !== "win32") {
|
|
55
|
-
await fs.rename(from, to);
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
const delays = [10, 25, 60, 120, 250];
|
|
59
|
-
let lastErr;
|
|
60
|
-
for (let i = 0; i <= delays.length; i++) {
|
|
61
|
-
try {
|
|
62
|
-
await fs.rename(from, to);
|
|
63
|
-
return;
|
|
64
|
-
} catch (err) {
|
|
65
|
-
lastErr = err;
|
|
66
|
-
const code = err?.code;
|
|
67
|
-
if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {
|
|
68
|
-
throw err;
|
|
69
|
-
}
|
|
70
|
-
await new Promise((resolve4) => setTimeout(resolve4, delays[i]));
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
throw lastErr;
|
|
74
|
-
}
|
|
75
8
|
|
|
76
9
|
// src/utils/error.ts
|
|
77
10
|
function toErrorMessage(err) {
|
|
78
11
|
return err instanceof Error ? err.message : String(err);
|
|
79
12
|
}
|
|
80
13
|
|
|
14
|
+
// src/utils/expect-defined.ts
|
|
15
|
+
function expectDefined(value, label) {
|
|
16
|
+
if (value === null || value === void 0) {
|
|
17
|
+
const err = new Error("Expected value to be defined");
|
|
18
|
+
err.name = "ExpectDefinedError";
|
|
19
|
+
throw err;
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
|
|
81
24
|
// src/utils/merge-models-payload.ts
|
|
82
25
|
function mergeModelsPayload(base, overlay) {
|
|
83
26
|
const out = {};
|
|
@@ -141,6 +84,180 @@ function stripUndefined(obj) {
|
|
|
141
84
|
return out;
|
|
142
85
|
}
|
|
143
86
|
|
|
87
|
+
// src/utils/token-estimate.ts
|
|
88
|
+
var RoughTokenEstimate = (text, charsPerToken = 3.5) => Math.max(1, Math.ceil(text.length / charsPerToken));
|
|
89
|
+
var ESTIMATE_CACHE = /* @__PURE__ */ new Map();
|
|
90
|
+
var _estimateCacheOrder = [];
|
|
91
|
+
var ESTIMATE_CACHE_MAX_SIZE = 5e4;
|
|
92
|
+
function getCachedEstimate(key, compute) {
|
|
93
|
+
const existing = ESTIMATE_CACHE.get(key);
|
|
94
|
+
if (existing !== void 0) return existing;
|
|
95
|
+
if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {
|
|
96
|
+
while (ESTIMATE_CACHE.size > Math.floor(ESTIMATE_CACHE_MAX_SIZE / 2)) {
|
|
97
|
+
const oldest = _estimateCacheOrder.shift();
|
|
98
|
+
if (oldest !== void 0) ESTIMATE_CACHE.delete(oldest);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const estimate = compute(key);
|
|
102
|
+
ESTIMATE_CACHE.set(key, estimate);
|
|
103
|
+
_estimateCacheOrder.push(key);
|
|
104
|
+
return estimate;
|
|
105
|
+
}
|
|
106
|
+
function estimateToolInputTokens(input) {
|
|
107
|
+
if (typeof input === "string") return RoughTokenEstimate(input);
|
|
108
|
+
if (input === null || typeof input !== "object") {
|
|
109
|
+
return RoughTokenEstimate(String(input));
|
|
110
|
+
}
|
|
111
|
+
return getCachedEstimate(JSON.stringify(input), (key) => RoughTokenEstimate(key));
|
|
112
|
+
}
|
|
113
|
+
function estimateToolResultTokens(content) {
|
|
114
|
+
if (typeof content === "string") return RoughTokenEstimate(content);
|
|
115
|
+
return getCachedEstimate(JSON.stringify(content), (key) => RoughTokenEstimate(key));
|
|
116
|
+
}
|
|
117
|
+
function estimateTextTokens(text) {
|
|
118
|
+
return RoughTokenEstimate(text);
|
|
119
|
+
}
|
|
120
|
+
function computeMessageTokens(msg) {
|
|
121
|
+
if (typeof msg.content === "string") return estimateTextTokens(msg.content);
|
|
122
|
+
let total = 0;
|
|
123
|
+
for (const b of msg.content) {
|
|
124
|
+
if (b.type === "text") total += estimateTextTokens(b.text);
|
|
125
|
+
else if (b.type === "tool_use") total += estimateToolInputTokens(b.input);
|
|
126
|
+
else if (b.type === "tool_result") total += estimateToolResultTokens(b.content);
|
|
127
|
+
else total += RoughTokenEstimate(JSON.stringify(b));
|
|
128
|
+
}
|
|
129
|
+
return total;
|
|
130
|
+
}
|
|
131
|
+
function estimateMessageTokens(messages) {
|
|
132
|
+
let total = 0;
|
|
133
|
+
for (const m of messages) {
|
|
134
|
+
if (typeof m._estTokens === "number" && m._estTokens > 0) {
|
|
135
|
+
total += m._estTokens;
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
total += computeMessageTokens(m);
|
|
139
|
+
}
|
|
140
|
+
return total;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// src/types/errors.ts
|
|
144
|
+
var ERROR_CODES = {
|
|
145
|
+
// General
|
|
146
|
+
VALIDATION_ERROR: "VALIDATION_ERROR"};
|
|
147
|
+
var WrongStackError = class extends Error {
|
|
148
|
+
code;
|
|
149
|
+
subsystem;
|
|
150
|
+
severity;
|
|
151
|
+
recoverable;
|
|
152
|
+
context;
|
|
153
|
+
constructor(opts) {
|
|
154
|
+
super(opts.message, { cause: opts.cause });
|
|
155
|
+
this.name = "WrongStackError";
|
|
156
|
+
this.code = opts.code;
|
|
157
|
+
this.subsystem = opts.subsystem;
|
|
158
|
+
this.severity = opts.severity ?? "error";
|
|
159
|
+
this.recoverable = opts.recoverable ?? false;
|
|
160
|
+
this.context = opts.context;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Render a one-line user-facing description.
|
|
164
|
+
* Subclasses should override for domain-specific formatting.
|
|
165
|
+
*/
|
|
166
|
+
describe() {
|
|
167
|
+
const ctx = this.context ? ` ${formatContext(this.context)}` : "";
|
|
168
|
+
return `${this.code}: ${this.message}${ctx}`;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
function formatContext(ctx) {
|
|
172
|
+
const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
|
|
173
|
+
return parts.length > 0 ? `[${parts.join(" ")}]` : "";
|
|
174
|
+
}
|
|
175
|
+
var FetchError = class extends WrongStackError {
|
|
176
|
+
status;
|
|
177
|
+
constructor(opts) {
|
|
178
|
+
super({
|
|
179
|
+
message: opts.message,
|
|
180
|
+
code: ERROR_CODES.VALIDATION_ERROR,
|
|
181
|
+
subsystem: "general",
|
|
182
|
+
severity: "error",
|
|
183
|
+
recoverable: opts.status === 429 || opts.status >= 500,
|
|
184
|
+
context: { status: opts.status, ...opts.context },
|
|
185
|
+
cause: opts.cause
|
|
186
|
+
});
|
|
187
|
+
this.name = "FetchError";
|
|
188
|
+
this.status = opts.status;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
// src/utils/atomic-write.ts
|
|
193
|
+
async function atomicWrite(targetPath, content, opts = {}) {
|
|
194
|
+
const dir = path4.dirname(targetPath);
|
|
195
|
+
await fs.mkdir(dir, { recursive: true });
|
|
196
|
+
const tmp = path4.join(dir, `.${path4.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
|
|
197
|
+
try {
|
|
198
|
+
if (typeof content === "string") {
|
|
199
|
+
await fs.writeFile(tmp, content, { flag: "wx", encoding: opts.encoding ?? "utf8" });
|
|
200
|
+
} else {
|
|
201
|
+
await fs.writeFile(tmp, content, { flag: "wx" });
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
const fh = await fs.open(tmp, "r+");
|
|
205
|
+
try {
|
|
206
|
+
await fh.sync();
|
|
207
|
+
} finally {
|
|
208
|
+
await fh.close();
|
|
209
|
+
}
|
|
210
|
+
} catch {
|
|
211
|
+
}
|
|
212
|
+
let mode;
|
|
213
|
+
try {
|
|
214
|
+
const stat3 = await fs.stat(targetPath);
|
|
215
|
+
mode = stat3.mode & 511;
|
|
216
|
+
} catch {
|
|
217
|
+
mode = opts.mode;
|
|
218
|
+
}
|
|
219
|
+
if (mode !== void 0) {
|
|
220
|
+
await fs.chmod(tmp, mode);
|
|
221
|
+
}
|
|
222
|
+
await renameWithRetry(tmp, targetPath);
|
|
223
|
+
if (mode !== void 0 && process.platform === "win32") {
|
|
224
|
+
try {
|
|
225
|
+
await fs.chmod(targetPath, mode);
|
|
226
|
+
} catch {
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
} catch (err) {
|
|
230
|
+
try {
|
|
231
|
+
await fs.unlink(tmp);
|
|
232
|
+
} catch {
|
|
233
|
+
}
|
|
234
|
+
throw err;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
var TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EBUSY", "EACCES", "ENOTEMPTY"]);
|
|
238
|
+
async function renameWithRetry(from, to) {
|
|
239
|
+
if (process.platform !== "win32") {
|
|
240
|
+
await fs.rename(from, to);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const delays = [10, 25, 60, 120, 250];
|
|
244
|
+
let lastErr;
|
|
245
|
+
for (let i = 0; i <= delays.length; i++) {
|
|
246
|
+
try {
|
|
247
|
+
await fs.rename(from, to);
|
|
248
|
+
return;
|
|
249
|
+
} catch (err) {
|
|
250
|
+
lastErr = err;
|
|
251
|
+
const code = err?.code;
|
|
252
|
+
if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {
|
|
253
|
+
throw err;
|
|
254
|
+
}
|
|
255
|
+
await new Promise((resolve4) => setTimeout(resolve4, delays[i]));
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
throw lastErr;
|
|
259
|
+
}
|
|
260
|
+
|
|
144
261
|
// src/models/models-registry.ts
|
|
145
262
|
var DEFAULT_URL = "https://models.dev/api.json";
|
|
146
263
|
var ENV_URL_KEY = "WRONGSTACK_MODELS_DEV_URL";
|
|
@@ -175,6 +292,14 @@ var DefaultModelsRegistry = class {
|
|
|
175
292
|
payload;
|
|
176
293
|
/** Memoised overlay payload (in-memory / fetched / file). */
|
|
177
294
|
overlayPayload;
|
|
295
|
+
/**
|
|
296
|
+
* Extra providers injected at runtime via `mergeOverlay()` — e.g. an
|
|
297
|
+
* openai-compatible server (omniroute, LiteLLM, …) auto-discovered from its
|
|
298
|
+
* `/v1/models` endpoint at boot. Applied LAST (on top of base + curated
|
|
299
|
+
* overlay) and re-applied across `refresh()` so the discovered catalog
|
|
300
|
+
* survives a models.dev refetch.
|
|
301
|
+
*/
|
|
302
|
+
extraOverlay;
|
|
178
303
|
fetchedAt;
|
|
179
304
|
cacheFile;
|
|
180
305
|
url;
|
|
@@ -210,9 +335,22 @@ var DefaultModelsRegistry = class {
|
|
|
210
335
|
}
|
|
211
336
|
const overlay = await this.loadOverlay(opts);
|
|
212
337
|
const base = await this.loadBase(opts, Object.keys(overlay).length > 0);
|
|
213
|
-
this.payload = mergeModelsPayload(base, overlay);
|
|
338
|
+
this.payload = this.withExtraOverlay(mergeModelsPayload(base, overlay));
|
|
214
339
|
return this.payload;
|
|
215
340
|
}
|
|
341
|
+
/**
|
|
342
|
+
* Merge an additional provider payload on top of the resolved catalog. Used
|
|
343
|
+
* for runtime-discovered openai-compatible providers. Remembered so it is
|
|
344
|
+
* re-applied across `refresh()`. A no-op for an empty payload.
|
|
345
|
+
*/
|
|
346
|
+
mergeOverlay(payload) {
|
|
347
|
+
if (!hasEntries(payload)) return;
|
|
348
|
+
this.extraOverlay = this.extraOverlay ? mergeModelsPayload(this.extraOverlay, payload) : payload;
|
|
349
|
+
if (this.payload) this.payload = mergeModelsPayload(this.payload, this.extraOverlay);
|
|
350
|
+
}
|
|
351
|
+
withExtraOverlay(payload) {
|
|
352
|
+
return this.extraOverlay ? mergeModelsPayload(payload, this.extraOverlay) : payload;
|
|
353
|
+
}
|
|
216
354
|
/**
|
|
217
355
|
* Load the models.dev base payload: fresh cache → network → stale cache.
|
|
218
356
|
* On total failure, degrade to `{}` (so a non-empty overlay still drives
|
|
@@ -261,7 +399,11 @@ var DefaultModelsRegistry = class {
|
|
|
261
399
|
});
|
|
262
400
|
clearTimeout(timeout);
|
|
263
401
|
if (!res.ok) {
|
|
264
|
-
throw new
|
|
402
|
+
throw new FetchError({
|
|
403
|
+
message: `ModelsRegistry: HTTP ${res.status} fetching ${this.url}`,
|
|
404
|
+
status: res.status,
|
|
405
|
+
context: { url: this.url, op: "refreshModels" }
|
|
406
|
+
});
|
|
265
407
|
}
|
|
266
408
|
const json = await res.json();
|
|
267
409
|
this.fetchedAt = /* @__PURE__ */ new Date();
|
|
@@ -275,7 +417,11 @@ var DefaultModelsRegistry = class {
|
|
|
275
417
|
} catch (err) {
|
|
276
418
|
clearTimeout(timeout);
|
|
277
419
|
if (err instanceof Error && err.name === "AbortError") {
|
|
278
|
-
throw new
|
|
420
|
+
throw new FetchError({
|
|
421
|
+
message: `ModelsRegistry: fetch timed out after ${this.refreshTimeoutMs}ms`,
|
|
422
|
+
status: 408,
|
|
423
|
+
context: { url: this.url, op: "refreshModels", timedOut: true }
|
|
424
|
+
});
|
|
279
425
|
}
|
|
280
426
|
throw err;
|
|
281
427
|
}
|
|
@@ -311,7 +457,11 @@ var DefaultModelsRegistry = class {
|
|
|
311
457
|
method: "GET",
|
|
312
458
|
headers: { accept: "application/json" }
|
|
313
459
|
});
|
|
314
|
-
if (!res.ok) throw new
|
|
460
|
+
if (!res.ok) throw new FetchError({
|
|
461
|
+
message: `HTTP ${res.status}`,
|
|
462
|
+
status: res.status,
|
|
463
|
+
context: { url: this.url, op: "refreshModels" }
|
|
464
|
+
});
|
|
315
465
|
const json = await res.json();
|
|
316
466
|
const envelope = {
|
|
317
467
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -345,7 +495,7 @@ var DefaultModelsRegistry = class {
|
|
|
345
495
|
async refresh() {
|
|
346
496
|
const base = await this.refreshBase();
|
|
347
497
|
const overlay = await this.loadOverlay({ force: true });
|
|
348
|
-
this.payload = mergeModelsPayload(base, overlay);
|
|
498
|
+
this.payload = this.withExtraOverlay(mergeModelsPayload(base, overlay));
|
|
349
499
|
return this.payload;
|
|
350
500
|
}
|
|
351
501
|
async listProviders() {
|
|
@@ -570,7 +720,7 @@ var DEFAULT_MODES = [
|
|
|
570
720
|
description: "Current-data research \u2014 search web, verify, inject findings into context",
|
|
571
721
|
prompt: modePrompt("research-web"),
|
|
572
722
|
tags: ["research", "web", "current-data", "up-to-date"],
|
|
573
|
-
toolPreferences: ["
|
|
723
|
+
toolPreferences: ["search/fetch", "search/fetch", "search", "fetch", "context_manager"],
|
|
574
724
|
suggestedSkills: ["research-web", "tech-stack", "node-modern", "security-scanner", "react-modern"]
|
|
575
725
|
}
|
|
576
726
|
];
|
|
@@ -679,72 +829,6 @@ async function loadUserModes(modesDir) {
|
|
|
679
829
|
return modes;
|
|
680
830
|
}
|
|
681
831
|
|
|
682
|
-
// src/utils/expect-defined.ts
|
|
683
|
-
function expectDefined(value, label) {
|
|
684
|
-
if (value === null || value === void 0) {
|
|
685
|
-
const err = new Error("Expected value to be defined");
|
|
686
|
-
err.name = "ExpectDefinedError";
|
|
687
|
-
throw err;
|
|
688
|
-
}
|
|
689
|
-
return value;
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
// src/utils/token-estimate.ts
|
|
693
|
-
var RoughTokenEstimate = (text, charsPerToken = 3.5) => Math.max(1, Math.ceil(text.length / charsPerToken));
|
|
694
|
-
var ESTIMATE_CACHE = /* @__PURE__ */ new Map();
|
|
695
|
-
var _estimateCacheOrder = [];
|
|
696
|
-
var ESTIMATE_CACHE_MAX_SIZE = 5e4;
|
|
697
|
-
function getCachedEstimate(key, compute) {
|
|
698
|
-
const existing = ESTIMATE_CACHE.get(key);
|
|
699
|
-
if (existing !== void 0) return existing;
|
|
700
|
-
if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {
|
|
701
|
-
while (ESTIMATE_CACHE.size > Math.floor(ESTIMATE_CACHE_MAX_SIZE / 2)) {
|
|
702
|
-
const oldest = _estimateCacheOrder.shift();
|
|
703
|
-
if (oldest !== void 0) ESTIMATE_CACHE.delete(oldest);
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
const estimate = compute(key);
|
|
707
|
-
ESTIMATE_CACHE.set(key, estimate);
|
|
708
|
-
_estimateCacheOrder.push(key);
|
|
709
|
-
return estimate;
|
|
710
|
-
}
|
|
711
|
-
function estimateToolInputTokens(input) {
|
|
712
|
-
if (typeof input === "string") return RoughTokenEstimate(input);
|
|
713
|
-
if (input === null || typeof input !== "object") {
|
|
714
|
-
return RoughTokenEstimate(String(input));
|
|
715
|
-
}
|
|
716
|
-
return getCachedEstimate(JSON.stringify(input), (key) => RoughTokenEstimate(key));
|
|
717
|
-
}
|
|
718
|
-
function estimateToolResultTokens(content) {
|
|
719
|
-
if (typeof content === "string") return RoughTokenEstimate(content);
|
|
720
|
-
return getCachedEstimate(JSON.stringify(content), (key) => RoughTokenEstimate(key));
|
|
721
|
-
}
|
|
722
|
-
function estimateTextTokens(text) {
|
|
723
|
-
return RoughTokenEstimate(text);
|
|
724
|
-
}
|
|
725
|
-
function computeMessageTokens(msg) {
|
|
726
|
-
if (typeof msg.content === "string") return estimateTextTokens(msg.content);
|
|
727
|
-
let total = 0;
|
|
728
|
-
for (const b of msg.content) {
|
|
729
|
-
if (b.type === "text") total += estimateTextTokens(b.text);
|
|
730
|
-
else if (b.type === "tool_use") total += estimateToolInputTokens(b.input);
|
|
731
|
-
else if (b.type === "tool_result") total += estimateToolResultTokens(b.content);
|
|
732
|
-
else total += RoughTokenEstimate(JSON.stringify(b));
|
|
733
|
-
}
|
|
734
|
-
return total;
|
|
735
|
-
}
|
|
736
|
-
function estimateMessageTokens(messages) {
|
|
737
|
-
let total = 0;
|
|
738
|
-
for (const m of messages) {
|
|
739
|
-
if (typeof m._estTokens === "number" && m._estTokens > 0) {
|
|
740
|
-
total += m._estTokens;
|
|
741
|
-
continue;
|
|
742
|
-
}
|
|
743
|
-
total += computeMessageTokens(m);
|
|
744
|
-
}
|
|
745
|
-
return total;
|
|
746
|
-
}
|
|
747
|
-
|
|
748
832
|
// src/types/blocks.ts
|
|
749
833
|
function isTextBlock(b) {
|
|
750
834
|
return b.type === "text";
|