mapSessionEvents.ts ×11

Frontier kind: Code frontier

unlabeled · c_bb893b49821c

39 tests · 32722 LOC · 175 files · introduces 0 tests · 72 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
11 ranges72 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
2739 ranges32722 lines · 175 files · Browse complete extent
All tests (intent)
39 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: 72 introduced LOC across 11 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/copilot/mapSessionEvents.ts 72 introduced LOC · 11 ranges

Open complete file

241 * commands so clients see the simplified form.
242 */
243 > export async function mapSessionEvents( mapSessionEvents.ts
244 > session: URI,
245 > db: ISessionDatabase | undefined,
246 > events: readonly SessionEvent[],
247 > options: URI | IMapSessionEventsOptions | undefined = undefined,
248 > ): Promise<{ turns: Turn[]; subagentTurnsByToolCallId: ReadonlyMap<string, Turn[]> }> {
249 > const workingDirectory = options instanceof URI ? options : options?.workingDirectory;
250 > let currentModel = options instanceof URI ? undefined : options?.model;
251 > let currentAgent = options instanceof URI ? undefined : options?.agent;
252 > // First pass: collect tool-arg info and identify edit tool calls so we
253 > // can batch-load their stored file edits before the second pass needs
254 > // them at `tool.execution_complete` time. We also build the
255 > // `agentId` -> parent tool call id map here so the second pass can route
256 > // sub-agent events without depending on event ordering.
257 > const toolInfoByCallId = new Map<string, IToolStartInfo>();
258 > const editToolCallIds: string[] = [];
259 > const completionsByCallId = new Map<string, ToolExecutionCompleteData>();
260 >
261 > // The SDK tags events that originate from a sub-agent with an
262 > // envelope-level `agentId` (the deprecated `data.parentToolCallId` is no
263 > // longer populated). `subagent.started` carries both the sub-agent's
264 > // `agentId` and the parent tool call id it was spawned from, so we map
265 > // one to the other and resolve every later sub-agent event through it.
266 > const parentToolCallIdByAgentId = new Map<string, string>();
267 > const resolveParentToolCallId = (agentId: string | undefined, deprecatedParentToolCallId: string | undefined): string | undefined => {
268 const mapped = agentId ? parentToolCallIdByAgentId.get(agentId) : undefined;
269 return mapped ?? deprecatedParentToolCallId;
270 };
272 > for (const e of events) {
273 if (e.type === 'subagent.started') {
274 if (e.agentId) {
293 }
294 }
296 > // Pre-load stored file-edit metadata for all edit tool calls.
297 > let storedEdits: Map<string, IFileEditRecord[]> | undefined;
298 > if (db && editToolCallIds.length > 0) {
299 try {
300 const records = await db.getFileEdits(editToolCallIds);
314 }
315 }
317 > const sessionUriStr = session.toString();
318 > const providerId = session.scheme;
319 > const rawSessionId = AgentSession.id(session);
320 > const turns: Turn[] = [];
321 >
322 > // Subagent state. Each subagent has its own active turn builder; only
323 > // the most recent turn per subagent is built (subagents currently emit
324 > // at most one turn per invocation).
325 > const subagentBuilders = new Map<string, ITurnBuilder>();
326 > const subagentTurnStates = new Map<string, TurnState>();
327 > const subagentTurns = new Map<string, Turn[]>();
328 > const subagentInfoByToolCallId = new Map<string, ISubagentInfo>();
329 >
330 > let parentBuilder: ITurnBuilder | undefined;
331 > let parentTurnState = TurnState.Cancelled;
332 > let parentTurnAborted = false;
333 > let rootAssistantTurnActive = false;
334 > let pendingAutoModeResolved: Extract<SessionEvent, { type: 'session.auto_mode_resolved' }>['data'] | undefined;
335 >
336 > const flushParent = (): void => {
337 > if (!parentBuilder) {
338 > return;
339 > }
340 turns.push(finalizeTurn(parentBuilder, parentTurnState));
341 parentBuilder = undefined;
342 parentTurnState = TurnState.Cancelled;
343 parentTurnAborted = false;
345 >
346 > const flushSubagent = (parentToolCallId: string): void => {
347 const builder = subagentBuilders.get(parentToolCallId);
348 if (!builder) {
360 subagentTurns.set(parentToolCallId, list);
361 };
363 > const ensureSubagentBuilder = (parentToolCallId: string): ITurnBuilder => {
364 let builder = subagentBuilders.get(parentToolCallId);
365 if (!builder) {
372 return builder;
373 };
375 > const targetBuilderFor = (parentToolCallId: string | undefined): ITurnBuilder | undefined => {
376 if (parentToolCallId) {
377 return ensureSubagentBuilder(parentToolCallId);
379 return parentBuilder;
380 };
382 > for (const e of events) {
383 switch (e.type) {
384 case 'assistant.turn_start':
604 }
605 }
607 > flushParent();
608 > for (const parentToolCallId of [...subagentBuilders.keys()]) {
609 flushSubagent(parentToolCallId);
610 }
612 > return { turns, subagentTurnsByToolCallId: subagentTurns };
613 >
614 > function appendFallbackToolRequests(builder: ITurnBuilder, toolRequests: readonly AssistantMessageToolRequest[], parentToolCallId: string | undefined): void {
615 for (const request of toolRequests) {
616 const completion = completionsByCallId.get(request.toolCallId);