@cortexkit/opencode-magic-context 0.42.5 → 0.42.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +1 -0
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-jyj54gbe.js → conflict-warning-hook-aktepwpz.js} +3 -3
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/context-authority.d.ts +28 -1
- package/dist/features/magic-context/context-authority.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/open-opencode-db.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-local.d.ts +1 -0
- package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding.d.ts +1 -1
- package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts +12 -0
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts +1 -0
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +1 -1
- package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -1
- package/dist/hooks/auto-update-checker/index.d.ts.map +1 -1
- package/dist/hooks/magic-context/cache-busting-signals.d.ts +0 -1
- package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-delivery.d.ts +8 -0
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +12 -0
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +4 -4
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-state-sync.d.ts +3 -0
- package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-transport.d.ts +24 -2
- package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-wire.d.ts +1 -1
- package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
- package/dist/hooks/magic-context/producer-window-guard.d.ts +31 -1
- package/dist/hooks/magic-context/producer-window-guard.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +6 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts +8 -0
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-formatting.d.ts +6 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +30 -0
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-refusal-recovery.d.ts +28 -0
- package/dist/hooks/magic-context/rust-refusal-recovery.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +7 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/{index-jkrqhc7y.js → index-a9ssj59b.js} +94 -15
- package/dist/{index-3wbd8sdq.js → index-djp6rwz6.js} +455 -46
- package/dist/{index-p474rw9p.js → index-ngjmj6xx.js} +1 -1
- package/dist/{index-d8mgqezq.js → index-s61hh7gv.js} +50 -17
- package/dist/{index-1ar7b3e9.js → index-znraa0kv.js} +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1485 -360
- package/dist/plugin/embedding-bootstrap.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/memory-id-translation.d.ts +23 -0
- package/dist/plugin/memory-id-translation.d.ts.map +1 -0
- package/dist/plugin/rust-tool-backends.d.ts +1 -1
- package/dist/plugin/rust-tool-backends.d.ts.map +1 -1
- package/dist/{recomp-orchestrator-k20sfpm2.js → recomp-orchestrator-0xx1364v.js} +4 -4
- package/dist/{send-session-notification-xnypkxpx.js → send-session-notification-jbxknvar.js} +2 -2
- package/dist/shared/auto-update-provenance.d.ts +9 -0
- package/dist/shared/auto-update-provenance.d.ts.map +1 -0
- package/dist/shared/conflict-detector.d.ts +5 -1
- package/dist/shared/conflict-detector.d.ts.map +1 -1
- package/dist/shared/opencode-db-path.d.ts +31 -2
- package/dist/shared/opencode-db-path.d.ts.map +1 -1
- package/dist/shared/prompt-surface-runtime.d.ts +3 -3
- package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
- package/dist/{storage-meta-session-x3j0q9qy.js → storage-meta-session-z818pn1e.js} +2 -2
- package/dist/tools/ctx-expand/mode.d.ts +31 -0
- package/dist/tools/ctx-expand/mode.d.ts.map +1 -0
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/constants.d.ts +1 -1
- package/dist/tools/ctx-note/constants.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/types.d.ts +1 -1
- package/dist/tools/ctx-note/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/types.d.ts +1 -1
- package/dist/tools/ctx-search/types.d.ts.map +1 -1
- package/dist/tools/light-descriptions.d.ts +2 -2
- package/dist/tools/light-descriptions.d.ts.map +1 -1
- package/dist/v2/hidden-completion.d.ts +69 -13
- package/dist/v2/hidden-completion.d.ts.map +1 -1
- package/dist/v2/hooks/context.d.ts +13 -1
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/hidden-child.d.ts +31 -0
- package/dist/v2/hooks/hidden-child.d.ts.map +1 -0
- package/dist/v2/hooks/store.d.ts.map +1 -1
- package/dist/v2/hooks/types.d.ts +99 -19
- package/dist/v2/hooks/types.d.ts.map +1 -1
- package/dist/v2/server.d.ts +19 -0
- package/dist/v2/server.d.ts.map +1 -1
- package/dist/v2/server.js +1781 -253
- package/dist/v2/store-reader.d.ts +11 -5
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/v2/tui/index.d.ts +10 -0
- package/dist/v2/tui/index.d.ts.map +1 -0
- package/dist/v2/tui/types.d.ts +80 -0
- package/dist/v2/tui/types.d.ts.map +1 -0
- package/package.json +5 -4
- package/src/agents/magic-context-prompt.ts +1 -1
- package/src/config/index.ts +31 -1
- package/src/config/protected-tokens.test.ts +40 -0
- package/src/config/schema/magic-context.ts +8 -3
- package/src/shared/auto-update-provenance.ts +42 -0
- package/src/shared/conflict-detector.test.ts +53 -0
- package/src/shared/conflict-detector.ts +88 -19
- package/src/shared/models-dev-cache.test.ts +25 -0
- package/src/shared/opencode-db-path.test.ts +96 -0
- package/src/shared/opencode-db-path.ts +146 -15
- package/src/shared/prompt-surface-a1-golden.md +12 -16
- package/src/shared/prompt-surface-runtime.test.ts +20 -0
- package/src/shared/prompt-surface-runtime.ts +7 -5
- package/src/tui/entry.mjs +11 -1
- package/src/v2/tui/host-contract.test.ts +202 -0
- package/src/v2/tui/index.ts +270 -0
- package/src/v2/tui/types.ts +67 -0
package/dist/v2/server.js
CHANGED
|
@@ -53526,6 +53526,13 @@ function parseJsonc(content, options = {}) {
|
|
|
53526
53526
|
const normalized = stripTrailingCommas(stripJsonComments(content));
|
|
53527
53527
|
return sanitizeParsedJson(JSON.parse(normalized), options);
|
|
53528
53528
|
}
|
|
53529
|
+
function readJsoncFile(filePath) {
|
|
53530
|
+
try {
|
|
53531
|
+
return parseJsonc(readFileSync(filePath, "utf-8"));
|
|
53532
|
+
} catch (_error) {
|
|
53533
|
+
return null;
|
|
53534
|
+
}
|
|
53535
|
+
}
|
|
53529
53536
|
function detectConfigFile(basePath) {
|
|
53530
53537
|
const jsoncPath = `${basePath}.jsonc`;
|
|
53531
53538
|
const jsonPath = `${basePath}.json`;
|
|
@@ -59744,6 +59751,7 @@ var DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65;
|
|
|
59744
59751
|
var EXECUTE_THRESHOLD_CAP_MESSAGE = "execute_threshold is capped at 90% for cache safety: output capacity is reserved from the usable context window, and the remaining 10% absorbs mid-turn growth before the absolute 95% emergency wall. Use a value between 20 and 90.";
|
|
59745
59752
|
var DEFAULT_HISTORIAN_TIMEOUT_MS = 600000;
|
|
59746
59753
|
var DEFAULT_HISTORY_BUDGET_PERCENTAGE = 0.15;
|
|
59754
|
+
var PROTECTED_TOKENS_MIN = 4000;
|
|
59747
59755
|
var DEFAULT_LOCAL_EMBEDDING_MODEL = "Xenova/all-MiniLM-L6-v2";
|
|
59748
59756
|
var PiThinkingLevelSchema = _enum(["off", "minimal", "low", "medium", "high", "xhigh", "max"]).optional();
|
|
59749
59757
|
var OmpThinkingLevelSchema = _enum(["off", "minimal", "low", "medium", "high", "xhigh", "max", "inherit", "auto"]).optional();
|
|
@@ -60113,8 +60121,8 @@ var MagicContextConfigSchema = object({
|
|
|
60113
60121
|
smart_notes: object({
|
|
60114
60122
|
retina_handoff: boolean2().default(false).describe("When true, dreamer skips smart notes whose surface conditions compiled to retina provider configs at authoring time. Default false keeps both paths active until the retina consumer is deployed.")
|
|
60115
60123
|
}).default({ retina_handoff: false }).describe("Smart-note ownership transition controls."),
|
|
60116
|
-
cache_ttl: union([string2(), object({ default: string2() }).catchall(string2())]).default("5m").describe(`How long Magic Context assumes the provider's cached prefix stays valid. This is MC's own deferral gate — it does not change the provider's actual cache lifetime. String (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "model
|
|
60117
|
-
prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe("Prompt-surface presets: default is full; models use bare model IDs, provider/model, or provider/* routing keys. Guidance and tool-description overrides are user-level only.
|
|
60124
|
+
cache_ttl: union([string2(), object({ default: string2() }).catchall(string2())]).default("5m").describe(`How long Magic Context assumes the provider's cached prefix stays valid. This is MC's own deferral gate — it does not change the provider's actual cache lifetime. String (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "provider/model": "1h", "provider/*": "never" }); keys resolve most-specific first (exact provider/model, bare model ID, shorter dash-prefixes, then the provider/* wildcard, then default). Set to "never" to mean MC never assumes expiry (for lanes kept warm externally by a cache-keep tool) — disables the idle-TTL heuristic so MC never initiates a rebuild based on elapsed time. Provider-side extended TTL is a separate request-level concern (cache_control: { ttl } in the request body).`),
|
|
60125
|
+
prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe("Prompt-surface presets: default is full; models use bare model IDs, provider/model, or provider/* routing keys. Guidance and tool-description overrides are user-level only. OpenCode 1.x, Pi, and OMP register tool descriptions once per process (they follow the default preset). OpenCode 2 rewrites the five ctx_* descriptions per request from the draft model."),
|
|
60118
60126
|
output_reserve: union([
|
|
60119
60127
|
number2().min(0),
|
|
60120
60128
|
object({ default: number2().min(0) }).catchall(number2().min(0))
|
|
@@ -60130,7 +60138,7 @@ var MagicContextConfigSchema = object({
|
|
|
60130
60138
|
execute_threshold_tokens: object({
|
|
60131
60139
|
default: number2().min(5000).max(2000000).optional()
|
|
60132
60140
|
}).catchall(number2().min(5000).max(2000000)).optional().describe("Absolute token thresholds per model. When matched, overrides execute_threshold_percentage for that model. Accepts `default` for all models or per-model keys. Values above 90% × context_limit are clamped with a warning log. Min 5_000, max 2_000_000."),
|
|
60133
|
-
protected_tokens: number2().int().min(
|
|
60141
|
+
protected_tokens: number2().int().min(PROTECTED_TOKENS_MIN).max(1e6).optional().describe("Positive integer token floor to protect from automatic reclaim (min: 4_000, max: 1_000_000). When omitted, the derived default is clamp(round(0.05 × usableSoft), min(16_000, round(0.08 × usableSoft)), 64_000)."),
|
|
60134
60142
|
protected_tags: unknown().optional().describe("Deprecated: number of recent tags to protect. Ignored for behaviour; use protected_tokens instead.").meta({ deprecated: true }),
|
|
60135
60143
|
clear_reasoning_age: number2().min(10).default(50).describe("Clear reasoning/thinking blocks older than N tags (default: 50)"),
|
|
60136
60144
|
history_budget_percentage: number2().min(0.05).max(0.5).default(DEFAULT_HISTORY_BUDGET_PERCENTAGE).describe("Fraction of usable context (context_limit × execute_threshold) reserved for the session history block (default: 0.15)"),
|
|
@@ -61449,6 +61457,9 @@ function redactConfigValue(value) {
|
|
|
61449
61457
|
return typeof value;
|
|
61450
61458
|
}
|
|
61451
61459
|
var warnedProtectedTagsDeprecation = false;
|
|
61460
|
+
function formatProtectedTokensBelowMinWarning(value) {
|
|
61461
|
+
return `protected_tokens is a token floor (minimum ${PROTECTED_TOKENS_MIN}, default derived from the context window); ${value} looks like the old protected_tags count. Remove the key to use the default, or set a token count such as 16000.`;
|
|
61462
|
+
}
|
|
61452
61463
|
function warnProtectedTagsDeprecationOnce() {
|
|
61453
61464
|
if (!warnedProtectedTagsDeprecation) {
|
|
61454
61465
|
warnedProtectedTagsDeprecation = true;
|
|
@@ -61539,6 +61550,11 @@ function parsePluginConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
|
61539
61550
|
delete patched[key];
|
|
61540
61551
|
const defaultVal = defaults[key];
|
|
61541
61552
|
const reason = customMessagesByKey.get(key);
|
|
61553
|
+
const invalidRawValue = rawConfig[key];
|
|
61554
|
+
if (key === "protected_tokens" && typeof invalidRawValue === "number" && invalidRawValue < PROTECTED_TOKENS_MIN) {
|
|
61555
|
+
warnings.push(formatProtectedTokensBelowMinWarning(invalidRawValue));
|
|
61556
|
+
continue;
|
|
61557
|
+
}
|
|
61542
61558
|
warnings.push(`"${key}": invalid value (${redactConfigValue(rawConfig[key])}), using default ${JSON.stringify(defaultVal)}.${reason ? ` ${reason}` : ""}`);
|
|
61543
61559
|
}
|
|
61544
61560
|
const retryMigrated = migrateLegacyAgentEnabledInMemory(migrateDreamerV2(migrateLegacyExperimental(patched, preMigrationWarnings), preMigrationWarnings), preMigrationWarnings);
|
|
@@ -61732,6 +61748,10 @@ function loadPluginConfigDetailed(directory) {
|
|
|
61732
61748
|
cacheTtlConfigured
|
|
61733
61749
|
};
|
|
61734
61750
|
}
|
|
61751
|
+
|
|
61752
|
+
// src/v2/server.ts
|
|
61753
|
+
init_logger();
|
|
61754
|
+
|
|
61735
61755
|
// src/features/magic-context/memory/project-identity.ts
|
|
61736
61756
|
init_logger();
|
|
61737
61757
|
import { execFileSync } from "node:child_process";
|
|
@@ -64109,6 +64129,28 @@ async function pullAndApplyMirrorPageWithStatus(args) {
|
|
|
64109
64129
|
limit
|
|
64110
64130
|
});
|
|
64111
64131
|
const nextCursor = applyMirrorPage({ db: args.db, page: response.page });
|
|
64132
|
+
if (args.domain === "memories" && args.module.memoryIdentityAck) {
|
|
64133
|
+
const rowsByProject = new Map;
|
|
64134
|
+
for (const feed of response.page.rows) {
|
|
64135
|
+
if (feed.domain !== "memories" || feed.op === "tombstone")
|
|
64136
|
+
continue;
|
|
64137
|
+
const project = rowString(feed.full_row_snapshot, "project_path");
|
|
64138
|
+
if (!project)
|
|
64139
|
+
continue;
|
|
64140
|
+
const identity = mirrorIdentity(args.db, "memories", project, feed.module_row_id);
|
|
64141
|
+
if (!identity)
|
|
64142
|
+
continue;
|
|
64143
|
+
const rows = rowsByProject.get(project) ?? [];
|
|
64144
|
+
rows.push({
|
|
64145
|
+
module_row_id: feed.module_row_id,
|
|
64146
|
+
context_row_id: identity.context_row_id
|
|
64147
|
+
});
|
|
64148
|
+
rowsByProject.set(project, rows);
|
|
64149
|
+
}
|
|
64150
|
+
for (const [project, rows] of rowsByProject) {
|
|
64151
|
+
await args.module.memoryIdentityAck({ project, rows });
|
|
64152
|
+
}
|
|
64153
|
+
}
|
|
64112
64154
|
return {
|
|
64113
64155
|
cursor: nextCursor,
|
|
64114
64156
|
hasMore: response.page.has_more,
|
|
@@ -64222,6 +64264,25 @@ function extractTexts(parts) {
|
|
|
64222
64264
|
}
|
|
64223
64265
|
return texts;
|
|
64224
64266
|
}
|
|
64267
|
+
function extractToolResultBodyTokens(parts) {
|
|
64268
|
+
let tokens = 0;
|
|
64269
|
+
for (const part of parts) {
|
|
64270
|
+
if (part === null || typeof part !== "object")
|
|
64271
|
+
continue;
|
|
64272
|
+
const p = part;
|
|
64273
|
+
if (p.type !== "tool")
|
|
64274
|
+
continue;
|
|
64275
|
+
const state = p.state;
|
|
64276
|
+
if (!state || typeof state !== "object")
|
|
64277
|
+
continue;
|
|
64278
|
+
const body = state.output ?? state.error;
|
|
64279
|
+
if (body === undefined)
|
|
64280
|
+
continue;
|
|
64281
|
+
const text = typeof body === "string" ? body : JSON.stringify(body);
|
|
64282
|
+
tokens += Math.ceil(text.length / 4);
|
|
64283
|
+
}
|
|
64284
|
+
return tokens;
|
|
64285
|
+
}
|
|
64225
64286
|
function extractToolCallSummaries(parts) {
|
|
64226
64287
|
const summaries = [];
|
|
64227
64288
|
for (const part of parts) {
|
|
@@ -65409,7 +65470,7 @@ function refreshTailHygieneBaseline(input) {
|
|
|
65409
65470
|
for (let index = input.previous.baselineParts.length;index < measured.parts.length; index += 1) {
|
|
65410
65471
|
const part = measured.parts[index];
|
|
65411
65472
|
turnDeltaT += part.tokens;
|
|
65412
|
-
if (part.kind !== "toolOutput")
|
|
65473
|
+
if (part.kind !== "toolOutput" || !part.protected)
|
|
65413
65474
|
turnDeltaU += part.uTokens;
|
|
65414
65475
|
}
|
|
65415
65476
|
return {
|
|
@@ -66477,15 +66538,16 @@ import { isAbsolute as isAbsolute4, join as join7 } from "node:path";
|
|
|
66477
66538
|
var cachedResolution = null;
|
|
66478
66539
|
var lastReadFailure = null;
|
|
66479
66540
|
var claimedDiagnostics = new Set;
|
|
66480
|
-
function openCodeDataDir() {
|
|
66481
|
-
return join7(
|
|
66541
|
+
function openCodeDataDir(env = process.env, dataHome) {
|
|
66542
|
+
return join7(dataHome ?? env.XDG_DATA_HOME ?? join7(homedir8(), ".local", "share"), "opencode");
|
|
66482
66543
|
}
|
|
66483
|
-
function environmentKey(dataDir) {
|
|
66544
|
+
function environmentKey(dataDir, hostGeneration, channel, env) {
|
|
66484
66545
|
return [
|
|
66546
|
+
hostGeneration,
|
|
66485
66547
|
dataDir,
|
|
66486
|
-
|
|
66487
|
-
|
|
66488
|
-
|
|
66548
|
+
env.OPENCODE_DB ?? "",
|
|
66549
|
+
env.OPENCODE_DISABLE_CHANNEL_DB ?? "",
|
|
66550
|
+
channel ?? env.OPENCODE_CHANNEL ?? ""
|
|
66489
66551
|
].join("\x00");
|
|
66490
66552
|
}
|
|
66491
66553
|
function channelPath(dataDir, channel) {
|
|
@@ -66517,8 +66579,8 @@ function discoverOpenCodeDb(dataDir) {
|
|
|
66517
66579
|
const channel = name === "opencode.db" ? null : name.slice("opencode-".length, -".db".length) || null;
|
|
66518
66580
|
return { path: existing.path, source: "discovered", channel };
|
|
66519
66581
|
}
|
|
66520
|
-
function
|
|
66521
|
-
const explicit =
|
|
66582
|
+
function resolveV1Fresh(dataDir, env = process.env) {
|
|
66583
|
+
const explicit = env.OPENCODE_DB;
|
|
66522
66584
|
if (explicit !== undefined && explicit.length > 0) {
|
|
66523
66585
|
if (explicit === ":memory:") {
|
|
66524
66586
|
return { path: explicit, source: "OPENCODE_DB", channel: null };
|
|
@@ -66529,24 +66591,47 @@ function resolveFresh(dataDir) {
|
|
|
66529
66591
|
channel: null
|
|
66530
66592
|
};
|
|
66531
66593
|
}
|
|
66532
|
-
const disableChannelDb =
|
|
66594
|
+
const disableChannelDb = env.OPENCODE_DISABLE_CHANNEL_DB;
|
|
66533
66595
|
if (disableChannelDb === "1" || disableChannelDb === "true") {
|
|
66534
66596
|
return { path: join7(dataDir, "opencode.db"), source: "default", channel: null };
|
|
66535
66597
|
}
|
|
66536
|
-
const channel =
|
|
66598
|
+
const channel = env.OPENCODE_CHANNEL;
|
|
66537
66599
|
if (channel !== undefined && channel.length > 0) {
|
|
66538
66600
|
return { path: channelPath(dataDir, channel), source: "channel", channel };
|
|
66539
66601
|
}
|
|
66540
66602
|
return discoverOpenCodeDb(dataDir);
|
|
66541
66603
|
}
|
|
66542
|
-
function
|
|
66543
|
-
|
|
66544
|
-
|
|
66604
|
+
function sourceOpenCodeDatabaseFilename(hostGeneration, channel, env = process.env) {
|
|
66605
|
+
if (hostGeneration === "v1") {
|
|
66606
|
+
const explicit = env.OPENCODE_DB;
|
|
66607
|
+
if (explicit !== undefined && explicit.length > 0)
|
|
66608
|
+
return explicit;
|
|
66609
|
+
if (env.OPENCODE_DISABLE_CHANNEL_DB === "1" || env.OPENCODE_DISABLE_CHANNEL_DB === "true") {
|
|
66610
|
+
return "opencode.db";
|
|
66611
|
+
}
|
|
66612
|
+
return ["latest", "beta", "prod"].includes(channel) ? "opencode.db" : `opencode-${channel}.db`;
|
|
66613
|
+
}
|
|
66614
|
+
return env.OPENCODE_DB ?? (["latest", "dev", "beta", "next", "prod"].includes(channel) || env.OPENCODE_DISABLE_CHANNEL_DB === "1" || env.OPENCODE_DISABLE_CHANNEL_DB === "true" ? "opencode.db" : `opencode-${channel.replace(/[^a-zA-Z0-9._-]/g, "")}.db`);
|
|
66615
|
+
}
|
|
66616
|
+
function resolveV2Fresh(dataDir, channel, env) {
|
|
66617
|
+
const filename = sourceOpenCodeDatabaseFilename("v2", channel, env);
|
|
66618
|
+
const explicit = env.OPENCODE_DB !== undefined;
|
|
66619
|
+
return {
|
|
66620
|
+
path: filename === ":memory:" ? filename : join7(dataDir, filename),
|
|
66621
|
+
source: explicit ? "OPENCODE_DB" : env.OPENCODE_CHANNEL ? "channel" : "default",
|
|
66622
|
+
channel: explicit ? null : channel
|
|
66623
|
+
};
|
|
66624
|
+
}
|
|
66625
|
+
function resolveOpenCodeDbPath(hostGeneration = "v1", options = {}) {
|
|
66626
|
+
const env = options.env ?? process.env;
|
|
66627
|
+
const dataDir = openCodeDataDir(env, options.dataHome);
|
|
66628
|
+
const channel = options.channel ?? env.OPENCODE_CHANNEL;
|
|
66629
|
+
const key = environmentKey(dataDir, hostGeneration, channel, env);
|
|
66545
66630
|
if (cachedResolution?.key === key && (!cachedResolution.existed || existsSync8(cachedResolution.resolution.path))) {
|
|
66546
66631
|
if (cachedResolution.existed)
|
|
66547
66632
|
return cachedResolution.resolution;
|
|
66548
66633
|
}
|
|
66549
|
-
const resolution =
|
|
66634
|
+
const resolution = hostGeneration === "v2" ? resolveV2Fresh(dataDir, channel ?? "latest", env) : resolveV1Fresh(dataDir, env);
|
|
66550
66635
|
cachedResolution = {
|
|
66551
66636
|
key,
|
|
66552
66637
|
resolution,
|
|
@@ -66554,6 +66639,29 @@ function resolveOpenCodeDbPath() {
|
|
|
66554
66639
|
};
|
|
66555
66640
|
return resolution;
|
|
66556
66641
|
}
|
|
66642
|
+
function schemaTableNames(db, schema = "main") {
|
|
66643
|
+
const rows = db.prepare(`SELECT name FROM ${schema}.sqlite_master WHERE type = 'table' AND name IN ('message', 'part', 'session', 'project', 'session_message')`).all();
|
|
66644
|
+
return new Set(rows.flatMap((row) => typeof row.name === "string" ? [row.name] : []));
|
|
66645
|
+
}
|
|
66646
|
+
function detectOpenCodeStoreGeneration(db, schema = "main") {
|
|
66647
|
+
const tables = schemaTableNames(db, schema);
|
|
66648
|
+
const hasV1Messages = tables.has("message") && tables.has("part");
|
|
66649
|
+
if (hasV1Messages)
|
|
66650
|
+
return "v1";
|
|
66651
|
+
if (tables.has("session_message"))
|
|
66652
|
+
return "v2";
|
|
66653
|
+
if (tables.has("session") || tables.has("project"))
|
|
66654
|
+
return "v1";
|
|
66655
|
+
return "unknown";
|
|
66656
|
+
}
|
|
66657
|
+
function assertOpenCodeStoreGeneration(db, expected, path, schema = "main") {
|
|
66658
|
+
const actual = detectOpenCodeStoreGeneration(db, schema);
|
|
66659
|
+
if (actual === expected)
|
|
66660
|
+
return;
|
|
66661
|
+
if (actual === "unknown")
|
|
66662
|
+
return;
|
|
66663
|
+
throw new Error(`OpenCode store generation mismatch at ${path}: expected ${expected}, found ${actual}; refusing generation-specific database access`);
|
|
66664
|
+
}
|
|
66557
66665
|
function openCodeDbPathExists(resolution = resolveOpenCodeDbPath()) {
|
|
66558
66666
|
return resolution.path !== ":memory:" && existsSync8(resolution.path);
|
|
66559
66667
|
}
|
|
@@ -66611,6 +66719,12 @@ function getReadOnlySessionDb() {
|
|
|
66611
66719
|
}
|
|
66612
66720
|
closeCachedReadOnlyDb();
|
|
66613
66721
|
const db = new Database(dbPath, { readonly: true });
|
|
66722
|
+
try {
|
|
66723
|
+
assertOpenCodeStoreGeneration(db, "v1", dbPath);
|
|
66724
|
+
} catch (error) {
|
|
66725
|
+
closeQuietly(db);
|
|
66726
|
+
throw error;
|
|
66727
|
+
}
|
|
66614
66728
|
cachedReadOnlyDb = { path: dbPath, db };
|
|
66615
66729
|
clearOpenCodeDbReadFailure();
|
|
66616
66730
|
return db;
|
|
@@ -67002,6 +67116,20 @@ function countRawSessionMessageOrdinalsFromDb(db, sessionId) {
|
|
|
67002
67116
|
)`).get(sessionId);
|
|
67003
67117
|
return typeof row?.count === "number" ? row.count : 0;
|
|
67004
67118
|
}
|
|
67119
|
+
function readRawSessionMessageIdOrdinalsFromDb(db, sessionId) {
|
|
67120
|
+
const messageRows = db.prepare("SELECT id, data FROM message WHERE session_id = ? ORDER BY time_created ASC, id ASC").all(sessionId).filter(isRawMessageRow);
|
|
67121
|
+
const ordinalById = new Map;
|
|
67122
|
+
let ordinal = 0;
|
|
67123
|
+
for (const row of messageRows) {
|
|
67124
|
+
const info = parseJsonRecord(row.data);
|
|
67125
|
+
if (isRawCompactionSummaryInfo(info))
|
|
67126
|
+
continue;
|
|
67127
|
+
ordinal += 1;
|
|
67128
|
+
if (info)
|
|
67129
|
+
ordinalById.set(row.id, ordinal);
|
|
67130
|
+
}
|
|
67131
|
+
return ordinalById;
|
|
67132
|
+
}
|
|
67005
67133
|
function readRawSessionMessageOrdinalPageFromDb(db, sessionId, after, limit) {
|
|
67006
67134
|
const pageSize = Math.max(1, Math.floor(limit));
|
|
67007
67135
|
const rows = (after ? db.prepare(`SELECT id, data, time_created
|
|
@@ -68260,6 +68388,17 @@ function getRawSessionStoredMessageCount(sessionId) {
|
|
|
68260
68388
|
return 0;
|
|
68261
68389
|
return withReadOnlySessionDb((db) => countStoredRawSessionMessagesFromDb(db, sessionId));
|
|
68262
68390
|
}
|
|
68391
|
+
function readRawSessionMessageIdOrdinals(sessionId) {
|
|
68392
|
+
const provider = sessionProviders.get(sessionId);
|
|
68393
|
+
if (provider?.readMessageIdOrdinals)
|
|
68394
|
+
return provider.readMessageIdOrdinals();
|
|
68395
|
+
if (provider) {
|
|
68396
|
+
return new Map(provider.readMessages().map((message) => [message.id, message.ordinal]));
|
|
68397
|
+
}
|
|
68398
|
+
if (!openCodeDbExists())
|
|
68399
|
+
return new Map;
|
|
68400
|
+
return withReadOnlySessionDb((db) => readRawSessionMessageIdOrdinalsFromDb(db, sessionId));
|
|
68401
|
+
}
|
|
68263
68402
|
function readRawSessionMessagePartsById(sessionId, messageId, onQuery) {
|
|
68264
68403
|
const provider = sessionProviders.get(sessionId);
|
|
68265
68404
|
if (provider?.readMessagePartsById)
|
|
@@ -68427,6 +68566,14 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
68427
68566
|
const totalMessageCount = getCachedAbsoluteMessageCount(sessionId) ?? messages.length;
|
|
68428
68567
|
const startOrdinal = Math.max(1, offset);
|
|
68429
68568
|
const completedToolArcs = buildToolArcs(messages).flatMap((arc) => arc.resOrdinal === null ? [] : [{ start: arc.invOrdinal, end: arc.resOrdinal }]);
|
|
68569
|
+
const completedToolComponents = [];
|
|
68570
|
+
for (const arc of completedToolArcs) {
|
|
68571
|
+
const component = completedToolComponents[completedToolComponents.length - 1];
|
|
68572
|
+
if (component && arc.start <= component.end)
|
|
68573
|
+
component.end = Math.max(component.end, arc.end);
|
|
68574
|
+
else
|
|
68575
|
+
completedToolComponents.push({ ...arc });
|
|
68576
|
+
}
|
|
68430
68577
|
const lines = [];
|
|
68431
68578
|
const lineMeta = [];
|
|
68432
68579
|
const flushedToolOnlyBlocks = [];
|
|
@@ -68440,6 +68587,25 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
68440
68587
|
let pendingNoiseMeta = [];
|
|
68441
68588
|
let commitClusters = 0;
|
|
68442
68589
|
let lastFlushedRole = "";
|
|
68590
|
+
let admittedOversizeComponentEnd = null;
|
|
68591
|
+
let currentBlockApproxTokens = 0;
|
|
68592
|
+
let formattedBudgetCrossed = false;
|
|
68593
|
+
let sourceCharacters = 0;
|
|
68594
|
+
const toolResultBoundaries = [];
|
|
68595
|
+
function pinComponentWhenFormattedBudgetCrosses(ordinal, appendedText) {
|
|
68596
|
+
if (admittedOversizeComponentEnd !== null || formattedBudgetCrossed || !currentBlock)
|
|
68597
|
+
return;
|
|
68598
|
+
currentBlockApproxTokens += estimateTokens(appendedText) + (currentBlock.parts.length > 1 ? 1 : 0);
|
|
68599
|
+
if (totalTokens + currentBlockApproxTokens + 64 <= tokenBudget)
|
|
68600
|
+
return;
|
|
68601
|
+
const previewTokens = totalTokens + estimateTokens(formatBlock(currentBlock));
|
|
68602
|
+
if (previewTokens <= tokenBudget)
|
|
68603
|
+
return;
|
|
68604
|
+
formattedBudgetCrossed = true;
|
|
68605
|
+
const component = completedToolComponents.find((candidate) => candidate.start <= ordinal && candidate.end >= ordinal);
|
|
68606
|
+
if (component)
|
|
68607
|
+
admittedOversizeComponentEnd = component.end;
|
|
68608
|
+
}
|
|
68443
68609
|
function recordFilteredNoise(meta) {
|
|
68444
68610
|
pendingNoiseMeta.push(meta);
|
|
68445
68611
|
if (!currentBlock) {
|
|
@@ -68466,7 +68632,23 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
68466
68632
|
highestScannedOrdinal = Math.max(highestScannedOrdinal, lastOrdinal);
|
|
68467
68633
|
lastMessageId = currentBlock.meta[currentBlock.meta.length - 1]?.messageId ?? "";
|
|
68468
68634
|
messagesProcessed += currentBlock.meta.length;
|
|
68635
|
+
const lineStart = sourceCharacters + (lines.length > 0 ? 1 : 0);
|
|
68636
|
+
const renderedParts = currentBlock.parts.join(" / ");
|
|
68637
|
+
let partOffset = lineStart + (blockText.length - renderedParts.length);
|
|
68638
|
+
for (let index = 0;index < currentBlock.parts.length; index++) {
|
|
68639
|
+
const part = currentBlock.parts[index] ?? "";
|
|
68640
|
+
const partMeta = currentBlock.partMeta[index];
|
|
68641
|
+
if (partMeta && partMeta.toolResultBodyTokens > 0) {
|
|
68642
|
+
toolResultBoundaries.push({
|
|
68643
|
+
ordinal: partMeta.ordinal,
|
|
68644
|
+
sourceOffset: partOffset,
|
|
68645
|
+
bodyTokens: partMeta.toolResultBodyTokens
|
|
68646
|
+
});
|
|
68647
|
+
}
|
|
68648
|
+
partOffset += part.length + (index + 1 < currentBlock.parts.length ? 3 : 0);
|
|
68649
|
+
}
|
|
68469
68650
|
lines.push(blockText);
|
|
68651
|
+
sourceCharacters = lineStart + blockText.length;
|
|
68470
68652
|
lineMeta.push(...currentBlock.meta);
|
|
68471
68653
|
totalTokens += blockTokens;
|
|
68472
68654
|
if (currentBlock.isToolOnly) {
|
|
@@ -68476,11 +68658,15 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
68476
68658
|
});
|
|
68477
68659
|
}
|
|
68478
68660
|
currentBlock = null;
|
|
68661
|
+
currentBlockApproxTokens = 0;
|
|
68479
68662
|
return true;
|
|
68480
68663
|
}
|
|
68481
68664
|
for (const msg of messages) {
|
|
68482
68665
|
if (eligibleEndOrdinal !== undefined && msg.ordinal >= eligibleEndOrdinal)
|
|
68483
68666
|
break;
|
|
68667
|
+
if (admittedOversizeComponentEnd !== null && msg.ordinal > admittedOversizeComponentEnd) {
|
|
68668
|
+
break;
|
|
68669
|
+
}
|
|
68484
68670
|
if (msg.ordinal < startOrdinal)
|
|
68485
68671
|
continue;
|
|
68486
68672
|
const meta = { ordinal: msg.ordinal, messageId: msg.id };
|
|
@@ -68494,6 +68680,10 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
68494
68680
|
if (currentBlock && currentBlock.role === "A") {
|
|
68495
68681
|
currentBlock.endOrdinal = msg.ordinal;
|
|
68496
68682
|
currentBlock.parts.push(tcText);
|
|
68683
|
+
currentBlock.partMeta.push({
|
|
68684
|
+
ordinal: msg.ordinal,
|
|
68685
|
+
toolResultBodyTokens: extractToolResultBodyTokens(msg.parts)
|
|
68686
|
+
});
|
|
68497
68687
|
currentBlock.meta.push(...pendingNoiseMeta, meta);
|
|
68498
68688
|
pendingNoiseMeta = [];
|
|
68499
68689
|
} else {
|
|
@@ -68504,12 +68694,19 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
68504
68694
|
startOrdinal: pendingNoiseMeta[0]?.ordinal ?? msg.ordinal,
|
|
68505
68695
|
endOrdinal: msg.ordinal,
|
|
68506
68696
|
parts: [tcText],
|
|
68697
|
+
partMeta: [
|
|
68698
|
+
{
|
|
68699
|
+
ordinal: msg.ordinal,
|
|
68700
|
+
toolResultBodyTokens: extractToolResultBodyTokens(msg.parts)
|
|
68701
|
+
}
|
|
68702
|
+
],
|
|
68507
68703
|
meta: [...pendingNoiseMeta, meta],
|
|
68508
68704
|
commitHashes: [],
|
|
68509
68705
|
isToolOnly: true
|
|
68510
68706
|
};
|
|
68511
68707
|
pendingNoiseMeta = [];
|
|
68512
68708
|
}
|
|
68709
|
+
pinComponentWhenFormattedBudgetCrosses(msg.ordinal, tcText);
|
|
68513
68710
|
continue;
|
|
68514
68711
|
}
|
|
68515
68712
|
const role = compactRole(msg.role);
|
|
@@ -68526,11 +68723,16 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
68526
68723
|
if (currentBlock && currentBlock.role === role) {
|
|
68527
68724
|
currentBlock.endOrdinal = msg.ordinal;
|
|
68528
68725
|
currentBlock.parts.push(text);
|
|
68726
|
+
currentBlock.partMeta.push({
|
|
68727
|
+
ordinal: msg.ordinal,
|
|
68728
|
+
toolResultBodyTokens: extractToolResultBodyTokens(msg.parts)
|
|
68729
|
+
});
|
|
68529
68730
|
currentBlock.meta.push(...pendingNoiseMeta, meta);
|
|
68530
68731
|
currentBlock.commitHashes = mergeCommitHashes(currentBlock.commitHashes, compacted.commitHashes);
|
|
68531
68732
|
if (msgHasNarrative)
|
|
68532
68733
|
currentBlock.isToolOnly = false;
|
|
68533
68734
|
pendingNoiseMeta = [];
|
|
68735
|
+
pinComponentWhenFormattedBudgetCrosses(msg.ordinal, text);
|
|
68534
68736
|
continue;
|
|
68535
68737
|
}
|
|
68536
68738
|
if (!flushCurrentBlock())
|
|
@@ -68540,11 +68742,18 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
68540
68742
|
startOrdinal: pendingNoiseMeta[0]?.ordinal ?? msg.ordinal,
|
|
68541
68743
|
endOrdinal: msg.ordinal,
|
|
68542
68744
|
parts: [text],
|
|
68745
|
+
partMeta: [
|
|
68746
|
+
{
|
|
68747
|
+
ordinal: msg.ordinal,
|
|
68748
|
+
toolResultBodyTokens: extractToolResultBodyTokens(msg.parts)
|
|
68749
|
+
}
|
|
68750
|
+
],
|
|
68543
68751
|
meta: [...pendingNoiseMeta, meta],
|
|
68544
68752
|
commitHashes: [...compacted.commitHashes],
|
|
68545
68753
|
isToolOnly: !msgHasNarrative
|
|
68546
68754
|
};
|
|
68547
68755
|
pendingNoiseMeta = [];
|
|
68756
|
+
pinComponentWhenFormattedBudgetCrosses(msg.ordinal, text);
|
|
68548
68757
|
}
|
|
68549
68758
|
if (flushCurrentBlock() && pendingNoiseMeta.length > 0) {
|
|
68550
68759
|
highestScannedOrdinal = Math.max(highestScannedOrdinal, pendingNoiseMeta[pendingNoiseMeta.length - 1]?.ordinal ?? highestScannedOrdinal);
|
|
@@ -68575,7 +68784,8 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
68575
68784
|
...messagesProcessed === 0 && text.length === 0 ? { filteredNoiseLines: pendingNoiseMeta } : {},
|
|
68576
68785
|
commitClusterCount: commitClusters,
|
|
68577
68786
|
toolOnlyRanges,
|
|
68578
|
-
completedToolArcs
|
|
68787
|
+
completedToolArcs,
|
|
68788
|
+
toolResultBoundaries
|
|
68579
68789
|
};
|
|
68580
68790
|
}
|
|
68581
68791
|
function readRawSessionSeedTail(sessionId, boundaryId, onQuery) {
|
|
@@ -69537,6 +69747,114 @@ function isSqliteLockError(error) {
|
|
|
69537
69747
|
function tableExists2(db, name) {
|
|
69538
69748
|
return Boolean(db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = ?").get(name));
|
|
69539
69749
|
}
|
|
69750
|
+
function tableHasHarnessColumn(db, name) {
|
|
69751
|
+
if (!tableExists2(db, name))
|
|
69752
|
+
return false;
|
|
69753
|
+
return db.prepare(`PRAGMA table_info(${name})`).all().some((column) => column.name === "harness");
|
|
69754
|
+
}
|
|
69755
|
+
var V85_OPENCODE2_RELABEL_TABLES = [
|
|
69756
|
+
"tags",
|
|
69757
|
+
"pending_ops",
|
|
69758
|
+
"source_contents",
|
|
69759
|
+
"compartments",
|
|
69760
|
+
"compartment_chunk_embeddings",
|
|
69761
|
+
"session_projects",
|
|
69762
|
+
"compartment_events",
|
|
69763
|
+
"compression_depth",
|
|
69764
|
+
"session_facts",
|
|
69765
|
+
"primer_candidates",
|
|
69766
|
+
"notes",
|
|
69767
|
+
"message_history_index",
|
|
69768
|
+
"message_history_source",
|
|
69769
|
+
"pending_session_cleanup",
|
|
69770
|
+
"message_history_orphan_sweep",
|
|
69771
|
+
"session_meta",
|
|
69772
|
+
"subagent_invocations",
|
|
69773
|
+
"historian_runs",
|
|
69774
|
+
"transform_decisions",
|
|
69775
|
+
"recomp_compartments",
|
|
69776
|
+
"recomp_facts"
|
|
69777
|
+
];
|
|
69778
|
+
var V85_OPTIONAL_OPENCODE2_RELABEL_TABLES = ["session_project_backfill_state"];
|
|
69779
|
+
function deleteLosingOpenCode2Twin(db, table, joinColumns, newerPredicate) {
|
|
69780
|
+
if (!tableHasHarnessColumn(db, table))
|
|
69781
|
+
return;
|
|
69782
|
+
const naturalJoin = joinColumns.map((column) => `oc.${column} = o2.${column}`).join(" AND ");
|
|
69783
|
+
const o2On = naturalJoin ? `${naturalJoin} AND oc.harness = 'opencode'` : `oc.harness = 'opencode'`;
|
|
69784
|
+
const ocOn = naturalJoin ? `${naturalJoin} AND o2.harness = 'opencode2'` : `o2.harness = 'opencode2'`;
|
|
69785
|
+
db.exec(`
|
|
69786
|
+
DELETE FROM ${table}
|
|
69787
|
+
WHERE rowid IN (
|
|
69788
|
+
SELECT o2.rowid
|
|
69789
|
+
FROM ${table} AS o2
|
|
69790
|
+
JOIN ${table} AS oc
|
|
69791
|
+
ON ${o2On}
|
|
69792
|
+
WHERE o2.harness = 'opencode2'
|
|
69793
|
+
AND NOT (${newerPredicate})
|
|
69794
|
+
);
|
|
69795
|
+
DELETE FROM ${table}
|
|
69796
|
+
WHERE rowid IN (
|
|
69797
|
+
SELECT oc.rowid
|
|
69798
|
+
FROM ${table} AS oc
|
|
69799
|
+
JOIN ${table} AS o2
|
|
69800
|
+
ON ${ocOn}
|
|
69801
|
+
WHERE oc.harness = 'opencode'
|
|
69802
|
+
AND (${newerPredicate})
|
|
69803
|
+
);
|
|
69804
|
+
`);
|
|
69805
|
+
}
|
|
69806
|
+
function relabelOpenCode2HarnessRows(db) {
|
|
69807
|
+
deleteLosingOpenCode2Twin(db, "session_projects", ["session_id"], "o2.updated_at > oc.updated_at");
|
|
69808
|
+
deleteLosingOpenCode2Twin(db, "primer_candidates", ["project_path", "session_id", "source_start_message_id", "source_end_message_id"], "o2.created_at > oc.created_at");
|
|
69809
|
+
deleteLosingOpenCode2Twin(db, "transform_decisions", ["session_id", "message_id"], "o2.ts_ms > oc.ts_ms");
|
|
69810
|
+
deleteLosingOpenCode2Twin(db, "message_history_orphan_sweep", [], "COALESCE(o2.last_swept_at, -1) > COALESCE(oc.last_swept_at, -1)");
|
|
69811
|
+
if (tableHasHarnessColumn(db, "session_project_backfill_state")) {
|
|
69812
|
+
db.exec(`
|
|
69813
|
+
DELETE FROM session_project_backfill_state
|
|
69814
|
+
WHERE harness = 'opencode2'
|
|
69815
|
+
AND EXISTS (
|
|
69816
|
+
SELECT 1 FROM session_project_backfill_state WHERE harness = 'opencode'
|
|
69817
|
+
)
|
|
69818
|
+
AND NOT (
|
|
69819
|
+
(status = 'completed'
|
|
69820
|
+
AND (SELECT status FROM session_project_backfill_state WHERE harness = 'opencode')
|
|
69821
|
+
!= 'completed')
|
|
69822
|
+
OR (
|
|
69823
|
+
status = (SELECT status FROM session_project_backfill_state WHERE harness = 'opencode')
|
|
69824
|
+
AND COALESCE(started_at, -1) > COALESCE(
|
|
69825
|
+
(SELECT started_at FROM session_project_backfill_state WHERE harness = 'opencode'),
|
|
69826
|
+
-1
|
|
69827
|
+
)
|
|
69828
|
+
)
|
|
69829
|
+
);
|
|
69830
|
+
DELETE FROM session_project_backfill_state
|
|
69831
|
+
WHERE harness = 'opencode'
|
|
69832
|
+
AND EXISTS (
|
|
69833
|
+
SELECT 1 FROM session_project_backfill_state WHERE harness = 'opencode2'
|
|
69834
|
+
)
|
|
69835
|
+
AND (
|
|
69836
|
+
((SELECT status FROM session_project_backfill_state WHERE harness = 'opencode2') = 'completed'
|
|
69837
|
+
AND status != 'completed')
|
|
69838
|
+
OR (
|
|
69839
|
+
status = (SELECT status FROM session_project_backfill_state WHERE harness = 'opencode2')
|
|
69840
|
+
AND COALESCE(
|
|
69841
|
+
(SELECT started_at FROM session_project_backfill_state WHERE harness = 'opencode2'),
|
|
69842
|
+
-1
|
|
69843
|
+
) > COALESCE(started_at, -1)
|
|
69844
|
+
)
|
|
69845
|
+
);
|
|
69846
|
+
`);
|
|
69847
|
+
}
|
|
69848
|
+
const tables = new Set([
|
|
69849
|
+
...V85_OPENCODE2_RELABEL_TABLES,
|
|
69850
|
+
...V85_OPTIONAL_OPENCODE2_RELABEL_TABLES
|
|
69851
|
+
]);
|
|
69852
|
+
for (const table of tables) {
|
|
69853
|
+
if (!tableHasHarnessColumn(db, table))
|
|
69854
|
+
continue;
|
|
69855
|
+
db.exec(`UPDATE ${table} SET harness = 'opencode' WHERE harness = 'opencode2'`);
|
|
69856
|
+
}
|
|
69857
|
+
}
|
|
69540
69858
|
function healMismatchedTierClose(db, table, hasLegacy) {
|
|
69541
69859
|
if (!tableExists2(db, table))
|
|
69542
69860
|
return;
|
|
@@ -71699,6 +72017,13 @@ var MIGRATIONS = [
|
|
|
71699
72017
|
ensureColumn(db, "session_meta", "protected_tokens_effective", "INTEGER");
|
|
71700
72018
|
ensureColumn(db, "session_meta", "protected_tokens_pre_snapshot", "TEXT");
|
|
71701
72019
|
}
|
|
72020
|
+
},
|
|
72021
|
+
{
|
|
72022
|
+
version: 85,
|
|
72023
|
+
description: "relabel OpenCode 1.x mis-tagged opencode2 session rows",
|
|
72024
|
+
up(db) {
|
|
72025
|
+
relabelOpenCode2HarnessRows(db);
|
|
72026
|
+
}
|
|
71702
72027
|
}
|
|
71703
72028
|
];
|
|
71704
72029
|
var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -72855,6 +73180,7 @@ function runToolOwnerBackfill(db) {
|
|
|
72855
73180
|
const escapedDbPath = opencodeDbPath.replaceAll("'", "''");
|
|
72856
73181
|
db.exec(`ATTACH '${escapedDbPath}' AS oc_backfill`);
|
|
72857
73182
|
try {
|
|
73183
|
+
assertOpenCodeStoreGeneration(db, "v1", opencodeDbPath, "oc_backfill");
|
|
72858
73184
|
backfillToolOwnersInChunks(db, result);
|
|
72859
73185
|
} finally {
|
|
72860
73186
|
try {
|
|
@@ -73070,7 +73396,7 @@ var lastMigrationOnOpenRefusal = null;
|
|
|
73070
73396
|
function getSchemaFenceRejection() {
|
|
73071
73397
|
return lastSchemaFenceRejection;
|
|
73072
73398
|
}
|
|
73073
|
-
var LATEST_SUPPORTED_VERSION =
|
|
73399
|
+
var LATEST_SUPPORTED_VERSION = 85;
|
|
73074
73400
|
var BOOT_SQLITE_BUSY_TIMEOUT_MS = 5000;
|
|
73075
73401
|
var PERMISSIONS_ENFORCEABLE = process.platform !== "win32";
|
|
73076
73402
|
var defaultStoragePermissionFs = { chmodSync: chmodSync2, mkdirSync: mkdirSync4 };
|
|
@@ -73524,7 +73850,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
73524
73850
|
tag_id INTEGER,
|
|
73525
73851
|
session_id TEXT,
|
|
73526
73852
|
content TEXT,
|
|
73527
|
-
created_at INTEGER,
|
|
73853
|
+
created_at INTEGER, -- epoch ms; Date.now() on source writes, preserved on session clones
|
|
73528
73854
|
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
73529
73855
|
PRIMARY KEY(session_id, tag_id)
|
|
73530
73856
|
);
|
|
@@ -73548,7 +73874,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
73548
73874
|
p1_embedding BLOB,
|
|
73549
73875
|
p1_embedding_model_id TEXT,
|
|
73550
73876
|
legacy INTEGER NOT NULL DEFAULT 0,
|
|
73551
|
-
created_at INTEGER NOT NULL,
|
|
73877
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
73552
73878
|
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
73553
73879
|
UNIQUE(session_id, sequence)
|
|
73554
73880
|
);
|
|
@@ -73567,7 +73893,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
73567
73893
|
model_id TEXT NOT NULL,
|
|
73568
73894
|
dims INTEGER NOT NULL,
|
|
73569
73895
|
vector BLOB NOT NULL,
|
|
73570
|
-
created_at INTEGER NOT NULL,
|
|
73896
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
73571
73897
|
UNIQUE(compartment_id, model_id, window_index)
|
|
73572
73898
|
);
|
|
73573
73899
|
CREATE INDEX IF NOT EXISTS idx_cce_session ON compartment_chunk_embeddings(session_id);
|
|
@@ -73590,7 +73916,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
73590
73916
|
kind TEXT NOT NULL,
|
|
73591
73917
|
at_compartment INTEGER,
|
|
73592
73918
|
fields_json TEXT NOT NULL DEFAULT '{}',
|
|
73593
|
-
created_at INTEGER NOT NULL,
|
|
73919
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
73594
73920
|
harness TEXT NOT NULL DEFAULT 'opencode'
|
|
73595
73921
|
);
|
|
73596
73922
|
CREATE INDEX IF NOT EXISTS idx_compartment_events_session
|
|
@@ -73619,7 +73945,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
73619
73945
|
session_id TEXT NOT NULL,
|
|
73620
73946
|
category TEXT NOT NULL,
|
|
73621
73947
|
content TEXT NOT NULL,
|
|
73622
|
-
created_at INTEGER NOT NULL,
|
|
73948
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
73623
73949
|
updated_at INTEGER NOT NULL,
|
|
73624
73950
|
harness TEXT NOT NULL DEFAULT 'opencode'
|
|
73625
73951
|
);
|
|
@@ -73638,7 +73964,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
73638
73964
|
source_message_time INTEGER NOT NULL,
|
|
73639
73965
|
question_embedding BLOB,
|
|
73640
73966
|
question_embedding_model_id TEXT,
|
|
73641
|
-
created_at INTEGER NOT NULL,
|
|
73967
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
73642
73968
|
UNIQUE(project_path, harness, session_id, source_start_message_id, source_end_message_id)
|
|
73643
73969
|
);
|
|
73644
73970
|
CREATE INDEX IF NOT EXISTS idx_primer_candidates_project_time
|
|
@@ -73661,7 +73987,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
73661
73987
|
answer_refreshed_at INTEGER,
|
|
73662
73988
|
source_candidate_ids TEXT NOT NULL DEFAULT '[]',
|
|
73663
73989
|
source_candidate_provenance TEXT,
|
|
73664
|
-
created_at INTEGER NOT NULL,
|
|
73990
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
73665
73991
|
updated_at INTEGER NOT NULL
|
|
73666
73992
|
);
|
|
73667
73993
|
CREATE INDEX IF NOT EXISTS idx_primers_project_status_observed
|
|
@@ -73774,7 +74100,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
73774
74100
|
job_id TEXT,
|
|
73775
74101
|
cursor TEXT,
|
|
73776
74102
|
status TEXT NOT NULL DEFAULT 'pending',
|
|
73777
|
-
created_at INTEGER NOT NULL DEFAULT 0,
|
|
74103
|
+
created_at INTEGER NOT NULL DEFAULT 0, -- epoch ms (Date.now())
|
|
73778
74104
|
updated_at INTEGER NOT NULL DEFAULT 0,
|
|
73779
74105
|
UNIQUE(session_id, request_key)
|
|
73780
74106
|
);
|
|
@@ -73815,7 +74141,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
|
|
|
73815
74141
|
shadow_epoch INTEGER NOT NULL DEFAULT 0,
|
|
73816
74142
|
corpus_hash TEXT NOT NULL DEFAULT '',
|
|
73817
74143
|
coverage_json TEXT NOT NULL DEFAULT '{}',
|
|
73818
|
-
created_at INTEGER NOT NULL DEFAULT 0,
|
|
74144
|
+
created_at INTEGER NOT NULL DEFAULT 0, -- epoch ms (Date.now())
|
|
73819
74145
|
UNIQUE(dedup_key, cohort_key)
|
|
73820
74146
|
);
|
|
73821
74147
|
CREATE INDEX IF NOT EXISTS idx_embedding_measurement_session
|
|
@@ -74238,7 +74564,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
74238
74564
|
importance_avg REAL,
|
|
74239
74565
|
discarded_last INTEGER NOT NULL DEFAULT 0,
|
|
74240
74566
|
legacy INTEGER NOT NULL DEFAULT 0,
|
|
74241
|
-
created_at INTEGER NOT NULL
|
|
74567
|
+
created_at INTEGER NOT NULL -- epoch ms (Date.now())
|
|
74242
74568
|
);
|
|
74243
74569
|
CREATE INDEX IF NOT EXISTS idx_historian_runs_session
|
|
74244
74570
|
ON historian_runs(session_id, created_at DESC);
|
|
@@ -74291,7 +74617,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
74291
74617
|
importance INTEGER NOT NULL DEFAULT 50,
|
|
74292
74618
|
episode_type TEXT,
|
|
74293
74619
|
pass_number INTEGER NOT NULL,
|
|
74294
|
-
created_at INTEGER NOT NULL,
|
|
74620
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
74295
74621
|
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
74296
74622
|
UNIQUE(session_id, sequence)
|
|
74297
74623
|
);
|
|
@@ -74302,7 +74628,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
74302
74628
|
category TEXT NOT NULL,
|
|
74303
74629
|
content TEXT NOT NULL,
|
|
74304
74630
|
pass_number INTEGER NOT NULL,
|
|
74305
|
-
created_at INTEGER NOT NULL,
|
|
74631
|
+
created_at INTEGER NOT NULL, -- epoch ms (Date.now())
|
|
74306
74632
|
harness TEXT NOT NULL DEFAULT 'opencode'
|
|
74307
74633
|
);
|
|
74308
74634
|
|
|
@@ -81305,6 +81631,7 @@ async function injectWasmOrt() {
|
|
|
81305
81631
|
try {
|
|
81306
81632
|
const { module: ortWeb, entryPath } = await importWasmOrtForRuntime();
|
|
81307
81633
|
if (ortWeb.env?.wasm) {
|
|
81634
|
+
ortWeb.env.wasm.numThreads = 1;
|
|
81308
81635
|
ortWeb.env.wasm.wasmPaths = `${pathToFileURL2(dirname7(entryPath)).href}/`;
|
|
81309
81636
|
}
|
|
81310
81637
|
globalThis[Symbol.for("onnxruntime")] = ortWeb;
|
|
@@ -88642,6 +88969,19 @@ function normalizeSDKResponse(response, fallback, options) {
|
|
|
88642
88969
|
return fallback;
|
|
88643
88970
|
}
|
|
88644
88971
|
// src/shared/prompt-surface-runtime.ts
|
|
88972
|
+
import { existsSync as existsSync12, readFileSync as readFileSync11, statSync as statSync10 } from "node:fs";
|
|
88973
|
+
import { dirname as dirname8, isAbsolute as isAbsolute5, resolve as resolve5 } from "node:path";
|
|
88974
|
+
|
|
88975
|
+
// src/tools/light-descriptions.ts
|
|
88976
|
+
var CTX_REDUCE_LIGHT_DESCRIPTION = `Marking QUEUES content for release. It stays fully visible to you until it is actually released, which may be the next turn or many turns later. Newest tags stay protected until they age out. Release leaves a placeholder; recover only by rerunning the source or recovery tool. Mark only finished material. Mark analyzed, redundant, saved, or confirmatory outputs; keep user messages, unresolved errors, unextracted evidence, and exact wording. NEVER blanket-mark a large range: review every tag first.`;
|
|
88977
|
+
var CTX_EXPAND_LIGHT_DESCRIPTION = `For ctx_expand users, recover compacted conversation by passing a session-history heading's inclusive start/end ordinals. Results are raw [N] U:/A: transcript capped near 15K tokens; oversized ranges return the head and a continuation. Use verbose=true to list each message ordinal, part previews, and tool-output sizes; use message=N for one complete stored message and its tool exchanges. NEVER expand ranges after the last compartment because that live tail is already visible.`;
|
|
88978
|
+
var CTX_NOTE_LIGHT_DESCRIPTION = `For ctx_note: write saves, read lists, update changes one note (note_ids=[N]), dismiss retires 1–50 (note_ids); surface_condition makes a smart note. Smart-note conditions must be externally verifiable via GitHub, disk, git, or web—not this conversation or future actions.`;
|
|
88979
|
+
var CTX_MEMORY_LIGHT_DESCRIPTION = `For ctx_memory users, write one standalone durable fact with category and content; update one ID, archive one or more IDs, merge two or more IDs, or get one to twenty numeric IDs. get reads memories in every status; list remains dreamer-only, so primary agents must NEVER assume bulk-list access.`;
|
|
88980
|
+
var CTX_SEARCH_LIGHT_DESCRIPTION = `For ctx_search users, retrieve only hidden recall: memories not in <project-memory>, compacted messages outside the live tail, commits, and notes; phrase query as a question carrying exact terms. Omit sources for broad search; select memory, message, git_commit, or note, or pass memory IDs directly. Hits expand through ctx_expand.`;
|
|
88981
|
+
|
|
88982
|
+
// src/shared/prompt-surface-runtime.ts
|
|
88983
|
+
var GUIDANCE_MARKER = "## Magic Context";
|
|
88984
|
+
var GUIDANCE_MARKER_LINE = /^## Magic Context[\t ]*\r?$/gm;
|
|
88645
88985
|
var ACTIVE_TOOL_IDS = [
|
|
88646
88986
|
"ctx_reduce",
|
|
88647
88987
|
"ctx_expand",
|
|
@@ -88649,7 +88989,99 @@ var ACTIVE_TOOL_IDS = [
|
|
|
88649
88989
|
"ctx_memory",
|
|
88650
88990
|
"ctx_search"
|
|
88651
88991
|
];
|
|
88992
|
+
var LIGHT_TOOL_DESCRIPTIONS = {
|
|
88993
|
+
ctx_reduce: CTX_REDUCE_LIGHT_DESCRIPTION,
|
|
88994
|
+
ctx_expand: CTX_EXPAND_LIGHT_DESCRIPTION,
|
|
88995
|
+
ctx_note: CTX_NOTE_LIGHT_DESCRIPTION,
|
|
88996
|
+
ctx_memory: CTX_MEMORY_LIGHT_DESCRIPTION,
|
|
88997
|
+
ctx_search: CTX_SEARCH_LIGHT_DESCRIPTION
|
|
88998
|
+
};
|
|
88652
88999
|
var PROMPT_SURFACE_TOOL_ID_SET = new Set(ACTIVE_TOOL_IDS);
|
|
89000
|
+
function resolveUserConfigDirectory(options) {
|
|
89001
|
+
if (options.userConfigDirectory)
|
|
89002
|
+
return resolve5(options.userConfigDirectory);
|
|
89003
|
+
const sharedBase = cortexKitUserConfigBasePath();
|
|
89004
|
+
const shared = detectConfigFile(sharedBase);
|
|
89005
|
+
if (shared.format !== "none")
|
|
89006
|
+
return dirname8(shared.path);
|
|
89007
|
+
if (options.harness) {
|
|
89008
|
+
const legacy = resolveLegacyConfigSourcesForHarness(options.directory ?? process.cwd(), options.harness === "omp" ? "pi" : options.harness === "opencode2" ? "opencode" : options.harness).user.find((source) => existsSync12(source.path));
|
|
89009
|
+
if (legacy)
|
|
89010
|
+
return dirname8(legacy.path);
|
|
89011
|
+
}
|
|
89012
|
+
return dirname8(sharedBase);
|
|
89013
|
+
}
|
|
89014
|
+
function markerCount(content) {
|
|
89015
|
+
return content.match(GUIDANCE_MARKER_LINE)?.length ?? 0;
|
|
89016
|
+
}
|
|
89017
|
+
function createPromptSurfaceRuntime(options) {
|
|
89018
|
+
const userConfigDirectory = resolveUserConfigDirectory(options);
|
|
89019
|
+
const warned = new Set;
|
|
89020
|
+
const warnOnce = (key, message) => {
|
|
89021
|
+
if (warned.has(key))
|
|
89022
|
+
return;
|
|
89023
|
+
warned.add(key);
|
|
89024
|
+
options.warn(message);
|
|
89025
|
+
};
|
|
89026
|
+
const readGuidanceOverride = (configuredPath) => {
|
|
89027
|
+
if (!configuredPath)
|
|
89028
|
+
return;
|
|
89029
|
+
const path = isAbsolute5(configuredPath) ? configuredPath : resolve5(userConfigDirectory, configuredPath);
|
|
89030
|
+
let content;
|
|
89031
|
+
try {
|
|
89032
|
+
if (!statSync10(path).isFile()) {
|
|
89033
|
+
warnOnce(`guidance-not-file:${path}`, `prompt_surface.guidance_override_path (${path}) is not a file; using built-in guidance.`);
|
|
89034
|
+
return;
|
|
89035
|
+
}
|
|
89036
|
+
content = readFileSync11(path, "utf8");
|
|
89037
|
+
} catch (error) {
|
|
89038
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
89039
|
+
warnOnce(`guidance-unreadable:${path}:${reason}`, `prompt_surface.guidance_override_path (${path}) could not be read (${reason}); using built-in guidance.`);
|
|
89040
|
+
return;
|
|
89041
|
+
}
|
|
89042
|
+
if (content.trim().length === 0) {
|
|
89043
|
+
warnOnce(`guidance-empty:${path}`, `prompt_surface.guidance_override_path (${path}) is empty; using built-in guidance.`);
|
|
89044
|
+
return;
|
|
89045
|
+
}
|
|
89046
|
+
const markers = markerCount(content);
|
|
89047
|
+
if (markers !== 1) {
|
|
89048
|
+
warnOnce(`guidance-marker-count:${path}:${markers}`, `prompt_surface.guidance_override_path (${path}) must contain exactly one ${JSON.stringify(GUIDANCE_MARKER)} section marker; found ${markers}. Using built-in guidance.`);
|
|
89049
|
+
return;
|
|
89050
|
+
}
|
|
89051
|
+
return content;
|
|
89052
|
+
};
|
|
89053
|
+
return {
|
|
89054
|
+
resolveRegistration(config, modelKey) {
|
|
89055
|
+
const { preset } = resolvePromptSurface(config, modelKey);
|
|
89056
|
+
const overrides = config?.tool_descriptions ?? {};
|
|
89057
|
+
for (const [toolId, description] of Object.entries(overrides)) {
|
|
89058
|
+
if (!PROMPT_SURFACE_TOOL_ID_SET.has(toolId)) {
|
|
89059
|
+
warnOnce(`unknown-tool:${toolId}`, `prompt_surface.tool_descriptions.${toolId} is not a known ctx_* tool ID; the override was ignored.`);
|
|
89060
|
+
} else if (description.trim().length === 0) {
|
|
89061
|
+
warnOnce(`empty-tool:${toolId}`, `prompt_surface.tool_descriptions.${toolId} is empty; the override was ignored.`);
|
|
89062
|
+
}
|
|
89063
|
+
}
|
|
89064
|
+
return {
|
|
89065
|
+
preset,
|
|
89066
|
+
descriptionFor(toolId, fullDescription) {
|
|
89067
|
+
if (!PROMPT_SURFACE_TOOL_ID_SET.has(toolId))
|
|
89068
|
+
return fullDescription;
|
|
89069
|
+
const override = overrides[toolId];
|
|
89070
|
+
if (override !== undefined && override.trim().length > 0)
|
|
89071
|
+
return override;
|
|
89072
|
+
return preset === "light" ? LIGHT_TOOL_DESCRIPTIONS[toolId] : fullDescription;
|
|
89073
|
+
}
|
|
89074
|
+
};
|
|
89075
|
+
},
|
|
89076
|
+
resolveGuidance(config, modelKey) {
|
|
89077
|
+
const { preset } = resolvePromptSurface(config, modelKey);
|
|
89078
|
+
return {
|
|
89079
|
+
preset,
|
|
89080
|
+
primaryOverride: readGuidanceOverride(config?.guidance_override_path)
|
|
89081
|
+
};
|
|
89082
|
+
}
|
|
89083
|
+
};
|
|
89084
|
+
}
|
|
88653
89085
|
var guidanceEpochCacheByRuntime = new WeakMap;
|
|
88654
89086
|
function createPromptSurfaceGuidanceEpochCache(runtime) {
|
|
88655
89087
|
const shared = guidanceEpochCacheByRuntime.get(runtime);
|
|
@@ -88972,7 +89404,7 @@ init_logger();
|
|
|
88972
89404
|
// src/features/magic-context/compaction-marker.ts
|
|
88973
89405
|
init_logger();
|
|
88974
89406
|
import { createHash as createHash16 } from "node:crypto";
|
|
88975
|
-
import { existsSync as
|
|
89407
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
88976
89408
|
var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
88977
89409
|
var ID_PREFIX_HEX_LENGTH = 12;
|
|
88978
89410
|
var ID_SUFFIX_LENGTH = 14;
|
|
@@ -89044,10 +89476,16 @@ function getWritableOpenCodeDb() {
|
|
|
89044
89476
|
closeQuietly(cachedWriteDb.db);
|
|
89045
89477
|
} catch {}
|
|
89046
89478
|
}
|
|
89047
|
-
if (!
|
|
89479
|
+
if (!existsSync13(dbPath)) {
|
|
89048
89480
|
throw new Error(`OpenCode database not found at ${dbPath} (source=${resolution.source}; is OpenCode installed?)`);
|
|
89049
89481
|
}
|
|
89050
89482
|
const db = new Database(dbPath);
|
|
89483
|
+
try {
|
|
89484
|
+
assertOpenCodeStoreGeneration(db, "v1", dbPath);
|
|
89485
|
+
} catch (error) {
|
|
89486
|
+
closeQuietly(db);
|
|
89487
|
+
throw error;
|
|
89488
|
+
}
|
|
89051
89489
|
db.exec("PRAGMA busy_timeout=5000");
|
|
89052
89490
|
db.exec("PRAGMA journal_mode=WAL");
|
|
89053
89491
|
cachedWriteDb = { path: dbPath, db };
|
|
@@ -94704,17 +95142,65 @@ function persistFilteredNoise(db, sessionId, chunk, eligibleEnd) {
|
|
|
94704
95142
|
}
|
|
94705
95143
|
|
|
94706
95144
|
// src/hooks/magic-context/producer-window-guard.ts
|
|
94707
|
-
var PRODUCER_WINDOW_REFUSAL_MARGIN = 0.
|
|
95145
|
+
var PRODUCER_WINDOW_REFUSAL_MARGIN = 0.03;
|
|
95146
|
+
var HISTORIAN_TRUNCATION_MARKER = "[… tokens truncated by Magic Context to fit the historian window …]";
|
|
95147
|
+
function producerInputTokenLimit(contextLimitTokens, maxOutputTokens) {
|
|
95148
|
+
if (typeof contextLimitTokens !== "number" || !Number.isFinite(contextLimitTokens) || contextLimitTokens <= 0 || !Number.isFinite(maxOutputTokens) || maxOutputTokens < 0) {
|
|
95149
|
+
return;
|
|
95150
|
+
}
|
|
95151
|
+
const usableInputTokens = Math.max(0, Math.floor(contextLimitTokens - maxOutputTokens));
|
|
95152
|
+
return Math.max(0, Math.floor(usableInputTokens * (1 - PRODUCER_WINDOW_REFUSAL_MARGIN)));
|
|
95153
|
+
}
|
|
94708
95154
|
function producerWindowFailureReason(input) {
|
|
94709
95155
|
const { producerSourceTokens, contextLimitTokens, maxOutputTokens } = input;
|
|
94710
|
-
|
|
95156
|
+
const producerInputLimitTokens = producerInputTokenLimit(contextLimitTokens, maxOutputTokens);
|
|
95157
|
+
if (producerInputLimitTokens === undefined || typeof contextLimitTokens !== "number" || !Number.isFinite(producerSourceTokens) || producerSourceTokens <= 0) {
|
|
94711
95158
|
return null;
|
|
94712
95159
|
}
|
|
94713
95160
|
const usableInputTokens = Math.max(0, Math.floor(contextLimitTokens - maxOutputTokens));
|
|
94714
|
-
|
|
94715
|
-
if (producerSourceTokens < refusalThreshold)
|
|
95161
|
+
if (producerSourceTokens <= producerInputLimitTokens)
|
|
94716
95162
|
return null;
|
|
94717
|
-
return `producer_source_exceeds_window producer_source_tokens=${Math.round(producerSourceTokens)} usable_input_tokens=${usableInputTokens} context_limit_tokens=${Math.round(contextLimitTokens)} max_output_tokens=${Math.round(maxOutputTokens)}
|
|
95163
|
+
return `producer_source_exceeds_window producer_source_tokens=${Math.round(producerSourceTokens)} usable_input_tokens=${usableInputTokens} producer_input_limit_tokens=${producerInputLimitTokens} context_limit_tokens=${Math.round(contextLimitTokens)} max_output_tokens=${Math.round(maxOutputTokens)} estimator_margin=${PRODUCER_WINDOW_REFUSAL_MARGIN}`;
|
|
95164
|
+
}
|
|
95165
|
+
function splitMarkerPair() {
|
|
95166
|
+
return `
|
|
95167
|
+
${HISTORIAN_TRUNCATION_MARKER}
|
|
95168
|
+
${HISTORIAN_TRUNCATION_MARKER}
|
|
95169
|
+
`;
|
|
95170
|
+
}
|
|
95171
|
+
function fitAtomicHistorianSourceToProducerWindow(args) {
|
|
95172
|
+
const producerInputLimitTokens = producerInputTokenLimit(args.contextLimitTokens, args.maxOutputTokens);
|
|
95173
|
+
const originalTokens = estimateTokens(args.text);
|
|
95174
|
+
if (producerInputLimitTokens === undefined || originalTokens < producerInputLimitTokens || producerInputLimitTokens <= 0) {
|
|
95175
|
+
return { text: args.text, producerInputLimitTokens, removedTokens: 0 };
|
|
95176
|
+
}
|
|
95177
|
+
const boundary = [...args.resultBoundaries ?? []].filter((candidate) => Number.isFinite(candidate.sourceOffset) && candidate.sourceOffset > 0 && candidate.sourceOffset < args.text.length).sort((a, b) => b.bodyTokens - a.bodyTokens || a.ordinal - b.ordinal)[0];
|
|
95178
|
+
const splitOffset = boundary?.sourceOffset ?? Math.floor(args.text.length / 2);
|
|
95179
|
+
const left = args.text.slice(0, splitOffset);
|
|
95180
|
+
const right = args.text.slice(splitOffset);
|
|
95181
|
+
const markers = splitMarkerPair();
|
|
95182
|
+
const target = producerInputLimitTokens;
|
|
95183
|
+
let lo = 0;
|
|
95184
|
+
let hi = 1;
|
|
95185
|
+
let best = markers;
|
|
95186
|
+
for (let iteration = 0;iteration < 48; iteration++) {
|
|
95187
|
+
const scale = (lo + hi) / 2;
|
|
95188
|
+
const leftLength = Math.floor(left.length * scale);
|
|
95189
|
+
const rightLength = Math.floor(right.length * scale);
|
|
95190
|
+
const candidate = left.slice(0, leftLength) + markers + right.slice(right.length - rightLength);
|
|
95191
|
+
if (estimateTokens(candidate) <= target) {
|
|
95192
|
+
best = candidate;
|
|
95193
|
+
lo = scale;
|
|
95194
|
+
} else {
|
|
95195
|
+
hi = scale;
|
|
95196
|
+
}
|
|
95197
|
+
}
|
|
95198
|
+
return {
|
|
95199
|
+
text: best,
|
|
95200
|
+
producerInputLimitTokens,
|
|
95201
|
+
...boundary ? { splitBoundaryOrdinal: boundary.ordinal } : {},
|
|
95202
|
+
removedTokens: Math.max(0, originalTokens - estimateTokens(best))
|
|
95203
|
+
};
|
|
94718
95204
|
}
|
|
94719
95205
|
|
|
94720
95206
|
// src/hooks/magic-context/protected-tail-boundary.ts
|
|
@@ -97075,6 +97561,25 @@ function shouldSuppressHistorianAlert(sessionId) {
|
|
|
97075
97561
|
lastHistorianAlertBySession.set(sessionId, Date.now());
|
|
97076
97562
|
return false;
|
|
97077
97563
|
}
|
|
97564
|
+
function findDanglingPublicationBoundary(sessionId, compartments, resolveOrdinal = readRawSessionMessageOrdinalById) {
|
|
97565
|
+
for (const compartment of compartments) {
|
|
97566
|
+
if (resolveOrdinal(sessionId, compartment.startMessageId) === null) {
|
|
97567
|
+
return {
|
|
97568
|
+
sequence: compartment.sequence,
|
|
97569
|
+
side: "start",
|
|
97570
|
+
messageId: compartment.startMessageId
|
|
97571
|
+
};
|
|
97572
|
+
}
|
|
97573
|
+
if (resolveOrdinal(sessionId, compartment.endMessageId) === null) {
|
|
97574
|
+
return {
|
|
97575
|
+
sequence: compartment.sequence,
|
|
97576
|
+
side: "end",
|
|
97577
|
+
messageId: compartment.endMessageId
|
|
97578
|
+
};
|
|
97579
|
+
}
|
|
97580
|
+
}
|
|
97581
|
+
return null;
|
|
97582
|
+
}
|
|
97078
97583
|
async function runCompartmentAgent(deps) {
|
|
97079
97584
|
const {
|
|
97080
97585
|
client,
|
|
@@ -97278,11 +97783,20 @@ async function runCompartmentAgent(deps) {
|
|
|
97278
97783
|
rollbackDrainReservation();
|
|
97279
97784
|
return;
|
|
97280
97785
|
}
|
|
97281
|
-
const
|
|
97786
|
+
const fittedAtomicSource = chunk.oversizeAtomicUnit ? fitAtomicHistorianSourceToProducerWindow({
|
|
97787
|
+
text: chunk.text,
|
|
97788
|
+
resultBoundaries: chunk.toolResultBoundaries,
|
|
97789
|
+
contextLimitTokens: deps.historianContextLimit,
|
|
97790
|
+
maxOutputTokens: deps.historianMaxOutputTokens ?? 32000
|
|
97791
|
+
}) : null;
|
|
97792
|
+
const chunkText = chunk.oversizeAtomicUnit ? fittedAtomicSource?.text ?? chunk.text : truncateHistorianInputIfNeeded(chunk.text, historianChunkTokens);
|
|
97282
97793
|
const producerSourceTokens = estimateTokens(chunkText);
|
|
97283
97794
|
if (boundarySnapshot.oversizeAtomicUnit || chunk.oversizeAtomicUnit) {
|
|
97284
97795
|
sessionLog(sessionId, `historian oversize admission: range=${chunk.startIndex}-${chunk.endIndex} rawComponentTokens=${boundarySnapshot.diagnostics?.head.completedFence.tokenMass ?? "unknown"} perRunCap=${perRunCap} producerSourceTokens=${producerSourceTokens} historianChunkTokens=${historianChunkTokens}; ${describeBoundaryDiagnostics(boundarySnapshot)}`);
|
|
97285
97796
|
}
|
|
97797
|
+
if (fittedAtomicSource && fittedAtomicSource.removedTokens > 0) {
|
|
97798
|
+
sessionLog(sessionId, `historian pathological component split: range=${chunk.startIndex}-${chunk.endIndex} resultBoundary=${fittedAtomicSource.splitBoundaryOrdinal ?? "midpoint"} removedTokens=${fittedAtomicSource.removedTokens} producerSourceTokens=${producerSourceTokens} producerInputLimitTokens=${fittedAtomicSource.producerInputLimitTokens ?? "unknown"}`);
|
|
97799
|
+
}
|
|
97286
97800
|
const producerWindowFailure = producerWindowFailureReason({
|
|
97287
97801
|
producerSourceTokens,
|
|
97288
97802
|
contextLimitTokens: deps.historianContextLimit,
|
|
@@ -97413,6 +97927,16 @@ ${chunkText}`,
|
|
|
97413
97927
|
return;
|
|
97414
97928
|
}
|
|
97415
97929
|
const compartmentTagKeys = await getRawSessionTagKeysThrough(sessionId, lastCompartmentEnd, { db });
|
|
97930
|
+
const danglingBoundary = findDanglingPublicationBoundary(sessionId, newCompartments);
|
|
97931
|
+
if (danglingBoundary) {
|
|
97932
|
+
const reason = `compartment boundary disappeared before publication (sequence=${danglingBoundary.sequence} side=${danglingBoundary.side} missing_id=${danglingBoundary.messageId})`;
|
|
97933
|
+
telemetry.failureReason = `publish-boundary: ${reason}`;
|
|
97934
|
+
sessionLog(sessionId, `historian publish refused: sequence=${danglingBoundary.sequence} side=${danglingBoundary.side} missing_id=${danglingBoundary.messageId}; raw snapshot changed during the historian run`);
|
|
97935
|
+
const failCount = incrementHistorianFailure(db, sessionId, reason);
|
|
97936
|
+
await notifyHistorianIssue(buildHistorianFailureNotice(failCount, reason));
|
|
97937
|
+
rollbackDrainReservation();
|
|
97938
|
+
return;
|
|
97939
|
+
}
|
|
97416
97940
|
let published = false;
|
|
97417
97941
|
const transactionStartedAt = performance.now();
|
|
97418
97942
|
db.exec("BEGIN IMMEDIATE");
|
|
@@ -98319,7 +98843,7 @@ function canConsumeDeferredOnThisPass(args) {
|
|
|
98319
98843
|
return args.schedulerDecision === "execute" || args.contextPercentage >= (args.forceMaterializationPercentage ?? escalationBands(65).forceMaterializationPercentage);
|
|
98320
98844
|
}
|
|
98321
98845
|
function hasReclaimRide(signals) {
|
|
98322
|
-
return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory
|
|
98846
|
+
return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory;
|
|
98323
98847
|
}
|
|
98324
98848
|
|
|
98325
98849
|
// src/hooks/magic-context/caveman-cleanup.ts
|
|
@@ -98441,7 +98965,7 @@ function replayCavemanCompression(sessionId, db, targets, tags) {
|
|
|
98441
98965
|
}
|
|
98442
98966
|
|
|
98443
98967
|
// src/hooks/magic-context/compaction-off-transition.ts
|
|
98444
|
-
import { existsSync as
|
|
98968
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
98445
98969
|
init_logger();
|
|
98446
98970
|
var loggedUnverifiedMarkerCleanupRetry = false;
|
|
98447
98971
|
var COMPACTION_OFF_FLIP_NOTICE = [
|
|
@@ -98477,7 +99001,7 @@ function clearCachedM0Baseline(db, sessionId) {
|
|
|
98477
99001
|
return (result.changes ?? 0) > 0;
|
|
98478
99002
|
}
|
|
98479
99003
|
function cleanupOffMarkers(sessionId) {
|
|
98480
|
-
if (!
|
|
99004
|
+
if (!existsSync14(getOpenCodeDbPath())) {
|
|
98481
99005
|
return { verified: true, removedLineages: 0, removedRows: 0, retainedLineages: 0 };
|
|
98482
99006
|
}
|
|
98483
99007
|
return removeMcOwnedCompactionMarkers(sessionId, MARKER_SUMMARY_TEXT);
|
|
@@ -99440,7 +99964,7 @@ function createPassOutcome() {
|
|
|
99440
99964
|
}
|
|
99441
99965
|
|
|
99442
99966
|
// src/hooks/magic-context/rust-mode-transform.ts
|
|
99443
|
-
import { createHash as createHash19 } from "node:crypto";
|
|
99967
|
+
import { createHash as createHash19, randomUUID as randomUUID4 } from "node:crypto";
|
|
99444
99968
|
init_logger();
|
|
99445
99969
|
|
|
99446
99970
|
// src/hooks/magic-context/module-state-sync.ts
|
|
@@ -99681,11 +100205,35 @@ function toFlatModuleWireBody(payload) {
|
|
|
99681
100205
|
function moduleWireBodyBytes(payload) {
|
|
99682
100206
|
return Buffer.byteLength(JSON.stringify(toFlatModuleWireBody(payload)));
|
|
99683
100207
|
}
|
|
99684
|
-
function buildPagedModuleTransformPayloads(body, pageMaxBytes = MODULE_PAGE_MAX_BYTES) {
|
|
100208
|
+
function buildPagedModuleTransformPayloads(body, pageMaxBytes = MODULE_PAGE_MAX_BYTES, forcePageEnvelope = false) {
|
|
99685
100209
|
const serializedBody = JSON.stringify(body);
|
|
99686
100210
|
const unpagedBytes = Buffer.byteLength(serializedBody);
|
|
99687
|
-
if (unpagedBytes <= pageMaxBytes)
|
|
99688
|
-
|
|
100211
|
+
if (unpagedBytes <= pageMaxBytes) {
|
|
100212
|
+
if (!forcePageEnvelope)
|
|
100213
|
+
return [{ page: body, bytes: unpagedBytes }];
|
|
100214
|
+
const pageContent = Object.fromEntries([
|
|
100215
|
+
"input",
|
|
100216
|
+
"messages",
|
|
100217
|
+
"native_messages",
|
|
100218
|
+
"ts_output",
|
|
100219
|
+
"ts_ck_messages",
|
|
100220
|
+
"normalizations",
|
|
100221
|
+
"tool_input_key_orders"
|
|
100222
|
+
].filter((field) => {
|
|
100223
|
+
const value = body[field];
|
|
100224
|
+
return Array.isArray(value) || value !== null && typeof value === "object" && field === "tool_input_key_orders";
|
|
100225
|
+
}).map((field) => [field, body[field]]));
|
|
100226
|
+
const page = {
|
|
100227
|
+
transform_page_id: crypto2.createHash("sha256").update(serializedBody).digest("hex"),
|
|
100228
|
+
transform_generation: body.shadow_generation ?? 0,
|
|
100229
|
+
transform_page_index: 0,
|
|
100230
|
+
transform_page_total: 1,
|
|
100231
|
+
transform_page_complete: true,
|
|
100232
|
+
transform_page_digest: transformPageDigest(pageContent),
|
|
100233
|
+
...body
|
|
100234
|
+
};
|
|
100235
|
+
return [{ page, bytes: Buffer.byteLength(JSON.stringify(page)) }];
|
|
100236
|
+
}
|
|
99689
100237
|
const arrayFields = [
|
|
99690
100238
|
"input",
|
|
99691
100239
|
"messages",
|
|
@@ -100329,36 +100877,43 @@ function canonicalOrdinalForMessageId(args) {
|
|
|
100329
100877
|
args.state.idOrdinalMemo.set(args.messageId, canonical);
|
|
100330
100878
|
return canonical;
|
|
100331
100879
|
}
|
|
100332
|
-
|
|
100880
|
+
var boundaryDiagnosticObserverForTest = null;
|
|
100881
|
+
function logBoundaryDiagnostic(sessionId, message) {
|
|
100882
|
+
sessionLog(sessionId, message);
|
|
100883
|
+
boundaryDiagnosticObserverForTest?.(message);
|
|
100884
|
+
}
|
|
100885
|
+
function readCompartmentBoundaryResolution(args) {
|
|
100333
100886
|
const startRaw = args.readRawById(args.compartment.startMessageId);
|
|
100334
100887
|
const endRaw = args.readRawById(args.compartment.endMessageId);
|
|
100335
|
-
|
|
100336
|
-
|
|
100337
|
-
|
|
100338
|
-
|
|
100339
|
-
|
|
100340
|
-
|
|
100341
|
-
|
|
100342
|
-
|
|
100343
|
-
|
|
100344
|
-
|
|
100345
|
-
|
|
100346
|
-
|
|
100347
|
-
|
|
100348
|
-
|
|
100349
|
-
|
|
100350
|
-
|
|
100351
|
-
|
|
100352
|
-
|
|
100353
|
-
|
|
100354
|
-
|
|
100888
|
+
return {
|
|
100889
|
+
startRaw,
|
|
100890
|
+
endRaw,
|
|
100891
|
+
startOrdinal: canonicalOrdinalForMessageId({
|
|
100892
|
+
sessionId: args.sessionId,
|
|
100893
|
+
raw: startRaw,
|
|
100894
|
+
messageId: args.compartment.startMessageId,
|
|
100895
|
+
generation: args.state.moduleGeneration,
|
|
100896
|
+
state: args.state
|
|
100897
|
+
}),
|
|
100898
|
+
endOrdinal: canonicalOrdinalForMessageId({
|
|
100899
|
+
sessionId: args.sessionId,
|
|
100900
|
+
raw: endRaw,
|
|
100901
|
+
messageId: args.compartment.endMessageId,
|
|
100902
|
+
generation: args.state.moduleGeneration,
|
|
100903
|
+
state: args.state
|
|
100904
|
+
})
|
|
100905
|
+
};
|
|
100906
|
+
}
|
|
100907
|
+
function serializeCompartment(args) {
|
|
100908
|
+
const startCreatedAt = args.startRaw?.createdAt;
|
|
100909
|
+
const endCreatedAt = args.endRaw?.createdAt;
|
|
100355
100910
|
const dateRange = typeof startCreatedAt === "number" && typeof endCreatedAt === "number" ? { start_date: formatDate(startCreatedAt), end_date: formatDate(endCreatedAt) } : {};
|
|
100356
100911
|
return {
|
|
100357
100912
|
sequence: args.compartment.sequence,
|
|
100358
|
-
start_message: startOrdinal,
|
|
100359
|
-
end_message: endOrdinal,
|
|
100360
|
-
start_message_id: flatBlockIdForRawMessage(args.compartment.startMessageId, startRaw, "start"),
|
|
100361
|
-
end_message_id: flatBlockIdForRawMessage(args.compartment.endMessageId, endRaw, "end"),
|
|
100913
|
+
start_message: args.startOrdinal,
|
|
100914
|
+
end_message: args.endOrdinal,
|
|
100915
|
+
start_message_id: flatBlockIdForRawMessage(args.compartment.startMessageId, args.startRaw, "start"),
|
|
100916
|
+
end_message_id: flatBlockIdForRawMessage(args.compartment.endMessageId, args.endRaw, "end"),
|
|
100362
100917
|
...dateRange,
|
|
100363
100918
|
title: args.compartment.title,
|
|
100364
100919
|
content: args.compartment.content,
|
|
@@ -100372,6 +100927,15 @@ function serializeCompartment(args) {
|
|
|
100372
100927
|
created_at: args.compartment.createdAt
|
|
100373
100928
|
};
|
|
100374
100929
|
}
|
|
100930
|
+
function adjacentCompartmentBoundaryId(args) {
|
|
100931
|
+
const previous = args.direction === "previous";
|
|
100932
|
+
const row = args.db.prepare(`SELECT ${previous ? "end_message_id" : "start_message_id"} AS message_id
|
|
100933
|
+
FROM compartments
|
|
100934
|
+
WHERE session_id = ? AND sequence ${previous ? "<" : ">"} ?
|
|
100935
|
+
ORDER BY sequence ${previous ? "DESC" : "ASC"}
|
|
100936
|
+
LIMIT 1`).get(args.sessionId, args.sequence);
|
|
100937
|
+
return typeof row?.message_id === "string" && row.message_id.length > 0 ? row.message_id : null;
|
|
100938
|
+
}
|
|
100375
100939
|
function seedBoundaryFromSerializedCompartments(compartments) {
|
|
100376
100940
|
const serialized = compartments.filter(isRecord3).filter((compartment) => typeof compartment.sequence === "number" && typeof compartment.end_message_id === "string");
|
|
100377
100941
|
serialized.sort((left, right) => left.sequence - right.sequence);
|
|
@@ -100844,21 +101408,102 @@ async function buildModuleStateSyncPayload(args) {
|
|
|
100844
101408
|
const compartments = [];
|
|
100845
101409
|
let serializedCount = 0;
|
|
100846
101410
|
const compartmentsToSerialize = compartmentsChanged ? args.force ? inventory ? readCompartmentsAfterSequence(args.pass.db, args.pass.sessionId, inventory.maxCompartmentSequence) : getCompartments(args.pass.db, args.pass.sessionId) : readCompartmentsAfterSequence(args.pass.db, args.pass.sessionId, acked.compartment_sequence) : [];
|
|
100847
|
-
|
|
100848
|
-
|
|
100849
|
-
|
|
100850
|
-
|
|
100851
|
-
|
|
101411
|
+
const boundaryResolutions = new Map;
|
|
101412
|
+
const resolveBoundary = (compartment) => {
|
|
101413
|
+
const cached = boundaryResolutions.get(compartment.sequence);
|
|
101414
|
+
if (cached)
|
|
101415
|
+
return cached;
|
|
101416
|
+
const resolved = readCompartmentBoundaryResolution({
|
|
100852
101417
|
compartment,
|
|
100853
101418
|
sessionId: args.pass.sessionId,
|
|
100854
101419
|
readRawById,
|
|
100855
101420
|
state: args.state
|
|
100856
101421
|
});
|
|
100857
|
-
|
|
101422
|
+
boundaryResolutions.set(compartment.sequence, resolved);
|
|
101423
|
+
return resolved;
|
|
101424
|
+
};
|
|
101425
|
+
const canonicalOrdinalForAdjacentId = (messageId) => {
|
|
101426
|
+
if (!messageId)
|
|
101427
|
+
return null;
|
|
101428
|
+
const raw = readRawById(messageId);
|
|
101429
|
+
return canonicalOrdinalForMessageId({
|
|
101430
|
+
sessionId: args.pass.sessionId,
|
|
101431
|
+
raw,
|
|
101432
|
+
messageId,
|
|
101433
|
+
generation: args.state.moduleGeneration,
|
|
101434
|
+
state: args.state
|
|
101435
|
+
});
|
|
101436
|
+
};
|
|
101437
|
+
let firstRawOrdinal;
|
|
101438
|
+
for (const [index, compartment] of compartmentsToSerialize.entries()) {
|
|
101439
|
+
args.options?.beforeSerializeCompartment?.();
|
|
101440
|
+
if (args.options?.shouldAbortSeed?.())
|
|
101441
|
+
return "seed_budget";
|
|
101442
|
+
const boundary = resolveBoundary(compartment);
|
|
101443
|
+
if (boundary.startOrdinal === "mismatch" || boundary.endOrdinal === "mismatch") {
|
|
100858
101444
|
return "mismatch";
|
|
100859
|
-
|
|
100860
|
-
|
|
100861
|
-
|
|
101445
|
+
}
|
|
101446
|
+
const startMissing = boundary.startOrdinal === null;
|
|
101447
|
+
const endMissing = boundary.endOrdinal === null;
|
|
101448
|
+
if (startMissing && endMissing) {
|
|
101449
|
+
logBoundaryDiagnostic(args.pass.sessionId, `state-sync compartment skipped session=${args.pass.sessionId} sequence=${compartment.sequence} missing_start_id=${compartment.startMessageId} missing_end_id=${compartment.endMessageId} method=both_boundaries_dangling`);
|
|
101450
|
+
continue;
|
|
101451
|
+
}
|
|
101452
|
+
let startOrdinal = boundary.startOrdinal;
|
|
101453
|
+
if (startOrdinal === null) {
|
|
101454
|
+
const previous = compartmentsToSerialize[index - 1];
|
|
101455
|
+
const previousBoundaryId = previous ? previous.endMessageId : adjacentCompartmentBoundaryId({
|
|
101456
|
+
db: args.pass.db,
|
|
101457
|
+
sessionId: args.pass.sessionId,
|
|
101458
|
+
sequence: compartment.sequence,
|
|
101459
|
+
direction: "previous"
|
|
101460
|
+
});
|
|
101461
|
+
const previousEnd = previous ? resolveBoundary(previous).endOrdinal : canonicalOrdinalForAdjacentId(previousBoundaryId);
|
|
101462
|
+
if (previousEnd === "mismatch")
|
|
101463
|
+
return "mismatch";
|
|
101464
|
+
if (typeof previousEnd === "number") {
|
|
101465
|
+
startOrdinal = previousEnd + 1;
|
|
101466
|
+
logBoundaryDiagnostic(args.pass.sessionId, `state-sync boundary repaired session=${args.pass.sessionId} sequence=${compartment.sequence} side=start missing_id=${compartment.startMessageId} resolved_ordinal=${startOrdinal} method=previous_compartment_end_plus_one`);
|
|
101467
|
+
} else if (previousBoundaryId === null) {
|
|
101468
|
+
if (firstRawOrdinal === undefined) {
|
|
101469
|
+
const ordinals = [
|
|
101470
|
+
...readRawSessionMessageIdOrdinals(args.pass.sessionId).values()
|
|
101471
|
+
].filter((ordinal) => ordinal >= 1).sort((left, right) => left - right);
|
|
101472
|
+
firstRawOrdinal = ordinals[0] ?? null;
|
|
101473
|
+
}
|
|
101474
|
+
startOrdinal = firstRawOrdinal;
|
|
101475
|
+
if (startOrdinal !== null) {
|
|
101476
|
+
logBoundaryDiagnostic(args.pass.sessionId, `state-sync boundary repaired session=${args.pass.sessionId} sequence=${compartment.sequence} side=start missing_id=${compartment.startMessageId} resolved_ordinal=${startOrdinal} method=raw_store_first_ordinal`);
|
|
101477
|
+
}
|
|
101478
|
+
}
|
|
101479
|
+
}
|
|
101480
|
+
let endOrdinal = boundary.endOrdinal;
|
|
101481
|
+
if (endOrdinal === null) {
|
|
101482
|
+
const next = compartmentsToSerialize[index + 1];
|
|
101483
|
+
const nextStart = next ? resolveBoundary(next).startOrdinal : canonicalOrdinalForAdjacentId(adjacentCompartmentBoundaryId({
|
|
101484
|
+
db: args.pass.db,
|
|
101485
|
+
sessionId: args.pass.sessionId,
|
|
101486
|
+
sequence: compartment.sequence,
|
|
101487
|
+
direction: "next"
|
|
101488
|
+
}));
|
|
101489
|
+
if (nextStart === "mismatch")
|
|
101490
|
+
return "mismatch";
|
|
101491
|
+
if (typeof nextStart === "number") {
|
|
101492
|
+
endOrdinal = nextStart - 1;
|
|
101493
|
+
logBoundaryDiagnostic(args.pass.sessionId, `state-sync boundary repaired session=${args.pass.sessionId} sequence=${compartment.sequence} side=end missing_id=${compartment.endMessageId} resolved_ordinal=${endOrdinal} method=next_compartment_start_minus_one`);
|
|
101494
|
+
}
|
|
101495
|
+
}
|
|
101496
|
+
if (startOrdinal === null || endOrdinal === null || startOrdinal > endOrdinal) {
|
|
101497
|
+
logBoundaryDiagnostic(args.pass.sessionId, `state-sync compartment skipped session=${args.pass.sessionId} sequence=${compartment.sequence} missing_start_id=${startMissing ? compartment.startMessageId : "none"} missing_end_id=${endMissing ? compartment.endMessageId : "none"} method=${startOrdinal !== null && endOrdinal !== null ? "invalid_repaired_range" : "no_adjacent_canonical_boundary"}`);
|
|
101498
|
+
continue;
|
|
101499
|
+
}
|
|
101500
|
+
compartments.push(serializeCompartment({
|
|
101501
|
+
compartment,
|
|
101502
|
+
startRaw: boundary.startRaw,
|
|
101503
|
+
endRaw: boundary.endRaw,
|
|
101504
|
+
startOrdinal,
|
|
101505
|
+
endOrdinal
|
|
101506
|
+
}));
|
|
100862
101507
|
serializedCount += 1;
|
|
100863
101508
|
const yieldEvery = Math.max(1, args.options?.yieldEveryCompartments ?? 10);
|
|
100864
101509
|
if (serializedCount % yieldEvery === 0) {
|
|
@@ -103763,7 +104408,8 @@ async function runPostTransformPhase(args) {
|
|
|
103763
104408
|
const firstRenderBust = m0M1EnabledForFold && !completeCachedPrefixAvailable;
|
|
103764
104409
|
let foldExecutedThisPass = false;
|
|
103765
104410
|
let publishedM1RefreshedThisPass = false;
|
|
103766
|
-
|
|
104411
|
+
let prefixPreflightFailed = false;
|
|
104412
|
+
const softRefreshOpportunity = args.schedulerDecision === "execute" || deferredMaterialize;
|
|
103767
104413
|
let m0RematerializedThisPass = false;
|
|
103768
104414
|
const m0CoverageBeforeFold = args.sessionMeta.cachedM0Bytes === null ? -1 : args.sessionMeta.cachedM0MaxCompartmentSeq;
|
|
103769
104415
|
let m0MaterializeReason = null;
|
|
@@ -103790,6 +104436,7 @@ async function runPostTransformPhase(args) {
|
|
|
103790
104436
|
compactionOff
|
|
103791
104437
|
});
|
|
103792
104438
|
preparedPrefix = foldResult;
|
|
104439
|
+
prefixPreflightFailed = foldResult.materializationContentionRetryExhausted === true;
|
|
103793
104440
|
foldExecutedThisPass = foldExecutesThisPass(foldDueDecision.value || softRefreshOpportunity, foldResult.m0RematerializedThisPass);
|
|
103794
104441
|
publishedM1RefreshedThisPass = !foldResult.materializationContentionRetryExhausted && previousM1 !== args.sessionMeta.cachedM1Bytes?.toString("utf8");
|
|
103795
104442
|
m0RematerializedThisPass = foldResult.m0RematerializedThisPass;
|
|
@@ -103811,29 +104458,29 @@ async function runPostTransformPhase(args) {
|
|
|
103811
104458
|
}
|
|
103812
104459
|
} catch (error) {
|
|
103813
104460
|
preparedPrefix = cachedPrefixBeforePreflight;
|
|
104461
|
+
prefixPreflightFailed = true;
|
|
103814
104462
|
args.passOutcome?.record("m0-m1-fold-preexecution-degradation");
|
|
103815
104463
|
sessionLog(args.sessionId, "transform: m[0] HARD fold pre-execution failed:", getErrorMessage(error));
|
|
103816
104464
|
}
|
|
103817
104465
|
sessionLog(args.sessionId, `m[0] HARD fold decision: reason=${foldDueDecision.reason ?? "unknown"} executed=${foldExecutedThisPass}`);
|
|
103818
104466
|
}
|
|
103819
|
-
const
|
|
103820
|
-
const shouldReadPendingOps = !compactionOff && (materializationRequested || args.schedulerDecision === "execute" || forceMaterialization || foldExecutedThisPass || firstRenderBust || compartmentRunning);
|
|
104467
|
+
const shouldReadPendingOps = !compactionOff && (materializationRequested || publishedM1RefreshedThisPass || args.schedulerDecision === "execute" || forceMaterialization || foldExecutedThisPass || firstRenderBust || compartmentRunning);
|
|
103821
104468
|
const pendingOps = shouldReadPendingOps ? getPendingOps(args.db, args.sessionId) : [];
|
|
103822
104469
|
const hasPendingUserOps = pendingOps.length > 0;
|
|
103823
104470
|
const formatPendingOpsDepth = () => {
|
|
103824
104471
|
const depth = getPendingOpsCount(args.db, args.sessionId);
|
|
103825
104472
|
return depth === null ? "not loaded (deferred pass)" : String(depth);
|
|
103826
104473
|
};
|
|
103827
|
-
const shouldApplyPendingOps = !compactionOff && (args.schedulerDecision === "execute" || materializationRequested || forceMaterialization || foldExecutedThisPass || firstRenderBust) && publishedWorkDrainAllowed;
|
|
103828
104474
|
const rideSignals = {
|
|
103829
104475
|
hardFold: foldExecutedThisPass || firstRenderBust,
|
|
103830
|
-
force:
|
|
103831
|
-
explicitFlush: isExplicitFlush,
|
|
103832
|
-
publishedHistory: publishedM1RefreshedThisPass || !m0M1EnabledForFold && (args.pendingCompartmentInjection?.compartmentCount ?? 0) > 0 && (args.historyRebuiltThisPass || args.rebuiltHistoryFromInitialPrepare || args.canConsumeDeferredLate && args.deferredHistoryWasPendingAtPassStart)
|
|
103833
|
-
|
|
103834
|
-
|
|
103835
|
-
|
|
103836
|
-
|
|
104476
|
+
force: emergencyDropEligible && (args.contextUsage.percentage >= 95 || getEmergencyInputSample(args.db, args.sessionId) === 0),
|
|
104477
|
+
explicitFlush: isExplicitFlush || deferredMaterialize && !prefixPreflightFailed,
|
|
104478
|
+
publishedHistory: publishedM1RefreshedThisPass || !m0M1EnabledForFold && (args.pendingCompartmentInjection?.compartmentCount ?? 0) > 0 && (args.historyRebuiltThisPass || args.rebuiltHistoryFromInitialPrepare || args.canConsumeDeferredLate && args.deferredHistoryWasPendingAtPassStart)
|
|
104479
|
+
};
|
|
104480
|
+
const publishedWorkDrainAllowed = !compactionOff && hasReclaimRide(rideSignals);
|
|
104481
|
+
const shouldApplyPendingOps = publishedWorkDrainAllowed;
|
|
104482
|
+
const shouldRunHeuristics = !compactionOff && hasReclaimRide(rideSignals) && (rideSignals.publishedHistory || materializationRequested || forceMaterialization || foldExecutedThisPass || firstRenderBust || emergencyDropEligible || args.schedulerDecision === "execute" && (!alreadyRanThisTurn || !args.fullFeatureMode));
|
|
104483
|
+
const isCacheBustingPass = publishedWorkDrainAllowed;
|
|
103837
104484
|
if (isCacheBustingPass && args.client && args.ctxReduceAvailability.callable && !hasLoggedCtxReducePermissionDeny(args.sessionId)) {
|
|
103838
104485
|
try {
|
|
103839
104486
|
const denied = await resolveToolPermissionDenied(args.client, args.sessionId, "ctx_reduce", args.activeAgent);
|
|
@@ -103859,13 +104506,8 @@ async function runPostTransformPhase(args) {
|
|
|
103859
104506
|
if (!shouldApplyPendingOps && args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
|
|
103860
104507
|
sessionLog(args.sessionId, `pending ops WILL NOT APPLY — reason=${args.schedulerDeferReason} pendingOps=${formatPendingOpsDepth()} context=${args.contextUsage.percentage.toFixed(1)}%`);
|
|
103861
104508
|
}
|
|
103862
|
-
if (
|
|
103863
|
-
|
|
103864
|
-
const bypassReason = forceMaterialization ? `emergency >=${args.forceMaterializationPercentage}%` : "m0 hard fold";
|
|
103865
|
-
sessionLog(args.sessionId, `transform: compartment-gate bypass (${bypassReason}) — applying ${pendingOps.length} pending ops while compartment agent runs (${args.contextUsage.percentage.toFixed(1)}%)`);
|
|
103866
|
-
} else {
|
|
103867
|
-
sessionLog(args.sessionId, "transform: deferring pending ops — compartment agent in progress");
|
|
103868
|
-
}
|
|
104509
|
+
if (hasPendingUserOps && !shouldApplyPendingOps) {
|
|
104510
|
+
sessionLog(args.sessionId, `pending ops held — reason=no originating cache-bust opportunity; scheduler=${args.schedulerDecision}, historianRunning=${compartmentRunning}`);
|
|
103869
104511
|
}
|
|
103870
104512
|
let explicitMaterializedSuccessfully = false;
|
|
103871
104513
|
let deferredMaterializedSuccessfully = false;
|
|
@@ -103897,9 +104539,6 @@ async function runPostTransformPhase(args) {
|
|
|
103897
104539
|
const tApply = performance.now();
|
|
103898
104540
|
pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, args.targets, args.contextUsage.percentage >= 95 ? newestCtxReduceTagNumbers(getTagsBySession(args.db, args.sessionId)) : args.protectedTagIds, undefined, pendingOps, [], new Set, (reduction) => droppedTokenReductions.push(reduction));
|
|
103899
104541
|
if (pendingOpsDidMutate) {
|
|
103900
|
-
rideSignals.agentDrop = true;
|
|
103901
|
-
isCacheBustingPass = hasReclaimRide(rideSignals);
|
|
103902
|
-
shouldRunHeuristics = isCacheBustingPass;
|
|
103903
104542
|
droppedCount += pendingOps.length;
|
|
103904
104543
|
for (const pendingOp of pendingOps) {
|
|
103905
104544
|
const message = args.targets.get(pendingOp.tagId)?.message;
|
|
@@ -104661,6 +105300,8 @@ var RUST_PARK_RETRY_INTERVAL = 5;
|
|
|
104661
105300
|
var RUST_EMERGENCY_WALL_PCT = 95;
|
|
104662
105301
|
var RUST_PARK_PROBE_PRESSURE_BYPASS_PCT = 90;
|
|
104663
105302
|
var RUST_SEND_TIMEOUT_MS = 15000;
|
|
105303
|
+
var RUST_SILENT_RESEND_AFTER_MS = 1e4;
|
|
105304
|
+
var RUST_HEALTH_PROBE_TIMEOUT_MS = 2000;
|
|
104664
105305
|
var RUST_LKG_FROZEN_HEALTHY_PASS_LIMIT = 8;
|
|
104665
105306
|
var RUST_LKG_FROZEN_RAW_TAIL_GROWTH_LIMIT = 16;
|
|
104666
105307
|
function activeAgentFromMessages(messages) {
|
|
@@ -105570,6 +106211,64 @@ function createRustModeTransform(deps, options) {
|
|
|
105570
106211
|
clearTimeout(timer);
|
|
105571
106212
|
}
|
|
105572
106213
|
};
|
|
106214
|
+
const callTransformWithSilentResend = async (args, attemptTimeoutMs) => {
|
|
106215
|
+
const startedAtMs = Date.now();
|
|
106216
|
+
const deadlineMs = startedAtMs + attemptTimeoutMs;
|
|
106217
|
+
const silentAfterMs = options.silentResendAfterMsForTests ?? RUST_SILENT_RESEND_AFTER_MS;
|
|
106218
|
+
const probeTimeoutMs = options.healthProbeTimeoutMsForTests ?? RUST_HEALTH_PROBE_TIMEOUT_MS;
|
|
106219
|
+
const originalAttemptId = randomUUID4();
|
|
106220
|
+
const originalBody = isRecord6(args.body) ? { ...args.body, attempt_id: originalAttemptId } : args.body;
|
|
106221
|
+
const original = callModule({ ...args, body: originalBody }, attemptTimeoutMs);
|
|
106222
|
+
if (attemptTimeoutMs <= silentAfterMs)
|
|
106223
|
+
return original;
|
|
106224
|
+
let silentTimer;
|
|
106225
|
+
const first = await Promise.race([
|
|
106226
|
+
original.then((response) => ({ kind: "response", response }), (error) => ({ kind: "error", error })),
|
|
106227
|
+
new Promise((resolve) => {
|
|
106228
|
+
silentTimer = setTimeout(() => resolve({ kind: "silent" }), silentAfterMs);
|
|
106229
|
+
})
|
|
106230
|
+
]);
|
|
106231
|
+
if (first.kind !== "silent")
|
|
106232
|
+
clearTimeout(silentTimer);
|
|
106233
|
+
if (first.kind === "response")
|
|
106234
|
+
return first.response;
|
|
106235
|
+
if (first.kind === "error")
|
|
106236
|
+
throw first.error;
|
|
106237
|
+
const probeBudgetMs = Math.min(probeTimeoutMs, Math.max(0, deadlineMs - Date.now()));
|
|
106238
|
+
if (probeBudgetMs <= 0)
|
|
106239
|
+
return original;
|
|
106240
|
+
try {
|
|
106241
|
+
await callModule({
|
|
106242
|
+
sessionId: args.sessionId,
|
|
106243
|
+
projectRoot: args.projectRoot,
|
|
106244
|
+
method: "session.status",
|
|
106245
|
+
body: {
|
|
106246
|
+
method: "session.status",
|
|
106247
|
+
v: 1,
|
|
106248
|
+
session_id: args.sessionId
|
|
106249
|
+
},
|
|
106250
|
+
bypassSessionLane: true
|
|
106251
|
+
}, probeBudgetMs);
|
|
106252
|
+
} catch {
|
|
106253
|
+
return original;
|
|
106254
|
+
}
|
|
106255
|
+
const remainingMs = Math.max(0, deadlineMs - Date.now());
|
|
106256
|
+
if (remainingMs <= 0)
|
|
106257
|
+
return original;
|
|
106258
|
+
const resendAttemptId = randomUUID4();
|
|
106259
|
+
sessionLog(args.sessionId, `rust silent resend original_attempt=${originalAttemptId} resend_attempt=${resendAttemptId} silent_gap_ms=${Date.now() - startedAtMs}`);
|
|
106260
|
+
const resendBody = isRecord6(args.body) ? {
|
|
106261
|
+
...args.body,
|
|
106262
|
+
attempt_id: resendAttemptId,
|
|
106263
|
+
original_attempt_id: originalAttemptId,
|
|
106264
|
+
resend: true
|
|
106265
|
+
} : args.body;
|
|
106266
|
+
return callModule({
|
|
106267
|
+
...args,
|
|
106268
|
+
body: resendBody,
|
|
106269
|
+
bypassSessionLane: true
|
|
106270
|
+
}, remainingMs);
|
|
106271
|
+
};
|
|
105573
106272
|
const markFailure = (sessionId, state, error) => {
|
|
105574
106273
|
state.consecutiveFailures = isNonRetryableStateSyncFailure(error) ? Math.max(RUST_FAILURE_PARK_THRESHOLD, state.consecutiveFailures + 1) : state.consecutiveFailures + 1;
|
|
105575
106274
|
state.failureCount += 1;
|
|
@@ -105786,6 +106485,8 @@ function createRustModeTransform(deps, options) {
|
|
|
105786
106485
|
} catch {}
|
|
105787
106486
|
let appliedAt;
|
|
105788
106487
|
let emergencyFailClosed = false;
|
|
106488
|
+
let providerProvenEmergency = false;
|
|
106489
|
+
let recoveryProjectRoot = options.projectRoot ?? deps.directory ?? "";
|
|
105789
106490
|
const passUsageSnapshot = loadContextUsage(deps.contextUsageMap, deps.db, sessionId);
|
|
105790
106491
|
requestInputTokens = Math.max(0, Math.floor(passUsageSnapshot.inputTokens));
|
|
105791
106492
|
let preflightError;
|
|
@@ -105819,11 +106520,15 @@ function createRustModeTransform(deps, options) {
|
|
|
105819
106520
|
}
|
|
105820
106521
|
const transformGeometry = transformGeometryForWire(resolvedWindowGeometry);
|
|
105821
106522
|
const hasTrustedEmergencyWall = transformGeometry ? transformGeometry.usable_hard > 0 : resolvedContextLimit !== undefined && resolvedContextLimit > 0;
|
|
105822
|
-
|
|
106523
|
+
const hardWallPercentage = hardWallUsagePercentage(passUsageSnapshot, transformGeometry);
|
|
106524
|
+
const providerOverflowProven = isProviderOverflowFailClosedProven(sessionId);
|
|
106525
|
+
emergencyFailClosed = providerOverflowProven || hardWallPercentage >= RUST_EMERGENCY_WALL_PCT && hasTrustedEmergencyWall;
|
|
105823
106526
|
if (overflowState) {
|
|
105824
106527
|
const detectedLimitMatchesModel = overflowState.detectedContextLimitModelKey === null || canonicalModelIdentity(overflowState.detectedContextLimitModelKey) === canonicalModelIdentity(modelKey ?? "");
|
|
105825
106528
|
const hasProviderProof = overflowState.detectedContextLimit > 0 && detectedLimitMatchesModel || isProviderOverflowReconfirmed(sessionId);
|
|
105826
|
-
|
|
106529
|
+
const persistedProviderEmergency = overflowState.needsEmergencyRecovery && overflowState.emergencyRecoveryOrigin === "provider_overflow" && hasProviderProof;
|
|
106530
|
+
emergencyFailClosed ||= persistedProviderEmergency;
|
|
106531
|
+
providerProvenEmergency = hardWallPercentage >= RUST_EMERGENCY_WALL_PCT && (providerOverflowProven || persistedProviderEmergency);
|
|
105827
106532
|
}
|
|
105828
106533
|
const serveRawFallback = (cause) => {
|
|
105829
106534
|
const contextLimit = transformGeometry?.usable_hard ?? resolvedContextLimit ?? (overflowState && overflowState.detectedContextLimit > 0 ? overflowState.detectedContextLimit : undefined);
|
|
@@ -106126,6 +106831,7 @@ function createRustModeTransform(deps, options) {
|
|
|
106126
106831
|
nowMs: Date.now()
|
|
106127
106832
|
};
|
|
106128
106833
|
const projectRoot = options.projectRoot ?? directory;
|
|
106834
|
+
recoveryProjectRoot = projectRoot;
|
|
106129
106835
|
const authoritySeqAdoption = { used: false };
|
|
106130
106836
|
const memorySyncRequested = options.memorySyncRequestedSessions?.delete(sessionId) === true;
|
|
106131
106837
|
const currentStateSyncInputSignature = stateSyncInputSignature({
|
|
@@ -106320,7 +107026,7 @@ function createRustModeTransform(deps, options) {
|
|
|
106320
107026
|
logStage(sessionId, "wireBuild", wireBuildStartedAt, timings, wireDelta ? `mode=tail_delta input=${encodedInput.length}` : "mode=full");
|
|
106321
107027
|
const sendTransformSeries = async (payload, detail = "") => {
|
|
106322
107028
|
const pagingStartedAt = performance.now();
|
|
106323
|
-
const pages = buildPagedModuleTransformPayloads(payload, options.modulePageMaxBytes);
|
|
107029
|
+
const pages = buildPagedModuleTransformPayloads(payload, options.modulePageMaxBytes, true);
|
|
106324
107030
|
timings.paging += performance.now() - pagingStartedAt;
|
|
106325
107031
|
const seedMessageCount = Array.isArray(payload.input) ? payload.input.length : Array.isArray(payload.messages) ? payload.messages.length : 0;
|
|
106326
107032
|
const paged = pages.some((entry) => typeof entry.page.transform_page_id === "string");
|
|
@@ -106331,7 +107037,7 @@ function createRustModeTransform(deps, options) {
|
|
|
106331
107037
|
try {
|
|
106332
107038
|
const attemptClass = paged ? index === pages.length - 1 ? "transform_series_execute" : "transform_page_upload" : undefined;
|
|
106333
107039
|
const attemptTimeoutMs = options.moduleTimeoutMs ?? (attemptClass === "transform_series_execute" ? transformColdStartExecuteTimeoutMs(seedMessageCount) : attemptClass === "transform_page_upload" ? TRANSFORM_PAGE_UPLOAD_TIMEOUT_MS : timeoutMs);
|
|
106334
|
-
|
|
107040
|
+
const callArgs = {
|
|
106335
107041
|
sessionId,
|
|
106336
107042
|
projectRoot,
|
|
106337
107043
|
method: "transform",
|
|
@@ -106342,7 +107048,8 @@ function createRustModeTransform(deps, options) {
|
|
|
106342
107048
|
},
|
|
106343
107049
|
generationSensitive: paged && index > 0,
|
|
106344
107050
|
attemptClass
|
|
106345
|
-
}
|
|
107051
|
+
};
|
|
107052
|
+
moduleResponse = page.transform_page_complete ? await callTransformWithSilentResend(callArgs, attemptTimeoutMs) : await callModule(callArgs, attemptTimeoutMs);
|
|
106346
107053
|
} catch (error) {
|
|
106347
107054
|
if (paged && isTransformPageAttemptMismatch(error)) {
|
|
106348
107055
|
return {
|
|
@@ -106868,6 +107575,21 @@ function createRustModeTransform(deps, options) {
|
|
|
106868
107575
|
sessionLog(sessionId, "mc_rust_emergency_refusal before_lkg");
|
|
106869
107576
|
markFailure(sessionId, state, error);
|
|
106870
107577
|
finishPass(false, false);
|
|
107578
|
+
const refusedUser = newestUserMessage(messages);
|
|
107579
|
+
const refusedUserMessageId = refusedUser ? messageIdOf(refusedUser) : null;
|
|
107580
|
+
if (refusedUserMessageId) {
|
|
107581
|
+
try {
|
|
107582
|
+
options.onEngineReconnectRefusal?.({
|
|
107583
|
+
sessionId,
|
|
107584
|
+
projectRoot: recoveryProjectRoot,
|
|
107585
|
+
refusedUserMessageId,
|
|
107586
|
+
providerProvenEmergency,
|
|
107587
|
+
compactionOff: deps.compactionOff === true
|
|
107588
|
+
});
|
|
107589
|
+
} catch (recoveryError) {
|
|
107590
|
+
sessionLog(sessionId, "rust refusal recovery failed to arm:", recoveryError);
|
|
107591
|
+
}
|
|
107592
|
+
}
|
|
106871
107593
|
throw new EmergencyFailClosedError(ENGINE_RECONNECTING_USER_MESSAGE, {
|
|
106872
107594
|
cause: error
|
|
106873
107595
|
});
|
|
@@ -107356,6 +108078,7 @@ function createTransform(deps) {
|
|
|
107356
108078
|
projectRoot: deps.rustModeProjectRoot,
|
|
107357
108079
|
notifyParked: deps.onRustModeParked,
|
|
107358
108080
|
onProjectPrepared: deps.onRustModeProjectPrepared,
|
|
108081
|
+
onEngineReconnectRefusal: deps.onRustEngineReconnectRefusal,
|
|
107359
108082
|
memorySyncRequestedSessions: deps.rustMemorySyncRequestedSessions,
|
|
107360
108083
|
allowAuthorityProtocolBypassForTests: deps.rustModeAllowAuthorityProtocolBypassForTests
|
|
107361
108084
|
}) : undefined;
|
|
@@ -108437,6 +109160,264 @@ async function maybeSendUpgradeReminder(deps, sessionId) {
|
|
|
108437
109160
|
}
|
|
108438
109161
|
}
|
|
108439
109162
|
|
|
109163
|
+
// src/shared/conflict-detector.ts
|
|
109164
|
+
import { homedir as homedir10 } from "node:os";
|
|
109165
|
+
import { join as join12 } from "node:path";
|
|
109166
|
+
init_logger();
|
|
109167
|
+
|
|
109168
|
+
// src/shared/opencode-config-dir.ts
|
|
109169
|
+
import { homedir as homedir9 } from "node:os";
|
|
109170
|
+
import { join as join11, resolve as resolve6 } from "node:path";
|
|
109171
|
+
function getCliConfigDir() {
|
|
109172
|
+
const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
109173
|
+
if (envConfigDir) {
|
|
109174
|
+
return resolve6(envConfigDir);
|
|
109175
|
+
}
|
|
109176
|
+
if (process.platform === "win32") {
|
|
109177
|
+
return join11(homedir9(), ".config", "opencode");
|
|
109178
|
+
}
|
|
109179
|
+
return join11(process.env.XDG_CONFIG_HOME || join11(homedir9(), ".config"), "opencode");
|
|
109180
|
+
}
|
|
109181
|
+
function getOpenCodeConfigDir(_options) {
|
|
109182
|
+
return getCliConfigDir();
|
|
109183
|
+
}
|
|
109184
|
+
function getOpenCodeConfigPaths(options) {
|
|
109185
|
+
const configDir = getOpenCodeConfigDir(options);
|
|
109186
|
+
return {
|
|
109187
|
+
configDir,
|
|
109188
|
+
configJson: join11(configDir, "opencode.json"),
|
|
109189
|
+
configJsonc: join11(configDir, "opencode.jsonc"),
|
|
109190
|
+
packageJson: join11(configDir, "package.json"),
|
|
109191
|
+
omoConfig: join11(configDir, "magic-context.jsonc")
|
|
109192
|
+
};
|
|
109193
|
+
}
|
|
109194
|
+
|
|
109195
|
+
// src/shared/conflict-detector.ts
|
|
109196
|
+
function detectConflicts(directory, options) {
|
|
109197
|
+
const compactionEnabled = options?.compactionEnabled ?? true;
|
|
109198
|
+
const hostGeneration = options?.hostGeneration ?? "v1";
|
|
109199
|
+
const conflicts = {
|
|
109200
|
+
compactionAuto: false,
|
|
109201
|
+
compactionPrune: false,
|
|
109202
|
+
dcpPlugin: false,
|
|
109203
|
+
omoPreemptiveCompaction: false,
|
|
109204
|
+
omoContextWindowMonitor: false,
|
|
109205
|
+
omoAnthropicRecovery: false
|
|
109206
|
+
};
|
|
109207
|
+
const reasons = [];
|
|
109208
|
+
let compactionResult = options?.resolvedCompaction ?? checkCompaction(directory, hostGeneration);
|
|
109209
|
+
if (process.env.OPENCODE_DISABLE_AUTOCOMPACT) {
|
|
109210
|
+
compactionResult = { auto: false, prune: false };
|
|
109211
|
+
}
|
|
109212
|
+
if (hostGeneration === "v1" && compactionEnabled && compactionResult.auto) {
|
|
109213
|
+
conflicts.compactionAuto = true;
|
|
109214
|
+
reasons.push(options?.resolvedCompaction ? "OpenCode auto-compaction is enabled (compaction.auto=true) (resolved config)" : "OpenCode auto-compaction is enabled (compaction.auto=true)");
|
|
109215
|
+
}
|
|
109216
|
+
if (hostGeneration === "v1" && compactionEnabled && compactionResult.prune) {
|
|
109217
|
+
conflicts.compactionPrune = true;
|
|
109218
|
+
reasons.push(options?.resolvedCompaction ? "OpenCode prune is enabled (compaction.prune=true) (resolved config)" : "OpenCode prune is enabled (compaction.prune=true)");
|
|
109219
|
+
}
|
|
109220
|
+
const dcpFound = checkDcpPlugin(directory);
|
|
109221
|
+
if (dcpFound) {
|
|
109222
|
+
conflicts.dcpPlugin = true;
|
|
109223
|
+
reasons.push("opencode-dcp plugin is installed — it conflicts with Magic Context's context management");
|
|
109224
|
+
}
|
|
109225
|
+
const omoResult = checkOmoHooks(directory);
|
|
109226
|
+
if (omoResult.preemptiveCompaction) {
|
|
109227
|
+
conflicts.omoPreemptiveCompaction = true;
|
|
109228
|
+
reasons.push("oh-my-opencode preemptive-compaction hook is active — it triggers compaction that conflicts with historian");
|
|
109229
|
+
}
|
|
109230
|
+
if (omoResult.contextWindowMonitor) {
|
|
109231
|
+
conflicts.omoContextWindowMonitor = true;
|
|
109232
|
+
reasons.push("oh-my-opencode context-window-monitor hook is active — it injects usage warnings that overlap with Magic Context nudges");
|
|
109233
|
+
}
|
|
109234
|
+
if (omoResult.anthropicRecovery) {
|
|
109235
|
+
conflicts.omoAnthropicRecovery = true;
|
|
109236
|
+
reasons.push("oh-my-opencode anthropic-context-window-limit-recovery hook is active — it triggers emergency compaction that bypasses historian");
|
|
109237
|
+
}
|
|
109238
|
+
return {
|
|
109239
|
+
hasConflict: reasons.length > 0,
|
|
109240
|
+
reasons,
|
|
109241
|
+
conflicts,
|
|
109242
|
+
nativeCompaction: {
|
|
109243
|
+
auto: compactionResult.auto,
|
|
109244
|
+
prune: hostGeneration === "v1" ? compactionResult.prune : false
|
|
109245
|
+
}
|
|
109246
|
+
};
|
|
109247
|
+
}
|
|
109248
|
+
function checkCompaction(directory, hostGeneration) {
|
|
109249
|
+
if (process.env.OPENCODE_DISABLE_AUTOCOMPACT) {
|
|
109250
|
+
return { auto: false, prune: false };
|
|
109251
|
+
}
|
|
109252
|
+
const projectResult = readProjectCompaction(directory, hostGeneration);
|
|
109253
|
+
if (projectResult.resolved)
|
|
109254
|
+
return projectResult;
|
|
109255
|
+
const userResult = readUserCompaction(hostGeneration);
|
|
109256
|
+
if (userResult.resolved)
|
|
109257
|
+
return userResult;
|
|
109258
|
+
return { auto: true, prune: false };
|
|
109259
|
+
}
|
|
109260
|
+
function readProjectCompaction(directory, hostGeneration) {
|
|
109261
|
+
const dotOcJsonc = join12(directory, ".opencode", "opencode.jsonc");
|
|
109262
|
+
const dotOcJson = join12(directory, ".opencode", "opencode.json");
|
|
109263
|
+
const dotOcConfig = readJsoncFile(dotOcJsonc) ?? readJsoncFile(dotOcJson);
|
|
109264
|
+
if (dotOcConfig?.compaction) {
|
|
109265
|
+
const c = dotOcConfig.compaction;
|
|
109266
|
+
if (c.auto !== undefined || hostGeneration === "v1" && c.prune !== undefined || hostGeneration === "v2" && (c.keep?.tokens !== undefined || c.buffer !== undefined)) {
|
|
109267
|
+
return resolvedCompactionBlock(c, hostGeneration);
|
|
109268
|
+
}
|
|
109269
|
+
}
|
|
109270
|
+
const rootJsonc = join12(directory, "opencode.jsonc");
|
|
109271
|
+
const rootJson = join12(directory, "opencode.json");
|
|
109272
|
+
const rootConfig = readJsoncFile(rootJsonc) ?? readJsoncFile(rootJson);
|
|
109273
|
+
if (rootConfig?.compaction) {
|
|
109274
|
+
const c = rootConfig.compaction;
|
|
109275
|
+
if (c.auto !== undefined || hostGeneration === "v1" && c.prune !== undefined || hostGeneration === "v2" && (c.keep?.tokens !== undefined || c.buffer !== undefined)) {
|
|
109276
|
+
return resolvedCompactionBlock(c, hostGeneration);
|
|
109277
|
+
}
|
|
109278
|
+
}
|
|
109279
|
+
return { auto: false, prune: false, resolved: false };
|
|
109280
|
+
}
|
|
109281
|
+
function readUserCompaction(hostGeneration) {
|
|
109282
|
+
try {
|
|
109283
|
+
const paths = getOpenCodeConfigPaths({ binary: "opencode" });
|
|
109284
|
+
const config = readJsoncFile(paths.configJsonc) ?? readJsoncFile(paths.configJson);
|
|
109285
|
+
if (config?.compaction) {
|
|
109286
|
+
const c = config.compaction;
|
|
109287
|
+
if (c.auto !== undefined || hostGeneration === "v1" && c.prune !== undefined || hostGeneration === "v2" && (c.keep?.tokens !== undefined || c.buffer !== undefined)) {
|
|
109288
|
+
return resolvedCompactionBlock(c, hostGeneration);
|
|
109289
|
+
}
|
|
109290
|
+
}
|
|
109291
|
+
} catch {}
|
|
109292
|
+
return { auto: false, prune: false, resolved: false };
|
|
109293
|
+
}
|
|
109294
|
+
function resolvedCompactionBlock(block, hostGeneration) {
|
|
109295
|
+
if (hostGeneration === "v2") {
|
|
109296
|
+
return {
|
|
109297
|
+
auto: block.auto !== false,
|
|
109298
|
+
prune: false,
|
|
109299
|
+
resolved: true,
|
|
109300
|
+
...typeof block.keep?.tokens === "number" ? { keepTokens: block.keep.tokens } : {},
|
|
109301
|
+
...typeof block.buffer === "number" ? { buffer: block.buffer } : {}
|
|
109302
|
+
};
|
|
109303
|
+
}
|
|
109304
|
+
return { auto: block.auto === true, prune: block.prune === true, resolved: true };
|
|
109305
|
+
}
|
|
109306
|
+
var DCP_PACKAGE_NAMES = new Set(["@tarquinen/opencode-dcp"]);
|
|
109307
|
+
function checkDcpPlugin(directory) {
|
|
109308
|
+
const plugins = collectPluginEntries(directory);
|
|
109309
|
+
return plugins.some((p) => matchesPackageName(p, DCP_PACKAGE_NAMES));
|
|
109310
|
+
}
|
|
109311
|
+
function matchesPackageName(entry, canonicalNames) {
|
|
109312
|
+
if (entry.startsWith("file:") || entry.startsWith("http:") || entry.startsWith("https:") || entry.startsWith("/") || entry.startsWith("./") || entry.startsWith("../")) {
|
|
109313
|
+
return false;
|
|
109314
|
+
}
|
|
109315
|
+
const lastAt = entry.lastIndexOf("@");
|
|
109316
|
+
const nameOnly = lastAt > 0 ? entry.slice(0, lastAt) : entry;
|
|
109317
|
+
return canonicalNames.has(nameOnly);
|
|
109318
|
+
}
|
|
109319
|
+
function extractPluginName(entry) {
|
|
109320
|
+
if (typeof entry === "string")
|
|
109321
|
+
return entry;
|
|
109322
|
+
if (Array.isArray(entry) && typeof entry[0] === "string")
|
|
109323
|
+
return entry[0];
|
|
109324
|
+
return null;
|
|
109325
|
+
}
|
|
109326
|
+
function collectPluginEntries(directory) {
|
|
109327
|
+
const plugins = [];
|
|
109328
|
+
const pushFrom = (entries) => {
|
|
109329
|
+
if (!entries)
|
|
109330
|
+
return;
|
|
109331
|
+
for (const entry of entries) {
|
|
109332
|
+
const name = extractPluginName(entry);
|
|
109333
|
+
if (name)
|
|
109334
|
+
plugins.push(name);
|
|
109335
|
+
}
|
|
109336
|
+
};
|
|
109337
|
+
for (const configPath of [
|
|
109338
|
+
join12(directory, ".opencode", "opencode.jsonc"),
|
|
109339
|
+
join12(directory, ".opencode", "opencode.json"),
|
|
109340
|
+
join12(directory, "opencode.jsonc"),
|
|
109341
|
+
join12(directory, "opencode.json")
|
|
109342
|
+
]) {
|
|
109343
|
+
const config = readJsoncFile(configPath);
|
|
109344
|
+
pushFrom(config?.plugin);
|
|
109345
|
+
}
|
|
109346
|
+
try {
|
|
109347
|
+
const paths = getOpenCodeConfigPaths({ binary: "opencode" });
|
|
109348
|
+
for (const configPath of [paths.configJsonc, paths.configJson]) {
|
|
109349
|
+
const config = readJsoncFile(configPath);
|
|
109350
|
+
pushFrom(config?.plugin);
|
|
109351
|
+
}
|
|
109352
|
+
} catch {}
|
|
109353
|
+
return plugins;
|
|
109354
|
+
}
|
|
109355
|
+
var OMO_PACKAGE_NAMES = new Set(["oh-my-opencode", "oh-my-openagent"]);
|
|
109356
|
+
function checkOmoHooks(directory) {
|
|
109357
|
+
const result = {
|
|
109358
|
+
preemptiveCompaction: false,
|
|
109359
|
+
contextWindowMonitor: false,
|
|
109360
|
+
anthropicRecovery: false
|
|
109361
|
+
};
|
|
109362
|
+
const plugins = collectPluginEntries(directory);
|
|
109363
|
+
const hasOmo = plugins.some((p) => matchesPackageName(p, OMO_PACKAGE_NAMES));
|
|
109364
|
+
if (!hasOmo)
|
|
109365
|
+
return result;
|
|
109366
|
+
const disabledHooks = readOmoDisabledHooks(directory);
|
|
109367
|
+
result.preemptiveCompaction = !disabledHooks.has("preemptive-compaction");
|
|
109368
|
+
result.contextWindowMonitor = !disabledHooks.has("context-window-monitor");
|
|
109369
|
+
result.anthropicRecovery = !disabledHooks.has("anthropic-context-window-limit-recovery");
|
|
109370
|
+
return result;
|
|
109371
|
+
}
|
|
109372
|
+
function readOmoDisabledHooks(directory) {
|
|
109373
|
+
const disabled = new Set;
|
|
109374
|
+
const configNames = [
|
|
109375
|
+
"oh-my-opencode.jsonc",
|
|
109376
|
+
"oh-my-opencode.json",
|
|
109377
|
+
"oh-my-openagent.jsonc",
|
|
109378
|
+
"oh-my-openagent.json"
|
|
109379
|
+
];
|
|
109380
|
+
try {
|
|
109381
|
+
const paths = getOpenCodeConfigPaths({ binary: "opencode" });
|
|
109382
|
+
for (const name of configNames) {
|
|
109383
|
+
const configPath = join12(paths.configDir, name);
|
|
109384
|
+
const config = readJsoncFile(configPath);
|
|
109385
|
+
if (config?.disabled_hooks) {
|
|
109386
|
+
for (const hook of config.disabled_hooks) {
|
|
109387
|
+
disabled.add(hook);
|
|
109388
|
+
}
|
|
109389
|
+
}
|
|
109390
|
+
}
|
|
109391
|
+
} catch {}
|
|
109392
|
+
for (const name of configNames) {
|
|
109393
|
+
const config = readJsoncFile(join12(directory, name));
|
|
109394
|
+
if (config?.disabled_hooks) {
|
|
109395
|
+
for (const hook of config.disabled_hooks) {
|
|
109396
|
+
disabled.add(hook);
|
|
109397
|
+
}
|
|
109398
|
+
}
|
|
109399
|
+
}
|
|
109400
|
+
const homeDir = process.env.HOME || homedir10();
|
|
109401
|
+
const omoHomeDir = join12(homeDir, ".omo");
|
|
109402
|
+
for (const name of ["omo.jsonc", "omo.json"]) {
|
|
109403
|
+
const config = readJsoncFile(join12(omoHomeDir, name));
|
|
109404
|
+
if (config?.["[opencode]"]?.disabled_hooks) {
|
|
109405
|
+
for (const hook of config["[opencode]"].disabled_hooks) {
|
|
109406
|
+
disabled.add(hook);
|
|
109407
|
+
}
|
|
109408
|
+
}
|
|
109409
|
+
}
|
|
109410
|
+
for (const name of ["omo.jsonc", "omo.json"]) {
|
|
109411
|
+
const config = readJsoncFile(join12(directory, ".omo", name));
|
|
109412
|
+
if (config?.["[opencode]"]?.disabled_hooks) {
|
|
109413
|
+
for (const hook of config["[opencode]"].disabled_hooks) {
|
|
109414
|
+
disabled.add(hook);
|
|
109415
|
+
}
|
|
109416
|
+
}
|
|
109417
|
+
}
|
|
109418
|
+
return disabled;
|
|
109419
|
+
}
|
|
109420
|
+
|
|
108440
109421
|
// src/v2/hooks/context.ts
|
|
108441
109422
|
init_data_path();
|
|
108442
109423
|
|
|
@@ -108808,7 +109789,240 @@ ${data.output?.output ?? ""}`
|
|
|
108808
109789
|
return [...content.length ? [make("assistant", content)] : [], ...results];
|
|
108809
109790
|
}
|
|
108810
109791
|
|
|
109792
|
+
// src/v2/hooks/hidden-child.ts
|
|
109793
|
+
var HIDDEN_HISTORIAN_AGENT = "historian";
|
|
109794
|
+
var HIDDEN_DREAMER_AGENT = "dreamer-classifier";
|
|
109795
|
+
async function registerHiddenChildAgents(agent) {
|
|
109796
|
+
await agent.transform((editor) => {
|
|
109797
|
+
for (const id of [HIDDEN_HISTORIAN_AGENT, HIDDEN_DREAMER_AGENT]) {
|
|
109798
|
+
editor.update(id, (config) => {
|
|
109799
|
+
config.system = "Magic Context hidden completion carrier.";
|
|
109800
|
+
config.description = "Internal Magic Context hidden completion carrier.";
|
|
109801
|
+
config.mode = "primary";
|
|
109802
|
+
config.hidden = true;
|
|
109803
|
+
config.request.settings = {};
|
|
109804
|
+
config.request.headers = {};
|
|
109805
|
+
config.request.body = {};
|
|
109806
|
+
config.permissions = [{ action: "*", resource: "*", effect: "deny" }];
|
|
109807
|
+
});
|
|
109808
|
+
}
|
|
109809
|
+
});
|
|
109810
|
+
}
|
|
109811
|
+
function newestUserText(draft) {
|
|
109812
|
+
const message = draft.messages.at(-1);
|
|
109813
|
+
if (!message || message.role !== undefined && message.role !== "user")
|
|
109814
|
+
return;
|
|
109815
|
+
const content = message.content;
|
|
109816
|
+
if (typeof content === "string" && content.length > 0)
|
|
109817
|
+
return content;
|
|
109818
|
+
const parts = Array.isArray(content) ? content : Array.isArray(message.parts) ? message.parts : [];
|
|
109819
|
+
for (const part of parts) {
|
|
109820
|
+
if (!part || typeof part !== "object")
|
|
109821
|
+
continue;
|
|
109822
|
+
const record = part;
|
|
109823
|
+
if (typeof record.text !== "string" || record.text.length === 0)
|
|
109824
|
+
continue;
|
|
109825
|
+
if (record.type === undefined || record.type === "text" || record.type === "input_text") {
|
|
109826
|
+
return record.text;
|
|
109827
|
+
}
|
|
109828
|
+
}
|
|
109829
|
+
return;
|
|
109830
|
+
}
|
|
109831
|
+
function calibratedParts(attempt) {
|
|
109832
|
+
const parts = attempt.request.body.parts;
|
|
109833
|
+
if (!Array.isArray(parts) || parts.length === 0 || parts.some((part) => !part || typeof part !== "object" || part.type !== "text" || typeof part.text !== "string")) {
|
|
109834
|
+
throw new HiddenCompletionRefusal("hidden_prompt_unrecognized", "Hidden completion accepts text-only calibrated prompts", true);
|
|
109835
|
+
}
|
|
109836
|
+
return parts.map((part) => ({ type: "text", text: part.text }));
|
|
109837
|
+
}
|
|
109838
|
+
|
|
109839
|
+
class HiddenChildHook {
|
|
109840
|
+
childIDs = new Set;
|
|
109841
|
+
attempts = new Map;
|
|
109842
|
+
registerChild(sessionID) {
|
|
109843
|
+
this.childIDs.add(sessionID);
|
|
109844
|
+
}
|
|
109845
|
+
registerAttempt(marker, attempt) {
|
|
109846
|
+
this.registerChild(attempt.childSessionId);
|
|
109847
|
+
this.attempts.set(marker, attempt);
|
|
109848
|
+
}
|
|
109849
|
+
releaseAttempt(marker) {
|
|
109850
|
+
this.attempts.delete(marker);
|
|
109851
|
+
}
|
|
109852
|
+
owns(sessionID) {
|
|
109853
|
+
return this.childIDs.has(sessionID);
|
|
109854
|
+
}
|
|
109855
|
+
apply(draft) {
|
|
109856
|
+
if (!this.owns(draft.sessionID))
|
|
109857
|
+
return false;
|
|
109858
|
+
const raw = newestUserText(draft);
|
|
109859
|
+
const stripped = raw === undefined ? undefined : stripWellFormedLeadingTagPrefix(raw);
|
|
109860
|
+
const attempt = (raw !== undefined ? this.attempts.get(raw) : undefined) ?? (stripped && stripped !== raw ? this.attempts.get(stripped) : undefined);
|
|
109861
|
+
if (!attempt || attempt.childSessionId !== draft.sessionID) {
|
|
109862
|
+
throw new HiddenCompletionRefusal("hidden_prompt_unrecognized", "Refusing an unregistered prompt on a Magic Context hidden-run session", true);
|
|
109863
|
+
}
|
|
109864
|
+
if (attempt.request.signal?.aborted) {
|
|
109865
|
+
throw new Error("Hidden completion prompt aborted");
|
|
109866
|
+
}
|
|
109867
|
+
const system = typeof attempt.request.body.system === "string" ? attempt.request.body.system : attempt.identity.system;
|
|
109868
|
+
const temperature = attempt.request.body.temperature;
|
|
109869
|
+
draft.system = [{ type: "text", text: system }];
|
|
109870
|
+
draft.messages = [{ role: "user", content: calibratedParts(attempt) }];
|
|
109871
|
+
draft.options = {
|
|
109872
|
+
maxOutputTokens: 32768,
|
|
109873
|
+
maxTokens: 32768,
|
|
109874
|
+
...typeof temperature === "number" && Number.isFinite(temperature) ? { temperature } : {}
|
|
109875
|
+
};
|
|
109876
|
+
draft.tools = {};
|
|
109877
|
+
attempt.shaped = true;
|
|
109878
|
+
return true;
|
|
109879
|
+
}
|
|
109880
|
+
}
|
|
109881
|
+
|
|
108811
109882
|
// src/v2/hidden-completion.ts
|
|
109883
|
+
var META_PREFIX = "opencode2_hidden_children:";
|
|
109884
|
+
var POLL_INTERVAL_MS = 200;
|
|
109885
|
+
function hiddenChildrenMetaKey(projectIdentity) {
|
|
109886
|
+
return `${META_PREFIX}${projectIdentity}`;
|
|
109887
|
+
}
|
|
109888
|
+
function emptyMeta() {
|
|
109889
|
+
return { version: 1, active: {}, retired_children: [] };
|
|
109890
|
+
}
|
|
109891
|
+
function isModel(value) {
|
|
109892
|
+
if (!value || typeof value !== "object")
|
|
109893
|
+
return false;
|
|
109894
|
+
const model = value;
|
|
109895
|
+
return typeof model.providerID === "string" && typeof model.modelID === "string";
|
|
109896
|
+
}
|
|
109897
|
+
function isRole(value) {
|
|
109898
|
+
return value === "historian" || value === "dreamer";
|
|
109899
|
+
}
|
|
109900
|
+
function isPersistedChild(value) {
|
|
109901
|
+
if (!value || typeof value !== "object")
|
|
109902
|
+
return false;
|
|
109903
|
+
const child = value;
|
|
109904
|
+
return typeof child.id === "string" && isRole(child.role) && typeof child.generation === "string" && typeof child.title === "string" && isModel(child.model) && typeof child.created_at === "number" && typeof child.title_reasserted === "boolean";
|
|
109905
|
+
}
|
|
109906
|
+
function parseMeta(value) {
|
|
109907
|
+
if (value === null)
|
|
109908
|
+
return emptyMeta();
|
|
109909
|
+
let parsed;
|
|
109910
|
+
try {
|
|
109911
|
+
parsed = JSON.parse(value);
|
|
109912
|
+
} catch (error) {
|
|
109913
|
+
throw new Error("Invalid OpenCode 2 hidden-child metadata JSON", { cause: error });
|
|
109914
|
+
}
|
|
109915
|
+
if (!parsed || typeof parsed !== "object") {
|
|
109916
|
+
throw new Error("Invalid OpenCode 2 hidden-child metadata");
|
|
109917
|
+
}
|
|
109918
|
+
const candidate = parsed;
|
|
109919
|
+
if (candidate.version !== 1 || !candidate.active || !candidate.retired_children) {
|
|
109920
|
+
throw new Error("Unsupported OpenCode 2 hidden-child metadata version");
|
|
109921
|
+
}
|
|
109922
|
+
const active = {};
|
|
109923
|
+
for (const role of ["historian", "dreamer"]) {
|
|
109924
|
+
const child = candidate.active[role];
|
|
109925
|
+
if (child !== undefined) {
|
|
109926
|
+
if (!isPersistedChild(child) || child.role !== role) {
|
|
109927
|
+
throw new Error(`Invalid OpenCode 2 ${role} child metadata`);
|
|
109928
|
+
}
|
|
109929
|
+
active[role] = child;
|
|
109930
|
+
}
|
|
109931
|
+
}
|
|
109932
|
+
const retired = candidate.retired_children;
|
|
109933
|
+
if (!Array.isArray(retired) || retired.some((child) => !isPersistedChild(child) || typeof child.retired_at !== "number" || typeof child.reason !== "string")) {
|
|
109934
|
+
throw new Error("Invalid OpenCode 2 retired-child metadata");
|
|
109935
|
+
}
|
|
109936
|
+
return { version: 1, active, retired_children: retired };
|
|
109937
|
+
}
|
|
109938
|
+
|
|
109939
|
+
class HiddenChildStateStore {
|
|
109940
|
+
db;
|
|
109941
|
+
key;
|
|
109942
|
+
constructor(db, projectIdentity) {
|
|
109943
|
+
this.db = db;
|
|
109944
|
+
this.key = hiddenChildrenMetaKey(projectIdentity);
|
|
109945
|
+
}
|
|
109946
|
+
read() {
|
|
109947
|
+
const row = this.db.prepare("SELECT value FROM schema_migrations_meta WHERE key = ?").get(this.key);
|
|
109948
|
+
return parseMeta(row?.value ?? null);
|
|
109949
|
+
}
|
|
109950
|
+
mutate(change) {
|
|
109951
|
+
return this.db.transaction(() => {
|
|
109952
|
+
const state = this.read();
|
|
109953
|
+
const result = change(state);
|
|
109954
|
+
this.db.prepare(`INSERT INTO schema_migrations_meta (key, value) VALUES (?, ?)
|
|
109955
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(this.key, JSON.stringify(state));
|
|
109956
|
+
return result;
|
|
109957
|
+
})();
|
|
109958
|
+
}
|
|
109959
|
+
put(child) {
|
|
109960
|
+
this.mutate((state) => {
|
|
109961
|
+
state.active[child.role] = child;
|
|
109962
|
+
});
|
|
109963
|
+
}
|
|
109964
|
+
updateModel(child, model) {
|
|
109965
|
+
return this.mutate((state) => {
|
|
109966
|
+
const active = state.active[child.role];
|
|
109967
|
+
if (!active || active.id !== child.id)
|
|
109968
|
+
return { ...child, model };
|
|
109969
|
+
active.model = model;
|
|
109970
|
+
return { ...active };
|
|
109971
|
+
});
|
|
109972
|
+
}
|
|
109973
|
+
markTitleReasserted(child) {
|
|
109974
|
+
return this.mutate((state) => {
|
|
109975
|
+
const active = state.active[child.role];
|
|
109976
|
+
if (!active || active.id !== child.id)
|
|
109977
|
+
return { ...child, title_reasserted: true };
|
|
109978
|
+
active.title_reasserted = true;
|
|
109979
|
+
return { ...active };
|
|
109980
|
+
});
|
|
109981
|
+
}
|
|
109982
|
+
retire(child, reason) {
|
|
109983
|
+
this.mutate((state) => {
|
|
109984
|
+
const active = state.active[child.role];
|
|
109985
|
+
if (!active || active.id !== child.id)
|
|
109986
|
+
return;
|
|
109987
|
+
state.retired_children.push({
|
|
109988
|
+
...active,
|
|
109989
|
+
retired_at: Date.now(),
|
|
109990
|
+
reason
|
|
109991
|
+
});
|
|
109992
|
+
delete state.active[child.role];
|
|
109993
|
+
});
|
|
109994
|
+
}
|
|
109995
|
+
}
|
|
109996
|
+
function modelKey(model) {
|
|
109997
|
+
return `${model.providerID}/${model.modelID}`;
|
|
109998
|
+
}
|
|
109999
|
+
function sameModel(left, right) {
|
|
110000
|
+
return modelKey(left) === modelKey(right) && left.variant === right.variant;
|
|
110001
|
+
}
|
|
110002
|
+
function configuredHead(identity) {
|
|
110003
|
+
const candidates = [identity.model, ...identity.configuredModels ?? []];
|
|
110004
|
+
for (const candidate of candidates) {
|
|
110005
|
+
const entry = toModelEntry(candidate);
|
|
110006
|
+
const parsed = entry ? parseProviderModel(entry.model) : null;
|
|
110007
|
+
if (parsed)
|
|
110008
|
+
return { ...parsed, ...entry?.qualifier ? { variant: entry.qualifier } : {} };
|
|
110009
|
+
}
|
|
110010
|
+
return;
|
|
110011
|
+
}
|
|
110012
|
+
function roleFor(identity) {
|
|
110013
|
+
return identity.kind === "dreamer-task" ? "dreamer" : "historian";
|
|
110014
|
+
}
|
|
110015
|
+
function roleTitle(role) {
|
|
110016
|
+
return role === "historian" ? "Magic Context historian" : "Magic Context dreamer";
|
|
110017
|
+
}
|
|
110018
|
+
function roleAgent(role) {
|
|
110019
|
+
return role === "historian" ? HIDDEN_HISTORIAN_AGENT : HIDDEN_DREAMER_AGENT;
|
|
110020
|
+
}
|
|
110021
|
+
function promptText(request) {
|
|
110022
|
+
const parts = request.body.parts;
|
|
110023
|
+
return Array.isArray(parts) ? parts.flatMap((part) => part && typeof part === "object" && typeof part.text === "string" ? [part.text] : []).join(`
|
|
110024
|
+
`) : "";
|
|
110025
|
+
}
|
|
108812
110026
|
function meter(system, prompt, text) {
|
|
108813
110027
|
return {
|
|
108814
110028
|
input: estimateTokens(system) + estimateTokens(prompt),
|
|
@@ -108817,115 +110031,294 @@ function meter(system, prompt, text) {
|
|
|
108817
110031
|
cacheWrite: 0
|
|
108818
110032
|
};
|
|
108819
110033
|
}
|
|
108820
|
-
|
|
110034
|
+
function successfulReusableAssistant(row) {
|
|
110035
|
+
return row !== undefined && typeof row.data.finish === "string" && row.data.error === undefined && row.data.tokens !== undefined;
|
|
110036
|
+
}
|
|
110037
|
+
function assistantText(row) {
|
|
110038
|
+
const text = (row.data.content ?? []).flatMap((part) => part.type === "text" && typeof part.text === "string" ? [part.text] : []).join("");
|
|
110039
|
+
return text.length > 0 ? text : null;
|
|
110040
|
+
}
|
|
110041
|
+
function errorText(value) {
|
|
110042
|
+
if (value instanceof Error)
|
|
110043
|
+
return value.message;
|
|
110044
|
+
if (typeof value === "string")
|
|
110045
|
+
return value;
|
|
110046
|
+
try {
|
|
110047
|
+
return JSON.stringify(value);
|
|
110048
|
+
} catch {
|
|
110049
|
+
return String(value);
|
|
110050
|
+
}
|
|
110051
|
+
}
|
|
110052
|
+
function requestModel(request, current) {
|
|
110053
|
+
const requested = request.body.model;
|
|
110054
|
+
if (requested && typeof requested.providerID === "string" && typeof requested.modelID === "string") {
|
|
110055
|
+
return {
|
|
110056
|
+
providerID: requested.providerID,
|
|
110057
|
+
modelID: requested.modelID,
|
|
110058
|
+
...typeof request.body.variant === "string" ? { variant: request.body.variant } : {}
|
|
110059
|
+
};
|
|
110060
|
+
}
|
|
110061
|
+
return current;
|
|
110062
|
+
}
|
|
110063
|
+
function withReader(openReader, read) {
|
|
110064
|
+
const reader = openReader();
|
|
110065
|
+
try {
|
|
110066
|
+
return read(reader);
|
|
110067
|
+
} finally {
|
|
110068
|
+
reader.close?.();
|
|
110069
|
+
}
|
|
110070
|
+
}
|
|
110071
|
+
async function sleepUntilPoll(signal, deadline) {
|
|
110072
|
+
if (signal?.aborted)
|
|
110073
|
+
throw new Error("Hidden completion prompt aborted");
|
|
110074
|
+
const delay = Math.min(POLL_INTERVAL_MS, Math.max(0, deadline - Date.now()));
|
|
110075
|
+
if (delay <= 0)
|
|
110076
|
+
return;
|
|
110077
|
+
await new Promise((resolve, reject) => {
|
|
110078
|
+
const timer = setTimeout(resolve, delay);
|
|
110079
|
+
const abort = () => {
|
|
110080
|
+
clearTimeout(timer);
|
|
110081
|
+
reject(new Error("Hidden completion prompt aborted"));
|
|
110082
|
+
};
|
|
110083
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
110084
|
+
if (signal?.aborted)
|
|
110085
|
+
abort();
|
|
110086
|
+
else
|
|
110087
|
+
setTimeout(() => {
|
|
110088
|
+
signal?.removeEventListener("abort", abort);
|
|
110089
|
+
}, delay);
|
|
110090
|
+
});
|
|
110091
|
+
}
|
|
110092
|
+
async function awaitAssistantRow(openReader, childID, afterSeq, deadline, signal) {
|
|
110093
|
+
for (;; ) {
|
|
110094
|
+
const row = withReader(openReader, (reader) => reader.latestAssistant(childID));
|
|
110095
|
+
if (row && row.seq > afterSeq) {
|
|
110096
|
+
if (row.data.error !== undefined) {
|
|
110097
|
+
throw new Error(`Hidden completion provider error: ${errorText(row.data.error)}`);
|
|
110098
|
+
}
|
|
110099
|
+
if (typeof row.data.finish === "string")
|
|
110100
|
+
return row;
|
|
110101
|
+
}
|
|
110102
|
+
if (Date.now() >= deadline) {
|
|
110103
|
+
throw new Error("Hidden completion timed out waiting for a persisted assistant row");
|
|
110104
|
+
}
|
|
110105
|
+
await sleepUntilPoll(signal, deadline);
|
|
110106
|
+
}
|
|
110107
|
+
}
|
|
110108
|
+
async function createV2HiddenCompletionExecutor(host, options) {
|
|
108821
110109
|
const runs = new WeakMap;
|
|
108822
|
-
const
|
|
108823
|
-
const
|
|
108824
|
-
const
|
|
108825
|
-
|
|
108826
|
-
|
|
108827
|
-
|
|
108828
|
-
|
|
108829
|
-
}
|
|
108830
|
-
const
|
|
108831
|
-
|
|
108832
|
-
|
|
108833
|
-
|
|
108834
|
-
|
|
108835
|
-
|
|
108836
|
-
|
|
108837
|
-
|
|
108838
|
-
|
|
108839
|
-
|
|
108840
|
-
|
|
108841
|
-
|
|
108842
|
-
|
|
108843
|
-
|
|
108844
|
-
|
|
108845
|
-
|
|
108846
|
-
|
|
108847
|
-
|
|
108848
|
-
|
|
108849
|
-
if (
|
|
108850
|
-
|
|
110110
|
+
const store = new HiddenChildStateStore(options.db, options.projectIdentity);
|
|
110111
|
+
const generation = options.generation ?? "opencode2";
|
|
110112
|
+
const roleTails = new Map;
|
|
110113
|
+
const persisted = store.read();
|
|
110114
|
+
for (const child of [...Object.values(persisted.active), ...persisted.retired_children]) {
|
|
110115
|
+
if (child)
|
|
110116
|
+
options.hook.registerChild(child.id);
|
|
110117
|
+
}
|
|
110118
|
+
const acquireRole = async (role) => {
|
|
110119
|
+
const previous = roleTails.get(role) ?? Promise.resolve();
|
|
110120
|
+
let release;
|
|
110121
|
+
const gate = new Promise((resolve) => {
|
|
110122
|
+
release = resolve;
|
|
110123
|
+
});
|
|
110124
|
+
const tail = previous.then(() => gate);
|
|
110125
|
+
roleTails.set(role, tail);
|
|
110126
|
+
await previous;
|
|
110127
|
+
return () => {
|
|
110128
|
+
release();
|
|
110129
|
+
if (roleTails.get(role) === tail)
|
|
110130
|
+
roleTails.delete(role);
|
|
110131
|
+
};
|
|
110132
|
+
};
|
|
110133
|
+
const resolveHead = async (identity) => {
|
|
110134
|
+
const configured = configuredHead(identity);
|
|
110135
|
+
if (configured)
|
|
110136
|
+
return configured;
|
|
110137
|
+
if (!identity.parentSessionId) {
|
|
110138
|
+
throw new HiddenCompletionRefusal("hidden_model_unsupported", "Hidden completion requires a configured model or an existing parent session model", true);
|
|
108851
110139
|
}
|
|
108852
|
-
const
|
|
108853
|
-
if (!
|
|
108854
|
-
throw new HiddenCompletionRefusal("
|
|
110140
|
+
const parent = await host.get({ sessionID: identity.parentSessionId });
|
|
110141
|
+
if (!parent.model) {
|
|
110142
|
+
throw new HiddenCompletionRefusal("hidden_model_unsupported", "Hidden completion could not resolve the parent session model", true);
|
|
108855
110143
|
}
|
|
108856
|
-
|
|
108857
|
-
|
|
108858
|
-
|
|
108859
|
-
|
|
110144
|
+
return {
|
|
110145
|
+
providerID: parent.model.providerID,
|
|
110146
|
+
modelID: parent.model.id,
|
|
110147
|
+
...parent.model.variant ? { variant: parent.model.variant } : {}
|
|
110148
|
+
};
|
|
110149
|
+
};
|
|
110150
|
+
const switchChildModel = async (run, requested) => {
|
|
110151
|
+
if (sameModel(run.child.model, requested))
|
|
110152
|
+
return;
|
|
110153
|
+
await host.switchModel({
|
|
110154
|
+
sessionID: run.child.id,
|
|
110155
|
+
model: {
|
|
110156
|
+
providerID: requested.providerID,
|
|
110157
|
+
id: requested.modelID,
|
|
110158
|
+
...requested.variant ? { variant: requested.variant } : {}
|
|
108860
110159
|
}
|
|
108861
|
-
|
|
108862
|
-
|
|
108863
|
-
|
|
108864
|
-
|
|
108865
|
-
|
|
108866
|
-
|
|
108867
|
-
|
|
108868
|
-
|
|
108869
|
-
}
|
|
110160
|
+
});
|
|
110161
|
+
run.child = store.updateModel(run.child, requested);
|
|
110162
|
+
};
|
|
110163
|
+
const retire = (run, reason) => {
|
|
110164
|
+
if (run.retired)
|
|
110165
|
+
return;
|
|
110166
|
+
store.retire(run.child, reason);
|
|
110167
|
+
run.retired = true;
|
|
110168
|
+
};
|
|
110169
|
+
const interruptAndRetire = async (run, reason) => {
|
|
110170
|
+
try {
|
|
110171
|
+
await host.interrupt({ sessionID: run.child.id });
|
|
110172
|
+
} finally {
|
|
110173
|
+
retire(run, reason);
|
|
110174
|
+
}
|
|
110175
|
+
};
|
|
108870
110176
|
return {
|
|
108871
110177
|
capabilities: { tools: false, harness: "opencode2" },
|
|
108872
110178
|
async open(identity) {
|
|
108873
|
-
const
|
|
108874
|
-
const
|
|
108875
|
-
|
|
108876
|
-
|
|
108877
|
-
|
|
108878
|
-
|
|
108879
|
-
|
|
108880
|
-
|
|
110179
|
+
const role = roleFor(identity);
|
|
110180
|
+
const releaseRole = await acquireRole(role);
|
|
110181
|
+
let openedChild;
|
|
110182
|
+
try {
|
|
110183
|
+
await options.ensureAgent?.();
|
|
110184
|
+
const head = await resolveHead(identity);
|
|
110185
|
+
let active = store.read().active[role];
|
|
110186
|
+
if (active && active.generation !== generation) {
|
|
110187
|
+
store.retire(active, "host-generation-changed");
|
|
110188
|
+
active = undefined;
|
|
110189
|
+
}
|
|
110190
|
+
if (active) {
|
|
110191
|
+
const activeID = active.id;
|
|
110192
|
+
const latest = withReader(options.openReader, (reader) => reader.latestAssistant(activeID));
|
|
110193
|
+
if (!successfulReusableAssistant(latest)) {
|
|
110194
|
+
store.retire(active, "newest-assistant-not-reusable");
|
|
110195
|
+
active = undefined;
|
|
110196
|
+
}
|
|
110197
|
+
}
|
|
110198
|
+
if (!active) {
|
|
110199
|
+
const title = roleTitle(role);
|
|
110200
|
+
const created = await host.create({
|
|
110201
|
+
title,
|
|
110202
|
+
agent: roleAgent(role),
|
|
110203
|
+
model: {
|
|
110204
|
+
providerID: head.providerID,
|
|
110205
|
+
id: head.modelID,
|
|
110206
|
+
...head.variant ? { variant: head.variant } : {}
|
|
110207
|
+
},
|
|
110208
|
+
location: { directory: identity.directory },
|
|
110209
|
+
metadata: { magic_context: "hidden-run", role }
|
|
110210
|
+
});
|
|
110211
|
+
if (!created.id)
|
|
110212
|
+
throw new Error("OpenCode 2 did not return a child session id");
|
|
110213
|
+
active = {
|
|
110214
|
+
id: created.id,
|
|
110215
|
+
role,
|
|
110216
|
+
generation,
|
|
110217
|
+
title,
|
|
110218
|
+
model: head,
|
|
110219
|
+
created_at: Date.now(),
|
|
110220
|
+
title_reasserted: false
|
|
110221
|
+
};
|
|
110222
|
+
store.put(active);
|
|
110223
|
+
options.hook.registerChild(active.id);
|
|
110224
|
+
}
|
|
110225
|
+
openedChild = active;
|
|
110226
|
+
const handle = { id: active.id, childSessionId: active.id };
|
|
110227
|
+
const run = {
|
|
110228
|
+
identity,
|
|
110229
|
+
role,
|
|
110230
|
+
child: active,
|
|
110231
|
+
releaseRole,
|
|
110232
|
+
failed: false,
|
|
110233
|
+
retired: false
|
|
110234
|
+
};
|
|
110235
|
+
runs.set(handle, run);
|
|
110236
|
+
await switchChildModel(run, head);
|
|
110237
|
+
return handle;
|
|
110238
|
+
} catch (error) {
|
|
110239
|
+
if (openedChild)
|
|
110240
|
+
store.retire(openedChild, "hidden-run-open-failed");
|
|
110241
|
+
releaseRole();
|
|
110242
|
+
throw error;
|
|
110243
|
+
}
|
|
108881
110244
|
},
|
|
108882
110245
|
async attempt(handle, request) {
|
|
108883
110246
|
const run = runs.get(handle);
|
|
108884
110247
|
if (!run)
|
|
108885
110248
|
throw new Error("Unknown hidden completion run");
|
|
108886
|
-
|
|
108887
|
-
|
|
108888
|
-
if (sessionID === undefined)
|
|
108889
|
-
throw new Error("Hidden completion session id missing");
|
|
108890
|
-
const requested = request.body.model ?? actual;
|
|
108891
|
-
if (modelKey(requested) !== modelKey(actual))
|
|
108892
|
-
refuseModel(modelKey(requested), modelKey(actual));
|
|
108893
|
-
if (request.signal?.aborted)
|
|
110249
|
+
if (request.signal?.aborted) {
|
|
110250
|
+
await interruptAndRetire(run, "aborted-before-prompt");
|
|
108894
110251
|
throw new Error("Hidden completion prompt aborted");
|
|
108895
|
-
|
|
108896
|
-
const
|
|
108897
|
-
|
|
110252
|
+
}
|
|
110253
|
+
const requested = requestModel(request, run.child.model);
|
|
110254
|
+
await switchChildModel(run, requested);
|
|
110255
|
+
const baseline = withReader(options.openReader, (reader) => reader.latestSequence(run.child.id));
|
|
110256
|
+
const marker = `mc:hidden:${crypto.randomUUID()}:${crypto.randomUUID()}`;
|
|
110257
|
+
const attempt = {
|
|
110258
|
+
childSessionId: run.child.id,
|
|
110259
|
+
identity: run.identity,
|
|
110260
|
+
request,
|
|
110261
|
+
shaped: false
|
|
110262
|
+
};
|
|
110263
|
+
options.hook.registerAttempt(marker, attempt);
|
|
110264
|
+
const deadline = Date.now() + run.identity.timeoutMs;
|
|
110265
|
+
let abortReject;
|
|
110266
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
110267
|
+
abortReject = reject;
|
|
110268
|
+
});
|
|
110269
|
+
const onAbort = () => {
|
|
110270
|
+
interruptAndRetire(run, "prompt-aborted").finally(() => abortReject(new Error("Hidden completion prompt aborted")));
|
|
110271
|
+
};
|
|
110272
|
+
const deadlineTimer = setTimeout(() => {
|
|
110273
|
+
interruptAndRetire(run, "prompt-timeout").finally(() => abortReject(new Error("Hidden completion prompt timed out")));
|
|
110274
|
+
}, Math.max(0, deadline - Date.now()));
|
|
110275
|
+
request.signal?.addEventListener("abort", onAbort, { once: true });
|
|
108898
110276
|
try {
|
|
108899
|
-
|
|
108900
|
-
|
|
108901
|
-
|
|
108902
|
-
|
|
108903
|
-
|
|
108904
|
-
|
|
108905
|
-
|
|
108906
|
-
|
|
108907
|
-
|
|
108908
|
-
|
|
108909
|
-
|
|
108910
|
-
|
|
108911
|
-
|
|
108912
|
-
|
|
108913
|
-
|
|
110277
|
+
await Promise.race([
|
|
110278
|
+
host.prompt({ sessionID: run.child.id, text: marker }),
|
|
110279
|
+
aborted
|
|
110280
|
+
]);
|
|
110281
|
+
await Promise.race([host.wait({ sessionID: run.child.id }), aborted]);
|
|
110282
|
+
clearTimeout(deadlineTimer);
|
|
110283
|
+
const row = await Promise.race([
|
|
110284
|
+
awaitAssistantRow(options.openReader, run.child.id, baseline, deadline, request.signal),
|
|
110285
|
+
aborted
|
|
110286
|
+
]);
|
|
110287
|
+
if (!attempt.shaped) {
|
|
110288
|
+
throw new HiddenCompletionRefusal("hidden_prompt_unrecognized", "Host did not dispatch the hidden child context hook", true);
|
|
110289
|
+
}
|
|
110290
|
+
if (!run.child.title_reasserted) {
|
|
110291
|
+
await host.update({ sessionID: run.child.id, title: run.child.title });
|
|
110292
|
+
run.child = store.markTitleReasserted(run.child);
|
|
110293
|
+
}
|
|
110294
|
+
const text = assistantText(row);
|
|
108914
110295
|
const system = typeof request.body.system === "string" ? request.body.system : run.identity.system;
|
|
108915
|
-
const
|
|
108916
|
-
usage.input += run.usage?.input ?? 0;
|
|
108917
|
-
usage.output += run.usage?.output ?? 0;
|
|
108918
|
-
run.usage = usage;
|
|
110296
|
+
const tokens = row.data.tokens;
|
|
108919
110297
|
run.completion = {
|
|
108920
|
-
text
|
|
108921
|
-
|
|
108922
|
-
|
|
108923
|
-
|
|
108924
|
-
|
|
110298
|
+
text,
|
|
110299
|
+
reasoning: null,
|
|
110300
|
+
usage: tokens ? {
|
|
110301
|
+
input: tokens.input,
|
|
110302
|
+
output: tokens.output,
|
|
110303
|
+
cacheRead: tokens.cache.read,
|
|
110304
|
+
cacheWrite: tokens.cache.write
|
|
110305
|
+
} : meter(system, promptText(request), text ?? ""),
|
|
110306
|
+
lengthCapped: ["length", "max_tokens"].includes(row.data.finish ?? ""),
|
|
110307
|
+
providerId: row.data.model?.providerID ?? requested.providerID,
|
|
110308
|
+
modelId: row.data.model?.id ?? requested.modelID
|
|
108925
110309
|
};
|
|
110310
|
+
} catch (error) {
|
|
110311
|
+
run.failed = true;
|
|
110312
|
+
if (request.signal?.aborted && !run.retired) {
|
|
110313
|
+
await interruptAndRetire(run, "prompt-aborted");
|
|
110314
|
+
} else if (error instanceof Error && error.message.includes("timed out") && !run.retired) {
|
|
110315
|
+
await interruptAndRetire(run, "prompt-timeout");
|
|
110316
|
+
}
|
|
110317
|
+
throw error;
|
|
108926
110318
|
} finally {
|
|
108927
|
-
|
|
108928
|
-
|
|
110319
|
+
clearTimeout(deadlineTimer);
|
|
110320
|
+
request.signal?.removeEventListener("abort", onAbort);
|
|
110321
|
+
options.hook.releaseAttempt(marker);
|
|
108929
110322
|
}
|
|
108930
110323
|
},
|
|
108931
110324
|
async collect(handle) {
|
|
@@ -108934,18 +110327,27 @@ async function createV2HiddenCompletionExecutor(host, currentModel) {
|
|
|
108934
110327
|
throw new Error("Hidden completion has no settled output");
|
|
108935
110328
|
return completion;
|
|
108936
110329
|
},
|
|
108937
|
-
async close() {
|
|
110330
|
+
async close(handle, settlement) {
|
|
110331
|
+
if (!handle)
|
|
110332
|
+
return;
|
|
110333
|
+
const run = runs.get(handle);
|
|
110334
|
+
if (!run)
|
|
110335
|
+
return;
|
|
110336
|
+
try {
|
|
110337
|
+
if (!run.completion && (run.failed || !settlement.promptSettled)) {
|
|
110338
|
+
retire(run, "hidden-run-failed");
|
|
110339
|
+
}
|
|
110340
|
+
} finally {
|
|
110341
|
+
runs.delete(handle);
|
|
110342
|
+
run.releaseRole();
|
|
110343
|
+
}
|
|
110344
|
+
}
|
|
108938
110345
|
};
|
|
108939
110346
|
}
|
|
108940
110347
|
|
|
108941
110348
|
// src/v2/store-reader.ts
|
|
108942
|
-
import { join as join11 } from "node:path";
|
|
108943
|
-
function sourceDatabaseFilename(channel, env = process.env) {
|
|
108944
|
-
return env.OPENCODE_DB ?? (["latest", "dev", "beta", "next", "prod"].includes(channel) || env.OPENCODE_DISABLE_CHANNEL_DB === "1" || env.OPENCODE_DISABLE_CHANNEL_DB === "true" ? "opencode.db" : `opencode-${channel.replace(/[^a-zA-Z0-9._-]/g, "")}.db`);
|
|
108945
|
-
}
|
|
108946
110349
|
function gaDatabasePath(dataHome, channel = "latest", env = process.env) {
|
|
108947
|
-
|
|
108948
|
-
return filename === ":memory:" ? filename : join11(dataHome, "opencode", filename);
|
|
110350
|
+
return resolveOpenCodeDbPath("v2", { dataHome, channel, env }).path;
|
|
108949
110351
|
}
|
|
108950
110352
|
function decode2(row) {
|
|
108951
110353
|
const data = JSON.parse(row.data);
|
|
@@ -108962,6 +110364,12 @@ class V2StoreReader {
|
|
|
108962
110364
|
db;
|
|
108963
110365
|
constructor(path) {
|
|
108964
110366
|
this.db = new Database(path, { readonly: true, fileMustExist: true });
|
|
110367
|
+
try {
|
|
110368
|
+
assertOpenCodeStoreGeneration(this.db, "v2", path);
|
|
110369
|
+
} catch (error) {
|
|
110370
|
+
this.db.close();
|
|
110371
|
+
throw error;
|
|
110372
|
+
}
|
|
108965
110373
|
}
|
|
108966
110374
|
close() {
|
|
108967
110375
|
this.db.close();
|
|
@@ -108987,6 +110395,16 @@ class V2StoreReader {
|
|
|
108987
110395
|
idleRows(sessionID, after = -1) {
|
|
108988
110396
|
return this.all(sessionID, after, "idle");
|
|
108989
110397
|
}
|
|
110398
|
+
latestSequence(sessionID) {
|
|
110399
|
+
const row = this.db.prepare("SELECT MAX(seq) AS seq FROM session_message WHERE session_id = ?").get(sessionID);
|
|
110400
|
+
return typeof row?.seq === "number" ? row.seq : -1;
|
|
110401
|
+
}
|
|
110402
|
+
latestAssistant(sessionID) {
|
|
110403
|
+
const row = this.db.prepare(`SELECT id, session_id, type, seq, data FROM session_message
|
|
110404
|
+
WHERE session_id = ? AND type = 'assistant'
|
|
110405
|
+
ORDER BY seq DESC LIMIT 1`).get(sessionID);
|
|
110406
|
+
return row ? decode2(row) : undefined;
|
|
110407
|
+
}
|
|
108990
110408
|
window(sessionID) {
|
|
108991
110409
|
return this.db.transaction(() => {
|
|
108992
110410
|
const cut = this.latestCompaction(sessionID);
|
|
@@ -109062,7 +110480,7 @@ function buildDreamTaskRuntimeConfigs(dreamer, harness, language, muralModel) {
|
|
|
109062
110480
|
|
|
109063
110481
|
// src/features/magic-context/dreamer/task-executor.ts
|
|
109064
110482
|
import { createHash as createHash27 } from "node:crypto";
|
|
109065
|
-
import { existsSync as
|
|
110483
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
109066
110484
|
|
|
109067
110485
|
// src/agents/dreamer.ts
|
|
109068
110486
|
var DREAMER_AGENT = "dreamer";
|
|
@@ -112099,7 +113517,7 @@ function deterministicJitterMs(intervalMs, noteId, hash) {
|
|
|
112099
113517
|
}
|
|
112100
113518
|
|
|
112101
113519
|
// src/features/magic-context/smart-notes/wake-plane.ts
|
|
112102
|
-
import { join as
|
|
113520
|
+
import { join as join13 } from "node:path";
|
|
112103
113521
|
init_data_path();
|
|
112104
113522
|
var WAKE_PLANE_CAPABILITY = "wake.create";
|
|
112105
113523
|
var WAKE_PLANE_STATUS_TTL_MS = 5 * 60 * 1000;
|
|
@@ -112109,7 +113527,7 @@ var inFlightProbe = null;
|
|
|
112109
113527
|
var catalogProbe = probeWakePlaneCatalog;
|
|
112110
113528
|
var now = () => Date.now();
|
|
112111
113529
|
function connectionFile() {
|
|
112112
|
-
return
|
|
113530
|
+
return join13(getDataDir(), "cortexkit", "run", "subc-connection.json");
|
|
112113
113531
|
}
|
|
112114
113532
|
async function probeWakePlaneCatalog() {
|
|
112115
113533
|
const file = connectionFile();
|
|
@@ -112759,8 +114177,8 @@ async function archiveExpiredMemories(args) {
|
|
|
112759
114177
|
|
|
112760
114178
|
// src/features/magic-context/dreamer/maintain-docs-protected-enforcement.ts
|
|
112761
114179
|
init_logger();
|
|
112762
|
-
import { existsSync as
|
|
112763
|
-
import { join as
|
|
114180
|
+
import { existsSync as existsSync15, readFileSync as readFileSync12, writeFileSync as writeFileSync6 } from "node:fs";
|
|
114181
|
+
import { join as join14 } from "node:path";
|
|
112764
114182
|
|
|
112765
114183
|
// src/features/magic-context/dreamer/protected-regions.ts
|
|
112766
114184
|
var PROTECTED_START_TOKEN = "mc:protected START";
|
|
@@ -112861,10 +114279,10 @@ var MAINTAIN_DOCS_SNAPSHOT_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
|
|
|
112861
114279
|
function snapshotMaintainDocsFiles(docsDir) {
|
|
112862
114280
|
const snapshot = new Map;
|
|
112863
114281
|
for (const name of MAINTAIN_DOCS_SNAPSHOT_FILES) {
|
|
112864
|
-
const path =
|
|
114282
|
+
const path = join14(docsDir, name);
|
|
112865
114283
|
try {
|
|
112866
|
-
if (
|
|
112867
|
-
snapshot.set(name,
|
|
114284
|
+
if (existsSync15(path)) {
|
|
114285
|
+
snapshot.set(name, readFileSync12(path, "utf8"));
|
|
112868
114286
|
}
|
|
112869
114287
|
} catch {}
|
|
112870
114288
|
}
|
|
@@ -112872,9 +114290,9 @@ function snapshotMaintainDocsFiles(docsDir) {
|
|
|
112872
114290
|
}
|
|
112873
114291
|
function enforceMaintainDocsProtectedRegions(args) {
|
|
112874
114292
|
for (const [fileName, original] of args.snapshot) {
|
|
112875
|
-
const path =
|
|
114293
|
+
const path = join14(args.docsDir, fileName);
|
|
112876
114294
|
try {
|
|
112877
|
-
const current =
|
|
114295
|
+
const current = readFileSync12(path, "utf8");
|
|
112878
114296
|
const { text, violated } = enforceProtectedRegions(original, current);
|
|
112879
114297
|
if (!violated) {
|
|
112880
114298
|
continue;
|
|
@@ -112892,7 +114310,7 @@ import { createHash as createHash25 } from "node:crypto";
|
|
|
112892
114310
|
init_logger();
|
|
112893
114311
|
|
|
112894
114312
|
// src/features/magic-context/dreamer/map-memories-prompt.ts
|
|
112895
|
-
import { existsSync as
|
|
114313
|
+
import { existsSync as existsSync16, statSync as statSync11 } from "node:fs";
|
|
112896
114314
|
import path8 from "node:path";
|
|
112897
114315
|
var MAP_MEMORIES_SYSTEM_PROMPT = `You are a memory mapper for the magic-context system. You map project memories to the repository files that back them.
|
|
112898
114316
|
|
|
@@ -112930,7 +114348,7 @@ function extractMemoryCandidatePaths(content, repoDir) {
|
|
|
112930
114348
|
if (!abs.startsWith(`${root}/`))
|
|
112931
114349
|
continue;
|
|
112932
114350
|
try {
|
|
112933
|
-
if (
|
|
114351
|
+
if (existsSync16(abs) && statSync11(abs).isFile())
|
|
112934
114352
|
found.add(rel);
|
|
112935
114353
|
} catch {}
|
|
112936
114354
|
if (found.size >= MAX_SEED_PATHS_PER_MEMORY)
|
|
@@ -115562,8 +116980,8 @@ async function runAgenticTask(config, ctx, helpers) {
|
|
|
115562
116980
|
const lastRunAt = getTaskScheduleState(db, projectIdentity, config.task)?.lastRunAt ?? null;
|
|
115563
116981
|
const maintainDocsSnapshot = task === "maintain-docs" ? snapshotMaintainDocsFiles(docsDir) : undefined;
|
|
115564
116982
|
const existingDocs = task === "maintain-docs" ? {
|
|
115565
|
-
architecture:
|
|
115566
|
-
structure:
|
|
116983
|
+
architecture: existsSync17(`${docsDir}/ARCHITECTURE.md`),
|
|
116984
|
+
structure: existsSync17(`${docsDir}/STRUCTURE.md`)
|
|
115567
116985
|
} : undefined;
|
|
115568
116986
|
const abortController = new AbortController;
|
|
115569
116987
|
let leaseLost = false;
|
|
@@ -115790,11 +117208,11 @@ function planDueTasks(db, projectIdentity, tasks, now) {
|
|
|
115790
117208
|
}
|
|
115791
117209
|
return due;
|
|
115792
117210
|
}
|
|
115793
|
-
function advanceAfterRun(db, projectIdentity, due, finishedAt, status, error, schedulePatch) {
|
|
117211
|
+
function advanceAfterRun(db, projectIdentity, due, finishedAt, status, error, schedulePatch, startedAt) {
|
|
115794
117212
|
writeTaskScheduleState(db, {
|
|
115795
117213
|
projectPath: projectIdentity,
|
|
115796
117214
|
task: due.config.task,
|
|
115797
|
-
lastRunAt: status === "completed" ? finishedAt : readLastRunAt(db, projectIdentity, due.config.task),
|
|
117215
|
+
lastRunAt: status === "completed" ? startedAt ?? finishedAt : readLastRunAt(db, projectIdentity, due.config.task),
|
|
115798
117216
|
nextDueAt: nextDueAtMs(due.config.schedule, finishedAt, due.scheduledAt),
|
|
115799
117217
|
schedule: due.config.schedule,
|
|
115800
117218
|
lastStatus: status,
|
|
@@ -115878,6 +117296,7 @@ async function runDomainGroup(deps, group, cb) {
|
|
|
115878
117296
|
}
|
|
115879
117297
|
}
|
|
115880
117298
|
let outcome;
|
|
117299
|
+
const startedAt = Date.now();
|
|
115881
117300
|
try {
|
|
115882
117301
|
outcome = await executor(due.config, {
|
|
115883
117302
|
db,
|
|
@@ -115891,7 +117310,7 @@ async function runDomainGroup(deps, group, cb) {
|
|
|
115891
117310
|
}
|
|
115892
117311
|
const finishedAt = Date.now();
|
|
115893
117312
|
if (outcome.status === "completed") {
|
|
115894
|
-
advanceAfterRun(db, projectIdentity, due, finishedAt, "completed", null, outcome.schedulePatch);
|
|
117313
|
+
advanceAfterRun(db, projectIdentity, due, finishedAt, "completed", null, outcome.schedulePatch, startedAt);
|
|
115895
117314
|
cb?.onRan?.(due.config.task, outcome.detail, outcome.backlog);
|
|
115896
117315
|
} else if (outcome.transient) {
|
|
115897
117316
|
recordTransientFailure(db, projectIdentity, due, finishedAt, outcome.error ?? null);
|
|
@@ -116136,7 +117555,7 @@ function rawMessages(rows, history = rows) {
|
|
|
116136
117555
|
const ordinals = new Map(history.filter(isRawRow).map((row, index) => [row.id, index + 1]));
|
|
116137
117556
|
return rows.filter(isRawRow).map((row) => ({
|
|
116138
117557
|
id: row.id,
|
|
116139
|
-
ordinal: ordinals.get(row.id),
|
|
117558
|
+
ordinal: ordinals.get(row.id) ?? 0,
|
|
116140
117559
|
role: row.type === "assistant" ? "assistant" : "user",
|
|
116141
117560
|
createdAt: row.data.time?.created,
|
|
116142
117561
|
parts: row.type === "assistant" ? (row.data.content ?? []).map((part) => {
|
|
@@ -116170,20 +117589,96 @@ function createHostSeams(context, read, liveModels) {
|
|
|
116170
117589
|
hostRefuse: (_client, sessionID) => interruptBeforeProvider(context.session, sessionID)
|
|
116171
117590
|
};
|
|
116172
117591
|
}
|
|
117592
|
+
function toolResultText(result) {
|
|
117593
|
+
const content = result?.content ?? result?.output;
|
|
117594
|
+
if (typeof content === "string")
|
|
117595
|
+
return content;
|
|
117596
|
+
if (content && typeof content === "object" && !Array.isArray(content)) {
|
|
117597
|
+
const record = content;
|
|
117598
|
+
if (typeof record.text === "string")
|
|
117599
|
+
return record.text;
|
|
117600
|
+
if (typeof record.value === "string")
|
|
117601
|
+
return record.value;
|
|
117602
|
+
return "";
|
|
117603
|
+
}
|
|
117604
|
+
if (!Array.isArray(content))
|
|
117605
|
+
return "";
|
|
117606
|
+
return content.map((part) => {
|
|
117607
|
+
if (typeof part === "string")
|
|
117608
|
+
return part;
|
|
117609
|
+
if (!part || typeof part !== "object")
|
|
117610
|
+
return "";
|
|
117611
|
+
const record = part;
|
|
117612
|
+
if (typeof record.text === "string")
|
|
117613
|
+
return record.text;
|
|
117614
|
+
if (typeof record.value === "string")
|
|
117615
|
+
return record.value;
|
|
117616
|
+
return "";
|
|
117617
|
+
}).filter(Boolean).join(`
|
|
117618
|
+
`);
|
|
117619
|
+
}
|
|
117620
|
+
function catalogModels(listed) {
|
|
117621
|
+
const rows = Array.isArray(listed) ? listed : listed && typeof listed === "object" && Array.isArray(listed.data) ? listed.data : [];
|
|
117622
|
+
return rows.flatMap((row) => {
|
|
117623
|
+
if (!row || typeof row !== "object")
|
|
117624
|
+
return [];
|
|
117625
|
+
const model = row;
|
|
117626
|
+
if (typeof model.id !== "string" || typeof model.providerID !== "string")
|
|
117627
|
+
return [];
|
|
117628
|
+
const contextLimit = model.limit?.context;
|
|
117629
|
+
if (typeof contextLimit !== "number" || !Number.isFinite(contextLimit))
|
|
117630
|
+
return [];
|
|
117631
|
+
return [{ id: model.id, providerID: model.providerID, limit: { context: contextLimit } }];
|
|
117632
|
+
});
|
|
117633
|
+
}
|
|
117634
|
+
function applyV2PromptSurfaceTools(draft, runtime, config) {
|
|
117635
|
+
if (!draft.tools)
|
|
117636
|
+
return;
|
|
117637
|
+
const modelKey = `${draft.model.providerID}/${draft.model.id}`;
|
|
117638
|
+
const registration = runtime.resolveRegistration(config, modelKey);
|
|
117639
|
+
for (const id of ACTIVE_TOOL_IDS) {
|
|
117640
|
+
const tool = draft.tools[id];
|
|
117641
|
+
if (!tool)
|
|
117642
|
+
continue;
|
|
117643
|
+
tool.description = registration.descriptionFor(id, tool.description);
|
|
117644
|
+
}
|
|
117645
|
+
}
|
|
116173
117646
|
async function registerContext(context) {
|
|
116174
117647
|
const directory = context.location.directory;
|
|
116175
117648
|
const config = loadPluginConfigDetailed(directory).config;
|
|
116176
117649
|
if (!config.enabled || !isCompactionEnabled(config))
|
|
116177
117650
|
return;
|
|
117651
|
+
const conflicts = detectConflicts(directory, {
|
|
117652
|
+
compactionEnabled: true,
|
|
117653
|
+
hostGeneration: "v2"
|
|
117654
|
+
});
|
|
117655
|
+
if (conflicts.hasConflict) {
|
|
117656
|
+
console.warn(`[magic-context] v2 setup disabled by conflicting context hooks: ${conflicts.reasons.join("; ")}`);
|
|
117657
|
+
return;
|
|
117658
|
+
}
|
|
116178
117659
|
const folds = new FoldOwner(context.storage);
|
|
116179
117660
|
const limits = new Map;
|
|
116180
117661
|
const queriedModels = new Set;
|
|
116181
117662
|
const liveModels = new Map;
|
|
116182
|
-
const
|
|
116183
|
-
|
|
116184
|
-
|
|
116185
|
-
|
|
116186
|
-
}
|
|
117663
|
+
const promptSurfaceRuntime = createPromptSurfaceRuntime({
|
|
117664
|
+
harness: "opencode2",
|
|
117665
|
+
directory,
|
|
117666
|
+
warn: (message) => console.warn(`[magic-context] config warning: ${message}`)
|
|
117667
|
+
});
|
|
117668
|
+
let db;
|
|
117669
|
+
try {
|
|
117670
|
+
db = openDatabase() ?? undefined;
|
|
117671
|
+
} catch {}
|
|
117672
|
+
const hiddenChildHook = new HiddenChildHook;
|
|
117673
|
+
await registerHiddenChildAgents(context.agent);
|
|
117674
|
+
let hiddenAgentsReady;
|
|
117675
|
+
const hiddenCompletionExecutor = db && isDatabasePersisted(db) ? await createV2HiddenCompletionExecutor(context.session, {
|
|
117676
|
+
db,
|
|
117677
|
+
projectIdentity: resolveProjectIdentity(directory) ?? directory,
|
|
117678
|
+
hook: hiddenChildHook,
|
|
117679
|
+
ensureAgent: () => hiddenAgentsReady ??= context.agent.reload(),
|
|
117680
|
+
openReader: () => new V2StoreReader(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"))
|
|
117681
|
+
}) : undefined;
|
|
116187
117682
|
const dreamTrigger = hiddenCompletionExecutor && config.dreamer && !config.dreamer.disable ? startDreamTrigger(context, {
|
|
116188
117683
|
config: config.dreamer,
|
|
116189
117684
|
executor: hiddenCompletionExecutor,
|
|
@@ -116204,16 +117699,17 @@ async function registerContext(context) {
|
|
|
116204
117699
|
let toolDuties;
|
|
116205
117700
|
await context.tool.hook("execute.before", (draft) => assertExecutableToolInput(draft.input));
|
|
116206
117701
|
await context.tool.hook("execute.after", async (draft) => {
|
|
116207
|
-
if (!db
|
|
117702
|
+
if (!db)
|
|
117703
|
+
return;
|
|
117704
|
+
if (draft.status && draft.status !== "completed")
|
|
116208
117705
|
return;
|
|
116209
117706
|
try {
|
|
116210
117707
|
toolDuties ??= createToolExecuteAfterHook({ db, channel1StateBySession: channel1 });
|
|
116211
|
-
const
|
|
116212
|
-
const text = typeof content === "string" ? content : Array.isArray(content) ? content.filter((part) => part.type === "text").map((part) => part.text).join(`
|
|
116213
|
-
`) : "";
|
|
117708
|
+
const text = toolResultText(draft.result);
|
|
116214
117709
|
const output = { output: text };
|
|
116215
117710
|
await toolDuties({ ...draft, args: draft.input }, output);
|
|
116216
117711
|
if (draft.result && output.output !== text) {
|
|
117712
|
+
const content = draft.result.content;
|
|
116217
117713
|
if (typeof content === "string")
|
|
116218
117714
|
draft.result.content = output.output;
|
|
116219
117715
|
else if (Array.isArray(content) && output.output.startsWith(text))
|
|
@@ -116238,7 +117734,6 @@ async function registerContext(context) {
|
|
|
116238
117734
|
getCount: (sessionID) => read(sessionID).length
|
|
116239
117735
|
});
|
|
116240
117736
|
let transform;
|
|
116241
|
-
let db;
|
|
116242
117737
|
const refuseIfUnsafe = async (draft) => {
|
|
116243
117738
|
let unsafe = false;
|
|
116244
117739
|
try {
|
|
@@ -116252,10 +117747,8 @@ async function registerContext(context) {
|
|
|
116252
117747
|
const tokens = latest?.data.tokens;
|
|
116253
117748
|
const modelKey = `${draft.model.providerID}/${draft.model.id}`;
|
|
116254
117749
|
if (!queriedModels.has(modelKey)) {
|
|
116255
|
-
const catalog = await context.
|
|
116256
|
-
|
|
116257
|
-
});
|
|
116258
|
-
for (const model of catalog.data)
|
|
117750
|
+
const catalog = await Promise.resolve(context.model.list());
|
|
117751
|
+
for (const model of catalogModels(catalog))
|
|
116259
117752
|
limits.set(`${model.providerID}/${model.id}`, model.limit.context);
|
|
116260
117753
|
queriedModels.add(modelKey);
|
|
116261
117754
|
}
|
|
@@ -116275,7 +117768,8 @@ async function registerContext(context) {
|
|
|
116275
117768
|
} finally {
|
|
116276
117769
|
reader.close();
|
|
116277
117770
|
}
|
|
116278
|
-
} catch {
|
|
117771
|
+
} catch (error) {
|
|
117772
|
+
console.warn("[magic-context] v2 refuseIfUnsafe", error);
|
|
116279
117773
|
unsafe = true;
|
|
116280
117774
|
}
|
|
116281
117775
|
if (unsafe)
|
|
@@ -116328,6 +117822,26 @@ async function registerContext(context) {
|
|
|
116328
117822
|
}
|
|
116329
117823
|
});
|
|
116330
117824
|
await context.session.hook("context", async (draft) => {
|
|
117825
|
+
if (hiddenChildHook.apply(draft))
|
|
117826
|
+
return;
|
|
117827
|
+
liveModels.set(draft.sessionID, {
|
|
117828
|
+
providerID: draft.model.providerID,
|
|
117829
|
+
modelID: draft.model.id
|
|
117830
|
+
});
|
|
117831
|
+
variants.set(draft.sessionID, draft.model.variant);
|
|
117832
|
+
agents.set(draft.sessionID, draft.agent);
|
|
117833
|
+
applyV2PromptSurfaceTools(draft, promptSurfaceRuntime, config.prompt_surface);
|
|
117834
|
+
if (context.tool.transform) {
|
|
117835
|
+
const modelKey = `${draft.model.providerID}/${draft.model.id}`;
|
|
117836
|
+
const registration = promptSurfaceRuntime.resolveRegistration(config.prompt_surface, modelKey);
|
|
117837
|
+
await context.tool.transform((editor) => {
|
|
117838
|
+
for (const id of ACTIVE_TOOL_IDS) {
|
|
117839
|
+
editor.update(id, (tool) => {
|
|
117840
|
+
tool.description = registration.descriptionFor(id, tool.description);
|
|
117841
|
+
});
|
|
117842
|
+
}
|
|
117843
|
+
});
|
|
117844
|
+
}
|
|
116331
117845
|
let postFold = false;
|
|
116332
117846
|
try {
|
|
116333
117847
|
if (await refuseIfUnsafe(draft))
|
|
@@ -116444,6 +117958,9 @@ async function registerContext(context) {
|
|
|
116444
117958
|
const mapped = adaptPayload(draft, admitted);
|
|
116445
117959
|
await transform({}, mapped);
|
|
116446
117960
|
mapped.commit();
|
|
117961
|
+
if (db) {
|
|
117962
|
+
await deliverPendingChannel2(context, db, draft.sessionID, channel1.get(draft.sessionID));
|
|
117963
|
+
}
|
|
116447
117964
|
if (checkpoint && submitted !== undefined) {
|
|
116448
117965
|
const head = draft.messages.find((message) => message.id === HEAD_IDS[0]);
|
|
116449
117966
|
const baseline = head?.content.find((part) => part.type === "text")?.text;
|
|
@@ -116483,8 +118000,8 @@ ${baseline}
|
|
|
116483
118000
|
}
|
|
116484
118001
|
|
|
116485
118002
|
// src/v2/hooks/update-check.ts
|
|
116486
|
-
import { existsSync as
|
|
116487
|
-
import { dirname as
|
|
118003
|
+
import { existsSync as existsSync18, readFileSync as readFileSync13 } from "node:fs";
|
|
118004
|
+
import { dirname as dirname9, join as join16 } from "node:path";
|
|
116488
118005
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
116489
118006
|
|
|
116490
118007
|
// src/hooks/auto-update-checker/checker.ts
|
|
@@ -116492,26 +118009,26 @@ init_logger();
|
|
|
116492
118009
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
116493
118010
|
|
|
116494
118011
|
// src/hooks/auto-update-checker/constants.ts
|
|
116495
|
-
import { homedir as
|
|
116496
|
-
import { join as
|
|
118012
|
+
import { homedir as homedir11, platform } from "node:os";
|
|
118013
|
+
import { join as join15 } from "node:path";
|
|
116497
118014
|
var PACKAGE_NAME = "@cortexkit/opencode-magic-context";
|
|
116498
118015
|
var NPM_REGISTRY_URL = "https://registry.npmjs.org";
|
|
116499
118016
|
var NPM_FETCH_TIMEOUT = 1e4;
|
|
116500
118017
|
function getOpenCodeCacheRoot() {
|
|
116501
118018
|
if (platform() === "win32") {
|
|
116502
|
-
return
|
|
118019
|
+
return join15(process.env.LOCALAPPDATA ?? homedir11(), "opencode");
|
|
116503
118020
|
}
|
|
116504
|
-
return
|
|
118021
|
+
return join15(homedir11(), ".cache", "opencode");
|
|
116505
118022
|
}
|
|
116506
118023
|
function getOpenCodeConfigRoot() {
|
|
116507
118024
|
if (platform() === "win32") {
|
|
116508
|
-
return
|
|
118025
|
+
return join15(process.env.APPDATA ?? join15(homedir11(), "AppData", "Roaming"), "opencode");
|
|
116509
118026
|
}
|
|
116510
|
-
return
|
|
118027
|
+
return join15(process.env.XDG_CONFIG_HOME ?? join15(homedir11(), ".config"), "opencode");
|
|
116511
118028
|
}
|
|
116512
|
-
var CACHE_DIR =
|
|
116513
|
-
var USER_OPENCODE_CONFIG =
|
|
116514
|
-
var USER_OPENCODE_CONFIG_JSONC =
|
|
118029
|
+
var CACHE_DIR = join15(getOpenCodeCacheRoot(), "packages");
|
|
118030
|
+
var USER_OPENCODE_CONFIG = join15(getOpenCodeConfigRoot(), "opencode.json");
|
|
118031
|
+
var USER_OPENCODE_CONFIG_JSONC = join15(getOpenCodeConfigRoot(), "opencode.jsonc");
|
|
116515
118032
|
|
|
116516
118033
|
// src/hooks/auto-update-checker/semver.ts
|
|
116517
118034
|
function isValidSemver(version) {
|
|
@@ -116573,18 +118090,18 @@ async function getLatestVersion(channel = "latest", options = {}) {
|
|
|
116573
118090
|
// src/v2/hooks/update-check.ts
|
|
116574
118091
|
init_rpc_notifications();
|
|
116575
118092
|
function packageInfo() {
|
|
116576
|
-
let directory =
|
|
118093
|
+
let directory = dirname9(fileURLToPath2(import.meta.url));
|
|
116577
118094
|
for (;; ) {
|
|
116578
118095
|
try {
|
|
116579
|
-
const pkg = JSON.parse(
|
|
118096
|
+
const pkg = JSON.parse(readFileSync13(join16(directory, "package.json"), "utf8"));
|
|
116580
118097
|
if (pkg.name === "@cortexkit/opencode-magic-context" && typeof pkg.version === "string") {
|
|
116581
118098
|
return {
|
|
116582
118099
|
version: pkg.version,
|
|
116583
|
-
development:
|
|
118100
|
+
development: existsSync18(join16(directory, "src/v2/server.ts"))
|
|
116584
118101
|
};
|
|
116585
118102
|
}
|
|
116586
118103
|
} catch {}
|
|
116587
|
-
const parent =
|
|
118104
|
+
const parent = dirname9(directory);
|
|
116588
118105
|
if (parent === directory)
|
|
116589
118106
|
throw new Error("Magic Context package manifest is unavailable");
|
|
116590
118107
|
directory = parent;
|
|
@@ -116627,7 +118144,17 @@ function startUpdateChecks(context, check = (signal) => {
|
|
|
116627
118144
|
}
|
|
116628
118145
|
|
|
116629
118146
|
// src/v2/server.ts
|
|
118147
|
+
function isOpenCode2HostContext(context) {
|
|
118148
|
+
if (typeof context !== "object" || context === null)
|
|
118149
|
+
return false;
|
|
118150
|
+
const session = context.session;
|
|
118151
|
+
return typeof session === "object" && session !== null && typeof session.hook === "function";
|
|
118152
|
+
}
|
|
116630
118153
|
async function setup(context) {
|
|
118154
|
+
if (!isOpenCode2HostContext(context)) {
|
|
118155
|
+
log("v2 setup() called on a host without session.hook; v1 server lane owns this host, v2 lane inert");
|
|
118156
|
+
return async () => {};
|
|
118157
|
+
}
|
|
116631
118158
|
setHarness("opencode2");
|
|
116632
118159
|
const duties = await registerContext(context);
|
|
116633
118160
|
const checks = loadPluginConfigDetailed(context.location.directory).config.auto_update === false ? undefined : startUpdateChecks(context);
|
|
@@ -116643,5 +118170,6 @@ var server_default = {
|
|
|
116643
118170
|
};
|
|
116644
118171
|
export {
|
|
116645
118172
|
server_default as default,
|
|
118173
|
+
isOpenCode2HostContext,
|
|
116646
118174
|
setup
|
|
116647
118175
|
};
|