From 9a8a1af0b701ded5bde461c2cdb7ec403501995b Mon Sep 17 00:00:00 2001 From: Karl Krukow Date: Fri, 20 Feb 2026 07:38:24 +0100 Subject: [PATCH 1/2] Add update script to gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 62127d4..99a8809 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,5 @@ prompt.md *.asc plan.md +update.sh + From 83d4efe8b6faf65c51d603504bfda00dbbb96aee Mon Sep 17 00:00:00 2001 From: Karl Krukow Date: Fri, 20 Feb 2026 07:56:01 +0100 Subject: [PATCH 2/2] feat: add :client-name to session config (upstream PR #510) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add :client-name as an optional field to SessionConfig and ResumeSessionConfig. This allows SDK consumers to identify their application, which is included in the User-Agent header for API requests. The CLI server protocol already supports clientName on both session.create and session.resume requests — this change exposes it through the Clojure SDK API. Changes: - specs.clj: ::client-name spec, added to both config key sets - client.clj: forward :client-name in wire param builders, docstrings - integration_test.clj: 3 wire format tests (create, resume, omission) - API.md: added to session config table - CHANGELOG.md: entry under [Unreleased] Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CHANGELOG.md | 3 ++ doc/reference/API.md | 1 + src/github/copilot_sdk/client.clj | 4 +++ src/github/copilot_sdk/specs.clj | 10 ++++--- test/github/copilot_sdk/integration_test.clj | 29 ++++++++++++++++++++ 5 files changed, 43 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b89e585..b1ceba3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file. This change ## [Unreleased] +### Added (upstream PR #510 sync) +- `:client-name` option for `create-session` and `resume-session` — identifies the application using the SDK, included in the User-Agent header for API requests. Forwarded as `clientName` on the wire (upstream PR #510). + ### Changed (upstream PR #509 sync) - **BREAKING**: Deny all permissions by default — `requestPermission` is now always `true` on the wire, and permission requests are denied when no `:on-permission-request` handler is configured. Previously, omitting the handler meant the CLI never asked for permission. To restore the old behavior, pass `:on-permission-request copilot/approve-all` in your session config. diff --git a/doc/reference/API.md b/doc/reference/API.md index c39e234..010069e 100644 --- a/doc/reference/API.md +++ b/doc/reference/API.md @@ -214,6 +214,7 @@ Create a client and session together, ensuring both are cleaned up on exit. | Key | Type | Description | |-----|------|-------------| | `:session-id` | string | Custom session ID (optional) | +| `:client-name` | string | Client name to identify the application (included in User-Agent header) | | `:model` | string | Model to use (`"gpt-5.2"`, `"claude-sonnet-4.5"`, etc.) | | `:tools` | vector | Custom tools exposed to the CLI | | `:system-message` | map | System message customization (see below) | diff --git a/src/github/copilot_sdk/client.clj b/src/github/copilot_sdk/client.clj index 588c811..3384041 100644 --- a/src/github/copilot_sdk/client.clj +++ b/src/github/copilot_sdk/client.clj @@ -951,6 +951,7 @@ (util/clj->wire is))] (cond-> {} (:session-id config) (assoc :session-id (:session-id config)) + (:client-name config) (assoc :client-name (:client-name config)) (:model config) (assoc :model (:model config)) wire-tools (assoc :tools wire-tools) wire-sys-msg (assoc :system-message wire-sys-msg) @@ -998,6 +999,7 @@ wire-infinite-sessions (when-let [is (:infinite-sessions config)] (util/clj->wire is))] (cond-> {:session-id session-id} + (:client-name config) (assoc :client-name (:client-name config)) (:model config) (assoc :model (:model config)) wire-tools (assoc :tools wire-tools) wire-sys-msg (assoc :system-message wire-sys-msg) @@ -1037,6 +1039,7 @@ Config options: - :session-id - Custom session ID + - :client-name - Client name to identify the application (included in User-Agent header) - :model - Model to use (e.g., \"gpt-5.2\") - :tools - Vector of tool definitions - :system-message - System message config @@ -1081,6 +1084,7 @@ "Resume an existing session by ID. Config options (parity with create-session, upstream PR #376): + - :client-name - Client name to identify the application (included in User-Agent header) - :model - Change the model for the resumed session - :tools - Tools exposed to the CLI server - :system-message - System message configuration {:mode :content} diff --git a/src/github/copilot_sdk/specs.clj b/src/github/copilot_sdk/specs.clj index dbd3145..bb71dc3 100644 --- a/src/github/copilot_sdk/specs.clj +++ b/src/github/copilot_sdk/specs.clj @@ -195,8 +195,10 @@ ;; Disable resume flag (s/def ::disable-resume? boolean?) +(s/def ::client-name ::non-blank-string) + (def session-config-keys - #{:session-id :model :tools :system-message + #{:session-id :client-name :model :tools :system-message :available-tools :excluded-tools :provider :on-permission-request :streaming? :mcp-servers :custom-agents :config-dir :skill-directories @@ -206,7 +208,7 @@ (s/def ::session-config (closed-keys - (s/keys :opt-un [::session-id ::model ::tools ::system-message + (s/keys :opt-un [::session-id ::client-name ::model ::tools ::system-message ::available-tools ::excluded-tools ::provider ::on-permission-request ::streaming? ::mcp-servers ::custom-agents ::config-dir ::skill-directories @@ -216,7 +218,7 @@ session-config-keys)) (def ^:private resume-session-config-keys - #{:model :tools :system-message :available-tools :excluded-tools + #{:client-name :model :tools :system-message :available-tools :excluded-tools :provider :streaming? :on-permission-request :mcp-servers :custom-agents :config-dir :skill-directories :disabled-skills :infinite-sessions :reasoning-effort @@ -224,7 +226,7 @@ (s/def ::resume-session-config (closed-keys - (s/keys :opt-un [::model ::tools ::system-message ::available-tools ::excluded-tools + (s/keys :opt-un [::client-name ::model ::tools ::system-message ::available-tools ::excluded-tools ::provider ::streaming? ::on-permission-request ::mcp-servers ::custom-agents ::config-dir ::skill-directories ::disabled-skills ::infinite-sessions ::reasoning-effort diff --git a/test/github/copilot_sdk/integration_test.clj b/test/github/copilot_sdk/integration_test.clj index 21d0d66..9b8e46f 100644 --- a/test/github/copilot_sdk/integration_test.clj +++ b/test/github/copilot_sdk/integration_test.clj @@ -626,6 +626,35 @@ (is (= "direct" (:envValueMode create-params))) (is (= "direct" (:envValueMode resume-params)))))) +(deftest test-client-name-forwarded-on-wire + (testing "clientName is forwarded in session.create when set (upstream PR #510)" + (let [seen (atom {}) + _ (mock/set-request-hook! *mock-server* (fn [method params] + (when (#{"session.create"} method) + (swap! seen assoc method params)))) + _ (sdk/create-session *test-client* {:client-name "my-app"}) + create-params (get @seen "session.create")] + (is (= "my-app" (:clientName create-params))))) + + (testing "clientName is forwarded in session.resume when set (upstream PR #510)" + (let [seen (atom {}) + session-id (sdk/session-id (sdk/create-session *test-client* {})) + _ (mock/set-request-hook! *mock-server* (fn [method params] + (when (#{"session.resume"} method) + (swap! seen assoc method params)))) + _ (sdk/resume-session *test-client* session-id {:client-name "my-app"}) + resume-params (get @seen "session.resume")] + (is (= "my-app" (:clientName resume-params))))) + + (testing "clientName is omitted from wire when not set" + (let [seen (atom {}) + _ (mock/set-request-hook! *mock-server* (fn [method params] + (when (#{"session.create"} method) + (swap! seen assoc method params)))) + _ (sdk/create-session *test-client* {:model "gpt-5.2"}) + create-params (get @seen "session.create")] + (is (not (contains? create-params :clientName)))))) + ;; ----------------------------------------------------------------------------- ;; Permission Tests (upstream PR #509: deny-by-default) ;; -----------------------------------------------------------------------------