diff options
| author | Adam Malczewski <[email protected]> | 2026-04-01 17:12:10 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-04-01 17:12:10 +0900 |
| commit | 77a09e59e54540841d7c2cdbe7b6d0f4d1418744 (patch) | |
| tree | b7e9cdbc6c3669bb49675a37435921ee11238289 /lib | |
| parent | 9aacecab709bd7315a97675750e1874d858bdeef (diff) | |
| download | dispatch-adapter-copilot-77a09e59e54540841d7c2cdbe7b6d0f4d1418744.tar.gz dispatch-adapter-copilot-77a09e59e54540841d7c2cdbe7b6d0f4d1418744.zip | |
add model and pricing info
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/dispatch/adapter/base.rb | 2 | ||||
| -rw-r--r-- | lib/dispatch/adapter/copilot.rb | 53 | ||||
| -rw-r--r-- | lib/dispatch/adapter/model_info.rb | 8 | ||||
| -rw-r--r-- | lib/dispatch/adapter/rate_limiter.rb | 9 |
4 files changed, 56 insertions, 16 deletions
diff --git a/lib/dispatch/adapter/base.rb b/lib/dispatch/adapter/base.rb index dbd136a..4b7a6ed 100644 --- a/lib/dispatch/adapter/base.rb +++ b/lib/dispatch/adapter/base.rb @@ -11,7 +11,7 @@ module Dispatch raise NotImplementedError, "#{self.class}#model_name must be implemented" end - def count_tokens(_messages, system: nil, tools: []) + def count_tokens(_messages, system: nil, tools: []) # rubocop:disable Lint/UnusedMethodArgument -1 end diff --git a/lib/dispatch/adapter/copilot.rb b/lib/dispatch/adapter/copilot.rb index 728ce99..d8a54a0 100644 --- a/lib/dispatch/adapter/copilot.rb +++ b/lib/dispatch/adapter/copilot.rb @@ -116,23 +116,20 @@ module Dispatch def list_models ensure_authenticated! @rate_limiter.wait! - uri = URI("#{API_BASE}/v1/models") + uri = URI("#{API_BASE}/models") request = Net::HTTP::Get.new(uri) apply_headers!(request) + request["X-Github-Api-Version"] = "2025-10-01" response = execute_request(uri, request) data = parse_response!(response) models = data["data"] || [] - models.map do |m| - ModelInfo.new( - id: m["id"], - name: m["id"], - max_context_tokens: MODEL_CONTEXT_WINDOWS.fetch(m["id"], 0), - supports_vision: false, - supports_tool_use: true, - supports_streaming: true - ) + models.filter_map do |m| + next unless m["model_picker_enabled"] + next unless chat_model?(m) + + build_model_info(m) end end @@ -147,6 +144,40 @@ module Dispatch "Invalid thinking level: #{level.inspect}. Must be one of: #{VALID_THINKING_LEVELS.join(", ")}, or nil" end + def chat_model?(model_data) + capabilities = model_data["capabilities"] + return true unless capabilities + + model_type = capabilities["type"] + return true if model_type.nil? + + if model_type.is_a?(Array) + model_type.include?("chat") + else + model_type == "chat" + end + end + + def build_model_info(model_data) + capabilities = model_data["capabilities"] || {} + supports = capabilities["supports"] || {} + limits = capabilities["limits"] || {} + billing = model_data["billing"] || {} + + context_tokens = limits["max_context_window_tokens"] || + MODEL_CONTEXT_WINDOWS.fetch(model_data["id"], 0) + + ModelInfo.new( + id: model_data["id"], + name: model_data["name"] || model_data["id"], + max_context_tokens: context_tokens.to_i, + supports_vision: !!supports["vision"], + supports_tool_use: !!supports["tool_calls"], + supports_streaming: !!supports["streaming"], + premium_request_multiplier: billing["multiplier"]&.to_f + ) + end + def default_token_path File.join(Dir.home, ".config", "dispatch", "copilot_github_token") end @@ -571,7 +602,7 @@ module Dispatch next if line.empty? next unless line.start_with?("data: ") - data_str = line.sub(/\Adata: /, "") + data_str = line.delete_prefix("data: ") next if data_str == "[DONE]" data = JSON.parse(data_str) diff --git a/lib/dispatch/adapter/model_info.rb b/lib/dispatch/adapter/model_info.rb index 73d8a35..8ba2977 100644 --- a/lib/dispatch/adapter/model_info.rb +++ b/lib/dispatch/adapter/model_info.rb @@ -5,7 +5,13 @@ module Dispatch 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 6f10905..8d0789e 100644 --- a/lib/dispatch/adapter/rate_limiter.rb +++ b/lib/dispatch/adapter/rate_limiter.rb @@ -20,6 +20,7 @@ module Dispatch loop do wait_time = 0.0 + done = false File.open(rate_limit_file, File::RDWR | File::CREAT) do |file| file.flock(File::LOCK_EX) @@ -30,10 +31,12 @@ module Dispatch if wait_time <= 0 record_request(state, now) write_state(file, state) - return + done = true end end + return if done + sleep(wait_time) end end @@ -99,7 +102,7 @@ module Dispatch elapsed = now - last remaining = interval - elapsed - remaining > 0 ? remaining : 0.0 + remaining.positive? ? remaining : 0.0 end def compute_window_wait(state, now) @@ -115,7 +118,7 @@ module Dispatch oldest_in_window = log.min wait = oldest_in_window + period - now - wait > 0 ? wait : 0.0 + wait.positive? ? wait : 0.0 end def record_request(state, now) |
