ruby_llm-agents 1.3.4 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +101 -334
- data/app/controllers/concerns/ruby_llm/agents/sortable.rb +0 -1
- data/app/controllers/ruby_llm/agents/agents_controller.rb +5 -56
- data/app/controllers/ruby_llm/agents/dashboard_controller.rb +22 -106
- data/app/controllers/ruby_llm/agents/executions_controller.rb +4 -114
- data/app/controllers/ruby_llm/agents/tenants_controller.rb +30 -2
- data/app/helpers/ruby_llm/agents/application_helper.rb +19 -53
- data/app/models/ruby_llm/agents/execution/analytics.rb +13 -54
- data/app/models/ruby_llm/agents/execution/scopes.rb +61 -14
- data/app/models/ruby_llm/agents/execution.rb +46 -10
- data/app/models/ruby_llm/agents/execution_detail.rb +18 -0
- data/app/models/ruby_llm/agents/tenant/budgetable.rb +132 -24
- data/app/models/ruby_llm/agents/tenant/incrementable.rb +117 -0
- data/app/models/ruby_llm/agents/tenant/resettable.rb +128 -0
- data/app/models/ruby_llm/agents/tenant/trackable.rb +46 -12
- data/app/models/ruby_llm/agents/tenant.rb +2 -3
- data/app/models/ruby_llm/agents/tenant_budget.rb +6 -3
- data/app/services/ruby_llm/agents/agent_registry.rb +6 -112
- data/app/views/layouts/ruby_llm/agents/application.html.erb +87 -252
- data/app/views/ruby_llm/agents/agents/_config_agent.html.erb +71 -218
- data/app/views/ruby_llm/agents/agents/_config_embedder.html.erb +20 -63
- data/app/views/ruby_llm/agents/agents/_config_image_generator.html.erb +44 -131
- data/app/views/ruby_llm/agents/agents/_config_moderator.html.erb +16 -57
- data/app/views/ruby_llm/agents/agents/_config_speaker.html.erb +39 -104
- data/app/views/ruby_llm/agents/agents/_config_transcriber.html.erb +29 -82
- data/app/views/ruby_llm/agents/agents/_empty_state.html.erb +4 -14
- data/app/views/ruby_llm/agents/agents/index.html.erb +105 -274
- data/app/views/ruby_llm/agents/agents/show.html.erb +248 -378
- data/app/views/ruby_llm/agents/dashboard/_action_center.html.erb +29 -52
- data/app/views/ruby_llm/agents/dashboard/_tenant_budget.html.erb +73 -99
- data/app/views/ruby_llm/agents/dashboard/index.html.erb +228 -433
- data/app/views/ruby_llm/agents/executions/_execution.html.erb +1 -1
- data/app/views/ruby_llm/agents/executions/_filters.html.erb +4 -25
- data/app/views/ruby_llm/agents/executions/_list.html.erb +111 -152
- data/app/views/ruby_llm/agents/executions/index.html.erb +5 -7
- data/app/views/ruby_llm/agents/executions/show.html.erb +526 -1037
- data/app/views/ruby_llm/agents/shared/_agent_type_badge.html.erb +5 -21
- data/app/views/ruby_llm/agents/shared/_executions_table.html.erb +70 -191
- data/app/views/ruby_llm/agents/shared/_filter_dropdown.html.erb +16 -44
- data/app/views/ruby_llm/agents/shared/_select_dropdown.html.erb +12 -41
- data/app/views/ruby_llm/agents/shared/_status_badge.html.erb +11 -65
- data/app/views/ruby_llm/agents/shared/_tenant_filter.html.erb +6 -5
- data/app/views/ruby_llm/agents/system_config/show.html.erb +240 -351
- data/app/views/ruby_llm/agents/tenants/_form.html.erb +67 -77
- data/app/views/ruby_llm/agents/tenants/edit.html.erb +7 -9
- data/app/views/ruby_llm/agents/tenants/index.html.erb +100 -122
- data/app/views/ruby_llm/agents/tenants/show.html.erb +146 -336
- data/config/routes.rb +0 -13
- data/lib/generators/ruby_llm_agents/install_generator.rb +9 -14
- data/lib/generators/ruby_llm_agents/migrate_structure_generator.rb +2 -12
- data/lib/generators/ruby_llm_agents/restructure_generator.rb +0 -2
- data/lib/generators/ruby_llm_agents/templates/add_usage_counters_to_tenants_migration.rb.tt +37 -0
- data/lib/generators/ruby_llm_agents/templates/agent.rb.tt +1 -2
- data/lib/generators/ruby_llm_agents/templates/application_agent.rb.tt +1 -1
- data/lib/generators/ruby_llm_agents/templates/application_image_pipeline.rb.tt +0 -1
- data/lib/generators/ruby_llm_agents/templates/create_execution_details_migration.rb.tt +27 -0
- data/lib/generators/ruby_llm_agents/templates/create_tenants_migration.rb.tt +25 -0
- data/lib/generators/ruby_llm_agents/templates/image_pipeline.rb.tt +0 -1
- data/lib/generators/ruby_llm_agents/templates/initializer.rb.tt +9 -12
- data/lib/generators/ruby_llm_agents/templates/migration.rb.tt +40 -71
- data/lib/generators/ruby_llm_agents/templates/remove_agent_version_migration.rb.tt +13 -0
- data/lib/generators/ruby_llm_agents/templates/remove_workflow_columns_migration.rb.tt +19 -0
- data/lib/generators/ruby_llm_agents/templates/skills/AGENTS.md.tt +2 -4
- data/lib/generators/ruby_llm_agents/templates/skills/IMAGE_PIPELINES.md.tt +0 -1
- data/lib/generators/ruby_llm_agents/templates/split_execution_details_migration.rb.tt +232 -0
- data/lib/generators/ruby_llm_agents/upgrade_generator.rb +58 -262
- data/lib/ruby_llm/agents/audio/speaker.rb +0 -1
- data/lib/ruby_llm/agents/audio/transcriber.rb +0 -1
- data/lib/ruby_llm/agents/base_agent.rb +52 -6
- data/lib/ruby_llm/agents/core/base/callbacks.rb +142 -0
- data/lib/ruby_llm/agents/core/base.rb +23 -55
- data/lib/ruby_llm/agents/core/configuration.rb +58 -117
- data/lib/ruby_llm/agents/core/errors.rb +0 -58
- data/lib/ruby_llm/agents/core/instrumentation.rb +157 -110
- data/lib/ruby_llm/agents/core/llm_tenant.rb +8 -7
- data/lib/ruby_llm/agents/core/version.rb +1 -1
- data/lib/ruby_llm/agents/dsl/base.rb +157 -17
- data/lib/ruby_llm/agents/dsl/caching.rb +33 -2
- data/lib/ruby_llm/agents/dsl/reliability.rb +148 -0
- data/lib/ruby_llm/agents/dsl.rb +1 -2
- data/lib/ruby_llm/agents/image/analyzer/execution.rb +1 -2
- data/lib/ruby_llm/agents/image/background_remover/execution.rb +1 -2
- data/lib/ruby_llm/agents/image/concerns/image_operation_dsl.rb +1 -13
- data/lib/ruby_llm/agents/image/concerns/image_operation_execution.rb +2 -2
- data/lib/ruby_llm/agents/image/editor/dsl.rb +0 -14
- data/lib/ruby_llm/agents/image/editor/execution.rb +1 -10
- data/lib/ruby_llm/agents/image/editor.rb +0 -1
- data/lib/ruby_llm/agents/image/generator.rb +0 -21
- data/lib/ruby_llm/agents/image/pipeline/dsl.rb +0 -13
- data/lib/ruby_llm/agents/image/pipeline/execution.rb +0 -1
- data/lib/ruby_llm/agents/image/transformer/dsl.rb +0 -13
- data/lib/ruby_llm/agents/image/transformer/execution.rb +1 -10
- data/lib/ruby_llm/agents/image/transformer.rb +0 -1
- data/lib/ruby_llm/agents/image/upscaler/execution.rb +1 -2
- data/lib/ruby_llm/agents/image/variator/execution.rb +1 -2
- data/lib/ruby_llm/agents/infrastructure/alert_manager.rb +78 -173
- data/lib/ruby_llm/agents/infrastructure/budget/budget_query.rb +66 -2
- data/lib/ruby_llm/agents/infrastructure/budget/spend_recorder.rb +0 -12
- data/lib/ruby_llm/agents/infrastructure/circuit_breaker.rb +10 -13
- data/lib/ruby_llm/agents/pipeline/context.rb +0 -1
- data/lib/ruby_llm/agents/pipeline/middleware/budget.rb +28 -4
- data/lib/ruby_llm/agents/pipeline/middleware/cache.rb +3 -10
- data/lib/ruby_llm/agents/pipeline/middleware/instrumentation.rb +88 -55
- data/lib/ruby_llm/agents/pipeline/middleware/tenant.rb +5 -41
- data/lib/ruby_llm/agents/rails/engine.rb +6 -6
- data/lib/ruby_llm/agents/results/base.rb +1 -49
- data/lib/ruby_llm/agents/text/embedder.rb +0 -1
- data/lib/ruby_llm/agents.rb +1 -9
- data/lib/tasks/ruby_llm_agents.rake +34 -0
- metadata +12 -81
- data/app/controllers/ruby_llm/agents/api_configurations_controller.rb +0 -214
- data/app/controllers/ruby_llm/agents/workflows_controller.rb +0 -544
- data/app/mailers/ruby_llm/agents/alert_mailer.rb +0 -84
- data/app/mailers/ruby_llm/agents/application_mailer.rb +0 -28
- data/app/models/ruby_llm/agents/api_configuration.rb +0 -386
- data/app/models/ruby_llm/agents/execution/workflow.rb +0 -170
- data/app/models/ruby_llm/agents/tenant/configurable.rb +0 -135
- data/app/views/ruby_llm/agents/agents/_agent.html.erb +0 -98
- data/app/views/ruby_llm/agents/agents/_version_comparison.html.erb +0 -186
- data/app/views/ruby_llm/agents/agents/_workflow.html.erb +0 -126
- data/app/views/ruby_llm/agents/alert_mailer/alert_notification.html.erb +0 -107
- data/app/views/ruby_llm/agents/alert_mailer/alert_notification.text.erb +0 -18
- data/app/views/ruby_llm/agents/api_configurations/_api_key_field.html.erb +0 -34
- data/app/views/ruby_llm/agents/api_configurations/_form.html.erb +0 -288
- data/app/views/ruby_llm/agents/api_configurations/edit.html.erb +0 -95
- data/app/views/ruby_llm/agents/api_configurations/edit_tenant.html.erb +0 -97
- data/app/views/ruby_llm/agents/api_configurations/show.html.erb +0 -214
- data/app/views/ruby_llm/agents/api_configurations/tenant.html.erb +0 -179
- data/app/views/ruby_llm/agents/dashboard/_agent_comparison.html.erb +0 -73
- data/app/views/ruby_llm/agents/dashboard/_alerts_feed.html.erb +0 -62
- data/app/views/ruby_llm/agents/dashboard/_breaker_strip.html.erb +0 -47
- data/app/views/ruby_llm/agents/dashboard/_budgets_bar.html.erb +0 -75
- data/app/views/ruby_llm/agents/dashboard/_model_comparison.html.erb +0 -56
- data/app/views/ruby_llm/agents/dashboard/_model_cost_breakdown.html.erb +0 -115
- data/app/views/ruby_llm/agents/dashboard/_now_strip.html.erb +0 -59
- data/app/views/ruby_llm/agents/dashboard/_top_errors.html.erb +0 -60
- data/app/views/ruby_llm/agents/executions/_workflow_summary.html.erb +0 -86
- data/app/views/ruby_llm/agents/executions/dry_run.html.erb +0 -149
- data/app/views/ruby_llm/agents/shared/_breadcrumbs.html.erb +0 -48
- data/app/views/ruby_llm/agents/shared/_nav_link.html.erb +0 -27
- data/app/views/ruby_llm/agents/shared/_stat_card.html.erb +0 -14
- data/app/views/ruby_llm/agents/shared/_workflow_type_badge.html.erb +0 -35
- data/app/views/ruby_llm/agents/workflows/_empty_state.html.erb +0 -22
- data/app/views/ruby_llm/agents/workflows/_step_performance.html.erb +0 -228
- data/app/views/ruby_llm/agents/workflows/_structure_dsl.html.erb +0 -539
- data/app/views/ruby_llm/agents/workflows/_structure_parallel.html.erb +0 -76
- data/app/views/ruby_llm/agents/workflows/_structure_pipeline.html.erb +0 -74
- data/app/views/ruby_llm/agents/workflows/_structure_router.html.erb +0 -108
- data/app/views/ruby_llm/agents/workflows/_workflow_diagram.html.erb +0 -920
- data/app/views/ruby_llm/agents/workflows/index.html.erb +0 -179
- data/app/views/ruby_llm/agents/workflows/show.html.erb +0 -467
- data/lib/generators/ruby_llm_agents/api_configuration_generator.rb +0 -100
- data/lib/generators/ruby_llm_agents/templates/add_workflow_migration.rb.tt +0 -38
- data/lib/generators/ruby_llm_agents/templates/application_workflow.rb.tt +0 -48
- data/lib/generators/ruby_llm_agents/templates/create_api_configurations_migration.rb.tt +0 -90
- data/lib/generators/ruby_llm_agents/templates/skills/WORKFLOWS.md.tt +0 -551
- data/lib/ruby_llm/agents/core/base/moderation_dsl.rb +0 -181
- data/lib/ruby_llm/agents/core/base/moderation_execution.rb +0 -274
- data/lib/ruby_llm/agents/core/resolved_config.rb +0 -348
- data/lib/ruby_llm/agents/image/generator/content_policy.rb +0 -95
- data/lib/ruby_llm/agents/infrastructure/redactor.rb +0 -130
- data/lib/ruby_llm/agents/results/moderation_result.rb +0 -158
- data/lib/ruby_llm/agents/text/moderator.rb +0 -237
- data/lib/ruby_llm/agents/workflow/approval.rb +0 -205
- data/lib/ruby_llm/agents/workflow/approval_store.rb +0 -179
- data/lib/ruby_llm/agents/workflow/async.rb +0 -220
- data/lib/ruby_llm/agents/workflow/async_executor.rb +0 -156
- data/lib/ruby_llm/agents/workflow/dsl/executor.rb +0 -467
- data/lib/ruby_llm/agents/workflow/dsl/input_schema.rb +0 -244
- data/lib/ruby_llm/agents/workflow/dsl/iteration_executor.rb +0 -289
- data/lib/ruby_llm/agents/workflow/dsl/parallel_group.rb +0 -107
- data/lib/ruby_llm/agents/workflow/dsl/route_builder.rb +0 -150
- data/lib/ruby_llm/agents/workflow/dsl/schedule_helpers.rb +0 -187
- data/lib/ruby_llm/agents/workflow/dsl/step_config.rb +0 -352
- data/lib/ruby_llm/agents/workflow/dsl/step_executor.rb +0 -415
- data/lib/ruby_llm/agents/workflow/dsl/wait_config.rb +0 -257
- data/lib/ruby_llm/agents/workflow/dsl/wait_executor.rb +0 -317
- data/lib/ruby_llm/agents/workflow/dsl.rb +0 -576
- data/lib/ruby_llm/agents/workflow/instrumentation.rb +0 -249
- data/lib/ruby_llm/agents/workflow/notifiers/base.rb +0 -117
- data/lib/ruby_llm/agents/workflow/notifiers/email.rb +0 -117
- data/lib/ruby_llm/agents/workflow/notifiers/slack.rb +0 -180
- data/lib/ruby_llm/agents/workflow/notifiers/webhook.rb +0 -121
- data/lib/ruby_llm/agents/workflow/notifiers.rb +0 -70
- data/lib/ruby_llm/agents/workflow/orchestrator.rb +0 -416
- data/lib/ruby_llm/agents/workflow/result.rb +0 -592
- data/lib/ruby_llm/agents/workflow/thread_pool.rb +0 -185
- data/lib/ruby_llm/agents/workflow/throttle_manager.rb +0 -206
- data/lib/ruby_llm/agents/workflow/wait_result.rb +0 -213
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7f2dcacc45b93f72d6de4f0d8ac2f56d85288f9cacc5495838fbc40473714ddf
|
|
4
|
+
data.tar.gz: d6e2e7d7c78d9f6443cf8f01fa43733951e552922418ba8ee7226df4977d51a1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3231be55f4d51f39bb8339ac878a82eef2c2ee5d2894a53356c43a7fc20fd9381141e19d1b447e7c755a6117d687a241e7d3be701792ebf5e97ce3f5e7cf4758
|
|
7
|
+
data.tar.gz: d89ded2027aa6ef14494216a116fcf42a6b549128677ec24a3881a63109f06a15955d0c824d7b3ff9c8aeecaa1ebdd675099d38bb5a9dce8dd4344bf045cd15f
|
data/README.md
CHANGED
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
# RubyLLM::Agents
|
|
8
8
|
|
|
9
|
-
> **AI Agents:** For comprehensive documentation optimized for AI consumption, see [LLMS.txt](LLMS.txt)
|
|
10
|
-
|
|
11
9
|
> **Production-ready Rails engine for building, managing, and monitoring LLM-powered AI agents**
|
|
12
10
|
|
|
13
11
|
[](https://rubygems.org/gems/ruby_llm-agents)
|
|
@@ -23,88 +21,28 @@ Build intelligent AI agents in Ruby with a clean DSL, automatic execution tracki
|
|
|
23
21
|
- **Rails-Native** - Seamlessly integrates with your Rails app: models, jobs, caching, and Hotwire
|
|
24
22
|
- **Production-Ready** - Built-in retries, model fallbacks, circuit breakers, and budget limits
|
|
25
23
|
- **Full Observability** - Track every execution with costs, tokens, duration, and errors
|
|
26
|
-
- **Workflow Orchestration** - Compose agents into pipelines, parallel tasks, and conditional routers
|
|
27
24
|
- **Zero Lock-in** - Works with any LLM provider supported by RubyLLM
|
|
28
25
|
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
| Feature | Description | Docs |
|
|
32
|
-
|---------|-------------|------|
|
|
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) |
|
|
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) |
|
|
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) |
|
|
41
|
-
| **Dashboard** | Real-time Turbo-powered monitoring UI | [Dashboard](https://github.com/adham90/ruby_llm-agents/wiki/Dashboard) |
|
|
42
|
-
| **Streaming** | Real-time response streaming with TTFT tracking | [Streaming](https://github.com/adham90/ruby_llm-agents/wiki/Streaming) |
|
|
43
|
-
| **Conversation History** | Multi-turn conversations with message history | [Conversation History](https://github.com/adham90/ruby_llm-agents/wiki/Conversation-History) |
|
|
44
|
-
| **Attachments** | Images, PDFs, and multimodal support | [Attachments](https://github.com/adham90/ruby_llm-agents/wiki/Attachments) |
|
|
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) |
|
|
49
|
-
| **Alerts** | Slack, webhook, and custom notifications | [Alerts](https://github.com/adham90/ruby_llm-agents/wiki/Alerts) |
|
|
50
|
-
|
|
51
|
-
## Quick Start
|
|
52
|
-
|
|
53
|
-
### Installation
|
|
54
|
-
|
|
55
|
-
```ruby
|
|
56
|
-
# Gemfile
|
|
57
|
-
gem "ruby_llm-agents"
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
bundle install
|
|
62
|
-
rails generate ruby_llm_agents:install
|
|
63
|
-
rails db:migrate
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### Configure API Keys
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
|
-
# .env
|
|
70
|
-
OPENAI_API_KEY=sk-...
|
|
71
|
-
ANTHROPIC_API_KEY=sk-ant-...
|
|
72
|
-
GOOGLE_API_KEY=...
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### Create Your First Agent
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
rails generate ruby_llm_agents:agent SearchIntent query:required
|
|
79
|
-
```
|
|
26
|
+
## Show Me the Code
|
|
80
27
|
|
|
81
28
|
```ruby
|
|
82
|
-
# app/
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
@schema ||= RubyLLM::Schema.create do
|
|
96
|
-
string :refined_query, description: "Cleaned search query"
|
|
97
|
-
array :filters, of: :string, description: "Extracted filters"
|
|
98
|
-
end
|
|
99
|
-
end
|
|
29
|
+
# app/agents/search_intent_agent.rb
|
|
30
|
+
class SearchIntentAgent < ApplicationAgent
|
|
31
|
+
model "gpt-4o"
|
|
32
|
+
temperature 0.0
|
|
33
|
+
|
|
34
|
+
# Prompts with {placeholder} syntax - params auto-registered
|
|
35
|
+
system "You are a search intent analyzer. Extract structured data from queries."
|
|
36
|
+
prompt "Extract search intent from: {query}"
|
|
37
|
+
|
|
38
|
+
# Structured output with returns DSL
|
|
39
|
+
returns do
|
|
40
|
+
string :refined_query, description: "Cleaned search query"
|
|
41
|
+
array :filters, of: :string, description: "Extracted filters"
|
|
100
42
|
end
|
|
101
43
|
end
|
|
102
|
-
```
|
|
103
44
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
```ruby
|
|
107
|
-
result = LLM::SearchIntentAgent.call(query: "red summer dress under $50")
|
|
45
|
+
result = SearchIntentAgent.call(query: "red summer dress under $50")
|
|
108
46
|
|
|
109
47
|
result.content # => { refined_query: "red dress", filters: ["color:red", "price:<50"] }
|
|
110
48
|
result.total_cost # => 0.00025
|
|
@@ -112,11 +50,8 @@ result.total_tokens # => 150
|
|
|
112
50
|
result.duration_ms # => 850
|
|
113
51
|
```
|
|
114
52
|
|
|
115
|
-
### Multi-Turn Conversations
|
|
116
|
-
|
|
117
|
-
Build chatbots and conversational agents with message history:
|
|
118
|
-
|
|
119
53
|
```ruby
|
|
54
|
+
# Multi-turn conversations
|
|
120
55
|
result = ChatAgent.call(
|
|
121
56
|
query: "What's my name?",
|
|
122
57
|
messages: [
|
|
@@ -127,112 +62,124 @@ result = ChatAgent.call(
|
|
|
127
62
|
# => "Your name is Alice!"
|
|
128
63
|
```
|
|
129
64
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
65
|
+
```ruby
|
|
66
|
+
# Resilient agents with automatic retries and fallbacks
|
|
67
|
+
class ReliableAgent < ApplicationAgent
|
|
68
|
+
model "gpt-4o"
|
|
133
69
|
|
|
134
|
-
|
|
70
|
+
prompt "{query}"
|
|
135
71
|
|
|
136
|
-
|
|
137
|
-
|
|
72
|
+
on_failure do
|
|
73
|
+
retries times: 3, backoff: :exponential
|
|
74
|
+
fallback to: ["gpt-4o-mini", "claude-3-5-sonnet"]
|
|
75
|
+
circuit_breaker after: 10, within: 60, cooldown: 5.minutes
|
|
76
|
+
timeout 30
|
|
77
|
+
end
|
|
78
|
+
end
|
|
138
79
|
```
|
|
139
80
|
|
|
140
81
|
```ruby
|
|
141
|
-
#
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
|
82
|
+
# Vector embeddings for semantic search and RAG
|
|
83
|
+
# app/agents/embedders/document_embedder.rb
|
|
84
|
+
module Embedders
|
|
85
|
+
class DocumentEmbedder < ApplicationEmbedder
|
|
86
|
+
model "text-embedding-3-small"
|
|
87
|
+
dimensions 512
|
|
88
|
+
cache_for 1.week
|
|
155
89
|
end
|
|
156
90
|
end
|
|
157
|
-
```
|
|
158
91
|
|
|
159
|
-
|
|
160
|
-
# Single text embedding
|
|
161
|
-
result = LLM::Text::DocumentEmbedder.call(text: "Hello world")
|
|
92
|
+
result = Embedders::DocumentEmbedder.call(text: "Hello world")
|
|
162
93
|
result.vector # => [0.123, -0.456, ...]
|
|
163
94
|
result.dimensions # => 512
|
|
164
|
-
result.total_tokens # => 2
|
|
165
95
|
|
|
166
96
|
# Batch embedding
|
|
167
|
-
result =
|
|
97
|
+
result = Embedders::DocumentEmbedder.call(texts: ["Hello", "World", "Ruby"])
|
|
168
98
|
result.vectors # => [[...], [...], [...]]
|
|
169
|
-
|
|
99
|
+
```
|
|
170
100
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
101
|
+
```ruby
|
|
102
|
+
# Image generation, analysis, and pipelines
|
|
103
|
+
# app/agents/images/logo_generator.rb
|
|
104
|
+
module Images
|
|
105
|
+
class LogoGenerator < ApplicationImageGenerator
|
|
106
|
+
model "gpt-image-1"
|
|
107
|
+
size "1024x1024"
|
|
108
|
+
quality "hd"
|
|
109
|
+
style "vivid"
|
|
110
|
+
template "Professional logo design: {prompt}. Minimalist, scalable."
|
|
111
|
+
end
|
|
174
112
|
end
|
|
113
|
+
|
|
114
|
+
result = Images::LogoGenerator.call(prompt: "tech startup logo")
|
|
115
|
+
result.url # => "https://..."
|
|
116
|
+
result.save("logo.png")
|
|
175
117
|
```
|
|
176
118
|
|
|
177
|
-
Features
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
119
|
+
## Features
|
|
120
|
+
|
|
121
|
+
| Feature | Description | Docs |
|
|
122
|
+
|---------|-------------|------|
|
|
123
|
+
| **Agent DSL** | Declarative configuration with model, temperature, parameters, description | [Agent DSL](https://github.com/adham90/ruby_llm-agents/wiki/Agent-DSL) |
|
|
124
|
+
| **Execution Tracking** | Automatic logging with token usage, cost analytics, and fallback tracking | [Tracking](https://github.com/adham90/ruby_llm-agents/wiki/Execution-Tracking) |
|
|
125
|
+
| **Cost Analytics** | Track spending by agent, model, tenant, and time period | [Analytics](https://github.com/adham90/ruby_llm-agents/wiki/Execution-Tracking) |
|
|
126
|
+
| **Reliability** | Automatic retries, model fallbacks, circuit breakers with block DSL | [Reliability](https://github.com/adham90/ruby_llm-agents/wiki/Reliability) |
|
|
127
|
+
| **Budget Controls** | Daily/monthly limits with hard and soft enforcement | [Budgets](https://github.com/adham90/ruby_llm-agents/wiki/Budget-Controls) |
|
|
128
|
+
| **Multi-Tenancy** | Per-tenant API keys, budgets, circuit breakers, and execution isolation | [Multi-Tenancy](https://github.com/adham90/ruby_llm-agents/wiki/Multi-Tenancy) |
|
|
129
|
+
| **Async/Fiber** | Concurrent execution with Ruby fibers for high-throughput workloads | [Async](https://github.com/adham90/ruby_llm-agents/wiki/Async-Fiber) |
|
|
130
|
+
| **Dashboard** | Real-time Turbo-powered monitoring UI | [Dashboard](https://github.com/adham90/ruby_llm-agents/wiki/Dashboard) |
|
|
131
|
+
| **Streaming** | Real-time response streaming with TTFT tracking | [Streaming](https://github.com/adham90/ruby_llm-agents/wiki/Streaming) |
|
|
132
|
+
| **Conversation History** | Multi-turn conversations with message history | [Conversation History](https://github.com/adham90/ruby_llm-agents/wiki/Conversation-History) |
|
|
133
|
+
| **Attachments** | Images, PDFs, and multimodal support | [Attachments](https://github.com/adham90/ruby_llm-agents/wiki/Attachments) |
|
|
134
|
+
| **Embeddings** | Vector embeddings with batching, caching, and preprocessing | [Embeddings](https://github.com/adham90/ruby_llm-agents/wiki/Embeddings) |
|
|
135
|
+
| **Image Operations** | Generation, analysis, editing, pipelines with cost tracking | [Images](https://github.com/adham90/ruby_llm-agents/wiki/Image-Generation) |
|
|
136
|
+
| **Alerts** | Slack, webhook, and custom notifications | [Alerts](https://github.com/adham90/ruby_llm-agents/wiki/Alerts) |
|
|
183
137
|
|
|
184
|
-
|
|
138
|
+
## Quick Start
|
|
185
139
|
|
|
186
|
-
###
|
|
140
|
+
### Installation
|
|
187
141
|
|
|
188
|
-
|
|
142
|
+
```ruby
|
|
143
|
+
# Gemfile
|
|
144
|
+
gem "ruby_llm-agents"
|
|
145
|
+
```
|
|
189
146
|
|
|
190
147
|
```bash
|
|
191
|
-
|
|
192
|
-
rails generate ruby_llm_agents:
|
|
193
|
-
rails
|
|
194
|
-
rails generate ruby_llm_agents:background_remover Photo
|
|
195
|
-
rails generate ruby_llm_agents:image_pipeline Ecommerce --steps generate,upscale,analyze
|
|
148
|
+
bundle install
|
|
149
|
+
rails generate ruby_llm_agents:install
|
|
150
|
+
rails db:migrate
|
|
196
151
|
```
|
|
197
152
|
|
|
198
|
-
|
|
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")
|
|
153
|
+
### Configure API Keys
|
|
203
154
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
155
|
+
```bash
|
|
156
|
+
# .env
|
|
157
|
+
OPENAI_API_KEY=sk-...
|
|
158
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
159
|
+
GOOGLE_API_KEY=...
|
|
160
|
+
```
|
|
209
161
|
|
|
210
|
-
|
|
211
|
-
result = LLM::Image::PhotoBackgroundRemover.call(image: "portrait.jpg")
|
|
212
|
-
result.save("portrait_transparent.png")
|
|
162
|
+
### Generate an Agent
|
|
213
163
|
|
|
214
|
-
|
|
215
|
-
|
|
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
|
|
164
|
+
```bash
|
|
165
|
+
rails generate ruby_llm_agents:agent SearchIntent query:required
|
|
222
166
|
```
|
|
223
167
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
168
|
+
This creates `app/agents/search_intent_agent.rb` with the agent class ready to customize.
|
|
169
|
+
|
|
170
|
+
### Mount the Dashboard
|
|
171
|
+
|
|
172
|
+
```ruby
|
|
173
|
+
# config/routes.rb
|
|
174
|
+
mount RubyLLM::Agents::Engine => "/agents"
|
|
175
|
+
```
|
|
231
176
|
|
|
232
|
-
|
|
177
|
+

|
|
233
178
|
|
|
234
179
|
## Documentation
|
|
235
180
|
|
|
181
|
+
> **AI Agents:** For comprehensive documentation optimized for AI consumption, see [LLMS.txt](LLMS.txt)
|
|
182
|
+
|
|
236
183
|
> **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
184
|
|
|
238
185
|
| Guide | Description |
|
|
@@ -240,13 +187,11 @@ See [Image Operations](https://github.com/adham90/ruby_llm-agents/wiki/Image-Gen
|
|
|
240
187
|
| [Getting Started](https://github.com/adham90/ruby_llm-agents/wiki/Getting-Started) | Installation, configuration, first agent |
|
|
241
188
|
| [Agent DSL](https://github.com/adham90/ruby_llm-agents/wiki/Agent-DSL) | All DSL options: model, temperature, params, caching, description |
|
|
242
189
|
| [Reliability](https://github.com/adham90/ruby_llm-agents/wiki/Reliability) | Retries, fallbacks, circuit breakers, timeouts, reliability block |
|
|
243
|
-
| [Workflows](https://github.com/adham90/ruby_llm-agents/wiki/Workflows) | Pipelines, parallel execution, routers |
|
|
244
190
|
| [Budget Controls](https://github.com/adham90/ruby_llm-agents/wiki/Budget-Controls) | Spending limits, alerts, enforcement |
|
|
245
191
|
| [Multi-Tenancy](https://github.com/adham90/ruby_llm-agents/wiki/Multi-Tenancy) | Per-tenant budgets, isolation, configuration |
|
|
246
192
|
| [Async/Fiber](https://github.com/adham90/ruby_llm-agents/wiki/Async-Fiber) | Concurrent execution with Ruby fibers |
|
|
247
193
|
| [Testing Agents](https://github.com/adham90/ruby_llm-agents/wiki/Testing-Agents) | RSpec patterns, mocking, dry_run mode |
|
|
248
194
|
| [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
195
|
| [Embeddings](https://github.com/adham90/ruby_llm-agents/wiki/Embeddings) | Vector embeddings, batching, caching, preprocessing |
|
|
251
196
|
| [Image Generation](https://github.com/adham90/ruby_llm-agents/wiki/Image-Generation) | Text-to-image, templates, content policy, cost tracking |
|
|
252
197
|
| [Dashboard](https://github.com/adham90/ruby_llm-agents/wiki/Dashboard) | Setup, authentication, analytics |
|
|
@@ -254,184 +199,6 @@ See [Image Operations](https://github.com/adham90/ruby_llm-agents/wiki/Image-Gen
|
|
|
254
199
|
| [API Reference](https://github.com/adham90/ruby_llm-agents/wiki/API-Reference) | Complete class documentation |
|
|
255
200
|
| [Examples](https://github.com/adham90/ruby_llm-agents/wiki/Examples) | Real-world use cases and patterns |
|
|
256
201
|
|
|
257
|
-
## Reliability Features
|
|
258
|
-
|
|
259
|
-
Build resilient agents with built-in fault tolerance:
|
|
260
|
-
|
|
261
|
-
```ruby
|
|
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
|
|
281
|
-
|
|
282
|
-
param :query, required: true
|
|
283
|
-
|
|
284
|
-
def user_prompt
|
|
285
|
-
query
|
|
286
|
-
end
|
|
287
|
-
end
|
|
288
|
-
end
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
### Enhanced Result Object
|
|
292
|
-
|
|
293
|
-
The result object provides detailed execution metadata:
|
|
294
|
-
|
|
295
|
-
```ruby
|
|
296
|
-
result = LLM::ReliableAgent.call(query: "test")
|
|
297
|
-
|
|
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
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
## Workflow Orchestration
|
|
314
|
-
|
|
315
|
-
Compose agents into complex workflows:
|
|
316
|
-
|
|
317
|
-
```ruby
|
|
318
|
-
# Sequential pipeline - each step's output feeds the next
|
|
319
|
-
class ContentPipeline < RubyLLM::Agents::Workflow::Pipeline
|
|
320
|
-
timeout 60.seconds
|
|
321
|
-
max_cost 1.00
|
|
322
|
-
|
|
323
|
-
step :classify, agent: ClassifierAgent
|
|
324
|
-
step :enrich, agent: EnricherAgent
|
|
325
|
-
step :format, agent: FormatterAgent, optional: true
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
result = ContentPipeline.call(text: data)
|
|
329
|
-
result.steps[:classify].content # Individual step result
|
|
330
|
-
result.total_cost # Sum of all steps
|
|
331
|
-
|
|
332
|
-
# Parallel execution - run agents concurrently
|
|
333
|
-
class AnalysisPipeline < RubyLLM::Agents::Workflow::Parallel
|
|
334
|
-
fail_fast false # Continue even if a branch fails
|
|
335
|
-
|
|
336
|
-
branch :sentiment, agent: SentimentAgent
|
|
337
|
-
branch :entities, agent: EntityAgent
|
|
338
|
-
branch :summary, agent: SummaryAgent
|
|
339
|
-
end
|
|
340
|
-
|
|
341
|
-
result = AnalysisPipeline.call(text: content)
|
|
342
|
-
result.branches[:sentiment].content # Individual branch result
|
|
343
|
-
|
|
344
|
-
# Conditional routing - dispatch based on classification
|
|
345
|
-
class SupportRouter < RubyLLM::Agents::Workflow::Router
|
|
346
|
-
classifier_model "gpt-4o-mini"
|
|
347
|
-
|
|
348
|
-
route :support, to: SupportAgent, description: "Technical support issues"
|
|
349
|
-
route :sales, to: SalesAgent, description: "Sales and pricing questions"
|
|
350
|
-
route :default, to: GeneralAgent
|
|
351
|
-
end
|
|
352
|
-
|
|
353
|
-
result = SupportRouter.call(message: user_input)
|
|
354
|
-
result.routed_to # :support, :sales, or :default
|
|
355
|
-
```
|
|
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
|
-
|
|
394
|
-
## Cost & Budget Controls
|
|
395
|
-
|
|
396
|
-
Track and limit LLM spending:
|
|
397
|
-
|
|
398
|
-
```ruby
|
|
399
|
-
# config/initializers/ruby_llm_agents.rb
|
|
400
|
-
RubyLLM::Agents.configure do |config|
|
|
401
|
-
config.budgets = {
|
|
402
|
-
global_daily: 100.0, # $100/day limit
|
|
403
|
-
global_monthly: 2000.0, # $2000/month limit
|
|
404
|
-
per_agent_daily: {
|
|
405
|
-
"ExpensiveAgent" => 50.0
|
|
406
|
-
},
|
|
407
|
-
enforcement: :hard # Block when exceeded
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
config.alerts = {
|
|
411
|
-
on_events: [:budget_soft_cap, :budget_hard_cap, :breaker_open],
|
|
412
|
-
slack_webhook_url: ENV['SLACK_WEBHOOK_URL']
|
|
413
|
-
}
|
|
414
|
-
end
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
## Dashboard
|
|
418
|
-
|
|
419
|
-
Mount the real-time monitoring dashboard:
|
|
420
|
-
|
|
421
|
-
```ruby
|
|
422
|
-
# config/routes.rb
|
|
423
|
-
mount RubyLLM::Agents::Engine => "/agents"
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-

|
|
427
|
-
|
|
428
|
-
Features:
|
|
429
|
-
- Execution history with filtering and search
|
|
430
|
-
- Cost analytics by agent, model, and time period
|
|
431
|
-
- Performance trends and charts
|
|
432
|
-
- Token usage breakdowns
|
|
433
|
-
- Error tracking and debugging
|
|
434
|
-
|
|
435
202
|
## Requirements
|
|
436
203
|
|
|
437
204
|
- **Ruby** >= 3.1.0
|
|
@@ -48,7 +48,6 @@ module RubyLLM
|
|
|
48
48
|
@agents_by_type = {
|
|
49
49
|
agent: @agents.select { |a| a[:agent_type] == "agent" },
|
|
50
50
|
embedder: @agents.select { |a| a[:agent_type] == "embedder" },
|
|
51
|
-
moderator: @agents.select { |a| a[:agent_type] == "moderator" },
|
|
52
51
|
speaker: @agents.select { |a| a[:agent_type] == "speaker" },
|
|
53
52
|
transcriber: @agents.select { |a| a[:agent_type] == "transcriber" },
|
|
54
53
|
image_generator: @agents.select { |a| a[:agent_type] == "image_generator" }
|
|
@@ -60,7 +59,7 @@ module RubyLLM
|
|
|
60
59
|
Rails.logger.error("[RubyLLM::Agents] Error loading agents: #{e.message}")
|
|
61
60
|
@agents = []
|
|
62
61
|
@deleted_agents = []
|
|
63
|
-
@agents_by_type = { agent: [], embedder: [],
|
|
62
|
+
@agents_by_type = { agent: [], embedder: [], speaker: [], transcriber: [], image_generator: [] }
|
|
64
63
|
@agent_count = 0
|
|
65
64
|
@deleted_count = 0
|
|
66
65
|
@sort_params = { column: DEFAULT_AGENT_SORT_COLUMN, direction: DEFAULT_AGENT_SORT_DIRECTION }
|
|
@@ -119,13 +118,11 @@ module RubyLLM
|
|
|
119
118
|
def load_filter_options
|
|
120
119
|
# Single query to get all filter options (fixes N+1)
|
|
121
120
|
filter_data = Execution.by_agent(@agent_type)
|
|
122
|
-
.where.not(
|
|
123
|
-
.or(Execution.by_agent(@agent_type).where.not(model_id: nil))
|
|
121
|
+
.where.not(model_id: nil)
|
|
124
122
|
.or(Execution.by_agent(@agent_type).where.not(temperature: nil))
|
|
125
|
-
.pluck(:
|
|
123
|
+
.pluck(:model_id, :temperature)
|
|
126
124
|
|
|
127
|
-
@
|
|
128
|
-
@models = filter_data.map { |d| d[1] }.compact.uniq.sort
|
|
125
|
+
@models = filter_data.map(&:first).compact.uniq.sort
|
|
129
126
|
@temperatures = filter_data.map(&:last).compact.uniq.sort
|
|
130
127
|
end
|
|
131
128
|
|
|
@@ -149,7 +146,7 @@ module RubyLLM
|
|
|
149
146
|
|
|
150
147
|
# Builds a filtered scope for the current agent's executions
|
|
151
148
|
#
|
|
152
|
-
# Applies filters in order: status,
|
|
149
|
+
# Applies filters in order: status, model, temperature, time.
|
|
153
150
|
# Each filter is optional and only applied if values are provided.
|
|
154
151
|
#
|
|
155
152
|
# @return [ActiveRecord::Relation] Filtered execution scope
|
|
@@ -160,10 +157,6 @@ module RubyLLM
|
|
|
160
157
|
statuses = parse_array_param(:statuses)
|
|
161
158
|
scope = apply_status_filter(scope, statuses) if statuses.any?
|
|
162
159
|
|
|
163
|
-
# Apply version filter
|
|
164
|
-
versions = parse_array_param(:versions)
|
|
165
|
-
scope = scope.where(agent_version: versions) if versions.any?
|
|
166
|
-
|
|
167
160
|
# Apply model filter
|
|
168
161
|
models = parse_array_param(:models)
|
|
169
162
|
scope = scope.where(model_id: models) if models.any?
|
|
@@ -188,37 +181,6 @@ module RubyLLM
|
|
|
188
181
|
@trend_data = Execution.trend_analysis(agent_type: @agent_type, days: 30)
|
|
189
182
|
@status_distribution = Execution.by_agent(@agent_type).group(:status).count
|
|
190
183
|
@finish_reason_distribution = Execution.by_agent(@agent_type).finish_reason_distribution
|
|
191
|
-
load_version_comparison
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
# Loads version comparison data if multiple versions exist
|
|
195
|
-
#
|
|
196
|
-
# Includes trend data for sparkline charts.
|
|
197
|
-
#
|
|
198
|
-
# @return [void]
|
|
199
|
-
def load_version_comparison
|
|
200
|
-
return unless @versions.size >= 2
|
|
201
|
-
|
|
202
|
-
# Default to comparing two most recent versions
|
|
203
|
-
v1 = params[:compare_v1] || @versions[0]
|
|
204
|
-
v2 = params[:compare_v2] || @versions[1]
|
|
205
|
-
|
|
206
|
-
comparison_data = Execution.compare_versions(@agent_type, v1, v2, period: :this_month)
|
|
207
|
-
|
|
208
|
-
# Fetch trend data for sparklines
|
|
209
|
-
v1_trend = Execution.version_trend_data(@agent_type, v1, days: 14)
|
|
210
|
-
v2_trend = Execution.version_trend_data(@agent_type, v2, days: 14)
|
|
211
|
-
|
|
212
|
-
@version_comparison = {
|
|
213
|
-
v1: v1,
|
|
214
|
-
v2: v2,
|
|
215
|
-
data: comparison_data,
|
|
216
|
-
v1_trend: v1_trend,
|
|
217
|
-
v2_trend: v2_trend
|
|
218
|
-
}
|
|
219
|
-
rescue StandardError => e
|
|
220
|
-
Rails.logger.debug("[RubyLLM::Agents] Version comparison error: #{e.message}")
|
|
221
|
-
@version_comparison = nil
|
|
222
184
|
end
|
|
223
185
|
|
|
224
186
|
# Loads the current agent class configuration
|
|
@@ -234,7 +196,6 @@ module RubyLLM
|
|
|
234
196
|
# Common config for all types
|
|
235
197
|
@config = {
|
|
236
198
|
model: safe_config_call(:model),
|
|
237
|
-
version: safe_config_call(:version) || "N/A",
|
|
238
199
|
description: safe_config_call(:description)
|
|
239
200
|
}
|
|
240
201
|
|
|
@@ -242,8 +203,6 @@ module RubyLLM
|
|
|
242
203
|
case @agent_type_kind
|
|
243
204
|
when "embedder"
|
|
244
205
|
load_embedder_config
|
|
245
|
-
when "moderator"
|
|
246
|
-
load_moderator_config
|
|
247
206
|
when "speaker"
|
|
248
207
|
load_speaker_config
|
|
249
208
|
when "transcriber"
|
|
@@ -284,16 +243,6 @@ module RubyLLM
|
|
|
284
243
|
)
|
|
285
244
|
end
|
|
286
245
|
|
|
287
|
-
# Loads configuration specific to Moderators
|
|
288
|
-
#
|
|
289
|
-
# @return [void]
|
|
290
|
-
def load_moderator_config
|
|
291
|
-
@config.merge!(
|
|
292
|
-
threshold: safe_config_call(:threshold),
|
|
293
|
-
categories: safe_config_call(:categories)
|
|
294
|
-
)
|
|
295
|
-
end
|
|
296
|
-
|
|
297
246
|
# Loads configuration specific to Speakers
|
|
298
247
|
#
|
|
299
248
|
# @return [void]
|