activeagent 0.6.3 → 1.0.0.rc1

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 (282) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +210 -2
  3. data/README.md +15 -24
  4. data/lib/active_agent/base.rb +389 -39
  5. data/lib/active_agent/concerns/callbacks.rb +251 -0
  6. data/lib/active_agent/concerns/observers.rb +147 -0
  7. data/lib/active_agent/concerns/parameterized.rb +292 -0
  8. data/lib/active_agent/concerns/provider.rb +120 -0
  9. data/lib/active_agent/concerns/queueing.rb +36 -0
  10. data/lib/active_agent/concerns/rescue.rb +64 -0
  11. data/lib/active_agent/concerns/streaming.rb +282 -0
  12. data/lib/active_agent/concerns/tooling.rb +23 -0
  13. data/lib/active_agent/concerns/view.rb +150 -0
  14. data/lib/active_agent/configuration.rb +442 -20
  15. data/lib/active_agent/generation.rb +141 -47
  16. data/lib/active_agent/generation_provider/open_router/types.rb +505 -0
  17. data/lib/active_agent/generation_provider/xai_provider.rb +144 -0
  18. data/lib/active_agent/providers/_base_provider.rb +410 -0
  19. data/lib/active_agent/providers/anthropic/_types.rb +63 -0
  20. data/lib/active_agent/providers/anthropic/options.rb +53 -0
  21. data/lib/active_agent/providers/anthropic/request.rb +109 -0
  22. data/lib/active_agent/providers/anthropic/requests/_types.rb +190 -0
  23. data/lib/active_agent/providers/anthropic/requests/container_params.rb +19 -0
  24. data/lib/active_agent/providers/anthropic/requests/content/base.rb +21 -0
  25. data/lib/active_agent/providers/anthropic/requests/content/sources/base.rb +22 -0
  26. data/lib/active_agent/providers/anthropic/requests/context_management_config.rb +18 -0
  27. data/lib/active_agent/providers/anthropic/requests/messages/_types.rb +189 -0
  28. data/lib/active_agent/providers/anthropic/requests/messages/assistant.rb +23 -0
  29. data/lib/active_agent/providers/anthropic/requests/messages/base.rb +63 -0
  30. data/lib/active_agent/providers/anthropic/requests/messages/content/_types.rb +143 -0
  31. data/lib/active_agent/providers/anthropic/requests/messages/content/base.rb +21 -0
  32. data/lib/active_agent/providers/anthropic/requests/messages/content/document.rb +26 -0
  33. data/lib/active_agent/providers/anthropic/requests/messages/content/image.rb +23 -0
  34. data/lib/active_agent/providers/anthropic/requests/messages/content/redacted_thinking.rb +21 -0
  35. data/lib/active_agent/providers/anthropic/requests/messages/content/search_result.rb +27 -0
  36. data/lib/active_agent/providers/anthropic/requests/messages/content/sources/_types.rb +171 -0
  37. data/lib/active_agent/providers/anthropic/requests/messages/content/sources/base.rb +22 -0
  38. data/lib/active_agent/providers/anthropic/requests/messages/content/sources/document_base64.rb +25 -0
  39. data/lib/active_agent/providers/anthropic/requests/messages/content/sources/document_file.rb +23 -0
  40. data/lib/active_agent/providers/anthropic/requests/messages/content/sources/document_text.rb +25 -0
  41. data/lib/active_agent/providers/anthropic/requests/messages/content/sources/document_url.rb +23 -0
  42. data/lib/active_agent/providers/anthropic/requests/messages/content/sources/image_base64.rb +27 -0
  43. data/lib/active_agent/providers/anthropic/requests/messages/content/sources/image_file.rb +23 -0
  44. data/lib/active_agent/providers/anthropic/requests/messages/content/sources/image_url.rb +23 -0
  45. data/lib/active_agent/providers/anthropic/requests/messages/content/text.rb +22 -0
  46. data/lib/active_agent/providers/anthropic/requests/messages/content/thinking.rb +23 -0
  47. data/lib/active_agent/providers/anthropic/requests/messages/content/tool_result.rb +24 -0
  48. data/lib/active_agent/providers/anthropic/requests/messages/content/tool_use.rb +28 -0
  49. data/lib/active_agent/providers/anthropic/requests/messages/user.rb +21 -0
  50. data/lib/active_agent/providers/anthropic/requests/metadata.rb +18 -0
  51. data/lib/active_agent/providers/anthropic/requests/response_format.rb +22 -0
  52. data/lib/active_agent/providers/anthropic/requests/thinking_config/_types.rb +60 -0
  53. data/lib/active_agent/providers/anthropic/requests/thinking_config/base.rb +20 -0
  54. data/lib/active_agent/providers/anthropic/requests/thinking_config/disabled.rb +16 -0
  55. data/lib/active_agent/providers/anthropic/requests/thinking_config/enabled.rb +20 -0
  56. data/lib/active_agent/providers/anthropic/requests/tool_choice/_types.rb +78 -0
  57. data/lib/active_agent/providers/anthropic/requests/tool_choice/any.rb +17 -0
  58. data/lib/active_agent/providers/anthropic/requests/tool_choice/auto.rb +17 -0
  59. data/lib/active_agent/providers/anthropic/requests/tool_choice/base.rb +20 -0
  60. data/lib/active_agent/providers/anthropic/requests/tool_choice/none.rb +16 -0
  61. data/lib/active_agent/providers/anthropic/requests/tool_choice/tool.rb +20 -0
  62. data/lib/active_agent/providers/anthropic_provider.rb +211 -0
  63. data/lib/active_agent/providers/common/messages/_types.rb +124 -0
  64. data/lib/active_agent/providers/common/messages/assistant.rb +57 -0
  65. data/lib/active_agent/providers/common/messages/base.rb +17 -0
  66. data/lib/active_agent/providers/common/messages/system.rb +20 -0
  67. data/lib/active_agent/providers/common/messages/tool.rb +21 -0
  68. data/lib/active_agent/providers/common/messages/user.rb +20 -0
  69. data/lib/active_agent/providers/common/model.rb +361 -0
  70. data/lib/active_agent/providers/common/response.rb +13 -0
  71. data/lib/active_agent/providers/common/responses/_types.rb +51 -0
  72. data/lib/active_agent/providers/common/responses/base.rb +151 -0
  73. data/lib/active_agent/providers/common/responses/embed.rb +33 -0
  74. data/lib/active_agent/providers/common/responses/format.rb +31 -0
  75. data/lib/active_agent/providers/common/responses/message.rb +3 -0
  76. data/lib/active_agent/providers/common/responses/prompt.rb +42 -0
  77. data/lib/active_agent/providers/concerns/exception_handler.rb +72 -0
  78. data/lib/active_agent/providers/concerns/previewable.rb +150 -0
  79. data/lib/active_agent/providers/log_subscriber.rb +360 -0
  80. data/lib/active_agent/providers/mock/_types.rb +77 -0
  81. data/lib/active_agent/providers/mock/embedding_request.rb +17 -0
  82. data/lib/active_agent/providers/mock/messages/_types.rb +103 -0
  83. data/lib/active_agent/providers/mock/messages/assistant.rb +26 -0
  84. data/lib/active_agent/providers/mock/messages/base.rb +63 -0
  85. data/lib/active_agent/providers/mock/messages/user.rb +18 -0
  86. data/lib/active_agent/providers/mock/options.rb +30 -0
  87. data/lib/active_agent/providers/mock/request.rb +38 -0
  88. data/lib/active_agent/providers/mock_provider.rb +311 -0
  89. data/lib/active_agent/providers/ollama/_types.rb +5 -0
  90. data/lib/active_agent/providers/ollama/chat/_types.rb +44 -0
  91. data/lib/active_agent/providers/ollama/chat/request.rb +70 -0
  92. data/lib/active_agent/providers/ollama/chat/requests/_types.rb +3 -0
  93. data/lib/active_agent/providers/ollama/chat/requests/messages/_types.rb +116 -0
  94. data/lib/active_agent/providers/ollama/chat/requests/messages/assistant.rb +19 -0
  95. data/lib/active_agent/providers/ollama/chat/requests/messages/user.rb +19 -0
  96. data/lib/active_agent/providers/ollama/embedding/_types.rb +44 -0
  97. data/lib/active_agent/providers/ollama/embedding/request.rb +77 -0
  98. data/lib/active_agent/providers/ollama/embedding/requests/_types.rb +83 -0
  99. data/lib/active_agent/providers/ollama/embedding/requests/options.rb +104 -0
  100. data/lib/active_agent/providers/ollama/options.rb +27 -0
  101. data/lib/active_agent/providers/ollama_provider.rb +95 -0
  102. data/lib/active_agent/providers/open_ai/_base.rb +58 -0
  103. data/lib/active_agent/providers/open_ai/_types.rb +5 -0
  104. data/lib/active_agent/providers/open_ai/chat/_types.rb +44 -0
  105. data/lib/active_agent/providers/open_ai/chat/request.rb +215 -0
  106. data/lib/active_agent/providers/open_ai/chat/requests/_types.rb +229 -0
  107. data/lib/active_agent/providers/open_ai/chat/requests/audio.rb +24 -0
  108. data/lib/active_agent/providers/open_ai/chat/requests/messages/_types.rb +123 -0
  109. data/lib/active_agent/providers/open_ai/chat/requests/messages/assistant.rb +42 -0
  110. data/lib/active_agent/providers/open_ai/chat/requests/messages/base.rb +78 -0
  111. data/lib/active_agent/providers/open_ai/chat/requests/messages/content/_types.rb +133 -0
  112. data/lib/active_agent/providers/open_ai/chat/requests/messages/content/audio.rb +35 -0
  113. data/lib/active_agent/providers/open_ai/chat/requests/messages/content/base.rb +24 -0
  114. data/lib/active_agent/providers/open_ai/chat/requests/messages/content/file.rb +26 -0
  115. data/lib/active_agent/providers/open_ai/chat/requests/messages/content/files/_types.rb +60 -0
  116. data/lib/active_agent/providers/open_ai/chat/requests/messages/content/files/details.rb +41 -0
  117. data/lib/active_agent/providers/open_ai/chat/requests/messages/content/image.rb +37 -0
  118. data/lib/active_agent/providers/open_ai/chat/requests/messages/content/refusal.rb +25 -0
  119. data/lib/active_agent/providers/open_ai/chat/requests/messages/content/text.rb +25 -0
  120. data/lib/active_agent/providers/open_ai/chat/requests/messages/developer.rb +25 -0
  121. data/lib/active_agent/providers/open_ai/chat/requests/messages/function.rb +25 -0
  122. data/lib/active_agent/providers/open_ai/chat/requests/messages/system.rb +25 -0
  123. data/lib/active_agent/providers/open_ai/chat/requests/messages/tool.rb +26 -0
  124. data/lib/active_agent/providers/open_ai/chat/requests/messages/user.rb +32 -0
  125. data/lib/active_agent/providers/open_ai/chat/requests/prediction.rb +46 -0
  126. data/lib/active_agent/providers/open_ai/chat/requests/response_format.rb +53 -0
  127. data/lib/active_agent/providers/open_ai/chat/requests/stream_options.rb +24 -0
  128. data/lib/active_agent/providers/open_ai/chat/requests/tool_choice.rb +26 -0
  129. data/lib/active_agent/providers/open_ai/chat/requests/tools/_types.rb +5 -0
  130. data/lib/active_agent/providers/open_ai/chat/requests/tools/base.rb +22 -0
  131. data/lib/active_agent/providers/open_ai/chat/requests/tools/custom_tool.rb +41 -0
  132. data/lib/active_agent/providers/open_ai/chat/requests/tools/function_tool.rb +51 -0
  133. data/lib/active_agent/providers/open_ai/chat/requests/web_search_options.rb +45 -0
  134. data/lib/active_agent/providers/open_ai/chat_provider.rb +198 -0
  135. data/lib/active_agent/providers/open_ai/embedding/_types.rb +45 -0
  136. data/lib/active_agent/providers/open_ai/embedding/request.rb +85 -0
  137. data/lib/active_agent/providers/open_ai/embedding/requests/_types.rb +49 -0
  138. data/lib/active_agent/providers/open_ai/options.rb +74 -0
  139. data/lib/active_agent/providers/open_ai/responses/_types.rb +50 -0
  140. data/lib/active_agent/providers/open_ai/responses/request.rb +163 -0
  141. data/lib/active_agent/providers/open_ai/responses/requests/_types.rb +231 -0
  142. data/lib/active_agent/providers/open_ai/responses/requests/conversation.rb +23 -0
  143. data/lib/active_agent/providers/open_ai/responses/requests/inputs/_types.rb +264 -0
  144. data/lib/active_agent/providers/open_ai/responses/requests/inputs/assistant_message.rb +22 -0
  145. data/lib/active_agent/providers/open_ai/responses/requests/inputs/base.rb +89 -0
  146. data/lib/active_agent/providers/open_ai/responses/requests/inputs/code_interpreter_tool_call.rb +30 -0
  147. data/lib/active_agent/providers/open_ai/responses/requests/inputs/computer_tool_call.rb +28 -0
  148. data/lib/active_agent/providers/open_ai/responses/requests/inputs/computer_tool_call_output.rb +33 -0
  149. data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/_types.rb +207 -0
  150. data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/base.rb +22 -0
  151. data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/input_audio.rb +26 -0
  152. data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/input_file.rb +28 -0
  153. data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/input_image.rb +28 -0
  154. data/lib/active_agent/providers/open_ai/responses/requests/inputs/content/input_text.rb +25 -0
  155. data/lib/active_agent/providers/open_ai/responses/requests/inputs/custom_tool_call.rb +28 -0
  156. data/lib/active_agent/providers/open_ai/responses/requests/inputs/custom_tool_call_output.rb +27 -0
  157. data/lib/active_agent/providers/open_ai/responses/requests/inputs/developer_message.rb +20 -0
  158. data/lib/active_agent/providers/open_ai/responses/requests/inputs/file_search_tool_call.rb +25 -0
  159. data/lib/active_agent/providers/open_ai/responses/requests/inputs/function_call_output.rb +32 -0
  160. data/lib/active_agent/providers/open_ai/responses/requests/inputs/function_tool_call.rb +28 -0
  161. data/lib/active_agent/providers/open_ai/responses/requests/inputs/image_gen_tool_call.rb +27 -0
  162. data/lib/active_agent/providers/open_ai/responses/requests/inputs/input_message.rb +31 -0
  163. data/lib/active_agent/providers/open_ai/responses/requests/inputs/item_reference.rb +23 -0
  164. data/lib/active_agent/providers/open_ai/responses/requests/inputs/local_shell_tool_call.rb +26 -0
  165. data/lib/active_agent/providers/open_ai/responses/requests/inputs/local_shell_tool_call_output.rb +33 -0
  166. data/lib/active_agent/providers/open_ai/responses/requests/inputs/mcp_approval_request.rb +30 -0
  167. data/lib/active_agent/providers/open_ai/responses/requests/inputs/mcp_approval_response.rb +28 -0
  168. data/lib/active_agent/providers/open_ai/responses/requests/inputs/mcp_list_tools.rb +29 -0
  169. data/lib/active_agent/providers/open_ai/responses/requests/inputs/mcp_tool_call.rb +35 -0
  170. data/lib/active_agent/providers/open_ai/responses/requests/inputs/output_message.rb +35 -0
  171. data/lib/active_agent/providers/open_ai/responses/requests/inputs/reasoning.rb +33 -0
  172. data/lib/active_agent/providers/open_ai/responses/requests/inputs/system_message.rb +20 -0
  173. data/lib/active_agent/providers/open_ai/responses/requests/inputs/tool_call_base.rb +27 -0
  174. data/lib/active_agent/providers/open_ai/responses/requests/inputs/tool_message.rb +23 -0
  175. data/lib/active_agent/providers/open_ai/responses/requests/inputs/user_message.rb +20 -0
  176. data/lib/active_agent/providers/open_ai/responses/requests/inputs/web_search_tool_call.rb +24 -0
  177. data/lib/active_agent/providers/open_ai/responses/requests/prompt_reference.rb +23 -0
  178. data/lib/active_agent/providers/open_ai/responses/requests/reasoning.rb +23 -0
  179. data/lib/active_agent/providers/open_ai/responses/requests/stream_options.rb +20 -0
  180. data/lib/active_agent/providers/open_ai/responses/requests/text/_types.rb +89 -0
  181. data/lib/active_agent/providers/open_ai/responses/requests/text/base.rb +22 -0
  182. data/lib/active_agent/providers/open_ai/responses/requests/text/json_object.rb +20 -0
  183. data/lib/active_agent/providers/open_ai/responses/requests/text/json_schema.rb +48 -0
  184. data/lib/active_agent/providers/open_ai/responses/requests/text/plain.rb +20 -0
  185. data/lib/active_agent/providers/open_ai/responses/requests/text.rb +41 -0
  186. data/lib/active_agent/providers/open_ai/responses/requests/tool_choice.rb +26 -0
  187. data/lib/active_agent/providers/open_ai/responses/requests/tools/_types.rb +112 -0
  188. data/lib/active_agent/providers/open_ai/responses/requests/tools/base.rb +25 -0
  189. data/lib/active_agent/providers/open_ai/responses/requests/tools/code_interpreter_tool.rb +23 -0
  190. data/lib/active_agent/providers/open_ai/responses/requests/tools/computer_tool.rb +27 -0
  191. data/lib/active_agent/providers/open_ai/responses/requests/tools/custom_tool.rb +28 -0
  192. data/lib/active_agent/providers/open_ai/responses/requests/tools/file_search_tool.rb +27 -0
  193. data/lib/active_agent/providers/open_ai/responses/requests/tools/function_tool.rb +29 -0
  194. data/lib/active_agent/providers/open_ai/responses/requests/tools/image_generation_tool.rb +37 -0
  195. data/lib/active_agent/providers/open_ai/responses/requests/tools/local_shell_tool.rb +21 -0
  196. data/lib/active_agent/providers/open_ai/responses/requests/tools/mcp_tool.rb +41 -0
  197. data/lib/active_agent/providers/open_ai/responses/requests/tools/web_search_preview_tool.rb +24 -0
  198. data/lib/active_agent/providers/open_ai/responses/requests/tools/web_search_tool.rb +25 -0
  199. data/lib/active_agent/providers/open_ai/responses_provider.rb +153 -0
  200. data/lib/active_agent/providers/open_ai/schema.yml +65937 -0
  201. data/lib/active_agent/providers/open_ai_provider.rb +97 -0
  202. data/lib/active_agent/providers/open_router/_types.rb +45 -0
  203. data/lib/active_agent/providers/open_router/options.rb +93 -0
  204. data/lib/active_agent/providers/open_router/request.rb +83 -0
  205. data/lib/active_agent/providers/open_router/requests/_types.rb +198 -0
  206. data/lib/active_agent/providers/open_router/requests/message.rb +1 -0
  207. data/lib/active_agent/providers/open_router/requests/messages/_types.rb +59 -0
  208. data/lib/active_agent/providers/open_router/requests/messages/assistant.rb +20 -0
  209. data/lib/active_agent/providers/open_router/requests/messages/content/_types.rb +97 -0
  210. data/lib/active_agent/providers/open_router/requests/messages/content/file.rb +27 -0
  211. data/lib/active_agent/providers/open_router/requests/messages/content/files/_types.rb +61 -0
  212. data/lib/active_agent/providers/open_router/requests/messages/content/files/details.rb +26 -0
  213. data/lib/active_agent/providers/open_router/requests/messages/user.rb +30 -0
  214. data/lib/active_agent/providers/open_router/requests/plugin.rb +25 -0
  215. data/lib/active_agent/providers/open_router/requests/plugins/_types.rb +46 -0
  216. data/lib/active_agent/providers/open_router/requests/plugins/pdf_config.rb +29 -0
  217. data/lib/active_agent/providers/open_router/requests/prediction.rb +17 -0
  218. data/lib/active_agent/providers/open_router/requests/provider_preferences/_types.rb +44 -0
  219. data/lib/active_agent/providers/open_router/requests/provider_preferences/max_price.rb +30 -0
  220. data/lib/active_agent/providers/open_router/requests/provider_preferences.rb +64 -0
  221. data/lib/active_agent/providers/open_router/requests/response_format.rb +49 -0
  222. data/lib/active_agent/providers/open_router_provider.rb +53 -0
  223. data/lib/active_agent/providers/openai_provider.rb +2 -0
  224. data/lib/active_agent/providers/openrouter_provider.rb +2 -0
  225. data/lib/active_agent/railtie.rb +8 -6
  226. data/lib/active_agent/schema_generator.rb +333 -166
  227. data/lib/active_agent/version.rb +1 -1
  228. data/lib/active_agent.rb +112 -36
  229. data/lib/generators/active_agent/agent/USAGE +78 -0
  230. data/lib/generators/active_agent/{agent_generator.rb → agent/agent_generator.rb} +14 -4
  231. data/lib/generators/active_agent/install/USAGE +25 -0
  232. data/lib/generators/active_agent/{install_generator.rb → install/install_generator.rb} +1 -19
  233. data/lib/generators/active_agent/templates/agent.rb.tt +7 -3
  234. data/lib/generators/active_agent/templates/application_agent.rb.tt +0 -2
  235. data/lib/generators/erb/agent_generator.rb +31 -16
  236. data/lib/generators/erb/templates/instructions.md.erb.tt +3 -0
  237. data/lib/generators/erb/templates/instructions.md.tt +3 -0
  238. data/lib/generators/erb/templates/instructions.text.tt +1 -0
  239. data/lib/generators/erb/templates/message.md.erb.tt +5 -0
  240. data/lib/generators/erb/templates/schema.json.tt +10 -0
  241. data/lib/generators/test_unit/agent_generator.rb +1 -1
  242. data/lib/generators/test_unit/templates/functional_test.rb.tt +4 -2
  243. metadata +320 -65
  244. data/lib/active_agent/action_prompt/action.rb +0 -13
  245. data/lib/active_agent/action_prompt/base.rb +0 -623
  246. data/lib/active_agent/action_prompt/message.rb +0 -126
  247. data/lib/active_agent/action_prompt/prompt.rb +0 -136
  248. data/lib/active_agent/action_prompt.rb +0 -19
  249. data/lib/active_agent/callbacks.rb +0 -33
  250. data/lib/active_agent/generation_provider/anthropic_provider.rb +0 -163
  251. data/lib/active_agent/generation_provider/base.rb +0 -55
  252. data/lib/active_agent/generation_provider/base_adapter.rb +0 -19
  253. data/lib/active_agent/generation_provider/error_handling.rb +0 -167
  254. data/lib/active_agent/generation_provider/log_subscriber.rb +0 -92
  255. data/lib/active_agent/generation_provider/message_formatting.rb +0 -107
  256. data/lib/active_agent/generation_provider/ollama_provider.rb +0 -66
  257. data/lib/active_agent/generation_provider/open_ai_provider.rb +0 -279
  258. data/lib/active_agent/generation_provider/open_router_provider.rb +0 -385
  259. data/lib/active_agent/generation_provider/parameter_builder.rb +0 -119
  260. data/lib/active_agent/generation_provider/response.rb +0 -75
  261. data/lib/active_agent/generation_provider/responses_adapter.rb +0 -44
  262. data/lib/active_agent/generation_provider/stream_processing.rb +0 -58
  263. data/lib/active_agent/generation_provider/tool_management.rb +0 -142
  264. data/lib/active_agent/generation_provider.rb +0 -67
  265. data/lib/active_agent/log_subscriber.rb +0 -44
  266. data/lib/active_agent/parameterized.rb +0 -75
  267. data/lib/active_agent/prompt_helper.rb +0 -19
  268. data/lib/active_agent/queued_generation.rb +0 -12
  269. data/lib/active_agent/rescuable.rb +0 -34
  270. data/lib/active_agent/sanitizers.rb +0 -40
  271. data/lib/active_agent/streaming.rb +0 -34
  272. data/lib/active_agent/test_case.rb +0 -125
  273. data/lib/generators/USAGE +0 -47
  274. data/lib/generators/active_agent/USAGE +0 -56
  275. data/lib/generators/erb/install_generator.rb +0 -44
  276. data/lib/generators/erb/templates/layout.html.erb.tt +0 -1
  277. data/lib/generators/erb/templates/layout.json.erb.tt +0 -1
  278. data/lib/generators/erb/templates/layout.text.erb.tt +0 -1
  279. data/lib/generators/erb/templates/view.html.erb.tt +0 -5
  280. data/lib/generators/erb/templates/view.json.erb.tt +0 -16
  281. /data/lib/active_agent/{preview.rb → concerns/preview.rb} +0 -0
  282. /data/lib/generators/erb/templates/{view.text.erb.tt → message.text.erb.tt} +0 -0
data/lib/active_agent.rb CHANGED
@@ -1,42 +1,126 @@
1
- require "yaml"
1
+ # frozen_string_literal: true
2
+
3
+
2
4
  require "abstract_controller"
3
- require "active_agent/configuration"
4
- require "active_agent/generation_provider"
5
5
  require "active_agent/version"
6
6
  require "active_agent/deprecator"
7
- require "active_agent/railtie" if defined?(Rails)
8
- require "active_agent/sanitizers"
9
7
 
8
+ # Common Active Support usage in Action Agent
10
9
  require "active_support"
11
10
  require "active_support/rails"
12
11
  require "active_support/core_ext/class"
13
12
  require "active_support/core_ext/module/attr_internal"
14
13
  require "active_support/core_ext/string/inflections"
15
14
  require "active_support/lazy_load_hooks"
15
+
16
+ # Module Level Extensions
17
+ require "active_agent/configuration"
18
+ require "active_agent/railtie" if defined?(Rails)
19
+
20
+ # ActiveAgent is a framework for building AI agents with Rails-like conventions.
21
+ #
22
+ # It provides a structured approach to interacting with Large Language Models (LLMs)
23
+ # by offering a familiar interface inspired by ActionMailer. ActiveAgent handles
24
+ # prompt management, tool integration, streaming responses, and provider abstraction.
25
+ #
26
+ # = Core Concepts
27
+ #
28
+ # * **Agents**: Classes that inherit from {ActiveAgent::Base} and define prompts as methods
29
+ # * **Prompts**: Methods that return {Generation} objects for LLM interactions
30
+ # * **Tools**: Ruby methods that can be called by LLMs during generation
31
+ # * **Providers**: Abstraction layer for different LLM services (OpenAI, Anthropic, etc.)
32
+ # * **Streaming**: Real-time response handling via Server-Sent Events
33
+ #
34
+ # @example Creating a simple agent
35
+ # class GreetingAgent < ActiveAgent::Base
36
+ # generate_with :openai
37
+ #
38
+ # def welcome(name:)
39
+ # @name = name
40
+ # end
41
+ # end
42
+ #
43
+ # # app/views/greeting_agent/welcome.md.erb
44
+ # # Hello <%= @name %>! How can I help you today?
45
+ #
46
+ # generation = GreetingAgent.welcome(name: "Alice")
47
+ # response = generation.generate_now
48
+ #
49
+ # @example Using tools
50
+ # class WeatherAgent < ActiveAgent::Base
51
+ # generate_with :anthropic
52
+ #
53
+ # tool def get_weather(location:)
54
+ # # Call weather API
55
+ # { temperature: 72, condition: "sunny" }
56
+ # end
57
+ #
58
+ # def forecast(location:)
59
+ # @location = location
60
+ # end
61
+ # end
62
+ #
63
+ # @example Streaming responses
64
+ # class ChatAgent < ActiveAgent::Base
65
+ # generate_with :openai
66
+ #
67
+ # def chat(message:)
68
+ # @message = message
69
+ # end
70
+ # end
71
+ #
72
+ # ChatAgent.chat(message: "Tell me a story").generate do |stream|
73
+ # stream.on_text_delta { |delta| print delta }
74
+ # stream.on_tool_call { |name, args| puts "Calling #{name}" }
75
+ # end
76
+ #
77
+ # @see ActiveAgent::Base
78
+ # @see ActiveAgent::Configuration
79
+ # @see https://github.com/quiltt/activeagent ActiveAgent on GitHub
16
80
  module ActiveAgent
17
- include ActiveAgent::Sanitizers
18
81
  extend ActiveSupport::Autoload
19
82
 
83
+ # Eager autoload critical components.
84
+ #
85
+ # These components are loaded immediately when {eager_load!} is called,
86
+ # typically during Rails initialization in production environments.
20
87
  eager_autoload do
21
88
  autoload :Collector
22
89
  end
23
90
 
91
+ # Lazy autoload remaining components.
92
+ #
93
+ # These components are loaded on-demand when first referenced.
24
94
  autoload :Base
25
- autoload :Callbacks
26
- autoload :Streaming
95
+ autoload :Callbacks, "active_agent/concerns/callbacks"
96
+ autoload :Streaming, "active_agent/concerns/streaming"
27
97
  autoload :InlinePreviewInterceptor
28
- autoload :PromptHelper
29
98
  autoload :Generation
30
- autoload :GenerationProvider
31
- autoload :QueuedGeneration
32
- autoload :Parameterized
33
- autoload :Preview
34
- autoload :Previews, "active_agent/preview"
99
+ autoload :Queueing, "active_agent/concerns/queueing"
100
+ autoload :Parameterized, "active_agent/concerns/parameterized"
101
+ autoload :Preview, "active_agent/concerns/preview"
102
+ autoload :Previews, "active_agent/concerns/preview"
35
103
  autoload :GenerationJob
104
+ autoload :Observers, "active_agent/concerns/observers"
105
+ autoload :Provider, "active_agent/concerns/provider"
106
+ autoload :Rescue, "active_agent/concerns/rescue"
107
+ autoload :Tooling, "active_agent/concerns/tooling"
108
+ autoload :View, "active_agent/concerns/view"
36
109
 
37
110
  class << self
38
- attr_accessor :config
39
-
111
+ # Eagerly loads all ActiveAgent components and descendant agent classes.
112
+ #
113
+ # This method is called during Rails initialization in production mode
114
+ # to load all code upfront, improving request performance and catching
115
+ # load-time errors early.
116
+ #
117
+ # @return [void]
118
+ #
119
+ # @example Manual eager loading
120
+ # ActiveAgent.eager_load!
121
+ #
122
+ # @note In Rails applications, this is automatically called when
123
+ # +config.eager_load+ is true (default in production).
40
124
  def eager_load!
41
125
  super
42
126
 
@@ -44,31 +128,23 @@ module ActiveAgent
44
128
  agent.eager_load! unless agent.abstract?
45
129
  end
46
130
  end
47
-
48
- # @return [void]
49
- def configure
50
- yield self
51
-
52
- sanitizers_reset!
53
- end
54
-
55
- # @return [void]
56
- def load_configuration(file)
57
- if File.exist?(file)
58
- config_file = YAML.load(ERB.new(File.read(file)).result, aliases: true)
59
- env = ENV["RAILS_ENV"] || ENV["ENV"] || "development"
60
- @config = config_file[env] || config_file
61
- else
62
- @config = {}
63
- end
64
-
65
- sanitizers_reset!
66
- end
67
131
  end
68
132
  end
69
133
 
134
+ # Autoload MIME type support for content type handling.
135
+ #
136
+ # ActiveAgent uses ActionDispatch's MIME type system for handling
137
+ # different content types in prompts and responses.
70
138
  autoload :Mime, "action_dispatch/http/mime_type"
71
139
 
140
+ # Register markdown MIME type for template rendering, Not needed in Rails 8.1
141
+ Mime::Type.register "text/markdown", :md, [], %w[md markdown] unless Mime::Type.lookup_by_extension(:md)
142
+
143
+ # Configure ActionView integration when loaded.
144
+ #
145
+ # Sets up default formats and MIME type implementation for rendering
146
+ # agent prompt templates. This ensures proper content type handling
147
+ # for various template formats (.md.erb, .txt.erb, etc.).
72
148
  ActiveSupport.on_load(:action_view) do
73
149
  ActionView::Base.default_formats ||= Mime::SET.symbols
74
150
  ActionView::Template.mime_types_implementation = Mime
@@ -0,0 +1,78 @@
1
+ Description:
2
+ Generates a new agent and its views. Passes the agent name, either
3
+ CamelCased or under_scored, and an optional list of actions as arguments.
4
+
5
+ This generates an agent class in app/agents and invokes your template
6
+ engine and test framework generators. If no ApplicationAgent exists,
7
+ it will be created automatically.
8
+
9
+ By default, markdown format templates are created. You can specify text
10
+ format using the --format option. Optionally generate JSON schema files
11
+ for actions using the --json-schema flag, or use --json-object for
12
+ JSON object response format without schemas.
13
+
14
+ Options:
15
+ --format=FORMAT Specify format for templates (default: markdown)
16
+ Can be: text, markdown
17
+ Example: --format=text
18
+
19
+ --json-schema Generate JSON schema files for each action
20
+ Creates action_name.json files
21
+ Sets response_format: :json_schema in agent methods
22
+
23
+ --json-object Generate agent methods with JSON object response format
24
+ Sets response_format: :json_object in agent methods
25
+ Does not create schema files
26
+
27
+ Examples:
28
+ `bin/rails generate active_agent:agent inventory search`
29
+
30
+ creates an inventory agent with markdown templates:
31
+ Agent: app/agents/inventory_agent.rb
32
+ Instructions: app/views/inventory_agent/instructions.md
33
+ View: app/views/inventory_agent/search.md.erb
34
+ Test: test/docs/inventory_agent_test.rb
35
+
36
+ `bin/rails generate active_agent:agent inventory search --format=text`
37
+
38
+ creates an inventory agent with text templates:
39
+ Agent: app/agents/inventory_agent.rb
40
+ Instructions: app/views/inventory_agent/instructions.text
41
+ View: app/views/inventory_agent/search.text.erb
42
+ Test: test/docs/inventory_agent_test.rb
43
+
44
+ `bin/rails generate active_agent:agent inventory search --json-schema`
45
+
46
+ creates an inventory agent with markdown templates and JSON schema:
47
+ Agent: app/agents/inventory_agent.rb
48
+ Instructions: app/views/inventory_agent/instructions.md
49
+ View: app/views/inventory_agent/search.md.erb
50
+ Schema: app/views/inventory_agent/search.json
51
+ Test: test/docs/inventory_agent_test.rb
52
+
53
+ `bin/rails generate active_agent:agent inventory search --json-object`
54
+
55
+ creates an inventory agent with JSON object response format:
56
+ Agent: app/agents/inventory_agent.rb
57
+ Instructions: app/views/inventory_agent/instructions.md
58
+ View: app/views/inventory_agent/search.md.erb
59
+ Test: test/docs/inventory_agent_test.rb
60
+
61
+ `bin/rails generate active_agent:agent inventory search update report`
62
+
63
+ creates an inventory agent with multiple actions:
64
+ Agent: app/agents/inventory_agent.rb
65
+ Instructions: app/views/inventory_agent/instructions.md
66
+ Views: app/views/inventory_agent/search.md.erb
67
+ app/views/inventory_agent/update.md.erb
68
+ app/views/inventory_agent/report.md.erb
69
+ Test: test/docs/inventory_agent_test.rb
70
+
71
+ `bin/rails generate active_agent:agent admin/user create --json-schema`
72
+
73
+ creates a namespaced admin/user agent with schema:
74
+ Agent: app/agents/admin/user_agent.rb
75
+ Instructions: app/views/admin/user_agent/instructions.md
76
+ View: app/views/admin/user_agent/create.md.erb
77
+ Schema: app/views/admin/user_agent/create.json
78
+ Test: test/docs/admin/user_agent_test.rb
@@ -3,9 +3,11 @@
3
3
  module ActiveAgent
4
4
  module Generators
5
5
  class AgentGenerator < ::Rails::Generators::NamedBase
6
- source_root File.expand_path("templates", __dir__)
6
+ source_root File.expand_path("../templates", __dir__)
7
7
  argument :actions, type: :array, default: [], banner: "method method"
8
- class_option :formats, type: :array, default: [ "text" ], desc: "Specify formats to generate (text, html, json)"
8
+ class_option :format, type: :string, default: "markdown", desc: "Specify format for templates (text or markdown)"
9
+ class_option :json_schema, type: :boolean, default: false, desc: "Generate JSON schema files for actions"
10
+ class_option :json_object, type: :boolean, default: false, desc: "Generate actions with JSON object response format"
9
11
 
10
12
  check_class_collision suffix: "Agent"
11
13
 
@@ -31,8 +33,16 @@ module ActiveAgent
31
33
 
32
34
  private
33
35
 
34
- def formats
35
- options[:formats].map(&:to_sym)
36
+ def format
37
+ options[:format].to_sym
38
+ end
39
+
40
+ def json_schema?
41
+ options[:json_schema]
42
+ end
43
+
44
+ def json_object?
45
+ options[:json_object]
36
46
  end
37
47
 
38
48
  def file_name # :doc:
@@ -0,0 +1,25 @@
1
+ Description:
2
+ Sets up ActiveAgent in your Rails application by creating the necessary
3
+ configuration files and application agent class.
4
+
5
+ This generator creates:
6
+ - Configuration file (config/active_agent.yml) unless --skip-config is used
7
+ - Application agent base class (app/agents/application_agent.rb)
8
+
9
+ Options:
10
+ --skip-config Skip the creation of config/active_agent.yml
11
+
12
+ Examples:
13
+ `bin/rails generate active_agent:install`
14
+
15
+ creates the basic ActiveAgent setup:
16
+ Config: config/active_agent.yml
17
+ Base Agent: app/agents/application_agent.rb
18
+
19
+ `bin/rails generate active_agent:install --skip-config`
20
+
21
+ creates ActiveAgent setup without configuration file:
22
+ Base Agent: app/agents/application_agent.rb
23
+
24
+ After running this generator, you can create individual agents with:
25
+ `bin/rails generate active_agent:agent AGENT_NAME ACTION_NAME`
@@ -4,20 +4,8 @@ module ActiveAgent
4
4
  module Generators
5
5
  class InstallGenerator < ::Rails::Generators::Base
6
6
  class_option :skip_config, type: :boolean, default: false, desc: "Skip configuration file generation"
7
- class_option :formats, type: :array, default: [ "text" ], desc: "Specify formats to generate (text, html, json)"
8
7
 
9
- def initialize(*args, **kwargs)
10
- super(*args, **kwargs)
11
-
12
- # We must duplicate due to immutable hash
13
- dup_options = options.dup
14
- @options = dup_options.merge(template_engine: :erb)
15
- end
16
-
17
- def self.usage_path
18
- @usage_path ||= File.expand_path("../USAGE", __dir__)
19
- end
20
- source_root File.expand_path("templates", __dir__)
8
+ source_root File.expand_path("../templates", __dir__)
21
9
 
22
10
  def create_configuration
23
11
  template "active_agent.yml", "config/active_agent.yml" unless options[:skip_config]
@@ -31,14 +19,8 @@ module ActiveAgent
31
19
  end
32
20
  end
33
21
 
34
- hook_for :template_engine
35
-
36
22
  private
37
23
 
38
- def formats
39
- options[:formats].map(&:to_sym)
40
- end
41
-
42
24
  def application_agent_file_name
43
25
  "app/agents/application_agent.rb"
44
26
  end
@@ -5,9 +5,13 @@ class <%= class_name %>Agent < ApplicationAgent
5
5
 
6
6
  <% end -%>
7
7
  def <%= action %>
8
- @message = "Cats go.."
9
-
10
- prompt message: @message
8
+ <% if json_schema? -%>
9
+ prompt(params[:message], response_format: :json_schema)
10
+ <% elsif json_object? -%>
11
+ prompt(params[:message], response_format: :json_object)
12
+ <% else -%>
13
+ prompt(params[:message])
14
+ <% end -%>
11
15
  end
12
16
  <% end -%>
13
17
  end
@@ -1,7 +1,5 @@
1
1
  <% module_namespacing do -%>
2
2
  class ApplicationAgent < ActiveAgent::Base
3
- layout "agent"
4
-
5
3
  generate_with :openai, model: "gpt-4o-mini", instructions: "You are a helpful assistant."
6
4
  end
7
5
  <% end %>
@@ -7,7 +7,9 @@ module Erb # :nodoc:
7
7
  class AgentGenerator < Base # :nodoc:
8
8
  source_root File.expand_path("templates", __dir__)
9
9
  argument :actions, type: :array, default: [], banner: "method method"
10
- class_option :formats, type: :array, default: [ "text" ], desc: "Specify formats to generate (text, html, json)"
10
+ class_option :format, type: :string, default: "markdown", desc: "Specify format for templates (text or markdown)"
11
+ class_option :json_schema, type: :boolean, default: false, desc: "Generate JSON schema files for actions"
12
+ class_option :json_object, type: :boolean, default: false, desc: "Generate actions with JSON object response format"
11
13
 
12
14
  def initialize(*args, **kwargs)
13
15
  super(*args, **kwargs)
@@ -18,32 +20,45 @@ module Erb # :nodoc:
18
20
  end
19
21
 
20
22
  def copy_view_files
21
- view_base_path = File.join("app/views", class_path, file_name + "_agent")
23
+ view_base_path = File.join("app/views/agents", class_path, file_name)
22
24
  empty_directory view_base_path
23
25
 
24
- if behavior == :invoke
25
- formats.each do |format|
26
- layout_path = File.join("app/views/layouts", class_path, filename_with_extensions("agent", format))
27
- template filename_with_extensions(:layout, format), layout_path unless File.exist?(layout_path)
28
- end
29
- end
30
-
31
- instructions_path = File.join(view_base_path, "instructions.text.erb")
32
- template "instructions.text.erb.tt", instructions_path
26
+ # Create instructions file with the specified format (no .erb extension)
27
+ file_extension = format == "markdown" ? "md" : format
28
+ instructions_file = "instructions.#{file_extension}"
29
+ instructions_path = File.join(view_base_path, instructions_file)
30
+ template "instructions.#{file_extension}.tt", instructions_path
33
31
 
32
+ # Create action view files
34
33
  actions.each do |action|
35
34
  @action = action
36
35
 
37
- formats.each do |format|
38
- @path = File.join(view_base_path, filename_with_extensions(action, format))
39
- template filename_with_extensions(:view, format), @path
36
+ # Create message file in specified format
37
+ action_file = "#{action}.#{file_extension}.erb"
38
+ action_path = File.join(view_base_path, action_file)
39
+ template "message.#{file_extension}.erb.tt", action_path
40
+
41
+ # Create schema file if requested
42
+ if json_schema?
43
+ schema_file = "#{action}.json"
44
+ schema_path = File.join(view_base_path, schema_file)
45
+ template "schema.json.tt", schema_path
40
46
  end
41
47
  end
42
48
  end
43
49
 
44
50
  private
45
- def formats
46
- options[:formats].map(&:to_sym)
51
+
52
+ def format
53
+ options[:format]
54
+ end
55
+
56
+ def json_schema?
57
+ options[:json_schema]
58
+ end
59
+
60
+ def json_object?
61
+ options[:json_object]
47
62
  end
48
63
 
49
64
  def file_name
@@ -0,0 +1,3 @@
1
+ # Instructions
2
+
3
+ Add your agent instructions here in markdown format.
@@ -0,0 +1,3 @@
1
+ # Instructions
2
+
3
+ Add your agent instructions here in markdown format.
@@ -0,0 +1 @@
1
+ Instructions for an AI agent
@@ -0,0 +1,5 @@
1
+ # <%= class_name %>#<%= @action %>
2
+
3
+ Add your message template here. You can use ERB to access instance variables and params.
4
+
5
+ Example: <%%= @message %>
@@ -0,0 +1,10 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "example_property": {
5
+ "type": "string",
6
+ "description": "Add your property description here"
7
+ }
8
+ },
9
+ "required": ["example_property"]
10
+ }
@@ -17,7 +17,7 @@ module TestUnit # :nodoc:
17
17
  end
18
18
 
19
19
  def create_preview_files
20
- template "preview.rb", File.join("test/agents/previews", class_path, "#{file_name}_agent_preview.rb")
20
+ template "preview.rb", File.join("test/docs/previews", class_path, "#{file_name}_agent_preview.rb")
21
21
  end
22
22
 
23
23
  private
@@ -7,8 +7,10 @@ class <%= class_name %>AgentTest < ActiveAgent::TestCase
7
7
 
8
8
  <% end -%>
9
9
  test "<%= action %>" do
10
- agent = <%= class_name %>Agent.<%= action %>
11
- assert_equal <%= action.to_s.humanize.inspect %>, agent.prompt_context
10
+ generation = <%= class_name %>Agent.<%= action %>
11
+ assert_not_nil generation
12
+ # Test the generation by calling generate_now if needed
13
+ # response = generation.generate_now
12
14
  end
13
15
  <% end -%>
14
16
  <% if actions.blank? -%>