helicone-rb 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5102ee7eb685c57698bb42b3a1818b1690b634a1f04fe1a2d5689c7d8b24c423
4
- data.tar.gz: 0a37bb68ba76a4b51c8472d96d01cde87fd98df5e35d21b1d6519cb6b3991a9d
3
+ metadata.gz: a118f742137f788207fb3e4b724ec2420884ef5610776d1437385cd2fa963649
4
+ data.tar.gz: 44b4d16c5295b974afa28d2b9f694bf0c2b0cb95ba810826eaa5a72b141cd1e1
5
5
  SHA512:
6
- metadata.gz: 8a801ebeb724ee8428a7c6ab73900a7dddabf1ad7524efe19391e431fc2bdb4bffe91bc9053c08c31f1e7e6398371cdcdd97437994cd4c9fec1532982e2d2f13
7
- data.tar.gz: 2abcda0fcc478de60f6192967f9465f815d68476495b6c5988145bcbc7361b0f4dfcf8ef97a3924e09302c48c058f556bd848111eda8e8fe977ffec01dfee9f9
6
+ metadata.gz: b689d259dbc4f8b583a62d5b95e84053aa58f41d594cf03fb5b681dc10d180e4d3ab5d86844d9875821c3d6b8c3270ff7e5faf5660c89501a8e72e8e7bf9d1b0
7
+ data.tar.gz: 6aa3ef6dda08bccd058deb550c23a0059693f759476b8394fa0d0c5f24497475decd2beb81a7f5818c6a58e243b8d8484bda22e405fcd965ae602bd789451904
@@ -4,7 +4,7 @@ module Helicone
4
4
  class Agent
5
5
  MAX_ITERATIONS = 10
6
6
 
7
- attr_reader :client, :tools, :messages, :context, :turn_model, :response_model
7
+ attr_reader :client, :tools, :messages, :context, :model
8
8
 
9
9
  # Create an agent with tools and optional context
10
10
  #
@@ -14,14 +14,12 @@ module Helicone
14
14
  # @param context [Object] Context object passed to tool#initialize
15
15
  # @param system_prompt [String] System prompt
16
16
  # @param messages [Array<Helicone::Message>] Initial messages (for continuing conversations)
17
- # @param turn_model [String] Model for tool-calling turns (defaults to Helicone.configuration.default_model)
18
- # @param response_model [String] Model for final response (defaults to turn_model)
19
- def initialize(client: nil, session: nil, tools: [], context: nil, system_prompt: nil, messages: [], turn_model: nil, response_model: nil)
17
+ # @param model [String] Model to use (defaults to Helicone.configuration.default_model)
18
+ def initialize(client: nil, session: nil, tools: [], context: nil, system_prompt: nil, messages: [], model: nil)
20
19
  @client = client || build_client(session: session)
21
20
  @tools = tools
22
21
  @context = context
23
- @turn_model = turn_model
24
- @response_model = response_model || turn_model
22
+ @model = model
25
23
  @messages = messages.dup
26
24
 
27
25
  # Add system message at the start if provided and not already present
@@ -30,17 +28,17 @@ module Helicone
30
28
  end
31
29
  end
32
30
 
33
- # Run the agent with a prompt, executing tools until done
31
+ # Run the agent with an optional prompt, executing tools until done
34
32
  #
35
- # @param prompt [String] User prompt to start with
33
+ # @param prompt [String, nil] User prompt to add (nil to use existing messages)
36
34
  # @param max_iterations [Integer] Maximum tool execution loops
37
35
  # @return [AgentResult]
38
- def run(prompt, max_iterations: MAX_ITERATIONS)
39
- @messages << Message.user_text(prompt)
36
+ def run(prompt = nil, max_iterations: MAX_ITERATIONS)
37
+ @messages << Message.user_text(prompt) if prompt
40
38
 
41
39
  iterations = 0
42
40
  while iterations < max_iterations
43
- response = call_llm(model: @turn_model)
41
+ response = call_llm
44
42
 
45
43
  tool_calls = response.tool_calls
46
44
  if tool_calls && !tool_calls.empty?
@@ -59,17 +57,7 @@ module Helicone
59
57
 
60
58
  iterations += 1
61
59
  else
62
- # No tool calls - if response_model differs, make final call with it
63
- if @response_model && @response_model != @turn_model
64
- final_response = @client.chat(messages: @messages, model: @response_model)
65
- return AgentResult.new(
66
- content: final_response.content,
67
- messages: @messages,
68
- iterations: iterations,
69
- response: final_response
70
- )
71
- end
72
-
60
+ # No tool calls - we're done
73
61
  return AgentResult.new(
74
62
  content: response.content,
75
63
  messages: @messages,
@@ -80,7 +68,7 @@ module Helicone
80
68
  end
81
69
 
82
70
  # Max iterations reached - make one final call without tools to get a response
83
- final_response = @client.chat(messages: @messages, model: @response_model)
71
+ final_response = @client.chat(messages: @messages, model: @model)
84
72
 
85
73
  AgentResult.new(
86
74
  content: final_response.content,
@@ -106,10 +94,10 @@ module Helicone
106
94
  Helicone.configuration.logger
107
95
  end
108
96
 
109
- def call_llm(model: nil)
97
+ def call_llm
110
98
  @client.chat(
111
99
  messages: @messages,
112
- model: model,
100
+ model: @model,
113
101
  tools: tools_for_api,
114
102
  tool_choice: "auto"
115
103
  )
@@ -121,16 +109,17 @@ module Helicone
121
109
  end
122
110
 
123
111
  def execute_tool(tool_call)
124
- tool_class = find_tool_class(tool_call.name)
112
+ tool = find_tool(tool_call.name)
125
113
 
126
- unless tool_class
114
+ unless tool
127
115
  logger.warn("[Helicone::Agent] Unknown tool: #{tool_call.name}")
128
116
  return { error: "Unknown tool: #{tool_call.name}" }
129
117
  end
130
118
 
131
119
  logger.info("[Helicone::Agent] Executing tool: #{tool_call.name} with #{tool_call.arguments}")
132
120
 
133
- tool_instance = tool_class.new(@context)
121
+ # Support both tool classes and tool instances
122
+ tool_instance = tool.is_a?(Class) ? tool.new(@context) : tool
134
123
  result = tool_instance.execute(**tool_call.arguments)
135
124
 
136
125
  result_preview = result.inspect
@@ -143,7 +132,7 @@ module Helicone
143
132
  { error: e.message }
144
133
  end
145
134
 
146
- def find_tool_class(name)
135
+ def find_tool(name)
147
136
  @tools.find { |t| t.function_name == name }
148
137
  end
149
138
 
@@ -13,7 +13,7 @@ module Helicone
13
13
  def initialize(session_id: nil, session_name: nil, account_id: nil, account_name: nil)
14
14
  @client = OpenAI::Client.new(
15
15
  access_token: ENV["HELICONE_API_KEY"],
16
- uri_base: Helicone::URI_BASE
16
+ uri_base: Helicone.configuration.base_url
17
17
  )
18
18
 
19
19
  # Add Helicone session headers if provided
@@ -3,16 +3,17 @@
3
3
  require "logger"
4
4
 
5
5
  module Helicone
6
- URI_BASE = "https://ai-gateway.helicone.ai/v1"
6
+ DEFAULT_BASE_URL = "https://ai-gateway.helicone.ai/v1"
7
7
 
8
8
  class Configuration
9
- attr_accessor :logger, :default_model
9
+ attr_accessor :logger, :default_model, :base_url
10
10
 
11
11
  # Initialize configuration with defaults
12
12
  #
13
13
  # @return [Configuration]
14
14
  def initialize
15
15
  @default_model = "gpt-4o"
16
+ @base_url = DEFAULT_BASE_URL
16
17
  @logger = Logger.new($stdout, level: Logger::INFO)
17
18
  end
18
19
  end
@@ -113,9 +113,11 @@ module Helicone
113
113
  #
114
114
  # @return [Hash] Message formatted for the API
115
115
  def to_h
116
- # If this is a raw message (assistant with tool_calls), return it as-is
117
116
  if @raw_message
118
- @raw_message
117
+ # Select only the fields needed for the API
118
+ hash = { role: @raw_message[:role], content: @raw_message[:content] }
119
+ hash[:tool_calls] = @raw_message[:tool_calls] if @raw_message[:tool_calls]
120
+ hash
119
121
  else
120
122
  hash = { role: role, content: content }
121
123
  hash[:tool_call_id] = tool_call_id if tool_call_id
data/lib/helicone/tool.rb CHANGED
@@ -98,5 +98,19 @@ module Helicone
98
98
  def execute(**args)
99
99
  raise NotImplementedError, "Subclasses must implement #execute"
100
100
  end
101
+
102
+ # Delegate to class method for instances
103
+ #
104
+ # @return [Hash] Tool definition formatted for OpenAI API
105
+ def to_openai_tool
106
+ self.class.to_openai_tool
107
+ end
108
+
109
+ # Delegate to class method for instances
110
+ #
111
+ # @return [String] The function name
112
+ def function_name
113
+ self.class.function_name
114
+ end
101
115
  end
102
116
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Helicone
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: helicone-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Genevere