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
@@ -0,0 +1,264 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "content/_types"
4
+
5
+ require_relative "base"
6
+ require_relative "tool_call_base"
7
+ require_relative "input_message"
8
+ require_relative "output_message"
9
+ require_relative "user_message"
10
+ require_relative "system_message"
11
+ require_relative "developer_message"
12
+ require_relative "assistant_message"
13
+ require_relative "tool_message"
14
+ require_relative "function_call_output"
15
+ require_relative "item_reference"
16
+ require_relative "reasoning"
17
+
18
+ # Tool call types
19
+ require_relative "file_search_tool_call"
20
+ require_relative "computer_tool_call"
21
+ require_relative "computer_tool_call_output"
22
+ require_relative "web_search_tool_call"
23
+ require_relative "function_tool_call"
24
+ require_relative "image_gen_tool_call"
25
+ require_relative "code_interpreter_tool_call"
26
+ require_relative "local_shell_tool_call"
27
+ require_relative "local_shell_tool_call_output"
28
+ require_relative "custom_tool_call"
29
+ require_relative "custom_tool_call_output"
30
+
31
+ # MCP types
32
+ require_relative "mcp_list_tools"
33
+ require_relative "mcp_approval_request"
34
+ require_relative "mcp_approval_response"
35
+ require_relative "mcp_tool_call"
36
+
37
+ module ActiveAgent
38
+ module Providers
39
+ module OpenAI
40
+ module Responses
41
+ module Requests
42
+ module Inputs
43
+ # Type for handling items (array of items - full Item types)
44
+ class ItemsType < ActiveModel::Type::Value
45
+ def initialize
46
+ super
47
+ @item_type = ItemType.new
48
+ end
49
+
50
+ def cast(value)
51
+ case value
52
+ when String
53
+ # Plain text string becomes array with single user message
54
+ [ UserMessage.new(text: value) ]
55
+ when Array
56
+ value.map { |item| @item_type.cast(item) }
57
+ when Hash
58
+ # Single hash becomes array with one item
59
+ [ @item_type.cast(value) ]
60
+ when nil
61
+ nil
62
+ else
63
+ raise ArgumentError, "Cannot cast #{value.class} to Items (expected String, Array, Hash, or nil)"
64
+ end
65
+ end
66
+
67
+ def serialize(value)
68
+ case value
69
+ when String
70
+ value
71
+ when Array
72
+ value.map { |v| @item_type.serialize(v) }
73
+ when Hash
74
+ @item_type.serialize(value)
75
+ when nil
76
+ nil
77
+ else
78
+ raise ArgumentError, "Cannot serialize #{value.class}"
79
+ end
80
+ end
81
+
82
+ def deserialize(value)
83
+ cast(value)
84
+ end
85
+ end
86
+
87
+ # Type for handling individual items (messages, tool calls, reasoning, etc.)
88
+ class ItemType < ActiveModel::Type::Value
89
+ def initialize
90
+ super
91
+ @content_type = Content::ContentType.new
92
+ end
93
+
94
+ def cast(value)
95
+ case value
96
+ when ::OpenAI::Internal::Type::BaseModel
97
+ cast(value.to_h)
98
+ when Base
99
+ value
100
+ when String
101
+ # Plain text string becomes user message
102
+ UserMessage.new(text: value)
103
+ when Hash
104
+ hash = value.deep_symbolize_keys
105
+ type = hash[:type]&.to_sym
106
+
107
+ case type
108
+ # Message types
109
+ when :message, nil
110
+ cast_message(hash)
111
+ # Tool call types
112
+ when :file_search_call
113
+ FileSearchToolCall.new(**hash)
114
+ when :computer_call
115
+ ComputerToolCall.new(**hash)
116
+ when :computer_call_output
117
+ ComputerToolCallOutput.new(**hash)
118
+ when :web_search_call
119
+ WebSearchToolCall.new(**hash)
120
+ when :function_call
121
+ FunctionToolCall.new(**hash)
122
+ when :function_call_output
123
+ FunctionCallOutput.new(**hash)
124
+ when :image_generation_call
125
+ ImageGenToolCall.new(**hash)
126
+ when :code_interpreter_call
127
+ CodeInterpreterToolCall.new(**hash)
128
+ when :local_shell_call
129
+ LocalShellToolCall.new(**hash)
130
+ when :local_shell_call_output
131
+ LocalShellToolCallOutput.new(**hash)
132
+ when :custom_tool_call
133
+ CustomToolCall.new(**hash)
134
+ when :custom_tool_call_output
135
+ CustomToolCallOutput.new(**hash)
136
+ # MCP types
137
+ when :mcp_list_tools
138
+ MCPListTools.new(**hash)
139
+ when :mcp_approval_request
140
+ MCPApprovalRequest.new(**hash)
141
+ when :mcp_approval_response
142
+ MCPApprovalResponse.new(**hash)
143
+ when :mcp_call
144
+ MCPToolCall.new(**hash)
145
+ # Other types
146
+ when :reasoning
147
+ Reasoning.new(**hash)
148
+ when :item_reference
149
+ ItemReference.new(**hash)
150
+ else
151
+ raise ArgumentError, "Unknown item type: #{type.inspect}"
152
+ end
153
+ when nil
154
+ nil
155
+ else
156
+ raise ArgumentError, "Cannot cast #{value.class} to Item (expected Base, Hash, String, or nil)"
157
+ end
158
+ end
159
+
160
+ def serialize(value)
161
+ case value
162
+ when Base
163
+ hash = value.serialize
164
+
165
+ if hash[:content] in [ { type: "input_text", text: String } ]
166
+ hash[:content] = hash[:content].first[:text]
167
+ end
168
+
169
+ hash
170
+ when Hash
171
+ value
172
+ when nil
173
+ nil
174
+ else
175
+ raise ArgumentError, "Cannot serialize #{value.class} as Item"
176
+ end
177
+ end
178
+
179
+ def deserialize(value)
180
+ cast(value)
181
+ end
182
+
183
+ private
184
+
185
+ def cast_message(hash)
186
+ role = hash[:role]&.to_sym
187
+
188
+ case role
189
+ when :system
190
+ SystemMessage.new(**hash)
191
+ when :developer
192
+ DeveloperMessage.new(**hash)
193
+ when :user, nil
194
+ UserMessage.new(**hash)
195
+ when :assistant
196
+ AssistantMessage.new(**hash)
197
+ when :tool
198
+ ToolMessage.new(**hash)
199
+ else
200
+ raise ArgumentError, "Unknown message role: #{role.inspect}"
201
+ end
202
+ end
203
+ end
204
+
205
+ # Type for handling messages (array of messages) - kept for backwards compatibility
206
+ class MessagesType < ActiveModel::Type::Value
207
+ def initialize
208
+ super
209
+ @item_type = ItemType.new
210
+ end
211
+
212
+ def cast(value)
213
+ case value
214
+ when String
215
+ value
216
+ when Array
217
+ value.map { |item| @item_type.cast(item) }
218
+ when Hash
219
+ # Single hash becomes array with one message
220
+ [ @item_type.cast(value) ]
221
+ when nil
222
+ nil
223
+ else
224
+ raise ArgumentError, "Cannot cast #{value.class} to Input (expected String, Array, or Hash)"
225
+ end
226
+ end
227
+
228
+ def serialize(value)
229
+ case value
230
+ when String
231
+ value
232
+ when Array
233
+ grouped = []
234
+
235
+ value.each do |message|
236
+ if grouped.empty?
237
+ grouped << message.deep_dup
238
+ elsif grouped.last.role == message.role && grouped.last.type == message.type
239
+ grouped.last.content += message.content.deep_dup
240
+ else
241
+ grouped << message.deep_dup
242
+ end
243
+ end
244
+
245
+ grouped.map { |v| @item_type.serialize(v) }
246
+ when Hash
247
+ @item_type.serialize(value)
248
+ when nil
249
+ nil
250
+ else
251
+ raise ArgumentError, "Cannot serialize #{value.class}"
252
+ end
253
+ end
254
+
255
+ def deserialize(value)
256
+ cast(value)
257
+ end
258
+ end
259
+ end
260
+ end
261
+ end
262
+ end
263
+ end
264
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "output_message"
4
+
5
+ module ActiveAgent
6
+ module Providers
7
+ module OpenAI
8
+ module Responses
9
+ module Requests
10
+ module Inputs
11
+ # Assistant message output for OpenAI Responses API.
12
+ #
13
+ # Represents an assistant message in the conversation history.
14
+ class AssistantMessage < OutputMessage
15
+ attribute :role, :string, as: "assistant"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_agent/providers/common/model"
4
+ require_relative "content/_types"
5
+
6
+ module ActiveAgent
7
+ module Providers
8
+ module OpenAI
9
+ module Responses
10
+ module Requests
11
+ module Inputs
12
+ # Base class for input items in Responses API
13
+ class Base < Common::BaseModel
14
+ attribute :role, :string
15
+ attribute :content, Content::ContentsType.new
16
+
17
+ validates :role, inclusion: {
18
+ in: %w[system user assistant developer tool],
19
+ allow_nil: true
20
+ }
21
+
22
+ # Define content setter methods for different content types
23
+ %i[text image document].each do |content_type|
24
+ define_method(:"#{content_type}=") do |value|
25
+ self.content ||= []
26
+ self.content += [ { content_type => value } ]
27
+ end
28
+ end
29
+
30
+ # Converts to common format.
31
+ #
32
+ # @return [Hash] message in canonical format
33
+ def to_common
34
+ {
35
+ role: map_role_to_common,
36
+ content: extract_text_content,
37
+ name: respond_to?(:name) ? name : nil,
38
+ tool_call_id: respond_to?(:tool_call_id) ? tool_call_id : nil
39
+ }.compact
40
+ end
41
+
42
+ private
43
+
44
+ # Maps OpenAI roles to canonical roles.
45
+ #
46
+ # @return [String] canonical role name
47
+ def map_role_to_common
48
+ case role
49
+ when "developer", "system"
50
+ "system"
51
+ when "user"
52
+ "user"
53
+ when "assistant"
54
+ "assistant"
55
+ when "tool", "function"
56
+ "tool"
57
+ else
58
+ role
59
+ end
60
+ end
61
+
62
+ # Extracts text content from OpenAI's content structure.
63
+ #
64
+ # @return [String, nil] extracted text content
65
+ def extract_text_content
66
+ return nil unless respond_to?(:content)
67
+
68
+ case content
69
+ when String
70
+ content
71
+ when Array
72
+ # For Responses API, content is an array of content objects (InputText, etc.)
73
+ content.select { |part| part.respond_to?(:text) }
74
+ .map(&:text)
75
+ .compact
76
+ .join("\n")
77
+ when nil
78
+ nil
79
+ else
80
+ content.to_s
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "tool_call_base"
4
+
5
+ module ActiveAgent
6
+ module Providers
7
+ module OpenAI
8
+ module Responses
9
+ module Requests
10
+ module Inputs
11
+ # Code interpreter tool call - runs Python code
12
+ class CodeInterpreterToolCall < ToolCallBase
13
+ attribute :type, :string, as: "code_interpreter_call"
14
+ attribute :container_id, :string
15
+ attribute :code, :string # Can be null
16
+ attribute :outputs # Always an array of output objects, can be empty
17
+
18
+ validates :type, inclusion: { in: %w[code_interpreter_call], allow_nil: false }
19
+ validates :container_id, presence: true
20
+ validates :status, inclusion: {
21
+ in: %w[in_progress completed incomplete interpreting failed],
22
+ allow_nil: false
23
+ }
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "tool_call_base"
4
+
5
+ module ActiveAgent
6
+ module Providers
7
+ module OpenAI
8
+ module Responses
9
+ module Requests
10
+ module Inputs
11
+ # Computer tool call - computer use tool
12
+ class ComputerToolCall < ToolCallBase
13
+ attribute :type, :string, as: "computer_call"
14
+ attribute :call_id, :string
15
+ attribute :action # ComputerAction object
16
+ attribute :pending_safety_checks # Always an array of safety check objects
17
+
18
+ validates :type, inclusion: { in: %w[computer_call], allow_nil: false }
19
+ validates :call_id, presence: true
20
+ validates :action, presence: true
21
+ validates :pending_safety_checks, presence: true
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module ActiveAgent
6
+ module Providers
7
+ module OpenAI
8
+ module Responses
9
+ module Requests
10
+ module Inputs
11
+ # Computer tool call output
12
+ class ComputerToolCallOutput < Base
13
+ attribute :type, :string, as: "computer_call_output"
14
+ attribute :id, :string
15
+ attribute :call_id, :string
16
+ attribute :acknowledged_safety_checks # Always an array of safety check objects
17
+ attribute :output # ComputerScreenshotImage object
18
+ attribute :status, :string
19
+
20
+ validates :type, inclusion: { in: %w[computer_call_output], allow_nil: false }
21
+ validates :call_id, presence: true
22
+ validates :output, presence: true
23
+ validates :status, inclusion: {
24
+ in: %w[in_progress completed incomplete],
25
+ allow_nil: true
26
+ }
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,207 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+ require_relative "input_audio"
5
+ require_relative "input_file"
6
+ require_relative "input_image"
7
+ require_relative "input_text"
8
+
9
+ module ActiveAgent
10
+ module Providers
11
+ module OpenAI
12
+ module Responses
13
+ module Requests
14
+ module Inputs
15
+ module Content
16
+ # Type for handling content (string or array of content parts)
17
+ class ContentsType < ActiveModel::Type::Value
18
+ def initialize
19
+ super
20
+ @content_type = ContentType.new
21
+ end
22
+
23
+ def cast(value)
24
+ case value
25
+ when String
26
+ # Plain text string - keep as string
27
+ value
28
+ when Array
29
+ # Array of content parts - cast each part
30
+ value.map { |part| @content_type.cast(part) }
31
+ when nil
32
+ nil
33
+ else
34
+ raise ArgumentError, "Cannot cast #{value.class} to Contents (expected String, Array, or nil)"
35
+ end
36
+ end
37
+
38
+ def serialize(value)
39
+ case value
40
+ when String
41
+ value
42
+ when Array
43
+ value.map { |part| @content_type.serialize(part) }
44
+ when nil
45
+ nil
46
+ else
47
+ raise ArgumentError, "Cannot serialize #{value.class} as Contents"
48
+ end
49
+ end
50
+
51
+ def deserialize(value)
52
+ cast(value)
53
+ end
54
+ end
55
+
56
+ # Type for individual content items
57
+ class ContentType < ActiveModel::Type::Value
58
+ def cast(value)
59
+ case value
60
+ when Base
61
+ value
62
+ when Hash
63
+ hash = value.deep_symbolize_keys
64
+ type = hash[:type]&.to_sym
65
+
66
+ case type
67
+ when :input_text, :output_text
68
+ InputText.new(**hash.except(:annotations, :logprobs, :type))
69
+ when :input_image
70
+ InputImage.new(**hash)
71
+ when :input_file
72
+ InputFile.new(**hash)
73
+ when nil
74
+ # When type is nil, check for specific content keys to infer type
75
+ if hash.key?(:text)
76
+ InputText.new(**hash)
77
+ elsif hash.key?(:image)
78
+ InputImage.new(**hash.merge(image_url: hash.delete(:image)))
79
+ elsif hash.key?(:document)
80
+ cast_document_to_file(hash)
81
+ else
82
+ raise ArgumentError, "Cannot determine content type from hash keys: #{hash.keys.inspect}"
83
+ end
84
+ else
85
+ raise ArgumentError, "Unknown content type: #{type.inspect}"
86
+ end
87
+ when String
88
+ # Plain text string becomes input_text
89
+ InputText.new(text: value)
90
+ when nil
91
+ nil
92
+ else
93
+ raise ArgumentError, "Cannot cast #{value.class} to Content (expected Base, Hash, String, or nil)"
94
+ end
95
+ end
96
+
97
+ def serialize(value)
98
+ case value
99
+ when Base
100
+ value.serialize
101
+ when Hash
102
+ value
103
+ when String
104
+ { type: "input_text", text: value }
105
+ when nil
106
+ nil
107
+ else
108
+ raise ArgumentError, "Cannot serialize #{value.class} as Content"
109
+ end
110
+ end
111
+
112
+ def deserialize(value)
113
+ cast(value)
114
+ end
115
+
116
+ private
117
+
118
+ def cast_document_to_file(hash)
119
+ document_value = hash.delete(:document)
120
+
121
+ case document_value
122
+ when String
123
+ if uri?(document_value)
124
+ # It's a URI/URL (http/https)
125
+ InputFile.new(**hash.merge(file_url: document_value))
126
+ elsif data_uri?(document_value)
127
+ # It's a data URI (e.g., data:application/pdf;base64,...)
128
+ # NOTE: While the OpenAI docs say filename is optional, it is required with base64 format
129
+ media_type, _data = parse_data_uri(document_value)
130
+ filename = generate_filename_from_media_type(media_type)
131
+ InputFile.new(**hash.merge(file_data: document_value, filename: filename))
132
+ else
133
+ raise ArgumentError, "Cannot determine source type for document value: #{document_value.inspect}"
134
+ end
135
+ else
136
+ raise ArgumentError, "Expected String for document key, got #{document_value.class}"
137
+ end
138
+ end
139
+
140
+ def uri?(value)
141
+ # Check if it looks like a URI (http://, https://, etc.)
142
+ value.match?(%r{\A(https?)://}i)
143
+ end
144
+
145
+ def data_uri?(value)
146
+ # Check if it's a data URI (data:...)
147
+ value.match?(/\Adata:/i)
148
+ end
149
+
150
+ def parse_data_uri(data_uri)
151
+ # Parse data URI format: data:mime/type;base64,encoded_data
152
+ match = data_uri.match(/\Adata:([^;,]+)(;base64)?,(.+)\z/i)
153
+ raise ArgumentError, "Invalid data URI format: #{data_uri[0..50]}..." unless match
154
+
155
+ media_type = match[1]
156
+ is_base64 = !match[2].nil?
157
+ data = match[3]
158
+
159
+ unless is_base64
160
+ raise ArgumentError, "Only base64-encoded data URIs are supported: #{data_uri[0..50]}..."
161
+ end
162
+
163
+ [ media_type, data ]
164
+ end
165
+
166
+ def generate_filename_from_media_type(media_type)
167
+ # Map common media types to file extensions
168
+ extension = case media_type
169
+ when "application/pdf"
170
+ "pdf"
171
+ when "application/msword"
172
+ "doc"
173
+ when "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
174
+ "docx"
175
+ when "application/vnd.ms-excel"
176
+ "xls"
177
+ when "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
178
+ "xlsx"
179
+ when "application/vnd.ms-powerpoint"
180
+ "ppt"
181
+ when "application/vnd.openxmlformats-officedocument.presentationml.presentation"
182
+ "pptx"
183
+ when "text/plain"
184
+ "txt"
185
+ when "text/csv"
186
+ "csv"
187
+ when "text/html"
188
+ "html"
189
+ when "application/json"
190
+ "json"
191
+ when "application/xml", "text/xml"
192
+ "xml"
193
+ else
194
+ # Try to extract extension from media type (e.g., "application/xyz" -> "xyz")
195
+ media_type.split("/").last.split("+").first
196
+ end
197
+
198
+ "document.#{extension}"
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_agent/providers/common/model"
4
+
5
+ module ActiveAgent
6
+ module Providers
7
+ module OpenAI
8
+ module Responses
9
+ module Requests
10
+ module Inputs
11
+ module Content
12
+ # Base class for content parts
13
+ class Base < Common::BaseModel
14
+ attribute :type, :string
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end