Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .copilot-schema-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.61
1.0.63
49 changes: 49 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,47 @@ All notable changes to this project will be documented in this file. This change
## [Unreleased]

### Added (post-v1.0.1 sync)
- **`:memory` session configuration** — port of upstream
[PR #1617](https://github.com/github/copilot-sdk/pull/1617). `create-session`
and `resume-session` now accept an optional `:memory` map (shape
`{:enabled boolean}`) that configures the agent's persistent memory. It is
forwarded on **both** `session.create` and `session.resume`, omitted entirely
when the key is absent (never wire `null`), and wire-encoded as `memory`. In
`:mode :empty` it is defaulted to `{:enabled false}` (caller can override).
Added a `::memory` spec (reusing the existing `::enabled`).
- **`:otlp-protocol` telemetry option** — port of upstream
[PR #1648](https://github.com/github/copilot-sdk/pull/1648). The client
`:telemetry` map accepts an optional `:otlp-protocol` (`"http/json"` or
`"http/protobuf"`), mapped to the `OTEL_EXPORTER_OTLP_PROTOCOL` environment
variable on the spawned CLI. Added `::otlp-protocol` to the `::telemetry` spec.
- **Graceful `runtime.shutdown` in `stop!`** — port of upstream
[PR #1667](https://github.com/github/copilot-sdk/pull/1667) (restores the
behavior of the reverted PR #1539). For SDK-spawned (non-external) processes,
`stop!` now sends a `runtime.shutdown` RPC bounded by a 10-second timeout
before closing the connection, falling back to process termination
(SIGTERM → SIGKILL) on timeout or error. `force-stop!` is unchanged.
- **`:mcp-defer-tools` MCP option** — new in upstream CLI schema 1.0.63. Stdio
and HTTP/SSE MCP server configs accept an optional `:mcp-defer-tools` keyword
(`:auto` or `:never`) controlling tool-deferral. Wire-encoded as `deferTools`
with the keyword value stringified. Added `::mcp-defer-tools` spec to both MCP
server specs.
- **`:copilot/session.todos_changed` event** — new signal-only event in upstream
CLI schema 1.0.63. Carries no payload; fires when the agent's todos / todo-deps
table is written. Added to the public `event-types` and `session-events` sets.
- **New optional event-data fields** (upstream CLI schema 1.0.63):
- `:copilot/assistant.usage`: `:content-filter-triggered` (boolean),
`:finish-reason` (string).
- `:copilot/tool.execution_complete`: `:structured-content` (arbitrary
structured tool result).
- `:copilot/assistant.message`: `:server-tools` (replaces the removed
`anthropicAdvisorBlocks` / `anthropicAdvisorModel` fields).
- `:copilot/tool.execution_start`: `:tool-description`.
- **`::model-billing` token-prices spec** — port of upstream
[PR #1633](https://github.com/github/copilot-sdk/pull/1633). The
`::model-billing` spec gains an optional `:token-prices` map
(`:input-price`, `:output-price`, `:cache-price`, `:batch-size`,
`:context-max`, `:long-context`); `list-models` already passes the whole
billing map through, so this is documentation/validation only.
- **`:defer` tool-definition option** — port of upstream
[PR #1632](https://github.com/github/copilot-sdk/pull/1632). `define-tool` and
`define-tool-from-spec` now accept an optional `:defer` keyword (`:auto` or
Expand All @@ -14,6 +55,14 @@ All notable changes to this project will be documented in this file. This change
the runtime applies its default (`"auto"`). Added `::defer` value spec
(`#{:auto :never}`) to the `::tool` spec.

### Changed (post-v1.0.1 sync)
- Bumped pinned `@github/copilot` schema 1.0.61 → 1.0.63
([PR #1686](https://github.com/github/copilot-sdk/pull/1686) and intermediate
1.0.62), regenerating `generated/event_specs.clj` and `generated/coerce.clj`.
Pulls in the new `session.todos_changed` event, optional usage /
tool-execution / assistant-message fields, the MCP `deferTools` config, and
the `ExtensionSource` enum extension (`plugin` / `session`).

### Added (v1.0.1 sync)
- **`open-canvases` snapshot** — port of upstream PR #1604. A new
`github.copilot-sdk/open-canvases` (also `github.copilot-sdk.session/open-canvases`)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Add to your `deps.edn`:

```clojure
;; From Maven Central
io.github.copilot-community-sdk/copilot-sdk-clojure {:mvn/version "1.0.1.0"}
io.github.copilot-community-sdk/copilot-sdk-clojure {:mvn/version "1.0.1.1"}

;; Or git dependency
io.github.copilot-community-sdk/copilot-sdk-clojure {:git/url "https://github.com/copilot-community-sdk/copilot-sdk-clojure.git"
Expand Down
2 changes: 1 addition & 1 deletion build.clj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
(:import [java.io File]))

(def lib 'io.github.copilot-community-sdk/copilot-sdk-clojure)
(def version "1.0.1.0")
(def version "1.0.1.1")
(def class-dir "target/classes")

(defn- try-sh
Expand Down
2 changes: 1 addition & 1 deletion doc/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ copilot --version
Add to your `deps.edn`:

```clojure
{:deps {io.github.copilot-community-sdk/copilot-sdk-clojure {:mvn/version "1.0.1.0"}}}
{:deps {io.github.copilot-community-sdk/copilot-sdk-clojure {:mvn/version "1.0.1.1"}}}
```

Or use as a Git dependency:
Expand Down
4 changes: 4 additions & 0 deletions doc/mcp/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ Here's a complete working example using the official [`@modelcontextprotocol/ser
| `:mcp-tools` | vector | Yes | Tools to enable (`["*"]` for all, `[]` for none, or specific tool names) |
| `:mcp-server-type` | keyword | No | `:local` or `:stdio` (defaults to local) |
| `:mcp-timeout` | number | No | Timeout in milliseconds |
| `:mcp-defer-tools` | keyword | No | Tool-deferral policy: `:auto` (defer tool registration until needed) or `:never`. Wire-encoded as `deferTools` (upstream schema 1.0.63) |
| `:env` | map | No | Environment variables for the subprocess |
| `:cwd` | string | No | Working directory for the subprocess |

Expand All @@ -122,12 +123,15 @@ Here's a complete working example using the official [`@modelcontextprotocol/ser
| `:mcp-url` | string | Yes | Server URL |
| `:mcp-tools` | vector | Yes | Tools to enable (`["*"]` for all) |
| `:mcp-timeout` | number | No | Timeout in milliseconds |
| `:mcp-defer-tools` | keyword | No | Tool-deferral policy: `:auto` or `:never`. Wire-encoded as `deferTools` (upstream schema 1.0.63) |
| `:mcp-headers` | map | No | HTTP headers (e.g., for authentication) |

### Key Naming Convention

MCP server config keys use an `:mcp-` prefix in Clojure (e.g., `:mcp-command`, `:mcp-args`, `:mcp-tools`) to distinguish them from other configuration options. On the wire, the SDK automatically strips this prefix to match the upstream protocol (e.g., `command`, `args`, `tools`).

Some prefixed keys map to a camelCase wire key rather than a bare strip: `:mcp-defer-tools` becomes `deferTools`, and its keyword value (`:auto`/`:never`) is stringified.

The non-prefixed keys `:env` and `:cwd` are shared with other config types and do not have an `:mcp-` prefix.

## Tool Filtering
Expand Down
31 changes: 24 additions & 7 deletions doc/reference/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ Get information about the current shared client state. Returns `nil` if no share
| `:remote?` | boolean | `false` | When `true`, append `--remote` to the spawned CLI args so the CLI exposes the session over a GitHub-hosted remote endpoint. Ignored when `:cli-url` is set. (upstream PR #1192) |
| `:session-idle-timeout-seconds` | integer | `0` (disabled) | Server-wide session idle timeout in seconds. When `> 0`, append `--session-idle-timeout <n>` to the spawned CLI so idle sessions are cleaned up after the given duration. |
| `:on-list-models` | fn | nil | Zero-arg function returning model info maps. Bypasses `models.list` RPC; does not require `start!`. Results are cached the same way as RPC results |
| `:telemetry` | map | nil | OpenTelemetry export config, applied as environment variables to the **spawned** CLI (ignored when connecting to an existing server via `:cli-url` or a parent process via `:is-child-process?`, since no CLI is spawned). When present, enables OTel. Keys (all optional): `:otlp-endpoint` (OTLP HTTP endpoint), `:file-path` (write spans to a file), `:exporter-type` (exporter selection), `:source-name` (service/source name), `:capture-content?` (boolean — capture prompt/response content; **off by default for privacy**). See [Observability](#observability). (upstream PR #785) |
| `:telemetry` | map | nil | OpenTelemetry export config, applied as environment variables to the **spawned** CLI (ignored when connecting to an existing server via `:cli-url` or a parent process via `:is-child-process?`, since no CLI is spawned). When present, enables OTel. Keys (all optional): `:otlp-endpoint` (OTLP HTTP endpoint), `:otlp-protocol` (`"http/json"` or `"http/protobuf"` — sets `OTEL_EXPORTER_OTLP_PROTOCOL`), `:file-path` (write spans to a file), `:exporter-type` (exporter selection), `:source-name` (service/source name), `:capture-content?` (boolean — capture prompt/response content; **off by default for privacy**). See [Observability](#observability). (upstream PR #785, [PR #1648](https://github.com/github/copilot-sdk/pull/1648)) |
| `:on-get-trace-context` | fn | nil | Zero-arg function returning `{:traceparent "..." :tracestate "..."}`, called per request (session create/resume and each message send) to propagate a distributed-trace context. Only `:traceparent` and `:tracestate` are forwarded. See [Observability](#observability) |
| `:is-child-process?` | boolean | `false` | When `true`, connect via own stdio to a parent Copilot CLI process (no process spawning). Requires `:use-stdio?` `true`; mutually exclusive with `:cli-url` |
| `:session-fs` | map | nil | Session filesystem provider config. Keys: `:initial-cwd` (string, required), `:session-state-path` (string, required), `:conventions` (`"windows"` or `"posix"`, required). When set, the client calls `sessionFs.setProvider` on connect and routes filesystem operations through per-session handlers. See [Session Filesystem](#session-filesystem) |
| `:mode` | keyword | `:copilot-cli` | Client multitenancy mode: `:copilot-cli` (default — preserve historical CLI behavior) or `:empty` (multi-tenant SaaS hosts that must isolate sessions from local machine state). In `:empty` mode the SDK requires at least one tenant-scoped storage root (`:copilot-home`, `:session-fs`, `:cli-url`, or `:is-child-process?`), sets `COPILOT_DISABLE_KEYTAR=1` on the spawned CLI, spreads 9 safe defaults under caller session config, forces `installedPlugins []`, and normalizes `:system-message` to strip `environment_context`. See [Client Mode](#client-mode-empty). (upstream PR #1428) |
| `:mode` | keyword | `:copilot-cli` | Client multitenancy mode: `:copilot-cli` (default — preserve historical CLI behavior) or `:empty` (multi-tenant SaaS hosts that must isolate sessions from local machine state). In `:empty` mode the SDK requires at least one tenant-scoped storage root (`:copilot-home`, `:session-fs`, `:cli-url`, or `:is-child-process?`), sets `COPILOT_DISABLE_KEYTAR=1` on the spawned CLI, spreads 10 safe defaults under caller session config, forces `installedPlugins []`, and normalizes `:system-message` to strip `environment_context`. See [Client Mode](#client-mode-empty). (upstream PR #1428) |

### Methods

Expand Down Expand Up @@ -167,6 +167,13 @@ Create a client, start it, and ensure `stop!` runs on exit.

Stop the server and close all sessions gracefully.

For SDK-spawned processes (not `:external-server?`), `stop!` issues a
`runtime.shutdown` RPC before closing the connection, giving the CLI a chance to
flush state and exit cleanly. The call is bounded by a 10-second timeout; on
timeout or error the SDK falls back to terminating the process (SIGTERM, then
SIGKILL). Connecting to an external server (`:cli-url`) skips the shutdown RPC and
the process is left running. (upstream [PR #1667](https://github.com/github/copilot-sdk/pull/1667))

#### `force-stop!`

```clojure
Expand Down Expand Up @@ -291,6 +298,7 @@ Create a client and session together, ensuring both are cleaned up on exit.
| `:coauthor-enabled` | boolean | Add a Copilot Co-authored-by trailer to commits made by the CLI. Forwarded via `session.options.update`. Defaulted to `false` in `:empty` mode. (upstream PR #1428) |
| `:manage-schedule-enabled` | boolean | Enable the built-in schedule-management tools. Forwarded via `session.options.update`. Defaulted to `false` in `:empty` mode. (upstream PR #1428) |
| `:open-canvases` | vector | (resume-session / join-session only) Seed the open-canvases snapshot when reconnecting. Each entry: `{:instance-id ... :extension-id ... :canvas-id ... :reopen bool :availability "ready"\|"stale" :extension-name? ... :title? ... :status? ... :url? ... :input? {...}}`. Caller-defined `:input` keys are preserved verbatim through wire conversion (no kebab→camel re-casing). See [`open-canvases`](#open-canvases). (upstream PR #1604) |
| `:memory` | map | Persistent-memory configuration. Shape: `{:enabled boolean}`. Sent on **both** `session.create` and `session.resume`; omitted entirely when the key is absent (never wire `null`). Wire-encoded as `memory`. In `:mode :empty` it is defaulted to `{:enabled false}` (caller can override). (upstream [PR #1617](https://github.com/github/copilot-sdk/pull/1617)) |

#### `resume-session`

Expand Down Expand Up @@ -441,7 +449,14 @@ Requires authentication (unless `:on-list-models` is provided). Returns a vector
:max-prompt-image-size 20971520}}}
:model-policy {:policy-state "enabled"
:terms "..."}
:model-billing {:multiplier 1.0}
:model-billing {:multiplier 1.0
;; Per-token prices (upstream PR #1633), present when the
;; model reports them; keys are optional:
:token-prices {:input-price 0.00000125
:output-price 0.00001
:cache-price 0.0000003125
:long-context {:input-price 0.0000025
:output-price 0.00002}}}
;; Model picker categorization (CLI 1.0.46+):
:model-picker-category "powerful" ;; "lightweight" | "versatile" | "powerful"
:model-picker-price-category "very_high" ;; "low" | "medium" | "high" | "very_high"
Expand Down Expand Up @@ -1470,6 +1485,7 @@ Convert an unqualified event keyword to a namespace-qualified `:copilot/` keywor
| `:copilot/session.plan_changed` | Session plan created/updated/deleted; data: `{:operation "create"/"update"/"delete"}` |
| `:copilot/session.workspace_file_changed` | Workspace file created or updated; data: `{:path "...", :operation "create"/"update"}` |
| `:copilot/session.task_complete` | Task completed by the session agent; data: `{:summary "..." :aborted? false}` (both optional) |
| `:copilot/session.todos_changed` | Signal-only: the agent's todos / todo-deps table was written. **No payload.** Events arrive in order; debounce on arrival if needed (upstream schema 1.0.63) |
| `:copilot/session.schedule_created` | Scheduled prompt registered via `/every`; data: `{:id <pos-int> :interval-ms <pos-int> :prompt "..."}` (upstream schema 1.0.42) |
| `:copilot/session.schedule_cancelled` | Scheduled prompt cancelled from the schedule manager dialog; data: `{:id <pos-int>}` (upstream schema 1.0.42) |
| `:copilot/session.autopilot_objective_changed` | Autopilot objective lifecycle events; data: `{:operation #{"create" "update" "delete"}}` (required) with optional `:id` (integer) and `:status` (upstream schema 1.0.56). The `:status` enum is widened to include `"active"`, `"paused"`, `"cap_reached"`, `"completed"`. |
Expand All @@ -1485,13 +1501,13 @@ Convert an unqualified event keyword to a namespace-qualified `:copilot/` keywor
| `:copilot/assistant.message_delta` | Streaming response chunk |
| `:copilot/assistant.streaming_delta` | Response size update during streaming; data: `{:total-response-size-bytes N}` |
| `:copilot/assistant.turn_end` | Assistant turn completed |
| `:copilot/assistant.usage` | Token usage for this turn |
| `:copilot/assistant.usage` | Token usage for this turn; data may include optional `:content-filter-triggered` (boolean) and `:finish-reason` (string) (upstream schema 1.0.63) |
| `:copilot/abort` | Current message aborted |
| `:copilot/tool.user_requested` | Tool execution requested by user |
| `:copilot/tool.execution_start` | Tool execution started; data includes `:tool-call-id`, `:tool-name`, optional `:arguments`, `:parent-tool-call-id`, `:mcp-server-name`, `:mcp-tool-name`, `:model` |
| `:copilot/tool.execution_progress` | Tool execution progress update |
| `:copilot/tool.execution_partial_result` | Tool execution partial result |
| `:copilot/tool.execution_complete` | Tool execution completed |
| `:copilot/tool.execution_complete` | Tool execution completed; data may include optional `:structured-content` (arbitrary structured tool result) (upstream schema 1.0.63) |
| `:copilot/subagent.started` | Subagent started; data includes :tool-call-id, :agent-name, :agent-display-name, :agent-description |
| `:copilot/subagent.completed` | Subagent completed; data includes :tool-call-id, :agent-name, :agent-display-name, optional :model, :total-tool-calls, :total-tokens, :duration-ms |
| `:copilot/subagent.failed` | Subagent failed; data includes :tool-call-id, :agent-name, :agent-display-name, :error, optional :model, :total-tool-calls, :total-tokens, :duration-ms |
Expand Down Expand Up @@ -1630,13 +1646,14 @@ spawned CLI. Presence of the map enables OTel; all sub-keys are optional:
| Key | Type | Description | CLI env var |
|-----|------|-------------|-------------|
| `:otlp-endpoint` | string | OTLP HTTP endpoint to export spans to | `OTEL_EXPORTER_OTLP_ENDPOINT` |
| `:otlp-protocol` | string | OTLP wire protocol: `"http/json"` or `"http/protobuf"` | `OTEL_EXPORTER_OTLP_PROTOCOL` |
| `:file-path` | string | Write spans to a local file instead of/alongside OTLP | `COPILOT_OTEL_FILE_EXPORTER_PATH` |
| `:exporter-type` | string | Exporter selection | `COPILOT_OTEL_EXPORTER_TYPE` |
| `:source-name` | string | Service / source name attached to spans | `COPILOT_OTEL_SOURCE_NAME` |
| `:capture-content?` | boolean | Capture prompt/response content in spans. **Defaults to off** — only enable in trusted environments, as it records message content | `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` |

When `:telemetry` is present the SDK sets `COPILOT_OTEL_ENABLED=true` on the CLI process.
(upstream PR #785)
(upstream PR #785, [PR #1648](https://github.com/github/copilot-sdk/pull/1648))

#### Distributed trace propagation (`:on-get-trace-context`)

Expand Down Expand Up @@ -1736,7 +1753,7 @@ What `:empty` mode enforces (vs `:copilot-cli`):
`:skip-embedding-retrieval true`, `:embedding-cache-storage :in-memory`,
`:enable-on-demand-instruction-discovery false`, `:enable-file-hooks false`,
`:enable-host-git-operations false`, `:enable-session-store false`,
`:enable-skills false`.
`:enable-skills false`, `:memory {:enabled false}`.
- **System message normalization**: the SDK strips the `environment_context`
section from the system message (or promotes `:append` to `:customize`) so
no host-environment context leaks. If the caller already provides their own
Expand Down
2 changes: 1 addition & 1 deletion schemas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ These files are fetched verbatim from the `@github/copilot` npm package at the v

**Do not edit by hand.** To update, run `bb schemas:fetch` after bumping `.copilot-schema-version`.

Currently pinned version: `1.0.61`
Currently pinned version: `1.0.63`
Loading
Loading