Add session RPC wrappers and close test coverage gaps#85
Conversation
Add infrastructure for testing server→client JSON-RPC calls (hooks.invoke, userInput.request, systemMessage.transform): - Add pending-responses atom to MockServer record for tracking outstanding server→client RPC requests - Modify server-loop to handle JSON-RPC response messages (no :method field) by routing them to pending promise channels - Add public send-rpc-request! function that sends a JSON-RPC request to the client, blocks until response arrives, and returns the result - Add 30+ method stubs to handle-request case statement for all session RPC methods (mode, plan, workspace, agent, fleet, skills, mcp, extensions, plugins, compaction, shell, elicitation, mcp.config, tools.handlePending) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Close several test coverage gaps relative to Node.js/Python SDKs: Hooks (6 tests): - test-hooks-pre-tool-use: preToolUse handler invoked with correct input - test-hooks-post-tool-use: postToolUse handler invoked - test-hooks-session-start: sessionStart handler invoked - test-hooks-unknown-type-returns-nil: unknown hook type returns nil - test-hooks-handler-exception-returns-nil: handler errors return nil - test-hooks-no-hooks-registered: no hooks → nil result User input (2 tests): - test-user-input-handler-invoked: handler receives question/choices - test-user-input-no-handler-errors: missing handler returns error System message transforms (3 tests): - test-system-message-transform-callback: transform fn invoked - test-system-message-transform-error-returns-original: error fallback - test-system-message-transform-no-callback-passthrough: passthrough Tool result normalization (3 tests): - test-tool-result-string-passthrough: string result via v3 broadcast - test-tool-result-nil-normalized: nil → empty string - test-tool-result-structured-object: ToolResultObject forwarded Also adds session.error-data spec tests and enriched spec fields. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add 19 experimental RPC wrapper functions for generated session/server Session-level (session.clj, 15 functions): - mode-get, mode-set! — agent mode (interactive/plan/autopilot) - workspace-list-files, workspace-read-file, workspace-create-file! - fleet-start! — parallel sub-sessions Server-level (client.clj, 4 functions): All functions follow the existing ^:experimental pattern used by skills-list, mcp-list, etc. Also includes: - 27 new integration tests (14 for gap coverage + 13 for RPC wrappers) - s/fdef instrumentation for all 19 new public functions - CHANGELOG.md entries under [Unreleased] Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add documentation for 19 new experimental functions: - Mode: mode-get, mode-set! (interactive/plan/autopilot) - Workspace: workspace-list-files, workspace-read-file, workspace-create-file! - Fleet: fleet-start! Includes code examples and reference tables matching existing doc style. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds missing public (experimental) RPC wrapper functions and closes several integration/spec coverage gaps, improving parity with upstream Copilot SDK behavior while expanding the mock server to support server→client RPC testing.
Changes:
- Enhanced the integration-test mock server to support server→client JSON-RPC requests and response routing.
- Added experimental session-level and server-level (MCP config) RPC wrapper functions with instrumentation.
- Expanded tests/specs/docs/changelog, including enriched
session.errorevent data spec and reference docs.
Show a summary per file
| File | Description |
|---|---|
| test/github/copilot_sdk/mock_server.clj | Adds pending response routing + helper to test server→client RPCs. |
| test/github/copilot_sdk/integration_test.clj | Adds many new integration tests (hooks, user input, transforms, tool results, some wrappers). |
| test/github/copilot_sdk_test.clj | Adds spec validation tests for enriched session.error payloads. |
| src/github/copilot_sdk/specs.clj | Extends ::session.error-data spec with additional optional fields. |
| src/github/copilot_sdk/session.clj | Adds experimental session RPC wrapper functions (mode/plan/workspace/agent/fleet). |
| src/github/copilot_sdk/instrument.clj | Adds s/fdef + instrument/unstrument registrations for new public wrappers. |
| src/github/copilot_sdk/client.clj | Adds experimental MCP config RPC wrappers (server-level). |
| doc/reference/API.md | Updates :copilot/session.error event documentation to reflect new optional fields. |
| CHANGELOG.md | Documents the added wrappers, tests, mock server enhancements, and spec changes. |
Copilot's findings
Comments suppressed due to low confidence (3)
src/github/copilot_sdk/session.clj:1254
- New public wrapper
agent-reload!doesn’t appear to have integration test coverage (no references found undertest/). Please add an integration test for this wrapper (similar to theagent-list/agent-select!tests) to ensure the RPC method is invoked and any return value normalization is verified under instrumentation.
(defn ^:experimental agent-reload!
"Reload all custom agents."
[session]
(let [{:keys [session-id client]} session
conn (connection-io client)]
(util/wire->clj
(proto/send-request! conn "session.agent.reload" {:sessionId session-id}))))
src/github/copilot_sdk/client.clj:1242
mcp-config-update!pre-converts params withutil/clj->wire, butproto/send-request!already performs that conversion. Please remove the extra conversion and passparamsdirectly so conversion happens in one place.
(defn ^:experimental mcp-config-update!
"Update an MCP server configuration.
params is a map with server config to update."
[client params]
(ensure-connected! client)
(let [conn (:connection-io @(:state client))]
(util/wire->clj
(proto/send-request! conn "mcp.config.update" (util/clj->wire params)))))
src/github/copilot_sdk/client.clj:1251
mcp-config-remove!pre-converts params withutil/clj->wire, butproto/send-request!already performs that conversion. Please remove the extra conversion and passparamsdirectly to avoid redundant work and potential double-encoding edge cases.
(defn ^:experimental mcp-config-remove!
"Remove an MCP server configuration.
params is a map identifying the server to remove."
[client params]
(ensure-connected! client)
(let [conn (:connection-io @(:state client))]
(util/wire->clj
(proto/send-request! conn "mcp.config.remove" (util/clj->wire params)))))
- Files reviewed: 9/9 changed files
- Comments generated: 6
Add 5 dedicated integration tests: - test-agent-get-current: verifies session.agent.getCurrent RPC - test-agent-reload: verifies session.agent.reload RPC - test-mcp-config-add: verifies mcp.config.add with params forwarded - test-mcp-config-update: verifies mcp.config.update with params forwarded - test-mcp-config-remove: verifies mcp.config.remove with params forwarded All 19 new RPC wrappers now have dedicated test coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- SKILL.md: 9-phase process (discovery → gap analysis → TDD → review → PR → self-review) - References AGENTS.md as single source of truth for project details - references/PROJECT.md: lean upstream↔Clojure file mapping and wire conversion cheat sheet - Common pitfalls section verified against real bug history - Phase 9 self-review keeps skill current after each sync Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR expands the Clojure Copilot SDK’s experimental RPC surface with named wrappers for additional session/server RPCs, and closes multiple parity-related test coverage gaps by enhancing the mock server to support server→client JSON-RPC.
Changes:
- Add experimental session-level RPC wrappers (mode/plan/workspace/agent/fleet) and server-level MCP config wrappers.
- Enhance the integration test mock server to support server→client RPC requests and response routing; add broad new integration/spec tests.
- Extend specs/docs/changelog/instrumentation to cover new APIs and enriched
session.errorevent data.
Show a summary per file
| File | Description |
|---|---|
| test/github/copilot_sdk/mock_server.clj | Adds pending response routing and send-rpc-request! to test server→client RPC handlers; stubs many new RPC methods. |
| test/github/copilot_sdk/integration_test.clj | Adds integration tests for hooks/user-input/system-message transforms/tool-result normalization and new RPC wrappers. |
| test/github/copilot_sdk_test.clj | Adds spec tests for enriched ::session.error-data. |
| src/github/copilot_sdk/specs.clj | Extends ::session.error-data spec with optional fields. |
| src/github/copilot_sdk/session.clj | Adds experimental session RPC wrapper functions (mode/plan/workspace/agent/fleet). |
| src/github/copilot_sdk/instrument.clj | Adds s/fdef + instrumentation entries for new public functions. |
| src/github/copilot_sdk/client.clj | Adds experimental server-level MCP config wrapper functions. |
| doc/reference/API.md | Documents new experimental wrappers and the enriched :copilot/session.error event shape. |
| CHANGELOG.md | Records newly added wrappers/tests and the enriched error event spec. |
| .github/copilot-instructions.md | Updates documented project structure entries. |
Copilot's findings
- Files reviewed: 12/12 changed files
- Comments generated: 5
There was a problem hiding this comment.
Pull request overview
This PR expands the Clojure Copilot SDK’s public surface with experimental wrapper functions for previously “generated-only” RPCs, and closes a set of parity-driven test gaps by enhancing the mock server to support server→client RPC testing.
Changes:
- Add experimental session-level RPC wrapper functions (mode/plan/workspace/agent/fleet) and server-level MCP config RPC wrappers.
- Enhance the mock server to support server→client JSON-RPC requests and route client responses back to the test caller.
- Add substantial new integration/spec tests and update API reference + changelog to document the new APIs and enriched
session.errorevent data.
Show a summary per file
| File | Description |
|---|---|
test/github/copilot_sdk/mock_server.clj |
Adds pending response routing + send-rpc-request! helper and many new RPC method stubs for testing. |
test/github/copilot_sdk/integration_test.clj |
Adds integration coverage for hooks/userInput/systemMessage transforms/tool result normalization and new RPC wrappers. |
test/github/copilot_sdk_test.clj |
Adds spec validation tests for ::session.error-data. |
src/github/copilot_sdk/specs.clj |
Enriches ::session.error-data spec with optional fields (:status-code, :provider-call-id, :url). |
src/github/copilot_sdk/session.clj |
Adds experimental session RPC wrapper functions (mode/plan/workspace/agent/fleet). |
src/github/copilot_sdk/instrument.clj |
Adds s/fdef + instrumentation allowlist entries for new public functions. |
src/github/copilot_sdk/client.clj |
Adds experimental server-level MCP config wrapper functions. |
doc/reference/API.md |
Documents the new experimental wrappers and expands session.error event data docs. |
CHANGELOG.md |
Adds Unreleased entries for new APIs/tests and notes the session.error spec enrichment. |
.github/skills/update-upstream/SKILL.md |
Introduces a codified upstream-sync workflow skill doc. |
.github/skills/update-upstream/references/PROJECT.md |
Adds mapping and wire-conversion reference for upstream syncs. |
.github/copilot-instructions.md |
Updates documented repo structure/source file list. |
Copilot's findings
Comments suppressed due to low confidence (3)
src/github/copilot_sdk/client.clj:1242
mcp-config-update!pre-convertsparamswithutil/clj->wirebefore callingproto/send-request!, butproto/send-request!already converts params to wire format. To avoid double-conversion and keep wrapper behavior consistent, passparamsdirectly toproto/send-request!.
[client params]
(ensure-connected! client)
(let [conn (:connection-io @(:state client))]
(util/wire->clj
(proto/send-request! conn "mcp.config.update" (util/clj->wire params)))))
src/github/copilot_sdk/client.clj:1251
mcp-config-remove!pre-convertsparamswithutil/clj->wirebefore callingproto/send-request!, butproto/send-request!already converts params to wire format. Passparamsdirectly toproto/send-request!to avoid redundant/double conversion.
params is a map identifying the server to remove."
[client params]
(ensure-connected! client)
(let [conn (:connection-io @(:state client))]
(util/wire->clj
(proto/send-request! conn "mcp.config.remove" (util/clj->wire params)))))
doc/reference/API.md:965
- The plan-read example/documentation uses
:exists?, bututil/wire->cljwill convert a wire boolean field likeexiststo:exists(no?). Please update this example (and the corresponding docs) to match the actual returned key, or adjust the implementation to normalize to:exists?.
;; Read/update session plan
(session/plan-read my-session)
;; => {:exists? true :content "# Plan\n..." :file-path "/path/to/plan.md"}
(session/plan-update! my-session "# Updated Plan\n...")
(session/plan-delete! my-session)
- Files reviewed: 12/12 changed files
- Comments generated: 3
- Fix ::status-code spec: use integer? instead of int? (Long compatibility) - Fix plan-read: rename :exists → :exists? in return value to match docstring (proto/send-request! already applies clj->wire internally) - Fix mock server: distinguish requests (has :id) from notifications (no :id), only write response for requests per JSON-RPC spec - Fix send-rpc-request! docstring to match actual behavior - Strengthen test-plan-read assertions to verify :exists? key and return shape Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR expands the Clojure Copilot SDK’s experimental public API surface by adding named wrapper functions for previously-generated session/server RPC methods, and closes several integration-test parity gaps (hooks, user input, system message transforms, tool results, MCP config).
Changes:
- Added experimental session-level RPC wrappers (mode/plan/workspace/agent/fleet) plus server-level MCP config wrappers.
- Enhanced the mock server to support server→client JSON-RPC requests (response routing +
send-rpc-request!) and added many method stubs. - Added a substantial set of new integration/spec tests and updated API docs/changelog accordingly.
Show a summary per file
| File | Description |
|---|---|
test/github/copilot_sdk/mock_server.clj |
Adds pending response routing + send-rpc-request! and stubs for additional RPC methods. |
test/github/copilot_sdk/integration_test.clj |
Adds integration tests for hooks, user input, system transforms, tool-result normalization, and new RPC wrappers. |
test/github/copilot_sdk_test.clj |
Adds spec validation tests for enriched session.error data. |
src/github/copilot_sdk/specs.clj |
Extends ::session.error-data spec with new optional fields. |
src/github/copilot_sdk/session.clj |
Adds experimental session RPC wrapper functions. |
src/github/copilot_sdk/instrument.clj |
Adds s/fdef coverage + instrumentation allowlists for new public functions. |
src/github/copilot_sdk/client.clj |
Adds experimental server-level MCP config RPC wrapper functions. |
doc/reference/API.md |
Documents new wrappers and updates session.error event data docs. |
CHANGELOG.md |
Records new APIs/tests and upstream-sync spec enrichment. |
.github/skills/update-upstream/SKILL.md |
Adds an upstream-sync workflow “skill” document. |
.github/skills/update-upstream/references/PROJECT.md |
Adds upstream↔Clojure mapping + wire conversion notes. |
.github/copilot-instructions.md |
Updates documented project structure listing. |
Copilot's findings
- Files reviewed: 12/12 changed files
- Comments generated: 3
- Fix mock stub for session.ui.elicitation: return elicitation result shape
({:action :content}) instead of nested {:result {}}
- Fix changelog: update test count from 13 to 18
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Closes parity-driven coverage gaps by enhancing the mock server to support server→client JSON-RPC requests, adding broad integration tests (hooks/user input/system message transforms/tool result normalization), and introducing experimental wrapper functions for previously-generated session/server RPC methods.
Changes:
- Enhanced the test mock server to support server→client RPC request/response routing (
send-rpc-request!, pending response tracking). - Added extensive integration/spec tests covering hooks, user-input requests, system-message transforms, tool-result normalization, and the new RPC wrappers.
- Added experimental session-level and server-level RPC wrapper functions with corresponding specs/instrumentation and documentation/changelog updates.
Show a summary per file
| File | Description |
|---|---|
| test/github/copilot_sdk/mock_server.clj | Adds server→client RPC support and many new RPC stubs for tests. |
| test/github/copilot_sdk/integration_test.clj | Adds integration tests for hooks/user input/transforms/tool normalization and wrapper methods. |
| test/github/copilot_sdk_test.clj | Adds spec validation tests for enriched session.error event data. |
| src/github/copilot_sdk/specs.clj | Extends ::session.error-data spec with optional fields. |
| src/github/copilot_sdk/session.clj | Adds experimental session RPC wrapper functions (mode/plan/workspace/agent/fleet). |
| src/github/copilot_sdk/instrument.clj | Adds s/fdef + instrumentation allowlist entries for new public functions. |
| src/github/copilot_sdk/client.clj | Adds experimental server-level MCP config RPC wrappers. |
| doc/reference/API.md | Documents new wrappers and enriched session.error event data. |
| CHANGELOG.md | Records new wrappers/tests and spec enrichment under Unreleased. |
| .github/skills/update-upstream/SKILL.md | Adds a documented upstream sync workflow as a reusable skill. |
| .github/skills/update-upstream/references/PROJECT.md | Adds upstream↔Clojure file mapping + wire conversion notes for sync work. |
| .github/copilot-instructions.md | Updates documented project structure listing. |
Copilot's findings
- Files reviewed: 12/12 changed files
- Comments generated: 1
Assert that fleet-start! always uses the session's own ID and that user-provided params cannot override it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR expands the Clojure Copilot SDK’s experimental surface with named wrappers for remaining session/server RPCs, and closes multiple parity-driven test gaps by enhancing the mock server to support bidirectional (server→client) JSON-RPC testing.
Changes:
- Added experimental session-level RPC wrapper functions (mode/plan/workspace/agent/fleet) plus server-level MCP config wrappers, with instrumentation (
s/fdef) and integration tests. - Enhanced the mock server to support server→client RPC requests (
send-rpc-request!) and response routing, enabling new hook/userInput/systemMessage tests. - Extended specs/docs/changelog to cover enriched
session.errorevent data and new experimental APIs.
Show a summary per file
| File | Description |
|---|---|
test/github/copilot_sdk/mock_server.clj |
Adds server→client RPC support via pending response routing and send-rpc-request!; expands RPC method stubs. |
test/github/copilot_sdk/integration_test.clj |
Adds integration tests for hooks, user input, system message transforms, tool result normalization, and new RPC wrappers. |
test/github/copilot_sdk_test.clj |
Adds spec validation tests for enriched ::session.error-data. |
src/github/copilot_sdk/specs.clj |
Extends ::session.error-data with optional fields like :status-code, :provider-call-id, :url. |
src/github/copilot_sdk/session.clj |
Adds experimental session RPC wrappers (mode/plan/workspace/agent/fleet). |
src/github/copilot_sdk/instrument.clj |
Adds s/fdef entries and instruments the new public wrapper functions. |
src/github/copilot_sdk/client.clj |
Adds experimental server-level MCP config RPC wrappers. |
doc/reference/API.md |
Documents new experimental wrappers and enriched session.error event payload shape. |
CHANGELOG.md |
Records newly added wrappers/tests/mock enhancements and the enriched error-data spec under Unreleased. |
.github/skills/update-upstream/SKILL.md |
Introduces an upstream sync skill document (contains a minor typo). |
.github/skills/update-upstream/references/PROJECT.md |
Adds upstream↔Clojure mapping and wire conversion notes for sync workflow. |
.github/copilot-instructions.md |
Updates the documented project structure/file list. |
Copilot's findings
- Files reviewed: 12/12 changed files
- Comments generated: 1
(:name, :command, :args) not the :mcp-prefixed keys used in session config :mcp-servers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR expands the Clojure Copilot SDK’s experimental surface area by adding named wrappers for previously “generated-only” RPC methods, and closes a set of parity-driven test coverage gaps by enhancing the mock server to support server→client RPC flows.
Changes:
- Added experimental session-level and server-level RPC wrapper functions (mode/plan/workspace/agent/fleet + MCP config) with
s/fdefinstrumentation entries. - Enhanced the integration-test mock server to support server→client JSON-RPC requests (response routing +
send-rpc-request!) and added extensive new integration tests for hooks, user-input, system-message transforms, tool result normalization, and the new wrappers. - Enriched
session.errorevent data spec + updated API docs and changelog accordingly.
Show a summary per file
| File | Description |
|---|---|
| test/github/copilot_sdk/mock_server.clj | Adds server→client RPC request support (pending response routing) + many method stubs for new wrapper tests. |
| test/github/copilot_sdk/integration_test.clj | Adds integration tests covering hooks, user input, system message transforms, tool normalization, and new RPC wrappers. |
| test/github/copilot_sdk_test.clj | Adds spec validation tests for the enriched ::session.error-data shape. |
| src/github/copilot_sdk/specs.clj | Extends ::session.error-data with optional status/url/provider-call-id fields. |
| src/github/copilot_sdk/session.clj | Adds experimental session RPC wrappers (mode/plan/workspace/agents/fleet). |
| src/github/copilot_sdk/instrument.clj | Adds s/fdef + instrument/unstrument allowlist entries for the new public functions. |
| src/github/copilot_sdk/client.clj | Adds experimental server-level MCP config RPC wrappers. |
| doc/reference/API.md | Documents the new experimental wrappers and the enriched session.error event data. |
| CHANGELOG.md | Records the new wrappers, tests, mock server enhancements, and spec enrichment under Unreleased. |
| .github/skills/update-upstream/SKILL.md | Adds an “update-upstream” skill doc for the upstream sync workflow. |
| .github/skills/update-upstream/references/PROJECT.md | Adds upstream↔Clojure mapping reference + wire conversion notes for syncing. |
| .github/copilot-instructions.md | Updates documented project structure to include additional source files. |
Copilot's findings
- Files reviewed: 12/12 changed files
- Comments generated: 0 new
Summary
Close test coverage gaps identified by a file-by-file parity review against the Node.js and Python SDKs, and add named wrapper functions for all remaining generated session RPC methods.
Test coverage gaps closed (27 new tests)
userInput.requestserver→client RPC handlerToolResultObjectvia v3 broadcastmcp.config.listserver-level RPCNew experimental RPC wrappers (19 functions)
Session-level (
session.clj):mode-get,mode-set!— agent mode (interactive/plan/autopilot)plan-read,plan-update!,plan-delete!— session plan file opsworkspace-list-files,workspace-read-file,workspace-create-file!agent-list,agent-get-current,agent-select!,agent-deselect!,agent-reload!fleet-start!— parallel sub-sessionsServer-level (
client.clj):mcp-config-list,mcp-config-add!,mcp-config-update!,mcp-config-remove!Mock server enhancements
send-rpc-request!— enables testing server→client RPCs (hooks, user-input, transforms)Instrumentation
Full
s/fdefcoverage andinstrument-all!/unstrument-all!entries for all 19 new public functions.Before/After
Not included
Multi-client broadcast tests are deferred — they require significant mock server rework to support a two-client-one-session topology. These could be added as E2E tests in a follow-up.
Commits