@github/copilot-sdk 0.1.33-preview.2 → 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.
package/dist/session.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { ConnectionError, ResponseError } from "vscode-jsonrpc/node.js";
2
2
  import { createSessionRpc } from "./generated/rpc.js";
3
+ import { getTraceContext } from "./telemetry.js";
3
4
  const NO_RESULT_PERMISSION_V2_ERROR = "Permission handlers cannot return 'no-result' when connected to a protocol v2 server.";
4
5
  class CopilotSession {
5
6
  /**
@@ -8,12 +9,14 @@ class CopilotSession {
8
9
  * @param sessionId - The unique identifier for this session
9
10
  * @param connection - The JSON-RPC message connection to the Copilot CLI
10
11
  * @param workspacePath - Path to the session workspace directory (when infinite sessions enabled)
12
+ * @param traceContextProvider - Optional callback to get W3C Trace Context for outbound RPCs
11
13
  * @internal This constructor is internal. Use {@link CopilotClient.createSession} to create sessions.
12
14
  */
13
- constructor(sessionId, connection, _workspacePath) {
15
+ constructor(sessionId, connection, _workspacePath, traceContextProvider) {
14
16
  this.sessionId = sessionId;
15
17
  this.connection = connection;
16
18
  this._workspacePath = _workspacePath;
19
+ this.traceContextProvider = traceContextProvider;
17
20
  }
18
21
  eventHandlers = /* @__PURE__ */ new Set();
19
22
  typedEventHandlers = /* @__PURE__ */ new Map();
@@ -21,7 +24,9 @@ class CopilotSession {
21
24
  permissionHandler;
22
25
  userInputHandler;
23
26
  hooks;
27
+ transformCallbacks;
24
28
  _rpc = null;
29
+ traceContextProvider;
25
30
  /**
26
31
  * Typed session-scoped RPC methods.
27
32
  */
@@ -59,6 +64,7 @@ class CopilotSession {
59
64
  */
60
65
  async send(options) {
61
66
  const response = await this.connection.sendRequest("session.send", {
67
+ ...await getTraceContext(this.traceContextProvider),
62
68
  sessionId: this.sessionId,
63
69
  prompt: options.prompt,
64
70
  attachments: options.attachments,
@@ -188,9 +194,19 @@ class CopilotSession {
188
194
  const { requestId, toolName } = event.data;
189
195
  const args = event.data.arguments;
190
196
  const toolCallId = event.data.toolCallId;
197
+ const traceparent = event.data.traceparent;
198
+ const tracestate = event.data.tracestate;
191
199
  const handler = this.toolHandlers.get(toolName);
192
200
  if (handler) {
193
- void this._executeToolAndRespond(requestId, toolName, toolCallId, args, handler);
201
+ void this._executeToolAndRespond(
202
+ requestId,
203
+ toolName,
204
+ toolCallId,
205
+ args,
206
+ handler,
207
+ traceparent,
208
+ tracestate
209
+ );
194
210
  }
195
211
  } else if (event.type === "permission.requested") {
196
212
  const { requestId, permissionRequest } = event.data;
@@ -203,13 +219,15 @@ class CopilotSession {
203
219
  * Executes a tool handler and sends the result back via RPC.
204
220
  * @internal
205
221
  */
206
- async _executeToolAndRespond(requestId, toolName, toolCallId, args, handler) {
222
+ async _executeToolAndRespond(requestId, toolName, toolCallId, args, handler, traceparent, tracestate) {
207
223
  try {
208
224
  const rawResult = await handler(args, {
209
225
  sessionId: this.sessionId,
210
226
  toolCallId,
211
227
  toolName,
212
- arguments: args
228
+ arguments: args,
229
+ traceparent,
230
+ tracestate
213
231
  });
214
232
  let result;
215
233
  if (rawResult == null) {
@@ -323,6 +341,40 @@ class CopilotSession {
323
341
  registerHooks(hooks) {
324
342
  this.hooks = hooks;
325
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
+ }
326
378
  /**
327
379
  * Handles a permission request in the v2 protocol format (synchronous RPC).
328
380
  * Used as a back-compat adapter when connected to a v2 server.
@@ -502,14 +554,16 @@ class CopilotSession {
502
554
  * The new model takes effect for the next message. Conversation history is preserved.
503
555
  *
504
556
  * @param model - Model ID to switch to
557
+ * @param options - Optional settings for the new model
505
558
  *
506
559
  * @example
507
560
  * ```typescript
508
561
  * await session.setModel("gpt-4.1");
562
+ * await session.setModel("claude-sonnet-4.6", { reasoningEffort: "high" });
509
563
  * ```
510
564
  */
511
- async setModel(model) {
512
- await this.rpc.model.switchTo({ modelId: model });
565
+ async setModel(model, options) {
566
+ await this.rpc.model.switchTo({ modelId: model, ...options });
513
567
  }
514
568
  /**
515
569
  * Log a message to the session timeline.
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Trace-context helpers.
3
+ *
4
+ * The SDK does not depend on any OpenTelemetry packages. Instead, users
5
+ * provide an {@link TraceContextProvider} callback via client options.
6
+ *
7
+ * @module telemetry
8
+ */
9
+ import type { TraceContext, TraceContextProvider } from "./types.js";
10
+ /**
11
+ * Calls the user-provided {@link TraceContextProvider} to obtain the current
12
+ * W3C Trace Context. Returns `{}` when no provider is configured.
13
+ */
14
+ export declare function getTraceContext(provider?: TraceContextProvider): Promise<TraceContext>;
@@ -0,0 +1,11 @@
1
+ async function getTraceContext(provider) {
2
+ if (!provider) return {};
3
+ try {
4
+ return await provider() ?? {};
5
+ } catch {
6
+ return {};
7
+ }
8
+ }
9
+ export {
10
+ getTraceContext
11
+ };
package/dist/types.d.ts CHANGED
@@ -6,6 +6,38 @@ export type SessionEvent = GeneratedSessionEvent;
6
6
  /**
7
7
  * Options for creating a CopilotClient
8
8
  */
9
+ /**
10
+ * W3C Trace Context headers used for distributed trace propagation.
11
+ */
12
+ export interface TraceContext {
13
+ traceparent?: string;
14
+ tracestate?: string;
15
+ }
16
+ /**
17
+ * Callback that returns the current W3C Trace Context.
18
+ * Wire this up to your OpenTelemetry (or other tracing) SDK to enable
19
+ * distributed trace propagation between your app and the Copilot CLI.
20
+ */
21
+ export type TraceContextProvider = () => TraceContext | Promise<TraceContext>;
22
+ /**
23
+ * Configuration for OpenTelemetry instrumentation.
24
+ *
25
+ * When provided via {@link CopilotClientOptions.telemetry}, the SDK sets
26
+ * the corresponding environment variables on the spawned CLI process so
27
+ * that the CLI's built-in OTel exporter is configured automatically.
28
+ */
29
+ export interface TelemetryConfig {
30
+ /** OTLP HTTP endpoint URL for trace/metric export. Sets OTEL_EXPORTER_OTLP_ENDPOINT. */
31
+ otlpEndpoint?: string;
32
+ /** File path for JSON-lines trace output. Sets COPILOT_OTEL_FILE_EXPORTER_PATH. */
33
+ filePath?: string;
34
+ /** Exporter backend type: "otlp-http" or "file". Sets COPILOT_OTEL_EXPORTER_TYPE. */
35
+ exporterType?: string;
36
+ /** Instrumentation scope name. Sets COPILOT_OTEL_SOURCE_NAME. */
37
+ sourceName?: string;
38
+ /** Whether to capture message content (prompts, responses). Sets OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT. */
39
+ captureContent?: boolean;
40
+ }
9
41
  export interface CopilotClientOptions {
10
42
  /**
11
43
  * Path to the CLI executable or JavaScript entry point.
@@ -83,6 +115,37 @@ export interface CopilotClientOptions {
83
115
  * available from your custom provider.
84
116
  */
85
117
  onListModels?: () => Promise<ModelInfo[]> | ModelInfo[];
118
+ /**
119
+ * OpenTelemetry configuration for the CLI process.
120
+ * When provided, the corresponding OTel environment variables are set
121
+ * on the spawned CLI server.
122
+ */
123
+ telemetry?: TelemetryConfig;
124
+ /**
125
+ * Advanced: callback that returns the current W3C Trace Context for distributed
126
+ * trace propagation. Most users do not need this — the {@link telemetry} config
127
+ * alone is sufficient to collect traces from the CLI.
128
+ *
129
+ * This callback is only useful when your application creates its own
130
+ * OpenTelemetry spans and you want them to appear in the **same** distributed
131
+ * trace as the CLI's spans. The SDK calls this before `session.create`,
132
+ * `session.resume`, and `session.send` RPCs to inject `traceparent`/`tracestate`
133
+ * into the request.
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * import { propagation, context } from "@opentelemetry/api";
138
+ *
139
+ * const client = new CopilotClient({
140
+ * onGetTraceContext: () => {
141
+ * const carrier: Record<string, string> = {};
142
+ * propagation.inject(context.active(), carrier);
143
+ * return carrier;
144
+ * },
145
+ * });
146
+ * ```
147
+ */
148
+ onGetTraceContext?: TraceContextProvider;
86
149
  }
87
150
  /**
88
151
  * Configuration for creating a session
@@ -108,6 +171,10 @@ export interface ToolInvocation {
108
171
  toolCallId: string;
109
172
  toolName: string;
110
173
  arguments: unknown;
174
+ /** W3C Trace Context traceparent from the CLI's execute_tool span. */
175
+ traceparent?: string;
176
+ /** W3C Trace Context tracestate from the CLI's execute_tool span. */
177
+ tracestate?: string;
111
178
  }
112
179
  export type ToolHandler<TArgs = unknown> = (args: TArgs, invocation: ToolInvocation) => Promise<unknown> | unknown;
113
180
  /**
@@ -160,6 +227,46 @@ export interface ToolCallRequestPayload {
160
227
  export interface ToolCallResponsePayload {
161
228
  result: ToolResult;
162
229
  }
230
+ /**
231
+ * Known system prompt section identifiers for the "customize" mode.
232
+ * Each section corresponds to a distinct part of the system prompt.
233
+ */
234
+ export type SystemPromptSection = "identity" | "tone" | "tool_efficiency" | "environment_context" | "code_change_rules" | "guidelines" | "safety" | "tool_instructions" | "custom_instructions" | "last_instructions";
235
+ /** Section metadata for documentation and tooling. */
236
+ export declare const SYSTEM_PROMPT_SECTIONS: Record<SystemPromptSection, {
237
+ description: string;
238
+ }>;
239
+ /**
240
+ * Transform callback for a single section: receives current content, returns new content.
241
+ */
242
+ export type SectionTransformFn = (currentContent: string) => string | Promise<string>;
243
+ /**
244
+ * Override action: a string literal for static overrides, or a callback for transforms.
245
+ *
246
+ * - `"replace"`: Replace section content entirely
247
+ * - `"remove"`: Remove the section
248
+ * - `"append"`: Append to existing section content
249
+ * - `"prepend"`: Prepend to existing section content
250
+ * - `function`: Transform callback — receives current section content, returns new content
251
+ */
252
+ export type SectionOverrideAction = "replace" | "remove" | "append" | "prepend" | SectionTransformFn;
253
+ /**
254
+ * Override operation for a single system prompt section.
255
+ */
256
+ export interface SectionOverride {
257
+ /**
258
+ * The operation to perform on this section.
259
+ * Can be a string action or a transform callback function.
260
+ */
261
+ action: SectionOverrideAction;
262
+ /**
263
+ * Content for the override. Optional for all actions.
264
+ * - For replace, omitting content replaces with an empty string.
265
+ * - For append/prepend, content is added before/after the existing section.
266
+ * - Ignored for the remove action.
267
+ */
268
+ content?: string;
269
+ }
163
270
  /**
164
271
  * Append mode: Use CLI foundation with optional appended content (default).
165
272
  */
@@ -182,12 +289,31 @@ export interface SystemMessageReplaceConfig {
182
289
  */
183
290
  content: string;
184
291
  }
292
+ /**
293
+ * Customize mode: Override individual sections of the system prompt.
294
+ * Keeps the SDK-managed prompt structure while allowing targeted modifications.
295
+ */
296
+ export interface SystemMessageCustomizeConfig {
297
+ mode: "customize";
298
+ /**
299
+ * Override specific sections of the system prompt by section ID.
300
+ * Unknown section IDs gracefully fall back: content-bearing overrides are appended
301
+ * to additional instructions, and "remove" on unknown sections is a silent no-op.
302
+ */
303
+ sections?: Partial<Record<SystemPromptSection, SectionOverride>>;
304
+ /**
305
+ * Additional content appended after all sections.
306
+ * Equivalent to append mode's content field — provided for convenience.
307
+ */
308
+ content?: string;
309
+ }
185
310
  /**
186
311
  * System message configuration for session creation.
187
312
  * - Append mode (default): SDK foundation + optional custom content
188
313
  * - Replace mode: Full control, caller provides entire system message
314
+ * - Customize mode: Section-level overrides with graceful fallback
189
315
  */
190
- export type SystemMessageConfig = SystemMessageAppendConfig | SystemMessageReplaceConfig;
316
+ export type SystemMessageConfig = SystemMessageAppendConfig | SystemMessageReplaceConfig | SystemMessageCustomizeConfig;
191
317
  /**
192
318
  * Permission request types from the server
193
319
  */
@@ -686,7 +812,7 @@ export interface MessageOptions {
686
812
  */
687
813
  prompt: string;
688
814
  /**
689
- * File, directory, or selection attachments
815
+ * File, directory, selection, or blob attachments
690
816
  */
691
817
  attachments?: Array<{
692
818
  type: "file";
@@ -711,6 +837,11 @@ export interface MessageOptions {
711
837
  };
712
838
  };
713
839
  text?: string;
840
+ } | {
841
+ type: "blob";
842
+ data: string;
843
+ mimeType: string;
844
+ displayName?: string;
714
845
  }>;
715
846
  /**
716
847
  * Message delivery mode
package/dist/types.js CHANGED
@@ -1,8 +1,23 @@
1
1
  function defineTool(name, config) {
2
2
  return { name, ...config };
3
3
  }
4
+ const SYSTEM_PROMPT_SECTIONS = {
5
+ identity: { description: "Agent identity preamble and mode statement" },
6
+ tone: { description: "Response style, conciseness rules, output formatting preferences" },
7
+ tool_efficiency: { description: "Tool usage patterns, parallel calling, batching guidelines" },
8
+ environment_context: { description: "CWD, OS, git root, directory listing, available tools" },
9
+ code_change_rules: { description: "Coding rules, linting/testing, ecosystem tools, style" },
10
+ guidelines: { description: "Tips, behavioral best practices, behavioral guidelines" },
11
+ safety: { description: "Environment limitations, prohibited actions, security policies" },
12
+ tool_instructions: { description: "Per-tool usage instructions" },
13
+ custom_instructions: { description: "Repository and organization custom instructions" },
14
+ last_instructions: {
15
+ description: "End-of-prompt instructions: parallel tool calling, persistence, task completion"
16
+ }
17
+ };
4
18
  const approveAll = () => ({ kind: "approved" });
5
19
  export {
20
+ SYSTEM_PROMPT_SECTIONS,
6
21
  approveAll,
7
22
  defineTool
8
23
  };
package/package.json CHANGED
@@ -4,18 +4,30 @@
4
4
  "type": "git",
5
5
  "url": "https://github.com/github/copilot-sdk.git"
6
6
  },
7
- "version": "0.1.33-preview.2",
7
+ "version": "0.1.33-preview.4",
8
8
  "description": "TypeScript SDK for programmatic control of GitHub Copilot CLI via JSON-RPC",
9
- "main": "./dist/index.js",
9
+ "main": "./dist/cjs/index.js",
10
10
  "types": "./dist/index.d.ts",
11
11
  "exports": {
12
12
  ".": {
13
- "import": "./dist/index.js",
14
- "types": "./dist/index.d.ts"
13
+ "import": {
14
+ "types": "./dist/index.d.ts",
15
+ "default": "./dist/index.js"
16
+ },
17
+ "require": {
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/cjs/index.js"
20
+ }
15
21
  },
16
22
  "./extension": {
17
- "import": "./dist/extension.js",
18
- "types": "./dist/extension.d.ts"
23
+ "import": {
24
+ "types": "./dist/extension.d.ts",
25
+ "default": "./dist/extension.js"
26
+ },
27
+ "require": {
28
+ "types": "./dist/extension.d.ts",
29
+ "default": "./dist/cjs/extension.js"
30
+ }
19
31
  }
20
32
  },
21
33
  "type": "module",
@@ -44,7 +56,7 @@
44
56
  "author": "GitHub",
45
57
  "license": "MIT",
46
58
  "dependencies": {
47
- "@github/copilot": "^1.0.4",
59
+ "@github/copilot": "^1.0.10-0",
48
60
  "vscode-jsonrpc": "^8.2.1",
49
61
  "zod": "^4.3.6"
50
62
  },