rager 0.5.0 → 0.6.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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +50 -7
  3. data/lib/rager/chat/options.rb +9 -5
  4. data/lib/rager/chat/providers/openai.rb +27 -26
  5. data/lib/rager/chat/schema.rb +3 -2
  6. data/lib/rager/config.rb +5 -1
  7. data/lib/rager/context.rb +168 -55
  8. data/lib/rager/embed/options.rb +1 -0
  9. data/lib/rager/embed/providers/openai.rb +8 -4
  10. data/lib/rager/errors/credentials_error.rb +24 -0
  11. data/lib/rager/errors/dependency_error.rb +23 -0
  12. data/lib/rager/errors/http_error.rb +12 -5
  13. data/lib/rager/errors/options_error.rb +10 -5
  14. data/lib/rager/errors/parse_error.rb +9 -5
  15. data/lib/rager/errors/template_error.rb +10 -4
  16. data/lib/rager/errors/timeout_error.rb +25 -0
  17. data/lib/rager/http/adapters/async_http.rb +67 -13
  18. data/lib/rager/http/adapters/mock.rb +43 -45
  19. data/lib/rager/http/adapters/net_http.rb +145 -0
  20. data/lib/rager/http/request.rb +2 -0
  21. data/lib/rager/image_gen/options.rb +1 -0
  22. data/lib/rager/image_gen/providers/replicate.rb +5 -4
  23. data/lib/rager/mesh_gen/options.rb +1 -0
  24. data/lib/rager/mesh_gen/providers/replicate.rb +7 -5
  25. data/lib/rager/providers.rb +49 -0
  26. data/lib/rager/rerank/options.rb +1 -0
  27. data/lib/rager/rerank/{query.rb → output.rb} +2 -2
  28. data/lib/rager/rerank/providers/abstract.rb +3 -2
  29. data/lib/rager/rerank/providers/cohere.rb +17 -14
  30. data/lib/rager/result.rb +49 -29
  31. data/lib/rager/search/options.rb +3 -1
  32. data/lib/rager/search/output.rb +14 -0
  33. data/lib/rager/search/providers/jina.rb +67 -0
  34. data/lib/rager/template/providers/abstract.rb +3 -2
  35. data/lib/rager/template/providers/erb.rb +6 -5
  36. data/lib/rager/types.rb +11 -7
  37. data/lib/rager/utils/http.rb +35 -28
  38. data/lib/rager/utils/replicate.rb +13 -16
  39. data/lib/rager/version.rb +1 -1
  40. metadata +10 -30
  41. data/lib/rager/chat.rb +0 -35
  42. data/lib/rager/embed.rb +0 -35
  43. data/lib/rager/errors/missing_credentials_error.rb +0 -19
  44. data/lib/rager/errors/unknown_provider_error.rb +0 -17
  45. data/lib/rager/image_gen.rb +0 -31
  46. data/lib/rager/mesh_gen.rb +0 -31
  47. data/lib/rager/rerank/result.rb +0 -13
  48. data/lib/rager/rerank.rb +0 -35
  49. data/lib/rager/search/providers/brave.rb +0 -59
  50. data/lib/rager/search/result.rb +0 -14
  51. data/lib/rager/search.rb +0 -35
  52. data/lib/rager/template/input.rb +0 -11
  53. data/lib/rager/template.rb +0 -35
@@ -1,9 +1,10 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "sorbet-runtime"
5
4
  require "json"
6
5
 
6
+ require "sorbet-runtime"
7
+
7
8
  module Rager
8
9
  module Utils
9
10
  module Replicate
@@ -15,8 +16,6 @@ module Rager
15
16
  return nil if download_url.nil?
16
17
 
17
18
  Rager::Utils::Http.download_binary(download_url)
18
- rescue
19
- nil
20
19
  end
21
20
 
22
21
  sig { params(prediction_url: String, key: T.nilable(String), path: String, http_adapter: T.nilable(Rager::Http::Adapters::Abstract)).returns(T.nilable(String)) }
@@ -25,14 +24,12 @@ module Rager
25
24
  return nil if download_url.nil?
26
25
 
27
26
  Rager::Utils::Http.download_file(download_url, path)
28
- rescue
29
- nil
30
27
  end
31
28
 
32
29
  sig { params(prediction_url: String, key: T.nilable(String), http_adapter: T.nilable(Rager::Http::Adapters::Abstract)).returns(T.nilable(String)) }
33
30
  def self.get_download_url(prediction_url, key = nil, http_adapter: nil)
34
31
  api_key = ENV["REPLICATE_API_KEY"]
35
- raise Rager::Errors::MissingCredentialsError.new("Replicate", "REPLICATE_API_KEY") if api_key.nil?
32
+ raise Rager::Errors::CredentialsError.new("Replicate", env_var: ["REPLICATE_API_KEY"]) if api_key.nil?
36
33
 
37
34
  adapter = http_adapter || Rager.config.http_adapter
38
35
  response = adapter.make_request(
@@ -42,14 +39,14 @@ module Rager
42
39
  )
43
40
  )
44
41
 
45
- raise Rager::Errors::HttpError.new(adapter, response.status, T.cast(response.body, T.nilable(String))) unless response.success?
42
+ raise Rager::Errors::HttpError.new(adapter, prediction_url, response.status, body: response.body&.to_s) unless response.success?
46
43
 
47
44
  data = JSON.parse(T.cast(T.must(response.body), String))
48
45
  return nil if ["starting", "processing"].include?(data["status"])
49
46
 
50
47
  if data["status"] == "failed"
51
48
  error_msg = data["error"] || "Prediction failed"
52
- raise Rager::Errors::HttpError.new(adapter, 422, "Prediction failed: #{error_msg}")
49
+ raise Rager::Errors::HttpError.new(adapter, prediction_url, 422, body: error_msg)
53
50
  end
54
51
 
55
52
  return nil unless data["status"] == "succeeded"
@@ -70,11 +67,7 @@ module Rager
70
67
  return nil if download_url.nil? || download_url.empty?
71
68
  download_url
72
69
  rescue JSON::ParserError => e
73
- raise Rager::Errors::ParseError.new("Failed to parse prediction response", e.message)
74
- rescue Rager::Errors::HttpError, Rager::Errors::ParseError, Rager::Errors::MissingCredentialsError
75
- raise
76
- rescue
77
- nil
70
+ raise Rager::Errors::ParseError.new("Failed to parse prediction response", details: e.message)
78
71
  end
79
72
 
80
73
  sig { params(prediction_url: String, key: T.nilable(String), path: T.nilable(String), max_attempts: Integer, sleep_interval: Integer, http_adapter: T.nilable(Rager::Http::Adapters::Abstract)).returns(T.nilable(String)) }
@@ -86,11 +79,15 @@ module Rager
86
79
  download_prediction(prediction_url, key, http_adapter: http_adapter)
87
80
  end
88
81
  return result unless result.nil?
89
- sleep(sleep_interval)
82
+ Rager::Utils::Http.sleep(sleep_interval)
90
83
  end
91
84
 
92
- adapter = http_adapter || Rager.config.http_adapter
93
- raise Rager::Errors::HttpError.new(adapter, 408, "Prediction polling timed out after #{max_attempts} attempts")
85
+ raise Rager::Errors::TimeoutError.new(
86
+ "Replicate prediction polling",
87
+ timeout_seconds: max_attempts * sleep_interval,
88
+ attempts: max_attempts,
89
+ details: "Prediction at #{prediction_url} did not complete within #{max_attempts} attempts"
90
+ )
94
91
  end
95
92
  end
96
93
  end
data/lib/rager/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Rager
5
- VERSION = "0.5.0"
5
+ VERSION = "0.6.0"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rager
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - mvkvc
@@ -23,20 +23,6 @@ dependencies:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
25
  version: '1.14'
26
- - !ruby/object:Gem::Dependency
27
- name: ostruct
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - "~>"
31
- - !ruby/object:Gem::Version
32
- version: 0.6.2
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: 0.6.2
40
26
  - !ruby/object:Gem::Dependency
41
27
  name: sorbet-runtime
42
28
  requirement: !ruby/object:Gem::Requirement
@@ -74,7 +60,6 @@ files:
74
60
  - LICENSE.md
75
61
  - README.md
76
62
  - lib/rager.rb
77
- - lib/rager/chat.rb
78
63
  - lib/rager/chat/message.rb
79
64
  - lib/rager/chat/message_content.rb
80
65
  - lib/rager/chat/message_content_image_type.rb
@@ -87,49 +72,44 @@ files:
87
72
  - lib/rager/chat/schema.rb
88
73
  - lib/rager/config.rb
89
74
  - lib/rager/context.rb
90
- - lib/rager/embed.rb
91
75
  - lib/rager/embed/options.rb
92
76
  - lib/rager/embed/providers/abstract.rb
93
77
  - lib/rager/embed/providers/openai.rb
94
78
  - lib/rager/error.rb
79
+ - lib/rager/errors/credentials_error.rb
80
+ - lib/rager/errors/dependency_error.rb
95
81
  - lib/rager/errors/http_error.rb
96
- - lib/rager/errors/missing_credentials_error.rb
97
82
  - lib/rager/errors/options_error.rb
98
83
  - lib/rager/errors/parse_error.rb
99
84
  - lib/rager/errors/template_error.rb
100
- - lib/rager/errors/unknown_provider_error.rb
85
+ - lib/rager/errors/timeout_error.rb
101
86
  - lib/rager/http/adapters/abstract.rb
102
87
  - lib/rager/http/adapters/async_http.rb
103
88
  - lib/rager/http/adapters/mock.rb
89
+ - lib/rager/http/adapters/net_http.rb
104
90
  - lib/rager/http/request.rb
105
91
  - lib/rager/http/response.rb
106
92
  - lib/rager/http/verb.rb
107
- - lib/rager/image_gen.rb
108
93
  - lib/rager/image_gen/options.rb
109
94
  - lib/rager/image_gen/output_format.rb
110
95
  - lib/rager/image_gen/providers/abstract.rb
111
96
  - lib/rager/image_gen/providers/replicate.rb
112
97
  - lib/rager/logger.rb
113
- - lib/rager/mesh_gen.rb
114
98
  - lib/rager/mesh_gen/options.rb
115
99
  - lib/rager/mesh_gen/providers/abstract.rb
116
100
  - lib/rager/mesh_gen/providers/replicate.rb
117
101
  - lib/rager/operation.rb
118
102
  - lib/rager/options.rb
119
- - lib/rager/rerank.rb
103
+ - lib/rager/providers.rb
120
104
  - lib/rager/rerank/options.rb
105
+ - lib/rager/rerank/output.rb
121
106
  - lib/rager/rerank/providers/abstract.rb
122
107
  - lib/rager/rerank/providers/cohere.rb
123
- - lib/rager/rerank/query.rb
124
- - lib/rager/rerank/result.rb
125
108
  - lib/rager/result.rb
126
- - lib/rager/search.rb
127
109
  - lib/rager/search/options.rb
110
+ - lib/rager/search/output.rb
128
111
  - lib/rager/search/providers/abstract.rb
129
- - lib/rager/search/providers/brave.rb
130
- - lib/rager/search/result.rb
131
- - lib/rager/template.rb
132
- - lib/rager/template/input.rb
112
+ - lib/rager/search/providers/jina.rb
133
113
  - lib/rager/template/options.rb
134
114
  - lib/rager/template/providers/abstract.rb
135
115
  - lib/rager/template/providers/erb.rb
@@ -157,5 +137,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
137
  requirements: []
158
138
  rubygems_version: 3.6.7
159
139
  specification_version: 4
160
- summary: Build continuously improving AI applications.
140
+ summary: Build continuously improving generative workflows.
161
141
  test_files: []
data/lib/rager/chat.rb DELETED
@@ -1,35 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "sorbet-runtime"
5
-
6
- module Rager
7
- module Chat
8
- extend T::Sig
9
-
10
- sig do
11
- params(
12
- messages: Rager::Types::ChatInput,
13
- options: Rager::Chat::Options
14
- ).returns(Rager::Types::ChatOutput)
15
- end
16
- def self.chat(messages, options = Rager::Chat::Options.new)
17
- provider = get_provider(options.provider)
18
- provider.chat(messages, options)
19
- end
20
-
21
- sig do
22
- params(
23
- key: String
24
- ).returns(Rager::Chat::Providers::Abstract)
25
- end
26
- def self.get_provider(key)
27
- case key.downcase
28
- when "openai"
29
- Rager::Chat::Providers::Openai.new
30
- else
31
- raise Rager::Errors::UnknownProviderError.new(Rager::Operation::Chat, key)
32
- end
33
- end
34
- end
35
- end
data/lib/rager/embed.rb DELETED
@@ -1,35 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "sorbet-runtime"
5
-
6
- module Rager
7
- module Embed
8
- extend T::Sig
9
-
10
- sig do
11
- params(
12
- text: Rager::Types::EmbedInput,
13
- options: Rager::Embed::Options
14
- ).returns(Rager::Types::EmbedOutput)
15
- end
16
- def self.embed(text, options = Rager::Embed::Options.new)
17
- provider = get_provider(options.provider)
18
- provider.embed(text, options)
19
- end
20
-
21
- sig do
22
- params(
23
- key: String
24
- ).returns(Rager::Embed::Providers::Abstract)
25
- end
26
- def self.get_provider(key)
27
- case key.downcase
28
- when "openai"
29
- Rager::Embed::Providers::Openai.new
30
- else
31
- raise Rager::Errors::UnknownProviderError.new(Rager::Operation::Embed, key)
32
- end
33
- end
34
- end
35
- end
@@ -1,19 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "sorbet-runtime"
5
-
6
- module Rager
7
- module Errors
8
- class MissingCredentialsError < Rager::Error
9
- extend T::Sig
10
-
11
- sig { params(provider_name: String, env_var: T.nilable(String)).void }
12
- def initialize(provider_name, env_var = nil)
13
- message = "Missing credentials for provider #{provider_name}"
14
- message += " -- attempted lookup with #{env_var}" if env_var
15
- super(message)
16
- end
17
- end
18
- end
19
- end
@@ -1,17 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "sorbet-runtime"
5
-
6
- module Rager
7
- module Errors
8
- class UnknownProviderError < Rager::Error
9
- extend T::Sig
10
-
11
- sig { params(operation: Rager::Operation, key: String).void }
12
- def initialize(operation, key)
13
- super("Unknown provider #{key} for operation #{operation.serialize}")
14
- end
15
- end
16
- end
17
- end
@@ -1,31 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "sorbet-runtime"
5
-
6
- module Rager
7
- module ImageGen
8
- extend T::Sig
9
-
10
- sig do
11
- params(
12
- prompt: Rager::Types::ImageGenInput,
13
- options: Rager::ImageGen::Options
14
- ).returns(Rager::Types::ImageGenOutput)
15
- end
16
- def self.image_gen(prompt, options = Rager::ImageGen::Options.new)
17
- provider = get_provider(options.provider)
18
- provider.image_gen(prompt, options)
19
- end
20
-
21
- sig { params(key: String).returns(Rager::ImageGen::Providers::Abstract) }
22
- def self.get_provider(key)
23
- case key.downcase
24
- when "replicate"
25
- Rager::ImageGen::Providers::Replicate.new
26
- else
27
- raise Rager::Errors::UnknownProviderError.new(Rager::Operation::ImageGen, key)
28
- end
29
- end
30
- end
31
- end
@@ -1,31 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "sorbet-runtime"
5
-
6
- module Rager
7
- module MeshGen
8
- extend T::Sig
9
-
10
- sig do
11
- params(
12
- image_url: Rager::Types::MeshGenInput,
13
- options: Rager::MeshGen::Options
14
- ).returns(Rager::Types::MeshGenOutput)
15
- end
16
- def self.mesh_gen(image_url, options = Rager::MeshGen::Options.new)
17
- provider = get_provider(options.provider)
18
- provider.mesh_gen(image_url, options)
19
- end
20
-
21
- sig { params(key: String).returns(Rager::MeshGen::Providers::Abstract) }
22
- def self.get_provider(key)
23
- case key.downcase
24
- when "replicate"
25
- Rager::MeshGen::Providers::Replicate.new
26
- else
27
- raise Rager::Errors::UnknownProviderError.new(Rager::Operation::MeshGen, key)
28
- end
29
- end
30
- end
31
- end
@@ -1,13 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "sorbet-runtime"
5
-
6
- module Rager
7
- module Rerank
8
- class Result < T::Struct
9
- const :score, Float
10
- const :index, Integer
11
- end
12
- end
13
- end
data/lib/rager/rerank.rb DELETED
@@ -1,35 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "sorbet-runtime"
5
-
6
- module Rager
7
- module Rerank
8
- extend T::Sig
9
-
10
- sig do
11
- params(
12
- query: Rager::Types::RerankInput,
13
- options: Rager::Rerank::Options
14
- ).returns(Rager::Types::RerankOutput)
15
- end
16
- def self.rerank(query, options = Rager::Rerank::Options.new)
17
- provider = get_provider(options.provider)
18
- provider.rerank(query, options)
19
- end
20
-
21
- sig do
22
- params(
23
- key: String
24
- ).returns(Rager::Rerank::Providers::Abstract)
25
- end
26
- def self.get_provider(key)
27
- case key.downcase
28
- when "cohere"
29
- Rager::Rerank::Providers::Cohere.new
30
- else
31
- raise Rager::Errors::UnknownProviderError.new(Rager::Operation::Rerank, key)
32
- end
33
- end
34
- end
35
- end
@@ -1,59 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "json"
5
- require "uri"
6
- require "sorbet-runtime"
7
-
8
- module Rager
9
- module Search
10
- module Providers
11
- class Brave < Rager::Search::Providers::Abstract
12
- extend T::Sig
13
-
14
- sig do
15
- override.params(
16
- query: String,
17
- options: Rager::Search::Options
18
- ).returns(Rager::Types::SearchOutput)
19
- end
20
- def search(query, options)
21
- api_key = options.api_key || ENV["BRAVE_API_KEY"]
22
- raise Rager::Errors::MissingCredentialsError.new("Brave", "BRAVE_API_KEY") if api_key.nil?
23
-
24
- params = {"q" => query}.tap do |p|
25
- p["count"] = options.n.to_s if options.n
26
- end
27
-
28
- request = Rager::Http::Request.new(
29
- verb: Rager::Http::Verb::Get,
30
- url: "https://api.search.brave.com/res/v1/web/search?#{URI.encode_www_form(params)}",
31
- headers: {
32
- "Accept" => "application/json",
33
- "Accept-Encoding" => "gzip",
34
- "x-subscription-token" => api_key
35
- }
36
- )
37
-
38
- response = Rager.config.http_adapter.make_request(request)
39
- response_body = T.cast(T.must(response.body), String)
40
-
41
- raise Rager::Errors::HttpError.new(Rager.config.http_adapter, response.status, response_body) if response.status != 200
42
-
43
- parsed_response = JSON.parse(response_body)
44
- web_results = parsed_response.dig("web", "results") || []
45
-
46
- web_results.filter_map do |result|
47
- next unless result["title"] && result["url"] && result["description"]
48
-
49
- Rager::Search::Result.new(
50
- title: result["title"],
51
- url: result["url"],
52
- description: result["description"]
53
- )
54
- end
55
- end
56
- end
57
- end
58
- end
59
- end
@@ -1,14 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "sorbet-runtime"
5
-
6
- module Rager
7
- module Search
8
- class Result < T::Struct
9
- const :title, String
10
- const :url, String
11
- const :description, String
12
- end
13
- end
14
- end
data/lib/rager/search.rb DELETED
@@ -1,35 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "sorbet-runtime"
5
-
6
- module Rager
7
- module Search
8
- extend T::Sig
9
-
10
- sig do
11
- params(
12
- query: Rager::Types::SearchInput,
13
- options: Rager::Search::Options
14
- ).returns(Rager::Types::SearchOutput)
15
- end
16
- def self.search(query, options = Rager::Search::Options.new)
17
- provider = get_provider(options.provider)
18
- provider.search(query, options)
19
- end
20
-
21
- sig do
22
- params(
23
- key: String
24
- ).returns(Rager::Search::Providers::Abstract)
25
- end
26
- def self.get_provider(key)
27
- case key.downcase
28
- when "brave"
29
- Rager::Search::Providers::Brave.new
30
- else
31
- raise Rager::Errors::UnknownProviderError.new(Rager::Operation::Search, key)
32
- end
33
- end
34
- end
35
- end
@@ -1,11 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module Rager
5
- module Template
6
- class Input < T::Struct
7
- const :template, String
8
- const :variables, T::Hash[Symbol, T.untyped]
9
- end
10
- end
11
- end
@@ -1,35 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "sorbet-runtime"
5
-
6
- module Rager
7
- module Template
8
- extend T::Sig
9
-
10
- sig do
11
- params(
12
- input: Rager::Types::TemplateInput,
13
- options: Rager::Template::Options
14
- ).returns(Rager::Types::TemplateOutput)
15
- end
16
- def self.template(input, options = Rager::Template::Options.new)
17
- provider = get_provider(options.provider)
18
- provider.template(input, options)
19
- end
20
-
21
- sig do
22
- params(
23
- key: String
24
- ).returns(Rager::Template::Providers::Abstract)
25
- end
26
- def self.get_provider(key)
27
- case key.downcase
28
- when "erb"
29
- Rager::Template::Providers::Erb.new
30
- else
31
- raise Rager::Errors::UnknownProviderError.new(Rager::Operation::Template, key)
32
- end
33
- end
34
- end
35
- end