@cortexkit/opencode-magic-context 0.17.1 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/features/magic-context/dreamer/runner.d.ts +15 -0
- package/dist/features/magic-context/dreamer/runner.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/sidekick/agent.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +14 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts +1 -0
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +1 -1
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +1 -1
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/tool-definition-tokens.d.ts +11 -0
- package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -1
- package/dist/features/magic-context/types.d.ts +1 -0
- package/dist/features/magic-context/types.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts +2 -0
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts +2 -0
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-compressor.d.ts +1 -0
- package/dist/hooks/magic-context/compartment-runner-compressor.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +7 -0
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +2 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/todo-view.d.ts +102 -0
- package/dist/hooks/magic-context/todo-view.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +1 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-message-helpers.d.ts +22 -0
- package/dist/hooks/magic-context/transform-message-helpers.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +2 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/index.js +660 -185
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts +2 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/model-suggestion-retry.d.ts +37 -0
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
- package/dist/shared/models-dev-cache.d.ts.map +1 -1
- package/dist/shared/resolve-fallbacks.d.ts +32 -0
- package/dist/shared/resolve-fallbacks.d.ts.map +1 -0
- package/dist/shared/tag-transcript.d.ts.map +1 -1
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/shared/index.ts +1 -0
- package/src/shared/model-suggestion-retry.test.ts +251 -0
- package/src/shared/model-suggestion-retry.ts +194 -6
- package/src/shared/models-dev-cache.ts +7 -7
- package/src/shared/resolve-fallbacks.test.ts +136 -0
- package/src/shared/resolve-fallbacks.ts +76 -0
- package/src/shared/tag-transcript.ts +3 -2
- package/src/tui/index.tsx +114 -18
package/dist/index.js
CHANGED
|
@@ -15122,6 +15122,161 @@ var init_model_requirements = __esm(() => {
|
|
|
15122
15122
|
};
|
|
15123
15123
|
});
|
|
15124
15124
|
|
|
15125
|
+
// src/features/magic-context/overflow-detection.ts
|
|
15126
|
+
function extractErrorMessage(error51) {
|
|
15127
|
+
if (!error51)
|
|
15128
|
+
return "";
|
|
15129
|
+
if (typeof error51 === "string")
|
|
15130
|
+
return error51;
|
|
15131
|
+
if (typeof error51 === "object") {
|
|
15132
|
+
const obj = error51;
|
|
15133
|
+
const nested = obj.error;
|
|
15134
|
+
if (nested && typeof nested.message === "string" && nested.message.length > 0) {
|
|
15135
|
+
return nested.message;
|
|
15136
|
+
}
|
|
15137
|
+
}
|
|
15138
|
+
if (error51 instanceof Error)
|
|
15139
|
+
return error51.message;
|
|
15140
|
+
if (typeof error51 === "object") {
|
|
15141
|
+
const obj = error51;
|
|
15142
|
+
if (typeof obj.message === "string")
|
|
15143
|
+
return obj.message;
|
|
15144
|
+
if (typeof obj.responseBody === "string")
|
|
15145
|
+
return obj.responseBody;
|
|
15146
|
+
try {
|
|
15147
|
+
return JSON.stringify(error51);
|
|
15148
|
+
} catch {
|
|
15149
|
+
return String(error51);
|
|
15150
|
+
}
|
|
15151
|
+
}
|
|
15152
|
+
return String(error51);
|
|
15153
|
+
}
|
|
15154
|
+
function detectOverflow(error51) {
|
|
15155
|
+
const message = extractErrorMessage(error51);
|
|
15156
|
+
if (!message) {
|
|
15157
|
+
return { isOverflow: false };
|
|
15158
|
+
}
|
|
15159
|
+
const hasStatus413 = /\b413\b/.test(message) && /(entity|payload|context|prompt)/i.test(message);
|
|
15160
|
+
let matched;
|
|
15161
|
+
for (const pattern of OVERFLOW_PATTERNS) {
|
|
15162
|
+
if (pattern.test(message)) {
|
|
15163
|
+
matched = pattern;
|
|
15164
|
+
break;
|
|
15165
|
+
}
|
|
15166
|
+
}
|
|
15167
|
+
if (!matched && !hasStatus413) {
|
|
15168
|
+
return { isOverflow: false };
|
|
15169
|
+
}
|
|
15170
|
+
const reportedLimit = parseReportedLimit(message);
|
|
15171
|
+
return {
|
|
15172
|
+
isOverflow: true,
|
|
15173
|
+
reportedLimit,
|
|
15174
|
+
matchedPattern: matched?.source
|
|
15175
|
+
};
|
|
15176
|
+
}
|
|
15177
|
+
function parseReportedLimit(message) {
|
|
15178
|
+
if (!message)
|
|
15179
|
+
return;
|
|
15180
|
+
for (const pattern of LIMIT_EXTRACTION_PATTERNS) {
|
|
15181
|
+
const match = message.match(pattern);
|
|
15182
|
+
if (!match)
|
|
15183
|
+
continue;
|
|
15184
|
+
const raw = match[1];
|
|
15185
|
+
if (!raw)
|
|
15186
|
+
continue;
|
|
15187
|
+
const value = Number.parseInt(raw, 10);
|
|
15188
|
+
if (!Number.isFinite(value))
|
|
15189
|
+
continue;
|
|
15190
|
+
if (value < MIN_PLAUSIBLE_LIMIT || value > MAX_PLAUSIBLE_LIMIT)
|
|
15191
|
+
continue;
|
|
15192
|
+
return value;
|
|
15193
|
+
}
|
|
15194
|
+
return;
|
|
15195
|
+
}
|
|
15196
|
+
var OVERFLOW_PATTERNS, LIMIT_EXTRACTION_PATTERNS, MIN_PLAUSIBLE_LIMIT = 1024, MAX_PLAUSIBLE_LIMIT = 1e7;
|
|
15197
|
+
var init_overflow_detection = __esm(() => {
|
|
15198
|
+
OVERFLOW_PATTERNS = [
|
|
15199
|
+
/prompt is too long/i,
|
|
15200
|
+
/input is too long for requested model/i,
|
|
15201
|
+
/exceeds the context window/i,
|
|
15202
|
+
/input token count.*exceeds the maximum/i,
|
|
15203
|
+
/maximum prompt length is \d+/i,
|
|
15204
|
+
/reduce the length of the messages/i,
|
|
15205
|
+
/maximum context length is \d+ tokens/i,
|
|
15206
|
+
/exceeds the limit of \d+/i,
|
|
15207
|
+
/exceeds the available context size/i,
|
|
15208
|
+
/greater than the context length/i,
|
|
15209
|
+
/context window exceeds limit/i,
|
|
15210
|
+
/exceeded model token limit/i,
|
|
15211
|
+
/context[_ ]length[_ ]exceeded/i,
|
|
15212
|
+
/request entity too large/i,
|
|
15213
|
+
/context length is only \d+ tokens/i,
|
|
15214
|
+
/input length.*exceeds.*context length/i,
|
|
15215
|
+
/prompt too long; exceeded (?:max )?context length/i,
|
|
15216
|
+
/too large for model with \d+ maximum context length/i,
|
|
15217
|
+
/model_context_window_exceeded/i,
|
|
15218
|
+
/context size has been exceeded/i
|
|
15219
|
+
];
|
|
15220
|
+
LIMIT_EXTRACTION_PATTERNS = [
|
|
15221
|
+
/maximum prompt length is (\d+)/i,
|
|
15222
|
+
/maximum context length is (\d+) tokens?/i,
|
|
15223
|
+
/context length is only (\d+) tokens?/i,
|
|
15224
|
+
/exceeds the limit of (\d+)/i,
|
|
15225
|
+
/too large for model with (\d+) maximum context length/i,
|
|
15226
|
+
/context size.*(\d+) tokens?/i,
|
|
15227
|
+
/exceeds? the context length of (\d+)/i,
|
|
15228
|
+
/max(?:imum)?.*context.*?(\d+)/i
|
|
15229
|
+
];
|
|
15230
|
+
});
|
|
15231
|
+
|
|
15232
|
+
// src/shared/resolve-fallbacks.ts
|
|
15233
|
+
function resolveFallbackChain(agentName, userFallbacks) {
|
|
15234
|
+
const userList = normalizeUserFallbacks(userFallbacks);
|
|
15235
|
+
if (userList.length > 0) {
|
|
15236
|
+
return dedupe(userList.filter(isValidModelSpec));
|
|
15237
|
+
}
|
|
15238
|
+
const builtin = getAgentFallbackModels(agentName);
|
|
15239
|
+
if (!builtin || builtin.length === 0)
|
|
15240
|
+
return [];
|
|
15241
|
+
return dedupe(builtin.filter(isValidModelSpec));
|
|
15242
|
+
}
|
|
15243
|
+
function normalizeUserFallbacks(userFallbacks) {
|
|
15244
|
+
if (!userFallbacks)
|
|
15245
|
+
return [];
|
|
15246
|
+
if (typeof userFallbacks === "string") {
|
|
15247
|
+
const trimmed = userFallbacks.trim();
|
|
15248
|
+
return trimmed ? [trimmed] : [];
|
|
15249
|
+
}
|
|
15250
|
+
return userFallbacks.map((s) => s.trim()).filter((s) => s.length > 0);
|
|
15251
|
+
}
|
|
15252
|
+
function isValidModelSpec(spec) {
|
|
15253
|
+
const slash = spec.indexOf("/");
|
|
15254
|
+
return slash > 0 && slash < spec.length - 1;
|
|
15255
|
+
}
|
|
15256
|
+
function dedupe(list) {
|
|
15257
|
+
const seen = new Set;
|
|
15258
|
+
const out = [];
|
|
15259
|
+
for (const item of list) {
|
|
15260
|
+
if (seen.has(item))
|
|
15261
|
+
continue;
|
|
15262
|
+
seen.add(item);
|
|
15263
|
+
out.push(item);
|
|
15264
|
+
}
|
|
15265
|
+
return out;
|
|
15266
|
+
}
|
|
15267
|
+
function parseProviderModel(spec) {
|
|
15268
|
+
const slash = spec.indexOf("/");
|
|
15269
|
+
if (slash < 1 || slash >= spec.length - 1)
|
|
15270
|
+
return null;
|
|
15271
|
+
return {
|
|
15272
|
+
providerID: spec.slice(0, slash).trim(),
|
|
15273
|
+
modelID: spec.slice(slash + 1).trim()
|
|
15274
|
+
};
|
|
15275
|
+
}
|
|
15276
|
+
var init_resolve_fallbacks = __esm(() => {
|
|
15277
|
+
init_model_requirements();
|
|
15278
|
+
});
|
|
15279
|
+
|
|
15125
15280
|
// src/shared/model-suggestion-retry.ts
|
|
15126
15281
|
function extractMessage(error51) {
|
|
15127
15282
|
if (typeof error51 === "string")
|
|
@@ -15177,6 +15332,9 @@ function parseModelSuggestion(error51) {
|
|
|
15177
15332
|
};
|
|
15178
15333
|
}
|
|
15179
15334
|
async function promptWithTimeout(client, args, timeoutMs, signal) {
|
|
15335
|
+
if (signal?.aborted) {
|
|
15336
|
+
throw new Error("prompt aborted by external signal");
|
|
15337
|
+
}
|
|
15180
15338
|
const controller = new AbortController;
|
|
15181
15339
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
15182
15340
|
const onExternalAbort = () => controller.abort();
|
|
@@ -15199,16 +15357,39 @@ async function promptWithTimeout(client, args, timeoutMs, signal) {
|
|
|
15199
15357
|
signal?.removeEventListener("abort", onExternalAbort);
|
|
15200
15358
|
}
|
|
15201
15359
|
}
|
|
15202
|
-
|
|
15203
|
-
|
|
15360
|
+
function isNonRetryable(error51, externalSignal) {
|
|
15361
|
+
if (externalSignal?.aborted)
|
|
15362
|
+
return true;
|
|
15363
|
+
if (error51 instanceof Error) {
|
|
15364
|
+
if (error51.name === "AbortError")
|
|
15365
|
+
return true;
|
|
15366
|
+
if (error51.message === "prompt aborted by external signal")
|
|
15367
|
+
return true;
|
|
15368
|
+
if (/^prompt timed out after \d+ms$/.test(error51.message))
|
|
15369
|
+
return true;
|
|
15370
|
+
}
|
|
15371
|
+
if (detectOverflow(error51).isOverflow)
|
|
15372
|
+
return true;
|
|
15373
|
+
return false;
|
|
15374
|
+
}
|
|
15375
|
+
function shortErr(error51) {
|
|
15376
|
+
if (error51 instanceof Error) {
|
|
15377
|
+
return error51.name && error51.name !== "Error" ? `${error51.name}: ${error51.message}` : error51.message;
|
|
15378
|
+
}
|
|
15379
|
+
return extractMessage(error51);
|
|
15380
|
+
}
|
|
15381
|
+
async function attemptOnce(client, args, timeoutMs, signal, callContext, label) {
|
|
15204
15382
|
try {
|
|
15205
|
-
await promptWithTimeout(client, args, timeoutMs,
|
|
15383
|
+
await promptWithTimeout(client, args, timeoutMs, signal);
|
|
15384
|
+
return;
|
|
15206
15385
|
} catch (error51) {
|
|
15386
|
+
if (isNonRetryable(error51, signal))
|
|
15387
|
+
throw error51;
|
|
15207
15388
|
const suggestion = parseModelSuggestion(error51);
|
|
15208
15389
|
if (!suggestion || !args.body.model) {
|
|
15209
15390
|
throw error51;
|
|
15210
15391
|
}
|
|
15211
|
-
log(
|
|
15392
|
+
log(`[${callContext}] ${label}: model not found, retrying with suggestion`, {
|
|
15212
15393
|
original: `${suggestion.providerID}/${suggestion.modelID}`,
|
|
15213
15394
|
suggested: suggestion.suggestion
|
|
15214
15395
|
});
|
|
@@ -15221,11 +15402,59 @@ async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
|
|
|
15221
15402
|
modelID: suggestion.suggestion
|
|
15222
15403
|
}
|
|
15223
15404
|
}
|
|
15224
|
-
}, timeoutMs,
|
|
15405
|
+
}, timeoutMs, signal);
|
|
15225
15406
|
}
|
|
15226
15407
|
}
|
|
15408
|
+
async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
|
|
15409
|
+
const timeoutMs = options.timeoutMs ?? 300000;
|
|
15410
|
+
const callContext = options.callContext ?? "subagent";
|
|
15411
|
+
const fallbacks = options.fallbackModels ?? [];
|
|
15412
|
+
const explicitPrimaryLabel = args.body.model?.providerID && args.body.model.modelID ? `${args.body.model.providerID}/${args.body.model.modelID}` : "primary";
|
|
15413
|
+
let lastError = null;
|
|
15414
|
+
try {
|
|
15415
|
+
await attemptOnce(client, args, timeoutMs, options.signal, callContext, explicitPrimaryLabel);
|
|
15416
|
+
return;
|
|
15417
|
+
} catch (error51) {
|
|
15418
|
+
lastError = error51;
|
|
15419
|
+
if (isNonRetryable(error51, options.signal))
|
|
15420
|
+
throw error51;
|
|
15421
|
+
if (fallbacks.length === 0) {
|
|
15422
|
+
throw error51;
|
|
15423
|
+
}
|
|
15424
|
+
log(`[${callContext}] primary (${explicitPrimaryLabel}) failed: ${shortErr(error51)}; trying ${fallbacks.length} fallback(s)`);
|
|
15425
|
+
}
|
|
15426
|
+
for (let i = 0;i < fallbacks.length; i += 1) {
|
|
15427
|
+
const parsed = parseProviderModel(fallbacks[i]);
|
|
15428
|
+
if (!parsed) {
|
|
15429
|
+
log(`[${callContext}] skipping invalid fallback spec: ${fallbacks[i]}`);
|
|
15430
|
+
continue;
|
|
15431
|
+
}
|
|
15432
|
+
const label = `${parsed.providerID}/${parsed.modelID}`;
|
|
15433
|
+
const attemptArgs = {
|
|
15434
|
+
...args,
|
|
15435
|
+
body: { ...args.body, model: parsed }
|
|
15436
|
+
};
|
|
15437
|
+
try {
|
|
15438
|
+
await attemptOnce(client, attemptArgs, timeoutMs, options.signal, callContext, label);
|
|
15439
|
+
log(`[${callContext}] fallback succeeded with ${label} (attempt ${i + 2}/${fallbacks.length + 1})`);
|
|
15440
|
+
return;
|
|
15441
|
+
} catch (error51) {
|
|
15442
|
+
lastError = error51;
|
|
15443
|
+
if (isNonRetryable(error51, options.signal))
|
|
15444
|
+
throw error51;
|
|
15445
|
+
const remaining = fallbacks.length - i - 1;
|
|
15446
|
+
if (remaining > 0) {
|
|
15447
|
+
log(`[${callContext}] ${label} failed: ${shortErr(error51)}; ${remaining} fallback(s) left`);
|
|
15448
|
+
}
|
|
15449
|
+
}
|
|
15450
|
+
}
|
|
15451
|
+
log(`[${callContext}] all models exhausted; tried: ${[explicitPrimaryLabel, ...fallbacks].join(", ")}; last error: ${shortErr(lastError)}`);
|
|
15452
|
+
throw lastError ?? new Error("All fallback models failed");
|
|
15453
|
+
}
|
|
15227
15454
|
var init_model_suggestion_retry = __esm(() => {
|
|
15455
|
+
init_overflow_detection();
|
|
15228
15456
|
init_logger();
|
|
15457
|
+
init_resolve_fallbacks();
|
|
15229
15458
|
});
|
|
15230
15459
|
|
|
15231
15460
|
// src/shared/normalize-sdk-response.ts
|
|
@@ -15257,6 +15486,7 @@ var init_shared = __esm(() => {
|
|
|
15257
15486
|
init_logger();
|
|
15258
15487
|
init_model_requirements();
|
|
15259
15488
|
init_model_suggestion_retry();
|
|
15489
|
+
init_resolve_fallbacks();
|
|
15260
15490
|
});
|
|
15261
15491
|
|
|
15262
15492
|
// src/shared/record-type-guard.ts
|
|
@@ -147913,8 +148143,20 @@ function keyFor(providerID, modelID, agentName) {
|
|
|
147913
148143
|
const agent = agentName && agentName.length > 0 ? agentName : "default";
|
|
147914
148144
|
return `${providerID}/${modelID}/${agent}`;
|
|
147915
148145
|
}
|
|
148146
|
+
function fingerprintFor(description, parameters) {
|
|
148147
|
+
const descLen = description.length;
|
|
148148
|
+
if (parameters === undefined)
|
|
148149
|
+
return `${descLen}:none`;
|
|
148150
|
+
if (parameters === null)
|
|
148151
|
+
return `${descLen}:null`;
|
|
148152
|
+
if (typeof parameters !== "object")
|
|
148153
|
+
return `${descLen}:${typeof parameters}`;
|
|
148154
|
+
const keys = Object.keys(parameters);
|
|
148155
|
+
return `${descLen}:obj:${keys.length}:${keys.sort().join(",")}`;
|
|
148156
|
+
}
|
|
147916
148157
|
function setDatabase(db) {
|
|
147917
148158
|
persistenceDb = db;
|
|
148159
|
+
cachedInsertStmt = null;
|
|
147918
148160
|
}
|
|
147919
148161
|
function loadToolDefinitionMeasurements(db) {
|
|
147920
148162
|
let rows = [];
|
|
@@ -147937,6 +148179,10 @@ function recordToolDefinition(providerID, modelID, agentName, toolID, descriptio
|
|
|
147937
148179
|
if (!providerID || !modelID || !toolID)
|
|
147938
148180
|
return;
|
|
147939
148181
|
const key = keyFor(providerID, modelID, agentName);
|
|
148182
|
+
const fp = fingerprintFor(description ?? "", parameters);
|
|
148183
|
+
let innerFp = fingerprints.get(key);
|
|
148184
|
+
if (innerFp && innerFp.get(toolID) === fp)
|
|
148185
|
+
return;
|
|
147940
148186
|
let paramsText = "";
|
|
147941
148187
|
try {
|
|
147942
148188
|
paramsText = parameters === undefined ? "" : JSON.stringify(parameters);
|
|
@@ -147950,13 +148196,23 @@ function recordToolDefinition(providerID, modelID, agentName, toolID, descriptio
|
|
|
147950
148196
|
measurements.set(key, inner);
|
|
147951
148197
|
}
|
|
147952
148198
|
inner.set(toolID, tokens);
|
|
148199
|
+
if (!innerFp) {
|
|
148200
|
+
innerFp = new Map;
|
|
148201
|
+
fingerprints.set(key, innerFp);
|
|
148202
|
+
}
|
|
148203
|
+
innerFp.set(toolID, fp);
|
|
147953
148204
|
if (persistenceDb) {
|
|
147954
148205
|
try {
|
|
147955
148206
|
const agent = agentName && agentName.length > 0 ? agentName : "default";
|
|
147956
|
-
|
|
148207
|
+
if (!cachedInsertStmt) {
|
|
148208
|
+
cachedInsertStmt = persistenceDb.prepare(`INSERT OR REPLACE INTO tool_definition_measurements
|
|
147957
148209
|
(provider_id, model_id, agent_name, tool_id, token_count, recorded_at)
|
|
147958
|
-
VALUES (?, ?, ?, ?, ?, ?)`)
|
|
147959
|
-
|
|
148210
|
+
VALUES (?, ?, ?, ?, ?, ?)`);
|
|
148211
|
+
}
|
|
148212
|
+
cachedInsertStmt.run(providerID, modelID, agent, toolID, tokens, Date.now());
|
|
148213
|
+
} catch {
|
|
148214
|
+
cachedInsertStmt = null;
|
|
148215
|
+
}
|
|
147960
148216
|
}
|
|
147961
148217
|
}
|
|
147962
148218
|
function getMeasuredToolDefinitionTokens(providerID, modelID, agentName) {
|
|
@@ -147970,10 +148226,11 @@ function getMeasuredToolDefinitionTokens(providerID, modelID, agentName) {
|
|
|
147970
148226
|
total += tokens;
|
|
147971
148227
|
return total;
|
|
147972
148228
|
}
|
|
147973
|
-
var measurements, persistenceDb = null;
|
|
148229
|
+
var measurements, fingerprints, persistenceDb = null, cachedInsertStmt = null;
|
|
147974
148230
|
var init_tool_definition_tokens = __esm(() => {
|
|
147975
148231
|
init_read_session_formatting();
|
|
147976
148232
|
measurements = new Map;
|
|
148233
|
+
fingerprints = new Map;
|
|
147977
148234
|
});
|
|
147978
148235
|
|
|
147979
148236
|
// ../../node_modules/.bun/esprima@4.0.1/node_modules/esprima/dist/esprima.js
|
|
@@ -160007,6 +160264,25 @@ var init_migrations = __esm(async () => {
|
|
|
160007
160264
|
WHERE type = 'tool' AND tool_owner_message_id IS NULL;
|
|
160008
160265
|
`);
|
|
160009
160266
|
}
|
|
160267
|
+
},
|
|
160268
|
+
{
|
|
160269
|
+
version: 11,
|
|
160270
|
+
description: "Add todo state synthesis columns to session_meta",
|
|
160271
|
+
up: (db) => {
|
|
160272
|
+
const cols = db.prepare("PRAGMA table_info(session_meta)").all();
|
|
160273
|
+
if (!cols.some((c) => c.name === "last_todo_state")) {
|
|
160274
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN last_todo_state TEXT DEFAULT ''");
|
|
160275
|
+
}
|
|
160276
|
+
if (!cols.some((c) => c.name === "todo_synthetic_call_id")) {
|
|
160277
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_call_id TEXT DEFAULT ''");
|
|
160278
|
+
}
|
|
160279
|
+
if (!cols.some((c) => c.name === "todo_synthetic_anchor_message_id")) {
|
|
160280
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_anchor_message_id TEXT DEFAULT ''");
|
|
160281
|
+
}
|
|
160282
|
+
if (!cols.some((c) => c.name === "todo_synthetic_state_json")) {
|
|
160283
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_state_json TEXT DEFAULT ''");
|
|
160284
|
+
}
|
|
160285
|
+
}
|
|
160010
160286
|
}
|
|
160011
160287
|
];
|
|
160012
160288
|
});
|
|
@@ -160489,6 +160765,10 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
160489
160765
|
note_nudge_trigger_message_id TEXT DEFAULT '',
|
|
160490
160766
|
note_nudge_sticky_text TEXT DEFAULT '',
|
|
160491
160767
|
note_nudge_sticky_message_id TEXT DEFAULT '',
|
|
160768
|
+
last_todo_state TEXT DEFAULT '',
|
|
160769
|
+
todo_synthetic_call_id TEXT DEFAULT '',
|
|
160770
|
+
todo_synthetic_anchor_message_id TEXT DEFAULT '',
|
|
160771
|
+
todo_synthetic_state_json TEXT DEFAULT '',
|
|
160492
160772
|
is_subagent INTEGER DEFAULT 0,
|
|
160493
160773
|
last_context_percentage REAL DEFAULT 0,
|
|
160494
160774
|
last_input_tokens INTEGER DEFAULT 0,
|
|
@@ -160553,6 +160833,10 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
160553
160833
|
ensureColumn(db, "session_meta", "note_nudge_trigger_message_id", "TEXT DEFAULT ''");
|
|
160554
160834
|
ensureColumn(db, "session_meta", "note_nudge_sticky_text", "TEXT DEFAULT ''");
|
|
160555
160835
|
ensureColumn(db, "session_meta", "note_nudge_sticky_message_id", "TEXT DEFAULT ''");
|
|
160836
|
+
ensureColumn(db, "session_meta", "last_todo_state", "TEXT DEFAULT ''");
|
|
160837
|
+
ensureColumn(db, "session_meta", "todo_synthetic_call_id", "TEXT DEFAULT ''");
|
|
160838
|
+
ensureColumn(db, "session_meta", "todo_synthetic_anchor_message_id", "TEXT DEFAULT ''");
|
|
160839
|
+
ensureColumn(db, "session_meta", "todo_synthetic_state_json", "TEXT DEFAULT ''");
|
|
160556
160840
|
ensureColumn(db, "session_meta", "note_last_read_at", "INTEGER DEFAULT 0");
|
|
160557
160841
|
ensureColumn(db, "session_meta", "times_execute_threshold_reached", "INTEGER DEFAULT 0");
|
|
160558
160842
|
ensureColumn(db, "session_meta", "compartment_in_progress", "INTEGER DEFAULT 0");
|
|
@@ -160617,6 +160901,10 @@ function healNullTextColumns(db) {
|
|
|
160617
160901
|
["note_nudge_trigger_message_id", ""],
|
|
160618
160902
|
["note_nudge_sticky_text", ""],
|
|
160619
160903
|
["note_nudge_sticky_message_id", ""],
|
|
160904
|
+
["last_todo_state", ""],
|
|
160905
|
+
["todo_synthetic_call_id", ""],
|
|
160906
|
+
["todo_synthetic_anchor_message_id", ""],
|
|
160907
|
+
["todo_synthetic_state_json", ""],
|
|
160620
160908
|
["system_prompt_hash", ""],
|
|
160621
160909
|
["stripped_placeholder_ids", ""],
|
|
160622
160910
|
["memory_block_cache", ""],
|
|
@@ -160722,7 +161010,7 @@ function isSessionMetaRow(row) {
|
|
|
160722
161010
|
if (row === null || typeof row !== "object")
|
|
160723
161011
|
return false;
|
|
160724
161012
|
const r = row;
|
|
160725
|
-
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag);
|
|
161013
|
+
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag) && isStringOrNull(r.last_todo_state);
|
|
160726
161014
|
}
|
|
160727
161015
|
function getDefaultSessionMeta(sessionId) {
|
|
160728
161016
|
return {
|
|
@@ -160742,7 +161030,8 @@ function getDefaultSessionMeta(sessionId) {
|
|
|
160742
161030
|
systemPromptTokens: 0,
|
|
160743
161031
|
conversationTokens: 0,
|
|
160744
161032
|
toolCallTokens: 0,
|
|
160745
|
-
clearedReasoningThroughTag: 0
|
|
161033
|
+
clearedReasoningThroughTag: 0,
|
|
161034
|
+
lastTodoState: ""
|
|
160746
161035
|
};
|
|
160747
161036
|
}
|
|
160748
161037
|
function ensureSessionMetaRow(db, sessionId) {
|
|
@@ -160754,6 +161043,7 @@ function toSessionMeta(row) {
|
|
|
160754
161043
|
const transformErrorRaw = typeof row.last_transform_error === "string" ? row.last_transform_error : "";
|
|
160755
161044
|
const cacheTtlRaw = typeof row.cache_ttl === "string" && row.cache_ttl.length > 0 ? row.cache_ttl : "5m";
|
|
160756
161045
|
const systemPromptHashRaw = row.system_prompt_hash == null ? "" : row.system_prompt_hash;
|
|
161046
|
+
const lastTodoStateRaw = typeof row.last_todo_state === "string" ? row.last_todo_state : "";
|
|
160757
161047
|
const numOrZero = (value) => typeof value === "number" ? value : 0;
|
|
160758
161048
|
return {
|
|
160759
161049
|
sessionId: row.session_id,
|
|
@@ -160772,7 +161062,8 @@ function toSessionMeta(row) {
|
|
|
160772
161062
|
systemPromptTokens: numOrZero(row.system_prompt_tokens),
|
|
160773
161063
|
conversationTokens: numOrZero(row.conversation_tokens),
|
|
160774
161064
|
toolCallTokens: numOrZero(row.tool_call_tokens),
|
|
160775
|
-
clearedReasoningThroughTag: numOrZero(row.cleared_reasoning_through_tag)
|
|
161065
|
+
clearedReasoningThroughTag: numOrZero(row.cleared_reasoning_through_tag),
|
|
161066
|
+
lastTodoState: lastTodoStateRaw
|
|
160776
161067
|
};
|
|
160777
161068
|
}
|
|
160778
161069
|
var META_COLUMNS, BOOLEAN_META_KEYS;
|
|
@@ -160793,7 +161084,8 @@ var init_storage_meta_shared = __esm(() => {
|
|
|
160793
161084
|
systemPromptTokens: "system_prompt_tokens",
|
|
160794
161085
|
conversationTokens: "conversation_tokens",
|
|
160795
161086
|
toolCallTokens: "tool_call_tokens",
|
|
160796
|
-
clearedReasoningThroughTag: "cleared_reasoning_through_tag"
|
|
161087
|
+
clearedReasoningThroughTag: "cleared_reasoning_through_tag",
|
|
161088
|
+
lastTodoState: "last_todo_state"
|
|
160797
161089
|
};
|
|
160798
161090
|
BOOLEAN_META_KEYS = new Set(["isSubagent", "compartmentInProgress"]);
|
|
160799
161091
|
});
|
|
@@ -160829,6 +161121,12 @@ function isPersistedNoteNudgeRow(row) {
|
|
|
160829
161121
|
const r = row;
|
|
160830
161122
|
return typeof r.note_nudge_trigger_pending === "number" && typeof r.note_nudge_trigger_message_id === "string" && typeof r.note_nudge_sticky_text === "string" && typeof r.note_nudge_sticky_message_id === "string";
|
|
160831
161123
|
}
|
|
161124
|
+
function isPersistedTodoSyntheticAnchorRow(row) {
|
|
161125
|
+
if (row === null || typeof row !== "object")
|
|
161126
|
+
return false;
|
|
161127
|
+
const r = row;
|
|
161128
|
+
return typeof r.todo_synthetic_call_id === "string" && typeof r.todo_synthetic_anchor_message_id === "string" && typeof r.todo_synthetic_state_json === "string";
|
|
161129
|
+
}
|
|
160832
161130
|
function isPersistedHistorianFailureRow(row) {
|
|
160833
161131
|
if (row === null || typeof row !== "object")
|
|
160834
161132
|
return false;
|
|
@@ -160951,6 +161249,29 @@ function setPersistedDeliveredNoteNudge(db, sessionId, text, messageId = "") {
|
|
|
160951
161249
|
function clearPersistedNoteNudge(db, sessionId) {
|
|
160952
161250
|
db.prepare("UPDATE session_meta SET note_nudge_trigger_pending = 0, note_nudge_trigger_message_id = '', note_nudge_sticky_text = '', note_nudge_sticky_message_id = '' WHERE session_id = ?").run(sessionId);
|
|
160953
161251
|
}
|
|
161252
|
+
function getPersistedTodoSyntheticAnchor(db, sessionId) {
|
|
161253
|
+
const result = db.prepare("SELECT todo_synthetic_call_id, todo_synthetic_anchor_message_id, todo_synthetic_state_json FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
161254
|
+
if (!isPersistedTodoSyntheticAnchorRow(result)) {
|
|
161255
|
+
return null;
|
|
161256
|
+
}
|
|
161257
|
+
if (result.todo_synthetic_call_id.length === 0 || result.todo_synthetic_anchor_message_id.length === 0) {
|
|
161258
|
+
return null;
|
|
161259
|
+
}
|
|
161260
|
+
return {
|
|
161261
|
+
callId: result.todo_synthetic_call_id,
|
|
161262
|
+
messageId: result.todo_synthetic_anchor_message_id,
|
|
161263
|
+
stateJson: result.todo_synthetic_state_json
|
|
161264
|
+
};
|
|
161265
|
+
}
|
|
161266
|
+
function setPersistedTodoSyntheticAnchor(db, sessionId, callId, messageId, stateJson) {
|
|
161267
|
+
db.transaction(() => {
|
|
161268
|
+
ensureSessionMetaRow(db, sessionId);
|
|
161269
|
+
db.prepare("UPDATE session_meta SET todo_synthetic_call_id = ?, todo_synthetic_anchor_message_id = ?, todo_synthetic_state_json = ? WHERE session_id = ?").run(callId, messageId, stateJson, sessionId);
|
|
161270
|
+
})();
|
|
161271
|
+
}
|
|
161272
|
+
function clearPersistedTodoSyntheticAnchor(db, sessionId) {
|
|
161273
|
+
db.prepare("UPDATE session_meta SET todo_synthetic_call_id = '', todo_synthetic_anchor_message_id = '', todo_synthetic_state_json = '' WHERE session_id = ?").run(sessionId);
|
|
161274
|
+
}
|
|
160954
161275
|
function getNoteLastReadAt(db, sessionId) {
|
|
160955
161276
|
try {
|
|
160956
161277
|
const result = db.prepare("SELECT note_last_read_at FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
@@ -161103,7 +161424,7 @@ var init_resolve_subagent_fallback = __esm(async () => {
|
|
|
161103
161424
|
|
|
161104
161425
|
// src/features/magic-context/storage-meta-session.ts
|
|
161105
161426
|
function getOrCreateSessionMeta(db, sessionId) {
|
|
161106
|
-
const result = db.prepare("SELECT session_id, last_response_time, cache_ttl, counter, last_nudge_tokens, last_nudge_band, last_transform_error, is_subagent, last_context_percentage, last_input_tokens, times_execute_threshold_reached, compartment_in_progress, system_prompt_hash, system_prompt_tokens, conversation_tokens, tool_call_tokens, cleared_reasoning_through_tag FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
161427
|
+
const result = db.prepare("SELECT session_id, last_response_time, cache_ttl, counter, last_nudge_tokens, last_nudge_band, last_transform_error, is_subagent, last_context_percentage, last_input_tokens, times_execute_threshold_reached, compartment_in_progress, system_prompt_hash, system_prompt_tokens, conversation_tokens, tool_call_tokens, cleared_reasoning_through_tag, last_todo_state FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
161107
161428
|
if (isSessionMetaRow(result)) {
|
|
161108
161429
|
return toSessionMeta(result);
|
|
161109
161430
|
}
|
|
@@ -161677,9 +161998,7 @@ function loadModelsDevMetadataFromFile() {
|
|
|
161677
161998
|
try {
|
|
161678
161999
|
const configPath = getOpencodeConfigPath();
|
|
161679
162000
|
if (configPath && existsSync12(configPath)) {
|
|
161680
|
-
|
|
161681
|
-
raw = raw.replace(/"(?:[^"\\]|\\.)*"|\/\/.*$/gm, (match) => match.startsWith('"') ? match : "");
|
|
161682
|
-
const config2 = JSON.parse(raw);
|
|
162001
|
+
const config2 = parseJsonc(readFileSync8(configPath, "utf-8"));
|
|
161683
162002
|
if (config2.provider && typeof config2.provider === "object") {
|
|
161684
162003
|
for (const [providerId, provider2] of Object.entries(config2.provider)) {
|
|
161685
162004
|
if (!provider2?.models || typeof provider2.models !== "object")
|
|
@@ -161751,6 +162070,7 @@ function getModelsDevContextLimit(providerID, modelID) {
|
|
|
161751
162070
|
var RELOAD_INTERVAL_MS, apiCache = null, apiLoadedAt = 0, recentlySeenApiSizes, oscillationLogged = false, fileCache = null, fileLastAttempt = 0;
|
|
161752
162071
|
var init_models_dev_cache = __esm(() => {
|
|
161753
162072
|
init_data_path();
|
|
162073
|
+
init_jsonc_parser();
|
|
161754
162074
|
init_logger();
|
|
161755
162075
|
RELOAD_INTERVAL_MS = 5 * 60 * 1000;
|
|
161756
162076
|
recentlySeenApiSizes = new Set;
|
|
@@ -162098,7 +162418,8 @@ async function runHistorianPrompt(args) {
|
|
|
162098
162418
|
timeoutMs,
|
|
162099
162419
|
dumpLabel,
|
|
162100
162420
|
modelOverride,
|
|
162101
|
-
agentId = HISTORIAN_AGENT
|
|
162421
|
+
agentId = HISTORIAN_AGENT,
|
|
162422
|
+
fallbackModels
|
|
162102
162423
|
} = args;
|
|
162103
162424
|
let agentSessionId = null;
|
|
162104
162425
|
try {
|
|
@@ -162125,7 +162446,11 @@ async function runHistorianPrompt(args) {
|
|
|
162125
162446
|
...modelOverride ? { model: modelOverride } : {},
|
|
162126
162447
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
162127
162448
|
}
|
|
162128
|
-
}, {
|
|
162449
|
+
}, {
|
|
162450
|
+
timeoutMs: timeoutMs ?? DEFAULT_HISTORIAN_TIMEOUT_MS,
|
|
162451
|
+
fallbackModels: modelOverride ? undefined : fallbackModels,
|
|
162452
|
+
callContext: agentId === HISTORIAN_EDITOR_AGENT ? "historian:editor" : "historian"
|
|
162453
|
+
});
|
|
162129
162454
|
sessionLog(parentSessionId, `historian: prompt completed (attempt ${retryIndex + 1}/${MAX_HISTORIAN_RETRIES + 1})`);
|
|
162130
162455
|
break;
|
|
162131
162456
|
} catch (error51) {
|
|
@@ -163090,6 +163415,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
163090
163415
|
dumpLabelBase: `partial-recomp-${sessionId}-${chunk.startIndex}-${chunk.endIndex}-pass-${passCount + 1}`,
|
|
163091
163416
|
timeoutMs: historianTimeoutMs,
|
|
163092
163417
|
fallbackModelId: deps.fallbackModelId,
|
|
163418
|
+
fallbackModels: deps.fallbackModels,
|
|
163093
163419
|
twoPass: deps.historianTwoPass,
|
|
163094
163420
|
callbacks: {
|
|
163095
163421
|
onRepairRetry: async (error51) => {
|
|
@@ -164291,7 +164617,8 @@ async function runCompressorPass(args) {
|
|
|
164291
164617
|
targetTokens,
|
|
164292
164618
|
outputCount,
|
|
164293
164619
|
outputDepth,
|
|
164294
|
-
historianTimeoutMs
|
|
164620
|
+
historianTimeoutMs,
|
|
164621
|
+
fallbackModels
|
|
164295
164622
|
} = args;
|
|
164296
164623
|
const prompt = buildCompressorPrompt(compartments, currentTokens, targetTokens, outputDepth, outputCount);
|
|
164297
164624
|
let agentSessionId = null;
|
|
@@ -164313,7 +164640,11 @@ async function runCompressorPass(args) {
|
|
|
164313
164640
|
agent: HISTORIAN_AGENT2,
|
|
164314
164641
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
164315
164642
|
}
|
|
164316
|
-
}, {
|
|
164643
|
+
}, {
|
|
164644
|
+
timeoutMs: historianTimeoutMs ?? DEFAULT_HISTORIAN_TIMEOUT_MS,
|
|
164645
|
+
fallbackModels,
|
|
164646
|
+
callContext: "compressor"
|
|
164647
|
+
});
|
|
164317
164648
|
const messagesResponse = await client.session.messages({
|
|
164318
164649
|
path: { id: agentSessionId },
|
|
164319
164650
|
query: { directory }
|
|
@@ -164493,6 +164824,7 @@ ${chunk.text}`, { stateFilePath });
|
|
|
164493
164824
|
dumpLabelBase: `incremental-${sessionId}-${chunk.startIndex}-${chunk.endIndex}`,
|
|
164494
164825
|
timeoutMs: historianTimeoutMs,
|
|
164495
164826
|
fallbackModelId: deps.fallbackModelId,
|
|
164827
|
+
fallbackModels: deps.fallbackModels,
|
|
164496
164828
|
twoPass: deps.historianTwoPass
|
|
164497
164829
|
});
|
|
164498
164830
|
if (!validatedPass.ok) {
|
|
@@ -164541,6 +164873,7 @@ No new compartments or facts were written. Check the historian model/output and
|
|
|
164541
164873
|
directory: sessionDirectory,
|
|
164542
164874
|
historyBudgetTokens: deps.historyBudgetTokens,
|
|
164543
164875
|
historianTimeoutMs,
|
|
164876
|
+
fallbackModels: deps.fallbackModels,
|
|
164544
164877
|
minCompartmentRatio: deps.compressorMinCompartmentRatio,
|
|
164545
164878
|
maxMergeDepth: deps.compressorMaxMergeDepth
|
|
164546
164879
|
});
|
|
@@ -164729,6 +165062,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
164729
165062
|
dumpLabelBase: `recomp-${sessionId}-${chunk.startIndex}-${chunk.endIndex}-pass-${passCount + 1}`,
|
|
164730
165063
|
timeoutMs: historianTimeoutMs,
|
|
164731
165064
|
fallbackModelId: deps.fallbackModelId,
|
|
165065
|
+
fallbackModels: deps.fallbackModels,
|
|
164732
165066
|
twoPass: deps.historianTwoPass,
|
|
164733
165067
|
callbacks: {
|
|
164734
165068
|
onRepairRetry: async (error51) => {
|
|
@@ -164826,6 +165160,7 @@ Nothing was written.`;
|
|
|
164826
165160
|
directory: sessionDirectory,
|
|
164827
165161
|
historyBudgetTokens: deps.historyBudgetTokens,
|
|
164828
165162
|
historianTimeoutMs,
|
|
165163
|
+
fallbackModels: deps.fallbackModels,
|
|
164829
165164
|
minCompartmentRatio: deps.compressorMinCompartmentRatio,
|
|
164830
165165
|
maxMergeDepth: deps.compressorMaxMergeDepth
|
|
164831
165166
|
});
|
|
@@ -165695,6 +166030,7 @@ function buildDreamTaskPrompt(task, args) {
|
|
|
165695
166030
|
init_shared();
|
|
165696
166031
|
init_assistant_message_extractor();
|
|
165697
166032
|
init_logger();
|
|
166033
|
+
init_resolve_fallbacks();
|
|
165698
166034
|
|
|
165699
166035
|
// src/features/magic-context/sidekick/core.ts
|
|
165700
166036
|
var SIDEKICK_SYSTEM_PROMPT = `You are Sidekick, a focused memory-retrieval subagent for an AI coding assistant.
|
|
@@ -165714,6 +166050,7 @@ function stripThinkingBlocks(text) {
|
|
|
165714
166050
|
|
|
165715
166051
|
// src/features/magic-context/sidekick/agent.ts
|
|
165716
166052
|
async function runSidekick(deps) {
|
|
166053
|
+
const fallbackModels = resolveFallbackChain(SIDEKICK_AGENT, deps.config.fallback_models);
|
|
165717
166054
|
let agentSessionId = null;
|
|
165718
166055
|
try {
|
|
165719
166056
|
const createResponse = await deps.client.session.create({
|
|
@@ -165736,7 +166073,7 @@ async function runSidekick(deps) {
|
|
|
165736
166073
|
system: deps.config.system_prompt?.trim() || deps.config.prompt?.trim() || SIDEKICK_SYSTEM_PROMPT,
|
|
165737
166074
|
parts: [{ type: "text", text: deps.userMessage, synthetic: true }]
|
|
165738
166075
|
}
|
|
165739
|
-
}, { timeoutMs: deps.config.timeout_ms });
|
|
166076
|
+
}, { timeoutMs: deps.config.timeout_ms, fallbackModels, callContext: "sidekick" });
|
|
165740
166077
|
const messagesResponse = await deps.client.session.messages({
|
|
165741
166078
|
path: { id: agentSessionId },
|
|
165742
166079
|
query: { directory: deps.sessionDirectory ?? deps.projectPath }
|
|
@@ -166360,7 +166697,6 @@ function createLiveSessionState() {
|
|
|
166360
166697
|
|
|
166361
166698
|
// src/index.ts
|
|
166362
166699
|
init_conflict_warning_hook();
|
|
166363
|
-
|
|
166364
166700
|
// src/features/magic-context/dreamer/storage-dream-state.ts
|
|
166365
166701
|
var getDreamStateStatements = new WeakMap;
|
|
166366
166702
|
var setDreamStateStatements = new WeakMap;
|
|
@@ -166806,7 +167142,12 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
166806
167142
|
system: DREAMER_SYSTEM_PROMPT,
|
|
166807
167143
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
166808
167144
|
}
|
|
166809
|
-
}, {
|
|
167145
|
+
}, {
|
|
167146
|
+
timeoutMs: Math.min(remainingMs, 5 * 60 * 1000),
|
|
167147
|
+
signal: abortController.signal,
|
|
167148
|
+
fallbackModels: args.fallbackModels,
|
|
167149
|
+
callContext: "dreamer:user-memories"
|
|
167150
|
+
});
|
|
166810
167151
|
const messagesResponse = await args.client.session.messages({
|
|
166811
167152
|
path: { id: agentSessionId },
|
|
166812
167153
|
query: { directory: args.sessionDirectory }
|
|
@@ -166865,7 +167206,8 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
166865
167206
|
}
|
|
166866
167207
|
return result;
|
|
166867
167208
|
} catch (error51) {
|
|
166868
|
-
|
|
167209
|
+
const errorDescription = describeError(error51);
|
|
167210
|
+
log(`[dreamer] user-memories: review failed: ${errorDescription.brief}`, errorDescription.stackHead ? { stackHead: errorDescription.stackHead } : undefined);
|
|
166869
167211
|
return result;
|
|
166870
167212
|
} finally {
|
|
166871
167213
|
clearInterval(leaseInterval);
|
|
@@ -166896,6 +167238,7 @@ function insertDreamRun(db, run) {
|
|
|
166896
167238
|
|
|
166897
167239
|
// src/features/magic-context/dreamer/runner.ts
|
|
166898
167240
|
var dreamProjectDirectories = new Map;
|
|
167241
|
+
var CIRCUIT_BREAKER_THRESHOLD = 3;
|
|
166899
167242
|
function registerDreamProjectDirectory(projectIdentity, directory) {
|
|
166900
167243
|
dreamProjectDirectories.set(projectIdentity, directory);
|
|
166901
167244
|
}
|
|
@@ -166912,6 +167255,25 @@ function countNewIds(beforeIds, afterIds) {
|
|
|
166912
167255
|
}
|
|
166913
167256
|
return count;
|
|
166914
167257
|
}
|
|
167258
|
+
function getCircuitBreakerSignature(error51, brief) {
|
|
167259
|
+
if (error51 instanceof Error && error51.name && error51.name !== "Error") {
|
|
167260
|
+
return error51.name;
|
|
167261
|
+
}
|
|
167262
|
+
const namedError = error51;
|
|
167263
|
+
if (namedError && typeof namedError === "object" && typeof namedError.name === "string" && namedError.name.length > 0 && namedError.name !== "Error") {
|
|
167264
|
+
return namedError.name;
|
|
167265
|
+
}
|
|
167266
|
+
return brief.split(":")[0]?.trim().split(/\s+/)[0] || brief || "unknown";
|
|
167267
|
+
}
|
|
167268
|
+
function shouldSkipCircuitBreaker(error51, brief) {
|
|
167269
|
+
const namedError = error51;
|
|
167270
|
+
const name2 = error51 instanceof Error ? error51.name : namedError && typeof namedError === "object" && typeof namedError.name === "string" ? namedError.name : "";
|
|
167271
|
+
const combined = `${name2} ${brief}`.toLowerCase();
|
|
167272
|
+
return name2 === "AbortError" || combined.includes("lease");
|
|
167273
|
+
}
|
|
167274
|
+
function logWithStackHead(message, stackHead) {
|
|
167275
|
+
log(message, stackHead ? { stackHead } : undefined);
|
|
167276
|
+
}
|
|
166915
167277
|
function getOpenCodeDbPath2() {
|
|
166916
167278
|
return join13(getDataDir(), "opencode", "opencode.db");
|
|
166917
167279
|
}
|
|
@@ -167017,7 +167379,12 @@ async function identifyKeyFilesForSession(args) {
|
|
|
167017
167379
|
system: KEY_FILES_SYSTEM_PROMPT,
|
|
167018
167380
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
167019
167381
|
}
|
|
167020
|
-
}, {
|
|
167382
|
+
}, {
|
|
167383
|
+
timeoutMs: Math.min(remainingMs, 300000),
|
|
167384
|
+
signal: abortController.signal,
|
|
167385
|
+
fallbackModels: args.fallbackModels,
|
|
167386
|
+
callContext: `dreamer:key-files:${args.sessionId.slice(0, 12)}`
|
|
167387
|
+
});
|
|
167021
167388
|
const messagesResponse = await args.client.session.messages({
|
|
167022
167389
|
path: { id: agentSessionId },
|
|
167023
167390
|
query: { directory: args.sessionDirectory }
|
|
@@ -167090,6 +167457,7 @@ async function identifyKeyFiles(args) {
|
|
|
167090
167457
|
parentSessionId: args.parentSessionId,
|
|
167091
167458
|
sessionDirectory: args.sessionDirectory,
|
|
167092
167459
|
holderId: args.holderId,
|
|
167460
|
+
fallbackModels: args.fallbackModels,
|
|
167093
167461
|
deadline: args.deadline,
|
|
167094
167462
|
sessionId,
|
|
167095
167463
|
config: args.config
|
|
@@ -167143,6 +167511,9 @@ async function runDream(args) {
|
|
|
167143
167511
|
const deadline = startedAt + args.maxRuntimeMinutes * 60 * 1000;
|
|
167144
167512
|
const lastDreamAt = getDreamState(args.db, `last_dream_at:${args.projectIdentity}`) ?? getDreamState(args.db, "last_dream_at");
|
|
167145
167513
|
log(`[dreamer] last dream at: ${lastDreamAt ?? "never"} (project=${args.projectIdentity})`);
|
|
167514
|
+
let lastErrorSignature = null;
|
|
167515
|
+
let consecutiveSameErrorFailures = 0;
|
|
167516
|
+
let circuitBreakerTripped = false;
|
|
167146
167517
|
try {
|
|
167147
167518
|
for (const taskName of args.tasks) {
|
|
167148
167519
|
if (Date.now() > deadline) {
|
|
@@ -167203,7 +167574,9 @@ async function runDream(args) {
|
|
|
167203
167574
|
}
|
|
167204
167575
|
}, {
|
|
167205
167576
|
timeoutMs: args.taskTimeoutMinutes * 60 * 1000,
|
|
167206
|
-
signal: taskAbortController.signal
|
|
167577
|
+
signal: taskAbortController.signal,
|
|
167578
|
+
fallbackModels: args.fallbackModels,
|
|
167579
|
+
callContext: `dreamer:${taskName}`
|
|
167207
167580
|
});
|
|
167208
167581
|
const messagesResponse = await args.client.session.messages({
|
|
167209
167582
|
path: { id: agentSessionId },
|
|
@@ -167223,16 +167596,40 @@ async function runDream(args) {
|
|
|
167223
167596
|
durationMs,
|
|
167224
167597
|
result: taskResult
|
|
167225
167598
|
});
|
|
167599
|
+
lastErrorSignature = null;
|
|
167600
|
+
consecutiveSameErrorFailures = 0;
|
|
167226
167601
|
} catch (error51) {
|
|
167227
167602
|
const durationMs = Date.now() - taskStartedAt;
|
|
167228
|
-
const
|
|
167229
|
-
|
|
167603
|
+
const errorDescription = describeError(error51);
|
|
167604
|
+
logWithStackHead(`[dreamer] task ${taskName}: failed after ${(durationMs / 1000).toFixed(1)}s — ${errorDescription.brief}`, errorDescription.stackHead);
|
|
167230
167605
|
result.tasks.push({
|
|
167231
167606
|
name: taskName,
|
|
167232
167607
|
durationMs,
|
|
167233
167608
|
result: null,
|
|
167234
|
-
error:
|
|
167609
|
+
error: errorDescription.brief
|
|
167235
167610
|
});
|
|
167611
|
+
if (shouldSkipCircuitBreaker(error51, errorDescription.brief)) {
|
|
167612
|
+
lastErrorSignature = null;
|
|
167613
|
+
consecutiveSameErrorFailures = 0;
|
|
167614
|
+
} else {
|
|
167615
|
+
const signature = getCircuitBreakerSignature(error51, errorDescription.brief);
|
|
167616
|
+
if (signature === lastErrorSignature) {
|
|
167617
|
+
consecutiveSameErrorFailures += 1;
|
|
167618
|
+
} else {
|
|
167619
|
+
lastErrorSignature = signature;
|
|
167620
|
+
consecutiveSameErrorFailures = 1;
|
|
167621
|
+
}
|
|
167622
|
+
if (consecutiveSameErrorFailures >= CIRCUIT_BREAKER_THRESHOLD) {
|
|
167623
|
+
circuitBreakerTripped = true;
|
|
167624
|
+
log(`[dreamer] circuit breaker: ${consecutiveSameErrorFailures} consecutive ${signature} failures — aborting remaining tasks`);
|
|
167625
|
+
result.tasks.push({
|
|
167626
|
+
name: "circuit-breaker",
|
|
167627
|
+
durationMs: 0,
|
|
167628
|
+
result: "",
|
|
167629
|
+
error: `Aborted remaining tasks: ${consecutiveSameErrorFailures} consecutive ${signature} failures. Configure dreamer model/fallback_models in magic-context.jsonc.`
|
|
167630
|
+
});
|
|
167631
|
+
}
|
|
167632
|
+
}
|
|
167236
167633
|
} finally {
|
|
167237
167634
|
clearInterval(leaseRenewalInterval);
|
|
167238
167635
|
if (agentSessionId) {
|
|
@@ -167244,8 +167641,20 @@ async function runDream(args) {
|
|
|
167244
167641
|
});
|
|
167245
167642
|
}
|
|
167246
167643
|
}
|
|
167644
|
+
if (circuitBreakerTripped) {
|
|
167645
|
+
break;
|
|
167646
|
+
}
|
|
167247
167647
|
}
|
|
167248
|
-
if (
|
|
167648
|
+
if (circuitBreakerTripped) {
|
|
167649
|
+
log("[dreamer] circuit breaker: skipping post-task phases");
|
|
167650
|
+
result.tasks.push({
|
|
167651
|
+
name: "post-task-phases",
|
|
167652
|
+
durationMs: 0,
|
|
167653
|
+
result: "",
|
|
167654
|
+
error: "Skipped post-task phases after circuit breaker tripped; configure dreamer model/fallback_models in magic-context.jsonc."
|
|
167655
|
+
});
|
|
167656
|
+
}
|
|
167657
|
+
if (!circuitBreakerTripped && args.experimentalUserMemories?.enabled && Date.now() <= deadline) {
|
|
167249
167658
|
const umStart = Date.now();
|
|
167250
167659
|
try {
|
|
167251
167660
|
const reviewResult = await reviewUserMemories({
|
|
@@ -167255,7 +167664,8 @@ async function runDream(args) {
|
|
|
167255
167664
|
sessionDirectory: args.sessionDirectory,
|
|
167256
167665
|
holderId,
|
|
167257
167666
|
deadline,
|
|
167258
|
-
promotionThreshold: args.experimentalUserMemories.promotionThreshold
|
|
167667
|
+
promotionThreshold: args.experimentalUserMemories.promotionThreshold,
|
|
167668
|
+
fallbackModels: args.fallbackModels
|
|
167259
167669
|
});
|
|
167260
167670
|
const umOutput = `promoted=${reviewResult.promoted} merged=${reviewResult.merged} dismissed=${reviewResult.dismissed} consumed=${reviewResult.candidatesConsumed}`;
|
|
167261
167671
|
if (reviewResult.promoted > 0 || reviewResult.merged > 0 || reviewResult.dismissed > 0) {
|
|
@@ -167267,16 +167677,17 @@ async function runDream(args) {
|
|
|
167267
167677
|
result: umOutput
|
|
167268
167678
|
});
|
|
167269
167679
|
} catch (error51) {
|
|
167270
|
-
|
|
167680
|
+
const errorDescription = describeError(error51);
|
|
167681
|
+
logWithStackHead(`[dreamer] user-memory review failed: ${errorDescription.brief}`, errorDescription.stackHead);
|
|
167271
167682
|
result.tasks.push({
|
|
167272
167683
|
name: "user memories",
|
|
167273
167684
|
durationMs: Date.now() - umStart,
|
|
167274
167685
|
result: "",
|
|
167275
|
-
error:
|
|
167686
|
+
error: errorDescription.brief
|
|
167276
167687
|
});
|
|
167277
167688
|
}
|
|
167278
167689
|
}
|
|
167279
|
-
if (Date.now() <= deadline) {
|
|
167690
|
+
if (!circuitBreakerTripped && Date.now() <= deadline) {
|
|
167280
167691
|
try {
|
|
167281
167692
|
await evaluateSmartNotes({
|
|
167282
167693
|
db: args.db,
|
|
@@ -167286,13 +167697,15 @@ async function runDream(args) {
|
|
|
167286
167697
|
sessionDirectory: args.sessionDirectory,
|
|
167287
167698
|
holderId,
|
|
167288
167699
|
deadline,
|
|
167289
|
-
result
|
|
167700
|
+
result,
|
|
167701
|
+
fallbackModels: args.fallbackModels
|
|
167290
167702
|
});
|
|
167291
167703
|
} catch (error51) {
|
|
167292
|
-
|
|
167704
|
+
const errorDescription = describeError(error51);
|
|
167705
|
+
logWithStackHead(`[dreamer] smart note evaluation failed: ${errorDescription.brief}`, errorDescription.stackHead);
|
|
167293
167706
|
}
|
|
167294
167707
|
}
|
|
167295
|
-
if (args.experimentalPinKeyFiles?.enabled && Date.now() <= deadline) {
|
|
167708
|
+
if (!circuitBreakerTripped && args.experimentalPinKeyFiles?.enabled && Date.now() <= deadline) {
|
|
167296
167709
|
const kfStart = Date.now();
|
|
167297
167710
|
try {
|
|
167298
167711
|
await identifyKeyFiles({
|
|
@@ -167303,7 +167716,8 @@ async function runDream(args) {
|
|
|
167303
167716
|
sessionDirectory: args.sessionDirectory ?? args.projectIdentity,
|
|
167304
167717
|
holderId,
|
|
167305
167718
|
deadline,
|
|
167306
|
-
config: args.experimentalPinKeyFiles
|
|
167719
|
+
config: args.experimentalPinKeyFiles,
|
|
167720
|
+
fallbackModels: args.fallbackModels
|
|
167307
167721
|
});
|
|
167308
167722
|
result.tasks.push({
|
|
167309
167723
|
name: "key files",
|
|
@@ -167311,12 +167725,13 @@ async function runDream(args) {
|
|
|
167311
167725
|
result: "completed"
|
|
167312
167726
|
});
|
|
167313
167727
|
} catch (error51) {
|
|
167314
|
-
|
|
167728
|
+
const errorDescription = describeError(error51);
|
|
167729
|
+
logWithStackHead(`[key-files] identification phase failed: ${errorDescription.brief}`, errorDescription.stackHead);
|
|
167315
167730
|
result.tasks.push({
|
|
167316
167731
|
name: "key files",
|
|
167317
167732
|
durationMs: Date.now() - kfStart,
|
|
167318
167733
|
result: "",
|
|
167319
|
-
error:
|
|
167734
|
+
error: errorDescription.brief
|
|
167320
167735
|
});
|
|
167321
167736
|
}
|
|
167322
167737
|
}
|
|
@@ -167351,7 +167766,13 @@ async function runDream(args) {
|
|
|
167351
167766
|
smartNotesPending: result.smartNotesPending,
|
|
167352
167767
|
memoryChanges: persistedMemoryChanges
|
|
167353
167768
|
});
|
|
167354
|
-
const POST_TASK_NAMES = new Set([
|
|
167769
|
+
const POST_TASK_NAMES = new Set([
|
|
167770
|
+
"smart-notes",
|
|
167771
|
+
"user memories",
|
|
167772
|
+
"key files",
|
|
167773
|
+
"post-task-phases",
|
|
167774
|
+
"circuit-breaker"
|
|
167775
|
+
]);
|
|
167355
167776
|
const hasSuccessfulTask = result.tasks.some((t) => !t.error && !POST_TASK_NAMES.has(t.name));
|
|
167356
167777
|
if (hasSuccessfulTask) {
|
|
167357
167778
|
setDreamState(args.db, `last_dream_at:${args.projectIdentity}`, String(result.finishedAt));
|
|
@@ -167430,7 +167851,12 @@ Only include notes whose conditions you could definitively evaluate. Skip notes
|
|
|
167430
167851
|
system: DREAMER_SYSTEM_PROMPT,
|
|
167431
167852
|
parts: [{ type: "text", text: evaluationPrompt, synthetic: true }]
|
|
167432
167853
|
}
|
|
167433
|
-
}, {
|
|
167854
|
+
}, {
|
|
167855
|
+
timeoutMs: Math.min(remainingMs, 300000),
|
|
167856
|
+
signal: abortController.signal,
|
|
167857
|
+
fallbackModels: args.fallbackModels,
|
|
167858
|
+
callContext: "dreamer:smart-notes"
|
|
167859
|
+
});
|
|
167434
167860
|
const messagesResponse = await args.client.session.messages({
|
|
167435
167861
|
path: { id: agentSessionId },
|
|
167436
167862
|
query: { directory: args.sessionDirectory ?? args.projectIdentity }
|
|
@@ -167489,15 +167915,15 @@ Only include notes whose conditions you could definitively evaluate. Skip notes
|
|
|
167489
167915
|
});
|
|
167490
167916
|
} catch (error51) {
|
|
167491
167917
|
const durationMs = Date.now() - taskStartedAt;
|
|
167492
|
-
const
|
|
167918
|
+
const errorDescription = describeError(error51);
|
|
167493
167919
|
args.result.smartNotesSurfaced = 0;
|
|
167494
167920
|
args.result.smartNotesPending = pendingNotes.length;
|
|
167495
|
-
|
|
167921
|
+
logWithStackHead(`[dreamer] smart notes: failed after ${(durationMs / 1000).toFixed(1)}s — ${errorDescription.brief}`, errorDescription.stackHead);
|
|
167496
167922
|
args.result.tasks.push({
|
|
167497
167923
|
name: "smart-notes",
|
|
167498
167924
|
durationMs,
|
|
167499
167925
|
result: null,
|
|
167500
|
-
error:
|
|
167926
|
+
error: errorDescription.brief
|
|
167501
167927
|
});
|
|
167502
167928
|
} finally {
|
|
167503
167929
|
clearInterval(leaseInterval);
|
|
@@ -167530,7 +167956,8 @@ async function processDreamQueue(args) {
|
|
|
167530
167956
|
maxRuntimeMinutes: args.maxRuntimeMinutes,
|
|
167531
167957
|
sessionDirectory: projectDirectory,
|
|
167532
167958
|
experimentalUserMemories: args.experimentalUserMemories,
|
|
167533
|
-
experimentalPinKeyFiles: args.experimentalPinKeyFiles
|
|
167959
|
+
experimentalPinKeyFiles: args.experimentalPinKeyFiles,
|
|
167960
|
+
fallbackModels: args.fallbackModels
|
|
167534
167961
|
});
|
|
167535
167962
|
} catch (error51) {
|
|
167536
167963
|
log(`[dreamer] runDream threw for ${entry.projectIdentity}: ${getErrorMessage(error51)}`);
|
|
@@ -168138,6 +168565,7 @@ function searchGitCommitsSync(db, projectPath, query, options) {
|
|
|
168138
168565
|
init_embedding();
|
|
168139
168566
|
init_project_identity();
|
|
168140
168567
|
init_logger();
|
|
168568
|
+
init_resolve_fallbacks();
|
|
168141
168569
|
await init_storage();
|
|
168142
168570
|
var DREAM_TIMER_INTERVAL_MS = 15 * 60 * 1000;
|
|
168143
168571
|
var activeTimer = null;
|
|
@@ -168224,7 +168652,8 @@ async function sweepProject(reg, origin) {
|
|
|
168224
168652
|
maxRuntimeMinutes: reg.dreamerConfig.max_runtime_minutes,
|
|
168225
168653
|
experimentalUserMemories: reg.experimentalUserMemories,
|
|
168226
168654
|
experimentalPinKeyFiles: reg.experimentalPinKeyFiles,
|
|
168227
|
-
projectIdentity: registrationIdentity
|
|
168655
|
+
projectIdentity: registrationIdentity,
|
|
168656
|
+
fallbackModels: resolveFallbackChain(DREAMER_AGENT, reg.dreamerConfig.fallback_models)
|
|
168228
168657
|
});
|
|
168229
168658
|
} catch (error51) {
|
|
168230
168659
|
log(`[dreamer] timer-triggered queue processing failed for ${reg.directory}:`, error51);
|
|
@@ -168752,6 +169181,7 @@ function createTagger() {
|
|
|
168752
169181
|
init_magic_context();
|
|
168753
169182
|
init_project_identity();
|
|
168754
169183
|
init_logger();
|
|
169184
|
+
init_resolve_fallbacks();
|
|
168755
169185
|
await init_storage();
|
|
168756
169186
|
|
|
168757
169187
|
// src/hooks/magic-context/command-handler.ts
|
|
@@ -169232,7 +169662,8 @@ Dreaming is not configured for this project.`, {});
|
|
|
169232
169662
|
maxRuntimeMinutes: deps.dreamer.config.max_runtime_minutes,
|
|
169233
169663
|
experimentalUserMemories: deps.dreamer.experimentalUserMemories,
|
|
169234
169664
|
experimentalPinKeyFiles: deps.dreamer.experimentalPinKeyFiles,
|
|
169235
|
-
projectIdentity: deps.dreamer.projectPath
|
|
169665
|
+
projectIdentity: deps.dreamer.projectPath,
|
|
169666
|
+
fallbackModels: deps.dreamer.fallbackModels
|
|
169236
169667
|
});
|
|
169237
169668
|
await deps.sendNotification(sessionId, result ? summarizeDreamResult(result) : "Dream queued, but another worker is already processing the queue.", {});
|
|
169238
169669
|
throwSentinel("CTX-DREAM");
|
|
@@ -169528,113 +169959,8 @@ function clearSessionTracking(sessionId) {
|
|
|
169528
169959
|
}
|
|
169529
169960
|
}
|
|
169530
169961
|
|
|
169531
|
-
// src/features/magic-context/overflow-detection.ts
|
|
169532
|
-
var OVERFLOW_PATTERNS = [
|
|
169533
|
-
/prompt is too long/i,
|
|
169534
|
-
/input is too long for requested model/i,
|
|
169535
|
-
/exceeds the context window/i,
|
|
169536
|
-
/input token count.*exceeds the maximum/i,
|
|
169537
|
-
/maximum prompt length is \d+/i,
|
|
169538
|
-
/reduce the length of the messages/i,
|
|
169539
|
-
/maximum context length is \d+ tokens/i,
|
|
169540
|
-
/exceeds the limit of \d+/i,
|
|
169541
|
-
/exceeds the available context size/i,
|
|
169542
|
-
/greater than the context length/i,
|
|
169543
|
-
/context window exceeds limit/i,
|
|
169544
|
-
/exceeded model token limit/i,
|
|
169545
|
-
/context[_ ]length[_ ]exceeded/i,
|
|
169546
|
-
/request entity too large/i,
|
|
169547
|
-
/context length is only \d+ tokens/i,
|
|
169548
|
-
/input length.*exceeds.*context length/i,
|
|
169549
|
-
/prompt too long; exceeded (?:max )?context length/i,
|
|
169550
|
-
/too large for model with \d+ maximum context length/i,
|
|
169551
|
-
/model_context_window_exceeded/i,
|
|
169552
|
-
/context size has been exceeded/i
|
|
169553
|
-
];
|
|
169554
|
-
var LIMIT_EXTRACTION_PATTERNS = [
|
|
169555
|
-
/maximum prompt length is (\d+)/i,
|
|
169556
|
-
/maximum context length is (\d+) tokens?/i,
|
|
169557
|
-
/context length is only (\d+) tokens?/i,
|
|
169558
|
-
/exceeds the limit of (\d+)/i,
|
|
169559
|
-
/too large for model with (\d+) maximum context length/i,
|
|
169560
|
-
/context size.*(\d+) tokens?/i,
|
|
169561
|
-
/exceeds? the context length of (\d+)/i,
|
|
169562
|
-
/max(?:imum)?.*context.*?(\d+)/i
|
|
169563
|
-
];
|
|
169564
|
-
var MIN_PLAUSIBLE_LIMIT = 1024;
|
|
169565
|
-
var MAX_PLAUSIBLE_LIMIT = 1e7;
|
|
169566
|
-
function extractErrorMessage(error51) {
|
|
169567
|
-
if (!error51)
|
|
169568
|
-
return "";
|
|
169569
|
-
if (typeof error51 === "string")
|
|
169570
|
-
return error51;
|
|
169571
|
-
if (typeof error51 === "object") {
|
|
169572
|
-
const obj = error51;
|
|
169573
|
-
const nested = obj.error;
|
|
169574
|
-
if (nested && typeof nested.message === "string" && nested.message.length > 0) {
|
|
169575
|
-
return nested.message;
|
|
169576
|
-
}
|
|
169577
|
-
}
|
|
169578
|
-
if (error51 instanceof Error)
|
|
169579
|
-
return error51.message;
|
|
169580
|
-
if (typeof error51 === "object") {
|
|
169581
|
-
const obj = error51;
|
|
169582
|
-
if (typeof obj.message === "string")
|
|
169583
|
-
return obj.message;
|
|
169584
|
-
if (typeof obj.responseBody === "string")
|
|
169585
|
-
return obj.responseBody;
|
|
169586
|
-
try {
|
|
169587
|
-
return JSON.stringify(error51);
|
|
169588
|
-
} catch {
|
|
169589
|
-
return String(error51);
|
|
169590
|
-
}
|
|
169591
|
-
}
|
|
169592
|
-
return String(error51);
|
|
169593
|
-
}
|
|
169594
|
-
function detectOverflow(error51) {
|
|
169595
|
-
const message = extractErrorMessage(error51);
|
|
169596
|
-
if (!message) {
|
|
169597
|
-
return { isOverflow: false };
|
|
169598
|
-
}
|
|
169599
|
-
const hasStatus413 = /\b413\b/.test(message) && /(entity|payload|context|prompt)/i.test(message);
|
|
169600
|
-
let matched;
|
|
169601
|
-
for (const pattern of OVERFLOW_PATTERNS) {
|
|
169602
|
-
if (pattern.test(message)) {
|
|
169603
|
-
matched = pattern;
|
|
169604
|
-
break;
|
|
169605
|
-
}
|
|
169606
|
-
}
|
|
169607
|
-
if (!matched && !hasStatus413) {
|
|
169608
|
-
return { isOverflow: false };
|
|
169609
|
-
}
|
|
169610
|
-
const reportedLimit = parseReportedLimit(message);
|
|
169611
|
-
return {
|
|
169612
|
-
isOverflow: true,
|
|
169613
|
-
reportedLimit,
|
|
169614
|
-
matchedPattern: matched?.source
|
|
169615
|
-
};
|
|
169616
|
-
}
|
|
169617
|
-
function parseReportedLimit(message) {
|
|
169618
|
-
if (!message)
|
|
169619
|
-
return;
|
|
169620
|
-
for (const pattern of LIMIT_EXTRACTION_PATTERNS) {
|
|
169621
|
-
const match = message.match(pattern);
|
|
169622
|
-
if (!match)
|
|
169623
|
-
continue;
|
|
169624
|
-
const raw = match[1];
|
|
169625
|
-
if (!raw)
|
|
169626
|
-
continue;
|
|
169627
|
-
const value = Number.parseInt(raw, 10);
|
|
169628
|
-
if (!Number.isFinite(value))
|
|
169629
|
-
continue;
|
|
169630
|
-
if (value < MIN_PLAUSIBLE_LIMIT || value > MAX_PLAUSIBLE_LIMIT)
|
|
169631
|
-
continue;
|
|
169632
|
-
return value;
|
|
169633
|
-
}
|
|
169634
|
-
return;
|
|
169635
|
-
}
|
|
169636
|
-
|
|
169637
169962
|
// src/hooks/magic-context/event-handler.ts
|
|
169963
|
+
init_overflow_detection();
|
|
169638
169964
|
init_storage_meta_persisted();
|
|
169639
169965
|
init_logger();
|
|
169640
169966
|
await __promiseAll([
|
|
@@ -170548,6 +170874,7 @@ async function runCompartmentPhase(args) {
|
|
|
170548
170874
|
historianChunkTokens: args.historianChunkTokens,
|
|
170549
170875
|
historyBudgetTokens: args.historyBudgetTokens,
|
|
170550
170876
|
historianTimeoutMs: args.historianTimeoutMs,
|
|
170877
|
+
fallbackModels: args.fallbackModels,
|
|
170551
170878
|
directory: args.compartmentDirectory,
|
|
170552
170879
|
fallbackModelId: args.fallbackModelId,
|
|
170553
170880
|
getNotificationParams: args.getNotificationParams,
|
|
@@ -170575,6 +170902,7 @@ async function runCompartmentPhase(args) {
|
|
|
170575
170902
|
historianChunkTokens: args.historianChunkTokens,
|
|
170576
170903
|
historyBudgetTokens: args.historyBudgetTokens,
|
|
170577
170904
|
historianTimeoutMs: args.historianTimeoutMs,
|
|
170905
|
+
fallbackModels: args.fallbackModels,
|
|
170578
170906
|
directory: args.compartmentDirectory,
|
|
170579
170907
|
fallbackModelId: args.fallbackModelId,
|
|
170580
170908
|
getNotificationParams: args.getNotificationParams,
|
|
@@ -170614,6 +170942,7 @@ async function runCompartmentPhase(args) {
|
|
|
170614
170942
|
directory: args.compartmentDirectory,
|
|
170615
170943
|
historyBudgetTokens: args.historyBudgetTokens,
|
|
170616
170944
|
historianTimeoutMs: args.historianTimeoutMs,
|
|
170945
|
+
fallbackModels: args.fallbackModels,
|
|
170617
170946
|
minCompartmentRatio: args.compressorMinCompartmentRatio,
|
|
170618
170947
|
maxMergeDepth: args.compressorMaxMergeDepth
|
|
170619
170948
|
}).then((compressed) => {
|
|
@@ -170711,6 +171040,46 @@ function countMessagesSinceLastUser(messages) {
|
|
|
170711
171040
|
}
|
|
170712
171041
|
return messagesSinceLastUser;
|
|
170713
171042
|
}
|
|
171043
|
+
function injectToolPartIntoLatestAssistant(messages, part) {
|
|
171044
|
+
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
171045
|
+
const message = messages[index];
|
|
171046
|
+
if (message.info.role !== "assistant")
|
|
171047
|
+
continue;
|
|
171048
|
+
if (typeof message.info.id !== "string")
|
|
171049
|
+
continue;
|
|
171050
|
+
if (hasToolPartWithCallId(message, part.callID)) {
|
|
171051
|
+
return message.info.id;
|
|
171052
|
+
}
|
|
171053
|
+
message.parts.push(part);
|
|
171054
|
+
return message.info.id;
|
|
171055
|
+
}
|
|
171056
|
+
return null;
|
|
171057
|
+
}
|
|
171058
|
+
function injectToolPartIntoAssistantById(messages, messageId, part) {
|
|
171059
|
+
for (const message of messages) {
|
|
171060
|
+
if (message.info.id !== messageId)
|
|
171061
|
+
continue;
|
|
171062
|
+
if (message.info.role !== "assistant")
|
|
171063
|
+
continue;
|
|
171064
|
+
if (hasToolPartWithCallId(message, part.callID))
|
|
171065
|
+
return true;
|
|
171066
|
+
message.parts.push(part);
|
|
171067
|
+
return true;
|
|
171068
|
+
}
|
|
171069
|
+
return false;
|
|
171070
|
+
}
|
|
171071
|
+
function hasToolPartWithCallId(message, callId) {
|
|
171072
|
+
for (const part of message.parts) {
|
|
171073
|
+
if (part === null || typeof part !== "object")
|
|
171074
|
+
continue;
|
|
171075
|
+
const p = part;
|
|
171076
|
+
if (p.type !== "tool")
|
|
171077
|
+
continue;
|
|
171078
|
+
if (p.callID === callId)
|
|
171079
|
+
return true;
|
|
171080
|
+
}
|
|
171081
|
+
return false;
|
|
171082
|
+
}
|
|
170714
171083
|
function appendReminderToUserMessage(message, reminder) {
|
|
170715
171084
|
for (const part of message.parts) {
|
|
170716
171085
|
if (!isTextPart(part)) {
|
|
@@ -172140,7 +172509,7 @@ function extractToolInfo(part) {
|
|
|
172140
172509
|
return null;
|
|
172141
172510
|
}
|
|
172142
172511
|
function buildToolFingerprints(messages) {
|
|
172143
|
-
const
|
|
172512
|
+
const fingerprints2 = new Map;
|
|
172144
172513
|
for (const message of messages) {
|
|
172145
172514
|
if (message.info.role !== "assistant")
|
|
172146
172515
|
continue;
|
|
@@ -172158,11 +172527,11 @@ function buildToolFingerprints(messages) {
|
|
|
172158
172527
|
try {
|
|
172159
172528
|
const fingerprint = `${ownerMsgId}:${info.toolName}:${JSON.stringify(info.args)}`;
|
|
172160
172529
|
const compositeKey = `${ownerMsgId}\x00${callId}`;
|
|
172161
|
-
|
|
172530
|
+
fingerprints2.set(compositeKey, fingerprint);
|
|
172162
172531
|
} catch {}
|
|
172163
172532
|
}
|
|
172164
172533
|
}
|
|
172165
|
-
return
|
|
172534
|
+
return fingerprints2;
|
|
172166
172535
|
}
|
|
172167
172536
|
function extractCallId(part) {
|
|
172168
172537
|
if (part.type === "tool" && typeof part.callID === "string")
|
|
@@ -172220,6 +172589,84 @@ function isVisibleNoteReadPart(part) {
|
|
|
172220
172589
|
return false;
|
|
172221
172590
|
}
|
|
172222
172591
|
|
|
172592
|
+
// src/hooks/magic-context/todo-view.ts
|
|
172593
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
172594
|
+
var TERMINAL_STATUSES = new Set(["completed", "cancelled"]);
|
|
172595
|
+
var TITLE_DONE_STATUSES = new Set(["completed"]);
|
|
172596
|
+
var SYNTHETIC_CALL_ID_PREFIX = "mc_synthetic_todo_";
|
|
172597
|
+
function normalizeTodoStateJson(todos) {
|
|
172598
|
+
if (!Array.isArray(todos))
|
|
172599
|
+
return null;
|
|
172600
|
+
const normalized = [];
|
|
172601
|
+
for (const todo of todos) {
|
|
172602
|
+
if (!isTodoItem(todo))
|
|
172603
|
+
return null;
|
|
172604
|
+
normalized.push({
|
|
172605
|
+
content: todo.content,
|
|
172606
|
+
status: todo.status,
|
|
172607
|
+
priority: todo.priority
|
|
172608
|
+
});
|
|
172609
|
+
}
|
|
172610
|
+
return JSON.stringify(normalized);
|
|
172611
|
+
}
|
|
172612
|
+
function buildSyntheticTodoPart(stateJson) {
|
|
172613
|
+
const todos = parseTodoState(stateJson);
|
|
172614
|
+
if (todos === null || todos.length === 0)
|
|
172615
|
+
return null;
|
|
172616
|
+
if (todos.every((t) => TERMINAL_STATUSES.has(t.status)))
|
|
172617
|
+
return null;
|
|
172618
|
+
const callID = computeSyntheticCallId(stateJson);
|
|
172619
|
+
const activeCount = todos.filter((t) => !TITLE_DONE_STATUSES.has(t.status)).length;
|
|
172620
|
+
const output = JSON.stringify(todos, null, 2);
|
|
172621
|
+
const ts = 0;
|
|
172622
|
+
return {
|
|
172623
|
+
type: "tool",
|
|
172624
|
+
callID,
|
|
172625
|
+
tool: "todowrite",
|
|
172626
|
+
state: {
|
|
172627
|
+
status: "completed",
|
|
172628
|
+
input: { todos },
|
|
172629
|
+
output,
|
|
172630
|
+
title: `${activeCount} todos`,
|
|
172631
|
+
metadata: { todos, truncated: false },
|
|
172632
|
+
time: { start: ts, end: ts }
|
|
172633
|
+
},
|
|
172634
|
+
syntheticTodoMarker: true
|
|
172635
|
+
};
|
|
172636
|
+
}
|
|
172637
|
+
function computeSyntheticCallId(stateJson) {
|
|
172638
|
+
const hash2 = createHash4("sha256").update(stateJson).digest("hex").slice(0, 16);
|
|
172639
|
+
return `${SYNTHETIC_CALL_ID_PREFIX}${hash2}`;
|
|
172640
|
+
}
|
|
172641
|
+
function parseTodoState(stateJson) {
|
|
172642
|
+
if (stateJson.length === 0)
|
|
172643
|
+
return null;
|
|
172644
|
+
try {
|
|
172645
|
+
const parsed = JSON.parse(stateJson);
|
|
172646
|
+
if (!Array.isArray(parsed))
|
|
172647
|
+
return null;
|
|
172648
|
+
const result = [];
|
|
172649
|
+
for (const item of parsed) {
|
|
172650
|
+
if (!isTodoItem(item))
|
|
172651
|
+
continue;
|
|
172652
|
+
result.push({
|
|
172653
|
+
content: item.content,
|
|
172654
|
+
status: item.status,
|
|
172655
|
+
priority: item.priority
|
|
172656
|
+
});
|
|
172657
|
+
}
|
|
172658
|
+
return result;
|
|
172659
|
+
} catch {
|
|
172660
|
+
return null;
|
|
172661
|
+
}
|
|
172662
|
+
}
|
|
172663
|
+
function isTodoItem(value) {
|
|
172664
|
+
if (value === null || typeof value !== "object")
|
|
172665
|
+
return false;
|
|
172666
|
+
const todo = value;
|
|
172667
|
+
return typeof todo.content === "string" && typeof todo.status === "string" && typeof todo.priority === "string";
|
|
172668
|
+
}
|
|
172669
|
+
|
|
172223
172670
|
// src/hooks/magic-context/transform-stage-logger.ts
|
|
172224
172671
|
init_logger();
|
|
172225
172672
|
function logTransformTiming(sessionId, stage, startMs, extra) {
|
|
@@ -172461,6 +172908,33 @@ async function runPostTransformPhase(args) {
|
|
|
172461
172908
|
const anchoredMessageId = appendReminderToLatestUserMessage(args.messages, noteInstruction);
|
|
172462
172909
|
markNoteNudgeDelivered(args.db, args.sessionId, noteInstruction, anchoredMessageId);
|
|
172463
172910
|
}
|
|
172911
|
+
if (args.fullFeatureMode) {
|
|
172912
|
+
const persistedAnchor = getPersistedTodoSyntheticAnchor(args.db, args.sessionId);
|
|
172913
|
+
if (isCacheBustingPass) {
|
|
172914
|
+
const part = buildSyntheticTodoPart(args.sessionMeta.lastTodoState);
|
|
172915
|
+
if (part === null) {
|
|
172916
|
+
if (persistedAnchor) {
|
|
172917
|
+
clearPersistedTodoSyntheticAnchor(args.db, args.sessionId);
|
|
172918
|
+
}
|
|
172919
|
+
} else if (persistedAnchor && persistedAnchor.callId === part.callID && injectToolPartIntoAssistantById(args.messages, persistedAnchor.messageId, part)) {
|
|
172920
|
+
if (persistedAnchor.stateJson.length === 0) {
|
|
172921
|
+
setPersistedTodoSyntheticAnchor(args.db, args.sessionId, persistedAnchor.callId, persistedAnchor.messageId, args.sessionMeta.lastTodoState);
|
|
172922
|
+
}
|
|
172923
|
+
} else {
|
|
172924
|
+
const anchoredMessageId = injectToolPartIntoLatestAssistant(args.messages, part);
|
|
172925
|
+
if (anchoredMessageId) {
|
|
172926
|
+
setPersistedTodoSyntheticAnchor(args.db, args.sessionId, part.callID, anchoredMessageId, args.sessionMeta.lastTodoState);
|
|
172927
|
+
} else if (persistedAnchor) {
|
|
172928
|
+
clearPersistedTodoSyntheticAnchor(args.db, args.sessionId);
|
|
172929
|
+
}
|
|
172930
|
+
}
|
|
172931
|
+
} else if (persistedAnchor && persistedAnchor.stateJson.length > 0) {
|
|
172932
|
+
const part = buildSyntheticTodoPart(persistedAnchor.stateJson);
|
|
172933
|
+
if (part !== null && part.callID === persistedAnchor.callId) {
|
|
172934
|
+
injectToolPartIntoAssistantById(args.messages, persistedAnchor.messageId, part);
|
|
172935
|
+
}
|
|
172936
|
+
}
|
|
172937
|
+
}
|
|
172464
172938
|
if (args.fullFeatureMode && args.autoSearch?.enabled && args.projectPath) {
|
|
172465
172939
|
const visibleMemoryIds = getVisibleMemoryIds(args.db, args.sessionId) ?? undefined;
|
|
172466
172940
|
try {
|
|
@@ -172692,6 +173166,7 @@ function createTransform(deps) {
|
|
|
172692
173166
|
historianChunkTokens: deps.getHistorianChunkTokens?.() ?? 20000,
|
|
172693
173167
|
historyBudgetTokens,
|
|
172694
173168
|
historianTimeoutMs: deps.historianTimeoutMs,
|
|
173169
|
+
fallbackModels: deps.fallbackModels,
|
|
172695
173170
|
directory: compartmentDirectory,
|
|
172696
173171
|
fallbackModelId,
|
|
172697
173172
|
getNotificationParams: () => notificationParams,
|
|
@@ -172861,6 +173336,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
|
|
|
172861
173336
|
historianChunkTokens: deps.getHistorianChunkTokens?.() ?? 20000,
|
|
172862
173337
|
historyBudgetTokens,
|
|
172863
173338
|
historianTimeoutMs: deps.historianTimeoutMs,
|
|
173339
|
+
fallbackModels: deps.fallbackModels,
|
|
172864
173340
|
compartmentDirectory,
|
|
172865
173341
|
messages,
|
|
172866
173342
|
pendingCompartmentInjection,
|
|
@@ -173701,9 +174177,17 @@ function createToolExecuteAfterHook(args) {
|
|
|
173701
174177
|
if (typedInput.tool === "todowrite") {
|
|
173702
174178
|
const todoArgs = typedInput.args;
|
|
173703
174179
|
const todos = todoArgs?.todos;
|
|
173704
|
-
|
|
173705
|
-
|
|
173706
|
-
|
|
174180
|
+
const sessionMeta = Array.isArray(todos) ? getOrCreateSessionMeta(args.db, typedInput.sessionID) : null;
|
|
174181
|
+
if (sessionMeta && !sessionMeta.isSubagent) {
|
|
174182
|
+
const normalizedTodos = normalizeTodoStateJson(todos);
|
|
174183
|
+
if (normalizedTodos !== null) {
|
|
174184
|
+
updateSessionMeta(args.db, typedInput.sessionID, {
|
|
174185
|
+
lastTodoState: normalizedTodos
|
|
174186
|
+
});
|
|
174187
|
+
}
|
|
174188
|
+
}
|
|
174189
|
+
if (Array.isArray(todos) && todos.length > 0 && todos.every((t) => typeof t === "object" && t !== null && (t.status === "completed" || t.status === "cancelled"))) {
|
|
174190
|
+
if (sessionMeta && !sessionMeta.isSubagent) {
|
|
173707
174191
|
onNoteTrigger(args.db, typedInput.sessionID, "todos_complete");
|
|
173708
174192
|
}
|
|
173709
174193
|
}
|
|
@@ -173719,7 +174203,7 @@ function createToolExecuteAfterHook(args) {
|
|
|
173719
174203
|
init_send_session_notification();
|
|
173720
174204
|
|
|
173721
174205
|
// src/hooks/magic-context/system-prompt-hash.ts
|
|
173722
|
-
import { createHash as
|
|
174206
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
173723
174207
|
import { existsSync as existsSync13, readFileSync as readFileSync9, realpathSync } from "node:fs";
|
|
173724
174208
|
import { join as join22, resolve as resolve4, sep } from "node:path";
|
|
173725
174209
|
|
|
@@ -174024,7 +174508,7 @@ ${sections.join(`
|
|
|
174024
174508
|
`);
|
|
174025
174509
|
if (systemContent.length === 0)
|
|
174026
174510
|
return;
|
|
174027
|
-
const currentHash =
|
|
174511
|
+
const currentHash = createHash5("md5").update(systemContent).digest("hex");
|
|
174028
174512
|
if (!sessionMetaEarly) {
|
|
174029
174513
|
return;
|
|
174030
174514
|
}
|
|
@@ -174039,14 +174523,12 @@ ${sections.join(`
|
|
|
174039
174523
|
} else if (previousHash === "" || previousHash === "0") {
|
|
174040
174524
|
sessionLog(sessionId, `system prompt hash initialized: ${currentHash} (len=${systemContent.length})`);
|
|
174041
174525
|
}
|
|
174042
|
-
const systemPromptTokens = estimateTokens(systemContent);
|
|
174043
174526
|
if (currentHash !== previousHash) {
|
|
174527
|
+
const systemPromptTokens = estimateTokens(systemContent);
|
|
174044
174528
|
updateSessionMeta(deps.db, sessionId, {
|
|
174045
174529
|
systemPromptHash: currentHash,
|
|
174046
174530
|
systemPromptTokens
|
|
174047
174531
|
});
|
|
174048
|
-
} else if (Math.abs(sessionMeta.systemPromptTokens - systemPromptTokens) > 50) {
|
|
174049
|
-
updateSessionMeta(deps.db, sessionId, { systemPromptTokens });
|
|
174050
174532
|
}
|
|
174051
174533
|
if (isCacheBusting) {
|
|
174052
174534
|
deps.systemPromptRefreshSessions.delete(sessionId);
|
|
@@ -174108,6 +174590,7 @@ function createMagicContextHook(deps) {
|
|
|
174108
174590
|
}
|
|
174109
174591
|
let lastScheduleCheckMs = 0;
|
|
174110
174592
|
const getHistorianChunkTokens = () => deriveHistorianChunkTokens(resolveHistorianContextLimit(deps.config.historian?.model));
|
|
174593
|
+
const historianFallbackModels = resolveFallbackChain(HISTORIAN_AGENT, deps.config.historian?.fallback_models);
|
|
174111
174594
|
const nudgePlacements = createNudgePlacementStore(db);
|
|
174112
174595
|
const historyRefreshSessions = deps.liveSessionState?.historyRefreshSessions ?? new Set;
|
|
174113
174596
|
const systemPromptRefreshSessions = deps.liveSessionState?.systemPromptRefreshSessions ?? new Set;
|
|
@@ -174167,6 +174650,7 @@ function createMagicContextHook(deps) {
|
|
|
174167
174650
|
executeThresholdPercentage: deps.config.execute_threshold_percentage,
|
|
174168
174651
|
executeThresholdTokens: deps.config.execute_threshold_tokens,
|
|
174169
174652
|
historianTimeoutMs: deps.config.historian_timeout_ms ?? DEFAULT_HISTORIAN_TIMEOUT_MS,
|
|
174653
|
+
fallbackModels: historianFallbackModels,
|
|
174170
174654
|
getNotificationParams: (sessionId) => getLiveNotificationParams(sessionId, liveModelBySession, variantBySession, agentBySession),
|
|
174171
174655
|
getModelKey: (sessionId) => {
|
|
174172
174656
|
const model = liveModelBySession.get(sessionId);
|
|
@@ -174244,7 +174728,8 @@ function createMagicContextHook(deps) {
|
|
|
174244
174728
|
enabled: true,
|
|
174245
174729
|
token_budget: deps.config.dreamer.pin_key_files.token_budget,
|
|
174246
174730
|
min_reads: deps.config.dreamer.pin_key_files.min_reads
|
|
174247
|
-
} : undefined
|
|
174731
|
+
} : undefined,
|
|
174732
|
+
fallbackModels: resolveFallbackChain(DREAMER_AGENT, deps.config.dreamer?.fallback_models)
|
|
174248
174733
|
}).catch((error51) => {
|
|
174249
174734
|
log("[dreamer] scheduled queue processing failed:", error51);
|
|
174250
174735
|
});
|
|
@@ -174278,6 +174763,7 @@ function createMagicContextHook(deps) {
|
|
|
174278
174763
|
sessionId,
|
|
174279
174764
|
historianChunkTokens: getHistorianChunkTokens(),
|
|
174280
174765
|
historianTimeoutMs: deps.config.historian_timeout_ms ?? DEFAULT_HISTORIAN_TIMEOUT_MS,
|
|
174766
|
+
fallbackModels: historianFallbackModels,
|
|
174281
174767
|
directory: deps.directory,
|
|
174282
174768
|
fallbackModelId: (() => {
|
|
174283
174769
|
const model = resolveLiveModel(sessionId);
|
|
@@ -174317,7 +174803,8 @@ function createMagicContextHook(deps) {
|
|
|
174317
174803
|
enabled: true,
|
|
174318
174804
|
token_budget: deps.config.dreamer.pin_key_files.token_budget,
|
|
174319
174805
|
min_reads: deps.config.dreamer.pin_key_files.min_reads
|
|
174320
|
-
} : undefined
|
|
174806
|
+
} : undefined,
|
|
174807
|
+
fallbackModels: resolveFallbackChain(DREAMER_AGENT, deps.config.dreamer.fallback_models)
|
|
174321
174808
|
} : undefined
|
|
174322
174809
|
});
|
|
174323
174810
|
const systemPromptHash = createSystemPromptHashHandler({
|
|
@@ -174979,19 +175466,7 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config2, liveSess
|
|
|
174979
175466
|
}
|
|
174980
175467
|
detail.nextNudgeAfter = detail.lastNudgeTokens + detail.nudgeInterval;
|
|
174981
175468
|
try {
|
|
174982
|
-
const
|
|
174983
|
-
const facts = db.prepare("SELECT content FROM session_facts WHERE session_id = ?").all(sessionId);
|
|
174984
|
-
let histTokens = 0;
|
|
174985
|
-
for (const c of compartments) {
|
|
174986
|
-
histTokens += estimateTokens(`<compartment start="${c.start_message}" end="${c.end_message}" title="${c.title}">
|
|
174987
|
-
${c.content}
|
|
174988
|
-
</compartment>
|
|
174989
|
-
`);
|
|
174990
|
-
}
|
|
174991
|
-
for (const f of facts) {
|
|
174992
|
-
histTokens += estimateTokens(`* ${f.content}
|
|
174993
|
-
`);
|
|
174994
|
-
}
|
|
175469
|
+
const histTokens = base.compartmentTokens + base.factTokens;
|
|
174995
175470
|
detail.historyBlockTokens = histTokens;
|
|
174996
175471
|
if (detail.contextLimit > 0) {
|
|
174997
175472
|
const budget = Math.floor(detail.contextLimit * (Math.min(detail.executeThreshold, 80) / 100) * detail.historyBudgetPercentage);
|
|
@@ -175164,7 +175639,7 @@ function normalizeLimit2(limit) {
|
|
|
175164
175639
|
return Math.max(1, Math.floor(limit));
|
|
175165
175640
|
}
|
|
175166
175641
|
function getAllowedActions(deps) {
|
|
175167
|
-
const allowed = deps.allowedActions?.length ? deps.allowedActions : [
|
|
175642
|
+
const allowed = deps.allowedActions?.length ? deps.allowedActions : ["write", "delete"];
|
|
175168
175643
|
return [...allowed];
|
|
175169
175644
|
}
|
|
175170
175645
|
function normalizeCategory(category) {
|
|
@@ -175270,7 +175745,7 @@ function createCtxMemoryTool(deps) {
|
|
|
175270
175745
|
return tool2({
|
|
175271
175746
|
description: CTX_MEMORY_DESCRIPTION,
|
|
175272
175747
|
args: {
|
|
175273
|
-
action: tool2.schema.enum(
|
|
175748
|
+
action: tool2.schema.enum([...CTX_MEMORY_DREAMER_ACTIONS]).describe("Action to perform on memories"),
|
|
175274
175749
|
content: tool2.schema.string().optional().describe("Memory content (required for write, update, merge)"),
|
|
175275
175750
|
category: tool2.schema.string().optional().describe("Memory category (required for write, optional filter for list, optional override for merge)"),
|
|
175276
175751
|
id: tool2.schema.number().optional().describe("Memory ID (required for delete, update, archive)"),
|
|
@@ -176036,11 +176511,11 @@ import { createServer } from "node:http";
|
|
|
176036
176511
|
import { dirname as dirname6 } from "node:path";
|
|
176037
176512
|
|
|
176038
176513
|
// src/shared/rpc-utils.ts
|
|
176039
|
-
import { createHash as
|
|
176514
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
176040
176515
|
import { join as join23 } from "node:path";
|
|
176041
176516
|
function projectHash(directory) {
|
|
176042
176517
|
const normalized = directory.replace(/\/+$/, "");
|
|
176043
|
-
return
|
|
176518
|
+
return createHash6("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
176044
176519
|
}
|
|
176045
176520
|
function rpcPortFilePath(storageDir, directory) {
|
|
176046
176521
|
return join23(storageDir, "rpc", projectHash(directory), "port");
|