Class: Durable::Llm::Providers::Opencode

Inherits:
Base
  • Object
show all
Defined in:
lib/durable/llm/providers/opencode.rb

Overview

OpenCode Zen provider for accessing OpenCode Zen’s language models through their API. Provides completion, embedding, and streaming capabilities with authentication handling, error management, and response normalization.

Defined Under Namespace

Classes: OpencodeChoice, OpencodeEmbeddingResponse, OpencodeMessage, OpencodeResponse, OpencodeStreamChoice, OpencodeStreamDelta, OpencodeStreamResponse

Constant Summary collapse

BASE_URL =
'https://opencode.ai/zen/v1'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

models, options, #stream?

Constructor Details

#initialize(api_key: nil) ⇒ Opencode

Returns a new instance of Opencode.



30
31
32
33
34
35
36
37
38
# File 'lib/durable/llm/providers/opencode.rb', line 30

def initialize(api_key: nil)
  super
  @api_key = api_key || default_api_key
  @conn = Faraday.new(url: BASE_URL) do |faraday|
    faraday.request :json
    faraday.response :json
    faraday.adapter Faraday.default_adapter
  end
end

Instance Attribute Details

#api_keyObject

Returns the value of attribute api_key.



28
29
30
# File 'lib/durable/llm/providers/opencode.rb', line 28

def api_key
  @api_key
end

Class Method Details

.stream?Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/durable/llm/providers/opencode.rb', line 66

def self.stream?
  true
end

Instance Method Details

#completion(options) ⇒ Object



40
41
42
43
44
45
46
47
# File 'lib/durable/llm/providers/opencode.rb', line 40

def completion(options)
  response = @conn.post('chat/completions') do |req|
    req.headers['Authorization'] = "Bearer #{@api_key}"
    req.body = options
  end

  handle_response(response)
end

#default_api_keyObject



20
21
22
23
24
25
26
# File 'lib/durable/llm/providers/opencode.rb', line 20

def default_api_key
  begin
    Durable::Llm.configuration.opencode&.api_key
  rescue NoMethodError
    nil
  end || ENV['OPENCODE_API_KEY']
end

#embedding(model:, input:, **options) ⇒ Object



49
50
51
52
53
54
55
56
# File 'lib/durable/llm/providers/opencode.rb', line 49

def embedding(model:, input:, **options)
  response = @conn.post('embeddings') do |req|
    req.headers['Authorization'] = "Bearer #{@api_key}"
    req.body = { model: model, input: input, **options }
  end

  handle_response(response, OpencodeEmbeddingResponse)
end

#modelsObject



58
59
60
61
62
63
64
# File 'lib/durable/llm/providers/opencode.rb', line 58

def models
  response = @conn.get('models') do |req|
    req.headers['Authorization'] = "Bearer #{@api_key}"
  end

  handle_response(response).data.map { |model| model['id'] }
end

#stream(options) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/durable/llm/providers/opencode.rb', line 70

def stream(options)
  options[:stream] = true

  response = @conn.post('chat/completions') do |req|
    req.headers['Authorization'] = "Bearer #{@api_key}"
    req.headers['Accept'] = 'text/event-stream'

    options['temperature'] = options['temperature'].to_f if options['temperature']

    req.body = options

    user_proc = proc do |chunk, _size, _total|
      yield OpencodeStreamResponse.new(chunk)
    end

    req.options.on_data = to_json_stream(user_proc: user_proc)
  end

  handle_response(response)
end