ticuna 0.2.2 → 0.2.3

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: '058bd0a97b93a756f03650373f98ba045b49a7b72499d8fd259d3520ab375fcd'
4
- data.tar.gz: 1377d3415e111d5ed72cee4e68f9ff9b98f4a1d947c6bbb854820d8abe82e765
3
+ metadata.gz: ed7e518a619aff9c77fec2caa59f41dac2b59579b8251f8e3a4c2a7c4ac67a6c
4
+ data.tar.gz: '0354393beca32a03a6cb6b3baec13f6c3ae778b30361e1dd0a7f99b9429145d8'
5
5
  SHA512:
6
- metadata.gz: 41144c5b7ba4226d026d055f33a960174dc7cde8e726dc68f19d2abc44dfda5cbf14fac3fe1f7bbdbd4c8b51d126712200fba3902f9d4e88dc1846f9eede7355
7
- data.tar.gz: a1d5312ecfb22e1f7fa99ae35bc1057a9aff4e5aae60faa227dbbe8d95f59eb31526126da0aa0cbdf2ac51e34b9958abfe03749064fe59058dfd42686f01bf07
6
+ metadata.gz: d3f77ed0c120817f1b9c9a78a0c46ef8478bc69aaad36f550011973eaaa2cede88fa36b3733921ac53b181b9236f130b2e00ff7b7071a497f244a622a4e17153
7
+ data.tar.gz: 4d1aaa4760a7b40fa09b7574d585322758445f9290b53272085694a3347794cf03d317d7f69b67b39eae309c28e74025d80c334c612d6acef735a00cfc36e897
data/CHANGELOG.md CHANGED
@@ -16,3 +16,9 @@
16
16
 
17
17
  ## [0.2.2] - 2025-10-06
18
18
  - Add support for OpenAI with stream and output_format (json or text), [PR here](https://github.com/thiagochirana/ticuna/pull/2)
19
+
20
+ ## [0.2.2.1] - 2025-10-06
21
+ - Remove timeout for requests
22
+
23
+ ## [0.2.3] - 2025-10-09
24
+ - Fix errors
@@ -2,8 +2,8 @@
2
2
 
3
3
  Ticuna.config do |c|
4
4
  # Configure your API Keys here
5
- # c.openai_token = ENV["OPENAI_API_KEY"]
6
- # c.anthropic_token = ENV["ANTHROPIC_API_KEY"]
7
- # c.deepseek_token = ENV["DEEPSEEK_API_KEY"]
8
- # c.mistral_token = ENV["MISTRAL_API_KEY"]
5
+ # c.openai_token = ENV.fetch("OPENAI_API_KEY", nil)
6
+ # c.anthropic_token = ENV.fetch("ANTHROPIC_API_KEY", nil)
7
+ # c.deepseek_token = ENV.fetch("DEEPSEEK_API_KEY", nil)
8
+ # c.mistral_token = ENV.fetch("MISTRAL_API_KEY", nil)
9
9
  end
@@ -15,7 +15,10 @@ module Ticuna
15
15
  "Content-Type" => "application/json",
16
16
  "Authorization" => "Bearer #{api_key}"
17
17
  }
18
- )
18
+ ) do |f|
19
+ f.options.timeout = nil
20
+ f.options.open_timeout = nil
21
+ end
19
22
  end
20
23
  end
21
24
  end
data/lib/ticuna/config.rb CHANGED
@@ -1,14 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "dotenv"
4
+ Dotenv.load
5
+
3
6
  module Ticuna
4
7
  class Config
5
8
  attr_accessor :openai_token, :anthropic_token, :deepseek_token, :mistral_token
6
9
 
7
10
  def initialize
8
- @openai_token = nil
9
- @anthropic_token = nil
10
- @deepseek_token = nil
11
- @mistral_token = nil
11
+ @openai_token = ENV.fetch("OPENAI_API_KEY", nil)
12
+ @anthropic_token = ENV.fetch("ANTHROPIC_API_KEY", nil)
13
+ @deepseek_token = ENV.fetch("DEEPSEEK_API_KEY", nil)
14
+ @mistral_token = ENV.fetch("MISTRAL_API_KEY", nil)
12
15
  end
13
16
 
14
17
  def openai_token=(token)
data/lib/ticuna/llm.rb CHANGED
@@ -1,28 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "ticuna/providers/openai"
4
+ require "ticuna/providers"
4
5
  require "ticuna/config"
5
6
  require "ticuna/response"
6
7
 
7
8
  module Ticuna
8
9
  class LLM
9
- PROVIDERS_ENV = {
10
- openai: -> { Ticuna.config.openai_token },
11
- anthropic: -> { Ticuna.config.anthropic_token },
12
- deepseek: -> { Ticuna.config.deepseek_token },
13
- mistral: -> { Ticuna.config.mistral_token }
14
- }.freeze
15
-
16
- PROVIDERS_CLIENT = {
17
- openai: -> { Ticuna::Providers::OpenAI.new(api_key: PROVIDERS_ENV[:openai].call) }
18
- # anthropic: -> { Ticuna::Providers::Anthropic.new(api_key: PROVIDERS_ENV[:anthropic].call) },
19
- # deepseek: -> { Ticuna::Providers::DeepSeek.new(api_key: PROVIDERS_ENV[:deepseek].call) },
20
- # mistral: -> { Ticuna::Providers::Mistral.new(api_key: PROVIDERS_ENV[:mistral].call) }
21
- }.freeze
22
-
23
10
  def self.new(provider = nil)
24
11
  provider_key = detect_provider(provider)
25
- provider_client = PROVIDERS_CLIENT[provider_key].call
12
+ provider_client = Ticuna::Providers::CLIENTS[provider_key].call
26
13
  new_instance = allocate
27
14
  new_instance.send(:initialize_llm, provider_client)
28
15
  new_instance
@@ -38,13 +25,13 @@ module Ticuna
38
25
  self
39
26
  end
40
27
 
41
- def ask(message, stream: false, model: "gpt-4.1-nano", output_format: :text, &block)
28
+ def ask(message, stream: false, model: :gpt_4_1, output_format: :text, &block)
42
29
  tool_contexts = @tools.map(&:context).compact.join("\n\n")
43
30
 
44
31
  system_message = if tool_contexts.empty?
45
32
  nil
46
33
  else
47
- { role: "system", content: "Tools contexts:\n\n#{tool_contexts}" }
34
+ { role: "developer", content: tool_contexts }
48
35
  end
49
36
 
50
37
  messages = if system_message
@@ -53,25 +40,42 @@ module Ticuna
53
40
  [{ role: "user", content: message }]
54
41
  end
55
42
 
43
+ model_string = resolve_model(model)
44
+
56
45
  Ticuna::Response.new(
57
- @provider.ask_with_messages(messages, stream: stream, model: model, output_format: output_format, &block)
46
+ @provider.ask_with_messages(messages, stream: stream, model: model_string, output_format: output_format, &block)
58
47
  )
59
48
  end
60
49
 
61
50
  private
62
51
 
63
- def self.detect_provider(provider)
64
- return provider.to_sym if provider
52
+ def resolve_model(model)
53
+ return model.to_s unless model.is_a?(Symbol)
54
+ return model if Ticuna::Providers::MODELS.key?(model)
55
+
56
+ available_models = Ticuna::Providers::MODELS.flat_map { |provider, models|
57
+ models.keys.map { |m| ":#{m} (#{provider})" }
58
+ }.join(", ")
59
+
60
+ raise "Model ':#{model}' not found. Available models: #{available_models}"
61
+ end
62
+
63
+ class << self
64
+ private
65
+
66
+ def detect_provider(provider)
67
+ return provider.to_sym if provider
65
68
 
66
- valid = PROVIDERS_ENV.reject { |_, env_var| env_var.call&.strip.to_s == "" }
69
+ valid = Ticuna::Providers::ENVS.reject { |_, env_var| env_var.call&.strip.to_s == "" }
67
70
 
68
- case valid.size
69
- when 0
70
- raise "Provider not found. Define at least one in config/initializers/ticuna.rb"
71
- when 1
72
- valid.keys.first
73
- else
74
- raise "Multiple LLM APIs providers detected: #{valid.keys.join(", ")}. Define one in Ticuna::LLM.new(provider: :provider_name)."
71
+ case valid.size
72
+ when 0
73
+ raise "Provider not found. Define at least one in config/initializers/ticuna.rb"
74
+ when 1
75
+ valid.keys.first
76
+ else
77
+ raise "Multiple LLM APIs providers detected: #{valid.keys.join(", ")}.\nDefine one in Ticuna::LLM.new(model: :provider_name)."
78
+ end
75
79
  end
76
80
  end
77
81
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ticuna
4
+ module Providers
5
+ MODELS = {
6
+ gpt_4_1: "gpt-4.1",
7
+ gpt_4_1_nano: "gpt-4.1-nano",
8
+ gpt_4_1_mini: "gpt-4.1-mini",
9
+ gpt_5: "gpt-5",
10
+ gpt_5_nano: "gpt-5-nano",
11
+ gpt_5_mini: "gpt-5-mini"
12
+ }.freeze
13
+
14
+ ENVS = {
15
+ openai: -> { Ticuna.config.openai_token }
16
+ # anthropic: -> { Ticuna.config.anthropic_token },
17
+ # deepseek: -> { Ticuna.config.deepseek_token },
18
+ # mistral: -> { Ticuna.config.mistral_token }
19
+ }.freeze
20
+
21
+ CLIENTS = {
22
+ openai: -> { Ticuna::Providers::OpenAI.new(api_key: ENVS[:openai].call) }
23
+ # anthropic: -> { Ticuna::Providers::Anthropic.new(api_key: ENVS[:anthropic].call) },
24
+ # deepseek: -> { Ticuna::Providers::DeepSeek.new(api_key: ENVS[:deepseek].call) },
25
+ # mistral: -> { Ticuna::Providers::Mistral.new(api_key: ENVS[:mistral].call) }
26
+ }.freeze
27
+ end
28
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ticuna
4
- VERSION = "0.2.2"
4
+ VERSION = "0.2.3"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ticuna
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chirana
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-10-06 00:00:00.000000000 Z
11
+ date: 2025-10-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -45,6 +45,7 @@ files:
45
45
  - lib/ticuna/base_provider.rb
46
46
  - lib/ticuna/config.rb
47
47
  - lib/ticuna/llm.rb
48
+ - lib/ticuna/providers.rb
48
49
  - lib/ticuna/providers/openai.rb
49
50
  - lib/ticuna/response.rb
50
51
  - lib/ticuna/tool.rb