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

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/README.md CHANGED
@@ -26,15 +26,16 @@ npm start
26
26
  ## Quick Start
27
27
 
28
28
  ```typescript
29
- import { CopilotClient } from "@github/copilot-sdk";
29
+ import { CopilotClient, approveAll } from "@github/copilot-sdk";
30
30
 
31
31
  // Create and start client
32
32
  const client = new CopilotClient();
33
33
  await client.start();
34
34
 
35
- // Create a session
35
+ // Create a session (onPermissionRequest is required)
36
36
  const session = await client.createSession({
37
37
  model: "gpt-5",
38
+ onPermissionRequest: approveAll,
38
39
  });
39
40
 
40
41
  // Wait for response using typed event handlers
@@ -59,7 +60,7 @@ await client.stop();
59
60
  Sessions also support `Symbol.asyncDispose` for use with [`await using`](https://github.com/tc39/proposal-explicit-resource-management) (TypeScript 5.2+/Node.js 18.0+):
60
61
 
61
62
  ```typescript
62
- await using session = await client.createSession({ model: "gpt-5" });
63
+ await using session = await client.createSession({ model: "gpt-5", onPermissionRequest: approveAll });
63
64
  // session is automatically disconnected when leaving scope
64
65
  ```
65
66
 
@@ -84,6 +85,8 @@ new CopilotClient(options?: CopilotClientOptions)
84
85
  - `autoStart?: boolean` - Auto-start server (default: true)
85
86
  - `githubToken?: string` - GitHub token for authentication. When provided, takes priority over other auth methods.
86
87
  - `useLoggedInUser?: boolean` - Whether to use logged-in user for authentication (default: true, but false when `githubToken` is provided). Cannot be used with `cliUrl`.
88
+ - `telemetry?: TelemetryConfig` - OpenTelemetry configuration for the CLI process. Providing this object enables telemetry — no separate flag needed. See [Telemetry](#telemetry) below.
89
+ - `onGetTraceContext?: TraceContextProvider` - Advanced: callback for linking your application's own OpenTelemetry spans into the same distributed trace as the CLI's spans. Not needed for normal telemetry collection. See [Telemetry](#telemetry) below.
87
90
 
88
91
  #### Methods
89
92
 
@@ -112,6 +115,7 @@ Create a new conversation session.
112
115
  - `systemMessage?: SystemMessageConfig` - System message customization (see below)
113
116
  - `infiniteSessions?: InfiniteSessionConfig` - Configure automatic context compaction (see below)
114
117
  - `provider?: ProviderConfig` - Custom API provider configuration (BYOK - Bring Your Own Key). See [Custom Providers](#custom-providers) section.
118
+ - `onPermissionRequest: PermissionHandler` - **Required.** Handler called before each tool execution to approve or deny it. Use `approveAll` to allow everything, or provide a custom function for fine-grained control. See [Permission Handling](#permission-handling) section.
115
119
  - `onUserInputRequest?: UserInputHandler` - Handler for user input requests from the agent. Enables the `ask_user` tool. See [User Input Requests](#user-input-requests) section.
116
120
  - `hooks?: SessionHooks` - Hook handlers for session lifecycle events. See [Session Hooks](#session-hooks) section.
117
121
 
@@ -296,9 +300,10 @@ See `SessionEvent` type in the source for full details.
296
300
 
297
301
  ## Image Support
298
302
 
299
- The SDK supports image attachments via the `attachments` parameter. You can attach images by providing their file path:
303
+ The SDK supports image attachments via the `attachments` parameter. You can attach images by providing their file path, or by passing base64-encoded data directly using a blob attachment:
300
304
 
301
305
  ```typescript
306
+ // File attachment — runtime reads from disk
302
307
  await session.send({
303
308
  prompt: "What's in this image?",
304
309
  attachments: [
@@ -308,6 +313,18 @@ await session.send({
308
313
  },
309
314
  ],
310
315
  });
316
+
317
+ // Blob attachment — provide base64 data directly
318
+ await session.send({
319
+ prompt: "What's in this image?",
320
+ attachments: [
321
+ {
322
+ type: "blob",
323
+ data: base64ImageData,
324
+ mimeType: "image/png",
325
+ },
326
+ ],
327
+ });
311
328
  ```
312
329
 
313
330
  Supported image formats include JPG, PNG, GIF, and other common image types. The agent's `view` tool can also read images directly from the filesystem, so you can also ask questions like:
@@ -601,6 +618,127 @@ const session = await client.createSession({
601
618
  > - For Azure OpenAI endpoints (`*.openai.azure.com`), you **must** use `type: "azure"`, not `type: "openai"`.
602
619
  > - The `baseUrl` should be just the host (e.g., `https://my-resource.openai.azure.com`). Do **not** include `/openai/v1` in the URL - the SDK handles path construction automatically.
603
620
 
621
+ ## Telemetry
622
+
623
+ The SDK supports OpenTelemetry for distributed tracing. Provide a `telemetry` config to enable trace export from the CLI process — this is all most users need:
624
+
625
+ ```typescript
626
+ const client = new CopilotClient({
627
+ telemetry: {
628
+ otlpEndpoint: "http://localhost:4318",
629
+ },
630
+ });
631
+ ```
632
+
633
+ With just this configuration, the CLI emits spans for every session, message, and tool call to your collector. No additional dependencies or setup required.
634
+
635
+ **TelemetryConfig options:**
636
+
637
+ - `otlpEndpoint?: string` - OTLP HTTP endpoint URL
638
+ - `filePath?: string` - File path for JSON-lines trace output
639
+ - `exporterType?: string` - `"otlp-http"` or `"file"`
640
+ - `sourceName?: string` - Instrumentation scope name
641
+ - `captureContent?: boolean` - Whether to capture message content
642
+
643
+ ### Advanced: Trace Context Propagation
644
+
645
+ > **You don't need this for normal telemetry collection.** The `telemetry` config above is sufficient to get full traces from the CLI.
646
+
647
+ `onGetTraceContext` is only needed if your application creates its own OpenTelemetry spans and you want them to appear in the **same distributed trace** as the CLI's spans — for example, to nest a "handle tool call" span inside the CLI's "execute tool" span, or to show the SDK call as a child of your application's request-handling span.
648
+
649
+ If you're already using `@opentelemetry/api` in your app and want this linkage, provide a callback:
650
+
651
+ ```typescript
652
+ import { propagation, context } from "@opentelemetry/api";
653
+
654
+ const client = new CopilotClient({
655
+ telemetry: { otlpEndpoint: "http://localhost:4318" },
656
+ onGetTraceContext: () => {
657
+ const carrier: Record<string, string> = {};
658
+ propagation.inject(context.active(), carrier);
659
+ return carrier;
660
+ },
661
+ });
662
+ ```
663
+
664
+ Inbound trace context from the CLI is available on the `ToolInvocation` object passed to tool handlers as `traceparent` and `tracestate` fields. See the [OpenTelemetry guide](../docs/observability/opentelemetry.md) for a full wire-up example.
665
+
666
+ ## Permission Handling
667
+
668
+ An `onPermissionRequest` handler is **required** whenever you create or resume a session. The handler is called before the agent executes each tool (file writes, shell commands, custom tools, etc.) and must return a decision.
669
+
670
+ ### Approve All (simplest)
671
+
672
+ Use the built-in `approveAll` helper to allow every tool call without any checks:
673
+
674
+ ```typescript
675
+ import { CopilotClient, approveAll } from "@github/copilot-sdk";
676
+
677
+ const session = await client.createSession({
678
+ model: "gpt-5",
679
+ onPermissionRequest: approveAll,
680
+ });
681
+ ```
682
+
683
+ ### Custom Permission Handler
684
+
685
+ Provide your own function to inspect each request and apply custom logic:
686
+
687
+ ```typescript
688
+ import type { PermissionRequest, PermissionRequestResult } from "@github/copilot-sdk";
689
+
690
+ const session = await client.createSession({
691
+ model: "gpt-5",
692
+ onPermissionRequest: (request: PermissionRequest, invocation): PermissionRequestResult => {
693
+ // request.kind — what type of operation is being requested:
694
+ // "shell" — executing a shell command
695
+ // "write" — writing or editing a file
696
+ // "read" — reading a file
697
+ // "mcp" — calling an MCP tool
698
+ // "custom-tool" — calling one of your registered tools
699
+ // "url" — fetching a URL
700
+ // "memory" — storing or retrieving persistent session memory
701
+ // "hook" — invoking a server-side hook or integration
702
+ // (additional kinds may be added; include a default case in handlers)
703
+ // request.toolCallId — the tool call that triggered this request
704
+ // request.toolName — name of the tool (for custom-tool / mcp)
705
+ // request.fileName — file being written (for write)
706
+ // request.fullCommandText — full shell command (for shell)
707
+
708
+ if (request.kind === "shell") {
709
+ // Deny shell commands
710
+ return { kind: "denied-interactively-by-user" };
711
+ }
712
+
713
+ return { kind: "approved" };
714
+ },
715
+ });
716
+ ```
717
+
718
+ ### Permission Result Kinds
719
+
720
+ | Kind | Meaning |
721
+ |------|---------|
722
+ | `"approved"` | Allow the tool to run |
723
+ | `"denied-interactively-by-user"` | User explicitly denied the request |
724
+ | `"denied-no-approval-rule-and-could-not-request-from-user"` | No approval rule matched and user could not be asked |
725
+ | `"denied-by-rules"` | Denied by a policy rule |
726
+ | `"denied-by-content-exclusion-policy"` | Denied due to a content exclusion policy |
727
+ | `"no-result"` | Leave the request unanswered (only valid with protocol v1; rejected by protocol v2 servers) |
728
+ ### Resuming Sessions
729
+
730
+ Pass `onPermissionRequest` when resuming a session too — it is required:
731
+
732
+ ```typescript
733
+ const session = await client.resumeSession("session-id", {
734
+ onPermissionRequest: approveAll,
735
+ });
736
+ ```
737
+
738
+ ### Per-Tool Skip Permission
739
+
740
+ To let a specific custom tool bypass the permission prompt entirely, set `skipPermission: true` on the tool definition. See [Skipping Permission Prompts](#skipping-permission-prompts) under Tools.
741
+
604
742
  ## User Input Requests
605
743
 
606
744
  Enable the agent to ask questions to the user using the `ask_user` tool by providing an `onUserInputRequest` handler: