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.
Files changed (190) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +101 -334
  3. data/app/controllers/concerns/ruby_llm/agents/sortable.rb +0 -1
  4. data/app/controllers/ruby_llm/agents/agents_controller.rb +5 -56
  5. data/app/controllers/ruby_llm/agents/dashboard_controller.rb +22 -106
  6. data/app/controllers/ruby_llm/agents/executions_controller.rb +4 -114
  7. data/app/controllers/ruby_llm/agents/tenants_controller.rb +30 -2
  8. data/app/helpers/ruby_llm/agents/application_helper.rb +19 -53
  9. data/app/models/ruby_llm/agents/execution/analytics.rb +13 -54
  10. data/app/models/ruby_llm/agents/execution/scopes.rb +61 -14
  11. data/app/models/ruby_llm/agents/execution.rb +46 -10
  12. data/app/models/ruby_llm/agents/execution_detail.rb +18 -0
  13. data/app/models/ruby_llm/agents/tenant/budgetable.rb +132 -24
  14. data/app/models/ruby_llm/agents/tenant/incrementable.rb +117 -0
  15. data/app/models/ruby_llm/agents/tenant/resettable.rb +128 -0
  16. data/app/models/ruby_llm/agents/tenant/trackable.rb +46 -12
  17. data/app/models/ruby_llm/agents/tenant.rb +2 -3
  18. data/app/models/ruby_llm/agents/tenant_budget.rb +6 -3
  19. data/app/services/ruby_llm/agents/agent_registry.rb +6 -112
  20. data/app/views/layouts/ruby_llm/agents/application.html.erb +87 -252
  21. data/app/views/ruby_llm/agents/agents/_config_agent.html.erb +71 -218
  22. data/app/views/ruby_llm/agents/agents/_config_embedder.html.erb +20 -63
  23. data/app/views/ruby_llm/agents/agents/_config_image_generator.html.erb +44 -131
  24. data/app/views/ruby_llm/agents/agents/_config_moderator.html.erb +16 -57
  25. data/app/views/ruby_llm/agents/agents/_config_speaker.html.erb +39 -104
  26. data/app/views/ruby_llm/agents/agents/_config_transcriber.html.erb +29 -82
  27. data/app/views/ruby_llm/agents/agents/_empty_state.html.erb +4 -14
  28. data/app/views/ruby_llm/agents/agents/index.html.erb +105 -274
  29. data/app/views/ruby_llm/agents/agents/show.html.erb +248 -378
  30. data/app/views/ruby_llm/agents/dashboard/_action_center.html.erb +29 -52
  31. data/app/views/ruby_llm/agents/dashboard/_tenant_budget.html.erb +73 -99
  32. data/app/views/ruby_llm/agents/dashboard/index.html.erb +228 -433
  33. data/app/views/ruby_llm/agents/executions/_execution.html.erb +1 -1
  34. data/app/views/ruby_llm/agents/executions/_filters.html.erb +4 -25
  35. data/app/views/ruby_llm/agents/executions/_list.html.erb +111 -152
  36. data/app/views/ruby_llm/agents/executions/index.html.erb +5 -7
  37. data/app/views/ruby_llm/agents/executions/show.html.erb +526 -1037
  38. data/app/views/ruby_llm/agents/shared/_agent_type_badge.html.erb +5 -21
  39. data/app/views/ruby_llm/agents/shared/_executions_table.html.erb +70 -191
  40. data/app/views/ruby_llm/agents/shared/_filter_dropdown.html.erb +16 -44
  41. data/app/views/ruby_llm/agents/shared/_select_dropdown.html.erb +12 -41
  42. data/app/views/ruby_llm/agents/shared/_status_badge.html.erb +11 -65
  43. data/app/views/ruby_llm/agents/shared/_tenant_filter.html.erb +6 -5
  44. data/app/views/ruby_llm/agents/system_config/show.html.erb +240 -351
  45. data/app/views/ruby_llm/agents/tenants/_form.html.erb +67 -77
  46. data/app/views/ruby_llm/agents/tenants/edit.html.erb +7 -9
  47. data/app/views/ruby_llm/agents/tenants/index.html.erb +100 -122
  48. data/app/views/ruby_llm/agents/tenants/show.html.erb +146 -336
  49. data/config/routes.rb +0 -13
  50. data/lib/generators/ruby_llm_agents/install_generator.rb +9 -14
  51. data/lib/generators/ruby_llm_agents/migrate_structure_generator.rb +2 -12
  52. data/lib/generators/ruby_llm_agents/restructure_generator.rb +0 -2
  53. data/lib/generators/ruby_llm_agents/templates/add_usage_counters_to_tenants_migration.rb.tt +37 -0
  54. data/lib/generators/ruby_llm_agents/templates/agent.rb.tt +1 -2
  55. data/lib/generators/ruby_llm_agents/templates/application_agent.rb.tt +1 -1
  56. data/lib/generators/ruby_llm_agents/templates/application_image_pipeline.rb.tt +0 -1
  57. data/lib/generators/ruby_llm_agents/templates/create_execution_details_migration.rb.tt +27 -0
  58. data/lib/generators/ruby_llm_agents/templates/create_tenants_migration.rb.tt +25 -0
  59. data/lib/generators/ruby_llm_agents/templates/image_pipeline.rb.tt +0 -1
  60. data/lib/generators/ruby_llm_agents/templates/initializer.rb.tt +9 -12
  61. data/lib/generators/ruby_llm_agents/templates/migration.rb.tt +40 -71
  62. data/lib/generators/ruby_llm_agents/templates/remove_agent_version_migration.rb.tt +13 -0
  63. data/lib/generators/ruby_llm_agents/templates/remove_workflow_columns_migration.rb.tt +19 -0
  64. data/lib/generators/ruby_llm_agents/templates/skills/AGENTS.md.tt +2 -4
  65. data/lib/generators/ruby_llm_agents/templates/skills/IMAGE_PIPELINES.md.tt +0 -1
  66. data/lib/generators/ruby_llm_agents/templates/split_execution_details_migration.rb.tt +232 -0
  67. data/lib/generators/ruby_llm_agents/upgrade_generator.rb +58 -262
  68. data/lib/ruby_llm/agents/audio/speaker.rb +0 -1
  69. data/lib/ruby_llm/agents/audio/transcriber.rb +0 -1
  70. data/lib/ruby_llm/agents/base_agent.rb +52 -6
  71. data/lib/ruby_llm/agents/core/base/callbacks.rb +142 -0
  72. data/lib/ruby_llm/agents/core/base.rb +23 -55
  73. data/lib/ruby_llm/agents/core/configuration.rb +58 -117
  74. data/lib/ruby_llm/agents/core/errors.rb +0 -58
  75. data/lib/ruby_llm/agents/core/instrumentation.rb +157 -110
  76. data/lib/ruby_llm/agents/core/llm_tenant.rb +8 -7
  77. data/lib/ruby_llm/agents/core/version.rb +1 -1
  78. data/lib/ruby_llm/agents/dsl/base.rb +157 -17
  79. data/lib/ruby_llm/agents/dsl/caching.rb +33 -2
  80. data/lib/ruby_llm/agents/dsl/reliability.rb +148 -0
  81. data/lib/ruby_llm/agents/dsl.rb +1 -2
  82. data/lib/ruby_llm/agents/image/analyzer/execution.rb +1 -2
  83. data/lib/ruby_llm/agents/image/background_remover/execution.rb +1 -2
  84. data/lib/ruby_llm/agents/image/concerns/image_operation_dsl.rb +1 -13
  85. data/lib/ruby_llm/agents/image/concerns/image_operation_execution.rb +2 -2
  86. data/lib/ruby_llm/agents/image/editor/dsl.rb +0 -14
  87. data/lib/ruby_llm/agents/image/editor/execution.rb +1 -10
  88. data/lib/ruby_llm/agents/image/editor.rb +0 -1
  89. data/lib/ruby_llm/agents/image/generator.rb +0 -21
  90. data/lib/ruby_llm/agents/image/pipeline/dsl.rb +0 -13
  91. data/lib/ruby_llm/agents/image/pipeline/execution.rb +0 -1
  92. data/lib/ruby_llm/agents/image/transformer/dsl.rb +0 -13
  93. data/lib/ruby_llm/agents/image/transformer/execution.rb +1 -10
  94. data/lib/ruby_llm/agents/image/transformer.rb +0 -1
  95. data/lib/ruby_llm/agents/image/upscaler/execution.rb +1 -2
  96. data/lib/ruby_llm/agents/image/variator/execution.rb +1 -2
  97. data/lib/ruby_llm/agents/infrastructure/alert_manager.rb +78 -173
  98. data/lib/ruby_llm/agents/infrastructure/budget/budget_query.rb +66 -2
  99. data/lib/ruby_llm/agents/infrastructure/budget/spend_recorder.rb +0 -12
  100. data/lib/ruby_llm/agents/infrastructure/circuit_breaker.rb +10 -13
  101. data/lib/ruby_llm/agents/pipeline/context.rb +0 -1
  102. data/lib/ruby_llm/agents/pipeline/middleware/budget.rb +28 -4
  103. data/lib/ruby_llm/agents/pipeline/middleware/cache.rb +3 -10
  104. data/lib/ruby_llm/agents/pipeline/middleware/instrumentation.rb +88 -55
  105. data/lib/ruby_llm/agents/pipeline/middleware/tenant.rb +5 -41
  106. data/lib/ruby_llm/agents/rails/engine.rb +6 -6
  107. data/lib/ruby_llm/agents/results/base.rb +1 -49
  108. data/lib/ruby_llm/agents/text/embedder.rb +0 -1
  109. data/lib/ruby_llm/agents.rb +1 -9
  110. data/lib/tasks/ruby_llm_agents.rake +34 -0
  111. metadata +12 -81
  112. data/app/controllers/ruby_llm/agents/api_configurations_controller.rb +0 -214
  113. data/app/controllers/ruby_llm/agents/workflows_controller.rb +0 -544
  114. data/app/mailers/ruby_llm/agents/alert_mailer.rb +0 -84
  115. data/app/mailers/ruby_llm/agents/application_mailer.rb +0 -28
  116. data/app/models/ruby_llm/agents/api_configuration.rb +0 -386
  117. data/app/models/ruby_llm/agents/execution/workflow.rb +0 -170
  118. data/app/models/ruby_llm/agents/tenant/configurable.rb +0 -135
  119. data/app/views/ruby_llm/agents/agents/_agent.html.erb +0 -98
  120. data/app/views/ruby_llm/agents/agents/_version_comparison.html.erb +0 -186
  121. data/app/views/ruby_llm/agents/agents/_workflow.html.erb +0 -126
  122. data/app/views/ruby_llm/agents/alert_mailer/alert_notification.html.erb +0 -107
  123. data/app/views/ruby_llm/agents/alert_mailer/alert_notification.text.erb +0 -18
  124. data/app/views/ruby_llm/agents/api_configurations/_api_key_field.html.erb +0 -34
  125. data/app/views/ruby_llm/agents/api_configurations/_form.html.erb +0 -288
  126. data/app/views/ruby_llm/agents/api_configurations/edit.html.erb +0 -95
  127. data/app/views/ruby_llm/agents/api_configurations/edit_tenant.html.erb +0 -97
  128. data/app/views/ruby_llm/agents/api_configurations/show.html.erb +0 -214
  129. data/app/views/ruby_llm/agents/api_configurations/tenant.html.erb +0 -179
  130. data/app/views/ruby_llm/agents/dashboard/_agent_comparison.html.erb +0 -73
  131. data/app/views/ruby_llm/agents/dashboard/_alerts_feed.html.erb +0 -62
  132. data/app/views/ruby_llm/agents/dashboard/_breaker_strip.html.erb +0 -47
  133. data/app/views/ruby_llm/agents/dashboard/_budgets_bar.html.erb +0 -75
  134. data/app/views/ruby_llm/agents/dashboard/_model_comparison.html.erb +0 -56
  135. data/app/views/ruby_llm/agents/dashboard/_model_cost_breakdown.html.erb +0 -115
  136. data/app/views/ruby_llm/agents/dashboard/_now_strip.html.erb +0 -59
  137. data/app/views/ruby_llm/agents/dashboard/_top_errors.html.erb +0 -60
  138. data/app/views/ruby_llm/agents/executions/_workflow_summary.html.erb +0 -86
  139. data/app/views/ruby_llm/agents/executions/dry_run.html.erb +0 -149
  140. data/app/views/ruby_llm/agents/shared/_breadcrumbs.html.erb +0 -48
  141. data/app/views/ruby_llm/agents/shared/_nav_link.html.erb +0 -27
  142. data/app/views/ruby_llm/agents/shared/_stat_card.html.erb +0 -14
  143. data/app/views/ruby_llm/agents/shared/_workflow_type_badge.html.erb +0 -35
  144. data/app/views/ruby_llm/agents/workflows/_empty_state.html.erb +0 -22
  145. data/app/views/ruby_llm/agents/workflows/_step_performance.html.erb +0 -228
  146. data/app/views/ruby_llm/agents/workflows/_structure_dsl.html.erb +0 -539
  147. data/app/views/ruby_llm/agents/workflows/_structure_parallel.html.erb +0 -76
  148. data/app/views/ruby_llm/agents/workflows/_structure_pipeline.html.erb +0 -74
  149. data/app/views/ruby_llm/agents/workflows/_structure_router.html.erb +0 -108
  150. data/app/views/ruby_llm/agents/workflows/_workflow_diagram.html.erb +0 -920
  151. data/app/views/ruby_llm/agents/workflows/index.html.erb +0 -179
  152. data/app/views/ruby_llm/agents/workflows/show.html.erb +0 -467
  153. data/lib/generators/ruby_llm_agents/api_configuration_generator.rb +0 -100
  154. data/lib/generators/ruby_llm_agents/templates/add_workflow_migration.rb.tt +0 -38
  155. data/lib/generators/ruby_llm_agents/templates/application_workflow.rb.tt +0 -48
  156. data/lib/generators/ruby_llm_agents/templates/create_api_configurations_migration.rb.tt +0 -90
  157. data/lib/generators/ruby_llm_agents/templates/skills/WORKFLOWS.md.tt +0 -551
  158. data/lib/ruby_llm/agents/core/base/moderation_dsl.rb +0 -181
  159. data/lib/ruby_llm/agents/core/base/moderation_execution.rb +0 -274
  160. data/lib/ruby_llm/agents/core/resolved_config.rb +0 -348
  161. data/lib/ruby_llm/agents/image/generator/content_policy.rb +0 -95
  162. data/lib/ruby_llm/agents/infrastructure/redactor.rb +0 -130
  163. data/lib/ruby_llm/agents/results/moderation_result.rb +0 -158
  164. data/lib/ruby_llm/agents/text/moderator.rb +0 -237
  165. data/lib/ruby_llm/agents/workflow/approval.rb +0 -205
  166. data/lib/ruby_llm/agents/workflow/approval_store.rb +0 -179
  167. data/lib/ruby_llm/agents/workflow/async.rb +0 -220
  168. data/lib/ruby_llm/agents/workflow/async_executor.rb +0 -156
  169. data/lib/ruby_llm/agents/workflow/dsl/executor.rb +0 -467
  170. data/lib/ruby_llm/agents/workflow/dsl/input_schema.rb +0 -244
  171. data/lib/ruby_llm/agents/workflow/dsl/iteration_executor.rb +0 -289
  172. data/lib/ruby_llm/agents/workflow/dsl/parallel_group.rb +0 -107
  173. data/lib/ruby_llm/agents/workflow/dsl/route_builder.rb +0 -150
  174. data/lib/ruby_llm/agents/workflow/dsl/schedule_helpers.rb +0 -187
  175. data/lib/ruby_llm/agents/workflow/dsl/step_config.rb +0 -352
  176. data/lib/ruby_llm/agents/workflow/dsl/step_executor.rb +0 -415
  177. data/lib/ruby_llm/agents/workflow/dsl/wait_config.rb +0 -257
  178. data/lib/ruby_llm/agents/workflow/dsl/wait_executor.rb +0 -317
  179. data/lib/ruby_llm/agents/workflow/dsl.rb +0 -576
  180. data/lib/ruby_llm/agents/workflow/instrumentation.rb +0 -249
  181. data/lib/ruby_llm/agents/workflow/notifiers/base.rb +0 -117
  182. data/lib/ruby_llm/agents/workflow/notifiers/email.rb +0 -117
  183. data/lib/ruby_llm/agents/workflow/notifiers/slack.rb +0 -180
  184. data/lib/ruby_llm/agents/workflow/notifiers/webhook.rb +0 -121
  185. data/lib/ruby_llm/agents/workflow/notifiers.rb +0 -70
  186. data/lib/ruby_llm/agents/workflow/orchestrator.rb +0 -416
  187. data/lib/ruby_llm/agents/workflow/result.rb +0 -592
  188. data/lib/ruby_llm/agents/workflow/thread_pool.rb +0 -185
  189. data/lib/ruby_llm/agents/workflow/throttle_manager.rb +0 -206
  190. data/lib/ruby_llm/agents/workflow/wait_result.rb +0 -213
@@ -1,235 +1,88 @@
1
- <%# Configuration partial for Base Agent types %>
2
- <div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6 mb-6">
3
- <h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
4
- Configuration
5
- </h3>
1
+ <%# Configuration partial for Base Agent types - grid layout %>
2
+ <%
3
+ retries_config = config[:retries] || {}
4
+ fallback_models = Array(config[:fallback_models]).compact
5
+ has_retries = (retries_config[:max] || 0) > 0
6
+ has_fallbacks = fallback_models.any?
7
+ has_total_timeout = config[:total_timeout].present?
8
+ has_circuit_breaker = config[:circuit_breaker].present?
9
+ has_any_reliability = has_retries || has_fallbacks || has_total_timeout || has_circuit_breaker
10
+ %>
6
11
 
7
- <!-- Basic Configuration -->
8
- <p class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-3">
9
- Basic
10
- </p>
11
-
12
- <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
13
- <div>
14
- <p class="text-sm text-gray-500 dark:text-gray-400">Model</p>
15
- <p class="font-medium text-gray-900 dark:text-gray-100">
16
- <%= config[:model] %>
17
- </p>
18
- </div>
19
-
20
- <div>
21
- <p class="text-sm text-gray-500 dark:text-gray-400">Temperature</p>
22
- <p class="font-medium text-gray-900 dark:text-gray-100">
23
- <%= config[:temperature] %>
24
- </p>
25
- </div>
26
-
27
- <div>
28
- <p class="text-sm text-gray-500 dark:text-gray-400">Timeout</p>
29
- <p class="font-medium text-gray-900 dark:text-gray-100">
30
- <%= config[:timeout] %> seconds
31
- </p>
32
- </div>
33
-
34
- <div>
35
- <p class="text-sm text-gray-500 dark:text-gray-400">Cache</p>
36
- <p class="font-medium text-gray-900 dark:text-gray-100">
12
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-4 font-mono text-xs">
13
+ <!-- Basic -->
14
+ <div>
15
+ <span class="text-[10px] text-gray-400 dark:text-gray-600 uppercase tracking-wider">basic</span>
16
+ <div class="mt-1.5 space-y-0.5">
17
+ <div class="flex items-center gap-3 py-1">
18
+ <span class="w-20 text-gray-400 dark:text-gray-600">model</span>
19
+ <span class="text-gray-900 dark:text-gray-200"><%= config[:model] %></span>
20
+ </div>
21
+ <div class="flex items-center gap-3 py-1">
22
+ <span class="w-20 text-gray-400 dark:text-gray-600">temperature</span>
23
+ <span class="text-gray-900 dark:text-gray-200"><%= config[:temperature] %></span>
24
+ </div>
25
+ <div class="flex items-center gap-3 py-1">
26
+ <span class="w-20 text-gray-400 dark:text-gray-600">timeout</span>
27
+ <span class="text-gray-900 dark:text-gray-200"><%= config[:timeout] %>s</span>
28
+ </div>
29
+ <div class="flex items-center gap-3 py-1">
30
+ <span class="w-20 text-gray-400 dark:text-gray-600">cache</span>
37
31
  <% if config[:cache_enabled] %>
38
- Enabled (<%= config[:cache_ttl].inspect %>)
32
+ <span class="text-green-500">enabled</span>
33
+ <span class="text-gray-400 dark:text-gray-600">(<%= config[:cache_ttl].inspect %>)</span>
39
34
  <% else %>
40
- <span class="text-gray-400 dark:text-gray-500">Disabled</span>
35
+ <span class="text-gray-400 dark:text-gray-600">disabled</span>
41
36
  <% end %>
42
- </p>
37
+ </div>
43
38
  </div>
44
39
  </div>
45
40
 
46
- <!-- Reliability Configuration -->
47
- <% retries_config = config[:retries] || {}
48
- fallback_models = Array(config[:fallback_models]).compact
49
- has_retries = (retries_config[:max] || 0) > 0
50
- has_fallbacks = fallback_models.any?
51
- has_total_timeout = config[:total_timeout].present?
52
- has_circuit_breaker = config[:circuit_breaker].present?
53
- has_any_reliability = has_retries || has_fallbacks || has_total_timeout || has_circuit_breaker %>
54
-
55
- <div class="border-t border-gray-100 dark:border-gray-700 pt-4 mb-6">
56
- <p class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-3">
57
- Reliability
58
- </p>
59
-
41
+ <!-- Reliability -->
42
+ <div>
43
+ <span class="text-[10px] text-gray-400 dark:text-gray-600 uppercase tracking-wider">reliability</span>
60
44
  <% if has_any_reliability %>
61
- <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
62
- <!-- Retries -->
63
- <div class="flex items-start gap-3 p-3 rounded-lg <%= has_retries ? 'bg-green-50 dark:bg-green-900/20' : 'bg-gray-50 dark:bg-gray-700/50' %>">
64
- <div class="flex-shrink-0 mt-0.5">
65
- <% if has_retries %>
66
- <svg class="w-5 h-5 text-green-500" fill="currentColor" viewBox="0 0 20 20">
67
- <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
68
- </svg>
69
- <% else %>
70
- <svg class="w-5 h-5 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
71
- <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
72
- </svg>
73
- <% end %>
74
- </div>
75
- <div>
76
- <p class="text-sm font-medium text-gray-900 dark:text-gray-100">Retries</p>
77
- <% if has_retries %>
78
- <p class="text-xs text-gray-600 dark:text-gray-400 mt-1">
79
- Max: <%= retries_config[:max] %> &middot; Backoff: <%= retries_config[:backoff] %> &middot; Base: <%= retries_config[:base] %>s &middot; Max delay: <%= retries_config[:max_delay] %>s
80
- </p>
81
- <% else %>
82
- <p class="text-xs text-gray-400 dark:text-gray-500 mt-1">Not configured</p>
83
- <% end %>
84
- </div>
45
+ <div class="mt-1.5 space-y-0.5">
46
+ <div class="flex items-center gap-2 py-1">
47
+ <span class="w-1.5 h-1.5 rounded-full flex-shrink-0 <%= has_retries ? 'bg-green-500' : 'bg-gray-400' %>"></span>
48
+ <span class="w-16 text-gray-400 dark:text-gray-600">retries</span>
49
+ <% if has_retries %>
50
+ <span class="text-gray-900 dark:text-gray-200"><%= retries_config[:max] %> max</span>
51
+ <% else %>
52
+ <span class="text-gray-400 dark:text-gray-600">&mdash;</span>
53
+ <% end %>
85
54
  </div>
86
-
87
- <!-- Fallback Models -->
88
- <div class="flex items-start gap-3 p-3 rounded-lg <%= has_fallbacks ? 'bg-green-50 dark:bg-green-900/20' : 'bg-gray-50 dark:bg-gray-700/50' %>">
89
- <div class="flex-shrink-0 mt-0.5">
90
- <% if has_fallbacks %>
91
- <svg class="w-5 h-5 text-green-500" fill="currentColor" viewBox="0 0 20 20">
92
- <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
93
- </svg>
94
- <% else %>
95
- <svg class="w-5 h-5 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
96
- <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
97
- </svg>
98
- <% end %>
99
- </div>
100
- <div>
101
- <p class="text-sm font-medium text-gray-900 dark:text-gray-100">Fallback Models</p>
102
- <% if has_fallbacks %>
103
- <p class="text-xs text-gray-600 dark:text-gray-400 mt-1"><%= fallback_models.join(" → ") %></p>
104
- <% else %>
105
- <p class="text-xs text-gray-400 dark:text-gray-500 mt-1">Not configured</p>
106
- <% end %>
107
- </div>
55
+ <div class="flex items-center gap-2 py-1">
56
+ <span class="w-1.5 h-1.5 rounded-full flex-shrink-0 <%= has_fallbacks ? 'bg-green-500' : 'bg-gray-400' %>"></span>
57
+ <span class="w-16 text-gray-400 dark:text-gray-600">fallbacks</span>
58
+ <% if has_fallbacks %>
59
+ <span class="text-gray-900 dark:text-gray-200 truncate"><%= fallback_models.join(" → ") %></span>
60
+ <% else %>
61
+ <span class="text-gray-400 dark:text-gray-600">&mdash;</span>
62
+ <% end %>
108
63
  </div>
109
-
110
- <!-- Total Timeout -->
111
- <div class="flex items-start gap-3 p-3 rounded-lg <%= has_total_timeout ? 'bg-green-50 dark:bg-green-900/20' : 'bg-gray-50 dark:bg-gray-700/50' %>">
112
- <div class="flex-shrink-0 mt-0.5">
113
- <% if has_total_timeout %>
114
- <svg class="w-5 h-5 text-green-500" fill="currentColor" viewBox="0 0 20 20">
115
- <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
116
- </svg>
117
- <% else %>
118
- <svg class="w-5 h-5 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
119
- <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
120
- </svg>
121
- <% end %>
122
- </div>
123
- <div>
124
- <p class="text-sm font-medium text-gray-900 dark:text-gray-100">Total Timeout</p>
125
- <% if has_total_timeout %>
126
- <p class="text-xs text-gray-600 dark:text-gray-400 mt-1"><%= config[:total_timeout] %> seconds across all attempts</p>
127
- <% else %>
128
- <p class="text-xs text-gray-400 dark:text-gray-500 mt-1">Not configured</p>
129
- <% end %>
130
- </div>
64
+ <div class="flex items-center gap-2 py-1">
65
+ <span class="w-1.5 h-1.5 rounded-full flex-shrink-0 <%= has_total_timeout ? 'bg-green-500' : 'bg-gray-400' %>"></span>
66
+ <span class="w-16 text-gray-400 dark:text-gray-600">timeout</span>
67
+ <% if has_total_timeout %>
68
+ <span class="text-gray-900 dark:text-gray-200"><%= config[:total_timeout] %>s total</span>
69
+ <% else %>
70
+ <span class="text-gray-400 dark:text-gray-600">&mdash;</span>
71
+ <% end %>
131
72
  </div>
132
-
133
- <!-- Circuit Breaker -->
134
- <div class="flex items-start gap-3 p-3 rounded-lg <%= has_circuit_breaker ? 'bg-green-50 dark:bg-green-900/20' : 'bg-gray-50 dark:bg-gray-700/50' %>">
135
- <div class="flex-shrink-0 mt-0.5">
136
- <% if has_circuit_breaker %>
137
- <svg class="w-5 h-5 text-green-500" fill="currentColor" viewBox="0 0 20 20">
138
- <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
139
- </svg>
140
- <% else %>
141
- <svg class="w-5 h-5 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
142
- <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
143
- </svg>
144
- <% end %>
145
- </div>
146
- <div>
147
- <p class="text-sm font-medium text-gray-900 dark:text-gray-100">Circuit Breaker</p>
148
- <% if has_circuit_breaker %>
149
- <% cb = config[:circuit_breaker] %>
150
- <p class="text-xs text-gray-600 dark:text-gray-400 mt-1">
151
- Opens after <%= cb[:errors] %> errors within <%= cb[:within] %>s &middot; Cooldown: <%= cb[:cooldown] %>s
152
- </p>
153
- <% else %>
154
- <p class="text-xs text-gray-400 dark:text-gray-500 mt-1">Not configured</p>
155
- <% end %>
156
- </div>
73
+ <div class="flex items-center gap-2 py-1">
74
+ <span class="w-1.5 h-1.5 rounded-full flex-shrink-0 <%= has_circuit_breaker ? 'bg-green-500' : 'bg-gray-400' %>"></span>
75
+ <span class="w-16 text-gray-400 dark:text-gray-600">breaker</span>
76
+ <% if has_circuit_breaker %>
77
+ <% cb = config[:circuit_breaker] %>
78
+ <span class="text-gray-900 dark:text-gray-200"><%= cb[:errors] %>/<%= cb[:within] %>s</span>
79
+ <% else %>
80
+ <span class="text-gray-400 dark:text-gray-600">&mdash;</span>
81
+ <% end %>
157
82
  </div>
158
83
  </div>
159
84
  <% else %>
160
- <p class="text-sm text-gray-400 dark:text-gray-500">No reliability features configured</p>
161
- <% end %>
162
- </div>
163
-
164
- <!-- Parameters -->
165
- <% if config[:params].present? && config[:params].any? %>
166
- <div class="border-t border-gray-100 dark:border-gray-700 pt-4">
167
- <p class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-3">
168
- Parameters
169
- </p>
170
- <div class="space-y-2">
171
- <% config[:params].each do |name, opts| %>
172
- <div class="flex items-center text-sm">
173
- <code class="bg-gray-100 dark:bg-gray-700 dark:text-gray-200 px-2 py-0.5 rounded font-mono">
174
- <%= name %>
175
- </code>
176
- <% if opts[:required] %>
177
- <span class="ml-2 text-xs text-red-500 dark:text-red-400 font-medium">required</span>
178
- <% elsif opts[:default].present? %>
179
- <span class="ml-2 text-xs text-gray-400 dark:text-gray-500">default: <%= opts[:default].inspect %></span>
180
- <% else %>
181
- <span class="ml-2 text-xs text-gray-400 dark:text-gray-500">optional</span>
182
- <% end %>
183
- </div>
184
- <% end %>
185
- </div>
186
- </div>
187
- <% end %>
188
-
189
- <!-- Available Tools -->
190
- <%
191
- class_tools = @agent_class.respond_to?(:tools) ? (@agent_class.tools || []) : []
192
- has_dynamic_tools = @agent_class.instance_methods(false).include?(:tools)
193
- %>
194
- <div class="border-t border-gray-100 dark:border-gray-700 pt-4">
195
- <p class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-3">
196
- Available Tools
197
- <% if class_tools.any? %>
198
- <span class="inline-flex items-center ml-2 px-1.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 dark:bg-blue-900/50 text-blue-800 dark:text-blue-300">
199
- <%= class_tools.size %>
200
- </span>
201
- <% elsif has_dynamic_tools %>
202
- <span class="inline-flex items-center ml-2 px-1.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 dark:bg-purple-900/50 text-purple-800 dark:text-purple-300">
203
- Dynamic
204
- </span>
205
- <% else %>
206
- <span class="inline-flex items-center ml-2 px-1.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-400">
207
- 0
208
- </span>
209
- <% end %>
210
- </p>
211
-
212
- <% if class_tools.any? %>
213
- <div class="space-y-2">
214
- <% class_tools.each do |tool_class| %>
215
- <div class="flex items-center text-sm">
216
- <code class="bg-gray-100 dark:bg-gray-700 dark:text-gray-200 px-2 py-0.5 rounded font-mono">
217
- <%= tool_class.respond_to?(:tool_name) ? tool_class.tool_name : tool_class.name.demodulize %>
218
- </code>
219
- </div>
220
- <% end %>
221
- </div>
222
- <% elsif has_dynamic_tools %>
223
- <p class="text-sm text-purple-600 dark:text-purple-400">
224
- This agent configures tools dynamically at runtime based on context.
225
- </p>
226
- <p class="text-xs text-gray-400 dark:text-gray-500 mt-1">
227
- Tools vary per execution based on feature flags and configuration.
228
- </p>
229
- <% else %>
230
- <p class="text-sm text-gray-400 dark:text-gray-500 italic">
231
- No tools configured for this agent.
232
- </p>
85
+ <div class="mt-1 py-1 text-gray-400 dark:text-gray-600">none configured</div>
233
86
  <% end %>
234
87
  </div>
235
88
  </div>
@@ -1,70 +1,27 @@
1
1
  <%# Configuration partial for Embedder types %>
2
- <div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6 mb-6">
3
- <h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
4
- Configuration
5
- </h3>
6
-
7
- <!-- Embedding Configuration -->
8
- <p class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-3">
9
- Embedding Settings
10
- </p>
11
-
12
- <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
13
- <div>
14
- <p class="text-sm text-gray-500 dark:text-gray-400">Model</p>
15
- <p class="font-medium text-gray-900 dark:text-gray-100">
16
- <%= config[:model] %>
17
- </p>
2
+ <div class="font-mono text-xs">
3
+ <span class="text-[10px] text-gray-400 dark:text-gray-600 uppercase tracking-wider">embedding settings</span>
4
+ <div class="mt-1 space-y-px">
5
+ <div class="flex items-center gap-3 py-1 px-2 -mx-2">
6
+ <span class="w-24 text-gray-400 dark:text-gray-600">model</span>
7
+ <span class="text-gray-900 dark:text-gray-200"><%= config[:model] %></span>
18
8
  </div>
19
-
20
- <div>
21
- <p class="text-sm text-gray-500 dark:text-gray-400">Dimensions</p>
22
- <p class="font-medium text-gray-900 dark:text-gray-100">
23
- <% if config[:dimensions] %>
24
- <%= config[:dimensions] %>
25
- <% else %>
26
- <span class="text-gray-400 dark:text-gray-500">Default</span>
27
- <% end %>
28
- </p>
9
+ <div class="flex items-center gap-3 py-1 px-2 -mx-2">
10
+ <span class="w-24 text-gray-400 dark:text-gray-600">dimensions</span>
11
+ <span class="text-gray-900 dark:text-gray-200"><%= config[:dimensions] || 'default' %></span>
29
12
  </div>
30
-
31
- <div>
32
- <p class="text-sm text-gray-500 dark:text-gray-400">Batch Size</p>
33
- <p class="font-medium text-gray-900 dark:text-gray-100">
34
- <% if config[:batch_size] %>
35
- <%= config[:batch_size] %> texts
36
- <% else %>
37
- <span class="text-gray-400 dark:text-gray-500">Default</span>
38
- <% end %>
39
- </p>
13
+ <div class="flex items-center gap-3 py-1 px-2 -mx-2">
14
+ <span class="w-24 text-gray-400 dark:text-gray-600">batch size</span>
15
+ <span class="text-gray-900 dark:text-gray-200"><%= config[:batch_size] ? "#{config[:batch_size]} texts" : 'default' %></span>
40
16
  </div>
41
-
42
- <div>
43
- <p class="text-sm text-gray-500 dark:text-gray-400">Cache</p>
44
- <p class="font-medium text-gray-900 dark:text-gray-100">
45
- <% if config[:cache_enabled] %>
46
- Enabled (<%= config[:cache_ttl].inspect %>)
47
- <% else %>
48
- <span class="text-gray-400 dark:text-gray-500">Disabled</span>
49
- <% end %>
50
- </p>
51
- </div>
52
- </div>
53
-
54
- <!-- Info Section -->
55
- <div class="border-t border-gray-100 dark:border-gray-700 pt-4">
56
- <div class="flex items-start gap-3 p-3 rounded-lg bg-blue-50 dark:bg-blue-900/20">
57
- <div class="flex-shrink-0 mt-0.5">
58
- <svg class="w-5 h-5 text-blue-500" fill="currentColor" viewBox="0 0 20 20">
59
- <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd"/>
60
- </svg>
61
- </div>
62
- <div>
63
- <p class="text-sm font-medium text-gray-900 dark:text-gray-100">Embedder</p>
64
- <p class="text-xs text-gray-600 dark:text-gray-400 mt-1">
65
- Generates vector embeddings for text content. Use for semantic search, similarity matching, and RAG applications.
66
- </p>
67
- </div>
17
+ <div class="flex items-center gap-3 py-1 px-2 -mx-2">
18
+ <span class="w-24 text-gray-400 dark:text-gray-600">cache</span>
19
+ <% if config[:cache_enabled] %>
20
+ <span class="text-green-500">enabled</span>
21
+ <span class="text-gray-400 dark:text-gray-600">(<%= config[:cache_ttl].inspect %>)</span>
22
+ <% else %>
23
+ <span class="text-gray-400 dark:text-gray-600">disabled</span>
24
+ <% end %>
68
25
  </div>
69
26
  </div>
70
27
  </div>
@@ -1,152 +1,65 @@
1
1
  <%# Configuration partial for ImageGenerator types %>
2
- <div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6 mb-6">
3
- <h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
4
- Configuration
5
- </h3>
6
-
7
- <!-- Image Generation Configuration -->
8
- <p class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-3">
9
- Image Generation Settings
10
- </p>
11
-
12
- <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
13
- <div>
14
- <p class="text-sm text-gray-500 dark:text-gray-400">Model</p>
15
- <p class="font-medium text-gray-900 dark:text-gray-100">
16
- <%= config[:model] %>
17
- </p>
2
+ <div class="font-mono text-xs">
3
+ <span class="text-[10px] text-gray-400 dark:text-gray-600 uppercase tracking-wider">image generation settings</span>
4
+ <div class="mt-1 space-y-px">
5
+ <div class="flex items-center gap-3 py-1 px-2 -mx-2">
6
+ <span class="w-28 text-gray-400 dark:text-gray-600">model</span>
7
+ <span class="text-gray-900 dark:text-gray-200"><%= config[:model] %></span>
18
8
  </div>
19
-
20
- <div>
21
- <p class="text-sm text-gray-500 dark:text-gray-400">Size</p>
22
- <p class="font-medium text-gray-900 dark:text-gray-100">
23
- <% if config[:size] %>
24
- <%= config[:size] %>
25
- <% else %>
26
- <span class="text-gray-400 dark:text-gray-500">Default</span>
27
- <% end %>
28
- </p>
9
+ <div class="flex items-center gap-3 py-1 px-2 -mx-2">
10
+ <span class="w-28 text-gray-400 dark:text-gray-600">size</span>
11
+ <span class="text-gray-900 dark:text-gray-200"><%= config[:size] || 'default' %></span>
29
12
  </div>
30
-
31
- <div>
32
- <p class="text-sm text-gray-500 dark:text-gray-400">Quality</p>
33
- <p class="font-medium text-gray-900 dark:text-gray-100">
34
- <% if config[:quality] %>
35
- <span class="<%= config[:quality] == 'hd' ? 'text-green-600 dark:text-green-400' : '' %>">
36
- <%= config[:quality].to_s.upcase %>
37
- </span>
38
- <% else %>
39
- <span class="text-gray-400 dark:text-gray-500">Standard</span>
40
- <% end %>
41
- </p>
13
+ <div class="flex items-center gap-3 py-1 px-2 -mx-2">
14
+ <span class="w-28 text-gray-400 dark:text-gray-600">quality</span>
15
+ <span class="text-gray-900 dark:text-gray-200"><%= config[:quality] ? config[:quality].to_s.upcase : 'standard' %></span>
42
16
  </div>
43
-
44
- <div>
45
- <p class="text-sm text-gray-500 dark:text-gray-400">Style</p>
46
- <p class="font-medium text-gray-900 dark:text-gray-100">
47
- <% if config[:style] %>
48
- <%= config[:style].to_s.titleize %>
49
- <% else %>
50
- <span class="text-gray-400 dark:text-gray-500">Default</span>
51
- <% end %>
52
- </p>
17
+ <div class="flex items-center gap-3 py-1 px-2 -mx-2">
18
+ <span class="w-28 text-gray-400 dark:text-gray-600">style</span>
19
+ <span class="text-gray-900 dark:text-gray-200"><%= config[:style] ? config[:style].to_s.titleize : 'default' %></span>
53
20
  </div>
54
- </div>
55
-
56
- <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
57
- <div>
58
- <p class="text-sm text-gray-500 dark:text-gray-400">Content Policy</p>
59
- <p class="font-medium text-gray-900 dark:text-gray-100">
60
- <% policy = config[:content_policy] || :standard %>
61
- <% policy_colors = {
62
- none: 'text-gray-400 dark:text-gray-500',
63
- standard: 'text-blue-600 dark:text-blue-400',
64
- moderate: 'text-yellow-600 dark:text-yellow-400',
65
- strict: 'text-green-600 dark:text-green-400'
66
- } %>
67
- <span class="<%= policy_colors[policy.to_sym] || 'text-gray-600' %>">
68
- <%= policy.to_s.titleize %>
69
- </span>
70
- </p>
21
+ <div class="flex items-center gap-3 py-1 px-2 -mx-2">
22
+ <span class="w-28 text-gray-400 dark:text-gray-600">content policy</span>
23
+ <span class="text-gray-900 dark:text-gray-200"><%= (config[:content_policy] || :standard).to_s %></span>
71
24
  </div>
72
-
73
- <div>
74
- <p class="text-sm text-gray-500 dark:text-gray-400">Cache</p>
75
- <p class="font-medium text-gray-900 dark:text-gray-100">
76
- <% if config[:cache_enabled] %>
77
- Enabled (<%= config[:cache_ttl].inspect %>)
78
- <% else %>
79
- <span class="text-gray-400 dark:text-gray-500">Disabled</span>
80
- <% end %>
81
- </p>
25
+ <div class="flex items-center gap-3 py-1 px-2 -mx-2">
26
+ <span class="w-28 text-gray-400 dark:text-gray-600">cache</span>
27
+ <% if config[:cache_enabled] %>
28
+ <span class="text-green-500">enabled</span>
29
+ <span class="text-gray-400 dark:text-gray-600">(<%= config[:cache_ttl].inspect %>)</span>
30
+ <% else %>
31
+ <span class="text-gray-400 dark:text-gray-600">disabled</span>
32
+ <% end %>
82
33
  </div>
83
-
84
34
  <% if config[:seed] %>
85
- <div>
86
- <p class="text-sm text-gray-500 dark:text-gray-400">Seed</p>
87
- <p class="font-medium text-gray-900 dark:text-gray-100">
88
- <%= config[:seed] %>
89
- </p>
35
+ <div class="flex items-center gap-3 py-1 px-2 -mx-2">
36
+ <span class="w-28 text-gray-400 dark:text-gray-600">seed</span>
37
+ <span class="text-gray-900 dark:text-gray-200"><%= config[:seed] %></span>
90
38
  </div>
91
39
  <% end %>
92
-
93
40
  <% if config[:guidance_scale] %>
94
- <div>
95
- <p class="text-sm text-gray-500 dark:text-gray-400">Guidance Scale</p>
96
- <p class="font-medium text-gray-900 dark:text-gray-100">
97
- <%= config[:guidance_scale] %>
98
- </p>
41
+ <div class="flex items-center gap-3 py-1 px-2 -mx-2">
42
+ <span class="w-28 text-gray-400 dark:text-gray-600">guidance scale</span>
43
+ <span class="text-gray-900 dark:text-gray-200"><%= config[:guidance_scale] %></span>
99
44
  </div>
100
45
  <% end %>
101
- </div>
102
-
103
- <% if config[:steps] %>
104
- <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
105
- <div>
106
- <p class="text-sm text-gray-500 dark:text-gray-400">Inference Steps</p>
107
- <p class="font-medium text-gray-900 dark:text-gray-100">
108
- <%= config[:steps] %>
109
- </p>
46
+ <% if config[:steps] %>
47
+ <div class="flex items-center gap-3 py-1 px-2 -mx-2">
48
+ <span class="w-28 text-gray-400 dark:text-gray-600">inference steps</span>
49
+ <span class="text-gray-900 dark:text-gray-200"><%= config[:steps] %></span>
110
50
  </div>
111
- </div>
112
- <% end %>
113
-
51
+ <% end %>
52
+ </div>
114
53
  <% if config[:template].present? %>
115
- <div class="mb-6">
116
- <p class="text-sm text-gray-500 dark:text-gray-400 mb-2">Prompt Template</p>
117
- <div class="bg-gray-50 dark:bg-gray-700 rounded-lg p-3">
118
- <code class="text-sm text-gray-700 dark:text-gray-300">
119
- <%= config[:template] %>
120
- </code>
121
- </div>
54
+ <div class="mt-3">
55
+ <span class="text-[10px] text-gray-400 dark:text-gray-600 uppercase tracking-wider">prompt template</span>
56
+ <div class="mt-1 py-1.5 px-2 -mx-2 text-gray-900 dark:text-gray-200"><%= config[:template] %></div>
122
57
  </div>
123
58
  <% end %>
124
-
125
59
  <% if config[:negative_prompt].present? %>
126
- <div class="mb-6">
127
- <p class="text-sm text-gray-500 dark:text-gray-400 mb-2">Negative Prompt</p>
128
- <div class="bg-gray-50 dark:bg-gray-700 rounded-lg p-3">
129
- <code class="text-sm text-gray-700 dark:text-gray-300">
130
- <%= config[:negative_prompt] %>
131
- </code>
132
- </div>
60
+ <div class="mt-3">
61
+ <span class="text-[10px] text-gray-400 dark:text-gray-600 uppercase tracking-wider">negative prompt</span>
62
+ <div class="mt-1 py-1.5 px-2 -mx-2 text-gray-900 dark:text-gray-200"><%= config[:negative_prompt] %></div>
133
63
  </div>
134
64
  <% end %>
135
-
136
- <!-- Info Section -->
137
- <div class="border-t border-gray-100 dark:border-gray-700 pt-4">
138
- <div class="flex items-start gap-3 p-3 rounded-lg bg-teal-50 dark:bg-teal-900/20">
139
- <div class="flex-shrink-0 mt-0.5">
140
- <svg class="w-5 h-5 text-teal-500" fill="currentColor" viewBox="0 0 20 20">
141
- <path fill-rule="evenodd" d="M4 3a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V5a2 2 0 00-2-2H4zm12 12H4l4-8 3 6 2-4 3 6z" clip-rule="evenodd"/>
142
- </svg>
143
- </div>
144
- <div>
145
- <p class="text-sm font-medium text-gray-900 dark:text-gray-100">Image Generator</p>
146
- <p class="text-xs text-gray-600 dark:text-gray-400 mt-1">
147
- Generates images from text prompts using AI models. Supports various sizes, quality levels, and style presets.
148
- </p>
149
- </div>
150
- </div>
151
- </div>
152
65
  </div>