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
@@ -7,6 +7,10 @@
7
7
 
8
8
  <div class="period-filter">
9
9
  <%= form_tag raif.admin_stats_tasks_path, method: :get, id: "period_filter_form", class: "d-flex align-items-center" do %>
10
+ <div class="form-check me-4 text-nowrap">
11
+ <%= check_box_tag :show_model_breakdown, "1", @show_model_breakdown, class: "form-check-input", id: "show_model_breakdown" %>
12
+ <%= label_tag :show_model_breakdown, t("raif.admin.stats.tasks.show_model_breakdown"), class: "form-check-label" %>
13
+ </div>
10
14
  <%= select_tag :period,
11
15
  options_for_select(
12
16
  [
@@ -28,16 +32,26 @@
28
32
  <thead class="table-light">
29
33
  <tr>
30
34
  <th><%= t("raif.admin.common.type") %></th>
31
- <th><%= t("raif.admin.common.count") %></th>
32
- <th><%= t("raif.admin.common.est_cost") %></th>
35
+ <% if @show_model_breakdown %>
36
+ <th><%= t("raif.admin.common.model") %></th>
37
+ <% end %>
38
+ <th class="text-end"><%= t("raif.admin.common.count") %></th>
39
+ <th class="text-end"><%= t("raif.admin.common.input_token_cost") %></th>
40
+ <th class="text-end"><%= t("raif.admin.common.output_token_cost") %></th>
41
+ <th class="text-end"><%= t("raif.admin.common.total_cost") %></th>
33
42
  </tr>
34
43
  </thead>
35
44
  <tbody>
36
- <% @task_counts_by_type.each do |type, count| %>
45
+ <% @task_stats_by_type.each do |task_stat| %>
37
46
  <tr>
38
- <td><%= type %></td>
39
- <td><%= number_with_delimiter(count) %></td>
40
- <td><%= number_to_currency(@task_costs_by_type[type] || 0, precision: 6) %></td>
47
+ <td><%= task_stat.type %></td>
48
+ <% if @show_model_breakdown %>
49
+ <td><%= task_stat.llm_model_key %></td>
50
+ <% end %>
51
+ <td class="text-end"><%= number_with_delimiter(task_stat.count) %></td>
52
+ <td class="text-end"><%= number_to_currency(task_stat.input_cost, precision: 2) %></td>
53
+ <td class="text-end"><%= number_to_currency(task_stat.output_cost, precision: 2) %></td>
54
+ <td class="text-end"><%= number_to_currency(task_stat.total_cost, precision: 2) %></td>
41
55
  </tr>
42
56
  <% end %>
43
57
  </tbody>
@@ -1,4 +1,9 @@
1
- <h1 class="my-4"><%= t("raif.admin.common.tasks") %></h1>
1
+ <div class="d-flex justify-content-between align-items-center my-4">
2
+ <h1 class="mb-0"><%= t("raif.admin.common.tasks") %></h1>
3
+ <%= link_to raif.admin_stats_tasks_path, class: "btn btn-outline-primary" do %>
4
+ <%= t("raif.admin.common.stats") %> &raquo;
5
+ <% end %>
6
+ </div>
2
7
 
3
8
  <div class="row">
4
9
  <div class="col-12">
@@ -93,22 +93,55 @@
93
93
  <div class="col-md-3"><strong><%= t("raif.admin.common.created_at") %>:</strong></div>
94
94
  <div class="col-md-9"><%= @task.raif_model_completion.created_at.rfc822 %></div>
95
95
  </div>
96
+ <div class="row mb-3">
97
+ <div class="col-md-3"><strong><%= t("raif.admin.common.retry_count") %>:</strong></div>
98
+ <div class="col-md-9"><%= @task.raif_model_completion.retry_count %></div>
99
+ </div>
96
100
  <div class="row mb-3">
97
101
  <div class="col-md-3"><strong><%= t("raif.admin.common.prompt_tokens") %>:</strong></div>
98
- <div class="col-md-9"><%= @task.raif_model_completion.prompt_tokens ? number_with_delimiter(@task.raif_model_completion.prompt_tokens) : "-" %></div>
102
+ <div class="col-md-9">
103
+ <% if @task.raif_model_completion.prompt_tokens %>
104
+ <%= number_with_delimiter(@task.raif_model_completion.prompt_tokens) %>
105
+ <% if @task.raif_model_completion.prompt_token_cost %>
106
+ <small>(<%= t("raif.admin.common.est_cost") %>: <%= "$" %><%= number_with_precision(@task.raif_model_completion.prompt_token_cost, precision: 6) %>)</small>
107
+ <% end %>
108
+ <% else %>
109
+ -
110
+ <% end %>
111
+ </div>
99
112
  </div>
100
113
  <div class="row mb-3">
101
114
  <div class="col-md-3"><strong><%= t("raif.admin.common.completion_tokens") %>:</strong></div>
102
- <div class="col-md-9"><%= @task.raif_model_completion.completion_tokens ? number_with_delimiter(@task.raif_model_completion.completion_tokens) : "-" %></div>
115
+ <div class="col-md-9">
116
+ <% if @task.raif_model_completion.completion_tokens %>
117
+ <%= number_with_delimiter(@task.raif_model_completion.completion_tokens) %>
118
+ <% if @task.raif_model_completion.output_token_cost %>
119
+ <small>(<%= t("raif.admin.common.est_cost") %>: <%= "$" %><%= number_with_precision(@task.raif_model_completion.output_token_cost, precision: 6) %>)</small>
120
+ <% end %>
121
+ <% else %>
122
+ -
123
+ <% end %>
124
+ </div>
103
125
  </div>
104
126
  <div class="row mb-3">
105
127
  <div class="col-md-3"><strong><%= t("raif.admin.common.total_tokens") %>:</strong></div>
106
- <div class="col-md-9"><%= @task.raif_model_completion.total_tokens ? number_with_delimiter(@task.raif_model_completion.total_tokens) : "-" %></div>
128
+ <div class="col-md-9">
129
+ <% if @task.raif_model_completion.total_tokens %>
130
+ <%= number_with_delimiter(@task.raif_model_completion.total_tokens) %>
131
+ <% if @task.raif_model_completion.total_cost %>
132
+ <small>(<%= t("raif.admin.common.est_cost") %>: <%= "$" %><%= number_with_precision(@task.raif_model_completion.total_cost, precision: 6) %>)</small>
133
+ <% end %>
134
+ <% else %>
135
+ -
136
+ <% end %>
137
+ </div>
107
138
  </div>
108
139
  </div>
109
140
  </div>
110
141
  <% end %>
111
142
 
143
+ <%= render "raif/admin/model_tools/list", model_tools: @task.available_model_tools_map %>
144
+
112
145
  <div class="card mb-4">
113
146
  <div class="card-header">
114
147
  <h5 class="mb-0"><%= t("raif.admin.common.system_prompt") %></h5>
@@ -1,5 +1,8 @@
1
+ <%# locals: (conversation:, conversation_entry:) %>
2
+
1
3
  <%= form_with model: conversation_entry,
2
4
  url: raif.conversation_entries_path(conversation),
5
+ id: dom_id(conversation, "entry_form"),
3
6
  local: true do |f| %>
4
7
 
5
8
  <% if conversation_entry.raif_user_tool_invocation %>
@@ -0,0 +1,10 @@
1
+ <%# locals: (conversation:) %>
2
+
3
+ <tr>
4
+ <td class="ps-2"><%= conversation.created_at.strftime("%B %d, %Y") %></td>
5
+ <td>
6
+ <%= link_to t("raif.conversations.index.table.view"),
7
+ raif.conversation_path(conversation),
8
+ class: "btn btn-sm btn-primary" %>
9
+ </td>
10
+ </tr>
@@ -0,0 +1,12 @@
1
+ <%# locals: (conversation:, conversation_entry:) %>
2
+
3
+ <%# Update the conversation entry now that it's been processed & has a model response %>
4
+ <%= turbo_stream.replace conversation_entry do %>
5
+ <%= render conversation_entry %>
6
+ <% end %>
7
+
8
+ <%= turbo_stream.replace dom_id(conversation, "entry_form") do %>
9
+ <%= render "raif/conversation_entries/form", conversation: conversation, conversation_entry: Raif::ConversationEntry.new %>
10
+ <% end %>
11
+
12
+ <%= turbo_stream.action :raif_scroll_to_bottom, ActionView::RecordIdentifier.dom_id(conversation, :entries) %>
@@ -0,0 +1,23 @@
1
+ <div class="conversation-history p-4">
2
+ <h2><%= t("raif.conversations.index.title") %></h2>
3
+
4
+ <% if @conversations.any? %>
5
+ <div class="table-responsive">
6
+ <table class="table table-striped">
7
+ <thead>
8
+ <tr>
9
+ <th><%= t("raif.conversations.index.table.started") %></th>
10
+ <th><%= t("raif.conversations.index.table.actions") %></th>
11
+ </tr>
12
+ </thead>
13
+ <tbody>
14
+ <%= render collection: @conversations, partial: "raif/conversations/conversation" %>
15
+ </tbody>
16
+ </table>
17
+ </div>
18
+ <% else %>
19
+ <div class="text-center py-4">
20
+ <p class="text-muted"><%= t("raif.conversations.index.no_conversations") %></p>
21
+ </div>
22
+ <% end %>
23
+ </div>
@@ -10,28 +10,37 @@ en:
10
10
  agents: Agents
11
11
  all: All
12
12
  arguments: Arguments
13
+ arguments_schema: Arguments Schema
13
14
  at: at
15
+ available_tools: Available Tools
14
16
  citations: Citations
15
17
  completed: Completed
16
18
  completed_at: Completed At
17
19
  completion_tokens: Completion Tokens
20
+ config: Config
18
21
  conversation_entries: Conversation Entries
19
22
  conversation_history: Conversation History
20
23
  conversations: Conversations
21
24
  count: Count
22
25
  created_at: Created At
23
26
  creator: Creator
27
+ description: Description
24
28
  details: Details
25
29
  entries_count: Entries Count
26
30
  entry: Entry
27
31
  est_cost: est. cost
32
+ est_costs: est. costs
28
33
  failed: Failed
29
34
  failed_at: Failed At
35
+ failure_error: Failure Error
36
+ failure_reason: Failure Reason
30
37
  filter: Filter
31
38
  final_answer: Final Answer
32
39
  id: ID
33
40
  in_progress: In Progress
34
41
  initial_task: Initial Task
42
+ input: Input
43
+ input_token_cost: Input Token Cost
35
44
  invalid_json: Invalid JSON
36
45
  iterations: Iterations
37
46
  language: Language
@@ -48,6 +57,9 @@ en:
48
57
  no_model_tool_invocations: No model tool invocations found.
49
58
  no_tasks: No tasks found.
50
59
  no_tool_calls: No tool calls
60
+ none: None
61
+ output: Output
62
+ output_token_cost: Output Token Cost
51
63
  pending: Pending
52
64
  period_all: All time
53
65
  period_day: Past 24 hours
@@ -61,8 +73,8 @@ en:
61
73
  requested_language: Requested Language
62
74
  response: Response
63
75
  response_format: Response Format
64
- response_format_parameter: Response Format Parameter
65
76
  result: Result
77
+ retry_count: Retry Count
66
78
  running: Running
67
79
  since: Since
68
80
  source: Source
@@ -73,15 +85,31 @@ en:
73
85
  task: Task
74
86
  tasks: Tasks
75
87
  tool_arguments: Tool Arguments
88
+ tool_call: Tool Call
76
89
  tool_calls: Tool Calls
77
90
  tool_invocations: Tool Invocations
78
91
  tool_name: Tool Name
92
+ tool_result: Tool Result
79
93
  tool_type: Tool Type
94
+ total: Total
80
95
  total_cost: Total Cost
81
96
  total_tokens: Total Tokens
82
97
  type: Type
83
98
  update: Update
84
99
  user_message: User Message
100
+ config:
101
+ show:
102
+ configuration_settings: Configuration Settings
103
+ default: default
104
+ key: Key
105
+ no_embedding_models_registered: No embedding models registered
106
+ no_llms_registered: No LLMs registered
107
+ not_set: Not set
108
+ registered_embedding_models: Registered Embedding Models
109
+ registered_llms: Registered LLMs
110
+ setting: Setting
111
+ title: Raif Configuration
112
+ value: Value
85
113
  conversations:
86
114
  show:
87
115
  back_to_conversations: Back to Conversations
@@ -98,8 +126,12 @@ en:
98
126
  back_to_model_tool_invocations: Back to Model Tool Invocations
99
127
  title: 'Model Tool Invocation #%{id}'
100
128
  stats:
129
+ model_tool_invocations:
130
+ back_to_stats: Back to Stats
131
+ title: Model Tool Invocation Stats
101
132
  tasks:
102
133
  back_to_stats: Back to Stats
134
+ show_model_breakdown: Show model breakdown
103
135
  title: Task Stats
104
136
  tasks:
105
137
  show:
@@ -6,10 +6,7 @@ en:
6
6
  errors:
7
7
  available_model_tools:
8
8
  too_short: must have at least 1 tool in addition to the agent_final_answer tool
9
- re_act_agent:
10
- errors:
11
- available_model_tools:
12
- too_short: must have at least 1 tool
9
+ final_answer_warning: 'Warning: This is your final iteration. You must provide your final answer using the agent_final_answer tool.'
13
10
  common:
14
11
  send: Send
15
12
  sources: Sources
@@ -18,6 +15,14 @@ en:
18
15
  type_your_message: Type your message...
19
16
  conversation:
20
17
  initial_chat_message: Hello, how can I help you today?
18
+ conversations:
19
+ index:
20
+ no_conversations: No conversations found.
21
+ table:
22
+ actions: Actions
23
+ started: Started
24
+ view: View
25
+ title: Past Conversations
21
26
  embedding_model_names:
22
27
  bedrock_titan_embed_text_v2: AWS Bedrock Titan Text Embeddings v2
23
28
  open_ai_text_embedding_3_large: OpenAI Text Embedding 3 Large
@@ -51,6 +56,9 @@ en:
51
56
  anthropic_claude_3_5_sonnet: Anthropic Claude 3.5 Sonnet
52
57
  anthropic_claude_3_7_sonnet: Anthropic Claude 3.7 Sonnet
53
58
  anthropic_claude_3_opus: Anthropic Claude 3 Opus
59
+ anthropic_claude_4_1_opus: Anthropic Claude 4.1 Opus
60
+ anthropic_claude_4_5_haiku: Anthropic Claude 4.5 Haiku
61
+ anthropic_claude_4_5_sonnet: Anthropic Claude 4.5 Sonnet
54
62
  anthropic_claude_4_opus: Anthropic Claude 4 Opus
55
63
  anthropic_claude_4_sonnet: Anthropic Claude 4 Sonnet
56
64
  bedrock_amazon_nova_lite: Amazon Nova Lite (via AWS Bedrock)
@@ -60,8 +68,15 @@ en:
60
68
  bedrock_claude_3_5_sonnet: Anthropic Claude 3.5 Sonnet (via AWS Bedrock)
61
69
  bedrock_claude_3_7_sonnet: Anthropic Claude 3.7 Sonnet (via AWS Bedrock)
62
70
  bedrock_claude_3_opus: Anthropic Claude 3 Opus (via AWS Bedrock)
71
+ bedrock_claude_4_1_opus: Claude 4.1 Opus (via AWS Bedrock)
72
+ bedrock_claude_4_5_haiku: Anthropic Claude 4.5 Haiku (via AWS Bedrock)
73
+ bedrock_claude_4_5_sonnet: Anthropic Claude 4.5 Sonnet (via AWS Bedrock)
63
74
  bedrock_claude_4_opus: Anthropic Claude 4 Opus (via AWS Bedrock)
64
75
  bedrock_claude_4_sonnet: Anthropic Claude 4 Sonnet (via AWS Bedrock)
76
+ google_gemini_2_5_flash: Google Gemini 2.5 Flash
77
+ google_gemini_2_5_pro: Google Gemini 2.5 Pro
78
+ google_gemini_3_0_flash: Google Gemini 3.0 Flash
79
+ google_gemini_3_0_pro: Google Gemini 3.0 Pro
65
80
  open_ai_gpt_3_5_turbo: OpenAI GPT-3.5 Turbo
66
81
  open_ai_gpt_4_1: OpenAI GPT-4.1
67
82
  open_ai_gpt_4_1_mini: OpenAI GPT-4.1 Mini
@@ -69,6 +84,8 @@ en:
69
84
  open_ai_gpt_4o: OpenAI GPT-4o
70
85
  open_ai_gpt_4o_mini: OpenAI GPT-4o Mini
71
86
  open_ai_gpt_5: OpenAI GPT-5
87
+ open_ai_gpt_5_1: OpenAI GPT-5.1
88
+ open_ai_gpt_5_2: OpenAI GPT-5.2
72
89
  open_ai_gpt_5_mini: OpenAI GPT-5 Mini
73
90
  open_ai_gpt_5_nano: OpenAI GPT-5 Nano
74
91
  open_ai_o1: OpenAI o1
@@ -83,6 +100,8 @@ en:
83
100
  open_ai_responses_gpt_4o: OpenAI GPT-4o (Responses API)
84
101
  open_ai_responses_gpt_4o_mini: OpenAI GPT-4o Mini (Responses API)
85
102
  open_ai_responses_gpt_5: OpenAI GPT-5 (Responses API)
103
+ open_ai_responses_gpt_5_1: OpenAI GPT-5.1 (Responses API)
104
+ open_ai_responses_gpt_5_2: OpenAI GPT-5.2 (Responses API)
86
105
  open_ai_responses_gpt_5_mini: OpenAI GPT-5 Mini (Responses API)
87
106
  open_ai_responses_gpt_5_nano: OpenAI GPT-5 Nano (Responses API)
88
107
  open_ai_responses_o1: OpenAI o1 (Responses API)
@@ -94,11 +113,21 @@ en:
94
113
  open_ai_responses_o4_mini: OpenAI o4 Mini (Responses API)
95
114
  open_router_claude_3_7_sonnet: Anthropic Claude 3.7 Sonnet (via OpenRouter)
96
115
  open_router_deepseek_chat_v3: DeepSeek Chat v3 (via OpenRouter)
116
+ open_router_deepseek_v3_1: DeepSeek v3.1 (via OpenRouter)
97
117
  open_router_gemini_2_0_flash: Google Gemini 2.0 Flash (via OpenRouter)
118
+ open_router_gemini_2_5_flash: Gemini 2.5 Flash (via OpenRouter)
119
+ open_router_gemini_2_5_pro: Gemini 2.5 Pro (via OpenRouter)
120
+ open_router_gemini_3_pro_preview: Gemini 3 Pro Preview (via OpenRouter)
121
+ open_router_grok_4: Grok 4 (via OpenRouter)
122
+ open_router_grok_4_1_fast: Grok 4.1 Fast (via OpenRouter)
123
+ open_router_kimi_k2_thinking: Kimi K2 Thinking (via OpenRouter)
98
124
  open_router_llama_3_1_8b_instruct: Meta Llama 3.1 8B Instruct (via OpenRouter)
99
125
  open_router_llama_3_3_70b_instruct: Meta Llama 3.3 70B Instruct (via OpenRouter)
100
126
  open_router_llama_4_maverick: Meta Llama 4 Maverick (via OpenRouter)
101
127
  open_router_llama_4_scout: Meta Llama 4 Scout (via OpenRouter)
128
+ open_router_minimax_m2: Minimax M2 (via OpenRouter)
129
+ open_router_mistral_large_3_2512: Mistral Large 3 (via OpenRouter)
130
+ open_router_mistral_small_3_2_24b: Mistral Small 3.2 24B (via OpenRouter)
102
131
  open_router_open_ai_gpt_oss_120b: OpenAI GPT-OSS 120B (via OpenRouter)
103
132
  open_router_open_ai_gpt_oss_20b: OpenAI GPT-OSS 20B (via OpenRouter)
104
133
  raif_test_llm: Raif Test LLM
data/config/routes.rb CHANGED
@@ -17,6 +17,7 @@ Raif::Engine.routes.draw do
17
17
 
18
18
  namespace :stats do
19
19
  resources :tasks, only: [:index]
20
+ resources :model_tool_invocations, only: [:index]
20
21
  end
21
22
 
22
23
  resources :tasks, only: [:index, :show]
@@ -24,5 +25,6 @@ Raif::Engine.routes.draw do
24
25
  resources :model_completions, only: [:index, :show]
25
26
  resources :agents, only: [:index, :show]
26
27
  resources :model_tool_invocations, only: [:index, :show]
28
+ resource :config, only: [:show]
27
29
  end
28
30
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddGeneratingEntryResponseToRaifConversations < ActiveRecord::Migration[7.1]
4
+ def change
5
+ add_column :raif_conversations, :generating_entry_response, :boolean, default: false, null: false
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddSourceToRaifTasks < ActiveRecord::Migration[7.1]
4
+ def change
5
+ add_reference :raif_tasks, :source, polymorphic: true, index: true
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddSourceToRaifAgents < ActiveRecord::Migration[7.1]
4
+ def change
5
+ add_reference :raif_agents, :source, polymorphic: true, index: true
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RenameTaskRunArgsToRunWith < ActiveRecord::Migration[7.1]
4
+ def change
5
+ rename_column :raif_tasks, :task_run_args, :run_with
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddRunWithToRaifAgents < ActiveRecord::Migration[7.1]
4
+ def change
5
+ json_column_type = if connection.adapter_name.downcase.include?("postgresql")
6
+ :jsonb
7
+ else
8
+ :json
9
+ end
10
+
11
+ add_column :raif_agents, :run_with, json_column_type
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddLlmMessagesMaxLengthToRaifConversations < ActiveRecord::Migration[7.1]
4
+ def change
5
+ add_column :raif_conversations, :llm_messages_max_length, :integer
6
+
7
+ reversible do |dir|
8
+ dir.up do
9
+ # Set default value for existing conversations
10
+ execute "UPDATE raif_conversations SET llm_messages_max_length = 50 WHERE llm_messages_max_length IS NULL"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddProviderToolCallIdToRaifModelToolInvocations < ActiveRecord::Migration[7.2]
4
+ def change
5
+ add_column :raif_model_tool_invocations, :provider_tool_call_id, :string
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddToolChoiceToRaifModelCompletions < ActiveRecord::Migration[7.2]
4
+ def change
5
+ add_column :raif_model_completions, :tool_choice, :string
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddSourceToRaifConversations < ActiveRecord::Migration[7.1]
4
+ def change
5
+ add_reference :raif_conversations, :source, polymorphic: true, index: true
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddFailureTrackingToRaifModelCompletions < ActiveRecord::Migration[7.1]
4
+ def change
5
+ add_column :raif_model_completions, :failed_at, :datetime
6
+ add_column :raif_model_completions, :failure_error, :string
7
+ add_column :raif_model_completions, :failure_reason, :text
8
+ add_index :raif_model_completions, :failed_at
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddCompletedAtToRaifModelCompletions < ActiveRecord::Migration[7.1]
4
+ def change
5
+ add_column :raif_model_completions, :completed_at, :datetime
6
+ add_index :raif_model_completions, :completed_at
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddStartedAtToRaifModelCompletions < ActiveRecord::Migration[7.1]
4
+ def change
5
+ add_column :raif_model_completions, :started_at, :datetime
6
+ add_index :raif_model_completions, :started_at
7
+ end
8
+ end
@@ -10,7 +10,7 @@
10
10
  # end
11
11
 
12
12
  # Enter your agent's system prompt here. Alternatively, you can change your agent's superclass
13
- # to an existing agent types (like Raif::Agents::ReActAgent) to utilize an existing system prompt.
13
+ # to an existing agent types (like Raif::Agents::NativeToolCallingAgent) to utilize an existing system prompt.
14
14
  def build_system_prompt
15
15
  # TODO: Implement your system prompt here
16
16
  end
@@ -1,5 +1,5 @@
1
1
  module Raif
2
- class ApplicationAgent < Raif::Agent
2
+ class ApplicationAgent < Raif::Agents::NativeToolCallingAgent
3
3
  # Add any shared agent behavior here
4
4
  end
5
5
  end
@@ -8,6 +8,12 @@
8
8
  # uncomment this callback to populate the available_model_tools attribute with your desired model tools.
9
9
  # before_create -> { self.available_model_tools = ["Raif::ModelTools::Example"] }
10
10
 
11
+ # Use this callback to run custom logic before prompting the model for an entry response.
12
+ # The block receives the entry as an argument, and `self` is the conversation instance.
13
+ # before_prompt_model_for_entry_response do |entry|
14
+ # # Custom logic here
15
+ # end
16
+
11
17
  # Override the methods below to customize the system prompt for this conversation type.
12
18
  # def system_prompt_intro
13
19
  # Raif.config.conversation_system_prompt_intro