1
>
/*---------------------------------------------------------------------------------------------
buildSessionEvents.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
>
import type { SessionEvent } from '@github/copilot-sdk';
7
>
import { generateUuid, isUUID } from '../../../../base/common/uuid.js';
8
>
import { ResponsePartKind, ToolCallStatus, ToolResultContentType, TurnState, type ToolCallCompletedState, type ToolResultContent, type ToolResultSubagentContent, type Turn } from '../../common/state/sessionState.js';
9
>
10
>
/**
11
>
* Default schema version stamped on the synthesized `session.start` event.
12
>
*
13
>
* The Copilot SDK owns the authoritative event-format schema version; this
14
>
* value is only meaningful when the resulting `events.jsonl` is actually
15
>
* resumed by a CLI. It is irrelevant to the reconstruction performed by
16
>
* {@link mapSessionEvents} (which ignores it), so unit tests can rely on the
17
>
* default. Callers that write a log for real resume SHOULD pass the version the
18
>
* target CLI expects.
19
>
*/
20
>
const DEFAULT_SESSION_EVENT_SCHEMA_VERSION = 1;
21
>
22
>
/**
23
>
* Producer identifier stamped on the synthesized `session.start` event so a
24
>
* migrated event log is attributable to this translation path rather than a
25
>
* genuine agent run.
26
>
*/
27
>
const MIGRATION_PRODUCER = 'vscode-copilot-migration';
28
>
29
>
/**
30
>
* Options controlling how {@link buildSessionEventsFromTurns} synthesizes a
31
>
* Copilot SDK event log from VS Code turns.
32
>
*/
33
>
export interface IBuildSessionEventsOptions {
34
>
/** The target session id (stamped on the `session.start` event). */
35
>
readonly sessionId: string;
36
>
/** Working directory of the session, recorded on `session.start` context. */
37
>
readonly workingDirectory?: string;
38
>
/** Model id to attribute the synthesized assistant messages to, if known. */
39
>
readonly model?: string;
40
>
/** Copilot application version string for `session.start`. Defaults to `0.0.0`. */
41
>
readonly copilotVersion?: string;
42
>
/** Event-format schema version for `session.start`. See {@link DEFAULT_SESSION_EVENT_SCHEMA_VERSION}. */
43
>
readonly schemaVersion?: number;
44
>
/** Base time for the synthesized (monotonically increasing) event timestamps. Defaults to now. */
45
>
readonly startTime?: Date;
46
>
}
47
>
48
>
/**
49
>
* Translates a sequence of VS Code {@link Turn}s into a Copilot SDK
50
>
* {@link SessionEvent} log (the on-disk `events.jsonl` shape), reversing the
51
>
* reconstruction performed by `mapSessionEvents`.
52
>
*
53
>
* The result is a valid parent-linked event chain: a leading `session.start`
54
>
* followed, per turn, by a `user.message` and the turn's response emitted in
55
>
* order — assistant markdown/reasoning as `assistant.message` events and each
56
>
* completed tool call as a `tool.execution_start` + `tool.execution_complete`
57
>
* pair (preceded by a `subagent.started` when the tool call carries sub-agent
58
>
* content, so the sub-agent name/description survive a resume). Assistant text
59
>
* accumulated before a tool call is flushed as its own `assistant.message` so
60
>
* the reconstructed part order matches the original.
61
>
*
62
>
* Every event envelope id must be a UUID (the Copilot runtime rejects non-UUID
63
>
* event ids). A turn whose {@link Turn.id} is already a UUID reuses it as the
64
>
* `user.message` envelope id, so the reconstructed turn keeps the same id the
65
>
* SDK's fork / truncate RPCs address and the caller can seed matching protocol
66
>
* turns; a non-UUID id is replaced with a minted UUID.
67
>
*
68
>
* Only completed tool calls are translated; streaming / pending tool states and
69
>
* file-edit content (which lives in the session database) are not yet emitted.
70
>
* A cancelled turn ({@link TurnState.Cancelled}) emits a trailing `abort` event
71
>
* so it reconstructs as cancelled. Content refs and system notifications are
72
>
* skipped.
73
>
*/
74
>
export function buildSessionEventsFromTurns(turns: readonly Turn[], options: IBuildSessionEventsOptions): SessionEvent[] {
75
const events: SessionEvent[] = [];
76
let parentId: string | null = null;