@github/copilot-sdk 0.1.33-preview.3 → 0.1.33-preview.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -208,6 +208,10 @@ export type SessionEvent = {
208
208
  * GitHub request tracing ID (x-github-request-id header) for correlating with server-side logs
209
209
  */
210
210
  providerCallId?: string;
211
+ /**
212
+ * Optional URL associated with this error that the user can open in a browser
213
+ */
214
+ url?: string;
211
215
  };
212
216
  } | {
213
217
  /**
@@ -318,6 +322,10 @@ export type SessionEvent = {
318
322
  * Human-readable informational message for display in the timeline
319
323
  */
320
324
  message: string;
325
+ /**
326
+ * Optional URL associated with this message that the user can open in a browser
327
+ */
328
+ url?: string;
321
329
  };
322
330
  } | {
323
331
  /**
@@ -349,6 +357,10 @@ export type SessionEvent = {
349
357
  * Human-readable warning message for display in the timeline
350
358
  */
351
359
  message: string;
360
+ /**
361
+ * Optional URL associated with this warning that the user can open in a browser
362
+ */
363
+ url?: string;
352
364
  };
353
365
  } | {
354
366
  /**
@@ -725,6 +737,22 @@ export type SessionEvent = {
725
737
  * Model that was selected at the time of shutdown
726
738
  */
727
739
  currentModel?: string;
740
+ /**
741
+ * Total tokens in context window at shutdown
742
+ */
743
+ currentTokens?: number;
744
+ /**
745
+ * System message token count at shutdown
746
+ */
747
+ systemTokens?: number;
748
+ /**
749
+ * Non-system message token count at shutdown
750
+ */
751
+ conversationTokens?: number;
752
+ /**
753
+ * Tool definitions token count at shutdown
754
+ */
755
+ toolDefinitionsTokens?: number;
728
756
  };
729
757
  } | {
730
758
  /**
@@ -808,6 +836,22 @@ export type SessionEvent = {
808
836
  * Current number of messages in the conversation
809
837
  */
810
838
  messagesLength: number;
839
+ /**
840
+ * Token count from system message(s)
841
+ */
842
+ systemTokens?: number;
843
+ /**
844
+ * Token count from non-system messages (user, assistant, tool)
845
+ */
846
+ conversationTokens?: number;
847
+ /**
848
+ * Token count from tool definitions
849
+ */
850
+ toolDefinitionsTokens?: number;
851
+ /**
852
+ * Whether this is the first usage_info event emitted in this session
853
+ */
854
+ isInitial?: boolean;
811
855
  };
812
856
  } | {
813
857
  /**
@@ -828,9 +872,22 @@ export type SessionEvent = {
828
872
  ephemeral?: boolean;
829
873
  type: "session.compaction_start";
830
874
  /**
831
- * Empty payload; the event signals that LLM-powered conversation compaction has begun
875
+ * Context window breakdown at the start of LLM-powered conversation compaction
832
876
  */
833
- data: {};
877
+ data: {
878
+ /**
879
+ * Token count from system message(s) at compaction start
880
+ */
881
+ systemTokens?: number;
882
+ /**
883
+ * Token count from non-system messages (user, assistant, tool) at compaction start
884
+ */
885
+ conversationTokens?: number;
886
+ /**
887
+ * Token count from tool definitions at compaction start
888
+ */
889
+ toolDefinitionsTokens?: number;
890
+ };
834
891
  } | {
835
892
  /**
836
893
  * Unique event identifier (UUID v4), generated when the event is emitted
@@ -914,6 +971,18 @@ export type SessionEvent = {
914
971
  * GitHub request tracing ID (x-github-request-id header) for the compaction LLM call
915
972
  */
916
973
  requestId?: string;
974
+ /**
975
+ * Token count from system message(s) after compaction
976
+ */
977
+ systemTokens?: number;
978
+ /**
979
+ * Token count from non-system messages (user, assistant, tool) after compaction
980
+ */
981
+ conversationTokens?: number;
982
+ /**
983
+ * Token count from tool definitions after compaction
984
+ */
985
+ toolDefinitionsTokens?: number;
917
986
  };
918
987
  } | {
919
988
  /**
@@ -934,13 +1003,17 @@ export type SessionEvent = {
934
1003
  ephemeral?: boolean;
935
1004
  type: "session.task_complete";
936
1005
  /**
937
- * Task completion notification with optional summary from the agent
1006
+ * Task completion notification with summary from the agent
938
1007
  */
939
1008
  data: {
940
1009
  /**
941
- * Optional summary of the completed task, provided by the agent
1010
+ * Summary of the completed task, provided by the agent
942
1011
  */
943
1012
  summary?: string;
1013
+ /**
1014
+ * Whether the tool call succeeded. False when validation failed (e.g., invalid arguments)
1015
+ */
1016
+ success?: boolean;
944
1017
  };
945
1018
  } | {
946
1019
  /**
@@ -960,9 +1033,6 @@ export type SessionEvent = {
960
1033
  */
961
1034
  ephemeral?: boolean;
962
1035
  type: "user.message";
963
- /**
964
- * User message content with optional attachments, source information, and interaction metadata
965
- */
966
1036
  data: {
967
1037
  /**
968
1038
  * The user's message text as displayed in the timeline
@@ -1106,9 +1176,9 @@ export type SessionEvent = {
1106
1176
  displayName?: string;
1107
1177
  })[];
1108
1178
  /**
1109
- * Origin of this message, used for timeline filtering and telemetry (e.g., "user", "autopilot", "skill", or "command")
1179
+ * Origin of this message, used for timeline filtering (e.g., "skill-pdf" for skill-injected messages that should be hidden from the user)
1110
1180
  */
1111
- source?: "user" | "autopilot" | "skill" | "system" | "command" | "immediate-prompt" | "jit-instruction" | "snippy-blocking" | "thinking-exhausted-continuation" | "other";
1181
+ source?: string;
1112
1182
  /**
1113
1183
  * The agent mode that was active when this message was sent
1114
1184
  */
@@ -2359,6 +2429,20 @@ export type SessionEvent = {
2359
2429
  * The full prompt given to the background agent
2360
2430
  */
2361
2431
  prompt?: string;
2432
+ } | {
2433
+ type: "agent_idle";
2434
+ /**
2435
+ * Unique identifier of the background agent
2436
+ */
2437
+ agentId: string;
2438
+ /**
2439
+ * Type of the agent (e.g., explore, task, general-purpose)
2440
+ */
2441
+ agentType: string;
2442
+ /**
2443
+ * Human-readable description of the agent task
2444
+ */
2445
+ description?: string;
2362
2446
  } | {
2363
2447
  type: "shell_completed";
2364
2448
  /**
@@ -2693,6 +2777,10 @@ export type SessionEvent = {
2693
2777
  * Whether the user can provide a free-form text response in addition to predefined choices
2694
2778
  */
2695
2779
  allowFreeform?: boolean;
2780
+ /**
2781
+ * The LLM-assigned tool call ID that triggered this request; used by remote UIs to correlate responses
2782
+ */
2783
+ toolCallId?: string;
2696
2784
  };
2697
2785
  } | {
2698
2786
  /**
@@ -2734,25 +2822,33 @@ export type SessionEvent = {
2734
2822
  ephemeral: true;
2735
2823
  type: "elicitation.requested";
2736
2824
  /**
2737
- * Structured form elicitation request with JSON schema definition for form fields
2825
+ * Elicitation request; may be form-based (structured input) or URL-based (browser redirect)
2738
2826
  */
2739
2827
  data: {
2740
2828
  /**
2741
2829
  * Unique identifier for this elicitation request; used to respond via session.respondToElicitation()
2742
2830
  */
2743
2831
  requestId: string;
2832
+ /**
2833
+ * Tool call ID from the LLM completion; used to correlate with CompletionChunk.toolCall.id for remote UIs
2834
+ */
2835
+ toolCallId?: string;
2836
+ /**
2837
+ * The source that initiated the request (MCP server name, or absent for agent-initiated)
2838
+ */
2839
+ elicitationSource?: string;
2744
2840
  /**
2745
2841
  * Message describing what information is needed from the user
2746
2842
  */
2747
2843
  message: string;
2748
2844
  /**
2749
- * Elicitation mode; currently only "form" is supported. Defaults to "form" when absent.
2845
+ * Elicitation mode; "form" for structured input, "url" for browser-based. Defaults to "form" when absent.
2750
2846
  */
2751
- mode?: "form";
2847
+ mode?: "form" | "url";
2752
2848
  /**
2753
- * JSON Schema describing the form fields to present to the user
2849
+ * JSON Schema describing the form fields to present to the user (form mode only)
2754
2850
  */
2755
- requestedSchema: {
2851
+ requestedSchema?: {
2756
2852
  /**
2757
2853
  * Schema type indicator (always 'object')
2758
2854
  */
@@ -2768,6 +2864,10 @@ export type SessionEvent = {
2768
2864
  */
2769
2865
  required?: string[];
2770
2866
  };
2867
+ /**
2868
+ * URL to open in the user's browser (url mode only)
2869
+ */
2870
+ url?: string;
2771
2871
  [k: string]: unknown;
2772
2872
  };
2773
2873
  } | {
@@ -2794,6 +2894,75 @@ export type SessionEvent = {
2794
2894
  */
2795
2895
  requestId: string;
2796
2896
  };
2897
+ } | {
2898
+ /**
2899
+ * Unique event identifier (UUID v4), generated when the event is emitted
2900
+ */
2901
+ id: string;
2902
+ /**
2903
+ * ISO 8601 timestamp when the event was created
2904
+ */
2905
+ timestamp: string;
2906
+ /**
2907
+ * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event.
2908
+ */
2909
+ parentId: string | null;
2910
+ ephemeral: true;
2911
+ type: "mcp.oauth_required";
2912
+ /**
2913
+ * OAuth authentication request for an MCP server
2914
+ */
2915
+ data: {
2916
+ /**
2917
+ * Unique identifier for this OAuth request; used to respond via session.respondToMcpOAuth()
2918
+ */
2919
+ requestId: string;
2920
+ /**
2921
+ * Display name of the MCP server that requires OAuth
2922
+ */
2923
+ serverName: string;
2924
+ /**
2925
+ * URL of the MCP server that requires OAuth
2926
+ */
2927
+ serverUrl: string;
2928
+ /**
2929
+ * Static OAuth client configuration, if the server specifies one
2930
+ */
2931
+ staticClientConfig?: {
2932
+ /**
2933
+ * OAuth client ID for the server
2934
+ */
2935
+ clientId: string;
2936
+ /**
2937
+ * Whether this is a public OAuth client
2938
+ */
2939
+ publicClient?: boolean;
2940
+ };
2941
+ };
2942
+ } | {
2943
+ /**
2944
+ * Unique event identifier (UUID v4), generated when the event is emitted
2945
+ */
2946
+ id: string;
2947
+ /**
2948
+ * ISO 8601 timestamp when the event was created
2949
+ */
2950
+ timestamp: string;
2951
+ /**
2952
+ * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event.
2953
+ */
2954
+ parentId: string | null;
2955
+ ephemeral: true;
2956
+ type: "mcp.oauth_completed";
2957
+ /**
2958
+ * MCP OAuth request completion notification
2959
+ */
2960
+ data: {
2961
+ /**
2962
+ * Request ID of the resolved OAuth request
2963
+ */
2964
+ requestId: string;
2965
+ };
2797
2966
  } | {
2798
2967
  /**
2799
2968
  * Unique event identifier (UUID v4), generated when the event is emitted
@@ -2896,6 +3065,42 @@ export type SessionEvent = {
2896
3065
  */
2897
3066
  command: string;
2898
3067
  };
3068
+ } | {
3069
+ /**
3070
+ * Unique event identifier (UUID v4), generated when the event is emitted
3071
+ */
3072
+ id: string;
3073
+ /**
3074
+ * ISO 8601 timestamp when the event was created
3075
+ */
3076
+ timestamp: string;
3077
+ /**
3078
+ * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event.
3079
+ */
3080
+ parentId: string | null;
3081
+ ephemeral: true;
3082
+ type: "command.execute";
3083
+ /**
3084
+ * Registered command dispatch request routed to the owning client
3085
+ */
3086
+ data: {
3087
+ /**
3088
+ * Unique identifier; used to respond via session.commands.handlePendingCommand()
3089
+ */
3090
+ requestId: string;
3091
+ /**
3092
+ * The full command text (e.g., /deploy production)
3093
+ */
3094
+ command: string;
3095
+ /**
3096
+ * Command name without leading /
3097
+ */
3098
+ commandName: string;
3099
+ /**
3100
+ * Raw argument string after the command name
3101
+ */
3102
+ args: string;
3103
+ };
2899
3104
  } | {
2900
3105
  /**
2901
3106
  * Unique event identifier (UUID v4), generated when the event is emitted
@@ -2920,6 +3125,33 @@ export type SessionEvent = {
2920
3125
  */
2921
3126
  requestId: string;
2922
3127
  };
3128
+ } | {
3129
+ /**
3130
+ * Unique event identifier (UUID v4), generated when the event is emitted
3131
+ */
3132
+ id: string;
3133
+ /**
3134
+ * ISO 8601 timestamp when the event was created
3135
+ */
3136
+ timestamp: string;
3137
+ /**
3138
+ * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event.
3139
+ */
3140
+ parentId: string | null;
3141
+ ephemeral: true;
3142
+ type: "commands.changed";
3143
+ /**
3144
+ * SDK command registration change notification
3145
+ */
3146
+ data: {
3147
+ /**
3148
+ * Current list of registered SDK commands
3149
+ */
3150
+ commands: {
3151
+ name: string;
3152
+ description?: string;
3153
+ }[];
3154
+ };
2923
3155
  } | {
2924
3156
  /**
2925
3157
  * Unique event identifier (UUID v4), generated when the event is emitted
@@ -3018,4 +3250,151 @@ export type SessionEvent = {
3018
3250
  ephemeral: true;
3019
3251
  type: "session.background_tasks_changed";
3020
3252
  data: {};
3253
+ } | {
3254
+ /**
3255
+ * Unique event identifier (UUID v4), generated when the event is emitted
3256
+ */
3257
+ id: string;
3258
+ /**
3259
+ * ISO 8601 timestamp when the event was created
3260
+ */
3261
+ timestamp: string;
3262
+ /**
3263
+ * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event.
3264
+ */
3265
+ parentId: string | null;
3266
+ ephemeral: true;
3267
+ type: "session.skills_loaded";
3268
+ data: {
3269
+ /**
3270
+ * Array of resolved skill metadata
3271
+ */
3272
+ skills: {
3273
+ /**
3274
+ * Unique identifier for the skill
3275
+ */
3276
+ name: string;
3277
+ /**
3278
+ * Description of what the skill does
3279
+ */
3280
+ description: string;
3281
+ /**
3282
+ * Source location type of the skill (e.g., project, personal, plugin)
3283
+ */
3284
+ source: string;
3285
+ /**
3286
+ * Whether the skill can be invoked by the user as a slash command
3287
+ */
3288
+ userInvocable: boolean;
3289
+ /**
3290
+ * Whether the skill is currently enabled
3291
+ */
3292
+ enabled: boolean;
3293
+ /**
3294
+ * Absolute path to the skill file, if available
3295
+ */
3296
+ path?: string;
3297
+ }[];
3298
+ };
3299
+ } | {
3300
+ /**
3301
+ * Unique event identifier (UUID v4), generated when the event is emitted
3302
+ */
3303
+ id: string;
3304
+ /**
3305
+ * ISO 8601 timestamp when the event was created
3306
+ */
3307
+ timestamp: string;
3308
+ /**
3309
+ * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event.
3310
+ */
3311
+ parentId: string | null;
3312
+ ephemeral: true;
3313
+ type: "session.mcp_servers_loaded";
3314
+ data: {
3315
+ /**
3316
+ * Array of MCP server status summaries
3317
+ */
3318
+ servers: {
3319
+ /**
3320
+ * Server name (config key)
3321
+ */
3322
+ name: string;
3323
+ /**
3324
+ * Connection status: connected, failed, pending, disabled, or not_configured
3325
+ */
3326
+ status: "connected" | "failed" | "pending" | "disabled" | "not_configured";
3327
+ /**
3328
+ * Configuration source: user, workspace, plugin, or builtin
3329
+ */
3330
+ source?: string;
3331
+ /**
3332
+ * Error message if the server failed to connect
3333
+ */
3334
+ error?: string;
3335
+ }[];
3336
+ };
3337
+ } | {
3338
+ /**
3339
+ * Unique event identifier (UUID v4), generated when the event is emitted
3340
+ */
3341
+ id: string;
3342
+ /**
3343
+ * ISO 8601 timestamp when the event was created
3344
+ */
3345
+ timestamp: string;
3346
+ /**
3347
+ * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event.
3348
+ */
3349
+ parentId: string | null;
3350
+ ephemeral: true;
3351
+ type: "session.mcp_server_status_changed";
3352
+ data: {
3353
+ /**
3354
+ * Name of the MCP server whose status changed
3355
+ */
3356
+ serverName: string;
3357
+ /**
3358
+ * New connection status: connected, failed, pending, disabled, or not_configured
3359
+ */
3360
+ status: "connected" | "failed" | "pending" | "disabled" | "not_configured";
3361
+ };
3362
+ } | {
3363
+ /**
3364
+ * Unique event identifier (UUID v4), generated when the event is emitted
3365
+ */
3366
+ id: string;
3367
+ /**
3368
+ * ISO 8601 timestamp when the event was created
3369
+ */
3370
+ timestamp: string;
3371
+ /**
3372
+ * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event.
3373
+ */
3374
+ parentId: string | null;
3375
+ ephemeral: true;
3376
+ type: "session.extensions_loaded";
3377
+ data: {
3378
+ /**
3379
+ * Array of discovered extensions and their status
3380
+ */
3381
+ extensions: {
3382
+ /**
3383
+ * Source-qualified extension ID (e.g., 'project:my-ext', 'user:auth-helper')
3384
+ */
3385
+ id: string;
3386
+ /**
3387
+ * Extension name (directory name)
3388
+ */
3389
+ name: string;
3390
+ /**
3391
+ * Discovery source
3392
+ */
3393
+ source: "project" | "user";
3394
+ /**
3395
+ * Current status: running, disabled, failed, or starting
3396
+ */
3397
+ status: "running" | "disabled" | "failed" | "starting";
3398
+ }[];
3399
+ };
3021
3400
  };
package/dist/index.d.ts CHANGED
@@ -5,5 +5,5 @@
5
5
  */
6
6
  export { CopilotClient } from "./client.js";
7
7
  export { CopilotSession, type AssistantMessageEvent } from "./session.js";
8
- export { defineTool, approveAll } from "./types.js";
9
- export type { ConnectionState, CopilotClientOptions, CustomAgentConfig, ForegroundSessionInfo, GetAuthStatusResponse, GetStatusResponse, InfiniteSessionConfig, MCPLocalServerConfig, MCPRemoteServerConfig, MCPServerConfig, MessageOptions, ModelBilling, ModelCapabilities, ModelInfo, ModelPolicy, PermissionHandler, PermissionRequest, PermissionRequestResult, ResumeSessionConfig, SessionConfig, SessionEvent, SessionEventHandler, SessionEventPayload, SessionEventType, SessionLifecycleEvent, SessionLifecycleEventType, SessionLifecycleHandler, SessionContext, SessionListFilter, SessionMetadata, SystemMessageAppendConfig, SystemMessageConfig, SystemMessageReplaceConfig, TelemetryConfig, TraceContext, TraceContextProvider, Tool, ToolHandler, ToolInvocation, ToolResultObject, TypedSessionEventHandler, TypedSessionLifecycleHandler, ZodSchema, } from "./types.js";
8
+ export { defineTool, approveAll, SYSTEM_PROMPT_SECTIONS } from "./types.js";
9
+ export type { ConnectionState, CopilotClientOptions, CustomAgentConfig, ForegroundSessionInfo, GetAuthStatusResponse, GetStatusResponse, InfiniteSessionConfig, MCPLocalServerConfig, MCPRemoteServerConfig, MCPServerConfig, MessageOptions, ModelBilling, ModelCapabilities, ModelInfo, ModelPolicy, PermissionHandler, PermissionRequest, PermissionRequestResult, ResumeSessionConfig, SectionOverride, SectionOverrideAction, SectionTransformFn, SessionConfig, SessionEvent, SessionEventHandler, SessionEventPayload, SessionEventType, SessionLifecycleEvent, SessionLifecycleEventType, SessionLifecycleHandler, SessionContext, SessionListFilter, SessionMetadata, SystemMessageAppendConfig, SystemMessageConfig, SystemMessageCustomizeConfig, SystemMessageReplaceConfig, SystemPromptSection, TelemetryConfig, TraceContext, TraceContextProvider, Tool, ToolHandler, ToolInvocation, ToolResultObject, TypedSessionEventHandler, TypedSessionLifecycleHandler, ZodSchema, } from "./types.js";
package/dist/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import { CopilotClient } from "./client.js";
2
2
  import { CopilotSession } from "./session.js";
3
- import { defineTool, approveAll } from "./types.js";
3
+ import { defineTool, approveAll, SYSTEM_PROMPT_SECTIONS } from "./types.js";
4
4
  export {
5
5
  CopilotClient,
6
6
  CopilotSession,
7
+ SYSTEM_PROMPT_SECTIONS,
7
8
  approveAll,
8
9
  defineTool
9
10
  };
package/dist/session.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import type { MessageConnection } from "vscode-jsonrpc/node.js";
6
6
  import { createSessionRpc } from "./generated/rpc.js";
7
- import type { MessageOptions, PermissionHandler, PermissionRequestResult, ReasoningEffort, SessionEvent, SessionEventHandler, SessionEventType, SessionHooks, Tool, ToolHandler, TraceContextProvider, TypedSessionEventHandler, UserInputHandler, UserInputResponse } from "./types.js";
7
+ import type { MessageOptions, PermissionHandler, PermissionRequestResult, ReasoningEffort, SectionTransformFn, SessionEvent, SessionEventHandler, SessionEventType, SessionHooks, Tool, ToolHandler, TraceContextProvider, TypedSessionEventHandler, UserInputHandler, UserInputResponse } from "./types.js";
8
8
  export declare const NO_RESULT_PERMISSION_V2_ERROR = "Permission handlers cannot return 'no-result' when connected to a protocol v2 server.";
9
9
  /** Assistant message event - the final response from the assistant. */
10
10
  export type AssistantMessageEvent = Extract<SessionEvent, {
@@ -45,6 +45,7 @@ export declare class CopilotSession {
45
45
  private permissionHandler?;
46
46
  private userInputHandler?;
47
47
  private hooks?;
48
+ private transformCallbacks?;
48
49
  private _rpc;
49
50
  private traceContextProvider?;
50
51
  /**
@@ -229,6 +230,28 @@ export declare class CopilotSession {
229
230
  * @internal This method is typically called internally when creating a session.
230
231
  */
231
232
  registerHooks(hooks?: SessionHooks): void;
233
+ /**
234
+ * Registers transform callbacks for system message sections.
235
+ *
236
+ * @param callbacks - Map of section ID to transform callback, or undefined to clear
237
+ * @internal This method is typically called internally when creating a session.
238
+ */
239
+ registerTransformCallbacks(callbacks?: Map<string, SectionTransformFn>): void;
240
+ /**
241
+ * Handles a systemMessage.transform request from the runtime.
242
+ * Dispatches each section to its registered transform callback.
243
+ *
244
+ * @param sections - Map of section IDs to their current rendered content
245
+ * @returns A promise that resolves with the transformed sections
246
+ * @internal This method is for internal use by the SDK.
247
+ */
248
+ _handleSystemMessageTransform(sections: Record<string, {
249
+ content: string;
250
+ }>): Promise<{
251
+ sections: Record<string, {
252
+ content: string;
253
+ }>;
254
+ }>;
232
255
  /**
233
256
  * Handles a permission request in the v2 protocol format (synchronous RPC).
234
257
  * Used as a back-compat adapter when connected to a v2 server.
package/dist/session.js CHANGED
@@ -24,6 +24,7 @@ class CopilotSession {
24
24
  permissionHandler;
25
25
  userInputHandler;
26
26
  hooks;
27
+ transformCallbacks;
27
28
  _rpc = null;
28
29
  traceContextProvider;
29
30
  /**
@@ -340,6 +341,40 @@ class CopilotSession {
340
341
  registerHooks(hooks) {
341
342
  this.hooks = hooks;
342
343
  }
344
+ /**
345
+ * Registers transform callbacks for system message sections.
346
+ *
347
+ * @param callbacks - Map of section ID to transform callback, or undefined to clear
348
+ * @internal This method is typically called internally when creating a session.
349
+ */
350
+ registerTransformCallbacks(callbacks) {
351
+ this.transformCallbacks = callbacks;
352
+ }
353
+ /**
354
+ * Handles a systemMessage.transform request from the runtime.
355
+ * Dispatches each section to its registered transform callback.
356
+ *
357
+ * @param sections - Map of section IDs to their current rendered content
358
+ * @returns A promise that resolves with the transformed sections
359
+ * @internal This method is for internal use by the SDK.
360
+ */
361
+ async _handleSystemMessageTransform(sections) {
362
+ const result = {};
363
+ for (const [sectionId, { content }] of Object.entries(sections)) {
364
+ const callback = this.transformCallbacks?.get(sectionId);
365
+ if (callback) {
366
+ try {
367
+ const transformed = await callback(content);
368
+ result[sectionId] = { content: transformed };
369
+ } catch (_error) {
370
+ result[sectionId] = { content };
371
+ }
372
+ } else {
373
+ result[sectionId] = { content };
374
+ }
375
+ }
376
+ return { sections: result };
377
+ }
343
378
  /**
344
379
  * Handles a permission request in the v2 protocol format (synchronous RPC).
345
380
  * Used as a back-compat adapter when connected to a v2 server.