raif 1.3.0 → 1.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.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -5
  3. data/app/assets/builds/raif.css +4 -1
  4. data/app/assets/builds/raif_admin.css +13 -1
  5. data/app/assets/javascript/raif/controllers/conversations_controller.js +1 -1
  6. data/app/assets/stylesheets/raif/admin/conversation.scss +16 -0
  7. data/app/assets/stylesheets/raif/conversations.scss +3 -0
  8. data/app/assets/stylesheets/raif.scss +2 -1
  9. data/app/controllers/raif/admin/application_controller.rb +16 -0
  10. data/app/controllers/raif/admin/configs_controller.rb +94 -0
  11. data/app/controllers/raif/admin/model_completions_controller.rb +18 -1
  12. data/app/controllers/raif/admin/model_tool_invocations_controller.rb +7 -1
  13. data/app/controllers/raif/admin/stats/model_tool_invocations_controller.rb +21 -0
  14. data/app/controllers/raif/admin/stats/tasks_controller.rb +15 -6
  15. data/app/controllers/raif/admin/stats_controller.rb +32 -3
  16. data/app/controllers/raif/conversation_entries_controller.rb +1 -0
  17. data/app/controllers/raif/conversations_controller.rb +10 -2
  18. data/app/jobs/raif/conversation_entry_job.rb +8 -6
  19. data/app/models/raif/admin/task_stat.rb +7 -0
  20. data/app/models/raif/agent.rb +63 -2
  21. data/app/models/raif/agents/native_tool_calling_agent.rb +101 -56
  22. data/app/models/raif/application_record.rb +18 -0
  23. data/app/models/raif/concerns/agent_inference_stats.rb +35 -0
  24. data/app/models/raif/concerns/json_schema_definition.rb +40 -5
  25. data/app/models/raif/concerns/llms/anthropic/message_formatting.rb +28 -0
  26. data/app/models/raif/concerns/llms/anthropic/response_tool_calls.rb +24 -0
  27. data/app/models/raif/concerns/llms/anthropic/tool_formatting.rb +4 -0
  28. data/app/models/raif/concerns/llms/bedrock/message_formatting.rb +36 -0
  29. data/app/models/raif/concerns/llms/bedrock/response_tool_calls.rb +26 -0
  30. data/app/models/raif/concerns/llms/bedrock/tool_formatting.rb +4 -0
  31. data/app/models/raif/concerns/llms/google/message_formatting.rb +109 -0
  32. data/app/models/raif/concerns/llms/google/response_tool_calls.rb +32 -0
  33. data/app/models/raif/concerns/llms/google/tool_formatting.rb +72 -0
  34. data/app/models/raif/concerns/llms/message_formatting.rb +11 -5
  35. data/app/models/raif/concerns/llms/open_ai/json_schema_validation.rb +3 -3
  36. data/app/models/raif/concerns/llms/open_ai_completions/message_formatting.rb +22 -0
  37. data/app/models/raif/concerns/llms/open_ai_completions/response_tool_calls.rb +22 -0
  38. data/app/models/raif/concerns/llms/open_ai_completions/tool_formatting.rb +4 -0
  39. data/app/models/raif/concerns/llms/open_ai_responses/message_formatting.rb +17 -0
  40. data/app/models/raif/concerns/llms/open_ai_responses/response_tool_calls.rb +26 -0
  41. data/app/models/raif/concerns/llms/open_ai_responses/tool_formatting.rb +4 -0
  42. data/app/models/raif/concerns/run_with.rb +127 -0
  43. data/app/models/raif/conversation.rb +91 -8
  44. data/app/models/raif/conversation_entry.rb +32 -1
  45. data/app/models/raif/embedding_model.rb +2 -1
  46. data/app/models/raif/embedding_models/open_ai.rb +1 -1
  47. data/app/models/raif/llm.rb +27 -2
  48. data/app/models/raif/llms/anthropic.rb +7 -19
  49. data/app/models/raif/llms/bedrock.rb +6 -20
  50. data/app/models/raif/llms/google.rb +140 -0
  51. data/app/models/raif/llms/open_ai_base.rb +19 -5
  52. data/app/models/raif/llms/open_ai_completions.rb +6 -11
  53. data/app/models/raif/llms/open_ai_responses.rb +6 -16
  54. data/app/models/raif/llms/open_router.rb +7 -13
  55. data/app/models/raif/model_completion.rb +61 -0
  56. data/app/models/raif/model_tool.rb +10 -2
  57. data/app/models/raif/model_tool_invocation.rb +38 -6
  58. data/app/models/raif/model_tools/agent_final_answer.rb +2 -7
  59. data/app/models/raif/model_tools/provider_managed/code_execution.rb +4 -0
  60. data/app/models/raif/model_tools/provider_managed/image_generation.rb +4 -0
  61. data/app/models/raif/model_tools/provider_managed/web_search.rb +4 -0
  62. data/app/models/raif/streaming_responses/google.rb +71 -0
  63. data/app/models/raif/task.rb +55 -12
  64. data/app/models/raif/user_tool_invocation.rb +19 -0
  65. data/app/views/layouts/raif/admin.html.erb +12 -1
  66. data/app/views/raif/admin/agents/_agent.html.erb +8 -0
  67. data/app/views/raif/admin/agents/_conversation_message.html.erb +28 -6
  68. data/app/views/raif/admin/agents/index.html.erb +2 -0
  69. data/app/views/raif/admin/agents/show.html.erb +46 -1
  70. data/app/views/raif/admin/configs/show.html.erb +117 -0
  71. data/app/views/raif/admin/conversations/_conversation_entry.html.erb +29 -34
  72. data/app/views/raif/admin/conversations/show.html.erb +2 -0
  73. data/app/views/raif/admin/model_completions/_model_completion.html.erb +9 -0
  74. data/app/views/raif/admin/model_completions/index.html.erb +26 -0
  75. data/app/views/raif/admin/model_completions/show.html.erb +124 -61
  76. data/app/views/raif/admin/model_tool_invocations/index.html.erb +22 -1
  77. data/app/views/raif/admin/model_tools/_list.html.erb +16 -0
  78. data/app/views/raif/admin/model_tools/_model_tool.html.erb +36 -0
  79. data/app/views/raif/admin/stats/_stats_tile.html.erb +34 -0
  80. data/app/views/raif/admin/stats/index.html.erb +71 -88
  81. data/app/views/raif/admin/stats/model_tool_invocations/index.html.erb +43 -0
  82. data/app/views/raif/admin/stats/tasks/index.html.erb +20 -6
  83. data/app/views/raif/admin/tasks/index.html.erb +6 -1
  84. data/app/views/raif/admin/tasks/show.html.erb +36 -3
  85. data/app/views/raif/conversation_entries/_form.html.erb +3 -0
  86. data/app/views/raif/conversations/_conversation.html.erb +10 -0
  87. data/app/views/raif/conversations/_entry_processed.turbo_stream.erb +12 -0
  88. data/app/views/raif/conversations/index.html.erb +23 -0
  89. data/config/locales/admin.en.yml +33 -1
  90. data/config/locales/en.yml +33 -4
  91. data/config/routes.rb +2 -0
  92. data/db/migrate/20250904194456_add_generating_entry_response_to_raif_conversations.rb +7 -0
  93. data/db/migrate/20250911125234_add_source_to_raif_tasks.rb +7 -0
  94. data/db/migrate/20251020005853_add_source_to_raif_agents.rb +7 -0
  95. data/db/migrate/20251020011346_rename_task_run_args_to_run_with.rb +7 -0
  96. data/db/migrate/20251020011405_add_run_with_to_raif_agents.rb +13 -0
  97. data/db/migrate/20251024160119_add_llm_messages_max_length_to_raif_conversations.rb +14 -0
  98. data/db/migrate/20251124185033_add_provider_tool_call_id_to_raif_model_tool_invocations.rb +7 -0
  99. data/db/migrate/20251128202941_add_tool_choice_to_raif_model_completions.rb +7 -0
  100. data/db/migrate/20260118144846_add_source_to_raif_conversations.rb +7 -0
  101. data/db/migrate/20260119000000_add_failure_tracking_to_raif_model_completions.rb +10 -0
  102. data/db/migrate/20260119000001_add_completed_at_to_raif_model_completions.rb +8 -0
  103. data/db/migrate/20260119000002_add_started_at_to_raif_model_completions.rb +8 -0
  104. data/lib/generators/raif/agent/templates/agent.rb.tt +1 -1
  105. data/lib/generators/raif/agent/templates/application_agent.rb.tt +1 -1
  106. data/lib/generators/raif/conversation/templates/conversation.rb.tt +6 -0
  107. data/lib/generators/raif/install/templates/initializer.rb +78 -10
  108. data/lib/generators/raif/task/templates/task.rb.tt +1 -1
  109. data/lib/raif/configuration.rb +37 -2
  110. data/lib/raif/engine.rb +8 -0
  111. data/lib/raif/errors/instance_dependent_schema_error.rb +8 -0
  112. data/lib/raif/errors/streaming_error.rb +6 -3
  113. data/lib/raif/errors.rb +1 -0
  114. data/lib/raif/evals/llm_judge.rb +2 -2
  115. data/lib/raif/evals/llm_judges/binary.rb +3 -3
  116. data/lib/raif/evals/llm_judges/comparative.rb +3 -3
  117. data/lib/raif/evals/llm_judges/scored.rb +1 -1
  118. data/lib/raif/evals/llm_judges/summarization.rb +2 -2
  119. data/lib/raif/evals/run.rb +1 -0
  120. data/lib/raif/json_schema_builder.rb +14 -0
  121. data/lib/raif/llm_registry.rb +207 -37
  122. data/lib/raif/messages.rb +180 -0
  123. data/lib/raif/version.rb +1 -1
  124. data/lib/raif.rb +9 -0
  125. data/lib/tasks/annotate_rb.rake +10 -0
  126. data/spec/support/rspec_helpers.rb +8 -8
  127. metadata +44 -9
  128. data/app/models/raif/agents/re_act_agent.rb +0 -127
  129. data/app/models/raif/agents/re_act_step.rb +0 -32
  130. data/app/models/raif/concerns/task_run_args.rb +0 -62
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: raif
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Roesch
@@ -84,16 +84,16 @@ dependencies:
84
84
  name: pagy
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "<"
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: '10.0'
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "<"
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: '10.0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rails
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -160,13 +160,16 @@ files:
160
160
  - app/assets/stylesheets/raif.scss
161
161
  - app/assets/stylesheets/raif/admin/conversation.scss
162
162
  - app/assets/stylesheets/raif/admin/stats.scss
163
+ - app/assets/stylesheets/raif/conversations.scss
163
164
  - app/assets/stylesheets/raif/loader.scss
164
165
  - app/assets/stylesheets/raif_admin.scss
165
166
  - app/controllers/raif/admin/agents_controller.rb
166
167
  - app/controllers/raif/admin/application_controller.rb
168
+ - app/controllers/raif/admin/configs_controller.rb
167
169
  - app/controllers/raif/admin/conversations_controller.rb
168
170
  - app/controllers/raif/admin/model_completions_controller.rb
169
171
  - app/controllers/raif/admin/model_tool_invocations_controller.rb
172
+ - app/controllers/raif/admin/stats/model_tool_invocations_controller.rb
170
173
  - app/controllers/raif/admin/stats/tasks_controller.rb
171
174
  - app/controllers/raif/admin/stats_controller.rb
172
175
  - app/controllers/raif/admin/tasks_controller.rb
@@ -177,11 +180,11 @@ files:
177
180
  - app/helpers/raif/shared/conversations_helper.rb
178
181
  - app/jobs/raif/application_job.rb
179
182
  - app/jobs/raif/conversation_entry_job.rb
183
+ - app/models/raif/admin/task_stat.rb
180
184
  - app/models/raif/agent.rb
181
185
  - app/models/raif/agents/native_tool_calling_agent.rb
182
- - app/models/raif/agents/re_act_agent.rb
183
- - app/models/raif/agents/re_act_step.rb
184
186
  - app/models/raif/application_record.rb
187
+ - app/models/raif/concerns/agent_inference_stats.rb
185
188
  - app/models/raif/concerns/boolean_timestamp.rb
186
189
  - app/models/raif/concerns/has_available_model_tools.rb
187
190
  - app/models/raif/concerns/has_llm.rb
@@ -191,16 +194,23 @@ files:
191
194
  - app/models/raif/concerns/llm_response_parsing.rb
192
195
  - app/models/raif/concerns/llm_temperature.rb
193
196
  - app/models/raif/concerns/llms/anthropic/message_formatting.rb
197
+ - app/models/raif/concerns/llms/anthropic/response_tool_calls.rb
194
198
  - app/models/raif/concerns/llms/anthropic/tool_formatting.rb
195
199
  - app/models/raif/concerns/llms/bedrock/message_formatting.rb
200
+ - app/models/raif/concerns/llms/bedrock/response_tool_calls.rb
196
201
  - app/models/raif/concerns/llms/bedrock/tool_formatting.rb
202
+ - app/models/raif/concerns/llms/google/message_formatting.rb
203
+ - app/models/raif/concerns/llms/google/response_tool_calls.rb
204
+ - app/models/raif/concerns/llms/google/tool_formatting.rb
197
205
  - app/models/raif/concerns/llms/message_formatting.rb
198
206
  - app/models/raif/concerns/llms/open_ai/json_schema_validation.rb
199
207
  - app/models/raif/concerns/llms/open_ai_completions/message_formatting.rb
208
+ - app/models/raif/concerns/llms/open_ai_completions/response_tool_calls.rb
200
209
  - app/models/raif/concerns/llms/open_ai_completions/tool_formatting.rb
201
210
  - app/models/raif/concerns/llms/open_ai_responses/message_formatting.rb
211
+ - app/models/raif/concerns/llms/open_ai_responses/response_tool_calls.rb
202
212
  - app/models/raif/concerns/llms/open_ai_responses/tool_formatting.rb
203
- - app/models/raif/concerns/task_run_args.rb
213
+ - app/models/raif/concerns/run_with.rb
204
214
  - app/models/raif/conversation.rb
205
215
  - app/models/raif/conversation_entry.rb
206
216
  - app/models/raif/embedding_model.rb
@@ -209,6 +219,7 @@ files:
209
219
  - app/models/raif/llm.rb
210
220
  - app/models/raif/llms/anthropic.rb
211
221
  - app/models/raif/llms/bedrock.rb
222
+ - app/models/raif/llms/google.rb
212
223
  - app/models/raif/llms/open_ai_base.rb
213
224
  - app/models/raif/llms/open_ai_completions.rb
214
225
  - app/models/raif/llms/open_ai_responses.rb
@@ -227,6 +238,7 @@ files:
227
238
  - app/models/raif/model_tools/wikipedia_search.rb
228
239
  - app/models/raif/streaming_responses/anthropic.rb
229
240
  - app/models/raif/streaming_responses/bedrock.rb
241
+ - app/models/raif/streaming_responses/google.rb
230
242
  - app/models/raif/streaming_responses/open_ai_completions.rb
231
243
  - app/models/raif/streaming_responses/open_ai_responses.rb
232
244
  - app/models/raif/task.rb
@@ -236,6 +248,7 @@ files:
236
248
  - app/views/raif/admin/agents/_conversation_message.html.erb
237
249
  - app/views/raif/admin/agents/index.html.erb
238
250
  - app/views/raif/admin/agents/show.html.erb
251
+ - app/views/raif/admin/configs/show.html.erb
239
252
  - app/views/raif/admin/conversations/_conversation.html.erb
240
253
  - app/views/raif/admin/conversations/_conversation_entry.html.erb
241
254
  - app/views/raif/admin/conversations/index.html.erb
@@ -246,7 +259,11 @@ files:
246
259
  - app/views/raif/admin/model_tool_invocations/_model_tool_invocation.html.erb
247
260
  - app/views/raif/admin/model_tool_invocations/index.html.erb
248
261
  - app/views/raif/admin/model_tool_invocations/show.html.erb
262
+ - app/views/raif/admin/model_tools/_list.html.erb
263
+ - app/views/raif/admin/model_tools/_model_tool.html.erb
264
+ - app/views/raif/admin/stats/_stats_tile.html.erb
249
265
  - app/views/raif/admin/stats/index.html.erb
266
+ - app/views/raif/admin/stats/model_tool_invocations/index.html.erb
250
267
  - app/views/raif/admin/stats/tasks/index.html.erb
251
268
  - app/views/raif/admin/tasks/_task.html.erb
252
269
  - app/views/raif/admin/tasks/index.html.erb
@@ -262,8 +279,11 @@ files:
262
279
  - app/views/raif/conversation_entries/create.turbo_stream.erb
263
280
  - app/views/raif/conversation_entries/new.turbo_stream.erb
264
281
  - app/views/raif/conversations/_available_user_tools.html.erb
282
+ - app/views/raif/conversations/_conversation.html.erb
283
+ - app/views/raif/conversations/_entry_processed.turbo_stream.erb
265
284
  - app/views/raif/conversations/_full_conversation.html.erb
266
285
  - app/views/raif/conversations/_initial_chat_message.html.erb
286
+ - app/views/raif/conversations/index.html.erb
267
287
  - app/views/raif/conversations/show.html.erb
268
288
  - config/i18n-tasks.yml
269
289
  - config/importmap.rb
@@ -282,6 +302,18 @@ files:
282
302
  - db/migrate/20250603202013_add_stream_response_to_raif_model_completions.rb
283
303
  - db/migrate/20250804013843_add_task_run_args_to_raif_tasks.rb
284
304
  - db/migrate/20250811171150_make_raif_task_creator_optional.rb
305
+ - db/migrate/20250904194456_add_generating_entry_response_to_raif_conversations.rb
306
+ - db/migrate/20250911125234_add_source_to_raif_tasks.rb
307
+ - db/migrate/20251020005853_add_source_to_raif_agents.rb
308
+ - db/migrate/20251020011346_rename_task_run_args_to_run_with.rb
309
+ - db/migrate/20251020011405_add_run_with_to_raif_agents.rb
310
+ - db/migrate/20251024160119_add_llm_messages_max_length_to_raif_conversations.rb
311
+ - db/migrate/20251124185033_add_provider_tool_call_id_to_raif_model_tool_invocations.rb
312
+ - db/migrate/20251128202941_add_tool_choice_to_raif_model_completions.rb
313
+ - db/migrate/20260118144846_add_source_to_raif_conversations.rb
314
+ - db/migrate/20260119000000_add_failure_tracking_to_raif_model_completions.rb
315
+ - db/migrate/20260119000001_add_completed_at_to_raif_model_completions.rb
316
+ - db/migrate/20260119000002_add_started_at_to_raif_model_completions.rb
285
317
  - exe/raif
286
318
  - lib/generators/raif/agent/agent_generator.rb
287
319
  - lib/generators/raif/agent/templates/agent.rb.tt
@@ -315,6 +347,7 @@ files:
315
347
  - lib/raif/engine.rb
316
348
  - lib/raif/errors.rb
317
349
  - lib/raif/errors/action_not_authorized_error.rb
350
+ - lib/raif/errors/instance_dependent_schema_error.rb
318
351
  - lib/raif/errors/invalid_config_error.rb
319
352
  - lib/raif/errors/invalid_conversation_type_error.rb
320
353
  - lib/raif/errors/invalid_model_file_input_error.rb
@@ -339,6 +372,7 @@ files:
339
372
  - lib/raif/json_schema_builder.rb
340
373
  - lib/raif/languages.rb
341
374
  - lib/raif/llm_registry.rb
375
+ - lib/raif/messages.rb
342
376
  - lib/raif/migration_checker.rb
343
377
  - lib/raif/rspec.rb
344
378
  - lib/raif/utils.rb
@@ -347,6 +381,7 @@ files:
347
381
  - lib/raif/utils/html_to_markdown_converter.rb
348
382
  - lib/raif/utils/readable_content_extractor.rb
349
383
  - lib/raif/version.rb
384
+ - lib/tasks/annotate_rb.rake
350
385
  - lib/tasks/raif_tasks.rake
351
386
  - spec/support/complex_test_tool.rb
352
387
  - spec/support/current_temperature_test_tool.rb
@@ -378,7 +413,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
378
413
  - !ruby/object:Gem::Version
379
414
  version: '0'
380
415
  requirements: []
381
- rubygems_version: 3.6.7
416
+ rubygems_version: 3.6.9
382
417
  specification_version: 4
383
418
  summary: Raif (Ruby AI Framework) is a Rails engine that helps you add AI-powered
384
419
  features to your Rails apps, such as tasks, conversations, and agents.
@@ -1,127 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Raif
4
- module Agents
5
- class ReActAgent < Raif::Agent
6
- validates :available_model_tools, length: {
7
- minimum: 1,
8
- message: ->(_object, _data) {
9
- I18n.t("raif.agents.re_act_agent.errors.available_model_tools.too_short")
10
- }
11
- }
12
-
13
- def build_system_prompt
14
- <<~PROMPT.strip
15
- You are an intelligent assistant that follows the ReAct (Reasoning + Acting) framework to complete tasks step by step using tool calls.
16
-
17
- # Available Tools
18
- You have access to the following tools:
19
- #{available_model_tools_map.values.map(&:description_for_llm).join("\n---\n")}
20
- # Your Responses
21
- Your responses should follow this structure & format:
22
- <thought>Your step-by-step reasoning about what to do</thought>
23
- <action>JSON object with "tool" and "arguments" keys</action>
24
- <observation>Results from the tool, which will be provided to you</observation>
25
- ... (repeat Thought/Action/Observation as needed until the task is complete)
26
- <thought>Final reasoning based on all observations</thought>
27
- <answer>Your final response to the user</answer>
28
-
29
- # How to Use Tools
30
- When you need to use a tool:
31
- 1. Identify which tool is appropriate for the task
32
- 2. Format your tool call using JSON with the required arguments and place it in the <action> tag
33
- 3. Here is an example: <action>{"tool": "tool_name", "arguments": {...}}</action>
34
-
35
- # Guidelines
36
- - Always think step by step
37
- - Use tools when appropriate, but don't use tools for tasks you can handle directly
38
- - Be concise in your reasoning but thorough in your analysis
39
- - If a tool returns an error, try to understand why and adjust your approach
40
- - If you're unsure about something, explain your uncertainty, but do not make things up
41
- - After each thought, make sure to also include an <action> or <answer>
42
- - Always provide a final answer that directly addresses the user's request
43
-
44
- Remember: Your goal is to be helpful, accurate, and efficient in solving the user's request.#{system_prompt_language_preference}
45
- PROMPT
46
- end
47
-
48
- private
49
-
50
- def process_iteration_model_completion(model_completion)
51
- agent_step = Raif::Agents::ReActStep.new(model_response_text: model_completion.raw_response)
52
-
53
- # Add the thought to conversation history
54
- if agent_step.thought
55
- add_conversation_history_entry({ role: "assistant", content: "<thought>#{agent_step.thought}</thought>" })
56
- end
57
-
58
- # If there's an answer, we're done
59
- if agent_step.answer
60
- self.final_answer = agent_step.answer
61
- add_conversation_history_entry({ role: "assistant", content: "<answer>#{agent_step.answer}</answer>" })
62
- return
63
- end
64
-
65
- # If there's an action, execute it
66
- process_action(agent_step.action) if agent_step.action
67
- end
68
-
69
- def process_action(action)
70
- add_conversation_history_entry({ role: "assistant", content: "<action>#{action}</action>" })
71
-
72
- # The action should always be a JSON object with "tool" and "arguments" keys
73
- parsed_action = begin
74
- JSON.parse(action)
75
- rescue JSON::ParserError => e
76
- add_conversation_history_entry({
77
- role: "assistant",
78
- content: "<observation>Error parsing action JSON: #{e.message}</observation>"
79
- })
80
-
81
- nil
82
- end
83
-
84
- return if parsed_action.blank?
85
-
86
- unless parsed_action["tool"] && parsed_action["arguments"]
87
- add_conversation_history_entry({
88
- role: "assistant",
89
- content: "<observation>Error: Invalid action specified. Please provide a valid action, formatted as a JSON object with 'tool' and 'arguments' keys.</observation>" # rubocop:disable Layout/LineLength
90
- })
91
- return
92
- end
93
-
94
- tool_name = parsed_action["tool"]
95
- tool_arguments = parsed_action["arguments"]
96
- tool_klass = available_model_tools_map[tool_name]
97
-
98
- # The model tried to use a tool that doesn't exist
99
- unless tool_klass
100
- add_conversation_history_entry({
101
- role: "assistant",
102
- content: "<observation>Error: Tool '#{tool_name}' not found. Available tools: #{available_model_tools_map.keys.join(", ")}</observation>"
103
- })
104
- return
105
- end
106
-
107
- unless JSON::Validator.validate(tool_klass.tool_arguments_schema, tool_arguments)
108
- add_conversation_history_entry({
109
- role: "assistant",
110
- content: "<observation>Error: Invalid tool arguments. Please provide valid arguments for the tool '#{tool_name}'. Tool arguments schema: #{tool_klass.tool_arguments_schema.to_json}</observation>" # rubocop:disable Layout/LineLength
111
- })
112
- return
113
- end
114
-
115
- tool_invocation = tool_klass.invoke_tool(tool_arguments: tool_arguments, source: self)
116
- observation = tool_klass.observation_for_invocation(tool_invocation)
117
-
118
- # Add the tool invocation to conversation history
119
- add_conversation_history_entry({
120
- role: "assistant",
121
- content: "<observation>#{observation}</observation>"
122
- })
123
- end
124
-
125
- end
126
- end
127
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Raif
4
- module Agents
5
- class ReActStep
6
- attr_reader :model_response_text
7
-
8
- def initialize(model_response_text:)
9
- @model_response_text = model_response_text
10
- end
11
-
12
- def thought
13
- @thought ||= extract_tag_content("thought")
14
- end
15
-
16
- def answer
17
- @answer ||= extract_tag_content("answer")
18
- end
19
-
20
- def action
21
- @action ||= extract_tag_content("action")
22
- end
23
-
24
- private
25
-
26
- def extract_tag_content(tag_name)
27
- match = model_response_text.match(%r{<#{tag_name}>(.*?)</#{tag_name}>}m)
28
- match && match[1] ? match[1].strip : nil
29
- end
30
- end
31
- end
32
- end
@@ -1,62 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Raif::Concerns::TaskRunArgs
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- class_attribute :_task_run_args, instance_writer: false, default: []
8
- end
9
-
10
- class_methods do
11
- # DSL for declaring persistent task arguments that will be serialized to the database
12
- # @param name [Symbol] The name of the argument
13
- def task_run_arg(name)
14
- # Ensure each class has its own array copy
15
- self._task_run_args = _task_run_args.dup
16
- _task_run_args << name.to_sym
17
-
18
- # Define getter that pulls from task_run_args JSON
19
- define_method(name) do
20
- return instance_variable_get("@#{name}") if instance_variable_defined?("@#{name}")
21
-
22
- value = task_run_args&.dig(name.to_s)
23
- return unless value
24
-
25
- # Deserialize GID if it's a string starting with gid://
26
- deserialized = if value.is_a?(String) && value.start_with?("gid://")
27
- begin
28
- GlobalID::Locator.locate(value)
29
- rescue ActiveRecord::RecordNotFound
30
- nil
31
- end
32
- else
33
- value
34
- end
35
-
36
- instance_variable_set("@#{name}", deserialized)
37
- end
38
-
39
- # Define setter that stores in memory (for use during run)
40
- define_method("#{name}=") do |value|
41
- instance_variable_set("@#{name}", value)
42
- end
43
- end
44
-
45
- # Transform run args into a hash that can be stored in the task_run_args database column
46
- def serialize_task_run_args(args)
47
- serialized_args = {}
48
- _task_run_args.each do |arg_name|
49
- next unless args.key?(arg_name)
50
-
51
- value = args[arg_name]
52
- serialized_args[arg_name.to_s] = if value.respond_to?(:to_global_id)
53
- value.to_global_id.to_s
54
- else
55
- value
56
- end
57
- end
58
-
59
- serialized_args
60
- end
61
- end
62
- end