Skip to content

Port upstream PRs #908, #916, #917, #970: elicitation provider, sessionFs, event fields#81

Merged
krukow merged 3 commits intomainfrom
upstream-sync/v0.2.1-batch
Apr 3, 2026
Merged

Port upstream PRs #908, #916, #917, #970: elicitation provider, sessionFs, event fields#81
krukow merged 3 commits intomainfrom
upstream-sync/v0.2.1-batch

Conversation

@krukow
Copy link
Copy Markdown
Collaborator

@krukow krukow commented Apr 2, 2026

Summary

Ports four upstream github/copilot-sdk PRs in a single batch, with 3 rounds of multi-model code review (Opus 4.6, GPT-5.4, Goldeneye) that caught and fixed 11 issues before submission.

Upstream Changes Ported

PR #908 — Elicitation Provider Support

  • :on-elicitation-request handler on SessionConfig and ResumeSessionConfig
  • Sends requestElicitation: true in session create/resume RPC when handler is provided
  • Handles elicitation.requested broadcast events → invokes handler → responds via session.ui.handlePendingElicitation RPC
  • Handler errors automatically send {:action "cancel"} to prevent hanging
  • capabilities.changed broadcast handling with deep-merge (state updated before event publish so observers see consistent state)
  • BREAKING: ::steerable? renamed to ::remote-steerable? (upstream wire field rename)
  • New event types: sampling.requested, sampling.completed, session.remote_steerable_changed, capabilities.changed

PR #916 — Event Payload Field Updates

  • skill.invoked: optional :description field
  • subagent.started/completed/failed: :agent-name, :agent-display-name, :agent-description, :model, :total-tool-calls, :total-tokens, :duration-ms
  • session.custom_agents_updated: full payload spec with :agents array, :warnings, :errors

PR #917 — SessionFs Virtual Filesystem

  • :session-fs client option ({:initial-cwd :session-state-path :conventions})
  • Calls sessionFs.setProvider RPC on connect (both start! and connect-with-streams!)
  • :create-session-fs-handler on session config — factory (fn [session] → handler-map) required when sessionFs is enabled
  • Dispatches 10 sessionFs.* RPC operations (readFile, writeFile, appendFile, exists, stat, mkdir, readdir, readdirWithTypes, rm, rename) to per-session handler maps
  • aborted? field on session.task_complete event data
  • All 4 session creation paths (sync/async × create/resume) handle sessionFs with proper cleanup on failure

PR #970 — Timeout Result Type

  • Added :timeout/"timeout" to ::result-type spec

Code Review Process

3 rounds of parallel multi-model review (Claude Opus 4.6, GPT-5.4, Goldeneye):

Round Issues Found Fixed
R1 6 (double clj->wire, spec mismatch, shallow merge, async gaps, zombie sessions, wrong field names) 6
R2 4 (agent-name redefinition, tools spec clash, event ordering, startup race) 3 (1 skipped — matches upstream)
R3 2 (async factory leak, connect-with-streams missing setProvider) 2

Supersedes

This PR supersedes the following automated upstream-sync draft PRs:

Testing

  • 114 tests, 366 assertions, 0 failures
  • 12 doc files validated, 0 warnings
  • All 18 examples pass (including new elicitation_provider.clj)
  • Integration tests cover: elicitation handler routing, error→cancel fallback, capabilities.changed state updates, requestElicitation wire flag, sessionFs handler storage

Files Changed

File Changes
src/github/copilot_sdk/client.clj Elicitation broadcast handler, sessionFs dispatch, capabilities.changed, wire params
src/github/copilot_sdk/session.clj Elicitation/sessionFs handlers, deep-merge capabilities, handler storage
src/github/copilot_sdk/specs.clj New specs for all features, corrected subagent/custom-agent specs
src/github/copilot_sdk.clj New event types in event sets
doc/reference/API.md Elicitation Provider and Session Filesystem sections, updated event reference
test/.../integration_test.clj 5 new tests for elicitation provider, capabilities, sessionFs
examples/elicitation_provider.clj New example with auto-approve handler
CHANGELOG.md All changes documented under [Unreleased]

… fields, sessionFs, timeout result-type

Elicitation Provider (PR #908):
- Add :on-elicitation-request handler to SessionConfig/ResumeSessionConfig
- Send requestElicitation flag in create/resume RPC
- Handle elicitation.requested broadcast → call handler → respond via
  session.ui.handlePendingElicitation (cancel on error)
- Handle capabilities.changed broadcast with deep-merge (state updated
  before event publish so observers see consistent state)
- Rename steerable → remote-steerable (BREAKING, upstream wire rename)
- Add event types: sampling.requested/completed,
  session.remote_steerable_changed, capabilities.changed

Event Payload Fields (PR #916):
- skill.invoked: add optional :description
- subagent.started/completed/failed: add :agent-name, :agent-description,
  :model, :total-tool-calls, :total-tokens, :duration-ms
- session.custom_agents_updated: full payload spec with :agents array,
  :warnings, :errors

SessionFs Virtual Filesystem (PR #917):
- Add :session-fs client option (initial-cwd, session-state-path, conventions)
- Call sessionFs.setProvider RPC on connect (start! and connect-with-streams!)
- Add :create-session-fs-handler to session config (required when sessionFs enabled)
- Dispatch 10 sessionFs.* RPC operations to per-session handler maps
- Add aborted? to session.task_complete event data
- All 4 session creation paths (sync/async × create/resume) handle sessionFs
  with proper cleanup on failure

Timeout Result Type (PR #970):
- Add :timeout/"timeout" to ::result-type spec

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 2, 2026 15:48
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Ports four upstream github/copilot-sdk PRs into the Clojure SDK, adding elicitation provider support, SessionFs virtual filesystem support, and expanded event payload/spec coverage while keeping protocol v3 behavior aligned.

Changes:

  • Add :on-elicitation-request support (wire flag + v3 broadcast handling + capabilities merge) and document/example it.
  • Add SessionFs provider support (:session-fs client option, sessionFs.setProvider, dispatch of sessionFs.* RPCs via per-session handler maps).
  • Update specs/docs/changelog for new/updated event fields and tool result type "timeout".

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/github/copilot_sdk/client.clj Adds v3 elicitation broadcast handler, capabilities.changed state application, and SessionFs RPC provider registration + request routing.
src/github/copilot_sdk/session.clj Stores elicitation/SessionFs handlers in session state; adds SessionFs dispatcher; deep-merge capabilities updates.
src/github/copilot_sdk/specs.clj Adds specs for SessionFs config, elicitation request, new/updated events, and "timeout" tool result type.
src/github/copilot_sdk.clj Extends event sets to include sampling/capabilities/remote-steerable related events.
doc/reference/API.md Documents :session-fs, elicitation provider, and updated event payload fields.
test/github/copilot_sdk/integration_test.clj Adds integration tests covering elicitation wire flag, v3 elicitation routing, handler error→cancel, and capabilities.changed update.
examples/elicitation_provider.clj New example demonstrating elicitation provider handler and event observation.
examples/README.md Documents the new elicitation provider example.
run-all-examples.sh Runs the new elicitation provider example in the examples script.
CHANGELOG.md Records the newly ported upstream features under [Unreleased].

@krukow krukow marked this pull request as ready for review April 2, 2026 16:15
- Define fn? specs for all 10 sessionFs handler keys (read-file, write-file, etc.)
- Move handle-session-fs-request! after channel? definition and use it
  instead of ManyToManyChannel instance check
- Remove (or result {}) coercion — pass nil through for void FS operations
- Add ::remote-steerable? to ::session.resume-data spec (was missing)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@krukow
Copy link
Copy Markdown
Collaborator Author

krukow commented Apr 2, 2026

Addressing Copilot Code Review Feedback (4 comments)

All 4 issues fixed in commit 2f87981:

1. Undefined sessionFs handler key specs (specs.clj:83)
✅ Added fn? specs for all 10 FS handler keys (::read-file, ::write-file, etc.). Instrumentation now catches non-function handlers.

2. ManyToManyChannel too narrow for channel detection (session.clj:155)

3. Nil coercion to {} for void FS ops (session.clj:157)
✅ Removed (or result {}) — void ops now return {:result nil} which serializes correctly via clj->wire.

4. ::remote-steerable? missing from session.resume-data (CHANGELOG.md:21)
✅ The changelog was correct — upstream session.resume events DO include remoteSteerable? (line 178 in generated session-events.ts). The actual bug was that our ::session.resume-data spec was missing ::remote-steerable?. Added it.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

- Update changelog: steerable → remote-steerable? to avoid stale entry
- Define ::source spec (string?) for user.message-data and custom-agent-info

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@krukow
Copy link
Copy Markdown
Collaborator Author

krukow commented Apr 2, 2026

Addressing Copilot Code Review Round 2 (2 comments)

Fixed in commit d7f45f3:

1. Changelog steerable/remote-steerable? inconsistency (CHANGELOG.md:8)
✅ Updated the old entry to say remote-steerable? instead of steerable?, reflecting the current spec name.

2. ::source spec not defined (specs.clj:778)
✅ Added (s/def ::source string?) — serves both ::user.message-data (free-form) and ::custom-agent-info (further constrained via s/and predicate).

@krukow krukow merged commit 6cb978b into main Apr 3, 2026
1 check passed
@krukow krukow deleted the upstream-sync/v0.2.1-batch branch April 3, 2026 06:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants