rails-agent-stack 0.1.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 (91) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/README.md +16 -0
  3. data/.github/workflows/ci.yml +32 -0
  4. data/.gitignore +8 -0
  5. data/.rspec +3 -0
  6. data/AGENTS.md +18 -0
  7. data/CHANGELOG.md +40 -0
  8. data/Gemfile +15 -0
  9. data/MIT-LICENSE +21 -0
  10. data/README.md +228 -0
  11. data/Rakefile +8 -0
  12. data/app/assets/images/rails_agents/kip-logo.png +0 -0
  13. data/app/assets/images/rails_agents/kip-waving.png +0 -0
  14. data/app/assets/stylesheets/rails_agents/application.css +411 -0
  15. data/app/controllers/rails_agents/application_controller.rb +25 -0
  16. data/app/controllers/rails_agents/connect_controller.rb +36 -0
  17. data/app/controllers/rails_agents/dashboard_controller.rb +70 -0
  18. data/app/controllers/rails_agents/handshake_controller.rb +55 -0
  19. data/app/controllers/rails_agents/open_wire_inbound_controller.rb +153 -0
  20. data/app/controllers/rails_agents/pulls_controller.rb +42 -0
  21. data/app/controllers/rails_agents/registrations_controller.rb +96 -0
  22. data/app/controllers/rails_agents/schema_controller.rb +123 -0
  23. data/app/controllers/rails_agents/sessions_controller.rb +76 -0
  24. data/app/controllers/rails_agents/tool_bridge_controller.rb +67 -0
  25. data/app/views/layouts/rails_agents/application.html.erb +18 -0
  26. data/app/views/rails_agents/dashboard/show.html.erb +139 -0
  27. data/app/views/rails_agents/registrations/new.html.erb +83 -0
  28. data/app/views/rails_agents/sessions/new.html.erb +73 -0
  29. data/app/views/rails_agents/shared/_auth_brand.html.erb +20 -0
  30. data/config/routes.rb +34 -0
  31. data/docs/AGENTS.md +220 -0
  32. data/docs/PRD.md +89 -0
  33. data/docs/assets/hero-banner.png +0 -0
  34. data/examples/support/agent.rb +14 -0
  35. data/examples/support/channels/.keep +0 -0
  36. data/examples/support/evals/smoke.yml +4 -0
  37. data/examples/support/knowledge/shipping.md +1 -0
  38. data/examples/support/memory.rb +3 -0
  39. data/examples/support/prompt.md +9 -0
  40. data/examples/support/skills/.keep +0 -0
  41. data/examples/support/tools/.keep +0 -0
  42. data/exe/rails-agents +6 -0
  43. data/lib/generators/rails_agents/agent/agent_generator.rb +80 -0
  44. data/lib/generators/rails_agents/agent/templates/agent.rb.tt +14 -0
  45. data/lib/generators/rails_agents/agent/templates/agent_database.rb.tt +42 -0
  46. data/lib/generators/rails_agents/agent/templates/channels/slack.rb.tt +8 -0
  47. data/lib/generators/rails_agents/agent/templates/evals/smoke.yml.tt +4 -0
  48. data/lib/generators/rails_agents/agent/templates/imports.yml.tt +9 -0
  49. data/lib/generators/rails_agents/agent/templates/memory.rb.tt +6 -0
  50. data/lib/generators/rails_agents/agent/templates/prompt.md.tt +10 -0
  51. data/lib/generators/rails_agents/agent/templates/prompt_database.md.tt +14 -0
  52. data/lib/generators/rails_agents/install/INSTALL +10 -0
  53. data/lib/generators/rails_agents/install/install_generator.rb +72 -0
  54. data/lib/generators/rails_agents/install/templates/AGENTS.md.tt +46 -0
  55. data/lib/generators/rails_agents/install/templates/initializer.rb.tt +8 -0
  56. data/lib/generators/rails_agents/install/templates/library_README.md.tt +28 -0
  57. data/lib/generators/rails_agents/install/templates/library_manifest.yml.tt +5 -0
  58. data/lib/generators/rails_agents/install/templates/rails_agents_autoload.rb.tt +10 -0
  59. data/lib/rails-agent-stack.rb +4 -0
  60. data/lib/rails_agents/background_agent.rb +15 -0
  61. data/lib/rails_agents/base.rb +294 -0
  62. data/lib/rails_agents/chat_agent.rb +15 -0
  63. data/lib/rails_agents/cli.rb +245 -0
  64. data/lib/rails_agents/client.rb +216 -0
  65. data/lib/rails_agents/configuration.rb +41 -0
  66. data/lib/rails_agents/creation_agent.rb +10 -0
  67. data/lib/rails_agents/credentials_writer.rb +38 -0
  68. data/lib/rails_agents/engine.rb +19 -0
  69. data/lib/rails_agents/knowledge_agent.rb +10 -0
  70. data/lib/rails_agents/library_imports.rb +163 -0
  71. data/lib/rails_agents/local_auth.rb +56 -0
  72. data/lib/rails_agents/local_sync.rb +113 -0
  73. data/lib/rails_agents/monitoring_agent.rb +10 -0
  74. data/lib/rails_agents/open_wire_adapter.rb +31 -0
  75. data/lib/rails_agents/operations_agent.rb +10 -0
  76. data/lib/rails_agents/railtie.rb +14 -0
  77. data/lib/rails_agents/tasks.rake +8 -0
  78. data/lib/rails_agents/version.rb +5 -0
  79. data/lib/rails_agents/workflow_agent.rb +11 -0
  80. data/lib/rails_agents.rb +57 -0
  81. data/rails-agent-stack.gemspec +49 -0
  82. data/rails-agents.code-workspace +25 -0
  83. data/spec/generators/agent_generator_spec.rb +36 -0
  84. data/spec/rails_agents/base_spec.rb +202 -0
  85. data/spec/rails_agents/client_spec.rb +121 -0
  86. data/spec/rails_agents/configuration_spec.rb +55 -0
  87. data/spec/rails_agents/library_imports_spec.rb +80 -0
  88. data/spec/rails_agents/local_sync_spec.rb +63 -0
  89. data/spec/rails_agents/taxonomy_spec.rb +52 -0
  90. data/spec/spec_helper.rb +27 -0
  91. metadata +229 -0
@@ -0,0 +1,4 @@
1
+ - name: greeting
2
+ input: "Hello"
3
+ expected_contains:
4
+ - "help"
@@ -0,0 +1 @@
1
+ # Orders ship within 2 business days.
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Conversation memory � managed by Rails Agent Cloud vector store.
@@ -0,0 +1,9 @@
1
+ # Support Agent
2
+
3
+ You are Support, a Knowledge agent for this Rails application.
4
+
5
+ - Answer plainly and confidently.
6
+ - Use tools to look up order status when asked.
7
+ - Escalate billing disputes to a human.
8
+
9
+ Provider credentials are stored in Rails Agent Cloud (BYOK) — not in this repository.
File without changes
File without changes
data/exe/rails-agents ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "rails_agents/cli"
5
+
6
+ RailsAgents::CLI.start(ARGV)
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/base"
4
+ require "rails/generators/named_base"
5
+
6
+ module RailsAgents
7
+ module Generators
8
+ class AgentGenerator < Rails::Generators::NamedBase
9
+ source_root File.expand_path("templates", __dir__)
10
+
11
+ class_option :type,
12
+ type: :string,
13
+ default: "knowledge",
14
+ desc: "Agent taxonomy: knowledge, workflow, operations, monitoring"
15
+
16
+ class_option :database,
17
+ type: :boolean,
18
+ default: false,
19
+ desc: "Scaffold database-connected tools (Knowledge agents)"
20
+
21
+ desc "Scaffold an agent directory under app/agents/"
22
+
23
+ def create_agent_directory
24
+ empty_directory agent_path
25
+ empty_directory File.join(agent_path, "tools")
26
+ empty_directory File.join(agent_path, "skills")
27
+ empty_directory File.join(agent_path, "knowledge")
28
+ empty_directory File.join(agent_path, "connectors")
29
+ empty_directory File.join(agent_path, "plugins")
30
+ empty_directory File.join(agent_path, "channels")
31
+ empty_directory File.join(agent_path, "evals")
32
+ end
33
+
34
+ def create_agent_files
35
+ if database?
36
+ template "agent_database.rb.tt", File.join(agent_path, "agent.rb")
37
+ template "prompt_database.md.tt", File.join(agent_path, "prompt.md")
38
+ else
39
+ template "agent.rb.tt", File.join(agent_path, "agent.rb")
40
+ template "prompt.md.tt", File.join(agent_path, "prompt.md")
41
+ end
42
+ template "memory.rb.tt", File.join(agent_path, "memory.rb")
43
+ template "imports.yml.tt", File.join(agent_path, "imports.yml")
44
+ template "channels/slack.rb.tt", File.join(agent_path, "channels/slack.rb")
45
+ template "evals/smoke.yml.tt", File.join(agent_path, "evals/smoke.yml")
46
+ end
47
+
48
+ private
49
+
50
+ def agent_path
51
+ File.join("app/agents", file_name)
52
+ end
53
+
54
+ def class_name
55
+ name.camelize
56
+ end
57
+
58
+ def agent_type
59
+ type = options[:type].to_s.downcase
60
+ return type if RailsAgents::TAXONOMY_TYPES.map(&:to_s).include?(type)
61
+
62
+ say "Unknown --type #{options[:type].inspect}; using knowledge.", :yellow
63
+ "knowledge"
64
+ end
65
+
66
+ def agent_base_class
67
+ {
68
+ "knowledge" => "KnowledgeAgent",
69
+ "workflow" => "WorkflowAgent",
70
+ "operations" => "OperationsAgent",
71
+ "monitoring" => "MonitoringAgent"
72
+ }.fetch(agent_type)
73
+ end
74
+
75
+ def database?
76
+ options[:database]
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class <%= class_name %> < RailsAgents::<%= agent_base_class %>
4
+ model :gpt_5_mini, provider: :openai, credential: :company_openai
5
+ memory :conversation
6
+ knowledge_from "knowledge/**/*"
7
+
8
+ tool :ping do
9
+ { status: "ok", agent: "<%= file_name %>" }
10
+ end
11
+
12
+ skill :triage, from: "skills/triage.rb"
13
+ channel :slack
14
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ class <%= class_name %> < RailsAgents::KnowledgeAgent
4
+ model :gpt_5_mini, provider: :openai, credential: :company_openai
5
+ memory :conversation
6
+ knowledge_from "knowledge/**/*"
7
+
8
+ tool :lookup_order do |order_number:|
9
+ order = Order.find_by(number: order_number)
10
+ return { error: "Order not found", order_number: order_number } unless order
11
+
12
+ {
13
+ number: order.number,
14
+ status: order.status,
15
+ customer_name: order.customer_name,
16
+ customer_email: order.customer_email,
17
+ total_cents: order.total_cents,
18
+ currency: order.currency,
19
+ shipped_at: order.shipped_at&.iso8601
20
+ }
21
+ end
22
+
23
+ tool :search_products do |query:|
24
+ scope = Product.where(status: "active")
25
+ if query.present?
26
+ pattern = "%#{query}%"
27
+ scope = scope.where("name LIKE ? OR sku LIKE ?", pattern, pattern)
28
+ end
29
+
30
+ scope.limit(10).map do |product|
31
+ {
32
+ sku: product.sku,
33
+ name: product.name,
34
+ price_cents: product.price_cents,
35
+ stock: product.stock,
36
+ collection: product.collection&.name
37
+ }
38
+ end
39
+ end
40
+
41
+ channel :web
42
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Slack channel connector � install via dashboard or:
4
+ # RailsAgents::Client.new.install_channel(kind: :slack)
5
+
6
+ RailsAgents.configure do |config|
7
+ # Channel OAuth handled by Rails Agent Cloud.
8
+ end
@@ -0,0 +1,4 @@
1
+ - name: smoke
2
+ input: "Hello"
3
+ expected_contains:
4
+ - "ok"
@@ -0,0 +1,9 @@
1
+ version: 1
2
+
3
+ # Reuse capabilities from app/agents_library without duplicating source files.
4
+ # Example:
5
+ # imports:
6
+ # - kind: skill
7
+ # slug: triage
8
+ # from: library/skills/triage.rb
9
+ imports: []
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Managed conversation memory � synced to Rails Agent Cloud.
4
+ RailsAgents.configure do |config|
5
+ # Memory is cloud-managed; no local vector DB required.
6
+ end
@@ -0,0 +1,10 @@
1
+ # <%= class_name %> Agent
2
+
3
+ You are <%= class_name %>, a Knowledge agent for this Rails application.
4
+
5
+ - Answer plainly using database tools when the user asks about orders, products, or catalog data.
6
+ - Call `lookup_order` for order numbers (e.g. ORD-DEMO-1001).
7
+ - Call `search_products` to find products by name or SKU.
8
+ - Escalate to a human when you cannot answer safely or need write access.
9
+
10
+ Provider credentials are stored in Rails Agent Cloud — never paste API keys into this repo.
@@ -0,0 +1,14 @@
1
+ # <%= class_name %> Agent
2
+
3
+ You are <%= class_name %>, a database-connected Knowledge agent for this Rails app.
4
+
5
+ ## Tools
6
+
7
+ - `lookup_order(order_number:)` — order status, customer, total, shipped_at
8
+ - `search_products(query:)` — active products by name or SKU
9
+
10
+ ## Demo data
11
+
12
+ After `bin/rails db:seed`, try order numbers like `ORD-DEMO-1001` or ask about products such as "Classic Tee".
13
+
14
+ Provider credentials live in Rails Agent Cloud (BYOK). Do not commit secrets to this repository.
@@ -0,0 +1,10 @@
1
+ Rails Agents is mounted at /agents.
2
+
3
+ Next steps:
4
+
5
+ 1. bin/dev (or bin/rails server)
6
+ 2. Open http://localhost:3000/agents and connect your company workspace
7
+ 3. Read AGENTS.md in your app root
8
+ 4. bin/rails generate rails_agents:agent my_agent --type knowledge --database
9
+
10
+ Platform guide: https://rails-agent.com/docs/getting-started
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/base"
4
+
5
+ module RailsAgents
6
+ module Generators
7
+ class InstallGenerator < Rails::Generators::Base
8
+ source_root File.expand_path("templates", __dir__)
9
+
10
+ desc "Mount the Rails Agents engine and create the initializer"
11
+
12
+ def create_initializer
13
+ template "initializer.rb.tt", "config/initializers/rails_agents.rb"
14
+ template "rails_agents_autoload.rb.tt", "config/initializers/rails_agents_autoload.rb"
15
+ end
16
+
17
+ def mount_engine
18
+ route "mount RailsAgents::Engine, at: \"/agents\""
19
+ end
20
+
21
+ def create_agents_guide
22
+ template "AGENTS.md.tt", "AGENTS.md"
23
+ end
24
+
25
+ def create_workspace_library
26
+ %w[tools skills connectors plugins knowledge knowledge/sources packages].each do |folder|
27
+ empty_directory File.join("app/agents_library", folder)
28
+ end
29
+ template "library_manifest.yml.tt", "app/agents_library/manifest.yml"
30
+ template "library_README.md.tt", "app/agents_library/README.md"
31
+ end
32
+
33
+ def create_env_placeholders
34
+ env_path = File.expand_path(".env", destination_root)
35
+ placeholders = <<~ENV
36
+
37
+ # Rails Agent Cloud platform key — NOT your OpenAI/Anthropic keys (those are BYOK in dashboard)
38
+ # Written automatically when you connect from /agents
39
+ RAILS_AGENTS_API_KEY=
40
+ RAILS_AGENTS_PROJECT_ID=
41
+ ENV
42
+
43
+ if File.exist?(env_path)
44
+ unless File.read(env_path).include?("RAILS_AGENTS_API_KEY")
45
+ append_to_file ".env", placeholders
46
+ end
47
+ else
48
+ create_file ".env.rails_agents.example", placeholders.lstrip
49
+ end
50
+ end
51
+
52
+ def show_next_steps
53
+ return unless behavior == :invoke
54
+
55
+ port = ENV.fetch("PORT", "3000")
56
+ url = "http://localhost:#{port}/agents"
57
+
58
+ say ""
59
+ say "============================================================", :green
60
+ say " Rails Agents installed", :green
61
+ say "============================================================", :green
62
+ say ""
63
+ say " 1. Start server: bin/dev (or bin/rails server)", :green
64
+ say " 2. Connect: #{url}", :green
65
+ say " 3. Read AGENTS.md — scaffold your first database Knowledge agent:", :green
66
+ say " bin/rails generate rails_agents:agent my_agent --type knowledge --database", :green
67
+ say "============================================================", :green
68
+ say ""
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,46 @@
1
+ # AGENTS.md — <%= Rails.application.class.module_parent_name rescue "YourApp" %>
2
+
3
+ Project guide for external coding agents. Platform docs: [rails-agents/docs/AGENTS.md](https://github.com/Tiny-Bubble-Company/rails-agents/blob/main/docs/AGENTS.md)
4
+
5
+ ## This app
6
+
7
+ - Rails Agent mounted at `/agents`
8
+ - Demo ecommerce models: `Collection`, `Product`, `Order`, `OrderItem`
9
+ - Seed data: `bin/rails db:seed` (order numbers like `ORD-DEMO-1001`)
10
+
11
+ ## First agent (database Knowledge)
12
+
13
+ Reference implementation: `app/agents/store_assistant/`
14
+
15
+ ```bash
16
+ bin/rails generate rails_agents:agent store_assistant --type knowledge --database
17
+ bundle exec rails-agents sync store_assistant
18
+ bundle exec rails-agents run store_assistant "Status of ORD-DEMO-1001?"
19
+ ```
20
+
21
+ ## BYOK
22
+
23
+ Store OpenAI/Anthropic/etc. keys in **cloud dashboard → Settings → Providers**. Reference in agent.rb:
24
+
25
+ ```ruby
26
+ model :gpt_5_mini, provider: :openai, credential: :company_openai
27
+ ```
28
+
29
+ Never commit provider API keys to this repository.
30
+
31
+ ## Reusable capabilities
32
+
33
+ Keep agent-specific files under `app/agents/<slug>/`. Put stable tools, skills,
34
+ knowledge, or plugin manifests needed by multiple agents under
35
+ `app/agents_library/`, then attach them through the agent's `imports.yml`.
36
+
37
+ Do not move a capability into the Library until another agent needs it.
38
+
39
+ ## Taxonomy
40
+
41
+ - **Knowledge** — understand and answer
42
+ - **Workflow** — execute predictable processes
43
+ - **Operations** — coordinate unpredictable real-world work
44
+ - **Monitoring** — observe changes and respond
45
+
46
+ See root gem `docs/AGENTS.md` for the full progressive path (tools → plugins → skills → channels → evals → deploy).
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ RailsAgents.configure do |config|
4
+ # Platform API key (https://cloud.rails-agent.com/dashboard/keys).
5
+ # Provider/model keys (BYOK) are stored in the cloud — reference them in agent.rb via credential:.
6
+ config.api_key = ENV["RAILS_AGENTS_API_KEY"]
7
+ config.project_id = ENV["RAILS_AGENTS_PROJECT_ID"]
8
+ end
@@ -0,0 +1,28 @@
1
+ # Agent Library
2
+
3
+ Reusable capabilities shared by agents in this Rails application.
4
+
5
+ - `tools/` — Ruby actions and service wrappers
6
+ - `skills/` — reusable multi-step behavior
7
+ - `packages/` — installable capabilities from Skills.sh, Microsoft APM, and Smithery
8
+ - `knowledge/` — documents and data-source definitions
9
+ - `connectors/` — external connection manifests
10
+
11
+ Keep one-off capabilities inside `app/agents/<slug>/`. Move a capability here
12
+ only when multiple agents should reuse the same implementation.
13
+
14
+ Attach shared files in an agent's `imports.yml`:
15
+
16
+ ```yaml
17
+ version: 1
18
+ imports:
19
+ - kind: skill
20
+ slug: triage
21
+ from: library/skills/triage.rb
22
+ - kind: package
23
+ slug: frontend_design
24
+ from: library/packages/frontend_design
25
+ ```
26
+
27
+ `rails-agents sync <agent>` uploads imported files into that agent's runtime
28
+ bundle without duplicating the shared source in the repository.
@@ -0,0 +1,5 @@
1
+ version: 1
2
+
3
+ # Workspace capabilities that may be reused by multiple agents.
4
+ # Agents opt in through app/agents/<slug>/imports.yml.
5
+ resources: []
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Prevents Zeitwerk from treating agent definitions and shared assets as normal
4
+ # application namespaces. Agents load through the Rails Agent runtime.
5
+ Rails.application.configure do
6
+ config.before_configuration do
7
+ Rails.autoloaders.main.ignore(Rails.root.join("app/agents"))
8
+ Rails.autoloaders.main.ignore(Rails.root.join("app/agents_library"))
9
+ end
10
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Bundler.require for gem "rails-agent-stack" loads this file.
4
+ require "rails_agents"
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsAgents
4
+ # @deprecated Use {OperationsAgent} for async / scheduled agents.
5
+ class BackgroundAgent < OperationsAgent
6
+ def self.inherited(subclass)
7
+ super
8
+ warn "[RailsAgents] BackgroundAgent is deprecated; use OperationsAgent instead.", uplevel: 1
9
+ end
10
+
11
+ def self.agent_kind
12
+ :operations
13
+ end
14
+ end
15
+ end