summaryrefslogtreecommitdiffhomepage
path: root/lib
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-04-28 14:10:04 +0900
committerAdam Malczewski <[email protected]>2026-04-28 14:10:04 +0900
commit1ec2afaa21b8c3ef336982e80259b9bb79e3fb32 (patch)
tree7cf43fbd4efc6d6834744d800822255fd3d44d05 /lib
parente6c2f23b58a1e87088ee75632c74fee4f15f6a94 (diff)
downloaddispatch-adapter-copilot-1ec2afaa21b8c3ef336982e80259b9bb79e3fb32.tar.gz
dispatch-adapter-copilot-1ec2afaa21b8c3ef336982e80259b9bb79e3fb32.zip
updatesdev
Diffstat (limited to 'lib')
-rw-r--r--lib/dispatch/adapter/base.rb31
-rw-r--r--lib/dispatch/adapter/copilot.rb23
-rw-r--r--lib/dispatch/adapter/errors.rb30
-rw-r--r--lib/dispatch/adapter/message.rb31
-rw-r--r--lib/dispatch/adapter/model_info.rb17
-rw-r--r--lib/dispatch/adapter/rate_limiter.rb2
-rw-r--r--lib/dispatch/adapter/response.rb23
-rw-r--r--lib/dispatch/adapter/tool_definition.rb7
8 files changed, 14 insertions, 150 deletions
diff --git a/lib/dispatch/adapter/base.rb b/lib/dispatch/adapter/base.rb
deleted file mode 100644
index 4b7a6ed..0000000
--- a/lib/dispatch/adapter/base.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-module Dispatch
- module Adapter
- class Base
- def chat(_messages, system: nil, tools: [], stream: false, max_tokens: nil, thinking: nil, &_block)
- raise NotImplementedError, "#{self.class}#chat must be implemented"
- end
-
- def model_name
- raise NotImplementedError, "#{self.class}#model_name must be implemented"
- end
-
- def count_tokens(_messages, system: nil, tools: []) # rubocop:disable Lint/UnusedMethodArgument
- -1
- end
-
- def list_models
- raise NotImplementedError, "#{self.class}#list_models must be implemented"
- end
-
- def provider_name
- self.class.name
- end
-
- def max_context_tokens
- nil
- end
- end
- end
-end
diff --git a/lib/dispatch/adapter/copilot.rb b/lib/dispatch/adapter/copilot.rb
index d8a54a0..b14c5c0 100644
--- a/lib/dispatch/adapter/copilot.rb
+++ b/lib/dispatch/adapter/copilot.rb
@@ -6,12 +6,7 @@ require "json"
require "securerandom"
require "fileutils"
-require_relative "errors"
-require_relative "message"
-require_relative "response"
-require_relative "tool_definition"
-require_relative "model_info"
-require_relative "base"
+require "dispatch/adapter/interface"
require_relative "rate_limiter"
require_relative "version"
@@ -56,7 +51,7 @@ module Dispatch
VALID_THINKING_LEVELS = %w[low medium high].freeze
- def initialize(model: "gpt-4.1", github_token: nil, token_path: nil, max_tokens: 8192, thinking: nil,
+ def initialize(model: "gpt-4.1", github_token: nil, token_path: nil, max_tokens: 8192, thinking: "high",
min_request_interval: 3.0, rate_limit: nil)
super()
@model = model
@@ -88,9 +83,13 @@ module Dispatch
body = {
model: @model,
messages: wire_messages,
- max_tokens: effective_max_tokens,
stream: stream
}
+ if uses_max_completion_tokens?
+ body[:max_completion_tokens] = effective_max_tokens
+ else
+ body[:max_tokens] = effective_max_tokens
+ end
body[:tools] = wire_tools unless wire_tools.empty?
body[:reasoning_effort] = effective_thinking if effective_thinking
@@ -178,6 +177,10 @@ module Dispatch
)
end
+ def uses_max_completion_tokens?
+ @model.match?(/o[1-9]|gpt-5|gemini/)
+ end
+
def default_token_path
File.join(Dir.home, ".config", "dispatch", "copilot_github_token")
end
@@ -457,13 +460,13 @@ module Dispatch
def merge_consecutive_roles(messages)
return messages if messages.empty?
- merged = [messages.first.dup]
+ merged = [ messages.first.dup ]
messages[1..].each do |msg|
prev = merged.last
if prev[:role] == msg[:role] && prev[:role] != "tool" && !msg.key?(:tool_calls) && !prev.key?(:tool_calls)
- prev[:content] = [prev[:content], msg[:content]].compact.join("\n\n")
+ prev[:content] = [ prev[:content], msg[:content] ].compact.join("\n\n")
else
merged << msg.dup
end
diff --git a/lib/dispatch/adapter/errors.rb b/lib/dispatch/adapter/errors.rb
deleted file mode 100644
index 86f9c14..0000000
--- a/lib/dispatch/adapter/errors.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-module Dispatch
- module Adapter
- class Error < StandardError
- attr_reader :status_code, :provider
-
- def initialize(message = nil, status_code: nil, provider: nil)
- @status_code = status_code
- @provider = provider
- super(message)
- end
- end
-
- class AuthenticationError < Error; end
-
- class RateLimitError < Error
- attr_reader :retry_after
-
- def initialize(message = nil, status_code: nil, provider: nil, retry_after: nil)
- @retry_after = retry_after
- super(message, status_code:, provider:)
- end
- end
-
- class ServerError < Error; end
- class RequestError < Error; end
- class ConnectionError < Error; end
- end
-end
diff --git a/lib/dispatch/adapter/message.rb b/lib/dispatch/adapter/message.rb
deleted file mode 100644
index eb51c99..0000000
--- a/lib/dispatch/adapter/message.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-module Dispatch
- module Adapter
- Message = Struct.new(:role, :content, keyword_init: true)
-
- TextBlock = Struct.new(:type, :text, keyword_init: true) do
- def initialize(text:, type: "text")
- super(type:, text:)
- end
- end
-
- ImageBlock = Struct.new(:type, :source, :media_type, keyword_init: true) do
- def initialize(source:, media_type:, type: "image")
- super(type:, source:, media_type:)
- end
- end
-
- ToolUseBlock = Struct.new(:type, :id, :name, :arguments, keyword_init: true) do
- def initialize(id:, name:, arguments:, type: "tool_use")
- super(type:, id:, name:, arguments:)
- end
- end
-
- ToolResultBlock = Struct.new(:type, :tool_use_id, :content, :is_error, keyword_init: true) do
- def initialize(tool_use_id:, content:, is_error: false, type: "tool_result")
- super(type:, tool_use_id:, content:, is_error:)
- end
- end
- end
-end
diff --git a/lib/dispatch/adapter/model_info.rb b/lib/dispatch/adapter/model_info.rb
deleted file mode 100644
index 8ba2977..0000000
--- a/lib/dispatch/adapter/model_info.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-module Dispatch
- module Adapter
- ModelInfo = Struct.new(
- :id, :name, :max_context_tokens,
- :supports_vision, :supports_tool_use, :supports_streaming,
- :premium_request_multiplier,
- keyword_init: true
- ) do
- def initialize(id:, name:, max_context_tokens:, supports_vision:, supports_tool_use:, supports_streaming:,
- premium_request_multiplier: nil)
- super
- end
- end
- end
-end
diff --git a/lib/dispatch/adapter/rate_limiter.rb b/lib/dispatch/adapter/rate_limiter.rb
index 8d0789e..1b05582 100644
--- a/lib/dispatch/adapter/rate_limiter.rb
+++ b/lib/dispatch/adapter/rate_limiter.rb
@@ -90,7 +90,7 @@ module Dispatch
def compute_wait(state, now)
cooldown_wait = compute_cooldown_wait(state, now)
window_wait = compute_window_wait(state, now)
- [cooldown_wait, window_wait].max
+ [ cooldown_wait, window_wait ].max
end
def compute_cooldown_wait(state, now)
diff --git a/lib/dispatch/adapter/response.rb b/lib/dispatch/adapter/response.rb
deleted file mode 100644
index b4ba3eb..0000000
--- a/lib/dispatch/adapter/response.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-module Dispatch
- module Adapter
- Response = Struct.new(:content, :tool_calls, :model, :stop_reason, :usage, keyword_init: true) do
- def initialize(model:, stop_reason:, usage:, content: nil, tool_calls: [])
- super
- end
- end
-
- Usage = Struct.new(:input_tokens, :output_tokens, :cache_read_tokens, :cache_creation_tokens, keyword_init: true) do
- def initialize(input_tokens:, output_tokens:, cache_read_tokens: 0, cache_creation_tokens: 0)
- super
- end
- end
-
- StreamDelta = Struct.new(:type, :text, :tool_call_id, :tool_name, :argument_delta, keyword_init: true) do
- def initialize(type:, text: nil, tool_call_id: nil, tool_name: nil, argument_delta: nil)
- super
- end
- end
- end
-end
diff --git a/lib/dispatch/adapter/tool_definition.rb b/lib/dispatch/adapter/tool_definition.rb
deleted file mode 100644
index 7b435a3..0000000
--- a/lib/dispatch/adapter/tool_definition.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-module Dispatch
- module Adapter
- ToolDefinition = Struct.new(:name, :description, :parameters, keyword_init: true)
- end
-end