@cortexkit/pi-magic-context 0.17.1 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +414 -49
- package/dist/subagent-entry.js +43 -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) {
|
|
@@ -158180,13 +158199,16 @@ function runMigrations(db) {
|
|
|
158180
158199
|
|
|
158181
158200
|
// ../plugin/src/features/magic-context/tool-definition-tokens.ts
|
|
158182
158201
|
var measurements = new Map;
|
|
158202
|
+
var fingerprints = new Map;
|
|
158183
158203
|
var persistenceDb = null;
|
|
158204
|
+
var cachedInsertStmt = null;
|
|
158184
158205
|
function keyFor(providerID, modelID, agentName) {
|
|
158185
158206
|
const agent = agentName && agentName.length > 0 ? agentName : "default";
|
|
158186
158207
|
return `${providerID}/${modelID}/${agent}`;
|
|
158187
158208
|
}
|
|
158188
158209
|
function setDatabase(db) {
|
|
158189
158210
|
persistenceDb = db;
|
|
158211
|
+
cachedInsertStmt = null;
|
|
158190
158212
|
}
|
|
158191
158213
|
function loadToolDefinitionMeasurements(db) {
|
|
158192
158214
|
let rows = [];
|
|
@@ -158682,6 +158704,10 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
158682
158704
|
note_nudge_trigger_message_id TEXT DEFAULT '',
|
|
158683
158705
|
note_nudge_sticky_text TEXT DEFAULT '',
|
|
158684
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 '',
|
|
158685
158711
|
is_subagent INTEGER DEFAULT 0,
|
|
158686
158712
|
last_context_percentage REAL DEFAULT 0,
|
|
158687
158713
|
last_input_tokens INTEGER DEFAULT 0,
|
|
@@ -158746,6 +158772,10 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
158746
158772
|
ensureColumn(db, "session_meta", "note_nudge_trigger_message_id", "TEXT DEFAULT ''");
|
|
158747
158773
|
ensureColumn(db, "session_meta", "note_nudge_sticky_text", "TEXT DEFAULT ''");
|
|
158748
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 ''");
|
|
158749
158779
|
ensureColumn(db, "session_meta", "note_last_read_at", "INTEGER DEFAULT 0");
|
|
158750
158780
|
ensureColumn(db, "session_meta", "times_execute_threshold_reached", "INTEGER DEFAULT 0");
|
|
158751
158781
|
ensureColumn(db, "session_meta", "compartment_in_progress", "INTEGER DEFAULT 0");
|
|
@@ -158810,6 +158840,10 @@ function healNullTextColumns(db) {
|
|
|
158810
158840
|
["note_nudge_trigger_message_id", ""],
|
|
158811
158841
|
["note_nudge_sticky_text", ""],
|
|
158812
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", ""],
|
|
158813
158847
|
["system_prompt_hash", ""],
|
|
158814
158848
|
["stripped_placeholder_ids", ""],
|
|
158815
158849
|
["memory_block_cache", ""],
|
|
@@ -158903,7 +158937,8 @@ var META_COLUMNS = {
|
|
|
158903
158937
|
systemPromptTokens: "system_prompt_tokens",
|
|
158904
158938
|
conversationTokens: "conversation_tokens",
|
|
158905
158939
|
toolCallTokens: "tool_call_tokens",
|
|
158906
|
-
clearedReasoningThroughTag: "cleared_reasoning_through_tag"
|
|
158940
|
+
clearedReasoningThroughTag: "cleared_reasoning_through_tag",
|
|
158941
|
+
lastTodoState: "last_todo_state"
|
|
158907
158942
|
};
|
|
158908
158943
|
var BOOLEAN_META_KEYS = new Set(["isSubagent", "compartmentInProgress"]);
|
|
158909
158944
|
function isStringOrNull(value) {
|
|
@@ -158916,7 +158951,7 @@ function isSessionMetaRow(row) {
|
|
|
158916
158951
|
if (row === null || typeof row !== "object")
|
|
158917
158952
|
return false;
|
|
158918
158953
|
const r = row;
|
|
158919
|
-
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);
|
|
158920
158955
|
}
|
|
158921
158956
|
function getDefaultSessionMeta(sessionId) {
|
|
158922
158957
|
return {
|
|
@@ -158936,7 +158971,8 @@ function getDefaultSessionMeta(sessionId) {
|
|
|
158936
158971
|
systemPromptTokens: 0,
|
|
158937
158972
|
conversationTokens: 0,
|
|
158938
158973
|
toolCallTokens: 0,
|
|
158939
|
-
clearedReasoningThroughTag: 0
|
|
158974
|
+
clearedReasoningThroughTag: 0,
|
|
158975
|
+
lastTodoState: ""
|
|
158940
158976
|
};
|
|
158941
158977
|
}
|
|
158942
158978
|
function ensureSessionMetaRow(db, sessionId) {
|
|
@@ -158948,6 +158984,7 @@ function toSessionMeta(row) {
|
|
|
158948
158984
|
const transformErrorRaw = typeof row.last_transform_error === "string" ? row.last_transform_error : "";
|
|
158949
158985
|
const cacheTtlRaw = typeof row.cache_ttl === "string" && row.cache_ttl.length > 0 ? row.cache_ttl : "5m";
|
|
158950
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 : "";
|
|
158951
158988
|
const numOrZero = (value) => typeof value === "number" ? value : 0;
|
|
158952
158989
|
return {
|
|
158953
158990
|
sessionId: row.session_id,
|
|
@@ -158966,7 +159003,8 @@ function toSessionMeta(row) {
|
|
|
158966
159003
|
systemPromptTokens: numOrZero(row.system_prompt_tokens),
|
|
158967
159004
|
conversationTokens: numOrZero(row.conversation_tokens),
|
|
158968
159005
|
toolCallTokens: numOrZero(row.tool_call_tokens),
|
|
158969
|
-
clearedReasoningThroughTag: numOrZero(row.cleared_reasoning_through_tag)
|
|
159006
|
+
clearedReasoningThroughTag: numOrZero(row.cleared_reasoning_through_tag),
|
|
159007
|
+
lastTodoState: lastTodoStateRaw
|
|
158970
159008
|
};
|
|
158971
159009
|
}
|
|
158972
159010
|
|
|
@@ -159182,7 +159220,7 @@ function resolveIsSubagentFromOpenCodeDb(sessionId) {
|
|
|
159182
159220
|
|
|
159183
159221
|
// ../plugin/src/features/magic-context/storage-meta-session.ts
|
|
159184
159222
|
function getOrCreateSessionMeta(db, sessionId) {
|
|
159185
|
-
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);
|
|
159186
159224
|
if (isSessionMetaRow(result)) {
|
|
159187
159225
|
return toSessionMeta(result);
|
|
159188
159226
|
}
|
|
@@ -159748,14 +159786,118 @@ function expandFallbackChain(chain) {
|
|
|
159748
159786
|
}
|
|
159749
159787
|
return models;
|
|
159750
159788
|
}
|
|
159789
|
+
function getAgentFallbackModels(agent) {
|
|
159790
|
+
const requirement = AGENT_MODEL_REQUIREMENTS[agent];
|
|
159791
|
+
if (!requirement)
|
|
159792
|
+
return;
|
|
159793
|
+
return expandFallbackChain(requirement.fallbackChain);
|
|
159794
|
+
}
|
|
159751
159795
|
|
|
159752
159796
|
// ../plugin/src/shared/models-dev-cache.ts
|
|
159753
159797
|
init_data_path();
|
|
159754
|
-
init_logger();
|
|
159755
159798
|
import { createHash as createHash3 } from "node:crypto";
|
|
159756
159799
|
import { existsSync as existsSync4, readFileSync } from "node:fs";
|
|
159757
159800
|
import { homedir as homedir2, platform } from "node:os";
|
|
159758
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();
|
|
159759
159901
|
var RELOAD_INTERVAL_MS = 5 * 60 * 1000;
|
|
159760
159902
|
var apiCache = null;
|
|
159761
159903
|
var recentlySeenApiSizes = new Set;
|
|
@@ -159830,9 +159972,7 @@ function loadModelsDevMetadataFromFile() {
|
|
|
159830
159972
|
try {
|
|
159831
159973
|
const configPath = getOpencodeConfigPath();
|
|
159832
159974
|
if (configPath && existsSync4(configPath)) {
|
|
159833
|
-
|
|
159834
|
-
raw = raw.replace(/"(?:[^"\\]|\\.)*"|\/\/.*$/gm, (match) => match.startsWith('"') ? match : "");
|
|
159835
|
-
const config2 = JSON.parse(raw);
|
|
159975
|
+
const config2 = parseJsonc(readFileSync(configPath, "utf-8"));
|
|
159836
159976
|
if (config2.provider && typeof config2.provider === "object") {
|
|
159837
159977
|
for (const [providerId, provider2] of Object.entries(config2.provider)) {
|
|
159838
159978
|
if (!provider2?.models || typeof provider2.models !== "object")
|
|
@@ -160771,6 +160911,53 @@ init_logger();
|
|
|
160771
160911
|
|
|
160772
160912
|
// ../plugin/src/shared/model-suggestion-retry.ts
|
|
160773
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
|
|
160774
160961
|
function extractMessage(error51) {
|
|
160775
160962
|
if (typeof error51 === "string")
|
|
160776
160963
|
return error51;
|
|
@@ -160825,6 +161012,9 @@ function parseModelSuggestion(error51) {
|
|
|
160825
161012
|
};
|
|
160826
161013
|
}
|
|
160827
161014
|
async function promptWithTimeout(client, args, timeoutMs, signal) {
|
|
161015
|
+
if (signal?.aborted) {
|
|
161016
|
+
throw new Error("prompt aborted by external signal");
|
|
161017
|
+
}
|
|
160828
161018
|
const controller = new AbortController;
|
|
160829
161019
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
160830
161020
|
const onExternalAbort = () => controller.abort();
|
|
@@ -160847,16 +161037,39 @@ async function promptWithTimeout(client, args, timeoutMs, signal) {
|
|
|
160847
161037
|
signal?.removeEventListener("abort", onExternalAbort);
|
|
160848
161038
|
}
|
|
160849
161039
|
}
|
|
160850
|
-
|
|
160851
|
-
|
|
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) {
|
|
160852
161062
|
try {
|
|
160853
|
-
await promptWithTimeout(client, args, timeoutMs,
|
|
161063
|
+
await promptWithTimeout(client, args, timeoutMs, signal);
|
|
161064
|
+
return;
|
|
160854
161065
|
} catch (error51) {
|
|
161066
|
+
if (isNonRetryable(error51, signal))
|
|
161067
|
+
throw error51;
|
|
160855
161068
|
const suggestion = parseModelSuggestion(error51);
|
|
160856
161069
|
if (!suggestion || !args.body.model) {
|
|
160857
161070
|
throw error51;
|
|
160858
161071
|
}
|
|
160859
|
-
log(
|
|
161072
|
+
log(`[${callContext}] ${label}: model not found, retrying with suggestion`, {
|
|
160860
161073
|
original: `${suggestion.providerID}/${suggestion.modelID}`,
|
|
160861
161074
|
suggested: suggestion.suggestion
|
|
160862
161075
|
});
|
|
@@ -160869,9 +161082,55 @@ async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
|
|
|
160869
161082
|
modelID: suggestion.suggestion
|
|
160870
161083
|
}
|
|
160871
161084
|
}
|
|
160872
|
-
}, timeoutMs,
|
|
161085
|
+
}, timeoutMs, signal);
|
|
160873
161086
|
}
|
|
160874
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
|
+
}
|
|
160875
161134
|
// ../plugin/src/shared/normalize-sdk-response.ts
|
|
160876
161135
|
function normalizeSDKResponse(response, fallback, options) {
|
|
160877
161136
|
if (response === null || response === undefined) {
|
|
@@ -162049,7 +162308,12 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
162049
162308
|
system: DREAMER_SYSTEM_PROMPT,
|
|
162050
162309
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
162051
162310
|
}
|
|
162052
|
-
}, {
|
|
162311
|
+
}, {
|
|
162312
|
+
timeoutMs: Math.min(remainingMs, 5 * 60 * 1000),
|
|
162313
|
+
signal: abortController.signal,
|
|
162314
|
+
fallbackModels: args.fallbackModels,
|
|
162315
|
+
callContext: "dreamer:user-memories"
|
|
162316
|
+
});
|
|
162053
162317
|
const messagesResponse = await args.client.session.messages({
|
|
162054
162318
|
path: { id: agentSessionId },
|
|
162055
162319
|
query: { directory: args.sessionDirectory }
|
|
@@ -162108,7 +162372,8 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
162108
162372
|
}
|
|
162109
162373
|
return result;
|
|
162110
162374
|
} catch (error51) {
|
|
162111
|
-
|
|
162375
|
+
const errorDescription = describeError(error51);
|
|
162376
|
+
log(`[dreamer] user-memories: review failed: ${errorDescription.brief}`, errorDescription.stackHead ? { stackHead: errorDescription.stackHead } : undefined);
|
|
162112
162377
|
return result;
|
|
162113
162378
|
} finally {
|
|
162114
162379
|
clearInterval(leaseInterval);
|
|
@@ -162140,6 +162405,7 @@ function insertDreamRun(db, run) {
|
|
|
162140
162405
|
|
|
162141
162406
|
// ../plugin/src/features/magic-context/dreamer/runner.ts
|
|
162142
162407
|
var dreamProjectDirectories = new Map;
|
|
162408
|
+
var CIRCUIT_BREAKER_THRESHOLD = 3;
|
|
162143
162409
|
function registerDreamProjectDirectory(projectIdentity, directory) {
|
|
162144
162410
|
dreamProjectDirectories.set(projectIdentity, directory);
|
|
162145
162411
|
}
|
|
@@ -162156,6 +162422,25 @@ function countNewIds(beforeIds, afterIds) {
|
|
|
162156
162422
|
}
|
|
162157
162423
|
return count;
|
|
162158
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
|
+
}
|
|
162159
162444
|
function getOpenCodeDbPath2() {
|
|
162160
162445
|
return join9(getDataDir(), "opencode", "opencode.db");
|
|
162161
162446
|
}
|
|
@@ -162261,7 +162546,12 @@ async function identifyKeyFilesForSession(args) {
|
|
|
162261
162546
|
system: KEY_FILES_SYSTEM_PROMPT,
|
|
162262
162547
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
162263
162548
|
}
|
|
162264
|
-
}, {
|
|
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
|
+
});
|
|
162265
162555
|
const messagesResponse = await args.client.session.messages({
|
|
162266
162556
|
path: { id: agentSessionId },
|
|
162267
162557
|
query: { directory: args.sessionDirectory }
|
|
@@ -162334,6 +162624,7 @@ async function identifyKeyFiles(args) {
|
|
|
162334
162624
|
parentSessionId: args.parentSessionId,
|
|
162335
162625
|
sessionDirectory: args.sessionDirectory,
|
|
162336
162626
|
holderId: args.holderId,
|
|
162627
|
+
fallbackModels: args.fallbackModels,
|
|
162337
162628
|
deadline: args.deadline,
|
|
162338
162629
|
sessionId,
|
|
162339
162630
|
config: args.config
|
|
@@ -162387,6 +162678,9 @@ async function runDream(args) {
|
|
|
162387
162678
|
const deadline = startedAt + args.maxRuntimeMinutes * 60 * 1000;
|
|
162388
162679
|
const lastDreamAt = getDreamState(args.db, `last_dream_at:${args.projectIdentity}`) ?? getDreamState(args.db, "last_dream_at");
|
|
162389
162680
|
log(`[dreamer] last dream at: ${lastDreamAt ?? "never"} (project=${args.projectIdentity})`);
|
|
162681
|
+
let lastErrorSignature = null;
|
|
162682
|
+
let consecutiveSameErrorFailures = 0;
|
|
162683
|
+
let circuitBreakerTripped = false;
|
|
162390
162684
|
try {
|
|
162391
162685
|
for (const taskName of args.tasks) {
|
|
162392
162686
|
if (Date.now() > deadline) {
|
|
@@ -162447,7 +162741,9 @@ async function runDream(args) {
|
|
|
162447
162741
|
}
|
|
162448
162742
|
}, {
|
|
162449
162743
|
timeoutMs: args.taskTimeoutMinutes * 60 * 1000,
|
|
162450
|
-
signal: taskAbortController.signal
|
|
162744
|
+
signal: taskAbortController.signal,
|
|
162745
|
+
fallbackModels: args.fallbackModels,
|
|
162746
|
+
callContext: `dreamer:${taskName}`
|
|
162451
162747
|
});
|
|
162452
162748
|
const messagesResponse = await args.client.session.messages({
|
|
162453
162749
|
path: { id: agentSessionId },
|
|
@@ -162467,16 +162763,40 @@ async function runDream(args) {
|
|
|
162467
162763
|
durationMs,
|
|
162468
162764
|
result: taskResult
|
|
162469
162765
|
});
|
|
162766
|
+
lastErrorSignature = null;
|
|
162767
|
+
consecutiveSameErrorFailures = 0;
|
|
162470
162768
|
} catch (error51) {
|
|
162471
162769
|
const durationMs = Date.now() - taskStartedAt;
|
|
162472
|
-
const
|
|
162473
|
-
|
|
162770
|
+
const errorDescription = describeError(error51);
|
|
162771
|
+
logWithStackHead(`[dreamer] task ${taskName}: failed after ${(durationMs / 1000).toFixed(1)}s — ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162474
162772
|
result.tasks.push({
|
|
162475
162773
|
name: taskName,
|
|
162476
162774
|
durationMs,
|
|
162477
162775
|
result: null,
|
|
162478
|
-
error:
|
|
162776
|
+
error: errorDescription.brief
|
|
162479
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
|
+
}
|
|
162480
162800
|
} finally {
|
|
162481
162801
|
clearInterval(leaseRenewalInterval);
|
|
162482
162802
|
if (agentSessionId) {
|
|
@@ -162488,8 +162808,20 @@ async function runDream(args) {
|
|
|
162488
162808
|
});
|
|
162489
162809
|
}
|
|
162490
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
|
+
});
|
|
162491
162823
|
}
|
|
162492
|
-
if (args.experimentalUserMemories?.enabled && Date.now() <= deadline) {
|
|
162824
|
+
if (!circuitBreakerTripped && args.experimentalUserMemories?.enabled && Date.now() <= deadline) {
|
|
162493
162825
|
const umStart = Date.now();
|
|
162494
162826
|
try {
|
|
162495
162827
|
const reviewResult = await reviewUserMemories({
|
|
@@ -162499,7 +162831,8 @@ async function runDream(args) {
|
|
|
162499
162831
|
sessionDirectory: args.sessionDirectory,
|
|
162500
162832
|
holderId,
|
|
162501
162833
|
deadline,
|
|
162502
|
-
promotionThreshold: args.experimentalUserMemories.promotionThreshold
|
|
162834
|
+
promotionThreshold: args.experimentalUserMemories.promotionThreshold,
|
|
162835
|
+
fallbackModels: args.fallbackModels
|
|
162503
162836
|
});
|
|
162504
162837
|
const umOutput = `promoted=${reviewResult.promoted} merged=${reviewResult.merged} dismissed=${reviewResult.dismissed} consumed=${reviewResult.candidatesConsumed}`;
|
|
162505
162838
|
if (reviewResult.promoted > 0 || reviewResult.merged > 0 || reviewResult.dismissed > 0) {
|
|
@@ -162511,16 +162844,17 @@ async function runDream(args) {
|
|
|
162511
162844
|
result: umOutput
|
|
162512
162845
|
});
|
|
162513
162846
|
} catch (error51) {
|
|
162514
|
-
|
|
162847
|
+
const errorDescription = describeError(error51);
|
|
162848
|
+
logWithStackHead(`[dreamer] user-memory review failed: ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162515
162849
|
result.tasks.push({
|
|
162516
162850
|
name: "user memories",
|
|
162517
162851
|
durationMs: Date.now() - umStart,
|
|
162518
162852
|
result: "",
|
|
162519
|
-
error:
|
|
162853
|
+
error: errorDescription.brief
|
|
162520
162854
|
});
|
|
162521
162855
|
}
|
|
162522
162856
|
}
|
|
162523
|
-
if (Date.now() <= deadline) {
|
|
162857
|
+
if (!circuitBreakerTripped && Date.now() <= deadline) {
|
|
162524
162858
|
try {
|
|
162525
162859
|
await evaluateSmartNotes({
|
|
162526
162860
|
db: args.db,
|
|
@@ -162530,13 +162864,15 @@ async function runDream(args) {
|
|
|
162530
162864
|
sessionDirectory: args.sessionDirectory,
|
|
162531
162865
|
holderId,
|
|
162532
162866
|
deadline,
|
|
162533
|
-
result
|
|
162867
|
+
result,
|
|
162868
|
+
fallbackModels: args.fallbackModels
|
|
162534
162869
|
});
|
|
162535
162870
|
} catch (error51) {
|
|
162536
|
-
|
|
162871
|
+
const errorDescription = describeError(error51);
|
|
162872
|
+
logWithStackHead(`[dreamer] smart note evaluation failed: ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162537
162873
|
}
|
|
162538
162874
|
}
|
|
162539
|
-
if (args.experimentalPinKeyFiles?.enabled && Date.now() <= deadline) {
|
|
162875
|
+
if (!circuitBreakerTripped && args.experimentalPinKeyFiles?.enabled && Date.now() <= deadline) {
|
|
162540
162876
|
const kfStart = Date.now();
|
|
162541
162877
|
try {
|
|
162542
162878
|
await identifyKeyFiles({
|
|
@@ -162547,7 +162883,8 @@ async function runDream(args) {
|
|
|
162547
162883
|
sessionDirectory: args.sessionDirectory ?? args.projectIdentity,
|
|
162548
162884
|
holderId,
|
|
162549
162885
|
deadline,
|
|
162550
|
-
config: args.experimentalPinKeyFiles
|
|
162886
|
+
config: args.experimentalPinKeyFiles,
|
|
162887
|
+
fallbackModels: args.fallbackModels
|
|
162551
162888
|
});
|
|
162552
162889
|
result.tasks.push({
|
|
162553
162890
|
name: "key files",
|
|
@@ -162555,12 +162892,13 @@ async function runDream(args) {
|
|
|
162555
162892
|
result: "completed"
|
|
162556
162893
|
});
|
|
162557
162894
|
} catch (error51) {
|
|
162558
|
-
|
|
162895
|
+
const errorDescription = describeError(error51);
|
|
162896
|
+
logWithStackHead(`[key-files] identification phase failed: ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162559
162897
|
result.tasks.push({
|
|
162560
162898
|
name: "key files",
|
|
162561
162899
|
durationMs: Date.now() - kfStart,
|
|
162562
162900
|
result: "",
|
|
162563
|
-
error:
|
|
162901
|
+
error: errorDescription.brief
|
|
162564
162902
|
});
|
|
162565
162903
|
}
|
|
162566
162904
|
}
|
|
@@ -162595,7 +162933,13 @@ async function runDream(args) {
|
|
|
162595
162933
|
smartNotesPending: result.smartNotesPending,
|
|
162596
162934
|
memoryChanges: persistedMemoryChanges
|
|
162597
162935
|
});
|
|
162598
|
-
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
|
+
]);
|
|
162599
162943
|
const hasSuccessfulTask = result.tasks.some((t) => !t.error && !POST_TASK_NAMES.has(t.name));
|
|
162600
162944
|
if (hasSuccessfulTask) {
|
|
162601
162945
|
setDreamState(args.db, `last_dream_at:${args.projectIdentity}`, String(result.finishedAt));
|
|
@@ -162674,7 +163018,12 @@ Only include notes whose conditions you could definitively evaluate. Skip notes
|
|
|
162674
163018
|
system: DREAMER_SYSTEM_PROMPT,
|
|
162675
163019
|
parts: [{ type: "text", text: evaluationPrompt, synthetic: true }]
|
|
162676
163020
|
}
|
|
162677
|
-
}, {
|
|
163021
|
+
}, {
|
|
163022
|
+
timeoutMs: Math.min(remainingMs, 300000),
|
|
163023
|
+
signal: abortController.signal,
|
|
163024
|
+
fallbackModels: args.fallbackModels,
|
|
163025
|
+
callContext: "dreamer:smart-notes"
|
|
163026
|
+
});
|
|
162678
163027
|
const messagesResponse = await args.client.session.messages({
|
|
162679
163028
|
path: { id: agentSessionId },
|
|
162680
163029
|
query: { directory: args.sessionDirectory ?? args.projectIdentity }
|
|
@@ -162733,15 +163082,15 @@ Only include notes whose conditions you could definitively evaluate. Skip notes
|
|
|
162733
163082
|
});
|
|
162734
163083
|
} catch (error51) {
|
|
162735
163084
|
const durationMs = Date.now() - taskStartedAt;
|
|
162736
|
-
const
|
|
163085
|
+
const errorDescription = describeError(error51);
|
|
162737
163086
|
args.result.smartNotesSurfaced = 0;
|
|
162738
163087
|
args.result.smartNotesPending = pendingNotes.length;
|
|
162739
|
-
|
|
163088
|
+
logWithStackHead(`[dreamer] smart notes: failed after ${(durationMs / 1000).toFixed(1)}s — ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162740
163089
|
args.result.tasks.push({
|
|
162741
163090
|
name: "smart-notes",
|
|
162742
163091
|
durationMs,
|
|
162743
163092
|
result: null,
|
|
162744
|
-
error:
|
|
163093
|
+
error: errorDescription.brief
|
|
162745
163094
|
});
|
|
162746
163095
|
} finally {
|
|
162747
163096
|
clearInterval(leaseInterval);
|
|
@@ -162774,7 +163123,8 @@ async function processDreamQueue(args) {
|
|
|
162774
163123
|
maxRuntimeMinutes: args.maxRuntimeMinutes,
|
|
162775
163124
|
sessionDirectory: projectDirectory,
|
|
162776
163125
|
experimentalUserMemories: args.experimentalUserMemories,
|
|
162777
|
-
experimentalPinKeyFiles: args.experimentalPinKeyFiles
|
|
163126
|
+
experimentalPinKeyFiles: args.experimentalPinKeyFiles,
|
|
163127
|
+
fallbackModels: args.fallbackModels
|
|
162778
163128
|
});
|
|
162779
163129
|
} catch (error51) {
|
|
162780
163130
|
log(`[dreamer] runDream threw for ${entry.projectIdentity}: ${getErrorMessage(error51)}`);
|
|
@@ -163498,7 +163848,8 @@ async function sweepProject(reg, origin) {
|
|
|
163498
163848
|
maxRuntimeMinutes: reg.dreamerConfig.max_runtime_minutes,
|
|
163499
163849
|
experimentalUserMemories: reg.experimentalUserMemories,
|
|
163500
163850
|
experimentalPinKeyFiles: reg.experimentalPinKeyFiles,
|
|
163501
|
-
projectIdentity: registrationIdentity
|
|
163851
|
+
projectIdentity: registrationIdentity,
|
|
163852
|
+
fallbackModels: resolveFallbackChain(DREAMER_AGENT, reg.dreamerConfig.fallback_models)
|
|
163502
163853
|
});
|
|
163503
163854
|
} catch (error51) {
|
|
163504
163855
|
log(`[dreamer] timer-triggered queue processing failed for ${reg.directory}:`, error51);
|
|
@@ -165296,8 +165647,9 @@ function tagTranscript(sessionId, transcript, tagger, db, options = {}) {
|
|
|
165296
165647
|
continue;
|
|
165297
165648
|
const messageId = message.info.id;
|
|
165298
165649
|
let textOrdinal = 0;
|
|
165299
|
-
|
|
165300
|
-
|
|
165650
|
+
const parts = message.parts;
|
|
165651
|
+
for (let partIndex = 0;partIndex < parts.length; partIndex += 1) {
|
|
165652
|
+
const part = parts[partIndex];
|
|
165301
165653
|
if (part === undefined)
|
|
165302
165654
|
continue;
|
|
165303
165655
|
if (part.kind === "text") {
|
|
@@ -166264,7 +166616,7 @@ var DEDUP_SAFE_TOOLS = new Set([
|
|
|
166264
166616
|
"mcp_lsp_prepare_rename"
|
|
166265
166617
|
]);
|
|
166266
166618
|
function buildPiToolFingerprints(messages) {
|
|
166267
|
-
const
|
|
166619
|
+
const fingerprints2 = new Map;
|
|
166268
166620
|
for (const message of messages) {
|
|
166269
166621
|
if (!message || typeof message !== "object")
|
|
166270
166622
|
continue;
|
|
@@ -166295,10 +166647,10 @@ function buildPiToolFingerprints(messages) {
|
|
|
166295
166647
|
} catch {
|
|
166296
166648
|
continue;
|
|
166297
166649
|
}
|
|
166298
|
-
|
|
166650
|
+
fingerprints2.set(p.id, `${p.name}:${serialized}`);
|
|
166299
166651
|
}
|
|
166300
166652
|
}
|
|
166301
|
-
return
|
|
166653
|
+
return fingerprints2;
|
|
166302
166654
|
}
|
|
166303
166655
|
function collectStaleReduceCallIds(messages, messageIdToMaxTag, toolAgeCutoff) {
|
|
166304
166656
|
const staleCallIds = new Set;
|
|
@@ -170396,7 +170748,8 @@ async function runCompressorPass2(args) {
|
|
|
170396
170748
|
targetTokens,
|
|
170397
170749
|
outputCount,
|
|
170398
170750
|
outputDepth,
|
|
170399
|
-
historianTimeoutMs
|
|
170751
|
+
historianTimeoutMs,
|
|
170752
|
+
fallbackModels
|
|
170400
170753
|
} = args;
|
|
170401
170754
|
const prompt = buildCompressorPrompt(compartments, currentTokens, targetTokens, outputDepth, outputCount);
|
|
170402
170755
|
let agentSessionId = null;
|
|
@@ -170418,7 +170771,11 @@ async function runCompressorPass2(args) {
|
|
|
170418
170771
|
agent: HISTORIAN_AGENT2,
|
|
170419
170772
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
170420
170773
|
}
|
|
170421
|
-
}, {
|
|
170774
|
+
}, {
|
|
170775
|
+
timeoutMs: historianTimeoutMs ?? DEFAULT_HISTORIAN_TIMEOUT_MS,
|
|
170776
|
+
fallbackModels,
|
|
170777
|
+
callContext: "compressor"
|
|
170778
|
+
});
|
|
170422
170779
|
const messagesResponse = await client.session.messages({
|
|
170423
170780
|
path: { id: agentSessionId },
|
|
170424
170781
|
query: { directory }
|
|
@@ -170556,7 +170913,8 @@ async function runHistorianPrompt(args) {
|
|
|
170556
170913
|
timeoutMs,
|
|
170557
170914
|
dumpLabel,
|
|
170558
170915
|
modelOverride,
|
|
170559
|
-
agentId = HISTORIAN_AGENT
|
|
170916
|
+
agentId = HISTORIAN_AGENT,
|
|
170917
|
+
fallbackModels
|
|
170560
170918
|
} = args;
|
|
170561
170919
|
let agentSessionId = null;
|
|
170562
170920
|
try {
|
|
@@ -170583,7 +170941,11 @@ async function runHistorianPrompt(args) {
|
|
|
170583
170941
|
...modelOverride ? { model: modelOverride } : {},
|
|
170584
170942
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
170585
170943
|
}
|
|
170586
|
-
}, {
|
|
170944
|
+
}, {
|
|
170945
|
+
timeoutMs: timeoutMs ?? DEFAULT_HISTORIAN_TIMEOUT_MS,
|
|
170946
|
+
fallbackModels: modelOverride ? undefined : fallbackModels,
|
|
170947
|
+
callContext: agentId === HISTORIAN_EDITOR_AGENT ? "historian:editor" : "historian"
|
|
170948
|
+
});
|
|
170587
170949
|
sessionLog(parentSessionId, `historian: prompt completed (attempt ${retryIndex + 1}/${MAX_HISTORIAN_RETRIES + 1})`);
|
|
170588
170950
|
break;
|
|
170589
170951
|
} catch (error51) {
|
|
@@ -171039,6 +171401,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
171039
171401
|
dumpLabelBase: `partial-recomp-${sessionId}-${chunk.startIndex}-${chunk.endIndex}-pass-${passCount + 1}`,
|
|
171040
171402
|
timeoutMs: historianTimeoutMs,
|
|
171041
171403
|
fallbackModelId: deps.fallbackModelId,
|
|
171404
|
+
fallbackModels: deps.fallbackModels,
|
|
171042
171405
|
twoPass: deps.historianTwoPass,
|
|
171043
171406
|
callbacks: {
|
|
171044
171407
|
onRepairRetry: async (error51) => {
|
|
@@ -171241,6 +171604,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
171241
171604
|
dumpLabelBase: `recomp-${sessionId}-${chunk.startIndex}-${chunk.endIndex}-pass-${passCount + 1}`,
|
|
171242
171605
|
timeoutMs: historianTimeoutMs,
|
|
171243
171606
|
fallbackModelId: deps.fallbackModelId,
|
|
171607
|
+
fallbackModels: deps.fallbackModels,
|
|
171244
171608
|
twoPass: deps.historianTwoPass,
|
|
171245
171609
|
callbacks: {
|
|
171246
171610
|
onRepairRetry: async (error51) => {
|
|
@@ -171338,6 +171702,7 @@ Nothing was written.`;
|
|
|
171338
171702
|
directory: sessionDirectory,
|
|
171339
171703
|
historyBudgetTokens: deps.historyBudgetTokens,
|
|
171340
171704
|
historianTimeoutMs,
|
|
171705
|
+
fallbackModels: deps.fallbackModels,
|
|
171341
171706
|
minCompartmentRatio: deps.compressorMinCompartmentRatio,
|
|
171342
171707
|
maxMergeDepth: deps.compressorMaxMergeDepth
|
|
171343
171708
|
});
|
|
@@ -171874,7 +172239,7 @@ import {
|
|
|
171874
172239
|
// package.json
|
|
171875
172240
|
var package_default = {
|
|
171876
172241
|
name: "@cortexkit/pi-magic-context",
|
|
171877
|
-
version: "0.
|
|
172242
|
+
version: "0.18.0",
|
|
171878
172243
|
type: "module",
|
|
171879
172244
|
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
171880
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) {
|
|
@@ -157004,13 +157023,16 @@ function mergeCommitHashes(existing, next) {
|
|
|
157004
157023
|
|
|
157005
157024
|
// ../plugin/src/features/magic-context/tool-definition-tokens.ts
|
|
157006
157025
|
var measurements = new Map;
|
|
157026
|
+
var fingerprints = new Map;
|
|
157007
157027
|
var persistenceDb = null;
|
|
157028
|
+
var cachedInsertStmt = null;
|
|
157008
157029
|
function keyFor(providerID, modelID, agentName) {
|
|
157009
157030
|
const agent = agentName && agentName.length > 0 ? agentName : "default";
|
|
157010
157031
|
return `${providerID}/${modelID}/${agent}`;
|
|
157011
157032
|
}
|
|
157012
157033
|
function setDatabase(db) {
|
|
157013
157034
|
persistenceDb = db;
|
|
157035
|
+
cachedInsertStmt = null;
|
|
157014
157036
|
}
|
|
157015
157037
|
function loadToolDefinitionMeasurements(db) {
|
|
157016
157038
|
let rows = [];
|
|
@@ -157506,6 +157528,10 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
157506
157528
|
note_nudge_trigger_message_id TEXT DEFAULT '',
|
|
157507
157529
|
note_nudge_sticky_text TEXT DEFAULT '',
|
|
157508
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 '',
|
|
157509
157535
|
is_subagent INTEGER DEFAULT 0,
|
|
157510
157536
|
last_context_percentage REAL DEFAULT 0,
|
|
157511
157537
|
last_input_tokens INTEGER DEFAULT 0,
|
|
@@ -157570,6 +157596,10 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
157570
157596
|
ensureColumn(db, "session_meta", "note_nudge_trigger_message_id", "TEXT DEFAULT ''");
|
|
157571
157597
|
ensureColumn(db, "session_meta", "note_nudge_sticky_text", "TEXT DEFAULT ''");
|
|
157572
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 ''");
|
|
157573
157603
|
ensureColumn(db, "session_meta", "note_last_read_at", "INTEGER DEFAULT 0");
|
|
157574
157604
|
ensureColumn(db, "session_meta", "times_execute_threshold_reached", "INTEGER DEFAULT 0");
|
|
157575
157605
|
ensureColumn(db, "session_meta", "compartment_in_progress", "INTEGER DEFAULT 0");
|
|
@@ -157634,6 +157664,10 @@ function healNullTextColumns(db) {
|
|
|
157634
157664
|
["note_nudge_trigger_message_id", ""],
|
|
157635
157665
|
["note_nudge_sticky_text", ""],
|
|
157636
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", ""],
|
|
157637
157671
|
["system_prompt_hash", ""],
|
|
157638
157672
|
["stripped_placeholder_ids", ""],
|
|
157639
157673
|
["memory_block_cache", ""],
|
|
@@ -163995,7 +164029,8 @@ var META_COLUMNS = {
|
|
|
163995
164029
|
systemPromptTokens: "system_prompt_tokens",
|
|
163996
164030
|
conversationTokens: "conversation_tokens",
|
|
163997
164031
|
toolCallTokens: "tool_call_tokens",
|
|
163998
|
-
clearedReasoningThroughTag: "cleared_reasoning_through_tag"
|
|
164032
|
+
clearedReasoningThroughTag: "cleared_reasoning_through_tag",
|
|
164033
|
+
lastTodoState: "last_todo_state"
|
|
163999
164034
|
};
|
|
164000
164035
|
var BOOLEAN_META_KEYS = new Set(["isSubagent", "compartmentInProgress"]);
|
|
164001
164036
|
function isStringOrNull(value) {
|
|
@@ -164008,7 +164043,7 @@ function isSessionMetaRow(row) {
|
|
|
164008
164043
|
if (row === null || typeof row !== "object")
|
|
164009
164044
|
return false;
|
|
164010
164045
|
const r = row;
|
|
164011
|
-
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);
|
|
164012
164047
|
}
|
|
164013
164048
|
function getDefaultSessionMeta(sessionId) {
|
|
164014
164049
|
return {
|
|
@@ -164028,7 +164063,8 @@ function getDefaultSessionMeta(sessionId) {
|
|
|
164028
164063
|
systemPromptTokens: 0,
|
|
164029
164064
|
conversationTokens: 0,
|
|
164030
164065
|
toolCallTokens: 0,
|
|
164031
|
-
clearedReasoningThroughTag: 0
|
|
164066
|
+
clearedReasoningThroughTag: 0,
|
|
164067
|
+
lastTodoState: ""
|
|
164032
164068
|
};
|
|
164033
164069
|
}
|
|
164034
164070
|
function ensureSessionMetaRow(db, sessionId) {
|
|
@@ -164040,6 +164076,7 @@ function toSessionMeta(row) {
|
|
|
164040
164076
|
const transformErrorRaw = typeof row.last_transform_error === "string" ? row.last_transform_error : "";
|
|
164041
164077
|
const cacheTtlRaw = typeof row.cache_ttl === "string" && row.cache_ttl.length > 0 ? row.cache_ttl : "5m";
|
|
164042
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 : "";
|
|
164043
164080
|
const numOrZero = (value) => typeof value === "number" ? value : 0;
|
|
164044
164081
|
return {
|
|
164045
164082
|
sessionId: row.session_id,
|
|
@@ -164058,7 +164095,8 @@ function toSessionMeta(row) {
|
|
|
164058
164095
|
systemPromptTokens: numOrZero(row.system_prompt_tokens),
|
|
164059
164096
|
conversationTokens: numOrZero(row.conversation_tokens),
|
|
164060
164097
|
toolCallTokens: numOrZero(row.tool_call_tokens),
|
|
164061
|
-
clearedReasoningThroughTag: numOrZero(row.cleared_reasoning_through_tag)
|
|
164098
|
+
clearedReasoningThroughTag: numOrZero(row.cleared_reasoning_through_tag),
|
|
164099
|
+
lastTodoState: lastTodoStateRaw
|
|
164062
164100
|
};
|
|
164063
164101
|
}
|
|
164064
164102
|
|
|
@@ -164274,7 +164312,7 @@ function resolveIsSubagentFromOpenCodeDb(sessionId) {
|
|
|
164274
164312
|
|
|
164275
164313
|
// ../plugin/src/features/magic-context/storage-meta-session.ts
|
|
164276
164314
|
function getOrCreateSessionMeta(db, sessionId) {
|
|
164277
|
-
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);
|
|
164278
164316
|
if (isSessionMetaRow(result)) {
|
|
164279
164317
|
return toSessionMeta(result);
|
|
164280
164318
|
}
|
package/package.json
CHANGED