Skip to content

ai-chat-ui: extractJsonStringField parses the full string before its regex fallback #17974

Description

@safisa

Bug Description:

extractJsonStringField in packages/ai-chat-ui/src/common/toolcall-utils.ts tries JSON.parse on the whole string first and only falls back to a regex when it throws:

try {
    const parsed = JSON.parse(json);
    ...
} catch {
    const regex = new RegExp('"' + fieldName + '"\\s*:\\s*"([^"]*)"?');
    return regex.exec(json)?.[1];
}

The fallback exists for streaming, where the arguments are truncated and therefore invalid JSON — so during streaming the parse always throws, and JSON.parse still scans the entire string before failing. It is called from getArgumentsLabel in the body of ToolCallContent (toolcall-part-renderer.tsx), i.e. on every render while the arguments grow, making the label quadratic in argument size.

Measured with 64-char deltas: 1 MB of arguments → ~7 s of CPU, 2 MB → ~27 s. Conflated tree updates bring this down in practice, but it is pure waste — the regex alone answers in microseconds.

Suggested fix: try the regex first and fall back to JSON.parse (or skip the parse when the string is not yet balanced).

Separately, the regex matches the first "<field>": "..." anywhere in the string, including inside a content value — writing a JSON file that itself has a "path" property shows the wrong label. Cosmetic, but wrong.

Steps to Reproduce:

  1. In agent mode, have the agent call writeFileContent with a multi-megabyte content argument (e.g. an embedded base64 image).
  2. Profile the frontend while the arguments stream in — JSON.parse under extractJsonStringField dominates.

Additional Information

  • Operating System: macOS 26.6.2
  • Theia Version: 1.75.0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugbugs found in the applicationtheia-aiissues related to TheiaAI

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions