summaryrefslogtreecommitdiffhomepage
path: root/.rules/changelog/2026-03
diff options
context:
space:
mode:
Diffstat (limited to '.rules/changelog/2026-03')
-rw-r--r--.rules/changelog/2026-03/31/01.md30
-rw-r--r--.rules/changelog/2026-03/31/02.md30
-rw-r--r--.rules/changelog/2026-03/31/03.md13
3 files changed, 73 insertions, 0 deletions
diff --git a/.rules/changelog/2026-03/31/01.md b/.rules/changelog/2026-03/31/01.md
new file mode 100644
index 0000000..78cf9ef
--- /dev/null
+++ b/.rules/changelog/2026-03/31/01.md
@@ -0,0 +1,30 @@
+# Changelog — 2026-03-31 #01
+
+## Full gem implementation of dispatch-adapter-copilot
+
+### New Files
+
+- `lib/dispatch/adapter/errors.rb` — Error hierarchy (Error, AuthenticationError, RateLimitError, ServerError, RequestError, ConnectionError)
+- `lib/dispatch/adapter/message.rb` — Message, TextBlock, ImageBlock, ToolUseBlock, ToolResultBlock structs
+- `lib/dispatch/adapter/response.rb` — Response, Usage, StreamDelta structs
+- `lib/dispatch/adapter/tool_definition.rb` — ToolDefinition struct
+- `lib/dispatch/adapter/model_info.rb` — ModelInfo struct
+- `lib/dispatch/adapter/base.rb` — Abstract adapter base class with interface contract
+- `lib/dispatch/adapter/version.rb` — CopilotVersion module for gemspec version reference
+- `spec/dispatch/adapter/structs_spec.rb` — Tests for all canonical structs
+- `spec/dispatch/adapter/base_spec.rb` — Tests for Base interface defaults and NotImplementedError
+- `spec/dispatch/adapter/errors_spec.rb` — Tests for error hierarchy and attributes
+
+### Modified Files
+
+- `lib/dispatch/adapter/copilot.rb` — Rewrote from empty module to full Copilot adapter class inheriting from Base, with HTTP auth (device flow + Copilot token exchange), chat (non-streaming and SSE streaming), tool conversion, message merging, error mapping, list_models, and thinking/reasoning_effort support
+- `spec/dispatch/adapter/copilot_spec.rb` — Comprehensive WebMock-based tests covering text responses, tool calls, mixed responses, system param, max_tokens override, tool definitions, ToolUseBlock/ToolResultBlock wire conversion, ImageBlock error, consecutive message merging, streaming text deltas, streaming tool call deltas, list_models, thinking parameter (constructor default, per-call override, validation, nil disable), and error mapping for all HTTP status codes and connection failures
+- `spec/spec_helper.rb` — Cleaned up config
+- `dispatch-adapter-copilot.gemspec` — Updated version reference, summary, description, homepage, removed TODOs
+- `Gemfile` — Added webmock dependency
+- `README.md` — Replaced with actual gem documentation and usage examples
+- `.rubocop.yml` — Added NewCops, FrozenStringLiteralComment enforcement, and method/class length limits
+
+### Deleted Files
+
+- `lib/dispatch/adapter/copilot/version.rb` — Replaced by `lib/dispatch/adapter/version.rb`
diff --git a/.rules/changelog/2026-03/31/02.md b/.rules/changelog/2026-03/31/02.md
new file mode 100644
index 0000000..9f8a115
--- /dev/null
+++ b/.rules/changelog/2026-03/31/02.md
@@ -0,0 +1,30 @@
+# Changelog — 2026-03-31 #02
+
+## Comprehensive test suite and bug fixes
+
+### Tests Added
+
+- **structs_spec.rb**: Added struct equality tests (same values equal, different values not equal)
+- **errors_spec.rb**: Added StandardError inheritance test, rescue-as-StandardError test, RateLimitError retry_after default, rescue-as-Error test
+- **copilot_spec.rb**: Added tests for:
+ - VERSION constant accessibility
+ - Multiple tool calls in a single response
+ - Empty tools array omits `tools` key from request body
+ - TextBlock array in user messages converted to string content
+ - ToolResultBlock with array content (Array of TextBlocks)
+ - ToolResultBlock with is_error: true
+ - finish_reason "length" maps to :max_tokens stop_reason
+ - Assistant message containing mixed text + tool_use blocks
+ - Streaming usage data capture
+ - Multiple parallel tool calls in streaming
+ - Copilot token caching (reuses token, only 1 token request for 2 chats)
+ - Authentication failure on Copilot token exchange
+
+### Bug Fixes
+
+- **copilot.rb**: Fixed `Array(hash)` bug in `build_wire_messages` — `Array()` on a Hash converts it to key-value pairs instead of wrapping in an array. Replaced with explicit `is_a?(Array)` check.
+- **copilot.rb**: Fixed empty argument fragment yielding in streaming — empty string arguments from initial tool_call chunks were being yielded as `tool_use_delta` events. Added `next if arg_frag.empty?` guard.
+
+### Total Test Count
+
+84 examples, 0 failures across 4 spec files.
diff --git a/.rules/changelog/2026-03/31/03.md b/.rules/changelog/2026-03/31/03.md
new file mode 100644
index 0000000..e2e8ecc
--- /dev/null
+++ b/.rules/changelog/2026-03/31/03.md
@@ -0,0 +1,13 @@
+# Changelog — 2026-03-31 #03
+
+## Accept plain hashes as tool definitions in chat
+
+### Modified Files
+
+- **lib/dispatch/adapter/copilot.rb** — Updated `build_wire_tools` to use a new `tool_attr` helper method instead of direct method calls. Added `tool_attr(tool, key)` private method that supports both struct-style method access and Hash-style key access (symbol and string keys). This allows `chat(tools:)` to accept plain hashes alongside `ToolDefinition` structs.
+- **spec/dispatch/adapter/copilot_spec.rb** — Added 3 tests: plain hashes with symbol keys, plain hashes with string keys, and mixed ToolDefinition structs + plain hashes.
+- **README.md** — Updated Tool Calling section to document plain hash support and added a usage example.
+
+### Rationale
+
+The Dispatch tool registry (`Registry#to_a`) returns plain hashes to avoid cross-gem dependencies. This change allows adapters to accept tools from the registry without requiring a conversion step.