Skip to content

Commit 9768cb0

Browse files
committed
release: copilot-sdk-cpp v0.4.2
- Update protocol and type coverage for Copilot CLI 1.0.102-1. - Add structured responses, live tool updates, and skill providers. - Add installation confirmation and extension launch callbacks. - Expand session configuration, MCP authentication, and filesystem APIs. - Improve request cancellation, response tracking, and runtime shutdown.
1 parent 034e320 commit 9768cb0

54 files changed

Lines changed: 35123 additions & 29032 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/ci.yml‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,10 @@ jobs:
2222
# Deliberately no -G: runner images rotate their Visual Studio version, and pinning
2323
# one ("Visual Studio 17 2022") breaks the Windows job the moment the image moves on.
2424
# CMake's per-platform default is correct on all three runners.
25-
run: cmake -B build -DCMAKE_BUILD_TYPE=Release -DCOPILOT_BUILD_TESTS=ON
25+
run: cmake -B build -DCMAKE_BUILD_TYPE=Release
2626

2727
- name: Build
2828
run: cmake --build build --config Release
2929

30-
- name: Run Unit Tests
31-
run: ctest --test-dir build -C Release -E "^E2ETest\." --output-on-failure
32-
env:
33-
COPILOT_SDK_CPP_SKIP_E2E: 1
30+
- name: Check generated protocol catalog
31+
run: cmake --build build --config Release --target copilot_codegen_check

‎CHANGELOG.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Changelog
2+
3+
## 0.4.2
4+
5+
- Update protocol coverage for Copilot CLI 1.0.102-1.
6+
- Add request-correlated and structured message waiting, live tool replacement,
7+
skill providers, installation confirmation, and extension launch callbacks.
8+
- Expand session, agent, provider, MCP authentication, and binary filesystem APIs.
9+
- Fix hook error-object parsing, reentrant JSON-RPC callbacks, request cancellation,
10+
session admission races, and runtime shutdown and process-tree cleanup.

‎CMakeLists.txt‎

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.20)
2-
project(copilot_sdk_cpp VERSION 0.4.1 LANGUAGES CXX)
2+
project(copilot_sdk_cpp VERSION 0.4.2 LANGUAGES CXX)
33

44
# Enable folder organization in IDEs
55
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
@@ -13,9 +13,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
1313
set(CMAKE_CXX_EXTENSIONS OFF)
1414

1515
# Options
16-
option(COPILOT_BUILD_TESTS "Build tests" ON)
1716
option(COPILOT_BUILD_EXAMPLES "Build examples" ON)
18-
option(COPILOT_BUILD_SNAPSHOT_TESTS "Build snapshot conformance tests (requires upstream snapshots + Python)" OFF)
1917
option(COPILOT_WITH_FASTMCPP "Build in-process MCP examples with fastmcpp" OFF)
2018

2119
# Protocol code generation
@@ -73,7 +71,7 @@ add_library(copilot_sdk_cpp
7371
include/copilot/types.hpp
7472
include/copilot/events.hpp
7573
include/copilot/extension.hpp
76-
include/copilot/factory.hpp
74+
include/copilot/workflow.hpp
7775
include/copilot/generated/api_types.hpp
7876
include/copilot/generated/compatibility_types.hpp
7977
include/copilot/generated/protocol_version.hpp
@@ -96,7 +94,7 @@ add_library(copilot_sdk_cpp
9694
src/types.cpp
9795
src/events.cpp
9896
src/extension.cpp
99-
src/factory.cpp
97+
src/workflow.cpp
10098
src/transport.cpp
10199
src/transport_ffi.cpp
102100
src/jsonrpc.cpp
@@ -144,12 +142,6 @@ set_target_properties(copilot_sdk_cpp PROPERTIES
144142
FOLDER "Libraries"
145143
)
146144

147-
# Tests
148-
if(COPILOT_BUILD_TESTS)
149-
enable_testing()
150-
add_subdirectory(tests)
151-
endif()
152-
153145
# Examples
154146
if(COPILOT_BUILD_EXAMPLES)
155147
add_subdirectory(examples)

‎CONTRIBUTING.md‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,20 @@ cmake -S . -B build
77
cmake --build build --config Release
88
```
99

10-
## Tests
10+
## Validation
11+
12+
Build the library and examples, then check the generated protocol catalog:
1113

1214
```sh
13-
ctest --test-dir build -C Release --output-on-failure
15+
cmake --build build --target copilot_codegen_check
1416
```
1517

16-
- E2E tests require the Copilot CLI (`copilot`) to be installed and authenticated.
17-
- Skip E2E tests in CI/non-interactive runs: set `COPILOT_SDK_CPP_SKIP_E2E=1`.
18+
The catalog check requires Python 3.
1819

1920
## Style
2021

2122
- Format C++ with `.clang-format` (4 spaces, Allman braces):
22-
- `clang-format -i src/*.cpp include/copilot/*.hpp examples/*.cpp tests/*.cpp`
23+
- `clang-format -i src/*.cpp include/copilot/*.hpp examples/*.cpp`
2324

2425
## Pull Requests
2526

‎README.md‎

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,27 @@ C++ SDK for interacting with the Copilot CLI agent runtime (JSON-RPC over stdio
66
[![C++20](https://img.shields.io/badge/C%2B%2B-20-blue)]()
77
[![License](https://img.shields.io/badge/license-MIT-green)]()
88

9+
## Version 0.4.2
10+
11+
Targets Copilot CLI 1.0.102-1 and SDK protocol version 3.
12+
13+
- Correlate message waiters with the originating request, including sub-agent,
14+
abort, and autopilot events; receive structured JSON with `response_schema`
15+
and `send_and_wait_structured`.
16+
- Replace session tools at runtime with `Session::set_tools`; use tool namespaces
17+
and per-invocation agent/request identifiers.
18+
- Supply session skill providers, installation confirmation handlers, and extension
19+
launch providers. Handle MCP authentication token updates or runtime refresh.
20+
- Configure diagnostics, agent/hook directories, sandboxing, image generation,
21+
transcript recovery, and the expanded provider/agent options.
22+
- Cancel incoming JSON-RPC requests and run request callbacks independently of the
23+
reader. Retire session callbacks on teardown and shut down owned runtimes gracefully.
24+
- Use generated binary SessionFs request/result types and report partial writes
25+
with `SessionFsError::write_changed`.
26+
27+
Known limitations: experimental AHP hosting is not implemented. The in-process
28+
macOS UI-thread dispatcher is not provided.
29+
930
## Build
1031

1132
Requirements: CMake 3.20+ and a C++20 compiler.
@@ -15,29 +36,11 @@ cmake -S . -B build
1536
cmake --build build --config Release
1637
```
1738

18-
## Tests
19-
20-
Unit tests:
21-
22-
```sh
23-
ctest --test-dir build -C Release --output-on-failure
24-
```
25-
26-
E2E tests (real Copilot CLI):
27-
- Require `copilot` to be installed and authenticated.
28-
- To disable E2E tests in CI/non-interactive runs, set `COPILOT_SDK_CPP_SKIP_E2E=1`.
29-
30-
Snapshot conformance tests (optional):
31-
- Require Python 3 and the upstream `copilot-sdk` snapshots directory.
32-
- Install Python deps: `python -m pip install --user -r tests/snapshot_tests/requirements.txt`
33-
- Enable with `-DCOPILOT_BUILD_SNAPSHOT_TESTS=ON` and set `-DCOPILOT_SDK_CPP_SNAPSHOT_DIR=...` if auto-detection fails.
34-
- Run: `cmake --build build --target run_snapshot_tests --config Release`
35-
3639
## Official protocol baseline and code generation
3740

3841
`schemas/official-baseline.json` pins the official SDK commit, protocol version,
39-
schema hashes, and the complete generated surface: 1,203 API definitions, 494
40-
session-event definitions, 363 RPC methods, and 122 event variants. Generated
42+
schema hashes, and the complete generated surface: 1,899 API definitions, 679
43+
session-event definitions, 619 RPC methods, and 163 event variants. Generated
4144
wire-preserving types live under `include/copilot/generated/`; the existing
4245
handwritten public API remains the ergonomic layer.
4346

@@ -73,8 +76,8 @@ Advanced parity includes:
7376
`copilot_runtime_*` native ABI (`prebuilds/<platform>/runtime.node`).
7477
- `CopilotRequestHandler` and WebSocket handlers for streamed model-layer I/O.
7578
- Automatic MCP OAuth event handling and pending-request responses.
76-
- `create_canvas`, `define_factory`, `Session::factory()`, and `join_session`
77-
helpers for canvas, factory, and extension consumers.
79+
- `create_canvas`, `define_workflow`, `Session::workflow()`, and `join_session`
80+
helpers for canvas, workflow, and extension consumers.
7881

7982
## Custom Tools
8083

‎include/copilot/cancellation.hpp‎

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Copyright (c) 2025 Elias Bachaalany
2+
// SPDX-License-Identifier: MIT
3+
4+
#pragma once
5+
6+
#include <atomic>
7+
#include <cstdint>
8+
#include <functional>
9+
#include <map>
10+
#include <memory>
11+
#include <mutex>
12+
#include <vector>
13+
14+
namespace copilot
15+
{
16+
17+
namespace detail
18+
{
19+
20+
struct CancellationState
21+
{
22+
std::atomic<bool> cancelled{false};
23+
std::mutex mutex;
24+
uint64_t next_callback_id = 1;
25+
std::map<uint64_t, std::function<void()>> callbacks;
26+
27+
void cancel()
28+
{
29+
std::map<uint64_t, std::function<void()>> to_run;
30+
{
31+
std::lock_guard<std::mutex> lock(mutex);
32+
if (cancelled.exchange(true))
33+
return;
34+
to_run.swap(callbacks);
35+
}
36+
for (auto& [_, callback] : to_run)
37+
{
38+
try
39+
{
40+
callback();
41+
}
42+
catch (...)
43+
{
44+
}
45+
}
46+
}
47+
};
48+
49+
} // namespace detail
50+
51+
/// Observer side of a cancellation signal. A default-constructed token is never
52+
/// cancelled. Copies share state.
53+
class CancellationToken
54+
{
55+
public:
56+
CancellationToken() = default;
57+
58+
bool is_cancelled() const noexcept
59+
{
60+
return state_ && state_->cancelled.load();
61+
}
62+
63+
/// Run `callback` once when the token is cancelled (immediately if it already
64+
/// is). Returns an id for unregister(); 0 when the callback ran inline or the
65+
/// token can never be cancelled.
66+
uint64_t on_cancel(std::function<void()> callback) const
67+
{
68+
if (!state_)
69+
return 0;
70+
{
71+
std::lock_guard<std::mutex> lock(state_->mutex);
72+
if (!state_->cancelled.load())
73+
{
74+
const auto id = state_->next_callback_id++;
75+
state_->callbacks.emplace(id, std::move(callback));
76+
return id;
77+
}
78+
}
79+
callback();
80+
return 0;
81+
}
82+
83+
void unregister(uint64_t id) const
84+
{
85+
if (!state_ || id == 0)
86+
return;
87+
std::lock_guard<std::mutex> lock(state_->mutex);
88+
state_->callbacks.erase(id);
89+
}
90+
91+
private:
92+
friend class CancellationSource;
93+
explicit CancellationToken(std::shared_ptr<detail::CancellationState> state)
94+
: state_(std::move(state))
95+
{
96+
}
97+
98+
std::shared_ptr<detail::CancellationState> state_;
99+
};
100+
101+
/// Owner side of a cancellation signal.
102+
class CancellationSource
103+
{
104+
public:
105+
CancellationSource() : state_(std::make_shared<detail::CancellationState>()) {}
106+
107+
CancellationToken token() const
108+
{
109+
return CancellationToken(state_);
110+
}
111+
112+
/// Signal cancellation; callbacks run on the calling thread, once.
113+
void cancel()
114+
{
115+
state_->cancel();
116+
}
117+
118+
bool is_cancelled() const noexcept
119+
{
120+
return state_->cancelled.load();
121+
}
122+
123+
private:
124+
std::shared_ptr<detail::CancellationState> state_;
125+
};
126+
127+
} // namespace copilot

‎include/copilot/canvas.hpp‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ class CanvasError : public std::runtime_error
1818
{
1919
}
2020

21-
const std::string& code() const noexcept { return code_; }
21+
const std::string& code() const noexcept
22+
{
23+
return code_;
24+
}
2225

2326
private:
2427
std::string code_;
@@ -29,6 +32,8 @@ struct CanvasAction
2932
std::string name;
3033
std::optional<std::string> description;
3134
std::optional<json> input_schema;
35+
/// Returned JSON becomes the invoke_canvas_action tool result. A ToolResultObject
36+
/// shape with binaryResultsForLlm supplies images to the model.
3237
std::function<json(const json&)> handler;
3338
};
3439

@@ -48,8 +53,14 @@ class Canvas
4853
public:
4954
explicit Canvas(CanvasOptions options);
5055

51-
const std::string& id() const noexcept { return id_; }
52-
const json& declaration() const noexcept { return declaration_; }
56+
const std::string& id() const noexcept
57+
{
58+
return id_;
59+
}
60+
const json& declaration() const noexcept
61+
{
62+
return declaration_;
63+
}
5364
json handle_open(const json& request) const;
5465
void handle_close(const json& request) const;
5566
json handle_action(const std::string& action, const json& request) const;

0 commit comments

Comments
 (0)