diff --git a/CHANGELOG.md b/CHANGELOG.md index 92c397a..cdeee2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. This change ## [Unreleased] +### Added (upstream PR #605 sync) +- `:copilot/subagent.deselected` event type added to `::event-type` spec, `event-types` var, and API reference table (upstream PR #605 / CLI 0.0.420). +- `:github-reference` attachment type: represents a GitHub issue, PR, or discussion attached to a user message. Added to `::attachment-type` spec and `::attachment` spec. Data fields: `number`, `title`, `reference-type` (`"issue"/"pr"/"discussion"`), `state`, `url` (upstream PR #605). +- `::assistant.turn_start-data` spec with `turn-id` (required) and `interaction-id` (optional). +- `:interaction-id` optional field added to `::user.message-data`, `::assistant.turn_start-data`, `::assistant.message_delta-data`, and `::tool.execution_complete-data` specs (upstream PR #605). +- `:model` optional field added to `::tool.execution_complete-data` spec — model used for the tool execution (upstream PR #605). +- `:plugin-name` and `:plugin-version` optional fields added to `::skill.invoked-data` spec (upstream PR #605). + ### Added (documentation) - Azure Managed Identity BYOK guide (`doc/auth/azure-managed-identity.md`): shows how to use `DefaultAzureCredential` with short-lived bearer tokens for Azure AI Foundry, with Clojure examples for basic usage and token refresh (upstream PR #498). - Updated BYOK limitations to link to the Managed Identity workaround instead of listing it as fully unsupported. diff --git a/doc/reference/API.md b/doc/reference/API.md index 92dc366..ea09fee 100644 --- a/doc/reference/API.md +++ b/doc/reference/API.md @@ -594,6 +594,7 @@ Send a message to the session. Returns immediately with the message ID. | `:file` | `:type`, `:path` | `:display-name`, `:line-range` | File attachment | | `:directory` | `:type`, `:path` | `:display-name`, `:line-range` | Directory attachment | | `:selection` | `:type`, `:file-path`, `:display-name` | `:selection-range`, `:text` | Code selection attachment | +| `:github-reference` | `:type`, `:number`, `:title`, `:reference-type`, `:state`, `:url` | — | GitHub issue, PR, or discussion reference | `:line-range` is a map with `:start` and `:end` line numbers (zero-based) to restrict the attachment to a range of lines: @@ -887,6 +888,7 @@ copilot/tool-events | `:copilot/subagent.completed` | Subagent completed | | `:copilot/subagent.failed` | Subagent failed | | `:copilot/subagent.selected` | Subagent selected | +| `:copilot/subagent.deselected` | Subagent deselected | | `:copilot/hook.start` | Hook invocation started | | `:copilot/hook.end` | Hook invocation finished | | `:copilot/system.message` | System message emitted | diff --git a/src/github/copilot_sdk.clj b/src/github/copilot_sdk.clj index 969bf68..b65ae79 100644 --- a/src/github/copilot_sdk.clj +++ b/src/github/copilot_sdk.clj @@ -72,6 +72,7 @@ :copilot/subagent.completed :copilot/subagent.failed :copilot/subagent.selected + :copilot/subagent.deselected :copilot/skill.invoked :copilot/hook.start :copilot/hook.end diff --git a/src/github/copilot_sdk/specs.clj b/src/github/copilot_sdk/specs.clj index 6a95fd8..4c25333 100644 --- a/src/github/copilot_sdk/specs.clj +++ b/src/github/copilot_sdk/specs.clj @@ -240,7 +240,7 @@ ;; ----------------------------------------------------------------------------- (s/def ::prompt ::non-blank-string) -(s/def ::attachment-type #{:file :directory :selection}) +(s/def ::attachment-type #{:file :directory :selection :github-reference}) (s/def ::type ::attachment-type) (s/def ::path ::non-blank-string) (s/def ::file-path ::non-blank-string) @@ -274,9 +274,26 @@ :opt-un [::selection-range ::text]) #(= :selection (:type %)))) +;; GitHub reference attachment (issue, PR, or discussion) +;; Note: ::state is already defined as (instance? Atom) for the client record, +;; so we cannot use s/keys here — manual predicates validate the :state field instead. +(s/def ::number nat-int?) +(s/def ::reference-type #{"issue" "pr" "discussion"}) +(s/def ::url string?) +(s/def ::attachment-state string?) +(s/def ::github-reference-attachment + (s/and map? + #(= :github-reference (:type %)) + #(nat-int? (:number %)) + #(string? (:title %)) + #(contains? #{"issue" "pr" "discussion"} (:reference-type %)) + #(string? (:state %)) + #(string? (:url %)))) + (s/def ::attachment (s/or :file-or-directory ::file-or-directory-attachment - :selection ::selection-attachment)) + :selection ::selection-attachment + :github-reference ::github-reference-attachment)) (s/def ::attachments (s/coll-of ::attachment)) (s/def ::mode #{:enqueue :immediate}) @@ -365,6 +382,7 @@ :copilot/tool.user_requested :copilot/tool.execution_start :copilot/tool.execution_partial_result :copilot/tool.execution_progress :copilot/tool.execution_complete :copilot/subagent.started :copilot/subagent.completed :copilot/subagent.failed :copilot/subagent.selected + :copilot/subagent.deselected :copilot/skill.invoked :copilot/hook.start :copilot/hook.end :copilot/system.message}) @@ -381,20 +399,26 @@ (s/def ::session.idle-data map?) (s/def ::agent-mode #{:interactive :plan :autopilot :shell}) +(s/def ::interaction-id string?) (s/def ::user.message-data (s/keys :req-un [::content] - :opt-un [::transformed-content ::attachments ::source ::agent-mode])) + :opt-un [::transformed-content ::attachments ::source ::agent-mode ::interaction-id])) (s/def ::assistant.message-data (s/keys :req-un [::message-id ::content] :opt-un [::tool-requests ::parent-tool-call-id])) (s/def ::total-response-size-bytes nat-int?) +(s/def ::turn-id ::non-blank-string) + +(s/def ::assistant.turn_start-data + (s/keys :req-un [::turn-id] + :opt-un [::interaction-id])) (s/def ::assistant.message_delta-data (s/keys :req-un [::message-id ::delta-content] - :opt-un [::parent-tool-call-id])) + :opt-un [::parent-tool-call-id ::interaction-id])) (s/def ::assistant.streaming_delta-data (s/keys :req-un [::total-response-size-bytes])) @@ -410,7 +434,8 @@ (s/def ::tool.execution_complete-data (s/keys :req-un [::tool-call-id ::success?] - :opt-un [::is-user-requested? ::result ::error ::tool-telemetry ::parent-tool-call-id])) + :opt-un [::is-user-requested? ::result ::error ::tool-telemetry ::parent-tool-call-id + ::model ::interaction-id])) ;; Session shutdown event (s/def ::shutdown-type #{"routine" "error"}) @@ -465,10 +490,12 @@ ;; Skill invoked event (s/def ::allowed-tools (s/coll-of string?)) +(s/def ::plugin-name string?) +(s/def ::plugin-version string?) (s/def ::skill.invoked-data (s/keys :req-un [::name ::path ::content] - :opt-un [::allowed-tools])) + :opt-un [::allowed-tools ::plugin-name ::plugin-version])) ;; Generic session event (s/def ::session-event @@ -641,4 +668,5 @@ ;; Session model operations (session.model.getCurrent / switchTo) ;; ----------------------------------------------------------------------------- +(s/def ::model string?) (s/def ::model-id (s/nilable string?)) diff --git a/src/github/copilot_sdk/util.clj b/src/github/copilot_sdk/util.clj index 7be98fe..147f773 100644 --- a/src/github/copilot_sdk/util.clj +++ b/src/github/copilot_sdk/util.clj @@ -97,6 +97,14 @@ (:selection-range att) (assoc :selection (clj->wire (:selection-range att))) (:text att) (assoc :text (:text att))) + :github-reference + {:type "github_reference" + :number (:number att) + :title (:title att) + :referenceType (name (:reference-type att)) + :state (:state att) + :url (:url att)} + ;; :file and :directory (cond-> {:type (name (:type att)) :path (:path att)}