Commit Graph

13 Commits

Author SHA1 Message Date
roboomp cb63ebd9f5 fix(session): preserved compaction data for rewinds
Kept superseded summaries and preserveData durable while deriving forward transcript elision from the active compaction.

Added branch and rewind coverage for snapcompact archives and OpenAI remote replacement history.

Fixes #4090
2026-07-23 19:53:05 +00:00
can1357 8205d3ee31 style: applied biome formatting to merged fix commits 2026-07-23 11:39:15 +02:00
can1357 e488d09751 fix(coding-agent): keep failed tails visible in read-only session history
Route loadSessionMessagesReadOnly through transcript mode (collapsed to the
latest compaction) so history:// transcripts of on-disk sessions retain
failed/aborted assistant tails that the provider-context builder now drops.
2026-07-23 11:37:10 +02:00
roboomp 1e209caeee perf(session): gate blob-ref resolution behind synchronous precheck
resolveBlobRefsInEntries handed every non-session entry to the recursive
async resolvePersistedBlobRefs walk, allocating and awaiting child promises
even for plain-text entries with no blob:sha256: refs. On large text-heavy
histories this dominated the blob_resolve phase of session open.

Add a cheap synchronous containsBlobRef precheck that early-exits on the
first ref and allocates nothing. Interleave the precheck with per-entry
initiation so positive entries still start resolution at the same relative
point as the old filter+map schedule (a later entry that gains a ref during
an earlier BlobStore.get is still scanned after that mutation).

Blob-free N=5000 fixture: blob_resolve median 19.5ms -> 1.1ms, zero
BlobStore.get calls.

Fixes #5922
2026-07-17 23:25:16 +00:00
roboomp b6b947bdbe fix(openai): rendered native response images
- Normalized completed image_generation_call results into assistant image blocks.
- Persisted image bytes through the session blob store and rendered them in live, replay, ACP, proxy, telemetry, and HTML paths.
- Added response normalization, persistence, and TUI rendering regressions.

Fixes #4768
2026-07-14 16:15:53 +00:00
oldschoola 4c4cc8857a fix(coding-agent): preserve multibyte UTF-8 across stream chunks in session loader
Address review: the per-chunk Buffer.from(chunk).toString("utf8") string concat corrupted multibyte sequences (e.g. ✓, emoji) that straddled a chunk boundary — silent data loss in exactly the ≥8MiB long sessions that take this path. Keep the buffer as a Uint8Array and pass it directly to Bun.JSONL.parseChunk (it accepts typed arrays and parses UTF-8 natively), so no decoding happens until a complete record is parsed. Only the title-slot first line is decoded, and only after the full line (up to its '\n') is buffered, so it is a complete UTF-8 sequence.

Also: drop the defensive 'read || 0' (read is number per typings); add a multibyte multi-chunk parity test (>128KiB fixture) that would have caught the bug.
2026-06-29 18:28:39 -07:00
oldschoola 66d3676d25 perf(coding-agent): speed up large-session resume with Bun.JSONL
The ≥8MiB session-load path (loadEntriesFromFileStream) used node:readline + per-line JSON.parse, while the common (<8MiB) path already used Bun's native Bun.JSONL. The large-session path is now the lone outlier getting the slower parser.

Rewrite loadEntriesFromFileStream to a lenient streaming Bun.JSONL.parseChunk loop: stream the file via Bun.file().stream() into a bounded buffer (memory guard preserved — the file is never fully loaded, which is why the 8MiB threshold exists), skip malformed records to the next newline instead of throwing, peel/fold the non-JSON first-line title slot, terminate a trailing newline-less record, and keep isEnoent→empty. Removed the now-unused node:fs + node:readline imports.

Measured ~9.5ms → ~6.0ms (-37%) loading a 10MiB valid session; the remaining cost is I/O + native parse (floor).

Correctness: new session-loader-stream.test.ts asserts the stream path produces byte-identical entries + titleSlot to parseSessionContent (the common-path parser) across title-slot / blank / malformed / no-trailing-newline / missing-file cases.
2026-06-29 18:28:39 -07:00
roboomp cc2cf5c7d0 fix(session): scope compaction elision to active branch
Restrict the supersede sweep to compactions on the path from the current leaf so a newer compaction never rewrites a sibling branch's still-current summary or drops its preserveData. Streaming load now collects the active-branch ids before eliding instead of trampling sibling compactions encountered in file order.

Refs #3789
2026-06-29 06:22:04 +00:00
roboomp e8b2c5d058 fix(session): avoid ctrl-c rewrites for compacted sessions
Stream large session loads, elide superseded compaction payloads, skip synchronous rewrites when the append-only file is already current, and provide usable picker previews for developer-started forks.

Fixes #3789
2026-06-29 06:13:43 +00:00
can1357 0ce330ab79 feat(session): implemented persistent session title tracking
- Added a fixed-width title slot system to serialize and persist session titles across physical files and backend storage.
- Integrated automated session title updates triggered by todo replan operations using conversation history context.
- Extended storage interfaces across memory, file-system, Redis, and SQL backends to support independent title metadata updates.
- Implemented title metadata parsing within session loaders and list utilities to ensure accurate retrieval and display.
2026-06-28 07:27:00 +02:00
can1357 af6e83a651 fix(coding-agent): replaced JSON string equality checks with deep equality
- Changed provider delta input comparisons in `buildResponsesDeltaInput` to use `Bun.deepEquals` instead of stringified JSON checks.
- Updated session message diffing to return early on length changes and compare normalized entries with deep equality.
- Replaced JSON-string assertions in the issue-966 repro test with `Bun.deepEquals` for stable equality checks.
2026-06-17 13:45:11 +02:00
can1357 e4a87fa3ce feat(coding-agent): added matplotlib rendering and image persistence across session reload
- Added Matplotlib figure PNG rendering and display tracking in Python runner to emit PNG output immediately when figures are displayed via display(fig).
- Extended session persistence to externalize oversized image payloads in both content and details.images, enabling tool result images to survive session reload.
- Enhanced session loader to resolve image data payloads and blob references across content and details.images during session reconstruction.
- Added image cache invalidation in TUI image component when image protocol, cell dimensions, or Kitty Unicode placeholder mode changes.
- Added comprehensive test coverage for Matplotlib display, image persistence across reload, and TUI image rendering with protocol and dimension changes.
2026-06-17 13:19:28 +02:00
can1357 24c8bb24c6 feat(session): added modular session APIs and rebuilt listing/persistence behavior
- Added session-domain modules and exports for session-entries, context, listing, loader, and migrations.
- Changed persistence to async append writes plus writeTextAtomic, removing sync line APIs.
- Added compaction-aware session context rebuild with dangling tool-call cleanup.
- Added resumable session resolution with status inference, id/stem/suffix matching, and backup recovery.
2026-06-14 02:02:53 +02:00