claude_swarm 1.0.1 → 1.0.2
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/.claude/commands/release.md +1 -1
- data/.claude/hooks/lint-code-files.rb +65 -0
- data/.rubocop.yml +22 -2
- data/CHANGELOG.md +14 -1
- data/CLAUDE.md +1 -1
- data/CONTRIBUTING.md +69 -0
- data/README.md +27 -2
- data/Rakefile +71 -3
- data/analyze_coverage.rb +94 -0
- data/docs/v2/CHANGELOG.swarm_cli.md +43 -0
- data/docs/v2/CHANGELOG.swarm_memory.md +379 -0
- data/docs/v2/CHANGELOG.swarm_sdk.md +362 -0
- data/docs/v2/README.md +308 -0
- data/docs/v2/guides/claude-code-agents.md +262 -0
- data/docs/v2/guides/complete-tutorial.md +3088 -0
- data/docs/v2/guides/getting-started.md +1456 -0
- data/docs/v2/guides/memory-adapters.md +998 -0
- data/docs/v2/guides/plugins.md +816 -0
- data/docs/v2/guides/quick-start-cli.md +1745 -0
- data/docs/v2/guides/rails-integration.md +1902 -0
- data/docs/v2/guides/swarm-memory.md +599 -0
- data/docs/v2/reference/cli.md +729 -0
- data/docs/v2/reference/ruby-dsl.md +2154 -0
- data/docs/v2/reference/yaml.md +1835 -0
- data/docs-team-swarm.yml +2222 -0
- data/examples/learning-assistant/assistant.md +7 -0
- data/examples/learning-assistant/example-memories/concept-example.md +90 -0
- data/examples/learning-assistant/example-memories/experience-example.md +66 -0
- data/examples/learning-assistant/example-memories/fact-example.md +76 -0
- data/examples/learning-assistant/example-memories/memory-index.md +78 -0
- data/examples/learning-assistant/example-memories/skill-example.md +168 -0
- data/examples/learning-assistant/learning_assistant.rb +34 -0
- data/examples/learning-assistant/learning_assistant.yml +20 -0
- data/examples/v2/dsl/01_basic.rb +44 -0
- data/examples/v2/dsl/02_core_parameters.rb +59 -0
- data/examples/v2/dsl/03_capabilities.rb +71 -0
- data/examples/v2/dsl/04_llm_parameters.rb +56 -0
- data/examples/v2/dsl/05_advanced_flags.rb +73 -0
- data/examples/v2/dsl/06_permissions.rb +80 -0
- data/examples/v2/dsl/07_mcp_server.rb +62 -0
- data/examples/v2/dsl/08_swarm_hooks.rb +53 -0
- data/examples/v2/dsl/09_agent_hooks.rb +67 -0
- data/examples/v2/dsl/10_all_agents_hooks.rb +67 -0
- data/examples/v2/dsl/11_delegation.rb +60 -0
- data/examples/v2/dsl/12_complete_integration.rb +137 -0
- data/examples/v2/file_tools_swarm.yml +102 -0
- data/examples/v2/hooks/01_basic_hooks.rb +133 -0
- data/examples/v2/hooks/02_usage_tracking.rb +201 -0
- data/examples/v2/hooks/03_production_monitoring.rb +429 -0
- data/examples/v2/hooks/agent_stop_exit_0.yml +21 -0
- data/examples/v2/hooks/agent_stop_exit_1.yml +21 -0
- data/examples/v2/hooks/agent_stop_exit_2.yml +26 -0
- data/examples/v2/hooks/multiple_hooks_all_pass.yml +37 -0
- data/examples/v2/hooks/multiple_hooks_first_fails.yml +37 -0
- data/examples/v2/hooks/multiple_hooks_second_fails.yml +37 -0
- data/examples/v2/hooks/multiple_hooks_warnings.yml +37 -0
- data/examples/v2/hooks/post_tool_use_exit_0.yml +24 -0
- data/examples/v2/hooks/post_tool_use_exit_1.yml +24 -0
- data/examples/v2/hooks/post_tool_use_exit_2.yml +24 -0
- data/examples/v2/hooks/post_tool_use_multi_matcher_exit_0.yml +26 -0
- data/examples/v2/hooks/post_tool_use_multi_matcher_exit_1.yml +26 -0
- data/examples/v2/hooks/post_tool_use_multi_matcher_exit_2.yml +26 -0
- data/examples/v2/hooks/pre_tool_use_exit_0.yml +24 -0
- data/examples/v2/hooks/pre_tool_use_exit_1.yml +24 -0
- data/examples/v2/hooks/pre_tool_use_exit_2.yml +24 -0
- data/examples/v2/hooks/pre_tool_use_multi_matcher_exit_0.yml +26 -0
- data/examples/v2/hooks/pre_tool_use_multi_matcher_exit_1.yml +26 -0
- data/examples/v2/hooks/pre_tool_use_multi_matcher_exit_2.yml +27 -0
- data/examples/v2/hooks/swarm_summary.sh +44 -0
- data/examples/v2/hooks/user_prompt_exit_0.yml +21 -0
- data/examples/v2/hooks/user_prompt_exit_1.yml +21 -0
- data/examples/v2/hooks/user_prompt_exit_2.yml +21 -0
- data/examples/v2/hooks/validate_bash.rb +59 -0
- data/examples/v2/multi_directory_permissions.yml +221 -0
- data/examples/v2/node_context_demo.rb +127 -0
- data/examples/v2/node_workflow.rb +173 -0
- data/examples/v2/path_resolution_demo.rb +216 -0
- data/examples/v2/simple-swarm-v2.rb +90 -0
- data/examples/v2/simple-swarm-v2.yml +62 -0
- data/examples/v2/swarm.yml +71 -0
- data/examples/v2/swarm_with_hooks.yml +61 -0
- data/examples/v2/swarm_with_hooks_simple.yml +25 -0
- data/examples/v2/think_tool_demo.rb +62 -0
- data/exe/swarm +6 -0
- data/lib/claude_swarm/claude_mcp_server.rb +0 -6
- data/lib/claude_swarm/cli.rb +10 -3
- data/lib/claude_swarm/commands/ps.rb +19 -20
- data/lib/claude_swarm/commands/show.rb +1 -1
- data/lib/claude_swarm/configuration.rb +10 -12
- data/lib/claude_swarm/mcp_generator.rb +10 -1
- data/lib/claude_swarm/orchestrator.rb +73 -49
- data/lib/claude_swarm/system_utils.rb +37 -11
- data/lib/claude_swarm/version.rb +1 -1
- data/lib/claude_swarm/worktree_manager.rb +1 -0
- data/lib/claude_swarm/yaml_loader.rb +22 -0
- data/lib/claude_swarm.rb +6 -2
- data/lib/swarm_cli/cli.rb +201 -0
- data/lib/swarm_cli/command_registry.rb +61 -0
- data/lib/swarm_cli/commands/mcp_serve.rb +130 -0
- data/lib/swarm_cli/commands/mcp_tools.rb +148 -0
- data/lib/swarm_cli/commands/migrate.rb +55 -0
- data/lib/swarm_cli/commands/run.rb +173 -0
- data/lib/swarm_cli/config_loader.rb +97 -0
- data/lib/swarm_cli/formatters/human_formatter.rb +711 -0
- data/lib/swarm_cli/formatters/json_formatter.rb +51 -0
- data/lib/swarm_cli/interactive_repl.rb +918 -0
- data/lib/swarm_cli/mcp_serve_options.rb +44 -0
- data/lib/swarm_cli/mcp_tools_options.rb +59 -0
- data/lib/swarm_cli/migrate_options.rb +54 -0
- data/lib/swarm_cli/migrator.rb +132 -0
- data/lib/swarm_cli/options.rb +151 -0
- data/lib/swarm_cli/ui/components/agent_badge.rb +33 -0
- data/lib/swarm_cli/ui/components/content_block.rb +120 -0
- data/lib/swarm_cli/ui/components/divider.rb +57 -0
- data/lib/swarm_cli/ui/components/panel.rb +62 -0
- data/lib/swarm_cli/ui/components/usage_stats.rb +70 -0
- data/lib/swarm_cli/ui/formatters/cost.rb +49 -0
- data/lib/swarm_cli/ui/formatters/number.rb +58 -0
- data/lib/swarm_cli/ui/formatters/text.rb +77 -0
- data/lib/swarm_cli/ui/formatters/time.rb +73 -0
- data/lib/swarm_cli/ui/icons.rb +59 -0
- data/lib/swarm_cli/ui/renderers/event_renderer.rb +188 -0
- data/lib/swarm_cli/ui/state/agent_color_cache.rb +45 -0
- data/lib/swarm_cli/ui/state/depth_tracker.rb +40 -0
- data/lib/swarm_cli/ui/state/spinner_manager.rb +170 -0
- data/lib/swarm_cli/ui/state/usage_tracker.rb +62 -0
- data/lib/swarm_cli/version.rb +5 -0
- data/lib/swarm_cli.rb +44 -0
- data/lib/swarm_memory/adapters/base.rb +141 -0
- data/lib/swarm_memory/adapters/filesystem_adapter.rb +845 -0
- data/lib/swarm_memory/chat_extension.rb +34 -0
- data/lib/swarm_memory/cli/commands.rb +306 -0
- data/lib/swarm_memory/core/entry.rb +37 -0
- data/lib/swarm_memory/core/frontmatter_parser.rb +108 -0
- data/lib/swarm_memory/core/metadata_extractor.rb +68 -0
- data/lib/swarm_memory/core/path_normalizer.rb +75 -0
- data/lib/swarm_memory/core/semantic_index.rb +244 -0
- data/lib/swarm_memory/core/storage.rb +288 -0
- data/lib/swarm_memory/core/storage_read_tracker.rb +63 -0
- data/lib/swarm_memory/dsl/builder_extension.rb +40 -0
- data/lib/swarm_memory/dsl/memory_config.rb +113 -0
- data/lib/swarm_memory/embeddings/embedder.rb +36 -0
- data/lib/swarm_memory/embeddings/informers_embedder.rb +152 -0
- data/lib/swarm_memory/errors.rb +21 -0
- data/lib/swarm_memory/integration/cli_registration.rb +30 -0
- data/lib/swarm_memory/integration/configuration.rb +43 -0
- data/lib/swarm_memory/integration/registration.rb +31 -0
- data/lib/swarm_memory/integration/sdk_plugin.rb +531 -0
- data/lib/swarm_memory/optimization/analyzer.rb +244 -0
- data/lib/swarm_memory/optimization/defragmenter.rb +863 -0
- data/lib/swarm_memory/prompts/memory.md.erb +109 -0
- data/lib/swarm_memory/prompts/memory_assistant.md.erb +181 -0
- data/lib/swarm_memory/prompts/memory_researcher.md.erb +281 -0
- data/lib/swarm_memory/prompts/memory_retrieval.md.erb +78 -0
- data/lib/swarm_memory/search/semantic_search.rb +112 -0
- data/lib/swarm_memory/search/text_search.rb +42 -0
- data/lib/swarm_memory/search/text_similarity.rb +80 -0
- data/lib/swarm_memory/skills/meta/deep-learning.md +101 -0
- data/lib/swarm_memory/skills/meta/deep-learning.yml +14 -0
- data/lib/swarm_memory/tools/load_skill.rb +313 -0
- data/lib/swarm_memory/tools/memory_defrag.rb +382 -0
- data/lib/swarm_memory/tools/memory_delete.rb +99 -0
- data/lib/swarm_memory/tools/memory_edit.rb +185 -0
- data/lib/swarm_memory/tools/memory_glob.rb +160 -0
- data/lib/swarm_memory/tools/memory_grep.rb +247 -0
- data/lib/swarm_memory/tools/memory_multi_edit.rb +281 -0
- data/lib/swarm_memory/tools/memory_read.rb +123 -0
- data/lib/swarm_memory/tools/memory_write.rb +231 -0
- data/lib/swarm_memory/utils.rb +50 -0
- data/lib/swarm_memory/version.rb +5 -0
- data/lib/swarm_memory.rb +166 -0
- data/lib/swarm_sdk/agent/RETRY_LOGIC.md +127 -0
- data/lib/swarm_sdk/agent/builder.rb +461 -0
- data/lib/swarm_sdk/agent/chat/context_tracker.rb +314 -0
- data/lib/swarm_sdk/agent/chat/hook_integration.rb +372 -0
- data/lib/swarm_sdk/agent/chat/logging_helpers.rb +116 -0
- data/lib/swarm_sdk/agent/chat/system_reminder_injector.rb +152 -0
- data/lib/swarm_sdk/agent/chat.rb +1159 -0
- data/lib/swarm_sdk/agent/context.rb +112 -0
- data/lib/swarm_sdk/agent/context_manager.rb +309 -0
- data/lib/swarm_sdk/agent/definition.rb +556 -0
- data/lib/swarm_sdk/claude_code_agent_adapter.rb +205 -0
- data/lib/swarm_sdk/configuration.rb +296 -0
- data/lib/swarm_sdk/context_compactor/metrics.rb +147 -0
- data/lib/swarm_sdk/context_compactor/token_counter.rb +106 -0
- data/lib/swarm_sdk/context_compactor.rb +340 -0
- data/lib/swarm_sdk/hooks/adapter.rb +359 -0
- data/lib/swarm_sdk/hooks/context.rb +197 -0
- data/lib/swarm_sdk/hooks/definition.rb +80 -0
- data/lib/swarm_sdk/hooks/error.rb +29 -0
- data/lib/swarm_sdk/hooks/executor.rb +146 -0
- data/lib/swarm_sdk/hooks/registry.rb +147 -0
- data/lib/swarm_sdk/hooks/result.rb +150 -0
- data/lib/swarm_sdk/hooks/shell_executor.rb +254 -0
- data/lib/swarm_sdk/hooks/tool_call.rb +35 -0
- data/lib/swarm_sdk/hooks/tool_result.rb +62 -0
- data/lib/swarm_sdk/log_collector.rb +51 -0
- data/lib/swarm_sdk/log_stream.rb +69 -0
- data/lib/swarm_sdk/markdown_parser.rb +75 -0
- data/lib/swarm_sdk/model_aliases.json +5 -0
- data/lib/swarm_sdk/models.json +1 -0
- data/lib/swarm_sdk/models.rb +120 -0
- data/lib/swarm_sdk/node/agent_config.rb +49 -0
- data/lib/swarm_sdk/node/builder.rb +439 -0
- data/lib/swarm_sdk/node/transformer_executor.rb +248 -0
- data/lib/swarm_sdk/node_context.rb +170 -0
- data/lib/swarm_sdk/node_orchestrator.rb +384 -0
- data/lib/swarm_sdk/permissions/config.rb +239 -0
- data/lib/swarm_sdk/permissions/error_formatter.rb +121 -0
- data/lib/swarm_sdk/permissions/path_matcher.rb +35 -0
- data/lib/swarm_sdk/permissions/validator.rb +173 -0
- data/lib/swarm_sdk/permissions_builder.rb +122 -0
- data/lib/swarm_sdk/plugin.rb +147 -0
- data/lib/swarm_sdk/plugin_registry.rb +101 -0
- data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +243 -0
- data/lib/swarm_sdk/providers/openai_with_responses.rb +582 -0
- data/lib/swarm_sdk/result.rb +97 -0
- data/lib/swarm_sdk/swarm/agent_initializer.rb +334 -0
- data/lib/swarm_sdk/swarm/all_agents_builder.rb +140 -0
- data/lib/swarm_sdk/swarm/builder.rb +586 -0
- data/lib/swarm_sdk/swarm/mcp_configurator.rb +151 -0
- data/lib/swarm_sdk/swarm/tool_configurator.rb +419 -0
- data/lib/swarm_sdk/swarm.rb +982 -0
- data/lib/swarm_sdk/tools/bash.rb +274 -0
- data/lib/swarm_sdk/tools/clock.rb +44 -0
- data/lib/swarm_sdk/tools/delegate.rb +164 -0
- data/lib/swarm_sdk/tools/document_converters/base_converter.rb +83 -0
- data/lib/swarm_sdk/tools/document_converters/docx_converter.rb +99 -0
- data/lib/swarm_sdk/tools/document_converters/html_converter.rb +101 -0
- data/lib/swarm_sdk/tools/document_converters/pdf_converter.rb +78 -0
- data/lib/swarm_sdk/tools/document_converters/xlsx_converter.rb +194 -0
- data/lib/swarm_sdk/tools/edit.rb +150 -0
- data/lib/swarm_sdk/tools/glob.rb +158 -0
- data/lib/swarm_sdk/tools/grep.rb +228 -0
- data/lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb +43 -0
- data/lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb +163 -0
- data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +65 -0
- data/lib/swarm_sdk/tools/multi_edit.rb +232 -0
- data/lib/swarm_sdk/tools/path_resolver.rb +43 -0
- data/lib/swarm_sdk/tools/read.rb +251 -0
- data/lib/swarm_sdk/tools/registry.rb +93 -0
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +96 -0
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +76 -0
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +91 -0
- data/lib/swarm_sdk/tools/stores/read_tracker.rb +61 -0
- data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +224 -0
- data/lib/swarm_sdk/tools/stores/storage.rb +148 -0
- data/lib/swarm_sdk/tools/stores/todo_manager.rb +65 -0
- data/lib/swarm_sdk/tools/think.rb +95 -0
- data/lib/swarm_sdk/tools/todo_write.rb +216 -0
- data/lib/swarm_sdk/tools/web_fetch.rb +261 -0
- data/lib/swarm_sdk/tools/write.rb +117 -0
- data/lib/swarm_sdk/utils.rb +50 -0
- data/lib/swarm_sdk/version.rb +5 -0
- data/lib/swarm_sdk.rb +157 -0
- data/llm.v2.txt +13407 -0
- data/rubocop/cop/security/no_reflection_methods.rb +47 -0
- data/rubocop/cop/security/no_ruby_llm_logger.rb +32 -0
- data/swarm_cli.gemspec +57 -0
- data/swarm_memory.gemspec +28 -0
- data/swarm_sdk.gemspec +41 -0
- data/team.yml +1 -1
- data/team_full.yml +1875 -0
- data/{team_v2.yml → team_sdk.yml} +121 -52
- metadata +247 -4
- data/EXAMPLES.md +0 -164
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# NodeContext Demo
|
|
5
|
+
#
|
|
6
|
+
# This example demonstrates the NodeContext capabilities:
|
|
7
|
+
# - Access original_prompt from any node
|
|
8
|
+
# - Access all previous node results
|
|
9
|
+
# - Convenience accessors (ctx.content)
|
|
10
|
+
#
|
|
11
|
+
# Run: ruby examples/node_context_demo.rb
|
|
12
|
+
|
|
13
|
+
require_relative "../lib/swarm_sdk"
|
|
14
|
+
|
|
15
|
+
swarm = SwarmSDK.build do
|
|
16
|
+
name("NodeContext Demo")
|
|
17
|
+
|
|
18
|
+
# Define agents
|
|
19
|
+
agent(:planner) do
|
|
20
|
+
model("claude-sonnet-4-5")
|
|
21
|
+
provider("openai")
|
|
22
|
+
description("Planning agent")
|
|
23
|
+
system_prompt("Create a brief plan.")
|
|
24
|
+
tools(include_default: false)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
agent(:implementer) do
|
|
28
|
+
model("claude-sonnet-4-5")
|
|
29
|
+
provider("openai")
|
|
30
|
+
description("Implementation agent")
|
|
31
|
+
system_prompt("Implement the plan.")
|
|
32
|
+
tools(include_default: false)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
agent(:reviewer) do
|
|
36
|
+
model("claude-sonnet-4-5")
|
|
37
|
+
provider("openai")
|
|
38
|
+
description("Review agent")
|
|
39
|
+
system_prompt("Review the work.")
|
|
40
|
+
tools(include_default: false)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Node 1: Planning
|
|
44
|
+
node(:planning) do
|
|
45
|
+
agent(:planner)
|
|
46
|
+
|
|
47
|
+
output do |ctx|
|
|
48
|
+
puts "\n[planning output transformer]"
|
|
49
|
+
puts " ctx.content: #{ctx.content[0..60]}..."
|
|
50
|
+
puts " ctx.original_prompt: #{ctx.original_prompt}"
|
|
51
|
+
puts " ctx.node_name: #{ctx.node_name}"
|
|
52
|
+
|
|
53
|
+
"PLAN: #{ctx.content}"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Node 2: Implementation
|
|
58
|
+
node(:implementation) do
|
|
59
|
+
agent(:implementer)
|
|
60
|
+
depends_on(:planning)
|
|
61
|
+
|
|
62
|
+
input do |ctx|
|
|
63
|
+
puts "\n[implementation input transformer]"
|
|
64
|
+
puts " ctx.content (transformed from planning): #{ctx.content[0..60]}..."
|
|
65
|
+
puts " ctx.original_prompt: #{ctx.original_prompt}"
|
|
66
|
+
puts " ctx.all_results[:planning].content: #{ctx.all_results[:planning].content[0..40]}..."
|
|
67
|
+
puts " ctx.node_name: #{ctx.node_name}"
|
|
68
|
+
puts " ctx.dependencies: #{ctx.dependencies.inspect}"
|
|
69
|
+
|
|
70
|
+
ctx.content
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
output do |ctx|
|
|
74
|
+
"IMPLEMENTATION: #{ctx.content}"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Node 3: Review - demonstrate accessing ALL previous results
|
|
79
|
+
node(:review) do
|
|
80
|
+
agent(:reviewer) # No delegation, just solo review
|
|
81
|
+
|
|
82
|
+
depends_on(:implementation)
|
|
83
|
+
|
|
84
|
+
input do |ctx|
|
|
85
|
+
puts "\n[review input transformer]"
|
|
86
|
+
puts " ctx.original_prompt: #{ctx.original_prompt}"
|
|
87
|
+
puts " ctx.all_results.keys: #{ctx.all_results.keys.inspect}"
|
|
88
|
+
|
|
89
|
+
# Access specific previous nodes
|
|
90
|
+
plan = ctx.all_results[:planning].content
|
|
91
|
+
impl = ctx.all_results[:implementation].content
|
|
92
|
+
|
|
93
|
+
puts " Planning node result: #{plan[0..40]}..."
|
|
94
|
+
puts " Implementation node result: #{impl[0..40]}..."
|
|
95
|
+
|
|
96
|
+
<<~PROMPT
|
|
97
|
+
Review this work:
|
|
98
|
+
|
|
99
|
+
ORIGINAL REQUEST: #{ctx.original_prompt}
|
|
100
|
+
|
|
101
|
+
PLAN:
|
|
102
|
+
#{plan}
|
|
103
|
+
|
|
104
|
+
IMPLEMENTATION:
|
|
105
|
+
#{impl}
|
|
106
|
+
|
|
107
|
+
Provide feedback.
|
|
108
|
+
PROMPT
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
start_node(:planning)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
puts "=" * 80
|
|
116
|
+
puts "NodeContext Demo"
|
|
117
|
+
puts "=" * 80
|
|
118
|
+
puts "\nExecuting workflow with NodeContext...\n"
|
|
119
|
+
|
|
120
|
+
result = swarm.execute("Build a todo API")
|
|
121
|
+
|
|
122
|
+
puts "\n"
|
|
123
|
+
puts "=" * 80
|
|
124
|
+
puts "Final Result:"
|
|
125
|
+
puts "=" * 80
|
|
126
|
+
puts result.content
|
|
127
|
+
puts "=" * 80
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Node-Based Workflow Example
|
|
5
|
+
#
|
|
6
|
+
# This example demonstrates how to use nodes to create multi-stage workflows
|
|
7
|
+
# where different teams of agents collaborate in sequence.
|
|
8
|
+
#
|
|
9
|
+
# Features demonstrated:
|
|
10
|
+
# - NodeContext for accessing original_prompt and all_results
|
|
11
|
+
# - Multi-node workflows with delegation
|
|
12
|
+
# - Input/output transformers with full context access
|
|
13
|
+
#
|
|
14
|
+
# Run: ruby examples/node_workflow.rb
|
|
15
|
+
|
|
16
|
+
require_relative "../lib/swarm_sdk"
|
|
17
|
+
|
|
18
|
+
swarm = SwarmSDK.build do
|
|
19
|
+
name("Haiku Workflow")
|
|
20
|
+
|
|
21
|
+
# Define all agents globally
|
|
22
|
+
agent(:planner) do
|
|
23
|
+
model("claude-sonnet-4-5")
|
|
24
|
+
description("Planning agent who breaks down tasks into smaller subtasks")
|
|
25
|
+
provider("openai")
|
|
26
|
+
system_prompt(<<~PROMPT)
|
|
27
|
+
Your job is to break down tasks into smaller subtasks. Extract the intent of the user's prompt and break it down into smaller subtasks.
|
|
28
|
+
Return a list of subtasks.
|
|
29
|
+
PROMPT
|
|
30
|
+
tools(include_default: false)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
agent(:implementer) do
|
|
34
|
+
model("claude-sonnet-4-5")
|
|
35
|
+
description("Execution agent who executes the subtasks given to them")
|
|
36
|
+
provider("openai")
|
|
37
|
+
system_prompt(<<~PROMPT)
|
|
38
|
+
Your job is to execute the subtasks given to you.
|
|
39
|
+
PROMPT
|
|
40
|
+
tools(include_default: false)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
agent(:verifier) do
|
|
44
|
+
model("claude-sonnet-4-5")
|
|
45
|
+
description("Verifier agent who verifies the implementation")
|
|
46
|
+
provider("openai")
|
|
47
|
+
system_prompt(<<~PROMPT)
|
|
48
|
+
Your job is to verify work given to you and return a summary of your findings
|
|
49
|
+
PROMPT
|
|
50
|
+
tools(include_default: false)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Stage 1: Planning
|
|
54
|
+
node(:planning) do
|
|
55
|
+
# Input transformer - ctx.content is the initial prompt
|
|
56
|
+
input do |ctx|
|
|
57
|
+
<<~PROMPT
|
|
58
|
+
Please break down the following prompt into smaller subtasks:
|
|
59
|
+
|
|
60
|
+
#{ctx.content}
|
|
61
|
+
PROMPT
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
agent(:planner)
|
|
65
|
+
|
|
66
|
+
# Output transformer - ctx has access to original prompt and results
|
|
67
|
+
output do |ctx|
|
|
68
|
+
<<~PROMPT
|
|
69
|
+
Here are the subtasks:
|
|
70
|
+
|
|
71
|
+
#{ctx.content}
|
|
72
|
+
|
|
73
|
+
Please implement these subtasks.
|
|
74
|
+
PROMPT
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Stage 2: Implementation
|
|
79
|
+
node(:implementation) do
|
|
80
|
+
# verifier is auto-added (mentioned in delegates_to)
|
|
81
|
+
agent(:implementer).delegates_to(:verifier)
|
|
82
|
+
|
|
83
|
+
depends_on(:planning)
|
|
84
|
+
|
|
85
|
+
# Demonstrate NodeContext in input transformer
|
|
86
|
+
input do |ctx|
|
|
87
|
+
puts "\n[Node: implementation]"
|
|
88
|
+
puts " Original prompt: '#{ctx.original_prompt}'"
|
|
89
|
+
puts " Planning result: '#{ctx.all_results[:planning].content[0..60]}...'"
|
|
90
|
+
puts " Transformed input: '#{ctx.content[0..60]}...'\n"
|
|
91
|
+
|
|
92
|
+
ctx.content # Use transformed content from planning output
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Transform output for review stage
|
|
96
|
+
output do |ctx|
|
|
97
|
+
<<~PROMPT
|
|
98
|
+
Here is the implementation:
|
|
99
|
+
|
|
100
|
+
#{ctx.content}
|
|
101
|
+
|
|
102
|
+
Please review this implementation against the original plan.
|
|
103
|
+
PROMPT
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Stage 3: Review
|
|
108
|
+
node(:review) do
|
|
109
|
+
agent(:verifier)
|
|
110
|
+
|
|
111
|
+
depends_on(:implementation)
|
|
112
|
+
|
|
113
|
+
# Demonstrate full NodeContext capabilities - access ALL previous results
|
|
114
|
+
input do |ctx|
|
|
115
|
+
# Access original prompt
|
|
116
|
+
original = ctx.original_prompt
|
|
117
|
+
|
|
118
|
+
# Access specific previous node results via all_results
|
|
119
|
+
plan = ctx.all_results[:planning].content
|
|
120
|
+
implementation = ctx.all_results[:implementation].content
|
|
121
|
+
|
|
122
|
+
# Current (transformed) content from implementation output
|
|
123
|
+
transformed = ctx.content
|
|
124
|
+
|
|
125
|
+
puts "\n[Node: review]"
|
|
126
|
+
puts " Accessing via NodeContext:"
|
|
127
|
+
puts " - Original prompt: '#{original}'"
|
|
128
|
+
puts " - Planning result: '#{plan[0..50]}...'"
|
|
129
|
+
puts " - Implementation result: '#{implementation[0..50]}...'"
|
|
130
|
+
puts " - Transformed input: '#{transformed[0..50]}...'\n"
|
|
131
|
+
|
|
132
|
+
<<~PROMPT
|
|
133
|
+
Review the implementation against the original plan:
|
|
134
|
+
|
|
135
|
+
ORIGINAL REQUEST: #{original}
|
|
136
|
+
|
|
137
|
+
PLAN:
|
|
138
|
+
#{plan}
|
|
139
|
+
|
|
140
|
+
IMPLEMENTATION:
|
|
141
|
+
#{implementation}
|
|
142
|
+
|
|
143
|
+
Provide feedback on whether this follows the plan and suggest improvements.
|
|
144
|
+
PROMPT
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
start_node(:planning)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
puts "=" * 80
|
|
152
|
+
puts "Node-Based Workflow Example"
|
|
153
|
+
puts "=" * 80
|
|
154
|
+
puts
|
|
155
|
+
puts "This swarm has 3 stages:"
|
|
156
|
+
puts "1. Planning - Break down the task"
|
|
157
|
+
puts "2. Implementation - Execute the subtasks"
|
|
158
|
+
puts "3. Review - Verify the work"
|
|
159
|
+
puts
|
|
160
|
+
puts "=" * 80
|
|
161
|
+
puts
|
|
162
|
+
|
|
163
|
+
# Execute the workflow
|
|
164
|
+
result = swarm.execute("Write a haiku about the weather") do |log|
|
|
165
|
+
puts log.to_json
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
puts "\n"
|
|
169
|
+
puts "=" * 80
|
|
170
|
+
puts "Final Result:"
|
|
171
|
+
puts "=" * 80
|
|
172
|
+
puts result.content
|
|
173
|
+
puts "=" * 80
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Path Resolution Demo
|
|
5
|
+
#
|
|
6
|
+
# Demonstrates how SwarmSDK resolves file paths relative to agent directories.
|
|
7
|
+
# This is a CRITICAL feature introduced in v1.0 that ensures agents operate
|
|
8
|
+
# in their configured directory, not Dir.pwd.
|
|
9
|
+
#
|
|
10
|
+
# Key Concepts:
|
|
11
|
+
# 1. Each agent has a `directory` (singular) configuration
|
|
12
|
+
# 2. Relative paths in file tools are resolved against this directory
|
|
13
|
+
# 3. Absolute paths are used as-is
|
|
14
|
+
# 4. This is fiber-safe (no reliance on Dir.pwd)
|
|
15
|
+
#
|
|
16
|
+
# Run: bundle exec ruby -Ilib lib/swarm_sdk/examples/path_resolution_demo.rb
|
|
17
|
+
|
|
18
|
+
require "swarm_sdk"
|
|
19
|
+
require "fileutils"
|
|
20
|
+
require "tmpdir"
|
|
21
|
+
|
|
22
|
+
ENV["OPENAI_API_KEY"] = "test-key"
|
|
23
|
+
|
|
24
|
+
# Create a test directory structure for demonstration
|
|
25
|
+
demo_root = File.join(Dir.tmpdir, "swarm_path_demo_#{Process.pid}")
|
|
26
|
+
FileUtils.mkdir_p(demo_root)
|
|
27
|
+
|
|
28
|
+
# Create subdirectories
|
|
29
|
+
frontend_dir = File.join(demo_root, "frontend")
|
|
30
|
+
backend_dir = File.join(demo_root, "backend")
|
|
31
|
+
shared_dir = File.join(demo_root, "shared")
|
|
32
|
+
|
|
33
|
+
FileUtils.mkdir_p([frontend_dir, backend_dir, shared_dir])
|
|
34
|
+
|
|
35
|
+
# Create test files
|
|
36
|
+
File.write(File.join(frontend_dir, "index.html"), "<html><body>Frontend</body></html>")
|
|
37
|
+
File.write(File.join(backend_dir, "server.rb"), "puts 'Backend server'")
|
|
38
|
+
File.write(File.join(shared_dir, "config.yml"), "shared: true")
|
|
39
|
+
File.write(File.join(demo_root, "README.md"), "# Project Root")
|
|
40
|
+
|
|
41
|
+
puts "=" * 80
|
|
42
|
+
puts "PATH RESOLUTION DEMO"
|
|
43
|
+
puts "=" * 80
|
|
44
|
+
puts ""
|
|
45
|
+
puts "Test directory structure created at: #{demo_root}"
|
|
46
|
+
puts ""
|
|
47
|
+
puts "Directory structure:"
|
|
48
|
+
puts " #{demo_root}/"
|
|
49
|
+
puts " ├── README.md"
|
|
50
|
+
puts " ├── frontend/"
|
|
51
|
+
puts " │ └── index.html"
|
|
52
|
+
puts " ├── backend/"
|
|
53
|
+
puts " │ └── server.rb"
|
|
54
|
+
puts " └── shared/"
|
|
55
|
+
puts " └── config.yml"
|
|
56
|
+
puts ""
|
|
57
|
+
puts "=" * 80
|
|
58
|
+
puts ""
|
|
59
|
+
|
|
60
|
+
# Build a swarm with agents in different directories
|
|
61
|
+
swarm = SwarmSDK.build do
|
|
62
|
+
name("Path Resolution Demo Swarm")
|
|
63
|
+
lead(:coordinator)
|
|
64
|
+
|
|
65
|
+
# Coordinator works in project root
|
|
66
|
+
agent(:coordinator) do
|
|
67
|
+
description("Coordinator working in project root")
|
|
68
|
+
model("gpt-5-nano")
|
|
69
|
+
provider("openai")
|
|
70
|
+
|
|
71
|
+
# This agent's directory is the project root
|
|
72
|
+
directory(demo_root)
|
|
73
|
+
|
|
74
|
+
tools(:Read, :Write, :Glob)
|
|
75
|
+
delegates_to(:frontend_agent, :backend_agent)
|
|
76
|
+
|
|
77
|
+
system_prompt(<<~PROMPT)
|
|
78
|
+
You demonstrate path resolution behavior in SwarmSDK.
|
|
79
|
+
|
|
80
|
+
Your working directory is: #{demo_root}
|
|
81
|
+
|
|
82
|
+
When you use file tools:
|
|
83
|
+
- Relative paths like "README.md" resolve to #{File.join(demo_root, "README.md")}
|
|
84
|
+
- Relative paths like "frontend/index.html" resolve to #{File.join(demo_root, "frontend/index.html")}
|
|
85
|
+
- Absolute paths like "/tmp/test.txt" are used as-is
|
|
86
|
+
|
|
87
|
+
Demonstrate this by:
|
|
88
|
+
1. Reading "README.md" (relative path)
|
|
89
|
+
2. Listing files with Glob("*") (relative pattern)
|
|
90
|
+
3. Trying to access files in subdirectories
|
|
91
|
+
PROMPT
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Frontend agent works in frontend/ directory
|
|
95
|
+
agent(:frontend_agent) do
|
|
96
|
+
description("Frontend agent working in frontend/ directory")
|
|
97
|
+
model("gpt-5-nano")
|
|
98
|
+
provider("openai")
|
|
99
|
+
|
|
100
|
+
# This agent's directory is frontend/
|
|
101
|
+
directory(frontend_dir)
|
|
102
|
+
|
|
103
|
+
tools(:Read, :Write, :Glob)
|
|
104
|
+
|
|
105
|
+
system_prompt(<<~PROMPT)
|
|
106
|
+
You are a frontend agent working in: #{frontend_dir}
|
|
107
|
+
|
|
108
|
+
Path resolution for your tools:
|
|
109
|
+
- Relative path "index.html" → #{File.join(frontend_dir, "index.html")}
|
|
110
|
+
- Relative path "../shared/config.yml" → #{File.join(demo_root, "shared/config.yml")}
|
|
111
|
+
- Absolute paths are used as-is
|
|
112
|
+
|
|
113
|
+
When asked to demonstrate:
|
|
114
|
+
1. Read "index.html" (relative path in your directory)
|
|
115
|
+
2. Try to read "../shared/config.yml" (relative path to parent)
|
|
116
|
+
3. List files with Glob("*.html") (relative pattern)
|
|
117
|
+
PROMPT
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Backend agent works in backend/ directory
|
|
121
|
+
agent(:backend_agent) do
|
|
122
|
+
description("Backend agent working in backend/ directory")
|
|
123
|
+
model("gpt-5-nano")
|
|
124
|
+
provider("openai")
|
|
125
|
+
|
|
126
|
+
# This agent's directory is backend/
|
|
127
|
+
directory(backend_dir)
|
|
128
|
+
|
|
129
|
+
tools(:Read, :Write, :Glob)
|
|
130
|
+
|
|
131
|
+
system_prompt(<<~PROMPT)
|
|
132
|
+
You are a backend agent working in: #{backend_dir}
|
|
133
|
+
|
|
134
|
+
Path resolution for your tools:
|
|
135
|
+
- Relative path "server.rb" → #{File.join(backend_dir, "server.rb")}
|
|
136
|
+
- Relative path "../README.md" → #{File.join(demo_root, "README.md")}
|
|
137
|
+
- Absolute paths are used as-is
|
|
138
|
+
|
|
139
|
+
When asked to demonstrate:
|
|
140
|
+
1. Read "server.rb" (relative path in your directory)
|
|
141
|
+
2. Try to read "../README.md" (relative path to parent)
|
|
142
|
+
3. List files with Glob("*.rb") (relative pattern)
|
|
143
|
+
PROMPT
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
puts "✅ Swarm created with 3 agents in different directories"
|
|
148
|
+
puts ""
|
|
149
|
+
puts "Agent Directories:"
|
|
150
|
+
puts " coordinator → #{demo_root}"
|
|
151
|
+
puts " frontend_agent → #{frontend_dir}"
|
|
152
|
+
puts " backend_agent → #{backend_dir}"
|
|
153
|
+
puts ""
|
|
154
|
+
puts "=" * 80
|
|
155
|
+
puts ""
|
|
156
|
+
|
|
157
|
+
# Verify agent configurations
|
|
158
|
+
puts "AGENT CONFIGURATIONS:"
|
|
159
|
+
puts "-" * 80
|
|
160
|
+
swarm.agent_names.each do |agent_name|
|
|
161
|
+
agent_def = swarm.agent_definition(agent_name)
|
|
162
|
+
puts "#{agent_name}:"
|
|
163
|
+
puts " directory: #{agent_def.directory}"
|
|
164
|
+
puts " tools: #{agent_def.tools.map { |t| t[:name] }.join(", ")}"
|
|
165
|
+
puts ""
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
puts "PATH RESOLUTION EXAMPLES:"
|
|
169
|
+
puts "-" * 80
|
|
170
|
+
puts ""
|
|
171
|
+
puts "Coordinator (directory: #{demo_root}):"
|
|
172
|
+
puts " 'README.md' → #{File.join(demo_root, "README.md")}"
|
|
173
|
+
puts " 'frontend/index.html' → #{File.join(demo_root, "frontend/index.html")}"
|
|
174
|
+
puts ""
|
|
175
|
+
puts "Frontend Agent (directory: #{frontend_dir}):"
|
|
176
|
+
puts " 'index.html' → #{File.join(frontend_dir, "index.html")}"
|
|
177
|
+
puts " '../shared/config.yml' → #{File.join(demo_root, "shared/config.yml")}"
|
|
178
|
+
puts " '../README.md' → #{File.join(demo_root, "README.md")}"
|
|
179
|
+
puts ""
|
|
180
|
+
puts "Backend Agent (directory: #{backend_dir}):"
|
|
181
|
+
puts " 'server.rb' → #{File.join(backend_dir, "server.rb")}"
|
|
182
|
+
puts " '../shared/config.yml' → #{File.join(demo_root, "shared/config.yml")}"
|
|
183
|
+
puts " '../README.md' → #{File.join(demo_root, "README.md")}"
|
|
184
|
+
puts ""
|
|
185
|
+
|
|
186
|
+
# Uncomment below to test with actual LLM calls (requires API key and time)
|
|
187
|
+
# puts "LIVE TESTS (uncomment to run):"
|
|
188
|
+
# puts "-" * 80
|
|
189
|
+
# result = swarm.execute("Read the file 'README.md' and tell me what it contains.")
|
|
190
|
+
# puts "Result: #{result.content}"
|
|
191
|
+
# puts ""
|
|
192
|
+
|
|
193
|
+
puts "=" * 80
|
|
194
|
+
puts "KEY TAKEAWAYS"
|
|
195
|
+
puts "=" * 80
|
|
196
|
+
puts ""
|
|
197
|
+
puts "1. Each agent has ONE directory (singular, not plural)"
|
|
198
|
+
puts "2. Relative paths are resolved against the agent's directory"
|
|
199
|
+
puts "3. Absolute paths are used as-is"
|
|
200
|
+
puts "4. Agents can access parent/sibling dirs via '../' relative paths"
|
|
201
|
+
puts "5. This is fiber-safe and doesn't rely on Dir.pwd"
|
|
202
|
+
puts ""
|
|
203
|
+
puts "MIGRATION NOTE:"
|
|
204
|
+
puts " OLD (v0.x): directories: ['.', 'lib/', 'test/'] # Multiple dirs"
|
|
205
|
+
puts " NEW (v1.0): directory: 'lib/' # Single dir"
|
|
206
|
+
puts ""
|
|
207
|
+
puts "For multi-directory access, use permissions:"
|
|
208
|
+
puts " directory: 'lib/'"
|
|
209
|
+
puts " permissions:"
|
|
210
|
+
puts " Read:"
|
|
211
|
+
puts " allowed_paths: ['../test/**']"
|
|
212
|
+
puts ""
|
|
213
|
+
|
|
214
|
+
# Cleanup
|
|
215
|
+
FileUtils.rm_rf(demo_root)
|
|
216
|
+
puts "✅ Demo complete! Test directory cleaned up."
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Ruby DSL version of simple-swarm-v2.yml
|
|
4
|
+
#
|
|
5
|
+
# This demonstrates how to define the same swarm using Ruby's programmatic DSL
|
|
6
|
+
# instead of YAML. The Ruby DSL provides more flexibility and allows for
|
|
7
|
+
# dynamic configuration, conditionals, and Ruby language features.
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# swarm run examples/v2/simple-swarm-v2.rb
|
|
11
|
+
# swarm run examples/v2/simple-swarm-v2.rb "Build a user authentication system"
|
|
12
|
+
# swarm run examples/v2/simple-swarm-v2.rb -p "Create a REST API for products"
|
|
13
|
+
|
|
14
|
+
SwarmSDK.build do
|
|
15
|
+
name "Full-Stack Development Team"
|
|
16
|
+
lead :architect
|
|
17
|
+
|
|
18
|
+
# Lead architect who coordinates the team
|
|
19
|
+
agent :architect do
|
|
20
|
+
coding_agent(true)
|
|
21
|
+
description "Lead architect who coordinates the development team"
|
|
22
|
+
model "gpt-5-mini"
|
|
23
|
+
provider "openai"
|
|
24
|
+
|
|
25
|
+
system_prompt <<~PROMPT
|
|
26
|
+
You are the lead architect coordinating a development team. You have access to:
|
|
27
|
+
- frontend_dev: Specializes in React and UI/UX
|
|
28
|
+
- backend_dev: Specializes in APIs and databases
|
|
29
|
+
- qa_engineer: Handles testing and code review
|
|
30
|
+
|
|
31
|
+
When given a task, break it down and delegate appropriately. Frontend work goes
|
|
32
|
+
to frontend_dev, backend work to backend_dev. Always have qa_engineer review
|
|
33
|
+
the final implementation.
|
|
34
|
+
For maximum efficiency, whenever you need to perform multiple independent operations, invoke all relevant tools simultaneously rather than sequentially.
|
|
35
|
+
PROMPT
|
|
36
|
+
|
|
37
|
+
delegates_to :frontend_dev, :backend_dev, :qa_engineer
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Frontend specialist
|
|
41
|
+
agent :frontend_dev do
|
|
42
|
+
coding_agent(true)
|
|
43
|
+
description "Frontend developer specializing in React and UI/UX"
|
|
44
|
+
model "anthropic:claude-sonnet-4-5"
|
|
45
|
+
provider "openai"
|
|
46
|
+
system_prompt <<~PROMPT
|
|
47
|
+
You are a frontend developer specializing in React and modern UI/UX.
|
|
48
|
+
Focus on component design, user experience, and responsive layouts.
|
|
49
|
+
When you complete work, you can delegate to qa_engineer for review.
|
|
50
|
+
For maximum efficiency, whenever you need to perform multiple independent operations, invoke all relevant tools simultaneously rather than sequentially.
|
|
51
|
+
PROMPT
|
|
52
|
+
|
|
53
|
+
delegates_to :qa_engineer
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Backend specialist
|
|
57
|
+
agent :backend_dev do
|
|
58
|
+
coding_agent(true)
|
|
59
|
+
description "Backend developer specializing in APIs and databases"
|
|
60
|
+
model "anthropic:claude-sonnet-4-5"
|
|
61
|
+
provider "openai"
|
|
62
|
+
|
|
63
|
+
system_prompt <<~PROMPT
|
|
64
|
+
You are a backend developer specializing in REST APIs, databases, and
|
|
65
|
+
server-side logic. Focus on scalability, security, and clean architecture.
|
|
66
|
+
When you complete work, you can delegate to qa_engineer for review.
|
|
67
|
+
For maximum efficiency, whenever you need to perform multiple independent operations, invoke all relevant tools simultaneously rather than sequentially.
|
|
68
|
+
PROMPT
|
|
69
|
+
|
|
70
|
+
delegates_to :qa_engineer
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# QA engineer
|
|
74
|
+
agent :qa_engineer do
|
|
75
|
+
coding_agent(true)
|
|
76
|
+
description "QA engineer who reviews code and creates test plans"
|
|
77
|
+
model "gpt-5-mini"
|
|
78
|
+
provider "openai"
|
|
79
|
+
|
|
80
|
+
system_prompt <<~PROMPT
|
|
81
|
+
You are a QA engineer responsible for code review and test planning.
|
|
82
|
+
Review implementations for bugs, edge cases, and potential issues.
|
|
83
|
+
Suggest improvements and create comprehensive test plans.
|
|
84
|
+
Be thorough but constructive in your feedback.
|
|
85
|
+
For maximum efficiency, whenever you need to perform multiple independent operations, invoke all relevant tools simultaneously rather than sequentially.
|
|
86
|
+
PROMPT
|
|
87
|
+
|
|
88
|
+
delegates_to # No delegations
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
swarm:
|
|
3
|
+
name: "Full-Stack Development Team"
|
|
4
|
+
lead: architect
|
|
5
|
+
agents:
|
|
6
|
+
architect:
|
|
7
|
+
description: "Lead architect who coordinates the development team"
|
|
8
|
+
model: gpt-5-mini
|
|
9
|
+
provider: openai
|
|
10
|
+
system_prompt: |
|
|
11
|
+
You are the lead architect coordinating a development team. You have access to:
|
|
12
|
+
- frontend_dev: Specializes in React and UI/UX
|
|
13
|
+
- backend_dev: Specializes in APIs and databases
|
|
14
|
+
- qa_engineer: Handles testing and code review
|
|
15
|
+
|
|
16
|
+
When given a task, break it down and delegate appropriately. Frontend work goes
|
|
17
|
+
to frontend_dev, backend work to backend_dev. Always have qa_engineer review
|
|
18
|
+
the final implementation.
|
|
19
|
+
For maximum efficiency, whenever you need to perform multiple independent operations, invoke all relevant tools simultaneously rather than sequentially.
|
|
20
|
+
tools: []
|
|
21
|
+
delegates_to: [frontend_dev, backend_dev, qa_engineer]
|
|
22
|
+
directory: .
|
|
23
|
+
|
|
24
|
+
frontend_dev:
|
|
25
|
+
description: "Frontend developer specializing in React and UI/UX"
|
|
26
|
+
model: anthropic:claude-sonnet-4-5
|
|
27
|
+
provider: openai
|
|
28
|
+
system_prompt: |
|
|
29
|
+
You are a frontend developer specializing in React and modern UI/UX.
|
|
30
|
+
Focus on component design, user experience, and responsive layouts.
|
|
31
|
+
When you complete work, you can delegate to qa_engineer for review.
|
|
32
|
+
For maximum efficiency, whenever you need to perform multiple independent operations, invoke all relevant tools simultaneously rather than sequentially.
|
|
33
|
+
tools: []
|
|
34
|
+
delegates_to: [qa_engineer]
|
|
35
|
+
directory: .
|
|
36
|
+
|
|
37
|
+
backend_dev:
|
|
38
|
+
description: "Backend developer specializing in APIs and databases"
|
|
39
|
+
model: anthropic:claude-sonnet-4-5
|
|
40
|
+
provider: openai
|
|
41
|
+
system_prompt: |
|
|
42
|
+
You are a backend developer specializing in REST APIs, databases, and
|
|
43
|
+
server-side logic. Focus on scalability, security, and clean architecture.
|
|
44
|
+
When you complete work, you can delegate to qa_engineer for review.
|
|
45
|
+
For maximum efficiency, whenever you need to perform multiple independent operations, invoke all relevant tools simultaneously rather than sequentially.
|
|
46
|
+
tools: []
|
|
47
|
+
delegates_to: [qa_engineer]
|
|
48
|
+
directory: .
|
|
49
|
+
|
|
50
|
+
qa_engineer:
|
|
51
|
+
description: "QA engineer who reviews code and creates test plans"
|
|
52
|
+
model: gpt-5-mini
|
|
53
|
+
provider: openai
|
|
54
|
+
system_prompt: |
|
|
55
|
+
You are a QA engineer responsible for code review and test planning.
|
|
56
|
+
Review implementations for bugs, edge cases, and potential issues.
|
|
57
|
+
Suggest improvements and create comprehensive test plans.
|
|
58
|
+
Be thorough but constructive in your feedback.
|
|
59
|
+
For maximum efficiency, whenever you need to perform multiple independent operations, invoke all relevant tools simultaneously rather than sequentially.
|
|
60
|
+
tools: []
|
|
61
|
+
delegates_to: []
|
|
62
|
+
directory: .
|