@cortexkit/pi-magic-context 0.17.2 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +408 -46
- package/dist/subagent-entry.js +40 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -158111,6 +158111,25 @@ var MIGRATIONS = [
|
|
|
158111
158111
|
WHERE type = 'tool' AND tool_owner_message_id IS NULL;
|
|
158112
158112
|
`);
|
|
158113
158113
|
}
|
|
158114
|
+
},
|
|
158115
|
+
{
|
|
158116
|
+
version: 11,
|
|
158117
|
+
description: "Add todo state synthesis columns to session_meta",
|
|
158118
|
+
up: (db) => {
|
|
158119
|
+
const cols = db.prepare("PRAGMA table_info(session_meta)").all();
|
|
158120
|
+
if (!cols.some((c) => c.name === "last_todo_state")) {
|
|
158121
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN last_todo_state TEXT DEFAULT ''");
|
|
158122
|
+
}
|
|
158123
|
+
if (!cols.some((c) => c.name === "todo_synthetic_call_id")) {
|
|
158124
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_call_id TEXT DEFAULT ''");
|
|
158125
|
+
}
|
|
158126
|
+
if (!cols.some((c) => c.name === "todo_synthetic_anchor_message_id")) {
|
|
158127
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_anchor_message_id TEXT DEFAULT ''");
|
|
158128
|
+
}
|
|
158129
|
+
if (!cols.some((c) => c.name === "todo_synthetic_state_json")) {
|
|
158130
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_state_json TEXT DEFAULT ''");
|
|
158131
|
+
}
|
|
158132
|
+
}
|
|
158114
158133
|
}
|
|
158115
158134
|
];
|
|
158116
158135
|
function ensureMigrationsTable(db) {
|
|
@@ -158685,6 +158704,10 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
158685
158704
|
note_nudge_trigger_message_id TEXT DEFAULT '',
|
|
158686
158705
|
note_nudge_sticky_text TEXT DEFAULT '',
|
|
158687
158706
|
note_nudge_sticky_message_id TEXT DEFAULT '',
|
|
158707
|
+
last_todo_state TEXT DEFAULT '',
|
|
158708
|
+
todo_synthetic_call_id TEXT DEFAULT '',
|
|
158709
|
+
todo_synthetic_anchor_message_id TEXT DEFAULT '',
|
|
158710
|
+
todo_synthetic_state_json TEXT DEFAULT '',
|
|
158688
158711
|
is_subagent INTEGER DEFAULT 0,
|
|
158689
158712
|
last_context_percentage REAL DEFAULT 0,
|
|
158690
158713
|
last_input_tokens INTEGER DEFAULT 0,
|
|
@@ -158749,6 +158772,10 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
158749
158772
|
ensureColumn(db, "session_meta", "note_nudge_trigger_message_id", "TEXT DEFAULT ''");
|
|
158750
158773
|
ensureColumn(db, "session_meta", "note_nudge_sticky_text", "TEXT DEFAULT ''");
|
|
158751
158774
|
ensureColumn(db, "session_meta", "note_nudge_sticky_message_id", "TEXT DEFAULT ''");
|
|
158775
|
+
ensureColumn(db, "session_meta", "last_todo_state", "TEXT DEFAULT ''");
|
|
158776
|
+
ensureColumn(db, "session_meta", "todo_synthetic_call_id", "TEXT DEFAULT ''");
|
|
158777
|
+
ensureColumn(db, "session_meta", "todo_synthetic_anchor_message_id", "TEXT DEFAULT ''");
|
|
158778
|
+
ensureColumn(db, "session_meta", "todo_synthetic_state_json", "TEXT DEFAULT ''");
|
|
158752
158779
|
ensureColumn(db, "session_meta", "note_last_read_at", "INTEGER DEFAULT 0");
|
|
158753
158780
|
ensureColumn(db, "session_meta", "times_execute_threshold_reached", "INTEGER DEFAULT 0");
|
|
158754
158781
|
ensureColumn(db, "session_meta", "compartment_in_progress", "INTEGER DEFAULT 0");
|
|
@@ -158813,6 +158840,10 @@ function healNullTextColumns(db) {
|
|
|
158813
158840
|
["note_nudge_trigger_message_id", ""],
|
|
158814
158841
|
["note_nudge_sticky_text", ""],
|
|
158815
158842
|
["note_nudge_sticky_message_id", ""],
|
|
158843
|
+
["last_todo_state", ""],
|
|
158844
|
+
["todo_synthetic_call_id", ""],
|
|
158845
|
+
["todo_synthetic_anchor_message_id", ""],
|
|
158846
|
+
["todo_synthetic_state_json", ""],
|
|
158816
158847
|
["system_prompt_hash", ""],
|
|
158817
158848
|
["stripped_placeholder_ids", ""],
|
|
158818
158849
|
["memory_block_cache", ""],
|
|
@@ -158906,7 +158937,8 @@ var META_COLUMNS = {
|
|
|
158906
158937
|
systemPromptTokens: "system_prompt_tokens",
|
|
158907
158938
|
conversationTokens: "conversation_tokens",
|
|
158908
158939
|
toolCallTokens: "tool_call_tokens",
|
|
158909
|
-
clearedReasoningThroughTag: "cleared_reasoning_through_tag"
|
|
158940
|
+
clearedReasoningThroughTag: "cleared_reasoning_through_tag",
|
|
158941
|
+
lastTodoState: "last_todo_state"
|
|
158910
158942
|
};
|
|
158911
158943
|
var BOOLEAN_META_KEYS = new Set(["isSubagent", "compartmentInProgress"]);
|
|
158912
158944
|
function isStringOrNull(value) {
|
|
@@ -158919,7 +158951,7 @@ function isSessionMetaRow(row) {
|
|
|
158919
158951
|
if (row === null || typeof row !== "object")
|
|
158920
158952
|
return false;
|
|
158921
158953
|
const r = row;
|
|
158922
|
-
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag);
|
|
158954
|
+
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag) && isStringOrNull(r.last_todo_state);
|
|
158923
158955
|
}
|
|
158924
158956
|
function getDefaultSessionMeta(sessionId) {
|
|
158925
158957
|
return {
|
|
@@ -158939,7 +158971,8 @@ function getDefaultSessionMeta(sessionId) {
|
|
|
158939
158971
|
systemPromptTokens: 0,
|
|
158940
158972
|
conversationTokens: 0,
|
|
158941
158973
|
toolCallTokens: 0,
|
|
158942
|
-
clearedReasoningThroughTag: 0
|
|
158974
|
+
clearedReasoningThroughTag: 0,
|
|
158975
|
+
lastTodoState: ""
|
|
158943
158976
|
};
|
|
158944
158977
|
}
|
|
158945
158978
|
function ensureSessionMetaRow(db, sessionId) {
|
|
@@ -158951,6 +158984,7 @@ function toSessionMeta(row) {
|
|
|
158951
158984
|
const transformErrorRaw = typeof row.last_transform_error === "string" ? row.last_transform_error : "";
|
|
158952
158985
|
const cacheTtlRaw = typeof row.cache_ttl === "string" && row.cache_ttl.length > 0 ? row.cache_ttl : "5m";
|
|
158953
158986
|
const systemPromptHashRaw = row.system_prompt_hash == null ? "" : row.system_prompt_hash;
|
|
158987
|
+
const lastTodoStateRaw = typeof row.last_todo_state === "string" ? row.last_todo_state : "";
|
|
158954
158988
|
const numOrZero = (value) => typeof value === "number" ? value : 0;
|
|
158955
158989
|
return {
|
|
158956
158990
|
sessionId: row.session_id,
|
|
@@ -158969,7 +159003,8 @@ function toSessionMeta(row) {
|
|
|
158969
159003
|
systemPromptTokens: numOrZero(row.system_prompt_tokens),
|
|
158970
159004
|
conversationTokens: numOrZero(row.conversation_tokens),
|
|
158971
159005
|
toolCallTokens: numOrZero(row.tool_call_tokens),
|
|
158972
|
-
clearedReasoningThroughTag: numOrZero(row.cleared_reasoning_through_tag)
|
|
159006
|
+
clearedReasoningThroughTag: numOrZero(row.cleared_reasoning_through_tag),
|
|
159007
|
+
lastTodoState: lastTodoStateRaw
|
|
158973
159008
|
};
|
|
158974
159009
|
}
|
|
158975
159010
|
|
|
@@ -159185,7 +159220,7 @@ function resolveIsSubagentFromOpenCodeDb(sessionId) {
|
|
|
159185
159220
|
|
|
159186
159221
|
// ../plugin/src/features/magic-context/storage-meta-session.ts
|
|
159187
159222
|
function getOrCreateSessionMeta(db, sessionId) {
|
|
159188
|
-
const result = db.prepare("SELECT session_id, last_response_time, cache_ttl, counter, last_nudge_tokens, last_nudge_band, last_transform_error, is_subagent, last_context_percentage, last_input_tokens, times_execute_threshold_reached, compartment_in_progress, system_prompt_hash, system_prompt_tokens, conversation_tokens, tool_call_tokens, cleared_reasoning_through_tag FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
159223
|
+
const result = db.prepare("SELECT session_id, last_response_time, cache_ttl, counter, last_nudge_tokens, last_nudge_band, last_transform_error, is_subagent, last_context_percentage, last_input_tokens, times_execute_threshold_reached, compartment_in_progress, system_prompt_hash, system_prompt_tokens, conversation_tokens, tool_call_tokens, cleared_reasoning_through_tag, last_todo_state FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
159189
159224
|
if (isSessionMetaRow(result)) {
|
|
159190
159225
|
return toSessionMeta(result);
|
|
159191
159226
|
}
|
|
@@ -159751,14 +159786,118 @@ function expandFallbackChain(chain) {
|
|
|
159751
159786
|
}
|
|
159752
159787
|
return models;
|
|
159753
159788
|
}
|
|
159789
|
+
function getAgentFallbackModels(agent) {
|
|
159790
|
+
const requirement = AGENT_MODEL_REQUIREMENTS[agent];
|
|
159791
|
+
if (!requirement)
|
|
159792
|
+
return;
|
|
159793
|
+
return expandFallbackChain(requirement.fallbackChain);
|
|
159794
|
+
}
|
|
159754
159795
|
|
|
159755
159796
|
// ../plugin/src/shared/models-dev-cache.ts
|
|
159756
159797
|
init_data_path();
|
|
159757
|
-
init_logger();
|
|
159758
159798
|
import { createHash as createHash3 } from "node:crypto";
|
|
159759
159799
|
import { existsSync as existsSync4, readFileSync } from "node:fs";
|
|
159760
159800
|
import { homedir as homedir2, platform } from "node:os";
|
|
159761
159801
|
import { join as join8 } from "node:path";
|
|
159802
|
+
|
|
159803
|
+
// ../plugin/src/shared/jsonc-parser.ts
|
|
159804
|
+
function stripJsonComments(content) {
|
|
159805
|
+
let result = "";
|
|
159806
|
+
let inString = false;
|
|
159807
|
+
let escaped = false;
|
|
159808
|
+
let inLineComment = false;
|
|
159809
|
+
let inBlockComment = false;
|
|
159810
|
+
for (let index = 0;index < content.length; index += 1) {
|
|
159811
|
+
const char = content[index];
|
|
159812
|
+
const next = content[index + 1];
|
|
159813
|
+
if (inLineComment) {
|
|
159814
|
+
if (char === `
|
|
159815
|
+
`) {
|
|
159816
|
+
inLineComment = false;
|
|
159817
|
+
result += char;
|
|
159818
|
+
}
|
|
159819
|
+
continue;
|
|
159820
|
+
}
|
|
159821
|
+
if (inBlockComment) {
|
|
159822
|
+
if (char === "*" && next === "/") {
|
|
159823
|
+
inBlockComment = false;
|
|
159824
|
+
index += 1;
|
|
159825
|
+
}
|
|
159826
|
+
continue;
|
|
159827
|
+
}
|
|
159828
|
+
if (inString) {
|
|
159829
|
+
result += char;
|
|
159830
|
+
if (escaped) {
|
|
159831
|
+
escaped = false;
|
|
159832
|
+
} else if (char === "\\") {
|
|
159833
|
+
escaped = true;
|
|
159834
|
+
} else if (char === '"') {
|
|
159835
|
+
inString = false;
|
|
159836
|
+
}
|
|
159837
|
+
continue;
|
|
159838
|
+
}
|
|
159839
|
+
if (char === '"') {
|
|
159840
|
+
inString = true;
|
|
159841
|
+
result += char;
|
|
159842
|
+
continue;
|
|
159843
|
+
}
|
|
159844
|
+
if (char === "/" && next === "/") {
|
|
159845
|
+
inLineComment = true;
|
|
159846
|
+
index += 1;
|
|
159847
|
+
continue;
|
|
159848
|
+
}
|
|
159849
|
+
if (char === "/" && next === "*") {
|
|
159850
|
+
inBlockComment = true;
|
|
159851
|
+
index += 1;
|
|
159852
|
+
continue;
|
|
159853
|
+
}
|
|
159854
|
+
result += char;
|
|
159855
|
+
}
|
|
159856
|
+
return result;
|
|
159857
|
+
}
|
|
159858
|
+
function stripTrailingCommas(content) {
|
|
159859
|
+
let result = "";
|
|
159860
|
+
let inString = false;
|
|
159861
|
+
let escaped = false;
|
|
159862
|
+
for (let index = 0;index < content.length; index += 1) {
|
|
159863
|
+
const char = content[index];
|
|
159864
|
+
if (inString) {
|
|
159865
|
+
result += char;
|
|
159866
|
+
if (escaped) {
|
|
159867
|
+
escaped = false;
|
|
159868
|
+
} else if (char === "\\") {
|
|
159869
|
+
escaped = true;
|
|
159870
|
+
} else if (char === '"') {
|
|
159871
|
+
inString = false;
|
|
159872
|
+
}
|
|
159873
|
+
continue;
|
|
159874
|
+
}
|
|
159875
|
+
if (char === '"') {
|
|
159876
|
+
inString = true;
|
|
159877
|
+
result += char;
|
|
159878
|
+
continue;
|
|
159879
|
+
}
|
|
159880
|
+
if (char === ",") {
|
|
159881
|
+
let lookahead = index + 1;
|
|
159882
|
+
while (lookahead < content.length && /\s/.test(content[lookahead] ?? "")) {
|
|
159883
|
+
lookahead += 1;
|
|
159884
|
+
}
|
|
159885
|
+
const next = content[lookahead];
|
|
159886
|
+
if (next === "}" || next === "]") {
|
|
159887
|
+
continue;
|
|
159888
|
+
}
|
|
159889
|
+
}
|
|
159890
|
+
result += char;
|
|
159891
|
+
}
|
|
159892
|
+
return result;
|
|
159893
|
+
}
|
|
159894
|
+
function parseJsonc(content) {
|
|
159895
|
+
const normalized = stripTrailingCommas(stripJsonComments(content));
|
|
159896
|
+
return JSON.parse(normalized);
|
|
159897
|
+
}
|
|
159898
|
+
|
|
159899
|
+
// ../plugin/src/shared/models-dev-cache.ts
|
|
159900
|
+
init_logger();
|
|
159762
159901
|
var RELOAD_INTERVAL_MS = 5 * 60 * 1000;
|
|
159763
159902
|
var apiCache = null;
|
|
159764
159903
|
var recentlySeenApiSizes = new Set;
|
|
@@ -159833,9 +159972,7 @@ function loadModelsDevMetadataFromFile() {
|
|
|
159833
159972
|
try {
|
|
159834
159973
|
const configPath = getOpencodeConfigPath();
|
|
159835
159974
|
if (configPath && existsSync4(configPath)) {
|
|
159836
|
-
|
|
159837
|
-
raw = raw.replace(/"(?:[^"\\]|\\.)*"|\/\/.*$/gm, (match) => match.startsWith('"') ? match : "");
|
|
159838
|
-
const config2 = JSON.parse(raw);
|
|
159975
|
+
const config2 = parseJsonc(readFileSync(configPath, "utf-8"));
|
|
159839
159976
|
if (config2.provider && typeof config2.provider === "object") {
|
|
159840
159977
|
for (const [providerId, provider2] of Object.entries(config2.provider)) {
|
|
159841
159978
|
if (!provider2?.models || typeof provider2.models !== "object")
|
|
@@ -160774,6 +160911,53 @@ init_logger();
|
|
|
160774
160911
|
|
|
160775
160912
|
// ../plugin/src/shared/model-suggestion-retry.ts
|
|
160776
160913
|
init_logger();
|
|
160914
|
+
|
|
160915
|
+
// ../plugin/src/shared/resolve-fallbacks.ts
|
|
160916
|
+
function resolveFallbackChain(agentName, userFallbacks) {
|
|
160917
|
+
const userList = normalizeUserFallbacks(userFallbacks);
|
|
160918
|
+
if (userList.length > 0) {
|
|
160919
|
+
return dedupe(userList.filter(isValidModelSpec));
|
|
160920
|
+
}
|
|
160921
|
+
const builtin = getAgentFallbackModels(agentName);
|
|
160922
|
+
if (!builtin || builtin.length === 0)
|
|
160923
|
+
return [];
|
|
160924
|
+
return dedupe(builtin.filter(isValidModelSpec));
|
|
160925
|
+
}
|
|
160926
|
+
function normalizeUserFallbacks(userFallbacks) {
|
|
160927
|
+
if (!userFallbacks)
|
|
160928
|
+
return [];
|
|
160929
|
+
if (typeof userFallbacks === "string") {
|
|
160930
|
+
const trimmed = userFallbacks.trim();
|
|
160931
|
+
return trimmed ? [trimmed] : [];
|
|
160932
|
+
}
|
|
160933
|
+
return userFallbacks.map((s) => s.trim()).filter((s) => s.length > 0);
|
|
160934
|
+
}
|
|
160935
|
+
function isValidModelSpec(spec) {
|
|
160936
|
+
const slash = spec.indexOf("/");
|
|
160937
|
+
return slash > 0 && slash < spec.length - 1;
|
|
160938
|
+
}
|
|
160939
|
+
function dedupe(list) {
|
|
160940
|
+
const seen = new Set;
|
|
160941
|
+
const out = [];
|
|
160942
|
+
for (const item of list) {
|
|
160943
|
+
if (seen.has(item))
|
|
160944
|
+
continue;
|
|
160945
|
+
seen.add(item);
|
|
160946
|
+
out.push(item);
|
|
160947
|
+
}
|
|
160948
|
+
return out;
|
|
160949
|
+
}
|
|
160950
|
+
function parseProviderModel(spec) {
|
|
160951
|
+
const slash = spec.indexOf("/");
|
|
160952
|
+
if (slash < 1 || slash >= spec.length - 1)
|
|
160953
|
+
return null;
|
|
160954
|
+
return {
|
|
160955
|
+
providerID: spec.slice(0, slash).trim(),
|
|
160956
|
+
modelID: spec.slice(slash + 1).trim()
|
|
160957
|
+
};
|
|
160958
|
+
}
|
|
160959
|
+
|
|
160960
|
+
// ../plugin/src/shared/model-suggestion-retry.ts
|
|
160777
160961
|
function extractMessage(error51) {
|
|
160778
160962
|
if (typeof error51 === "string")
|
|
160779
160963
|
return error51;
|
|
@@ -160828,6 +161012,9 @@ function parseModelSuggestion(error51) {
|
|
|
160828
161012
|
};
|
|
160829
161013
|
}
|
|
160830
161014
|
async function promptWithTimeout(client, args, timeoutMs, signal) {
|
|
161015
|
+
if (signal?.aborted) {
|
|
161016
|
+
throw new Error("prompt aborted by external signal");
|
|
161017
|
+
}
|
|
160831
161018
|
const controller = new AbortController;
|
|
160832
161019
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
160833
161020
|
const onExternalAbort = () => controller.abort();
|
|
@@ -160850,16 +161037,39 @@ async function promptWithTimeout(client, args, timeoutMs, signal) {
|
|
|
160850
161037
|
signal?.removeEventListener("abort", onExternalAbort);
|
|
160851
161038
|
}
|
|
160852
161039
|
}
|
|
160853
|
-
|
|
160854
|
-
|
|
161040
|
+
function isNonRetryable(error51, externalSignal) {
|
|
161041
|
+
if (externalSignal?.aborted)
|
|
161042
|
+
return true;
|
|
161043
|
+
if (error51 instanceof Error) {
|
|
161044
|
+
if (error51.name === "AbortError")
|
|
161045
|
+
return true;
|
|
161046
|
+
if (error51.message === "prompt aborted by external signal")
|
|
161047
|
+
return true;
|
|
161048
|
+
if (/^prompt timed out after \d+ms$/.test(error51.message))
|
|
161049
|
+
return true;
|
|
161050
|
+
}
|
|
161051
|
+
if (detectOverflow(error51).isOverflow)
|
|
161052
|
+
return true;
|
|
161053
|
+
return false;
|
|
161054
|
+
}
|
|
161055
|
+
function shortErr(error51) {
|
|
161056
|
+
if (error51 instanceof Error) {
|
|
161057
|
+
return error51.name && error51.name !== "Error" ? `${error51.name}: ${error51.message}` : error51.message;
|
|
161058
|
+
}
|
|
161059
|
+
return extractMessage(error51);
|
|
161060
|
+
}
|
|
161061
|
+
async function attemptOnce(client, args, timeoutMs, signal, callContext, label) {
|
|
160855
161062
|
try {
|
|
160856
|
-
await promptWithTimeout(client, args, timeoutMs,
|
|
161063
|
+
await promptWithTimeout(client, args, timeoutMs, signal);
|
|
161064
|
+
return;
|
|
160857
161065
|
} catch (error51) {
|
|
161066
|
+
if (isNonRetryable(error51, signal))
|
|
161067
|
+
throw error51;
|
|
160858
161068
|
const suggestion = parseModelSuggestion(error51);
|
|
160859
161069
|
if (!suggestion || !args.body.model) {
|
|
160860
161070
|
throw error51;
|
|
160861
161071
|
}
|
|
160862
|
-
log(
|
|
161072
|
+
log(`[${callContext}] ${label}: model not found, retrying with suggestion`, {
|
|
160863
161073
|
original: `${suggestion.providerID}/${suggestion.modelID}`,
|
|
160864
161074
|
suggested: suggestion.suggestion
|
|
160865
161075
|
});
|
|
@@ -160872,9 +161082,55 @@ async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
|
|
|
160872
161082
|
modelID: suggestion.suggestion
|
|
160873
161083
|
}
|
|
160874
161084
|
}
|
|
160875
|
-
}, timeoutMs,
|
|
161085
|
+
}, timeoutMs, signal);
|
|
160876
161086
|
}
|
|
160877
161087
|
}
|
|
161088
|
+
async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
|
|
161089
|
+
const timeoutMs = options.timeoutMs ?? 300000;
|
|
161090
|
+
const callContext = options.callContext ?? "subagent";
|
|
161091
|
+
const fallbacks = options.fallbackModels ?? [];
|
|
161092
|
+
const explicitPrimaryLabel = args.body.model?.providerID && args.body.model.modelID ? `${args.body.model.providerID}/${args.body.model.modelID}` : "primary";
|
|
161093
|
+
let lastError = null;
|
|
161094
|
+
try {
|
|
161095
|
+
await attemptOnce(client, args, timeoutMs, options.signal, callContext, explicitPrimaryLabel);
|
|
161096
|
+
return;
|
|
161097
|
+
} catch (error51) {
|
|
161098
|
+
lastError = error51;
|
|
161099
|
+
if (isNonRetryable(error51, options.signal))
|
|
161100
|
+
throw error51;
|
|
161101
|
+
if (fallbacks.length === 0) {
|
|
161102
|
+
throw error51;
|
|
161103
|
+
}
|
|
161104
|
+
log(`[${callContext}] primary (${explicitPrimaryLabel}) failed: ${shortErr(error51)}; trying ${fallbacks.length} fallback(s)`);
|
|
161105
|
+
}
|
|
161106
|
+
for (let i = 0;i < fallbacks.length; i += 1) {
|
|
161107
|
+
const parsed = parseProviderModel(fallbacks[i]);
|
|
161108
|
+
if (!parsed) {
|
|
161109
|
+
log(`[${callContext}] skipping invalid fallback spec: ${fallbacks[i]}`);
|
|
161110
|
+
continue;
|
|
161111
|
+
}
|
|
161112
|
+
const label = `${parsed.providerID}/${parsed.modelID}`;
|
|
161113
|
+
const attemptArgs = {
|
|
161114
|
+
...args,
|
|
161115
|
+
body: { ...args.body, model: parsed }
|
|
161116
|
+
};
|
|
161117
|
+
try {
|
|
161118
|
+
await attemptOnce(client, attemptArgs, timeoutMs, options.signal, callContext, label);
|
|
161119
|
+
log(`[${callContext}] fallback succeeded with ${label} (attempt ${i + 2}/${fallbacks.length + 1})`);
|
|
161120
|
+
return;
|
|
161121
|
+
} catch (error51) {
|
|
161122
|
+
lastError = error51;
|
|
161123
|
+
if (isNonRetryable(error51, options.signal))
|
|
161124
|
+
throw error51;
|
|
161125
|
+
const remaining = fallbacks.length - i - 1;
|
|
161126
|
+
if (remaining > 0) {
|
|
161127
|
+
log(`[${callContext}] ${label} failed: ${shortErr(error51)}; ${remaining} fallback(s) left`);
|
|
161128
|
+
}
|
|
161129
|
+
}
|
|
161130
|
+
}
|
|
161131
|
+
log(`[${callContext}] all models exhausted; tried: ${[explicitPrimaryLabel, ...fallbacks].join(", ")}; last error: ${shortErr(lastError)}`);
|
|
161132
|
+
throw lastError ?? new Error("All fallback models failed");
|
|
161133
|
+
}
|
|
160878
161134
|
// ../plugin/src/shared/normalize-sdk-response.ts
|
|
160879
161135
|
function normalizeSDKResponse(response, fallback, options) {
|
|
160880
161136
|
if (response === null || response === undefined) {
|
|
@@ -162052,7 +162308,12 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
162052
162308
|
system: DREAMER_SYSTEM_PROMPT,
|
|
162053
162309
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
162054
162310
|
}
|
|
162055
|
-
}, {
|
|
162311
|
+
}, {
|
|
162312
|
+
timeoutMs: Math.min(remainingMs, 5 * 60 * 1000),
|
|
162313
|
+
signal: abortController.signal,
|
|
162314
|
+
fallbackModels: args.fallbackModels,
|
|
162315
|
+
callContext: "dreamer:user-memories"
|
|
162316
|
+
});
|
|
162056
162317
|
const messagesResponse = await args.client.session.messages({
|
|
162057
162318
|
path: { id: agentSessionId },
|
|
162058
162319
|
query: { directory: args.sessionDirectory }
|
|
@@ -162111,7 +162372,8 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
162111
162372
|
}
|
|
162112
162373
|
return result;
|
|
162113
162374
|
} catch (error51) {
|
|
162114
|
-
|
|
162375
|
+
const errorDescription = describeError(error51);
|
|
162376
|
+
log(`[dreamer] user-memories: review failed: ${errorDescription.brief}`, errorDescription.stackHead ? { stackHead: errorDescription.stackHead } : undefined);
|
|
162115
162377
|
return result;
|
|
162116
162378
|
} finally {
|
|
162117
162379
|
clearInterval(leaseInterval);
|
|
@@ -162143,6 +162405,7 @@ function insertDreamRun(db, run) {
|
|
|
162143
162405
|
|
|
162144
162406
|
// ../plugin/src/features/magic-context/dreamer/runner.ts
|
|
162145
162407
|
var dreamProjectDirectories = new Map;
|
|
162408
|
+
var CIRCUIT_BREAKER_THRESHOLD = 3;
|
|
162146
162409
|
function registerDreamProjectDirectory(projectIdentity, directory) {
|
|
162147
162410
|
dreamProjectDirectories.set(projectIdentity, directory);
|
|
162148
162411
|
}
|
|
@@ -162159,6 +162422,25 @@ function countNewIds(beforeIds, afterIds) {
|
|
|
162159
162422
|
}
|
|
162160
162423
|
return count;
|
|
162161
162424
|
}
|
|
162425
|
+
function getCircuitBreakerSignature(error51, brief) {
|
|
162426
|
+
if (error51 instanceof Error && error51.name && error51.name !== "Error") {
|
|
162427
|
+
return error51.name;
|
|
162428
|
+
}
|
|
162429
|
+
const namedError = error51;
|
|
162430
|
+
if (namedError && typeof namedError === "object" && typeof namedError.name === "string" && namedError.name.length > 0 && namedError.name !== "Error") {
|
|
162431
|
+
return namedError.name;
|
|
162432
|
+
}
|
|
162433
|
+
return brief.split(":")[0]?.trim().split(/\s+/)[0] || brief || "unknown";
|
|
162434
|
+
}
|
|
162435
|
+
function shouldSkipCircuitBreaker(error51, brief) {
|
|
162436
|
+
const namedError = error51;
|
|
162437
|
+
const name2 = error51 instanceof Error ? error51.name : namedError && typeof namedError === "object" && typeof namedError.name === "string" ? namedError.name : "";
|
|
162438
|
+
const combined = `${name2} ${brief}`.toLowerCase();
|
|
162439
|
+
return name2 === "AbortError" || combined.includes("lease");
|
|
162440
|
+
}
|
|
162441
|
+
function logWithStackHead(message, stackHead) {
|
|
162442
|
+
log(message, stackHead ? { stackHead } : undefined);
|
|
162443
|
+
}
|
|
162162
162444
|
function getOpenCodeDbPath2() {
|
|
162163
162445
|
return join9(getDataDir(), "opencode", "opencode.db");
|
|
162164
162446
|
}
|
|
@@ -162264,7 +162546,12 @@ async function identifyKeyFilesForSession(args) {
|
|
|
162264
162546
|
system: KEY_FILES_SYSTEM_PROMPT,
|
|
162265
162547
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
162266
162548
|
}
|
|
162267
|
-
}, {
|
|
162549
|
+
}, {
|
|
162550
|
+
timeoutMs: Math.min(remainingMs, 300000),
|
|
162551
|
+
signal: abortController.signal,
|
|
162552
|
+
fallbackModels: args.fallbackModels,
|
|
162553
|
+
callContext: `dreamer:key-files:${args.sessionId.slice(0, 12)}`
|
|
162554
|
+
});
|
|
162268
162555
|
const messagesResponse = await args.client.session.messages({
|
|
162269
162556
|
path: { id: agentSessionId },
|
|
162270
162557
|
query: { directory: args.sessionDirectory }
|
|
@@ -162337,6 +162624,7 @@ async function identifyKeyFiles(args) {
|
|
|
162337
162624
|
parentSessionId: args.parentSessionId,
|
|
162338
162625
|
sessionDirectory: args.sessionDirectory,
|
|
162339
162626
|
holderId: args.holderId,
|
|
162627
|
+
fallbackModels: args.fallbackModels,
|
|
162340
162628
|
deadline: args.deadline,
|
|
162341
162629
|
sessionId,
|
|
162342
162630
|
config: args.config
|
|
@@ -162390,6 +162678,9 @@ async function runDream(args) {
|
|
|
162390
162678
|
const deadline = startedAt + args.maxRuntimeMinutes * 60 * 1000;
|
|
162391
162679
|
const lastDreamAt = getDreamState(args.db, `last_dream_at:${args.projectIdentity}`) ?? getDreamState(args.db, "last_dream_at");
|
|
162392
162680
|
log(`[dreamer] last dream at: ${lastDreamAt ?? "never"} (project=${args.projectIdentity})`);
|
|
162681
|
+
let lastErrorSignature = null;
|
|
162682
|
+
let consecutiveSameErrorFailures = 0;
|
|
162683
|
+
let circuitBreakerTripped = false;
|
|
162393
162684
|
try {
|
|
162394
162685
|
for (const taskName of args.tasks) {
|
|
162395
162686
|
if (Date.now() > deadline) {
|
|
@@ -162450,7 +162741,9 @@ async function runDream(args) {
|
|
|
162450
162741
|
}
|
|
162451
162742
|
}, {
|
|
162452
162743
|
timeoutMs: args.taskTimeoutMinutes * 60 * 1000,
|
|
162453
|
-
signal: taskAbortController.signal
|
|
162744
|
+
signal: taskAbortController.signal,
|
|
162745
|
+
fallbackModels: args.fallbackModels,
|
|
162746
|
+
callContext: `dreamer:${taskName}`
|
|
162454
162747
|
});
|
|
162455
162748
|
const messagesResponse = await args.client.session.messages({
|
|
162456
162749
|
path: { id: agentSessionId },
|
|
@@ -162470,16 +162763,40 @@ async function runDream(args) {
|
|
|
162470
162763
|
durationMs,
|
|
162471
162764
|
result: taskResult
|
|
162472
162765
|
});
|
|
162766
|
+
lastErrorSignature = null;
|
|
162767
|
+
consecutiveSameErrorFailures = 0;
|
|
162473
162768
|
} catch (error51) {
|
|
162474
162769
|
const durationMs = Date.now() - taskStartedAt;
|
|
162475
|
-
const
|
|
162476
|
-
|
|
162770
|
+
const errorDescription = describeError(error51);
|
|
162771
|
+
logWithStackHead(`[dreamer] task ${taskName}: failed after ${(durationMs / 1000).toFixed(1)}s — ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162477
162772
|
result.tasks.push({
|
|
162478
162773
|
name: taskName,
|
|
162479
162774
|
durationMs,
|
|
162480
162775
|
result: null,
|
|
162481
|
-
error:
|
|
162776
|
+
error: errorDescription.brief
|
|
162482
162777
|
});
|
|
162778
|
+
if (shouldSkipCircuitBreaker(error51, errorDescription.brief)) {
|
|
162779
|
+
lastErrorSignature = null;
|
|
162780
|
+
consecutiveSameErrorFailures = 0;
|
|
162781
|
+
} else {
|
|
162782
|
+
const signature = getCircuitBreakerSignature(error51, errorDescription.brief);
|
|
162783
|
+
if (signature === lastErrorSignature) {
|
|
162784
|
+
consecutiveSameErrorFailures += 1;
|
|
162785
|
+
} else {
|
|
162786
|
+
lastErrorSignature = signature;
|
|
162787
|
+
consecutiveSameErrorFailures = 1;
|
|
162788
|
+
}
|
|
162789
|
+
if (consecutiveSameErrorFailures >= CIRCUIT_BREAKER_THRESHOLD) {
|
|
162790
|
+
circuitBreakerTripped = true;
|
|
162791
|
+
log(`[dreamer] circuit breaker: ${consecutiveSameErrorFailures} consecutive ${signature} failures — aborting remaining tasks`);
|
|
162792
|
+
result.tasks.push({
|
|
162793
|
+
name: "circuit-breaker",
|
|
162794
|
+
durationMs: 0,
|
|
162795
|
+
result: "",
|
|
162796
|
+
error: `Aborted remaining tasks: ${consecutiveSameErrorFailures} consecutive ${signature} failures. Configure dreamer model/fallback_models in magic-context.jsonc.`
|
|
162797
|
+
});
|
|
162798
|
+
}
|
|
162799
|
+
}
|
|
162483
162800
|
} finally {
|
|
162484
162801
|
clearInterval(leaseRenewalInterval);
|
|
162485
162802
|
if (agentSessionId) {
|
|
@@ -162491,8 +162808,20 @@ async function runDream(args) {
|
|
|
162491
162808
|
});
|
|
162492
162809
|
}
|
|
162493
162810
|
}
|
|
162811
|
+
if (circuitBreakerTripped) {
|
|
162812
|
+
break;
|
|
162813
|
+
}
|
|
162814
|
+
}
|
|
162815
|
+
if (circuitBreakerTripped) {
|
|
162816
|
+
log("[dreamer] circuit breaker: skipping post-task phases");
|
|
162817
|
+
result.tasks.push({
|
|
162818
|
+
name: "post-task-phases",
|
|
162819
|
+
durationMs: 0,
|
|
162820
|
+
result: "",
|
|
162821
|
+
error: "Skipped post-task phases after circuit breaker tripped; configure dreamer model/fallback_models in magic-context.jsonc."
|
|
162822
|
+
});
|
|
162494
162823
|
}
|
|
162495
|
-
if (args.experimentalUserMemories?.enabled && Date.now() <= deadline) {
|
|
162824
|
+
if (!circuitBreakerTripped && args.experimentalUserMemories?.enabled && Date.now() <= deadline) {
|
|
162496
162825
|
const umStart = Date.now();
|
|
162497
162826
|
try {
|
|
162498
162827
|
const reviewResult = await reviewUserMemories({
|
|
@@ -162502,7 +162831,8 @@ async function runDream(args) {
|
|
|
162502
162831
|
sessionDirectory: args.sessionDirectory,
|
|
162503
162832
|
holderId,
|
|
162504
162833
|
deadline,
|
|
162505
|
-
promotionThreshold: args.experimentalUserMemories.promotionThreshold
|
|
162834
|
+
promotionThreshold: args.experimentalUserMemories.promotionThreshold,
|
|
162835
|
+
fallbackModels: args.fallbackModels
|
|
162506
162836
|
});
|
|
162507
162837
|
const umOutput = `promoted=${reviewResult.promoted} merged=${reviewResult.merged} dismissed=${reviewResult.dismissed} consumed=${reviewResult.candidatesConsumed}`;
|
|
162508
162838
|
if (reviewResult.promoted > 0 || reviewResult.merged > 0 || reviewResult.dismissed > 0) {
|
|
@@ -162514,16 +162844,17 @@ async function runDream(args) {
|
|
|
162514
162844
|
result: umOutput
|
|
162515
162845
|
});
|
|
162516
162846
|
} catch (error51) {
|
|
162517
|
-
|
|
162847
|
+
const errorDescription = describeError(error51);
|
|
162848
|
+
logWithStackHead(`[dreamer] user-memory review failed: ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162518
162849
|
result.tasks.push({
|
|
162519
162850
|
name: "user memories",
|
|
162520
162851
|
durationMs: Date.now() - umStart,
|
|
162521
162852
|
result: "",
|
|
162522
|
-
error:
|
|
162853
|
+
error: errorDescription.brief
|
|
162523
162854
|
});
|
|
162524
162855
|
}
|
|
162525
162856
|
}
|
|
162526
|
-
if (Date.now() <= deadline) {
|
|
162857
|
+
if (!circuitBreakerTripped && Date.now() <= deadline) {
|
|
162527
162858
|
try {
|
|
162528
162859
|
await evaluateSmartNotes({
|
|
162529
162860
|
db: args.db,
|
|
@@ -162533,13 +162864,15 @@ async function runDream(args) {
|
|
|
162533
162864
|
sessionDirectory: args.sessionDirectory,
|
|
162534
162865
|
holderId,
|
|
162535
162866
|
deadline,
|
|
162536
|
-
result
|
|
162867
|
+
result,
|
|
162868
|
+
fallbackModels: args.fallbackModels
|
|
162537
162869
|
});
|
|
162538
162870
|
} catch (error51) {
|
|
162539
|
-
|
|
162871
|
+
const errorDescription = describeError(error51);
|
|
162872
|
+
logWithStackHead(`[dreamer] smart note evaluation failed: ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162540
162873
|
}
|
|
162541
162874
|
}
|
|
162542
|
-
if (args.experimentalPinKeyFiles?.enabled && Date.now() <= deadline) {
|
|
162875
|
+
if (!circuitBreakerTripped && args.experimentalPinKeyFiles?.enabled && Date.now() <= deadline) {
|
|
162543
162876
|
const kfStart = Date.now();
|
|
162544
162877
|
try {
|
|
162545
162878
|
await identifyKeyFiles({
|
|
@@ -162550,7 +162883,8 @@ async function runDream(args) {
|
|
|
162550
162883
|
sessionDirectory: args.sessionDirectory ?? args.projectIdentity,
|
|
162551
162884
|
holderId,
|
|
162552
162885
|
deadline,
|
|
162553
|
-
config: args.experimentalPinKeyFiles
|
|
162886
|
+
config: args.experimentalPinKeyFiles,
|
|
162887
|
+
fallbackModels: args.fallbackModels
|
|
162554
162888
|
});
|
|
162555
162889
|
result.tasks.push({
|
|
162556
162890
|
name: "key files",
|
|
@@ -162558,12 +162892,13 @@ async function runDream(args) {
|
|
|
162558
162892
|
result: "completed"
|
|
162559
162893
|
});
|
|
162560
162894
|
} catch (error51) {
|
|
162561
|
-
|
|
162895
|
+
const errorDescription = describeError(error51);
|
|
162896
|
+
logWithStackHead(`[key-files] identification phase failed: ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162562
162897
|
result.tasks.push({
|
|
162563
162898
|
name: "key files",
|
|
162564
162899
|
durationMs: Date.now() - kfStart,
|
|
162565
162900
|
result: "",
|
|
162566
|
-
error:
|
|
162901
|
+
error: errorDescription.brief
|
|
162567
162902
|
});
|
|
162568
162903
|
}
|
|
162569
162904
|
}
|
|
@@ -162598,7 +162933,13 @@ async function runDream(args) {
|
|
|
162598
162933
|
smartNotesPending: result.smartNotesPending,
|
|
162599
162934
|
memoryChanges: persistedMemoryChanges
|
|
162600
162935
|
});
|
|
162601
|
-
const POST_TASK_NAMES = new Set([
|
|
162936
|
+
const POST_TASK_NAMES = new Set([
|
|
162937
|
+
"smart-notes",
|
|
162938
|
+
"user memories",
|
|
162939
|
+
"key files",
|
|
162940
|
+
"post-task-phases",
|
|
162941
|
+
"circuit-breaker"
|
|
162942
|
+
]);
|
|
162602
162943
|
const hasSuccessfulTask = result.tasks.some((t) => !t.error && !POST_TASK_NAMES.has(t.name));
|
|
162603
162944
|
if (hasSuccessfulTask) {
|
|
162604
162945
|
setDreamState(args.db, `last_dream_at:${args.projectIdentity}`, String(result.finishedAt));
|
|
@@ -162677,7 +163018,12 @@ Only include notes whose conditions you could definitively evaluate. Skip notes
|
|
|
162677
163018
|
system: DREAMER_SYSTEM_PROMPT,
|
|
162678
163019
|
parts: [{ type: "text", text: evaluationPrompt, synthetic: true }]
|
|
162679
163020
|
}
|
|
162680
|
-
}, {
|
|
163021
|
+
}, {
|
|
163022
|
+
timeoutMs: Math.min(remainingMs, 300000),
|
|
163023
|
+
signal: abortController.signal,
|
|
163024
|
+
fallbackModels: args.fallbackModels,
|
|
163025
|
+
callContext: "dreamer:smart-notes"
|
|
163026
|
+
});
|
|
162681
163027
|
const messagesResponse = await args.client.session.messages({
|
|
162682
163028
|
path: { id: agentSessionId },
|
|
162683
163029
|
query: { directory: args.sessionDirectory ?? args.projectIdentity }
|
|
@@ -162736,15 +163082,15 @@ Only include notes whose conditions you could definitively evaluate. Skip notes
|
|
|
162736
163082
|
});
|
|
162737
163083
|
} catch (error51) {
|
|
162738
163084
|
const durationMs = Date.now() - taskStartedAt;
|
|
162739
|
-
const
|
|
163085
|
+
const errorDescription = describeError(error51);
|
|
162740
163086
|
args.result.smartNotesSurfaced = 0;
|
|
162741
163087
|
args.result.smartNotesPending = pendingNotes.length;
|
|
162742
|
-
|
|
163088
|
+
logWithStackHead(`[dreamer] smart notes: failed after ${(durationMs / 1000).toFixed(1)}s — ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162743
163089
|
args.result.tasks.push({
|
|
162744
163090
|
name: "smart-notes",
|
|
162745
163091
|
durationMs,
|
|
162746
163092
|
result: null,
|
|
162747
|
-
error:
|
|
163093
|
+
error: errorDescription.brief
|
|
162748
163094
|
});
|
|
162749
163095
|
} finally {
|
|
162750
163096
|
clearInterval(leaseInterval);
|
|
@@ -162777,7 +163123,8 @@ async function processDreamQueue(args) {
|
|
|
162777
163123
|
maxRuntimeMinutes: args.maxRuntimeMinutes,
|
|
162778
163124
|
sessionDirectory: projectDirectory,
|
|
162779
163125
|
experimentalUserMemories: args.experimentalUserMemories,
|
|
162780
|
-
experimentalPinKeyFiles: args.experimentalPinKeyFiles
|
|
163126
|
+
experimentalPinKeyFiles: args.experimentalPinKeyFiles,
|
|
163127
|
+
fallbackModels: args.fallbackModels
|
|
162781
163128
|
});
|
|
162782
163129
|
} catch (error51) {
|
|
162783
163130
|
log(`[dreamer] runDream threw for ${entry.projectIdentity}: ${getErrorMessage(error51)}`);
|
|
@@ -163501,7 +163848,8 @@ async function sweepProject(reg, origin) {
|
|
|
163501
163848
|
maxRuntimeMinutes: reg.dreamerConfig.max_runtime_minutes,
|
|
163502
163849
|
experimentalUserMemories: reg.experimentalUserMemories,
|
|
163503
163850
|
experimentalPinKeyFiles: reg.experimentalPinKeyFiles,
|
|
163504
|
-
projectIdentity: registrationIdentity
|
|
163851
|
+
projectIdentity: registrationIdentity,
|
|
163852
|
+
fallbackModels: resolveFallbackChain(DREAMER_AGENT, reg.dreamerConfig.fallback_models)
|
|
163505
163853
|
});
|
|
163506
163854
|
} catch (error51) {
|
|
163507
163855
|
log(`[dreamer] timer-triggered queue processing failed for ${reg.directory}:`, error51);
|
|
@@ -165299,8 +165647,9 @@ function tagTranscript(sessionId, transcript, tagger, db, options = {}) {
|
|
|
165299
165647
|
continue;
|
|
165300
165648
|
const messageId = message.info.id;
|
|
165301
165649
|
let textOrdinal = 0;
|
|
165302
|
-
|
|
165303
|
-
|
|
165650
|
+
const parts = message.parts;
|
|
165651
|
+
for (let partIndex = 0;partIndex < parts.length; partIndex += 1) {
|
|
165652
|
+
const part = parts[partIndex];
|
|
165304
165653
|
if (part === undefined)
|
|
165305
165654
|
continue;
|
|
165306
165655
|
if (part.kind === "text") {
|
|
@@ -170399,7 +170748,8 @@ async function runCompressorPass2(args) {
|
|
|
170399
170748
|
targetTokens,
|
|
170400
170749
|
outputCount,
|
|
170401
170750
|
outputDepth,
|
|
170402
|
-
historianTimeoutMs
|
|
170751
|
+
historianTimeoutMs,
|
|
170752
|
+
fallbackModels
|
|
170403
170753
|
} = args;
|
|
170404
170754
|
const prompt = buildCompressorPrompt(compartments, currentTokens, targetTokens, outputDepth, outputCount);
|
|
170405
170755
|
let agentSessionId = null;
|
|
@@ -170421,7 +170771,11 @@ async function runCompressorPass2(args) {
|
|
|
170421
170771
|
agent: HISTORIAN_AGENT2,
|
|
170422
170772
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
170423
170773
|
}
|
|
170424
|
-
}, {
|
|
170774
|
+
}, {
|
|
170775
|
+
timeoutMs: historianTimeoutMs ?? DEFAULT_HISTORIAN_TIMEOUT_MS,
|
|
170776
|
+
fallbackModels,
|
|
170777
|
+
callContext: "compressor"
|
|
170778
|
+
});
|
|
170425
170779
|
const messagesResponse = await client.session.messages({
|
|
170426
170780
|
path: { id: agentSessionId },
|
|
170427
170781
|
query: { directory }
|
|
@@ -170559,7 +170913,8 @@ async function runHistorianPrompt(args) {
|
|
|
170559
170913
|
timeoutMs,
|
|
170560
170914
|
dumpLabel,
|
|
170561
170915
|
modelOverride,
|
|
170562
|
-
agentId = HISTORIAN_AGENT
|
|
170916
|
+
agentId = HISTORIAN_AGENT,
|
|
170917
|
+
fallbackModels
|
|
170563
170918
|
} = args;
|
|
170564
170919
|
let agentSessionId = null;
|
|
170565
170920
|
try {
|
|
@@ -170586,7 +170941,11 @@ async function runHistorianPrompt(args) {
|
|
|
170586
170941
|
...modelOverride ? { model: modelOverride } : {},
|
|
170587
170942
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
170588
170943
|
}
|
|
170589
|
-
}, {
|
|
170944
|
+
}, {
|
|
170945
|
+
timeoutMs: timeoutMs ?? DEFAULT_HISTORIAN_TIMEOUT_MS,
|
|
170946
|
+
fallbackModels: modelOverride ? undefined : fallbackModels,
|
|
170947
|
+
callContext: agentId === HISTORIAN_EDITOR_AGENT ? "historian:editor" : "historian"
|
|
170948
|
+
});
|
|
170590
170949
|
sessionLog(parentSessionId, `historian: prompt completed (attempt ${retryIndex + 1}/${MAX_HISTORIAN_RETRIES + 1})`);
|
|
170591
170950
|
break;
|
|
170592
170951
|
} catch (error51) {
|
|
@@ -171042,6 +171401,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
171042
171401
|
dumpLabelBase: `partial-recomp-${sessionId}-${chunk.startIndex}-${chunk.endIndex}-pass-${passCount + 1}`,
|
|
171043
171402
|
timeoutMs: historianTimeoutMs,
|
|
171044
171403
|
fallbackModelId: deps.fallbackModelId,
|
|
171404
|
+
fallbackModels: deps.fallbackModels,
|
|
171045
171405
|
twoPass: deps.historianTwoPass,
|
|
171046
171406
|
callbacks: {
|
|
171047
171407
|
onRepairRetry: async (error51) => {
|
|
@@ -171244,6 +171604,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
171244
171604
|
dumpLabelBase: `recomp-${sessionId}-${chunk.startIndex}-${chunk.endIndex}-pass-${passCount + 1}`,
|
|
171245
171605
|
timeoutMs: historianTimeoutMs,
|
|
171246
171606
|
fallbackModelId: deps.fallbackModelId,
|
|
171607
|
+
fallbackModels: deps.fallbackModels,
|
|
171247
171608
|
twoPass: deps.historianTwoPass,
|
|
171248
171609
|
callbacks: {
|
|
171249
171610
|
onRepairRetry: async (error51) => {
|
|
@@ -171341,6 +171702,7 @@ Nothing was written.`;
|
|
|
171341
171702
|
directory: sessionDirectory,
|
|
171342
171703
|
historyBudgetTokens: deps.historyBudgetTokens,
|
|
171343
171704
|
historianTimeoutMs,
|
|
171705
|
+
fallbackModels: deps.fallbackModels,
|
|
171344
171706
|
minCompartmentRatio: deps.compressorMinCompartmentRatio,
|
|
171345
171707
|
maxMergeDepth: deps.compressorMaxMergeDepth
|
|
171346
171708
|
});
|
|
@@ -171877,7 +172239,7 @@ import {
|
|
|
171877
172239
|
// package.json
|
|
171878
172240
|
var package_default = {
|
|
171879
172241
|
name: "@cortexkit/pi-magic-context",
|
|
171880
|
-
version: "0.
|
|
172242
|
+
version: "0.18.0",
|
|
171881
172243
|
type: "module",
|
|
171882
172244
|
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
171883
172245
|
main: "dist/index.js",
|
package/dist/subagent-entry.js
CHANGED
|
@@ -24343,6 +24343,25 @@ var MIGRATIONS = [
|
|
|
24343
24343
|
WHERE type = 'tool' AND tool_owner_message_id IS NULL;
|
|
24344
24344
|
`);
|
|
24345
24345
|
}
|
|
24346
|
+
},
|
|
24347
|
+
{
|
|
24348
|
+
version: 11,
|
|
24349
|
+
description: "Add todo state synthesis columns to session_meta",
|
|
24350
|
+
up: (db) => {
|
|
24351
|
+
const cols = db.prepare("PRAGMA table_info(session_meta)").all();
|
|
24352
|
+
if (!cols.some((c) => c.name === "last_todo_state")) {
|
|
24353
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN last_todo_state TEXT DEFAULT ''");
|
|
24354
|
+
}
|
|
24355
|
+
if (!cols.some((c) => c.name === "todo_synthetic_call_id")) {
|
|
24356
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_call_id TEXT DEFAULT ''");
|
|
24357
|
+
}
|
|
24358
|
+
if (!cols.some((c) => c.name === "todo_synthetic_anchor_message_id")) {
|
|
24359
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_anchor_message_id TEXT DEFAULT ''");
|
|
24360
|
+
}
|
|
24361
|
+
if (!cols.some((c) => c.name === "todo_synthetic_state_json")) {
|
|
24362
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_state_json TEXT DEFAULT ''");
|
|
24363
|
+
}
|
|
24364
|
+
}
|
|
24346
24365
|
}
|
|
24347
24366
|
];
|
|
24348
24367
|
function ensureMigrationsTable(db) {
|
|
@@ -157509,6 +157528,10 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
157509
157528
|
note_nudge_trigger_message_id TEXT DEFAULT '',
|
|
157510
157529
|
note_nudge_sticky_text TEXT DEFAULT '',
|
|
157511
157530
|
note_nudge_sticky_message_id TEXT DEFAULT '',
|
|
157531
|
+
last_todo_state TEXT DEFAULT '',
|
|
157532
|
+
todo_synthetic_call_id TEXT DEFAULT '',
|
|
157533
|
+
todo_synthetic_anchor_message_id TEXT DEFAULT '',
|
|
157534
|
+
todo_synthetic_state_json TEXT DEFAULT '',
|
|
157512
157535
|
is_subagent INTEGER DEFAULT 0,
|
|
157513
157536
|
last_context_percentage REAL DEFAULT 0,
|
|
157514
157537
|
last_input_tokens INTEGER DEFAULT 0,
|
|
@@ -157573,6 +157596,10 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
157573
157596
|
ensureColumn(db, "session_meta", "note_nudge_trigger_message_id", "TEXT DEFAULT ''");
|
|
157574
157597
|
ensureColumn(db, "session_meta", "note_nudge_sticky_text", "TEXT DEFAULT ''");
|
|
157575
157598
|
ensureColumn(db, "session_meta", "note_nudge_sticky_message_id", "TEXT DEFAULT ''");
|
|
157599
|
+
ensureColumn(db, "session_meta", "last_todo_state", "TEXT DEFAULT ''");
|
|
157600
|
+
ensureColumn(db, "session_meta", "todo_synthetic_call_id", "TEXT DEFAULT ''");
|
|
157601
|
+
ensureColumn(db, "session_meta", "todo_synthetic_anchor_message_id", "TEXT DEFAULT ''");
|
|
157602
|
+
ensureColumn(db, "session_meta", "todo_synthetic_state_json", "TEXT DEFAULT ''");
|
|
157576
157603
|
ensureColumn(db, "session_meta", "note_last_read_at", "INTEGER DEFAULT 0");
|
|
157577
157604
|
ensureColumn(db, "session_meta", "times_execute_threshold_reached", "INTEGER DEFAULT 0");
|
|
157578
157605
|
ensureColumn(db, "session_meta", "compartment_in_progress", "INTEGER DEFAULT 0");
|
|
@@ -157637,6 +157664,10 @@ function healNullTextColumns(db) {
|
|
|
157637
157664
|
["note_nudge_trigger_message_id", ""],
|
|
157638
157665
|
["note_nudge_sticky_text", ""],
|
|
157639
157666
|
["note_nudge_sticky_message_id", ""],
|
|
157667
|
+
["last_todo_state", ""],
|
|
157668
|
+
["todo_synthetic_call_id", ""],
|
|
157669
|
+
["todo_synthetic_anchor_message_id", ""],
|
|
157670
|
+
["todo_synthetic_state_json", ""],
|
|
157640
157671
|
["system_prompt_hash", ""],
|
|
157641
157672
|
["stripped_placeholder_ids", ""],
|
|
157642
157673
|
["memory_block_cache", ""],
|
|
@@ -163998,7 +164029,8 @@ var META_COLUMNS = {
|
|
|
163998
164029
|
systemPromptTokens: "system_prompt_tokens",
|
|
163999
164030
|
conversationTokens: "conversation_tokens",
|
|
164000
164031
|
toolCallTokens: "tool_call_tokens",
|
|
164001
|
-
clearedReasoningThroughTag: "cleared_reasoning_through_tag"
|
|
164032
|
+
clearedReasoningThroughTag: "cleared_reasoning_through_tag",
|
|
164033
|
+
lastTodoState: "last_todo_state"
|
|
164002
164034
|
};
|
|
164003
164035
|
var BOOLEAN_META_KEYS = new Set(["isSubagent", "compartmentInProgress"]);
|
|
164004
164036
|
function isStringOrNull(value) {
|
|
@@ -164011,7 +164043,7 @@ function isSessionMetaRow(row) {
|
|
|
164011
164043
|
if (row === null || typeof row !== "object")
|
|
164012
164044
|
return false;
|
|
164013
164045
|
const r = row;
|
|
164014
|
-
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag);
|
|
164046
|
+
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag) && isStringOrNull(r.last_todo_state);
|
|
164015
164047
|
}
|
|
164016
164048
|
function getDefaultSessionMeta(sessionId) {
|
|
164017
164049
|
return {
|
|
@@ -164031,7 +164063,8 @@ function getDefaultSessionMeta(sessionId) {
|
|
|
164031
164063
|
systemPromptTokens: 0,
|
|
164032
164064
|
conversationTokens: 0,
|
|
164033
164065
|
toolCallTokens: 0,
|
|
164034
|
-
clearedReasoningThroughTag: 0
|
|
164066
|
+
clearedReasoningThroughTag: 0,
|
|
164067
|
+
lastTodoState: ""
|
|
164035
164068
|
};
|
|
164036
164069
|
}
|
|
164037
164070
|
function ensureSessionMetaRow(db, sessionId) {
|
|
@@ -164043,6 +164076,7 @@ function toSessionMeta(row) {
|
|
|
164043
164076
|
const transformErrorRaw = typeof row.last_transform_error === "string" ? row.last_transform_error : "";
|
|
164044
164077
|
const cacheTtlRaw = typeof row.cache_ttl === "string" && row.cache_ttl.length > 0 ? row.cache_ttl : "5m";
|
|
164045
164078
|
const systemPromptHashRaw = row.system_prompt_hash == null ? "" : row.system_prompt_hash;
|
|
164079
|
+
const lastTodoStateRaw = typeof row.last_todo_state === "string" ? row.last_todo_state : "";
|
|
164046
164080
|
const numOrZero = (value) => typeof value === "number" ? value : 0;
|
|
164047
164081
|
return {
|
|
164048
164082
|
sessionId: row.session_id,
|
|
@@ -164061,7 +164095,8 @@ function toSessionMeta(row) {
|
|
|
164061
164095
|
systemPromptTokens: numOrZero(row.system_prompt_tokens),
|
|
164062
164096
|
conversationTokens: numOrZero(row.conversation_tokens),
|
|
164063
164097
|
toolCallTokens: numOrZero(row.tool_call_tokens),
|
|
164064
|
-
clearedReasoningThroughTag: numOrZero(row.cleared_reasoning_through_tag)
|
|
164098
|
+
clearedReasoningThroughTag: numOrZero(row.cleared_reasoning_through_tag),
|
|
164099
|
+
lastTodoState: lastTodoStateRaw
|
|
164065
164100
|
};
|
|
164066
164101
|
}
|
|
164067
164102
|
|
|
@@ -164277,7 +164312,7 @@ function resolveIsSubagentFromOpenCodeDb(sessionId) {
|
|
|
164277
164312
|
|
|
164278
164313
|
// ../plugin/src/features/magic-context/storage-meta-session.ts
|
|
164279
164314
|
function getOrCreateSessionMeta(db, sessionId) {
|
|
164280
|
-
const result = db.prepare("SELECT session_id, last_response_time, cache_ttl, counter, last_nudge_tokens, last_nudge_band, last_transform_error, is_subagent, last_context_percentage, last_input_tokens, times_execute_threshold_reached, compartment_in_progress, system_prompt_hash, system_prompt_tokens, conversation_tokens, tool_call_tokens, cleared_reasoning_through_tag FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
164315
|
+
const result = db.prepare("SELECT session_id, last_response_time, cache_ttl, counter, last_nudge_tokens, last_nudge_band, last_transform_error, is_subagent, last_context_percentage, last_input_tokens, times_execute_threshold_reached, compartment_in_progress, system_prompt_hash, system_prompt_tokens, conversation_tokens, tool_call_tokens, cleared_reasoning_through_tag, last_todo_state FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
164281
164316
|
if (isSessionMetaRow(result)) {
|
|
164282
164317
|
return toSessionMeta(result);
|
|
164283
164318
|
}
|
package/package.json
CHANGED