diff options
Diffstat (limited to '.rules/changelog')
| -rw-r--r-- | .rules/changelog/2026-03/31/01.md | 30 | ||||
| -rw-r--r-- | .rules/changelog/2026-03/31/02.md | 30 | ||||
| -rw-r--r-- | .rules/changelog/2026-03/31/03.md | 13 |
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. |
