editChunkExtractor.ts ×5

Frontier kind: Code frontier

unlabeled · c_f6322c619c2f

1063 tests · 3475 LOC · 19 files · introduces 0 tests · 97 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
5 ranges97 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
485 ranges3475 lines · 19 files · Browse complete extent
All tests (intent)
1063 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 97 introduced LOC across 5 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/shared/editChunkExtractor.ts 97 introduced LOC · 5 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- editChunkExtractor.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > /*
7 > * Extracts the explicit AI-written text chunks from a file-edit tool's
8 > * input payload. Both Claude (via @anthropic-ai/claude-agent-sdk) and
9 > * Copilot CLI (via @github/copilot-sdk) accept canonical tool schemas
10 > * whose shapes we can read structurally — Claude uses PascalCase names
11 > * (`Write`, `Edit`, `MultiEdit`) with `_string` fields, Copilot uses
12 > * snake_case (`create`, `edit`, `str_replace`, `insert`,
13 > * `str_replace_editor` command-dispatched, `apply_patch` /
14 > * `git_apply_patch` V4A patch body) with `_str` / `file_text` fields.
15 > *
16 > * Returning an empty array means "we couldn't read this — fall back to
17 > * whole-file scoring." Defensive against malformed SDK input: every
18 > * branch checks the value shape before reading.
19 > *
20 > * Coverage invariant: every tool the agent host currently treats as a
21 > * file-edit tool (`isClaudeFileEditTool`, `isEditTool` in Copilot) has
22 > * a matching case below — so in practice every edit gets chunked
23 > * scoring. The whole-file fallback is a safety net for SDK shape drift
24 > * (a tool input changes shape) and for newly added tools (a new edit
25 > * tool added to one of those gates without a matching case here). If
26 > * you add a new file-edit tool to either gate, add a case here too so
27 > * the survival reporter keeps producing chunked scores.
28 > */
29 >
30 > /**
31 > * Returns the AI-written text chunks for a known file-edit tool, or
32 > * `[]` if the tool / input shape is not recognised. Callers should
33 > * treat `[]` as "fall back to whole-file scoring."
34 > *
35 > * Supported Claude SDK tools (one file per call):
36 > * - `Write { content }` → `[content]`
37 > * - `Edit { new_string }` → `[new_string]`
38 > * - `MultiEdit { edits: [{ new_string }] }` → one chunk per edit
39 > *
40 > * Supported Copilot CLI tools (one file per call unless noted):
41 > * - `create { file_text }` → `[file_text]`
42 > * - `edit`, `str_replace { new_str }` → `[new_str]`
43 > * - `insert { new_str }` → `[new_str]`
44 > * - `str_replace_editor { command, ... }` → dispatch on command
45 > * - `apply_patch`, `git_apply_patch` → `+` lines from the
46 > * V4A patch body, scoped to {@link forFilePath} when supplied
47 > * (the patch may touch multiple files; we only want chunks for
48 > * the file we're sampling).
49 > *
50 > * `NotebookEdit` is not handled here: the reporter currently skips
51 > * `.ipynb` files at launch time, so notebook tool inputs never reach
52 > * the survival math. Add a branch here if we extend tracking to
53 > * notebooks.
54 > *
55 > * @param toolName Tool identifier (Claude PascalCase or Copilot
56 > * snake_case; tools we don't recognise just return `[]`).
57 > * @param input The tool input. May be `unknown`, a JSON object,
58 > * or — for `apply_patch` — a bare V4A patch string. Defensive
59 > * against all three.
60 > * @param forFilePath Optional. When supplied and the tool is a
61 > * multi-file patch (`apply_patch` / `git_apply_patch`), only the
62 > * `+` lines under that file's header contribute. Single-file tools
63 > * ignore this argument.
64 > */
65 > export function extractAiChunks(toolName: string, input: unknown, forFilePath?: string): string[] {
66 switch (toolName) {
67 // ---- Claude SDK -------------------------------------------------
90 }
91 }
93 function readStringField(input: unknown, field: string): string[] {
94 if (typeof input !== 'object' || input === null) {
98 return typeof value === 'string' ? [value] : [];
99 }
101 function readMultiEdit(input: unknown, field: string): string[] {
102 if (typeof input !== 'object' || input === null) {
118 return chunks;
119 }
121 > /**
122 > * `str_replace_editor` dispatches on `command`. We extract chunks per
123 > * command type — `view` and `undo_edit` produce no chunks.
124 > */
125 function readStrReplaceEditor(input: unknown): string[] {
126 if (typeof input !== 'object' || input === null) {
138 }
139 }
141 > /**
142 > * Headers of the V4A patch format the Copilot `apply_patch` tool
143 > * accepts. Mirrors {@link copilotToolDisplay.APPLY_PATCH_FILE_HEADERS};
144 > * kept duplicated here so this module stays free of cross-provider
145 > * imports.
146 > */
147 > const APPLY_PATCH_FILE_HEADERS = [
148 > /^\s*\*\*\*\s+Update File:\s*(.+?)\s*$/,
149 > /^\s*\*\*\*\s+Add File:\s*(.+?)\s*$/,
150 > /^\s*\*\*\*\s+Delete File:\s*(.+?)\s*$/,
151 > /^\s*\*\*\*\s+Move to:\s*(.+?)\s*$/,
152 > ];
153 >
154 > /**
155 > * Extracts the AI-written additions from a V4A patch body, grouped by
156 > * the file header that introduced them. When `forFilePath` is set,
157 > * only that file's additions are returned (joined into a single
158 > * chunk); otherwise every file's additions are returned, in document
159 > * order.
160 > *
161 > * The Copilot SDK delivers `apply_patch` with `arguments` as a raw
162 > * patch string (custom tool format), not as a JSON object, so the
163 > * string fallback is the common case for apply_patch.
164 > */
165 function readApplyPatch(input: unknown, forFilePath?: string): string[] {
166 let text: string | undefined;