raif 1.0.0 → 1.2.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 (116) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +346 -43
  3. data/app/assets/builds/raif.css +26 -1
  4. data/app/assets/stylesheets/raif/admin/stats.scss +12 -0
  5. data/app/assets/stylesheets/raif/loader.scss +27 -1
  6. data/app/controllers/raif/admin/application_controller.rb +14 -0
  7. data/app/controllers/raif/admin/stats/tasks_controller.rb +25 -0
  8. data/app/controllers/raif/admin/stats_controller.rb +19 -0
  9. data/app/controllers/raif/admin/tasks_controller.rb +18 -2
  10. data/app/controllers/raif/conversations_controller.rb +5 -1
  11. data/app/models/raif/agent.rb +11 -9
  12. data/app/models/raif/agents/native_tool_calling_agent.rb +11 -1
  13. data/app/models/raif/agents/re_act_agent.rb +6 -0
  14. data/app/models/raif/concerns/has_available_model_tools.rb +1 -1
  15. data/app/models/raif/concerns/json_schema_definition.rb +28 -0
  16. data/app/models/raif/concerns/llm_response_parsing.rb +42 -14
  17. data/app/models/raif/concerns/llm_temperature.rb +17 -0
  18. data/app/models/raif/concerns/llms/anthropic/message_formatting.rb +51 -0
  19. data/app/models/raif/concerns/llms/anthropic/tool_formatting.rb +56 -0
  20. data/app/models/raif/concerns/llms/bedrock/message_formatting.rb +70 -0
  21. data/app/models/raif/concerns/llms/bedrock/tool_formatting.rb +37 -0
  22. data/app/models/raif/concerns/llms/message_formatting.rb +42 -0
  23. data/app/models/raif/concerns/llms/open_ai/json_schema_validation.rb +138 -0
  24. data/app/models/raif/concerns/llms/open_ai_completions/message_formatting.rb +41 -0
  25. data/app/models/raif/concerns/llms/open_ai_completions/tool_formatting.rb +26 -0
  26. data/app/models/raif/concerns/llms/open_ai_responses/message_formatting.rb +43 -0
  27. data/app/models/raif/concerns/llms/open_ai_responses/tool_formatting.rb +42 -0
  28. data/app/models/raif/conversation.rb +28 -7
  29. data/app/models/raif/conversation_entry.rb +40 -8
  30. data/app/models/raif/embedding_model.rb +22 -0
  31. data/app/models/raif/embedding_models/bedrock.rb +34 -0
  32. data/app/models/raif/embedding_models/open_ai.rb +40 -0
  33. data/app/models/raif/llm.rb +108 -9
  34. data/app/models/raif/llms/anthropic.rb +72 -57
  35. data/app/models/raif/llms/bedrock.rb +165 -0
  36. data/app/models/raif/llms/open_ai_base.rb +66 -0
  37. data/app/models/raif/llms/open_ai_completions.rb +100 -0
  38. data/app/models/raif/llms/open_ai_responses.rb +144 -0
  39. data/app/models/raif/llms/open_router.rb +88 -0
  40. data/app/models/raif/model_completion.rb +23 -2
  41. data/app/models/raif/model_file_input.rb +113 -0
  42. data/app/models/raif/model_image_input.rb +4 -0
  43. data/app/models/raif/model_tool.rb +82 -52
  44. data/app/models/raif/model_tool_invocation.rb +8 -6
  45. data/app/models/raif/model_tools/agent_final_answer.rb +18 -27
  46. data/app/models/raif/model_tools/fetch_url.rb +27 -36
  47. data/app/models/raif/model_tools/provider_managed/base.rb +9 -0
  48. data/app/models/raif/model_tools/provider_managed/code_execution.rb +5 -0
  49. data/app/models/raif/model_tools/provider_managed/image_generation.rb +5 -0
  50. data/app/models/raif/model_tools/provider_managed/web_search.rb +5 -0
  51. data/app/models/raif/model_tools/wikipedia_search.rb +46 -55
  52. data/app/models/raif/streaming_responses/anthropic.rb +63 -0
  53. data/app/models/raif/streaming_responses/bedrock.rb +89 -0
  54. data/app/models/raif/streaming_responses/open_ai_completions.rb +76 -0
  55. data/app/models/raif/streaming_responses/open_ai_responses.rb +54 -0
  56. data/app/models/raif/task.rb +71 -16
  57. data/app/views/layouts/raif/admin.html.erb +10 -0
  58. data/app/views/raif/admin/agents/show.html.erb +3 -1
  59. data/app/views/raif/admin/conversations/_conversation.html.erb +1 -1
  60. data/app/views/raif/admin/conversations/_conversation_entry.html.erb +48 -0
  61. data/app/views/raif/admin/conversations/show.html.erb +4 -2
  62. data/app/views/raif/admin/model_completions/_model_completion.html.erb +8 -0
  63. data/app/views/raif/admin/model_completions/index.html.erb +2 -0
  64. data/app/views/raif/admin/model_completions/show.html.erb +58 -3
  65. data/app/views/raif/admin/stats/index.html.erb +128 -0
  66. data/app/views/raif/admin/stats/tasks/index.html.erb +45 -0
  67. data/app/views/raif/admin/tasks/_task.html.erb +5 -4
  68. data/app/views/raif/admin/tasks/index.html.erb +20 -2
  69. data/app/views/raif/admin/tasks/show.html.erb +3 -1
  70. data/app/views/raif/conversation_entries/_citations.html.erb +9 -0
  71. data/app/views/raif/conversation_entries/_conversation_entry.html.erb +22 -14
  72. data/app/views/raif/conversation_entries/_form.html.erb +1 -1
  73. data/app/views/raif/conversation_entries/_form_with_available_tools.html.erb +4 -4
  74. data/app/views/raif/conversation_entries/_message.html.erb +14 -3
  75. data/config/locales/admin.en.yml +16 -0
  76. data/config/locales/en.yml +47 -3
  77. data/config/routes.rb +6 -0
  78. data/db/migrate/20250224234252_create_raif_tables.rb +1 -1
  79. data/db/migrate/20250421202149_add_response_format_to_raif_conversations.rb +7 -0
  80. data/db/migrate/20250424200755_add_cost_columns_to_raif_model_completions.rb +14 -0
  81. data/db/migrate/20250424232946_add_created_at_indexes.rb +11 -0
  82. data/db/migrate/20250502155330_add_status_indexes_to_raif_tasks.rb +14 -0
  83. data/db/migrate/20250507155314_add_retry_count_to_raif_model_completions.rb +7 -0
  84. data/db/migrate/20250527213016_add_response_id_and_response_array_to_model_completions.rb +14 -0
  85. data/db/migrate/20250603140622_add_citations_to_raif_model_completions.rb +13 -0
  86. data/db/migrate/20250603202013_add_stream_response_to_raif_model_completions.rb +7 -0
  87. data/lib/generators/raif/agent/agent_generator.rb +22 -12
  88. data/lib/generators/raif/agent/templates/agent.rb.tt +3 -3
  89. data/lib/generators/raif/agent/templates/application_agent.rb.tt +7 -0
  90. data/lib/generators/raif/conversation/conversation_generator.rb +10 -0
  91. data/lib/generators/raif/conversation/templates/application_conversation.rb.tt +7 -0
  92. data/lib/generators/raif/conversation/templates/conversation.rb.tt +16 -14
  93. data/lib/generators/raif/install/templates/initializer.rb +62 -6
  94. data/lib/generators/raif/model_tool/model_tool_generator.rb +0 -5
  95. data/lib/generators/raif/model_tool/templates/model_tool.rb.tt +69 -56
  96. data/lib/generators/raif/task/templates/task.rb.tt +34 -23
  97. data/lib/raif/configuration.rb +63 -4
  98. data/lib/raif/embedding_model_registry.rb +83 -0
  99. data/lib/raif/engine.rb +56 -7
  100. data/lib/raif/errors/{open_ai/api_error.rb → invalid_model_file_input_error.rb} +1 -3
  101. data/lib/raif/errors/{anthropic/api_error.rb → invalid_model_image_input_error.rb} +1 -3
  102. data/lib/raif/errors/streaming_error.rb +18 -0
  103. data/lib/raif/errors/unsupported_feature_error.rb +8 -0
  104. data/lib/raif/errors.rb +4 -2
  105. data/lib/raif/json_schema_builder.rb +104 -0
  106. data/lib/raif/llm_registry.rb +315 -0
  107. data/lib/raif/migration_checker.rb +74 -0
  108. data/lib/raif/utils/html_fragment_processor.rb +169 -0
  109. data/lib/raif/utils.rb +1 -0
  110. data/lib/raif/version.rb +1 -1
  111. data/lib/raif.rb +7 -32
  112. data/lib/tasks/raif_tasks.rake +9 -4
  113. metadata +62 -12
  114. data/app/models/raif/llms/bedrock_claude.rb +0 -134
  115. data/app/models/raif/llms/open_ai.rb +0 -259
  116. data/lib/raif/default_llms.rb +0 -37
@@ -8,19 +8,23 @@ en:
8
8
  title: 'Agent #%{id}'
9
9
  common:
10
10
  agents: Agents
11
+ all: All
11
12
  arguments: Arguments
12
13
  at: at
14
+ citations: Citations
13
15
  completed: Completed
14
16
  completed_at: Completed At
15
17
  completion_tokens: Completion Tokens
16
18
  conversation_entries: Conversation Entries
17
19
  conversation_history: Conversation History
18
20
  conversations: Conversations
21
+ count: Count
19
22
  created_at: Created At
20
23
  creator: Creator
21
24
  details: Details
22
25
  entries_count: Entries Count
23
26
  entry: Entry
27
+ est_cost: est. cost
24
28
  failed: Failed
25
29
  failed_at: Failed At
26
30
  filter: Filter
@@ -38,12 +42,17 @@ en:
38
42
  model_response: Model Response
39
43
  model_tool_invocations: Model Tool Invocations
40
44
  no_agents: No agents found.
45
+ no_citations: No citations found in this response.
41
46
  no_conversations: No conversations found.
42
47
  no_model_completions: No model completions found.
43
48
  no_model_tool_invocations: No model tool invocations found.
44
49
  no_tasks: No tasks found.
45
50
  no_tool_calls: No tool calls
46
51
  pending: Pending
52
+ period_all: All time
53
+ period_day: Past 24 hours
54
+ period_month: Past month
55
+ period_week: Past week
47
56
  prettified: Prettified
48
57
  prompt: Prompt
49
58
  prompt_tokens: Prompt Tokens
@@ -58,6 +67,7 @@ en:
58
67
  since: Since
59
68
  source: Source
60
69
  started_at: Started At
70
+ stats: Stats
61
71
  status: Status
62
72
  system_prompt: System Prompt
63
73
  task: Task
@@ -67,8 +77,10 @@ en:
67
77
  tool_invocations: Tool Invocations
68
78
  tool_name: Tool Name
69
79
  tool_type: Tool Type
80
+ total_cost: Total Cost
70
81
  total_tokens: Total Tokens
71
82
  type: Type
83
+ update: Update
72
84
  user_message: User Message
73
85
  conversations:
74
86
  show:
@@ -85,6 +97,10 @@ en:
85
97
  show:
86
98
  back_to_model_tool_invocations: Back to Model Tool Invocations
87
99
  title: 'Model Tool Invocation #%{id}'
100
+ stats:
101
+ tasks:
102
+ back_to_stats: Back to Stats
103
+ title: Task Stats
88
104
  tasks:
89
105
  show:
90
106
  back_to_tasks: Back to Tasks
@@ -2,16 +2,27 @@
2
2
  en:
3
3
  raif:
4
4
  agents:
5
- errors:
6
- available_model_tools:
7
- too_short: must have at least 1 tool
5
+ native_tool_calling_agent:
6
+ errors:
7
+ available_model_tools:
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
8
13
  common:
9
14
  send: Send
15
+ sources: Sources
10
16
  there_was_an_error_generating_this_response: There was an error generating this response
11
17
  tools: Tools
12
18
  type_your_message: Type your message...
13
19
  conversation:
14
20
  initial_chat_message: Hello, how can I help you today?
21
+ embedding_model_names:
22
+ bedrock_titan_embed_text_v2: AWS Bedrock Titan Text Embeddings v2
23
+ open_ai_text_embedding_3_large: OpenAI Text Embedding 3 Large
24
+ open_ai_text_embedding_3_small: OpenAI Text Embedding 3 Small
25
+ open_ai_text_embedding_ada_002: OpenAI Text Embedding Ada 002
15
26
  languages:
16
27
  ar: Arabic
17
28
  da: Danish
@@ -40,11 +51,44 @@ en:
40
51
  anthropic_claude_3_5_sonnet: Anthropic Claude 3.5 Sonnet
41
52
  anthropic_claude_3_7_sonnet: Anthropic Claude 3.7 Sonnet
42
53
  anthropic_claude_3_opus: Anthropic Claude 3 Opus
54
+ anthropic_claude_4_opus: Anthropic Claude 4 Opus
55
+ anthropic_claude_4_sonnet: Anthropic Claude 4 Sonnet
56
+ bedrock_amazon_nova_lite: Amazon Nova Lite (via AWS Bedrock)
57
+ bedrock_amazon_nova_micro: Amazon Nova Micro (via AWS Bedrock)
58
+ bedrock_amazon_nova_pro: Amazon Nova Pro (via AWS Bedrock)
43
59
  bedrock_claude_3_5_haiku: Anthropic Claude 3.5 Haiku (via AWS Bedrock)
44
60
  bedrock_claude_3_5_sonnet: Anthropic Claude 3.5 Sonnet (via AWS Bedrock)
45
61
  bedrock_claude_3_7_sonnet: Anthropic Claude 3.7 Sonnet (via AWS Bedrock)
46
62
  bedrock_claude_3_opus: Anthropic Claude 3 Opus (via AWS Bedrock)
63
+ bedrock_claude_4_opus: Anthropic Claude 4 Opus (via AWS Bedrock)
64
+ bedrock_claude_4_sonnet: Anthropic Claude 4 Sonnet (via AWS Bedrock)
47
65
  open_ai_gpt_3_5_turbo: OpenAI GPT-3.5 Turbo
66
+ open_ai_gpt_4_1: OpenAI GPT-4.1
67
+ open_ai_gpt_4_1_mini: OpenAI GPT-4.1 Mini
68
+ open_ai_gpt_4_1_nano: OpenAI GPT-4.1 Nano
48
69
  open_ai_gpt_4o: OpenAI GPT-4o
49
70
  open_ai_gpt_4o_mini: OpenAI GPT-4o Mini
71
+ open_ai_o1: OpenAI o1
72
+ open_ai_o1_mini: OpenAI o1 Mini
73
+ open_ai_o3: OpenAI o3
74
+ open_ai_o3_mini: OpenAI o3 Mini
75
+ open_ai_o4_mini: OpenAI o4 Mini
76
+ open_ai_responses_gpt_3_5_turbo: OpenAI GPT-3.5 Turbo (Responses API)
77
+ open_ai_responses_gpt_4_1: OpenAI GPT-4.1 (Responses API)
78
+ open_ai_responses_gpt_4_1_mini: OpenAI GPT-4.1 Mini (Responses API)
79
+ open_ai_responses_gpt_4_1_nano: OpenAI GPT-4.1 Nano (Responses API)
80
+ open_ai_responses_gpt_4o: OpenAI GPT-4o (Responses API)
81
+ open_ai_responses_gpt_4o_mini: OpenAI GPT-4o Mini (Responses API)
82
+ open_ai_responses_o1: OpenAI o1 (Responses API)
83
+ open_ai_responses_o1_mini: OpenAI o1 Mini (Responses API)
84
+ open_ai_responses_o1_pro: OpenAI o1 Pro (Responses API)
85
+ open_ai_responses_o3: OpenAI o3 (Responses API)
86
+ open_ai_responses_o3_mini: OpenAI o3 Mini (Responses API)
87
+ open_ai_responses_o3_pro: OpenAI o3 Pro (Responses API)
88
+ open_ai_responses_o4_mini: OpenAI o4 Mini (Responses API)
89
+ open_router_claude_3_7_sonnet: Anthropic Claude 3.7 Sonnet (via OpenRouter)
90
+ open_router_deepseek_chat_v3: DeepSeek Chat v3 (via OpenRouter)
91
+ open_router_gemini_2_0_flash: Google Gemini 2.0 Flash (via OpenRouter)
92
+ open_router_llama_3_1_8b_instruct: Meta Llama 3.1 8B Instruct (via OpenRouter)
93
+ open_router_llama_3_3_70b_instruct: Meta Llama 3.3 70B Instruct (via OpenRouter)
50
94
  raif_test_llm: Raif Test LLM
data/config/routes.rb CHANGED
@@ -13,6 +13,12 @@ Raif::Engine.routes.draw do
13
13
 
14
14
  namespace :admin do
15
15
  root to: redirect("admin/model_completions")
16
+ resources :stats, only: [:index]
17
+
18
+ namespace :stats do
19
+ resources :tasks, only: [:index]
20
+ end
21
+
16
22
  resources :tasks, only: [:index, :show]
17
23
  resources :conversations, only: [:index, :show]
18
24
  resources :model_completions, only: [:index, :show]
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class CreateRaifTables < ActiveRecord::Migration[8.0]
3
+ class CreateRaifTables < ActiveRecord::Migration[7.1]
4
4
  def change
5
5
  json_column_type = if connection.adapter_name.downcase.include?("postgresql")
6
6
  :jsonb
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddResponseFormatToRaifConversations < ActiveRecord::Migration[7.1]
4
+ def change
5
+ add_column :raif_conversations, :response_format, :integer, default: 0, null: false
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddCostColumnsToRaifModelCompletions < ActiveRecord::Migration[7.1]
4
+ # If you need to backfill cost columns for existing records:
5
+ # Raif::ModelCompletion.find_each do |model_completion|
6
+ # model_completion.calculate_costs
7
+ # model_completion.save(validate: false)
8
+ # end
9
+ def change
10
+ add_column :raif_model_completions, :prompt_token_cost, :decimal, precision: 10, scale: 6
11
+ add_column :raif_model_completions, :output_token_cost, :decimal, precision: 10, scale: 6
12
+ add_column :raif_model_completions, :total_cost, :decimal, precision: 10, scale: 6
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddCreatedAtIndexes < ActiveRecord::Migration[7.1]
4
+ def change
5
+ add_index :raif_model_completions, :created_at
6
+ add_index :raif_tasks, :created_at
7
+ add_index :raif_conversations, :created_at
8
+ add_index :raif_conversation_entries, :created_at
9
+ add_index :raif_agents, :created_at
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddStatusIndexesToRaifTasks < ActiveRecord::Migration[7.1]
4
+ def change
5
+ add_index :raif_tasks, :completed_at
6
+ add_index :raif_tasks, :failed_at
7
+ add_index :raif_tasks, :started_at
8
+
9
+ # Index for type + status combinations which will be common in the admin interface
10
+ add_index :raif_tasks, [:type, :completed_at]
11
+ add_index :raif_tasks, [:type, :failed_at]
12
+ add_index :raif_tasks, [:type, :started_at]
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddRetryCountToRaifModelCompletions < ActiveRecord::Migration[7.1]
4
+ def change
5
+ add_column :raif_model_completions, :retry_count, :integer, default: 0, null: false
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddResponseIdAndResponseArrayToModelCompletions < 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_model_completions, :response_id, :string
12
+ add_column :raif_model_completions, :response_array, json_column_type
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddCitationsToRaifModelCompletions < 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_model_completions, :citations, json_column_type
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddStreamResponseToRaifModelCompletions < ActiveRecord::Migration[7.1]
4
+ def change
5
+ add_column :raif_model_completions, :stream_response, :boolean, default: false, null: false
6
+ end
7
+ end
@@ -1,22 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Raif
4
- class AgentGenerator < Rails::Generators::NamedBase
5
- source_root File.expand_path("templates", __dir__)
6
- desc "Creates a new Raif::Agent subclass in app/models/raif/agents"
4
+ module Generators
5
+ class AgentGenerator < Rails::Generators::NamedBase
6
+ source_root File.expand_path("templates", __dir__)
7
+ desc "Creates a new Raif::Agent subclass in app/models/raif/agents"
7
8
 
8
- def create_agent
9
- template "agent.rb.tt", "app/models/raif/agents/#{file_name}.rb"
10
- end
9
+ def create_application_agent
10
+ template "application_agent.rb.tt", "app/models/raif/application_agent.rb" unless File.exist?("app/models/raif/application_agent.rb")
11
+ end
11
12
 
12
- private
13
+ def create_agent
14
+ template "agent.rb.tt", "app/models/raif/agents/#{file_name}.rb"
15
+ end
13
16
 
14
- def class_name
15
- name.classify
16
- end
17
+ def create_directory
18
+ empty_directory "app/models/raif/agents" unless File.directory?("app/models/raif/agents")
19
+ end
20
+
21
+ private
22
+
23
+ def class_name
24
+ name.classify
25
+ end
17
26
 
18
- def file_name
19
- name.underscore
27
+ def file_name
28
+ name.underscore
29
+ end
20
30
  end
21
31
  end
22
32
  end
@@ -2,15 +2,15 @@
2
2
 
3
3
  module Raif
4
4
  module Agents
5
- class <%= class_name %> < Raif::Agent
5
+ class <%= class_name %> < Raif::ApplicationAgent
6
6
  # If you want to always include a certain set of model tools with this agent type,
7
7
  # uncomment this callback to populate the available_model_tools attribute with your desired model tools.
8
- # before_create -> {
8
+ # def populate_default_model_tools
9
9
  # self.available_model_tools ||= [
10
10
  # Raif::ModelTools::WikipediaSearchTool,
11
11
  # Raif::ModelTools::FetchUrlTool
12
12
  # ]
13
- # }
13
+ # end
14
14
 
15
15
  # Enter your agent's system prompt here. Alternatively, you can change your agent's superclass
16
16
  # to an existing agent types (like Raif::Agents::ReActAgent) to utilize an existing system prompt.
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Raif
4
+ class ApplicationAgent < Raif::Agent
5
+ # Add any shared agent behavior here
6
+ end
7
+ end
@@ -7,6 +7,16 @@ module Raif
7
7
 
8
8
  desc "Creates a new conversation type in the app/models/raif/conversations directory"
9
9
 
10
+ class_option :response_format,
11
+ type: :string,
12
+ default: "text",
13
+ desc: "Response format for the task (text, html, or json)"
14
+
15
+ def create_application_conversation
16
+ template "application_conversation.rb.tt",
17
+ "app/models/raif/application_conversation.rb" unless File.exist?("app/models/raif/application_conversation.rb")
18
+ end
19
+
10
20
  def create_conversation_file
11
21
  template "conversation.rb.tt", File.join("app/models/raif/conversations", "#{file_name}.rb")
12
22
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Raif
4
+ class ApplicationConversation < Raif::Conversation
5
+ # Add any shared conversation behavior here
6
+ end
7
+ end
@@ -2,28 +2,23 @@
2
2
 
3
3
  module Raif
4
4
  module Conversations
5
- class <%= class_name %> < Raif::Conversation
6
- # If you want to always include a certain set of model tools with this conversation type,
5
+ class <%= class_name %> < Raif::ApplicationConversation
6
+ # Set the response format for the task. Options are :html, :text, or :json.
7
+ # If you set this to something other than :text, make sure to include instructions to the model in your system prompt
8
+ llm_response_format :<%= options[:response_format] %>
9
+
10
+ # If you want to always include a certain set of model tools with this conversation type,
7
11
  # uncomment this callback to populate the available_model_tools attribute with your desired model tools.
8
12
  # before_create -> { self.available_model_tools = ["Raif::ModelTools::Example"] }
9
13
 
10
- # Override the methods below to customize the system prompt for this conversation type.
11
- # Raif::Conversation expects a JSON response with a message key from the model, so make sure your system prompt instructs the model to respond accordingly.
14
+ # Override the methods below to customize the system prompt for this conversation type.
12
15
  # def system_prompt_intro
13
16
  # Raif.config.conversation_system_prompt_intro
14
17
  # end
15
-
18
+
16
19
  # def build_system_prompt
17
20
  # <<~PROMPT
18
21
  # #{system_prompt_intro}
19
- #
20
- # # Your Responses
21
- # Your responses should always be in JSON format with a "message" field containing your response to your collaborator. For example:
22
- # {
23
- # "message": "Your response message"
24
- # }
25
- # #{tool_usage_system_prompt}
26
- # #{system_prompt_reminders}
27
22
  # #{system_prompt_language_preference}
28
23
  # PROMPT
29
24
  # end
@@ -32,6 +27,13 @@ module Raif
32
27
  # def initial_chat_message
33
28
  # I18n.t("#{self.class.name.underscore.gsub("/", ".")}.initial_chat_message")
34
29
  # end
30
+
31
+ # This method will be called when receing a model response to a Raif::ConversationEntry
32
+ # By default, it just passes the model response message through, but you can override
33
+ # for custom response message processing
34
+ # def process_model_response_message(message:, entry:)
35
+ # message
36
+ # end
35
37
  end
36
38
  end
37
- end
39
+ end
@@ -4,26 +4,56 @@ Raif.configure do |config|
4
4
  # Your OpenAI API key. Defaults to ENV["OPENAI_API_KEY"]
5
5
  # config.open_ai_api_key = ENV["OPENAI_API_KEY"]
6
6
 
7
- # Whether OpenAI models are enabled. Defaults to true
8
- # config.open_ai_models_enabled = true
7
+ # Whether OpenAI models are enabled.
8
+ # config.open_ai_models_enabled = ENV["OPENAI_API_KEY"].present?
9
+
10
+ # Whether OpenAI embedding models are enabled.
11
+ # config.open_ai_embedding_models_enabled = ENV["OPENAI_API_KEY"].present?
9
12
 
10
13
  # Your Anthropic API key. Defaults to ENV["ANTHROPIC_API_KEY"]
11
14
  # config.anthropic_api_key = ENV["ANTHROPIC_API_KEY"]
12
15
 
13
- # Whether Anthropic models are enabled. Defaults to true
14
- # config.anthropic_models_enabled = true
16
+ # Whether Anthropic models are enabled.
17
+ # config.anthropic_models_enabled = ENV["ANTHROPIC_API_KEY"].present?
15
18
 
16
- # Whether Anthropic models via AWS Bedrock are enabled. Defaults to true
17
- # config.anthropic_bedrock_models_enabled = true
19
+ # Whether Anthropic models via AWS Bedrock are enabled. Defaults to false
20
+ # config.bedrock_models_enabled = false
18
21
 
19
22
  # The AWS Bedrock region to use. Defaults to "us-east-1"
20
23
  # config.aws_bedrock_region = "us-east-1"
21
24
 
25
+ # Prefix to apply to the model name in AWS Bedrock API calls (e.g. us.anthropic.claude-3-5-haiku-20241022-v1:0)
26
+ # config.aws_bedrock_model_name_prefix = "us"
27
+
28
+ # Whether Titan embedding models are enabled. Defaults to false
29
+ # config.bedrock_embedding_models_enabled = false
30
+
31
+ # Your OpenRouter API key. Defaults to ENV["OPENROUTER_API_KEY"]
32
+ # config.open_router_api_key = ENV["OPENROUTER_API_KEY"]
33
+
34
+ # Whether OpenRouter models are enabled.
35
+ # config.open_router_models_enabled = ENV["OPENROUTER_API_KEY"].present?
36
+
37
+ # The app name to include in OpenRouter API requests headers. Optional.
38
+ # config.open_router_app_name = "My App"
39
+
40
+ # The site URL to include in OpenRouter API requests headers. Optional.
41
+ # config.open_router_site_url = "https://myapp.com"
42
+
22
43
  # The default LLM model to use. Defaults to "open_ai_gpt_4o"
23
44
  # Available keys:
45
+ # open_ai_gpt_4_1
46
+ # open_ai_gpt_4_1_mini
47
+ # open_ai_gpt_4_1_nano
24
48
  # open_ai_gpt_4o_mini
25
49
  # open_ai_gpt_4o
26
50
  # open_ai_gpt_3_5_turbo
51
+ # open_ai_responses_gpt_4_1
52
+ # open_ai_responses_gpt_4_1_mini
53
+ # open_ai_responses_gpt_4_1_nano
54
+ # open_ai_responses_gpt_4o_mini
55
+ # open_ai_responses_gpt_4o
56
+ # open_ai_gpt_3_5_turbo
27
57
  # anthropic_claude_3_7_sonnet
28
58
  # anthropic_claude_3_5_sonnet
29
59
  # anthropic_claude_3_5_haiku
@@ -32,8 +62,27 @@ Raif.configure do |config|
32
62
  # bedrock_claude_3_7_sonnet
33
63
  # bedrock_claude_3_5_haiku
34
64
  # bedrock_claude_3_opus
65
+ # bedrock_amazon_nova_micro
66
+ # bedrock_amazon_nova_lite
67
+ # bedrock_amazon_nova_pro
68
+ # open_router_claude_3_7_sonnet
69
+ # open_router_llama_3_3_70b_instruct
70
+ # open_router_llama_3_1_8b_instruct
71
+ # open_router_gemini_2_0_flash
72
+ # open_router_deepseek_chat_v3
73
+ #
35
74
  # config.default_llm_model_key = "open_ai_gpt_4o"
36
75
 
76
+ # The default embedding model to use when calling Raif.generate_embedding!
77
+ # Defaults to "open_ai_text_embedding_3_small"
78
+ # Available keys:
79
+ # open_ai_text_embedding_3_small
80
+ # open_ai_text_embedding_3_large
81
+ # open_ai_text_embedding_ada_002
82
+ # bedrock_titan_embed_text_v2
83
+ #
84
+ # config.default_embedding_model_key = "open_ai_text_embedding_3_small"
85
+
37
86
  # A lambda that returns true if the current user is authorized to access admin controllers.
38
87
  # By default it returns false, so you must implement this in your application to use the admin controllers.
39
88
  # If your application's user model has an admin? method, you could use something like this:
@@ -46,9 +95,13 @@ Raif.configure do |config|
46
95
 
47
96
  # The system prompt intro for Raif::Task instances. Defaults to "You are a helpful assistant."
48
97
  # config.task_system_prompt_intro = "You are a helpful assistant."
98
+ # Or you can use a lambda to return a dynamic system prompt intro:
99
+ # config.task_system_prompt_intro = ->(task){ "You are a helpful assistant. Today's date is #{Date.today.strftime('%B %d, %Y')}." }
49
100
 
50
101
  # The system prompt intro for Raif::Conversation instances. Defaults to "You are a helpful assistant who is collaborating with a teammate."
51
102
  # config.conversation_system_prompt_intro = "You are a helpful assistant who is collaborating with a teammate."
103
+ # Or you can use a lambda to return a dynamic system prompt intro:
104
+ # config.conversation_system_prompt_intro = ->(conversation){ "You are a helpful assistant talking to #{conversation.creator.email}. Today's date is #{Date.today.strftime('%B %d, %Y')}." }
52
105
 
53
106
  # The conversation types that are available. Defaults to ["Raif::Conversation"]
54
107
  # If you want to use custom conversation types that inherits from Raif::Conversation, you can add them here.
@@ -75,6 +128,9 @@ Raif.configure do |config|
75
128
  # The user tool types that are available. Defaults to []
76
129
  # config.user_tool_types = []
77
130
 
131
+ # The chunk size threshold for streaming updates. Defaults to 25.
132
+ # config.streaming_update_chunk_size_threshold = 25
133
+
78
134
  # Whether LLM API requests are enabled. Defaults to true.
79
135
  # Use this to globally disable requests to LLM APIs.
80
136
  # config.llm_api_requests_enabled = true
@@ -15,11 +15,6 @@ module Raif
15
15
  say_status :success, "Model tool created successfully", :green
16
16
  say "\nYou can now implement your model tool in:"
17
17
  say " app/models/raif/model_tools/#{file_name}.rb"
18
- say "\nImportant methods to implement:"
19
- say " - example_model_invocation: An example of how to invoke the tool, to be provided to the LLM"
20
- say " - tool_arguments_schema: JSON schema for validating arguments when the tool is invoked"
21
- say " - tool_description: A brief description of what the tool does, to be provided to the LLM"
22
- say " - process_invocation: The main method that executes the tool's functionality"
23
18
  end
24
19
 
25
20
  end