@cortexkit/opencode-magic-context 0.43.1 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -2
- package/dist/config/index.d.ts +13 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +6 -3
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +27 -0
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-956fkedc.js → conflict-warning-hook-48f7np9d.js} +5 -5
- package/dist/{derive-budgets-b8ybssh9.js → derive-budgets-8kgevxmx.js} +2 -2
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-embedding.d.ts +3 -2
- package/dist/features/magic-context/compartment-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/classify.d.ts +12 -0
- package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/curate-category-rotation.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/curate-memory-safety.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/failed-invocation-evidence.d.ts +13 -0
- package/dist/features/magic-context/dreamer/failed-invocation-evidence.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/lease.d.ts +5 -2
- package/dist/features/magic-context/dreamer/lease.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/memory-claim-safety.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/module-apply.d.ts +1 -0
- package/dist/features/magic-context/dreamer/module-apply.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/retrospective-learnings.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +1 -1
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts +2 -0
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts +19 -0
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/fail-closed-block.d.ts +7 -0
- package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -1
- package/dist/features/magic-context/index.d.ts +1 -0
- package/dist/features/magic-context/index.d.ts.map +1 -1
- package/dist/features/magic-context/install-instance-id.d.ts +33 -0
- package/dist/features/magic-context/install-instance-id.d.ts.map +1 -0
- package/dist/features/magic-context/memory/constants.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/memory/single-store-embedding-drain.d.ts +35 -0
- package/dist/features/magic-context/memory/single-store-embedding-drain.d.ts.map +1 -0
- package/dist/features/magic-context/memory/verification-paths.d.ts.map +1 -1
- package/dist/features/magic-context/message-index.d.ts +23 -0
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts +7 -0
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/overflow-detection.d.ts +31 -8
- package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts +40 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/session-decision-calibration.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +20 -5
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +1 -1
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage-notes.d.ts +1 -0
- package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
- package/dist/features/magic-context/storage-primers.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage-unavailable-reason.d.ts +17 -0
- package/dist/features/magic-context/storage-unavailable-reason.d.ts.map +1 -0
- package/dist/features/magic-context/storage.d.ts +1 -1
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/store-generation-rebase.d.ts +95 -2
- package/dist/features/magic-context/store-generation-rebase.d.ts.map +1 -1
- package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
- package/dist/features/magic-context/types.d.ts +8 -3
- package/dist/features/magic-context/types.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
- package/dist/hooks/magic-context/apply-operations.d.ts +105 -9
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-parser.d.ts +2 -0
- package/dist/hooks/magic-context/compartment-parser.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +1 -0
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +6 -0
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +2 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts +7 -0
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/context-limit-resolution.d.ts +31 -0
- package/dist/hooks/magic-context/context-limit-resolution.d.ts.map +1 -0
- package/dist/hooks/magic-context/ctx-reduce-availability.d.ts +60 -8
- package/dist/hooks/magic-context/ctx-reduce-availability.d.ts.map +1 -1
- package/dist/hooks/magic-context/embed-history-runner.d.ts +0 -1
- package/dist/hooks/magic-context/embed-history-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
- package/dist/hooks/magic-context/format-embed-status.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/historian-host-runner.d.ts +233 -0
- package/dist/hooks/magic-context/historian-host-runner.d.ts.map +1 -0
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/image-token-estimate.d.ts +9 -0
- package/dist/hooks/magic-context/image-token-estimate.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +60 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts +6 -0
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-client.d.ts +21 -0
- package/dist/hooks/magic-context/module-client.d.ts.map +1 -0
- package/dist/hooks/magic-context/module-state-sync.d.ts +6 -2
- package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-tool-backends.d.ts +47 -0
- package/dist/hooks/magic-context/module-tool-backends.d.ts.map +1 -0
- package/dist/hooks/magic-context/module-transport.d.ts +1 -1
- package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
- package/dist/hooks/magic-context/persist-filtered-noise.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +12 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +35 -0
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-refusal-recovery.d.ts +18 -0
- package/dist/hooks/magic-context/rust-refusal-recovery.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-served-m0.d.ts +20 -0
- package/dist/hooks/magic-context/rust-served-m0.d.ts.map +1 -0
- package/dist/hooks/magic-context/store-ahead-refusal.d.ts +40 -0
- package/dist/hooks/magic-context/store-ahead-refusal.d.ts.map +1 -0
- package/dist/hooks/magic-context/strip-content.d.ts +5 -5
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +9 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +19 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts +14 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-input-size.d.ts +21 -0
- package/dist/hooks/magic-context/tool-input-size.d.ts.map +1 -0
- package/dist/hooks/magic-context/tool-sweep-policy.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +124 -11
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +13 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/{index-0ccmyzbj.js → index-01ft0h3p.js} +1 -1
- package/dist/{index-j7cnyvq1.js → index-2zf5fv89.js} +254 -61
- package/dist/{index-kpmmr8s0.js → index-5f4qsnaq.js} +2 -2
- package/dist/{index-yc81txp4.js → index-c906f3ff.js} +4 -4
- package/dist/{index-1gtwrdc4.js → index-cj5qe2nw.js} +3 -3
- package/dist/{index-febg06dy.js → index-dx0xnd4q.js} +1 -1
- package/dist/{index-v8qr6tt2.js → index-pye48m79.js} +3 -3
- package/dist/{index-7wpwr2e2.js → index-rdey8znw.js} +1175 -290
- package/dist/{index-wgzyeyf5.js → index-tjq5jztd.js} +22 -6
- package/dist/{index-9r1cbh9e.js → index-v6wsttqt.js} +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3546 -1642
- package/dist/{message-time-backfill-0ccvyk9n.js → message-time-backfill-rm9wmcem.js} +3 -3
- package/dist/plugin/dream-timer.d.ts +2 -0
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/messages-transform.d.ts.map +1 -1
- package/dist/plugin/native-compaction-guard.d.ts +22 -0
- package/dist/plugin/native-compaction-guard.d.ts.map +1 -0
- package/dist/plugin/rpc-handlers.d.ts +11 -0
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/{read-session-chunk-z7fv0qjv.js → read-session-chunk-ktz5zt70.js} +5 -3
- package/dist/{recomp-orchestrator-r00aa5t3.js → recomp-orchestrator-ahekzt0s.js} +8 -8
- package/dist/{safe-notification-target-vrkjrbgb.js → safe-notification-target-6w0esgd6.js} +2 -2
- package/dist/{send-session-notification-3warjyjp.js → send-session-notification-w7xbnrsm.js} +4 -4
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/logger.d.ts.map +1 -1
- package/dist/shared/model-suggestion-retry.d.ts +13 -1
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
- package/dist/shared/opencode-db-path.d.ts.map +1 -1
- package/dist/shared/prompt-async-transport.d.ts +25 -0
- package/dist/shared/prompt-async-transport.d.ts.map +1 -0
- package/dist/shared/rpc-server.d.ts +1 -0
- package/dist/shared/rpc-server.d.ts.map +1 -1
- package/dist/shared/rpc-types.d.ts +16 -0
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/shared/rpc-utils.d.ts +3 -0
- package/dist/shared/rpc-utils.d.ts.map +1 -1
- package/dist/shared/sqlite-write-locker-test-support.d.ts +7 -0
- package/dist/shared/sqlite-write-locker-test-support.d.ts.map +1 -0
- package/dist/shared/status-summary.d.ts +9 -1
- package/dist/shared/status-summary.d.ts.map +1 -1
- package/dist/shared/tag-transcript.d.ts.map +1 -1
- package/dist/shared/test-fake-executable.d.ts +38 -0
- package/dist/shared/test-fake-executable.d.ts.map +1 -0
- package/dist/shared/user-facing-codes.d.ts +20 -5
- package/dist/shared/user-facing-codes.d.ts.map +1 -1
- package/dist/shared/window-geometry.d.ts +6 -3
- package/dist/shared/window-geometry.d.ts.map +1 -1
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/tools.d.ts.map +1 -1
- package/dist/v2/fold/boundary.d.ts +61 -0
- package/dist/v2/fold/boundary.d.ts.map +1 -0
- package/dist/v2/fold/restore.d.ts.map +1 -1
- package/dist/v2/hidden-completion.d.ts +16 -3
- package/dist/v2/hidden-completion.d.ts.map +1 -1
- package/dist/v2/hooks/context.d.ts +45 -14
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/hidden-child.d.ts +6 -0
- package/dist/v2/hooks/hidden-child.d.ts.map +1 -1
- package/dist/v2/hooks/payload.d.ts.map +1 -1
- package/dist/v2/hooks/refusal.d.ts +9 -1
- package/dist/v2/hooks/refusal.d.ts.map +1 -1
- package/dist/v2/hooks/restore-rows.d.ts +29 -0
- package/dist/v2/hooks/restore-rows.d.ts.map +1 -0
- package/dist/v2/hooks/rpc-live-state.d.ts +1 -1
- package/dist/v2/hooks/rpc-live-state.d.ts.map +1 -1
- package/dist/v2/hooks/rust-mode.d.ts +47 -0
- package/dist/v2/hooks/rust-mode.d.ts.map +1 -0
- package/dist/v2/hooks/session-project-backfill.d.ts +15 -0
- package/dist/v2/hooks/session-project-backfill.d.ts.map +1 -0
- package/dist/v2/hooks/storage-gate.d.ts +42 -0
- package/dist/v2/hooks/storage-gate.d.ts.map +1 -0
- package/dist/v2/hooks/storage-notice.d.ts +29 -0
- package/dist/v2/hooks/storage-notice.d.ts.map +1 -0
- package/dist/v2/hooks/store.d.ts +16 -0
- package/dist/v2/hooks/store.d.ts.map +1 -1
- package/dist/v2/hooks/tools.d.ts +11 -2
- package/dist/v2/hooks/tools.d.ts.map +1 -1
- package/dist/v2/hooks/types.d.ts +4 -0
- package/dist/v2/hooks/types.d.ts.map +1 -1
- package/dist/v2/hooks/update-check.d.ts +8 -0
- package/dist/v2/hooks/update-check.d.ts.map +1 -1
- package/dist/v2/hooks/usage-persist.d.ts +31 -0
- package/dist/v2/hooks/usage-persist.d.ts.map +1 -0
- package/dist/v2/server.js +12692 -8030
- package/dist/v2/store-reader.d.ts +17 -0
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/wrapup-orchestrator-9srk0kjf.js +18 -0
- package/package.json +1 -1
- package/src/agents/magic-context-prompt.ts +3 -3
- package/src/config/index.ts +40 -0
- package/src/config/misplaced-agent-model.test.ts +61 -0
- package/src/config/project-security.test.ts +17 -0
- package/src/config/project-security.ts +28 -4
- package/src/config/schema/magic-context.ts +29 -2
- package/src/shared/index.ts +1 -0
- package/src/shared/logger.test.ts +63 -2
- package/src/shared/logger.ts +23 -5
- package/src/shared/model-suggestion-retry.test.ts +115 -4
- package/src/shared/model-suggestion-retry.ts +57 -12
- package/src/shared/opencode-db-path.test.ts +18 -0
- package/src/shared/opencode-db-path.ts +5 -2
- package/src/shared/prompt-async-transport.test.ts +217 -0
- package/src/shared/prompt-async-transport.ts +242 -0
- package/src/shared/prompt-surface-a1-golden.md +8 -8
- package/src/shared/rpc-server.ts +13 -1
- package/src/shared/rpc-types.ts +17 -0
- package/src/shared/rpc-utils.ts +28 -0
- package/src/shared/sqlite-transaction-mode-guard.test.ts +198 -0
- package/src/shared/sqlite-write-locker-test-support.ts +62 -0
- package/src/shared/status-detail-text.test.ts +23 -0
- package/src/shared/status-summary.ts +25 -1
- package/src/shared/tag-transcript.ts +82 -19
- package/src/shared/test-fake-executable.test.ts +54 -0
- package/src/shared/test-fake-executable.ts +110 -0
- package/src/shared/user-facing-codes.ts +23 -5
- package/src/shared/window-geometry.ts +6 -3
- package/dist/v2/hooks/provider-admission.d.ts +0 -22
- package/dist/v2/hooks/provider-admission.d.ts.map +0 -1
- package/dist/wrapup-orchestrator-y0bs7t5a.js +0 -18
|
@@ -217,6 +217,29 @@ describe("status detail text", () => {
|
|
|
217
217
|
);
|
|
218
218
|
});
|
|
219
219
|
|
|
220
|
+
test("says which runner ran the session's completions and why", () => {
|
|
221
|
+
const status = formatStatusDetailMarkdown({
|
|
222
|
+
...STATUS_FIXTURE,
|
|
223
|
+
historianRunner: {
|
|
224
|
+
runner: "host",
|
|
225
|
+
source: "default_for_harness",
|
|
226
|
+
harness: "opencode",
|
|
227
|
+
observed: "last_completion",
|
|
228
|
+
},
|
|
229
|
+
dreamerRunner: {
|
|
230
|
+
runner: "broca",
|
|
231
|
+
source: "configured",
|
|
232
|
+
harness: "opencode",
|
|
233
|
+
observed: "resolved_for_route",
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
expect(status).toMatch(
|
|
238
|
+
/^- \*\*Historian runner:\*\* host \(default for harness opencode\)$/m,
|
|
239
|
+
);
|
|
240
|
+
expect(status).toContain("- **Dreamer runner:** broca (configured) · no completion yet");
|
|
241
|
+
});
|
|
242
|
+
|
|
220
243
|
test("does not expose module routing in the summary", () => {
|
|
221
244
|
const rustStatus = formatStatusDetailMarkdown({
|
|
222
245
|
...STATUS_FIXTURE,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { formatCacheTtlDisplay } from "./cache-ttl-display";
|
|
2
|
-
import type { StatusDetail } from "./rpc-types";
|
|
2
|
+
import type { RunnerStatus, StatusDetail } from "./rpc-types";
|
|
3
3
|
import { renderUserFacingFailure, type UserFacingFailureKey } from "./user-facing-codes";
|
|
4
4
|
|
|
5
5
|
export type StatusCompressionState = "off" | "compressing" | "ready" | "waiting";
|
|
@@ -32,6 +32,8 @@ export interface UserStatusSummary {
|
|
|
32
32
|
detail: string;
|
|
33
33
|
};
|
|
34
34
|
compactionMarker?: StatusDetail["compactionMarker"];
|
|
35
|
+
historianRunner?: RunnerStatus;
|
|
36
|
+
dreamerRunner?: RunnerStatus;
|
|
35
37
|
warnings: UserFacingFailureKey[];
|
|
36
38
|
hiddenVariantWarnings?: string[];
|
|
37
39
|
}
|
|
@@ -96,6 +98,8 @@ export function statusSummaryFromDetail(detail: StatusDetail): UserStatusSummary
|
|
|
96
98
|
total: 0,
|
|
97
99
|
},
|
|
98
100
|
historianRefusal: detail.historianRefusal,
|
|
101
|
+
historianRunner: detail.historianRunner,
|
|
102
|
+
dreamerRunner: detail.dreamerRunner,
|
|
99
103
|
compactionMarker: detail.compactionMarker,
|
|
100
104
|
warnings: [...new Set(warnings)],
|
|
101
105
|
hiddenVariantWarnings: detail.hiddenVariantWarnings ?? [],
|
|
@@ -122,6 +126,20 @@ function compressionText(summary: UserStatusSummary): string {
|
|
|
122
126
|
}
|
|
123
127
|
}
|
|
124
128
|
|
|
129
|
+
/**
|
|
130
|
+
* `host (default for harness opencode)` or `broca (configured)`, plus a note when
|
|
131
|
+
* no completion has run yet in the module's current process and the value is
|
|
132
|
+
* only what the session's route resolves to.
|
|
133
|
+
*/
|
|
134
|
+
export function runnerText(status: RunnerStatus): string {
|
|
135
|
+
const why =
|
|
136
|
+
status.source === "configured"
|
|
137
|
+
? "configured"
|
|
138
|
+
: `default for harness ${status.harness || "unknown"}`;
|
|
139
|
+
const observed = status.observed === "last_completion" ? "" : " · no completion yet";
|
|
140
|
+
return `${status.runner} (${why})${observed}`;
|
|
141
|
+
}
|
|
142
|
+
|
|
125
143
|
function reclaimableText(summary: UserStatusSummary): string {
|
|
126
144
|
const count = Math.max(0, Math.floor(summary.reclaimable.toolOutputCount));
|
|
127
145
|
if (count === 0) return "none";
|
|
@@ -170,6 +188,12 @@ export function renderUserStatusSummary(
|
|
|
170
188
|
],
|
|
171
189
|
["Search indexing", embeddingText(summary)],
|
|
172
190
|
];
|
|
191
|
+
if (summary.historianRunner) {
|
|
192
|
+
values.push(["Historian runner", runnerText(summary.historianRunner)]);
|
|
193
|
+
}
|
|
194
|
+
if (summary.dreamerRunner) {
|
|
195
|
+
values.push(["Dreamer runner", runnerText(summary.dreamerRunner)]);
|
|
196
|
+
}
|
|
173
197
|
if (summary.historianRefusal) {
|
|
174
198
|
values.push([
|
|
175
199
|
"Historian refusal",
|
|
@@ -66,6 +66,7 @@ import {
|
|
|
66
66
|
stripWellFormedLeadingTagPrefix,
|
|
67
67
|
} from "../hooks/magic-context/tag-content-primitives";
|
|
68
68
|
import type { TagTarget } from "../hooks/magic-context/tag-messages";
|
|
69
|
+
import { toolInputStringBytes } from "../hooks/magic-context/tool-input-size";
|
|
69
70
|
import type { Transcript, TranscriptMessage, TranscriptPart } from "./transcript";
|
|
70
71
|
|
|
71
72
|
export const TEXT_TAG_IDENTITY_MARKER = ":mc-text-v1:";
|
|
@@ -161,6 +162,12 @@ interface ToolOccurrence {
|
|
|
161
162
|
message: { info: { id?: string; role: string } };
|
|
162
163
|
part: TranscriptPart;
|
|
163
164
|
kind: "tool_use" | "tool_result";
|
|
165
|
+
/**
|
|
166
|
+
* The call's real input, captured the first time this pass overwrote it
|
|
167
|
+
* with the legacy marker, so a later real-argument render in the same pass
|
|
168
|
+
* can put it back.
|
|
169
|
+
*/
|
|
170
|
+
originalInput?: Record<string, unknown>;
|
|
164
171
|
}
|
|
165
172
|
|
|
166
173
|
interface TagTranscriptTiming {
|
|
@@ -1093,10 +1100,13 @@ function buildAggregateTarget(
|
|
|
1093
1100
|
const truncate = (): "truncated" | "absent" => {
|
|
1094
1101
|
// Keep the tool call and its result, but replace the call arguments with
|
|
1095
1102
|
// a non-executable marker and the result content with the dropped marker.
|
|
1103
|
+
// Legacy render, replayed only for `drop_mode = 'truncated'` tags until a
|
|
1104
|
+
// HARD fold converts them; new drops use skeletonReal().
|
|
1096
1105
|
const sentinel = `[dropped \u00a7${tagId}\u00a7]`;
|
|
1097
1106
|
let any = false;
|
|
1098
1107
|
for (const occ of occurrences) {
|
|
1099
1108
|
if (occ.kind === "tool_use" && occ.part.setToolInput) {
|
|
1109
|
+
occ.originalInput ??= occ.part.getToolInput?.() ?? undefined;
|
|
1100
1110
|
if (occ.part.setToolInput(droppedInputMarker(tagId))) any = true;
|
|
1101
1111
|
} else if (setToolContentOrText(occ.part, sentinel)) {
|
|
1102
1112
|
any = true;
|
|
@@ -1105,6 +1115,38 @@ function buildAggregateTarget(
|
|
|
1105
1115
|
return any ? "truncated" : "absent";
|
|
1106
1116
|
};
|
|
1107
1117
|
|
|
1118
|
+
const complete = (): boolean =>
|
|
1119
|
+
occurrences.some((occ) => occ.kind === "tool_use") &&
|
|
1120
|
+
occurrences.some((occ) => occ.kind === "tool_result");
|
|
1121
|
+
|
|
1122
|
+
const skeletonReal = (): "truncated" | "absent" | "incomplete" => {
|
|
1123
|
+
// Keep the tool call with the arguments the host gave it and replace
|
|
1124
|
+
// only the result content with the dropped marker. Nothing is written
|
|
1125
|
+
// into the argument position unless an earlier render this pass did,
|
|
1126
|
+
// in which case the real input goes back.
|
|
1127
|
+
if (!complete()) return "incomplete";
|
|
1128
|
+
const sentinel = `[dropped \u00a7${tagId}\u00a7]`;
|
|
1129
|
+
let any = false;
|
|
1130
|
+
for (const occ of occurrences) {
|
|
1131
|
+
if (occ.kind === "tool_use") {
|
|
1132
|
+
if (occ.originalInput && occ.part.setToolInput?.(occ.originalInput)) any = true;
|
|
1133
|
+
} else if (setToolContentOrText(occ.part, sentinel)) {
|
|
1134
|
+
any = true;
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
return any ? "truncated" : "absent";
|
|
1138
|
+
};
|
|
1139
|
+
|
|
1140
|
+
// Adapters without structural removal (or arcs that must keep their pair
|
|
1141
|
+
// beside native reasoning) cannot remove the call; drop() would keep it.
|
|
1142
|
+
const cannotRemove = (): boolean => {
|
|
1143
|
+
if (requiresToolArcSkeleton) return true;
|
|
1144
|
+
const authorization = occurrences.map((occ) => occ.part.canRemove?.());
|
|
1145
|
+
return !occurrences.every(
|
|
1146
|
+
(occ, index) => occ.part.remove && authorization[index] !== false,
|
|
1147
|
+
);
|
|
1148
|
+
};
|
|
1149
|
+
|
|
1108
1150
|
return {
|
|
1109
1151
|
measureReclaim(skeleton) {
|
|
1110
1152
|
let beforeTools = 0;
|
|
@@ -1125,10 +1167,8 @@ function buildAggregateTarget(
|
|
|
1125
1167
|
: (occ.part.getText() ?? "");
|
|
1126
1168
|
beforeTools += estimateTokens(before);
|
|
1127
1169
|
if (skeleton || !removable) {
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
? JSON.stringify(droppedInputMarker(tagId))
|
|
1131
|
-
: `[dropped §${tagId}§]`;
|
|
1170
|
+
// A kept call keeps its real arguments; only the result shrinks.
|
|
1171
|
+
const after = occ.kind === "tool_use" ? before : `[dropped §${tagId}§]`;
|
|
1132
1172
|
afterTools += estimateTokens(after);
|
|
1133
1173
|
}
|
|
1134
1174
|
}
|
|
@@ -1163,10 +1203,7 @@ function buildAggregateTarget(
|
|
|
1163
1203
|
return occurrences[0]?.part.getText() ?? null;
|
|
1164
1204
|
},
|
|
1165
1205
|
drop(): "removed" | "truncated" | "absent" | "incomplete" {
|
|
1166
|
-
|
|
1167
|
-
occurrences.some((occ) => occ.kind === "tool_use") &&
|
|
1168
|
-
occurrences.some((occ) => occ.kind === "tool_result");
|
|
1169
|
-
if (!complete) return "incomplete";
|
|
1206
|
+
if (!complete()) return "incomplete";
|
|
1170
1207
|
if (!requiresToolArcSkeleton) {
|
|
1171
1208
|
const authorization = occurrences.map((occ) => occ.part.canRemove?.());
|
|
1172
1209
|
// A failed durable marker is not permission to substitute a new
|
|
@@ -1178,19 +1215,23 @@ function buildAggregateTarget(
|
|
|
1178
1215
|
)
|
|
1179
1216
|
) {
|
|
1180
1217
|
// If removing this call's result would leave the provider
|
|
1181
|
-
// request ending on an assistant turn, keep
|
|
1182
|
-
// plus placeholder result instead.
|
|
1183
|
-
// to persist that mode
|
|
1218
|
+
// request ending on an assistant turn, keep the call with its
|
|
1219
|
+
// REAL arguments plus the placeholder result instead.
|
|
1220
|
+
// "truncated" tells callers to persist that mode
|
|
1221
|
+
// (`skeleton_real`), so later passes serve the same bytes.
|
|
1184
1222
|
// (The sentinel fallback below keeps call and result in place,
|
|
1185
1223
|
// so it needs no exception.)
|
|
1186
|
-
if (conversationEnd?.wouldStrand(occurrences)) return
|
|
1224
|
+
if (conversationEnd?.wouldStrand(occurrences)) return skeletonReal();
|
|
1187
1225
|
let removed = false;
|
|
1188
1226
|
for (const occ of occurrences) removed = occ.part.remove?.() || removed;
|
|
1189
1227
|
if (removed) conversationEnd?.noteRemoved(occurrences);
|
|
1190
1228
|
return removed ? "removed" : "absent";
|
|
1191
1229
|
}
|
|
1192
1230
|
}
|
|
1193
|
-
// Adapters without structural removal retain paired sentinels.
|
|
1231
|
+
// Adapters without structural removal retain paired sentinels. This
|
|
1232
|
+
// writes a marker into the call's arguments, so only replays of
|
|
1233
|
+
// existing `full` tags reach it: new drops check cannotRemove() and
|
|
1234
|
+
// use skeletonReal(), and a HARD fold converts the existing ones.
|
|
1194
1235
|
const sentinel = `[dropped \u00a7${tagId}\u00a7]`;
|
|
1195
1236
|
let any = false;
|
|
1196
1237
|
for (const occ of occurrences) {
|
|
@@ -1199,6 +1240,18 @@ function buildAggregateTarget(
|
|
|
1199
1240
|
return any ? "removed" : "absent";
|
|
1200
1241
|
},
|
|
1201
1242
|
truncate,
|
|
1243
|
+
skeletonReal,
|
|
1244
|
+
cannotRemove,
|
|
1245
|
+
inputStringBytes(): number | null {
|
|
1246
|
+
for (const occ of occurrences) {
|
|
1247
|
+
if (occ.kind !== "tool_use") continue;
|
|
1248
|
+
return toolInputStringBytes(occ.originalInput ?? occ.part.getToolInput?.() ?? null);
|
|
1249
|
+
}
|
|
1250
|
+
return null;
|
|
1251
|
+
},
|
|
1252
|
+
wouldStrandConversationEnd(): boolean {
|
|
1253
|
+
return conversationEnd?.wouldStrand(occurrences) ?? false;
|
|
1254
|
+
},
|
|
1202
1255
|
editMarker(): "truncated" | "absent" {
|
|
1203
1256
|
// Edit-marker: preserve the tool_use input's filePath + a region
|
|
1204
1257
|
// hint of the diff, sentinelize the result half. Separate from
|
|
@@ -1222,12 +1275,7 @@ function buildAggregateTarget(
|
|
|
1222
1275
|
return any ? "truncated" : "absent";
|
|
1223
1276
|
},
|
|
1224
1277
|
// Open invocations still belong to the current turn; only complete arcs reclaim.
|
|
1225
|
-
canDrop
|
|
1226
|
-
return (
|
|
1227
|
-
occurrences.some((occ) => occ.kind === "tool_use") &&
|
|
1228
|
-
occurrences.some((occ) => occ.kind === "tool_result")
|
|
1229
|
-
);
|
|
1230
|
-
},
|
|
1278
|
+
canDrop: complete,
|
|
1231
1279
|
requiresToolArcSkeleton,
|
|
1232
1280
|
// Non-mutating read of the invocation input (the tool_use occurrence
|
|
1233
1281
|
// carries the arguments). Used by smart-drops supersession selection.
|
|
@@ -1310,11 +1358,26 @@ function buildToolTarget(
|
|
|
1310
1358
|
return replaced ? "removed" : "absent";
|
|
1311
1359
|
},
|
|
1312
1360
|
truncate(): "truncated" | "absent" {
|
|
1361
|
+
// Legacy render, replayed only for unconverted `truncated` tags.
|
|
1313
1362
|
const changed = part.setToolInput
|
|
1314
1363
|
? part.setToolInput(droppedInputMarker(tagId))
|
|
1315
1364
|
: setToolContentOrText(part, `[dropped \u00a7${tagId}\u00a7]`);
|
|
1316
1365
|
return changed ? "truncated" : "absent";
|
|
1317
1366
|
},
|
|
1367
|
+
skeletonReal(): "truncated" | "absent" {
|
|
1368
|
+
// An invocation part keeps its real arguments untouched; a result
|
|
1369
|
+
// part's content becomes the dropped marker.
|
|
1370
|
+
if (part.setToolInput) return "truncated";
|
|
1371
|
+
return setToolContentOrText(part, `[dropped \u00a7${tagId}\u00a7]`)
|
|
1372
|
+
? "truncated"
|
|
1373
|
+
: "absent";
|
|
1374
|
+
},
|
|
1375
|
+
// drop() replaces an invocation part's arguments with a marker, so a
|
|
1376
|
+
// new drop of one keeps its real arguments instead.
|
|
1377
|
+
cannotRemove: () => part.setToolInput !== undefined,
|
|
1378
|
+
inputStringBytes(): number | null {
|
|
1379
|
+
return part.setToolInput ? toolInputStringBytes(part.getToolInput?.() ?? null) : 0;
|
|
1380
|
+
},
|
|
1318
1381
|
message: {
|
|
1319
1382
|
info: { id: message.info.id, role: message.info.role },
|
|
1320
1383
|
parts: [],
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { describe, expect, it } from "bun:test";
|
|
2
|
+
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import { basename, dirname } from "node:path";
|
|
4
|
+
import { testExecutableRoot, writeTestExecutable } from "./test-fake-executable";
|
|
5
|
+
|
|
6
|
+
// Fixed contents on purpose: a random body would create a new executable on
|
|
7
|
+
// every run, which is exactly what the helper exists to avoid.
|
|
8
|
+
const STUB = "#!/bin/sh\necho test-fake-executable-helper\n";
|
|
9
|
+
|
|
10
|
+
describe("writeTestExecutable", () => {
|
|
11
|
+
it("places the stub at a content-addressed path under the shared root", () => {
|
|
12
|
+
const path = writeTestExecutable("helper-stub", STUB);
|
|
13
|
+
|
|
14
|
+
expect(basename(path)).toBe("helper-stub");
|
|
15
|
+
expect(dirname(dirname(path))).toBe(testExecutableRoot());
|
|
16
|
+
expect(basename(dirname(path))).toMatch(/^[0-9a-f]{16}$/);
|
|
17
|
+
expect(readFileSync(path, "utf8")).toBe(STUB);
|
|
18
|
+
if (process.platform !== "win32") expect(statSync(path).mode & 0o111).not.toBe(0);
|
|
19
|
+
expect(readdirSync(dirname(path))).toEqual(["helper-stub"]);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("reuses the existing file instead of rewriting it", () => {
|
|
23
|
+
const first = writeTestExecutable("helper-stub", STUB);
|
|
24
|
+
const before = statSync(first);
|
|
25
|
+
const second = writeTestExecutable("helper-stub", STUB);
|
|
26
|
+
const after = statSync(second);
|
|
27
|
+
|
|
28
|
+
expect(second).toBe(first);
|
|
29
|
+
expect(after.ino).toBe(before.ino);
|
|
30
|
+
expect(after.mtimeMs).toBe(before.mtimeMs);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("gives different content or a different name a different directory", () => {
|
|
34
|
+
const base = writeTestExecutable("helper-stub", STUB);
|
|
35
|
+
const otherContent = writeTestExecutable("helper-stub", `${STUB}exit 0\n`);
|
|
36
|
+
const otherName = writeTestExecutable("helper-stub-2", STUB);
|
|
37
|
+
|
|
38
|
+
expect(new Set([dirname(base), dirname(otherContent), dirname(otherName)]).size).toBe(3);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("keeps a directory-name prefix verbatim before the hash", () => {
|
|
42
|
+
const prefix = "mc %MC_TEST% & shim ";
|
|
43
|
+
const path = writeTestExecutable("helper-stub", STUB, { dirPrefix: prefix });
|
|
44
|
+
const dirName = basename(dirname(path));
|
|
45
|
+
|
|
46
|
+
expect(dirName.startsWith(prefix)).toBe(true);
|
|
47
|
+
expect(dirName.slice(prefix.length)).toMatch(/^[0-9a-f]{16}$/);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("rejects names that would escape the stub directory", () => {
|
|
51
|
+
expect(() => writeTestExecutable("../escape", STUB)).toThrow();
|
|
52
|
+
expect(() => writeTestExecutable("stub", STUB, { dirPrefix: "a/b" })).toThrow();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
2
|
+
import {
|
|
3
|
+
chmodSync,
|
|
4
|
+
mkdirSync,
|
|
5
|
+
readFileSync,
|
|
6
|
+
renameSync,
|
|
7
|
+
rmSync,
|
|
8
|
+
statSync,
|
|
9
|
+
writeFileSync,
|
|
10
|
+
} from "node:fs";
|
|
11
|
+
import { tmpdir } from "node:os";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Test-only helper for fake executables (shell stubs standing in for opencode,
|
|
16
|
+
* sqlite3, bun, ...).
|
|
17
|
+
*
|
|
18
|
+
* macOS runs a malware assessment the first time any new executable file is
|
|
19
|
+
* launched. Writing a fresh stub into a fresh temp directory for every test
|
|
20
|
+
* case therefore triggers one assessment per case per run. Instead, each
|
|
21
|
+
* distinct stub lives at a fixed, content-addressed path and is written only
|
|
22
|
+
* once; later tests and later runs reuse the same file.
|
|
23
|
+
*
|
|
24
|
+
* Callers must never delete these files in per-test cleanup, and must never
|
|
25
|
+
* modify one in place: a test that needs a stub to "change" between steps asks
|
|
26
|
+
* for a second stub with different content, which lands at a different path.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/** Directory name under the OS temp dir that holds every shared fake executable. */
|
|
30
|
+
export const TEST_EXECUTABLE_ROOT_NAME = "magic-context-test-bin";
|
|
31
|
+
|
|
32
|
+
export function testExecutableRoot(): string {
|
|
33
|
+
return join(tmpdir(), TEST_EXECUTABLE_ROOT_NAME);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface WriteTestExecutableOptions {
|
|
37
|
+
/**
|
|
38
|
+
* Kept verbatim in front of the hash in the directory name. Use it only when
|
|
39
|
+
* the test depends on the directory name itself, for example to exercise
|
|
40
|
+
* quoting of spaces or shell metacharacters in the executable's path.
|
|
41
|
+
*/
|
|
42
|
+
dirPrefix?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function assertSinglePathSegment(label: string, value: string, allowEmpty: boolean): void {
|
|
46
|
+
if ((!allowEmpty && value.length === 0) || value === "." || value === "..") {
|
|
47
|
+
throw new Error(`writeTestExecutable: invalid ${label} ${JSON.stringify(value)}`);
|
|
48
|
+
}
|
|
49
|
+
if (value.includes("/") || value.includes("\\") || value.includes("\0")) {
|
|
50
|
+
throw new Error(`writeTestExecutable: ${label} must be a single path segment`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function hasExpectedContent(path: string, content: string): boolean {
|
|
55
|
+
try {
|
|
56
|
+
if (readFileSync(path, "utf8") !== content) return false;
|
|
57
|
+
// Windows has no executable bit, so content alone decides there.
|
|
58
|
+
return process.platform === "win32" || (statSync(path).mode & 0o111) !== 0;
|
|
59
|
+
} catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Returns the path of an executable named `name` whose bytes are `content`,
|
|
66
|
+
* creating it only when no identical file exists yet. The path is
|
|
67
|
+
* `<tmpdir>/magic-context-test-bin/<dirPrefix><first 16 hex of sha256(name, content)>/<name>`,
|
|
68
|
+
* so each directory holds exactly one executable and pointing PATH at it
|
|
69
|
+
* exposes nothing else.
|
|
70
|
+
*
|
|
71
|
+
* The file is written to a unique temporary name in the same directory and
|
|
72
|
+
* then renamed into place, so concurrent test processes never observe a
|
|
73
|
+
* half-written stub.
|
|
74
|
+
*/
|
|
75
|
+
export function writeTestExecutable(
|
|
76
|
+
name: string,
|
|
77
|
+
content: string,
|
|
78
|
+
options: WriteTestExecutableOptions = {},
|
|
79
|
+
): string {
|
|
80
|
+
const dirPrefix = options.dirPrefix ?? "";
|
|
81
|
+
assertSinglePathSegment("name", name, false);
|
|
82
|
+
assertSinglePathSegment("dirPrefix", dirPrefix, true);
|
|
83
|
+
|
|
84
|
+
// The NUL separator keeps ("ab", "c") and ("a", "bc") from sharing a hash.
|
|
85
|
+
const hash = createHash("sha256")
|
|
86
|
+
.update(name)
|
|
87
|
+
.update("\0")
|
|
88
|
+
.update(content)
|
|
89
|
+
.digest("hex")
|
|
90
|
+
.slice(0, 16);
|
|
91
|
+
const dir = join(testExecutableRoot(), `${dirPrefix}${hash}`);
|
|
92
|
+
const target = join(dir, name);
|
|
93
|
+
if (hasExpectedContent(target, content)) return target;
|
|
94
|
+
|
|
95
|
+
mkdirSync(dir, { recursive: true });
|
|
96
|
+
const staging = join(dir, `.${name}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`);
|
|
97
|
+
try {
|
|
98
|
+
writeFileSync(staging, content, { mode: 0o755 });
|
|
99
|
+
// The process umask can strip bits from the create mode; set them explicitly.
|
|
100
|
+
chmodSync(staging, 0o755);
|
|
101
|
+
renameSync(staging, target);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
rmSync(staging, { force: true });
|
|
104
|
+
// Another process may have won the race with identical bytes (Windows
|
|
105
|
+
// refuses to rename over a file that is currently open).
|
|
106
|
+
if (hasExpectedContent(target, content)) return target;
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
return target;
|
|
110
|
+
}
|
|
@@ -12,6 +12,12 @@ export const USER_FACING_FAILURES = {
|
|
|
12
12
|
sentence: "Some finished background sessions could not be removed from this host.",
|
|
13
13
|
action: "They are removed automatically the next time Magic Context runs inside a registered OpenCode service.",
|
|
14
14
|
},
|
|
15
|
+
historian_saved_history_misaligned: {
|
|
16
|
+
code: "MC-H03",
|
|
17
|
+
sentence:
|
|
18
|
+
"History compression is paused because this session's saved summaries no longer line up with its messages.",
|
|
19
|
+
action: "Run /ctx-recomp to rebuild them.",
|
|
20
|
+
},
|
|
15
21
|
recomp_unavailable: {
|
|
16
22
|
code: "MC-R01",
|
|
17
23
|
sentence: "History compression could not be rebuilt.",
|
|
@@ -27,6 +33,11 @@ export const USER_FACING_FAILURES = {
|
|
|
27
33
|
sentence: "Memory maintenance could not reach its model.",
|
|
28
34
|
action: "Check the model connection, then run /ctx-dream again.",
|
|
29
35
|
},
|
|
36
|
+
dream_step_limit: {
|
|
37
|
+
code: "MC-D10",
|
|
38
|
+
sentence: "Memory maintenance stopped at its hidden agent step limit.",
|
|
39
|
+
action: "This task needs less work per run; changing the model connection will not help.",
|
|
40
|
+
},
|
|
30
41
|
dream_empty_completion: {
|
|
31
42
|
code: "MC-D03",
|
|
32
43
|
sentence: "Memory maintenance received no usable response.",
|
|
@@ -183,11 +194,22 @@ export const USER_FACING_FAILURES = {
|
|
|
183
194
|
sentence: "History compression is paused while the engine syncs.",
|
|
184
195
|
action: "Retry in a moment.",
|
|
185
196
|
},
|
|
197
|
+
history_compression_needs_message: {
|
|
198
|
+
code: "MC-C12",
|
|
199
|
+
sentence: "History compression has not seen this session since Magic Context reconnected.",
|
|
200
|
+
action: "Send a message in this session first, then run /ctx-wrapup again.",
|
|
201
|
+
},
|
|
186
202
|
context_service_unavailable: {
|
|
187
203
|
code: "MC-C10",
|
|
188
204
|
sentence: "Magic Context is temporarily unavailable.",
|
|
189
205
|
action: "Retry in a moment.",
|
|
190
206
|
},
|
|
207
|
+
store_ahead_of_binary: {
|
|
208
|
+
code: "MC-C13",
|
|
209
|
+
sentence:
|
|
210
|
+
"Magic Context refused to start: its store (store.db) was migrated by a newer ck-mc build than the one running.",
|
|
211
|
+
action: "Update ck-mc, or roll back by restoring ck-mc together with context.db and store.db from the same backup.",
|
|
212
|
+
},
|
|
191
213
|
compaction_marker_missing: {
|
|
192
214
|
code: "MC-C11",
|
|
193
215
|
sentence:
|
|
@@ -204,11 +226,6 @@ export const USER_FACING_FAILURES = {
|
|
|
204
226
|
sentence: "Memory authority is inconsistent between the host and module.",
|
|
205
227
|
action: "Run `ck doctor drain-authority` before changing Rust mode.",
|
|
206
228
|
},
|
|
207
|
-
rust_mode_unsupported: {
|
|
208
|
-
code: "MC-S06",
|
|
209
|
-
sentence: "Experimental Rust transform mode is not available on this OpenCode host.",
|
|
210
|
-
action: 'Magic Context is running its TypeScript mode instead; set `transform_mode` to "ts" to stop requesting Rust.',
|
|
211
|
-
},
|
|
212
229
|
dreamer_task_failing: {
|
|
213
230
|
code: "MC-S05",
|
|
214
231
|
sentence: "A background maintenance task keeps failing on its schedule.",
|
|
@@ -267,6 +284,7 @@ export function capabilityRefusalCode(capability: CapabilityRefusal): string {
|
|
|
267
284
|
const DREAM_FAILURE_KEYS = {
|
|
268
285
|
provider_timeout: "dream_provider_timeout",
|
|
269
286
|
provider_error: "dream_provider_error",
|
|
287
|
+
step_limit: "dream_step_limit",
|
|
270
288
|
empty_completion: "dream_empty_completion",
|
|
271
289
|
no_models: "dream_no_models",
|
|
272
290
|
child_aborted: "dream_child_aborted",
|
|
@@ -645,9 +645,12 @@ export function hasTrustedAbsoluteWall(geometry: WindowGeometryResult): boolean
|
|
|
645
645
|
}
|
|
646
646
|
|
|
647
647
|
/**
|
|
648
|
-
* Successful requests can disprove static catalog metadata, but
|
|
649
|
-
*
|
|
650
|
-
*
|
|
648
|
+
* Successful requests can disprove static catalog metadata, but do not widen a
|
|
649
|
+
* provider, overlay, or observed-overflow wall here. A provider or overlay wall
|
|
650
|
+
* is the configured limit: a reading beyond it is real pressure against that
|
|
651
|
+
* limit (the usage handlers count it in full), not proof that the geometry
|
|
652
|
+
* should grow. An observed-overflow wall that a larger accepted request
|
|
653
|
+
* disproves is cleared by the usage handlers instead.
|
|
651
654
|
*/
|
|
652
655
|
export function applyProvenInputFloor(
|
|
653
656
|
geometry: WindowGeometryResult,
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export interface ProviderAdmissionInput {
|
|
2
|
-
/** Input + cached-read + cached-write tokens of the newest assistant reply. */
|
|
3
|
-
inputTokens: number;
|
|
4
|
-
/** The provider's own context window for the outgoing model, when the catalog knows it. */
|
|
5
|
-
rawContextLimit: number | undefined;
|
|
6
|
-
/** True when the host wrote a compaction after the reply the tokens were read from. */
|
|
7
|
-
hostCompactionReducedUsage: boolean;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Whether the OpenCode 2 context hook must stop a request before it reaches the
|
|
11
|
-
* provider.
|
|
12
|
-
*
|
|
13
|
-
* The provider's own context window is the only admission boundary here. Every
|
|
14
|
-
* other kind of pressure — in particular usage that fits the window but not the
|
|
15
|
-
* room reserved for the reply — has to be admitted, because the work that
|
|
16
|
-
* relieves it (compacting history into a compartment, and the high-pressure
|
|
17
|
-
* handling around it) all happens further down this same pass. A request stopped
|
|
18
|
-
* here runs none of it, so a session refused for pressure Magic Context could
|
|
19
|
-
* have removed is refused again on every following turn.
|
|
20
|
-
*/
|
|
21
|
-
export declare function refusesBeforeProvider(input: ProviderAdmissionInput): boolean;
|
|
22
|
-
//# sourceMappingURL=provider-admission.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"provider-admission.d.ts","sourceRoot":"","sources":["../../../src/v2/hooks/provider-admission.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,sBAAsB;IACnC,+EAA+E;IAC/E,WAAW,EAAE,MAAM,CAAC;IACpB,2FAA2F;IAC3F,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,uFAAuF;IACvF,0BAA0B,EAAE,OAAO,CAAC;CACvC;AAKD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAkB5E"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
runManagedWrapup2
|
|
3
|
-
} from "./index-1gtwrdc4.js";
|
|
4
|
-
import"./index-7wpwr2e2.js";
|
|
5
|
-
import"./index-sd3egckz.js";
|
|
6
|
-
import"./index-0ccmyzbj.js";
|
|
7
|
-
import"./index-yc81txp4.js";
|
|
8
|
-
import"./index-j7cnyvq1.js";
|
|
9
|
-
import"./index-y5145x8k.js";
|
|
10
|
-
import"./index-v8qr6tt2.js";
|
|
11
|
-
import"./index-9r1cbh9e.js";
|
|
12
|
-
import"./index-jdxxq8cz.js";
|
|
13
|
-
import"./index-febg06dy.js";
|
|
14
|
-
import"./index-wgzyeyf5.js";
|
|
15
|
-
import"./index-6z9g64js.js";
|
|
16
|
-
export {
|
|
17
|
-
runManagedWrapup2 as runManagedWrapup
|
|
18
|
-
};
|