Bug Description:
getFileContent caps its result at ai-features.workspaceFunctions.fileContentMaxSizeKB (default 256 KB). The whole-file write tools — writeFileContent and suggestFileContent in packages/ai-ide/src/browser/file-changeset-functions.ts — have no equivalent guard.
So the agent is refused a 2 MB read but will accept a 2 MB write. These tools require the model to emit the COMPLETE content as tool-call arguments, so cost scales with file size in output tokens. Base64 is the worst case: it tokenizes at ~3 chars/token, so ~1 MB of base64 is ~350K output tokens, past most models' max output.
A single huge argument value is also expensive downstream: the content is retained ~4x (targetState, _originalContent, the tool call's _arguments, the Monaco buffer); a base64 value makes the file effectively one enormous line, which is the pathological case for Monaco; session autosave re-serializes it every ≤5 s while it streams; and it is re-uploaded in history on every later turn.
Suggested fix: a size guard mirroring the read side — reject or warn above a configurable limit and point the model at writeFileReplacements.
Steps to Reproduce:
- In agent mode, ask the agent to create a JSON file with an embedded image, e.g.
{"name": "logo", "data": "data:image/png;base64,<~1 MB of base64>"}.
- The agent picks
writeFileContent and streams the whole payload as content.
- The call takes many minutes or never completes. No size warning at any point.
Additional Information
- Operating System: macOS 26.6.2
- Theia Version: 1.75.0
Bug Description:
getFileContentcaps its result atai-features.workspaceFunctions.fileContentMaxSizeKB(default 256 KB). The whole-file write tools —writeFileContentandsuggestFileContentinpackages/ai-ide/src/browser/file-changeset-functions.ts— have no equivalent guard.So the agent is refused a 2 MB read but will accept a 2 MB write. These tools require the model to emit the COMPLETE content as tool-call arguments, so cost scales with file size in output tokens. Base64 is the worst case: it tokenizes at ~3 chars/token, so ~1 MB of base64 is ~350K output tokens, past most models' max output.
A single huge argument value is also expensive downstream: the content is retained ~4x (
targetState,_originalContent, the tool call's_arguments, the Monaco buffer); a base64 value makes the file effectively one enormous line, which is the pathological case for Monaco; session autosave re-serializes it every ≤5 s while it streams; and it is re-uploaded in history on every later turn.Suggested fix: a size guard mirroring the read side — reject or warn above a configurable limit and point the model at
writeFileReplacements.Steps to Reproduce:
{"name": "logo", "data": "data:image/png;base64,<~1 MB of base64>"}.writeFileContentand streams the whole payload ascontent.Additional Information