Skip to content
Closed
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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. This change

## [Unreleased]

### Added (v0.1.30 sync)
- `disconnect!` function as the preferred way to close a session. Same semantics as `destroy!` — sends `session.destroy` RPC and releases in-memory resources while preserving disk state for resumption (upstream PR #599).

### Changed (v0.1.30 sync)
- `destroy!` is now deprecated and delegates to `disconnect!`. Matches upstream Node.js SDK where `destroy()` was deprecated in favor of `disconnect()` (upstream PR #599).
- `with-session` and `with-client-session` macros now call `disconnect!` instead of `destroy!` in their cleanup forms.
- `stop!` in client now internally calls `session/disconnect!` instead of `session/destroy!`.

## [0.1.30.0] - 2026-03-04
### Added (v0.1.30 sync)

Expand Down
10 changes: 10 additions & 0 deletions doc/reference/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -780,12 +780,22 @@ Alias for `switch-model!`, matching the upstream SDK's `setModel()` API.
;; After: claude-sonnet-4.5
```

#### `disconnect!`

```clojure
(copilot/disconnect! session)
```

Disconnect the session and free resources. Session data on disk is preserved for later resumption via `resume-session`. Use `delete-session!` to permanently remove session data from disk.

#### `destroy!`

```clojure
(copilot/destroy! session)
```

**Deprecated**: Use `disconnect!` instead.

Destroy the session and free resources.

#### `session-id`
Expand Down
2 changes: 1 addition & 1 deletion doc/style.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Short paragraphs (1–3 sentences). Use code blocks liberally.
- Use `h` as the alias for `github.copilot-sdk.helpers`
- Use `session` as the alias for `github.copilot-sdk.session`
- Prefer `def` over `let` in top-level examples for clarity
- Include cleanup (`stop!`, `destroy!`) in lifecycle examples
- Include cleanup (`stop!`, `disconnect!`) in lifecycle examples

### What to Avoid

Expand Down
22 changes: 17 additions & 5 deletions src/github/copilot_sdk.clj
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@
(client/<create-session client config))

(defmacro with-session
"Create a session and ensure destroy! on exit.
"Create a session and ensure disconnect! on exit.

Usage:
(with-session [s client {:on-permission-request copilot/approve-all
Expand All @@ -420,11 +420,11 @@
(try
~@body
(finally
(destroy! ~session-sym)))))
(disconnect! ~session-sym)))))

(defmacro with-client-session
"Create a client + session and ensure cleanup on exit.
Automatically calls destroy! on session and stop! on client.
Automatically calls disconnect! on session and stop! on client.

Four forms are supported:

Expand Down Expand Up @@ -666,10 +666,22 @@
[session]
(session/get-messages session))

(defn disconnect!
"Disconnect the session and free resources.
Session data on disk is preserved for later resumption via resume-session.

This is the preferred way to close a session. Use delete-session! to
permanently remove session data from disk."
[session]
(session/disconnect! session))

(defn destroy!
"Destroy the session and free resources."
"Destroy the session and free resources.

Deprecated: Use disconnect! instead. This function will be removed in a
future release."
[session]
(session/destroy! session))
(session/disconnect! session))

(defn events
"Get the event mult for this session. Use tap/untap to subscribe:
Expand Down
6 changes: 3 additions & 3 deletions src/github/copilot_sdk/client.clj
Original file line number Diff line number Diff line change
Expand Up @@ -605,13 +605,13 @@
(close! router-ch))
(swap! (:state client) assoc :router-ch nil :router-queue nil :router-thread nil)

;; 1. Destroy all sessions
;; 1. Disconnect all sessions
(doseq [[session-id _] sessions]
(try
(session/destroy! client session-id)
(session/disconnect! client session-id)
(catch Exception e
(swap! errors conj
(ex-info (str "Failed to destroy session " session-id)
(ex-info (str "Failed to disconnect session " session-id)
{:session-id session-id} e)))))
(swap! (:state client) assoc :sessions {} :session-io {})

Expand Down
8 changes: 8 additions & 0 deletions src/github/copilot_sdk/instrument.clj
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@
:args (s/cat :session ::specs/session)
:ret (s/coll-of map?))

(s/fdef github.copilot-sdk.session/disconnect!
:args (s/alt :handle (s/cat :session ::specs/session)
:explicit (s/cat :client ::specs/client
:session-id ::specs/session-id))
:ret nil?)

(s/fdef github.copilot-sdk.session/destroy!
:args (s/alt :handle (s/cat :session ::specs/session)
:explicit (s/cat :client ::specs/client
Expand Down Expand Up @@ -275,6 +281,7 @@
github.copilot-sdk.session/<send!
github.copilot-sdk.session/abort!
github.copilot-sdk.session/get-messages
github.copilot-sdk.session/disconnect!
github.copilot-sdk.session/destroy!
github.copilot-sdk.session/session-id
github.copilot-sdk.session/workspace-path
Expand Down Expand Up @@ -323,6 +330,7 @@
github.copilot-sdk.session/<send!
github.copilot-sdk.session/abort!
github.copilot-sdk.session/get-messages
github.copilot-sdk.session/disconnect!
github.copilot-sdk.session/destroy!
github.copilot-sdk.session/session-id
github.copilot-sdk.session/workspace-path
Expand Down
27 changes: 21 additions & 6 deletions src/github/copilot_sdk/session.clj
Original file line number Diff line number Diff line change
Expand Up @@ -598,13 +598,17 @@
result (proto/send-request! conn "session.getMessages" {:session-id session-id})]
(mapv #(update % :type util/event-type->keyword) (:events result)))))

(defn destroy!
"Destroy the session and free resources.
Can be called with either a CopilotSession handle or (client, session-id)."
(defn disconnect!
"Disconnect the session and free resources.
Session data on disk is preserved for later resumption via resume-session.
Can be called with either a CopilotSession handle or (client, session-id).

This is the preferred way to close a session. Use delete-session! in
client to permanently remove session data from disk."
([session]
(destroy! (:client session) (:session-id session)))
(disconnect! (:client session) (:session-id session)))
([client session-id]
(log/debug "Destroying session: " session-id)
(log/debug "Disconnecting session: " session-id)
(when-not (:destroyed? (session-state client session-id))
(let [conn (connection-io client)]
;; Try to notify server, but don't block forever if connection is broken
Expand All @@ -621,9 +625,20 @@
;; Close the event source channel - this propagates to all tapped channels
(when-let [{:keys [event-chan]} (session-io client session-id)]
(close! event-chan))
(log/debug "Session destroyed: " session-id)
(log/debug "Session disconnected: " session-id)
nil))))

(defn destroy!
"Destroy the session and free resources.
Can be called with either a CopilotSession handle or (client, session-id).

Deprecated: Use disconnect! instead. This function will be removed in a
future release. disconnect! is the preferred method for closing sessions."
([session]
(disconnect! session))
([client session-id]
(disconnect! client session-id)))

(defn events
"Get the event mult for this session. Use tap to subscribe:

Expand Down