Skip to content

Commit de31e65

Browse files
krukowCopilot
andcommitted
Sync with upstream copilot-sdk post-v0.2.2 (batch 2)
Port four upstream changes landed after v0.2.2: - PR #1108: includeSubAgentStreamingEvents session option (default true) and :agent-id on base events. provider-level :headers on ProviderConfig. - CLI 1.0.28 (PR #1089): ::can-offer-session-approval? spec for writeFile permission events. - CLI 1.0.32 (PR #1105): ::reasoning-tokens spec for assistant.usage and session.usage_info events. Changes: - specs.clj: add ::include-sub-agent-streaming-events?, ::request-headers, ::headers (provider), ::agent-id, ::can-offer-session-approval?, ::reasoning-tokens. Extend session-config-keys and resume-session-config-keys sets plus corresponding :opt-un lists on ::session-config, ::resume-session-config, ::join-session-config, ::send-options, ::provider, ::base-event. - client.clj: build-create-session-params and build-resume-session-params unconditionally emit :include-sub-agent-streaming-events with default true, matching upstream ?? true semantics. - session.clj: send! and <send-async* forward :request-headers when set. - API.md and CHANGELOG.md: document new options and specs. - integration_test.clj: 8 new tests covering wire shape for includeSubAgentStreamingEvents (create+resume, default+explicit), requestHeaders (send! + send-async + omission), provider headers, and the three new specs. All reviewers (Claude Opus 4.6, GPT-5.4, GPT-5.3-Codex) found the change correct. The GPT-5 finding that :request-headers was not forwarded through the async send path was addressed in this commit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent f21206e commit de31e65

6 files changed

Lines changed: 190 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file. This change
33

44
## [Unreleased]
55

6+
### Added (post-v0.2.2 sync, batch 2)
7+
- **`includeSubAgentStreamingEvents` session option** — new boolean `:include-sub-agent-streaming-events?` on `::session-config`, `::resume-session-config`, and `::join-session-config`. When `true` (default), sub-agent streaming events are forwarded to the parent session's event stream. (upstream PR #1108)
8+
- **Per-request HTTP headers on `send!`** — new `:request-headers` option (map of string→string) on `::send-options`. Forwarded as wire `requestHeaders` and merged with provider-level headers by the CLI. (upstream PR #1094)
9+
- **Provider-level HTTP headers** — new `:headers` field (map of string→string) on `::provider` config. Sent with each model request to BYOK endpoints. (upstream PR #1094)
10+
- **`::can-offer-session-approval?`** spec — boolean field present on `permission.requested` events of kind `writeFile`, indicating the CLI can offer a "trust this session" choice. (CLI 1.0.28, upstream PR #1089)
11+
- **`::reasoning-tokens`** spec — non-negative integer field on `assistant.usage` and `session.usage_info` events tracking tokens used for reasoning content. (CLI 1.0.32, upstream PR #1105)
12+
- **`::agent-id`** spec — optional string field on `::base-event`, identifying which (sub-)agent emitted the event. (upstream PR #1108)
13+
- Integration tests for all new wire fields and specs (7 new tests).
14+
615
### Added (post-v0.2.2 sync)
716
- **`convert-mcp-call-tool-result`** — new public function in `tools` namespace that converts MCP `CallToolResult` format into the SDK's `ToolResultObject`. Handles text, image, and resource content types. (upstream PR #1049)
817
- **`default-join-session-permission-handler`** — new permission handler for `resume-session` that returns `{:kind :no-result}`, signaling the CLI to handle permissions itself. Sends `requestPermission: false` on the wire. (upstream PR #1056)

doc/reference/API.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ Create a client and session together, ensuring both are cleaned up on exit.
237237
| `:system-message` | map | System message customization (see below) |
238238
| `:available-tools` | vector | List of allowed tool names |
239239
| `:excluded-tools` | vector | List of excluded tool names |
240-
| `:provider` | map | Provider config for BYOK (see [BYOK docs](../auth/byok.md)). Required key: `:base-url`. Optional: `:provider-type` (`:openai`/`:azure`/`:anthropic`), `:wire-api` (`:completions`/`:responses`), `:api-key`, `:bearer-token`, `:azure-options` |
240+
| `:provider` | map | Provider config for BYOK (see [BYOK docs](../auth/byok.md)). Required key: `:base-url`. Optional: `:provider-type` (`:openai`/`:azure`/`:anthropic`), `:wire-api` (`:completions`/`:responses`), `:api-key`, `:bearer-token`, `:azure-options`, `:headers` (map of HTTP header name→value, sent with each provider request — upstream PR #1094) |
241241
| `: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` |
242242
| `:commands` | vector | Command definitions (slash commands). See [Commands](#commands) |
243243
| `:custom-agents` | vector | Custom agent configs. Each agent map: `:agent-name` (required), `:agent-prompt` (required), `:agent-display-name`, `:agent-description`, `:agent-tools`, `:agent-infer?`, `:agent-skills` (vector of strings), `:mcp-servers` |
@@ -258,6 +258,7 @@ Create a client and session together, ensuring both are cleaned up on exit.
258258
| `:create-session-fs-handler` | fn | Factory for session filesystem handlers. Required when `:session-fs` is set on the client. Called as `(factory session)`, returns a map of FS handler functions. See [Session Filesystem](#session-filesystem) |
259259
| `:enable-config-discovery` | boolean | Auto-discover `.mcp.json`, `.vscode/mcp.json`, skills, etc. Instruction files always load regardless. (upstream PR #1044) |
260260
| `:model-capabilities` | map | Model capabilities override. DeepPartial of model capabilities, e.g. `{:model-supports {:supports-vision true}}`. (upstream PR #1029) |
261+
| `:include-sub-agent-streaming-events?` | boolean | Forward streaming events from sub-agents to the parent session's event stream. Defaults to `true` on the wire. (upstream PR #1108) |
261262

262263
#### `resume-session`
263264

@@ -683,6 +684,7 @@ Send a message to the session. Returns immediately with the message ID.
683684
| `:prompt` | string | The message/prompt to send |
684685
| `:attachments` | vector | File attachments (see below) |
685686
| `:mode` | keyword | `:enqueue` or `:immediate` |
687+
| `:request-headers` | map | Extra HTTP headers (string→string) forwarded to the model provider for this request. Merged with provider-level `:headers`. (upstream PR #1094) |
686688

687689
**Attachment types:**
688690

src/github/copilot_sdk/client.clj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,6 +1401,10 @@
14011401
(assoc :enable-config-discovery (:enable-config-discovery config))
14021402
(:model-capabilities config)
14031403
(assoc :model-capabilities (util/clj->wire (:model-capabilities config)))
1404+
true (assoc :include-sub-agent-streaming-events
1405+
(if (some? (:include-sub-agent-streaming-events? config))
1406+
(:include-sub-agent-streaming-events? config)
1407+
true))
14041408
true (assoc :env-value-mode "direct"))))
14051409

14061410
(defn- build-resume-session-params
@@ -1464,6 +1468,10 @@
14641468
(assoc :enable-config-discovery (:enable-config-discovery config))
14651469
(:model-capabilities config)
14661470
(assoc :model-capabilities (util/clj->wire (:model-capabilities config)))
1471+
true (assoc :include-sub-agent-streaming-events
1472+
(if (some? (:include-sub-agent-streaming-events? config))
1473+
(:include-sub-agent-streaming-events? config)
1474+
true))
14671475
true (assoc :env-value-mode "direct"))))
14681476

14691477
(defn- pre-register-session

src/github/copilot_sdk/session.clj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,8 @@
499499
:prompt (:prompt opts)}
500500
trace-ctx (merge trace-ctx)
501501
wire-attachments (assoc :attachments wire-attachments)
502-
(:mode opts) (assoc :mode (name (:mode opts))))
502+
(:mode opts) (assoc :mode (name (:mode opts)))
503+
(:request-headers opts) (assoc :request-headers (:request-headers opts)))
503504
result (proto/send-request! conn "session.send" params)
504505
msg-id (:message-id result)]
505506
(log/debug "send! completed for session " session-id " message-id=" msg-id)
@@ -705,7 +706,8 @@
705706
:prompt (:prompt opts)}
706707
trace-ctx (merge trace-ctx)
707708
wire-attachments (assoc :attachments wire-attachments)
708-
(:mode opts) (assoc :mode (name (:mode opts))))
709+
(:mode opts) (assoc :mode (name (:mode opts)))
710+
(:request-headers opts) (assoc :request-headers (:request-headers opts)))
709711
response-ch (proto/send-request conn "session.send" params)
710712
[result port] (if deadline-ch
711713
(async/alts! [response-ch deadline-ch])

src/github/copilot_sdk/specs.clj

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,14 @@
250250
(s/def ::azure-options
251251
(s/keys :opt-un [::azure-api-version]))
252252

253+
;; Provider :headers — extra HTTP headers forwarded with each model request
254+
;; (upstream PR #1094, available since CLI 1.0.32). Map of header name → value.
255+
(s/def ::headers (s/map-of string? string?))
256+
253257
(s/def ::provider
254258
(s/keys :req-un [::base-url]
255-
:opt-un [::provider-type ::wire-api ::api-key ::bearer-token ::azure-options]))
259+
:opt-un [::provider-type ::wire-api ::api-key ::bearer-token ::azure-options
260+
::headers]))
256261

257262
;; -----------------------------------------------------------------------------
258263
;; Session configuration
@@ -360,6 +365,10 @@
360365
;; enableConfigDiscovery: auto-discover MCP configs, skills, instruction files (upstream PR #1044)
361366
(s/def ::enable-config-discovery boolean?)
362367

368+
;; includeSubAgentStreamingEvents: forward streaming events from sub-agents to the parent
369+
;; session's event stream (upstream PR #1108). Defaults to true on the wire.
370+
(s/def ::include-sub-agent-streaming-events? boolean?)
371+
363372
;; modelCapabilities override for session config / setModel (upstream PR #1029).
364373
;; DeepPartial<ModelCapabilities> — same shape as ::model-capabilities since all fields are already optional.
365374

@@ -371,7 +380,8 @@
371380
:disabled-skills :large-output :infinite-sessions
372381
:reasoning-effort :on-user-input-request :on-elicitation-request :hooks
373382
:working-directory :agent :on-event :create-session-fs-handler
374-
:enable-config-discovery :model-capabilities})
383+
:enable-config-discovery :model-capabilities
384+
:include-sub-agent-streaming-events?})
375385

376386
(s/def ::session-config
377387
(closed-keys
@@ -383,7 +393,8 @@
383393
::disabled-skills ::large-output ::infinite-sessions
384394
::reasoning-effort ::on-user-input-request ::on-elicitation-request ::hooks
385395
::working-directory ::agent ::on-event ::create-session-fs-handler
386-
::enable-config-discovery ::model-capabilities])
396+
::enable-config-discovery ::model-capabilities
397+
::include-sub-agent-streaming-events?])
387398
session-config-keys))
388399

389400
(def ^:private resume-session-config-keys
@@ -392,7 +403,8 @@
392403
:mcp-servers :custom-agents :config-dir :skill-directories
393404
:disabled-skills :infinite-sessions :reasoning-effort
394405
:on-user-input-request :on-elicitation-request :hooks :working-directory :disable-resume? :agent :on-event
395-
:create-session-fs-handler :enable-config-discovery :model-capabilities})
406+
:create-session-fs-handler :enable-config-discovery :model-capabilities
407+
:include-sub-agent-streaming-events?})
396408

397409
(s/def ::resume-session-config
398410
(closed-keys
@@ -403,7 +415,8 @@
403415
::disabled-skills ::infinite-sessions ::reasoning-effort
404416
::on-user-input-request ::on-elicitation-request ::hooks ::working-directory ::disable-resume? ::agent
405417
::on-event ::create-session-fs-handler
406-
::enable-config-discovery ::model-capabilities])
418+
::enable-config-discovery ::model-capabilities
419+
::include-sub-agent-streaming-events?])
407420
resume-session-config-keys))
408421

409422
;; join-session config: same as resume-session-config but :on-permission-request is optional.
@@ -417,7 +430,8 @@
417430
::disabled-skills ::infinite-sessions ::reasoning-effort
418431
::on-user-input-request ::on-elicitation-request ::hooks ::working-directory ::disable-resume? ::agent
419432
::on-event ::create-session-fs-handler
420-
::enable-config-discovery ::model-capabilities])
433+
::enable-config-discovery ::model-capabilities
434+
::include-sub-agent-streaming-events?])
421435
resume-session-config-keys))
422436

423437
;; -----------------------------------------------------------------------------
@@ -504,9 +518,13 @@
504518
(s/def ::inbound-attachments (s/coll-of ::inbound-attachment))
505519
(s/def ::mode #{:enqueue :immediate})
506520

521+
;; Per-request HTTP headers forwarded to the model provider (upstream PR #1094).
522+
;; Map of header name → value, merged with any provider-level headers.
523+
(s/def ::request-headers (s/map-of string? string?))
524+
507525
(s/def ::send-options
508526
(s/keys :req-un [::prompt]
509-
:opt-un [::attachments ::mode ::timeout-ms]))
527+
:opt-un [::attachments ::mode ::timeout-ms ::request-headers]))
510528

511529
(s/def ::timeout-ms pos-int?)
512530

@@ -566,6 +584,17 @@
566584
(s/def ::event-timestamp ::timestamp)
567585
(s/def ::parent-id (s/nilable ::non-blank-string))
568586
(s/def ::ephemeral? boolean?)
587+
;; agent-id: identifies which (sub-)agent emitted an event. Present on most events
588+
;; once sub-agent streaming is enabled (upstream PR #1108).
589+
(s/def ::agent-id string?)
590+
591+
;; canOfferSessionApproval: writeFile permission requests carry this hint indicating
592+
;; whether the CLI can present a "trust this session" option (upstream CLI 1.0.28).
593+
(s/def ::can-offer-session-approval? boolean?)
594+
595+
;; reasoningTokens: per-message / per-session tokens used for reasoning content
596+
;; (upstream CLI 1.0.32). Reported on assistant.usage and session.usage_info events.
597+
(s/def ::reasoning-tokens nat-int?)
569598

570599
;; Session log specs (upstream PR #737)
571600
(s/def ::level #{"info" "warning" "error"})
@@ -574,7 +603,7 @@
574603

575604
(s/def ::base-event
576605
(s/keys :req-un [::event-id ::event-timestamp ::parent-id]
577-
:opt-un [::ephemeral?]))
606+
:opt-un [::ephemeral? ::agent-id]))
578607

579608
;; Event type enum (namespaced under :copilot/)
580609
(s/def ::event-type

0 commit comments

Comments
 (0)