Establish OpenCode compatibility certification corpus
Some checks failed
Some checks failed
This commit is contained in:
66
ruby/live_probe.rb
Normal file
66
ruby/live_probe.rb
Normal file
@@ -0,0 +1,66 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "json"
|
||||
require "time"
|
||||
|
||||
gem_path = File.expand_path(ENV.fetch("OPENCODE_RUBY_PATH"))
|
||||
$LOAD_PATH.unshift(File.join(gem_path, "lib"))
|
||||
require "opencode-ruby"
|
||||
|
||||
base_url = ENV.fetch("OPENCODE_BASE_URL")
|
||||
model = ENV.fetch("OPENCODE_COMPAT_MODEL", "compat/compat-model")
|
||||
expected_text = ENV.fetch("OPENCODE_COMPAT_EXPECTED_TEXT", "compat-ok")
|
||||
client = Opencode::Client.new(base_url: base_url, timeout: 30)
|
||||
session_id = nil
|
||||
|
||||
begin
|
||||
health = client.health
|
||||
raise "OpenCode health did not report healthy: #{health.inspect}" unless health[:healthy] || health[:ok]
|
||||
|
||||
session = client.create_session(title: "opencode-compat isolated probe")
|
||||
session_id = session.fetch(:id)
|
||||
observed_parts = []
|
||||
|
||||
result = client.stream(
|
||||
session_id,
|
||||
"Reply with exactly: #{expected_text}",
|
||||
model: model,
|
||||
stream_timeout: 30,
|
||||
first_event_timeout: 15,
|
||||
idle_stream_timeout: 15
|
||||
) do |part|
|
||||
observed_parts << JSON.parse(JSON.generate(part))
|
||||
end
|
||||
|
||||
unless result.full_text.include?(expected_text)
|
||||
raise "Expected final text to include #{expected_text.inspect}, got #{result.full_text.inspect}"
|
||||
end
|
||||
|
||||
messages = client.get_messages(session_id)
|
||||
assistant_messages = Array(messages).select { |message| message.dig(:info, :role) == "assistant" }
|
||||
raise "No authoritative assistant exchange returned" if assistant_messages.empty?
|
||||
|
||||
puts JSON.generate(
|
||||
status: "pass",
|
||||
checked_at: Time.now.utc.iso8601,
|
||||
opencode_base_url: base_url,
|
||||
opencode_health: health,
|
||||
opencode_ruby_version: Opencode::VERSION,
|
||||
opencode_ruby_commit: ENV["OPENCODE_RUBY_COMMIT"],
|
||||
session_id: session_id,
|
||||
expected_text: expected_text,
|
||||
full_text: result.full_text,
|
||||
observed_part_count: observed_parts.length,
|
||||
authoritative_assistant_message_count: assistant_messages.length
|
||||
)
|
||||
rescue StandardError => error
|
||||
diagnostic = {error: "#{error.class}: #{error.message}"}
|
||||
if session_id
|
||||
diagnostic[:session_status] = client.session_status
|
||||
diagnostic[:messages] = client.get_messages(session_id)
|
||||
end
|
||||
warn JSON.generate(diagnostic)
|
||||
raise
|
||||
ensure
|
||||
client.delete_session(session_id) if session_id
|
||||
end
|
||||
69
ruby/opencode_ruby_fixture_contract.rb
Normal file
69
ruby/opencode_ruby_fixture_contract.rb
Normal file
@@ -0,0 +1,69 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "json"
|
||||
|
||||
root = File.expand_path("..", __dir__)
|
||||
gem_path = File.expand_path(ENV.fetch("OPENCODE_RUBY_PATH"))
|
||||
$LOAD_PATH.unshift(File.join(gem_path, "lib"))
|
||||
require "opencode-ruby"
|
||||
|
||||
manifest = JSON.parse(File.read(File.join(root, "fixtures/manifest.json")))
|
||||
failures = []
|
||||
|
||||
manifest.fetch("fixtures").each do |entry|
|
||||
reply = Opencode::Reply.new
|
||||
event_path = File.join(root, "fixtures", entry.fetch("events"))
|
||||
expected_path = File.join(root, "fixtures", entry.fetch("expected"))
|
||||
|
||||
File.foreach(event_path) do |line|
|
||||
next if line.strip.empty?
|
||||
|
||||
reply.apply(JSON.parse(line, symbolize_names: true))
|
||||
end
|
||||
|
||||
result = reply.result
|
||||
expected = JSON.parse(File.read(expected_path))
|
||||
actual = {
|
||||
"full_text" => result.full_text,
|
||||
"reasoning_text" => result.reasoning_text,
|
||||
"tool_count" => result.tool_parts.length,
|
||||
"prompt_blocked" => reply.prompt_blocked?,
|
||||
"total_cost" => reply.total_cost,
|
||||
"total_input_tokens" => reply.total_input_tokens,
|
||||
"total_output_tokens" => reply.total_output_tokens
|
||||
}
|
||||
|
||||
if (tool_expectation = expected["tool"])
|
||||
tool = result.tool_parts.first || reply.parts.find { |part| part["type"] == "tool" }
|
||||
actual["tool"] = {
|
||||
"tool" => tool&.fetch("tool", nil),
|
||||
"status" => tool&.fetch("status", nil),
|
||||
"callID" => tool&.fetch("callID", nil),
|
||||
"opencode_request_id" => tool&.dig("input", "opencode_request_id")
|
||||
}
|
||||
expected["tool"] = tool_expectation
|
||||
end
|
||||
|
||||
expected.each do |key, value|
|
||||
next if actual[key] == value
|
||||
|
||||
failures << "#{entry.fetch("id")}: #{key} expected #{value.inspect}, got #{actual[key].inspect}"
|
||||
end
|
||||
|
||||
unless failures.any? { |failure| failure.start_with?("#{entry.fetch("id")}:") }
|
||||
puts "PASS #{entry.fetch("id")}"
|
||||
end
|
||||
end
|
||||
|
||||
unless failures.empty?
|
||||
warn failures.join("\n")
|
||||
exit 1
|
||||
end
|
||||
|
||||
puts JSON.generate(
|
||||
status: "pass",
|
||||
adapter: "opencode-ruby",
|
||||
adapter_version: Opencode::VERSION,
|
||||
adapter_commit: ENV["OPENCODE_RUBY_COMMIT"],
|
||||
fixture_count: manifest.fetch("fixtures").length
|
||||
)
|
||||
Reference in New Issue
Block a user