Skip to content

Commit 8a58b08

Browse files
authored
Merge pull request #32 from copilot-community-sdk/upstream-sync/require-permission-handler-v0.1.26
Port upstream PRs #554, #555, #544: require permission handler, add custom-tool kind, task_complete event
2 parents f7cbf52 + bbe312f commit 8a58b08

23 files changed

Lines changed: 401 additions & 286 deletions

CHANGELOG.md

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

44
## [Unreleased]
55

6+
### Changed (upstream PR #554 sync)
7+
- **BREAKING**: `:on-permission-request` is now **required** when calling `create-session`, `resume-session`, `<create-session`, and `<resume-session`. Calls without a handler throw `ExceptionInfo` with a descriptive message. This matches upstream Node.js SDK where `onPermissionRequest` is required in `SessionConfig` and `ResumeSessionConfig` (upstream PR #554).
8+
- `create-session` and `<create-session` no longer accept a 0-arity (no config) form — a config map with `:on-permission-request` must always be provided.
9+
- `resume-session` and `<resume-session` no longer accept a 2-arity (no config) form — a config map with `:on-permission-request` must always be provided.
10+
- All examples, tests, and documentation updated to always pass `:on-permission-request`.
11+
12+
### Added (upstream PR #555 sync)
13+
- `:custom-tool` permission kind — `::permission-kind` spec now includes `:custom-tool`, matching the upstream `PermissionRequest.kind` union type. Permission handlers will receive `{:permission-kind :custom-tool ...}` for SDK-registered custom tool invocations (upstream PR #555).
14+
15+
### Added (upstream PR #544 sync)
16+
- `:copilot/session.task_complete` event type added to `::event-type` spec (from upstream generated session event types).
17+
618
### Added (documentation)
719
- Microsoft Foundry Local BYOK provider guide in `doc/auth/byok.md`: quick start example, installation instructions, and connection troubleshooting (upstream PR #461).
820

README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ The simplest way to use the SDK is with the `query` helper:
4949
;; => "4"
5050

5151
;; With model selection
52-
(h/query "Explain monads in one sentence" :session {:model "claude-sonnet-4.5"})
52+
(h/query "Explain monads in one sentence" :session {:on-permission-request copilot/approve-all :model "claude-sonnet-4.5"})
5353

5454
;; With a system prompt
55-
(h/query "What is Clojure?" :session {:system-prompt "You are a helpful assistant. Be concise."})
55+
(h/query "What is Clojure?" :session {:on-permission-request copilot/approve-all :system-prompt "You are a helpful assistant. Be concise."})
5656
```
5757

5858
### More Control
@@ -62,7 +62,8 @@ For multi-turn conversations, pass a session instance to `query`:
6262
```clojure
6363
(require '[github.copilot-sdk :as copilot])
6464

65-
(copilot/with-client-session [session {:model "claude-haiku-4.5"}]
65+
(copilot/with-client-session [session {:on-permission-request copilot/approve-all
66+
:model "claude-haiku-4.5"}]
6667
;; Session maintains context between queries
6768
(println (h/query "What is the capital of France?" :session session))
6869
(println (h/query "What is its population?" :session session)))
@@ -71,7 +72,8 @@ For multi-turn conversations, pass a session instance to `query`:
7172
Or use the full API for maximum flexibility:
7273

7374
```clojure
74-
(copilot/with-client-session [session {:model "claude-haiku-4.5"}]
75+
(copilot/with-client-session [session {:on-permission-request copilot/approve-all
76+
:model "claude-haiku-4.5"}]
7577
(println (-> (copilot/send-and-wait! session {:prompt "What is the capital of France?"})
7678
(get-in [:data :content]))))
7779
```
@@ -86,7 +88,7 @@ Use `<send!` with core.async for non-blocking operations:
8688

8789
(copilot/with-client [client {}]
8890
;; Launch multiple requests in parallel
89-
(let [sessions (repeatedly 3 #(copilot/create-session client {}))
91+
(let [sessions (repeatedly 3 #(copilot/create-session client {:on-permission-request copilot/approve-all}))
9092
channels (map #(copilot/<send! %1 {:prompt %2})
9193
sessions
9294
["Capital of France?" "Capital of Japan?" "Capital of Brazil?"])]
@@ -226,7 +228,8 @@ await client.stop();
226228
(str "Hello, " name "!"))}))
227229

228230
(def session (copilot/create-session client
229-
{:model "claude-haiku-4.5"
231+
{:on-permission-request copilot/approve-all
232+
:model "claude-haiku-4.5"
230233
:tools [greet-tool]}))
231234

232235
(let [ch (chan 100)]

doc/getting-started.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ For more control, use the explicit client/session API:
6161
```clojure
6262
(require '[github.copilot-sdk :as copilot])
6363

64-
(copilot/with-client-session [session {:model "gpt-5.2"}]
64+
(copilot/with-client-session [session {:on-permission-request copilot/approve-all
65+
:model "gpt-5.2"}]
6566
(let [response (copilot/send-and-wait! session {:prompt "What is 2 + 2?"})]
6667
(println (get-in response [:data :content]))))
6768
```
@@ -91,7 +92,7 @@ Right now, you wait for the complete response before seeing anything. Let's make
9192
(defmethod handle-event :copilot/session.idle [_]
9293
(println))
9394

94-
(run! handle-event (h/query-seq! "Tell me a short joke" :session {:streaming? true}))
95+
(run! handle-event (h/query-seq! "Tell me a short joke" :session {:on-permission-request copilot/approve-all :streaming? true}))
9596
```
9697

9798
### Using core.async Channels
@@ -100,7 +101,8 @@ Right now, you wait for the complete response before seeing anything. Let's make
100101
(require '[clojure.core.async :refer [chan tap go-loop <!]])
101102
(require '[github.copilot-sdk :as copilot])
102103

103-
(copilot/with-client-session [session {:model "gpt-5.2" :streaming? true}]
104+
(copilot/with-client-session [session {:on-permission-request copilot/approve-all
105+
:model "gpt-5.2" :streaming? true}]
104106
(let [ch (chan 256)
105107
done (promise)]
106108
(tap (copilot/events session) ch)
@@ -133,7 +135,8 @@ Use `<create-session` and `<send!` for fully non-blocking operations inside `go`
133135
(copilot/with-client [client]
134136
(let [result-ch
135137
(go
136-
(let [session (<! (copilot/<create-session client {:model "gpt-5.2"}))]
138+
(let [session (<! (copilot/<create-session client {:on-permission-request copilot/approve-all
139+
:model "gpt-5.2"}))]
137140
(when (instance? Throwable session)
138141
(throw session))
139142
(let [answer (<! (copilot/<send! session {:prompt "Capital of France?"}))]
@@ -178,7 +181,8 @@ Now for the powerful part. Let's give Copilot the ability to call your code by d
178181
(copilot/result-success
179182
(str city ": " temp "°F and " condition))))}))
180183

181-
(copilot/with-client-session [session {:model "gpt-5.2"
184+
(copilot/with-client-session [session {:on-permission-request copilot/approve-all
185+
:model "gpt-5.2"
182186
:tools [get-weather]}]
183187
(println (h/query "What's the weather like in Seattle and Tokyo?"
184188
:session session)))
@@ -206,7 +210,8 @@ Let's put it all together into an interactive assistant:
206210
(copilot/result-success
207211
(str city ": " temp "°F and " condition))))}))
208212

209-
(copilot/with-client-session [session {:model "gpt-5.2"
213+
(copilot/with-client-session [session {:on-permission-request copilot/approve-all
214+
:model "gpt-5.2"
210215
:streaming? true
211216
:tools [get-weather]}]
212217
(println "🌤️ Weather Assistant (type 'exit' to quit)")
@@ -260,8 +265,8 @@ you provide an `:on-permission-request` handler.
260265
Use `approve-all` to permit everything:
261266

262267
```clojure
263-
(copilot/with-client-session [session {:model "gpt-5.2"
264-
:on-permission-request copilot/approve-all}]
268+
(copilot/with-client-session [session {:on-permission-request copilot/approve-all
269+
:model "gpt-5.2"}]
265270
...)
266271
```
267272

@@ -272,7 +277,8 @@ Or write a custom handler for fine-grained control. See [Permission Handling](./
272277
Pass `:client-name` to identify your application in API requests (included in the User-Agent header):
273278

274279
```clojure
275-
(copilot/with-client-session [session {:model "gpt-5.2"
280+
(copilot/with-client-session [session {:on-permission-request copilot/approve-all
281+
:model "gpt-5.2"
276282
:client-name "my-weather-app"}]
277283
...)
278284
```

0 commit comments

Comments
 (0)