@wolfx/opencode-magic-context 0.24.1 → 0.26.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/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/agents/permissions.d.ts +6 -0
- package/dist/agents/permissions.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +22 -0
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts +25 -0
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-prompts.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-local.d.ts +7 -3
- package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-openai.d.ts +8 -4
- package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-provider.d.ts +8 -4
- package/dist/features/magic-context/memory/embedding-provider.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
- package/dist/features/magic-context/memory/relocate-memory.d.ts +58 -0
- package/dist/features/magic-context/memory/relocate-memory.d.ts.map +1 -0
- package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts +6 -0
- package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts +41 -3
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +2 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +37 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts +1 -0
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts +4 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +2 -2
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +58 -2
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +3 -3
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/tagger.d.ts +1 -1
- package/dist/features/magic-context/tagger.d.ts.map +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts +49 -0
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -0
- package/dist/features/magic-context/types.d.ts +1 -0
- package/dist/features/magic-context/types.d.ts.map +1 -1
- package/dist/features/magic-context/v22-deferred-backfill.d.ts.map +1 -1
- package/dist/hooks/magic-context/apply-operations.d.ts +3 -25
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/caveman-cleanup.d.ts +1 -0
- package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-delivery.d.ts +2 -0
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts +7 -5
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +7 -2
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
- package/dist/hooks/magic-context/derive-budgets.d.ts +5 -9
- package/dist/hooks/magic-context/derive-budgets.d.ts.map +1 -1
- package/dist/hooks/magic-context/embed-session-state.d.ts +14 -0
- package/dist/hooks/magic-context/embed-session-state.d.ts.map +1 -0
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-payloads.d.ts +1 -0
- package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -1
- package/dist/hooks/magic-context/format-embed-status.d.ts +9 -0
- package/dist/hooks/magic-context/format-embed-status.d.ts.map +1 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts +2 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts +10 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
- package/dist/hooks/magic-context/strip-content.d.ts +0 -1
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-content-primitives.d.ts +2 -0
- package/dist/hooks/magic-context/tag-content-primitives.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-id-fallback.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +10 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-reclaim.d.ts +12 -0
- package/dist/hooks/magic-context/tool-reclaim.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +32 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-operations.d.ts +1 -1
- package/dist/hooks/magic-context/transform-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +6 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +2 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1767 -613
- package/dist/plugin/conflict-warning-hook.d.ts.map +1 -1
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/shared/announcement.d.ts +1 -1
- package/dist/shared/index.d.ts +0 -1
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
- package/dist/shared/resolve-fallbacks.d.ts +16 -16
- package/dist/shared/resolve-fallbacks.d.ts.map +1 -1
- package/dist/shared/rpc-types.d.ts +20 -0
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/shared/sqlite.d.ts +5 -1
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/tools/ctx-expand/constants.d.ts +1 -1
- package/dist/tools/ctx-expand/constants.d.ts.map +1 -1
- package/dist/tools/ctx-expand/render.d.ts +43 -0
- package/dist/tools/ctx-expand/render.d.ts.map +1 -0
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
- package/dist/tools/ctx-expand/types.d.ts +6 -2
- package/dist/tools/ctx-expand/types.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/constants.d.ts +1 -1
- package/dist/tools/ctx-reduce/constants.d.ts.map +1 -1
- package/dist/tools/ctx-search/tools.d.ts.map +1 -1
- package/dist/tui/data/context-db.d.ts +4 -2
- package/dist/tui/data/context-db.d.ts.map +1 -1
- package/package.json +5 -11
- package/src/shared/announcement.ts +6 -6
- package/src/shared/index.ts +0 -1
- package/src/shared/model-suggestion-retry.test.ts +61 -1
- package/src/shared/model-suggestion-retry.ts +22 -0
- package/src/shared/resolve-fallbacks.test.ts +37 -71
- package/src/shared/resolve-fallbacks.ts +16 -26
- package/src/shared/rpc-types.ts +11 -0
- package/src/shared/sqlite-bind-style.test.ts +82 -0
- package/src/shared/sqlite.ts +30 -1
- package/src/shared/tag-transcript.test.ts +3 -1
- package/src/shared/tag-transcript.ts +19 -17
- package/src/tui/data/context-db.ts +34 -2
- package/src/tui/index.tsx +58 -4
- package/src/tui/slots/sidebar-content.tsx +18 -9
- package/dist/shared/model-requirements.d.ts +0 -26
- package/dist/shared/model-requirements.d.ts.map +0 -1
- package/src/shared/model-requirements.ts +0 -86
package/dist/index.js
CHANGED
|
@@ -47,20 +47,9 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
|
47
47
|
var __promiseAll = (args) => Promise.all(args);
|
|
48
48
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
49
49
|
|
|
50
|
-
// src/agents/dreamer.ts
|
|
51
|
-
var DREAMER_AGENT = "dreamer";
|
|
52
|
-
|
|
53
50
|
// src/agents/historian.ts
|
|
54
|
-
var exports_historian = {};
|
|
55
|
-
__export(exports_historian, {
|
|
56
|
-
HISTORIAN_EDITOR_AGENT: () => HISTORIAN_EDITOR_AGENT,
|
|
57
|
-
HISTORIAN_AGENT: () => HISTORIAN_AGENT
|
|
58
|
-
});
|
|
59
51
|
var HISTORIAN_AGENT = "historian", HISTORIAN_EDITOR_AGENT = "historian-editor";
|
|
60
52
|
|
|
61
|
-
// src/agents/sidekick.ts
|
|
62
|
-
var SIDEKICK_AGENT = "sidekick";
|
|
63
|
-
|
|
64
53
|
// src/shared/jsonc-parser.ts
|
|
65
54
|
import { existsSync, readFileSync } from "node:fs";
|
|
66
55
|
function stripJsonComments(content) {
|
|
@@ -14879,14 +14868,16 @@ var init_magic_context = __esm(() => {
|
|
|
14879
14868
|
}).optional();
|
|
14880
14869
|
HistorianConfigSchema = AgentOverrideConfigSchema.extend({
|
|
14881
14870
|
two_pass: exports_external.boolean().default(false).describe("Run a second editor pass over historian output to clean low-signal U: lines and cross-compartment duplicates. Adds ~1 extra API call and ~1.3x cost per historian run. Useful for models without extended thinking support. (default: false)"),
|
|
14882
|
-
thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level passed as --thinking <level> to Pi historian subagent invocations. Required when using reasoning models (e.g. github-copilot/gpt-5.4) because Pi's default thinking-level resolution can pick a value the provider rejects. OpenCode users set variant instead. Valid: off | minimal | low | medium | high | xhigh")
|
|
14871
|
+
thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level passed as --thinking <level> to Pi historian subagent invocations. Required when using reasoning models (e.g. github-copilot/gpt-5.4) because Pi's default thinking-level resolution can pick a value the provider rejects. OpenCode users set variant instead. Valid: off | minimal | low | medium | high | xhigh"),
|
|
14872
|
+
disallowed_tools: exports_external.array(exports_external.enum(["*", "read", "aft_outline", "aft_zoom", "aft_search"])).default([]).describe(`OpenCode only. Tools to REMOVE from the historian's default allow-list [read, aft_outline, aft_zoom, aft_search]. Applies to both historian and historian-editor agents. Use ["*"] to strip all tool definitions from the model request — this prevents weak instruction-following models (e.g. mistral-small-latest) from entering tool-calling loops. Individual tool names remove just that tool. Note: a user-supplied historian.permission override can re-allow a tool that disallowed_tools removed — disallowed_tools sets the baseline, permission overrides take precedence. (default: [])`)
|
|
14883
14873
|
}).optional();
|
|
14884
14874
|
BaseEmbeddingConfigSchema = exports_external.object({
|
|
14885
14875
|
provider: exports_external.enum(["local", "openai-compatible", "off"]).default("local").describe("Embedding provider. 'local' uses Xenova/all-MiniLM-L6-v2, 'openai-compatible' requires endpoint and model, 'off' disables embeddings."),
|
|
14886
14876
|
model: exports_external.string().optional().describe("Embedding model name. Required for openai-compatible, ignored for local."),
|
|
14887
14877
|
endpoint: exports_external.string().optional().describe("API endpoint URL. Required when provider is openai-compatible."),
|
|
14888
14878
|
api_key: exports_external.string().optional().describe("API key for remote embedding provider (optional)"),
|
|
14889
|
-
input_type: exports_external.string().optional().describe("
|
|
14879
|
+
input_type: exports_external.string().optional().describe("Default input_type for stored/indexed (passage) embeddings in the request body. Required by some openai-compatible providers (e.g. NVIDIA NIM). Omitted from the request when unset."),
|
|
14880
|
+
query_input_type: exports_external.string().optional().describe("Optional input_type for query (search) embeddings on asymmetric models (e.g. NVIDIA NIM 'query'). When unset, query embeddings use embedding.input_type. Passage/stored content always uses embedding.input_type."),
|
|
14890
14881
|
truncate: exports_external.string().optional().describe("Optional truncate mode sent in the embedding request body (e.g. NVIDIA NIM accepts 'NONE' | 'START' | 'END'). Omitted from the request when unset."),
|
|
14891
14882
|
max_input_tokens: exports_external.number().int().positive().optional().describe("Optional maximum input tokens for chunk embeddings. Defaults conservatively to 512 when omitted.")
|
|
14892
14883
|
}).superRefine((data, ctx) => {
|
|
@@ -14916,6 +14907,7 @@ var init_magic_context = __esm(() => {
|
|
|
14916
14907
|
if (data.provider === "openai-compatible") {
|
|
14917
14908
|
const apiKey = data.api_key?.trim();
|
|
14918
14909
|
const inputType = data.input_type?.trim();
|
|
14910
|
+
const queryInputType = data.query_input_type?.trim();
|
|
14919
14911
|
const truncate = data.truncate?.trim();
|
|
14920
14912
|
return {
|
|
14921
14913
|
provider: "openai-compatible",
|
|
@@ -14923,6 +14915,7 @@ var init_magic_context = __esm(() => {
|
|
|
14923
14915
|
endpoint: data.endpoint?.trim() ?? "",
|
|
14924
14916
|
...apiKey ? { api_key: apiKey } : {},
|
|
14925
14917
|
...inputType ? { input_type: inputType } : {},
|
|
14918
|
+
...queryInputType ? { query_input_type: queryInputType } : {},
|
|
14926
14919
|
...truncate ? { truncate } : {},
|
|
14927
14920
|
...data.max_input_tokens ? { max_input_tokens: data.max_input_tokens } : {}
|
|
14928
14921
|
};
|
|
@@ -15284,58 +15277,6 @@ var init_logger = __esm(() => {
|
|
|
15284
15277
|
}
|
|
15285
15278
|
});
|
|
15286
15279
|
|
|
15287
|
-
// src/shared/model-requirements.ts
|
|
15288
|
-
function expandFallbackChain(chain) {
|
|
15289
|
-
const models = [];
|
|
15290
|
-
for (const entry of chain) {
|
|
15291
|
-
for (const provider of entry.providers) {
|
|
15292
|
-
models.push(`${provider}/${entry.model}`);
|
|
15293
|
-
}
|
|
15294
|
-
}
|
|
15295
|
-
return models;
|
|
15296
|
-
}
|
|
15297
|
-
function getAgentFallbackModels(agent) {
|
|
15298
|
-
const requirement = AGENT_MODEL_REQUIREMENTS[agent];
|
|
15299
|
-
if (!requirement)
|
|
15300
|
-
return;
|
|
15301
|
-
return expandFallbackChain(requirement.fallbackChain);
|
|
15302
|
-
}
|
|
15303
|
-
var HISTORIAN_FALLBACK_CHAIN, DREAMER_FALLBACK_CHAIN, SIDEKICK_FALLBACK_CHAIN, AGENT_MODEL_REQUIREMENTS;
|
|
15304
|
-
var init_model_requirements = __esm(() => {
|
|
15305
|
-
HISTORIAN_FALLBACK_CHAIN = [
|
|
15306
|
-
{ providers: ["github-copilot", "anthropic", "opencode"], model: "claude-sonnet-4-6" },
|
|
15307
|
-
{ providers: ["opencode-go"], model: "minimax-m2.7" },
|
|
15308
|
-
{
|
|
15309
|
-
providers: ["zai-coding-plan", "bailian-coding-plan", "opencode-go", "opencode"],
|
|
15310
|
-
model: "glm-5"
|
|
15311
|
-
},
|
|
15312
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.4" },
|
|
15313
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3.1-pro" }
|
|
15314
|
-
];
|
|
15315
|
-
DREAMER_FALLBACK_CHAIN = [
|
|
15316
|
-
{ providers: ["github-copilot", "anthropic", "opencode"], model: "claude-sonnet-4-6" },
|
|
15317
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
15318
|
-
{
|
|
15319
|
-
providers: ["zai-coding-plan", "bailian-coding-plan", "opencode-go", "opencode"],
|
|
15320
|
-
model: "glm-5"
|
|
15321
|
-
},
|
|
15322
|
-
{ providers: ["opencode-go"], model: "minimax-m2.7" },
|
|
15323
|
-
{ providers: ["github-copilot", "openai", "opencode"], model: "gpt-5.4-mini" }
|
|
15324
|
-
];
|
|
15325
|
-
SIDEKICK_FALLBACK_CHAIN = [
|
|
15326
|
-
{ providers: ["cerebras"], model: "qwen-3-235b-a22b-instruct-2507" },
|
|
15327
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
15328
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.4-mini" },
|
|
15329
|
-
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
15330
|
-
];
|
|
15331
|
-
AGENT_MODEL_REQUIREMENTS = {
|
|
15332
|
-
[HISTORIAN_AGENT]: { fallbackChain: HISTORIAN_FALLBACK_CHAIN },
|
|
15333
|
-
[HISTORIAN_EDITOR_AGENT]: { fallbackChain: HISTORIAN_FALLBACK_CHAIN },
|
|
15334
|
-
[DREAMER_AGENT]: { fallbackChain: DREAMER_FALLBACK_CHAIN },
|
|
15335
|
-
[SIDEKICK_AGENT]: { fallbackChain: SIDEKICK_FALLBACK_CHAIN }
|
|
15336
|
-
};
|
|
15337
|
-
});
|
|
15338
|
-
|
|
15339
15280
|
// src/features/magic-context/overflow-detection.ts
|
|
15340
15281
|
function extractErrorMessage(error51) {
|
|
15341
15282
|
if (!error51)
|
|
@@ -15449,15 +15390,9 @@ __export(exports_resolve_fallbacks, {
|
|
|
15449
15390
|
resolveFallbackChain: () => resolveFallbackChain,
|
|
15450
15391
|
parseProviderModel: () => parseProviderModel
|
|
15451
15392
|
});
|
|
15452
|
-
function resolveFallbackChain(
|
|
15393
|
+
function resolveFallbackChain(userFallbacks) {
|
|
15453
15394
|
const userList = normalizeUserFallbacks(userFallbacks);
|
|
15454
|
-
|
|
15455
|
-
return dedupe(userList.filter(isValidModelSpec));
|
|
15456
|
-
}
|
|
15457
|
-
const builtin = getAgentFallbackModels(agentName);
|
|
15458
|
-
if (!builtin || builtin.length === 0)
|
|
15459
|
-
return [];
|
|
15460
|
-
return dedupe(builtin.filter(isValidModelSpec));
|
|
15395
|
+
return dedupe(userList.filter(isValidModelSpec));
|
|
15461
15396
|
}
|
|
15462
15397
|
function normalizeUserFallbacks(userFallbacks) {
|
|
15463
15398
|
if (!userFallbacks)
|
|
@@ -15492,9 +15427,6 @@ function parseProviderModel(spec) {
|
|
|
15492
15427
|
modelID: spec.slice(slash + 1).trim()
|
|
15493
15428
|
};
|
|
15494
15429
|
}
|
|
15495
|
-
var init_resolve_fallbacks = __esm(() => {
|
|
15496
|
-
init_model_requirements();
|
|
15497
|
-
});
|
|
15498
15430
|
|
|
15499
15431
|
// src/shared/model-suggestion-retry.ts
|
|
15500
15432
|
function extractMessage(error51) {
|
|
@@ -15565,9 +15497,11 @@ async function promptWithTimeout(client, args, timeoutMs, signal) {
|
|
|
15565
15497
|
});
|
|
15566
15498
|
} catch (error51) {
|
|
15567
15499
|
if (signal?.aborted) {
|
|
15500
|
+
await abortChildRun(client, args.path.id);
|
|
15568
15501
|
throw new Error("prompt aborted by external signal");
|
|
15569
15502
|
}
|
|
15570
15503
|
if (controller.signal.aborted) {
|
|
15504
|
+
await abortChildRun(client, args.path.id);
|
|
15571
15505
|
throw new Error(`prompt timed out after ${timeoutMs}ms`);
|
|
15572
15506
|
}
|
|
15573
15507
|
throw error51;
|
|
@@ -15576,6 +15510,13 @@ async function promptWithTimeout(client, args, timeoutMs, signal) {
|
|
|
15576
15510
|
signal?.removeEventListener("abort", onExternalAbort);
|
|
15577
15511
|
}
|
|
15578
15512
|
}
|
|
15513
|
+
async function abortChildRun(client, sessionId) {
|
|
15514
|
+
try {
|
|
15515
|
+
await client.session.abort({ path: { id: sessionId } });
|
|
15516
|
+
} catch (error51) {
|
|
15517
|
+
log(`[model-retry] child session abort failed for ${sessionId}: ${String(error51)}`);
|
|
15518
|
+
}
|
|
15519
|
+
}
|
|
15579
15520
|
function isNonRetryable(error51, externalSignal) {
|
|
15580
15521
|
if (externalSignal?.aborted)
|
|
15581
15522
|
return true;
|
|
@@ -15673,7 +15614,6 @@ async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
|
|
|
15673
15614
|
var init_model_suggestion_retry = __esm(() => {
|
|
15674
15615
|
init_overflow_detection();
|
|
15675
15616
|
init_logger();
|
|
15676
|
-
init_resolve_fallbacks();
|
|
15677
15617
|
});
|
|
15678
15618
|
|
|
15679
15619
|
// src/shared/normalize-sdk-response.ts
|
|
@@ -15703,9 +15643,7 @@ function normalizeSDKResponse(response, fallback, options) {
|
|
|
15703
15643
|
// src/shared/index.ts
|
|
15704
15644
|
var init_shared = __esm(() => {
|
|
15705
15645
|
init_logger();
|
|
15706
|
-
init_model_requirements();
|
|
15707
15646
|
init_model_suggestion_retry();
|
|
15708
|
-
init_resolve_fallbacks();
|
|
15709
15647
|
});
|
|
15710
15648
|
|
|
15711
15649
|
// src/shared/record-type-guard.ts
|
|
@@ -15847,7 +15785,7 @@ function isSessionMetaRow(row) {
|
|
|
15847
15785
|
if (row === null || typeof row !== "object")
|
|
15848
15786
|
return false;
|
|
15849
15787
|
const r = row;
|
|
15850
|
-
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.observed_safe_input_tokens) && isNumberOrNull(r.cache_alert_sent) && 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) && isBlobOrNull(r.cached_m0_bytes) && isBlobOrNull(r.cached_m1_bytes) && isNumberOrNull(r.cached_m0_project_memory_epoch) && isStringOrNull(r.cached_m0_workspace_fingerprint) && isNumberOrNull(r.cached_m0_project_user_profile_version) && isNumberOrNull(r.cached_m0_max_compartment_seq) && isNumberOrNull(r.cached_m0_max_memory_id) && isNumberOrNull(r.cached_m0_max_mutation_id) && isNumberOrNull(r.cached_m0_max_memory_mutation_id) && isStringOrNull(r.cached_m0_project_docs_hash) && isNumberOrNull(r.cached_m0_materialized_at) && isNumberOrNull(r.cached_m0_session_facts_version) && isStringOrNull(r.cached_m0_upgrade_state) && isStringOrNull(r.cached_m0_system_hash) && isStringOrNull(r.cached_m0_tool_set_hash) && isStringOrNull(r.cached_m0_model_key) && isStringOrNull(r.last_observed_model_key) && isNumberOrNull(r.last_usage_context_limit) && isNumberOrNull(r.prior_boundary_ordinal) && isNumberOrNull(r.protected_tail_policy_version) && isNumberOrNull(r.protected_tail_drain_window_started_at) && isNumberOrNull(r.protected_tail_drain_tokens) && isNumberOrNull(r.recovery_no_eligible_head_count) && isNumberOrNull(r.force_emergency_bypass_window_start) && isNumberOrNull(r.force_emergency_bypass_used) && isNumberOrNull(r.upgrade_reminded_at) && isNumberOrNull(r.pi_stable_id_scheme);
|
|
15788
|
+
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.observed_safe_input_tokens) && isNumberOrNull(r.cache_alert_sent) && 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) && isBlobOrNull(r.cached_m0_bytes) && isBlobOrNull(r.cached_m1_bytes) && isNumberOrNull(r.cached_m0_project_memory_epoch) && isStringOrNull(r.cached_m0_workspace_fingerprint) && isNumberOrNull(r.cached_m0_project_user_profile_version) && isNumberOrNull(r.cached_m0_max_compartment_seq) && isNumberOrNull(r.cached_m0_max_memory_id) && isNumberOrNull(r.cached_m0_max_mutation_id) && isNumberOrNull(r.cached_m0_max_memory_mutation_id) && isStringOrNull(r.cached_m0_project_docs_hash) && isNumberOrNull(r.cached_m0_materialized_at) && isNumberOrNull(r.cached_m0_session_facts_version) && isStringOrNull(r.cached_m0_upgrade_state) && isStringOrNull(r.cached_m0_system_hash) && isStringOrNull(r.cached_m0_tool_set_hash) && isStringOrNull(r.cached_m0_model_key) && isStringOrNull(r.last_observed_model_key) && isNumberOrNull(r.last_usage_context_limit) && isNumberOrNull(r.prior_boundary_ordinal) && isNumberOrNull(r.protected_tail_policy_version) && isNumberOrNull(r.protected_tail_drain_window_started_at) && isNumberOrNull(r.protected_tail_drain_tokens) && isNumberOrNull(r.recovery_no_eligible_head_count) && isNumberOrNull(r.force_emergency_bypass_window_start) && isNumberOrNull(r.force_emergency_bypass_used) && isNumberOrNull(r.upgrade_reminded_at) && isNumberOrNull(r.pi_stable_id_scheme) && isNumberOrNull(r.tool_reclaim_watermark);
|
|
15851
15789
|
}
|
|
15852
15790
|
function getDefaultSessionMeta(sessionId) {
|
|
15853
15791
|
return {
|
|
@@ -15870,6 +15808,7 @@ function getDefaultSessionMeta(sessionId) {
|
|
|
15870
15808
|
conversationTokens: 0,
|
|
15871
15809
|
toolCallTokens: 0,
|
|
15872
15810
|
clearedReasoningThroughTag: 0,
|
|
15811
|
+
toolReclaimWatermark: 0,
|
|
15873
15812
|
lastTodoState: "",
|
|
15874
15813
|
cachedM0Bytes: null,
|
|
15875
15814
|
cachedM1Bytes: null,
|
|
@@ -15933,6 +15872,7 @@ function toSessionMeta(row) {
|
|
|
15933
15872
|
conversationTokens: numOrZero(row.conversation_tokens),
|
|
15934
15873
|
toolCallTokens: numOrZero(row.tool_call_tokens),
|
|
15935
15874
|
clearedReasoningThroughTag: numOrZero(row.cleared_reasoning_through_tag),
|
|
15875
|
+
toolReclaimWatermark: numOrZero(row.tool_reclaim_watermark),
|
|
15936
15876
|
lastTodoState: lastTodoStateRaw,
|
|
15937
15877
|
cachedM0Bytes: toBufferOrNull(row.cached_m0_bytes),
|
|
15938
15878
|
cachedM1Bytes: toBufferOrNull(row.cached_m1_bytes),
|
|
@@ -16042,6 +15982,7 @@ var init_storage_meta_shared = __esm(() => {
|
|
|
16042
15982
|
"conversation_tokens",
|
|
16043
15983
|
"tool_call_tokens",
|
|
16044
15984
|
"cleared_reasoning_through_tag",
|
|
15985
|
+
"tool_reclaim_watermark",
|
|
16045
15986
|
"last_todo_state",
|
|
16046
15987
|
"cached_m0_bytes",
|
|
16047
15988
|
"cached_m1_bytes",
|
|
@@ -16068,6 +16009,8 @@ var init_storage_meta_shared = __esm(() => {
|
|
|
16068
16009
|
"recovery_no_eligible_head_count",
|
|
16069
16010
|
"force_emergency_bypass_window_start",
|
|
16070
16011
|
"force_emergency_bypass_used",
|
|
16012
|
+
"emergency_drain_active",
|
|
16013
|
+
"historian_drain_failure_at",
|
|
16071
16014
|
"upgrade_reminded_at",
|
|
16072
16015
|
"pi_stable_id_scheme"
|
|
16073
16016
|
];
|
|
@@ -16090,6 +16033,7 @@ var init_storage_meta_shared = __esm(() => {
|
|
|
16090
16033
|
conversationTokens: "conversation_tokens",
|
|
16091
16034
|
toolCallTokens: "tool_call_tokens",
|
|
16092
16035
|
clearedReasoningThroughTag: "cleared_reasoning_through_tag",
|
|
16036
|
+
toolReclaimWatermark: "tool_reclaim_watermark",
|
|
16093
16037
|
lastTodoState: "last_todo_state",
|
|
16094
16038
|
cachedM0Bytes: "cached_m0_bytes",
|
|
16095
16039
|
cachedM1Bytes: "cached_m1_bytes",
|
|
@@ -16116,6 +16060,8 @@ var init_storage_meta_shared = __esm(() => {
|
|
|
16116
16060
|
recoveryNoEligibleHeadCount: "recovery_no_eligible_head_count",
|
|
16117
16061
|
forceEmergencyBypassWindowStart: "force_emergency_bypass_window_start",
|
|
16118
16062
|
forceEmergencyBypassUsed: "force_emergency_bypass_used",
|
|
16063
|
+
emergencyDrainActive: "emergency_drain_active",
|
|
16064
|
+
historianDrainFailureAt: "historian_drain_failure_at",
|
|
16119
16065
|
upgradeRemindedAt: "upgrade_reminded_at",
|
|
16120
16066
|
piStableIdScheme: "pi_stable_id_scheme"
|
|
16121
16067
|
};
|
|
@@ -16366,6 +16312,14 @@ function buildNodeSqliteDatabaseClass(DatabaseSync) {
|
|
|
16366
16312
|
}
|
|
16367
16313
|
super(typeof filename === "string" ? filename : ":memory:", translated);
|
|
16368
16314
|
}
|
|
16315
|
+
prepare(sql) {
|
|
16316
|
+
const stmt = super.prepare(sql);
|
|
16317
|
+
for (const method of ["run", "get", "all"]) {
|
|
16318
|
+
const original = stmt[method].bind(stmt);
|
|
16319
|
+
stmt[method] = (...args) => args.length === 1 && Array.isArray(args[0]) ? original(...args[0]) : original(...args);
|
|
16320
|
+
}
|
|
16321
|
+
return stmt;
|
|
16322
|
+
}
|
|
16369
16323
|
transaction(fn) {
|
|
16370
16324
|
const self = this;
|
|
16371
16325
|
const wrapped = function(...args) {
|
|
@@ -149342,6 +149296,9 @@ function stripCompleteTagPairsGlobally(value) {
|
|
|
149342
149296
|
function stripMalformedTagNotationGlobally(value) {
|
|
149343
149297
|
return value.replace(MALFORMED_TAG_GLOBAL_REGEX, "");
|
|
149344
149298
|
}
|
|
149299
|
+
function stripDanglingTagNotationGlobally(value) {
|
|
149300
|
+
return value.replace(DANGLING_TAG_GLOBAL_REGEX, "");
|
|
149301
|
+
}
|
|
149345
149302
|
function stripTagSectionCharacters(value) {
|
|
149346
149303
|
return value.replace(STRAY_SECTION_CHAR_REGEX, "");
|
|
149347
149304
|
}
|
|
@@ -149349,6 +149306,7 @@ function stripPersistedAssistantText(value) {
|
|
|
149349
149306
|
let text = stripWellFormedLeadingTagPrefix(value);
|
|
149350
149307
|
text = stripCompleteTagPairsGlobally(text);
|
|
149351
149308
|
text = stripMalformedTagNotationGlobally(text);
|
|
149309
|
+
text = stripDanglingTagNotationGlobally(text);
|
|
149352
149310
|
text = stripTagSectionCharacters(text);
|
|
149353
149311
|
return text.trim();
|
|
149354
149312
|
}
|
|
@@ -149361,6 +149319,7 @@ function stripTagPrefix(value) {
|
|
|
149361
149319
|
const prev = stripped;
|
|
149362
149320
|
stripped = stripped.replace(MALFORMED_TAG_PREFIX_REGEX, "");
|
|
149363
149321
|
stripped = stripped.replace(TAG_PREFIX_REGEX, "");
|
|
149322
|
+
stripped = stripped.replace(DANGLING_TAG_PREFIX_REGEX, "");
|
|
149364
149323
|
if (stripped === prev)
|
|
149365
149324
|
break;
|
|
149366
149325
|
}
|
|
@@ -149382,11 +149341,13 @@ function isThinkingPart(part) {
|
|
|
149382
149341
|
const candidate = part;
|
|
149383
149342
|
return candidate.type === "thinking" || candidate.type === "reasoning";
|
|
149384
149343
|
}
|
|
149385
|
-
var encoder, TAG_PREFIX_REGEX, MALFORMED_TAG_PREFIX_REGEX, COMPLETE_TAG_PAIR_GLOBAL_REGEX, MALFORMED_TAG_GLOBAL_REGEX, STRAY_SECTION_CHAR_REGEX;
|
|
149344
|
+
var encoder, TAG_PREFIX_REGEX, MALFORMED_TAG_PREFIX_REGEX, DANGLING_TAG_GLOBAL_REGEX, DANGLING_TAG_PREFIX_REGEX, COMPLETE_TAG_PAIR_GLOBAL_REGEX, MALFORMED_TAG_GLOBAL_REGEX, STRAY_SECTION_CHAR_REGEX;
|
|
149386
149345
|
var init_tag_content_primitives = __esm(() => {
|
|
149387
149346
|
encoder = new TextEncoder;
|
|
149388
149347
|
TAG_PREFIX_REGEX = /^(?:§\d+§\s*)+/;
|
|
149389
149348
|
MALFORMED_TAG_PREFIX_REGEX = /^(?:§\d+">§(?:\d+§)?\s*)+/;
|
|
149349
|
+
DANGLING_TAG_GLOBAL_REGEX = /\u00a7\d+(?!\.\d)[^\s\u00a7\w.]?/g;
|
|
149350
|
+
DANGLING_TAG_PREFIX_REGEX = /^(?:\u00a7\d+(?!\.\d)[^\s\u00a7\w.]?\s*)+/;
|
|
149390
149351
|
COMPLETE_TAG_PAIR_GLOBAL_REGEX = /\u00a7\d+\u00a7/g;
|
|
149391
149352
|
MALFORMED_TAG_GLOBAL_REGEX = /\u00a7\d+">(?:\u00a7(?:\d+\u00a7)?)?/g;
|
|
149392
149353
|
STRAY_SECTION_CHAR_REGEX = /\u00a7/g;
|
|
@@ -149450,12 +149411,13 @@ function setToolContent(part, content) {
|
|
|
149450
149411
|
part.content = content;
|
|
149451
149412
|
}
|
|
149452
149413
|
}
|
|
149453
|
-
function truncateToolPart(part) {
|
|
149414
|
+
function truncateToolPart(part, tagId) {
|
|
149454
149415
|
if (!isRecord(part))
|
|
149455
149416
|
return;
|
|
149417
|
+
const sentinel = `[dropped §${tagId}§]`;
|
|
149456
149418
|
if (part.type === "tool" && isRecord(part.state)) {
|
|
149457
149419
|
const state = part.state;
|
|
149458
|
-
state.output =
|
|
149420
|
+
state.output = sentinel;
|
|
149459
149421
|
if (isRecord(state.input)) {
|
|
149460
149422
|
const inputSize = estimateInputSize(state.input);
|
|
149461
149423
|
if (inputSize > 500) {
|
|
@@ -149465,7 +149427,7 @@ function truncateToolPart(part) {
|
|
|
149465
149427
|
return;
|
|
149466
149428
|
}
|
|
149467
149429
|
if (part.type === "tool_result") {
|
|
149468
|
-
part.content =
|
|
149430
|
+
part.content = sentinel;
|
|
149469
149431
|
return;
|
|
149470
149432
|
}
|
|
149471
149433
|
if (part.type === "tool-invocation" && isRecord(part.args)) {
|
|
@@ -149582,7 +149544,7 @@ class ToolMutationBatch {
|
|
|
149582
149544
|
this.affectedMessages.clear();
|
|
149583
149545
|
}
|
|
149584
149546
|
}
|
|
149585
|
-
function createToolDropTarget(compositeKey, thinkingParts, index, batch) {
|
|
149547
|
+
function createToolDropTarget(compositeKey, thinkingParts, index, batch, tagId) {
|
|
149586
149548
|
const drop = () => {
|
|
149587
149549
|
const entry = index.get(compositeKey);
|
|
149588
149550
|
if (!entry || entry.occurrences.length === 0)
|
|
@@ -149603,7 +149565,7 @@ function createToolDropTarget(compositeKey, thinkingParts, index, batch) {
|
|
|
149603
149565
|
if (!entry.hasResult)
|
|
149604
149566
|
return "incomplete";
|
|
149605
149567
|
for (const occurrence of entry.occurrences) {
|
|
149606
|
-
truncateToolPart(occurrence.part);
|
|
149568
|
+
truncateToolPart(occurrence.part, tagId);
|
|
149607
149569
|
}
|
|
149608
149570
|
clearThinkingParts(thinkingParts);
|
|
149609
149571
|
return "truncated";
|
|
@@ -149651,6 +149613,22 @@ var init_tool_drop_target = __esm(() => {
|
|
|
149651
149613
|
});
|
|
149652
149614
|
|
|
149653
149615
|
// src/hooks/magic-context/read-session-chunk.ts
|
|
149616
|
+
function estimateBlockTokens(blockText) {
|
|
149617
|
+
const cached2 = blockTokenMemo.get(blockText);
|
|
149618
|
+
if (cached2 !== undefined) {
|
|
149619
|
+
blockTokenMemo.delete(blockText);
|
|
149620
|
+
blockTokenMemo.set(blockText, cached2);
|
|
149621
|
+
return cached2;
|
|
149622
|
+
}
|
|
149623
|
+
const count = estimateTokens(blockText);
|
|
149624
|
+
if (blockTokenMemo.size >= BLOCK_TOKEN_MEMO_MAX) {
|
|
149625
|
+
const oldest = blockTokenMemo.keys().next().value;
|
|
149626
|
+
if (oldest !== undefined)
|
|
149627
|
+
blockTokenMemo.delete(oldest);
|
|
149628
|
+
}
|
|
149629
|
+
blockTokenMemo.set(blockText, count);
|
|
149630
|
+
return count;
|
|
149631
|
+
}
|
|
149654
149632
|
function cleanUserText(text) {
|
|
149655
149633
|
return removeSystemReminders(text).replace(OMO_INTERNAL_INITIATOR_MARKER, "").trim();
|
|
149656
149634
|
}
|
|
@@ -149818,7 +149796,7 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
149818
149796
|
if (!currentBlock)
|
|
149819
149797
|
return true;
|
|
149820
149798
|
const blockText = formatBlock(currentBlock);
|
|
149821
|
-
const blockTokens =
|
|
149799
|
+
const blockTokens = estimateBlockTokens(blockText);
|
|
149822
149800
|
if (totalTokens + blockTokens > tokenBudget && totalTokens > 0) {
|
|
149823
149801
|
return false;
|
|
149824
149802
|
}
|
|
@@ -149936,13 +149914,14 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
149936
149914
|
toolOnlyRanges
|
|
149937
149915
|
};
|
|
149938
149916
|
}
|
|
149939
|
-
var activeRawMessageCache = null, activeAbsoluteCountCache = null, sessionProviders, PROTECTED_TAIL_USER_TURNS = 5;
|
|
149917
|
+
var BLOCK_TOKEN_MEMO_MAX = 2048, blockTokenMemo, activeRawMessageCache = null, activeAbsoluteCountCache = null, sessionProviders, PROTECTED_TAIL_USER_TURNS = 5;
|
|
149940
149918
|
var init_read_session_chunk = __esm(async () => {
|
|
149941
149919
|
init_read_session_formatting();
|
|
149942
149920
|
init_tag_part_guards();
|
|
149943
149921
|
init_tool_drop_target();
|
|
149944
149922
|
init_read_session_formatting();
|
|
149945
149923
|
await init_read_session_db();
|
|
149924
|
+
blockTokenMemo = new Map;
|
|
149946
149925
|
sessionProviders = new Map;
|
|
149947
149926
|
});
|
|
149948
149927
|
|
|
@@ -150687,6 +150666,9 @@ function resolveDatabasePath(dbPathOverride) {
|
|
|
150687
150666
|
const dbDir = getMagicContextStorageDir();
|
|
150688
150667
|
return { dbDir, dbPath: join6(dbDir, "context.db") };
|
|
150689
150668
|
}
|
|
150669
|
+
function getDatabasePath(db) {
|
|
150670
|
+
return pathByDatabase.get(db) ?? null;
|
|
150671
|
+
}
|
|
150690
150672
|
function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
150691
150673
|
if (existsSync7(targetDbPath))
|
|
150692
150674
|
return;
|
|
@@ -151197,6 +151179,8 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
151197
151179
|
recovery_no_eligible_head_count INTEGER NOT NULL DEFAULT 0,
|
|
151198
151180
|
force_emergency_bypass_window_start INTEGER NOT NULL DEFAULT 0,
|
|
151199
151181
|
force_emergency_bypass_used INTEGER NOT NULL DEFAULT 0,
|
|
151182
|
+
emergency_drain_active INTEGER NOT NULL DEFAULT 0,
|
|
151183
|
+
historian_drain_failure_at INTEGER NOT NULL DEFAULT 0,
|
|
151200
151184
|
cached_m0_materialized_at INTEGER,
|
|
151201
151185
|
cached_m0_session_facts_version INTEGER,
|
|
151202
151186
|
cached_m0_upgrade_state TEXT,
|
|
@@ -151260,6 +151244,23 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
151260
151244
|
CREATE INDEX IF NOT EXISTS idx_historian_runs_status
|
|
151261
151245
|
ON historian_runs(status, created_at DESC);
|
|
151262
151246
|
|
|
151247
|
+
CREATE TABLE IF NOT EXISTS transform_decisions (
|
|
151248
|
+
session_id TEXT NOT NULL,
|
|
151249
|
+
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
151250
|
+
message_id TEXT NOT NULL,
|
|
151251
|
+
ts_ms INTEGER NOT NULL,
|
|
151252
|
+
decision TEXT NOT NULL,
|
|
151253
|
+
materialized INTEGER NOT NULL DEFAULT 0,
|
|
151254
|
+
materialize_reason TEXT,
|
|
151255
|
+
emergency INTEGER NOT NULL DEFAULT 0,
|
|
151256
|
+
dropped_tokens INTEGER NOT NULL DEFAULT 0,
|
|
151257
|
+
dropped_count INTEGER NOT NULL DEFAULT 0,
|
|
151258
|
+
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
151259
|
+
PRIMARY KEY (session_id, harness, message_id)
|
|
151260
|
+
);
|
|
151261
|
+
CREATE INDEX IF NOT EXISTS idx_transform_decisions_session_harness
|
|
151262
|
+
ON transform_decisions(session_id, harness);
|
|
151263
|
+
|
|
151263
151264
|
CREATE INDEX IF NOT EXISTS idx_tags_session_tag_number ON tags(session_id, tag_number);
|
|
151264
151265
|
CREATE INDEX IF NOT EXISTS idx_tags_session_message_id ON tags(session_id, message_id);
|
|
151265
151266
|
CREATE INDEX IF NOT EXISTS idx_pending_ops_session ON pending_ops(session_id);
|
|
@@ -151337,6 +151338,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
151337
151338
|
ensureColumn(db, "session_meta", "historian_last_failure_at", "INTEGER DEFAULT NULL");
|
|
151338
151339
|
ensureColumn(db, "session_meta", "system_prompt_hash", "TEXT DEFAULT ''");
|
|
151339
151340
|
ensureColumn(db, "session_meta", "cleared_reasoning_through_tag", "INTEGER DEFAULT 0");
|
|
151341
|
+
ensureColumn(db, "session_meta", "tool_reclaim_watermark", "INTEGER DEFAULT 0");
|
|
151340
151342
|
ensureColumn(db, "session_meta", "stripped_placeholder_ids", "TEXT DEFAULT ''");
|
|
151341
151343
|
ensureColumn(db, "session_meta", "stale_reduce_stripped_ids", "TEXT DEFAULT ''");
|
|
151342
151344
|
ensureColumn(db, "session_meta", "processed_image_stripped_ids", "TEXT DEFAULT ''");
|
|
@@ -151410,6 +151412,8 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
151410
151412
|
ensureColumn(db, "session_meta", "recovery_no_eligible_head_count", "INTEGER NOT NULL DEFAULT 0");
|
|
151411
151413
|
ensureColumn(db, "session_meta", "force_emergency_bypass_window_start", "INTEGER NOT NULL DEFAULT 0");
|
|
151412
151414
|
ensureColumn(db, "session_meta", "force_emergency_bypass_used", "INTEGER NOT NULL DEFAULT 0");
|
|
151415
|
+
ensureColumn(db, "session_meta", "emergency_drain_active", "INTEGER NOT NULL DEFAULT 0");
|
|
151416
|
+
ensureColumn(db, "session_meta", "historian_drain_failure_at", "INTEGER NOT NULL DEFAULT 0");
|
|
151413
151417
|
ensureColumn(db, "session_meta", "cached_m0_materialized_at", "INTEGER");
|
|
151414
151418
|
ensureColumn(db, "session_meta", "cached_m0_session_facts_version", "INTEGER");
|
|
151415
151419
|
ensureColumn(db, "session_meta", "cached_m0_upgrade_state", "TEXT");
|
|
@@ -151488,6 +151492,22 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
151488
151492
|
failed_at INTEGER NOT NULL,
|
|
151489
151493
|
UNIQUE(table_name, row_id)
|
|
151490
151494
|
);
|
|
151495
|
+
CREATE TABLE IF NOT EXISTS transform_decisions (
|
|
151496
|
+
session_id TEXT NOT NULL,
|
|
151497
|
+
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
151498
|
+
message_id TEXT NOT NULL,
|
|
151499
|
+
ts_ms INTEGER NOT NULL,
|
|
151500
|
+
decision TEXT NOT NULL,
|
|
151501
|
+
materialized INTEGER NOT NULL DEFAULT 0,
|
|
151502
|
+
materialize_reason TEXT,
|
|
151503
|
+
emergency INTEGER NOT NULL DEFAULT 0,
|
|
151504
|
+
dropped_tokens INTEGER NOT NULL DEFAULT 0,
|
|
151505
|
+
dropped_count INTEGER NOT NULL DEFAULT 0,
|
|
151506
|
+
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
151507
|
+
PRIMARY KEY (session_id, harness, message_id)
|
|
151508
|
+
);
|
|
151509
|
+
CREATE INDEX IF NOT EXISTS idx_transform_decisions_session_harness
|
|
151510
|
+
ON transform_decisions(session_id, harness);
|
|
151491
151511
|
`);
|
|
151492
151512
|
ensureColumn(db, "tags", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
151493
151513
|
ensureColumn(db, "pending_ops", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
@@ -151573,7 +151593,9 @@ function healNullIntegerColumns(db) {
|
|
|
151573
151593
|
["protected_tail_drain_tokens", 0],
|
|
151574
151594
|
["recovery_no_eligible_head_count", 0],
|
|
151575
151595
|
["force_emergency_bypass_window_start", 0],
|
|
151576
|
-
["force_emergency_bypass_used", 0]
|
|
151596
|
+
["force_emergency_bypass_used", 0],
|
|
151597
|
+
["emergency_drain_active", 0],
|
|
151598
|
+
["historian_drain_failure_at", 0]
|
|
151577
151599
|
];
|
|
151578
151600
|
for (const [column, fallback] of columns) {
|
|
151579
151601
|
try {
|
|
@@ -151649,6 +151671,7 @@ function openDatabase(dbPathOrOptions) {
|
|
|
151649
151671
|
setDatabase(db);
|
|
151650
151672
|
loadToolDefinitionMeasurements(db);
|
|
151651
151673
|
databases.set(dbPath, db);
|
|
151674
|
+
pathByDatabase.set(db, dbPath);
|
|
151652
151675
|
persistenceByDatabase.set(db, true);
|
|
151653
151676
|
persistenceErrorByDatabase.delete(db);
|
|
151654
151677
|
return db;
|
|
@@ -151668,7 +151691,7 @@ function getDatabasePersistenceError(db) {
|
|
|
151668
151691
|
return null;
|
|
151669
151692
|
return persistenceErrorByDatabase.get(db) ?? null;
|
|
151670
151693
|
}
|
|
151671
|
-
var databases, persistenceByDatabase, persistenceErrorByDatabase, lastSchemaFenceRejection = null, LATEST_SUPPORTED_VERSION =
|
|
151694
|
+
var databases, persistenceByDatabase, persistenceErrorByDatabase, pathByDatabase, lastSchemaFenceRejection = null, LATEST_SUPPORTED_VERSION = 38, sqlitePragmaConfig, CHANNEL2_CLAIM_TTL_MS = 120000;
|
|
151672
151695
|
var init_storage_db = __esm(async () => {
|
|
151673
151696
|
init_data_path();
|
|
151674
151697
|
init_logger();
|
|
@@ -151682,6 +151705,7 @@ var init_storage_db = __esm(async () => {
|
|
|
151682
151705
|
databases = new Map;
|
|
151683
151706
|
persistenceByDatabase = new WeakMap;
|
|
151684
151707
|
persistenceErrorByDatabase = new WeakMap;
|
|
151708
|
+
pathByDatabase = new WeakMap;
|
|
151685
151709
|
sqlitePragmaConfig = {
|
|
151686
151710
|
cacheSizeMb: 64,
|
|
151687
151711
|
mmapSizeMb: 0
|
|
@@ -153000,6 +153024,41 @@ var init_migrations = __esm(async () => {
|
|
|
153000
153024
|
`);
|
|
153001
153025
|
}
|
|
153002
153026
|
}
|
|
153027
|
+
},
|
|
153028
|
+
{
|
|
153029
|
+
version: 37,
|
|
153030
|
+
description: "emergency drain catch-up latch + historian drain failure backoff",
|
|
153031
|
+
up: (db) => {
|
|
153032
|
+
const hasSessionMeta = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='session_meta'").get();
|
|
153033
|
+
if (!hasSessionMeta)
|
|
153034
|
+
return;
|
|
153035
|
+
ensureColumn(db, "session_meta", "emergency_drain_active", "INTEGER NOT NULL DEFAULT 0");
|
|
153036
|
+
ensureColumn(db, "session_meta", "historian_drain_failure_at", "INTEGER NOT NULL DEFAULT 0");
|
|
153037
|
+
}
|
|
153038
|
+
},
|
|
153039
|
+
{
|
|
153040
|
+
version: 38,
|
|
153041
|
+
description: "durable transform decisions for cache-event cause attribution",
|
|
153042
|
+
up: (db) => {
|
|
153043
|
+
db.exec(`
|
|
153044
|
+
CREATE TABLE IF NOT EXISTS transform_decisions (
|
|
153045
|
+
session_id TEXT NOT NULL,
|
|
153046
|
+
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
153047
|
+
message_id TEXT NOT NULL,
|
|
153048
|
+
ts_ms INTEGER NOT NULL,
|
|
153049
|
+
decision TEXT NOT NULL,
|
|
153050
|
+
materialized INTEGER NOT NULL DEFAULT 0,
|
|
153051
|
+
materialize_reason TEXT,
|
|
153052
|
+
emergency INTEGER NOT NULL DEFAULT 0,
|
|
153053
|
+
dropped_tokens INTEGER NOT NULL DEFAULT 0,
|
|
153054
|
+
dropped_count INTEGER NOT NULL DEFAULT 0,
|
|
153055
|
+
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
153056
|
+
PRIMARY KEY (session_id, harness, message_id)
|
|
153057
|
+
);
|
|
153058
|
+
CREATE INDEX IF NOT EXISTS idx_transform_decisions_session_harness
|
|
153059
|
+
ON transform_decisions(session_id, harness);
|
|
153060
|
+
`);
|
|
153061
|
+
}
|
|
153003
153062
|
}
|
|
153004
153063
|
];
|
|
153005
153064
|
LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -153404,7 +153463,9 @@ function toProtectedTailMeta(row) {
|
|
|
153404
153463
|
protectedTailDrainTokens: numberOr(r.protected_tail_drain_tokens, 0),
|
|
153405
153464
|
recoveryNoEligibleHeadCount: numberOr(r.recovery_no_eligible_head_count, 0),
|
|
153406
153465
|
forceEmergencyBypassWindowStart: numberOr(r.force_emergency_bypass_window_start, 0),
|
|
153407
|
-
forceEmergencyBypassUsed: numberOr(r.force_emergency_bypass_used, 0)
|
|
153466
|
+
forceEmergencyBypassUsed: numberOr(r.force_emergency_bypass_used, 0),
|
|
153467
|
+
emergencyDrainActive: numberOr(r.emergency_drain_active, 0),
|
|
153468
|
+
historianDrainFailureAt: numberOr(r.historian_drain_failure_at, 0)
|
|
153408
153469
|
};
|
|
153409
153470
|
}
|
|
153410
153471
|
function loadProtectedTailMeta(db, sessionId) {
|
|
@@ -153412,7 +153473,7 @@ function loadProtectedTailMeta(db, sessionId) {
|
|
|
153412
153473
|
const row = db.prepare(`SELECT prior_boundary_ordinal, protected_tail_policy_version,
|
|
153413
153474
|
protected_tail_drain_window_started_at, protected_tail_drain_tokens,
|
|
153414
153475
|
recovery_no_eligible_head_count, force_emergency_bypass_window_start,
|
|
153415
|
-
force_emergency_bypass_used
|
|
153476
|
+
force_emergency_bypass_used, emergency_drain_active, historian_drain_failure_at
|
|
153416
153477
|
FROM session_meta WHERE session_id = ?`).get(sessionId);
|
|
153417
153478
|
return toProtectedTailMeta(row);
|
|
153418
153479
|
}
|
|
@@ -153461,6 +153522,12 @@ function protectedTailWindowBudget(usagePercentage, usable, perRunCap) {
|
|
|
153461
153522
|
return Math.min(750000, Math.max(3 * perRunCap, Math.round(0.35 * usable)));
|
|
153462
153523
|
return Math.min(500000, Math.max(perRunCap, Math.round(0.2 * usable)));
|
|
153463
153524
|
}
|
|
153525
|
+
function emergencyDrainExitThreshold(executeThresholdPercentage) {
|
|
153526
|
+
if (!Number.isFinite(executeThresholdPercentage) || executeThresholdPercentage <= 0) {
|
|
153527
|
+
return EMERGENCY_DRAIN_FALLBACK_EXIT_PERCENTAGE;
|
|
153528
|
+
}
|
|
153529
|
+
return Math.max(0, executeThresholdPercentage - EMERGENCY_DRAIN_EXIT_MARGIN);
|
|
153530
|
+
}
|
|
153464
153531
|
function reserveProtectedTailDrainTokens(args) {
|
|
153465
153532
|
const now = args.now ?? Date.now();
|
|
153466
153533
|
const requested = Math.max(0, Math.floor(args.trueRawTokens));
|
|
@@ -153479,18 +153546,30 @@ function reserveProtectedTailDrainTokens(args) {
|
|
|
153479
153546
|
let meta3 = loadProtectedTailMeta(args.db, args.sessionId);
|
|
153480
153547
|
if (now - meta3.protectedTailDrainWindowStartedAt > DRAIN_WINDOW_MS) {
|
|
153481
153548
|
args.db.prepare(`UPDATE session_meta
|
|
153482
|
-
SET protected_tail_drain_window_started_at = ?, protected_tail_drain_tokens = 0
|
|
153483
|
-
|
|
153484
|
-
WHERE session_id = ?`).run(now, now, args.sessionId);
|
|
153549
|
+
SET protected_tail_drain_window_started_at = ?, protected_tail_drain_tokens = 0
|
|
153550
|
+
WHERE session_id = ?`).run(now, args.sessionId);
|
|
153485
153551
|
meta3 = loadProtectedTailMeta(args.db, args.sessionId);
|
|
153486
153552
|
}
|
|
153553
|
+
const exitThreshold = emergencyDrainExitThreshold(args.executeThresholdPercentage);
|
|
153554
|
+
let latchActiveSince = meta3.emergencyDrainActive;
|
|
153555
|
+
if (args.usagePercentage >= EMERGENCY_DRAIN_ENTER_PERCENTAGE) {
|
|
153556
|
+
if (latchActiveSince <= 0)
|
|
153557
|
+
latchActiveSince = now;
|
|
153558
|
+
} else if (latchActiveSince > 0) {
|
|
153559
|
+
const expired = now - latchActiveSince > EMERGENCY_DRAIN_MAX_LATCH_MS;
|
|
153560
|
+
if (args.usagePercentage < exitThreshold || expired)
|
|
153561
|
+
latchActiveSince = 0;
|
|
153562
|
+
}
|
|
153563
|
+
if (latchActiveSince !== meta3.emergencyDrainActive) {
|
|
153564
|
+
args.db.prepare("UPDATE session_meta SET emergency_drain_active = ? WHERE session_id = ?").run(latchActiveSince, args.sessionId);
|
|
153565
|
+
}
|
|
153566
|
+
const latchActive = latchActiveSince > 0;
|
|
153487
153567
|
const budget = protectedTailWindowBudget(args.usagePercentage, args.usable, args.perRunCap);
|
|
153488
153568
|
const remaining = Math.max(0, budget - meta3.protectedTailDrainTokens);
|
|
153489
153569
|
let reserved = Math.min(requested, args.perRunCap, remaining);
|
|
153490
153570
|
let bypass = false;
|
|
153491
|
-
const
|
|
153492
|
-
|
|
153493
|
-
if (reserved <= 0 && args.usagePercentage >= 95 && bypassUsed === 0) {
|
|
153571
|
+
const inFailureBackoff = meta3.historianDrainFailureAt > 0 && now - meta3.historianDrainFailureAt < EMERGENCY_DRAIN_FAILURE_BACKOFF_MS;
|
|
153572
|
+
if (reserved <= 0 && latchActive && !inFailureBackoff) {
|
|
153494
153573
|
reserved = Math.min(requested, args.perRunCap);
|
|
153495
153574
|
bypass = true;
|
|
153496
153575
|
}
|
|
@@ -153498,10 +153577,8 @@ function reserveProtectedTailDrainTokens(args) {
|
|
|
153498
153577
|
return;
|
|
153499
153578
|
args.db.prepare(`UPDATE session_meta
|
|
153500
153579
|
SET protected_tail_drain_window_started_at = CASE WHEN protected_tail_drain_window_started_at = 0 THEN ? ELSE protected_tail_drain_window_started_at END,
|
|
153501
|
-
protected_tail_drain_tokens = COALESCE(protected_tail_drain_tokens, 0) +
|
|
153502
|
-
|
|
153503
|
-
force_emergency_bypass_used = CASE WHEN ? THEN 1 ELSE force_emergency_bypass_used END
|
|
153504
|
-
WHERE session_id = ?`).run(now, reserved, bypass ? 1 : 0, now, bypass ? 1 : 0, args.sessionId);
|
|
153580
|
+
protected_tail_drain_tokens = COALESCE(protected_tail_drain_tokens, 0) + ?
|
|
153581
|
+
WHERE session_id = ?`).run(now, reserved, args.sessionId);
|
|
153505
153582
|
result = {
|
|
153506
153583
|
ok: true,
|
|
153507
153584
|
reservedTokens: reserved,
|
|
@@ -153511,6 +153588,25 @@ function reserveProtectedTailDrainTokens(args) {
|
|
|
153511
153588
|
})();
|
|
153512
153589
|
return result;
|
|
153513
153590
|
}
|
|
153591
|
+
function clearEmergencyDrainLatch(db, sessionId) {
|
|
153592
|
+
db.transaction(() => {
|
|
153593
|
+
ensureSessionMetaRow(db, sessionId);
|
|
153594
|
+
db.prepare("UPDATE session_meta SET emergency_drain_active = 0 WHERE session_id = ?").run(sessionId);
|
|
153595
|
+
})();
|
|
153596
|
+
}
|
|
153597
|
+
function recordHistorianDrainFailure(db, sessionId, now) {
|
|
153598
|
+
const ts = now ?? Date.now();
|
|
153599
|
+
db.transaction(() => {
|
|
153600
|
+
ensureSessionMetaRow(db, sessionId);
|
|
153601
|
+
db.prepare("UPDATE session_meta SET historian_drain_failure_at = ? WHERE session_id = ?").run(ts, sessionId);
|
|
153602
|
+
})();
|
|
153603
|
+
}
|
|
153604
|
+
function clearHistorianDrainFailure(db, sessionId) {
|
|
153605
|
+
db.transaction(() => {
|
|
153606
|
+
ensureSessionMetaRow(db, sessionId);
|
|
153607
|
+
db.prepare("UPDATE session_meta SET historian_drain_failure_at = 0 WHERE session_id = ?").run(sessionId);
|
|
153608
|
+
})();
|
|
153609
|
+
}
|
|
153514
153610
|
function rollbackProtectedTailDrainReservation(db, reservation) {
|
|
153515
153611
|
if (!reservation || reservation.tokens <= 0)
|
|
153516
153612
|
return;
|
|
@@ -154078,7 +154174,7 @@ function setSessionWorkMetrics(db, sessionId, newWorkTokens, totalInputTokens) {
|
|
|
154078
154174
|
SET new_work_tokens = ?, total_input_tokens = ?
|
|
154079
154175
|
WHERE session_id = ?`).run(Math.max(0, Math.floor(newWorkTokens)), Math.max(0, Math.floor(totalInputTokens)), sessionId);
|
|
154080
154176
|
}
|
|
154081
|
-
var CAS_RETRY_LIMIT = 5, AUTO_SEARCH_NO_HINT_REASONS, DEFAULT_PROTECTED_TAIL_META, DRAIN_WINDOW_MS;
|
|
154177
|
+
var CAS_RETRY_LIMIT = 5, AUTO_SEARCH_NO_HINT_REASONS, DEFAULT_PROTECTED_TAIL_META, DRAIN_WINDOW_MS, EMERGENCY_DRAIN_ENTER_PERCENTAGE = 95, EMERGENCY_DRAIN_EXIT_MARGIN = 10, EMERGENCY_DRAIN_FALLBACK_EXIT_PERCENTAGE = 55, EMERGENCY_DRAIN_FAILURE_BACKOFF_MS = 60000, EMERGENCY_DRAIN_MAX_LATCH_MS;
|
|
154082
154178
|
var init_storage_meta_persisted = __esm(() => {
|
|
154083
154179
|
init_logger();
|
|
154084
154180
|
init_storage_meta_shared();
|
|
@@ -154097,9 +154193,12 @@ var init_storage_meta_persisted = __esm(() => {
|
|
|
154097
154193
|
protectedTailDrainTokens: 0,
|
|
154098
154194
|
recoveryNoEligibleHeadCount: 0,
|
|
154099
154195
|
forceEmergencyBypassWindowStart: 0,
|
|
154100
|
-
forceEmergencyBypassUsed: 0
|
|
154196
|
+
forceEmergencyBypassUsed: 0,
|
|
154197
|
+
emergencyDrainActive: 0,
|
|
154198
|
+
historianDrainFailureAt: 0
|
|
154101
154199
|
};
|
|
154102
154200
|
DRAIN_WINDOW_MS = 10 * 60 * 1000;
|
|
154201
|
+
EMERGENCY_DRAIN_MAX_LATCH_MS = 30 * 60 * 1000;
|
|
154103
154202
|
});
|
|
154104
154203
|
|
|
154105
154204
|
// src/features/magic-context/resolve-subagent-fallback.ts
|
|
@@ -154126,7 +154225,8 @@ var exports_storage_meta_session = {};
|
|
|
154126
154225
|
__export(exports_storage_meta_session, {
|
|
154127
154226
|
updateSessionMeta: () => updateSessionMeta,
|
|
154128
154227
|
getOrCreateSessionMeta: () => getOrCreateSessionMeta,
|
|
154129
|
-
clearSession: () => clearSession
|
|
154228
|
+
clearSession: () => clearSession,
|
|
154229
|
+
advanceToolReclaimWatermark: () => advanceToolReclaimWatermark
|
|
154130
154230
|
});
|
|
154131
154231
|
import { Buffer as Buffer3 } from "node:buffer";
|
|
154132
154232
|
function getSessionMetaSelectColumns(db) {
|
|
@@ -154187,6 +154287,14 @@ function updateSessionMeta(db, sessionId, updates) {
|
|
|
154187
154287
|
db.prepare(`UPDATE session_meta SET ${setClauses.join(", ")} WHERE session_id = ?`).run(...values, sessionId);
|
|
154188
154288
|
})();
|
|
154189
154289
|
}
|
|
154290
|
+
function advanceToolReclaimWatermark(db, sessionId, maxTagNumber) {
|
|
154291
|
+
if (maxTagNumber <= 0)
|
|
154292
|
+
return;
|
|
154293
|
+
db.transaction(() => {
|
|
154294
|
+
ensureSessionMetaRow(db, sessionId);
|
|
154295
|
+
db.prepare("UPDATE session_meta SET tool_reclaim_watermark = MAX(COALESCE(tool_reclaim_watermark, 0), ?) WHERE session_id = ?").run(maxTagNumber, sessionId);
|
|
154296
|
+
})();
|
|
154297
|
+
}
|
|
154190
154298
|
function clearSession(db, sessionId) {
|
|
154191
154299
|
db.transaction(() => {
|
|
154192
154300
|
db.prepare("DELETE FROM pending_ops WHERE session_id = ?").run(sessionId);
|
|
@@ -154208,6 +154316,7 @@ function clearSession(db, sessionId) {
|
|
|
154208
154316
|
db.prepare("DELETE FROM subagent_invocations WHERE session_id = ?").run(sessionId);
|
|
154209
154317
|
db.prepare("DELETE FROM historian_runs WHERE session_id = ?").run(sessionId);
|
|
154210
154318
|
db.prepare("DELETE FROM plugin_messages WHERE session_id = ?").run(sessionId);
|
|
154319
|
+
db.prepare("DELETE FROM transform_decisions WHERE session_id = ?").run(sessionId);
|
|
154211
154320
|
clearIndexedMessages(db, sessionId);
|
|
154212
154321
|
})();
|
|
154213
154322
|
}
|
|
@@ -154225,6 +154334,7 @@ var init_storage_meta_session = __esm(async () => {
|
|
|
154225
154334
|
last_transform_error: "'' AS last_transform_error",
|
|
154226
154335
|
system_prompt_hash: "'' AS system_prompt_hash",
|
|
154227
154336
|
last_todo_state: "'' AS last_todo_state",
|
|
154337
|
+
tool_reclaim_watermark: "0 AS tool_reclaim_watermark",
|
|
154228
154338
|
cached_m0_bytes: "NULL AS cached_m0_bytes",
|
|
154229
154339
|
cached_m1_bytes: "NULL AS cached_m1_bytes",
|
|
154230
154340
|
cached_m0_project_memory_epoch: "NULL AS cached_m0_project_memory_epoch",
|
|
@@ -154632,12 +154742,37 @@ function getActiveTagTokenAggregate(db, sessionId, protectedTags = 0) {
|
|
|
154632
154742
|
nullCount: row?.null_count ?? 0
|
|
154633
154743
|
};
|
|
154634
154744
|
}
|
|
154635
|
-
function
|
|
154636
|
-
|
|
154745
|
+
function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, limit = 4) {
|
|
154746
|
+
if (limit <= 0)
|
|
154747
|
+
return [];
|
|
154748
|
+
const boundedLimit = Math.max(1, Math.min(10, Math.floor(limit)));
|
|
154749
|
+
const whereProtected = protectedTags > 0 ? `AND tag_number < (
|
|
154750
|
+
SELECT tag_number FROM tags
|
|
154751
|
+
WHERE session_id = ? AND status = 'active'
|
|
154752
|
+
ORDER BY tag_number DESC LIMIT 1 OFFSET ?
|
|
154753
|
+
)` : "";
|
|
154754
|
+
const params = protectedTags > 0 ? [sessionId, sessionId, protectedTags - 1, boundedLimit] : [sessionId, boundedLimit];
|
|
154755
|
+
const rows = db.prepare(`SELECT tag_number, tool_name
|
|
154756
|
+
FROM tags
|
|
154757
|
+
WHERE session_id = ? AND status = 'active' AND type = 'tool' ${whereProtected}
|
|
154758
|
+
ORDER BY tag_number ASC, id ASC
|
|
154759
|
+
LIMIT ?`).all(...params);
|
|
154760
|
+
return rows.filter((row) => typeof row.tag_number === "number").map((row) => ({
|
|
154761
|
+
tagNumber: row.tag_number,
|
|
154762
|
+
toolName: typeof row.tool_name === "string" ? row.tool_name : null
|
|
154763
|
+
}));
|
|
154764
|
+
}
|
|
154765
|
+
function getTriggerTagTokenUpperBound(db, sessionId, floor = 0) {
|
|
154766
|
+
const sql = floor > 0 ? `SELECT
|
|
154767
|
+
COALESCE(SUM(COALESCE(token_count, 0) + COALESCE(input_token_count, 0) + COALESCE(reasoning_token_count, 0)), 0) AS bound,
|
|
154768
|
+
COALESCE(SUM(CASE WHEN token_count IS NULL THEN 1 ELSE 0 END), 0) AS null_count
|
|
154769
|
+
FROM tags
|
|
154770
|
+
WHERE session_id = ? AND status IN ('active', 'dropped') AND tag_number >= ?` : `SELECT
|
|
154637
154771
|
COALESCE(SUM(COALESCE(token_count, 0) + COALESCE(input_token_count, 0) + COALESCE(reasoning_token_count, 0)), 0) AS bound,
|
|
154638
154772
|
COALESCE(SUM(CASE WHEN token_count IS NULL THEN 1 ELSE 0 END), 0) AS null_count
|
|
154639
154773
|
FROM tags
|
|
154640
|
-
WHERE session_id = ? AND status IN ('active', 'dropped')
|
|
154774
|
+
WHERE session_id = ? AND status IN ('active', 'dropped')`;
|
|
154775
|
+
const row = floor > 0 ? db.prepare(sql).get(sessionId, floor) : db.prepare(sql).get(sessionId);
|
|
154641
154776
|
return { bound: row?.bound ?? 0, nullCount: row?.null_count ?? 0 };
|
|
154642
154777
|
}
|
|
154643
154778
|
function getActiveTagTokenTotalsByMessage(db, sessionId) {
|
|
@@ -154666,10 +154801,12 @@ function getActiveTagTokenTotalsByMessage(db, sessionId) {
|
|
|
154666
154801
|
}
|
|
154667
154802
|
return out;
|
|
154668
154803
|
}
|
|
154669
|
-
function getAllStatusTagTokenTotalsFlat(db, sessionId) {
|
|
154670
|
-
const rows = db.prepare(`SELECT type, message_id, tool_owner_message_id, token_count, input_token_count, reasoning_token_count
|
|
154671
|
-
|
|
154672
|
-
|
|
154804
|
+
function getAllStatusTagTokenTotalsFlat(db, sessionId, floor = 0) {
|
|
154805
|
+
const rows = floor > 0 ? db.prepare(`SELECT type, message_id, tool_owner_message_id, token_count, input_token_count, reasoning_token_count
|
|
154806
|
+
FROM tags
|
|
154807
|
+
WHERE session_id = ? AND tag_number >= ?`).all(sessionId, floor) : db.prepare(`SELECT type, message_id, tool_owner_message_id, token_count, input_token_count, reasoning_token_count
|
|
154808
|
+
FROM tags
|
|
154809
|
+
WHERE session_id = ?`).all(sessionId);
|
|
154673
154810
|
const totals = new Map;
|
|
154674
154811
|
const nullMessageIds = new Set;
|
|
154675
154812
|
for (const row of rows) {
|
|
@@ -154828,6 +154965,47 @@ function getTagNumberByMessageId(db, sessionId, messageId) {
|
|
|
154828
154965
|
const row = getTagNumberByMessageIdStatement(db).get(sessionId, messageId);
|
|
154829
154966
|
return isTagNumberRow(row) ? row.tag_number : null;
|
|
154830
154967
|
}
|
|
154968
|
+
function isMinTagNumberRow(row) {
|
|
154969
|
+
return row !== null && typeof row === "object" && "m" in row;
|
|
154970
|
+
}
|
|
154971
|
+
function getMinMessageTagNumberForRawId(db, sessionId, rawId) {
|
|
154972
|
+
if (rawId.includes(":"))
|
|
154973
|
+
return null;
|
|
154974
|
+
let stmt = getMinMessageTagNumberForRawIdStatements.get(db);
|
|
154975
|
+
if (!stmt) {
|
|
154976
|
+
stmt = db.prepare("SELECT MIN(tag_number) AS m FROM tags WHERE session_id = ? AND message_id >= ? AND message_id < ?");
|
|
154977
|
+
getMinMessageTagNumberForRawIdStatements.set(db, stmt);
|
|
154978
|
+
}
|
|
154979
|
+
const row = stmt.get(sessionId, `${rawId}:`, `${rawId};`);
|
|
154980
|
+
return isMinTagNumberRow(row) && typeof row.m === "number" ? row.m : null;
|
|
154981
|
+
}
|
|
154982
|
+
function deriveTagLoadFloor(db, sessionId, rawIds) {
|
|
154983
|
+
let min = Number.POSITIVE_INFINITY;
|
|
154984
|
+
let probes = 0;
|
|
154985
|
+
let hits = 0;
|
|
154986
|
+
let skippedBeforeFirstHit = 0;
|
|
154987
|
+
for (const rawId of rawIds) {
|
|
154988
|
+
if (typeof rawId !== "string" || rawId.length === 0)
|
|
154989
|
+
continue;
|
|
154990
|
+
if (probes >= TAGGER_FLOOR_MAX_PROBES)
|
|
154991
|
+
break;
|
|
154992
|
+
probes++;
|
|
154993
|
+
const m = getMinMessageTagNumberForRawId(db, sessionId, rawId);
|
|
154994
|
+
if (m === null) {
|
|
154995
|
+
if (hits === 0)
|
|
154996
|
+
skippedBeforeFirstHit++;
|
|
154997
|
+
continue;
|
|
154998
|
+
}
|
|
154999
|
+
if (m < min)
|
|
155000
|
+
min = m;
|
|
155001
|
+
if (++hits >= TAGGER_FLOOR_SCAN_MESSAGES)
|
|
155002
|
+
break;
|
|
155003
|
+
}
|
|
155004
|
+
if (!Number.isFinite(min))
|
|
155005
|
+
return 0;
|
|
155006
|
+
const margin = TAGGER_FLOOR_SAFETY_MARGIN + skippedBeforeFirstHit * TAGGER_FLOOR_PER_SKIP_MARGIN;
|
|
155007
|
+
return Math.max(0, min - margin);
|
|
155008
|
+
}
|
|
154831
155009
|
function getTagsBySession(db, sessionId) {
|
|
154832
155010
|
const rows = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? ORDER BY tag_number ASC, id ASC`).all(sessionId).filter(isTagRow);
|
|
154833
155011
|
return rows.map(toTagEntry);
|
|
@@ -154966,7 +155144,7 @@ function deleteToolTagsByOwner(db, sessionId, ownerMsgId) {
|
|
|
154966
155144
|
const result = getDeleteToolTagsByOwnerStatement(db).run(sessionId, ownerMsgId);
|
|
154967
155145
|
return result.changes ?? 0;
|
|
154968
155146
|
}
|
|
154969
|
-
var insertTagStatements, updateTagStatusStatements, updateTagDropModeStatements, updateTagMessageIdStatements, getTagNumbersByMessageIdStatements, deleteTagsByMessageIdStatements, getMaxTagNumberBySessionStatements, getTagNumberByMessageIdStatements, updateTagByteSizeStatements, updateTagInputByteSizeStatements, CONTENT_ID_SUFFIX, updateTagTokenCountStatements, updateTagInputTokenCountStatements, getOwnerScopedToolTagNumbersStatements, TAG_SELECT_COLUMNS = "id, message_id, type, status, drop_mode, tool_name, input_byte_size, byte_size, reasoning_byte_size, session_id, tag_number, caveman_depth, tool_owner_message_id", getActiveTagsBySessionStatements, getMaxDroppedTagNumberStatements, getToolTagNumberByOwnerStatements, getNullOwnerToolTagStatements, adoptNullOwnerToolTagStatements, deleteToolTagsByOwnerStatements;
|
|
155147
|
+
var insertTagStatements, updateTagStatusStatements, updateTagDropModeStatements, updateTagMessageIdStatements, getTagNumbersByMessageIdStatements, deleteTagsByMessageIdStatements, getMaxTagNumberBySessionStatements, getTagNumberByMessageIdStatements, updateTagByteSizeStatements, updateTagInputByteSizeStatements, CONTENT_ID_SUFFIX, updateTagTokenCountStatements, updateTagInputTokenCountStatements, getOwnerScopedToolTagNumbersStatements, getMinMessageTagNumberForRawIdStatements, TAGGER_FLOOR_SCAN_MESSAGES = 8, TAGGER_FLOOR_MAX_PROBES = 64, TAGGER_FLOOR_SAFETY_MARGIN = 256, TAGGER_FLOOR_PER_SKIP_MARGIN = 64, TAG_SELECT_COLUMNS = "id, message_id, type, status, drop_mode, tool_name, input_byte_size, byte_size, reasoning_byte_size, session_id, tag_number, caveman_depth, tool_owner_message_id", getActiveTagsBySessionStatements, getMaxDroppedTagNumberStatements, getToolTagNumberByOwnerStatements, getNullOwnerToolTagStatements, adoptNullOwnerToolTagStatements, deleteToolTagsByOwnerStatements;
|
|
154970
155148
|
var init_storage_tags = __esm(() => {
|
|
154971
155149
|
insertTagStatements = new WeakMap;
|
|
154972
155150
|
updateTagStatusStatements = new WeakMap;
|
|
@@ -154982,6 +155160,7 @@ var init_storage_tags = __esm(() => {
|
|
|
154982
155160
|
updateTagTokenCountStatements = new WeakMap;
|
|
154983
155161
|
updateTagInputTokenCountStatements = new WeakMap;
|
|
154984
155162
|
getOwnerScopedToolTagNumbersStatements = new WeakMap;
|
|
155163
|
+
getMinMessageTagNumberForRawIdStatements = new WeakMap;
|
|
154985
155164
|
getActiveTagsBySessionStatements = new WeakMap;
|
|
154986
155165
|
getMaxDroppedTagNumberStatements = new WeakMap;
|
|
154987
155166
|
getToolTagNumberByOwnerStatements = new WeakMap;
|
|
@@ -156218,6 +156397,58 @@ var init_safe_notification_target = __esm(() => {
|
|
|
156218
156397
|
DEFAULT_TITLE_RE = /^(New session - |Child session - )\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
|
|
156219
156398
|
});
|
|
156220
156399
|
|
|
156400
|
+
// src/shared/rpc-notifications.ts
|
|
156401
|
+
var exports_rpc_notifications = {};
|
|
156402
|
+
__export(exports_rpc_notifications, {
|
|
156403
|
+
pushNotification: () => pushNotification,
|
|
156404
|
+
isTuiConnected: () => isTuiConnected,
|
|
156405
|
+
drainNotifications: () => drainNotifications
|
|
156406
|
+
});
|
|
156407
|
+
function pushNotification(type, payload, sessionId) {
|
|
156408
|
+
queue.push({ id: nextNotificationId++, type, payload, sessionId });
|
|
156409
|
+
if (queue.length > 100) {
|
|
156410
|
+
const newestPerSession = new Map;
|
|
156411
|
+
for (const n of queue) {
|
|
156412
|
+
const prev = newestPerSession.get(n.sessionId);
|
|
156413
|
+
if (prev === undefined || n.id > prev) {
|
|
156414
|
+
newestPerSession.set(n.sessionId, n.id);
|
|
156415
|
+
}
|
|
156416
|
+
}
|
|
156417
|
+
const mustKeep = new Set(newestPerSession.values());
|
|
156418
|
+
const byNewest = [...queue].sort((a, b) => b.id - a.id);
|
|
156419
|
+
const kept = [];
|
|
156420
|
+
for (const n of byNewest) {
|
|
156421
|
+
if (kept.length < 50 || mustKeep.has(n.id))
|
|
156422
|
+
kept.push(n);
|
|
156423
|
+
}
|
|
156424
|
+
queue = kept.sort((a, b) => a.id - b.id);
|
|
156425
|
+
}
|
|
156426
|
+
}
|
|
156427
|
+
function drainNotifications(lastReceivedId = 0, sessionId) {
|
|
156428
|
+
const now = Date.now();
|
|
156429
|
+
lastDrainAtAny = now;
|
|
156430
|
+
if (sessionId !== undefined)
|
|
156431
|
+
lastDrainAtBySession.set(sessionId, now);
|
|
156432
|
+
const matchesClient = (notification) => sessionId === undefined || notification.sessionId === undefined || notification.sessionId === sessionId;
|
|
156433
|
+
if (lastReceivedId > 0) {
|
|
156434
|
+
queue = queue.filter((notification) => !(notification.id <= lastReceivedId && matchesClient(notification)));
|
|
156435
|
+
}
|
|
156436
|
+
return queue.filter((notification) => notification.id > lastReceivedId && matchesClient(notification));
|
|
156437
|
+
}
|
|
156438
|
+
function isTuiConnected(sessionId) {
|
|
156439
|
+
const now = Date.now();
|
|
156440
|
+
if (sessionId !== undefined) {
|
|
156441
|
+
const at = lastDrainAtBySession.get(sessionId) ?? 0;
|
|
156442
|
+
return at > 0 && now - at < TUI_CONNECTED_WINDOW_MS;
|
|
156443
|
+
}
|
|
156444
|
+
return lastDrainAtAny > 0 && now - lastDrainAtAny < TUI_CONNECTED_WINDOW_MS;
|
|
156445
|
+
}
|
|
156446
|
+
var queue, nextNotificationId = 1, lastDrainAtBySession, lastDrainAtAny = 0, TUI_CONNECTED_WINDOW_MS = 3000;
|
|
156447
|
+
var init_rpc_notifications = __esm(() => {
|
|
156448
|
+
queue = [];
|
|
156449
|
+
lastDrainAtBySession = new Map;
|
|
156450
|
+
});
|
|
156451
|
+
|
|
156221
156452
|
// src/plugin/conflict-warning-hook.ts
|
|
156222
156453
|
var exports_conflict_warning_hook = {};
|
|
156223
156454
|
__export(exports_conflict_warning_hook, {
|
|
@@ -156552,6 +156783,9 @@ async function sendStartupAnnouncement(client, directory, version2, features, fo
|
|
|
156552
156783
|
if (!sessionId) {
|
|
156553
156784
|
return;
|
|
156554
156785
|
}
|
|
156786
|
+
const { isTuiConnected: isTuiConnected2 } = await Promise.resolve().then(() => (init_rpc_notifications(), exports_rpc_notifications));
|
|
156787
|
+
if (isTuiConnected2(sessionId) || isTuiConnected2())
|
|
156788
|
+
return;
|
|
156555
156789
|
if (await waitForSafeNotificationTarget(client, sessionId) === "skip")
|
|
156556
156790
|
return;
|
|
156557
156791
|
const bullets = features.map((line) => ` • ${line}`).join(`
|
|
@@ -164531,6 +164765,20 @@ function getDistinctStoredModelIds(db, projectPath) {
|
|
|
164531
164765
|
const rows = getDistinctStoredModelIdsStatement(db).all(projectPath);
|
|
164532
164766
|
return new Set(rows.map((row) => typeof row.modelId === "string" ? row.modelId : null));
|
|
164533
164767
|
}
|
|
164768
|
+
function getMemoryEmbedCoverage(db, projectPath, modelId) {
|
|
164769
|
+
const row = db.prepare(`SELECT
|
|
164770
|
+
COUNT(*) AS total,
|
|
164771
|
+
SUM(CASE WHEN EXISTS (
|
|
164772
|
+
SELECT 1 FROM memory_embeddings e
|
|
164773
|
+
WHERE e.memory_id = m.id AND e.model_id = ?
|
|
164774
|
+
) THEN 1 ELSE 0 END) AS embedded
|
|
164775
|
+
FROM memories m
|
|
164776
|
+
WHERE m.project_path = ? AND m.status = 'active'`).get(modelId, projectPath);
|
|
164777
|
+
return {
|
|
164778
|
+
total: typeof row?.total === "number" ? row.total : 0,
|
|
164779
|
+
embedded: typeof row?.embedded === "number" ? row.embedded : 0
|
|
164780
|
+
};
|
|
164781
|
+
}
|
|
164534
164782
|
var saveEmbeddingStatements, loadAllEmbeddingsStatements, deleteEmbeddingStatements, getStoredModelIdStatements, clearAllEmbeddingsStatements, getDistinctStoredModelIdsStatements;
|
|
164535
164783
|
var init_storage_memory_embeddings = __esm(() => {
|
|
164536
164784
|
saveEmbeddingStatements = new WeakMap;
|
|
@@ -165333,6 +165581,16 @@ function buildCanonicalChunkTextFromFts(db, sessionId, startOrdinal, endOrdinal)
|
|
|
165333
165581
|
return lines.join(`
|
|
165334
165582
|
`);
|
|
165335
165583
|
}
|
|
165584
|
+
function buildCompartmentSummaryFallbackText(db, compartmentId) {
|
|
165585
|
+
const row = db.prepare("SELECT title, p1, content FROM compartments WHERE id = ?").get(compartmentId);
|
|
165586
|
+
if (!row)
|
|
165587
|
+
return "";
|
|
165588
|
+
const title = typeof row.title === "string" ? row.title.trim() : "";
|
|
165589
|
+
const p1 = typeof row.p1 === "string" ? row.p1.trim() : "";
|
|
165590
|
+
const body = p1.length > 0 ? p1 : typeof row.content === "string" ? row.content.trim() : "";
|
|
165591
|
+
return [title, body].filter((s) => s.length > 0).join(`
|
|
165592
|
+
`);
|
|
165593
|
+
}
|
|
165336
165594
|
function canonicalizeInMemoryChunkTextForEmbedding(chunkText, startOrdinal, endOrdinal) {
|
|
165337
165595
|
const lines = [];
|
|
165338
165596
|
for (const rawLine of chunkText.split(/\r?\n/)) {
|
|
@@ -165575,6 +165833,28 @@ function countUnembeddedSessionCompartments(db, projectPath, sessionId, modelId)
|
|
|
165575
165833
|
)`).get(projectPath, sessionId, projectPath, modelId);
|
|
165576
165834
|
return typeof row?.n === "number" ? row.n : 0;
|
|
165577
165835
|
}
|
|
165836
|
+
function countSessionCompartmentEmbedCoverage(db, projectPath, sessionId, modelId) {
|
|
165837
|
+
const row = db.prepare(`SELECT
|
|
165838
|
+
COUNT(*) AS total,
|
|
165839
|
+
SUM(CASE WHEN EXISTS (
|
|
165840
|
+
SELECT 1 FROM compartment_chunk_embeddings e
|
|
165841
|
+
WHERE e.compartment_id = c.id
|
|
165842
|
+
AND e.project_path = ?
|
|
165843
|
+
AND e.model_id = ?
|
|
165844
|
+
) THEN 1 ELSE 0 END) AS embedded
|
|
165845
|
+
FROM compartments c
|
|
165846
|
+
JOIN session_projects sp
|
|
165847
|
+
ON sp.session_id = c.session_id
|
|
165848
|
+
AND sp.harness = c.harness
|
|
165849
|
+
AND sp.project_path = ?
|
|
165850
|
+
WHERE c.session_id = ?
|
|
165851
|
+
AND c.start_message IS NOT NULL
|
|
165852
|
+
AND c.end_message IS NOT NULL`).get(projectPath, modelId, projectPath, sessionId);
|
|
165853
|
+
return {
|
|
165854
|
+
total: typeof row?.total === "number" ? row.total : 0,
|
|
165855
|
+
embedded: typeof row?.embedded === "number" ? row.embedded : 0
|
|
165856
|
+
};
|
|
165857
|
+
}
|
|
165578
165858
|
var DEFAULT_COMPARTMENT_CHUNK_MAX_INPUT_TOKENS = 512, CHUNK_WINDOW_SAFETY_RATIO = 0.9, loadFtsRowsStatements, existingHashStatements, existingHashByProjectStatements, deleteByCompartmentStatements, insertEmbeddingStatements, distinctModelStatements, clearProjectStatements, clearProjectModelStatements, searchRowsStatements, searchRowsByModelStatements, backfillCandidateStatements, sessionBackfillCandidateStatements;
|
|
165579
165859
|
var init_compartment_chunk_embedding = __esm(() => {
|
|
165580
165860
|
init_read_session_formatting();
|
|
@@ -165732,6 +166012,18 @@ async function withQuietConsole(fn) {
|
|
|
165732
166012
|
console.error = origError;
|
|
165733
166013
|
}
|
|
165734
166014
|
}
|
|
166015
|
+
function isNativeRuntimeMissingError(error51) {
|
|
166016
|
+
const message = error51 instanceof Error ? error51.message : String(error51 ?? "");
|
|
166017
|
+
const lower = message.toLowerCase();
|
|
166018
|
+
const code = error51?.code;
|
|
166019
|
+
const name2 = error51?.name;
|
|
166020
|
+
if (code === "ERR_DLOPEN_FAILED" && lower.includes("onnxruntime")) {
|
|
166021
|
+
return true;
|
|
166022
|
+
}
|
|
166023
|
+
if (!lower.includes("onnxruntime-node"))
|
|
166024
|
+
return false;
|
|
166025
|
+
return code === "ERR_MODULE_NOT_FOUND" || name2 === "ResolveMessage" || lower.includes("cannot find package") || lower.includes("cannot find module") || lower.includes("err_module_not_found");
|
|
166026
|
+
}
|
|
165735
166027
|
function isTransientLoadError(error51) {
|
|
165736
166028
|
const message = error51 instanceof Error ? error51.message : String(error51 ?? "");
|
|
165737
166029
|
if (!message)
|
|
@@ -165796,6 +166088,9 @@ class LocalEmbeddingProvider {
|
|
|
165796
166088
|
if (this.pipeline) {
|
|
165797
166089
|
return true;
|
|
165798
166090
|
}
|
|
166091
|
+
if (nativeRuntimeMissing) {
|
|
166092
|
+
return false;
|
|
166093
|
+
}
|
|
165799
166094
|
if (this.initPromise) {
|
|
165800
166095
|
await this.initPromise;
|
|
165801
166096
|
return this.pipeline !== null;
|
|
@@ -165862,7 +166157,12 @@ class LocalEmbeddingProvider {
|
|
|
165862
166157
|
await releaseLock();
|
|
165863
166158
|
}
|
|
165864
166159
|
} catch (error51) {
|
|
165865
|
-
|
|
166160
|
+
if (isNativeRuntimeMissingError(error51)) {
|
|
166161
|
+
nativeRuntimeMissing = true;
|
|
166162
|
+
log("[magic-context] local embedding runtime is not installed (onnxruntime-node missing from this install). Local embeddings are disabled. Fix: reinstall the plugin (run `npx @wolfx/magic-context@latest doctor --force`), or configure an `openai-compatible`/`ollama` embedding endpoint instead. Existing memories are unaffected.");
|
|
166163
|
+
} else {
|
|
166164
|
+
log("[magic-context] embedding model failed to load:", error51);
|
|
166165
|
+
}
|
|
165866
166166
|
this.pipeline = null;
|
|
165867
166167
|
} finally {
|
|
165868
166168
|
this.initPromise = null;
|
|
@@ -165888,7 +166188,7 @@ class LocalEmbeddingProvider {
|
|
|
165888
166188
|
waiter();
|
|
165889
166189
|
}
|
|
165890
166190
|
}
|
|
165891
|
-
async embed(text, signal) {
|
|
166191
|
+
async embed(text, signal, _purpose) {
|
|
165892
166192
|
if (signal?.aborted)
|
|
165893
166193
|
return null;
|
|
165894
166194
|
if (this.disposing)
|
|
@@ -165914,7 +166214,7 @@ class LocalEmbeddingProvider {
|
|
|
165914
166214
|
this.finishInFlight();
|
|
165915
166215
|
}
|
|
165916
166216
|
}
|
|
165917
|
-
async embedBatch(texts, signal) {
|
|
166217
|
+
async embedBatch(texts, signal, _purpose) {
|
|
165918
166218
|
if (texts.length === 0) {
|
|
165919
166219
|
return [];
|
|
165920
166220
|
}
|
|
@@ -165973,7 +166273,7 @@ class LocalEmbeddingProvider {
|
|
|
165973
166273
|
return this.pipeline !== null;
|
|
165974
166274
|
}
|
|
165975
166275
|
}
|
|
165976
|
-
var LOCK_POLL_MS = 150, STALE_LOCK_MS, MAX_LOCK_WAIT_MS;
|
|
166276
|
+
var LOCK_POLL_MS = 150, STALE_LOCK_MS, MAX_LOCK_WAIT_MS, nativeRuntimeMissing = false;
|
|
165977
166277
|
var init_embedding_local = __esm(() => {
|
|
165978
166278
|
init_magic_context();
|
|
165979
166279
|
init_data_path();
|
|
@@ -166058,6 +166358,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
166058
166358
|
model;
|
|
166059
166359
|
apiKey;
|
|
166060
166360
|
inputType;
|
|
166361
|
+
queryInputType;
|
|
166061
166362
|
truncate;
|
|
166062
166363
|
initialized = false;
|
|
166063
166364
|
failureTimes = [];
|
|
@@ -166070,6 +166371,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
166070
166371
|
this.model = options.model?.trim() ?? "";
|
|
166071
166372
|
this.apiKey = options.apiKey?.trim() ?? "";
|
|
166072
166373
|
this.inputType = options.inputType?.trim() ?? "";
|
|
166374
|
+
this.queryInputType = options.queryInputType?.trim() ?? "";
|
|
166073
166375
|
this.truncate = options.truncate?.trim() ?? "";
|
|
166074
166376
|
this.maxInputTokens = typeof options.maxInputTokens === "number" && Number.isFinite(options.maxInputTokens) ? Math.max(1, Math.floor(options.maxInputTokens)) : 512;
|
|
166075
166377
|
this.modelId = getEmbeddingProviderIdentity({
|
|
@@ -166097,11 +166399,17 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
166097
166399
|
this.initialized = true;
|
|
166098
166400
|
return true;
|
|
166099
166401
|
}
|
|
166100
|
-
|
|
166101
|
-
|
|
166402
|
+
resolveInputTypeForPurpose(purpose = "passage") {
|
|
166403
|
+
if (purpose === "query") {
|
|
166404
|
+
return this.queryInputType || this.inputType;
|
|
166405
|
+
}
|
|
166406
|
+
return this.inputType;
|
|
166407
|
+
}
|
|
166408
|
+
async embed(text, signal, purpose) {
|
|
166409
|
+
const [embedding] = await this.embedBatch([text], signal, purpose);
|
|
166102
166410
|
return embedding ?? null;
|
|
166103
166411
|
}
|
|
166104
|
-
async embedBatch(texts, signal) {
|
|
166412
|
+
async embedBatch(texts, signal, purpose) {
|
|
166105
166413
|
if (texts.length === 0) {
|
|
166106
166414
|
return [];
|
|
166107
166415
|
}
|
|
@@ -166127,6 +166435,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
166127
166435
|
if (signal) {
|
|
166128
166436
|
signal.addEventListener("abort", onOuterAbort, { once: true });
|
|
166129
166437
|
}
|
|
166438
|
+
const inputTypeForRequest = this.resolveInputTypeForPurpose(purpose);
|
|
166130
166439
|
const response = await fetch(`${this.endpoint}/embeddings`, {
|
|
166131
166440
|
method: "POST",
|
|
166132
166441
|
headers: {
|
|
@@ -166136,7 +166445,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
166136
166445
|
body: JSON.stringify({
|
|
166137
166446
|
model: this.model,
|
|
166138
166447
|
input: texts,
|
|
166139
|
-
...
|
|
166448
|
+
...inputTypeForRequest ? { input_type: inputTypeForRequest } : {},
|
|
166140
166449
|
...this.truncate ? { truncate: this.truncate } : {}
|
|
166141
166450
|
}),
|
|
166142
166451
|
redirect: "error",
|
|
@@ -166387,6 +166696,121 @@ var init_storage_git_commit_embeddings = __esm(() => {
|
|
|
166387
166696
|
distinctModelIdStatements = new WeakMap;
|
|
166388
166697
|
});
|
|
166389
166698
|
|
|
166699
|
+
// src/features/magic-context/git-commits/storage-git-commits.ts
|
|
166700
|
+
function getInsertStatement(db) {
|
|
166701
|
+
let stmt = insertStatements.get(db);
|
|
166702
|
+
if (!stmt) {
|
|
166703
|
+
stmt = db.prepare(`INSERT INTO git_commits (sha, project_path, short_sha, message, author, committed_at, indexed_at)
|
|
166704
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
166705
|
+
ON CONFLICT(sha) DO UPDATE SET
|
|
166706
|
+
project_path = excluded.project_path,
|
|
166707
|
+
short_sha = excluded.short_sha,
|
|
166708
|
+
message = excluded.message,
|
|
166709
|
+
author = excluded.author,
|
|
166710
|
+
committed_at = excluded.committed_at,
|
|
166711
|
+
indexed_at = excluded.indexed_at
|
|
166712
|
+
WHERE git_commits.message != excluded.message`);
|
|
166713
|
+
insertStatements.set(db, stmt);
|
|
166714
|
+
}
|
|
166715
|
+
return stmt;
|
|
166716
|
+
}
|
|
166717
|
+
function getExistingShasStatement(db) {
|
|
166718
|
+
let stmt = existingShasStatements.get(db);
|
|
166719
|
+
if (!stmt) {
|
|
166720
|
+
stmt = db.prepare("SELECT sha FROM git_commits WHERE project_path = ?");
|
|
166721
|
+
existingShasStatements.set(db, stmt);
|
|
166722
|
+
}
|
|
166723
|
+
return stmt;
|
|
166724
|
+
}
|
|
166725
|
+
function getProjectCountStatement(db) {
|
|
166726
|
+
let stmt = projectCountStatements.get(db);
|
|
166727
|
+
if (!stmt) {
|
|
166728
|
+
stmt = db.prepare("SELECT COUNT(*) AS count FROM git_commits WHERE project_path = ?");
|
|
166729
|
+
projectCountStatements.set(db, stmt);
|
|
166730
|
+
}
|
|
166731
|
+
return stmt;
|
|
166732
|
+
}
|
|
166733
|
+
function getLatestCommitTimeStatement(db) {
|
|
166734
|
+
let stmt = latestCommitTimeStatements.get(db);
|
|
166735
|
+
if (!stmt) {
|
|
166736
|
+
stmt = db.prepare("SELECT MAX(committed_at) AS latest FROM git_commits WHERE project_path = ?");
|
|
166737
|
+
latestCommitTimeStatements.set(db, stmt);
|
|
166738
|
+
}
|
|
166739
|
+
return stmt;
|
|
166740
|
+
}
|
|
166741
|
+
function getEvictOverflowStatement(db) {
|
|
166742
|
+
let stmt = evictOverflowStatements.get(db);
|
|
166743
|
+
if (!stmt) {
|
|
166744
|
+
stmt = db.prepare(`DELETE FROM git_commits
|
|
166745
|
+
WHERE rowid IN (
|
|
166746
|
+
SELECT rowid FROM git_commits
|
|
166747
|
+
WHERE project_path = ?
|
|
166748
|
+
ORDER BY committed_at DESC, sha DESC
|
|
166749
|
+
LIMIT -1 OFFSET ?
|
|
166750
|
+
)`);
|
|
166751
|
+
evictOverflowStatements.set(db, stmt);
|
|
166752
|
+
}
|
|
166753
|
+
return stmt;
|
|
166754
|
+
}
|
|
166755
|
+
function upsertCommits(db, projectPath, commits) {
|
|
166756
|
+
if (commits.length === 0)
|
|
166757
|
+
return { inserted: 0, updated: 0 };
|
|
166758
|
+
const existing = new Set;
|
|
166759
|
+
for (const row of getExistingShasStatement(db).all(projectPath)) {
|
|
166760
|
+
existing.add(row.sha);
|
|
166761
|
+
}
|
|
166762
|
+
let inserted = 0;
|
|
166763
|
+
let updated = 0;
|
|
166764
|
+
const now = Date.now();
|
|
166765
|
+
const insertStmt = getInsertStatement(db);
|
|
166766
|
+
db.transaction(() => {
|
|
166767
|
+
for (const commit of commits) {
|
|
166768
|
+
const result = insertStmt.run(commit.sha, projectPath, commit.shortSha, commit.message, commit.author, commit.committedAtMs, now);
|
|
166769
|
+
if (result.changes > 0) {
|
|
166770
|
+
if (existing.has(commit.sha)) {
|
|
166771
|
+
updated++;
|
|
166772
|
+
} else {
|
|
166773
|
+
inserted++;
|
|
166774
|
+
existing.add(commit.sha);
|
|
166775
|
+
}
|
|
166776
|
+
}
|
|
166777
|
+
}
|
|
166778
|
+
})();
|
|
166779
|
+
return { inserted, updated };
|
|
166780
|
+
}
|
|
166781
|
+
function getCommitCount(db, projectPath) {
|
|
166782
|
+
const row = getProjectCountStatement(db).get(projectPath);
|
|
166783
|
+
return row?.count ?? 0;
|
|
166784
|
+
}
|
|
166785
|
+
function getLatestIndexedCommitTimeMs(db, projectPath) {
|
|
166786
|
+
const row = getLatestCommitTimeStatement(db).get(projectPath);
|
|
166787
|
+
return row?.latest ?? null;
|
|
166788
|
+
}
|
|
166789
|
+
function enforceProjectCap(db, projectPath, maxCommits) {
|
|
166790
|
+
if (maxCommits <= 0)
|
|
166791
|
+
return 0;
|
|
166792
|
+
const count = getCommitCount(db, projectPath);
|
|
166793
|
+
if (count <= maxCommits)
|
|
166794
|
+
return 0;
|
|
166795
|
+
getEvictOverflowStatement(db).run(projectPath, maxCommits);
|
|
166796
|
+
const after = getCommitCount(db, projectPath);
|
|
166797
|
+
const evicted = Math.max(0, count - after);
|
|
166798
|
+
if (evicted > 0) {
|
|
166799
|
+
log(`[git-commits] evicted ${evicted} oldest commits for project ${projectPath} (cap=${maxCommits}, was=${count})`);
|
|
166800
|
+
}
|
|
166801
|
+
return evicted;
|
|
166802
|
+
}
|
|
166803
|
+
var insertStatements, existingShasStatements, projectCountStatements, evictStatements, evictOverflowStatements, latestCommitTimeStatements;
|
|
166804
|
+
var init_storage_git_commits = __esm(() => {
|
|
166805
|
+
init_logger();
|
|
166806
|
+
insertStatements = new WeakMap;
|
|
166807
|
+
existingShasStatements = new WeakMap;
|
|
166808
|
+
projectCountStatements = new WeakMap;
|
|
166809
|
+
evictStatements = new WeakMap;
|
|
166810
|
+
evictOverflowStatements = new WeakMap;
|
|
166811
|
+
latestCommitTimeStatements = new WeakMap;
|
|
166812
|
+
});
|
|
166813
|
+
|
|
166390
166814
|
// src/features/magic-context/git-commits/sweep-coordinator.ts
|
|
166391
166815
|
function runImmediate2(db, body) {
|
|
166392
166816
|
db.exec("BEGIN IMMEDIATE");
|
|
@@ -166598,6 +167022,7 @@ function resolveEmbeddingConfig(config2) {
|
|
|
166598
167022
|
if (config2.provider === "openai-compatible") {
|
|
166599
167023
|
const apiKey = config2.api_key?.trim();
|
|
166600
167024
|
const inputType = config2.input_type?.trim();
|
|
167025
|
+
const queryInputType = config2.query_input_type?.trim();
|
|
166601
167026
|
const truncate = config2.truncate?.trim();
|
|
166602
167027
|
return {
|
|
166603
167028
|
provider: "openai-compatible",
|
|
@@ -166605,6 +167030,7 @@ function resolveEmbeddingConfig(config2) {
|
|
|
166605
167030
|
endpoint: config2.endpoint.trim(),
|
|
166606
167031
|
...apiKey ? { api_key: apiKey } : {},
|
|
166607
167032
|
...inputType ? { input_type: inputType } : {},
|
|
167033
|
+
...queryInputType ? { query_input_type: queryInputType } : {},
|
|
166608
167034
|
...truncate ? { truncate } : {},
|
|
166609
167035
|
...config2.max_input_tokens ? {
|
|
166610
167036
|
max_input_tokens: normalizeCompartmentChunkMaxInputTokens(config2.max_input_tokens)
|
|
@@ -166626,6 +167052,7 @@ function createProvider(config2) {
|
|
|
166626
167052
|
model: config2.model,
|
|
166627
167053
|
apiKey: config2.api_key,
|
|
166628
167054
|
inputType: config2.input_type,
|
|
167055
|
+
queryInputType: config2.query_input_type,
|
|
166629
167056
|
truncate: config2.truncate,
|
|
166630
167057
|
maxInputTokens: config2.max_input_tokens
|
|
166631
167058
|
});
|
|
@@ -166680,7 +167107,9 @@ function snapshotFor(registration) {
|
|
|
166680
167107
|
enabled,
|
|
166681
167108
|
gitCommitEnabled,
|
|
166682
167109
|
modelId: registration.observationMode || !providerIsOn ? "off" : registration.modelId,
|
|
166683
|
-
chunkModelId: registration.observationMode || !providerIsOn ? "off" : registration.chunkModelId
|
|
167110
|
+
chunkModelId: registration.observationMode || !providerIsOn ? "off" : registration.chunkModelId,
|
|
167111
|
+
model: registration.observationMode || !providerIsOn ? "off" : ("model" in registration.config) && registration.config.model.trim() ? registration.config.model.trim() : registration.modelId,
|
|
167112
|
+
provider: registration.observationMode || !providerIsOn ? "off" : registration.config.provider ?? "local"
|
|
166684
167113
|
};
|
|
166685
167114
|
}
|
|
166686
167115
|
function disposeProvider(provider) {
|
|
@@ -166806,7 +167235,7 @@ function getOrCreateProjectProvider(registration) {
|
|
|
166806
167235
|
registration.provider = provider;
|
|
166807
167236
|
return provider;
|
|
166808
167237
|
}
|
|
166809
|
-
async function embedTextForProject(projectIdentity, text, signal) {
|
|
167238
|
+
async function embedTextForProject(projectIdentity, text, signal, purpose = "passage") {
|
|
166810
167239
|
const registration = projectRegistrations.get(projectIdentity);
|
|
166811
167240
|
if (!registration)
|
|
166812
167241
|
return null;
|
|
@@ -166815,7 +167244,7 @@ async function embedTextForProject(projectIdentity, text, signal) {
|
|
|
166815
167244
|
const provider = getOrCreateProjectProvider(registration);
|
|
166816
167245
|
if (!provider)
|
|
166817
167246
|
return null;
|
|
166818
|
-
const vector = await provider.embed(text, signal);
|
|
167247
|
+
const vector = await provider.embed(text, signal, purpose);
|
|
166819
167248
|
if (!vector)
|
|
166820
167249
|
return null;
|
|
166821
167250
|
const current = projectRegistrations.get(projectIdentity);
|
|
@@ -166824,7 +167253,7 @@ async function embedTextForProject(projectIdentity, text, signal) {
|
|
|
166824
167253
|
}
|
|
166825
167254
|
return { vector, modelId, generation };
|
|
166826
167255
|
}
|
|
166827
|
-
async function embedBatchForProject(projectIdentity, texts, signal) {
|
|
167256
|
+
async function embedBatchForProject(projectIdentity, texts, signal, purpose = "passage") {
|
|
166828
167257
|
if (texts.length === 0) {
|
|
166829
167258
|
const registration2 = projectRegistrations.get(projectIdentity);
|
|
166830
167259
|
if (!registration2 || registration2.observationMode)
|
|
@@ -166840,7 +167269,7 @@ async function embedBatchForProject(projectIdentity, texts, signal) {
|
|
|
166840
167269
|
const provider = getOrCreateProjectProvider(registration);
|
|
166841
167270
|
if (!provider)
|
|
166842
167271
|
return null;
|
|
166843
|
-
const vectors = await provider.embedBatch(texts, signal);
|
|
167272
|
+
const vectors = await provider.embedBatch(texts, signal, purpose);
|
|
166844
167273
|
const current = projectRegistrations.get(projectIdentity);
|
|
166845
167274
|
if (!current || current.generation !== generation || current.runtimeFingerprint !== runtimeFingerprint) {
|
|
166846
167275
|
return null;
|
|
@@ -166891,12 +167320,13 @@ async function embedUnembeddedMemoriesForProject(db, projectIdentity, batchSize
|
|
|
166891
167320
|
}
|
|
166892
167321
|
async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates, signal) {
|
|
166893
167322
|
const noWork = [];
|
|
167323
|
+
const failed = [];
|
|
166894
167324
|
if (candidates.length === 0)
|
|
166895
|
-
return { embedded: 0, noWork };
|
|
167325
|
+
return { embedded: 0, noWork, failed };
|
|
166896
167326
|
const maxInputTokens = getProjectEmbeddingMaxInputTokens(projectIdentity);
|
|
166897
167327
|
const prepared = [];
|
|
166898
167328
|
for (const candidate of candidates) {
|
|
166899
|
-
const canonicalText = buildCanonicalChunkTextFromFts(db, candidate.sessionId, candidate.startMessage, candidate.endMessage);
|
|
167329
|
+
const canonicalText = buildCanonicalChunkTextFromFts(db, candidate.sessionId, candidate.startMessage, candidate.endMessage) || buildCompartmentSummaryFallbackText(db, candidate.id);
|
|
166900
167330
|
if (canonicalText.length === 0) {
|
|
166901
167331
|
noWork.push(candidate.id);
|
|
166902
167332
|
continue;
|
|
@@ -166909,7 +167339,7 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
|
|
|
166909
167339
|
prepared.push({ candidate, windows });
|
|
166910
167340
|
}
|
|
166911
167341
|
if (prepared.length === 0)
|
|
166912
|
-
return { embedded: 0, noWork };
|
|
167342
|
+
return { embedded: 0, noWork, failed };
|
|
166913
167343
|
let embedded = 0;
|
|
166914
167344
|
let i = 0;
|
|
166915
167345
|
while (i < prepared.length) {
|
|
@@ -166926,35 +167356,60 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
|
|
|
166926
167356
|
const texts = [];
|
|
166927
167357
|
for (const item of slice)
|
|
166928
167358
|
texts.push(...item.windows.map((w) => w.text));
|
|
166929
|
-
|
|
166930
|
-
|
|
166931
|
-
if (!result)
|
|
166932
|
-
continue;
|
|
167359
|
+
const persistedIds = new Set;
|
|
167360
|
+
for (let attempt = 0;attempt < EMBED_SLICE_RETRY_ATTEMPTS; attempt++) {
|
|
166933
167361
|
if (signal?.aborted)
|
|
166934
167362
|
break;
|
|
166935
|
-
let
|
|
166936
|
-
|
|
166937
|
-
|
|
166938
|
-
|
|
166939
|
-
|
|
166940
|
-
|
|
167363
|
+
let result = null;
|
|
167364
|
+
const attemptStart = Date.now();
|
|
167365
|
+
try {
|
|
167366
|
+
result = await embedBatchForProject(projectIdentity, texts, signal);
|
|
167367
|
+
} catch (error51) {
|
|
167368
|
+
log("[magic-context] failed to proactively embed compartment chunks:", error51);
|
|
167369
|
+
}
|
|
167370
|
+
if (signal?.aborted)
|
|
167371
|
+
break;
|
|
167372
|
+
if (result) {
|
|
167373
|
+
let offset = 0;
|
|
167374
|
+
for (const item of slice) {
|
|
167375
|
+
const vectors = result.vectors.slice(offset, offset + item.windows.length);
|
|
167376
|
+
offset += item.windows.length;
|
|
167377
|
+
if (persistedIds.has(item.candidate.id))
|
|
167378
|
+
continue;
|
|
167379
|
+
if (vectors.length !== item.windows.length || vectors.some((v) => !v)) {
|
|
167380
|
+
continue;
|
|
167381
|
+
}
|
|
167382
|
+
const rows = item.windows.map((window, index) => ({
|
|
167383
|
+
compartmentId: item.candidate.id,
|
|
167384
|
+
sessionId: item.candidate.sessionId,
|
|
167385
|
+
projectPath: projectIdentity,
|
|
167386
|
+
window,
|
|
167387
|
+
modelId,
|
|
167388
|
+
vector: vectors[index]
|
|
167389
|
+
}));
|
|
167390
|
+
replaceCompartmentChunkEmbeddings(db, rows);
|
|
167391
|
+
persistedIds.add(item.candidate.id);
|
|
166941
167392
|
}
|
|
166942
|
-
const rows = item.windows.map((window, index) => ({
|
|
166943
|
-
compartmentId: item.candidate.id,
|
|
166944
|
-
sessionId: item.candidate.sessionId,
|
|
166945
|
-
projectPath: projectIdentity,
|
|
166946
|
-
window,
|
|
166947
|
-
modelId,
|
|
166948
|
-
vector: vectors[index]
|
|
166949
|
-
}));
|
|
166950
|
-
replaceCompartmentChunkEmbeddings(db, rows);
|
|
166951
|
-
embedded += 1;
|
|
166952
167393
|
}
|
|
166953
|
-
|
|
166954
|
-
|
|
167394
|
+
if (persistedIds.size === slice.length)
|
|
167395
|
+
break;
|
|
167396
|
+
if (persistedIds.size > 0)
|
|
167397
|
+
break;
|
|
167398
|
+
if (Date.now() - attemptStart >= EMBED_SLOW_FAILURE_NO_RETRY_MS)
|
|
167399
|
+
break;
|
|
167400
|
+
if (attempt < EMBED_SLICE_RETRY_ATTEMPTS - 1) {
|
|
167401
|
+
await new Promise((resolve6) => setTimeout(resolve6, EMBED_SLICE_RETRY_BASE_MS * 2 ** attempt));
|
|
167402
|
+
}
|
|
167403
|
+
}
|
|
167404
|
+
embedded += persistedIds.size;
|
|
167405
|
+
if (!signal?.aborted) {
|
|
167406
|
+
for (const item of slice) {
|
|
167407
|
+
if (!persistedIds.has(item.candidate.id))
|
|
167408
|
+
failed.push(item.candidate.id);
|
|
167409
|
+
}
|
|
166955
167410
|
}
|
|
166956
167411
|
}
|
|
166957
|
-
return { embedded, noWork };
|
|
167412
|
+
return { embedded, noWork, failed };
|
|
166958
167413
|
}
|
|
166959
167414
|
async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, options) {
|
|
166960
167415
|
const snapshot = getProjectEmbeddingSnapshot(projectIdentity);
|
|
@@ -166977,9 +167432,11 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
|
|
|
166977
167432
|
renewal.unref?.();
|
|
166978
167433
|
const batchSize = Math.max(1, options?.batchSize ?? CHUNK_DRAIN_BATCH_SIZE);
|
|
166979
167434
|
const skipIds = [];
|
|
167435
|
+
const failedIds = [];
|
|
166980
167436
|
let embedded = 0;
|
|
166981
167437
|
let aborted2 = false;
|
|
166982
|
-
let
|
|
167438
|
+
let providerDown = false;
|
|
167439
|
+
let consecutiveFailedBatches = 0;
|
|
166983
167440
|
try {
|
|
166984
167441
|
options?.onProgress?.({ embedded, total });
|
|
166985
167442
|
for (;; ) {
|
|
@@ -166987,15 +167444,26 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
|
|
|
166987
167444
|
aborted2 = true;
|
|
166988
167445
|
break;
|
|
166989
167446
|
}
|
|
166990
|
-
const candidates = loadUnembeddedSessionChunkCandidates(db, projectIdentity, sessionId, snapshot.chunkModelId, batchSize, skipIds);
|
|
167447
|
+
const candidates = loadUnembeddedSessionChunkCandidates(db, projectIdentity, sessionId, snapshot.chunkModelId, batchSize, [...skipIds, ...failedIds]);
|
|
166991
167448
|
if (candidates.length === 0)
|
|
166992
167449
|
break;
|
|
166993
|
-
const {
|
|
167450
|
+
const {
|
|
167451
|
+
embedded: n,
|
|
167452
|
+
noWork,
|
|
167453
|
+
failed
|
|
167454
|
+
} = await embedCandidateChunkBatch(db, projectIdentity, snapshot.chunkModelId, candidates, options?.signal);
|
|
166994
167455
|
for (const id of noWork)
|
|
166995
167456
|
skipIds.push(id);
|
|
167457
|
+
for (const id of failed)
|
|
167458
|
+
failedIds.push(id);
|
|
166996
167459
|
if (n === 0 && noWork.length === 0) {
|
|
166997
|
-
|
|
166998
|
-
|
|
167460
|
+
consecutiveFailedBatches += 1;
|
|
167461
|
+
if (consecutiveFailedBatches >= MAX_CONSECUTIVE_FAILED_BATCHES) {
|
|
167462
|
+
providerDown = true;
|
|
167463
|
+
break;
|
|
167464
|
+
}
|
|
167465
|
+
} else {
|
|
167466
|
+
consecutiveFailedBatches = 0;
|
|
166999
167467
|
}
|
|
167000
167468
|
embedded += n;
|
|
167001
167469
|
options?.onProgress?.({ embedded: Math.min(embedded, total), total });
|
|
@@ -167003,23 +167471,58 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
|
|
|
167003
167471
|
}
|
|
167004
167472
|
} finally {
|
|
167005
167473
|
clearInterval(renewal);
|
|
167006
|
-
|
|
167474
|
+
try {
|
|
167475
|
+
releaseGitSweepLease(db, projectIdentity, holderId);
|
|
167476
|
+
} catch (error51) {
|
|
167477
|
+
log("[magic-context] embed drain: lease release failed (will TTL-expire):", error51);
|
|
167478
|
+
}
|
|
167007
167479
|
}
|
|
167008
167480
|
if (aborted2)
|
|
167009
|
-
return { status: "aborted", embedded, total };
|
|
167010
|
-
if (
|
|
167481
|
+
return { status: "aborted", embedded, total, failed: failedIds.length };
|
|
167482
|
+
if (providerDown || failedIds.length > 0) {
|
|
167011
167483
|
const remaining = Math.max(0, countUnembeddedSessionCompartments(db, projectIdentity, sessionId, snapshot.chunkModelId) - skipIds.length);
|
|
167012
|
-
if (remaining > 0)
|
|
167013
|
-
return { status: "stalled", embedded, total, remaining };
|
|
167484
|
+
if (remaining > 0) {
|
|
167485
|
+
return { status: "stalled", embedded, total, remaining, failed: failedIds.length };
|
|
167486
|
+
}
|
|
167014
167487
|
}
|
|
167015
|
-
return { status: "done", embedded, total };
|
|
167488
|
+
return { status: "done", embedded, total, failed: failedIds.length };
|
|
167016
167489
|
}
|
|
167017
|
-
|
|
167490
|
+
function getEmbeddingCoverageStatus(db, projectIdentity, sessionId) {
|
|
167491
|
+
const snapshot = getProjectEmbeddingSnapshot(projectIdentity);
|
|
167492
|
+
if (!snapshot?.enabled || snapshot.chunkModelId === "off") {
|
|
167493
|
+
return {
|
|
167494
|
+
enabled: false,
|
|
167495
|
+
model: snapshot?.model ?? "off",
|
|
167496
|
+
provider: snapshot?.provider ?? "off",
|
|
167497
|
+
session: { embedded: 0, total: 0 },
|
|
167498
|
+
memories: { embedded: 0, total: 0 },
|
|
167499
|
+
commits: { embedded: 0, total: 0, gitEnabled: false }
|
|
167500
|
+
};
|
|
167501
|
+
}
|
|
167502
|
+
const session = countSessionCompartmentEmbedCoverage(db, projectIdentity, sessionId, snapshot.chunkModelId);
|
|
167503
|
+
const memories = getMemoryEmbedCoverage(db, projectIdentity, snapshot.modelId);
|
|
167504
|
+
const gitEnabled = snapshot.gitCommitEnabled;
|
|
167505
|
+
const commits = gitEnabled ? {
|
|
167506
|
+
embedded: countEmbeddedCommits(db, projectIdentity),
|
|
167507
|
+
total: getCommitCount(db, projectIdentity),
|
|
167508
|
+
gitEnabled: true
|
|
167509
|
+
} : { embedded: 0, total: 0, gitEnabled: false };
|
|
167510
|
+
return {
|
|
167511
|
+
enabled: true,
|
|
167512
|
+
model: snapshot.model,
|
|
167513
|
+
provider: snapshot.provider,
|
|
167514
|
+
session,
|
|
167515
|
+
memories,
|
|
167516
|
+
commits
|
|
167517
|
+
};
|
|
167518
|
+
}
|
|
167519
|
+
var OFF_PROVIDER_IDENTITY = "embedding-provider:off", SWEEP_MAX_WALL_CLOCK_MS, CHUNK_DRAIN_BATCH_SIZE = 8, MAX_WINDOWS_PER_EMBED_CALL = 2, SESSION_EMBED_LEASE_RENEWAL_MS, EMBED_SLICE_RETRY_ATTEMPTS = 3, EMBED_SLICE_RETRY_BASE_MS = 250, EMBED_SLOW_FAILURE_NO_RETRY_MS = 1e4, MAX_CONSECUTIVE_FAILED_BATCHES = 3, projectRegistrations, loadUnembeddedMemoriesStatements, globalRegistrationGeneration = 0, testProviderFactory = null;
|
|
167018
167520
|
var init_project_embedding_registry = __esm(() => {
|
|
167019
167521
|
init_magic_context();
|
|
167020
167522
|
init_logger();
|
|
167021
167523
|
init_compartment_chunk_embedding();
|
|
167022
167524
|
init_storage_git_commit_embeddings();
|
|
167525
|
+
init_storage_git_commits();
|
|
167023
167526
|
init_sweep_coordinator();
|
|
167024
167527
|
init_embedding_cache();
|
|
167025
167528
|
init_embedding_identity();
|
|
@@ -167044,6 +167547,7 @@ function createProvider2(config2) {
|
|
|
167044
167547
|
model: config2.model,
|
|
167045
167548
|
apiKey: config2.api_key,
|
|
167046
167549
|
inputType: config2.input_type,
|
|
167550
|
+
queryInputType: config2.query_input_type,
|
|
167047
167551
|
truncate: config2.truncate,
|
|
167048
167552
|
maxInputTokens: config2.max_input_tokens
|
|
167049
167553
|
});
|
|
@@ -167300,58 +167804,6 @@ var init_models_dev_cache = __esm(() => {
|
|
|
167300
167804
|
init_logger();
|
|
167301
167805
|
});
|
|
167302
167806
|
|
|
167303
|
-
// src/shared/rpc-notifications.ts
|
|
167304
|
-
var exports_rpc_notifications = {};
|
|
167305
|
-
__export(exports_rpc_notifications, {
|
|
167306
|
-
pushNotification: () => pushNotification,
|
|
167307
|
-
isTuiConnected: () => isTuiConnected,
|
|
167308
|
-
drainNotifications: () => drainNotifications
|
|
167309
|
-
});
|
|
167310
|
-
function pushNotification(type, payload, sessionId) {
|
|
167311
|
-
queue2.push({ id: nextNotificationId++, type, payload, sessionId });
|
|
167312
|
-
if (queue2.length > 100) {
|
|
167313
|
-
const newestPerSession = new Map;
|
|
167314
|
-
for (const n of queue2) {
|
|
167315
|
-
const prev = newestPerSession.get(n.sessionId);
|
|
167316
|
-
if (prev === undefined || n.id > prev) {
|
|
167317
|
-
newestPerSession.set(n.sessionId, n.id);
|
|
167318
|
-
}
|
|
167319
|
-
}
|
|
167320
|
-
const mustKeep = new Set(newestPerSession.values());
|
|
167321
|
-
const byNewest = [...queue2].sort((a, b) => b.id - a.id);
|
|
167322
|
-
const kept = [];
|
|
167323
|
-
for (const n of byNewest) {
|
|
167324
|
-
if (kept.length < 50 || mustKeep.has(n.id))
|
|
167325
|
-
kept.push(n);
|
|
167326
|
-
}
|
|
167327
|
-
queue2 = kept.sort((a, b) => a.id - b.id);
|
|
167328
|
-
}
|
|
167329
|
-
}
|
|
167330
|
-
function drainNotifications(lastReceivedId = 0, sessionId) {
|
|
167331
|
-
const now = Date.now();
|
|
167332
|
-
lastDrainAtAny = now;
|
|
167333
|
-
if (sessionId !== undefined)
|
|
167334
|
-
lastDrainAtBySession.set(sessionId, now);
|
|
167335
|
-
const matchesClient = (notification) => sessionId === undefined || notification.sessionId === undefined || notification.sessionId === sessionId;
|
|
167336
|
-
if (lastReceivedId > 0) {
|
|
167337
|
-
queue2 = queue2.filter((notification) => !(notification.id <= lastReceivedId && matchesClient(notification)));
|
|
167338
|
-
}
|
|
167339
|
-
return queue2.filter((notification) => notification.id > lastReceivedId && matchesClient(notification));
|
|
167340
|
-
}
|
|
167341
|
-
function isTuiConnected(sessionId) {
|
|
167342
|
-
const now = Date.now();
|
|
167343
|
-
if (sessionId !== undefined) {
|
|
167344
|
-
const at = lastDrainAtBySession.get(sessionId) ?? 0;
|
|
167345
|
-
return at > 0 && now - at < TUI_CONNECTED_WINDOW_MS;
|
|
167346
|
-
}
|
|
167347
|
-
return lastDrainAtAny > 0 && now - lastDrainAtAny < TUI_CONNECTED_WINDOW_MS;
|
|
167348
|
-
}
|
|
167349
|
-
var queue2, nextNotificationId = 1, lastDrainAtBySession, lastDrainAtAny = 0, TUI_CONNECTED_WINDOW_MS = 3000;
|
|
167350
|
-
var init_rpc_notifications = __esm(() => {
|
|
167351
|
-
queue2 = [];
|
|
167352
|
-
lastDrainAtBySession = new Map;
|
|
167353
|
-
});
|
|
167354
|
-
|
|
167355
167807
|
// src/features/magic-context/compartment-embedding.ts
|
|
167356
167808
|
async function embedAndStoreCompartmentChunks(db, sessionId, projectPath, compartments) {
|
|
167357
167809
|
if (compartments.length === 0)
|
|
@@ -167360,7 +167812,7 @@ async function embedAndStoreCompartmentChunks(db, sessionId, projectPath, compar
|
|
|
167360
167812
|
for (const compartment of compartments) {
|
|
167361
167813
|
try {
|
|
167362
167814
|
const fromMemory = compartment.sourceChunkText ? canonicalizeInMemoryChunkTextForEmbedding(compartment.sourceChunkText, compartment.startMessage, compartment.endMessage) : "";
|
|
167363
|
-
const canonicalText = fromMemory || buildCanonicalChunkTextFromFts(db, sessionId, compartment.startMessage, compartment.endMessage);
|
|
167815
|
+
const canonicalText = fromMemory || buildCanonicalChunkTextFromFts(db, sessionId, compartment.startMessage, compartment.endMessage) || buildCompartmentSummaryFallbackText(db, compartment.id);
|
|
167364
167816
|
if (canonicalText.length === 0)
|
|
167365
167817
|
continue;
|
|
167366
167818
|
const windows = chunkCanonicalText(canonicalText, compartment.startMessage, compartment.endMessage, maxInputTokens);
|
|
@@ -170560,29 +171012,12 @@ function resolveHistorianContextLimit(historianModelOverride) {
|
|
|
170560
171012
|
return DEFAULT_HISTORIAN_CONTEXT_FALLBACK;
|
|
170561
171013
|
}
|
|
170562
171014
|
if (typeof historianModelOverride === "string" && historianModelOverride.trim() !== "") {
|
|
170563
|
-
console.warn(`[magic-context] historian.model "${historianModelOverride}" lacks provider prefix ("provider/model-id"); using
|
|
170564
|
-
}
|
|
170565
|
-
const chain = AGENT_MODEL_REQUIREMENTS[HISTORIAN_AGENT]?.fallbackChain;
|
|
170566
|
-
if (!chain || chain.length === 0)
|
|
170567
|
-
return DEFAULT_HISTORIAN_CONTEXT_FALLBACK;
|
|
170568
|
-
const expanded = expandFallbackChain(chain);
|
|
170569
|
-
let minLimit;
|
|
170570
|
-
for (const key of expanded) {
|
|
170571
|
-
const [providerID, ...rest] = key.split("/");
|
|
170572
|
-
const modelID = rest.join("/");
|
|
170573
|
-
if (!providerID || !modelID)
|
|
170574
|
-
continue;
|
|
170575
|
-
const limit = getSdkContextLimit(providerID, modelID);
|
|
170576
|
-
if (typeof limit !== "number" || limit <= 0)
|
|
170577
|
-
continue;
|
|
170578
|
-
if (minLimit === undefined || limit < minLimit)
|
|
170579
|
-
minLimit = limit;
|
|
171015
|
+
console.warn(`[magic-context] historian.model "${historianModelOverride}" lacks provider prefix ("provider/model-id"); using the default context limit for chunk-budget derivation.`);
|
|
170580
171016
|
}
|
|
170581
|
-
return
|
|
171017
|
+
return DEFAULT_HISTORIAN_CONTEXT_FALLBACK;
|
|
170582
171018
|
}
|
|
170583
171019
|
var TRIGGER_BUDGET_PERCENTAGE = 0.05, TRIGGER_BUDGET_MIN = 5000, TRIGGER_BUDGET_MAX = 50000, HISTORIAN_CHUNK_PERCENTAGE = 0.25, HISTORIAN_CHUNK_MIN = 8000, HISTORIAN_CHUNK_MAX = 50000, DEFAULT_HISTORIAN_CONTEXT_FALLBACK = 128000;
|
|
170584
171020
|
var init_derive_budgets = __esm(() => {
|
|
170585
|
-
init_model_requirements();
|
|
170586
171021
|
init_models_dev_cache();
|
|
170587
171022
|
});
|
|
170588
171023
|
|
|
@@ -170903,7 +171338,7 @@ function buildToolArcs(messages) {
|
|
|
170903
171338
|
}
|
|
170904
171339
|
return arcs.sort((a, b) => a.invOrdinal - b.invOrdinal || (a.resOrdinal ?? Number.MAX_SAFE_INTEGER) - (b.resOrdinal ?? Number.MAX_SAFE_INTEGER));
|
|
170905
171340
|
}
|
|
170906
|
-
function fenceBoundaryForToolArcs(candidate, arcs, lastCompartmentEndOrdinal) {
|
|
171341
|
+
function fenceBoundaryForToolArcs(candidate, arcs, lastCompartmentEndOrdinal, recentOpenArcCutoff) {
|
|
170907
171342
|
let boundary = candidate;
|
|
170908
171343
|
for (const arc of arcs) {
|
|
170909
171344
|
if (arc.resOrdinal !== null) {
|
|
@@ -170912,6 +171347,8 @@ function fenceBoundaryForToolArcs(candidate, arcs, lastCompartmentEndOrdinal) {
|
|
|
170912
171347
|
}
|
|
170913
171348
|
continue;
|
|
170914
171349
|
}
|
|
171350
|
+
if (arc.invOrdinal < recentOpenArcCutoff)
|
|
171351
|
+
continue;
|
|
170915
171352
|
if (arc.invOrdinal >= lastCompartmentEndOrdinal + 1 && arc.invOrdinal < boundary) {
|
|
170916
171353
|
return arc.invOrdinal;
|
|
170917
171354
|
}
|
|
@@ -171151,7 +171588,7 @@ function semanticSnapBoundary(args) {
|
|
|
171151
171588
|
return snapped;
|
|
171152
171589
|
}
|
|
171153
171590
|
function applyHeadCap(args) {
|
|
171154
|
-
const { index, protectedTailStart, offset, arcs, capTokens } = args;
|
|
171591
|
+
const { index, protectedTailStart, offset, arcs, capTokens, recentOpenArcCutoff } = args;
|
|
171155
171592
|
if (offset >= protectedTailStart)
|
|
171156
171593
|
return { eligibleEndOrdinal: offset, oversizeAtomicUnit: false };
|
|
171157
171594
|
let end = index.findHeadEndForCap(offset, protectedTailStart, capTokens);
|
|
@@ -171159,7 +171596,7 @@ function applyHeadCap(args) {
|
|
|
171159
171596
|
for (const arc of arcs) {
|
|
171160
171597
|
const resOrdinal = arc.resOrdinal;
|
|
171161
171598
|
if (resOrdinal === null) {
|
|
171162
|
-
if (arc.invOrdinal >= offset && arc.invOrdinal < end) {
|
|
171599
|
+
if (arc.invOrdinal >= recentOpenArcCutoff && arc.invOrdinal >= offset && arc.invOrdinal < end) {
|
|
171163
171600
|
end = Math.min(end, arc.invOrdinal);
|
|
171164
171601
|
}
|
|
171165
171602
|
continue;
|
|
@@ -171226,7 +171663,14 @@ function resolveProtectedTailBoundary(ctx) {
|
|
|
171226
171663
|
}
|
|
171227
171664
|
if (ctx.mode === "manual-full-recomp") {
|
|
171228
171665
|
const arcs2 = buildToolArcs(messages);
|
|
171229
|
-
const
|
|
171666
|
+
const recompTarget = deriveProtectedTailTokenTarget({
|
|
171667
|
+
contextLimit: ctx.contextLimit,
|
|
171668
|
+
executeThresholdPercentage: ctx.executeThresholdPercentage,
|
|
171669
|
+
usagePercentage: 0,
|
|
171670
|
+
triggerBudget: ctx.triggerBudget
|
|
171671
|
+
});
|
|
171672
|
+
const recentOpenArcCutoff2 = index.findSuffixStartForTokens(recompTarget.N);
|
|
171673
|
+
const firstOpenArc = arcs2.find((arc) => arc.resOrdinal === null && arc.invOrdinal >= offset && arc.invOrdinal >= recentOpenArcCutoff2);
|
|
171230
171674
|
const protectedTailStart2 = firstOpenArc?.invOrdinal ?? rawMessageCount + 1;
|
|
171231
171675
|
const rawRangeFingerprint2 = computeRawRangeFingerprint(messages, offset, protectedTailStart2);
|
|
171232
171676
|
return {
|
|
@@ -171268,13 +171712,14 @@ function resolveProtectedTailBoundary(ctx) {
|
|
|
171268
171712
|
const scaledN = ctx.emergencyTailScale ? Math.max(1, Math.floor(target.N * ctx.emergencyTailScale)) : target.N;
|
|
171269
171713
|
const arcs = buildToolArcs(messages);
|
|
171270
171714
|
let boundary = index.findSuffixStartForTokens(scaledN);
|
|
171715
|
+
const recentOpenArcCutoff = boundary;
|
|
171271
171716
|
let boundaryReason = boundary === 1 ? "whole-session-smaller-than-tail" : "size-walk";
|
|
171272
171717
|
const tokenAtBoundary = index.tokenForOrdinal(boundary);
|
|
171273
171718
|
if (boundary <= rawMessageCount && tokenAtBoundary > Math.max(2 * scaledN, 64000) && boundary < rawMessageCount) {
|
|
171274
171719
|
boundary += 1;
|
|
171275
171720
|
boundaryReason = "huge-message-exception";
|
|
171276
171721
|
}
|
|
171277
|
-
boundary = fenceBoundaryForToolArcs(boundary, arcs, ctx.lastCompartmentEndOrdinal);
|
|
171722
|
+
boundary = fenceBoundaryForToolArcs(boundary, arcs, ctx.lastCompartmentEndOrdinal, recentOpenArcCutoff);
|
|
171278
171723
|
const snapped = semanticSnapBoundary({
|
|
171279
171724
|
messages,
|
|
171280
171725
|
index,
|
|
@@ -171284,7 +171729,7 @@ function resolveProtectedTailBoundary(ctx) {
|
|
|
171284
171729
|
});
|
|
171285
171730
|
if (snapped !== boundary)
|
|
171286
171731
|
boundaryReason = "semantic-snap";
|
|
171287
|
-
boundary = fenceBoundaryForToolArcs(snapped, arcs, ctx.lastCompartmentEndOrdinal);
|
|
171732
|
+
boundary = fenceBoundaryForToolArcs(snapped, arcs, ctx.lastCompartmentEndOrdinal, recentOpenArcCutoff);
|
|
171288
171733
|
let runtimeFloor = offset;
|
|
171289
171734
|
if (ctx.migrationFloorActive)
|
|
171290
171735
|
runtimeFloor = Math.max(runtimeFloor, ctx.priorBoundaryOrdinal);
|
|
@@ -171320,7 +171765,8 @@ function resolveProtectedTailBoundary(ctx) {
|
|
|
171320
171765
|
offset,
|
|
171321
171766
|
arcs,
|
|
171322
171767
|
lastCompartmentEndOrdinal: ctx.lastCompartmentEndOrdinal,
|
|
171323
|
-
capTokens: perRunCap
|
|
171768
|
+
capTokens: perRunCap,
|
|
171769
|
+
recentOpenArcCutoff
|
|
171324
171770
|
});
|
|
171325
171771
|
const rawRangeFingerprint = computeRawRangeFingerprint(messages, offset, head.eligibleEndOrdinal);
|
|
171326
171772
|
return {
|
|
@@ -171371,7 +171817,7 @@ function resolveBoundaryContext(args) {
|
|
|
171371
171817
|
}
|
|
171372
171818
|
let storedTokenTotals;
|
|
171373
171819
|
try {
|
|
171374
|
-
storedTokenTotals = getAllStatusTagTokenTotalsFlat(args.db, args.sessionId).totals;
|
|
171820
|
+
storedTokenTotals = getAllStatusTagTokenTotalsFlat(args.db, args.sessionId, args.taggerFloor ?? 0).totals;
|
|
171375
171821
|
} catch (error51) {
|
|
171376
171822
|
sessionLog(args.sessionId, "protected-tail stored-token map unavailable (live fallback):", error51);
|
|
171377
171823
|
}
|
|
@@ -173575,6 +174021,7 @@ async function runCompartmentAgent(deps) {
|
|
|
173575
174021
|
const count = recordHighPressureNoEligibleHead(db, boundarySnapshot);
|
|
173576
174022
|
sessionLog(sessionId, `historian high-pressure no-op: recovery remains armed (noEligibleHeadCount=${count})`);
|
|
173577
174023
|
}
|
|
174024
|
+
clearEmergencyDrainLatch(db, sessionId);
|
|
173578
174025
|
telemetry.status = "noop";
|
|
173579
174026
|
telemetry.failureReason = "nothing to compact before protected tail";
|
|
173580
174027
|
rollbackDrainReservation();
|
|
@@ -173589,7 +174036,8 @@ async function runCompartmentAgent(deps) {
|
|
|
173589
174036
|
trueRawTokens: boundarySnapshot.trueRawEligibleTokens,
|
|
173590
174037
|
usagePercentage: boundarySnapshot.usagePercentage,
|
|
173591
174038
|
usable,
|
|
173592
|
-
perRunCap
|
|
174039
|
+
perRunCap,
|
|
174040
|
+
executeThresholdPercentage: boundarySnapshot.executeThresholdPercentage
|
|
173593
174041
|
});
|
|
173594
174042
|
if (!reserve.ok) {
|
|
173595
174043
|
sessionLog(sessionId, `historian rate-limit skip: ${reserve.skippedReason ?? "quota exhausted"}`);
|
|
@@ -173608,6 +174056,7 @@ async function runCompartmentAgent(deps) {
|
|
|
173608
174056
|
} else {
|
|
173609
174057
|
recordHighPressureNoEligibleHead(db, boundarySnapshot);
|
|
173610
174058
|
}
|
|
174059
|
+
clearEmergencyDrainLatch(db, sessionId);
|
|
173611
174060
|
telemetry.status = "noop";
|
|
173612
174061
|
telemetry.failureReason = "chunk empty after filtering";
|
|
173613
174062
|
rollbackDrainReservation();
|
|
@@ -173715,6 +174164,7 @@ ${chunkText}`,
|
|
|
173715
174164
|
}
|
|
173716
174165
|
appendCompartments(db, sessionId, persistedCompartments);
|
|
173717
174166
|
clearHistorianFailureState(db, sessionId);
|
|
174167
|
+
clearHistorianDrainFailure(db, sessionId);
|
|
173718
174168
|
recordProtectedTailPublicationFloor(db, sessionId, lastCompartmentEnd + 1);
|
|
173719
174169
|
clearEmergencyRecovery(db, sessionId);
|
|
173720
174170
|
drainReservation = null;
|
|
@@ -173818,8 +174268,11 @@ ${chunkText}`,
|
|
|
173818
174268
|
}
|
|
173819
174269
|
} finally {
|
|
173820
174270
|
if (!completedSuccessfully) {
|
|
173821
|
-
if (!retainDrainReservationForRetryThrottle)
|
|
174271
|
+
if (!retainDrainReservationForRetryThrottle) {
|
|
173822
174272
|
rollbackDrainReservation();
|
|
174273
|
+
} else {
|
|
174274
|
+
recordHistorianDrainFailure(db, sessionId);
|
|
174275
|
+
}
|
|
173823
174276
|
updateSessionMeta(db, sessionId, { compartmentInProgress: false });
|
|
173824
174277
|
}
|
|
173825
174278
|
recordTelemetry();
|
|
@@ -176933,7 +177386,6 @@ var init_memory_migration = __esm(async () => {
|
|
|
176933
177386
|
init_shared();
|
|
176934
177387
|
init_assistant_message_extractor();
|
|
176935
177388
|
init_logger();
|
|
176936
|
-
init_resolve_fallbacks();
|
|
176937
177389
|
init_project_identity();
|
|
176938
177390
|
init_storage_memory();
|
|
176939
177391
|
await init_storage();
|
|
@@ -177249,17 +177701,20 @@ function shouldShowAnnouncement() {
|
|
|
177249
177701
|
}
|
|
177250
177702
|
return state.version !== ANNOUNCEMENT_VERSION;
|
|
177251
177703
|
}
|
|
177252
|
-
var ANNOUNCEMENT_VERSION = "0.
|
|
177704
|
+
var ANNOUNCEMENT_VERSION = "0.26.0", ANNOUNCEMENT_FEATURES, ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/F2uWxjGnU", STATE_FILENAME = "last_announced_version";
|
|
177253
177705
|
var init_announcement = __esm(() => {
|
|
177254
177706
|
init_data_path();
|
|
177255
177707
|
ANNOUNCEMENT_FEATURES = [
|
|
177256
|
-
"
|
|
177257
|
-
"
|
|
177258
|
-
"
|
|
177259
|
-
"
|
|
177260
|
-
"
|
|
177708
|
+
"Faster on large sessions: per-message transform overhead is at least 2x lower on typical passes and up to ~10x lower when history summarization fires (no more multi-second pause on big sessions).",
|
|
177709
|
+
"No more surprise models: the built-in fallback chain is gone. Hidden agents only use the model (and fallback_models) you configure — no confusing 'model not found' for providers you never set up. `doctor` now records every historian run so real failures are visible.",
|
|
177710
|
+
"Anthropic thinking-block fix: clearing old reasoning no longer risks a stale-signature rejection on Claude / Bedrock / proxied-Claude routes. Plus fewer prompt-cache busts.",
|
|
177711
|
+
"Community fixes: TUI crash on the upgrade progress panel (#168), historian.disallowed_tools for weak models that loop on tool calls (#166), and a Pi-only config key leak (#167).",
|
|
177712
|
+
"New: doctor migrate-session re-homes a session (and optionally its memories) to another project, with a dry-run preview."
|
|
177261
177713
|
];
|
|
177262
177714
|
});
|
|
177715
|
+
|
|
177716
|
+
// src/agents/dreamer.ts
|
|
177717
|
+
var DREAMER_AGENT = "dreamer";
|
|
177263
177718
|
// src/agents/permissions.ts
|
|
177264
177719
|
function buildAllowOnlyPermission(allowedTools) {
|
|
177265
177720
|
const permission = { "*": "deny" };
|
|
@@ -177269,6 +177724,11 @@ function buildAllowOnlyPermission(allowedTools) {
|
|
|
177269
177724
|
return permission;
|
|
177270
177725
|
}
|
|
177271
177726
|
var HISTORIAN_ALLOWED_TOOLS = ["read", "aft_outline", "aft_zoom", "aft_search"];
|
|
177727
|
+
function applyDisallowedTools(defaults, disallowed) {
|
|
177728
|
+
if (disallowed.includes("*"))
|
|
177729
|
+
return [];
|
|
177730
|
+
return defaults.filter((t) => !disallowed.includes(t));
|
|
177731
|
+
}
|
|
177272
177732
|
var DREAMER_ALLOWED_TOOLS = [
|
|
177273
177733
|
"read",
|
|
177274
177734
|
"grep",
|
|
@@ -177284,6 +177744,10 @@ var DREAMER_ALLOWED_TOOLS = [
|
|
|
177284
177744
|
"ctx_note"
|
|
177285
177745
|
];
|
|
177286
177746
|
var SIDEKICK_ALLOWED_TOOLS = ["ctx_search", "aft_outline", "aft_zoom"];
|
|
177747
|
+
|
|
177748
|
+
// src/agents/sidekick.ts
|
|
177749
|
+
var SIDEKICK_AGENT = "sidekick";
|
|
177750
|
+
|
|
177287
177751
|
// src/config/index.ts
|
|
177288
177752
|
init_jsonc_parser();
|
|
177289
177753
|
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
|
|
@@ -177986,9 +178450,9 @@ function getMagicContextBuiltinCommands() {
|
|
|
177986
178450
|
template: "ctx-dream",
|
|
177987
178451
|
description: "Run the hidden dreamer maintenance pass for this project now"
|
|
177988
178452
|
},
|
|
177989
|
-
"ctx-embed
|
|
177990
|
-
template: "ctx-embed
|
|
177991
|
-
description: "
|
|
178453
|
+
"ctx-embed": {
|
|
178454
|
+
template: "ctx-embed",
|
|
178455
|
+
description: "Embedding status, or start/pause history compartment embedding (start | pause)"
|
|
177992
178456
|
}
|
|
177993
178457
|
};
|
|
177994
178458
|
}
|
|
@@ -178237,6 +178701,7 @@ ${modeIntro}
|
|
|
178237
178701
|
4. **Write or update** using the Write tool. Always write to project root, NOT to .planning/.
|
|
178238
178702
|
|
|
178239
178703
|
### Rules
|
|
178704
|
+
- **NEVER touch protected regions**: any content between \`<!-- mc:protected START ... -->\` and \`<!-- mc:protected END -->\` is hand-authored and cache-critical. Reproduce it BYTE-FOR-BYTE in your rewrite — do not edit, reword, reorder, summarize, trim, or drop a single line of it, and keep the marker comments themselves. Only a human edits that region.
|
|
178240
178705
|
- **Be prescriptive**: "Use X pattern" not "X pattern is used"
|
|
178241
178706
|
- **Always include file paths** in backticks
|
|
178242
178707
|
- **Write current state only**: no temporal language, no history
|
|
@@ -178373,7 +178838,6 @@ init_project_identity();
|
|
|
178373
178838
|
init_shared();
|
|
178374
178839
|
init_assistant_message_extractor();
|
|
178375
178840
|
init_logger();
|
|
178376
|
-
init_resolve_fallbacks();
|
|
178377
178841
|
init_subagent_token_capture();
|
|
178378
178842
|
await init_storage();
|
|
178379
178843
|
|
|
@@ -178395,7 +178859,7 @@ function stripThinkingBlocks(text) {
|
|
|
178395
178859
|
|
|
178396
178860
|
// src/features/magic-context/sidekick/agent.ts
|
|
178397
178861
|
async function runSidekick(deps) {
|
|
178398
|
-
const fallbackModels = resolveFallbackChain(
|
|
178862
|
+
const fallbackModels = resolveFallbackChain(deps.config.fallback_models);
|
|
178399
178863
|
let agentSessionId = null;
|
|
178400
178864
|
const startedAt = Date.now();
|
|
178401
178865
|
let invocationRecorded = false;
|
|
@@ -178485,6 +178949,11 @@ init_project_identity();
|
|
|
178485
178949
|
import { createHash as createHash6 } from "node:crypto";
|
|
178486
178950
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
178487
178951
|
import path5 from "node:path";
|
|
178952
|
+
|
|
178953
|
+
// src/features/magic-context/memory/relocate-memory.ts
|
|
178954
|
+
var memoryCopyColumnsCache = new WeakMap;
|
|
178955
|
+
|
|
178956
|
+
// src/features/magic-context/v22-deferred-backfill.ts
|
|
178488
178957
|
var BATCH_SIZE = 25;
|
|
178489
178958
|
var YIELD_EVERY_N_ROWS = 5;
|
|
178490
178959
|
var BACKFILL_META_KEY = "v22_legacy_memory_backfill";
|
|
@@ -178722,6 +179191,7 @@ function createLiveSessionState() {
|
|
|
178722
179191
|
|
|
178723
179192
|
// src/index.ts
|
|
178724
179193
|
init_conflict_warning_hook();
|
|
179194
|
+
|
|
178725
179195
|
// src/features/magic-context/dreamer/storage-dream-state.ts
|
|
178726
179196
|
var getDreamStateStatements = new WeakMap;
|
|
178727
179197
|
var setDreamStateStatements = new WeakMap;
|
|
@@ -178859,7 +179329,7 @@ function enqueueDream(db, projectIdentity, reason, force = false) {
|
|
|
178859
179329
|
return db.transaction(() => {
|
|
178860
179330
|
if (!hasActiveDreamLease(db)) {
|
|
178861
179331
|
const staleThresholdMs = force ? 2 * 60 * 1000 : 120 * 60 * 1000;
|
|
178862
|
-
db.prepare("DELETE FROM dream_queue WHERE project_path = ? AND started_at IS NOT NULL AND started_at < ?").run(
|
|
179332
|
+
db.prepare("DELETE FROM dream_queue WHERE project_path = ? AND started_at IS NOT NULL AND started_at < ?").run(projectIdentity, now - staleThresholdMs);
|
|
178863
179333
|
}
|
|
178864
179334
|
const existing = db.prepare("SELECT id FROM dream_queue WHERE project_path = ?").get(projectIdentity);
|
|
178865
179335
|
if (existing) {
|
|
@@ -178915,21 +179385,21 @@ function clearStaleEntries(db, maxAgeMs, projectIdentity) {
|
|
|
178915
179385
|
return result.changes;
|
|
178916
179386
|
}
|
|
178917
179387
|
// src/features/magic-context/dreamer/runner.ts
|
|
179388
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
179389
|
+
import { join as join12 } from "node:path";
|
|
178918
179390
|
init_shared();
|
|
178919
179391
|
init_assistant_message_extractor();
|
|
178920
179392
|
init_data_path();
|
|
178921
179393
|
init_logger();
|
|
178922
179394
|
await init_sqlite();
|
|
178923
|
-
import { existsSync as existsSync10 } from "node:fs";
|
|
178924
|
-
import { join as join12 } from "node:path";
|
|
178925
179395
|
|
|
178926
179396
|
// src/features/magic-context/key-files/identify-key-files.ts
|
|
179397
|
+
import { readFileSync as readFileSync8 } from "node:fs";
|
|
179398
|
+
import { isAbsolute as isAbsolute3, join as join11, relative as relative2 } from "node:path";
|
|
178927
179399
|
init_read_session_formatting();
|
|
178928
179400
|
init_shared();
|
|
178929
179401
|
init_assistant_message_extractor();
|
|
178930
179402
|
init_logger();
|
|
178931
|
-
import { readFileSync as readFileSync8 } from "node:fs";
|
|
178932
|
-
import { isAbsolute as isAbsolute3, join as join11, relative as relative2 } from "node:path";
|
|
178933
179403
|
init_subagent_token_capture();
|
|
178934
179404
|
init_aft_availability();
|
|
178935
179405
|
init_project_key_files();
|
|
@@ -180554,120 +181024,7 @@ ${body}` : subject;
|
|
|
180554
181024
|
init_logger();
|
|
180555
181025
|
init_embedding();
|
|
180556
181026
|
init_storage_git_commit_embeddings();
|
|
180557
|
-
|
|
180558
|
-
// src/features/magic-context/git-commits/storage-git-commits.ts
|
|
180559
|
-
init_logger();
|
|
180560
|
-
var insertStatements = new WeakMap;
|
|
180561
|
-
var existingShasStatements = new WeakMap;
|
|
180562
|
-
var projectCountStatements = new WeakMap;
|
|
180563
|
-
var evictStatements = new WeakMap;
|
|
180564
|
-
var evictOverflowStatements = new WeakMap;
|
|
180565
|
-
var latestCommitTimeStatements = new WeakMap;
|
|
180566
|
-
function getInsertStatement(db) {
|
|
180567
|
-
let stmt = insertStatements.get(db);
|
|
180568
|
-
if (!stmt) {
|
|
180569
|
-
stmt = db.prepare(`INSERT INTO git_commits (sha, project_path, short_sha, message, author, committed_at, indexed_at)
|
|
180570
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
180571
|
-
ON CONFLICT(sha) DO UPDATE SET
|
|
180572
|
-
project_path = excluded.project_path,
|
|
180573
|
-
short_sha = excluded.short_sha,
|
|
180574
|
-
message = excluded.message,
|
|
180575
|
-
author = excluded.author,
|
|
180576
|
-
committed_at = excluded.committed_at,
|
|
180577
|
-
indexed_at = excluded.indexed_at
|
|
180578
|
-
WHERE git_commits.message != excluded.message`);
|
|
180579
|
-
insertStatements.set(db, stmt);
|
|
180580
|
-
}
|
|
180581
|
-
return stmt;
|
|
180582
|
-
}
|
|
180583
|
-
function getExistingShasStatement(db) {
|
|
180584
|
-
let stmt = existingShasStatements.get(db);
|
|
180585
|
-
if (!stmt) {
|
|
180586
|
-
stmt = db.prepare("SELECT sha FROM git_commits WHERE project_path = ?");
|
|
180587
|
-
existingShasStatements.set(db, stmt);
|
|
180588
|
-
}
|
|
180589
|
-
return stmt;
|
|
180590
|
-
}
|
|
180591
|
-
function getProjectCountStatement(db) {
|
|
180592
|
-
let stmt = projectCountStatements.get(db);
|
|
180593
|
-
if (!stmt) {
|
|
180594
|
-
stmt = db.prepare("SELECT COUNT(*) AS count FROM git_commits WHERE project_path = ?");
|
|
180595
|
-
projectCountStatements.set(db, stmt);
|
|
180596
|
-
}
|
|
180597
|
-
return stmt;
|
|
180598
|
-
}
|
|
180599
|
-
function getLatestCommitTimeStatement(db) {
|
|
180600
|
-
let stmt = latestCommitTimeStatements.get(db);
|
|
180601
|
-
if (!stmt) {
|
|
180602
|
-
stmt = db.prepare("SELECT MAX(committed_at) AS latest FROM git_commits WHERE project_path = ?");
|
|
180603
|
-
latestCommitTimeStatements.set(db, stmt);
|
|
180604
|
-
}
|
|
180605
|
-
return stmt;
|
|
180606
|
-
}
|
|
180607
|
-
function getEvictOverflowStatement(db) {
|
|
180608
|
-
let stmt = evictOverflowStatements.get(db);
|
|
180609
|
-
if (!stmt) {
|
|
180610
|
-
stmt = db.prepare(`DELETE FROM git_commits
|
|
180611
|
-
WHERE rowid IN (
|
|
180612
|
-
SELECT rowid FROM git_commits
|
|
180613
|
-
WHERE project_path = ?
|
|
180614
|
-
ORDER BY committed_at DESC, sha DESC
|
|
180615
|
-
LIMIT -1 OFFSET ?
|
|
180616
|
-
)`);
|
|
180617
|
-
evictOverflowStatements.set(db, stmt);
|
|
180618
|
-
}
|
|
180619
|
-
return stmt;
|
|
180620
|
-
}
|
|
180621
|
-
function upsertCommits(db, projectPath, commits) {
|
|
180622
|
-
if (commits.length === 0)
|
|
180623
|
-
return { inserted: 0, updated: 0 };
|
|
180624
|
-
const existing = new Set;
|
|
180625
|
-
for (const row of getExistingShasStatement(db).all(projectPath)) {
|
|
180626
|
-
existing.add(row.sha);
|
|
180627
|
-
}
|
|
180628
|
-
let inserted = 0;
|
|
180629
|
-
let updated = 0;
|
|
180630
|
-
const now = Date.now();
|
|
180631
|
-
const insertStmt = getInsertStatement(db);
|
|
180632
|
-
db.transaction(() => {
|
|
180633
|
-
for (const commit of commits) {
|
|
180634
|
-
const result = insertStmt.run(commit.sha, projectPath, commit.shortSha, commit.message, commit.author, commit.committedAtMs, now);
|
|
180635
|
-
if (result.changes > 0) {
|
|
180636
|
-
if (existing.has(commit.sha)) {
|
|
180637
|
-
updated++;
|
|
180638
|
-
} else {
|
|
180639
|
-
inserted++;
|
|
180640
|
-
existing.add(commit.sha);
|
|
180641
|
-
}
|
|
180642
|
-
}
|
|
180643
|
-
}
|
|
180644
|
-
})();
|
|
180645
|
-
return { inserted, updated };
|
|
180646
|
-
}
|
|
180647
|
-
function getCommitCount(db, projectPath) {
|
|
180648
|
-
const row = getProjectCountStatement(db).get(projectPath);
|
|
180649
|
-
return row?.count ?? 0;
|
|
180650
|
-
}
|
|
180651
|
-
function getLatestIndexedCommitTimeMs(db, projectPath) {
|
|
180652
|
-
const row = getLatestCommitTimeStatement(db).get(projectPath);
|
|
180653
|
-
return row?.latest ?? null;
|
|
180654
|
-
}
|
|
180655
|
-
function enforceProjectCap(db, projectPath, maxCommits) {
|
|
180656
|
-
if (maxCommits <= 0)
|
|
180657
|
-
return 0;
|
|
180658
|
-
const count = getCommitCount(db, projectPath);
|
|
180659
|
-
if (count <= maxCommits)
|
|
180660
|
-
return 0;
|
|
180661
|
-
getEvictOverflowStatement(db).run(projectPath, maxCommits);
|
|
180662
|
-
const after = getCommitCount(db, projectPath);
|
|
180663
|
-
const evicted = Math.max(0, count - after);
|
|
180664
|
-
if (evicted > 0) {
|
|
180665
|
-
log(`[git-commits] evicted ${evicted} oldest commits for project ${projectPath} (cap=${maxCommits}, was=${count})`);
|
|
180666
|
-
}
|
|
180667
|
-
return evicted;
|
|
180668
|
-
}
|
|
180669
|
-
|
|
180670
|
-
// src/features/magic-context/git-commits/indexer.ts
|
|
181027
|
+
init_storage_git_commits();
|
|
180671
181028
|
var MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
180672
181029
|
var EMBED_BATCH_SIZE = 16;
|
|
180673
181030
|
var EMBED_MAX_PER_SWEEP = 500;
|
|
@@ -180905,12 +181262,12 @@ function searchGitCommitsSync(db, projectPath, query, options) {
|
|
|
180905
181262
|
|
|
180906
181263
|
// src/features/magic-context/git-commits/index.ts
|
|
180907
181264
|
init_storage_git_commit_embeddings();
|
|
181265
|
+
init_storage_git_commits();
|
|
180908
181266
|
init_sweep_coordinator();
|
|
180909
181267
|
|
|
180910
181268
|
// src/plugin/dream-timer.ts
|
|
180911
181269
|
init_embedding();
|
|
180912
181270
|
init_logger();
|
|
180913
|
-
init_resolve_fallbacks();
|
|
180914
181271
|
await init_storage();
|
|
180915
181272
|
var DREAM_TIMER_INTERVAL_MS = 15 * 60 * 1000;
|
|
180916
181273
|
var activeTimer = null;
|
|
@@ -181013,7 +181370,7 @@ async function sweepProject(reg, origin, db, gitCommitEnabled = getProjectEmbedd
|
|
|
181013
181370
|
experimentalPinKeyFiles: reg.experimentalPinKeyFiles,
|
|
181014
181371
|
projectIdentity: reg.projectIdentity,
|
|
181015
181372
|
sessionDirectoryOverride: reg.directory,
|
|
181016
|
-
fallbackModels: resolveFallbackChain(
|
|
181373
|
+
fallbackModels: resolveFallbackChain(reg.dreamerConfig.fallback_models)
|
|
181017
181374
|
});
|
|
181018
181375
|
} catch (error51) {
|
|
181019
181376
|
log(`[dreamer] timer-triggered queue processing failed for ${reg.projectIdentity}:`, error51);
|
|
@@ -181462,10 +181819,9 @@ function makeToolCompositeKey(ownerMsgId, callId) {
|
|
|
181462
181819
|
}
|
|
181463
181820
|
var GET_COUNTER_SQL = `SELECT counter FROM session_meta WHERE session_id = ?`;
|
|
181464
181821
|
var GET_ASSIGNMENTS_SQL = "SELECT message_id, tag_number, type, tool_owner_message_id FROM tags WHERE session_id = ? ORDER BY tag_number ASC";
|
|
181822
|
+
var GET_ASSIGNMENTS_SCOPED_SQL = "SELECT message_id, tag_number, type, tool_owner_message_id FROM tags WHERE session_id = ? AND tag_number >= ? ORDER BY tag_number ASC";
|
|
181465
181823
|
var PROBE_DATA_VERSION_SQL = "PRAGMA main.data_version";
|
|
181466
|
-
var PROBE_TOTAL_CHANGES_SQL = "SELECT total_changes() AS tc";
|
|
181467
181824
|
var probeDataVersionStatements = new WeakMap;
|
|
181468
|
-
var probeTotalChangesStatements = new WeakMap;
|
|
181469
181825
|
function getProbeDataVersionStatement(db) {
|
|
181470
181826
|
let stmt = probeDataVersionStatements.get(db);
|
|
181471
181827
|
if (!stmt) {
|
|
@@ -181474,14 +181830,6 @@ function getProbeDataVersionStatement(db) {
|
|
|
181474
181830
|
}
|
|
181475
181831
|
return stmt;
|
|
181476
181832
|
}
|
|
181477
|
-
function getProbeTotalChangesStatement(db) {
|
|
181478
|
-
let stmt = probeTotalChangesStatements.get(db);
|
|
181479
|
-
if (!stmt) {
|
|
181480
|
-
stmt = db.prepare(PROBE_TOTAL_CHANGES_SQL);
|
|
181481
|
-
probeTotalChangesStatements.set(db, stmt);
|
|
181482
|
-
}
|
|
181483
|
-
return stmt;
|
|
181484
|
-
}
|
|
181485
181833
|
function isAssignmentRow(row) {
|
|
181486
181834
|
if (row === null || typeof row !== "object") {
|
|
181487
181835
|
return false;
|
|
@@ -181674,20 +182022,18 @@ function createTagger() {
|
|
|
181674
182022
|
}
|
|
181675
182023
|
function probeSignature(db) {
|
|
181676
182024
|
const dvRow = getProbeDataVersionStatement(db).get();
|
|
181677
|
-
const tcRow = getProbeTotalChangesStatement(db).get();
|
|
181678
182025
|
return {
|
|
181679
|
-
dataVersion: dvRow?.data_version ?? 0
|
|
181680
|
-
totalChanges: tcRow?.tc ?? 0
|
|
182026
|
+
dataVersion: dvRow?.data_version ?? 0
|
|
181681
182027
|
};
|
|
181682
182028
|
}
|
|
181683
|
-
function initFromDb(sessionId, db) {
|
|
182029
|
+
function initFromDb(sessionId, db, floor = 0) {
|
|
181684
182030
|
const probe = probeSignature(db);
|
|
181685
182031
|
const cached2 = loadSignatures.get(sessionId);
|
|
181686
|
-
if (cached2 !== undefined && cached2.db === db && cached2.dataVersion === probe.dataVersion && cached2.
|
|
182032
|
+
if (cached2 !== undefined && cached2.db === db && cached2.dataVersion === probe.dataVersion && cached2.floor === floor) {
|
|
181687
182033
|
return;
|
|
181688
182034
|
}
|
|
181689
182035
|
const row = db.prepare(GET_COUNTER_SQL).get(sessionId);
|
|
181690
|
-
const assignmentRows = db.prepare(GET_ASSIGNMENTS_SQL).all(sessionId).filter(isAssignmentRow);
|
|
182036
|
+
const assignmentRows = (floor > 0 ? db.prepare(GET_ASSIGNMENTS_SCOPED_SQL).all(sessionId, floor) : db.prepare(GET_ASSIGNMENTS_SQL).all(sessionId)).filter(isAssignmentRow);
|
|
181691
182037
|
const sessionAssignments = getSessionAssignments(sessionId);
|
|
181692
182038
|
sessionAssignments.clear();
|
|
181693
182039
|
let maxTagNumber = 0;
|
|
@@ -181708,7 +182054,7 @@ function createTagger() {
|
|
|
181708
182054
|
loadSignatures.set(sessionId, {
|
|
181709
182055
|
db,
|
|
181710
182056
|
dataVersion: probe.dataVersion,
|
|
181711
|
-
|
|
182057
|
+
floor
|
|
181712
182058
|
});
|
|
181713
182059
|
}
|
|
181714
182060
|
function cleanup(sessionId) {
|
|
@@ -181731,13 +182077,13 @@ function createTagger() {
|
|
|
181731
182077
|
cleanup
|
|
181732
182078
|
};
|
|
181733
182079
|
}
|
|
182080
|
+
|
|
181734
182081
|
// src/hooks/magic-context/hook.ts
|
|
181735
182082
|
init_magic_context();
|
|
181736
182083
|
init_project_identity();
|
|
181737
182084
|
init_project_embedding_registry();
|
|
181738
182085
|
await init_storage();
|
|
181739
182086
|
init_logger();
|
|
181740
|
-
init_resolve_fallbacks();
|
|
181741
182087
|
init_rpc_notifications();
|
|
181742
182088
|
|
|
181743
182089
|
// src/hooks/magic-context/command-handler.ts
|
|
@@ -181788,6 +182134,7 @@ await __promiseAll([
|
|
|
181788
182134
|
// src/hooks/magic-context/compartment-trigger.ts
|
|
181789
182135
|
init_compartment_storage();
|
|
181790
182136
|
init_logger();
|
|
182137
|
+
init_read_session_true_raw_tokens();
|
|
181791
182138
|
await __promiseAll([
|
|
181792
182139
|
init_storage(),
|
|
181793
182140
|
init_protected_tail_boundary(),
|
|
@@ -181802,6 +182149,38 @@ var TAIL_SIZE_TRIGGER_MULTIPLIER = 3;
|
|
|
181802
182149
|
var FORCE_COMPARTMENT_PERCENTAGE = 80;
|
|
181803
182150
|
var BLOCK_UNTIL_DONE_PERCENTAGE = 95;
|
|
181804
182151
|
var FORCE_MATERIALIZE_PERCENTAGE = 85;
|
|
182152
|
+
var CONTENT_TAG_OWNER_SUFFIX = /:(?:p|file)\d+$/;
|
|
182153
|
+
function tagOwnerMessageId(row) {
|
|
182154
|
+
if (row.type === "tool")
|
|
182155
|
+
return row.tool_owner_message_id ?? row.message_id;
|
|
182156
|
+
return row.message_id.replace(CONTENT_TAG_OWNER_SUFFIX, "");
|
|
182157
|
+
}
|
|
182158
|
+
function getActiveOrDroppedTagOwnerMessageIds(db, sessionId, floor = 0) {
|
|
182159
|
+
const rows = floor > 0 ? db.prepare(`SELECT type, message_id, tool_owner_message_id
|
|
182160
|
+
FROM tags
|
|
182161
|
+
WHERE session_id = ? AND status IN ('active', 'dropped') AND tag_number >= ?`).all(sessionId, floor) : db.prepare(`SELECT type, message_id, tool_owner_message_id
|
|
182162
|
+
FROM tags
|
|
182163
|
+
WHERE session_id = ? AND status IN ('active', 'dropped')`).all(sessionId);
|
|
182164
|
+
const owners = new Set;
|
|
182165
|
+
for (const row of rows)
|
|
182166
|
+
owners.add(tagOwnerMessageId(row));
|
|
182167
|
+
return owners;
|
|
182168
|
+
}
|
|
182169
|
+
function estimateUntaggedInMemoryTailUpperBound(db, sessionId, inMemoryTail, taggerFloor = 0) {
|
|
182170
|
+
const lastCompartmentEnd = getLastCompartmentEndMessage(db, sessionId);
|
|
182171
|
+
const coveredOwnerMessageIds = getActiveOrDroppedTagOwnerMessageIds(db, sessionId, taggerFloor);
|
|
182172
|
+
let total = 0;
|
|
182173
|
+
for (const message of inMemoryTail.messages) {
|
|
182174
|
+
if (message.ordinal <= lastCompartmentEnd)
|
|
182175
|
+
continue;
|
|
182176
|
+
if (coveredOwnerMessageIds.has(message.id))
|
|
182177
|
+
continue;
|
|
182178
|
+
total += estimateTrueRawMessageTokens(message, {
|
|
182179
|
+
providerShapeVersion: "opencode-v1"
|
|
182180
|
+
}).total;
|
|
182181
|
+
}
|
|
182182
|
+
return total;
|
|
182183
|
+
}
|
|
181805
182184
|
function buildTriggerInMemoryTail(db, sessionId, messages) {
|
|
181806
182185
|
if (messages.length === 0)
|
|
181807
182186
|
return;
|
|
@@ -181873,7 +182252,7 @@ function resolveBoundaryContextLimit(usage, fallbackContextLimit) {
|
|
|
181873
182252
|
}
|
|
181874
182253
|
return 128000;
|
|
181875
182254
|
}
|
|
181876
|
-
function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail) {
|
|
182255
|
+
function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail, taggerFloor = 0) {
|
|
181877
182256
|
return withRawSessionMessageCache(() => {
|
|
181878
182257
|
try {
|
|
181879
182258
|
const memoryPrimed = inMemoryTail ? primeInMemoryTailRawMessageCache({
|
|
@@ -181902,7 +182281,8 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
|
|
|
181902
182281
|
contextLimit: resolveBoundaryContextLimit(usage, contextLimit),
|
|
181903
182282
|
executeThresholdPercentage,
|
|
181904
182283
|
usage,
|
|
181905
|
-
usageSource: "live"
|
|
182284
|
+
usageSource: "live",
|
|
182285
|
+
taggerFloor
|
|
181906
182286
|
});
|
|
181907
182287
|
const hasProtectedEligibleHead = boundary.offset < boundary.protectedTailStart;
|
|
181908
182288
|
if (!hasProtectedEligibleHead) {
|
|
@@ -181933,7 +182313,7 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
|
|
|
181933
182313
|
}
|
|
181934
182314
|
});
|
|
181935
182315
|
}
|
|
181936
|
-
function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, clearReasoningAge, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail) {
|
|
182316
|
+
function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, clearReasoningAge, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail, taggerFloorOverride) {
|
|
181937
182317
|
if (sessionMeta.compartmentInProgress) {
|
|
181938
182318
|
sessionLog(sessionId, `compartment trigger: skipped — historian already in progress (usage=${usage.percentage.toFixed(1)}%)`);
|
|
181939
182319
|
return { shouldFire: false };
|
|
@@ -181947,14 +182327,17 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
|
|
|
181947
182327
|
inMemoryTail = undefined;
|
|
181948
182328
|
}
|
|
181949
182329
|
}
|
|
182330
|
+
const taggerFloor = taggerFloorOverride !== undefined && taggerFloorOverride > 0 ? taggerFloorOverride : inMemoryTail ? deriveTagLoadFloor(db, sessionId, inMemoryTail.messages.map((m) => m.id)) : 0;
|
|
181950
182331
|
const proactiveFloorForGate = getProactiveCompartmentTriggerPercentage(executeThresholdPercentage);
|
|
181951
|
-
if (
|
|
182332
|
+
if (usage.percentage < proactiveFloorForGate) {
|
|
181952
182333
|
try {
|
|
181953
|
-
const { bound, nullCount } = getTriggerTagTokenUpperBound(db, sessionId);
|
|
182334
|
+
const { bound: persistedBound, nullCount } = getTriggerTagTokenUpperBound(db, sessionId, taggerFloor);
|
|
181954
182335
|
if (nullCount === 0) {
|
|
181955
|
-
const
|
|
182336
|
+
const untaggedUpperBound = inMemoryTail ? estimateUntaggedInMemoryTailUpperBound(db, sessionId, inMemoryTail, taggerFloor) : 0;
|
|
182337
|
+
const eligibleUpperBound = persistedBound + untaggedUpperBound;
|
|
181956
182338
|
if (eligibleUpperBound < triggerBudget) {
|
|
181957
|
-
|
|
182339
|
+
const memorySuffix = inMemoryTail ? ` (persisted=${persistedBound}, untagged-memory≤${untaggedUpperBound})` : "";
|
|
182340
|
+
sessionLog(sessionId, `compartment trigger: cheap-skip at ${usage.percentage.toFixed(1)}% (below proactive floor ${proactiveFloorForGate}%) — live-tail upper bound ${eligibleUpperBound}${memorySuffix} < triggerBudget ${triggerBudget}; no size trigger possible, skipped full raw read`);
|
|
181958
182341
|
return { shouldFire: false };
|
|
181959
182342
|
}
|
|
181960
182343
|
}
|
|
@@ -181962,7 +182345,7 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
|
|
|
181962
182345
|
sessionLog(sessionId, `compartment trigger: cheap-gate skipped (falling through to full read): ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
181963
182346
|
}
|
|
181964
182347
|
}
|
|
181965
|
-
const tailInfo = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail);
|
|
182348
|
+
const tailInfo = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail, taggerFloor);
|
|
181966
182349
|
if (!tailInfo.hasNewRawHistory) {
|
|
181967
182350
|
try {
|
|
181968
182351
|
const lastCompartmentEnd = getLastCompartmentEndMessage(db, sessionId);
|
|
@@ -182328,7 +182711,7 @@ function createMagicContextCommandHandler(deps) {
|
|
|
182328
182711
|
const isAugCommand = (command) => command === "ctx-aug";
|
|
182329
182712
|
const isDreamCommand = (command) => command === "ctx-dream";
|
|
182330
182713
|
const isSessionUpgradeCommand = (command) => command === "ctx-session-upgrade";
|
|
182331
|
-
const
|
|
182714
|
+
const isEmbedCommand = (command) => command === "ctx-embed";
|
|
182332
182715
|
return {
|
|
182333
182716
|
"command.execute.before": async (input, _output, _params) => {
|
|
182334
182717
|
const isStatus = isStatusCommand(input.command);
|
|
@@ -182337,8 +182720,8 @@ function createMagicContextCommandHandler(deps) {
|
|
|
182337
182720
|
const isAug = isAugCommand(input.command);
|
|
182338
182721
|
const isDream = isDreamCommand(input.command);
|
|
182339
182722
|
const isSessionUpgrade = isSessionUpgradeCommand(input.command);
|
|
182340
|
-
const
|
|
182341
|
-
if (!isStatus && !isFlush && !isRecomp && !isAug && !isDream && !isSessionUpgrade && !
|
|
182723
|
+
const isEmbed = isEmbedCommand(input.command);
|
|
182724
|
+
if (!isStatus && !isFlush && !isRecomp && !isAug && !isDream && !isSessionUpgrade && !isEmbed) {
|
|
182342
182725
|
return;
|
|
182343
182726
|
}
|
|
182344
182727
|
const sessionId = input.sessionID;
|
|
@@ -182351,15 +182734,50 @@ function createMagicContextCommandHandler(deps) {
|
|
|
182351
182734
|
await executeDreaming(deps, sessionId);
|
|
182352
182735
|
return;
|
|
182353
182736
|
}
|
|
182354
|
-
if (
|
|
182355
|
-
const
|
|
182356
|
-
|
|
182357
|
-
|
|
182737
|
+
if (isEmbed) {
|
|
182738
|
+
const sub = input.arguments.trim().toLowerCase();
|
|
182739
|
+
if (sub === "pause") {
|
|
182740
|
+
const summary = deps.pauseEmbedDrain ? deps.pauseEmbedDrain(sessionId) : "Embedding pause is unavailable.";
|
|
182741
|
+
if (isTuiConnected(sessionId)) {
|
|
182742
|
+
pushNotification("action", { action: "show-result-dialog", title: "Embed", message: summary }, sessionId);
|
|
182743
|
+
} else {
|
|
182744
|
+
await deps.sendNotification(sessionId, summary, {});
|
|
182745
|
+
}
|
|
182746
|
+
throwSentinel(input.command);
|
|
182747
|
+
}
|
|
182748
|
+
if (sub === "start") {
|
|
182749
|
+
const summary = deps.executeEmbedHistory ? await deps.executeEmbedHistory(sessionId) : "Semantic embedding is not configured for this project, so there is nothing to embed.";
|
|
182750
|
+
if (isTuiConnected(sessionId)) {
|
|
182751
|
+
pushNotification("action", { action: "show-result-dialog", title: "Embed", message: summary }, sessionId);
|
|
182752
|
+
} else {
|
|
182753
|
+
await deps.sendNotification(sessionId, summary, {});
|
|
182754
|
+
}
|
|
182755
|
+
throwSentinel(input.command);
|
|
182756
|
+
}
|
|
182757
|
+
if (sub !== "") {
|
|
182758
|
+
await deps.sendNotification(sessionId, "Usage: `/ctx-embed` (status), `/ctx-embed start`, or `/ctx-embed pause`.", {});
|
|
182759
|
+
throwSentinel(input.command);
|
|
182760
|
+
}
|
|
182761
|
+
if (isTuiConnected(sessionId)) {
|
|
182762
|
+
pushNotification("action", { action: "show-embed-dialog" }, sessionId);
|
|
182763
|
+
sessionLog(sessionId, "command ctx-embed: pushed show-embed-dialog to TUI");
|
|
182764
|
+
throwSentinel(input.command);
|
|
182765
|
+
}
|
|
182766
|
+
result = deps.getEmbedStatusText ? `## Embedding Status
|
|
182767
|
+
|
|
182768
|
+
${deps.getEmbedStatusText(sessionId)}` : `## Embedding Status
|
|
182769
|
+
|
|
182770
|
+
Embedding status is unavailable.`;
|
|
182358
182771
|
}
|
|
182359
182772
|
if (isFlush) {
|
|
182360
182773
|
result = executeFlush(deps.db, sessionId);
|
|
182361
182774
|
clearCachedM0M1(deps.db, sessionId);
|
|
182362
182775
|
deps.onFlush?.(sessionId);
|
|
182776
|
+
if (isTuiConnected(sessionId)) {
|
|
182777
|
+
pushNotification("action", { action: "show-flush-dialog", message: result }, sessionId);
|
|
182778
|
+
sessionLog(sessionId, "command ctx-flush: pushed show-flush-dialog to TUI");
|
|
182779
|
+
throwSentinel(input.command);
|
|
182780
|
+
}
|
|
182363
182781
|
}
|
|
182364
182782
|
if (isStatus) {
|
|
182365
182783
|
if (isTuiConnected(sessionId)) {
|
|
@@ -182486,6 +182904,34 @@ ${snap.error}`;
|
|
|
182486
182904
|
// src/hooks/magic-context/hook.ts
|
|
182487
182905
|
init_derive_budgets();
|
|
182488
182906
|
|
|
182907
|
+
// src/hooks/magic-context/embed-session-state.ts
|
|
182908
|
+
var embedPauseBySession = new Set;
|
|
182909
|
+
var embedRunStateBySession = new Map;
|
|
182910
|
+
var autoEmbedAttemptedBySession = new Set;
|
|
182911
|
+
function getEmbedDrainUiStatus(sessionId, progress) {
|
|
182912
|
+
if (embedPauseBySession.has(sessionId)) {
|
|
182913
|
+
return { status: "paused" };
|
|
182914
|
+
}
|
|
182915
|
+
if (progress?.kind === "embed" && progress.phase === "recomp") {
|
|
182916
|
+
return { status: "running" };
|
|
182917
|
+
}
|
|
182918
|
+
if (progress?.kind === "embed" && (progress.phase === "failed" || progress.phase === "skipped") && progress.message) {
|
|
182919
|
+
if (/provider/i.test(progress.message)) {
|
|
182920
|
+
return { status: "stopped", detail: progress.message };
|
|
182921
|
+
}
|
|
182922
|
+
}
|
|
182923
|
+
return { status: "idle" };
|
|
182924
|
+
}
|
|
182925
|
+
function clearEmbedSessionState(sessionId) {
|
|
182926
|
+
embedPauseBySession.delete(sessionId);
|
|
182927
|
+
const ctrl = embedRunStateBySession.get(sessionId);
|
|
182928
|
+
if (ctrl) {
|
|
182929
|
+
ctrl.abort();
|
|
182930
|
+
embedRunStateBySession.delete(sessionId);
|
|
182931
|
+
}
|
|
182932
|
+
autoEmbedAttemptedBySession.delete(sessionId);
|
|
182933
|
+
}
|
|
182934
|
+
|
|
182489
182935
|
// src/features/magic-context/message-index-async.ts
|
|
182490
182936
|
init_logger();
|
|
182491
182937
|
await init_message_index();
|
|
@@ -182634,9 +183080,142 @@ function clearSessionTracking(sessionId) {
|
|
|
182634
183080
|
// src/hooks/magic-context/event-handler.ts
|
|
182635
183081
|
init_overflow_detection();
|
|
182636
183082
|
init_storage_meta_persisted();
|
|
183083
|
+
await init_storage();
|
|
183084
|
+
|
|
183085
|
+
// src/features/magic-context/transform-decision-log.ts
|
|
183086
|
+
await __promiseAll([
|
|
183087
|
+
init_sqlite(),
|
|
183088
|
+
init_storage_db()
|
|
183089
|
+
]);
|
|
183090
|
+
var canonicalReasons = new Set([
|
|
183091
|
+
"system_hash",
|
|
183092
|
+
"model_change",
|
|
183093
|
+
"project_memory_epoch",
|
|
183094
|
+
"ttl_idle",
|
|
183095
|
+
"explicit_flush",
|
|
183096
|
+
"max_mutation_id",
|
|
183097
|
+
"first_render",
|
|
183098
|
+
"pressure_refold",
|
|
183099
|
+
"upgrade_state",
|
|
183100
|
+
"cached_m1_missing"
|
|
183101
|
+
]);
|
|
183102
|
+
var piReasonAliases = {
|
|
183103
|
+
project_memory_change: "project_memory_epoch",
|
|
183104
|
+
pending_mutations: "max_mutation_id",
|
|
183105
|
+
renderer_upgrade: "upgrade_state",
|
|
183106
|
+
cache_invalid: "cached_m1_missing",
|
|
183107
|
+
drift: "pressure_refold"
|
|
183108
|
+
};
|
|
183109
|
+
var sharedReasonAliases = {
|
|
183110
|
+
model_key: "model_change",
|
|
183111
|
+
pressure: "pressure_refold"
|
|
183112
|
+
};
|
|
183113
|
+
var pendingDecisionBySession = new Map;
|
|
183114
|
+
var pendingPiDecisionBySession = new Map;
|
|
183115
|
+
var lastBoundMessageIdBySession = new Map;
|
|
183116
|
+
var scheduledWriteTokensBySession = new Map;
|
|
183117
|
+
var writerOverrideForTests = null;
|
|
183118
|
+
function normalizeMaterializeReason(harness, reason, rematerialized) {
|
|
183119
|
+
const raw = typeof reason === "string" ? reason.trim() : "";
|
|
183120
|
+
if (raw.length > 0) {
|
|
183121
|
+
const alias = sharedReasonAliases[raw] ?? (harness === "pi" ? piReasonAliases[raw] : undefined) ?? undefined;
|
|
183122
|
+
if (alias)
|
|
183123
|
+
return alias;
|
|
183124
|
+
if (canonicalReasons.has(raw))
|
|
183125
|
+
return raw;
|
|
183126
|
+
return null;
|
|
183127
|
+
}
|
|
183128
|
+
return rematerialized ? "pressure_refold" : null;
|
|
183129
|
+
}
|
|
183130
|
+
function clearOpenCodePendingTransformDecision(sessionId) {
|
|
183131
|
+
pendingDecisionBySession.delete(sessionId);
|
|
183132
|
+
}
|
|
183133
|
+
function clearTransformDecisionSession(sessionId) {
|
|
183134
|
+
pendingDecisionBySession.delete(sessionId);
|
|
183135
|
+
pendingPiDecisionBySession.delete(sessionId);
|
|
183136
|
+
lastBoundMessageIdBySession.delete(sessionId);
|
|
183137
|
+
scheduledWriteTokensBySession.delete(sessionId);
|
|
183138
|
+
}
|
|
183139
|
+
function recordPendingTransformDecision(sessionId, decision) {
|
|
183140
|
+
if (!decision.bustedThisPass) {
|
|
183141
|
+
pendingDecisionBySession.delete(sessionId);
|
|
183142
|
+
return;
|
|
183143
|
+
}
|
|
183144
|
+
pendingDecisionBySession.set(sessionId, decision);
|
|
183145
|
+
}
|
|
183146
|
+
function scheduleOpenCodeTransformDecisionWrite(args) {
|
|
183147
|
+
const pending = pendingDecisionBySession.get(args.sessionId);
|
|
183148
|
+
if (!pending)
|
|
183149
|
+
return false;
|
|
183150
|
+
if (lastBoundMessageIdBySession.get(args.sessionId) === args.messageId) {
|
|
183151
|
+
return false;
|
|
183152
|
+
}
|
|
183153
|
+
const dbPath = getDatabasePath(args.db);
|
|
183154
|
+
if (!dbPath)
|
|
183155
|
+
return false;
|
|
183156
|
+
lastBoundMessageIdBySession.set(args.sessionId, args.messageId);
|
|
183157
|
+
pendingDecisionBySession.delete(args.sessionId);
|
|
183158
|
+
const token = addScheduledWriteToken(args.sessionId);
|
|
183159
|
+
setTimeout(() => {
|
|
183160
|
+
try {
|
|
183161
|
+
if (!hasScheduledWriteToken(args.sessionId, token))
|
|
183162
|
+
return;
|
|
183163
|
+
writeTransformDecisionBestEffort(dbPath, {
|
|
183164
|
+
...pending,
|
|
183165
|
+
sessionId: args.sessionId,
|
|
183166
|
+
harness: "opencode",
|
|
183167
|
+
messageId: args.messageId,
|
|
183168
|
+
inputTokens: args.inputTokens
|
|
183169
|
+
});
|
|
183170
|
+
} finally {
|
|
183171
|
+
deleteScheduledWriteToken(args.sessionId, token);
|
|
183172
|
+
}
|
|
183173
|
+
}, 0);
|
|
183174
|
+
return true;
|
|
183175
|
+
}
|
|
183176
|
+
function addScheduledWriteToken(sessionId) {
|
|
183177
|
+
const token = Symbol(sessionId);
|
|
183178
|
+
let tokens = scheduledWriteTokensBySession.get(sessionId);
|
|
183179
|
+
if (!tokens) {
|
|
183180
|
+
tokens = new Set;
|
|
183181
|
+
scheduledWriteTokensBySession.set(sessionId, tokens);
|
|
183182
|
+
}
|
|
183183
|
+
tokens.add(token);
|
|
183184
|
+
return token;
|
|
183185
|
+
}
|
|
183186
|
+
function hasScheduledWriteToken(sessionId, token) {
|
|
183187
|
+
return scheduledWriteTokensBySession.get(sessionId)?.has(token) === true;
|
|
183188
|
+
}
|
|
183189
|
+
function deleteScheduledWriteToken(sessionId, token) {
|
|
183190
|
+
const tokens = scheduledWriteTokensBySession.get(sessionId);
|
|
183191
|
+
if (!tokens)
|
|
183192
|
+
return;
|
|
183193
|
+
tokens.delete(token);
|
|
183194
|
+
if (tokens.size === 0)
|
|
183195
|
+
scheduledWriteTokensBySession.delete(sessionId);
|
|
183196
|
+
}
|
|
183197
|
+
function writeTransformDecisionBestEffort(dbPath, row) {
|
|
183198
|
+
try {
|
|
183199
|
+
const writer = writerOverrideForTests ?? writeTransformDecisionRow;
|
|
183200
|
+
writer(dbPath, row);
|
|
183201
|
+
} catch {}
|
|
183202
|
+
}
|
|
183203
|
+
function writeTransformDecisionRow(dbPath, row) {
|
|
183204
|
+
const db = new Database(dbPath);
|
|
183205
|
+
try {
|
|
183206
|
+
db.exec("PRAGMA busy_timeout=0");
|
|
183207
|
+
db.prepare(`INSERT OR REPLACE INTO transform_decisions (
|
|
183208
|
+
session_id, harness, message_id, ts_ms, decision, materialized,
|
|
183209
|
+
materialize_reason, emergency, dropped_tokens, dropped_count, input_tokens
|
|
183210
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(row.sessionId, row.harness, row.messageId, row.tsMs, row.decision, row.materialized ? 1 : 0, row.materializeReason, row.emergency ? 1 : 0, Math.max(0, Math.floor(row.droppedTokens)), Math.max(0, Math.floor(row.droppedCount)), Math.max(0, Math.floor(row.inputTokens)));
|
|
183211
|
+
} finally {
|
|
183212
|
+
closeQuietly(db);
|
|
183213
|
+
}
|
|
183214
|
+
}
|
|
183215
|
+
|
|
183216
|
+
// src/hooks/magic-context/event-handler.ts
|
|
182637
183217
|
init_logger();
|
|
182638
183218
|
init_models_dev_cache();
|
|
182639
|
-
await init_storage();
|
|
182640
183219
|
|
|
182641
183220
|
// src/hooks/magic-context/channel2-delivery.ts
|
|
182642
183221
|
init_storage_meta_persisted();
|
|
@@ -182846,6 +183425,13 @@ function computePressure(input) {
|
|
|
182846
183425
|
function approxThousands(tokens) {
|
|
182847
183426
|
return `${Math.round(tokens / 1000)}k`;
|
|
182848
183427
|
}
|
|
183428
|
+
function formatOldestReclaimableHint(hint) {
|
|
183429
|
+
if (!hint || hint.length === 0)
|
|
183430
|
+
return "";
|
|
183431
|
+
const rendered = hint.slice(0, 4).map((tag) => `§${tag.tagNumber}§ ${tag.toolName ?? "tool"}`).join(" · ");
|
|
183432
|
+
return rendered.length > 0 ? `
|
|
183433
|
+
oldest reclaimable: ${rendered}.` : "";
|
|
183434
|
+
}
|
|
182849
183435
|
var CHANNEL2_USABLE_FRACTION = 1 / 3;
|
|
182850
183436
|
var CHANNEL2_MIN_RECLAIMABLE = 1e4;
|
|
182851
183437
|
function shouldTriggerChannel2(input) {
|
|
@@ -182855,14 +183441,16 @@ function shouldTriggerChannel2(input) {
|
|
|
182855
183441
|
return true;
|
|
182856
183442
|
return input.reclaimableTokens >= input.usableTokens * CHANNEL2_USABLE_FRACTION;
|
|
182857
183443
|
}
|
|
182858
|
-
function buildChannel2Reminder(undroppedTokens) {
|
|
183444
|
+
function buildChannel2Reminder(undroppedTokens, hint) {
|
|
182859
183445
|
const amount = approxThousands(undroppedTokens);
|
|
183446
|
+
const hintText = formatOldestReclaimableHint(hint);
|
|
182860
183447
|
return `<system-reminder>
|
|
182861
|
-
` + `Routine context housekeeping is near: a large span of this session will be comparted soon, ` + `and ~${amount} tokens of tool output remain unreduced. Drop spent outputs with ctx_reduce ` + `first so the archived span is the part that matters
|
|
183448
|
+
` + `Routine context housekeeping is near: a large span of this session will be comparted soon, ` + `and ~${amount} tokens of tool output remain unreduced. Drop spent outputs with ctx_reduce ` + `first so the archived span is the part that matters.${hintText}
|
|
182862
183449
|
` + `</system-reminder>`;
|
|
182863
183450
|
}
|
|
182864
|
-
function buildChannel1Reminder(level, undroppedTokens) {
|
|
183451
|
+
function buildChannel1Reminder(level, undroppedTokens, hint) {
|
|
182865
183452
|
const amount = approxThousands(undroppedTokens);
|
|
183453
|
+
const hintText = formatOldestReclaimableHint(hint);
|
|
182866
183454
|
let body;
|
|
182867
183455
|
switch (level) {
|
|
182868
183456
|
case "gentle":
|
|
@@ -182878,7 +183466,7 @@ function buildChannel1Reminder(level, undroppedTokens) {
|
|
|
182878
183466
|
return `
|
|
182879
183467
|
|
|
182880
183468
|
<system-reminder>
|
|
182881
|
-
${body}
|
|
183469
|
+
${body}${hintText}
|
|
182882
183470
|
</system-reminder>`;
|
|
182883
183471
|
}
|
|
182884
183472
|
|
|
@@ -182932,10 +183520,10 @@ async function maybeDeliverChannel2(sessionId, deps) {
|
|
|
182932
183520
|
try {
|
|
182933
183521
|
const client3 = getLiveServerClient(serverUrl, deps.directory);
|
|
182934
183522
|
const promptContext = await resolvePromptContext(client3, sessionId);
|
|
182935
|
-
const reminder = buildChannel2Reminder(deps.reclaimableTokens);
|
|
183523
|
+
const reminder = buildChannel2Reminder(deps.reclaimableTokens, deps.oldestReclaimableToolTags);
|
|
182936
183524
|
const body = {
|
|
182937
183525
|
noReply: false,
|
|
182938
|
-
parts: [{ type: "text", text: reminder }]
|
|
183526
|
+
parts: [{ type: "text", text: reminder, synthetic: true }]
|
|
182939
183527
|
};
|
|
182940
183528
|
if (promptContext?.agent)
|
|
182941
183529
|
body.agent = promptContext.agent;
|
|
@@ -183031,11 +183619,13 @@ function getMessageUpdatedAssistantInfo(properties) {
|
|
|
183031
183619
|
}
|
|
183032
183620
|
const tokens = isRecord(info.tokens) ? info.tokens : undefined;
|
|
183033
183621
|
const cache = tokens && isRecord(tokens.cache) ? tokens.cache : undefined;
|
|
183622
|
+
const time3 = isRecord(info.time) ? info.time : undefined;
|
|
183034
183623
|
return {
|
|
183035
183624
|
role: "assistant",
|
|
183036
183625
|
finish: typeof info.finish === "string" ? info.finish : undefined,
|
|
183037
183626
|
sessionID: info.sessionID,
|
|
183038
183627
|
messageID: typeof info.id === "string" ? info.id : undefined,
|
|
183628
|
+
completedAt: typeof time3?.completed === "number" ? time3.completed : undefined,
|
|
183039
183629
|
providerID: typeof info.providerID === "string" ? info.providerID : undefined,
|
|
183040
183630
|
modelID: typeof info.modelID === "string" ? info.modelID : undefined,
|
|
183041
183631
|
tokens: {
|
|
@@ -183098,8 +183688,8 @@ init_project_identity();
|
|
|
183098
183688
|
import * as crypto2 from "node:crypto";
|
|
183099
183689
|
init_session_project_storage();
|
|
183100
183690
|
init_storage_meta_persisted();
|
|
183101
|
-
init_logger();
|
|
183102
183691
|
await init_storage();
|
|
183692
|
+
init_logger();
|
|
183103
183693
|
|
|
183104
183694
|
// src/hooks/magic-context/boundary-execution.ts
|
|
183105
183695
|
var FORCE_MATERIALIZE_PERCENTAGE2 = 85;
|
|
@@ -183393,7 +183983,8 @@ function applyCavemanCleanup(sessionId, db, targets, tags, config2) {
|
|
|
183393
183983
|
const result = {
|
|
183394
183984
|
compressedToLite: 0,
|
|
183395
183985
|
compressedToFull: 0,
|
|
183396
|
-
compressedToUltra: 0
|
|
183986
|
+
compressedToUltra: 0,
|
|
183987
|
+
mutatedTextTags: 0
|
|
183397
183988
|
};
|
|
183398
183989
|
if (!config2.enabled)
|
|
183399
183990
|
return result;
|
|
@@ -183434,7 +184025,9 @@ function applyCavemanCleanup(sessionId, db, targets, tags, config2) {
|
|
|
183434
184025
|
const target = targets.get(tag.tagNumber);
|
|
183435
184026
|
if (!target)
|
|
183436
184027
|
continue;
|
|
183437
|
-
target.setContent(compressed);
|
|
184028
|
+
const didMutate = target.setContent(compressed);
|
|
184029
|
+
if (didMutate)
|
|
184030
|
+
result.mutatedTextTags += 1;
|
|
183438
184031
|
updateCavemanDepth(db, sessionId, tag.tagNumber, targetDepth);
|
|
183439
184032
|
if (targetDepth === DEPTH_LITE)
|
|
183440
184033
|
result.compressedToLite += 1;
|
|
@@ -184022,28 +184615,6 @@ function stripInlineThinking(messages, messageTagNumbers, clearReasoningAge) {
|
|
|
184022
184615
|
}
|
|
184023
184616
|
return stripped;
|
|
184024
184617
|
}
|
|
184025
|
-
function truncateErroredTools(messages, watermark, messageTagNumbers) {
|
|
184026
|
-
let truncated = 0;
|
|
184027
|
-
for (let i = 0;i < messages.length; i++) {
|
|
184028
|
-
const maxTag = messageTagNumbers.get(messages[i]) ?? 0;
|
|
184029
|
-
if (maxTag > watermark) {
|
|
184030
|
-
continue;
|
|
184031
|
-
}
|
|
184032
|
-
for (const part of messages[i].parts) {
|
|
184033
|
-
if (!isRecord(part) || part.type !== "tool" || !isRecord(part.state)) {
|
|
184034
|
-
continue;
|
|
184035
|
-
}
|
|
184036
|
-
if (part.state.status !== "error") {
|
|
184037
|
-
continue;
|
|
184038
|
-
}
|
|
184039
|
-
if (typeof part.state.error === "string" && part.state.error.length > 100) {
|
|
184040
|
-
part.state.error = `${part.state.error.slice(0, 100)}... [truncated]`;
|
|
184041
|
-
truncated++;
|
|
184042
|
-
}
|
|
184043
|
-
}
|
|
184044
|
-
}
|
|
184045
|
-
return truncated;
|
|
184046
|
-
}
|
|
184047
184618
|
var REASONING_IGNORED_PART_TYPES = new Set([
|
|
184048
184619
|
"step-start",
|
|
184049
184620
|
"step-finish",
|
|
@@ -184154,6 +184725,7 @@ function stripProcessedImages(messages, frozenIds, options) {
|
|
|
184154
184725
|
init_temporal_awareness();
|
|
184155
184726
|
|
|
184156
184727
|
// src/hooks/magic-context/transform-compartment-phase.ts
|
|
184728
|
+
init_compartment_storage();
|
|
184157
184729
|
init_logger();
|
|
184158
184730
|
await __promiseAll([
|
|
184159
184731
|
init_storage(),
|
|
@@ -184162,9 +184734,29 @@ await __promiseAll([
|
|
|
184162
184734
|
init_send_session_notification();
|
|
184163
184735
|
await __promiseAll([
|
|
184164
184736
|
init_inject_compartments(),
|
|
184165
|
-
init_protected_tail_boundary()
|
|
184737
|
+
init_protected_tail_boundary(),
|
|
184738
|
+
init_read_session_chunk()
|
|
184166
184739
|
]);
|
|
184167
|
-
|
|
184740
|
+
function runCompartmentPhase(args) {
|
|
184741
|
+
const historianRunnable = args.historianRunnable !== false;
|
|
184742
|
+
const willReadRawHistory = historianRunnable && args.canRunCompartments && getActiveCompartmentRun(args.sessionId) === undefined && (args.sessionMeta.compartmentInProgress || !args.skipAwaitForThisPass && args.contextUsage.percentage >= BLOCK_UNTIL_DONE_PERCENTAGE);
|
|
184743
|
+
if (!willReadRawHistory) {
|
|
184744
|
+
return runCompartmentPhaseImpl(args);
|
|
184745
|
+
}
|
|
184746
|
+
return withRawSessionMessageCache(() => {
|
|
184747
|
+
try {
|
|
184748
|
+
primeTailRawMessageCache({
|
|
184749
|
+
sessionId: args.resolvedSessionId,
|
|
184750
|
+
lastCompartmentEnd: getLastCompartmentEndMessage(args.db, args.resolvedSessionId),
|
|
184751
|
+
anchorMessageId: getLastCompartmentEndMessageId(args.db, args.resolvedSessionId)
|
|
184752
|
+
});
|
|
184753
|
+
} catch (error51) {
|
|
184754
|
+
sessionLog(args.sessionId, "compartment phase: tail prime failed (non-fatal):", error51);
|
|
184755
|
+
}
|
|
184756
|
+
return runCompartmentPhaseImpl(args);
|
|
184757
|
+
});
|
|
184758
|
+
}
|
|
184759
|
+
async function runCompartmentPhaseImpl(args) {
|
|
184168
184760
|
let pendingCompartmentInjection = args.pendingCompartmentInjection;
|
|
184169
184761
|
let compartmentInProgress = args.sessionMeta.compartmentInProgress;
|
|
184170
184762
|
let published = false;
|
|
@@ -184461,78 +185053,11 @@ function appendReminderToUserMessage(message, reminder) {
|
|
|
184461
185053
|
|
|
184462
185054
|
// src/hooks/magic-context/apply-operations.ts
|
|
184463
185055
|
await init_storage();
|
|
184464
|
-
|
|
184465
|
-
// src/hooks/magic-context/system-injection-stripper.ts
|
|
184466
|
-
var SYSTEM_INJECTION_MARKERS = [
|
|
184467
|
-
"<!-- OMO_INTERNAL_INITIATOR -->",
|
|
184468
|
-
"[SYSTEM DIRECTIVE: MAGIC-CONTEXT",
|
|
184469
|
-
"[SYSTEM DIRECTIVE: OH-MY-OPENCODE",
|
|
184470
|
-
"[Category+Skill Reminder]",
|
|
184471
|
-
"[EDIT ERROR - IMMEDIATE ACTION REQUIRED]",
|
|
184472
|
-
"[task CALL FAILED - IMMEDIATE RETRY REQUIRED]",
|
|
184473
|
-
"[EMERGENCY CONTEXT WINDOW WARNING]",
|
|
184474
|
-
"Unstable background agent appears idle",
|
|
184475
|
-
"**THE SUBAGENT JUST CLAIMED THIS TASK IS DONE."
|
|
184476
|
-
];
|
|
184477
|
-
var SYSTEM_REMINDER_REGEX = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
|
|
184478
|
-
var OMO_MARKER_REGEX = /<!-- OMO_INTERNAL_INITIATOR -->/g;
|
|
184479
|
-
function stripSystemInjection(text) {
|
|
184480
|
-
let hasInjection = false;
|
|
184481
|
-
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
184482
|
-
if (text.includes(marker)) {
|
|
184483
|
-
hasInjection = true;
|
|
184484
|
-
break;
|
|
184485
|
-
}
|
|
184486
|
-
}
|
|
184487
|
-
if (SYSTEM_REMINDER_REGEX.test(text))
|
|
184488
|
-
hasInjection = true;
|
|
184489
|
-
SYSTEM_REMINDER_REGEX.lastIndex = 0;
|
|
184490
|
-
if (!hasInjection)
|
|
184491
|
-
return null;
|
|
184492
|
-
let cleaned = text;
|
|
184493
|
-
cleaned = cleaned.replace(SYSTEM_REMINDER_REGEX, "");
|
|
184494
|
-
cleaned = cleaned.replace(OMO_MARKER_REGEX, "");
|
|
184495
|
-
cleaned = cleaned.replace(/\[SYSTEM DIRECTIVE: OH-MY-(?:OPENCODE|CLAUDE)[^\]]*\][\s\S]*?(?=\n\n(?!\s*[-*])|$)/g, "");
|
|
184496
|
-
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
184497
|
-
if (marker.startsWith("<!-- ") || marker.startsWith("[SYSTEM DIRECTIVE"))
|
|
184498
|
-
continue;
|
|
184499
|
-
const idx = cleaned.indexOf(marker);
|
|
184500
|
-
if (idx === -1)
|
|
184501
|
-
continue;
|
|
184502
|
-
const blockEnd = cleaned.indexOf(`
|
|
184503
|
-
|
|
184504
|
-
`, idx + marker.length);
|
|
184505
|
-
cleaned = blockEnd !== -1 ? cleaned.slice(0, idx) + cleaned.slice(blockEnd) : cleaned.slice(0, idx);
|
|
184506
|
-
}
|
|
184507
|
-
return cleaned.trim();
|
|
184508
|
-
}
|
|
184509
|
-
|
|
184510
|
-
// src/hooks/magic-context/apply-operations.ts
|
|
184511
|
-
init_tag_part_guards();
|
|
184512
|
-
var USER_DROP_PREVIEW_CHARS = 250;
|
|
184513
185056
|
var RECENT_TOOL_SKELETON_WINDOW = 20;
|
|
184514
|
-
function buildReplacementContent(tagId
|
|
184515
|
-
|
|
184516
|
-
|
|
184517
|
-
|
|
184518
|
-
}
|
|
184519
|
-
const currentContent = target.getContent?.() ?? "";
|
|
184520
|
-
const strippedInjection = stripSystemInjection(currentContent);
|
|
184521
|
-
if (strippedInjection !== null && stripTagPrefix(strippedInjection).trim().length === 0) {
|
|
184522
|
-
return `[dropped §${tagId}§]`;
|
|
184523
|
-
}
|
|
184524
|
-
const originalText = stripTagPrefix(currentContent);
|
|
184525
|
-
if (originalText.length <= USER_DROP_PREVIEW_CHARS) {
|
|
184526
|
-
return `[truncated §${tagId}§]
|
|
184527
|
-
${originalText}`;
|
|
184528
|
-
}
|
|
184529
|
-
const hardCut = originalText.slice(0, USER_DROP_PREVIEW_CHARS);
|
|
184530
|
-
const softCutIndex = hardCut.search(/\s\S*$/);
|
|
184531
|
-
const preview = softCutIndex > USER_DROP_PREVIEW_CHARS - 30 ? hardCut.slice(0, softCutIndex) : hardCut;
|
|
184532
|
-
return `[truncated §${tagId}§]
|
|
184533
|
-
${preview}…`;
|
|
184534
|
-
}
|
|
184535
|
-
function applyPendingOperations(sessionId, db, targets, protectedTags = 0, preloadedTags, preloadedPendingOps) {
|
|
185057
|
+
function buildReplacementContent(tagId) {
|
|
185058
|
+
return `[dropped §${tagId}§]`;
|
|
185059
|
+
}
|
|
185060
|
+
function applyPendingOperations(sessionId, db, targets, protectedTags = 0, preloadedTags, preloadedPendingOps, syntheticPendingOps = []) {
|
|
184536
185061
|
let didMutateMessage = false;
|
|
184537
185062
|
db.transaction(() => {
|
|
184538
185063
|
const tags = preloadedTags ?? getTagsBySession(db, sessionId);
|
|
@@ -184540,11 +185065,16 @@ function applyPendingOperations(sessionId, db, targets, protectedTags = 0, prelo
|
|
|
184540
185065
|
const tagTypeById = new Map(tags.map((tag) => [tag.tagNumber, tag.type]));
|
|
184541
185066
|
const protectedTagIds = protectedTags > 0 ? new Set(tags.filter((tag) => tag.status === "active").map((tag) => tag.tagNumber).sort((left, right) => right - left).slice(0, protectedTags)) : new Set;
|
|
184542
185067
|
const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
|
|
185068
|
+
const opsToApply = [
|
|
185069
|
+
...pendingOps.map((op) => ({ op, synthetic: false })),
|
|
185070
|
+
...syntheticPendingOps.map((op) => ({ op, synthetic: true }))
|
|
185071
|
+
];
|
|
184543
185072
|
const skeletonWindow = new Set(tags.filter((tag) => tag.type === "tool").map((tag) => tag.tagNumber).sort((left, right) => right - left).slice(0, RECENT_TOOL_SKELETON_WINDOW));
|
|
184544
|
-
for (const pendingOp of
|
|
185073
|
+
for (const { op: pendingOp, synthetic } of opsToApply) {
|
|
184545
185074
|
const tagStatus = tagStatusById.get(pendingOp.tagId);
|
|
184546
185075
|
if (tagStatus === "compacted" || tagStatus === "dropped") {
|
|
184547
|
-
|
|
185076
|
+
if (!synthetic)
|
|
185077
|
+
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
184548
185078
|
continue;
|
|
184549
185079
|
}
|
|
184550
185080
|
if (protectedTagIds.has(pendingOp.tagId)) {
|
|
@@ -184552,33 +185082,46 @@ function applyPendingOperations(sessionId, db, targets, protectedTags = 0, prelo
|
|
|
184552
185082
|
}
|
|
184553
185083
|
const target = targets.get(pendingOp.tagId);
|
|
184554
185084
|
const isToolTag = tagTypeById.get(pendingOp.tagId) === "tool";
|
|
185085
|
+
if (synthetic) {
|
|
185086
|
+
if (!isToolTag || target?.canDrop?.() !== true)
|
|
185087
|
+
continue;
|
|
185088
|
+
}
|
|
185089
|
+
let shouldPersistDrop = false;
|
|
184555
185090
|
if (isToolTag) {
|
|
184556
185091
|
if (skeletonWindow.has(pendingOp.tagId)) {
|
|
184557
185092
|
const truncResult = target?.truncate?.() ?? "absent";
|
|
184558
|
-
if (truncResult === "incomplete") {
|
|
185093
|
+
if (truncResult === "incomplete" || synthetic && truncResult !== "truncated") {
|
|
184559
185094
|
continue;
|
|
184560
185095
|
}
|
|
184561
185096
|
if (truncResult === "truncated") {
|
|
184562
185097
|
didMutateMessage = true;
|
|
184563
185098
|
}
|
|
184564
185099
|
updateTagDropMode(db, sessionId, pendingOp.tagId, "truncated");
|
|
185100
|
+
shouldPersistDrop = true;
|
|
184565
185101
|
} else {
|
|
184566
185102
|
const dropResult = target?.drop?.() ?? "absent";
|
|
184567
|
-
if (dropResult === "incomplete") {
|
|
185103
|
+
if (dropResult === "incomplete" || synthetic && dropResult !== "removed") {
|
|
184568
185104
|
continue;
|
|
184569
185105
|
}
|
|
184570
185106
|
if (dropResult === "removed") {
|
|
184571
185107
|
didMutateMessage = true;
|
|
184572
185108
|
}
|
|
184573
185109
|
updateTagDropMode(db, sessionId, pendingOp.tagId, "full");
|
|
185110
|
+
shouldPersistDrop = true;
|
|
184574
185111
|
}
|
|
184575
185112
|
} else if (target) {
|
|
184576
|
-
const changed = target.setContent(buildReplacementContent(pendingOp.tagId
|
|
185113
|
+
const changed = target.setContent(buildReplacementContent(pendingOp.tagId));
|
|
184577
185114
|
if (changed)
|
|
184578
185115
|
didMutateMessage = true;
|
|
185116
|
+
shouldPersistDrop = true;
|
|
185117
|
+
} else if (!synthetic) {
|
|
185118
|
+
shouldPersistDrop = true;
|
|
184579
185119
|
}
|
|
185120
|
+
if (!shouldPersistDrop)
|
|
185121
|
+
continue;
|
|
184580
185122
|
updateTagStatus(db, sessionId, pendingOp.tagId, "dropped");
|
|
184581
|
-
|
|
185123
|
+
if (!synthetic)
|
|
185124
|
+
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
184582
185125
|
}
|
|
184583
185126
|
})();
|
|
184584
185127
|
return didMutateMessage;
|
|
@@ -184602,7 +185145,7 @@ function applyFlushedStatuses(sessionId, db, targets, preloadedTags) {
|
|
|
184602
185145
|
}
|
|
184603
185146
|
}
|
|
184604
185147
|
} else if (target) {
|
|
184605
|
-
const changed = target.setContent(buildReplacementContent(tag.tagNumber
|
|
185148
|
+
const changed = target.setContent(buildReplacementContent(tag.tagNumber));
|
|
184606
185149
|
if (changed)
|
|
184607
185150
|
didMutateMessage = true;
|
|
184608
185151
|
}
|
|
@@ -184779,6 +185322,7 @@ function createExistingTagResolver(sessionId, tagger, db) {
|
|
|
184779
185322
|
return;
|
|
184780
185323
|
}
|
|
184781
185324
|
updateTagMessageId(db, sessionId, fallback.tagNumber, currentContentId);
|
|
185325
|
+
tagger.unbindTag(sessionId, fallback.contentId);
|
|
184782
185326
|
tagger.bindTag(sessionId, currentContentId, fallback.tagNumber);
|
|
184783
185327
|
usedTagNumbers.add(fallback.tagNumber);
|
|
184784
185328
|
return fallback.tagNumber;
|
|
@@ -184799,7 +185343,45 @@ function logTransformTiming(sessionId, stage, startMs, extra) {
|
|
|
184799
185343
|
}
|
|
184800
185344
|
|
|
184801
185345
|
// src/hooks/magic-context/tag-messages.ts
|
|
184802
|
-
|
|
185346
|
+
var TOOL_OWNER_CACHE_KEY_SEP = "\x00";
|
|
185347
|
+
function makeToolOwnerCacheKey(sessionId, callId) {
|
|
185348
|
+
return `${sessionId}${TOOL_OWNER_CACHE_KEY_SEP}${callId}`;
|
|
185349
|
+
}
|
|
185350
|
+
function getCachedCandidateToolOwners(db, sessionId, callId, cache, onLookup) {
|
|
185351
|
+
const key = makeToolOwnerCacheKey(sessionId, callId);
|
|
185352
|
+
const cached2 = cache.candidateOwnersByCallId.get(key);
|
|
185353
|
+
if (cached2 !== undefined)
|
|
185354
|
+
return cached2;
|
|
185355
|
+
onLookup?.({ kind: "candidates", callId });
|
|
185356
|
+
const candidates = getCandidateToolOwners(db, sessionId, callId);
|
|
185357
|
+
cache.candidateOwnersByCallId.set(key, candidates);
|
|
185358
|
+
return candidates;
|
|
185359
|
+
}
|
|
185360
|
+
function getCachedMessageTimesFromOpenCodeDb(sessionId, messageIds, cache, onLookup) {
|
|
185361
|
+
const uncached = [...new Set(messageIds)].filter((id) => !cache.messageTimesById.has(id));
|
|
185362
|
+
if (uncached.length > 0) {
|
|
185363
|
+
onLookup?.({ kind: "messageTimes", messageIds: uncached });
|
|
185364
|
+
const resolved = getMessageTimesFromOpenCodeDb(sessionId, uncached);
|
|
185365
|
+
for (const id of uncached) {
|
|
185366
|
+
cache.messageTimesById.set(id, resolved.get(id) ?? null);
|
|
185367
|
+
}
|
|
185368
|
+
}
|
|
185369
|
+
const times = new Map;
|
|
185370
|
+
for (const id of messageIds) {
|
|
185371
|
+
const time3 = cache.messageTimesById.get(id);
|
|
185372
|
+
if (typeof time3 === "number")
|
|
185373
|
+
times.set(id, time3);
|
|
185374
|
+
}
|
|
185375
|
+
return times;
|
|
185376
|
+
}
|
|
185377
|
+
function invalidateCachedCandidateToolOwnersIfNewOwner(cache, sessionId, callId, ownerMsgId) {
|
|
185378
|
+
const key = makeToolOwnerCacheKey(sessionId, callId);
|
|
185379
|
+
const cached2 = cache.candidateOwnersByCallId.get(key);
|
|
185380
|
+
if (cached2 !== undefined && !cached2.includes(ownerMsgId)) {
|
|
185381
|
+
cache.candidateOwnersByCallId.delete(key);
|
|
185382
|
+
}
|
|
185383
|
+
}
|
|
185384
|
+
function deriveToolOwnerMessageId(sessionId, db, message, obs, unpaired, cache, onFallbackLookup) {
|
|
184803
185385
|
const messageId = typeof message.info.id === "string" ? message.info.id : "";
|
|
184804
185386
|
if (obs.kind === "invocation") {
|
|
184805
185387
|
if (messageId) {
|
|
@@ -184819,10 +185401,10 @@ function deriveToolOwnerMessageId(sessionId, db, message, obs, unpaired) {
|
|
|
184819
185401
|
return popped;
|
|
184820
185402
|
}
|
|
184821
185403
|
if (messageId) {
|
|
184822
|
-
const candidates =
|
|
185404
|
+
const candidates = getCachedCandidateToolOwners(db, sessionId, obs.callId, cache, onFallbackLookup);
|
|
184823
185405
|
if (candidates.length > 0) {
|
|
184824
185406
|
const ids = [...candidates, messageId];
|
|
184825
|
-
const times =
|
|
185407
|
+
const times = getCachedMessageTimesFromOpenCodeDb(sessionId, ids, cache, onFallbackLookup);
|
|
184826
185408
|
const persisted = pickNearestPriorOwner(candidates, messageId, times);
|
|
184827
185409
|
if (persisted !== null)
|
|
184828
185410
|
return persisted;
|
|
@@ -184903,6 +185485,7 @@ function extractToolTagMetadata(part) {
|
|
|
184903
185485
|
}
|
|
184904
185486
|
function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
184905
185487
|
const skipPrefixInjection = options.skipPrefixInjection === true;
|
|
185488
|
+
const onToolOwnerFallbackLookup = options.onToolOwnerFallbackLookup;
|
|
184906
185489
|
const targets = new Map;
|
|
184907
185490
|
const reasoningByMessage = new Map;
|
|
184908
185491
|
const messageTagNumbers = new Map;
|
|
@@ -184910,6 +185493,10 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
184910
185493
|
const toolThinkingByCallId = new Map;
|
|
184911
185494
|
const toolCallIndex = new Map;
|
|
184912
185495
|
const unpairedInvocations = new Map;
|
|
185496
|
+
const ownerDerivationCache = {
|
|
185497
|
+
candidateOwnersByCallId: new Map,
|
|
185498
|
+
messageTimesById: new Map
|
|
185499
|
+
};
|
|
184913
185500
|
const ownerByPartKey = new Map;
|
|
184914
185501
|
const batch = new ToolMutationBatch(messages);
|
|
184915
185502
|
const assignments = tagger.getAssignments(sessionId);
|
|
@@ -184950,7 +185537,7 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
184950
185537
|
const toolObservation = extractToolCallObservation(part);
|
|
184951
185538
|
if (toolObservation) {
|
|
184952
185539
|
const _tDerive = performance.now();
|
|
184953
|
-
const ownerMsgId = deriveToolOwnerMessageId(sessionId, db, message, toolObservation, unpairedInvocations);
|
|
185540
|
+
const ownerMsgId = deriveToolOwnerMessageId(sessionId, db, message, toolObservation, unpairedInvocations, ownerDerivationCache, onToolOwnerFallbackLookup);
|
|
184954
185541
|
accDerive += performance.now() - _tDerive;
|
|
184955
185542
|
const compositeKey = makeToolCompositeKey(ownerMsgId, toolObservation.callId);
|
|
184956
185543
|
const entry = toolCallIndex.get(compositeKey) ?? {
|
|
@@ -184969,6 +185556,7 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
184969
185556
|
if (orphan !== null) {
|
|
184970
185557
|
const claimed = adoptNullOwnerToolTag(db, orphan.id, ownerMsgId);
|
|
184971
185558
|
if (claimed) {
|
|
185559
|
+
invalidateCachedCandidateToolOwnersIfNewOwner(ownerDerivationCache, sessionId, toolObservation.callId, ownerMsgId);
|
|
184972
185560
|
tagger.bindToolTag(sessionId, toolObservation.callId, ownerMsgId, orphan.tagNumber);
|
|
184973
185561
|
existingTagId = orphan.tagNumber;
|
|
184974
185562
|
} else {
|
|
@@ -184976,6 +185564,13 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
184976
185564
|
}
|
|
184977
185565
|
}
|
|
184978
185566
|
}
|
|
185567
|
+
if (existingTagId === undefined) {
|
|
185568
|
+
const persisted = getToolTagNumberByOwner(db, sessionId, toolObservation.callId, ownerMsgId);
|
|
185569
|
+
if (persisted !== null) {
|
|
185570
|
+
tagger.bindToolTag(sessionId, toolObservation.callId, ownerMsgId, persisted);
|
|
185571
|
+
existingTagId = persisted;
|
|
185572
|
+
}
|
|
185573
|
+
}
|
|
184979
185574
|
if (existingTagId !== undefined) {
|
|
184980
185575
|
toolTagByCallId.set(compositeKey, existingTagId);
|
|
184981
185576
|
messageTagNumbers.set(message, Math.max(messageTagNumbers.get(message) ?? 0, existingTagId));
|
|
@@ -185048,6 +185643,7 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
185048
185643
|
inputTokenCount,
|
|
185049
185644
|
reasoningTokenCount: reasoningTokens
|
|
185050
185645
|
}));
|
|
185646
|
+
invalidateCachedCandidateToolOwnersIfNewOwner(ownerDerivationCache, sessionId, toolPart.callID, ownerMsgId);
|
|
185051
185647
|
accAssignToolTag += performance.now() - _tAssignTool;
|
|
185052
185648
|
messageTagNumbers.set(message, Math.max(messageTagNumbers.get(message) ?? 0, tagId));
|
|
185053
185649
|
if (!skipPrefixInjection) {
|
|
@@ -185119,7 +185715,7 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
185119
185715
|
logTransformTiming(sessionId, "tag.saveSource", performance.now() - accSaveSource);
|
|
185120
185716
|
for (const [compositeKey, tagId] of toolTagByCallId) {
|
|
185121
185717
|
const thinkingParts = toolThinkingByCallId.get(compositeKey) ?? [];
|
|
185122
|
-
targets.set(tagId, createToolDropTarget(compositeKey, thinkingParts, toolCallIndex, batch));
|
|
185718
|
+
targets.set(tagId, createToolDropTarget(compositeKey, thinkingParts, toolCallIndex, batch, tagId));
|
|
185123
185719
|
}
|
|
185124
185720
|
const hasRecentReduceCall = lastReduceMessageIndex >= 0 && messages.length - lastReduceMessageIndex <= RECENT_REDUCE_LOOKBACK;
|
|
185125
185721
|
return {
|
|
@@ -186046,7 +186642,7 @@ async function runAutoSearchHint(args) {
|
|
|
186046
186642
|
embeddingEnabled,
|
|
186047
186643
|
gitCommitsEnabled,
|
|
186048
186644
|
embedQuery: async (text, signal) => {
|
|
186049
|
-
const result = await embedTextForProject(options.projectPath, text, signal);
|
|
186645
|
+
const result = await embedTextForProject(options.projectPath, text, signal, "query");
|
|
186050
186646
|
return result?.vector ?? null;
|
|
186051
186647
|
},
|
|
186052
186648
|
isEmbeddingRuntimeEnabled: () => embeddingEnabled === true,
|
|
@@ -186227,6 +186823,51 @@ function planEmergencyDrop(input) {
|
|
|
186227
186823
|
};
|
|
186228
186824
|
}
|
|
186229
186825
|
|
|
186826
|
+
// src/hooks/magic-context/system-injection-stripper.ts
|
|
186827
|
+
var SYSTEM_INJECTION_MARKERS = [
|
|
186828
|
+
"<!-- OMO_INTERNAL_INITIATOR -->",
|
|
186829
|
+
"[SYSTEM DIRECTIVE: MAGIC-CONTEXT",
|
|
186830
|
+
"[SYSTEM DIRECTIVE: OH-MY-OPENCODE",
|
|
186831
|
+
"[Category+Skill Reminder]",
|
|
186832
|
+
"[EDIT ERROR - IMMEDIATE ACTION REQUIRED]",
|
|
186833
|
+
"[task CALL FAILED - IMMEDIATE RETRY REQUIRED]",
|
|
186834
|
+
"[EMERGENCY CONTEXT WINDOW WARNING]",
|
|
186835
|
+
"Unstable background agent appears idle",
|
|
186836
|
+
"**THE SUBAGENT JUST CLAIMED THIS TASK IS DONE."
|
|
186837
|
+
];
|
|
186838
|
+
var SYSTEM_REMINDER_REGEX = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
|
|
186839
|
+
var OMO_MARKER_REGEX = /<!-- OMO_INTERNAL_INITIATOR -->/g;
|
|
186840
|
+
function stripSystemInjection(text) {
|
|
186841
|
+
let hasInjection = false;
|
|
186842
|
+
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
186843
|
+
if (text.includes(marker)) {
|
|
186844
|
+
hasInjection = true;
|
|
186845
|
+
break;
|
|
186846
|
+
}
|
|
186847
|
+
}
|
|
186848
|
+
if (SYSTEM_REMINDER_REGEX.test(text))
|
|
186849
|
+
hasInjection = true;
|
|
186850
|
+
SYSTEM_REMINDER_REGEX.lastIndex = 0;
|
|
186851
|
+
if (!hasInjection)
|
|
186852
|
+
return null;
|
|
186853
|
+
let cleaned = text;
|
|
186854
|
+
cleaned = cleaned.replace(SYSTEM_REMINDER_REGEX, "");
|
|
186855
|
+
cleaned = cleaned.replace(OMO_MARKER_REGEX, "");
|
|
186856
|
+
cleaned = cleaned.replace(/\[SYSTEM DIRECTIVE: OH-MY-(?:OPENCODE|CLAUDE)[^\]]*\][\s\S]*?(?=\n\n(?!\s*[-*])|$)/g, "");
|
|
186857
|
+
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
186858
|
+
if (marker.startsWith("<!-- ") || marker.startsWith("[SYSTEM DIRECTIVE"))
|
|
186859
|
+
continue;
|
|
186860
|
+
const idx = cleaned.indexOf(marker);
|
|
186861
|
+
if (idx === -1)
|
|
186862
|
+
continue;
|
|
186863
|
+
const blockEnd = cleaned.indexOf(`
|
|
186864
|
+
|
|
186865
|
+
`, idx + marker.length);
|
|
186866
|
+
cleaned = blockEnd !== -1 ? cleaned.slice(0, idx) + cleaned.slice(blockEnd) : cleaned.slice(0, idx);
|
|
186867
|
+
}
|
|
186868
|
+
return cleaned.trim();
|
|
186869
|
+
}
|
|
186870
|
+
|
|
186230
186871
|
// src/hooks/magic-context/heuristic-cleanup.ts
|
|
186231
186872
|
init_tag_part_guards();
|
|
186232
186873
|
var DEDUP_SAFE_TOOLS = new Set([
|
|
@@ -186245,6 +186886,7 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
186245
186886
|
const maxTag = getMaxTagNumberBySession(db, sessionId);
|
|
186246
186887
|
const protectedCutoff = maxTag - config2.protectedTags;
|
|
186247
186888
|
let droppedTools = 0;
|
|
186889
|
+
let emergencyDroppedTools = 0;
|
|
186248
186890
|
let deduplicatedTools = 0;
|
|
186249
186891
|
let droppedInjections = 0;
|
|
186250
186892
|
if (config2.emergency) {
|
|
@@ -186276,6 +186918,7 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
186276
186918
|
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
186277
186919
|
updateTagDropMode(db, sessionId, tag.tagNumber, "full");
|
|
186278
186920
|
droppedTools++;
|
|
186921
|
+
emergencyDroppedTools++;
|
|
186279
186922
|
}
|
|
186280
186923
|
}
|
|
186281
186924
|
setEmergencyDropSample(db, sessionId, emergency.currentTotalInputTokens);
|
|
@@ -186354,7 +186997,9 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
186354
186997
|
continue;
|
|
186355
186998
|
updateTagDropMode(db, sessionId, tag.tagNumber, "full");
|
|
186356
186999
|
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
186357
|
-
|
|
187000
|
+
if (result === "removed" || result === "truncated") {
|
|
187001
|
+
deduplicatedTools++;
|
|
187002
|
+
}
|
|
186358
187003
|
}
|
|
186359
187004
|
}
|
|
186360
187005
|
})();
|
|
@@ -186363,6 +187008,7 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
186363
187008
|
sessionLog(sessionId, `heuristic cleanup: dropped ${droppedTools} tool tags, deduplicated ${deduplicatedTools} tool calls, dropped ${droppedInjections} system injections`);
|
|
186364
187009
|
}
|
|
186365
187010
|
let compressedTextTags = 0;
|
|
187011
|
+
let mutatedTextTags = 0;
|
|
186366
187012
|
if (config2.caveman?.enabled) {
|
|
186367
187013
|
const cavemanResult = applyCavemanCleanup(sessionId, db, targets, tags, {
|
|
186368
187014
|
enabled: true,
|
|
@@ -186370,8 +187016,16 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
186370
187016
|
protectedTags: config2.protectedTags
|
|
186371
187017
|
});
|
|
186372
187018
|
compressedTextTags = cavemanResult.compressedToLite + cavemanResult.compressedToFull + cavemanResult.compressedToUltra;
|
|
187019
|
+
mutatedTextTags = cavemanResult.mutatedTextTags;
|
|
186373
187020
|
}
|
|
186374
|
-
return {
|
|
187021
|
+
return {
|
|
187022
|
+
droppedTools,
|
|
187023
|
+
deduplicatedTools,
|
|
187024
|
+
droppedInjections,
|
|
187025
|
+
emergencyDroppedTools,
|
|
187026
|
+
compressedTextTags,
|
|
187027
|
+
mutatedTextTags
|
|
187028
|
+
};
|
|
186375
187029
|
}
|
|
186376
187030
|
function extractToolInfo(part) {
|
|
186377
187031
|
if (part.type === "tool" && typeof part.tool === "string" && DEDUP_SAFE_TOOLS.has(part.tool)) {
|
|
@@ -186545,6 +187199,42 @@ function isTodoItem(value) {
|
|
|
186545
187199
|
return typeof todo.content === "string" && typeof todo.status === "string" && (todo.priority === undefined || typeof todo.priority === "string");
|
|
186546
187200
|
}
|
|
186547
187201
|
|
|
187202
|
+
// src/hooks/magic-context/tool-reclaim.ts
|
|
187203
|
+
await init_storage();
|
|
187204
|
+
function buildSyntheticToolReclaimOps(input) {
|
|
187205
|
+
const watermark = Math.max(0, input.watermark);
|
|
187206
|
+
if (watermark <= 0)
|
|
187207
|
+
return [];
|
|
187208
|
+
const realPendingTagIds = new Set((input.pendingOps ?? []).map((op) => op.tagId));
|
|
187209
|
+
const tags = getActiveTagsBySession(input.db, input.sessionId);
|
|
187210
|
+
const synthetic = [];
|
|
187211
|
+
for (const tag of tags) {
|
|
187212
|
+
if (tag.type !== "tool")
|
|
187213
|
+
continue;
|
|
187214
|
+
if (tag.status !== "active")
|
|
187215
|
+
continue;
|
|
187216
|
+
if (tag.tagNumber > watermark)
|
|
187217
|
+
continue;
|
|
187218
|
+
if (realPendingTagIds.has(tag.tagNumber))
|
|
187219
|
+
continue;
|
|
187220
|
+
if (input.targets.get(tag.tagNumber)?.canDrop?.() !== true)
|
|
187221
|
+
continue;
|
|
187222
|
+
synthetic.push({
|
|
187223
|
+
id: 0,
|
|
187224
|
+
sessionId: input.sessionId,
|
|
187225
|
+
tagId: tag.tagNumber,
|
|
187226
|
+
operation: "drop",
|
|
187227
|
+
queuedAt: 0
|
|
187228
|
+
});
|
|
187229
|
+
}
|
|
187230
|
+
return synthetic;
|
|
187231
|
+
}
|
|
187232
|
+
function advanceToolReclaimWatermarkToCurrentMax(db, sessionId) {
|
|
187233
|
+
const maxTagNumber = getMaxTagNumberBySession(db, sessionId);
|
|
187234
|
+
advanceToolReclaimWatermark(db, sessionId, maxTagNumber);
|
|
187235
|
+
return maxTagNumber;
|
|
187236
|
+
}
|
|
187237
|
+
|
|
186548
187238
|
// src/hooks/magic-context/transform-postprocess-phase.ts
|
|
186549
187239
|
var DEGRADE_CACHE_WARNING_THRESHOLD = 10;
|
|
186550
187240
|
var degradedCacheCountBySession = new BoundedSessionMap(100);
|
|
@@ -186561,7 +187251,6 @@ async function runPostTransformPhase(args) {
|
|
|
186561
187251
|
const emergencyDropEligible = args.contextUsage.percentage >= args.forceMaterializationPercentage;
|
|
186562
187252
|
const activeCompartmentRun = args.canRunCompartments ? getActiveCompartmentRun(args.sessionId) : undefined;
|
|
186563
187253
|
const compartmentRunning = args.canRunCompartments && !args.awaitedCompartmentRun && activeCompartmentRun !== undefined;
|
|
186564
|
-
const emergencyBypassCompartmentGate = forceMaterialization;
|
|
186565
187254
|
const deferredMaterialize = args.canConsumeDeferredLate && deferredMaterializationWasPending;
|
|
186566
187255
|
const materializationRequested = isExplicitFlush || deferredMaterialize;
|
|
186567
187256
|
const m0M1EnabledForFold = args.fullFeatureMode && args.m0M1 !== undefined && (!!args.m0M1.projectPath || !!args.m0M1.projectDirectory);
|
|
@@ -186573,11 +187262,12 @@ async function runPostTransformPhase(args) {
|
|
|
186573
187262
|
projectDirectory: args.m0M1.projectDirectory,
|
|
186574
187263
|
hardSignals: args.m0M1.hardSignals
|
|
186575
187264
|
}).value : false;
|
|
187265
|
+
const bypassCompartmentGate = forceMaterialization || m0HardFoldThisPass;
|
|
186576
187266
|
const shouldReadPendingOps = materializationRequested || args.schedulerDecision === "execute" || forceMaterialization || m0HardFoldThisPass || compartmentRunning;
|
|
186577
187267
|
const pendingOps = shouldReadPendingOps ? getPendingOps(args.db, args.sessionId) : [];
|
|
186578
187268
|
const hasPendingUserOps = pendingOps.length > 0;
|
|
186579
|
-
const shouldApplyPendingOps = (args.schedulerDecision === "execute" || materializationRequested || forceMaterialization || m0HardFoldThisPass) && (!compartmentRunning ||
|
|
186580
|
-
const shouldRunHeuristics = (!compartmentRunning ||
|
|
187269
|
+
const shouldApplyPendingOps = (args.schedulerDecision === "execute" || materializationRequested || forceMaterialization || m0HardFoldThisPass) && (!compartmentRunning || bypassCompartmentGate);
|
|
187270
|
+
const shouldRunHeuristics = (!compartmentRunning || bypassCompartmentGate) && (materializationRequested || forceMaterialization || m0HardFoldThisPass || emergencyDropEligible || args.schedulerDecision === "execute" && (!alreadyRanThisTurn || !args.fullFeatureMode));
|
|
186581
187271
|
const isCacheBustingPass = shouldApplyPendingOps || shouldRunHeuristics;
|
|
186582
187272
|
const canUseEmptySentinels = modelAcceptsEmptyContent(args.resolvedProviderID);
|
|
186583
187273
|
if (shouldRunHeuristics) {
|
|
@@ -186589,8 +187279,9 @@ async function runPostTransformPhase(args) {
|
|
|
186589
187279
|
sessionLog(args.sessionId, `transform: skipping heuristics (already ran for turn ${args.currentTurnId})`);
|
|
186590
187280
|
}
|
|
186591
187281
|
if (compartmentRunning && hasPendingUserOps) {
|
|
186592
|
-
if (
|
|
186593
|
-
|
|
187282
|
+
if (bypassCompartmentGate) {
|
|
187283
|
+
const bypassReason = forceMaterialization ? "emergency >=85%" : "m0 hard fold";
|
|
187284
|
+
sessionLog(args.sessionId, `transform: compartment-gate bypass (${bypassReason}) — applying ${pendingOps.length} pending ops while compartment agent runs (${args.contextUsage.percentage.toFixed(1)}%)`);
|
|
186594
187285
|
} else {
|
|
186595
187286
|
sessionLog(args.sessionId, "transform: deferring pending ops — compartment agent in progress");
|
|
186596
187287
|
}
|
|
@@ -186599,12 +187290,24 @@ async function runPostTransformPhase(args) {
|
|
|
186599
187290
|
let deferredMaterializedSuccessfully = false;
|
|
186600
187291
|
let heuristicsRanSuccessfully = false;
|
|
186601
187292
|
let pendingOpsRanSuccessfully = false;
|
|
187293
|
+
let pendingOpsDidMutate = false;
|
|
187294
|
+
let heuristicOrReasoningDidMutate = false;
|
|
187295
|
+
let droppedCount = 0;
|
|
187296
|
+
const droppedTokens = 0;
|
|
187297
|
+
let emergency = false;
|
|
187298
|
+
let m0RematerializedThisPass = false;
|
|
187299
|
+
let m0MaterializeReason = null;
|
|
187300
|
+
let m0M1InjectedThisPass = false;
|
|
187301
|
+
let autoReclaimDidMutateThisPass = false;
|
|
186602
187302
|
try {
|
|
186603
187303
|
if (shouldApplyPendingOps) {
|
|
186604
187304
|
const applyReason = isExplicitFlush ? "explicit_flush" : deferredMaterialize ? "deferred_materialization" : `scheduler_execute (scheduler=${args.schedulerDecision})`;
|
|
186605
187305
|
sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${pendingOps.length}, context=${args.contextUsage.percentage.toFixed(1)}%`);
|
|
186606
187306
|
const tApply = performance.now();
|
|
186607
|
-
applyPendingOperations(args.sessionId, args.db, args.targets, args.protectedTags, undefined, pendingOps);
|
|
187307
|
+
pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, args.targets, args.protectedTags, undefined, pendingOps);
|
|
187308
|
+
if (pendingOpsDidMutate) {
|
|
187309
|
+
droppedCount += pendingOps.length;
|
|
187310
|
+
}
|
|
186608
187311
|
logTransformTiming(args.sessionId, "applyPendingOperations", tApply);
|
|
186609
187312
|
}
|
|
186610
187313
|
if (shouldRunHeuristics) {
|
|
@@ -186622,9 +187325,12 @@ async function runPostTransformPhase(args) {
|
|
|
186622
187325
|
} : undefined,
|
|
186623
187326
|
caveman: cavemanConfig
|
|
186624
187327
|
}, heuristicTags);
|
|
186625
|
-
logTransformTiming(args.sessionId, "applyHeuristicCleanup", t5, `droppedTools=${cleanup.droppedTools} deduplicatedTools=${cleanup.deduplicatedTools} droppedInjections=${cleanup.droppedInjections} compressedTextTags=${cleanup.compressedTextTags}`);
|
|
187328
|
+
logTransformTiming(args.sessionId, "applyHeuristicCleanup", t5, `droppedTools=${cleanup.droppedTools} deduplicatedTools=${cleanup.deduplicatedTools} droppedInjections=${cleanup.droppedInjections} compressedTextTags=${cleanup.compressedTextTags} mutatedTextTags=${cleanup.mutatedTextTags}`);
|
|
187329
|
+
const heuristicMutationCount = cleanup.droppedTools + cleanup.deduplicatedTools + cleanup.droppedInjections + cleanup.mutatedTextTags;
|
|
187330
|
+
droppedCount += cleanup.droppedTools + cleanup.deduplicatedTools + cleanup.droppedInjections + cleanup.mutatedTextTags;
|
|
187331
|
+
emergency ||= cleanup.emergencyDroppedTools > 0;
|
|
186626
187332
|
const t7 = performance.now();
|
|
186627
|
-
const clearedReasoning = clearOldReasoning(args.messages, args.reasoningByMessage, args.messageTagNumbers, args.clearReasoningAge);
|
|
187333
|
+
const clearedReasoning = canUseEmptySentinels ? clearOldReasoning(args.messages, args.reasoningByMessage, args.messageTagNumbers, args.clearReasoningAge) : 0;
|
|
186628
187334
|
if (canUseEmptySentinels) {
|
|
186629
187335
|
stripClearedReasoning(args.messages);
|
|
186630
187336
|
}
|
|
@@ -186648,6 +187354,8 @@ async function runPostTransformPhase(args) {
|
|
|
186648
187354
|
}
|
|
186649
187355
|
}
|
|
186650
187356
|
logTransformTiming(args.sessionId, "clearOldReasoning", t7);
|
|
187357
|
+
heuristicOrReasoningDidMutate = heuristicMutationCount + clearedReasoning + strippedInline > 0;
|
|
187358
|
+
droppedCount += clearedReasoning + strippedInline;
|
|
186651
187359
|
if (pendingMaterializationAtPassStart) {
|
|
186652
187360
|
args.pendingMaterializationSessions.delete(args.sessionId);
|
|
186653
187361
|
}
|
|
@@ -186658,7 +187366,35 @@ async function runPostTransformPhase(args) {
|
|
|
186658
187366
|
if (args.schedulerDecision === "execute" && !materializationRequested) {
|
|
186659
187367
|
updateSessionMeta(args.db, args.sessionId, { lastResponseTime: Date.now() });
|
|
186660
187368
|
}
|
|
187369
|
+
const toolReclaimExecutePass = args.schedulerDecision === "execute";
|
|
187370
|
+
const alreadyMutatingThisPass = pendingOpsDidMutate || heuristicOrReasoningDidMutate;
|
|
187371
|
+
let autoReclaimTargetCount = 0;
|
|
187372
|
+
let autoReclaimDidMutate = false;
|
|
187373
|
+
if (toolReclaimExecutePass && alreadyMutatingThisPass && !emergencyDropEligible) {
|
|
187374
|
+
const syntheticPendingOps = buildSyntheticToolReclaimOps({
|
|
187375
|
+
db: args.db,
|
|
187376
|
+
sessionId: args.sessionId,
|
|
187377
|
+
targets: args.targets,
|
|
187378
|
+
watermark: args.sessionMeta.toolReclaimWatermark ?? 0,
|
|
187379
|
+
pendingOps
|
|
187380
|
+
});
|
|
187381
|
+
autoReclaimTargetCount = syntheticPendingOps.length;
|
|
187382
|
+
if (syntheticPendingOps.length > 0) {
|
|
187383
|
+
autoReclaimDidMutate = applyPendingOperations(args.sessionId, args.db, args.targets, args.protectedTags, undefined, [], syntheticPendingOps);
|
|
187384
|
+
if (autoReclaimDidMutate) {
|
|
187385
|
+
droppedCount += syntheticPendingOps.length;
|
|
187386
|
+
autoReclaimDidMutateThisPass = true;
|
|
187387
|
+
}
|
|
187388
|
+
}
|
|
187389
|
+
}
|
|
186661
187390
|
args.batch?.finalize();
|
|
187391
|
+
if (toolReclaimExecutePass) {
|
|
187392
|
+
const maxTagNumber = advanceToolReclaimWatermarkToCurrentMax(args.db, args.sessionId);
|
|
187393
|
+
args.sessionMeta.toolReclaimWatermark = Math.max(args.sessionMeta.toolReclaimWatermark ?? 0, maxTagNumber);
|
|
187394
|
+
}
|
|
187395
|
+
if (autoReclaimTargetCount > 0) {
|
|
187396
|
+
sessionLog(args.sessionId, `tool reclaim auto-drop: targets=${autoReclaimTargetCount} mutated=${autoReclaimDidMutate}`);
|
|
187397
|
+
}
|
|
186662
187398
|
logTransformTiming(args.sessionId, "batchFinalize:heuristics", performance.now());
|
|
186663
187399
|
if (args.sessionMeta.lastTransformError !== null) {
|
|
186664
187400
|
updateSessionMeta(args.db, args.sessionId, { lastTransformError: null });
|
|
@@ -186670,11 +187406,6 @@ async function runPostTransformPhase(args) {
|
|
|
186670
187406
|
deferredMaterializedSuccessfully = true;
|
|
186671
187407
|
heuristicsRanSuccessfully = true;
|
|
186672
187408
|
}
|
|
186673
|
-
if (args.watermark > 0) {
|
|
186674
|
-
const tWatermarkCleanup = performance.now();
|
|
186675
|
-
truncateErroredTools(args.messages, args.watermark, args.messageTagNumbers);
|
|
186676
|
-
logTransformTiming(args.sessionId, "watermarkCleanup", tWatermarkCleanup);
|
|
186677
|
-
}
|
|
186678
187409
|
if (shouldApplyPendingOps) {
|
|
186679
187410
|
pendingOpsRanSuccessfully = true;
|
|
186680
187411
|
}
|
|
@@ -186733,6 +187464,9 @@ async function runPostTransformPhase(args) {
|
|
|
186733
187464
|
hardSignals: args.m0M1.hardSignals
|
|
186734
187465
|
});
|
|
186735
187466
|
if (result.injected) {
|
|
187467
|
+
m0M1InjectedThisPass = true;
|
|
187468
|
+
m0RematerializedThisPass ||= result.m0RematerializedThisPass;
|
|
187469
|
+
m0MaterializeReason = result.decision.reason ?? m0MaterializeReason;
|
|
186736
187470
|
sessionLog(args.sessionId, `transform: injected m[0]/m[1] (rematerialized=${result.m0RematerializedThisPass}, reason=${result.decision.reason ?? "cache_hit"})`);
|
|
186737
187471
|
}
|
|
186738
187472
|
} catch (error51) {
|
|
@@ -186941,7 +187675,19 @@ async function runPostTransformPhase(args) {
|
|
|
186941
187675
|
sessionLog(args.sessionId, `sticky-injection GC: pruned ${prunedAnchors} note-nudge anchor(s), ${prunedDecisions} auto-search decision(s)`);
|
|
186942
187676
|
}
|
|
186943
187677
|
}
|
|
186944
|
-
|
|
187678
|
+
const materializeReason = m0MaterializeReason ?? (explicitMaterializedSuccessfully ? "explicit_flush" : null);
|
|
187679
|
+
const materialized = m0RematerializedThisPass || explicitMaterializedSuccessfully || deferredMaterializedSuccessfully;
|
|
187680
|
+
const bustedThisPass = args.didMutateFromFlushedStatuses || pendingOpsDidMutate || heuristicOrReasoningDidMutate || autoReclaimDidMutateThisPass || m0RematerializedThisPass || m0M1InjectedThisPass && historyWasConsumedThisPass || historyWasConsumedThisPass;
|
|
187681
|
+
return {
|
|
187682
|
+
explicitMaterializedSuccessfully,
|
|
187683
|
+
deferredMaterializedSuccessfully,
|
|
187684
|
+
materialized,
|
|
187685
|
+
materializeReason,
|
|
187686
|
+
droppedTokens,
|
|
187687
|
+
droppedCount,
|
|
187688
|
+
emergency,
|
|
187689
|
+
bustedThisPass
|
|
187690
|
+
};
|
|
186945
187691
|
}
|
|
186946
187692
|
function checkM0MutationDriftAndSignal(args) {
|
|
186947
187693
|
const currentMaxMutationId = getMaxM0MutationId(args.db, args.sessionId) ?? 0;
|
|
@@ -186976,6 +187722,12 @@ function clearMessageTokensCache(sessionId, messageId) {
|
|
|
186976
187722
|
cache.delete(messageId);
|
|
186977
187723
|
}
|
|
186978
187724
|
var recordedSessionProjectIdentity = new BoundedSessionMap(MESSAGE_TOKENS_CACHE_MAX);
|
|
187725
|
+
function deriveTaggerLoadFloor(messages, sessionId, db) {
|
|
187726
|
+
return deriveTagLoadFloor(db, sessionId, function* () {
|
|
187727
|
+
for (const message of messages)
|
|
187728
|
+
yield message.info?.id;
|
|
187729
|
+
}());
|
|
187730
|
+
}
|
|
186979
187731
|
function findLastAssistantModel2(messages) {
|
|
186980
187732
|
for (let i = messages.length - 1;i >= 0; i--) {
|
|
186981
187733
|
const info = messages[i].info;
|
|
@@ -186998,6 +187750,7 @@ function createTransform(deps) {
|
|
|
186998
187750
|
return;
|
|
186999
187751
|
}
|
|
187000
187752
|
const resolvedSessionId = sessionId;
|
|
187753
|
+
clearOpenCodePendingTransformDecision(sessionId);
|
|
187001
187754
|
logTransformTiming(sessionId, "findSessionId", startTime, `messages=${messages.length}`);
|
|
187002
187755
|
const db = deps.db;
|
|
187003
187756
|
if (deps.client !== undefined) {
|
|
@@ -187300,12 +188053,16 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
187300
188053
|
recordSessionProjectIdentity(db, sessionId, sessionProjectIdentity);
|
|
187301
188054
|
recordedSessionProjectIdentity.set(sessionId, sessionProjectIdentity);
|
|
187302
188055
|
}
|
|
188056
|
+
const taggerFloor = deriveTaggerLoadFloor(messages, sessionId, db);
|
|
188057
|
+
if (taggerFloor === 0 && messages.length > 0) {
|
|
188058
|
+
sessionLog(sessionId, `tag floor: 0 (full-scan fallback) — no leading wire message resolved a tag across ${messages.length} msgs`);
|
|
188059
|
+
}
|
|
187303
188060
|
let triggerBoundarySnapshot;
|
|
187304
188061
|
if (fullFeatureMode && historianRunnable && !sessionMeta.compartmentInProgress) {
|
|
187305
188062
|
const tTrigger = performance.now();
|
|
187306
188063
|
try {
|
|
187307
188064
|
const inMemoryTail = buildTriggerInMemoryTail(db, sessionId, extractInMemoryMessageViews(messages));
|
|
187308
|
-
const triggerResult = checkCompartmentTrigger(db, sessionId, sessionMeta, boundaryUsageForProtectedTail, sessionMeta.lastContextPercentage, boundaryExecuteThreshold, deriveTriggerBudget(boundaryContextLimit, boundaryExecuteThreshold), deps.clearReasoningAge, deps.commitClusterTrigger, undefined, boundaryContextLimit, inMemoryTail);
|
|
188065
|
+
const triggerResult = checkCompartmentTrigger(db, sessionId, sessionMeta, boundaryUsageForProtectedTail, sessionMeta.lastContextPercentage, boundaryExecuteThreshold, deriveTriggerBudget(boundaryContextLimit, boundaryExecuteThreshold), deps.clearReasoningAge, deps.commitClusterTrigger, undefined, boundaryContextLimit, inMemoryTail, taggerFloor);
|
|
187309
188066
|
if (triggerResult.shouldFire) {
|
|
187310
188067
|
sessionLog(sessionId, `compartment trigger: firing (reason=${triggerResult.reason})`);
|
|
187311
188068
|
updateSessionMeta(db, sessionId, { compartmentInProgress: true });
|
|
@@ -187347,7 +188104,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
187347
188104
|
try {
|
|
187348
188105
|
const t0 = performance.now();
|
|
187349
188106
|
const tInitFromDb = performance.now();
|
|
187350
|
-
deps.tagger.initFromDb(sessionId, db);
|
|
188107
|
+
deps.tagger.initFromDb(sessionId, db, taggerFloor);
|
|
187351
188108
|
logTransformTiming(sessionId, "tag.initFromDb", tInitFromDb);
|
|
187352
188109
|
const skipPrefixInjection = !ctxReduceEnabledEffective;
|
|
187353
188110
|
const result = tagMessages(sessionId, messages, deps.tagger, db, {
|
|
@@ -187399,7 +188156,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
187399
188156
|
const persistedReasoningWatermark = sessionMeta?.clearedReasoningThroughTag ?? 0;
|
|
187400
188157
|
if (persistedReasoningWatermark > 0) {
|
|
187401
188158
|
const tReplay = performance.now();
|
|
187402
|
-
const replayed = replayClearedReasoning(messages, reasoningByMessage, messageTagNumbers, persistedReasoningWatermark);
|
|
188159
|
+
const replayed = canUseEmptySentinels ? replayClearedReasoning(messages, reasoningByMessage, messageTagNumbers, persistedReasoningWatermark) : 0;
|
|
187403
188160
|
const replayedInline = replayStrippedInlineThinking(messages, messageTagNumbers, persistedReasoningWatermark);
|
|
187404
188161
|
if (replayed > 0 || replayedInline > 0) {
|
|
187405
188162
|
sessionLog(sessionId, `reasoning replay: cleared=${replayed} inlineStripped=${replayedInline} (watermark=${persistedReasoningWatermark})`);
|
|
@@ -187497,7 +188254,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
187497
188254
|
const wasEmergencyBlock = contextUsageEarly.percentage >= FORCE_MATERIALIZE_PERCENTAGE && compartmentPhase.justAwaitedPublication;
|
|
187498
188255
|
const historyRebuiltThisPass = wasEmergencyBlock ? compartmentPhase.rebuiltHistoryThisPass : rebuiltHistoryFromInitialPrepare || compartmentPhase.rebuiltHistoryThisPass;
|
|
187499
188256
|
const tPostProcess = performance.now();
|
|
187500
|
-
await runPostTransformPhase({
|
|
188257
|
+
const postTransformResult = await runPostTransformPhase({
|
|
187501
188258
|
sessionId,
|
|
187502
188259
|
db,
|
|
187503
188260
|
messages,
|
|
@@ -187551,6 +188308,19 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
187551
188308
|
hardSignals: m0HardSignals
|
|
187552
188309
|
}
|
|
187553
188310
|
});
|
|
188311
|
+
if (postTransformResult.bustedThisPass) {
|
|
188312
|
+
recordPendingTransformDecision(sessionId, {
|
|
188313
|
+
tsMs: Date.now(),
|
|
188314
|
+
decision: schedulerDecision,
|
|
188315
|
+
materialized: postTransformResult.materialized,
|
|
188316
|
+
materializeReason: normalizeMaterializeReason("opencode", postTransformResult.materializeReason, postTransformResult.materialized),
|
|
188317
|
+
emergency: postTransformResult.emergency,
|
|
188318
|
+
droppedTokens: postTransformResult.droppedTokens,
|
|
188319
|
+
droppedCount: postTransformResult.droppedCount,
|
|
188320
|
+
inputTokens: contextUsage.inputTokens,
|
|
188321
|
+
bustedThisPass: true
|
|
188322
|
+
});
|
|
188323
|
+
}
|
|
187554
188324
|
logTransformTiming(sessionId, "postTransformPhase", tPostProcess);
|
|
187555
188325
|
const msgTokens = getMessageTokensCache(sessionId);
|
|
187556
188326
|
let storedByMessage;
|
|
@@ -187701,6 +188471,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
187701
188471
|
const executeThresholdTokens = Math.round((resolvedContextLimit ?? 0) * resolvedExecuteThresholdPct / 100);
|
|
187702
188472
|
const usableTokens = Math.max(0, executeThresholdTokens - contextUsage.inputTokens + liveTailTokens);
|
|
187703
188473
|
resetLastNudgeCycleIfTailShrank(db, sessionId, tailToolTokens);
|
|
188474
|
+
const oldestReclaimableToolTags = getOldestActiveUnprotectedToolTags(db, sessionId, deps.protectedTags);
|
|
187704
188475
|
deps.channel1StateBySession.set(sessionId, {
|
|
187705
188476
|
tailToolTokens,
|
|
187706
188477
|
historyBudgetTokens: historyBudgetTokens ?? 0,
|
|
@@ -187709,9 +188480,10 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
187709
188480
|
lastInputTokens: contextUsage.inputTokens,
|
|
187710
188481
|
turnToolTokens: 0,
|
|
187711
188482
|
usableTokens,
|
|
187712
|
-
reducedSinceRefresh: false
|
|
188483
|
+
reducedSinceRefresh: false,
|
|
188484
|
+
oldestReclaimableToolTags
|
|
187713
188485
|
});
|
|
187714
|
-
const channel2MetricsKnown =
|
|
188486
|
+
const channel2MetricsKnown = resolvedContextLimit !== undefined && resolvedContextLimit > 0 && resolvedExecuteThresholdPct > 0;
|
|
187715
188487
|
if (channel2MetricsKnown) {
|
|
187716
188488
|
const channel2ShouldTrigger = shouldTriggerChannel2({
|
|
187717
188489
|
reclaimableTokens: tailToolTokens,
|
|
@@ -187735,6 +188507,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
187735
188507
|
}
|
|
187736
188508
|
const elapsed = (performance.now() - startTime).toFixed(1);
|
|
187737
188509
|
sessionLog(sessionId, `transform completed in ${elapsed}ms (${messages.length} messages, ${targets.size} targets, watermark: ${watermark})`);
|
|
188510
|
+
deps.maybeAutoEmbedSession?.(sessionId);
|
|
187738
188511
|
};
|
|
187739
188512
|
}
|
|
187740
188513
|
function resolveHistoryBudgetTokens(historyBudgetPercentage, contextUsage, executeThresholdPercentage, modelKey, executeThresholdTokens, resolvedContextLimit) {
|
|
@@ -187780,18 +188553,14 @@ function evictExpiredUsageEntries(contextUsageMap) {
|
|
|
187780
188553
|
}
|
|
187781
188554
|
async function deliverChannel2IfPending(deps, sessionId) {
|
|
187782
188555
|
try {
|
|
187783
|
-
try {
|
|
187784
|
-
const meta3 = getOrCreateSessionMeta(deps.db, sessionId);
|
|
187785
|
-
if (meta3.isSubagent)
|
|
187786
|
-
return;
|
|
187787
|
-
} catch {}
|
|
187788
188556
|
const baseline = deps.channel1StateBySession?.get(sessionId);
|
|
187789
188557
|
await maybeDeliverChannel2(sessionId, {
|
|
187790
188558
|
db: deps.db,
|
|
187791
188559
|
serverUrl: deps.serverUrl,
|
|
187792
188560
|
directory: deps.directory ?? ".",
|
|
187793
188561
|
reclaimableTokens: baseline ? baseline.tailToolTokens + baseline.turnToolTokens : undefined,
|
|
187794
|
-
usableTokens: baseline?.usableTokens
|
|
188562
|
+
usableTokens: baseline?.usableTokens,
|
|
188563
|
+
oldestReclaimableToolTags: baseline?.oldestReclaimableToolTags
|
|
187795
188564
|
});
|
|
187796
188565
|
} catch (error51) {
|
|
187797
188566
|
sessionLog(sessionId, "channel2 delivery wrapper failed (ignored):", error51);
|
|
@@ -187933,6 +188702,15 @@ function createEventHandler2(deps) {
|
|
|
187933
188702
|
info.tokens?.cache?.write
|
|
187934
188703
|
];
|
|
187935
188704
|
const hasUsageTokens = usageTokens.some((value) => typeof value === "number" && value > 0);
|
|
188705
|
+
const terminalAssistantUpdate = info.messageID !== undefined && hasUsageTokens && (typeof info.finish === "string" || typeof info.completedAt === "number");
|
|
188706
|
+
if (terminalAssistantUpdate && info.messageID) {
|
|
188707
|
+
scheduleOpenCodeTransformDecisionWrite({
|
|
188708
|
+
db: deps.db,
|
|
188709
|
+
sessionId: info.sessionID,
|
|
188710
|
+
messageId: info.messageID,
|
|
188711
|
+
inputTokens: (info.tokens?.input ?? 0) + (info.tokens?.cache?.read ?? 0) + (info.tokens?.cache?.write ?? 0)
|
|
188712
|
+
});
|
|
188713
|
+
}
|
|
187936
188714
|
sessionLog(info.sessionID, `event message.updated: provider=${info.providerID} model=${info.modelID} hasUsageTokens=${hasUsageTokens} tokens.input=${info.tokens?.input} cache.read=${info.tokens?.cache?.read} cache.write=${info.tokens?.cache?.write}`);
|
|
187937
188715
|
const hasKnownUsage = hasUsageTokens || deps.contextUsageMap.has(info.sessionID);
|
|
187938
188716
|
if (!hasKnownUsage) {
|
|
@@ -188090,6 +188868,7 @@ function createEventHandler2(deps) {
|
|
|
188090
188868
|
deps.onSessionDeleted?.(sessionId);
|
|
188091
188869
|
deps.contextUsageMap.delete(sessionId);
|
|
188092
188870
|
deps.tagger.cleanup(sessionId);
|
|
188871
|
+
clearTransformDecisionSession(sessionId);
|
|
188093
188872
|
clearMessageTokensCache(sessionId);
|
|
188094
188873
|
invalidateTrueRawTokenCache({ sessionId, reason: "session.deleted" });
|
|
188095
188874
|
return;
|
|
@@ -188097,6 +188876,46 @@ function createEventHandler2(deps) {
|
|
|
188097
188876
|
};
|
|
188098
188877
|
}
|
|
188099
188878
|
|
|
188879
|
+
// src/hooks/magic-context/format-embed-status.ts
|
|
188880
|
+
function formatEmbedStatusText(coverage, drain) {
|
|
188881
|
+
if (!coverage.enabled) {
|
|
188882
|
+
return "Embedding is off (no provider configured).";
|
|
188883
|
+
}
|
|
188884
|
+
const lines = [];
|
|
188885
|
+
lines.push(`Embedding — model: ${coverage.model} (${coverage.provider})`);
|
|
188886
|
+
lines.push(`This session: ${coverage.session.embedded} / ${coverage.session.total} compartments embedded`);
|
|
188887
|
+
lines.push(`Project memories: ${coverage.memories.embedded} / ${coverage.memories.total} embedded`);
|
|
188888
|
+
if (coverage.commits.gitEnabled) {
|
|
188889
|
+
lines.push(`Git commits: ${coverage.commits.embedded} / ${coverage.commits.total}`);
|
|
188890
|
+
} else {
|
|
188891
|
+
lines.push("Git commits: 0 / 0 (git indexing off)");
|
|
188892
|
+
}
|
|
188893
|
+
let drainLine = "Drain: idle";
|
|
188894
|
+
switch (drain.status) {
|
|
188895
|
+
case "running": {
|
|
188896
|
+
const e = drain.embedded ?? coverage.session.embedded;
|
|
188897
|
+
const t = drain.total ?? coverage.session.total;
|
|
188898
|
+
const failedSuffix = drain.failed && drain.failed > 0 ? ` (${drain.failed} failed)` : "";
|
|
188899
|
+
drainLine = `Drain: running ${e}/${t}${failedSuffix}`;
|
|
188900
|
+
break;
|
|
188901
|
+
}
|
|
188902
|
+
case "paused": {
|
|
188903
|
+
const e = drain.embedded ?? coverage.session.embedded;
|
|
188904
|
+
const t = drain.total ?? coverage.session.total;
|
|
188905
|
+
drainLine = `Drain: paused ${e}/${t}`;
|
|
188906
|
+
break;
|
|
188907
|
+
}
|
|
188908
|
+
case "stopped":
|
|
188909
|
+
drainLine = "Drain: stopped (provider down)";
|
|
188910
|
+
break;
|
|
188911
|
+
default:
|
|
188912
|
+
drainLine = "Drain: idle";
|
|
188913
|
+
}
|
|
188914
|
+
lines.push(drainLine);
|
|
188915
|
+
return lines.join(`
|
|
188916
|
+
`);
|
|
188917
|
+
}
|
|
188918
|
+
|
|
188100
188919
|
// src/hooks/magic-context/hook.ts
|
|
188101
188920
|
await __promiseAll([
|
|
188102
188921
|
init_inject_compartments(),
|
|
@@ -188338,7 +189157,7 @@ function maybeInjectChannel1Nudge(args, sessionId, tool, output) {
|
|
|
188338
189157
|
setLastNudgeLevel(args.db, sessionId, decision.nextLastNudgeLevel);
|
|
188339
189158
|
if (!decision.fire)
|
|
188340
189159
|
return;
|
|
188341
|
-
out.output += buildChannel1Reminder(decision.level, decision.undroppedTokens);
|
|
189160
|
+
out.output += buildChannel1Reminder(decision.level, decision.undroppedTokens, state.oldestReclaimableToolTags);
|
|
188342
189161
|
sessionLog(sessionId, `channel1 nudge fired: level=${decision.level} undropped~${Math.round(decision.undroppedTokens / 1000)}k tool=${tool}`);
|
|
188343
189162
|
}
|
|
188344
189163
|
function createToolExecuteAfterHook(args) {
|
|
@@ -188410,9 +189229,7 @@ Context is managed for you entirely automatically — there's nothing to prune a
|
|
|
188410
189229
|
var CTX_NOTE_GUIDANCE = `Use \`ctx_note\` ONLY for genuinely future concerns — something to revisit much later, not work coming up in the next few turns (that's already in your active context) and not active multi-step work (use todos for that). Magic Context preserves your full context across both compaction and restarts, so an upcoming restart or "let's come back to this later" is never a reason to take a note — nothing is lost either way. Notes you do take survive compression and resurface at natural work boundaries (after commits, historian runs, todo completion).`;
|
|
188411
189230
|
var TOOL_HISTORY_GUIDANCE = `Compressed history intentionally omits tool calls and their outputs — summaries like "I edited file X" are historian records, not patterns to replicate. In the live conversation, older tool calls and their results are cleaned up to save context — you may see your own past messages referencing actions without the corresponding tool call or result visible. This is normal context management. ALWAYS use real tool calls; never simulate, fabricate, or inline tool outputs in your text. If there is no tool result message, the action did not happen. NEVER simulate, hallucinate or claim tool calls, command output, search results, file edits, or diffs in plain text as if they actually occurred.`;
|
|
188412
189231
|
var BASE_INTRO = (protectedTags) => `Messages and tool outputs are tagged with §N§ identifiers (e.g., §1§, §42§).
|
|
188413
|
-
Use \`ctx_reduce\` to
|
|
188414
|
-
- \`drop\`: Remove entirely (best for tool outputs you already acted on).
|
|
188415
|
-
Syntax: "3-5", "1,2,9", or "1-5,8,12-15". Last ${protectedTags} tags are protected.
|
|
189232
|
+
Use \`ctx_reduce\` to mark spent tagged content as discardable and reclaim space. Marking is NOT an immediate delete — it queues the content, which stays fully visible until space is actually needed (as soon as the next turn if you're already under pressure, much later if not), so mark a tool output as soon as you're done with it rather than hoarding the call for the end of the turn. The last ${protectedTags} tags are protected (marking one just queues it until it ages out). Syntax: "3-5", "1,2,9", or "1-5,8,12-15".
|
|
188416
189233
|
Do not announce or narrate \`ctx_reduce\` drops — just call the tool silently. Saying "I'll drop these outputs" wastes tokens the user does not care about.
|
|
188417
189234
|
${CTX_NOTE_GUIDANCE}
|
|
188418
189235
|
Use \`ctx_memory\` for durable project knowledge: write what future sessions must know, update/archive/merge the memories you see in \`<project-memory>\` when they drift. Memories persist across sessions and every new session starts with them.
|
|
@@ -188431,7 +189248,7 @@ Use \`ctx_expand\` to recover the raw conversation behind a \`<compartment>\` su
|
|
|
188431
189248
|
\`ctx_search\` returns ranked results from memories, git commits, and raw message history. Use message ordinals from results with \`ctx_expand\` to retrieve surrounding conversation context.
|
|
188432
189249
|
${TOOL_HISTORY_GUIDANCE}
|
|
188433
189250
|
NEVER drop large ranges blindly (e.g., "1-50"). Review each tag before deciding.
|
|
188434
|
-
|
|
189251
|
+
Keep your user's instructions and intent — never drop a user message for its directive, even an old one. But a large block of pasted content inside a user message (logs, data dumps, long code, attachments) is fair to mark discardable once you've extracted what you need — it stays searchable via \`ctx_search\`.
|
|
188435
189252
|
NEVER drop assistant text messages unless they are exceptionally large. Your conversation messages are lightweight; only large tool outputs are worth dropping.
|
|
188436
189253
|
Before your turn finishes, consider using \`ctx_reduce\` to drop large tool outputs you no longer need.`;
|
|
188437
189254
|
var BASE_INTRO_NO_REDUCE = () => `${CTX_NOTE_GUIDANCE}
|
|
@@ -188779,7 +189596,7 @@ function createMagicContextHook(deps) {
|
|
|
188779
189596
|
}
|
|
188780
189597
|
let lastScheduleCheckMs = 0;
|
|
188781
189598
|
const getHistorianChunkTokens = () => deriveHistorianChunkTokens(resolveHistorianContextLimit(deps.config.historian?.model));
|
|
188782
|
-
const historianFallbackModels = resolveFallbackChain(
|
|
189599
|
+
const historianFallbackModels = resolveFallbackChain(deps.config.historian?.fallback_models);
|
|
188783
189600
|
const historyRefreshSessions = deps.liveSessionState?.historyRefreshSessions ?? new Set;
|
|
188784
189601
|
const deferredHistoryRefreshSessions = deps.liveSessionState?.deferredHistoryRefreshSessions ?? new Set;
|
|
188785
189602
|
try {
|
|
@@ -188852,29 +189669,55 @@ function createMagicContextHook(deps) {
|
|
|
188852
189669
|
ensureProjectRegistered: ensureProjectRegisteredFromOpenCodeDirectory,
|
|
188853
189670
|
getNotificationParams: (sid) => getLiveNotificationParams(sid, liveModelBySession, variantBySession, agentBySession)
|
|
188854
189671
|
});
|
|
188855
|
-
const executeEmbedHistory = async (sessionId) => {
|
|
189672
|
+
const executeEmbedHistory = async (sessionId, options) => {
|
|
188856
189673
|
if (deps.config.memory?.enabled === false) {
|
|
188857
189674
|
return "Memory is disabled for this project, so there is no semantic embedding to backfill.";
|
|
188858
189675
|
}
|
|
188859
189676
|
const directory = sessionDirectoryBySession.get(sessionId) ?? deps.directory;
|
|
189677
|
+
const active = embedRunStateBySession.get(sessionId);
|
|
189678
|
+
if (active && !active.signal.aborted && !options?.signal) {
|
|
189679
|
+
return "Embedding is already running for this session.";
|
|
189680
|
+
}
|
|
188860
189681
|
await ensureProjectRegisteredFromOpenCodeDirectory(directory, db);
|
|
188861
189682
|
const sessionProjectIdentity = resolveProjectIdentity(directory);
|
|
188862
|
-
|
|
188863
|
-
const
|
|
188864
|
-
|
|
188865
|
-
|
|
188866
|
-
|
|
188867
|
-
|
|
188868
|
-
|
|
188869
|
-
|
|
188870
|
-
|
|
188871
|
-
|
|
188872
|
-
|
|
188873
|
-
|
|
189683
|
+
embedPauseBySession.delete(sessionId);
|
|
189684
|
+
const prior = embedRunStateBySession.get(sessionId);
|
|
189685
|
+
if (prior)
|
|
189686
|
+
prior.abort();
|
|
189687
|
+
const controller = new AbortController;
|
|
189688
|
+
embedRunStateBySession.set(sessionId, controller);
|
|
189689
|
+
const signal = options?.signal ?? controller.signal;
|
|
189690
|
+
if (!options?.silent) {
|
|
189691
|
+
setRecompStarting({ recompProgressBySession }, sessionId, "Embedding history…", "embed");
|
|
189692
|
+
}
|
|
189693
|
+
let runFailed = 0;
|
|
189694
|
+
let outcome;
|
|
189695
|
+
try {
|
|
189696
|
+
outcome = await embedSessionCompartmentChunks(db, sessionProjectIdentity, sessionId, {
|
|
189697
|
+
signal,
|
|
189698
|
+
onProgress: ({ embedded, total }) => {
|
|
189699
|
+
const cur = recompProgressBySession.get(sessionId);
|
|
189700
|
+
if (!cur || cur.phase !== "recomp")
|
|
189701
|
+
return;
|
|
189702
|
+
recompProgressBySession.set(sessionId, {
|
|
189703
|
+
...cur,
|
|
189704
|
+
processedMessages: embedded,
|
|
189705
|
+
totalMessages: total,
|
|
189706
|
+
updatedAt: Date.now()
|
|
189707
|
+
});
|
|
189708
|
+
}
|
|
189709
|
+
});
|
|
189710
|
+
} finally {
|
|
189711
|
+
if (embedRunStateBySession.get(sessionId) === controller) {
|
|
189712
|
+
embedRunStateBySession.delete(sessionId);
|
|
188874
189713
|
}
|
|
188875
|
-
}
|
|
189714
|
+
}
|
|
189715
|
+
if ("failed" in outcome)
|
|
189716
|
+
runFailed = outcome.failed;
|
|
188876
189717
|
const terminal = (phase, message) => {
|
|
188877
|
-
|
|
189718
|
+
if (!options?.silent) {
|
|
189719
|
+
setRecompTerminal({ recompProgressBySession }, sessionId, phase, message);
|
|
189720
|
+
}
|
|
188878
189721
|
return message;
|
|
188879
189722
|
};
|
|
188880
189723
|
switch (outcome.status) {
|
|
@@ -188883,15 +189726,78 @@ function createMagicContextHook(deps) {
|
|
|
188883
189726
|
case "disabled":
|
|
188884
189727
|
return terminal("skipped", "No embedding provider is configured, so there is nothing to embed.");
|
|
188885
189728
|
case "busy":
|
|
188886
|
-
return terminal("skipped",
|
|
188887
|
-
case "aborted":
|
|
188888
|
-
|
|
189729
|
+
return terminal("skipped", "Embedding is already running for this project. Try again shortly.");
|
|
189730
|
+
case "aborted": {
|
|
189731
|
+
const cov = getEmbeddingCoverageStatus(db, sessionProjectIdentity, sessionId);
|
|
189732
|
+
const msg = `Paused at ${cov.session.embedded}/${cov.session.total} compartments embedded.`;
|
|
189733
|
+
return terminal("skipped", msg);
|
|
189734
|
+
}
|
|
188889
189735
|
case "stalled":
|
|
188890
|
-
return terminal("skipped", `Embedded ${outcome.embedded} compartments; ${outcome.remaining} could not be embedded (the provider returned no result). Run /ctx-embed
|
|
189736
|
+
return terminal("skipped", `Embedded ${outcome.embedded} compartments; ${outcome.remaining} could not be embedded (the provider returned no result). Run /ctx-embed start again to retry them.`);
|
|
188891
189737
|
default:
|
|
188892
|
-
return terminal("done", `Embedded ${outcome.embedded} compartment${outcome.embedded === 1 ? "" : "s"} of history for semantic search.`);
|
|
189738
|
+
return terminal("done", `Embedded ${outcome.embedded} compartment${outcome.embedded === 1 ? "" : "s"} of history for semantic search${runFailed > 0 ? ` (${runFailed} failed)` : ""}.`);
|
|
188893
189739
|
}
|
|
188894
189740
|
};
|
|
189741
|
+
const pauseEmbedDrain = (sessionId) => {
|
|
189742
|
+
embedPauseBySession.add(sessionId);
|
|
189743
|
+
const ctrl = embedRunStateBySession.get(sessionId);
|
|
189744
|
+
if (ctrl)
|
|
189745
|
+
ctrl.abort();
|
|
189746
|
+
const directory = sessionDirectoryBySession.get(sessionId) ?? deps.directory;
|
|
189747
|
+
const sessionProjectIdentity = resolveProjectIdentity(directory);
|
|
189748
|
+
const cov = getEmbeddingCoverageStatus(db, sessionProjectIdentity, sessionId);
|
|
189749
|
+
return `Paused at ${cov.session.embedded}/${cov.session.total} compartments embedded.`;
|
|
189750
|
+
};
|
|
189751
|
+
const getEmbedStatusText = (sessionId) => {
|
|
189752
|
+
const directory = sessionDirectoryBySession.get(sessionId) ?? deps.directory;
|
|
189753
|
+
const sessionProjectIdentity = resolveProjectIdentity(directory);
|
|
189754
|
+
const coverage = getEmbeddingCoverageStatus(db, sessionProjectIdentity, sessionId);
|
|
189755
|
+
const progress = recompProgressBySession.get(sessionId);
|
|
189756
|
+
const drainUi = getEmbedDrainUiStatus(sessionId, progress);
|
|
189757
|
+
return formatEmbedStatusText(coverage, {
|
|
189758
|
+
status: drainUi.status,
|
|
189759
|
+
embedded: progress?.processedMessages,
|
|
189760
|
+
total: progress?.totalMessages
|
|
189761
|
+
});
|
|
189762
|
+
};
|
|
189763
|
+
const maybeAutoEmbedSession = (sessionId) => {
|
|
189764
|
+
if (autoEmbedAttemptedBySession.has(sessionId))
|
|
189765
|
+
return;
|
|
189766
|
+
if (embedPauseBySession.has(sessionId))
|
|
189767
|
+
return;
|
|
189768
|
+
if (deps.config.memory?.enabled === false)
|
|
189769
|
+
return;
|
|
189770
|
+
autoEmbedAttemptedBySession.add(sessionId);
|
|
189771
|
+
const directory = sessionDirectoryBySession.get(sessionId) ?? deps.directory;
|
|
189772
|
+
(async () => {
|
|
189773
|
+
try {
|
|
189774
|
+
await new Promise((resolve6) => setTimeout(resolve6, 0));
|
|
189775
|
+
await ensureProjectRegisteredFromOpenCodeDirectory(directory, db);
|
|
189776
|
+
const sessionProjectIdentity = resolveProjectIdentity(directory);
|
|
189777
|
+
const coverage = getEmbeddingCoverageStatus(db, sessionProjectIdentity, sessionId);
|
|
189778
|
+
if (!coverage.enabled)
|
|
189779
|
+
return;
|
|
189780
|
+
const remaining = coverage.session.total - coverage.session.embedded;
|
|
189781
|
+
if (remaining <= 0)
|
|
189782
|
+
return;
|
|
189783
|
+
const notifyParams = getLiveNotificationParams(sessionId, liveModelBySession, variantBySession, agentBySession);
|
|
189784
|
+
if (!isTuiConnected(sessionId)) {
|
|
189785
|
+
const startMsg = `Embedding ${remaining} compartment${remaining === 1 ? "" : "s"} of history in the background…`;
|
|
189786
|
+
await sendIgnoredMessage(deps.client, sessionId, startMsg, {
|
|
189787
|
+
...notifyParams
|
|
189788
|
+
});
|
|
189789
|
+
}
|
|
189790
|
+
const summary = await executeEmbedHistory(sessionId);
|
|
189791
|
+
if (!isTuiConnected(sessionId)) {
|
|
189792
|
+
await sendIgnoredMessage(deps.client, sessionId, summary, {
|
|
189793
|
+
...notifyParams
|
|
189794
|
+
});
|
|
189795
|
+
}
|
|
189796
|
+
} catch (error51) {
|
|
189797
|
+
log("[magic-context] auto-embed drain failed:", error51);
|
|
189798
|
+
}
|
|
189799
|
+
})();
|
|
189800
|
+
};
|
|
188895
189801
|
const sidekickRunnable = isSidekickRunnable(deps.config);
|
|
188896
189802
|
const sidekickConfig = sidekickRunnable ? deps.config.sidekick : undefined;
|
|
188897
189803
|
const transform2 = createTransform({
|
|
@@ -188953,7 +189859,8 @@ function createMagicContextHook(deps) {
|
|
|
188953
189859
|
cavemanTextCompression: ctxReduceEnabled === false && deps.config.caveman_text_compression?.enabled === true ? {
|
|
188954
189860
|
enabled: true,
|
|
188955
189861
|
minChars: deps.config.caveman_text_compression.min_chars ?? 500
|
|
188956
|
-
} : undefined
|
|
189862
|
+
} : undefined,
|
|
189863
|
+
maybeAutoEmbedSession
|
|
188957
189864
|
});
|
|
188958
189865
|
const eventHandler = createEventHandler2({
|
|
188959
189866
|
contextUsageMap,
|
|
@@ -188982,6 +189889,7 @@ function createMagicContextHook(deps) {
|
|
|
188982
189889
|
recompProgressBySession.delete(sessionId);
|
|
188983
189890
|
internalChildSessions.delete(sessionId);
|
|
188984
189891
|
channel1StateBySession.delete(sessionId);
|
|
189892
|
+
clearEmbedSessionState(sessionId);
|
|
188985
189893
|
}
|
|
188986
189894
|
});
|
|
188987
189895
|
const runDreamQueueInBackground = () => {
|
|
@@ -189016,7 +189924,7 @@ function createMagicContextHook(deps) {
|
|
|
189016
189924
|
token_budget: dreaming.pin_key_files.token_budget,
|
|
189017
189925
|
min_reads: dreaming.pin_key_files.min_reads
|
|
189018
189926
|
} : undefined,
|
|
189019
|
-
fallbackModels: resolveFallbackChain(
|
|
189927
|
+
fallbackModels: resolveFallbackChain(dreaming.fallback_models),
|
|
189020
189928
|
projectIdentity: projectPath
|
|
189021
189929
|
}).catch((error51) => {
|
|
189022
189930
|
log("[dreamer] scheduled queue processing failed:", error51);
|
|
@@ -189047,6 +189955,8 @@ function createMagicContextHook(deps) {
|
|
|
189047
189955
|
executeRecomp: historianRunnable ? async (sessionId, options) => runManagedRecomp(buildManagedRecompCtx(sessionId), sessionId, options) : undefined,
|
|
189048
189956
|
runUpgrade: historianRunnable ? async (sessionId) => runManagedUpgrade(buildManagedRecompCtx(sessionId), sessionId) : undefined,
|
|
189049
189957
|
executeEmbedHistory,
|
|
189958
|
+
pauseEmbedDrain,
|
|
189959
|
+
getEmbedStatusText,
|
|
189050
189960
|
sendNotification: async (sessionId, text, params) => {
|
|
189051
189961
|
await sendIgnoredMessage(deps.client, sessionId, text, {
|
|
189052
189962
|
...getLiveNotificationParams(sessionId, liveModelBySession, variantBySession, agentBySession),
|
|
@@ -189073,7 +189983,7 @@ function createMagicContextHook(deps) {
|
|
|
189073
189983
|
token_budget: dreamerConfig.pin_key_files.token_budget,
|
|
189074
189984
|
min_reads: dreamerConfig.pin_key_files.min_reads
|
|
189075
189985
|
} : undefined,
|
|
189076
|
-
fallbackModels: resolveFallbackChain(
|
|
189986
|
+
fallbackModels: resolveFallbackChain(dreamerConfig.fallback_models)
|
|
189077
189987
|
} : undefined
|
|
189078
189988
|
});
|
|
189079
189989
|
const systemPromptHash = createSystemPromptHashHandler({
|
|
@@ -189259,6 +190169,7 @@ function truncateError(name2, code, message, maxLen = 240) {
|
|
|
189259
190169
|
|
|
189260
190170
|
// src/plugin/rpc-handlers.ts
|
|
189261
190171
|
init_project_identity();
|
|
190172
|
+
init_project_embedding_registry();
|
|
189262
190173
|
init_tool_definition_tokens();
|
|
189263
190174
|
await init_storage();
|
|
189264
190175
|
|
|
@@ -189979,6 +190890,26 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config2, liveSess
|
|
|
189979
190890
|
}
|
|
189980
190891
|
return detail;
|
|
189981
190892
|
}
|
|
190893
|
+
function buildEmbedDetail(db, sessionId, dir, liveSessionState) {
|
|
190894
|
+
const projectIdentity = resolveProjectIdentity(dir);
|
|
190895
|
+
const coverage = getEmbeddingCoverageStatus(db, projectIdentity, sessionId);
|
|
190896
|
+
const progress = liveSessionState.recompProgressBySession.get(sessionId);
|
|
190897
|
+
const drainUi = getEmbedDrainUiStatus(sessionId, progress);
|
|
190898
|
+
const statusText = formatEmbedStatusText(coverage, {
|
|
190899
|
+
status: drainUi.status,
|
|
190900
|
+
embedded: progress?.processedMessages,
|
|
190901
|
+
total: progress?.totalMessages
|
|
190902
|
+
});
|
|
190903
|
+
return {
|
|
190904
|
+
enabled: coverage.enabled,
|
|
190905
|
+
model: coverage.model,
|
|
190906
|
+
provider: coverage.provider,
|
|
190907
|
+
session: coverage.session,
|
|
190908
|
+
memories: coverage.memories,
|
|
190909
|
+
commits: coverage.commits,
|
|
190910
|
+
statusText
|
|
190911
|
+
};
|
|
190912
|
+
}
|
|
189982
190913
|
function registerRpcHandlers(rpcServer, args) {
|
|
189983
190914
|
const { directory, config: config2, liveSessionState } = args;
|
|
189984
190915
|
const rawConfig = config2;
|
|
@@ -190001,6 +190932,19 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
190001
190932
|
return { error: "unavailable" };
|
|
190002
190933
|
return buildStatusDetail(db, sessionId, dir, modelKey, rawConfig, liveSessionState, injectionBudgetTokens);
|
|
190003
190934
|
});
|
|
190935
|
+
rpcServer.handle("embed-detail", async (params) => {
|
|
190936
|
+
const sessionId = String(params.sessionId ?? "");
|
|
190937
|
+
const dir = String(params.directory ?? directory);
|
|
190938
|
+
const db = getDb();
|
|
190939
|
+
if (!db || !sessionId)
|
|
190940
|
+
return { error: "unavailable" };
|
|
190941
|
+
try {
|
|
190942
|
+
return buildEmbedDetail(db, sessionId, dir, liveSessionState);
|
|
190943
|
+
} catch (err) {
|
|
190944
|
+
log("[rpc] embed-detail error:", err);
|
|
190945
|
+
return { error: "unavailable" };
|
|
190946
|
+
}
|
|
190947
|
+
});
|
|
190004
190948
|
rpcServer.handle("compartment-count", async (params) => {
|
|
190005
190949
|
const sessionId = String(params.sessionId ?? "");
|
|
190006
190950
|
const db = getDb();
|
|
@@ -190015,8 +190959,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
190015
190959
|
});
|
|
190016
190960
|
const buildManagedCtx = async (db) => {
|
|
190017
190961
|
const { deriveHistorianChunkTokens: deriveHistorianChunkTokens2, resolveHistorianContextLimit: resolveHistorianContextLimit2 } = await Promise.resolve().then(() => (init_derive_budgets(), exports_derive_budgets));
|
|
190018
|
-
const { resolveFallbackChain: resolveFallbackChain2 } = await Promise.resolve().then(() =>
|
|
190019
|
-
const { HISTORIAN_AGENT: HISTORIAN_AGENT2 } = await Promise.resolve().then(() => exports_historian);
|
|
190962
|
+
const { resolveFallbackChain: resolveFallbackChain2 } = await Promise.resolve().then(() => exports_resolve_fallbacks);
|
|
190020
190963
|
const DEFAULT_HISTORIAN_TIMEOUT_MS2 = 600000;
|
|
190021
190964
|
return {
|
|
190022
190965
|
client: args.client,
|
|
@@ -190027,7 +190970,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
190027
190970
|
historianTimeoutMs: config2.historian_timeout_ms ?? DEFAULT_HISTORIAN_TIMEOUT_MS2,
|
|
190028
190971
|
memoryEnabled: config2.memory?.enabled ?? true,
|
|
190029
190972
|
autoPromote: config2.memory?.auto_promote ?? true,
|
|
190030
|
-
fallbackModels: resolveFallbackChain2(
|
|
190973
|
+
fallbackModels: resolveFallbackChain2(config2.historian?.fallback_models),
|
|
190031
190974
|
runMigration: config2.memory?.enabled !== false && !!config2.historian?.model,
|
|
190032
190975
|
userMemoriesEnabled: config2.dreamer?.user_memories?.enabled === true,
|
|
190033
190976
|
historianTwoPass: config2.historian?.two_pass === true,
|
|
@@ -190123,27 +191066,225 @@ Older parts of this session are summarized into <compartment> blocks inside <ses
|
|
|
190123
191066
|
|
|
190124
191067
|
ctx_expand(start=120, end=245) ← the compartment's own start/end attributes
|
|
190125
191068
|
|
|
190126
|
-
Returns the raw transcript as [N] U:/A: lines, capped at ~15K tokens; an oversized range returns the head and tells you where to continue. Also works with ordinals from ctx_search message results — expand a window around a hit (e.g. start=N-10, end=N+5). Ranges after the last compartment are your live tail — already visible in context, not expandable
|
|
191069
|
+
Returns the raw transcript as [N] U:/A: lines, capped at ~15K tokens; an oversized range returns the head and tells you where to continue. Also works with ordinals from ctx_search message results — expand a window around a hit (e.g. start=N-10, end=N+5). Ranges after the last compartment are your live tail — already visible in context, not expandable.
|
|
191070
|
+
|
|
191071
|
+
Two recovery modes for finer detail:
|
|
191072
|
+
- ctx_expand(start=120, end=245, verbose=true) — lists each message SEPARATELY with its ordinal [N] and a per-part preview (each tool call shown with its output size). Use this to find the exact message or tool call you want, then recover it in full by ordinal.
|
|
191073
|
+
- ctx_expand(message=138) — returns the FULL untruncated content of the message at that ordinal: every text part, and every tool call's complete input + output, read from stored history. This is the cheap way to get back a tool output you dropped with ctx_reduce — the original is still in storage even though the wire shows [dropped §N§]. If the message was deleted from history (session prune/revert), it says so.`;
|
|
190127
191074
|
var CTX_EXPAND_TOKEN_BUDGET = 15000;
|
|
190128
191075
|
|
|
191076
|
+
// src/tools/ctx-expand/render.ts
|
|
191077
|
+
init_read_session_formatting();
|
|
191078
|
+
await init_read_session_chunk();
|
|
191079
|
+
function isRecord3(value) {
|
|
191080
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
191081
|
+
}
|
|
191082
|
+
function roleLabel(role) {
|
|
191083
|
+
if (role === "assistant")
|
|
191084
|
+
return "A (assistant)";
|
|
191085
|
+
if (role === "user")
|
|
191086
|
+
return "U (user)";
|
|
191087
|
+
return role;
|
|
191088
|
+
}
|
|
191089
|
+
function truncate2(value, max) {
|
|
191090
|
+
const t = value.trim();
|
|
191091
|
+
return t.length <= max ? t : `${t.slice(0, max)}…`;
|
|
191092
|
+
}
|
|
191093
|
+
function keyArg(input) {
|
|
191094
|
+
if (!input)
|
|
191095
|
+
return "";
|
|
191096
|
+
for (const k of ["filePath", "path", "pattern", "query", "symbol", "module", "action"]) {
|
|
191097
|
+
const v = input[k];
|
|
191098
|
+
if (typeof v === "string" && v.length > 0)
|
|
191099
|
+
return truncate2(v, 60);
|
|
191100
|
+
}
|
|
191101
|
+
if (typeof input.description === "string")
|
|
191102
|
+
return truncate2(input.description, 60);
|
|
191103
|
+
return "";
|
|
191104
|
+
}
|
|
191105
|
+
function asToolPart(part) {
|
|
191106
|
+
const type = typeof part.type === "string" ? part.type : "";
|
|
191107
|
+
if (type === "tool") {
|
|
191108
|
+
const state = isRecord3(part.state) ? part.state : null;
|
|
191109
|
+
const output = state && typeof state.output === "string" ? state.output : state && state.output != null ? JSON.stringify(state.output) : null;
|
|
191110
|
+
const metadata = state && isRecord3(state.metadata) ? state.metadata : null;
|
|
191111
|
+
const title = state && typeof state.title === "string" && state.title || metadata && typeof metadata.title === "string" && metadata.title || null;
|
|
191112
|
+
return {
|
|
191113
|
+
name: typeof part.tool === "string" ? part.tool : "tool",
|
|
191114
|
+
callId: typeof part.callID === "string" ? part.callID : "",
|
|
191115
|
+
title,
|
|
191116
|
+
input: state && isRecord3(state.input) ? state.input : null,
|
|
191117
|
+
output
|
|
191118
|
+
};
|
|
191119
|
+
}
|
|
191120
|
+
if (type === "tool_use") {
|
|
191121
|
+
return {
|
|
191122
|
+
name: typeof part.name === "string" ? part.name : "tool",
|
|
191123
|
+
callId: typeof part.id === "string" ? part.id : "",
|
|
191124
|
+
title: null,
|
|
191125
|
+
input: isRecord3(part.input) ? part.input : null,
|
|
191126
|
+
output: null
|
|
191127
|
+
};
|
|
191128
|
+
}
|
|
191129
|
+
if (type === "tool_result") {
|
|
191130
|
+
const content = part.content;
|
|
191131
|
+
const output = typeof content === "string" ? content : content != null ? JSON.stringify(content) : null;
|
|
191132
|
+
return {
|
|
191133
|
+
name: "tool_result",
|
|
191134
|
+
callId: typeof part.tool_use_id === "string" ? part.tool_use_id : "",
|
|
191135
|
+
title: null,
|
|
191136
|
+
input: null,
|
|
191137
|
+
output
|
|
191138
|
+
};
|
|
191139
|
+
}
|
|
191140
|
+
return null;
|
|
191141
|
+
}
|
|
191142
|
+
function textOf(part) {
|
|
191143
|
+
if (part.type === "text" && typeof part.text === "string")
|
|
191144
|
+
return part.text;
|
|
191145
|
+
return null;
|
|
191146
|
+
}
|
|
191147
|
+
function reasoningOf(part) {
|
|
191148
|
+
if ((part.type === "reasoning" || part.type === "thinking") && typeof part.text === "string") {
|
|
191149
|
+
return part.text;
|
|
191150
|
+
}
|
|
191151
|
+
return null;
|
|
191152
|
+
}
|
|
191153
|
+
function renderPartPreview(part) {
|
|
191154
|
+
if (!isRecord3(part))
|
|
191155
|
+
return null;
|
|
191156
|
+
const text = textOf(part);
|
|
191157
|
+
if (text !== null) {
|
|
191158
|
+
const t = truncate2(text, 200);
|
|
191159
|
+
return t.length > 0 ? ` • ${t}` : null;
|
|
191160
|
+
}
|
|
191161
|
+
const tool = asToolPart(part);
|
|
191162
|
+
if (tool) {
|
|
191163
|
+
const arg = keyArg(tool.input);
|
|
191164
|
+
const head = arg ? `${tool.name}(${arg})` : tool.name;
|
|
191165
|
+
return tool.output !== null ? ` • tool ${head} → output ~${estimateTokens(tool.output)} tok` : ` • tool ${head}`;
|
|
191166
|
+
}
|
|
191167
|
+
const reasoning = reasoningOf(part);
|
|
191168
|
+
if (reasoning !== null)
|
|
191169
|
+
return ` • [reasoning] ${truncate2(reasoning, 120)}`;
|
|
191170
|
+
const type = typeof part.type === "string" ? part.type : "part";
|
|
191171
|
+
if (type === "file")
|
|
191172
|
+
return " • [file]";
|
|
191173
|
+
if (type === "step-start" || type === "step-finish")
|
|
191174
|
+
return null;
|
|
191175
|
+
return ` • [${type}]`;
|
|
191176
|
+
}
|
|
191177
|
+
function renderPartFull(part) {
|
|
191178
|
+
if (!isRecord3(part))
|
|
191179
|
+
return null;
|
|
191180
|
+
const text = textOf(part);
|
|
191181
|
+
if (text !== null) {
|
|
191182
|
+
return text.trim().length > 0 ? ` [text]
|
|
191183
|
+
${text}` : null;
|
|
191184
|
+
}
|
|
191185
|
+
const tool = asToolPart(part);
|
|
191186
|
+
if (tool) {
|
|
191187
|
+
const lines = [];
|
|
191188
|
+
const idSuffix = tool.callId ? ` #${tool.callId}` : "";
|
|
191189
|
+
lines.push(` [tool: ${tool.name}${idSuffix}]`);
|
|
191190
|
+
if (tool.title && tool.title.trim().length > 0) {
|
|
191191
|
+
lines.push(` description: ${tool.title.trim()}`);
|
|
191192
|
+
}
|
|
191193
|
+
if (tool.input)
|
|
191194
|
+
lines.push(` input: ${JSON.stringify(tool.input)}`);
|
|
191195
|
+
if (tool.output !== null)
|
|
191196
|
+
lines.push(` output:
|
|
191197
|
+
${tool.output}`);
|
|
191198
|
+
return lines.join(`
|
|
191199
|
+
`);
|
|
191200
|
+
}
|
|
191201
|
+
const type = typeof part.type === "string" ? part.type : "part";
|
|
191202
|
+
if (type === "file") {
|
|
191203
|
+
const name2 = typeof part.filename === "string" && part.filename || typeof part.url === "string" && part.url || "";
|
|
191204
|
+
return ` [file]${name2 ? ` ${name2}` : ""}`;
|
|
191205
|
+
}
|
|
191206
|
+
return null;
|
|
191207
|
+
}
|
|
191208
|
+
function renderMessageByOrdinal(sessionId, ordinal) {
|
|
191209
|
+
const msg = readRawSessionMessages(sessionId).find((m) => m.ordinal === ordinal);
|
|
191210
|
+
if (!msg) {
|
|
191211
|
+
return `No message at ordinal ${ordinal} in this session's stored history — it was deleted ` + `(session prune/revert) or the ordinal is wrong, so it can't be recovered. ` + `Re-run the tool if you still need the data.`;
|
|
191212
|
+
}
|
|
191213
|
+
const rendered = msg.parts.map(renderPartFull).filter((l) => l !== null);
|
|
191214
|
+
const lines = [`[${msg.ordinal}] ${roleLabel(msg.role)} — full recovery:`, ""];
|
|
191215
|
+
if (rendered.length === 0) {
|
|
191216
|
+
lines.push(" (no recoverable content — message had only structural/reasoning parts)");
|
|
191217
|
+
} else {
|
|
191218
|
+
lines.push(...rendered);
|
|
191219
|
+
}
|
|
191220
|
+
return lines.join(`
|
|
191221
|
+
`);
|
|
191222
|
+
}
|
|
191223
|
+
function renderVerboseRange(sessionId, start, end, tokenBudget) {
|
|
191224
|
+
const messages = readRawSessionMessages(sessionId).filter((m) => m.ordinal >= start && m.ordinal <= end);
|
|
191225
|
+
const out = [];
|
|
191226
|
+
let usedTokens = 0;
|
|
191227
|
+
let lastOrdinal = start - 1;
|
|
191228
|
+
let truncated = false;
|
|
191229
|
+
for (const msg of messages) {
|
|
191230
|
+
const header = `[${msg.ordinal}] ${roleLabel(msg.role)}`;
|
|
191231
|
+
const partLines = msg.parts.map(renderPartPreview).filter((l) => l !== null);
|
|
191232
|
+
const block = partLines.length > 0 ? `${header}
|
|
191233
|
+
${partLines.join(`
|
|
191234
|
+
`)}` : header;
|
|
191235
|
+
const blockTokens = estimateTokens(block);
|
|
191236
|
+
if (usedTokens + blockTokens > tokenBudget && out.length > 0) {
|
|
191237
|
+
truncated = true;
|
|
191238
|
+
break;
|
|
191239
|
+
}
|
|
191240
|
+
out.push(block);
|
|
191241
|
+
usedTokens += blockTokens;
|
|
191242
|
+
lastOrdinal = msg.ordinal;
|
|
191243
|
+
}
|
|
191244
|
+
return { text: out.join(`
|
|
191245
|
+
|
|
191246
|
+
`), lastOrdinal, truncated };
|
|
191247
|
+
}
|
|
191248
|
+
|
|
190129
191249
|
// src/tools/ctx-expand/tools.ts
|
|
190130
191250
|
function createCtxExpandTool(deps) {
|
|
190131
191251
|
return tool({
|
|
190132
191252
|
description: CTX_EXPAND_DESCRIPTION,
|
|
190133
191253
|
args: {
|
|
190134
|
-
start: tool.schema.number().describe(`First message ordinal to expand — a compartment's start="N" attribute, or an ordinal from a ctx_search message hit`),
|
|
190135
|
-
end: tool.schema.number().describe(`Last message ordinal to expand (inclusive) — a compartment's end="M" attribute`)
|
|
191254
|
+
start: tool.schema.number().optional().describe(`First message ordinal to expand — a compartment's start="N" attribute, or an ordinal from a ctx_search message hit`),
|
|
191255
|
+
end: tool.schema.number().optional().describe(`Last message ordinal to expand (inclusive) — a compartment's end="M" attribute`),
|
|
191256
|
+
verbose: tool.schema.boolean().optional().describe("With start/end: list each message separately with its ordinal [N] and per-part preview (each tool call shown with its output size), so you can pick one to recover in full by ordinal."),
|
|
191257
|
+
message: tool.schema.number().optional().describe("Full untruncated recovery of ONE message by its ordinal (every text part + every tool call's complete input/output). Use an ordinal from a compartment, ctx_search hit, or verbose range. Recovers a tool output you dropped with ctx_reduce.")
|
|
190136
191258
|
},
|
|
190137
191259
|
async execute(args, toolContext) {
|
|
190138
191260
|
const sessionId = toolContext.sessionID;
|
|
191261
|
+
if (typeof args.message === "number" && args.message >= 1) {
|
|
191262
|
+
return renderMessageByOrdinal(sessionId, args.message);
|
|
191263
|
+
}
|
|
190139
191264
|
if (!args.start || !args.end || args.start < 1 || args.end < args.start) {
|
|
190140
|
-
return "Error: start and end
|
|
191265
|
+
return "Error: provide either message=<ordinal>, or start and end (positive integers, start <= end).";
|
|
190141
191266
|
}
|
|
190142
191267
|
const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, sessionId);
|
|
190143
191268
|
if (lastCompartmentEnd >= 0 && args.start > lastCompartmentEnd) {
|
|
190144
191269
|
return `Range ${args.start}-${args.end} is entirely within the live tail (after the last compacted message ${lastCompartmentEnd}); those messages are already visible in context.`;
|
|
190145
191270
|
}
|
|
190146
191271
|
const effectiveEnd = lastCompartmentEnd >= 0 ? Math.min(args.end, lastCompartmentEnd) : args.end;
|
|
191272
|
+
if (args.verbose === true) {
|
|
191273
|
+
const v = renderVerboseRange(sessionId, args.start, effectiveEnd, CTX_EXPAND_TOKEN_BUDGET);
|
|
191274
|
+
if (!v.text) {
|
|
191275
|
+
return `No messages found in range ${args.start}-${effectiveEnd}. The range may be outside this session's history.`;
|
|
191276
|
+
}
|
|
191277
|
+
const out = [
|
|
191278
|
+
`Messages ${args.start}-${v.lastOrdinal} (verbose). Recover any one in full with ctx_expand(message=<ordinal>):`,
|
|
191279
|
+
"",
|
|
191280
|
+
v.text
|
|
191281
|
+
];
|
|
191282
|
+
if (v.truncated) {
|
|
191283
|
+
out.push("", `Truncated at message ${v.lastOrdinal} (budget: ~${CTX_EXPAND_TOKEN_BUDGET} tokens). Call again with start=${v.lastOrdinal + 1} end=${effectiveEnd} verbose=true for more.`);
|
|
191284
|
+
}
|
|
191285
|
+
return out.join(`
|
|
191286
|
+
`);
|
|
191287
|
+
}
|
|
190147
191288
|
const chunk = readSessionChunk(sessionId, CTX_EXPAND_TOKEN_BUDGET, args.start, effectiveEnd + 1);
|
|
190148
191289
|
if (!chunk.text || chunk.messageCount === 0) {
|
|
190149
191290
|
return `No messages found in range ${args.start}-${args.end}. The range may be outside this session's history.`;
|
|
@@ -190181,6 +191322,7 @@ Actions:
|
|
|
190181
191322
|
Example: ctx_memory(action="write", category="CONSTRAINTS", content="Pi stores sessions as JSONL under ~/.pi/agent/sessions/, not SQLite")`;
|
|
190182
191323
|
var DEFAULT_SEARCH_LIMIT2 = 10;
|
|
190183
191324
|
// src/tools/ctx-memory/tools.ts
|
|
191325
|
+
import { tool as tool2 } from "@opencode-ai/plugin";
|
|
190184
191326
|
init_memory();
|
|
190185
191327
|
init_embedding();
|
|
190186
191328
|
init_embedding_cache();
|
|
@@ -190188,7 +191330,6 @@ init_normalize_hash();
|
|
|
190188
191330
|
init_workspaces();
|
|
190189
191331
|
init_logger();
|
|
190190
191332
|
await init_storage();
|
|
190191
|
-
import { tool as tool2 } from "@opencode-ai/plugin";
|
|
190192
191333
|
|
|
190193
191334
|
// src/tools/ctx-memory/types.ts
|
|
190194
191335
|
var CTX_MEMORY_ACTIONS = ["write", "archive", "update", "merge"];
|
|
@@ -190837,15 +191978,16 @@ function createCtxNoteTools(deps) {
|
|
|
190837
191978
|
};
|
|
190838
191979
|
}
|
|
190839
191980
|
// src/tools/ctx-reduce/constants.ts
|
|
190840
|
-
var CTX_REDUCE_DESCRIPTION = `
|
|
190841
|
-
|
|
190842
|
-
|
|
190843
|
-
|
|
190844
|
-
-
|
|
190845
|
-
-
|
|
190846
|
-
|
|
190847
|
-
|
|
190848
|
-
|
|
191981
|
+
var CTX_REDUCE_DESCRIPTION = `Mark spent tagged content as discardable to reclaim context space. This is NOT an immediate delete. Use §N§ identifiers visible in the conversation. The \`drop\` param accepts ranges: "3-5", "1,2,9", "1-5,8".
|
|
191982
|
+
|
|
191983
|
+
How it works:
|
|
191984
|
+
- Marking QUEUES content for release. It stays fully visible to you until context space is actually needed — which may be as soon as the next turn if you are already under pressure, or many turns later if not. So mark spent outputs as soon as you finish with them; don't hoard the call for the end of the turn.
|
|
191985
|
+
- The newest tags are protected: marking one just queues it until it ages out of the recent window, so marking recent output is harmless.
|
|
191986
|
+
- When content is finally released it becomes a short placeholder, and re-running the tool is the only way to get it back. So mark only what you are genuinely DONE with — the test is "have I extracted what I need from this?", not "is it safe / do I have time before it drops?".
|
|
191987
|
+
|
|
191988
|
+
Mark discardable once processed: large outputs you've summarized, repeated or redundant dumps, data written to disk, status/log output that only confirmed an expected state.
|
|
191989
|
+
Keep: user messages, unresolved errors, raw evidence you haven't extracted yet, and outputs whose exact wording may matter later.
|
|
191990
|
+
Never blanket-mark large ranges (e.g. "1-50") — review what each tag holds first.`;
|
|
190849
191991
|
// src/tools/ctx-reduce/tools.ts
|
|
190850
191992
|
import { tool as tool4 } from "@opencode-ai/plugin";
|
|
190851
191993
|
|
|
@@ -191112,7 +192254,7 @@ function createCtxSearchTool(deps) {
|
|
|
191112
192254
|
memoryEnabled,
|
|
191113
192255
|
embeddingEnabled,
|
|
191114
192256
|
embedQuery: async (text, signal) => {
|
|
191115
|
-
const result = await embedTextForProject(projectPath, text, signal);
|
|
192257
|
+
const result = await embedTextForProject(projectPath, text, signal, "query");
|
|
191116
192258
|
return result?.vector ?? null;
|
|
191117
192259
|
},
|
|
191118
192260
|
isEmbeddingRuntimeEnabled: () => embeddingEnabled === true,
|
|
@@ -191215,7 +192357,6 @@ function createToolRegistry(args) {
|
|
|
191215
192357
|
init_conflict_detector();
|
|
191216
192358
|
init_data_path();
|
|
191217
192359
|
init_logger();
|
|
191218
|
-
init_model_requirements();
|
|
191219
192360
|
init_models_dev_cache();
|
|
191220
192361
|
|
|
191221
192362
|
// src/shared/rpc-server.ts
|
|
@@ -191428,6 +192569,9 @@ class MagicContextRpcServer {
|
|
|
191428
192569
|
}
|
|
191429
192570
|
|
|
191430
192571
|
// src/index.ts
|
|
192572
|
+
var HISTORIAN_MAX_STEPS = 40;
|
|
192573
|
+
var SIDEKICK_MAX_STEPS = 40;
|
|
192574
|
+
var DREAMER_MAX_STEPS = 150;
|
|
191431
192575
|
var plugin = async (ctx) => {
|
|
191432
192576
|
const pluginConfig = loadPluginConfig(ctx.directory);
|
|
191433
192577
|
setSqlitePragmaConfig({
|
|
@@ -191620,12 +192764,13 @@ var plugin = async (ctx) => {
|
|
|
191620
192764
|
await hooks.magicContext?.["experimental.text.complete"]?.(input, output);
|
|
191621
192765
|
},
|
|
191622
192766
|
config: async (config2) => {
|
|
191623
|
-
const buildHiddenAgentConfig = (
|
|
192767
|
+
const buildHiddenAgentConfig = (prompt, allowedTools, maxSteps, overrides) => {
|
|
191624
192768
|
const { permission: overridePermission, ...restOverrides } = overrides ?? {};
|
|
191625
192769
|
const basePermission = buildAllowOnlyPermission(allowedTools);
|
|
191626
192770
|
return {
|
|
191627
192771
|
prompt,
|
|
191628
|
-
|
|
192772
|
+
steps: maxSteps,
|
|
192773
|
+
maxSteps,
|
|
191629
192774
|
...restOverrides,
|
|
191630
192775
|
permission: {
|
|
191631
192776
|
...basePermission,
|
|
@@ -191647,6 +192792,7 @@ var plugin = async (ctx) => {
|
|
|
191647
192792
|
max_runtime_minutes: _max,
|
|
191648
192793
|
tasks: _tasks,
|
|
191649
192794
|
task_timeout_minutes: _tto,
|
|
192795
|
+
thinking_level: _thinkingLevel,
|
|
191650
192796
|
...agentOverrides
|
|
191651
192797
|
} = pluginConfig.dreamer;
|
|
191652
192798
|
return agentOverrides;
|
|
@@ -191655,20 +192801,28 @@ var plugin = async (ctx) => {
|
|
|
191655
192801
|
const {
|
|
191656
192802
|
timeout_ms: _timeoutMs,
|
|
191657
192803
|
system_prompt: _systemPrompt,
|
|
192804
|
+
thinking_level: _thinkingLevel,
|
|
191658
192805
|
...agentOverrides
|
|
191659
192806
|
} = pluginConfig.sidekick;
|
|
191660
192807
|
return agentOverrides;
|
|
191661
192808
|
})() : undefined;
|
|
191662
192809
|
const historianAgentOverrides = pluginConfig.historian ? (() => {
|
|
191663
|
-
const {
|
|
192810
|
+
const {
|
|
192811
|
+
two_pass: _twoPass,
|
|
192812
|
+
disallowed_tools: _disallowedTools,
|
|
192813
|
+
thinking_level: _thinkingLevel,
|
|
192814
|
+
...agentOverrides
|
|
192815
|
+
} = pluginConfig.historian;
|
|
191664
192816
|
return agentOverrides;
|
|
191665
192817
|
})() : undefined;
|
|
192818
|
+
const historianDisallowed = pluginConfig.historian?.disallowed_tools ?? [];
|
|
192819
|
+
const historianAllowedTools = applyDisallowedTools(HISTORIAN_ALLOWED_TOOLS, historianDisallowed);
|
|
191666
192820
|
config2.agent = {
|
|
191667
192821
|
...config2.agent ?? {},
|
|
191668
|
-
[DREAMER_AGENT]: buildHiddenAgentConfig(
|
|
191669
|
-
[HISTORIAN_AGENT]: buildHiddenAgentConfig(
|
|
191670
|
-
[HISTORIAN_EDITOR_AGENT]: buildHiddenAgentConfig(
|
|
191671
|
-
[SIDEKICK_AGENT]: buildHiddenAgentConfig(
|
|
192822
|
+
[DREAMER_AGENT]: buildHiddenAgentConfig(DREAMER_SYSTEM_PROMPT, DREAMER_ALLOWED_TOOLS, DREAMER_MAX_STEPS, dreamerAgentOverrides),
|
|
192823
|
+
[HISTORIAN_AGENT]: buildHiddenAgentConfig(COMPARTMENT_AGENT_SYSTEM_PROMPT, historianAllowedTools, HISTORIAN_MAX_STEPS, historianAgentOverrides),
|
|
192824
|
+
[HISTORIAN_EDITOR_AGENT]: buildHiddenAgentConfig(HISTORIAN_EDITOR_SYSTEM_PROMPT, historianAllowedTools, HISTORIAN_MAX_STEPS, historianAgentOverrides),
|
|
192825
|
+
[SIDEKICK_AGENT]: buildHiddenAgentConfig(SIDEKICK_SYSTEM_PROMPT, SIDEKICK_ALLOWED_TOOLS, SIDEKICK_MAX_STEPS, sidekickAgentOverrides)
|
|
191672
192826
|
};
|
|
191673
192827
|
}
|
|
191674
192828
|
};
|