CD-1284: stream vault downloads to disk; add vault_read_text tool#20
Merged
Merged
Conversation
Two changes to the native Case.dev vault tools:
1. downloadCaseDevVaultObject buffered the entire object in memory
(new Uint8Array(await response.arrayBuffer())) before writing. On
multi-GB originals the sandbox OOM killer SIGKILLs the linc process
~73s in — confirmed twice in production against a 2.18GB scanned
PDF (bridge.rpc_exit {signal: SIGKILL} in the session logs, run dead
with no terminal event). Stream the response body straight to disk
with pipeline(); memory stays constant at any file size.
2. New vault_read_text / casedev_vault_read_text tools: fetch the
object's full extracted text (GET /vault/{id}/objects/{objectId}/text,
page-numbered when the source is paginated) into a workspace .txt
and return path + char/page-marker stats. Raw originals are often
scanned images the sandbox cannot read; the extracted text is the
right surface for reading, grepping, or comprehensively analyzing
document content. Download tool descriptions now carry the
originals-vs-content contrast, and downloads of ingested objects
include a note pointing at vault_read_text.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| const filename = baseName.endsWith(".txt") ? baseName : `${baseName}.txt`; | ||
| await mkdir(params.outDir, { recursive: true }); | ||
| const outputPath = safeOutputPath(params.outDir, filename); | ||
| await writeFile(outputPath, text, "utf8"); |
CI regenerates models.generated.ts from the live gateway during Build, and the catalog has moved since the last sync (Jun 23) — the committed file and the live catalog disagreed, so local checks passed while CI failed on the full-control example's claude-sonnet-4-20250514 (dropped upstream). Sync the generated catalog and move the example to claude-sonnet-5. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The catalog sync raised claude-sonnet-4-5's context window from 200K to 1M, stranding the test's hardcoded 190K usage far below the compaction threshold. Derive the near-limit usage from model.contextWindow so future catalog growth can't strand it again. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Thurgood-AI
approved these changes
Jul 11, 2026
Thurgood-AI
left a comment
There was a problem hiding this comment.
Approved. The download path now streams instead of buffering multi-GB originals, the extracted-text tool is wired through both native tool names with page-marker metadata, and the model-catalog/threshold updates are internally consistent.
Verification:
- Focused vault API suite: 7/7 passed locally
- CI build/check/test: green
- Vercel checks: green
Non-blocking follow-up: streaming to a temporary file and atomically renaming on success would prevent a failed transfer from leaving a partial file at the final path. The current behavior fails the tool call loudly and a retry truncates/replaces the destination, so I don't consider that a merge blocker.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
downloadCaseDevVaultObjectbuffers the whole object in memory before writing (casedev-vault-api.ts—new Uint8Array(await response.arrayBuffer())). Downloading a 2.18GB scanned PDF gets the linc process OOM-SIGKILLed ~73s in — confirmed twice in prod session logs (bridge.rpc_exit {code: null, signal: "SIGKILL"}immediately aftervault_downloadstart, run dead with the UI spinning). Linear: CD-1280/CD-1284.And even when a giant download succeeds, the raw original is usually a scanned PDF the sandbox can't read — the content agents actually need is the extracted text, which case.dev now serves page-numbered per object (
GET /vault/{id}/objects/{objectId}/text, casedotdev-mono CD-1282, verified live).Changes
pipeline(Readable.fromWeb(response.body), createWriteStream(...))— constant memory at any size;bytesfromstat.vault_read_text/casedev_vault_read_texttools — write the extracted, page-numbered text into the workspace as.txt, return{path, chars, pageMarkers, note}; content never enters model context. Contrasting descriptions on the download tools (originals = raw bytes / content = read_text), plus a note in download results for ingested objects.Tests
ReadableStreambody to disk, verifies content + byte countreadCaseDevVaultObjectTextwrites the file with page-marker stats and hits the right endpointnpm run checkclean (biome, tsgo, shrinkwrap, browser-smoke)Rollout
After merge + release, casedotdev-mono bumps
@casemark/lincand rebuilds the Daytona snapshots (CD-1284 tracks the chain). Post-deploy verification: the production giant-doc chat that currently dies at ~73s should read one 23MB page-numbered text file and answer with page citations.🤖 Generated with Claude Code