@cortexkit/pi-magic-context 0.38.1 → 0.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/{index-8e0zezh7.js → index-qqgk7jmy.js} +2200 -147
- package/dist/index.js +538 -182
- package/dist/subagent-entry.js +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -134,6 +134,7 @@ import {
|
|
|
134
134
|
getAllStatusTagTokenTotalsFlat,
|
|
135
135
|
getAutoSearchHintDecisions,
|
|
136
136
|
getCachedAbsoluteMessageCount,
|
|
137
|
+
getChannel1NudgeState,
|
|
137
138
|
getChannel2NudgeClaim,
|
|
138
139
|
getChannel2NudgeState,
|
|
139
140
|
getCompactionModeRecord,
|
|
@@ -149,7 +150,6 @@ import {
|
|
|
149
150
|
getLastCompartmentEndMessage,
|
|
150
151
|
getLastCompartmentEndMessageId,
|
|
151
152
|
getLastIndexedOrdinal,
|
|
152
|
-
getLastNudgeLevel,
|
|
153
153
|
getLastNudgeUndropped,
|
|
154
154
|
getLatestHistorianInvocationId,
|
|
155
155
|
getLegacyProtectedTailStartOrdinal,
|
|
@@ -343,11 +343,11 @@ import {
|
|
|
343
343
|
saveRecompStagingPass,
|
|
344
344
|
saveSourceContent,
|
|
345
345
|
scheduleAfterBootQuiet,
|
|
346
|
+
setChannel1NudgeState,
|
|
346
347
|
setChannel2NudgeState,
|
|
347
348
|
setCompactionModeRecord,
|
|
348
349
|
setDeferredExecutePendingIfAbsent,
|
|
349
350
|
setEmergencyDropSample,
|
|
350
|
-
setLastNudgeLevel,
|
|
351
351
|
setLastNudgeUndropped,
|
|
352
352
|
setMemoryClassification,
|
|
353
353
|
setMuralCue,
|
|
@@ -361,6 +361,7 @@ import {
|
|
|
361
361
|
setSqlitePragmaConfig,
|
|
362
362
|
setStoragePrivatePermissionEnforcement,
|
|
363
363
|
setTodoSnapshot,
|
|
364
|
+
shouldUseStickyChannel1Reminder,
|
|
364
365
|
sourceNameForMemory,
|
|
365
366
|
stripChannel1ReminderSpans,
|
|
366
367
|
stripMemoryMuralBlock,
|
|
@@ -395,7 +396,7 @@ import {
|
|
|
395
396
|
withMigrationLanguageDirective,
|
|
396
397
|
withRawMessageProvider,
|
|
397
398
|
withRawSessionMessageCache
|
|
398
|
-
} from "./index-
|
|
399
|
+
} from "./index-qqgk7jmy.js";
|
|
399
400
|
import {
|
|
400
401
|
pushNotification
|
|
401
402
|
} from "./index-hw34xmzk.js";
|
|
@@ -417,49 +418,104 @@ import {
|
|
|
417
418
|
import { createRequire as createRequire3 } from "node:module";
|
|
418
419
|
import { join as join5, resolve as resolve2 } from "node:path";
|
|
419
420
|
|
|
420
|
-
// ../plugin/src/shared/
|
|
421
|
-
function
|
|
422
|
-
|
|
423
|
-
return dedupe(userList.filter(isValidModelSpec));
|
|
421
|
+
// ../plugin/src/shared/model-resolution.ts
|
|
422
|
+
function asRecord(value) {
|
|
423
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
|
|
424
424
|
}
|
|
425
|
-
function
|
|
426
|
-
if (
|
|
427
|
-
return
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
425
|
+
function readString(value) {
|
|
426
|
+
if (typeof value !== "string")
|
|
427
|
+
return;
|
|
428
|
+
const trimmed = value.trim();
|
|
429
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
430
|
+
}
|
|
431
|
+
function hasOwn(record, key) {
|
|
432
|
+
return Object.hasOwn(record, key);
|
|
433
|
+
}
|
|
434
|
+
function normalizeModelEntry(entry, harness) {
|
|
435
|
+
if (typeof entry === "string") {
|
|
436
|
+
const model2 = readString(entry);
|
|
437
|
+
return model2 ? { model: model2 } : undefined;
|
|
431
438
|
}
|
|
432
|
-
|
|
439
|
+
const objectEntry = asRecord(entry);
|
|
440
|
+
if (!objectEntry)
|
|
441
|
+
return;
|
|
442
|
+
const model = readString(objectEntry.model);
|
|
443
|
+
if (!model)
|
|
444
|
+
return;
|
|
445
|
+
const qualifier = readString(objectEntry[harness === "opencode" ? "variant" : "thinking_level"]);
|
|
446
|
+
return qualifier ? { model, qualifier } : { model };
|
|
433
447
|
}
|
|
434
|
-
function
|
|
435
|
-
const slash =
|
|
436
|
-
return slash > 0 && slash <
|
|
448
|
+
function isValidModelReference(entry) {
|
|
449
|
+
const slash = entry.model.indexOf("/");
|
|
450
|
+
return slash > 0 && slash < entry.model.length - 1;
|
|
437
451
|
}
|
|
438
|
-
function
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
452
|
+
function sameAttempt(a, b) {
|
|
453
|
+
return a.model === b.model && a.qualifier === b.qualifier;
|
|
454
|
+
}
|
|
455
|
+
function resolveFallbackEntries(value, harness) {
|
|
456
|
+
const values = Array.isArray(value) ? value : value === undefined ? [] : [value];
|
|
457
|
+
const resolved = [];
|
|
458
|
+
for (const value2 of values) {
|
|
459
|
+
const entry = normalizeModelEntry(value2, harness);
|
|
460
|
+
if (!entry || !isValidModelReference(entry))
|
|
443
461
|
continue;
|
|
444
|
-
|
|
445
|
-
|
|
462
|
+
if (resolved.some((candidate) => sameAttempt(candidate, entry)))
|
|
463
|
+
continue;
|
|
464
|
+
resolved.push(entry);
|
|
446
465
|
}
|
|
447
|
-
return
|
|
466
|
+
return resolved;
|
|
448
467
|
}
|
|
449
|
-
function
|
|
450
|
-
const
|
|
451
|
-
if (
|
|
452
|
-
return
|
|
468
|
+
function resolvePrimaryEntry(args) {
|
|
469
|
+
const entry = normalizeModelEntry(args.entry, args.harness);
|
|
470
|
+
if (!entry)
|
|
471
|
+
return;
|
|
472
|
+
const qualifier = entry.qualifier ?? readString(args.defaultQualifier);
|
|
473
|
+
return qualifier ? { ...entry, qualifier } : entry;
|
|
474
|
+
}
|
|
475
|
+
function resolveHistorianModel(config, harness) {
|
|
476
|
+
const historian = asRecord(asRecord(config)?.historian);
|
|
477
|
+
const block = asRecord(historian?.[harness]);
|
|
478
|
+
if (!block)
|
|
479
|
+
return { fallbacks: [] };
|
|
453
480
|
return {
|
|
454
|
-
|
|
455
|
-
|
|
481
|
+
primary: resolvePrimaryEntry({
|
|
482
|
+
entry: block.model,
|
|
483
|
+
defaultQualifier: block[harness === "opencode" ? "variant" : "thinking_level"],
|
|
484
|
+
harness
|
|
485
|
+
}),
|
|
486
|
+
fallbacks: resolveFallbackEntries(block.fallback_models, harness)
|
|
456
487
|
};
|
|
457
488
|
}
|
|
458
|
-
function
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
const
|
|
462
|
-
|
|
489
|
+
function resolveDreamerTaskModel(args) {
|
|
490
|
+
const dreamer = asRecord(asRecord(args.config)?.dreamer);
|
|
491
|
+
const harnessBlock = asRecord(dreamer?.[args.harness]);
|
|
492
|
+
const taskBlock = asRecord(asRecord(harnessBlock?.tasks)?.[args.task]);
|
|
493
|
+
const schedulingTask = asRecord(asRecord(dreamer?.tasks)?.[args.task]);
|
|
494
|
+
if (!harnessBlock) {
|
|
495
|
+
return {
|
|
496
|
+
fallbacks: [],
|
|
497
|
+
schedule: readString(schedulingTask?.schedule),
|
|
498
|
+
timeoutMinutes: typeof taskBlock?.timeout_minutes === "number" ? taskBlock.timeout_minutes : undefined,
|
|
499
|
+
promotionThreshold: typeof schedulingTask?.promotion_threshold === "number" ? schedulingTask.promotion_threshold : undefined
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
const taskQualifier = taskBlock?.[args.harness === "opencode" ? "variant" : "thinking_level"];
|
|
503
|
+
const harnessQualifier = harnessBlock[args.harness === "opencode" ? "variant" : "thinking_level"] ?? normalizeModelEntry(harnessBlock.model, args.harness)?.qualifier;
|
|
504
|
+
const taskHasModel = taskBlock !== undefined && hasOwn(taskBlock, "model");
|
|
505
|
+
const usesMuralModel = !taskHasModel && args.task === "compress-cues" && Boolean(readString(args.muralModel));
|
|
506
|
+
const primarySource = taskHasModel ? taskBlock?.model : usesMuralModel ? args.muralModel : harnessBlock.model;
|
|
507
|
+
const fallbackSource = taskBlock !== undefined && hasOwn(taskBlock, "fallback_models") ? taskBlock.fallback_models : harnessBlock.fallback_models;
|
|
508
|
+
return {
|
|
509
|
+
primary: resolvePrimaryEntry({
|
|
510
|
+
entry: primarySource,
|
|
511
|
+
defaultQualifier: usesMuralModel ? harnessQualifier : taskQualifier ?? harnessQualifier,
|
|
512
|
+
harness: args.harness
|
|
513
|
+
}),
|
|
514
|
+
fallbacks: resolveFallbackEntries(fallbackSource, args.harness),
|
|
515
|
+
schedule: readString(schedulingTask?.schedule),
|
|
516
|
+
timeoutMinutes: typeof taskBlock?.timeout_minutes === "number" ? taskBlock.timeout_minutes : undefined,
|
|
517
|
+
promotionThreshold: typeof schedulingTask?.promotion_threshold === "number" ? schedulingTask.promotion_threshold : undefined
|
|
518
|
+
};
|
|
463
519
|
}
|
|
464
520
|
|
|
465
521
|
// ../plugin/src/features/magic-context/dreamer/task-registry.ts
|
|
@@ -528,25 +584,23 @@ function compareTaskOrder(a, b) {
|
|
|
528
584
|
}
|
|
529
585
|
|
|
530
586
|
// ../plugin/src/features/magic-context/dreamer/task-config.ts
|
|
531
|
-
function buildDreamTaskRuntimeConfigs(dreamer, language) {
|
|
532
|
-
const tasks = dreamer.tasks ?? {};
|
|
587
|
+
function buildDreamTaskRuntimeConfigs(dreamer, harness, language, muralModel) {
|
|
533
588
|
return CANONICAL_DREAM_TASKS.map((task) => {
|
|
534
|
-
const
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
const thinkingLevel = t.thinking_level ?? dreamer.thinking_level;
|
|
589
|
+
const resolved = resolveDreamerTaskModel({
|
|
590
|
+
config: { dreamer },
|
|
591
|
+
harness,
|
|
592
|
+
task,
|
|
593
|
+
muralModel
|
|
594
|
+
});
|
|
541
595
|
return {
|
|
542
596
|
task,
|
|
543
|
-
schedule:
|
|
544
|
-
model,
|
|
545
|
-
fallbackModels,
|
|
546
|
-
thinkingLevel,
|
|
597
|
+
schedule: resolved.schedule ?? "",
|
|
598
|
+
model: resolved.primary,
|
|
599
|
+
fallbackModels: resolved.fallbacks,
|
|
600
|
+
thinkingLevel: harness === "pi" ? resolved.primary?.qualifier : undefined,
|
|
547
601
|
language,
|
|
548
|
-
timeoutMinutes:
|
|
549
|
-
promotionThreshold:
|
|
602
|
+
timeoutMinutes: resolved.timeoutMinutes ?? 20,
|
|
603
|
+
promotionThreshold: resolved.promotionThreshold
|
|
550
604
|
};
|
|
551
605
|
});
|
|
552
606
|
}
|
|
@@ -1951,6 +2005,59 @@ function shouldKeepSubagents() {
|
|
|
1951
2005
|
return keepSubagents;
|
|
1952
2006
|
}
|
|
1953
2007
|
|
|
2008
|
+
// ../plugin/src/shared/resolve-fallbacks.ts
|
|
2009
|
+
function resolveFallbackChain(userFallbacks) {
|
|
2010
|
+
const userList = normalizeUserFallbacks(userFallbacks);
|
|
2011
|
+
return dedupe(userList.filter(isValidModelSpec));
|
|
2012
|
+
}
|
|
2013
|
+
function normalizeUserFallbacks(userFallbacks) {
|
|
2014
|
+
if (!userFallbacks)
|
|
2015
|
+
return [];
|
|
2016
|
+
if (typeof userFallbacks === "string") {
|
|
2017
|
+
const trimmed = userFallbacks.trim();
|
|
2018
|
+
return trimmed ? [trimmed] : [];
|
|
2019
|
+
}
|
|
2020
|
+
return userFallbacks.map((s) => s.trim()).filter((s) => s.length > 0);
|
|
2021
|
+
}
|
|
2022
|
+
function isValidModelSpec(spec) {
|
|
2023
|
+
const slash = spec.indexOf("/");
|
|
2024
|
+
return slash > 0 && slash < spec.length - 1;
|
|
2025
|
+
}
|
|
2026
|
+
function dedupe(list) {
|
|
2027
|
+
const seen = new Set;
|
|
2028
|
+
const out = [];
|
|
2029
|
+
for (const item of list) {
|
|
2030
|
+
if (seen.has(item))
|
|
2031
|
+
continue;
|
|
2032
|
+
seen.add(item);
|
|
2033
|
+
out.push(item);
|
|
2034
|
+
}
|
|
2035
|
+
return out;
|
|
2036
|
+
}
|
|
2037
|
+
function parseProviderModel(spec) {
|
|
2038
|
+
const slash = spec.indexOf("/");
|
|
2039
|
+
if (slash < 1 || slash >= spec.length - 1)
|
|
2040
|
+
return null;
|
|
2041
|
+
return {
|
|
2042
|
+
providerID: spec.slice(0, slash).trim(),
|
|
2043
|
+
modelID: spec.slice(slash + 1).trim()
|
|
2044
|
+
};
|
|
2045
|
+
}
|
|
2046
|
+
function modelBodyField(spec) {
|
|
2047
|
+
const entry = toModelEntry(spec);
|
|
2048
|
+
if (!entry)
|
|
2049
|
+
return {};
|
|
2050
|
+
const parsed = parseProviderModel(entry.model);
|
|
2051
|
+
return parsed ? { model: parsed, ...entry.qualifier ? { variant: entry.qualifier } : {} } : {};
|
|
2052
|
+
}
|
|
2053
|
+
function toModelEntry(spec) {
|
|
2054
|
+
if (typeof spec === "string") {
|
|
2055
|
+
const model = spec.trim();
|
|
2056
|
+
return model ? { model } : undefined;
|
|
2057
|
+
}
|
|
2058
|
+
return spec;
|
|
2059
|
+
}
|
|
2060
|
+
|
|
1954
2061
|
// src/clone-inheritance.ts
|
|
1955
2062
|
import { readFile } from "node:fs/promises";
|
|
1956
2063
|
var CONTENT_ID_SUFFIX = /:(?:p|file)\d+$/;
|
|
@@ -2530,14 +2637,35 @@ class PiSubagentRunner {
|
|
|
2530
2637
|
return { result: isolatedResult, extensionRetryUsed: true };
|
|
2531
2638
|
}
|
|
2532
2639
|
async runModelChain(options, runMode, primaryModelRef) {
|
|
2533
|
-
const
|
|
2534
|
-
const
|
|
2640
|
+
const attempts = [];
|
|
2641
|
+
const seenAttempts = new Set;
|
|
2642
|
+
const appendAttempt = (candidate) => {
|
|
2643
|
+
if (!candidate.model)
|
|
2644
|
+
return;
|
|
2645
|
+
const key = `${candidate.model}\x00${candidate.qualifier ?? ""}`;
|
|
2646
|
+
if (seenAttempts.has(key))
|
|
2647
|
+
return;
|
|
2648
|
+
seenAttempts.add(key);
|
|
2649
|
+
attempts.push(candidate);
|
|
2650
|
+
};
|
|
2651
|
+
if (options.model) {
|
|
2652
|
+
appendAttempt({
|
|
2653
|
+
model: options.model,
|
|
2654
|
+
...options.thinkingLevel ? { qualifier: options.thinkingLevel } : {}
|
|
2655
|
+
});
|
|
2656
|
+
}
|
|
2657
|
+
for (const candidate of options.fallbackModels ?? []) {
|
|
2658
|
+
appendAttempt(typeof candidate === "string" ? { model: candidate } : candidate);
|
|
2659
|
+
}
|
|
2660
|
+
if (attempts.length === 0)
|
|
2661
|
+
attempts.push(undefined);
|
|
2535
2662
|
let lastResult = null;
|
|
2536
2663
|
for (let index = 0;index < attempts.length; index += 1) {
|
|
2537
|
-
const
|
|
2664
|
+
const attempt = attempts[index];
|
|
2538
2665
|
const attemptOptions = {
|
|
2539
2666
|
...options,
|
|
2540
|
-
model,
|
|
2667
|
+
model: attempt?.model,
|
|
2668
|
+
thinkingLevel: attempt?.qualifier,
|
|
2541
2669
|
fallbackModels: undefined
|
|
2542
2670
|
};
|
|
2543
2671
|
const result = await this.runOnce(attemptOptions, runMode, index === 0 ? primaryModelRef : undefined);
|
|
@@ -4091,15 +4219,18 @@ async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
|
|
|
4091
4219
|
log(`[${callContext}] primary (${explicitPrimaryLabel}) failed: ${shortErr(error)}; trying ${fallbacks.length} fallback(s)`);
|
|
4092
4220
|
}
|
|
4093
4221
|
for (let i = 0;i < fallbacks.length; i += 1) {
|
|
4094
|
-
const
|
|
4222
|
+
const fallback = toModelEntry(fallbacks[i]);
|
|
4223
|
+
const parsed = fallback ? parseProviderModel(fallback.model) : null;
|
|
4095
4224
|
if (!parsed) {
|
|
4096
|
-
log(`[${callContext}] skipping invalid fallback spec: ${fallbacks[i]}`);
|
|
4225
|
+
log(`[${callContext}] skipping invalid fallback spec: ${String(fallbacks[i])}`);
|
|
4097
4226
|
continue;
|
|
4098
4227
|
}
|
|
4099
4228
|
const label = `${parsed.providerID}/${parsed.modelID}`;
|
|
4229
|
+
const { variant: _primaryVariant, ...bodyWithoutPrimaryVariant } = baseBody;
|
|
4100
4230
|
const attemptArgs = copyPromptArgs(baseArgs, {
|
|
4101
|
-
...
|
|
4102
|
-
model: parsed
|
|
4231
|
+
...bodyWithoutPrimaryVariant,
|
|
4232
|
+
model: parsed,
|
|
4233
|
+
...fallback?.qualifier ? { variant: fallback.qualifier } : {}
|
|
4103
4234
|
});
|
|
4104
4235
|
try {
|
|
4105
4236
|
await attemptOnce(client, attemptArgs, timeoutMs, options.signal, callContext, label);
|
|
@@ -4115,7 +4246,7 @@ async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
|
|
|
4115
4246
|
}
|
|
4116
4247
|
}
|
|
4117
4248
|
}
|
|
4118
|
-
log(`[${callContext}] all models exhausted; tried: ${[explicitPrimaryLabel, ...fallbacks].join(", ")}; last error: ${shortErr(lastError)}`);
|
|
4249
|
+
log(`[${callContext}] all models exhausted; tried: ${[explicitPrimaryLabel, ...fallbacks.map((fallback) => toModelEntry(fallback)?.model ?? String(fallback))].join(", ")}; last error: ${shortErr(lastError)}`);
|
|
4119
4250
|
throw lastError ?? new Error("All fallback models failed");
|
|
4120
4251
|
}
|
|
4121
4252
|
async function attemptAndValidate(client, args, timeoutMs, signal, callContext, attempt, options) {
|
|
@@ -4153,15 +4284,18 @@ async function promptSyncWithValidatedOutputRetry(client, args, options) {
|
|
|
4153
4284
|
log(`[${callContext}] primary (${explicitPrimaryLabel}) failed validation/prompt: ${shortErr(error)}; trying ${fallbacks.length} fallback(s)`);
|
|
4154
4285
|
}
|
|
4155
4286
|
for (let i = 0;i < fallbacks.length; i += 1) {
|
|
4156
|
-
const
|
|
4287
|
+
const fallback = toModelEntry(fallbacks[i]);
|
|
4288
|
+
const parsed = fallback ? parseProviderModel(fallback.model) : null;
|
|
4157
4289
|
if (!parsed) {
|
|
4158
|
-
log(`[${callContext}] skipping invalid fallback spec: ${fallbacks[i]}`);
|
|
4290
|
+
log(`[${callContext}] skipping invalid fallback spec: ${String(fallbacks[i])}`);
|
|
4159
4291
|
continue;
|
|
4160
4292
|
}
|
|
4161
4293
|
const label = `${parsed.providerID}/${parsed.modelID}`;
|
|
4294
|
+
const { variant: _primaryVariant, ...bodyWithoutPrimaryVariant } = baseBody;
|
|
4162
4295
|
const attemptArgs = copyPromptArgs(baseArgs, {
|
|
4163
|
-
...
|
|
4164
|
-
model: parsed
|
|
4296
|
+
...bodyWithoutPrimaryVariant,
|
|
4297
|
+
model: parsed,
|
|
4298
|
+
...fallback?.qualifier ? { variant: fallback.qualifier } : {}
|
|
4165
4299
|
});
|
|
4166
4300
|
const attempt = {
|
|
4167
4301
|
label,
|
|
@@ -4186,7 +4320,7 @@ async function promptSyncWithValidatedOutputRetry(client, args, options) {
|
|
|
4186
4320
|
}
|
|
4187
4321
|
}
|
|
4188
4322
|
}
|
|
4189
|
-
log(`[${callContext}] all models exhausted; tried: ${[explicitPrimaryLabel, ...fallbacks].join(", ")}; original error: ${shortErr(firstError)}; last error: ${shortErr(lastError)}`);
|
|
4323
|
+
log(`[${callContext}] all models exhausted; tried: ${[explicitPrimaryLabel, ...fallbacks.map((fallback) => toModelEntry(fallback)?.model ?? String(fallback))].join(", ")}; original error: ${shortErr(firstError)}; last error: ${shortErr(lastError)}`);
|
|
4190
4324
|
throw firstError ?? lastError ?? new Error("All fallback models failed validation");
|
|
4191
4325
|
}
|
|
4192
4326
|
// ../plugin/src/shared/normalize-sdk-response.ts
|
|
@@ -6889,15 +7023,60 @@ function getAsyncModule() {
|
|
|
6889
7023
|
})();
|
|
6890
7024
|
return asyncModulePromise;
|
|
6891
7025
|
}
|
|
7026
|
+
function acquireSandboxModule(signal) {
|
|
7027
|
+
const modulePromise = getAsyncModule();
|
|
7028
|
+
if (!signal)
|
|
7029
|
+
return modulePromise;
|
|
7030
|
+
if (signal.aborted) {
|
|
7031
|
+
return Promise.reject(signal.reason ?? new Error("smart-note check aborted"));
|
|
7032
|
+
}
|
|
7033
|
+
return new Promise((resolve, reject) => {
|
|
7034
|
+
const cleanup = () => signal.removeEventListener("abort", onAbort);
|
|
7035
|
+
const onAbort = () => {
|
|
7036
|
+
cleanup();
|
|
7037
|
+
reject(signal.reason ?? new Error("smart-note check aborted"));
|
|
7038
|
+
};
|
|
7039
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
7040
|
+
modulePromise.then((module) => {
|
|
7041
|
+
cleanup();
|
|
7042
|
+
resolve(module);
|
|
7043
|
+
}, (error) => {
|
|
7044
|
+
cleanup();
|
|
7045
|
+
reject(error);
|
|
7046
|
+
});
|
|
7047
|
+
});
|
|
7048
|
+
}
|
|
6892
7049
|
var sandboxRunChain = Promise.resolve();
|
|
6893
|
-
function withSandboxLock(fn) {
|
|
6894
|
-
const
|
|
7050
|
+
function withSandboxLock(fn, signal, cancelled) {
|
|
7051
|
+
const start = () => signal?.aborted && cancelled ? cancelled() : fn();
|
|
7052
|
+
const run = sandboxRunChain.then(start, start);
|
|
6895
7053
|
sandboxRunChain = run.then(() => {
|
|
6896
7054
|
return;
|
|
6897
7055
|
}, () => {
|
|
6898
7056
|
return;
|
|
6899
7057
|
});
|
|
6900
|
-
return run;
|
|
7058
|
+
return resolveBeforeAbort(run, signal, cancelled);
|
|
7059
|
+
}
|
|
7060
|
+
function resolveBeforeAbort(run, signal, cancelled) {
|
|
7061
|
+
if (!signal || !cancelled)
|
|
7062
|
+
return run;
|
|
7063
|
+
if (signal.aborted)
|
|
7064
|
+
return Promise.resolve(cancelled());
|
|
7065
|
+
return new Promise((resolve, reject) => {
|
|
7066
|
+
const cleanup = () => signal.removeEventListener("abort", abort);
|
|
7067
|
+
const abort = () => {
|
|
7068
|
+
cleanup();
|
|
7069
|
+
resolve(cancelled());
|
|
7070
|
+
};
|
|
7071
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
7072
|
+
run.then((result) => {
|
|
7073
|
+
cleanup();
|
|
7074
|
+
resolve(result);
|
|
7075
|
+
}, (error) => {
|
|
7076
|
+
cleanup();
|
|
7077
|
+
reject(error);
|
|
7078
|
+
});
|
|
7079
|
+
});
|
|
6901
7080
|
}
|
|
6902
7081
|
var DEFAULT_TIMEOUT_MS = 2000;
|
|
6903
7082
|
var DEFAULT_HEAP_LIMIT_BYTES = 8 * 1024 * 1024;
|
|
@@ -6924,9 +7103,17 @@ async function runCompiledSmartNoteCheck(options) {
|
|
|
6924
7103
|
if (Buffer.byteLength(options.compiledCheck, "utf8") > MAX_COMPILED_CHECK_BYTES) {
|
|
6925
7104
|
return failureResult("compiled check exceeds 64 KiB", false);
|
|
6926
7105
|
}
|
|
6927
|
-
|
|
7106
|
+
let quickjs;
|
|
7107
|
+
try {
|
|
7108
|
+
quickjs = await acquireSandboxModule(options.signal);
|
|
7109
|
+
} catch (error) {
|
|
7110
|
+
if (options.signal?.aborted)
|
|
7111
|
+
return cancelledResult(options.signal.reason);
|
|
7112
|
+
return failureResult(formatSandboxError(error), false);
|
|
7113
|
+
}
|
|
7114
|
+
return withSandboxLock(() => runCompiledSmartNoteCheckLocked(options, quickjs), options.signal, () => cancelledResult(options.signal?.reason));
|
|
6928
7115
|
}
|
|
6929
|
-
async function runCompiledSmartNoteCheckLocked(options) {
|
|
7116
|
+
async function runCompiledSmartNoteCheckLocked(options, quickjs) {
|
|
6930
7117
|
if (options.signal?.aborted)
|
|
6931
7118
|
return cancelledResult(options.signal.reason);
|
|
6932
7119
|
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
@@ -6946,8 +7133,6 @@ async function runCompiledSmartNoteCheckLocked(options) {
|
|
|
6946
7133
|
throwIfRunAborted(controller.signal);
|
|
6947
7134
|
const capabilities = resolveCapabilitiesForRun(options, controller.signal);
|
|
6948
7135
|
const deadline = Date.now() + timeoutMs;
|
|
6949
|
-
const quickjs = await getAsyncModule();
|
|
6950
|
-
throwIfRunAborted(controller.signal);
|
|
6951
7136
|
const context = quickjs.newContext();
|
|
6952
7137
|
try {
|
|
6953
7138
|
context.runtime.setMemoryLimit(options.heapLimitBytes ?? DEFAULT_HEAP_LIMIT_BYTES);
|
|
@@ -7552,7 +7737,7 @@ async function evaluateSmartNotes(args) {
|
|
|
7552
7737
|
projectIdentity: args.projectIdentity,
|
|
7553
7738
|
projectRoot,
|
|
7554
7739
|
maxChecks: 10,
|
|
7555
|
-
sweepBudgetMs: 1e4,
|
|
7740
|
+
sweepBudgetMs: args.sweepBudgetMs ?? 1e4,
|
|
7556
7741
|
leaseHeld,
|
|
7557
7742
|
signal: leaseAbortController.signal,
|
|
7558
7743
|
retinaHandoff: args.retinaHandoff
|
|
@@ -8077,19 +8262,26 @@ function parseMapMemoriesManifest(text) {
|
|
|
8077
8262
|
if (out.length === 0 && body.trim().length > 0) {
|
|
8078
8263
|
throw new Error(describeUnrecognizedManifestShape(text, "mappings", "memory"));
|
|
8079
8264
|
}
|
|
8080
|
-
assertNoDuplicateManifestIds(out.map((entry) => entry.id), "mappings");
|
|
8081
8265
|
return out;
|
|
8082
8266
|
}
|
|
8083
8267
|
function validateMapMemoriesManifest(text, expectedIds) {
|
|
8084
8268
|
const parsed = parseMapMemoriesManifest(text);
|
|
8085
8269
|
assertParsedManifestNonEmpty(parsed.length, expectedIds.size, text, "mappings", "memory");
|
|
8086
|
-
|
|
8270
|
+
assertNoDuplicateManifestIds(parsed.filter((entry) => expectedIds.has(entry.id)).map((entry) => entry.id), "mappings");
|
|
8087
8271
|
return parsed;
|
|
8088
8272
|
}
|
|
8089
8273
|
|
|
8090
8274
|
// ../plugin/src/features/magic-context/dreamer/map-memories.ts
|
|
8091
8275
|
var MAP_BATCH_SIZE = 80;
|
|
8276
|
+
var MAP_BATCH_FLOOR_MS = 240000;
|
|
8277
|
+
var CONSECUTIVE_TIMEOUT_LIMIT2 = 2;
|
|
8092
8278
|
var MAX_INDEPENDENT_REQUEUE_PER_RUN = MAP_BATCH_SIZE;
|
|
8279
|
+
function computeMapBatchSliceMs(remainingMs, batchesRemaining) {
|
|
8280
|
+
return Math.min(remainingMs, Math.max(MAP_BATCH_FLOOR_MS, Math.floor(remainingMs / batchesRemaining)));
|
|
8281
|
+
}
|
|
8282
|
+
function isTimeoutClassError2(error) {
|
|
8283
|
+
return error instanceof Error && /^prompt timed out after \d+ms$/.test(error.message);
|
|
8284
|
+
}
|
|
8093
8285
|
function shouldRequeueIndependentMapping(state2, content, repoDir) {
|
|
8094
8286
|
if (!state2.hasSentinel || state2.files.length > 0)
|
|
8095
8287
|
return false;
|
|
@@ -8137,27 +8329,64 @@ async function mapMemories(args) {
|
|
|
8137
8329
|
return result;
|
|
8138
8330
|
const batches = [];
|
|
8139
8331
|
for (let i = 0;i < inputs.length; i += MAP_BATCH_SIZE) {
|
|
8140
|
-
batches.push(inputs.slice(i, i + MAP_BATCH_SIZE));
|
|
8332
|
+
batches.push({ inputs: inputs.slice(i, i + MAP_BATCH_SIZE), isOmissionRetry: false });
|
|
8141
8333
|
}
|
|
8142
8334
|
result.remaining = inputs.length;
|
|
8143
8335
|
const abortController = new AbortController;
|
|
8144
8336
|
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort(), args.leaseAcquisition);
|
|
8145
8337
|
try {
|
|
8338
|
+
let consecutiveTimeouts = 0;
|
|
8339
|
+
let timeoutStreakElapsedMs = [];
|
|
8146
8340
|
for (let i = 0;i < batches.length; i += 1) {
|
|
8147
8341
|
const remainingMs = Math.max(0, args.deadline - Date.now());
|
|
8148
|
-
if (remainingMs <= 0)
|
|
8342
|
+
if (remainingMs <= 0) {
|
|
8343
|
+
result.stopReason = "deadline";
|
|
8149
8344
|
break;
|
|
8150
|
-
|
|
8151
|
-
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
|
|
8345
|
+
}
|
|
8346
|
+
if (remainingMs < MAP_BATCH_FLOOR_MS) {
|
|
8347
|
+
result.stopReason = "deadline";
|
|
8348
|
+
log(`[dreamer] map-memories: stopping before batch ${i + 1}/${batches.length} — remaining budget ${remainingMs}ms is below the ${MAP_BATCH_FLOOR_MS}ms batch floor; banking ${result.mapped + result.independent} mapping(s)`);
|
|
8349
|
+
break;
|
|
8350
|
+
}
|
|
8351
|
+
const sliceMs = computeMapBatchSliceMs(remainingMs, batches.length - i);
|
|
8352
|
+
const batch = batches[i];
|
|
8353
|
+
if (!batch)
|
|
8354
|
+
break;
|
|
8355
|
+
const outcome = await mapOneBatch(args, batch.inputs, sliceMs, abortController.signal);
|
|
8356
|
+
const committed = outcome.mapped + outcome.independent;
|
|
8357
|
+
result.mapped += outcome.mapped;
|
|
8358
|
+
result.independent += outcome.independent;
|
|
8359
|
+
result.remaining -= committed;
|
|
8360
|
+
if (committed > 0) {
|
|
8361
|
+
result.batches += 1;
|
|
8362
|
+
args.onProgress?.(result.mapped + result.independent);
|
|
8363
|
+
}
|
|
8364
|
+
if (outcome.requeue?.length) {
|
|
8365
|
+
if (!batch.isOmissionRetry) {
|
|
8366
|
+
batches.splice(i + 1, 0, {
|
|
8367
|
+
inputs: outcome.requeue,
|
|
8368
|
+
isOmissionRetry: true
|
|
8369
|
+
});
|
|
8370
|
+
log(`[dreamer] map-memories: committed ${committed}/${batch.inputs.length} mapping(s); requeueing ${outcome.requeue.length} omitted id(s) in a targeted retry`);
|
|
8371
|
+
} else {
|
|
8372
|
+
log(`[dreamer] map-memories: targeted retry still omitted ${outcome.requeue.length} id(s); leaving them unmapped for the next run`);
|
|
8373
|
+
}
|
|
8374
|
+
}
|
|
8375
|
+
if (outcome.failure?.class === "timeout") {
|
|
8376
|
+
consecutiveTimeouts += 1;
|
|
8377
|
+
timeoutStreakElapsedMs.push(outcome.failure.elapsedMs);
|
|
8378
|
+
if (consecutiveTimeouts >= CONSECUTIVE_TIMEOUT_LIMIT2) {
|
|
8379
|
+
result.stopReason = "timeout-circuit-breaker";
|
|
8380
|
+
log(`[dreamer] map-memories starvation: circuit breaker tripped after ${consecutiveTimeouts} consecutive batch timeouts (model too slow for its time slice); per-batch elapsed [${timeoutStreakElapsedMs.join("ms, ")}ms] vs ${sliceMs}ms slice; stopping with ${result.remaining} mapping(s) remaining`);
|
|
8381
|
+
break;
|
|
8382
|
+
}
|
|
8383
|
+
} else {
|
|
8384
|
+
consecutiveTimeouts = 0;
|
|
8385
|
+
timeoutStreakElapsedMs = [];
|
|
8386
|
+
}
|
|
8158
8387
|
}
|
|
8159
8388
|
result.complete = result.remaining === 0;
|
|
8160
|
-
log(`[dreamer] map-memories: mapped=${result.mapped} independent=${result.independent} batches=${result.batches} remaining=${result.remaining} complete=${result.complete}`);
|
|
8389
|
+
log(`[dreamer] map-memories: committed=${result.mapped + result.independent} mapped=${result.mapped} independent=${result.independent} batches=${result.batches} remaining=${result.remaining} complete=${result.complete}${result.stopReason ? ` stop_reason=${result.stopReason}` : ""}`);
|
|
8161
8390
|
return result;
|
|
8162
8391
|
} finally {
|
|
8163
8392
|
heartbeat.stop();
|
|
@@ -8211,12 +8440,16 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
8211
8440
|
const text = extractLatestAssistantText(messages);
|
|
8212
8441
|
if (!text)
|
|
8213
8442
|
throw new Error("map-memories returned no output");
|
|
8214
|
-
validateMapMemoriesManifest(text, new Set(batch.map((memory) => memory.id)));
|
|
8215
|
-
return text;
|
|
8443
|
+
return validateMapMemoriesManifest(text, new Set(batch.map((memory) => memory.id)));
|
|
8216
8444
|
}
|
|
8217
8445
|
});
|
|
8218
8446
|
recordInvocation2(args, startedAt, { status: "completed", messages: run.output });
|
|
8219
|
-
|
|
8447
|
+
const outcome = await applyParsedBatchMappings(args, batch, run.validated);
|
|
8448
|
+
const returnedIds = new Set(run.validated.filter((entry) => batch.some((memory) => memory.id === entry.id)).map((entry) => entry.id));
|
|
8449
|
+
return {
|
|
8450
|
+
...outcome,
|
|
8451
|
+
requeue: batch.filter((memory) => !returnedIds.has(memory.id))
|
|
8452
|
+
};
|
|
8220
8453
|
} catch (error) {
|
|
8221
8454
|
const desc = describeError(error);
|
|
8222
8455
|
log(`[dreamer] map-memories batch failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
|
|
@@ -8225,7 +8458,14 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
8225
8458
|
throw error;
|
|
8226
8459
|
if (signal.aborted)
|
|
8227
8460
|
throw error;
|
|
8228
|
-
return {
|
|
8461
|
+
return {
|
|
8462
|
+
mapped: 0,
|
|
8463
|
+
independent: 0,
|
|
8464
|
+
failure: {
|
|
8465
|
+
class: isTimeoutClassError2(error) ? "timeout" : "other",
|
|
8466
|
+
elapsedMs: Date.now() - startedAt
|
|
8467
|
+
}
|
|
8468
|
+
};
|
|
8229
8469
|
} finally {
|
|
8230
8470
|
if (agentSessionId && !shouldKeepSubagents()) {
|
|
8231
8471
|
await args.client.session.delete({
|
|
@@ -8237,14 +8477,21 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
8237
8477
|
}
|
|
8238
8478
|
}
|
|
8239
8479
|
}
|
|
8240
|
-
async function
|
|
8241
|
-
const batchIds = new Set(batch.map((
|
|
8242
|
-
const
|
|
8243
|
-
|
|
8244
|
-
if (
|
|
8480
|
+
async function applyParsedBatchMappings(args, batch, parsed) {
|
|
8481
|
+
const batchIds = new Set(batch.map((memory) => memory.id));
|
|
8482
|
+
const valid = parsed.filter((entry) => batchIds.has(entry.id));
|
|
8483
|
+
const unknown = parsed.filter((entry) => !batchIds.has(entry.id));
|
|
8484
|
+
if (unknown.length > 0) {
|
|
8485
|
+
log(`[dreamer] map-memories warning: dropping ${unknown.length} unknown mapping entr${unknown.length === 1 ? "y" : "ies"} outside the current batch (${unknown.map((entry) => entry.id).join(", ")})`);
|
|
8486
|
+
}
|
|
8487
|
+
assertNoDuplicateManifestIds(valid.map((entry) => entry.id), "mappings");
|
|
8488
|
+
if (valid.length * 2 < batch.length) {
|
|
8489
|
+
throw new Error(`mappings manifest covers ${valid.length}/${batch.length} batch ids after filtering unknown entries; rejecting mostly-wrong manifest`);
|
|
8490
|
+
}
|
|
8491
|
+
if (valid.length === 0)
|
|
8245
8492
|
return { mapped: 0, independent: 0 };
|
|
8246
8493
|
const planned = [];
|
|
8247
|
-
for (const p of
|
|
8494
|
+
for (const p of valid) {
|
|
8248
8495
|
if (p.independent) {
|
|
8249
8496
|
planned.push({ id: p.id, files: [], independent: true });
|
|
8250
8497
|
continue;
|
|
@@ -9549,14 +9796,13 @@ function parseVerifyManifest(text) {
|
|
|
9549
9796
|
if (verifyIds(out).length === 0 && body.trim().length > 0) {
|
|
9550
9797
|
throw new Error(describeUnrecognizedManifestShape(text, "verify", "verified"));
|
|
9551
9798
|
}
|
|
9552
|
-
assertNoDuplicateManifestIds(verifyIds(out), "verify");
|
|
9553
9799
|
return out;
|
|
9554
9800
|
}
|
|
9555
9801
|
function validateVerifyManifest(text, expectedIds) {
|
|
9556
9802
|
const parsed = parseVerifyManifest(text);
|
|
9557
9803
|
const ids = verifyIds(parsed);
|
|
9558
9804
|
assertParsedManifestNonEmpty(ids.length, expectedIds.size, text, "verify", "verified");
|
|
9559
|
-
|
|
9805
|
+
assertNoDuplicateManifestIds(ids.filter((id) => expectedIds.has(id)), "verify");
|
|
9560
9806
|
return parsed;
|
|
9561
9807
|
}
|
|
9562
9808
|
|
|
@@ -9709,19 +9955,14 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
9709
9955
|
const text = extractLatestAssistantText(messages);
|
|
9710
9956
|
if (!text)
|
|
9711
9957
|
throw new Error("verify returned no output");
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
if (providerFailure)
|
|
9717
|
-
throw providerFailure;
|
|
9718
|
-
throw error;
|
|
9719
|
-
}
|
|
9720
|
-
return text;
|
|
9958
|
+
const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
|
|
9959
|
+
if (providerFailure)
|
|
9960
|
+
throw providerFailure;
|
|
9961
|
+
return validateVerifyManifest(text, new Set(batch.map((memory) => memory.id)));
|
|
9721
9962
|
}
|
|
9722
9963
|
});
|
|
9723
9964
|
recordInvocation4(args, startedAt, { status: "completed", messages: run.output });
|
|
9724
|
-
return await
|
|
9965
|
+
return await applyParsedVerifyManifest(args, batch, run.validated);
|
|
9725
9966
|
} catch (error) {
|
|
9726
9967
|
const desc = describeError(error);
|
|
9727
9968
|
const providerFailure = error instanceof DreamerProviderOutputFailureError ? error : undefined;
|
|
@@ -9741,17 +9982,31 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
9741
9982
|
}
|
|
9742
9983
|
}
|
|
9743
9984
|
}
|
|
9744
|
-
async function
|
|
9985
|
+
async function applyParsedVerifyManifest(args, batch, parsed) {
|
|
9745
9986
|
const batchIds = new Set(batch.map((m) => m.id));
|
|
9746
|
-
const
|
|
9747
|
-
|
|
9987
|
+
const valid = {
|
|
9988
|
+
verified: parsed.verified.filter((entry) => batchIds.has(entry.id)),
|
|
9989
|
+
updated: parsed.updated.filter((entry) => batchIds.has(entry.id)),
|
|
9990
|
+
archived: parsed.archived.filter((entry) => batchIds.has(entry.id))
|
|
9991
|
+
};
|
|
9992
|
+
const unknown = [...parsed.verified, ...parsed.updated, ...parsed.archived].filter((entry) => !batchIds.has(entry.id));
|
|
9993
|
+
if (unknown.length > 0) {
|
|
9994
|
+
log(`[dreamer] verify warning: dropping ${unknown.length} unknown verification entr${unknown.length === 1 ? "y" : "ies"} outside the current batch (${unknown.map((entry) => entry.id).join(", ")})`);
|
|
9995
|
+
}
|
|
9996
|
+
const validIds = [...valid.verified, ...valid.updated, ...valid.archived].map((entry) => entry.id);
|
|
9997
|
+
assertNoDuplicateManifestIds(validIds, "verify");
|
|
9998
|
+
if (validIds.length * 2 < batch.length) {
|
|
9999
|
+
throw new Error(`verify manifest covers ${validIds.length}/${batch.length} batch ids after filtering unknown entries; rejecting mostly-wrong manifest`);
|
|
10000
|
+
}
|
|
10001
|
+
if (validIds.length === 0)
|
|
10002
|
+
return { verified: 0, updated: 0, archived: 0 };
|
|
9748
10003
|
const now = Date.now();
|
|
9749
10004
|
const writes = [];
|
|
9750
|
-
for (const v of
|
|
10005
|
+
for (const v of valid.verified) {
|
|
9751
10006
|
const files = await normalizeFiles(args, v.files);
|
|
9752
10007
|
writes.push({ kind: "verify", id: v.id, files });
|
|
9753
10008
|
}
|
|
9754
|
-
for (const u of
|
|
10009
|
+
for (const u of valid.updated) {
|
|
9755
10010
|
const content = u.content.trim();
|
|
9756
10011
|
if (!content || content.length > 20000) {
|
|
9757
10012
|
const files2 = await normalizeFiles(args, u.files);
|
|
@@ -9767,7 +10022,7 @@ async function applyVerifyManifest(args, batch, manifestText) {
|
|
|
9767
10022
|
hash: computeNormalizedHash(content)
|
|
9768
10023
|
});
|
|
9769
10024
|
}
|
|
9770
|
-
for (const a of
|
|
10025
|
+
for (const a of valid.archived) {
|
|
9771
10026
|
writes.push({ kind: "archive", id: a.id, reason: a.reason });
|
|
9772
10027
|
}
|
|
9773
10028
|
if (writes.length === 0)
|
|
@@ -10074,7 +10329,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
10074
10329
|
leaseKey,
|
|
10075
10330
|
deadline,
|
|
10076
10331
|
leaseAcquisition,
|
|
10077
|
-
model: config.model
|
|
10332
|
+
model: config.model,
|
|
10078
10333
|
fallbackModels: config.fallbackModels,
|
|
10079
10334
|
moduleRoute,
|
|
10080
10335
|
onProgress: (processed) => reportProgress(processed)
|
|
@@ -10123,8 +10378,19 @@ function createDreamTaskExecutor(deps) {
|
|
|
10123
10378
|
moduleRoute,
|
|
10124
10379
|
onProgress: (processed) => reportProgress(processed)
|
|
10125
10380
|
});
|
|
10126
|
-
log(`[dreamer] map-memories: mapped=${result.mapped} independent=${result.independent} batches=${result.batches} remaining=${result.remaining}`);
|
|
10381
|
+
log(`[dreamer] map-memories: committed=${result.mapped + result.independent} mapped=${result.mapped} independent=${result.independent} batches=${result.batches} remaining=${result.remaining} complete=${result.complete}${result.stopReason ? ` stop_reason=${result.stopReason}` : ""}`);
|
|
10127
10382
|
if (!result.complete) {
|
|
10383
|
+
if (result.stopReason === "timeout-circuit-breaker") {
|
|
10384
|
+
const error2 = `map-memories starvation: timeout circuit breaker stopped the run with ${result.remaining} remain`;
|
|
10385
|
+
recordRun("failed", error2);
|
|
10386
|
+
return { status: "failed", transient: true, error: error2 };
|
|
10387
|
+
}
|
|
10388
|
+
const processed = result.mapped + result.independent;
|
|
10389
|
+
if (processed > 0) {
|
|
10390
|
+
const progress = `map-memories: committed ${processed} mapping(s) (mapped ${result.mapped}, independent ${result.independent}); ${result.remaining} remain`;
|
|
10391
|
+
recordRun("completed", null, { progress });
|
|
10392
|
+
return { status: "completed" };
|
|
10393
|
+
}
|
|
10128
10394
|
const error = incompleteMessage(result.remaining);
|
|
10129
10395
|
recordRun("failed", error);
|
|
10130
10396
|
return { status: "failed", transient: true, error };
|
|
@@ -11235,7 +11501,7 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
|
|
|
11235
11501
|
}
|
|
11236
11502
|
try {
|
|
11237
11503
|
await runCompiledSmartNoteSweep(reg, db);
|
|
11238
|
-
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreamerConfig, reg.language);
|
|
11504
|
+
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreamerConfig, "opencode", reg.language, reg.mural?.model);
|
|
11239
11505
|
const executor = createDreamTaskExecutor({
|
|
11240
11506
|
client: reg.client,
|
|
11241
11507
|
sessionDirectory: reg.directory,
|
|
@@ -11245,7 +11511,6 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
|
|
|
11245
11511
|
userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreamerConfig),
|
|
11246
11512
|
ensureProjectRegistered: reg.ensureRegistered,
|
|
11247
11513
|
language: reg.language,
|
|
11248
|
-
dreamerModel: dreamerConfig.model,
|
|
11249
11514
|
mural: reg.mural,
|
|
11250
11515
|
memoryInjectionBudgetTokens: reg.memoryInjectionBudgetTokens,
|
|
11251
11516
|
retinaHandoff: reg.retinaHandoff,
|
|
@@ -11631,11 +11896,13 @@ function registerPiDreamerProject(opts) {
|
|
|
11631
11896
|
startDreamScheduleTimerFn({
|
|
11632
11897
|
directory: opts.projectDir,
|
|
11633
11898
|
projectIdentity: opts.projectIdentity,
|
|
11899
|
+
harness: "pi",
|
|
11634
11900
|
client,
|
|
11635
11901
|
dreamerConfig: opts.config,
|
|
11636
11902
|
language: opts.language,
|
|
11637
11903
|
gitCommitIndexing: opts.gitCommitIndexing,
|
|
11638
11904
|
retinaHandoff: opts.retinaHandoff,
|
|
11905
|
+
mural: opts.mural,
|
|
11639
11906
|
ensureRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
11640
11907
|
retrospectiveRawProvider: () => new PiRetrospectiveRawProvider({ projectCwd: opts.projectDir }),
|
|
11641
11908
|
primerRawProviderFactory: createPiPrimerRawProviderFactory()
|
|
@@ -11649,7 +11916,7 @@ function registerPiDreamerProject(opts) {
|
|
|
11649
11916
|
const runManual = async (task) => runManualDream({
|
|
11650
11917
|
db: opts.db,
|
|
11651
11918
|
projectIdentity: opts.projectIdentity,
|
|
11652
|
-
tasks: buildDreamTaskRuntimeConfigs(opts.config, opts.language),
|
|
11919
|
+
tasks: buildDreamTaskRuntimeConfigs(opts.config, "pi", opts.language, opts.mural?.model),
|
|
11653
11920
|
executor: createDreamTaskExecutor({
|
|
11654
11921
|
client,
|
|
11655
11922
|
sessionDirectory: opts.projectDir,
|
|
@@ -11661,7 +11928,8 @@ function registerPiDreamerProject(opts) {
|
|
|
11661
11928
|
userMemoryCollectionEnabled: userMemoryCollectionEnabled(opts.config),
|
|
11662
11929
|
ensureProjectRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
11663
11930
|
language: opts.language,
|
|
11664
|
-
retinaHandoff: opts.retinaHandoff
|
|
11931
|
+
retinaHandoff: opts.retinaHandoff,
|
|
11932
|
+
mural: opts.mural
|
|
11665
11933
|
}),
|
|
11666
11934
|
task
|
|
11667
11935
|
});
|
|
@@ -11697,7 +11965,6 @@ async function awaitInFlightDreamers() {
|
|
|
11697
11965
|
}
|
|
11698
11966
|
function createPiDreamerClient(opts) {
|
|
11699
11967
|
const runner = piSubagentRunnerFactory();
|
|
11700
|
-
const model = opts.config.model;
|
|
11701
11968
|
const session = {
|
|
11702
11969
|
create: async (args) => {
|
|
11703
11970
|
const sessionId = `magic-context-pi-dream-${++sessionCounter}`;
|
|
@@ -11718,7 +11985,7 @@ function createPiDreamerClient(opts) {
|
|
|
11718
11985
|
}
|
|
11719
11986
|
const userMessage = extractUserMessage(args);
|
|
11720
11987
|
const systemPrompt = extractSystemPrompt(args);
|
|
11721
|
-
const perTaskModel = extractBodyModel(args)
|
|
11988
|
+
const perTaskModel = extractBodyModel(args);
|
|
11722
11989
|
const requestedAgent = extractBodyAgent(args) ?? "magic-context-dreamer";
|
|
11723
11990
|
const runPromise = runner.run({
|
|
11724
11991
|
agent: requestedAgent,
|
|
@@ -11729,7 +11996,7 @@ function createPiDreamerClient(opts) {
|
|
|
11729
11996
|
timeoutMs: 30 * 60 * 1000,
|
|
11730
11997
|
cwd: dreamSession.directory,
|
|
11731
11998
|
signal: args.signal ?? undefined,
|
|
11732
|
-
thinkingLevel:
|
|
11999
|
+
thinkingLevel: extractBodyVariant(args)
|
|
11733
12000
|
});
|
|
11734
12001
|
inFlightDreams.add(runPromise);
|
|
11735
12002
|
try {
|
|
@@ -11820,6 +12087,13 @@ function extractBodyModel(args) {
|
|
|
11820
12087
|
}
|
|
11821
12088
|
return;
|
|
11822
12089
|
}
|
|
12090
|
+
function extractBodyVariant(args) {
|
|
12091
|
+
const body = args.body;
|
|
12092
|
+
if (typeof body !== "object" || body === null)
|
|
12093
|
+
return;
|
|
12094
|
+
const variant = body.variant;
|
|
12095
|
+
return typeof variant === "string" && variant.length > 0 ? variant : undefined;
|
|
12096
|
+
}
|
|
11823
12097
|
function extractBodyAgent(args) {
|
|
11824
12098
|
const body = args.body;
|
|
11825
12099
|
if (typeof body !== "object" || body === null)
|
|
@@ -12961,12 +13235,15 @@ function writeTransformDecisionRowOnDatabase(db, row, configureBusyTimeout) {
|
|
|
12961
13235
|
const systemHashNew = row.materialized ? row.systemHashNew : null;
|
|
12962
13236
|
const m0ModelKeyPrev = row.materialized ? row.m0ModelKeyPrev : null;
|
|
12963
13237
|
const m0ModelKeyNew = row.materialized ? row.m0ModelKeyNew : null;
|
|
13238
|
+
const m0ToolSetHashPrev = row.m0ToolSetHashPrev ?? null;
|
|
13239
|
+
const m0ToolSetHashNew = row.m0ToolSetHashNew ?? null;
|
|
12964
13240
|
db.prepare(`INSERT OR REPLACE INTO transform_decisions (
|
|
12965
13241
|
session_id, harness, message_id, ts_ms, decision, materialized,
|
|
12966
13242
|
materialize_reason, system_hash_prev, system_hash_new,
|
|
13243
|
+
m0_tool_set_hash_prev, m0_tool_set_hash_new,
|
|
12967
13244
|
m0_model_key_prev, m0_model_key_new, emergency, dropped_tokens,
|
|
12968
13245
|
dropped_count, input_tokens
|
|
12969
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(row.sessionId, row.harness, row.messageId, row.tsMs, row.decision, row.materialized ? 1 : 0, row.materializeReason, systemHashPrev, systemHashNew, m0ModelKeyPrev, m0ModelKeyNew, row.emergency ? 1 : 0, Math.max(0, Math.floor(row.droppedTokens)), Math.max(0, Math.floor(row.droppedCount)), Math.max(0, Math.floor(row.inputTokens)));
|
|
13246
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(row.sessionId, row.harness, row.messageId, row.tsMs, row.decision, row.materialized ? 1 : 0, row.materializeReason, systemHashPrev, systemHashNew, m0ToolSetHashPrev, m0ToolSetHashNew, m0ModelKeyPrev, m0ModelKeyNew, row.emergency ? 1 : 0, Math.max(0, Math.floor(row.droppedTokens)), Math.max(0, Math.floor(row.droppedCount)), Math.max(0, Math.floor(row.inputTokens)));
|
|
12970
13247
|
db.prepare(`DELETE FROM transform_decisions
|
|
12971
13248
|
WHERE session_id = ? AND harness = ?
|
|
12972
13249
|
AND rowid NOT IN (
|
|
@@ -16022,6 +16299,17 @@ function isSyntheticMessage(message, index, input) {
|
|
|
16022
16299
|
const role = typeof message.role === "string" ? message.role : "";
|
|
16023
16300
|
return role === "system" || role === "custom" || role === "compactionSummary";
|
|
16024
16301
|
}
|
|
16302
|
+
function countRealPiUserMessages(input) {
|
|
16303
|
+
let count = 0;
|
|
16304
|
+
for (let index = 0;index < input.messages.length; index += 1) {
|
|
16305
|
+
const message = input.messages[index];
|
|
16306
|
+
if (!isRecord3(message) || message.role !== "user")
|
|
16307
|
+
continue;
|
|
16308
|
+
if (!isSyntheticMessage(message, index, input))
|
|
16309
|
+
count += 1;
|
|
16310
|
+
}
|
|
16311
|
+
return count;
|
|
16312
|
+
}
|
|
16025
16313
|
function imageContentAndTokens(part) {
|
|
16026
16314
|
const data = typeof part.data === "string" ? part.data : "";
|
|
16027
16315
|
const mimeType = typeof part.mimeType === "string" ? part.mimeType : "image/png";
|
|
@@ -16215,7 +16503,7 @@ function excludedDraft(key, value) {
|
|
|
16215
16503
|
tokens: 0
|
|
16216
16504
|
};
|
|
16217
16505
|
}
|
|
16218
|
-
function finalizeParts(drafts, protectedTags) {
|
|
16506
|
+
function finalizeParts(drafts, protectedTags, pendingDropTagNumbers) {
|
|
16219
16507
|
const visibleTags = new Map;
|
|
16220
16508
|
for (const part of drafts) {
|
|
16221
16509
|
if (part.kind !== "excluded" && part.tag)
|
|
@@ -16230,7 +16518,8 @@ function finalizeParts(drafts, protectedTags) {
|
|
|
16230
16518
|
const parts = drafts.map((draft) => {
|
|
16231
16519
|
const protectedPart = draft.tag ? protectedNumbers.has(draft.tag.tagNumber) : false;
|
|
16232
16520
|
const tokens = Math.max(0, draft.tokens);
|
|
16233
|
-
const
|
|
16521
|
+
const queuedForDrop = draft.tag ? pendingDropTagNumbers.has(draft.tag.tagNumber) : false;
|
|
16522
|
+
const uTokens = draft.tag && !protectedPart && !queuedForDrop && draft.kind !== "excluded" ? tokens : 0;
|
|
16234
16523
|
t += tokens;
|
|
16235
16524
|
u += uTokens;
|
|
16236
16525
|
return {
|
|
@@ -16241,7 +16530,8 @@ function finalizeParts(drafts, protectedTags) {
|
|
|
16241
16530
|
uTokens,
|
|
16242
16531
|
tagNumber: draft.tag?.tagNumber ?? null,
|
|
16243
16532
|
tagStatus: draft.tag ? "active" : null,
|
|
16244
|
-
protected: protectedPart
|
|
16533
|
+
protected: protectedPart,
|
|
16534
|
+
queuedForDrop
|
|
16245
16535
|
};
|
|
16246
16536
|
});
|
|
16247
16537
|
const clampedT = Math.max(0, t);
|
|
@@ -16383,29 +16673,34 @@ function measurePiTailHygiene(input) {
|
|
|
16383
16673
|
drafts.push(excludedDraft(`${key}\x00excluded`, part));
|
|
16384
16674
|
}
|
|
16385
16675
|
}
|
|
16386
|
-
return finalizeParts(drafts, input.protectedTags);
|
|
16676
|
+
return finalizeParts(drafts, input.protectedTags, input.pendingDropTagNumbers ?? new Set);
|
|
16387
16677
|
}
|
|
16388
16678
|
function sameMeasuredPrefix(baseline, current) {
|
|
16389
16679
|
if (current.length < baseline.length)
|
|
16390
|
-
return { valid: false, boundaryAdvanceU: 0 };
|
|
16680
|
+
return { valid: false, boundaryAdvanceU: 0, queuedDropDeltaU: 0 };
|
|
16391
16681
|
let boundaryAdvanceU = 0;
|
|
16682
|
+
let queuedDropDeltaU = 0;
|
|
16392
16683
|
for (let index = 0;index < baseline.length; index += 1) {
|
|
16393
16684
|
const before = baseline[index];
|
|
16394
16685
|
const after = current[index];
|
|
16395
16686
|
if (before.key !== after.key || before.contentHash !== after.contentHash || before.kind !== after.kind || before.tokens !== after.tokens || before.tagNumber !== after.tagNumber || before.tagStatus !== after.tagStatus) {
|
|
16396
|
-
return { valid: false, boundaryAdvanceU: 0 };
|
|
16687
|
+
return { valid: false, boundaryAdvanceU: 0, queuedDropDeltaU: 0 };
|
|
16397
16688
|
}
|
|
16398
16689
|
if (!before.protected && after.protected)
|
|
16399
|
-
return { valid: false, boundaryAdvanceU: 0 };
|
|
16690
|
+
return { valid: false, boundaryAdvanceU: 0, queuedDropDeltaU: 0 };
|
|
16400
16691
|
if (before.protected && !after.protected) {
|
|
16401
16692
|
if (after.tagStatus !== "active")
|
|
16402
|
-
return { valid: false, boundaryAdvanceU: 0 };
|
|
16403
|
-
boundaryAdvanceU += after.
|
|
16693
|
+
return { valid: false, boundaryAdvanceU: 0, queuedDropDeltaU: 0 };
|
|
16694
|
+
boundaryAdvanceU += after.uTokens;
|
|
16695
|
+
} else if (before.queuedForDrop !== after.queuedForDrop) {
|
|
16696
|
+
if (before.tagStatus !== "active" || after.tagStatus !== "active")
|
|
16697
|
+
return { valid: false, boundaryAdvanceU: 0, queuedDropDeltaU: 0 };
|
|
16698
|
+
queuedDropDeltaU += after.uTokens - before.uTokens;
|
|
16404
16699
|
} else if (before.uTokens !== after.uTokens) {
|
|
16405
|
-
return { valid: false, boundaryAdvanceU: 0 };
|
|
16700
|
+
return { valid: false, boundaryAdvanceU: 0, queuedDropDeltaU: 0 };
|
|
16406
16701
|
}
|
|
16407
16702
|
}
|
|
16408
|
-
return { valid: true, boundaryAdvanceU };
|
|
16703
|
+
return { valid: true, boundaryAdvanceU, queuedDropDeltaU };
|
|
16409
16704
|
}
|
|
16410
16705
|
function refreshPiTailHygieneBaseline(input) {
|
|
16411
16706
|
const measured = measurePiTailHygiene(input);
|
|
@@ -16437,7 +16732,7 @@ function refreshPiTailHygieneBaseline(input) {
|
|
|
16437
16732
|
};
|
|
16438
16733
|
}
|
|
16439
16734
|
let turnDeltaT = 0;
|
|
16440
|
-
let turnDeltaU = prefix.boundaryAdvanceU;
|
|
16735
|
+
let turnDeltaU = prefix.boundaryAdvanceU + prefix.queuedDropDeltaU;
|
|
16441
16736
|
for (let index = input.previous.baselineParts.length;index < measured.parts.length; index += 1) {
|
|
16442
16737
|
const part = measured.parts[index];
|
|
16443
16738
|
turnDeltaT += part.tokens;
|
|
@@ -16531,20 +16826,38 @@ function maybeChannel1ReminderForToolResult(args) {
|
|
|
16531
16826
|
if (deltaTokens === 0)
|
|
16532
16827
|
return null;
|
|
16533
16828
|
state2.turnDeltaT += deltaTokens;
|
|
16829
|
+
if (state2.agentDropsAppliedThisPass)
|
|
16830
|
+
return null;
|
|
16831
|
+
const nudgeState = getChannel1NudgeState(db, sessionId);
|
|
16534
16832
|
const decision = decideChannel1({
|
|
16535
16833
|
...state2,
|
|
16536
16834
|
lastNudgeUndropped: getLastNudgeUndropped(db, sessionId),
|
|
16537
|
-
lastNudgeLevel:
|
|
16835
|
+
lastNudgeLevel: nudgeState.level,
|
|
16538
16836
|
hasRecentReduce: state2.reducedSinceRefresh
|
|
16539
16837
|
});
|
|
16540
16838
|
setLastNudgeUndropped(db, sessionId, decision.nextLastNudge);
|
|
16541
|
-
|
|
16542
|
-
|
|
16839
|
+
if (!decision.fire) {
|
|
16840
|
+
setChannel1NudgeState(db, sessionId, {
|
|
16841
|
+
level: decision.nextLastNudgeLevel,
|
|
16842
|
+
ordinal: decision.nextLastNudgeLevel === "" ? 0 : nudgeState.ordinal
|
|
16843
|
+
});
|
|
16543
16844
|
return null;
|
|
16544
|
-
|
|
16845
|
+
}
|
|
16846
|
+
const sticky = shouldUseStickyChannel1Reminder({
|
|
16847
|
+
lastLevel: nudgeState.level,
|
|
16848
|
+
lastOrdinal: nudgeState.ordinal,
|
|
16849
|
+
level: decision.level,
|
|
16850
|
+
currentRealUserTurnCount: state2.realUserTurnCount
|
|
16851
|
+
});
|
|
16852
|
+
const block = {
|
|
16545
16853
|
type: "text",
|
|
16546
|
-
text: buildChannel1Reminder(decision.level, decision.undroppedTokens, state2.oldestReclaimableToolTags)
|
|
16854
|
+
text: buildChannel1Reminder(decision.level, decision.undroppedTokens, state2.usableWindow, state2.oldestReclaimableToolTags, sticky)
|
|
16547
16855
|
};
|
|
16856
|
+
setChannel1NudgeState(db, sessionId, {
|
|
16857
|
+
level: decision.level,
|
|
16858
|
+
ordinal: state2.realUserTurnCount
|
|
16859
|
+
});
|
|
16860
|
+
return block;
|
|
16548
16861
|
}
|
|
16549
16862
|
var CHANNEL2_NUDGE_CUSTOM_TYPE = "magic-context:ceiling-nudge";
|
|
16550
16863
|
function maybeDeliverChannel2Pi(pi, db, sessionId) {
|
|
@@ -16575,7 +16888,7 @@ function maybeDeliverChannel2Pi(pi, db, sessionId) {
|
|
|
16575
16888
|
try {
|
|
16576
16889
|
const message = {
|
|
16577
16890
|
customType: CHANNEL2_NUDGE_CUSTOM_TYPE,
|
|
16578
|
-
content: buildChannel2Reminder(undropped, baseline.oldestReclaimableToolTags),
|
|
16891
|
+
content: buildChannel2Reminder(undropped, baseline.usableWindow, baseline.oldestReclaimableToolTags),
|
|
16579
16892
|
display: false,
|
|
16580
16893
|
details: { kind: "channel-2-ceiling-nudge" }
|
|
16581
16894
|
};
|
|
@@ -21017,19 +21330,24 @@ async function runHistorianSubagentWithTransientRetries(args) {
|
|
|
21017
21330
|
}
|
|
21018
21331
|
return historianAbortResult(startedAt);
|
|
21019
21332
|
}
|
|
21020
|
-
function buildHistorianFallbackChain(primaryModel, fallbackModels, fallbackModelId) {
|
|
21021
|
-
const seen = new Set
|
|
21022
|
-
|
|
21023
|
-
|
|
21333
|
+
function buildHistorianFallbackChain(primaryModel, primaryThinkingLevel, fallbackModels, fallbackModelId) {
|
|
21334
|
+
const seen = new Set([
|
|
21335
|
+
`${primaryModel}\x00${primaryThinkingLevel ?? ""}`
|
|
21336
|
+
]);
|
|
21024
21337
|
const chain = [];
|
|
21025
21338
|
for (const candidate of fallbackModels ?? []) {
|
|
21026
|
-
|
|
21339
|
+
const entry = typeof candidate === "string" ? { model: candidate } : candidate;
|
|
21340
|
+
const key = `${entry.model}\x00${entry.qualifier ?? ""}`;
|
|
21341
|
+
if (!entry.model || seen.has(key))
|
|
21027
21342
|
continue;
|
|
21028
|
-
seen.add(
|
|
21029
|
-
chain.push({
|
|
21343
|
+
seen.add(key);
|
|
21344
|
+
chain.push({ entry, kind: "configured" });
|
|
21030
21345
|
}
|
|
21031
|
-
if (fallbackModelId
|
|
21032
|
-
|
|
21346
|
+
if (fallbackModelId) {
|
|
21347
|
+
const entry = { model: fallbackModelId };
|
|
21348
|
+
const key = `${entry.model}\x00`;
|
|
21349
|
+
if (!seen.has(key))
|
|
21350
|
+
chain.push({ entry, kind: "session" });
|
|
21033
21351
|
}
|
|
21034
21352
|
return chain;
|
|
21035
21353
|
}
|
|
@@ -21348,11 +21666,11 @@ ${chunkText}`,
|
|
|
21348
21666
|
validatedDraftText = repairResult.assistantText;
|
|
21349
21667
|
}
|
|
21350
21668
|
}
|
|
21351
|
-
const fallbackChain = buildHistorianFallbackChain(historianModel, fallbackModels, fallbackModelId);
|
|
21669
|
+
const fallbackChain = buildHistorianFallbackChain(historianModel, thinkingLevel, fallbackModels, fallbackModelId);
|
|
21352
21670
|
if (validatedPass.kind !== "ok" && !(validatedPass.kind === "spawn-failed" && validatedPass.reason === "abort") && fallbackChain.length > 0) {
|
|
21353
21671
|
for (let i = 0;i < fallbackChain.length; i += 1) {
|
|
21354
21672
|
const candidate = fallbackChain[i];
|
|
21355
|
-
sessionLog(sessionId, `historian: escalating to ${candidate.kind === "session" ? "session-model last resort" : "configured fallback model"} ${candidate.
|
|
21673
|
+
sessionLog(sessionId, `historian: escalating to ${candidate.kind === "session" ? "session-model last resort" : "configured fallback model"} ${candidate.entry.model}`);
|
|
21356
21674
|
const fbResult = await runHistorianSubagentWithTransientRetries({
|
|
21357
21675
|
runner,
|
|
21358
21676
|
sessionId,
|
|
@@ -21362,11 +21680,11 @@ ${chunkText}`,
|
|
|
21362
21680
|
agent: HISTORIAN_AGENT_NAME,
|
|
21363
21681
|
systemPrompt: historianSystemPrompt,
|
|
21364
21682
|
userMessage: prompt,
|
|
21365
|
-
model: candidate.
|
|
21683
|
+
model: candidate.entry.model,
|
|
21366
21684
|
timeoutMs: historianTimeoutMs,
|
|
21367
21685
|
cwd: directory,
|
|
21368
21686
|
signal,
|
|
21369
|
-
thinkingLevel,
|
|
21687
|
+
thinkingLevel: candidate.entry.qualifier,
|
|
21370
21688
|
onProgress: buildProgressLogger("fallback"),
|
|
21371
21689
|
accountingSessionId: sessionId,
|
|
21372
21690
|
accountingSubagent: "historian"
|
|
@@ -24475,11 +24793,13 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
24475
24793
|
if (!options.compactionOff && !sessionMetaForCh1.isSubagent) {
|
|
24476
24794
|
const tags = getTagsBySession(options.db, sessionId);
|
|
24477
24795
|
const protectedTags = options.protectedTags ?? 20;
|
|
24796
|
+
const pendingDropTagNumbers = new Set(getPendingOps(options.db, sessionId).filter((operation) => operation.operation === "drop").map((operation) => operation.tagId));
|
|
24478
24797
|
const stableId = (message) => message && typeof message === "object" ? result.postCommitEntryIdByRef.get(message) : undefined;
|
|
24479
24798
|
const baseline = refreshPiTailHygieneBaseline({
|
|
24480
24799
|
messages: outputMessages,
|
|
24481
24800
|
tags,
|
|
24482
24801
|
protectedTags,
|
|
24802
|
+
pendingDropTagNumbers,
|
|
24483
24803
|
stableId,
|
|
24484
24804
|
syntheticLeadingCount: result.syntheticLeadingCount,
|
|
24485
24805
|
cacheBusting: result.bustedThisPass,
|
|
@@ -24490,7 +24810,17 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
24490
24810
|
const oldestReclaimableToolTags = getOldestActiveUnprotectedToolTags(options.db, sessionId, protectedTags);
|
|
24491
24811
|
const channelState = {
|
|
24492
24812
|
...baseline,
|
|
24813
|
+
usableWindow: usageContextLimit ?? 0,
|
|
24814
|
+
realUserTurnCount: countRealPiUserMessages({
|
|
24815
|
+
messages: outputMessages,
|
|
24816
|
+
tags,
|
|
24817
|
+
protectedTags,
|
|
24818
|
+
pendingDropTagNumbers,
|
|
24819
|
+
stableId,
|
|
24820
|
+
syntheticLeadingCount: result.syntheticLeadingCount
|
|
24821
|
+
}),
|
|
24493
24822
|
reducedSinceRefresh: false,
|
|
24823
|
+
agentDropsAppliedThisPass: result.agentDropsAppliedThisPass,
|
|
24494
24824
|
oldestReclaimableToolTags
|
|
24495
24825
|
};
|
|
24496
24826
|
setPiChannel1Baseline(sessionId, channelState);
|
|
@@ -24515,6 +24845,7 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
24515
24845
|
messages: outputMessages,
|
|
24516
24846
|
tags,
|
|
24517
24847
|
protectedTags,
|
|
24848
|
+
pendingDropTagNumbers,
|
|
24518
24849
|
stableId,
|
|
24519
24850
|
syntheticLeadingCount: result.syntheticLeadingCount,
|
|
24520
24851
|
expectedSignature: baseline.contentSignature
|
|
@@ -25044,6 +25375,7 @@ async function runCompactionOffPipeline(args) {
|
|
|
25044
25375
|
droppedCount: 0,
|
|
25045
25376
|
emergency: false,
|
|
25046
25377
|
bustedThisPass: injectionResult?.m0Materialized === true,
|
|
25378
|
+
agentDropsAppliedThisPass: false,
|
|
25047
25379
|
targetCount: 0,
|
|
25048
25380
|
reasoningWatermark: args.sessionMeta.clearedReasoningThroughTag ?? 0,
|
|
25049
25381
|
activeTags: [],
|
|
@@ -25617,6 +25949,7 @@ async function runPipeline(args) {
|
|
|
25617
25949
|
droppedCount,
|
|
25618
25950
|
emergency,
|
|
25619
25951
|
bustedThisPass,
|
|
25952
|
+
agentDropsAppliedThisPass: pendingOpsDidMutate,
|
|
25620
25953
|
targetCount: targets.size,
|
|
25621
25954
|
reasoningWatermark: args.sessionMeta.clearedReasoningThroughTag ?? 0,
|
|
25622
25955
|
activeTags,
|
|
@@ -25909,6 +26242,7 @@ async function runValidatedHistorianPass(args) {
|
|
|
25909
26242
|
const firstRun = await runHistorianPrompt({
|
|
25910
26243
|
...args,
|
|
25911
26244
|
dumpLabel: `${args.dumpLabelBase}-initial`,
|
|
26245
|
+
modelOverride: args.model,
|
|
25912
26246
|
agentId: args.agentId
|
|
25913
26247
|
});
|
|
25914
26248
|
if (!firstRun.ok || !firstRun.result) {
|
|
@@ -25937,6 +26271,7 @@ async function runValidatedHistorianPass(args) {
|
|
|
25937
26271
|
...args,
|
|
25938
26272
|
prompt: repairPrompt,
|
|
25939
26273
|
dumpLabel: `${args.dumpLabelBase}-repair`,
|
|
26274
|
+
modelOverride: args.model,
|
|
25940
26275
|
agentId: args.agentId
|
|
25941
26276
|
});
|
|
25942
26277
|
if (!repairRun.ok || !repairRun.result) {
|
|
@@ -25977,7 +26312,8 @@ async function runEditorPassOrFallback(args) {
|
|
|
25977
26312
|
timeoutMs: args.timeoutMs,
|
|
25978
26313
|
dumpLabel: `${args.dumpLabelBase}-editor`,
|
|
25979
26314
|
agentId: HISTORIAN_EDITOR_AGENT,
|
|
25980
|
-
parentInvocationId: args.draftInvocationId ?? null
|
|
26315
|
+
parentInvocationId: args.draftInvocationId ?? null,
|
|
26316
|
+
modelOverride: args.model
|
|
25981
26317
|
});
|
|
25982
26318
|
if (!editorRun.ok || !editorRun.result) {
|
|
25983
26319
|
sessionLog(args.parentSessionId, "historian two-pass: editor call failed", {
|
|
@@ -26030,7 +26366,7 @@ async function runHistorianPrompt(args) {
|
|
|
26030
26366
|
});
|
|
26031
26367
|
};
|
|
26032
26368
|
try {
|
|
26033
|
-
sessionLog(parentSessionId, `historian: creating child session (agent=${
|
|
26369
|
+
sessionLog(parentSessionId, `historian: creating child session (agent=${toModelEntry(modelOverride)?.model ?? `agent:${agentId}`})`);
|
|
26034
26370
|
const createResponse = await createChildSessionWithFence({
|
|
26035
26371
|
client,
|
|
26036
26372
|
db,
|
|
@@ -26054,7 +26390,7 @@ async function runHistorianPrompt(args) {
|
|
|
26054
26390
|
query: { directory: sessionDirectory },
|
|
26055
26391
|
body: {
|
|
26056
26392
|
agent: agentId,
|
|
26057
|
-
...modelOverride
|
|
26393
|
+
...modelBodyField(modelOverride),
|
|
26058
26394
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
26059
26395
|
}
|
|
26060
26396
|
}, {
|
|
@@ -26124,10 +26460,21 @@ async function runHistorianPrompt(args) {
|
|
|
26124
26460
|
async function runFallbackHistorianPass(args) {
|
|
26125
26461
|
const seen = new Set;
|
|
26126
26462
|
const chain = [];
|
|
26127
|
-
|
|
26128
|
-
|
|
26463
|
+
const primary = toModelEntry(args.model);
|
|
26464
|
+
for (const candidateInput of [
|
|
26465
|
+
...args.fallbackModels ?? [],
|
|
26466
|
+
...args.fallbackModelId ? [{ model: args.fallbackModelId }] : []
|
|
26467
|
+
]) {
|
|
26468
|
+
const candidate = toModelEntry(candidateInput);
|
|
26469
|
+
if (!candidate)
|
|
26470
|
+
continue;
|
|
26471
|
+
const key = `${candidate.model}\x00${candidate.qualifier ?? ""}`;
|
|
26472
|
+
if (!candidate.model || seen.has(key))
|
|
26473
|
+
continue;
|
|
26474
|
+
if (primary?.model === candidate.model && primary.qualifier === candidate.qualifier) {
|
|
26129
26475
|
continue;
|
|
26130
|
-
|
|
26476
|
+
}
|
|
26477
|
+
seen.add(key);
|
|
26131
26478
|
chain.push(candidate);
|
|
26132
26479
|
}
|
|
26133
26480
|
if (chain.length === 0) {
|
|
@@ -26135,9 +26482,9 @@ async function runFallbackHistorianPass(args) {
|
|
|
26135
26482
|
}
|
|
26136
26483
|
let lastError = args.error;
|
|
26137
26484
|
for (let i = 0;i < chain.length; i += 1) {
|
|
26138
|
-
const
|
|
26139
|
-
const
|
|
26140
|
-
if (!
|
|
26485
|
+
const modelOverride = chain[i];
|
|
26486
|
+
const modelId = modelOverride.model;
|
|
26487
|
+
if (!parseModelOverride(modelId))
|
|
26141
26488
|
continue;
|
|
26142
26489
|
const isSessionModelLastResort = modelId === args.fallbackModelId && i === chain.length - 1;
|
|
26143
26490
|
sessionLog(args.parentSessionId, `compartment agent: retrying historian with ${modelId} (${isSessionModelLastResort ? "session-model last resort" : "configured fallback"} ${i + 1}/${chain.length})`);
|
|
@@ -26466,6 +26813,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
26466
26813
|
sequenceOffset: candidateCompartments.length,
|
|
26467
26814
|
dumpLabelBase: `recomp-${sessionId}-${chunk.startIndex}-${chunk.endIndex}-pass-${passCount + 1}`,
|
|
26468
26815
|
timeoutMs: historianTimeoutMs,
|
|
26816
|
+
model: deps.model,
|
|
26469
26817
|
fallbackModelId: deps.fallbackModelId,
|
|
26470
26818
|
fallbackModels: deps.fallbackModels,
|
|
26471
26819
|
twoPass: deps.historianTwoPass,
|
|
@@ -26886,6 +27234,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
26886
27234
|
sequenceOffset: candidateCompartments.length,
|
|
26887
27235
|
dumpLabelBase: `partial-recomp-${sessionId}-${chunk.startIndex}-${chunk.endIndex}-pass-${passCount + 1}`,
|
|
26888
27236
|
timeoutMs: historianTimeoutMs,
|
|
27237
|
+
model: deps.model,
|
|
26889
27238
|
fallbackModelId: deps.fallbackModelId,
|
|
26890
27239
|
fallbackModels: deps.fallbackModels,
|
|
26891
27240
|
twoPass: deps.historianTwoPass,
|
|
@@ -27077,11 +27426,11 @@ function createPiHistorianClient(args) {
|
|
|
27077
27426
|
agent: "magic-context-historian",
|
|
27078
27427
|
systemPrompt: args.systemPrompt,
|
|
27079
27428
|
userMessage: promptText,
|
|
27080
|
-
model: modelOverride ?? args.model,
|
|
27429
|
+
model: modelOverride?.model ?? args.model,
|
|
27081
27430
|
fallbackModels: modelOverride ? undefined : args.fallbackModels,
|
|
27082
27431
|
timeoutMs: args.timeoutMs,
|
|
27083
27432
|
cwd: args.directory,
|
|
27084
|
-
thinkingLevel: args.thinkingLevel,
|
|
27433
|
+
thinkingLevel: modelOverride ? modelOverride.qualifier : args.thinkingLevel,
|
|
27085
27434
|
accountingSessionId: args.accountingSessionId,
|
|
27086
27435
|
accountingSubagent: "recomp"
|
|
27087
27436
|
});
|
|
@@ -27129,7 +27478,8 @@ function readBodyModel(body) {
|
|
|
27129
27478
|
return;
|
|
27130
27479
|
const { providerID, modelID } = model;
|
|
27131
27480
|
if (typeof providerID === "string" && providerID.length > 0 && typeof modelID === "string" && modelID.length > 0) {
|
|
27132
|
-
|
|
27481
|
+
const qualifier = typeof body.variant === "string" && body.variant.length > 0 ? body.variant : undefined;
|
|
27482
|
+
return qualifier ? { model: `${providerID}/${modelID}`, qualifier } : { model: `${providerID}/${modelID}` };
|
|
27133
27483
|
}
|
|
27134
27484
|
return;
|
|
27135
27485
|
}
|
|
@@ -27739,13 +28089,17 @@ async function runPiMemoryMigration(deps) {
|
|
|
27739
28089
|
const prompt = buildMemoryMigrationPrompt(memories);
|
|
27740
28090
|
const modelChain = [];
|
|
27741
28091
|
const seenModels = new Set;
|
|
27742
|
-
for (const
|
|
27743
|
-
|
|
27744
|
-
|
|
28092
|
+
for (const candidate of [
|
|
28093
|
+
{
|
|
28094
|
+
model: deps.primaryModel ?? deps.model,
|
|
28095
|
+
...deps.primaryModel ? {} : deps.thinkingLevel ? { qualifier: deps.thinkingLevel } : {}
|
|
28096
|
+
},
|
|
28097
|
+
...(deps.fallbackModels ?? []).map((fallback) => typeof fallback === "string" ? { model: fallback } : fallback)
|
|
27745
28098
|
]) {
|
|
27746
|
-
|
|
27747
|
-
|
|
27748
|
-
|
|
28099
|
+
const key = `${candidate.model}\x00${candidate.qualifier ?? ""}`;
|
|
28100
|
+
if (candidate.model && !seenModels.has(key)) {
|
|
28101
|
+
seenModels.add(key);
|
|
28102
|
+
modelChain.push(candidate);
|
|
27749
28103
|
}
|
|
27750
28104
|
}
|
|
27751
28105
|
let parsed = null;
|
|
@@ -27753,17 +28107,17 @@ async function runPiMemoryMigration(deps) {
|
|
|
27753
28107
|
for (let i = 0;i < modelChain.length; i += 1) {
|
|
27754
28108
|
const model = modelChain[i];
|
|
27755
28109
|
if (i > 0) {
|
|
27756
|
-
sessionLog(deps.sessionId, `memory-migration: escalating to configured fallback model ${model} (${i}/${modelChain.length - 1})`);
|
|
28110
|
+
sessionLog(deps.sessionId, `memory-migration: escalating to configured fallback model ${model.model} (${i}/${modelChain.length - 1})`);
|
|
27757
28111
|
}
|
|
27758
28112
|
const result = await deps.runner.run({
|
|
27759
28113
|
agent: "magic-context-historian",
|
|
27760
28114
|
systemPrompt: withMigrationLanguageDirective(MIGRATION_SYSTEM_PROMPT2, deps.language),
|
|
27761
28115
|
userMessage: prompt,
|
|
27762
|
-
model,
|
|
28116
|
+
model: model.model,
|
|
27763
28117
|
fallbackModels: undefined,
|
|
27764
28118
|
timeoutMs: deps.timeoutMs ?? 5 * 60 * 1000,
|
|
27765
28119
|
cwd: deps.directory,
|
|
27766
|
-
thinkingLevel:
|
|
28120
|
+
thinkingLevel: model.qualifier,
|
|
27767
28121
|
accountingSessionId: deps.sessionId,
|
|
27768
28122
|
accountingSubagent: "recomp"
|
|
27769
28123
|
});
|
|
@@ -28277,7 +28631,7 @@ ${c.content}
|
|
|
28277
28631
|
// package.json
|
|
28278
28632
|
var package_default = {
|
|
28279
28633
|
name: "@cortexkit/pi-magic-context",
|
|
28280
|
-
version: "0.
|
|
28634
|
+
version: "0.39.0",
|
|
28281
28635
|
type: "module",
|
|
28282
28636
|
description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
|
|
28283
28637
|
main: "dist/index.js",
|
|
@@ -28308,7 +28662,7 @@ var package_default = {
|
|
|
28308
28662
|
build: "tsc -p ../retina-local-fs/tsconfig.build.json && rm -f dist/index.js dist/subagent-entry.js dist/*-*.js && bun build src/index.ts src/subagent-entry.ts --outdir dist --target node --format esm --splitting --external @earendil-works/pi-coding-agent --external @earendil-works/pi-tui --external @huggingface/transformers --external node:sqlite",
|
|
28309
28663
|
"build:e2e-argv": "bun build src/subagent-runner.ts --outfile ../../tests/docker/.generated/subagent-runner-e2e.mjs --target node --format esm --external node:sqlite",
|
|
28310
28664
|
typecheck: "tsc -p ../retina-local-fs/tsconfig.build.json && tsc --noEmit",
|
|
28311
|
-
test: "bun test",
|
|
28665
|
+
test: "bun install --frozen-lockfile && bun test",
|
|
28312
28666
|
lint: "biome check src",
|
|
28313
28667
|
"lint:fix": "biome check --write src",
|
|
28314
28668
|
format: "biome format --write src",
|
|
@@ -29627,12 +29981,13 @@ function resolveHistorianFromConfig(config) {
|
|
|
29627
29981
|
const historian = config.historian;
|
|
29628
29982
|
if (historian?.disable === true)
|
|
29629
29983
|
return;
|
|
29630
|
-
const
|
|
29631
|
-
|
|
29984
|
+
const resolved = resolveHistorianModel(config, "pi");
|
|
29985
|
+
const model = resolved.primary?.model;
|
|
29986
|
+
if (!model)
|
|
29632
29987
|
return;
|
|
29633
29988
|
const historianContextLimit = resolveHistorianContextLimit(model);
|
|
29634
29989
|
const historianChunkTokens = deriveHistorianChunkTokens(historianContextLimit);
|
|
29635
|
-
const fallbackModels =
|
|
29990
|
+
const fallbackModels = resolved.fallbacks;
|
|
29636
29991
|
return {
|
|
29637
29992
|
runner: new PiSubagentRunner,
|
|
29638
29993
|
model,
|
|
@@ -29640,7 +29995,7 @@ function resolveHistorianFromConfig(config) {
|
|
|
29640
29995
|
historianChunkTokens,
|
|
29641
29996
|
timeoutMs: config.historian_timeout_ms,
|
|
29642
29997
|
twoPass: historian?.two_pass === true,
|
|
29643
|
-
thinkingLevel:
|
|
29998
|
+
thinkingLevel: resolved.primary?.qualifier,
|
|
29644
29999
|
executeThresholdPercentage: config.execute_threshold_percentage,
|
|
29645
30000
|
executeThresholdTokens: config.execute_threshold_tokens,
|
|
29646
30001
|
commitClusterTrigger: config.commit_cluster_trigger,
|
|
@@ -30130,6 +30485,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
|
|
|
30130
30485
|
embeddingConfig: bootProjectDeps.config.embedding,
|
|
30131
30486
|
memoryEnabled: bootProjectDeps.config.memory.enabled,
|
|
30132
30487
|
retinaHandoff: bootProjectDeps.config.smart_notes.retina_handoff,
|
|
30488
|
+
mural: bootProjectDeps.config.mural,
|
|
30133
30489
|
language: bootProjectDeps.config.language,
|
|
30134
30490
|
gitCommitIndexing: bootProjectDeps.config.memory.git_commit_indexing,
|
|
30135
30491
|
onAdjunctsRefreshNeeded: signalPiSystemPromptRefreshForProject
|