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
2 changes: 1 addition & 1 deletion .copilot-schema-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.70
1.0.71-2
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,29 @@ All notable changes to this project will be documented in this file. This change

## [Unreleased]

### Added (v1.0.7-preview.2 post-release sync)
- **Opaque tool-definition metadata** — port of upstream
[PR #1864](https://github.com/github/copilot-sdk/pull/1864). `define-tool` and
`define-tool-from-spec` accept an optional `:metadata` map and forward its
host-defined contents on `session.create` and `session.resume`.
- **Tool-search configuration and metadata** — port of upstream
[PR #1933](https://github.com/github/copilot-sdk/pull/1933). Session create,
resume, and join configs accept `:tool-search` with optional `:enabled` and
`:defer-threshold`. A `tool_search_tool` override receives the current tool
metadata snapshot in `:available-tools`: each entry has `:name` and
`:description`, plus optional `:namespaced-name`, `:mcp-server-name`,
`:mcp-tool-name`, `:input-schema`, and `:defer-loading`. Tool result maps may
return `:tool-references`.
- **Schema regen to 1.0.71-2** — port of upstream schema updates
[`edbe6c66`](https://github.com/github/copilot-sdk/commit/edbe6c662a78216147cfae1a19c6d127f1e94797)
(1.0.71-0) and
[`9744fd52`](https://github.com/github/copilot-sdk/commit/9744fd52b2692aea35b72d263280c18319e2a6c1)
(1.0.71-2). Bumped `.copilot-schema-version` from `1.0.70` to `1.0.71-2`
and regenerated wire specs and coercions. The curated public idiom adds
optional canvas `:icon` paths and model-billing
`:promo` maps (`:ends-at`, with optional `:id`, `:discount-percent`, and
`:message`). No new public session event type was added.

## [1.0.7-preview.2.1] - 2026-07-15
### Added
- **API-surface drift guard** ([#120](https://github.com/copilot-community-sdk/copilot-sdk-clojure/issues/120)) —
Expand Down
158 changes: 149 additions & 9 deletions doc/api/API.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions doc/api/getting-started.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ <h2><a href="#prerequisites" id="prerequisites"></a>Prerequisites</h2>
</code></pre>
<h2><a href="#step-1-add-the-sdk-dependency" id="step-1-add-the-sdk-dependency"></a>Step 1: Add the SDK Dependency</h2>
<p>Add to your <code>deps.edn</code>:</p>
<pre><code class="language-clojure">{:deps {io.github.copilot-community-sdk/copilot-sdk-clojure {:mvn/version "1.0.5.0"}}}
<pre><code class="language-clojure">{:deps {io.github.copilot-community-sdk/copilot-sdk-clojure {:mvn/version "1.0.7-preview.2.1"}}}
</code></pre>
<p>Or use as a Git dependency:</p>
<pre><code class="language-clojure">{:deps {io.github.copilot-community-sdk/copilot-sdk-clojure
{:git/url "https://github.com/copilot-community-sdk/copilot-sdk-clojure"
:git/sha "169015a303443713a733b84a1d69623d83d20688"}}}
:git/sha "4702318e3be76c66e96a2942d4da52a4014c0758"}}}
</code></pre>
<h2><a href="#step-2-send-your-first-message" id="step-2-send-your-first-message"></a>Step 2: Send Your First Message</h2>
<p>The simplest way to use the SDK — about 3 lines of code:</p>
Expand Down
8 changes: 4 additions & 4 deletions doc/api/github.copilot-sdk.client.html

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions doc/api/github.copilot-sdk.helpers.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ <h2><a href="#options" id="options"></a>Options</h2>
<p>Returns a channel that yields event maps. The channel closes when the session becomes idle or errors.</p>
<p>Examples: (let <a href="ch (query-chan &quot;Tell me a story&quot; :session {:on-permission-request copilot/approve-all
:streaming? true})">ch (query-chan “Tell me a story” :session {:on-permission-request copilot/approve-all :streaming? true})</a> (go-loop [] (when-let <a href="event (&lt;! ch)">event (&lt;! ch)</a> (when (= :copilot/assistant.message_delta (:type event)) (print (get-in event <a href=":data :delta-content">:data :delta-content</a>))) (recur))))</p>
</div></div></div><div class="public anchor" id="var-query-seq.21"><h3>query-seq!</h3><div class="usage"><code>(query-seq! prompt &amp; {:keys [client session max-events], :or {max-events 256}})</code></div><div class="doc"><div class="markdown"><p>Execute a query and return a lazy sequence of events with guaranteed cleanup.</p>
<p>This variant limits consumption and ensures the session is disconnected even if the consumer stops early.</p>
</div></div></div><div class="public anchor" id="var-query-seq.21"><h3>query-seq!</h3><div class="usage"><code>(query-seq! prompt &amp; {:keys [client session max-events], :or {max-events 256}})</code></div><div class="doc"><div class="markdown"><p>Execute a query and return a bounded lazy sequence of events.</p>
<p>Cleanup (session disconnect) happens only when the sequence is realized all the way to the end of the event stream: either a <code>:copilot/session.idle</code> / <code>:copilot/session.error</code> event, or the events channel closing — detected when the next read yields <code>nil</code> (the end-of-stream sentinel, not an emitted event). Consuming the whole seq to its natural end releases the session and its event tap.</p>
<p>WARNING: cleanup is tied to reaching that end of stream, so a consumer that abandons the seq before it reaches a terminal event leaks the session and its event tap. For example <code>(first (query-seq! ...))</code> or <code>(take 1 (query-seq! ...))</code> realize just one element: they leak unless that first element already happens to be a terminal <code>:copilot/session.idle</code> / <code>:copilot/session.error</code> event (realizing the terminal event runs cleanup). The <code>:max-events</code> bound only caps how many events are yielded — it is not a cleanup guarantee; hitting a positive bound before a terminal event still leaks the session (the sole exception is <code>:max-events 0</code>, which disconnects immediately without emitting anything). Only use <code>query-seq!</code> when you will consume the sequence to its natural end. If you may stop early, prefer <code>query-chan</code> (explicit lifecycle — safe to stop early <em>provided you close the returned channel</em>) or <code>query</code> (single response, deterministic cleanup).</p>
<p>Keyword options: :client - Client options map :session - Session options map :max-events - Maximum number of events to emit (default: 256)</p>
<p>Returns a lazy sequence of at most :max-events events.</p>
</div></div></div><div class="public anchor" id="var-shutdown.21"><h3>shutdown!</h3><div class="usage"><code>(shutdown!)</code></div><div class="doc"><div class="markdown"><p>Shutdown the shared client. Call for clean exit. Safe to call multiple times or when no client exists.</p>
Expand Down
15 changes: 8 additions & 7 deletions doc/api/github.copilot-sdk.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
(println (get-in event [:data :content]))))
</code></pre>
</div></div></div><div class="public anchor" id="var-abort.21"><h3>abort!</h3><div class="usage"><code>(abort! session)</code></div><div class="doc"><div class="markdown"><p>Abort the currently processing message in this session.</p>
</div></div></div><div class="public anchor" id="var-approve-all"><h3>approve-all</h3><div class="usage"></div><div class="doc"><div class="markdown"><p>Permission handler that approves all requests with <code>{:kind :approve-once}</code>. See <code>github.copilot-sdk.client/approve-all</code>.</p>
</div></div></div><div class="public anchor" id="var-approve-all"><h3>approve-all</h3><div class="usage"><code>(approve-all request ctx)</code></div><div class="doc"><div class="markdown"><p>Permission handler that approves all requests with <code>{:kind :approve-once}</code>. See <code>github.copilot-sdk.client/approve-all</code>.</p>
</div></div></div><div class="public anchor" id="var-assistant-events"><h3>assistant-events</h3><div class="usage"></div><div class="doc"><div class="markdown"><p>Assistant response events.</p>
</div></div></div><div class="public anchor" id="var-capabilities"><h3>capabilities</h3><div class="usage"><code>(capabilities session)</code></div><div class="doc"><div class="markdown"><p>Get the host capabilities reported when the session was created or resumed. Returns a map, e.g. <code>{:ui {:elicitation true}}</code>.</p>
<p>Example:</p>
Expand All @@ -82,7 +82,7 @@
</code></pre>
</div></div></div><div class="public anchor" id="var-convert-mcp-call-tool-result"><h3>convert-mcp-call-tool-result</h3><div class="usage"><code>(convert-mcp-call-tool-result result)</code></div><div class="doc"><div class="markdown"><p>Convert an MCP CallToolResult into the SDK’s ToolResultObject format. See <code>github.copilot-sdk.tools/convert-mcp-call-tool-result</code>.</p>
</div></div></div><div class="public anchor" id="var-create-session"><h3>create-session</h3><div class="usage"><code>(create-session client config)</code></div><div class="doc"><div class="markdown"><p>Create a new conversation session.</p>
<p><code>:on-permission-request</code> is <strong>optional</strong> (since upstream PR #1308) — omit it to leave permission requests pending for manual resolution via <code>handle-pending-permission-request!</code>. Commonly-used config options: - :on-permission-request - Permission handler function (optional, e.g. <code>approve-all</code>). When omitted, permission requests surface as <code>:copilot/permission.requested</code> events and stay pending. - :session-id - Custom session ID - :model - Model to use (e.g., “gpt-5.4”, “claude-sonnet-4.5”) - :tools - Vector of tool definitions (use define-tool) - :system-message - {:mode :append/:replace :content “…”} - :available-tools - List of allowed tool names - :excluded-tools - List of excluded tool names - :provider - Custom provider config (BYOK) - :streaming? - Enable streaming deltas - :mcp-servers - MCP server configs map (keyed by server ID) - :custom-agents - Custom agent configs - :default-agent - Built-in agent config, e.g. {:excluded-tools <a href="&quot;private_tool&quot;">“private_tool”</a>} - :skill-directories - Additional skill directories to load - :disabled-skills - Disable specific skills by name - :working-directory - Working directory for the session (tool operations relative to this)</p>
<p><code>:on-permission-request</code> is <strong>optional</strong> (since upstream PR #1308) — omit it to leave permission requests pending for manual resolution via <code>handle-pending-permission-request!</code>. Commonly-used config options: - :on-permission-request - Permission handler function (optional, e.g. <code>approve-all</code>). When omitted, permission requests surface as <code>:copilot/permission.requested</code> events and stay pending. - :session-id - Custom session ID - :model - Model to use (e.g., “gpt-5.4”, “claude-sonnet-4.5”) - :tools - Vector of tool definitions (use define-tool) - :system-message - {:mode :append/:replace :content “…”} - :available-tools - List of allowed tool names - :excluded-tools - List of excluded tool names - :tool-search - Tool discovery config {:enabled :defer-threshold} - :provider - Custom provider config (BYOK) - :streaming? - Enable streaming deltas - :mcp-servers - MCP server configs map (keyed by server ID) - :custom-agents - Custom agent configs - :default-agent - Built-in agent config, e.g. {:excluded-tools <a href="&quot;private_tool&quot;">“private_tool”</a>} - :skill-directories - Additional skill directories to load - :disabled-skills - Disable specific skills by name - :working-directory - Working directory for the session (tool operations relative to this)</p>
<p>See the API reference (doc/reference/API.md in this repository) for the complete, current option list (including observability/telemetry, trace context, exit-plan-mode / auto-mode-switch handlers, skills, plugins, remote, and cloud session options).</p>
<p>Example:</p>
<pre><code class="language-clojure">(def session (copilot/create-session client {:on-permission-request copilot/approve-all
Expand All @@ -97,10 +97,11 @@
;; implement the remaining sessionFs operations...
})
</code></pre>
</div></div></div><div class="public anchor" id="var-default-join-session-permission-handler"><h3>default-join-session-permission-handler</h3><div class="usage"></div><div class="doc"><div class="markdown"><p>Default permission handler for resuming sessions. Returns <code>{:kind :no-result}</code> — the CLI handles permissions itself. When used with <code>resume-session</code>, sends <code>requestPermission: false</code> on the wire. See <code>github.copilot-sdk.client/default-join-session-permission-handler</code>.</p>
</div></div></div><div class="public anchor" id="var-default-join-session-permission-handler"><h3>default-join-session-permission-handler</h3><div class="usage"><code>(default-join-session-permission-handler request ctx)</code></div><div class="doc"><div class="markdown"><p>Default permission handler for resuming sessions. Returns <code>{:kind :no-result}</code> — the CLI handles permissions itself. When used with <code>resume-session</code>, sends <code>requestPermission: false</code> on the wire. See <code>github.copilot-sdk.client/default-join-session-permission-handler</code>.</p>
</div></div></div><div class="public anchor" id="var-define-tool"><h3>define-tool</h3><div class="usage"><code>(define-tool name opts)</code></div><div class="doc"><div class="markdown"><p>Define a tool with a handler function.</p>
<p>Arguments: - name - Tool name (string) - opts map: - :description - Tool description - :parameters - JSON schema for parameters - :handler - Function (fn <a href="args invocation">args invocation</a> -&gt; result) - :overrides-built-in-tool - When true, overrides a built-in tool of the same name - :defer - <code>:auto</code> or <code>:never</code> (upstream PR #1632). When <code>:auto</code> the tool may be deferred (loaded lazily via tool search); <code>:never</code> forces pre-loading. Defaults to <code>:auto</code>.</p>
<p>The handler receives: - args - The parsed arguments from the LLM - invocation - Map with :session-id, :tool-call-id, :tool-name, :arguments</p>
<p>Arguments: - name - Tool name (string) - opts map: - :description - Tool description - :parameters - JSON schema for parameters - :handler - Function (fn <a href="args invocation">args invocation</a> -&gt; result) - :overrides-built-in-tool - When true, overrides a built-in tool of the same name - :defer - <code>:auto</code> or <code>:never</code> (upstream PR #1632). When <code>:auto</code> the tool may be deferred (loaded lazily via tool search); <code>:never</code> forces pre-loading. Defaults to <code>:auto</code>. - :metadata - Opaque host-defined map forwarded to the runtime</p>
<p>The handler receives: - args - The parsed arguments from the LLM - invocation - Map with :session-id, :tool-call-id, :tool-name, :arguments, and optional :available-tools for <code>tool_search_tool</code></p>
<p>Return a string, or a tool result map with <code>:text-result-for-llm</code>, <code>:result-type</code>, and optional <code>:tool-references</code>.</p>
<p>Returns: a tool definition map</p>
<p>Example:</p>
<pre><code class="language-clojure">(def weather-tool
Expand Down Expand Up @@ -219,7 +220,7 @@
(copilot/stop! client))
</code></pre>
</div></div></div><div class="public anchor" id="var-list-models"><h3>list-models</h3><div class="usage"><code>(list-models client)</code></div><div class="doc"><div class="markdown"><p>List available models with their metadata. Requires authentication.</p>
<p>Returns a vector of model info maps with keys: :id :name :vendor :family :version :max-input-tokens :max-output-tokens :preview? :default-temperature :model-picker-priority :model-policy :vision-limits {:supported-media-types :max-prompt-images :max-prompt-image-size}</p>
<p>Returns a vector of model info maps with keys: :id :name :vendor :family :version :max-input-tokens :max-output-tokens :preview? :default-temperature :model-picker-priority :model-policy :model-billing {:multiplier :token-prices :promo {:ends-at :id :discount-percent :message}} :vision-limits {:supported-media-types :max-prompt-images :max-prompt-image-size}</p>
<p>Example:</p>
<pre><code class="language-clojure">(doseq [model (copilot/list-models client)]
(println (:name model) "-" (:id model)))
Expand Down Expand Up @@ -266,7 +267,7 @@
(unsub)
</code></pre>
</div></div></div><div class="public anchor" id="var-open-canvases"><h3>open-canvases</h3><div class="usage"><code>(open-canvases session)</code></div><div class="doc"><div class="markdown"><p>Get the current open-canvases snapshot for <code>session</code>. Returns a vector of canvas-instance maps. The snapshot is initialized from <code>session.resume</code> and updated by <code>:copilot/session.canvas.opened</code> / <code>:copilot/session.canvas.closed</code> events. <code>session.create</code> does NOT populate it (matches upstream Node.js).</p>
<p>Each entry has required keys <code>:instance-id</code>, <code>:extension-id</code>, <code>:canvas-id</code> and optional <code>:extension-name</code>, <code>:title</code>, <code>:status</code>, <code>:url</code>, <code>:input</code>.</p>
<p>Each entry has required keys <code>:instance-id</code>, <code>:extension-id</code>, <code>:canvas-id</code> and optional <code>:extension-name</code>, <code>:icon</code>, <code>:title</code>, <code>:status</code>, <code>:url</code>, <code>:input</code>.</p>
<p>Example:</p>
<pre><code class="language-clojure">(copilot/open-canvases session)
;; =&gt; [{:instance-id "i1" :canvas-id "diff" :extension-id "ext.x"
Expand Down
Loading