patient_llm 0.3.0 → 0.4.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: c5a3fc235def2976b4a57107239ab72e51a50a2b3abdfed579c0c0d4ea6f681d
4
- data.tar.gz: 77b63683fc706598ab29e2fa710d9d6650c568712301e1ff4d87bd8a50668228
3
+ metadata.gz: 87bcd18afe8c5a4c46e191946f51201e077b355d223ac9d1817bd4041041143f
4
+ data.tar.gz: 51a67045f05fc5f55ec1aee9391006eecf60170c3d3e47f3248d2169046ffa0e
5
5
  SHA512:
6
- metadata.gz: e43ffc0679e0ab348e8462884042ba538d734101acfb5b7ecb5e4058167dc3fdd7aa50ad953a091695faae5ad1ce4c25ff1b13614c2ac553587b3568115e8f9a
7
- data.tar.gz: 034554bf031c5696ddb2bf877463f9cbcf5e57e32cdc39563975de22f0ea6cde189be72cfe053ea1338144b320254196ed51589ded11ba753161e4af544de3e4
6
+ metadata.gz: 594c2deb985655a5396c587e6bce19f603f2f2ae9af3c6df1d8f268f5ac81d9a2542bedeed966f84700ed6f971cc1e1916bf0be3f217397fd07840a794a1f005
7
+ data.tar.gz: 2e4d20a58e2ce23bb882c1035a98aca401644b85171661b039aa1bc0b7ac5a55a207095ca5facf54723e6ff6baa06e39e752948411dbf3100183bcb041c082f5
data/CHANGELOG.md CHANGED
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## 0.4.0
8
+
9
+ ### Added
10
+
11
+ - Added `preprocessors:` option to provider configuration and `PatientLLM.ask` for applying named PatientHttp request preprocessors (e.g., AWS SigV4 request signing) at dispatch time. A per-request value replaces the provider default; pass an empty array to clear it for a single request.
12
+
13
+ ### Changed
14
+
15
+ - Requires patient_http version 1.2 or higher.
16
+
7
17
  ## 0.3.0
8
18
 
9
19
  ### Changed
data/README.md CHANGED
@@ -52,6 +52,38 @@ end
52
52
  > [!NOTE]
53
53
  > You can also set up encryption for your job payloads to ensure the entire serialized payload is always encrypted in the job queue. See the documentation for [patient_http-sidekiq](https://github.com/bdurand/patient_http-sidekiq#sensitive-data-handling) or [patient_http-solid_queue](https://github.com/bdurand/patient_http-solid_queue#sensitive-data-handling) for details.
54
54
 
55
+ ### Request signing (preprocessors)
56
+
57
+ Some providers require request signing rather than a static authentication header — for example, AWS Bedrock with SigV4, where a signature is computed over the final outgoing request. For these, register a [request preprocessor](https://github.com/bdurand/patient_http#request-preprocessors) on the PatientHttp configuration and reference it by name from the provider. Like secrets, only the preprocessor name is serialized into the job queue; the signing logic and credentials stay on the processor side.
58
+
59
+ ```ruby
60
+ PatientLLM.configure do |config|
61
+ config.provider :bedrock,
62
+ url: "https://bedrock-runtime.us-east-1.amazonaws.com",
63
+ serializer: :converse,
64
+ preprocessors: :aws_sigv4
65
+ end
66
+
67
+ PatientHttp::Sidekiq.configure do |config|
68
+ config.register_preprocessor(:aws_sigv4) do |request|
69
+ signer = Aws::Sigv4::Signer.new(
70
+ service: "bedrock",
71
+ region: "us-east-1",
72
+ credentials_provider: Aws::CredentialProviderChain.new.resolve
73
+ )
74
+ signature = signer.sign_request(
75
+ http_method: request.http_method.to_s.upcase,
76
+ url: request.url,
77
+ headers: request.headers.to_h,
78
+ body: request.body.to_s
79
+ )
80
+ signature.headers.each { |name, value| request.headers[name] = value }
81
+ end
82
+ end
83
+ ```
84
+
85
+ Multiple preprocessors can be given as an array; they run in order at dispatch time.
86
+
55
87
  ### Creating a Callback Class
56
88
 
57
89
  Create a callback class with `on_complete` and `on_error` methods. Callbacks receive
@@ -189,10 +221,13 @@ PatientLLM.ask(session,
189
221
  serializer: :messages, # Override the API format
190
222
  path: "/chat/completions", # Override the endpoint path
191
223
  headers: {"X-Custom" => "value"}, # Additional HTTP headers
192
- params: {max_completion_tokens: 1000} # Additional request parameters
224
+ params: {max_completion_tokens: 1000}, # Additional request parameters
225
+ preprocessors: :aws_sigv4 # Replace the provider's request preprocessors
193
226
  )
194
227
  ```
195
228
 
229
+ Note that `headers` and `params` are merged on top of the provider's configured values, while `preprocessors` (like `url`, `serializer`, and `path`) replaces the provider default. Pass `preprocessors: []` to clear a provider-level preprocessor for a single request.
230
+
196
231
  ### URL composition
197
232
 
198
233
  The full request URL is built by concatenating the base URL (from the provider registry or the `url:` option) with the `path`. When you don't set `path`, it defaults to the path for the active serializer (`/v1/chat/completions` for `:chat_completion`, `/v1/responses` for `:open_responses`, `/v1/messages` for `:messages`, `/converse` for `:converse`, `/v1beta/models/{model}:generateContent` for `:gemini`). A `{model}` placeholder in the path is replaced with the session's model at dispatch time, which is how the Gemini default targets Google's `/v1beta/models/{model}:generateContent` endpoint. Trailing slashes on the base and leading slashes on the path are normalized, so:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
@@ -216,6 +216,7 @@ module PatientLLM
216
216
  ask_kwargs[:path] = request_options["path"] if request_options["path"]
217
217
  ask_kwargs[:headers] = request_options["headers"] if request_options["headers"]
218
218
  ask_kwargs[:params] = request_options["params"] if request_options["params"]
219
+ ask_kwargs[:preprocessors] = request_options["preprocessors"] if request_options["preprocessors"]
219
220
 
220
221
  PatientLLM.ask(session, **ask_kwargs)
221
222
  end
@@ -29,8 +29,11 @@ module PatientLLM
29
29
  # @param path [String, nil] Override the default endpoint path
30
30
  # @param completion_path [String, nil] Deprecated alias for +path+
31
31
  # @param params [Hash] Additional parameters to merge into every request payload
32
+ # @param preprocessors [String, Symbol, Array<String, Symbol>, nil] Names of request
33
+ # preprocessors to apply to every request (e.g. for request signing). Names must be
34
+ # registered on the PatientHttp configuration with `register_preprocessor`.
32
35
  # @return [void]
33
- def provider(name, url:, headers: {}, serializer: :chat_completion, path: nil, completion_path: nil, params: {})
36
+ def provider(name, url:, headers: {}, serializer: :chat_completion, path: nil, completion_path: nil, params: {}, preprocessors: nil)
34
37
  if completion_path
35
38
  warn "PatientLLM::Configuration#provider: the `completion_path:` argument is deprecated; use `path:` instead", uplevel: 1
36
39
  path ||= completion_path
@@ -48,7 +51,8 @@ module PatientLLM
48
51
  headers: headers,
49
52
  serializer: sym,
50
53
  path: path,
51
- params: params
54
+ params: params,
55
+ preprocessors: preprocessors
52
56
  }
53
57
  end
54
58
 
data/lib/patient_llm.rb CHANGED
@@ -67,8 +67,11 @@ module PatientLLM
67
67
  # @param completion_path [String, nil] Deprecated alias for +path+
68
68
  # @param headers [Hash, nil] Additional headers merged on top of provider headers
69
69
  # @param params [Hash, nil] Additional params merged into the request payload
70
+ # @param preprocessors [String, Symbol, Array<String, Symbol>, nil] Names of request
71
+ # preprocessors to apply to this request. Replaces the provider's configured
72
+ # preprocessors; pass an empty array to clear them for this request.
70
73
  # @return [Object] Handler-specific identifier for the enqueued request
71
- def ask(session, provider:, callback:, callback_args: {}, url: nil, serializer: nil, path: nil, completion_path: nil, headers: nil, params: nil, tool_iteration: 0, original_request_id: nil) # :nodoc: tool_iteration and original_request_id are internal
74
+ def ask(session, provider:, callback:, callback_args: {}, url: nil, serializer: nil, path: nil, completion_path: nil, headers: nil, params: nil, preprocessors: nil, tool_iteration: 0, original_request_id: nil) # :nodoc: tool_iteration and original_request_id are internal
72
75
  if completion_path
73
76
  warn "PatientLLM.ask: the `completion_path:` argument is deprecated; use `path:` instead", uplevel: 1
74
77
  path ||= completion_path
@@ -95,6 +98,7 @@ module PatientLLM
95
98
  resolved_headers = {"anthropic-version" => ANTHROPIC_VERSION}.merge(resolved_headers)
96
99
  end
97
100
  resolved_params = (provider_config[:params] || {}).merge(params || {})
101
+ resolved_preprocessors = preprocessors || provider_config[:preprocessors]
98
102
 
99
103
  payload = session.request_payload(resolved_serializer)
100
104
  payload = deep_merge(payload, deep_stringify_keys(resolved_params)) unless resolved_params.empty?
@@ -107,11 +111,13 @@ module PatientLLM
107
111
  request_options["path"] = path if path
108
112
  request_options["headers"] = headers if headers && !headers.empty?
109
113
  request_options["params"] = params if params && !params.empty?
114
+ request_options["preprocessors"] = preprocessors if preprocessors
110
115
 
111
116
  PatientHttp.post(
112
117
  request_url,
113
118
  json: payload,
114
119
  headers: resolved_headers,
120
+ preprocessors: resolved_preprocessors,
115
121
  raise_error_responses: true,
116
122
  callback: PatientLLM::Callback,
117
123
  callback_args: {
data/patient_llm.gemspec CHANGED
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
37
37
 
38
38
  spec.required_ruby_version = ">= 3.0"
39
39
 
40
- spec.add_dependency "patient_http", "~> 1.1"
40
+ spec.add_dependency "patient_http", "~> 1.2"
41
41
  spec.add_dependency "prompt_builder"
42
42
 
43
43
  spec.add_development_dependency "bundler"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: patient_llm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Durand
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '1.1'
18
+ version: '1.2'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '1.1'
25
+ version: '1.2'
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: prompt_builder
28
28
  requirement: !ruby/object:Gem::Requirement