@code-yeongyu/senpi 2026.9.15-2 → 2026.9.16-2
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/CHANGELOG.md +48 -0
- package/README.md +1 -1
- package/dist/core/agent-session.d.ts +28 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +111 -13
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +4 -2
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/stream-watchdog.d.ts +56 -2
- package/dist/core/compaction/stream-watchdog.d.ts.map +1 -1
- package/dist/core/compaction/stream-watchdog.js +93 -15
- package/dist/core/compaction/stream-watchdog.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.d.ts +6 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js +17 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts +4 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js +31 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts +2 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js +16 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js +19 -8
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +2 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +13 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +66 -2
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +16 -10
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative-summary.js +4 -2
- package/dist/core/extensions/builtin/compaction/speculative-summary.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.d.ts +8 -1
- package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.js +31 -7
- package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/transient-failure.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/transient-failure.js +6 -3
- package/dist/core/extensions/builtin/compaction/transient-failure.js.map +1 -1
- package/dist/core/extensions/kernel-tools-context.d.ts +13 -0
- package/dist/core/extensions/kernel-tools-context.d.ts.map +1 -0
- package/dist/core/extensions/kernel-tools-context.js +3 -0
- package/dist/core/extensions/kernel-tools-context.js.map +1 -0
- package/dist/core/extensions/runner.d.ts +19 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +103 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +21 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts +5 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +1 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/retry-fallback/settings.d.ts +3 -0
- package/dist/core/retry-fallback/settings.d.ts.map +1 -1
- package/dist/core/retry-fallback/settings.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +27 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +78 -5
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-resident-store.d.ts +33 -7
- package/dist/core/session-resident-store.d.ts.map +1 -1
- package/dist/core/session-resident-store.js +163 -14
- package/dist/core/session-resident-store.js.map +1 -1
- package/dist/core/session-write-reservation.d.ts +6 -0
- package/dist/core/session-write-reservation.d.ts.map +1 -1
- package/dist/core/session-write-reservation.js +19 -0
- package/dist/core/session-write-reservation.js.map +1 -1
- package/dist/core/settings-manager.d.ts +35 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +62 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +4 -3
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/read.d.ts +3 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +16 -2
- package/dist/core/tools/read.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/assistant-render-descriptors.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-render-descriptors.js +12 -5
- package/dist/modes/interactive/components/assistant-render-descriptors.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts +2 -0
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js +5 -0
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +19 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +66 -14
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/session-tips.js +1 -1
- package/dist/modes/interactive/tips/catalog/session-tips.js.map +1 -1
- package/dist/modes/interactive/working-status.d.ts +3 -2
- package/dist/modes/interactive/working-status.d.ts.map +1 -1
- package/dist/modes/interactive/working-status.js +17 -4
- package/dist/modes/interactive/working-status.js.map +1 -1
- package/dist/modes/print-mode.d.ts +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +5 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/docs/extensions.md +5 -2
- package/docs/keybindings.md +1 -0
- package/docs/session-format.md +1 -1
- package/docs/sessions.md +3 -3
- package/docs/settings.md +31 -1
- package/docs/usage.md +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +35 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +24 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/http-server.ts +7 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/kernel-tools-protocol.ts +85 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/protocol.ts +6 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/agent-bridge.ts +30 -11
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/session-manager.ts +11 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +10 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/prelude.jl +46 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/runner.jl +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +29 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-contract.ts +12 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-context.d.ts +13 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-context.js +7 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-define.d.ts +10 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-define.js +12 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-errors.js +22 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-errors.ts +26 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-host.ts +134 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-naming.js +28 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-parse.d.ts +5 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-parse.js +255 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-pump.js +105 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-registry.d.ts +27 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-registry.js +127 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-schema.js +69 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-types.ts +42 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/prelude.ts +2 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +26 -3
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-runtime.js +20 -8
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-slot.ts +6 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-startup.ts +9 -7
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/workpool.js +37 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/kernel-tools-unavailable.ts +5 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel.ts +13 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/prelude.py +57 -3
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/prelude.rb +13 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/workpool.rb +38 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +13 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-queue.ts +2 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt-template.ts +4 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-handler.ts +31 -3
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/run-eval-cell.ts +52 -30
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +2 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +30 -3
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +5 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +2 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js +51 -12
- package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.d.ts +3 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.js +18 -3
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.d.ts +4 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.js +268 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.d.ts +18 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.js +69 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.d.ts +27 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.js +118 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.d.ts +21 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.js +24 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.d.ts +12 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.js +92 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.d.ts +47 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.js +8 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.d.ts +52 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.js +155 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts +4 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.js +3 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.d.ts +101 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.js +178 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +9 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/alibaba-token-plan.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.d.ts +15 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.js +15 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts +24 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +92 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomBytes, randomUUID } from "crypto";
|
|
2
|
-
import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readdirSync, readFileSync, readSync, statSync, writeFileSync, } from "fs";
|
|
2
|
+
import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readdirSync, readFileSync, readSync, rmSync, statSync, writeFileSync, } from "fs";
|
|
3
3
|
import { readdir } from "fs/promises";
|
|
4
4
|
import { join, resolve } from "path";
|
|
5
5
|
import { StringDecoder } from "string_decoder";
|
|
@@ -8,7 +8,7 @@ import { normalizePath, resolvePath } from "../utils/paths.js";
|
|
|
8
8
|
import { listSessionInfos, listSessionsFromDir } from "./session-discovery.js";
|
|
9
9
|
import { materializeSessionEntries } from "./session-entry-materializer.js";
|
|
10
10
|
import { ResidentStringStore } from "./session-resident-store.js";
|
|
11
|
-
import { registerSessionWriter, reserveSessionWrite } from "./session-write-reservation.js";
|
|
11
|
+
import { hasOtherLiveSessionWriter, registerSessionWriter, reserveSessionWrite, unregisterSessionWriter, } from "./session-write-reservation.js";
|
|
12
12
|
// Fork change: inlined UUIDv7 (upstream uses the `uuid` npm package). Keeps this
|
|
13
13
|
// package self-contained so consumers don't need a transitive `uuid` install.
|
|
14
14
|
function uuidv7() {
|
|
@@ -587,6 +587,12 @@ export class SessionManager {
|
|
|
587
587
|
if (persist && this.sessionDir && !existsSync(this.sessionDir)) {
|
|
588
588
|
mkdirSync(this.sessionDir, { recursive: true });
|
|
589
589
|
}
|
|
590
|
+
// Lazily resolved: the session id only exists once the header loads or
|
|
591
|
+
// newSession() runs. Unpersisted sessions disable eviction entirely —
|
|
592
|
+
// dropping strings with no backing would lose them.
|
|
593
|
+
this.residentStore.configure({
|
|
594
|
+
blobsDir: () => this.persist && this.sessionId ? join(this.sessionDir, "resident-blobs", this.sessionId) : undefined,
|
|
595
|
+
});
|
|
590
596
|
if (sessionFile) {
|
|
591
597
|
this._setSessionFile(sessionFile, preloadedFileEntries);
|
|
592
598
|
}
|
|
@@ -646,6 +652,10 @@ export class SessionManager {
|
|
|
646
652
|
this.fileEntries = entries;
|
|
647
653
|
const header = this.fileEntries.find((e) => e.type === "session");
|
|
648
654
|
this.sessionId = header?.id ?? createSessionId();
|
|
655
|
+
// Blobs left under this id by a process that is gone are a disposable cache:
|
|
656
|
+
// the JSONL is the authority for every entry and this store rewrites what it
|
|
657
|
+
// evicts, so clearing them bounds the directory to one process lifetime.
|
|
658
|
+
this._releaseBlobsDirUnlessShared();
|
|
649
659
|
if (migrateToCurrentVersion(this.fileEntries)) {
|
|
650
660
|
this._rewriteFile();
|
|
651
661
|
}
|
|
@@ -674,6 +684,10 @@ export class SessionManager {
|
|
|
674
684
|
if (options?.id !== undefined) {
|
|
675
685
|
assertValidSessionId(options.id);
|
|
676
686
|
}
|
|
687
|
+
// Capture the previous backing before the id changes: the blobsDir
|
|
688
|
+
// provider resolves against the new id after this assignment, so clear()
|
|
689
|
+
// below would otherwise leak the old session's blob directory on disk.
|
|
690
|
+
const previousBlobsDir = this.residentStore.resolvedBlobsDir();
|
|
677
691
|
this.sessionId = options?.id ?? createSessionId();
|
|
678
692
|
const timestamp = new Date().toISOString();
|
|
679
693
|
const header = {
|
|
@@ -688,6 +702,9 @@ export class SessionManager {
|
|
|
688
702
|
this.mirrorTrimmed = false;
|
|
689
703
|
this.fullEntryCount = 0;
|
|
690
704
|
this.residentStore.clear();
|
|
705
|
+
if (previousBlobsDir) {
|
|
706
|
+
this._removeBlobsDir(previousBlobsDir);
|
|
707
|
+
}
|
|
691
708
|
this.byId.clear();
|
|
692
709
|
this.entryOrdersById.clear();
|
|
693
710
|
this.messageEntryPositions = new WeakMap();
|
|
@@ -803,6 +820,13 @@ export class SessionManager {
|
|
|
803
820
|
getSessionFile() {
|
|
804
821
|
return this.sessionFile;
|
|
805
822
|
}
|
|
823
|
+
/**
|
|
824
|
+
* Exposes the resident store for out-of-band string lifecycles such as the
|
|
825
|
+
* agent's runtime message state (tokenized while idle, hydrated per turn).
|
|
826
|
+
*/
|
|
827
|
+
getResidentStore() {
|
|
828
|
+
return this.residentStore;
|
|
829
|
+
}
|
|
806
830
|
getResidentStoreStats() {
|
|
807
831
|
return this.residentStore.stats();
|
|
808
832
|
}
|
|
@@ -1024,6 +1048,35 @@ export class SessionManager {
|
|
|
1024
1048
|
this._trimMirrorAfterCompaction(entry);
|
|
1025
1049
|
return entry.id;
|
|
1026
1050
|
}
|
|
1051
|
+
/**
|
|
1052
|
+
* Release what outlives this manager in the process: the shared host's write
|
|
1053
|
+
* grant and the blob directory backing its resident mirror. The session JSONL
|
|
1054
|
+
* is untouched - it is the authority the next reader loads from. Idempotent.
|
|
1055
|
+
*/
|
|
1056
|
+
dispose() {
|
|
1057
|
+
unregisterSessionWriter(this);
|
|
1058
|
+
this._releaseBlobsDirUnlessShared();
|
|
1059
|
+
}
|
|
1060
|
+
/**
|
|
1061
|
+
* The blob directory is keyed by session id, so every live manager over the same
|
|
1062
|
+
* session file hydrates from it. Removing it while one of them is still reading
|
|
1063
|
+
* would cost that manager a full JSONL recovery per evicted string, so the last
|
|
1064
|
+
* owner to let go is the one that clears it.
|
|
1065
|
+
*/
|
|
1066
|
+
_releaseBlobsDirUnlessShared() {
|
|
1067
|
+
const blobsDir = this.residentStore.resolvedBlobsDir();
|
|
1068
|
+
if (!blobsDir)
|
|
1069
|
+
return;
|
|
1070
|
+
if (this.sessionFile && hasOtherLiveSessionWriter(this.sessionFile, this))
|
|
1071
|
+
return;
|
|
1072
|
+
this._removeBlobsDir(blobsDir);
|
|
1073
|
+
}
|
|
1074
|
+
_removeBlobsDir(dir) {
|
|
1075
|
+
try {
|
|
1076
|
+
rmSync(dir, { force: true, recursive: true });
|
|
1077
|
+
}
|
|
1078
|
+
catch { }
|
|
1079
|
+
}
|
|
1027
1080
|
_trimMirrorAfterCompaction(compaction) {
|
|
1028
1081
|
if (!this.persist)
|
|
1029
1082
|
return;
|
|
@@ -1042,7 +1095,7 @@ export class SessionManager {
|
|
|
1042
1095
|
entry.parentId = parentId;
|
|
1043
1096
|
parentId = entry.type === "session" ? null : entry.id;
|
|
1044
1097
|
}
|
|
1045
|
-
this.residentStore.
|
|
1098
|
+
this.residentStore.spillResident();
|
|
1046
1099
|
this.mirrorTrimmed = true;
|
|
1047
1100
|
this.fileEntries = [header, ...retained]
|
|
1048
1101
|
.filter((entry) => entry !== undefined)
|
|
@@ -1280,6 +1333,17 @@ export class SessionManager {
|
|
|
1280
1333
|
getEntryCount() {
|
|
1281
1334
|
return this.fullEntryCount;
|
|
1282
1335
|
}
|
|
1336
|
+
/**
|
|
1337
|
+
* Release the memoized materialized views. Materialized entries hold the full
|
|
1338
|
+
* persisted strings, so views kept between turns pin the whole session text
|
|
1339
|
+
* in memory even while nothing runs. The next read rebuilds them from the
|
|
1340
|
+
* bounded resident store.
|
|
1341
|
+
*/
|
|
1342
|
+
dropMaterializedCaches() {
|
|
1343
|
+
this.entriesCache = null;
|
|
1344
|
+
this.branchCache = null;
|
|
1345
|
+
this.compactEntriesCache = null;
|
|
1346
|
+
}
|
|
1283
1347
|
_materializeEntries(entries) {
|
|
1284
1348
|
return materializeSessionEntries(entries, {
|
|
1285
1349
|
residentStore: this.residentStore,
|
|
@@ -1503,11 +1567,19 @@ export class SessionManager {
|
|
|
1503
1567
|
parentId = labelEntry.id;
|
|
1504
1568
|
}
|
|
1505
1569
|
reserveSessionWrite(newSessionFile);
|
|
1570
|
+
// Materialize the branched entries while the previous backing is still
|
|
1571
|
+
// readable, then clear: re-externalizing tokenized entries after clear()
|
|
1572
|
+
// would bake sentinel tokens into the new branched JSONL.
|
|
1573
|
+
const branchedEntries = this._materializeEntries([...pathWithoutLabels, ...labelEntries]);
|
|
1574
|
+
const previousBlobsDir = this.residentStore.resolvedBlobsDir();
|
|
1506
1575
|
this.residentStore.clear();
|
|
1576
|
+
if (previousBlobsDir) {
|
|
1577
|
+
this._removeBlobsDir(previousBlobsDir);
|
|
1578
|
+
}
|
|
1507
1579
|
this.mirrorTrimmed = false;
|
|
1508
|
-
this.fileEntries = [header, ...pathWithoutLabels, ...labelEntries].map((entry) => this.residentStore.externalize(entry));
|
|
1509
1580
|
this.sessionId = newSessionId;
|
|
1510
1581
|
this.sessionFile = newSessionFile;
|
|
1582
|
+
this.fileEntries = [header, ...branchedEntries.map((entry) => this.residentStore.externalize(entry))];
|
|
1511
1583
|
this._buildIndex();
|
|
1512
1584
|
this.mutationCount++;
|
|
1513
1585
|
// Only write the file now if it contains an assistant message.
|
|
@@ -1540,8 +1612,9 @@ export class SessionManager {
|
|
|
1540
1612
|
labelEntries.push(labelEntry);
|
|
1541
1613
|
parentId = labelEntry.id;
|
|
1542
1614
|
}
|
|
1615
|
+
const branchedEntries = this._materializeEntries([...pathWithoutLabels, ...labelEntries]);
|
|
1543
1616
|
this.residentStore.clear();
|
|
1544
|
-
this.fileEntries = [header, ...
|
|
1617
|
+
this.fileEntries = [header, ...branchedEntries.map((entry) => this.residentStore.externalize(entry))];
|
|
1545
1618
|
this.sessionId = newSessionId;
|
|
1546
1619
|
this._buildIndex();
|
|
1547
1620
|
this.mutationCount++;
|