ruby_llm-agents 0.4.0 → 1.0.0.beta.1

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 (208) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +225 -34
  3. data/app/controllers/ruby_llm/agents/agents_controller.rb +136 -16
  4. data/app/controllers/ruby_llm/agents/api_configurations_controller.rb +214 -0
  5. data/app/controllers/ruby_llm/agents/dashboard_controller.rb +29 -9
  6. data/app/controllers/ruby_llm/agents/{settings_controller.rb → system_config_controller.rb} +3 -3
  7. data/app/controllers/ruby_llm/agents/tenants_controller.rb +109 -0
  8. data/app/controllers/ruby_llm/agents/workflows_controller.rb +355 -0
  9. data/app/helpers/ruby_llm/agents/application_helper.rb +25 -0
  10. data/app/models/ruby_llm/agents/api_configuration.rb +386 -0
  11. data/app/models/ruby_llm/agents/execution.rb +3 -0
  12. data/app/models/ruby_llm/agents/tenant_budget.rb +112 -14
  13. data/app/services/ruby_llm/agents/agent_registry.rb +51 -12
  14. data/app/views/layouts/ruby_llm/agents/application.html.erb +5 -30
  15. data/app/views/ruby_llm/agents/agents/_agent.html.erb +13 -1
  16. data/app/views/ruby_llm/agents/agents/_config_agent.html.erb +235 -0
  17. data/app/views/ruby_llm/agents/agents/_config_embedder.html.erb +70 -0
  18. data/app/views/ruby_llm/agents/agents/_config_image_generator.html.erb +152 -0
  19. data/app/views/ruby_llm/agents/agents/_config_moderator.html.erb +63 -0
  20. data/app/views/ruby_llm/agents/agents/_config_speaker.html.erb +108 -0
  21. data/app/views/ruby_llm/agents/agents/_config_transcriber.html.erb +91 -0
  22. data/app/views/ruby_llm/agents/agents/_workflow.html.erb +1 -1
  23. data/app/views/ruby_llm/agents/agents/index.html.erb +74 -9
  24. data/app/views/ruby_llm/agents/agents/show.html.erb +18 -378
  25. data/app/views/ruby_llm/agents/api_configurations/_api_key_field.html.erb +34 -0
  26. data/app/views/ruby_llm/agents/api_configurations/_form.html.erb +288 -0
  27. data/app/views/ruby_llm/agents/api_configurations/edit.html.erb +95 -0
  28. data/app/views/ruby_llm/agents/api_configurations/edit_tenant.html.erb +97 -0
  29. data/app/views/ruby_llm/agents/api_configurations/show.html.erb +211 -0
  30. data/app/views/ruby_llm/agents/api_configurations/tenant.html.erb +179 -0
  31. data/app/views/ruby_llm/agents/dashboard/_action_center.html.erb +1 -1
  32. data/app/views/ruby_llm/agents/dashboard/_agent_comparison.html.erb +269 -15
  33. data/app/views/ruby_llm/agents/executions/show.html.erb +98 -0
  34. data/app/views/ruby_llm/agents/shared/_agent_type_badge.html.erb +93 -0
  35. data/app/views/ruby_llm/agents/{settings → system_config}/show.html.erb +1 -1
  36. data/app/views/ruby_llm/agents/tenants/_form.html.erb +150 -0
  37. data/app/views/ruby_llm/agents/tenants/edit.html.erb +13 -0
  38. data/app/views/ruby_llm/agents/tenants/index.html.erb +129 -0
  39. data/app/views/ruby_llm/agents/tenants/show.html.erb +374 -0
  40. data/app/views/ruby_llm/agents/workflows/_step_performance.html.erb +236 -0
  41. data/app/views/ruby_llm/agents/workflows/_structure_parallel.html.erb +76 -0
  42. data/app/views/ruby_llm/agents/workflows/_structure_pipeline.html.erb +74 -0
  43. data/app/views/ruby_llm/agents/workflows/_structure_router.html.erb +108 -0
  44. data/app/views/ruby_llm/agents/workflows/show.html.erb +442 -0
  45. data/config/routes.rb +13 -1
  46. data/lib/generators/ruby_llm_agents/agent_generator.rb +56 -7
  47. data/lib/generators/ruby_llm_agents/api_configuration_generator.rb +100 -0
  48. data/lib/generators/ruby_llm_agents/background_remover_generator.rb +110 -0
  49. data/lib/generators/ruby_llm_agents/embedder_generator.rb +107 -0
  50. data/lib/generators/ruby_llm_agents/image_analyzer_generator.rb +115 -0
  51. data/lib/generators/ruby_llm_agents/image_editor_generator.rb +108 -0
  52. data/lib/generators/ruby_llm_agents/image_generator_generator.rb +116 -0
  53. data/lib/generators/ruby_llm_agents/image_pipeline_generator.rb +178 -0
  54. data/lib/generators/ruby_llm_agents/image_transformer_generator.rb +109 -0
  55. data/lib/generators/ruby_llm_agents/image_upscaler_generator.rb +103 -0
  56. data/lib/generators/ruby_llm_agents/image_variator_generator.rb +102 -0
  57. data/lib/generators/ruby_llm_agents/install_generator.rb +76 -4
  58. data/lib/generators/ruby_llm_agents/restructure_generator.rb +292 -0
  59. data/lib/generators/ruby_llm_agents/speaker_generator.rb +121 -0
  60. data/lib/generators/ruby_llm_agents/templates/add_execution_type_migration.rb.tt +8 -0
  61. data/lib/generators/ruby_llm_agents/templates/agent.rb.tt +99 -84
  62. data/lib/generators/ruby_llm_agents/templates/application_agent.rb.tt +42 -40
  63. data/lib/generators/ruby_llm_agents/templates/application_background_remover.rb.tt +26 -0
  64. data/lib/generators/ruby_llm_agents/templates/application_embedder.rb.tt +50 -0
  65. data/lib/generators/ruby_llm_agents/templates/application_image_analyzer.rb.tt +26 -0
  66. data/lib/generators/ruby_llm_agents/templates/application_image_editor.rb.tt +20 -0
  67. data/lib/generators/ruby_llm_agents/templates/application_image_generator.rb.tt +38 -0
  68. data/lib/generators/ruby_llm_agents/templates/application_image_pipeline.rb.tt +139 -0
  69. data/lib/generators/ruby_llm_agents/templates/application_image_transformer.rb.tt +21 -0
  70. data/lib/generators/ruby_llm_agents/templates/application_image_upscaler.rb.tt +20 -0
  71. data/lib/generators/ruby_llm_agents/templates/application_image_variator.rb.tt +20 -0
  72. data/lib/generators/ruby_llm_agents/templates/application_speaker.rb.tt +49 -0
  73. data/lib/generators/ruby_llm_agents/templates/application_transcriber.rb.tt +53 -0
  74. data/lib/generators/ruby_llm_agents/templates/background_remover.rb.tt +44 -0
  75. data/lib/generators/ruby_llm_agents/templates/create_api_configurations_migration.rb.tt +90 -0
  76. data/lib/generators/ruby_llm_agents/templates/embedder.rb.tt +41 -0
  77. data/lib/generators/ruby_llm_agents/templates/image_analyzer.rb.tt +45 -0
  78. data/lib/generators/ruby_llm_agents/templates/image_editor.rb.tt +35 -0
  79. data/lib/generators/ruby_llm_agents/templates/image_generator.rb.tt +47 -0
  80. data/lib/generators/ruby_llm_agents/templates/image_pipeline.rb.tt +50 -0
  81. data/lib/generators/ruby_llm_agents/templates/image_transformer.rb.tt +44 -0
  82. data/lib/generators/ruby_llm_agents/templates/image_upscaler.rb.tt +38 -0
  83. data/lib/generators/ruby_llm_agents/templates/image_variator.rb.tt +33 -0
  84. data/lib/generators/ruby_llm_agents/templates/skills/AGENTS.md.tt +228 -0
  85. data/lib/generators/ruby_llm_agents/templates/skills/BACKGROUND_REMOVERS.md.tt +131 -0
  86. data/lib/generators/ruby_llm_agents/templates/skills/EMBEDDERS.md.tt +255 -0
  87. data/lib/generators/ruby_llm_agents/templates/skills/IMAGE_ANALYZERS.md.tt +120 -0
  88. data/lib/generators/ruby_llm_agents/templates/skills/IMAGE_EDITORS.md.tt +102 -0
  89. data/lib/generators/ruby_llm_agents/templates/skills/IMAGE_GENERATORS.md.tt +282 -0
  90. data/lib/generators/ruby_llm_agents/templates/skills/IMAGE_PIPELINES.md.tt +228 -0
  91. data/lib/generators/ruby_llm_agents/templates/skills/IMAGE_TRANSFORMERS.md.tt +120 -0
  92. data/lib/generators/ruby_llm_agents/templates/skills/IMAGE_UPSCALERS.md.tt +110 -0
  93. data/lib/generators/ruby_llm_agents/templates/skills/IMAGE_VARIATORS.md.tt +120 -0
  94. data/lib/generators/ruby_llm_agents/templates/skills/SPEAKERS.md.tt +212 -0
  95. data/lib/generators/ruby_llm_agents/templates/skills/TOOLS.md.tt +227 -0
  96. data/lib/generators/ruby_llm_agents/templates/skills/TRANSCRIBERS.md.tt +251 -0
  97. data/lib/generators/ruby_llm_agents/templates/skills/WORKFLOWS.md.tt +300 -0
  98. data/lib/generators/ruby_llm_agents/templates/speaker.rb.tt +56 -0
  99. data/lib/generators/ruby_llm_agents/templates/transcriber.rb.tt +51 -0
  100. data/lib/generators/ruby_llm_agents/transcriber_generator.rb +107 -0
  101. data/lib/generators/ruby_llm_agents/upgrade_generator.rb +152 -1
  102. data/lib/ruby_llm/agents/audio/speaker.rb +553 -0
  103. data/lib/ruby_llm/agents/audio/transcriber.rb +669 -0
  104. data/lib/ruby_llm/agents/base_agent.rb +675 -0
  105. data/lib/ruby_llm/agents/core/base/moderation_dsl.rb +181 -0
  106. data/lib/ruby_llm/agents/core/base/moderation_execution.rb +274 -0
  107. data/lib/ruby_llm/agents/core/base.rb +135 -0
  108. data/lib/ruby_llm/agents/core/configuration.rb +981 -0
  109. data/lib/ruby_llm/agents/core/errors.rb +150 -0
  110. data/lib/ruby_llm/agents/{instrumentation.rb → core/instrumentation.rb} +93 -4
  111. data/lib/ruby_llm/agents/core/llm_tenant.rb +358 -0
  112. data/lib/ruby_llm/agents/core/resolved_config.rb +348 -0
  113. data/lib/ruby_llm/agents/{version.rb → core/version.rb} +1 -1
  114. data/lib/ruby_llm/agents/dsl/base.rb +110 -0
  115. data/lib/ruby_llm/agents/dsl/caching.rb +142 -0
  116. data/lib/ruby_llm/agents/dsl/reliability.rb +307 -0
  117. data/lib/ruby_llm/agents/dsl.rb +41 -0
  118. data/lib/ruby_llm/agents/image/analyzer/dsl.rb +130 -0
  119. data/lib/ruby_llm/agents/image/analyzer/execution.rb +402 -0
  120. data/lib/ruby_llm/agents/image/analyzer.rb +90 -0
  121. data/lib/ruby_llm/agents/image/background_remover/dsl.rb +154 -0
  122. data/lib/ruby_llm/agents/image/background_remover/execution.rb +240 -0
  123. data/lib/ruby_llm/agents/image/background_remover.rb +89 -0
  124. data/lib/ruby_llm/agents/image/concerns/image_operation_dsl.rb +91 -0
  125. data/lib/ruby_llm/agents/image/concerns/image_operation_execution.rb +165 -0
  126. data/lib/ruby_llm/agents/image/editor/dsl.rb +56 -0
  127. data/lib/ruby_llm/agents/image/editor/execution.rb +207 -0
  128. data/lib/ruby_llm/agents/image/editor.rb +92 -0
  129. data/lib/ruby_llm/agents/image/generator/active_storage_support.rb +127 -0
  130. data/lib/ruby_llm/agents/image/generator/content_policy.rb +95 -0
  131. data/lib/ruby_llm/agents/image/generator/pricing.rb +353 -0
  132. data/lib/ruby_llm/agents/image/generator/templates.rb +124 -0
  133. data/lib/ruby_llm/agents/image/generator.rb +455 -0
  134. data/lib/ruby_llm/agents/image/pipeline/dsl.rb +213 -0
  135. data/lib/ruby_llm/agents/image/pipeline/execution.rb +382 -0
  136. data/lib/ruby_llm/agents/image/pipeline.rb +97 -0
  137. data/lib/ruby_llm/agents/image/transformer/dsl.rb +148 -0
  138. data/lib/ruby_llm/agents/image/transformer/execution.rb +223 -0
  139. data/lib/ruby_llm/agents/image/transformer.rb +95 -0
  140. data/lib/ruby_llm/agents/image/upscaler/dsl.rb +83 -0
  141. data/lib/ruby_llm/agents/image/upscaler/execution.rb +219 -0
  142. data/lib/ruby_llm/agents/image/upscaler.rb +81 -0
  143. data/lib/ruby_llm/agents/image/variator/dsl.rb +62 -0
  144. data/lib/ruby_llm/agents/image/variator/execution.rb +189 -0
  145. data/lib/ruby_llm/agents/image/variator.rb +80 -0
  146. data/lib/ruby_llm/agents/{alert_manager.rb → infrastructure/alert_manager.rb} +17 -22
  147. data/lib/ruby_llm/agents/infrastructure/budget/budget_query.rb +145 -0
  148. data/lib/ruby_llm/agents/infrastructure/budget/config_resolver.rb +149 -0
  149. data/lib/ruby_llm/agents/infrastructure/budget/forecaster.rb +68 -0
  150. data/lib/ruby_llm/agents/infrastructure/budget/spend_recorder.rb +279 -0
  151. data/lib/ruby_llm/agents/infrastructure/budget_tracker.rb +275 -0
  152. data/lib/ruby_llm/agents/{execution_logger_job.rb → infrastructure/execution_logger_job.rb} +17 -1
  153. data/lib/ruby_llm/agents/{reliability → infrastructure/reliability}/executor.rb +2 -1
  154. data/lib/ruby_llm/agents/{reliability → infrastructure/reliability}/retry_strategy.rb +9 -3
  155. data/lib/ruby_llm/agents/{reliability.rb → infrastructure/reliability.rb} +11 -21
  156. data/lib/ruby_llm/agents/pipeline/builder.rb +215 -0
  157. data/lib/ruby_llm/agents/pipeline/context.rb +255 -0
  158. data/lib/ruby_llm/agents/pipeline/executor.rb +86 -0
  159. data/lib/ruby_llm/agents/pipeline/middleware/base.rb +124 -0
  160. data/lib/ruby_llm/agents/pipeline/middleware/budget.rb +95 -0
  161. data/lib/ruby_llm/agents/pipeline/middleware/cache.rb +171 -0
  162. data/lib/ruby_llm/agents/pipeline/middleware/instrumentation.rb +415 -0
  163. data/lib/ruby_llm/agents/pipeline/middleware/reliability.rb +276 -0
  164. data/lib/ruby_llm/agents/pipeline/middleware/tenant.rb +196 -0
  165. data/lib/ruby_llm/agents/pipeline.rb +68 -0
  166. data/lib/ruby_llm/agents/{engine.rb → rails/engine.rb} +79 -10
  167. data/lib/ruby_llm/agents/results/background_removal_result.rb +286 -0
  168. data/lib/ruby_llm/agents/{result.rb → results/base.rb} +73 -1
  169. data/lib/ruby_llm/agents/results/embedding_result.rb +243 -0
  170. data/lib/ruby_llm/agents/results/image_analysis_result.rb +314 -0
  171. data/lib/ruby_llm/agents/results/image_edit_result.rb +250 -0
  172. data/lib/ruby_llm/agents/results/image_generation_result.rb +346 -0
  173. data/lib/ruby_llm/agents/results/image_pipeline_result.rb +399 -0
  174. data/lib/ruby_llm/agents/results/image_transform_result.rb +251 -0
  175. data/lib/ruby_llm/agents/results/image_upscale_result.rb +255 -0
  176. data/lib/ruby_llm/agents/results/image_variation_result.rb +237 -0
  177. data/lib/ruby_llm/agents/results/moderation_result.rb +158 -0
  178. data/lib/ruby_llm/agents/results/speech_result.rb +338 -0
  179. data/lib/ruby_llm/agents/results/transcription_result.rb +408 -0
  180. data/lib/ruby_llm/agents/text/embedder.rb +444 -0
  181. data/lib/ruby_llm/agents/text/moderator.rb +237 -0
  182. data/lib/ruby_llm/agents/workflow/async.rb +220 -0
  183. data/lib/ruby_llm/agents/workflow/async_executor.rb +156 -0
  184. data/lib/ruby_llm/agents/{workflow.rb → workflow/orchestrator.rb} +6 -5
  185. data/lib/ruby_llm/agents/workflow/parallel.rb +34 -17
  186. data/lib/ruby_llm/agents/workflow/thread_pool.rb +185 -0
  187. data/lib/ruby_llm/agents.rb +86 -20
  188. metadata +189 -35
  189. data/lib/ruby_llm/agents/base/caching.rb +0 -40
  190. data/lib/ruby_llm/agents/base/cost_calculation.rb +0 -105
  191. data/lib/ruby_llm/agents/base/dsl.rb +0 -324
  192. data/lib/ruby_llm/agents/base/execution.rb +0 -283
  193. data/lib/ruby_llm/agents/base/reliability_dsl.rb +0 -82
  194. data/lib/ruby_llm/agents/base/reliability_execution.rb +0 -136
  195. data/lib/ruby_llm/agents/base/response_building.rb +0 -86
  196. data/lib/ruby_llm/agents/base/tool_tracking.rb +0 -57
  197. data/lib/ruby_llm/agents/base.rb +0 -209
  198. data/lib/ruby_llm/agents/budget_tracker.rb +0 -471
  199. data/lib/ruby_llm/agents/configuration.rb +0 -357
  200. /data/lib/ruby_llm/agents/{deprecations.rb → core/deprecations.rb} +0 -0
  201. /data/lib/ruby_llm/agents/{inflections.rb → core/inflections.rb} +0 -0
  202. /data/lib/ruby_llm/agents/{attempt_tracker.rb → infrastructure/attempt_tracker.rb} +0 -0
  203. /data/lib/ruby_llm/agents/{cache_helper.rb → infrastructure/cache_helper.rb} +0 -0
  204. /data/lib/ruby_llm/agents/{circuit_breaker.rb → infrastructure/circuit_breaker.rb} +0 -0
  205. /data/lib/ruby_llm/agents/{redactor.rb → infrastructure/redactor.rb} +0 -0
  206. /data/lib/ruby_llm/agents/{reliability → infrastructure/reliability}/breaker_manager.rb +0 -0
  207. /data/lib/ruby_llm/agents/{reliability → infrastructure/reliability}/execution_constraints.rb +0 -0
  208. /data/lib/ruby_llm/agents/{reliability → infrastructure/reliability}/fallback_routing.rb +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d8bfa346ee4010060508948c994bc719f5f1ff40dd2eec3aeb04500f2054341
4
- data.tar.gz: 5546ca87104e12ba0522c2a6161ed2917355fb6fffcc7cc6dffd9920963b1037
3
+ metadata.gz: 34342a67c548fae89c92f0cddb75ad820dfe6a334050f806c1acab9b9b84bf29
4
+ data.tar.gz: a7d57596ff69a931e28e36ee680976557bc9f704f4d69f2296988226ed3ff9ad
5
5
  SHA512:
6
- metadata.gz: 391c1202b7bb677337329b5bd5358e9cb5bc4589d37cf48291bb4ff427d8ba1e3e7db99e8787d079ecd2f08382a4aa9940c573ad33c3be2040aa2e6ec21eb353
7
- data.tar.gz: 9b1ae37b9ca74f060377d32232a9c26a33e411d285ac658be9508348d75316582aa47e309b85c3258fcaf33a1d5e103fdef2aa1090569b86140b046ee7e975fc
6
+ metadata.gz: 89f6e9f8c05ef128e2c55652b69f5a6e986499d1811fa5ed4a92958eeea1ad129359e39762a3d72124f83b9b38981201216eb5eb45849d2cb265471b1ed45ee7
7
+ data.tar.gz: a0d1d64b761f94051b18ad0d79585678b536145a8bdfcc05d22cf4e905a4a913848901e85f3dd2ef37b755f14ceb25372c766219af69fa5f12932c108b9e6086
data/README.md CHANGED
@@ -1,5 +1,13 @@
1
+ <picture>
2
+ <source media="(prefers-color-scheme: dark)" srcset="./logo_dark.png">
3
+ <source media="(prefers-color-scheme: light)" srcset="./logo_light.png">
4
+ <img alt="RubyLLM::Agents" src="./logo_light.png">
5
+ </picture>
6
+
1
7
  # RubyLLM::Agents
2
8
 
9
+ > **AI Agents:** For comprehensive documentation optimized for AI consumption, see [LLMS.txt](LLMS.txt)
10
+
3
11
  > **Production-ready Rails engine for building, managing, and monitoring LLM-powered AI agents**
4
12
 
5
13
  [![Gem Version](https://badge.fury.io/rb/ruby_llm-agents.svg)](https://rubygems.org/gems/ruby_llm-agents)
@@ -22,17 +30,22 @@ Build intelligent AI agents in Ruby with a clean DSL, automatic execution tracki
22
30
 
23
31
  | Feature | Description | Docs |
24
32
  |---------|-------------|------|
25
- | **Agent DSL** | Declarative configuration with model, temperature, parameters | [Agent DSL](https://github.com/adham90/ruby_llm-agents/wiki/Agent-DSL) |
26
- | **Execution Tracking** | Automatic logging with token usage and cost analytics | [Tracking](https://github.com/adham90/ruby_llm-agents/wiki/Execution-Tracking) |
27
- | **Cost Analytics** | Track spending by agent, model, and time period | [Analytics](https://github.com/adham90/ruby_llm-agents/wiki/Execution-Tracking) |
28
- | **Reliability** | Automatic retries, model fallbacks, circuit breakers | [Reliability](https://github.com/adham90/ruby_llm-agents/wiki/Reliability) |
33
+ | **Agent DSL** | Declarative configuration with model, temperature, parameters, description | [Agent DSL](https://github.com/adham90/ruby_llm-agents/wiki/Agent-DSL) |
34
+ | **Execution Tracking** | Automatic logging with token usage, cost analytics, and fallback tracking | [Tracking](https://github.com/adham90/ruby_llm-agents/wiki/Execution-Tracking) |
35
+ | **Cost Analytics** | Track spending by agent, model, tenant, and time period | [Analytics](https://github.com/adham90/ruby_llm-agents/wiki/Execution-Tracking) |
36
+ | **Reliability** | Automatic retries, model fallbacks, circuit breakers with block DSL | [Reliability](https://github.com/adham90/ruby_llm-agents/wiki/Reliability) |
29
37
  | **Budget Controls** | Daily/monthly limits with hard and soft enforcement | [Budgets](https://github.com/adham90/ruby_llm-agents/wiki/Budget-Controls) |
38
+ | **Multi-Tenancy** | Per-tenant API keys, budgets, circuit breakers, and execution isolation | [Multi-Tenancy](https://github.com/adham90/ruby_llm-agents/wiki/Multi-Tenancy) |
30
39
  | **Workflows** | Pipelines, parallel execution, conditional routers | [Workflows](https://github.com/adham90/ruby_llm-agents/wiki/Workflows) |
40
+ | **Async/Fiber** | Concurrent execution with Ruby fibers for high-throughput workloads | [Async](https://github.com/adham90/ruby_llm-agents/wiki/Async-Fiber) |
31
41
  | **Dashboard** | Real-time Turbo-powered monitoring UI | [Dashboard](https://github.com/adham90/ruby_llm-agents/wiki/Dashboard) |
32
42
  | **Streaming** | Real-time response streaming with TTFT tracking | [Streaming](https://github.com/adham90/ruby_llm-agents/wiki/Streaming) |
33
43
  | **Conversation History** | Multi-turn conversations with message history | [Conversation History](https://github.com/adham90/ruby_llm-agents/wiki/Conversation-History) |
34
44
  | **Attachments** | Images, PDFs, and multimodal support | [Attachments](https://github.com/adham90/ruby_llm-agents/wiki/Attachments) |
35
45
  | **PII Redaction** | Automatic sensitive data protection | [Security](https://github.com/adham90/ruby_llm-agents/wiki/PII-Redaction) |
46
+ | **Content Moderation** | Input/output safety checks with OpenAI moderation API | [Moderation](https://github.com/adham90/ruby_llm-agents/wiki/Moderation) |
47
+ | **Embeddings** | Vector embeddings with batching, caching, and preprocessing | [Embeddings](https://github.com/adham90/ruby_llm-agents/wiki/Embeddings) |
48
+ | **Image Operations** | Generation, analysis, editing, pipelines with cost tracking | [Images](https://github.com/adham90/ruby_llm-agents/wiki/Image-Generation) |
36
49
  | **Alerts** | Slack, webhook, and custom notifications | [Alerts](https://github.com/adham90/ruby_llm-agents/wiki/Alerts) |
37
50
 
38
51
  ## Quick Start
@@ -66,21 +79,23 @@ rails generate ruby_llm_agents:agent SearchIntent query:required
66
79
  ```
67
80
 
68
81
  ```ruby
69
- # app/agents/search_intent_agent.rb
70
- class SearchIntentAgent < ApplicationAgent
71
- model "gpt-4o"
72
- temperature 0.0
82
+ # app/llm/agents/search_intent_agent.rb
83
+ module LLM
84
+ class SearchIntentAgent < ApplicationAgent
85
+ model "gpt-4o"
86
+ temperature 0.0
73
87
 
74
- param :query, required: true
88
+ param :query, required: true
75
89
 
76
- def user_prompt
77
- "Extract search intent from: #{query}"
78
- end
90
+ def user_prompt
91
+ "Extract search intent from: #{query}"
92
+ end
79
93
 
80
- def schema
81
- @schema ||= RubyLLM::Schema.create do
82
- string :refined_query, description: "Cleaned search query"
83
- array :filters, of: :string, description: "Extracted filters"
94
+ def schema
95
+ @schema ||= RubyLLM::Schema.create do
96
+ string :refined_query, description: "Cleaned search query"
97
+ array :filters, of: :string, description: "Extracted filters"
98
+ end
84
99
  end
85
100
  end
86
101
  end
@@ -89,7 +104,7 @@ end
89
104
  ### Call the Agent
90
105
 
91
106
  ```ruby
92
- result = SearchIntentAgent.call(query: "red summer dress under $50")
107
+ result = LLM::SearchIntentAgent.call(query: "red summer dress under $50")
93
108
 
94
109
  result.content # => { refined_query: "red dress", filters: ["color:red", "price:<50"] }
95
110
  result.total_cost # => 0.00025
@@ -114,15 +129,126 @@ result = ChatAgent.call(
114
129
 
115
130
  See [Conversation History](https://github.com/adham90/ruby_llm-agents/wiki/Conversation-History) for more patterns.
116
131
 
132
+ ### Embeddings
133
+
134
+ Generate vector embeddings for semantic search, RAG, and similarity matching:
135
+
136
+ ```bash
137
+ rails generate ruby_llm_agents:embedder Document
138
+ ```
139
+
140
+ ```ruby
141
+ # app/llm/text/embedders/document_embedder.rb
142
+ module LLM
143
+ module Text
144
+ class DocumentEmbedder < ApplicationEmbedder
145
+ model "text-embedding-3-small"
146
+ dimensions 512
147
+ batch_size 100
148
+ cache_for 1.week
149
+
150
+ # Optional: preprocess text before embedding
151
+ def preprocess(text)
152
+ text.strip.downcase.gsub(/\s+/, ' ')
153
+ end
154
+ end
155
+ end
156
+ end
157
+ ```
158
+
159
+ ```ruby
160
+ # Single text embedding
161
+ result = LLM::Text::DocumentEmbedder.call(text: "Hello world")
162
+ result.vector # => [0.123, -0.456, ...]
163
+ result.dimensions # => 512
164
+ result.total_tokens # => 2
165
+
166
+ # Batch embedding
167
+ result = LLM::Text::DocumentEmbedder.call(texts: ["Hello", "World", "Ruby"])
168
+ result.vectors # => [[...], [...], [...]]
169
+ result.count # => 3
170
+
171
+ # With progress callback for large batches
172
+ LLM::Text::DocumentEmbedder.call(texts: large_array) do |batch_result, index|
173
+ puts "Processed batch #{index + 1}"
174
+ end
175
+ ```
176
+
177
+ Features:
178
+ - **Configurable dimensions** - Reduce dimensions for efficient storage
179
+ - **Batch processing** - Embed multiple texts in optimized API calls
180
+ - **Caching** - Cache embeddings to reduce API costs
181
+ - **Preprocessing** - Clean and normalize text before embedding
182
+ - **Execution tracking** - All embeddings logged with tokens and costs
183
+
184
+ See [Embeddings](https://github.com/adham90/ruby_llm-agents/wiki/Embeddings) for more patterns.
185
+
186
+ ### Image Operations
187
+
188
+ Comprehensive image capabilities with generation, analysis, editing, and pipelines:
189
+
190
+ ```bash
191
+ # Generate image generators, analyzers, pipelines, and more
192
+ rails generate ruby_llm_agents:image_generator Logo
193
+ rails generate ruby_llm_agents:image_analyzer Product
194
+ rails generate ruby_llm_agents:background_remover Photo
195
+ rails generate ruby_llm_agents:image_pipeline Ecommerce --steps generate,upscale,analyze
196
+ ```
197
+
198
+ ```ruby
199
+ # Image Generation - create images from prompts
200
+ result = LLM::Image::LogoGenerator.call(prompt: "tech startup logo")
201
+ result.url # => "https://..."
202
+ result.save("logo.png")
203
+
204
+ # Image Analysis - extract captions, tags, objects, colors
205
+ result = LLM::Image::ProductAnalyzer.call(image: "product.jpg")
206
+ result.caption # => "Red sneaker on white background"
207
+ result.tags # => ["sneaker", "red", "footwear"]
208
+ result.colors # => [{ hex: "#FF0000", percentage: 30 }]
209
+
210
+ # Background Removal - extract subjects with transparency
211
+ result = LLM::Image::PhotoBackgroundRemover.call(image: "portrait.jpg")
212
+ result.save("portrait_transparent.png")
213
+
214
+ # Image Pipelines - chain multiple operations
215
+ result = LLM::Image::EcommercePipeline.call(
216
+ prompt: "professional laptop photo",
217
+ high_quality: true
218
+ )
219
+ result.final_image # => Final processed image
220
+ result.total_cost # => Combined cost of all steps
221
+ result.step(:analyze).tags # => Access individual step results
222
+ ```
223
+
224
+ Features:
225
+ - **8 image operation classes** - Generator, Analyzer, Editor, Transformer, Upscaler, Variator, BackgroundRemover, Pipeline
226
+ - **Prompt templates** - Consistent styling with preset templates
227
+ - **Content policy** - Validate prompts with configurable safety levels
228
+ - **Cost tracking** - Dynamic pricing with execution logging
229
+ - **Image Pipelines** - Chain operations into automated workflows
230
+ - **ActiveStorage** - Attach images directly to Rails models
231
+
232
+ See [Image Operations](https://github.com/adham90/ruby_llm-agents/wiki/Image-Generation) for full documentation.
233
+
117
234
  ## Documentation
118
235
 
236
+ > **Note:** Wiki content lives in the [`wiki/`](wiki/) folder. To sync changes to the [GitHub Wiki](https://github.com/adham90/ruby_llm-agents/wiki), run `./scripts/sync-wiki.sh`.
237
+
119
238
  | Guide | Description |
120
239
  |-------|-------------|
121
240
  | [Getting Started](https://github.com/adham90/ruby_llm-agents/wiki/Getting-Started) | Installation, configuration, first agent |
122
- | [Agent DSL](https://github.com/adham90/ruby_llm-agents/wiki/Agent-DSL) | All DSL options: model, temperature, params, caching |
123
- | [Reliability](https://github.com/adham90/ruby_llm-agents/wiki/Reliability) | Retries, fallbacks, circuit breakers, timeouts |
241
+ | [Agent DSL](https://github.com/adham90/ruby_llm-agents/wiki/Agent-DSL) | All DSL options: model, temperature, params, caching, description |
242
+ | [Reliability](https://github.com/adham90/ruby_llm-agents/wiki/Reliability) | Retries, fallbacks, circuit breakers, timeouts, reliability block |
124
243
  | [Workflows](https://github.com/adham90/ruby_llm-agents/wiki/Workflows) | Pipelines, parallel execution, routers |
125
244
  | [Budget Controls](https://github.com/adham90/ruby_llm-agents/wiki/Budget-Controls) | Spending limits, alerts, enforcement |
245
+ | [Multi-Tenancy](https://github.com/adham90/ruby_llm-agents/wiki/Multi-Tenancy) | Per-tenant budgets, isolation, configuration |
246
+ | [Async/Fiber](https://github.com/adham90/ruby_llm-agents/wiki/Async-Fiber) | Concurrent execution with Ruby fibers |
247
+ | [Testing Agents](https://github.com/adham90/ruby_llm-agents/wiki/Testing-Agents) | RSpec patterns, mocking, dry_run mode |
248
+ | [Error Handling](https://github.com/adham90/ruby_llm-agents/wiki/Error-Handling) | Error types, recovery patterns |
249
+ | [Moderation](https://github.com/adham90/ruby_llm-agents/wiki/Moderation) | Content moderation for input/output safety |
250
+ | [Embeddings](https://github.com/adham90/ruby_llm-agents/wiki/Embeddings) | Vector embeddings, batching, caching, preprocessing |
251
+ | [Image Generation](https://github.com/adham90/ruby_llm-agents/wiki/Image-Generation) | Text-to-image, templates, content policy, cost tracking |
126
252
  | [Dashboard](https://github.com/adham90/ruby_llm-agents/wiki/Dashboard) | Setup, authentication, analytics |
127
253
  | [Production](https://github.com/adham90/ruby_llm-agents/wiki/Production-Deployment) | Deployment best practices, background jobs |
128
254
  | [API Reference](https://github.com/adham90/ruby_llm-agents/wiki/API-Reference) | Complete class documentation |
@@ -133,27 +259,55 @@ See [Conversation History](https://github.com/adham90/ruby_llm-agents/wiki/Conve
133
259
  Build resilient agents with built-in fault tolerance:
134
260
 
135
261
  ```ruby
136
- class ReliableAgent < ApplicationAgent
137
- model "gpt-4o"
262
+ # app/llm/agents/reliable_agent.rb
263
+ module LLM
264
+ class ReliableAgent < ApplicationAgent
265
+ model "gpt-4o"
266
+ description "A resilient agent with automatic retries and fallbacks"
267
+
268
+ # Option 1: Individual DSL methods
269
+ retries max: 3, backoff: :exponential
270
+ fallback_models "gpt-4o-mini", "claude-3-5-sonnet"
271
+ circuit_breaker errors: 10, within: 60, cooldown: 300
272
+ total_timeout 30
273
+
274
+ # Option 2: Grouped reliability block (equivalent to above)
275
+ reliability do
276
+ retries max: 3, backoff: :exponential
277
+ fallback_models "gpt-4o-mini", "claude-3-5-sonnet"
278
+ circuit_breaker errors: 10, within: 60, cooldown: 300
279
+ total_timeout 30
280
+ end
138
281
 
139
- # Retry on failures with exponential backoff
140
- retries max: 3, backoff: :exponential
282
+ param :query, required: true
141
283
 
142
- # Fall back to alternative models
143
- fallback_models "gpt-4o-mini", "claude-3-5-sonnet"
284
+ def user_prompt
285
+ query
286
+ end
287
+ end
288
+ end
289
+ ```
144
290
 
145
- # Prevent cascading failures
146
- circuit_breaker errors: 10, within: 60, cooldown: 300
291
+ ### Enhanced Result Object
147
292
 
148
- # Maximum time for all attempts
149
- total_timeout 30
293
+ The result object provides detailed execution metadata:
150
294
 
151
- param :query, required: true
295
+ ```ruby
296
+ result = LLM::ReliableAgent.call(query: "test")
152
297
 
153
- def user_prompt
154
- query
155
- end
156
- end
298
+ # Basic response
299
+ result.content # => { ... }
300
+ result.success? # => true
301
+
302
+ # Reliability info
303
+ result.attempts_count # => 2 (if retry occurred)
304
+ result.used_fallback? # => true (if fallback model used)
305
+ result.chosen_model_id # => "gpt-4o-mini" (actual model used)
306
+
307
+ # Cost & timing
308
+ result.total_cost # => 0.00025
309
+ result.total_tokens # => 150
310
+ result.duration_ms # => 850
157
311
  ```
158
312
 
159
313
  ## Workflow Orchestration
@@ -200,6 +354,43 @@ result = SupportRouter.call(message: user_input)
200
354
  result.routed_to # :support, :sales, or :default
201
355
  ```
202
356
 
357
+ ## Async/Fiber Concurrency
358
+
359
+ Run multiple agents concurrently with minimal resources using Ruby's Fiber scheduler:
360
+
361
+ ```ruby
362
+ # Add async gem to Gemfile
363
+ gem 'async'
364
+ ```
365
+
366
+ ```ruby
367
+ require 'async'
368
+
369
+ # Run agents concurrently - non-blocking I/O
370
+ Async do
371
+ results = RubyLLM::Agents::Async.batch([
372
+ [SentimentAgent, { input: "I love this!" }],
373
+ [SummaryAgent, { input: "Long text..." }],
374
+ [CategoryAgent, { input: "Product review" }]
375
+ ], max_concurrent: 10)
376
+ end
377
+
378
+ # Process large collections efficiently
379
+ Async do
380
+ results = RubyLLM::Agents::Async.each(texts, max_concurrent: 20) do |text|
381
+ AnalyzerAgent.call(input: text)
382
+ end
383
+ end
384
+ ```
385
+
386
+ Benefits:
387
+ - **100x less memory** - Fibers use ~10KB vs ~1MB per thread
388
+ - **Shared connections** - Single database connection for all fibers
389
+ - **Auto-detection** - Parallel workflows automatically use fibers in async context
390
+ - **Non-blocking retries** - Backoff delays don't block other operations
391
+
392
+ See [Async/Fiber](https://github.com/adham90/ruby_llm-agents/wiki/Async-Fiber) for more patterns.
393
+
203
394
  ## Cost & Budget Controls
204
395
 
205
396
  Track and limit LLM spending:
@@ -30,6 +30,16 @@ module RubyLLM
30
30
  @agents = all_items.reject { |a| a[:is_workflow] }
31
31
  @workflows = all_items.select { |a| a[:is_workflow] }
32
32
 
33
+ # Group agents by type for sub-tabs
34
+ @agents_by_type = {
35
+ agent: @agents.select { |a| a[:agent_type] == "agent" },
36
+ embedder: @agents.select { |a| a[:agent_type] == "embedder" },
37
+ moderator: @agents.select { |a| a[:agent_type] == "moderator" },
38
+ speaker: @agents.select { |a| a[:agent_type] == "speaker" },
39
+ transcriber: @agents.select { |a| a[:agent_type] == "transcriber" },
40
+ image_generator: @agents.select { |a| a[:agent_type] == "image_generator" }
41
+ }
42
+
33
43
  # Group workflows by type for sub-tabs
34
44
  @workflows_by_type = {
35
45
  pipeline: @workflows.select { |w| w[:workflow_type] == "pipeline" },
@@ -44,6 +54,7 @@ module RubyLLM
44
54
  Rails.logger.error("[RubyLLM::Agents] Error loading agents: #{e.message}")
45
55
  @agents = []
46
56
  @workflows = []
57
+ @agents_by_type = { agent: [], embedder: [], moderator: [], speaker: [], transcriber: [], image_generator: [] }
47
58
  @workflows_by_type = { pipeline: [], parallel: [], router: [] }
48
59
  @agent_count = 0
49
60
  @workflow_count = 0
@@ -69,7 +80,8 @@ module RubyLLM
69
80
 
70
81
  if @agent_class
71
82
  load_agent_config
72
- load_circuit_breaker_status
83
+ # Only load circuit breaker status for base agents
84
+ load_circuit_breaker_status if @agent_type_kind == "agent"
73
85
  end
74
86
  rescue StandardError => e
75
87
  Rails.logger.error("[RubyLLM::Agents] Error loading agent #{@agent_type}: #{e.message}")
@@ -207,26 +219,134 @@ module RubyLLM
207
219
  #
208
220
  # Extracts DSL-configured values from the agent class for display.
209
221
  # Only called if the agent class still exists.
222
+ # Detects agent type and loads appropriate config.
210
223
  #
211
224
  # @return [void]
212
225
  def load_agent_config
226
+ @agent_type_kind = AgentRegistry.send(:detect_agent_type, @agent_class)
227
+
228
+ # Common config for all types
213
229
  @config = {
214
- # Basic configuration
215
- model: @agent_class.model,
216
- temperature: @agent_class.temperature,
217
- version: @agent_class.version,
218
- description: @agent_class.respond_to?(:description) ? @agent_class.description : nil,
219
- timeout: @agent_class.timeout,
220
- cache_enabled: @agent_class.cache_enabled?,
221
- cache_ttl: @agent_class.cache_ttl,
222
- params: @agent_class.params,
223
-
224
- # Reliability configuration
225
- retries: @agent_class.retries,
226
- fallback_models: @agent_class.fallback_models,
227
- total_timeout: @agent_class.total_timeout,
228
- circuit_breaker: @agent_class.circuit_breaker_config
230
+ model: safe_config_call(:model),
231
+ version: safe_config_call(:version) || "N/A",
232
+ description: safe_config_call(:description)
229
233
  }
234
+
235
+ # Type-specific config
236
+ case @agent_type_kind
237
+ when "embedder"
238
+ load_embedder_config
239
+ when "moderator"
240
+ load_moderator_config
241
+ when "speaker"
242
+ load_speaker_config
243
+ when "transcriber"
244
+ load_transcriber_config
245
+ when "image_generator"
246
+ load_image_generator_config
247
+ else
248
+ load_base_agent_config
249
+ end
250
+ end
251
+
252
+ # Loads configuration specific to Base agents
253
+ #
254
+ # @return [void]
255
+ def load_base_agent_config
256
+ @config.merge!(
257
+ temperature: safe_config_call(:temperature),
258
+ timeout: safe_config_call(:timeout),
259
+ cache_enabled: safe_config_call(:cache_enabled?) || false,
260
+ cache_ttl: safe_config_call(:cache_ttl),
261
+ params: safe_config_call(:params) || {},
262
+ retries: safe_config_call(:retries),
263
+ fallback_models: safe_config_call(:fallback_models),
264
+ total_timeout: safe_config_call(:total_timeout),
265
+ circuit_breaker: safe_config_call(:circuit_breaker_config)
266
+ )
267
+ end
268
+
269
+ # Loads configuration specific to Embedders
270
+ #
271
+ # @return [void]
272
+ def load_embedder_config
273
+ @config.merge!(
274
+ dimensions: safe_config_call(:dimensions),
275
+ batch_size: safe_config_call(:batch_size),
276
+ cache_enabled: safe_config_call(:cache_enabled?) || false,
277
+ cache_ttl: safe_config_call(:cache_ttl)
278
+ )
279
+ end
280
+
281
+ # Loads configuration specific to Moderators
282
+ #
283
+ # @return [void]
284
+ def load_moderator_config
285
+ @config.merge!(
286
+ threshold: safe_config_call(:threshold),
287
+ categories: safe_config_call(:categories)
288
+ )
289
+ end
290
+
291
+ # Loads configuration specific to Speakers
292
+ #
293
+ # @return [void]
294
+ def load_speaker_config
295
+ @config.merge!(
296
+ provider: safe_config_call(:provider),
297
+ voice: safe_config_call(:voice),
298
+ voice_id: safe_config_call(:voice_id),
299
+ speed: safe_config_call(:speed),
300
+ output_format: safe_config_call(:output_format),
301
+ streaming: safe_config_call(:streaming?),
302
+ ssml_enabled: safe_config_call(:ssml_enabled?),
303
+ cache_enabled: safe_config_call(:cache_enabled?) || false,
304
+ cache_ttl: safe_config_call(:cache_ttl)
305
+ )
306
+ end
307
+
308
+ # Loads configuration specific to Transcribers
309
+ #
310
+ # @return [void]
311
+ def load_transcriber_config
312
+ @config.merge!(
313
+ language: safe_config_call(:language),
314
+ output_format: safe_config_call(:output_format),
315
+ include_timestamps: safe_config_call(:include_timestamps),
316
+ cache_enabled: safe_config_call(:cache_enabled?) || false,
317
+ cache_ttl: safe_config_call(:cache_ttl),
318
+ fallback_models: safe_config_call(:fallback_models)
319
+ )
320
+ end
321
+
322
+ # Loads configuration specific to ImageGenerators
323
+ #
324
+ # @return [void]
325
+ def load_image_generator_config
326
+ @config.merge!(
327
+ size: safe_config_call(:size),
328
+ quality: safe_config_call(:quality),
329
+ style: safe_config_call(:style),
330
+ content_policy: safe_config_call(:content_policy),
331
+ template: safe_config_call(:template_string),
332
+ negative_prompt: safe_config_call(:negative_prompt),
333
+ seed: safe_config_call(:seed),
334
+ guidance_scale: safe_config_call(:guidance_scale),
335
+ steps: safe_config_call(:steps),
336
+ cache_enabled: safe_config_call(:cache_enabled?) || false,
337
+ cache_ttl: safe_config_call(:cache_ttl)
338
+ )
339
+ end
340
+
341
+ # Safely calls a method on the agent class, returning nil on error
342
+ #
343
+ # @param method [Symbol] The method to call
344
+ # @return [Object, nil] The result or nil if error
345
+ def safe_config_call(method)
346
+ return nil unless @agent_class&.respond_to?(method)
347
+ @agent_class.public_send(method)
348
+ rescue StandardError
349
+ nil
230
350
  end
231
351
 
232
352
  # Loads circuit breaker status for the agent's models