copilot-sdk-supercharged 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 89d18c0ed24efd53b41059356f64e3f0194336f9a9916a46d6848619dc0b91d1
4
+ data.tar.gz: 43b3bde04215480b3bf8eb61394fb8e81667240162c11c98659c07c63ee416e7
5
+ SHA512:
6
+ metadata.gz: 1c3047beed3644b182ad7148c0e410df8a2c5e7eb013bb4651b8453b66843e68ab872b06bdc63654ee173861d0e438240beccb44ed0c626e7a0407a87d595a00
7
+ data.tar.gz: 1bc2cb8dd53d08a2c4c2d80cd39481347cc36fed6f26d589023f6b9b04e4ca841ef79fc776922aeea0b5c860fceb1cde077ef7eead79a5d9ed85337c7366dfdb
data/README.md ADDED
@@ -0,0 +1,301 @@
1
+ # Copilot Supercharged Ruby SDK
2
+
3
+ Ruby SDK for the [GitHub Copilot CLI](https://github.com/github/copilot). Communicates with the Copilot CLI server via JSON-RPC 2.0 over stdio or TCP.
4
+
5
+ ## Requirements
6
+
7
+ - Ruby >= 3.1
8
+ - GitHub Copilot CLI installed and authenticated
9
+
10
+ ## Installation
11
+
12
+ Add to your Gemfile:
13
+
14
+ ```ruby
15
+ gem "copilot-sdk-supercharged"
16
+ ```
17
+
18
+ Or install directly:
19
+
20
+ ```bash
21
+ gem install copilot-sdk-supercharged
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ```ruby
27
+ require "copilot"
28
+
29
+ # Create a client (spawns the CLI server process)
30
+ client = Copilot::CopilotClient.new(
31
+ cli_path: "/usr/local/bin/copilot",
32
+ log_level: "info"
33
+ )
34
+ client.start
35
+
36
+ # Create a session
37
+ session = client.create_session(model: "gpt-4")
38
+
39
+ # Subscribe to events
40
+ unsub = session.on do |event|
41
+ if event.type == Copilot::SessionEventType::ASSISTANT_MESSAGE
42
+ puts event.data["content"]
43
+ end
44
+ end
45
+
46
+ # Send a message and wait for the response
47
+ response = session.send_and_wait(prompt: "Hello, world!")
48
+
49
+ # Clean up
50
+ unsub.call
51
+ session.destroy
52
+ client.stop
53
+ ```
54
+
55
+ ## Connecting to an External Server
56
+
57
+ Instead of spawning a CLI process, connect to an already-running server:
58
+
59
+ ```ruby
60
+ client = Copilot::CopilotClient.new(cli_url: "localhost:8080")
61
+ client.start
62
+ ```
63
+
64
+ ## Custom Tools
65
+
66
+ Register tools that the assistant can invoke:
67
+
68
+ ```ruby
69
+ weather_tool = Copilot.define_tool(
70
+ name: "get_weather",
71
+ description: "Get weather for a city",
72
+ parameters: {
73
+ type: "object",
74
+ properties: {
75
+ city: { type: "string", description: "City name" }
76
+ },
77
+ required: ["city"]
78
+ }
79
+ ) do |args, invocation|
80
+ city = args["city"]
81
+ "It is 22 degrees and sunny in #{city}."
82
+ end
83
+
84
+ session = client.create_session(tools: [weather_tool])
85
+ ```
86
+
87
+ Tool handlers can return:
88
+ - A **String** (wrapped as a successful result)
89
+ - A **Hash** (passed through if it has `textResultForLlm`, otherwise JSON-serialized)
90
+ - A **`Copilot::ToolResult`** struct for full control over result type, errors, and telemetry
91
+
92
+ ## Permission Handling
93
+
94
+ Handle permission requests when the assistant wants to perform privileged operations:
95
+
96
+ ```ruby
97
+ session = client.create_session(
98
+ on_permission_request: ->(request, ctx) {
99
+ puts "Permission requested: #{request.kind}"
100
+ Copilot::PermissionRequestResult.new(kind: Copilot::PermissionKind::APPROVED)
101
+ }
102
+ )
103
+ ```
104
+
105
+ ## User Input
106
+
107
+ Enable the `ask_user` tool so the agent can ask questions:
108
+
109
+ ```ruby
110
+ session = client.create_session(
111
+ on_user_input_request: ->(request, ctx) {
112
+ puts "Agent asks: #{request.question}"
113
+ print "> "
114
+ answer = $stdin.gets.chomp
115
+ Copilot::UserInputResponse.new(answer: answer, was_freeform: true)
116
+ }
117
+ )
118
+ ```
119
+
120
+ ## Hooks
121
+
122
+ Intercept session lifecycle events with hooks:
123
+
124
+ ```ruby
125
+ hooks = Copilot::SessionHooks.new(
126
+ on_pre_tool_use: ->(input, ctx) {
127
+ puts "About to call tool: #{input['toolName']}"
128
+ # Return nil to proceed normally, or a hash with modifiedArgs, etc.
129
+ nil
130
+ },
131
+ on_post_tool_use: ->(input, ctx) {
132
+ puts "Tool #{input['toolName']} completed"
133
+ nil
134
+ },
135
+ on_session_start: ->(input, ctx) {
136
+ puts "Session started from: #{input['source']}"
137
+ nil
138
+ }
139
+ )
140
+
141
+ session = client.create_session(hooks: hooks)
142
+ ```
143
+
144
+ ## Event Subscriptions
145
+
146
+ ### Session Events
147
+
148
+ Subscribe to all events or specific event types:
149
+
150
+ ```ruby
151
+ # All events
152
+ unsub = session.on { |event| puts event.type }
153
+
154
+ # Specific event type
155
+ unsub = session.on(Copilot::SessionEventType::ASSISTANT_MESSAGE) do |event|
156
+ puts event.data["content"]
157
+ end
158
+
159
+ # Unsubscribe
160
+ unsub.call
161
+ ```
162
+
163
+ ### Lifecycle Events (Client-Level)
164
+
165
+ Monitor session lifecycle changes (useful in TUI+server mode):
166
+
167
+ ```ruby
168
+ unsub = client.on(Copilot::SessionLifecycleEventType::SESSION_CREATED) do |event|
169
+ puts "Session created: #{event.session_id}"
170
+ end
171
+ ```
172
+
173
+ ## Session Management
174
+
175
+ ```ruby
176
+ # List all sessions
177
+ sessions = client.list_sessions
178
+ sessions.each { |s| puts "#{s.session_id}: #{s.summary}" }
179
+
180
+ # Resume a session
181
+ session = client.resume_session("session-id-here")
182
+
183
+ # Delete a session
184
+ client.delete_session("session-id-here")
185
+
186
+ # Get last session ID
187
+ last_id = client.get_last_session_id
188
+ ```
189
+
190
+ ## Custom Providers (BYOK)
191
+
192
+ Use your own API endpoint:
193
+
194
+ ```ruby
195
+ session = client.create_session(
196
+ model: "my-model",
197
+ provider: Copilot::ProviderConfig.new(
198
+ type: "openai",
199
+ base_url: "https://api.example.com/v1",
200
+ api_key: "sk-..."
201
+ )
202
+ )
203
+ ```
204
+
205
+ ## MCP Servers
206
+
207
+ Configure Model Context Protocol servers:
208
+
209
+ ```ruby
210
+ session = client.create_session(
211
+ mcp_servers: {
212
+ "my-server" => {
213
+ tools: ["*"],
214
+ command: "npx",
215
+ args: ["-y", "@example/mcp-server"],
216
+ }
217
+ }
218
+ )
219
+ ```
220
+
221
+ ## Infinite Sessions
222
+
223
+ Enable automatic context compaction for long-running sessions:
224
+
225
+ ```ruby
226
+ session = client.create_session(
227
+ infinite_sessions: Copilot::InfiniteSessionConfig.new(
228
+ enabled: true,
229
+ background_compaction_threshold: 0.80,
230
+ buffer_exhaustion_threshold: 0.95
231
+ )
232
+ )
233
+
234
+ # Access workspace path for persisted state
235
+ puts session.workspace_path
236
+ ```
237
+
238
+ ## Streaming
239
+
240
+ Enable streaming to receive incremental message chunks:
241
+
242
+ ```ruby
243
+ session = client.create_session(streaming: true)
244
+
245
+ session.on(Copilot::SessionEventType::ASSISTANT_MESSAGE_DELTA) do |event|
246
+ print event.data["deltaContent"]
247
+ end
248
+ ```
249
+
250
+ ## API Reference
251
+
252
+ ### `Copilot::CopilotClient`
253
+
254
+ | Method | Description |
255
+ |--------|-------------|
256
+ | `start` | Start the CLI server and connect |
257
+ | `stop` | Graceful shutdown, returns array of errors |
258
+ | `force_stop` | Forceful shutdown |
259
+ | `create_session(**config)` | Create a new session |
260
+ | `resume_session(id, **config)` | Resume an existing session |
261
+ | `ping(message = nil)` | Ping the server |
262
+ | `get_status` | Get CLI version and protocol info |
263
+ | `get_auth_status` | Get authentication status |
264
+ | `list_models` | List available models (cached) |
265
+ | `list_sessions` | List all sessions |
266
+ | `get_last_session_id` | Get most recently updated session ID |
267
+ | `delete_session(id)` | Permanently delete a session |
268
+ | `get_foreground_session_id` | Get TUI foreground session |
269
+ | `set_foreground_session_id(id)` | Set TUI foreground session |
270
+ | `on(event_type = nil, &block)` | Subscribe to lifecycle events |
271
+
272
+ ### `Copilot::CopilotSession`
273
+
274
+ | Method | Description |
275
+ |--------|-------------|
276
+ | `send(prompt:, attachments:, mode:)` | Send a message |
277
+ | `send_and_wait(prompt:, timeout:)` | Send and wait for idle |
278
+ | `on(event_type = nil, &block)` | Subscribe to session events |
279
+ | `get_messages` | Get conversation history |
280
+ | `destroy` | Destroy the session |
281
+ | `abort` | Abort current processing |
282
+
283
+ ### Key Types
284
+
285
+ - `Copilot::Tool` - Tool definition with handler
286
+ - `Copilot::ToolResult` - Structured tool result
287
+ - `Copilot::SessionEvent` - Session event with type and data
288
+ - `Copilot::ModelInfo` - Model metadata
289
+ - `Copilot::ProviderConfig` - Custom API provider config
290
+ - `Copilot::SessionHooks` - Hook handlers
291
+ - `Copilot::InfiniteSessionConfig` - Infinite session settings
292
+
293
+ ## Threading Model
294
+
295
+ The SDK uses a background reader thread for the JSON-RPC connection. Event handlers and tool handlers are called from this reader thread. If you need to interact with non-thread-safe resources, use appropriate synchronization (Mutex, Queue, etc.).
296
+
297
+ The `send_and_wait` method uses a `Mutex` + `ConditionVariable` to block the calling thread until the session becomes idle, which is the recommended pattern for synchronous usage.
298
+
299
+ ## License
300
+
301
+ MIT - see [LICENSE](../LICENSE) for details.