Skip to content

fix(agent): Request-limit-unrecoverable-thread#2078

Open
lost-particles wants to merge 3 commits intoPostHog:mainfrom
lost-particles:fix/request-limit-unrecoverable-thread
Open

fix(agent): Request-limit-unrecoverable-thread#2078
lost-particles wants to merge 3 commits intoPostHog:mainfrom
lost-particles:fix/request-limit-unrecoverable-thread

Conversation

@lost-particles
Copy link
Copy Markdown

Fixes: #2048

Problem

Sometimes the prompt path was putting whole file bodies into the user message payload instead of only referencing paths:

  • When an ACP resource chunk used a file:// URI, our conversion logic was taking resource.text and embedding it as a <context>...</context> block in the Claude Agent SDK user message. That meant a large (or mistakenly huge) attachment could blow the serialized HTTP request size before the agent could even behave “normally.”
  • The buildCloudPromptBlocks test/harness helper was also reading text off disk and emitting resource blobs with inlined (truncated) content — structurally the same problem, and inconsistent with how production cloud flow stays path/artifact-centric.

This is independent of READ_TOOLS / permission labels in our agent package: those only classify tool names like Read (Claude Code tools reference — **Read). They don’t fetch files; the model invokes Read at runtime.

Anthropic’s Request too large doc explains pressure from big payloads and recommends patterns like chunked reads and PDF pages rather than dumping everything into one turn (Request too large).

Closes: #2048

Changes

  1. promptToClaude (acp-to-sdk.ts)
    For file:// on resource_link and resource, I only emit short path-first copy that aligns with Claude Code’s Read FileReadInput: file_path, optional offset / limit for large text, and optional pages (string ranges, e.g. "1-5") for PDFs (Agent SDK TypeScript — Read).
    For resource + file://, I stop forwarding resource.text into <context> so workspace files can’t be inlined that way anymore.

  2. file:// image blocks without base64 data
    I map those to the same path + Read style text instead of dropping them or silently doing nothing useful.

  3. Non filesystem schemes
    Where we still rely on inlined payloads for tests/other flows (e.g. attachment://), I keep link + <context> behavior so those cases don’t regress.

  4. buildCloudPromptBlocks (harness)
    Text attaches become resource_link with file:// URIs (same idea as production cloudPromptToBlocks), without readAbsoluteFile for TXT. Images in that harness stay embedded image (separate topic from resource). Production cloud stays uploads + artifact_ids.

  5. Tests
    I added/updated Vitest coverage so file:// + huge resource.text never appears in the SDK message, attachment:// inline behavior still works, and the cloud harness emits resource_link for text.

How did you test this?

  • pnpm test
  • pnpm --filter @posthog/agent test
  • pnpm --filter code test
  • pnpm --filter @posthog/git test

fix(agent): Request-limit-unrecoverable-thread

Stop inlining workspace file bodies from ACP resources into Claude SDK user
messages. For file:// on resource/resource_link, steer the model toward Read
(offset/limit, PDF pages) and preserve attachment:// and other schemes.

Update buildCloudPromptBlocks harness to use resource_link for text files.
Add/adjust Vitest coverage for stripping inlined file text vs attachment parity.
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 7, 2026

Comments Outside Diff (1)

  1. packages/agent/src/adapters/claude/conversion/acp-to-sdk.ts, line 111-115 (link)

    P2 With formatFileAttachment removed, the resource_link branch can call workspacePromptFromFileUri directly, consistent with the resource and image branches added in this PR.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: packages/agent/src/adapters/claude/conversion/acp-to-sdk.ts
    Line: 111-115
    
    Comment:
    With `formatFileAttachment` removed, the `resource_link` branch can call `workspacePromptFromFileUri` directly, consistent with the `resource` and `image` branches added in this PR.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 4 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 4
packages/agent/src/adapters/claude/conversion/acp-to-sdk.ts:82-86
`formatFileAttachment` is a one-line wrapper that adds no logic on top of `workspacePromptFromFileUri`. Per the team's simplicity rules, superfluous indirection should be removed — the call site already uses the exported function directly in the `resource` and `image` cases.

```suggestion
function isFileSchemeUri(uri: string | undefined | null): boolean {
```

### Issue 2 of 4
packages/agent/src/adapters/claude/conversion/acp-to-sdk.ts:111-115
With `formatFileAttachment` removed, the `resource_link` branch can call `workspacePromptFromFileUri` directly, consistent with the `resource` and `image` branches added in this PR.

```suggestion
        sdkText(
          chunk.uri.startsWith("file://")
            ? workspacePromptFromFileUri(chunk.uri)
            : formatUriAsLink(chunk.uri),
        ),
```

### Issue 3 of 4
packages/agent/src/adapters/claude/conversion/acp-to-sdk.test.ts:9-19
The team prefers parameterised tests. These two cases test the same function with different inputs and expected substrings — a natural fit for `it.each`. The binary/image extension branch is also unexercised and could be added as a third row.

```suggestion
describe("readToolGuidanceForPath", () => {
  it.each([
    ["/docs/x.pdf", ["pages"]],
    ["/proj/app.ts", ["offset", "limit"]],
    ["/assets/logo.png", ["Binary", "file_path"]],
  ])("guides reads for %s", (filePath, keywords) => {
    const guidance = readToolGuidanceForPath(filePath);
    for (const keyword of keywords) {
      expect(guidance).toContain(keyword);
    }
  });
});
```

### Issue 4 of 4
apps/code/src/renderer/features/editor/utils/cloud-prompt.ts:82-88
`pathToFileUri` re-implements what Node's built-in `pathToFileURL` already does correctly (including edge cases like a literal `%` in filenames). `fileURLToPath` from `node:url` is already used in the sibling `acp-to-sdk.ts` file, so the symmetric inverse is available in the same package.

```suggestion
import { pathToFileURL } from "node:url";

function pathToFileUri(filePath: string): string {
  return pathToFileURL(filePath).href;
}
```

Reviews (1): Last reviewed commit: "fix(agent): Request-limit-unrecoverable-..." | Re-trigger Greptile

Comment thread packages/agent/src/adapters/claude/conversion/acp-to-sdk.ts Outdated
Comment thread packages/agent/src/adapters/claude/conversion/acp-to-sdk.test.ts
Comment thread apps/code/src/renderer/features/editor/utils/cloud-prompt.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Thread becomes unrecoverable after hitting 32MB request limit

1 participant