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
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ marked `@experimental` upstream.
[PR #1954](https://github.com/github/copilot-sdk/pull/1954) (1.0.70-0), and
[PR #1962](https://github.com/github/copilot-sdk/pull/1962) (1.0.70). Bumped
`.copilot-schema-version` `1.0.68` → `1.0.70` and regenerated wire specs /
`.copilot-schema-version` `1.0.68` → `1.0.70` and regenerated wire specs /
Comment on lines 17 to +18
coercions via `bb codegen`. Schema 1.0.70 also widened `timeToFirstTokenMs`
from `integer` to `number`; the idiom `::time-to-first-token-ms` /
`::ttft-ms` specs now accept any non-negative number.
Expand All @@ -34,6 +35,21 @@ marked `@experimental` upstream.
optional experimental `:allow-all-permission-mode` / `:previous-allow-all-permission-mode`
fields (tri-state `#{"off" "auto" "on"}`) to the existing event; surfaced in the idiom
`::session.permissions_changed-data` spec and API reference.
- **`:enable-managed-settings?` session config** — port of upstream
[PR #1925](https://github.com/github/copilot-sdk/pull/1925). Boolean forwarded on
`session.create`/`session.resume`/join as wire `enableManagedSettings`, gated on
`some?` so an explicit `false` is sent verbatim and an absent key is omitted.
- **`:canvas-provider` session config** — port of upstream
[PR #1847](https://github.com/github/copilot-sdk/pull/1847). Map
`{:id "..." :name "..."}` (`:name` optional) forwarded on
`session.create`/`session.resume`/join as wire `canvasProvider`.
- **Telemetry forwarding on the `connect` handshake** — port of upstream
[PR #1909](https://github.com/github/copilot-sdk/pull/1909). When
`:on-github-telemetry` is registered, the SDK now also sends
`enableGitHubTelemetryForwarding: true` on the connection-level `connect`
handshake, so the first session's un-replayable `session.start` telemetry is
forwarded. The existing per-session `session.create`/`session.resume` flag is
retained for older CLIs.

### Added (v1.0.6-preview.1 sync)
Ported from upstream `github/copilot-sdk` (post-v1.0.5-preview.0). Schema bumped to
Expand Down
10 changes: 7 additions & 3 deletions doc/reference/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ Get information about the current shared client state. Returns `nil` if no share
| `: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), `: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) |
| `:on-github-telemetry` | fn | nil | **@experimental / Internal.** One-arg callback receiving each forwarded GitHub telemetry notification. Registering it adds `enableGitHubTelemetryForwarding: true` to the wire params of `session.create` and `session.resume`; the runtime then emits connection-global `gitHubTelemetry.event` notifications. A throwing handler is caught and logged (WARN) and cannot corrupt dispatch. Not a stable public SDK surface. See [Observability](#observability). ([PR #1835](https://github.com/github/copilot-sdk/pull/1835)) |
| `:on-github-telemetry` | fn | nil | **@experimental / Internal.** One-arg callback receiving each forwarded GitHub telemetry notification. Registering it adds `enableGitHubTelemetryForwarding: true` to the `connect` handshake (so the first session's un-replayable `session.start` telemetry is forwarded — upstream PR #1909) as well as to the wire params of `session.create` and `session.resume`; the runtime then emits connection-global `gitHubTelemetry.event` notifications. A throwing handler is caught and logged (WARN) and cannot corrupt dispatch. Not a stable public SDK surface. See [Observability](#observability). ([PR #1835](https://github.com/github/copilot-sdk/pull/1835)) |
| `: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 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) |
Expand Down Expand Up @@ -259,6 +259,8 @@ Create a client and session together, ensuring both are cleaned up on exit.
| `:excluded-builtin-agents` | vector | Names of built-in agents to hide/exclude from the session. Serialized as wire `excludedBuiltinAgents`. (upstream PR #1865) |
| `:enable-citations` | boolean | (Experimental) Opt into native model citations. Gated on `some?` — an explicit `false` is forwarded; an absent key is omitted. Serialized as wire `enableCitations`. (upstream PR #1865) |
| `:session-limits` | map | (Experimental) Session AI-credit limits. `{:max-ai-credits <number>}` — serialized as wire `sessionLimits.maxAiCredits`. (upstream PR #1865) |
| `:enable-managed-settings?` | boolean | Opt-in. When true, the runtime self-fetches enterprise managed settings (bypass-permissions policy) at session bootstrap using the session's `:github-token` (required; the runtime fails closed if omitted). Gated on `some?` — an explicit `false` is forwarded verbatim; an absent key is omitted. Serialized as wire `enableManagedSettings`. (upstream PR #1925) |
| `:canvas-provider` | map | Canvas provider identity for the session. `{:id "..." :name "..."}` (`:name` optional) — serialized as wire `canvasProvider.{id,name}`. (upstream PR #1847) |
| `:exp-assignments` | map | (Internal) Opaque experiment flight assignments. Keys are source-defined flight ids and are forwarded verbatim (string keys bypass kebab→camel conversion). Serialized as `expAssignments`. (upstream PR #1750) |
| `:mcp-servers` | map | MCP server configs keyed by server ID (see [MCP docs](../mcp/overview.md)). Local (stdio) servers: `:mcp-command`, `:mcp-args`, `:mcp-tools`. Remote (HTTP/SSE) servers: `:mcp-server-type` (`:http`/`:sse`), `:mcp-url`, `:mcp-tools`. Spec aliases: `::mcp-stdio-server` = `::mcp-local-server`, `::mcp-http-server` = `::mcp-remote-server` |
| `:commands` | vector | Command definitions (slash commands). See [Commands](#commands) |
Expand Down Expand Up @@ -1760,8 +1762,10 @@ send — forwarding only `:traceparent` and `:tracestate`:

Register a one-arg `:on-github-telemetry` callback in the **client** options to
receive the runtime's forwarded GitHub telemetry. Registering the callback is what
opts in: the SDK adds `enableGitHubTelemetryForwarding: true` to the wire params of
both `session.create` and `session.resume` (the flag is omitted entirely when no
opts in: the SDK adds `enableGitHubTelemetryForwarding: true` to the `connect`
handshake — so the first session's un-replayable `session.start` telemetry is
forwarded (upstream PR #1909) — as well as to the wire params of both
`session.create` and `session.resume` (the flag is omitted entirely when no
callback is set — `false` is never sent). The runtime then emits connection-global
`gitHubTelemetry.event` notifications, each passed to the callback:

Expand Down
39 changes: 37 additions & 2 deletions src/github/copilot_sdk/client.clj
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,9 @@
- :on-get-trace-context - Zero-arg fn returning {:traceparent ... :tracestate ...} for distributed trace propagation
- :on-github-telemetry - **Experimental / Internal**. One-arg fn invoked with each GitHub telemetry
notification (upstream PR #1835). Registering a handler opts the connection into
`enableGitHubTelemetryForwarding` on both `session.create` and `session.resume`;
`enableGitHubTelemetryForwarding` on the `connect` handshake (so the first
session's un-replayable `session.start` telemetry is forwarded, upstream PR #1909)
as well as on `session.create` and `session.resume`;
the runtime then emits connection-global `gitHubTelemetry.event` notifications,
each passed to this handler. The notification is an idiom-shaped map with keys
:session-id, :restricted, and :event; the event's :properties, :metrics, and
Expand Down Expand Up @@ -957,7 +959,16 @@
[client]
(let [{:keys [connection-io process options]} @(:state client)
token (:tcp-connection-token options)
connect-params (cond-> {} token (assoc :token token))
;; Opt in to GitHub telemetry forwarding at the connection level when a
;; handler is registered (upstream PR #1909). The runtime reads this flag
;; on the `connect` handshake so the first session's un-replayable
;; `session.start` telemetry is forwarded; it is also sent on
;; session.create/resume for older CLIs. csk camelCases "github" ->
;; "Github", so assoc the exact wire keyword (clj->wire is idempotent).
connect-params (cond-> {}
token (assoc :token token)
(some? (:on-github-telemetry client))
(assoc :enableGitHubTelemetryForwarding true))
exit-ch (:exit-chan process)
timeout-ch (async/timeout 60000)
await-rpc (fn [rpc-ch method-name]
Expand Down Expand Up @@ -2126,6 +2137,15 @@
;; wire keyword; clj->wire's camelCasing is idempotent on it.
(true? (:enable-github-telemetry-forwarding? config))
(assoc :enableGitHubTelemetryForwarding true)
;; enableManagedSettings (upstream PR #1925): opt-in for runtime self-fetch
;; of enterprise managed settings. Upstream spreads `config.enableManagedSettings`
;; verbatim, so forward the actual boolean (an explicit false is sent).
(some? (:enable-managed-settings? config))
(assoc :enable-managed-settings (:enable-managed-settings? config))
;; canvasProvider (upstream PR #1847): stable canvas-provider identity.
;; The nested {:id :name} map's kebab keys are camelCased by clj->wire.
(:canvas-provider config)
(assoc :canvas-provider (:canvas-provider config))
true (assoc :env-value-mode "direct"))))

(defn- stringify-keys-deep
Expand Down Expand Up @@ -2305,6 +2325,12 @@
;; wire keyword; clj->wire's camelCasing is idempotent on it.
(true? (:enable-github-telemetry-forwarding? config))
(assoc :enableGitHubTelemetryForwarding true)
;; enableManagedSettings + canvasProvider are SessionConfigBase fields
;; (upstream PRs #1925, #1847), honored on resume/join as well as create.
(some? (:enable-managed-settings? config))
(assoc :enable-managed-settings (:enable-managed-settings? config))
(:canvas-provider config)
(assoc :canvas-provider (:canvas-provider config))
true (assoc :env-value-mode "direct"))))

(defn- pre-register-session
Expand Down Expand Up @@ -2528,6 +2554,13 @@
`enableCitations`. (upstream PR #1865)
- :session-limits - Map (@experimental). Per-session accounting limits, e.g.
{:max-ai-credits 100}. Forwarded as `sessionLimits`. (upstream PR #1865)
- :enable-managed-settings? - Boolean (opt-in). When true, the runtime self-fetches enterprise
managed settings (bypass-permissions policy) at session bootstrap using the
session's `:github-token`, which must be set (the runtime fails closed
otherwise). Forwarded verbatim as `enableManagedSettings` — an explicit
`false` is sent on the wire. (upstream PR #1925)
- :canvas-provider - Map `{:id \"...\" :name \"...\"}` (`:name` optional). Identifies the canvas
provider for the session. Forwarded as `canvasProvider`. (upstream PR #1847)
- :remote-session - Keyword. Per-session Mission Control remote mode: :off, :export, or :on.
Forwarded as `remoteSession` on session.create. When omitted, the CLI
applies its default. (upstream PR #1295, CLI 1.0.48)
Expand Down Expand Up @@ -2685,6 +2718,8 @@
- :excluded-builtin-agents - Vector of strings. See `create-session` (upstream PR #1865).
- :enable-citations - Boolean (@experimental). See `create-session` (upstream PR #1865).
- :session-limits - Map (@experimental). See `create-session` (upstream PR #1865).
- :enable-managed-settings? - Boolean. See `create-session` (upstream PR #1925).
- :canvas-provider - Map `{:id .. :name ..}`. See `create-session` (upstream PR #1847).
- :on-exit-plan-mode - Handler for exitPlanMode.request RPCs. See `create-session`
(upstream PR #1228).
- :on-auto-mode-switch - Handler for autoModeSwitch.request RPCs. See `create-session`
Expand Down
28 changes: 23 additions & 5 deletions src/github/copilot_sdk/specs.clj
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,19 @@
(s/def ::max-ai-credits (s/and number? pos?))
(s/def ::session-limits (s/keys :opt-un [::max-ai-credits]))

;; enableManagedSettings (upstream PR #1925) — opt-in that makes the runtime
;; self-fetch enterprise managed settings (bypass-permissions policy) at session
;; bootstrap using the session's github token. Forwarded on create + resume/join.
(s/def ::enable-managed-settings? boolean?)

;; canvasProvider (upstream PR #1847) — stable identity for a host/SDK connection
;; that supplies built-in canvases, so canvases declared on a control connection
;; survive stdio reconnect and CLI restart instead of being re-keyed per
;; connection. `:id` is opaque and used verbatim as the canvas extension id;
;; `:name` is an optional display name. Forwarded on create + resume/join. Reuses
;; the generic ::id/::name specs, mirroring ::provider's nested-map convention.
(s/def ::canvas-provider (s/keys :req-un [::id] :opt-un [::name]))

(def session-config-keys
#{:session-id :client-name :model :tools :commands :system-message
:available-tools :excluded-tools :provider
Expand Down Expand Up @@ -850,7 +863,8 @@
:capi
:excluded-builtin-agents :enable-citations :session-limits
:providers :models :exp-assignments
:include-sub-agent-streaming-events?})
:include-sub-agent-streaming-events?
:enable-managed-settings? :canvas-provider})

(s/def ::session-config
(closed-keys
Expand Down Expand Up @@ -893,7 +907,8 @@
::capi
::excluded-builtin-agents ::enable-citations ::session-limits
::providers ::models ::exp-assignments
::include-sub-agent-streaming-events?])
::include-sub-agent-streaming-events?
::enable-managed-settings? ::canvas-provider])
session-config-keys))

(def ^:private resume-session-config-keys
Expand Down Expand Up @@ -932,7 +947,8 @@
:providers :models :exp-assignments
:include-sub-agent-streaming-events?
;; Upstream PR #1604: resume/join may seed the open-canvases snapshot.
:open-canvases})
:open-canvases
:enable-managed-settings? :canvas-provider})

(s/def ::resume-session-config
(closed-keys
Expand Down Expand Up @@ -973,7 +989,8 @@
::excluded-builtin-agents ::enable-citations ::session-limits
::providers ::models ::exp-assignments
::include-sub-agent-streaming-events?
::open-canvases])
::open-canvases
::enable-managed-settings? ::canvas-provider])
resume-session-config-keys))

;; join-session config: same as resume-session-config but :on-permission-request is optional.
Expand Down Expand Up @@ -1016,7 +1033,8 @@
::excluded-builtin-agents ::enable-citations ::session-limits
::providers ::models ::exp-assignments
::include-sub-agent-streaming-events?
::open-canvases])
::open-canvases
::enable-managed-settings? ::canvas-provider])
resume-session-config-keys))

;; -----------------------------------------------------------------------------
Expand Down
Loading
Loading