Class: Legion::LLM::Call::LexLLMAdapter

Inherits:
Object
  • Object
show all
Includes:
Legion::Logging::Helper
Defined in:
lib/legion/llm/call/lex_llm_adapter.rb

Overview

Adapts a lex-llm provider class to legion-llm’s native dispatch contract.

Defined Under Namespace

Classes: ToolShim

Constant Summary collapse

METADATA_KEYS =
%i[tier capabilities enabled].freeze
RESPONSES_PROVIDER_FAMILIES =
%i[openai vllm].freeze

Instance Method Summary collapse

Constructor Details

#initialize(provider_name, provider_class, instance_config: {}) ⇒ LexLLMAdapter

Returns a new instance of LexLLMAdapter.



16
17
18
19
20
21
22
# File 'lib/legion/llm/call/lex_llm_adapter.rb', line 16

def initialize(provider_name, provider_class, instance_config: {})
  @provider_name = provider_name.to_sym
  @provider_class = provider_class
  @instance_config = instance_config
  @capabilities = Array(instance_config[:capabilities] || instance_config['capabilities']).map(&:to_sym)
  @lex_llm_namespace = resolve_lex_llm_namespace
end

Instance Method Details

#chat(model:, messages:, **opts) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/legion/llm/call/lex_llm_adapter.rb', line 24

def chat(model:, messages:, **opts)
  response = provider.chat(
    messages:    normalize_messages(messages, system: opts[:system]),
    tools:       normalize_tools(opts[:tools]),
    temperature: opts[:temperature],
    params:      opts[:params] || {},
    headers:     opts[:headers] || {},
    schema:      opts[:schema],
    thinking:    opts[:thinking],
    tool_prefs:  opts[:tool_prefs],
    model:       model_info(model, offering_metadata: opts[:offering_metadata])
  )

  message_response(response, offering_metadata: opts[:offering_metadata])
end

#count_tokens(model:, messages:) ⇒ Object



127
128
129
130
131
132
133
# File 'lib/legion/llm/call/lex_llm_adapter.rb', line 127

def count_tokens(model:, messages:, **)
  {
    result: provider.count_tokens(messages: normalize_messages(messages), model: model_info(model)),
    model:  model,
    usage:  {}
  }
end

#embed(model:, text:, dimensions: nil, **opts) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/legion/llm/call/lex_llm_adapter.rb', line 90

def embed(model:, text:, dimensions: nil, **opts)
  model_info = model_info(model, offering_metadata: opts[:offering_metadata])
  response = provider.embed(
    text:       text,
    model:      model_info,
    dimensions: dimensions,
    params:     opts[:params] || {},
    headers:    opts[:headers] || {}
  )

  {
    result:   response.vectors,
    model:    response.model,
    usage:    { input_tokens: response.input_tokens.to_i, output_tokens: 0 },
    metadata: (offering_metadata: opts[:offering_metadata])
  }
end

#health(live: false) ⇒ Object



123
124
125
# File 'lib/legion/llm/call/lex_llm_adapter.rb', line 123

def health(live: false)
  provider.health(live: live)
end

#image(model:, prompt:, size:, with: nil, mask: nil, **opts) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/legion/llm/call/lex_llm_adapter.rb', line 108

def image(model:, prompt:, size:, with: nil, mask: nil, **opts)
  model_info = model_info(model, offering_metadata: opts[:offering_metadata])
  response = call_image_provider(
    prompt:  prompt,
    model:   model_info,
    size:    size,
    with:    with,
    mask:    mask,
    params:  opts[:params] || {},
    headers: opts[:headers] || {}
  )

  image_response(response, model: model_info, offering_metadata: opts[:offering_metadata])
end

#offerings(live: false, **filters) ⇒ Object



135
136
137
138
139
# File 'lib/legion/llm/call/lex_llm_adapter.rb', line 135

def offerings(live: false, **filters)
  return [] unless provider.respond_to?(:discover_offerings)

  provider.discover_offerings(live: live, **filters)
end

#responses(model:, body:, messages:, stream: false, **opts) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/legion/llm/call/lex_llm_adapter.rb', line 64

def responses(model:, body:, messages:, stream: false, **opts, &)
  raise Legion::LLM::ProviderError, "Responses API dispatch is not supported for #{provider_name}" unless supports?(:responses)

  payload = build_responses_payload(
    body:     body,
    model:    model,
    messages: messages,
    stream:   stream,
    system:   opts[:system],
    tools:    opts[:tools]
  )

  if stream
    stream_responses_payload(payload, offering_metadata: opts[:offering_metadata], &)
  else
    response = provider.connection.post(responses_url, payload)
    responses_hash_response(response.body, offering_metadata: opts[:offering_metadata])
  end
end

#stream(model:, messages:, **opts, &block) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/legion/llm/call/lex_llm_adapter.rb', line 40

def stream(model:, messages:, **opts, &block)
  accumulator = build_stream_accumulator
  response = provider.stream_chat(
    messages:    normalize_messages(messages, system: opts[:system]),
    tools:       normalize_tools(opts[:tools]),
    temperature: opts[:temperature],
    params:      opts[:params] || {},
    headers:     opts[:headers] || {},
    schema:      opts[:schema],
    thinking:    opts[:thinking],
    tool_prefs:  opts[:tool_prefs],
    model:       model_info(model, offering_metadata: opts[:offering_metadata])
  ) do |chunk|
    accumulate_stream_chunk(accumulator, chunk)
    block&.call(chunk)
  end

  if response
    message_response(response, offering_metadata: opts[:offering_metadata])
  else
    chunk_response(accumulator, offering_metadata: opts[:offering_metadata])
  end
end

#supports?(capability) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
87
88
# File 'lib/legion/llm/call/lex_llm_adapter.rb', line 84

def supports?(capability)
  return true unless capability.to_sym == :responses

  @capabilities.include?(:responses) || RESPONSES_PROVIDER_FAMILIES.include?(provider_name)
end