@cortexkit/pi-magic-context 0.38.1 → 0.40.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-kamc8t8p.js} +3160 -521
- package/dist/index.js +582 -496
- package/dist/subagent-entry.js +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
DEFAULT_MEMORY_BUDGET_TOKENS,
|
|
14
14
|
DEFAULT_USER_PROFILE_BUDGET_TOKENS,
|
|
15
15
|
Database,
|
|
16
|
+
FAIL_CLOSED_DOCTOR_COMMAND,
|
|
16
17
|
GIT_SWEEP_LEASE_RENEWAL_MS,
|
|
17
18
|
GLOBAL_USER_PROFILE_PROJECT_PATH,
|
|
18
19
|
LATEST_SUPPORTED_VERSION,
|
|
@@ -86,6 +87,8 @@ import {
|
|
|
86
87
|
copySessionStateForClone,
|
|
87
88
|
cosineSimilarity,
|
|
88
89
|
countPrimerCandidatesForProject,
|
|
90
|
+
createFailClosedBlockingError,
|
|
91
|
+
createFailClosedController,
|
|
89
92
|
createPrimer,
|
|
90
93
|
createPromptSurfaceGuidanceEpochCache,
|
|
91
94
|
createPromptSurfaceRuntime,
|
|
@@ -125,6 +128,7 @@ import {
|
|
|
125
128
|
findAdoptableFallbackTags,
|
|
126
129
|
findLastModelKeyFromBranch,
|
|
127
130
|
findPiFallbackToolOwnerTags,
|
|
131
|
+
formatFailClosedBlockingMessage,
|
|
128
132
|
formatWindowDerivationLine,
|
|
129
133
|
getActivePrimers,
|
|
130
134
|
getActiveTagsBySession,
|
|
@@ -134,6 +138,7 @@ import {
|
|
|
134
138
|
getAllStatusTagTokenTotalsFlat,
|
|
135
139
|
getAutoSearchHintDecisions,
|
|
136
140
|
getCachedAbsoluteMessageCount,
|
|
141
|
+
getChannel1NudgeState,
|
|
137
142
|
getChannel2NudgeClaim,
|
|
138
143
|
getChannel2NudgeState,
|
|
139
144
|
getCompactionModeRecord,
|
|
@@ -149,7 +154,6 @@ import {
|
|
|
149
154
|
getLastCompartmentEndMessage,
|
|
150
155
|
getLastCompartmentEndMessageId,
|
|
151
156
|
getLastIndexedOrdinal,
|
|
152
|
-
getLastNudgeLevel,
|
|
153
157
|
getLastNudgeUndropped,
|
|
154
158
|
getLatestHistorianInvocationId,
|
|
155
159
|
getLegacyProtectedTailStartOrdinal,
|
|
@@ -226,6 +230,7 @@ import {
|
|
|
226
230
|
hasMuralCueColumns,
|
|
227
231
|
hasPiFallbackMessageTags,
|
|
228
232
|
hasPiFallbackToolOwnerTags,
|
|
233
|
+
hasShareabilitySensitiveText,
|
|
229
234
|
incrementHistorianFailure,
|
|
230
235
|
indexCommitsForProject,
|
|
231
236
|
indexMessagesAfterOrdinal,
|
|
@@ -241,6 +246,7 @@ import {
|
|
|
241
246
|
isCompartmentLeaseHeld,
|
|
242
247
|
isDreamerRunnable,
|
|
243
248
|
isEditTool,
|
|
249
|
+
isFailClosedBlockingError,
|
|
244
250
|
isMessageIndexReconciledThrough,
|
|
245
251
|
isMessageIndexSourceCurrent,
|
|
246
252
|
isMidTurn,
|
|
@@ -343,11 +349,11 @@ import {
|
|
|
343
349
|
saveRecompStagingPass,
|
|
344
350
|
saveSourceContent,
|
|
345
351
|
scheduleAfterBootQuiet,
|
|
352
|
+
setChannel1NudgeState,
|
|
346
353
|
setChannel2NudgeState,
|
|
347
354
|
setCompactionModeRecord,
|
|
348
355
|
setDeferredExecutePendingIfAbsent,
|
|
349
356
|
setEmergencyDropSample,
|
|
350
|
-
setLastNudgeLevel,
|
|
351
357
|
setLastNudgeUndropped,
|
|
352
358
|
setMemoryClassification,
|
|
353
359
|
setMuralCue,
|
|
@@ -361,6 +367,8 @@ import {
|
|
|
361
367
|
setSqlitePragmaConfig,
|
|
362
368
|
setStoragePrivatePermissionEnforcement,
|
|
363
369
|
setTodoSnapshot,
|
|
370
|
+
shouldBypassFailClosedBlock,
|
|
371
|
+
shouldUseStickyChannel1Reminder,
|
|
364
372
|
sourceNameForMemory,
|
|
365
373
|
stripChannel1ReminderSpans,
|
|
366
374
|
stripMemoryMuralBlock,
|
|
@@ -395,7 +403,7 @@ import {
|
|
|
395
403
|
withMigrationLanguageDirective,
|
|
396
404
|
withRawMessageProvider,
|
|
397
405
|
withRawSessionMessageCache
|
|
398
|
-
} from "./index-
|
|
406
|
+
} from "./index-kamc8t8p.js";
|
|
399
407
|
import {
|
|
400
408
|
pushNotification
|
|
401
409
|
} from "./index-hw34xmzk.js";
|
|
@@ -417,49 +425,104 @@ import {
|
|
|
417
425
|
import { createRequire as createRequire3 } from "node:module";
|
|
418
426
|
import { join as join5, resolve as resolve2 } from "node:path";
|
|
419
427
|
|
|
420
|
-
// ../plugin/src/shared/
|
|
421
|
-
function
|
|
422
|
-
|
|
423
|
-
return dedupe(userList.filter(isValidModelSpec));
|
|
428
|
+
// ../plugin/src/shared/model-resolution.ts
|
|
429
|
+
function asRecord(value) {
|
|
430
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
|
|
424
431
|
}
|
|
425
|
-
function
|
|
426
|
-
if (
|
|
427
|
-
return
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
432
|
+
function readString(value) {
|
|
433
|
+
if (typeof value !== "string")
|
|
434
|
+
return;
|
|
435
|
+
const trimmed = value.trim();
|
|
436
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
437
|
+
}
|
|
438
|
+
function hasOwn(record, key) {
|
|
439
|
+
return Object.hasOwn(record, key);
|
|
440
|
+
}
|
|
441
|
+
function normalizeModelEntry(entry, harness) {
|
|
442
|
+
if (typeof entry === "string") {
|
|
443
|
+
const model2 = readString(entry);
|
|
444
|
+
return model2 ? { model: model2 } : undefined;
|
|
431
445
|
}
|
|
432
|
-
|
|
446
|
+
const objectEntry = asRecord(entry);
|
|
447
|
+
if (!objectEntry)
|
|
448
|
+
return;
|
|
449
|
+
const model = readString(objectEntry.model);
|
|
450
|
+
if (!model)
|
|
451
|
+
return;
|
|
452
|
+
const qualifier = readString(objectEntry[harness === "opencode" ? "variant" : "thinking_level"]);
|
|
453
|
+
return qualifier ? { model, qualifier } : { model };
|
|
433
454
|
}
|
|
434
|
-
function
|
|
435
|
-
const slash =
|
|
436
|
-
return slash > 0 && slash <
|
|
455
|
+
function isValidModelReference(entry) {
|
|
456
|
+
const slash = entry.model.indexOf("/");
|
|
457
|
+
return slash > 0 && slash < entry.model.length - 1;
|
|
437
458
|
}
|
|
438
|
-
function
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
459
|
+
function sameAttempt(a, b) {
|
|
460
|
+
return a.model === b.model && a.qualifier === b.qualifier;
|
|
461
|
+
}
|
|
462
|
+
function resolveFallbackEntries(value, harness) {
|
|
463
|
+
const values = Array.isArray(value) ? value : value === undefined ? [] : [value];
|
|
464
|
+
const resolved = [];
|
|
465
|
+
for (const value2 of values) {
|
|
466
|
+
const entry = normalizeModelEntry(value2, harness);
|
|
467
|
+
if (!entry || !isValidModelReference(entry))
|
|
443
468
|
continue;
|
|
444
|
-
|
|
445
|
-
|
|
469
|
+
if (resolved.some((candidate) => sameAttempt(candidate, entry)))
|
|
470
|
+
continue;
|
|
471
|
+
resolved.push(entry);
|
|
446
472
|
}
|
|
447
|
-
return
|
|
473
|
+
return resolved;
|
|
448
474
|
}
|
|
449
|
-
function
|
|
450
|
-
const
|
|
451
|
-
if (
|
|
452
|
-
return
|
|
475
|
+
function resolvePrimaryEntry(args) {
|
|
476
|
+
const entry = normalizeModelEntry(args.entry, args.harness);
|
|
477
|
+
if (!entry)
|
|
478
|
+
return;
|
|
479
|
+
const qualifier = entry.qualifier ?? readString(args.defaultQualifier);
|
|
480
|
+
return qualifier ? { ...entry, qualifier } : entry;
|
|
481
|
+
}
|
|
482
|
+
function resolveHistorianModel(config, harness) {
|
|
483
|
+
const historian = asRecord(asRecord(config)?.historian);
|
|
484
|
+
const block = asRecord(historian?.[harness]);
|
|
485
|
+
if (!block)
|
|
486
|
+
return { fallbacks: [] };
|
|
453
487
|
return {
|
|
454
|
-
|
|
455
|
-
|
|
488
|
+
primary: resolvePrimaryEntry({
|
|
489
|
+
entry: block.model,
|
|
490
|
+
defaultQualifier: block[harness === "opencode" ? "variant" : "thinking_level"],
|
|
491
|
+
harness
|
|
492
|
+
}),
|
|
493
|
+
fallbacks: resolveFallbackEntries(block.fallback_models, harness)
|
|
456
494
|
};
|
|
457
495
|
}
|
|
458
|
-
function
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
const
|
|
462
|
-
|
|
496
|
+
function resolveDreamerTaskModel(args) {
|
|
497
|
+
const dreamer = asRecord(asRecord(args.config)?.dreamer);
|
|
498
|
+
const harnessBlock = asRecord(dreamer?.[args.harness]);
|
|
499
|
+
const taskBlock = asRecord(asRecord(harnessBlock?.tasks)?.[args.task]);
|
|
500
|
+
const schedulingTask = asRecord(asRecord(dreamer?.tasks)?.[args.task]);
|
|
501
|
+
if (!harnessBlock) {
|
|
502
|
+
return {
|
|
503
|
+
fallbacks: [],
|
|
504
|
+
schedule: readString(schedulingTask?.schedule),
|
|
505
|
+
timeoutMinutes: typeof taskBlock?.timeout_minutes === "number" ? taskBlock.timeout_minutes : undefined,
|
|
506
|
+
promotionThreshold: typeof schedulingTask?.promotion_threshold === "number" ? schedulingTask.promotion_threshold : undefined
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
const taskQualifier = taskBlock?.[args.harness === "opencode" ? "variant" : "thinking_level"];
|
|
510
|
+
const harnessQualifier = harnessBlock[args.harness === "opencode" ? "variant" : "thinking_level"] ?? normalizeModelEntry(harnessBlock.model, args.harness)?.qualifier;
|
|
511
|
+
const taskHasModel = taskBlock !== undefined && hasOwn(taskBlock, "model");
|
|
512
|
+
const usesMuralModel = !taskHasModel && args.task === "compress-cues" && Boolean(readString(args.muralModel));
|
|
513
|
+
const primarySource = taskHasModel ? taskBlock?.model : usesMuralModel ? args.muralModel : harnessBlock.model;
|
|
514
|
+
const fallbackSource = taskBlock !== undefined && hasOwn(taskBlock, "fallback_models") ? taskBlock.fallback_models : harnessBlock.fallback_models;
|
|
515
|
+
return {
|
|
516
|
+
primary: resolvePrimaryEntry({
|
|
517
|
+
entry: primarySource,
|
|
518
|
+
defaultQualifier: usesMuralModel ? harnessQualifier : taskQualifier ?? harnessQualifier,
|
|
519
|
+
harness: args.harness
|
|
520
|
+
}),
|
|
521
|
+
fallbacks: resolveFallbackEntries(fallbackSource, args.harness),
|
|
522
|
+
schedule: readString(schedulingTask?.schedule),
|
|
523
|
+
timeoutMinutes: typeof taskBlock?.timeout_minutes === "number" ? taskBlock.timeout_minutes : undefined,
|
|
524
|
+
promotionThreshold: typeof schedulingTask?.promotion_threshold === "number" ? schedulingTask.promotion_threshold : undefined
|
|
525
|
+
};
|
|
463
526
|
}
|
|
464
527
|
|
|
465
528
|
// ../plugin/src/features/magic-context/dreamer/task-registry.ts
|
|
@@ -528,25 +591,23 @@ function compareTaskOrder(a, b) {
|
|
|
528
591
|
}
|
|
529
592
|
|
|
530
593
|
// ../plugin/src/features/magic-context/dreamer/task-config.ts
|
|
531
|
-
function buildDreamTaskRuntimeConfigs(dreamer, language) {
|
|
532
|
-
const tasks = dreamer.tasks ?? {};
|
|
594
|
+
function buildDreamTaskRuntimeConfigs(dreamer, harness, language, muralModel) {
|
|
533
595
|
return CANONICAL_DREAM_TASKS.map((task) => {
|
|
534
|
-
const
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
const thinkingLevel = t.thinking_level ?? dreamer.thinking_level;
|
|
596
|
+
const resolved = resolveDreamerTaskModel({
|
|
597
|
+
config: { dreamer },
|
|
598
|
+
harness,
|
|
599
|
+
task,
|
|
600
|
+
muralModel
|
|
601
|
+
});
|
|
541
602
|
return {
|
|
542
603
|
task,
|
|
543
|
-
schedule:
|
|
544
|
-
model,
|
|
545
|
-
fallbackModels,
|
|
546
|
-
thinkingLevel,
|
|
604
|
+
schedule: resolved.schedule ?? "",
|
|
605
|
+
model: resolved.primary,
|
|
606
|
+
fallbackModels: resolved.fallbacks,
|
|
607
|
+
thinkingLevel: harness === "pi" ? resolved.primary?.qualifier : undefined,
|
|
547
608
|
language,
|
|
548
|
-
timeoutMinutes:
|
|
549
|
-
promotionThreshold:
|
|
609
|
+
timeoutMinutes: resolved.timeoutMinutes ?? 20,
|
|
610
|
+
promotionThreshold: resolved.promotionThreshold
|
|
550
611
|
};
|
|
551
612
|
});
|
|
552
613
|
}
|
|
@@ -566,170 +627,6 @@ function summarizeDreamSchedule(dreamer) {
|
|
|
566
627
|
return enabled.map((t) => `${t} ${dreamer?.tasks[t]?.schedule}`).join(", ");
|
|
567
628
|
}
|
|
568
629
|
|
|
569
|
-
// ../plugin/src/features/magic-context/fail-closed-block.ts
|
|
570
|
-
var FAIL_CLOSED_DOCTOR_COMMAND = "npx @cortexkit/magic-context@latest doctor";
|
|
571
|
-
var FAIL_CLOSED_REPROBE_EVERY_N = 5;
|
|
572
|
-
|
|
573
|
-
class FailClosedBlockingError extends Error {
|
|
574
|
-
code = "FAIL_CLOSED_BLOCKING";
|
|
575
|
-
reason;
|
|
576
|
-
constructor(message, reason, options) {
|
|
577
|
-
super(message, options);
|
|
578
|
-
this.name = "FailClosedBlockingError";
|
|
579
|
-
this.reason = reason;
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
var OPENCODE_INTERNAL_AGENT_NAMES = new Set(["title", "summary", "compaction"]);
|
|
583
|
-
function isMagicContextHiddenAgentName(agent) {
|
|
584
|
-
if (agent === "sidekick" || agent === "smart-note-compiler" || agent.startsWith("smart-note-")) {
|
|
585
|
-
return true;
|
|
586
|
-
}
|
|
587
|
-
if (agent === "historian" || agent.startsWith("historian-"))
|
|
588
|
-
return true;
|
|
589
|
-
if (agent === "dreamer" || agent.startsWith("dreamer-"))
|
|
590
|
-
return true;
|
|
591
|
-
return false;
|
|
592
|
-
}
|
|
593
|
-
var MAX_FORMATTED_BLOCKING_PROCESSES = 8;
|
|
594
|
-
function normalizeFailClosedProcessKind(process2) {
|
|
595
|
-
switch (process2.kind) {
|
|
596
|
-
case "OpenCode server":
|
|
597
|
-
case "OpenCode instance (TUI/CLI)":
|
|
598
|
-
case "Pi":
|
|
599
|
-
case "process":
|
|
600
|
-
return process2.kind;
|
|
601
|
-
}
|
|
602
|
-
switch (process2.harness?.trim().toLowerCase()) {
|
|
603
|
-
case "opencode server":
|
|
604
|
-
return "OpenCode server";
|
|
605
|
-
case "opencode instance (tui/cli)":
|
|
606
|
-
case "opencode instance":
|
|
607
|
-
return "OpenCode instance (TUI/CLI)";
|
|
608
|
-
case "pi":
|
|
609
|
-
case "pi harness":
|
|
610
|
-
case "omp":
|
|
611
|
-
return "Pi";
|
|
612
|
-
default:
|
|
613
|
-
return "process";
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
function formatFailClosedBlockingProcesses(processes) {
|
|
617
|
-
const uniqueProcesses = new Map;
|
|
618
|
-
for (const process2 of processes) {
|
|
619
|
-
if (!Number.isInteger(process2.pid) || process2.pid <= 0)
|
|
620
|
-
continue;
|
|
621
|
-
const kind = normalizeFailClosedProcessKind(process2);
|
|
622
|
-
uniqueProcesses.set(`${kind}\x00${process2.pid}`, { kind, pid: process2.pid });
|
|
623
|
-
}
|
|
624
|
-
const entries = [...uniqueProcesses.values()];
|
|
625
|
-
const visible = entries.slice(0, MAX_FORMATTED_BLOCKING_PROCESSES);
|
|
626
|
-
const rendered = visible.map(({ kind, pid }) => `${kind} (PID ${pid})`);
|
|
627
|
-
const omitted = entries.length - visible.length;
|
|
628
|
-
if (omitted > 0)
|
|
629
|
-
rendered.push(`${omitted} more blocking process(es)`);
|
|
630
|
-
if (rendered.length === 0)
|
|
631
|
-
return "a live process";
|
|
632
|
-
if (rendered.length === 1)
|
|
633
|
-
return rendered[0];
|
|
634
|
-
const last = rendered.pop();
|
|
635
|
-
return `${rendered.join(", ")}, and ${last}`;
|
|
636
|
-
}
|
|
637
|
-
function formatFailClosedBlockingMessage(reason) {
|
|
638
|
-
if (reason.kind === "migration_guard") {
|
|
639
|
-
if (reason.unreadableFile) {
|
|
640
|
-
const arm = reason.unreadableArm ?? "io";
|
|
641
|
-
const recovery = arm === "io" ? `If none of these processes are running, it is safe to delete ${reason.unreadableFile} and retry.` : `The file may be a recent incomplete write; retry after the file is older than the ten-minute grace window, or stop the relevant process before deleting it.`;
|
|
642
|
-
return [
|
|
643
|
-
`Magic Context cannot migrate the shared database because RPC discovery file ${reason.unreadableFile} is uncertain (${arm} arm), so the absence of a live process cannot be proven.`,
|
|
644
|
-
recovery,
|
|
645
|
-
`Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
|
|
646
|
-
].join(" ");
|
|
647
|
-
}
|
|
648
|
-
return [
|
|
649
|
-
`Magic Context cannot migrate the shared database because ${formatFailClosedBlockingProcesses(reason.blockingProcesses)} may be running an older Magic Context build that would fail against the migrated database.`,
|
|
650
|
-
"Restart the blocking process (it will pick up the new build and migrate on start), or shut it down and retry.",
|
|
651
|
-
`Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
|
|
652
|
-
].join(" ");
|
|
653
|
-
}
|
|
654
|
-
if (reason.kind === "schema_fence") {
|
|
655
|
-
return [
|
|
656
|
-
`Magic Context cannot operate: this Magic Context build is older than the database; upgrade/restart this harness (upstream migration lane v${reason.persistedVersion}, build supports through v${reason.supportedVersion}).`,
|
|
657
|
-
`Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
|
|
658
|
-
].join(" ");
|
|
659
|
-
}
|
|
660
|
-
const cause = reason.cause.trim().length > 0 ? reason.cause.trim() : "unknown storage error";
|
|
661
|
-
return [
|
|
662
|
-
`Magic Context cannot operate: persistent storage failed (${cause}).`,
|
|
663
|
-
"The plugin will not silently degrade to native compaction while enabled.",
|
|
664
|
-
`Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
|
|
665
|
-
].join(" ");
|
|
666
|
-
}
|
|
667
|
-
function createFailClosedBlockingError(reason, options) {
|
|
668
|
-
return new FailClosedBlockingError(formatFailClosedBlockingMessage(reason), reason, options);
|
|
669
|
-
}
|
|
670
|
-
function isFailClosedBlockingError(error) {
|
|
671
|
-
return error instanceof FailClosedBlockingError || typeof error === "object" && error !== null && error.name === "FailClosedBlockingError" && error.code === "FAIL_CLOSED_BLOCKING";
|
|
672
|
-
}
|
|
673
|
-
function shouldBypassFailClosedBlock(input) {
|
|
674
|
-
if (input.isPiSubagentEnv === true)
|
|
675
|
-
return true;
|
|
676
|
-
if (input.isInternalChildSession === true)
|
|
677
|
-
return true;
|
|
678
|
-
const agent = typeof input.agent === "string" ? input.agent.trim() : "";
|
|
679
|
-
if (agent.length === 0)
|
|
680
|
-
return false;
|
|
681
|
-
if (OPENCODE_INTERNAL_AGENT_NAMES.has(agent))
|
|
682
|
-
return true;
|
|
683
|
-
if (isMagicContextHiddenAgentName(agent))
|
|
684
|
-
return true;
|
|
685
|
-
return false;
|
|
686
|
-
}
|
|
687
|
-
function createFailClosedController(options) {
|
|
688
|
-
const reprobeEveryN = Math.max(1, options?.reprobeEveryN ?? FAIL_CLOSED_REPROBE_EVERY_N);
|
|
689
|
-
let reason = null;
|
|
690
|
-
let blockedPassCount = 0;
|
|
691
|
-
return {
|
|
692
|
-
arm(next) {
|
|
693
|
-
reason = next;
|
|
694
|
-
blockedPassCount = 0;
|
|
695
|
-
},
|
|
696
|
-
clear() {
|
|
697
|
-
reason = null;
|
|
698
|
-
blockedPassCount = 0;
|
|
699
|
-
},
|
|
700
|
-
isArmed() {
|
|
701
|
-
return reason !== null;
|
|
702
|
-
},
|
|
703
|
-
getReason() {
|
|
704
|
-
return reason;
|
|
705
|
-
},
|
|
706
|
-
async enforce(input) {
|
|
707
|
-
if (!reason)
|
|
708
|
-
return;
|
|
709
|
-
if (!input.blockingEnabled)
|
|
710
|
-
return;
|
|
711
|
-
if (input.exempt)
|
|
712
|
-
return;
|
|
713
|
-
blockedPassCount += 1;
|
|
714
|
-
const shouldReprobe = typeof input.tryReopen === "function" && (blockedPassCount === 1 || blockedPassCount % reprobeEveryN === 0);
|
|
715
|
-
if (shouldReprobe) {
|
|
716
|
-
try {
|
|
717
|
-
const healed = await input.tryReopen?.();
|
|
718
|
-
if (healed) {
|
|
719
|
-
reason = null;
|
|
720
|
-
blockedPassCount = 0;
|
|
721
|
-
return;
|
|
722
|
-
}
|
|
723
|
-
} catch {}
|
|
724
|
-
}
|
|
725
|
-
const blockedReason = reason;
|
|
726
|
-
if (!blockedReason)
|
|
727
|
-
return;
|
|
728
|
-
throw createFailClosedBlockingError(blockedReason);
|
|
729
|
-
}
|
|
730
|
-
};
|
|
731
|
-
}
|
|
732
|
-
|
|
733
630
|
// ../plugin/src/features/magic-context/message-index-async.ts
|
|
734
631
|
function isDatabaseLockedError(error) {
|
|
735
632
|
if (!error || typeof error !== "object")
|
|
@@ -1951,6 +1848,59 @@ function shouldKeepSubagents() {
|
|
|
1951
1848
|
return keepSubagents;
|
|
1952
1849
|
}
|
|
1953
1850
|
|
|
1851
|
+
// ../plugin/src/shared/resolve-fallbacks.ts
|
|
1852
|
+
function resolveFallbackChain(userFallbacks) {
|
|
1853
|
+
const userList = normalizeUserFallbacks(userFallbacks);
|
|
1854
|
+
return dedupe(userList.filter(isValidModelSpec));
|
|
1855
|
+
}
|
|
1856
|
+
function normalizeUserFallbacks(userFallbacks) {
|
|
1857
|
+
if (!userFallbacks)
|
|
1858
|
+
return [];
|
|
1859
|
+
if (typeof userFallbacks === "string") {
|
|
1860
|
+
const trimmed = userFallbacks.trim();
|
|
1861
|
+
return trimmed ? [trimmed] : [];
|
|
1862
|
+
}
|
|
1863
|
+
return userFallbacks.map((s) => s.trim()).filter((s) => s.length > 0);
|
|
1864
|
+
}
|
|
1865
|
+
function isValidModelSpec(spec) {
|
|
1866
|
+
const slash = spec.indexOf("/");
|
|
1867
|
+
return slash > 0 && slash < spec.length - 1;
|
|
1868
|
+
}
|
|
1869
|
+
function dedupe(list) {
|
|
1870
|
+
const seen = new Set;
|
|
1871
|
+
const out = [];
|
|
1872
|
+
for (const item of list) {
|
|
1873
|
+
if (seen.has(item))
|
|
1874
|
+
continue;
|
|
1875
|
+
seen.add(item);
|
|
1876
|
+
out.push(item);
|
|
1877
|
+
}
|
|
1878
|
+
return out;
|
|
1879
|
+
}
|
|
1880
|
+
function parseProviderModel(spec) {
|
|
1881
|
+
const slash = spec.indexOf("/");
|
|
1882
|
+
if (slash < 1 || slash >= spec.length - 1)
|
|
1883
|
+
return null;
|
|
1884
|
+
return {
|
|
1885
|
+
providerID: spec.slice(0, slash).trim(),
|
|
1886
|
+
modelID: spec.slice(slash + 1).trim()
|
|
1887
|
+
};
|
|
1888
|
+
}
|
|
1889
|
+
function modelBodyField(spec) {
|
|
1890
|
+
const entry = toModelEntry(spec);
|
|
1891
|
+
if (!entry)
|
|
1892
|
+
return {};
|
|
1893
|
+
const parsed = parseProviderModel(entry.model);
|
|
1894
|
+
return parsed ? { model: parsed, ...entry.qualifier ? { variant: entry.qualifier } : {} } : {};
|
|
1895
|
+
}
|
|
1896
|
+
function toModelEntry(spec) {
|
|
1897
|
+
if (typeof spec === "string") {
|
|
1898
|
+
const model = spec.trim();
|
|
1899
|
+
return model ? { model } : undefined;
|
|
1900
|
+
}
|
|
1901
|
+
return spec;
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1954
1904
|
// src/clone-inheritance.ts
|
|
1955
1905
|
import { readFile } from "node:fs/promises";
|
|
1956
1906
|
var CONTENT_ID_SUFFIX = /:(?:p|file)\d+$/;
|
|
@@ -2530,14 +2480,35 @@ class PiSubagentRunner {
|
|
|
2530
2480
|
return { result: isolatedResult, extensionRetryUsed: true };
|
|
2531
2481
|
}
|
|
2532
2482
|
async runModelChain(options, runMode, primaryModelRef) {
|
|
2533
|
-
const
|
|
2534
|
-
const
|
|
2483
|
+
const attempts = [];
|
|
2484
|
+
const seenAttempts = new Set;
|
|
2485
|
+
const appendAttempt = (candidate) => {
|
|
2486
|
+
if (!candidate.model)
|
|
2487
|
+
return;
|
|
2488
|
+
const key = `${candidate.model}\x00${candidate.qualifier ?? ""}`;
|
|
2489
|
+
if (seenAttempts.has(key))
|
|
2490
|
+
return;
|
|
2491
|
+
seenAttempts.add(key);
|
|
2492
|
+
attempts.push(candidate);
|
|
2493
|
+
};
|
|
2494
|
+
if (options.model) {
|
|
2495
|
+
appendAttempt({
|
|
2496
|
+
model: options.model,
|
|
2497
|
+
...options.thinkingLevel ? { qualifier: options.thinkingLevel } : {}
|
|
2498
|
+
});
|
|
2499
|
+
}
|
|
2500
|
+
for (const candidate of options.fallbackModels ?? []) {
|
|
2501
|
+
appendAttempt(typeof candidate === "string" ? { model: candidate } : candidate);
|
|
2502
|
+
}
|
|
2503
|
+
if (attempts.length === 0)
|
|
2504
|
+
attempts.push(undefined);
|
|
2535
2505
|
let lastResult = null;
|
|
2536
2506
|
for (let index = 0;index < attempts.length; index += 1) {
|
|
2537
|
-
const
|
|
2507
|
+
const attempt = attempts[index];
|
|
2538
2508
|
const attemptOptions = {
|
|
2539
2509
|
...options,
|
|
2540
|
-
model,
|
|
2510
|
+
model: attempt?.model,
|
|
2511
|
+
thinkingLevel: attempt?.qualifier,
|
|
2541
2512
|
fallbackModels: undefined
|
|
2542
2513
|
};
|
|
2543
2514
|
const result = await this.runOnce(attemptOptions, runMode, index === 0 ? primaryModelRef : undefined);
|
|
@@ -4091,15 +4062,18 @@ async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
|
|
|
4091
4062
|
log(`[${callContext}] primary (${explicitPrimaryLabel}) failed: ${shortErr(error)}; trying ${fallbacks.length} fallback(s)`);
|
|
4092
4063
|
}
|
|
4093
4064
|
for (let i = 0;i < fallbacks.length; i += 1) {
|
|
4094
|
-
const
|
|
4065
|
+
const fallback = toModelEntry(fallbacks[i]);
|
|
4066
|
+
const parsed = fallback ? parseProviderModel(fallback.model) : null;
|
|
4095
4067
|
if (!parsed) {
|
|
4096
|
-
log(`[${callContext}] skipping invalid fallback spec: ${fallbacks[i]}`);
|
|
4068
|
+
log(`[${callContext}] skipping invalid fallback spec: ${String(fallbacks[i])}`);
|
|
4097
4069
|
continue;
|
|
4098
4070
|
}
|
|
4099
4071
|
const label = `${parsed.providerID}/${parsed.modelID}`;
|
|
4072
|
+
const { variant: _primaryVariant, ...bodyWithoutPrimaryVariant } = baseBody;
|
|
4100
4073
|
const attemptArgs = copyPromptArgs(baseArgs, {
|
|
4101
|
-
...
|
|
4102
|
-
model: parsed
|
|
4074
|
+
...bodyWithoutPrimaryVariant,
|
|
4075
|
+
model: parsed,
|
|
4076
|
+
...fallback?.qualifier ? { variant: fallback.qualifier } : {}
|
|
4103
4077
|
});
|
|
4104
4078
|
try {
|
|
4105
4079
|
await attemptOnce(client, attemptArgs, timeoutMs, options.signal, callContext, label);
|
|
@@ -4115,7 +4089,7 @@ async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
|
|
|
4115
4089
|
}
|
|
4116
4090
|
}
|
|
4117
4091
|
}
|
|
4118
|
-
log(`[${callContext}] all models exhausted; tried: ${[explicitPrimaryLabel, ...fallbacks].join(", ")}; last error: ${shortErr(lastError)}`);
|
|
4092
|
+
log(`[${callContext}] all models exhausted; tried: ${[explicitPrimaryLabel, ...fallbacks.map((fallback) => toModelEntry(fallback)?.model ?? String(fallback))].join(", ")}; last error: ${shortErr(lastError)}`);
|
|
4119
4093
|
throw lastError ?? new Error("All fallback models failed");
|
|
4120
4094
|
}
|
|
4121
4095
|
async function attemptAndValidate(client, args, timeoutMs, signal, callContext, attempt, options) {
|
|
@@ -4153,15 +4127,18 @@ async function promptSyncWithValidatedOutputRetry(client, args, options) {
|
|
|
4153
4127
|
log(`[${callContext}] primary (${explicitPrimaryLabel}) failed validation/prompt: ${shortErr(error)}; trying ${fallbacks.length} fallback(s)`);
|
|
4154
4128
|
}
|
|
4155
4129
|
for (let i = 0;i < fallbacks.length; i += 1) {
|
|
4156
|
-
const
|
|
4130
|
+
const fallback = toModelEntry(fallbacks[i]);
|
|
4131
|
+
const parsed = fallback ? parseProviderModel(fallback.model) : null;
|
|
4157
4132
|
if (!parsed) {
|
|
4158
|
-
log(`[${callContext}] skipping invalid fallback spec: ${fallbacks[i]}`);
|
|
4133
|
+
log(`[${callContext}] skipping invalid fallback spec: ${String(fallbacks[i])}`);
|
|
4159
4134
|
continue;
|
|
4160
4135
|
}
|
|
4161
4136
|
const label = `${parsed.providerID}/${parsed.modelID}`;
|
|
4137
|
+
const { variant: _primaryVariant, ...bodyWithoutPrimaryVariant } = baseBody;
|
|
4162
4138
|
const attemptArgs = copyPromptArgs(baseArgs, {
|
|
4163
|
-
...
|
|
4164
|
-
model: parsed
|
|
4139
|
+
...bodyWithoutPrimaryVariant,
|
|
4140
|
+
model: parsed,
|
|
4141
|
+
...fallback?.qualifier ? { variant: fallback.qualifier } : {}
|
|
4165
4142
|
});
|
|
4166
4143
|
const attempt = {
|
|
4167
4144
|
label,
|
|
@@ -4186,7 +4163,7 @@ async function promptSyncWithValidatedOutputRetry(client, args, options) {
|
|
|
4186
4163
|
}
|
|
4187
4164
|
}
|
|
4188
4165
|
}
|
|
4189
|
-
log(`[${callContext}] all models exhausted; tried: ${[explicitPrimaryLabel, ...fallbacks].join(", ")}; original error: ${shortErr(firstError)}; last error: ${shortErr(lastError)}`);
|
|
4166
|
+
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
4167
|
throw firstError ?? lastError ?? new Error("All fallback models failed validation");
|
|
4191
4168
|
}
|
|
4192
4169
|
// ../plugin/src/shared/normalize-sdk-response.ts
|
|
@@ -5694,153 +5671,6 @@ function isRustAuthorityDrainingError(error) {
|
|
|
5694
5671
|
return error instanceof Error && error.message.includes("authority_draining");
|
|
5695
5672
|
}
|
|
5696
5673
|
|
|
5697
|
-
// ../plugin/src/shared/redaction.ts
|
|
5698
|
-
import { homedir as homedir2, userInfo } from "node:os";
|
|
5699
|
-
function escapeRegex(value) {
|
|
5700
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5701
|
-
}
|
|
5702
|
-
var SECRET_WORDS = [
|
|
5703
|
-
"key",
|
|
5704
|
-
"token",
|
|
5705
|
-
"secret",
|
|
5706
|
-
"password",
|
|
5707
|
-
"auth",
|
|
5708
|
-
"authorization",
|
|
5709
|
-
"bearer",
|
|
5710
|
-
"credential"
|
|
5711
|
-
];
|
|
5712
|
-
var SECRET_SEGMENT_PATTERN = new RegExp(`^(?:${SECRET_WORDS.map((w) => `${w}s?`).join("|")})$`, "i");
|
|
5713
|
-
var TRAILING_DESCRIPTORS = new Set(["id", "ids", "value", "values", "header", "headers"]);
|
|
5714
|
-
function redactionTypeForKey(key) {
|
|
5715
|
-
const normalized = key.trim().toLowerCase().replace(/[^a-z0-9_.-]+/g, "_");
|
|
5716
|
-
const suffix = normalized.split(".").filter(Boolean).at(-1) ?? normalized;
|
|
5717
|
-
return suffix || "secret";
|
|
5718
|
-
}
|
|
5719
|
-
function isNonSecretScalarValue(value) {
|
|
5720
|
-
const v = value.trim();
|
|
5721
|
-
if (v === "true" || v === "false" || v === "null" || v === "undefined")
|
|
5722
|
-
return true;
|
|
5723
|
-
return /^[+-]?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(v);
|
|
5724
|
-
}
|
|
5725
|
-
var SECRET_QUALIFIERS = new Set([
|
|
5726
|
-
"api",
|
|
5727
|
-
"access",
|
|
5728
|
-
"private",
|
|
5729
|
-
"client",
|
|
5730
|
-
"auth",
|
|
5731
|
-
"authorization",
|
|
5732
|
-
"secret",
|
|
5733
|
-
"bearer",
|
|
5734
|
-
"session",
|
|
5735
|
-
"refresh",
|
|
5736
|
-
"service",
|
|
5737
|
-
"x",
|
|
5738
|
-
"openai",
|
|
5739
|
-
"anthropic",
|
|
5740
|
-
"google",
|
|
5741
|
-
"github",
|
|
5742
|
-
"huggingface",
|
|
5743
|
-
"aws",
|
|
5744
|
-
"azure"
|
|
5745
|
-
]);
|
|
5746
|
-
function sanitizePathString(value) {
|
|
5747
|
-
const home = homedir2();
|
|
5748
|
-
const username = userInfo().username;
|
|
5749
|
-
let sanitized = value;
|
|
5750
|
-
if (home) {
|
|
5751
|
-
sanitized = sanitized.replace(new RegExp(escapeRegex(home), "g"), "~");
|
|
5752
|
-
}
|
|
5753
|
-
sanitized = sanitized.replace(/\/Users\/[^/]+\//g, "/Users/<USER>/");
|
|
5754
|
-
sanitized = sanitized.replace(/\/home\/[^/]+\//g, "/home/<USER>/");
|
|
5755
|
-
sanitized = sanitized.replace(/C:\\Users\\[^\\]+\\/g, "C:\\Users\\<USER>\\");
|
|
5756
|
-
if (username) {
|
|
5757
|
-
sanitized = sanitized.replace(new RegExp(escapeRegex(username), "g"), "<USER>");
|
|
5758
|
-
}
|
|
5759
|
-
return sanitized;
|
|
5760
|
-
}
|
|
5761
|
-
var SECRET_TEXT_PATTERNS = [
|
|
5762
|
-
{
|
|
5763
|
-
pattern: /\bsk-ant-(?:api03-)?[A-Za-z0-9_-]{32,}/g,
|
|
5764
|
-
replacement: "<ANTHROPIC_API_KEY_REDACTED>"
|
|
5765
|
-
},
|
|
5766
|
-
{
|
|
5767
|
-
pattern: /\bsk-(?:proj-)?[A-Za-z0-9_-]{32,}/g,
|
|
5768
|
-
replacement: "<OPENAI_API_KEY_REDACTED>"
|
|
5769
|
-
},
|
|
5770
|
-
{
|
|
5771
|
-
pattern: /\bgithub_pat_[A-Za-z0-9_]{20,}/g,
|
|
5772
|
-
replacement: "<GITHUB_PAT_REDACTED>"
|
|
5773
|
-
},
|
|
5774
|
-
{
|
|
5775
|
-
pattern: /\b(?:gh[opsu]|ghr)_[A-Za-z0-9]{30,}/g,
|
|
5776
|
-
replacement: "<GITHUB_TOKEN_REDACTED>"
|
|
5777
|
-
},
|
|
5778
|
-
{
|
|
5779
|
-
pattern: /\bhf_[A-Za-z0-9]{30,}/g,
|
|
5780
|
-
replacement: "<HUGGINGFACE_TOKEN_REDACTED>"
|
|
5781
|
-
},
|
|
5782
|
-
{
|
|
5783
|
-
pattern: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,
|
|
5784
|
-
replacement: "<AWS_ACCESS_KEY_ID_REDACTED>"
|
|
5785
|
-
},
|
|
5786
|
-
{
|
|
5787
|
-
pattern: /\bxox[abprsuvc]-[A-Za-z0-9-]{10,}/g,
|
|
5788
|
-
replacement: "<SLACK_TOKEN_REDACTED>"
|
|
5789
|
-
},
|
|
5790
|
-
{
|
|
5791
|
-
pattern: /\bAIza[A-Za-z0-9_-]{35}\b/g,
|
|
5792
|
-
replacement: "<GOOGLE_API_KEY_REDACTED>"
|
|
5793
|
-
},
|
|
5794
|
-
{
|
|
5795
|
-
pattern: /\b(Authorization\s*:\s*Bearer\s+)([A-Za-z0-9._~+/=-]{8,})/gi,
|
|
5796
|
-
replacement: (_full, prefix) => `${prefix}<REDACTED:bearer>`
|
|
5797
|
-
},
|
|
5798
|
-
{
|
|
5799
|
-
pattern: /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,
|
|
5800
|
-
replacement: "<JWT_REDACTED>"
|
|
5801
|
-
},
|
|
5802
|
-
{
|
|
5803
|
-
pattern: /(["'])([^"']*(?:key|token|secret|password|auth|bearer|credential)[^"']*)\1(\s*:\s*)(["'])([^"']*)\4/gi,
|
|
5804
|
-
replacement: (full, quote, key, separator, valueQuote, value) => isNonSecretScalarValue(value) ? full : `${quote}${key}${quote}${separator}${valueQuote}<REDACTED:${redactionTypeForKey(key)}>${valueQuote}`
|
|
5805
|
-
},
|
|
5806
|
-
{
|
|
5807
|
-
pattern: /\b([A-Za-z0-9_.-]*(?:key|token|secret|password|auth|bearer|credential)[A-Za-z0-9_.-]*)\s*=\s*([^\s'"`]+)/gi,
|
|
5808
|
-
replacement: (full, key, value) => isNonSecretScalarValue(value) ? full : `${key}=<REDACTED:${redactionTypeForKey(key)}>`
|
|
5809
|
-
}
|
|
5810
|
-
];
|
|
5811
|
-
function redactSecretText(value) {
|
|
5812
|
-
let redacted = value;
|
|
5813
|
-
for (const { pattern, replacement } of SECRET_TEXT_PATTERNS) {
|
|
5814
|
-
if (typeof replacement === "string") {
|
|
5815
|
-
redacted = redacted.replace(pattern, replacement);
|
|
5816
|
-
} else {
|
|
5817
|
-
redacted = redacted.replace(pattern, replacement);
|
|
5818
|
-
}
|
|
5819
|
-
}
|
|
5820
|
-
return redacted;
|
|
5821
|
-
}
|
|
5822
|
-
function sanitizeDiagnosticText(value) {
|
|
5823
|
-
return redactSecretText(sanitizePathString(value));
|
|
5824
|
-
}
|
|
5825
|
-
var SHAREABILITY_SENSITIVE_PATTERNS = [
|
|
5826
|
-
/\bC:\/Users\/[^/\s]+/i,
|
|
5827
|
-
/(?:^|\s)~\/[^\s]+/,
|
|
5828
|
-
/\b(?:api[_-]?key|secret|token|password|passwd|pwd|client[_-]?secret|access[_-]?key)\b\s*[:=]\s*\S+/i,
|
|
5829
|
-
/\b(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\])(?::\d+)?\b/i,
|
|
5830
|
-
/\b(?:10|127)\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/,
|
|
5831
|
-
/\b192\.168\.\d{1,3}\.\d{1,3}\b/,
|
|
5832
|
-
/\b172\.(?:1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}\b/
|
|
5833
|
-
];
|
|
5834
|
-
function hasShareabilitySensitiveText(text) {
|
|
5835
|
-
try {
|
|
5836
|
-
if (sanitizeDiagnosticText(text) !== text)
|
|
5837
|
-
return true;
|
|
5838
|
-
return SHAREABILITY_SENSITIVE_PATTERNS.some((pattern) => pattern.test(text));
|
|
5839
|
-
} catch {
|
|
5840
|
-
return true;
|
|
5841
|
-
}
|
|
5842
|
-
}
|
|
5843
|
-
|
|
5844
5674
|
// ../plugin/src/features/magic-context/dreamer/classify-prompt.ts
|
|
5845
5675
|
var SCORING_GUIDANCE = `### How to score importance (1-100)
|
|
5846
5676
|
Importance decides which memories survive when the injected memory block is over budget: high scores stay in context, low scores drop first. So the score is only useful if it **discriminates** — if most memories land in the same band, you have not classified them, you have just labelled them.
|
|
@@ -6889,15 +6719,60 @@ function getAsyncModule() {
|
|
|
6889
6719
|
})();
|
|
6890
6720
|
return asyncModulePromise;
|
|
6891
6721
|
}
|
|
6722
|
+
function acquireSandboxModule(signal) {
|
|
6723
|
+
const modulePromise = getAsyncModule();
|
|
6724
|
+
if (!signal)
|
|
6725
|
+
return modulePromise;
|
|
6726
|
+
if (signal.aborted) {
|
|
6727
|
+
return Promise.reject(signal.reason ?? new Error("smart-note check aborted"));
|
|
6728
|
+
}
|
|
6729
|
+
return new Promise((resolve, reject) => {
|
|
6730
|
+
const cleanup = () => signal.removeEventListener("abort", onAbort);
|
|
6731
|
+
const onAbort = () => {
|
|
6732
|
+
cleanup();
|
|
6733
|
+
reject(signal.reason ?? new Error("smart-note check aborted"));
|
|
6734
|
+
};
|
|
6735
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
6736
|
+
modulePromise.then((module) => {
|
|
6737
|
+
cleanup();
|
|
6738
|
+
resolve(module);
|
|
6739
|
+
}, (error) => {
|
|
6740
|
+
cleanup();
|
|
6741
|
+
reject(error);
|
|
6742
|
+
});
|
|
6743
|
+
});
|
|
6744
|
+
}
|
|
6892
6745
|
var sandboxRunChain = Promise.resolve();
|
|
6893
|
-
function withSandboxLock(fn) {
|
|
6894
|
-
const
|
|
6746
|
+
function withSandboxLock(fn, signal, cancelled) {
|
|
6747
|
+
const start = () => signal?.aborted && cancelled ? cancelled() : fn();
|
|
6748
|
+
const run = sandboxRunChain.then(start, start);
|
|
6895
6749
|
sandboxRunChain = run.then(() => {
|
|
6896
6750
|
return;
|
|
6897
6751
|
}, () => {
|
|
6898
6752
|
return;
|
|
6899
6753
|
});
|
|
6900
|
-
return run;
|
|
6754
|
+
return resolveBeforeAbort(run, signal, cancelled);
|
|
6755
|
+
}
|
|
6756
|
+
function resolveBeforeAbort(run, signal, cancelled) {
|
|
6757
|
+
if (!signal || !cancelled)
|
|
6758
|
+
return run;
|
|
6759
|
+
if (signal.aborted)
|
|
6760
|
+
return Promise.resolve(cancelled());
|
|
6761
|
+
return new Promise((resolve, reject) => {
|
|
6762
|
+
const cleanup = () => signal.removeEventListener("abort", abort);
|
|
6763
|
+
const abort = () => {
|
|
6764
|
+
cleanup();
|
|
6765
|
+
resolve(cancelled());
|
|
6766
|
+
};
|
|
6767
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
6768
|
+
run.then((result) => {
|
|
6769
|
+
cleanup();
|
|
6770
|
+
resolve(result);
|
|
6771
|
+
}, (error) => {
|
|
6772
|
+
cleanup();
|
|
6773
|
+
reject(error);
|
|
6774
|
+
});
|
|
6775
|
+
});
|
|
6901
6776
|
}
|
|
6902
6777
|
var DEFAULT_TIMEOUT_MS = 2000;
|
|
6903
6778
|
var DEFAULT_HEAP_LIMIT_BYTES = 8 * 1024 * 1024;
|
|
@@ -6924,9 +6799,17 @@ async function runCompiledSmartNoteCheck(options) {
|
|
|
6924
6799
|
if (Buffer.byteLength(options.compiledCheck, "utf8") > MAX_COMPILED_CHECK_BYTES) {
|
|
6925
6800
|
return failureResult("compiled check exceeds 64 KiB", false);
|
|
6926
6801
|
}
|
|
6927
|
-
|
|
6802
|
+
let quickjs;
|
|
6803
|
+
try {
|
|
6804
|
+
quickjs = await acquireSandboxModule(options.signal);
|
|
6805
|
+
} catch (error) {
|
|
6806
|
+
if (options.signal?.aborted)
|
|
6807
|
+
return cancelledResult(options.signal.reason);
|
|
6808
|
+
return failureResult(formatSandboxError(error), false);
|
|
6809
|
+
}
|
|
6810
|
+
return withSandboxLock(() => runCompiledSmartNoteCheckLocked(options, quickjs), options.signal, () => cancelledResult(options.signal?.reason));
|
|
6928
6811
|
}
|
|
6929
|
-
async function runCompiledSmartNoteCheckLocked(options) {
|
|
6812
|
+
async function runCompiledSmartNoteCheckLocked(options, quickjs) {
|
|
6930
6813
|
if (options.signal?.aborted)
|
|
6931
6814
|
return cancelledResult(options.signal.reason);
|
|
6932
6815
|
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
@@ -6946,8 +6829,6 @@ async function runCompiledSmartNoteCheckLocked(options) {
|
|
|
6946
6829
|
throwIfRunAborted(controller.signal);
|
|
6947
6830
|
const capabilities = resolveCapabilitiesForRun(options, controller.signal);
|
|
6948
6831
|
const deadline = Date.now() + timeoutMs;
|
|
6949
|
-
const quickjs = await getAsyncModule();
|
|
6950
|
-
throwIfRunAborted(controller.signal);
|
|
6951
6832
|
const context = quickjs.newContext();
|
|
6952
6833
|
try {
|
|
6953
6834
|
context.runtime.setMemoryLimit(options.heapLimitBytes ?? DEFAULT_HEAP_LIMIT_BYTES);
|
|
@@ -7552,7 +7433,7 @@ async function evaluateSmartNotes(args) {
|
|
|
7552
7433
|
projectIdentity: args.projectIdentity,
|
|
7553
7434
|
projectRoot,
|
|
7554
7435
|
maxChecks: 10,
|
|
7555
|
-
sweepBudgetMs: 1e4,
|
|
7436
|
+
sweepBudgetMs: args.sweepBudgetMs ?? 1e4,
|
|
7556
7437
|
leaseHeld,
|
|
7557
7438
|
signal: leaseAbortController.signal,
|
|
7558
7439
|
retinaHandoff: args.retinaHandoff
|
|
@@ -8077,19 +7958,26 @@ function parseMapMemoriesManifest(text) {
|
|
|
8077
7958
|
if (out.length === 0 && body.trim().length > 0) {
|
|
8078
7959
|
throw new Error(describeUnrecognizedManifestShape(text, "mappings", "memory"));
|
|
8079
7960
|
}
|
|
8080
|
-
assertNoDuplicateManifestIds(out.map((entry) => entry.id), "mappings");
|
|
8081
7961
|
return out;
|
|
8082
7962
|
}
|
|
8083
7963
|
function validateMapMemoriesManifest(text, expectedIds) {
|
|
8084
7964
|
const parsed = parseMapMemoriesManifest(text);
|
|
8085
7965
|
assertParsedManifestNonEmpty(parsed.length, expectedIds.size, text, "mappings", "memory");
|
|
8086
|
-
|
|
7966
|
+
assertNoDuplicateManifestIds(parsed.filter((entry) => expectedIds.has(entry.id)).map((entry) => entry.id), "mappings");
|
|
8087
7967
|
return parsed;
|
|
8088
7968
|
}
|
|
8089
7969
|
|
|
8090
7970
|
// ../plugin/src/features/magic-context/dreamer/map-memories.ts
|
|
8091
7971
|
var MAP_BATCH_SIZE = 80;
|
|
7972
|
+
var MAP_BATCH_FLOOR_MS = 240000;
|
|
7973
|
+
var CONSECUTIVE_TIMEOUT_LIMIT2 = 2;
|
|
8092
7974
|
var MAX_INDEPENDENT_REQUEUE_PER_RUN = MAP_BATCH_SIZE;
|
|
7975
|
+
function computeMapBatchSliceMs(remainingMs, batchesRemaining) {
|
|
7976
|
+
return Math.min(remainingMs, Math.max(MAP_BATCH_FLOOR_MS, Math.floor(remainingMs / batchesRemaining)));
|
|
7977
|
+
}
|
|
7978
|
+
function isTimeoutClassError2(error) {
|
|
7979
|
+
return error instanceof Error && /^prompt timed out after \d+ms$/.test(error.message);
|
|
7980
|
+
}
|
|
8093
7981
|
function shouldRequeueIndependentMapping(state2, content, repoDir) {
|
|
8094
7982
|
if (!state2.hasSentinel || state2.files.length > 0)
|
|
8095
7983
|
return false;
|
|
@@ -8137,27 +8025,64 @@ async function mapMemories(args) {
|
|
|
8137
8025
|
return result;
|
|
8138
8026
|
const batches = [];
|
|
8139
8027
|
for (let i = 0;i < inputs.length; i += MAP_BATCH_SIZE) {
|
|
8140
|
-
batches.push(inputs.slice(i, i + MAP_BATCH_SIZE));
|
|
8028
|
+
batches.push({ inputs: inputs.slice(i, i + MAP_BATCH_SIZE), isOmissionRetry: false });
|
|
8141
8029
|
}
|
|
8142
8030
|
result.remaining = inputs.length;
|
|
8143
8031
|
const abortController = new AbortController;
|
|
8144
8032
|
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort(), args.leaseAcquisition);
|
|
8145
8033
|
try {
|
|
8034
|
+
let consecutiveTimeouts = 0;
|
|
8035
|
+
let timeoutStreakElapsedMs = [];
|
|
8146
8036
|
for (let i = 0;i < batches.length; i += 1) {
|
|
8147
8037
|
const remainingMs = Math.max(0, args.deadline - Date.now());
|
|
8148
|
-
if (remainingMs <= 0)
|
|
8038
|
+
if (remainingMs <= 0) {
|
|
8039
|
+
result.stopReason = "deadline";
|
|
8149
8040
|
break;
|
|
8150
|
-
|
|
8151
|
-
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
|
|
8041
|
+
}
|
|
8042
|
+
if (remainingMs < MAP_BATCH_FLOOR_MS) {
|
|
8043
|
+
result.stopReason = "deadline";
|
|
8044
|
+
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)`);
|
|
8045
|
+
break;
|
|
8046
|
+
}
|
|
8047
|
+
const sliceMs = computeMapBatchSliceMs(remainingMs, batches.length - i);
|
|
8048
|
+
const batch = batches[i];
|
|
8049
|
+
if (!batch)
|
|
8050
|
+
break;
|
|
8051
|
+
const outcome = await mapOneBatch(args, batch.inputs, sliceMs, abortController.signal);
|
|
8052
|
+
const committed = outcome.mapped + outcome.independent;
|
|
8053
|
+
result.mapped += outcome.mapped;
|
|
8054
|
+
result.independent += outcome.independent;
|
|
8055
|
+
result.remaining -= committed;
|
|
8056
|
+
if (committed > 0) {
|
|
8057
|
+
result.batches += 1;
|
|
8058
|
+
args.onProgress?.(result.mapped + result.independent);
|
|
8059
|
+
}
|
|
8060
|
+
if (outcome.requeue?.length) {
|
|
8061
|
+
if (!batch.isOmissionRetry) {
|
|
8062
|
+
batches.splice(i + 1, 0, {
|
|
8063
|
+
inputs: outcome.requeue,
|
|
8064
|
+
isOmissionRetry: true
|
|
8065
|
+
});
|
|
8066
|
+
log(`[dreamer] map-memories: committed ${committed}/${batch.inputs.length} mapping(s); requeueing ${outcome.requeue.length} omitted id(s) in a targeted retry`);
|
|
8067
|
+
} else {
|
|
8068
|
+
log(`[dreamer] map-memories: targeted retry still omitted ${outcome.requeue.length} id(s); leaving them unmapped for the next run`);
|
|
8069
|
+
}
|
|
8070
|
+
}
|
|
8071
|
+
if (outcome.failure?.class === "timeout") {
|
|
8072
|
+
consecutiveTimeouts += 1;
|
|
8073
|
+
timeoutStreakElapsedMs.push(outcome.failure.elapsedMs);
|
|
8074
|
+
if (consecutiveTimeouts >= CONSECUTIVE_TIMEOUT_LIMIT2) {
|
|
8075
|
+
result.stopReason = "timeout-circuit-breaker";
|
|
8076
|
+
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`);
|
|
8077
|
+
break;
|
|
8078
|
+
}
|
|
8079
|
+
} else {
|
|
8080
|
+
consecutiveTimeouts = 0;
|
|
8081
|
+
timeoutStreakElapsedMs = [];
|
|
8082
|
+
}
|
|
8158
8083
|
}
|
|
8159
8084
|
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}`);
|
|
8085
|
+
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
8086
|
return result;
|
|
8162
8087
|
} finally {
|
|
8163
8088
|
heartbeat.stop();
|
|
@@ -8211,12 +8136,16 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
8211
8136
|
const text = extractLatestAssistantText(messages);
|
|
8212
8137
|
if (!text)
|
|
8213
8138
|
throw new Error("map-memories returned no output");
|
|
8214
|
-
validateMapMemoriesManifest(text, new Set(batch.map((memory) => memory.id)));
|
|
8215
|
-
return text;
|
|
8139
|
+
return validateMapMemoriesManifest(text, new Set(batch.map((memory) => memory.id)));
|
|
8216
8140
|
}
|
|
8217
8141
|
});
|
|
8218
8142
|
recordInvocation2(args, startedAt, { status: "completed", messages: run.output });
|
|
8219
|
-
|
|
8143
|
+
const outcome = await applyParsedBatchMappings(args, batch, run.validated);
|
|
8144
|
+
const returnedIds = new Set(run.validated.filter((entry) => batch.some((memory) => memory.id === entry.id)).map((entry) => entry.id));
|
|
8145
|
+
return {
|
|
8146
|
+
...outcome,
|
|
8147
|
+
requeue: batch.filter((memory) => !returnedIds.has(memory.id))
|
|
8148
|
+
};
|
|
8220
8149
|
} catch (error) {
|
|
8221
8150
|
const desc = describeError(error);
|
|
8222
8151
|
log(`[dreamer] map-memories batch failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
|
|
@@ -8225,7 +8154,14 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
8225
8154
|
throw error;
|
|
8226
8155
|
if (signal.aborted)
|
|
8227
8156
|
throw error;
|
|
8228
|
-
return {
|
|
8157
|
+
return {
|
|
8158
|
+
mapped: 0,
|
|
8159
|
+
independent: 0,
|
|
8160
|
+
failure: {
|
|
8161
|
+
class: isTimeoutClassError2(error) ? "timeout" : "other",
|
|
8162
|
+
elapsedMs: Date.now() - startedAt
|
|
8163
|
+
}
|
|
8164
|
+
};
|
|
8229
8165
|
} finally {
|
|
8230
8166
|
if (agentSessionId && !shouldKeepSubagents()) {
|
|
8231
8167
|
await args.client.session.delete({
|
|
@@ -8237,14 +8173,21 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
8237
8173
|
}
|
|
8238
8174
|
}
|
|
8239
8175
|
}
|
|
8240
|
-
async function
|
|
8241
|
-
const batchIds = new Set(batch.map((
|
|
8242
|
-
const
|
|
8243
|
-
|
|
8244
|
-
if (
|
|
8176
|
+
async function applyParsedBatchMappings(args, batch, parsed) {
|
|
8177
|
+
const batchIds = new Set(batch.map((memory) => memory.id));
|
|
8178
|
+
const valid = parsed.filter((entry) => batchIds.has(entry.id));
|
|
8179
|
+
const unknown = parsed.filter((entry) => !batchIds.has(entry.id));
|
|
8180
|
+
if (unknown.length > 0) {
|
|
8181
|
+
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(", ")})`);
|
|
8182
|
+
}
|
|
8183
|
+
assertNoDuplicateManifestIds(valid.map((entry) => entry.id), "mappings");
|
|
8184
|
+
if (valid.length * 2 < batch.length) {
|
|
8185
|
+
throw new Error(`mappings manifest covers ${valid.length}/${batch.length} batch ids after filtering unknown entries; rejecting mostly-wrong manifest`);
|
|
8186
|
+
}
|
|
8187
|
+
if (valid.length === 0)
|
|
8245
8188
|
return { mapped: 0, independent: 0 };
|
|
8246
8189
|
const planned = [];
|
|
8247
|
-
for (const p of
|
|
8190
|
+
for (const p of valid) {
|
|
8248
8191
|
if (p.independent) {
|
|
8249
8192
|
planned.push({ id: p.id, files: [], independent: true });
|
|
8250
8193
|
continue;
|
|
@@ -9549,14 +9492,13 @@ function parseVerifyManifest(text) {
|
|
|
9549
9492
|
if (verifyIds(out).length === 0 && body.trim().length > 0) {
|
|
9550
9493
|
throw new Error(describeUnrecognizedManifestShape(text, "verify", "verified"));
|
|
9551
9494
|
}
|
|
9552
|
-
assertNoDuplicateManifestIds(verifyIds(out), "verify");
|
|
9553
9495
|
return out;
|
|
9554
9496
|
}
|
|
9555
9497
|
function validateVerifyManifest(text, expectedIds) {
|
|
9556
9498
|
const parsed = parseVerifyManifest(text);
|
|
9557
9499
|
const ids = verifyIds(parsed);
|
|
9558
9500
|
assertParsedManifestNonEmpty(ids.length, expectedIds.size, text, "verify", "verified");
|
|
9559
|
-
|
|
9501
|
+
assertNoDuplicateManifestIds(ids.filter((id) => expectedIds.has(id)), "verify");
|
|
9560
9502
|
return parsed;
|
|
9561
9503
|
}
|
|
9562
9504
|
|
|
@@ -9709,19 +9651,14 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
9709
9651
|
const text = extractLatestAssistantText(messages);
|
|
9710
9652
|
if (!text)
|
|
9711
9653
|
throw new Error("verify returned no output");
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
if (providerFailure)
|
|
9717
|
-
throw providerFailure;
|
|
9718
|
-
throw error;
|
|
9719
|
-
}
|
|
9720
|
-
return text;
|
|
9654
|
+
const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
|
|
9655
|
+
if (providerFailure)
|
|
9656
|
+
throw providerFailure;
|
|
9657
|
+
return validateVerifyManifest(text, new Set(batch.map((memory) => memory.id)));
|
|
9721
9658
|
}
|
|
9722
9659
|
});
|
|
9723
9660
|
recordInvocation4(args, startedAt, { status: "completed", messages: run.output });
|
|
9724
|
-
return await
|
|
9661
|
+
return await applyParsedVerifyManifest(args, batch, run.validated);
|
|
9725
9662
|
} catch (error) {
|
|
9726
9663
|
const desc = describeError(error);
|
|
9727
9664
|
const providerFailure = error instanceof DreamerProviderOutputFailureError ? error : undefined;
|
|
@@ -9741,17 +9678,31 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
9741
9678
|
}
|
|
9742
9679
|
}
|
|
9743
9680
|
}
|
|
9744
|
-
async function
|
|
9681
|
+
async function applyParsedVerifyManifest(args, batch, parsed) {
|
|
9745
9682
|
const batchIds = new Set(batch.map((m) => m.id));
|
|
9746
|
-
const
|
|
9747
|
-
|
|
9683
|
+
const valid = {
|
|
9684
|
+
verified: parsed.verified.filter((entry) => batchIds.has(entry.id)),
|
|
9685
|
+
updated: parsed.updated.filter((entry) => batchIds.has(entry.id)),
|
|
9686
|
+
archived: parsed.archived.filter((entry) => batchIds.has(entry.id))
|
|
9687
|
+
};
|
|
9688
|
+
const unknown = [...parsed.verified, ...parsed.updated, ...parsed.archived].filter((entry) => !batchIds.has(entry.id));
|
|
9689
|
+
if (unknown.length > 0) {
|
|
9690
|
+
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(", ")})`);
|
|
9691
|
+
}
|
|
9692
|
+
const validIds = [...valid.verified, ...valid.updated, ...valid.archived].map((entry) => entry.id);
|
|
9693
|
+
assertNoDuplicateManifestIds(validIds, "verify");
|
|
9694
|
+
if (validIds.length * 2 < batch.length) {
|
|
9695
|
+
throw new Error(`verify manifest covers ${validIds.length}/${batch.length} batch ids after filtering unknown entries; rejecting mostly-wrong manifest`);
|
|
9696
|
+
}
|
|
9697
|
+
if (validIds.length === 0)
|
|
9698
|
+
return { verified: 0, updated: 0, archived: 0 };
|
|
9748
9699
|
const now = Date.now();
|
|
9749
9700
|
const writes = [];
|
|
9750
|
-
for (const v of
|
|
9701
|
+
for (const v of valid.verified) {
|
|
9751
9702
|
const files = await normalizeFiles(args, v.files);
|
|
9752
9703
|
writes.push({ kind: "verify", id: v.id, files });
|
|
9753
9704
|
}
|
|
9754
|
-
for (const u of
|
|
9705
|
+
for (const u of valid.updated) {
|
|
9755
9706
|
const content = u.content.trim();
|
|
9756
9707
|
if (!content || content.length > 20000) {
|
|
9757
9708
|
const files2 = await normalizeFiles(args, u.files);
|
|
@@ -9767,7 +9718,7 @@ async function applyVerifyManifest(args, batch, manifestText) {
|
|
|
9767
9718
|
hash: computeNormalizedHash(content)
|
|
9768
9719
|
});
|
|
9769
9720
|
}
|
|
9770
|
-
for (const a of
|
|
9721
|
+
for (const a of valid.archived) {
|
|
9771
9722
|
writes.push({ kind: "archive", id: a.id, reason: a.reason });
|
|
9772
9723
|
}
|
|
9773
9724
|
if (writes.length === 0)
|
|
@@ -10074,7 +10025,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
10074
10025
|
leaseKey,
|
|
10075
10026
|
deadline,
|
|
10076
10027
|
leaseAcquisition,
|
|
10077
|
-
model: config.model
|
|
10028
|
+
model: config.model,
|
|
10078
10029
|
fallbackModels: config.fallbackModels,
|
|
10079
10030
|
moduleRoute,
|
|
10080
10031
|
onProgress: (processed) => reportProgress(processed)
|
|
@@ -10123,8 +10074,19 @@ function createDreamTaskExecutor(deps) {
|
|
|
10123
10074
|
moduleRoute,
|
|
10124
10075
|
onProgress: (processed) => reportProgress(processed)
|
|
10125
10076
|
});
|
|
10126
|
-
log(`[dreamer] map-memories: mapped=${result.mapped} independent=${result.independent} batches=${result.batches} remaining=${result.remaining}`);
|
|
10077
|
+
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
10078
|
if (!result.complete) {
|
|
10079
|
+
if (result.stopReason === "timeout-circuit-breaker") {
|
|
10080
|
+
const error2 = `map-memories starvation: timeout circuit breaker stopped the run with ${result.remaining} remain`;
|
|
10081
|
+
recordRun("failed", error2);
|
|
10082
|
+
return { status: "failed", transient: true, error: error2 };
|
|
10083
|
+
}
|
|
10084
|
+
const processed = result.mapped + result.independent;
|
|
10085
|
+
if (processed > 0) {
|
|
10086
|
+
const progress = `map-memories: committed ${processed} mapping(s) (mapped ${result.mapped}, independent ${result.independent}); ${result.remaining} remain`;
|
|
10087
|
+
recordRun("completed", null, { progress });
|
|
10088
|
+
return { status: "completed" };
|
|
10089
|
+
}
|
|
10128
10090
|
const error = incompleteMessage(result.remaining);
|
|
10129
10091
|
recordRun("failed", error);
|
|
10130
10092
|
return { status: "failed", transient: true, error };
|
|
@@ -11235,7 +11197,7 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
|
|
|
11235
11197
|
}
|
|
11236
11198
|
try {
|
|
11237
11199
|
await runCompiledSmartNoteSweep(reg, db);
|
|
11238
|
-
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreamerConfig, reg.language);
|
|
11200
|
+
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreamerConfig, "opencode", reg.language, reg.mural?.model);
|
|
11239
11201
|
const executor = createDreamTaskExecutor({
|
|
11240
11202
|
client: reg.client,
|
|
11241
11203
|
sessionDirectory: reg.directory,
|
|
@@ -11245,7 +11207,6 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
|
|
|
11245
11207
|
userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreamerConfig),
|
|
11246
11208
|
ensureProjectRegistered: reg.ensureRegistered,
|
|
11247
11209
|
language: reg.language,
|
|
11248
|
-
dreamerModel: dreamerConfig.model,
|
|
11249
11210
|
mural: reg.mural,
|
|
11250
11211
|
memoryInjectionBudgetTokens: reg.memoryInjectionBudgetTokens,
|
|
11251
11212
|
retinaHandoff: reg.retinaHandoff,
|
|
@@ -11631,11 +11592,13 @@ function registerPiDreamerProject(opts) {
|
|
|
11631
11592
|
startDreamScheduleTimerFn({
|
|
11632
11593
|
directory: opts.projectDir,
|
|
11633
11594
|
projectIdentity: opts.projectIdentity,
|
|
11595
|
+
harness: "pi",
|
|
11634
11596
|
client,
|
|
11635
11597
|
dreamerConfig: opts.config,
|
|
11636
11598
|
language: opts.language,
|
|
11637
11599
|
gitCommitIndexing: opts.gitCommitIndexing,
|
|
11638
11600
|
retinaHandoff: opts.retinaHandoff,
|
|
11601
|
+
mural: opts.mural,
|
|
11639
11602
|
ensureRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
11640
11603
|
retrospectiveRawProvider: () => new PiRetrospectiveRawProvider({ projectCwd: opts.projectDir }),
|
|
11641
11604
|
primerRawProviderFactory: createPiPrimerRawProviderFactory()
|
|
@@ -11649,7 +11612,7 @@ function registerPiDreamerProject(opts) {
|
|
|
11649
11612
|
const runManual = async (task) => runManualDream({
|
|
11650
11613
|
db: opts.db,
|
|
11651
11614
|
projectIdentity: opts.projectIdentity,
|
|
11652
|
-
tasks: buildDreamTaskRuntimeConfigs(opts.config, opts.language),
|
|
11615
|
+
tasks: buildDreamTaskRuntimeConfigs(opts.config, "pi", opts.language, opts.mural?.model),
|
|
11653
11616
|
executor: createDreamTaskExecutor({
|
|
11654
11617
|
client,
|
|
11655
11618
|
sessionDirectory: opts.projectDir,
|
|
@@ -11661,7 +11624,8 @@ function registerPiDreamerProject(opts) {
|
|
|
11661
11624
|
userMemoryCollectionEnabled: userMemoryCollectionEnabled(opts.config),
|
|
11662
11625
|
ensureProjectRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
11663
11626
|
language: opts.language,
|
|
11664
|
-
retinaHandoff: opts.retinaHandoff
|
|
11627
|
+
retinaHandoff: opts.retinaHandoff,
|
|
11628
|
+
mural: opts.mural
|
|
11665
11629
|
}),
|
|
11666
11630
|
task
|
|
11667
11631
|
});
|
|
@@ -11697,7 +11661,6 @@ async function awaitInFlightDreamers() {
|
|
|
11697
11661
|
}
|
|
11698
11662
|
function createPiDreamerClient(opts) {
|
|
11699
11663
|
const runner = piSubagentRunnerFactory();
|
|
11700
|
-
const model = opts.config.model;
|
|
11701
11664
|
const session = {
|
|
11702
11665
|
create: async (args) => {
|
|
11703
11666
|
const sessionId = `magic-context-pi-dream-${++sessionCounter}`;
|
|
@@ -11718,7 +11681,7 @@ function createPiDreamerClient(opts) {
|
|
|
11718
11681
|
}
|
|
11719
11682
|
const userMessage = extractUserMessage(args);
|
|
11720
11683
|
const systemPrompt = extractSystemPrompt(args);
|
|
11721
|
-
const perTaskModel = extractBodyModel(args)
|
|
11684
|
+
const perTaskModel = extractBodyModel(args);
|
|
11722
11685
|
const requestedAgent = extractBodyAgent(args) ?? "magic-context-dreamer";
|
|
11723
11686
|
const runPromise = runner.run({
|
|
11724
11687
|
agent: requestedAgent,
|
|
@@ -11729,7 +11692,7 @@ function createPiDreamerClient(opts) {
|
|
|
11729
11692
|
timeoutMs: 30 * 60 * 1000,
|
|
11730
11693
|
cwd: dreamSession.directory,
|
|
11731
11694
|
signal: args.signal ?? undefined,
|
|
11732
|
-
thinkingLevel:
|
|
11695
|
+
thinkingLevel: extractBodyVariant(args)
|
|
11733
11696
|
});
|
|
11734
11697
|
inFlightDreams.add(runPromise);
|
|
11735
11698
|
try {
|
|
@@ -11820,6 +11783,13 @@ function extractBodyModel(args) {
|
|
|
11820
11783
|
}
|
|
11821
11784
|
return;
|
|
11822
11785
|
}
|
|
11786
|
+
function extractBodyVariant(args) {
|
|
11787
|
+
const body = args.body;
|
|
11788
|
+
if (typeof body !== "object" || body === null)
|
|
11789
|
+
return;
|
|
11790
|
+
const variant = body.variant;
|
|
11791
|
+
return typeof variant === "string" && variant.length > 0 ? variant : undefined;
|
|
11792
|
+
}
|
|
11823
11793
|
function extractBodyAgent(args) {
|
|
11824
11794
|
const body = args.body;
|
|
11825
11795
|
if (typeof body !== "object" || body === null)
|
|
@@ -12019,6 +11989,28 @@ var embedPauseBySession = new Set;
|
|
|
12019
11989
|
var embedRunStateBySession = new Map;
|
|
12020
11990
|
var autoEmbedAttemptedBySession = new Set;
|
|
12021
11991
|
|
|
11992
|
+
// ../plugin/src/hooks/magic-context/format-embed-failure.ts
|
|
11993
|
+
function formatEmbedFailureSummary(embedded, remaining, failure) {
|
|
11994
|
+
const compartment = `compartment${embedded === 1 ? "" : "s"}`;
|
|
11995
|
+
if (!failure) {
|
|
11996
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} could not be embedded (the provider returned no result). Run /ctx-embed start again to retry them.`;
|
|
11997
|
+
}
|
|
11998
|
+
const retry = " Run /ctx-embed start again to retry them.";
|
|
11999
|
+
switch (failure.class) {
|
|
12000
|
+
case "substitution_rejected":
|
|
12001
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} rejected: ${failure.reason}. Fix: set embedding.model to the served spelling.`;
|
|
12002
|
+
case "http_error": {
|
|
12003
|
+
const fix = failure.reason.startsWith("HTTP 401") || failure.reason.startsWith("HTTP 403") ? " Fix: check embedding.api_key." : failure.reason.startsWith("HTTP 402") ? " Fix: check provider quota or billing." : failure.reason.startsWith("HTTP 404") ? " Fix: check embedding.endpoint and embedding.model." : failure.retryable ? retry : " Fix: check embedding.endpoint, embedding.model, and credentials.";
|
|
12004
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}.${fix}`;
|
|
12005
|
+
}
|
|
12006
|
+
case "invalid_envelope":
|
|
12007
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: configure an OpenAI-compatible embedding endpoint that returns data[].embedding.`;
|
|
12008
|
+
case "empty_result":
|
|
12009
|
+
case "transport_error":
|
|
12010
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}.${failure.retryable ? retry : ""}`;
|
|
12011
|
+
}
|
|
12012
|
+
}
|
|
12013
|
+
|
|
12022
12014
|
// ../plugin/src/hooks/magic-context/format-embed-status.ts
|
|
12023
12015
|
function formatEmbedStatusText(coverage, drain) {
|
|
12024
12016
|
if (!coverage.enabled) {
|
|
@@ -12168,7 +12160,7 @@ Paused at ${cov.session.embedded}/${cov.session.total} compartments embedded.`,
|
|
|
12168
12160
|
return {
|
|
12169
12161
|
text: `## /ctx-embed
|
|
12170
12162
|
|
|
12171
|
-
|
|
12163
|
+
${formatEmbedFailureSummary(outcome.embedded, outcome.remaining, outcome.failure)}`,
|
|
12172
12164
|
level: "info"
|
|
12173
12165
|
};
|
|
12174
12166
|
default:
|
|
@@ -12961,12 +12953,15 @@ function writeTransformDecisionRowOnDatabase(db, row, configureBusyTimeout) {
|
|
|
12961
12953
|
const systemHashNew = row.materialized ? row.systemHashNew : null;
|
|
12962
12954
|
const m0ModelKeyPrev = row.materialized ? row.m0ModelKeyPrev : null;
|
|
12963
12955
|
const m0ModelKeyNew = row.materialized ? row.m0ModelKeyNew : null;
|
|
12956
|
+
const m0ToolSetHashPrev = row.m0ToolSetHashPrev ?? null;
|
|
12957
|
+
const m0ToolSetHashNew = row.m0ToolSetHashNew ?? null;
|
|
12964
12958
|
db.prepare(`INSERT OR REPLACE INTO transform_decisions (
|
|
12965
12959
|
session_id, harness, message_id, ts_ms, decision, materialized,
|
|
12966
12960
|
materialize_reason, system_hash_prev, system_hash_new,
|
|
12961
|
+
m0_tool_set_hash_prev, m0_tool_set_hash_new,
|
|
12967
12962
|
m0_model_key_prev, m0_model_key_new, emergency, dropped_tokens,
|
|
12968
12963
|
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)));
|
|
12964
|
+
) 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
12965
|
db.prepare(`DELETE FROM transform_decisions
|
|
12971
12966
|
WHERE session_id = ? AND harness = ?
|
|
12972
12967
|
AND rowid NOT IN (
|
|
@@ -16022,6 +16017,17 @@ function isSyntheticMessage(message, index, input) {
|
|
|
16022
16017
|
const role = typeof message.role === "string" ? message.role : "";
|
|
16023
16018
|
return role === "system" || role === "custom" || role === "compactionSummary";
|
|
16024
16019
|
}
|
|
16020
|
+
function countRealPiUserMessages(input) {
|
|
16021
|
+
let count = 0;
|
|
16022
|
+
for (let index = 0;index < input.messages.length; index += 1) {
|
|
16023
|
+
const message = input.messages[index];
|
|
16024
|
+
if (!isRecord3(message) || message.role !== "user")
|
|
16025
|
+
continue;
|
|
16026
|
+
if (!isSyntheticMessage(message, index, input))
|
|
16027
|
+
count += 1;
|
|
16028
|
+
}
|
|
16029
|
+
return count;
|
|
16030
|
+
}
|
|
16025
16031
|
function imageContentAndTokens(part) {
|
|
16026
16032
|
const data = typeof part.data === "string" ? part.data : "";
|
|
16027
16033
|
const mimeType = typeof part.mimeType === "string" ? part.mimeType : "image/png";
|
|
@@ -16215,7 +16221,7 @@ function excludedDraft(key, value) {
|
|
|
16215
16221
|
tokens: 0
|
|
16216
16222
|
};
|
|
16217
16223
|
}
|
|
16218
|
-
function finalizeParts(drafts, protectedTags) {
|
|
16224
|
+
function finalizeParts(drafts, protectedTags, pendingDropTagNumbers) {
|
|
16219
16225
|
const visibleTags = new Map;
|
|
16220
16226
|
for (const part of drafts) {
|
|
16221
16227
|
if (part.kind !== "excluded" && part.tag)
|
|
@@ -16230,7 +16236,8 @@ function finalizeParts(drafts, protectedTags) {
|
|
|
16230
16236
|
const parts = drafts.map((draft) => {
|
|
16231
16237
|
const protectedPart = draft.tag ? protectedNumbers.has(draft.tag.tagNumber) : false;
|
|
16232
16238
|
const tokens = Math.max(0, draft.tokens);
|
|
16233
|
-
const
|
|
16239
|
+
const queuedForDrop = draft.tag ? pendingDropTagNumbers.has(draft.tag.tagNumber) : false;
|
|
16240
|
+
const uTokens = draft.tag && !protectedPart && !queuedForDrop && draft.kind !== "excluded" ? tokens : 0;
|
|
16234
16241
|
t += tokens;
|
|
16235
16242
|
u += uTokens;
|
|
16236
16243
|
return {
|
|
@@ -16241,7 +16248,8 @@ function finalizeParts(drafts, protectedTags) {
|
|
|
16241
16248
|
uTokens,
|
|
16242
16249
|
tagNumber: draft.tag?.tagNumber ?? null,
|
|
16243
16250
|
tagStatus: draft.tag ? "active" : null,
|
|
16244
|
-
protected: protectedPart
|
|
16251
|
+
protected: protectedPart,
|
|
16252
|
+
queuedForDrop
|
|
16245
16253
|
};
|
|
16246
16254
|
});
|
|
16247
16255
|
const clampedT = Math.max(0, t);
|
|
@@ -16383,29 +16391,34 @@ function measurePiTailHygiene(input) {
|
|
|
16383
16391
|
drafts.push(excludedDraft(`${key}\x00excluded`, part));
|
|
16384
16392
|
}
|
|
16385
16393
|
}
|
|
16386
|
-
return finalizeParts(drafts, input.protectedTags);
|
|
16394
|
+
return finalizeParts(drafts, input.protectedTags, input.pendingDropTagNumbers ?? new Set);
|
|
16387
16395
|
}
|
|
16388
16396
|
function sameMeasuredPrefix(baseline, current) {
|
|
16389
16397
|
if (current.length < baseline.length)
|
|
16390
|
-
return { valid: false, boundaryAdvanceU: 0 };
|
|
16398
|
+
return { valid: false, boundaryAdvanceU: 0, queuedDropDeltaU: 0 };
|
|
16391
16399
|
let boundaryAdvanceU = 0;
|
|
16400
|
+
let queuedDropDeltaU = 0;
|
|
16392
16401
|
for (let index = 0;index < baseline.length; index += 1) {
|
|
16393
16402
|
const before = baseline[index];
|
|
16394
16403
|
const after = current[index];
|
|
16395
16404
|
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 };
|
|
16405
|
+
return { valid: false, boundaryAdvanceU: 0, queuedDropDeltaU: 0 };
|
|
16397
16406
|
}
|
|
16398
16407
|
if (!before.protected && after.protected)
|
|
16399
|
-
return { valid: false, boundaryAdvanceU: 0 };
|
|
16408
|
+
return { valid: false, boundaryAdvanceU: 0, queuedDropDeltaU: 0 };
|
|
16400
16409
|
if (before.protected && !after.protected) {
|
|
16401
16410
|
if (after.tagStatus !== "active")
|
|
16402
|
-
return { valid: false, boundaryAdvanceU: 0 };
|
|
16403
|
-
boundaryAdvanceU += after.
|
|
16411
|
+
return { valid: false, boundaryAdvanceU: 0, queuedDropDeltaU: 0 };
|
|
16412
|
+
boundaryAdvanceU += after.uTokens;
|
|
16413
|
+
} else if (before.queuedForDrop !== after.queuedForDrop) {
|
|
16414
|
+
if (before.tagStatus !== "active" || after.tagStatus !== "active")
|
|
16415
|
+
return { valid: false, boundaryAdvanceU: 0, queuedDropDeltaU: 0 };
|
|
16416
|
+
queuedDropDeltaU += after.uTokens - before.uTokens;
|
|
16404
16417
|
} else if (before.uTokens !== after.uTokens) {
|
|
16405
|
-
return { valid: false, boundaryAdvanceU: 0 };
|
|
16418
|
+
return { valid: false, boundaryAdvanceU: 0, queuedDropDeltaU: 0 };
|
|
16406
16419
|
}
|
|
16407
16420
|
}
|
|
16408
|
-
return { valid: true, boundaryAdvanceU };
|
|
16421
|
+
return { valid: true, boundaryAdvanceU, queuedDropDeltaU };
|
|
16409
16422
|
}
|
|
16410
16423
|
function refreshPiTailHygieneBaseline(input) {
|
|
16411
16424
|
const measured = measurePiTailHygiene(input);
|
|
@@ -16437,7 +16450,7 @@ function refreshPiTailHygieneBaseline(input) {
|
|
|
16437
16450
|
};
|
|
16438
16451
|
}
|
|
16439
16452
|
let turnDeltaT = 0;
|
|
16440
|
-
let turnDeltaU = prefix.boundaryAdvanceU;
|
|
16453
|
+
let turnDeltaU = prefix.boundaryAdvanceU + prefix.queuedDropDeltaU;
|
|
16441
16454
|
for (let index = input.previous.baselineParts.length;index < measured.parts.length; index += 1) {
|
|
16442
16455
|
const part = measured.parts[index];
|
|
16443
16456
|
turnDeltaT += part.tokens;
|
|
@@ -16531,20 +16544,38 @@ function maybeChannel1ReminderForToolResult(args) {
|
|
|
16531
16544
|
if (deltaTokens === 0)
|
|
16532
16545
|
return null;
|
|
16533
16546
|
state2.turnDeltaT += deltaTokens;
|
|
16547
|
+
if (state2.agentDropsAppliedThisPass)
|
|
16548
|
+
return null;
|
|
16549
|
+
const nudgeState = getChannel1NudgeState(db, sessionId);
|
|
16534
16550
|
const decision = decideChannel1({
|
|
16535
16551
|
...state2,
|
|
16536
16552
|
lastNudgeUndropped: getLastNudgeUndropped(db, sessionId),
|
|
16537
|
-
lastNudgeLevel:
|
|
16553
|
+
lastNudgeLevel: nudgeState.level,
|
|
16538
16554
|
hasRecentReduce: state2.reducedSinceRefresh
|
|
16539
16555
|
});
|
|
16540
16556
|
setLastNudgeUndropped(db, sessionId, decision.nextLastNudge);
|
|
16541
|
-
|
|
16542
|
-
|
|
16557
|
+
if (!decision.fire) {
|
|
16558
|
+
setChannel1NudgeState(db, sessionId, {
|
|
16559
|
+
level: decision.nextLastNudgeLevel,
|
|
16560
|
+
ordinal: decision.nextLastNudgeLevel === "" ? 0 : nudgeState.ordinal
|
|
16561
|
+
});
|
|
16543
16562
|
return null;
|
|
16544
|
-
|
|
16563
|
+
}
|
|
16564
|
+
const sticky = shouldUseStickyChannel1Reminder({
|
|
16565
|
+
lastLevel: nudgeState.level,
|
|
16566
|
+
lastOrdinal: nudgeState.ordinal,
|
|
16567
|
+
level: decision.level,
|
|
16568
|
+
currentRealUserTurnCount: state2.realUserTurnCount
|
|
16569
|
+
});
|
|
16570
|
+
const block = {
|
|
16545
16571
|
type: "text",
|
|
16546
|
-
text: buildChannel1Reminder(decision.level, decision.undroppedTokens, state2.oldestReclaimableToolTags)
|
|
16572
|
+
text: buildChannel1Reminder(decision.level, decision.undroppedTokens, state2.usableWindow, state2.oldestReclaimableToolTags, sticky)
|
|
16547
16573
|
};
|
|
16574
|
+
setChannel1NudgeState(db, sessionId, {
|
|
16575
|
+
level: decision.level,
|
|
16576
|
+
ordinal: state2.realUserTurnCount
|
|
16577
|
+
});
|
|
16578
|
+
return block;
|
|
16548
16579
|
}
|
|
16549
16580
|
var CHANNEL2_NUDGE_CUSTOM_TYPE = "magic-context:ceiling-nudge";
|
|
16550
16581
|
function maybeDeliverChannel2Pi(pi, db, sessionId) {
|
|
@@ -16575,7 +16606,7 @@ function maybeDeliverChannel2Pi(pi, db, sessionId) {
|
|
|
16575
16606
|
try {
|
|
16576
16607
|
const message = {
|
|
16577
16608
|
customType: CHANNEL2_NUDGE_CUSTOM_TYPE,
|
|
16578
|
-
content: buildChannel2Reminder(undropped, baseline.oldestReclaimableToolTags),
|
|
16609
|
+
content: buildChannel2Reminder(undropped, baseline.usableWindow, baseline.oldestReclaimableToolTags),
|
|
16579
16610
|
display: false,
|
|
16580
16611
|
details: { kind: "channel-2-ceiling-nudge" }
|
|
16581
16612
|
};
|
|
@@ -21017,19 +21048,24 @@ async function runHistorianSubagentWithTransientRetries(args) {
|
|
|
21017
21048
|
}
|
|
21018
21049
|
return historianAbortResult(startedAt);
|
|
21019
21050
|
}
|
|
21020
|
-
function buildHistorianFallbackChain(primaryModel, fallbackModels, fallbackModelId) {
|
|
21021
|
-
const seen = new Set
|
|
21022
|
-
|
|
21023
|
-
|
|
21051
|
+
function buildHistorianFallbackChain(primaryModel, primaryThinkingLevel, fallbackModels, fallbackModelId) {
|
|
21052
|
+
const seen = new Set([
|
|
21053
|
+
`${primaryModel}\x00${primaryThinkingLevel ?? ""}`
|
|
21054
|
+
]);
|
|
21024
21055
|
const chain = [];
|
|
21025
21056
|
for (const candidate of fallbackModels ?? []) {
|
|
21026
|
-
|
|
21057
|
+
const entry = typeof candidate === "string" ? { model: candidate } : candidate;
|
|
21058
|
+
const key = `${entry.model}\x00${entry.qualifier ?? ""}`;
|
|
21059
|
+
if (!entry.model || seen.has(key))
|
|
21027
21060
|
continue;
|
|
21028
|
-
seen.add(
|
|
21029
|
-
chain.push({
|
|
21061
|
+
seen.add(key);
|
|
21062
|
+
chain.push({ entry, kind: "configured" });
|
|
21030
21063
|
}
|
|
21031
|
-
if (fallbackModelId
|
|
21032
|
-
|
|
21064
|
+
if (fallbackModelId) {
|
|
21065
|
+
const entry = { model: fallbackModelId };
|
|
21066
|
+
const key = `${entry.model}\x00`;
|
|
21067
|
+
if (!seen.has(key))
|
|
21068
|
+
chain.push({ entry, kind: "session" });
|
|
21033
21069
|
}
|
|
21034
21070
|
return chain;
|
|
21035
21071
|
}
|
|
@@ -21348,11 +21384,11 @@ ${chunkText}`,
|
|
|
21348
21384
|
validatedDraftText = repairResult.assistantText;
|
|
21349
21385
|
}
|
|
21350
21386
|
}
|
|
21351
|
-
const fallbackChain = buildHistorianFallbackChain(historianModel, fallbackModels, fallbackModelId);
|
|
21387
|
+
const fallbackChain = buildHistorianFallbackChain(historianModel, thinkingLevel, fallbackModels, fallbackModelId);
|
|
21352
21388
|
if (validatedPass.kind !== "ok" && !(validatedPass.kind === "spawn-failed" && validatedPass.reason === "abort") && fallbackChain.length > 0) {
|
|
21353
21389
|
for (let i = 0;i < fallbackChain.length; i += 1) {
|
|
21354
21390
|
const candidate = fallbackChain[i];
|
|
21355
|
-
sessionLog(sessionId, `historian: escalating to ${candidate.kind === "session" ? "session-model last resort" : "configured fallback model"} ${candidate.
|
|
21391
|
+
sessionLog(sessionId, `historian: escalating to ${candidate.kind === "session" ? "session-model last resort" : "configured fallback model"} ${candidate.entry.model}`);
|
|
21356
21392
|
const fbResult = await runHistorianSubagentWithTransientRetries({
|
|
21357
21393
|
runner,
|
|
21358
21394
|
sessionId,
|
|
@@ -21362,11 +21398,11 @@ ${chunkText}`,
|
|
|
21362
21398
|
agent: HISTORIAN_AGENT_NAME,
|
|
21363
21399
|
systemPrompt: historianSystemPrompt,
|
|
21364
21400
|
userMessage: prompt,
|
|
21365
|
-
model: candidate.
|
|
21401
|
+
model: candidate.entry.model,
|
|
21366
21402
|
timeoutMs: historianTimeoutMs,
|
|
21367
21403
|
cwd: directory,
|
|
21368
21404
|
signal,
|
|
21369
|
-
thinkingLevel,
|
|
21405
|
+
thinkingLevel: candidate.entry.qualifier,
|
|
21370
21406
|
onProgress: buildProgressLogger("fallback"),
|
|
21371
21407
|
accountingSessionId: sessionId,
|
|
21372
21408
|
accountingSubagent: "historian"
|
|
@@ -24475,11 +24511,13 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
24475
24511
|
if (!options.compactionOff && !sessionMetaForCh1.isSubagent) {
|
|
24476
24512
|
const tags = getTagsBySession(options.db, sessionId);
|
|
24477
24513
|
const protectedTags = options.protectedTags ?? 20;
|
|
24514
|
+
const pendingDropTagNumbers = new Set(getPendingOps(options.db, sessionId).filter((operation) => operation.operation === "drop").map((operation) => operation.tagId));
|
|
24478
24515
|
const stableId = (message) => message && typeof message === "object" ? result.postCommitEntryIdByRef.get(message) : undefined;
|
|
24479
24516
|
const baseline = refreshPiTailHygieneBaseline({
|
|
24480
24517
|
messages: outputMessages,
|
|
24481
24518
|
tags,
|
|
24482
24519
|
protectedTags,
|
|
24520
|
+
pendingDropTagNumbers,
|
|
24483
24521
|
stableId,
|
|
24484
24522
|
syntheticLeadingCount: result.syntheticLeadingCount,
|
|
24485
24523
|
cacheBusting: result.bustedThisPass,
|
|
@@ -24490,7 +24528,17 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
24490
24528
|
const oldestReclaimableToolTags = getOldestActiveUnprotectedToolTags(options.db, sessionId, protectedTags);
|
|
24491
24529
|
const channelState = {
|
|
24492
24530
|
...baseline,
|
|
24531
|
+
usableWindow: usageContextLimit ?? 0,
|
|
24532
|
+
realUserTurnCount: countRealPiUserMessages({
|
|
24533
|
+
messages: outputMessages,
|
|
24534
|
+
tags,
|
|
24535
|
+
protectedTags,
|
|
24536
|
+
pendingDropTagNumbers,
|
|
24537
|
+
stableId,
|
|
24538
|
+
syntheticLeadingCount: result.syntheticLeadingCount
|
|
24539
|
+
}),
|
|
24493
24540
|
reducedSinceRefresh: false,
|
|
24541
|
+
agentDropsAppliedThisPass: result.agentDropsAppliedThisPass,
|
|
24494
24542
|
oldestReclaimableToolTags
|
|
24495
24543
|
};
|
|
24496
24544
|
setPiChannel1Baseline(sessionId, channelState);
|
|
@@ -24515,6 +24563,7 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
24515
24563
|
messages: outputMessages,
|
|
24516
24564
|
tags,
|
|
24517
24565
|
protectedTags,
|
|
24566
|
+
pendingDropTagNumbers,
|
|
24518
24567
|
stableId,
|
|
24519
24568
|
syntheticLeadingCount: result.syntheticLeadingCount,
|
|
24520
24569
|
expectedSignature: baseline.contentSignature
|
|
@@ -25044,6 +25093,7 @@ async function runCompactionOffPipeline(args) {
|
|
|
25044
25093
|
droppedCount: 0,
|
|
25045
25094
|
emergency: false,
|
|
25046
25095
|
bustedThisPass: injectionResult?.m0Materialized === true,
|
|
25096
|
+
agentDropsAppliedThisPass: false,
|
|
25047
25097
|
targetCount: 0,
|
|
25048
25098
|
reasoningWatermark: args.sessionMeta.clearedReasoningThroughTag ?? 0,
|
|
25049
25099
|
activeTags: [],
|
|
@@ -25617,6 +25667,7 @@ async function runPipeline(args) {
|
|
|
25617
25667
|
droppedCount,
|
|
25618
25668
|
emergency,
|
|
25619
25669
|
bustedThisPass,
|
|
25670
|
+
agentDropsAppliedThisPass: pendingOpsDidMutate,
|
|
25620
25671
|
targetCount: targets.size,
|
|
25621
25672
|
reasoningWatermark: args.sessionMeta.clearedReasoningThroughTag ?? 0,
|
|
25622
25673
|
activeTags,
|
|
@@ -25909,6 +25960,7 @@ async function runValidatedHistorianPass(args) {
|
|
|
25909
25960
|
const firstRun = await runHistorianPrompt({
|
|
25910
25961
|
...args,
|
|
25911
25962
|
dumpLabel: `${args.dumpLabelBase}-initial`,
|
|
25963
|
+
modelOverride: args.model,
|
|
25912
25964
|
agentId: args.agentId
|
|
25913
25965
|
});
|
|
25914
25966
|
if (!firstRun.ok || !firstRun.result) {
|
|
@@ -25937,6 +25989,7 @@ async function runValidatedHistorianPass(args) {
|
|
|
25937
25989
|
...args,
|
|
25938
25990
|
prompt: repairPrompt,
|
|
25939
25991
|
dumpLabel: `${args.dumpLabelBase}-repair`,
|
|
25992
|
+
modelOverride: args.model,
|
|
25940
25993
|
agentId: args.agentId
|
|
25941
25994
|
});
|
|
25942
25995
|
if (!repairRun.ok || !repairRun.result) {
|
|
@@ -25977,7 +26030,8 @@ async function runEditorPassOrFallback(args) {
|
|
|
25977
26030
|
timeoutMs: args.timeoutMs,
|
|
25978
26031
|
dumpLabel: `${args.dumpLabelBase}-editor`,
|
|
25979
26032
|
agentId: HISTORIAN_EDITOR_AGENT,
|
|
25980
|
-
parentInvocationId: args.draftInvocationId ?? null
|
|
26033
|
+
parentInvocationId: args.draftInvocationId ?? null,
|
|
26034
|
+
modelOverride: args.model
|
|
25981
26035
|
});
|
|
25982
26036
|
if (!editorRun.ok || !editorRun.result) {
|
|
25983
26037
|
sessionLog(args.parentSessionId, "historian two-pass: editor call failed", {
|
|
@@ -26030,7 +26084,7 @@ async function runHistorianPrompt(args) {
|
|
|
26030
26084
|
});
|
|
26031
26085
|
};
|
|
26032
26086
|
try {
|
|
26033
|
-
sessionLog(parentSessionId, `historian: creating child session (agent=${
|
|
26087
|
+
sessionLog(parentSessionId, `historian: creating child session (agent=${toModelEntry(modelOverride)?.model ?? `agent:${agentId}`})`);
|
|
26034
26088
|
const createResponse = await createChildSessionWithFence({
|
|
26035
26089
|
client,
|
|
26036
26090
|
db,
|
|
@@ -26054,7 +26108,7 @@ async function runHistorianPrompt(args) {
|
|
|
26054
26108
|
query: { directory: sessionDirectory },
|
|
26055
26109
|
body: {
|
|
26056
26110
|
agent: agentId,
|
|
26057
|
-
...modelOverride
|
|
26111
|
+
...modelBodyField(modelOverride),
|
|
26058
26112
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
26059
26113
|
}
|
|
26060
26114
|
}, {
|
|
@@ -26124,10 +26178,21 @@ async function runHistorianPrompt(args) {
|
|
|
26124
26178
|
async function runFallbackHistorianPass(args) {
|
|
26125
26179
|
const seen = new Set;
|
|
26126
26180
|
const chain = [];
|
|
26127
|
-
|
|
26128
|
-
|
|
26181
|
+
const primary = toModelEntry(args.model);
|
|
26182
|
+
for (const candidateInput of [
|
|
26183
|
+
...args.fallbackModels ?? [],
|
|
26184
|
+
...args.fallbackModelId ? [{ model: args.fallbackModelId }] : []
|
|
26185
|
+
]) {
|
|
26186
|
+
const candidate = toModelEntry(candidateInput);
|
|
26187
|
+
if (!candidate)
|
|
26129
26188
|
continue;
|
|
26130
|
-
|
|
26189
|
+
const key = `${candidate.model}\x00${candidate.qualifier ?? ""}`;
|
|
26190
|
+
if (!candidate.model || seen.has(key))
|
|
26191
|
+
continue;
|
|
26192
|
+
if (primary?.model === candidate.model && primary.qualifier === candidate.qualifier) {
|
|
26193
|
+
continue;
|
|
26194
|
+
}
|
|
26195
|
+
seen.add(key);
|
|
26131
26196
|
chain.push(candidate);
|
|
26132
26197
|
}
|
|
26133
26198
|
if (chain.length === 0) {
|
|
@@ -26135,9 +26200,9 @@ async function runFallbackHistorianPass(args) {
|
|
|
26135
26200
|
}
|
|
26136
26201
|
let lastError = args.error;
|
|
26137
26202
|
for (let i = 0;i < chain.length; i += 1) {
|
|
26138
|
-
const
|
|
26139
|
-
const
|
|
26140
|
-
if (!
|
|
26203
|
+
const modelOverride = chain[i];
|
|
26204
|
+
const modelId = modelOverride.model;
|
|
26205
|
+
if (!parseModelOverride(modelId))
|
|
26141
26206
|
continue;
|
|
26142
26207
|
const isSessionModelLastResort = modelId === args.fallbackModelId && i === chain.length - 1;
|
|
26143
26208
|
sessionLog(args.parentSessionId, `compartment agent: retrying historian with ${modelId} (${isSessionModelLastResort ? "session-model last resort" : "configured fallback"} ${i + 1}/${chain.length})`);
|
|
@@ -26466,6 +26531,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
26466
26531
|
sequenceOffset: candidateCompartments.length,
|
|
26467
26532
|
dumpLabelBase: `recomp-${sessionId}-${chunk.startIndex}-${chunk.endIndex}-pass-${passCount + 1}`,
|
|
26468
26533
|
timeoutMs: historianTimeoutMs,
|
|
26534
|
+
model: deps.model,
|
|
26469
26535
|
fallbackModelId: deps.fallbackModelId,
|
|
26470
26536
|
fallbackModels: deps.fallbackModels,
|
|
26471
26537
|
twoPass: deps.historianTwoPass,
|
|
@@ -26886,6 +26952,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
26886
26952
|
sequenceOffset: candidateCompartments.length,
|
|
26887
26953
|
dumpLabelBase: `partial-recomp-${sessionId}-${chunk.startIndex}-${chunk.endIndex}-pass-${passCount + 1}`,
|
|
26888
26954
|
timeoutMs: historianTimeoutMs,
|
|
26955
|
+
model: deps.model,
|
|
26889
26956
|
fallbackModelId: deps.fallbackModelId,
|
|
26890
26957
|
fallbackModels: deps.fallbackModels,
|
|
26891
26958
|
twoPass: deps.historianTwoPass,
|
|
@@ -27077,11 +27144,11 @@ function createPiHistorianClient(args) {
|
|
|
27077
27144
|
agent: "magic-context-historian",
|
|
27078
27145
|
systemPrompt: args.systemPrompt,
|
|
27079
27146
|
userMessage: promptText,
|
|
27080
|
-
model: modelOverride ?? args.model,
|
|
27147
|
+
model: modelOverride?.model ?? args.model,
|
|
27081
27148
|
fallbackModels: modelOverride ? undefined : args.fallbackModels,
|
|
27082
27149
|
timeoutMs: args.timeoutMs,
|
|
27083
27150
|
cwd: args.directory,
|
|
27084
|
-
thinkingLevel: args.thinkingLevel,
|
|
27151
|
+
thinkingLevel: modelOverride ? modelOverride.qualifier : args.thinkingLevel,
|
|
27085
27152
|
accountingSessionId: args.accountingSessionId,
|
|
27086
27153
|
accountingSubagent: "recomp"
|
|
27087
27154
|
});
|
|
@@ -27129,7 +27196,8 @@ function readBodyModel(body) {
|
|
|
27129
27196
|
return;
|
|
27130
27197
|
const { providerID, modelID } = model;
|
|
27131
27198
|
if (typeof providerID === "string" && providerID.length > 0 && typeof modelID === "string" && modelID.length > 0) {
|
|
27132
|
-
|
|
27199
|
+
const qualifier = typeof body.variant === "string" && body.variant.length > 0 ? body.variant : undefined;
|
|
27200
|
+
return qualifier ? { model: `${providerID}/${modelID}`, qualifier } : { model: `${providerID}/${modelID}` };
|
|
27133
27201
|
}
|
|
27134
27202
|
return;
|
|
27135
27203
|
}
|
|
@@ -27739,13 +27807,17 @@ async function runPiMemoryMigration(deps) {
|
|
|
27739
27807
|
const prompt = buildMemoryMigrationPrompt(memories);
|
|
27740
27808
|
const modelChain = [];
|
|
27741
27809
|
const seenModels = new Set;
|
|
27742
|
-
for (const
|
|
27743
|
-
|
|
27744
|
-
|
|
27810
|
+
for (const candidate of [
|
|
27811
|
+
{
|
|
27812
|
+
model: deps.primaryModel ?? deps.model,
|
|
27813
|
+
...deps.primaryModel ? {} : deps.thinkingLevel ? { qualifier: deps.thinkingLevel } : {}
|
|
27814
|
+
},
|
|
27815
|
+
...(deps.fallbackModels ?? []).map((fallback) => typeof fallback === "string" ? { model: fallback } : fallback)
|
|
27745
27816
|
]) {
|
|
27746
|
-
|
|
27747
|
-
|
|
27748
|
-
|
|
27817
|
+
const key = `${candidate.model}\x00${candidate.qualifier ?? ""}`;
|
|
27818
|
+
if (candidate.model && !seenModels.has(key)) {
|
|
27819
|
+
seenModels.add(key);
|
|
27820
|
+
modelChain.push(candidate);
|
|
27749
27821
|
}
|
|
27750
27822
|
}
|
|
27751
27823
|
let parsed = null;
|
|
@@ -27753,17 +27825,17 @@ async function runPiMemoryMigration(deps) {
|
|
|
27753
27825
|
for (let i = 0;i < modelChain.length; i += 1) {
|
|
27754
27826
|
const model = modelChain[i];
|
|
27755
27827
|
if (i > 0) {
|
|
27756
|
-
sessionLog(deps.sessionId, `memory-migration: escalating to configured fallback model ${model} (${i}/${modelChain.length - 1})`);
|
|
27828
|
+
sessionLog(deps.sessionId, `memory-migration: escalating to configured fallback model ${model.model} (${i}/${modelChain.length - 1})`);
|
|
27757
27829
|
}
|
|
27758
27830
|
const result = await deps.runner.run({
|
|
27759
27831
|
agent: "magic-context-historian",
|
|
27760
27832
|
systemPrompt: withMigrationLanguageDirective(MIGRATION_SYSTEM_PROMPT2, deps.language),
|
|
27761
27833
|
userMessage: prompt,
|
|
27762
|
-
model,
|
|
27834
|
+
model: model.model,
|
|
27763
27835
|
fallbackModels: undefined,
|
|
27764
27836
|
timeoutMs: deps.timeoutMs ?? 5 * 60 * 1000,
|
|
27765
27837
|
cwd: deps.directory,
|
|
27766
|
-
thinkingLevel:
|
|
27838
|
+
thinkingLevel: model.qualifier,
|
|
27767
27839
|
accountingSessionId: deps.sessionId,
|
|
27768
27840
|
accountingSubagent: "recomp"
|
|
27769
27841
|
});
|
|
@@ -28277,7 +28349,7 @@ ${c.content}
|
|
|
28277
28349
|
// package.json
|
|
28278
28350
|
var package_default = {
|
|
28279
28351
|
name: "@cortexkit/pi-magic-context",
|
|
28280
|
-
version: "0.
|
|
28352
|
+
version: "0.40.0",
|
|
28281
28353
|
type: "module",
|
|
28282
28354
|
description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
|
|
28283
28355
|
main: "dist/index.js",
|
|
@@ -28308,7 +28380,7 @@ var package_default = {
|
|
|
28308
28380
|
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
28381
|
"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
28382
|
typecheck: "tsc -p ../retina-local-fs/tsconfig.build.json && tsc --noEmit",
|
|
28311
|
-
test: "bun test",
|
|
28383
|
+
test: "bun install --frozen-lockfile && bun test",
|
|
28312
28384
|
lint: "biome check src",
|
|
28313
28385
|
"lint:fix": "biome check --write src",
|
|
28314
28386
|
format: "biome format --write src",
|
|
@@ -28463,6 +28535,7 @@ function renderInner(s, theme, innerWidth) {
|
|
|
28463
28535
|
lines.push("* Conversation includes model Reasoning; hygiene excludes it.");
|
|
28464
28536
|
lines.push("");
|
|
28465
28537
|
lines.push(`Counts: ${s.compartmentCount} compartments · ${s.memoryCount} memories (${s.memoryBlockCount} injected) · ${s.sessionNoteCount + s.readySmartNoteCount} notes`);
|
|
28538
|
+
lines.push(`Active profile: ${s.activeProfile ?? "none"}`);
|
|
28466
28539
|
lines.push(`Historian: ${s.historianRunning ? theme.fg("warning", "running") : theme.fg("accent", "idle")}${s.historianFailureCount > 0 ? ` · ${theme.fg("error", `last failure ${s.historianLastFailureAt ? relTime(s.historianLastFailureAt) : "unknown"}`)}` : ""}`);
|
|
28467
28540
|
if (s.recompInFlight) {
|
|
28468
28541
|
lines.push(`Upgrade: ${theme.fg("warning", "recomp/upgrade running…")}`);
|
|
@@ -28593,6 +28666,7 @@ ${safeStringify(tool.parameters)}`);
|
|
|
28593
28666
|
const compressionBudget = contextLimit > 0 ? Math.floor(contextLimit * (Math.min(threshold.percentage, 80) / 100) * historyBudgetPercentage) : null;
|
|
28594
28667
|
return {
|
|
28595
28668
|
sessionId,
|
|
28669
|
+
activeProfile: deps.activeProfile ?? null,
|
|
28596
28670
|
usagePercentage,
|
|
28597
28671
|
inputTokens,
|
|
28598
28672
|
systemPromptTokens,
|
|
@@ -28825,7 +28899,14 @@ No active Pi session is available.`,
|
|
|
28825
28899
|
backlog: getDreamTaskBacklogs(currentDeps.db, currentDeps.projectIdentity, CANONICAL_DREAM_TASKS)
|
|
28826
28900
|
}, windowGeometry, resolveTailHygieneStatus(getPiChannel1Baseline(sessionId)));
|
|
28827
28901
|
const details = buildStatusDetails(currentDeps, sessionId);
|
|
28828
|
-
|
|
28902
|
+
const profileStatus = currentDeps.activeProfile ?? "none";
|
|
28903
|
+
sendCtxStatusMessage(pi, {
|
|
28904
|
+
title: "/ctx-status",
|
|
28905
|
+
text: `${statusText}
|
|
28906
|
+
|
|
28907
|
+
Active profile: ${profileStatus}`,
|
|
28908
|
+
level: "info"
|
|
28909
|
+
}, details);
|
|
28829
28910
|
} catch (error) {
|
|
28830
28911
|
sendCtxStatusMessage(pi, {
|
|
28831
28912
|
title: "/ctx-status",
|
|
@@ -28849,6 +28930,7 @@ function buildStatusDetails(deps, sessionId) {
|
|
|
28849
28930
|
return {
|
|
28850
28931
|
sessionId,
|
|
28851
28932
|
projectIdentity: deps.projectIdentity,
|
|
28933
|
+
activeProfile: deps.activeProfile ?? null,
|
|
28852
28934
|
activeTags: activeTags.length,
|
|
28853
28935
|
droppedTags: droppedTags.length,
|
|
28854
28936
|
totalBytes,
|
|
@@ -29627,12 +29709,13 @@ function resolveHistorianFromConfig(config) {
|
|
|
29627
29709
|
const historian = config.historian;
|
|
29628
29710
|
if (historian?.disable === true)
|
|
29629
29711
|
return;
|
|
29630
|
-
const
|
|
29631
|
-
|
|
29712
|
+
const resolved = resolveHistorianModel(config, "pi");
|
|
29713
|
+
const model = resolved.primary?.model;
|
|
29714
|
+
if (!model)
|
|
29632
29715
|
return;
|
|
29633
29716
|
const historianContextLimit = resolveHistorianContextLimit(model);
|
|
29634
29717
|
const historianChunkTokens = deriveHistorianChunkTokens(historianContextLimit);
|
|
29635
|
-
const fallbackModels =
|
|
29718
|
+
const fallbackModels = resolved.fallbacks;
|
|
29636
29719
|
return {
|
|
29637
29720
|
runner: new PiSubagentRunner,
|
|
29638
29721
|
model,
|
|
@@ -29640,7 +29723,7 @@ function resolveHistorianFromConfig(config) {
|
|
|
29640
29723
|
historianChunkTokens,
|
|
29641
29724
|
timeoutMs: config.historian_timeout_ms,
|
|
29642
29725
|
twoPass: historian?.two_pass === true,
|
|
29643
|
-
thinkingLevel:
|
|
29726
|
+
thinkingLevel: resolved.primary?.qualifier,
|
|
29644
29727
|
executeThresholdPercentage: config.execute_threshold_percentage,
|
|
29645
29728
|
executeThresholdTokens: config.execute_threshold_tokens,
|
|
29646
29729
|
commitClusterTrigger: config.commit_cluster_trigger,
|
|
@@ -29966,6 +30049,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
|
|
|
29966
30049
|
runnable: bootProjectDeps.dreamerEnabled,
|
|
29967
30050
|
scheduleSummary: summarizeDreamSchedule(bootProjectDeps.config.dreamer)
|
|
29968
30051
|
},
|
|
30052
|
+
activeProfile: bootProjectDeps.config.profile,
|
|
29969
30053
|
resolveStatusDeps: (ctx) => {
|
|
29970
30054
|
const current = resolveCurrentProjectDeps(ctx);
|
|
29971
30055
|
return {
|
|
@@ -29980,7 +30064,8 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
|
|
|
29980
30064
|
dreamer: {
|
|
29981
30065
|
runnable: current.dreamerEnabled,
|
|
29982
30066
|
scheduleSummary: summarizeDreamSchedule(current.config.dreamer)
|
|
29983
|
-
}
|
|
30067
|
+
},
|
|
30068
|
+
activeProfile: current.config.profile
|
|
29984
30069
|
};
|
|
29985
30070
|
}
|
|
29986
30071
|
});
|
|
@@ -30130,6 +30215,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
|
|
|
30130
30215
|
embeddingConfig: bootProjectDeps.config.embedding,
|
|
30131
30216
|
memoryEnabled: bootProjectDeps.config.memory.enabled,
|
|
30132
30217
|
retinaHandoff: bootProjectDeps.config.smart_notes.retina_handoff,
|
|
30218
|
+
mural: bootProjectDeps.config.mural,
|
|
30133
30219
|
language: bootProjectDeps.config.language,
|
|
30134
30220
|
gitCommitIndexing: bootProjectDeps.config.memory.git_commit_indexing,
|
|
30135
30221
|
onAdjunctsRefreshNeeded: signalPiSystemPromptRefreshForProject
|