claude_swarm 1.0.1 → 1.0.4
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 +7 -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 +249 -6
- data/EXAMPLES.md +0 -164
|
@@ -0,0 +1,1745 @@
|
|
|
1
|
+
# Getting Started with SwarmCLI
|
|
2
|
+
|
|
3
|
+
## What You'll Learn
|
|
4
|
+
|
|
5
|
+
- What SwarmCLI is and when to use it
|
|
6
|
+
- How to install and verify SwarmCLI (separate from SwarmSDK)
|
|
7
|
+
- The two execution modes: interactive (REPL) and non-interactive
|
|
8
|
+
- Available commands and their purposes
|
|
9
|
+
- How to use the interactive REPL for conversations
|
|
10
|
+
- How to use non-interactive mode with NDJSON streaming for automation
|
|
11
|
+
- Working with configuration files (YAML and Ruby DSL)
|
|
12
|
+
- Common workflows and real-world examples
|
|
13
|
+
- How to parse NDJSON output correctly (not single JSON objects)
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
- **Ruby 3.2.0 or higher** installed on your system
|
|
18
|
+
- **LLM API access** - an API key for OpenAI, Anthropic, or another provider
|
|
19
|
+
- **A swarm configuration file** - either YAML or Ruby DSL (see [Getting Started with SwarmSDK](getting-started.md))
|
|
20
|
+
- **10-15 minutes** to complete this guide
|
|
21
|
+
|
|
22
|
+
## What is SwarmCLI?
|
|
23
|
+
|
|
24
|
+
SwarmCLI is a command-line interface for running SwarmSDK swarms. It's a **separate gem** (`swarm_cli`) that depends on and extends `swarm_sdk`. Installing `swarm_cli` automatically installs `swarm_sdk` as a dependency.
|
|
25
|
+
|
|
26
|
+
**Two separate gems**:
|
|
27
|
+
- **`swarm_sdk`** - The core library for building agent swarms
|
|
28
|
+
- **`swarm_cli`** - The CLI tool for running swarms from the terminal
|
|
29
|
+
|
|
30
|
+
SwarmCLI provides two ways to interact with your AI agent teams:
|
|
31
|
+
|
|
32
|
+
**Interactive Mode (REPL)**: A conversational interface where you chat with your swarm in real-time. Perfect for:
|
|
33
|
+
- Exploratory work and experimentation
|
|
34
|
+
- Iterative development with feedback loops
|
|
35
|
+
- Learning how your agents collaborate
|
|
36
|
+
- Long conversations with context preservation
|
|
37
|
+
|
|
38
|
+
**Non-Interactive Mode**: One-shot task execution with immediate results and NDJSON streaming. Perfect for:
|
|
39
|
+
- Automation and scripting
|
|
40
|
+
- CI/CD pipelines
|
|
41
|
+
- Batch processing
|
|
42
|
+
- Real-time monitoring and cost tracking
|
|
43
|
+
- Scheduled tasks
|
|
44
|
+
|
|
45
|
+
**Why use SwarmCLI?** Instead of writing Ruby code to execute your swarms, you can simply run `swarm run config.yml` and start working. It's faster for quick tasks and provides a polished terminal experience with structured JSON output for automation.
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
Install the SwarmCLI gem (which automatically installs SwarmSDK as a dependency):
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
gem install swarm_cli
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**What gets installed**:
|
|
56
|
+
- `swarm_cli` gem (the CLI tool)
|
|
57
|
+
- `swarm_sdk` gem (automatically as a dependency)
|
|
58
|
+
- `swarm` executable (the command you'll use)
|
|
59
|
+
|
|
60
|
+
Or add to your Gemfile:
|
|
61
|
+
|
|
62
|
+
```ruby
|
|
63
|
+
gem 'swarm_cli' # This will also install swarm_sdk as a dependency
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Then install:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
bundle install
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Important notes**:
|
|
73
|
+
- `swarm_cli` and `swarm_sdk` are **separate gems**
|
|
74
|
+
- Installing `swarm_cli` automatically installs `swarm_sdk`
|
|
75
|
+
- The executable is called `swarm` (NOT `swarm_cli`)
|
|
76
|
+
- Requires Ruby 3.2.0 or higher
|
|
77
|
+
|
|
78
|
+
### Verify Installation
|
|
79
|
+
|
|
80
|
+
Check that SwarmCLI is installed correctly:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
swarm --version
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Expected output**:
|
|
87
|
+
```
|
|
88
|
+
SwarmCLI v2.0.0
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Check Ruby version:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
ruby -v
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Expected output**:
|
|
98
|
+
```
|
|
99
|
+
ruby 3.2.0 (or higher)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Get help on available commands:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
swarm --help
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Expected output**:
|
|
109
|
+
```
|
|
110
|
+
SwarmCLI v2.0.0 - AI Agent Orchestration
|
|
111
|
+
|
|
112
|
+
Usage:
|
|
113
|
+
swarm run CONFIG_FILE -p PROMPT [options]
|
|
114
|
+
swarm migrate INPUT_FILE [--output OUTPUT_FILE]
|
|
115
|
+
swarm mcp serve CONFIG_FILE
|
|
116
|
+
swarm mcp tools [TOOL_NAMES...]
|
|
117
|
+
|
|
118
|
+
Commands:
|
|
119
|
+
run Execute a swarm with AI agents
|
|
120
|
+
migrate Migrate Claude Swarm v1 config to SwarmSDK v2 format
|
|
121
|
+
mcp serve Start an MCP server exposing swarm lead agent
|
|
122
|
+
mcp tools Start an MCP server exposing SwarmSDK tools
|
|
123
|
+
|
|
124
|
+
Options:
|
|
125
|
+
-p, --prompt PROMPT Task prompt for the swarm
|
|
126
|
+
-o, --output FILE Output file for migrated config (default: stdout)
|
|
127
|
+
--output-format FORMAT Output format: 'human' or 'json' (default: human)
|
|
128
|
+
-q, --quiet Suppress progress output (human format only)
|
|
129
|
+
--truncate Truncate long outputs for concise view
|
|
130
|
+
--verbose Show system reminders and additional debug information
|
|
131
|
+
-h, --help Print help
|
|
132
|
+
-v, --version Print version
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Quick Start: Your First Command
|
|
136
|
+
|
|
137
|
+
Let's create a simple swarm configuration and run it.
|
|
138
|
+
|
|
139
|
+
### Step 1: Create a Configuration File
|
|
140
|
+
|
|
141
|
+
Create a file called `assistant.yml`:
|
|
142
|
+
|
|
143
|
+
```yaml
|
|
144
|
+
version: 2
|
|
145
|
+
swarm:
|
|
146
|
+
name: "Quick Start Assistant"
|
|
147
|
+
lead: helper
|
|
148
|
+
|
|
149
|
+
agents:
|
|
150
|
+
helper:
|
|
151
|
+
description: "A helpful assistant"
|
|
152
|
+
model: "gpt-4"
|
|
153
|
+
system_prompt: |
|
|
154
|
+
You are a helpful assistant.
|
|
155
|
+
Answer questions clearly and concisely.
|
|
156
|
+
tools:
|
|
157
|
+
- Write
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Step 2: Set Your API Key
|
|
161
|
+
|
|
162
|
+
Ensure your API key is set:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
export OPENAI_API_KEY="sk-your-key-here"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Or create a `.env` file:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
echo "OPENAI_API_KEY=sk-your-key-here" > .env
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Step 3: Run Interactive Mode
|
|
175
|
+
|
|
176
|
+
Start a conversation with your swarm:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
swarm run assistant.yml
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**Expected output**:
|
|
183
|
+
```
|
|
184
|
+
────────────────────────────────────────────────────────────
|
|
185
|
+
🚀 Swarm CLI Interactive REPL
|
|
186
|
+
────────────────────────────────────────────────────────────
|
|
187
|
+
|
|
188
|
+
Swarm: Quick Start Assistant
|
|
189
|
+
Lead Agent: helper
|
|
190
|
+
|
|
191
|
+
Type your message and press Enter to submit
|
|
192
|
+
Type /help for commands or /exit to quit
|
|
193
|
+
|
|
194
|
+
────────────────────────────────────────────────────────────
|
|
195
|
+
|
|
196
|
+
You ❯
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**Try it**: Type "What is 2 + 2?" and press Enter.
|
|
200
|
+
|
|
201
|
+
The swarm will process your question and respond. Continue the conversation by typing more messages.
|
|
202
|
+
|
|
203
|
+
### Step 4: Exit the REPL
|
|
204
|
+
|
|
205
|
+
Type `/exit` or press `Ctrl+D` to exit.
|
|
206
|
+
|
|
207
|
+
**Expected output**:
|
|
208
|
+
```
|
|
209
|
+
👋 Goodbye! Thanks for using Swarm CLI
|
|
210
|
+
|
|
211
|
+
────────────────────────────────────────────────────────────
|
|
212
|
+
📊 Session Summary
|
|
213
|
+
────────────────────────────────────────────────────────────
|
|
214
|
+
|
|
215
|
+
Messages sent: 1
|
|
216
|
+
Agents used: helper
|
|
217
|
+
LLM Requests: 1
|
|
218
|
+
Tool Calls: 0
|
|
219
|
+
Total Tokens: 245
|
|
220
|
+
Total Cost: $0.0012
|
|
221
|
+
Session Duration: 1.23s
|
|
222
|
+
|
|
223
|
+
────────────────────────────────────────────────────────────
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Congratulations! You've successfully run your first SwarmCLI command.
|
|
227
|
+
|
|
228
|
+
## Commands Overview
|
|
229
|
+
|
|
230
|
+
SwarmCLI provides four main commands:
|
|
231
|
+
|
|
232
|
+
### 1. swarm run
|
|
233
|
+
|
|
234
|
+
Execute a swarm with your agents. Supports both interactive and non-interactive modes.
|
|
235
|
+
|
|
236
|
+
**Interactive mode (REPL)**:
|
|
237
|
+
```bash
|
|
238
|
+
swarm run config.yml
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Non-interactive mode**:
|
|
242
|
+
```bash
|
|
243
|
+
swarm run config.yml -p "Your task here"
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Key options**:
|
|
247
|
+
- `-p, --prompt PROMPT` - Enable non-interactive mode with a prompt
|
|
248
|
+
- `--output-format FORMAT` - Choose output format: `human` (default) or `json` (NDJSON)
|
|
249
|
+
- `-q, --quiet` - Suppress progress output
|
|
250
|
+
- `--truncate` - Truncate long outputs for concise view
|
|
251
|
+
- `--verbose` - Show additional debug information
|
|
252
|
+
|
|
253
|
+
### 2. swarm migrate
|
|
254
|
+
|
|
255
|
+
Convert old Claude Swarm v1 configurations to SwarmSDK v2 format.
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
swarm migrate old-config.yml
|
|
259
|
+
swarm migrate old-config.yml --output new-config.yml
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**Use case**: Upgrading from version 1 to version 2.
|
|
263
|
+
|
|
264
|
+
### 3. swarm mcp serve
|
|
265
|
+
|
|
266
|
+
Start an MCP (Model Context Protocol) server that exposes your swarm as a tool.
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
swarm mcp serve config.yml
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Use case**: Integrating your swarm with MCP-compatible tools and frameworks.
|
|
273
|
+
|
|
274
|
+
### 4. swarm mcp tools
|
|
275
|
+
|
|
276
|
+
Start an MCP server that exposes SwarmSDK's built-in tools.
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# Expose all tools
|
|
280
|
+
swarm mcp tools
|
|
281
|
+
|
|
282
|
+
# Expose specific tools
|
|
283
|
+
swarm mcp tools Bash Grep Read
|
|
284
|
+
|
|
285
|
+
# Comma-separated (no spaces)
|
|
286
|
+
swarm mcp tools Read,Write,Edit
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**Use case**: Making SwarmSDK tools available to other MCP clients.
|
|
290
|
+
|
|
291
|
+
## Interactive Mode (REPL)
|
|
292
|
+
|
|
293
|
+
The interactive REPL provides a conversational interface for working with your swarm.
|
|
294
|
+
|
|
295
|
+
### Starting the REPL
|
|
296
|
+
|
|
297
|
+
**Basic usage**:
|
|
298
|
+
```bash
|
|
299
|
+
swarm run config.yml
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**With an initial message**:
|
|
303
|
+
```bash
|
|
304
|
+
swarm run config.yml "Start by analyzing the README.md file"
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
**With piped input**:
|
|
308
|
+
```bash
|
|
309
|
+
echo "Summarize the main.rb file" | swarm run config.yml
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
In all three cases above, you'll enter interactive mode, but the last two will send an initial message before the first prompt.
|
|
313
|
+
|
|
314
|
+
### Understanding the Interface
|
|
315
|
+
|
|
316
|
+
Once in the REPL, you'll see:
|
|
317
|
+
|
|
318
|
+
```
|
|
319
|
+
────────────────────────────────────────────────────────────
|
|
320
|
+
🚀 Swarm CLI Interactive REPL
|
|
321
|
+
────────────────────────────────────────────────────────────
|
|
322
|
+
|
|
323
|
+
Swarm: Development Team
|
|
324
|
+
Lead Agent: architect
|
|
325
|
+
|
|
326
|
+
Type your message and press Enter to submit
|
|
327
|
+
Type /help for commands or /exit to quit
|
|
328
|
+
|
|
329
|
+
────────────────────────────────────────────────────────────
|
|
330
|
+
|
|
331
|
+
You ❯
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**What you're seeing**:
|
|
335
|
+
1. **Header** - Welcome banner with swarm information
|
|
336
|
+
2. **Swarm name and lead agent** - Shows which swarm and agent you're talking to
|
|
337
|
+
3. **Instructions** - How to use the REPL
|
|
338
|
+
4. **Prompt** - `You ❯` indicates you can type your message
|
|
339
|
+
|
|
340
|
+
### Conversation Flow
|
|
341
|
+
|
|
342
|
+
**1. Type your message and press Enter**:
|
|
343
|
+
```
|
|
344
|
+
You ❯ What files are in this directory?
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
**2. The swarm processes your request**:
|
|
348
|
+
```
|
|
349
|
+
architect • thinking...
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
**3. The agent responds**:
|
|
353
|
+
```
|
|
354
|
+
architect:
|
|
355
|
+
Based on the directory listing, here are the files:
|
|
356
|
+
- README.md
|
|
357
|
+
- src/main.rb
|
|
358
|
+
- src/config.yml
|
|
359
|
+
- tests/test_main.rb
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**4. Context stats appear before next prompt**:
|
|
363
|
+
```
|
|
364
|
+
[architect • 1 msg • 245 tokens • $0.0012 • 15% context]
|
|
365
|
+
You ❯
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
These stats show:
|
|
369
|
+
- **Agent name**: Which agent you're talking to
|
|
370
|
+
- **Message count**: Number of messages sent
|
|
371
|
+
- **Token usage**: Total tokens consumed
|
|
372
|
+
- **Cost**: Total cost in USD
|
|
373
|
+
- **Context usage**: Percentage of context window used (color-coded: green < 50%, yellow < 80%, red ≥ 80%)
|
|
374
|
+
|
|
375
|
+
### REPL Commands
|
|
376
|
+
|
|
377
|
+
Type `/help` to see available commands:
|
|
378
|
+
|
|
379
|
+
| Command | Description |
|
|
380
|
+
|---------|-------------|
|
|
381
|
+
| `/help` | Show available commands |
|
|
382
|
+
| `/clear` | Clear the screen |
|
|
383
|
+
| `/history` | Show conversation history |
|
|
384
|
+
| `/exit` | Exit the REPL (or press Ctrl+D) |
|
|
385
|
+
|
|
386
|
+
**Using commands**:
|
|
387
|
+
|
|
388
|
+
```
|
|
389
|
+
You ❯ /help
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
Shows a help box with all commands and input tips.
|
|
393
|
+
|
|
394
|
+
```
|
|
395
|
+
You ❯ /history
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Shows your entire conversation with truncated long messages.
|
|
399
|
+
|
|
400
|
+
```
|
|
401
|
+
You ❯ /clear
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
Clears the screen and shows the welcome banner again.
|
|
405
|
+
|
|
406
|
+
```
|
|
407
|
+
You ❯ /exit
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
Exits the REPL and shows a session summary.
|
|
411
|
+
|
|
412
|
+
### Tab Completion
|
|
413
|
+
|
|
414
|
+
The REPL provides intelligent tab completion:
|
|
415
|
+
|
|
416
|
+
**Command completion**: Type `/` and press Tab to see available commands:
|
|
417
|
+
```
|
|
418
|
+
You ❯ /
|
|
419
|
+
/help /clear /history /exit
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
**File path completion**: Type `@` followed by a partial path and press Tab:
|
|
423
|
+
```
|
|
424
|
+
You ❯ Read @src/m
|
|
425
|
+
@src/main.rb @src/models/ @src/modules/
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**Navigation**:
|
|
429
|
+
- Press `Tab` to cycle forward through completions
|
|
430
|
+
- Press `Shift+Tab` to cycle backward
|
|
431
|
+
- Press `Enter` to accept the selected completion
|
|
432
|
+
|
|
433
|
+
### Context Preservation
|
|
434
|
+
|
|
435
|
+
The REPL maintains conversation context across messages:
|
|
436
|
+
|
|
437
|
+
```
|
|
438
|
+
You ❯ What files are in src/?
|
|
439
|
+
|
|
440
|
+
architect:
|
|
441
|
+
The src/ directory contains:
|
|
442
|
+
- main.rb
|
|
443
|
+
- config.yml
|
|
444
|
+
- utils.rb
|
|
445
|
+
|
|
446
|
+
You ❯ What does the first one do?
|
|
447
|
+
|
|
448
|
+
architect:
|
|
449
|
+
main.rb is the entry point. It loads the configuration and starts the application.
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
Notice how the second question ("What does the first one do?") references the previous response. The agent understands you're asking about `main.rb` because the conversation context is preserved.
|
|
453
|
+
|
|
454
|
+
### Session Summary
|
|
455
|
+
|
|
456
|
+
When you exit (via `/exit` or `Ctrl+D`), you'll see a summary:
|
|
457
|
+
|
|
458
|
+
```
|
|
459
|
+
────────────────────────────────────────────────────────────
|
|
460
|
+
📊 Session Summary
|
|
461
|
+
────────────────────────────────────────────────────────────
|
|
462
|
+
|
|
463
|
+
Messages sent: 5
|
|
464
|
+
Agents used: architect, coder, reviewer
|
|
465
|
+
LLM Requests: 8
|
|
466
|
+
Tool Calls: 12
|
|
467
|
+
Total Tokens: 1.2K
|
|
468
|
+
Total Cost: $0.0156
|
|
469
|
+
Session Duration: 2m 34s
|
|
470
|
+
|
|
471
|
+
────────────────────────────────────────────────────────────
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
This shows:
|
|
475
|
+
- **Messages sent**: Number of user messages
|
|
476
|
+
- **Agents used**: Which agents participated
|
|
477
|
+
- **LLM Requests**: Total API calls made
|
|
478
|
+
- **Tool Calls**: Total tool invocations
|
|
479
|
+
- **Tokens and cost**: Session totals
|
|
480
|
+
- **Duration**: Total time in the REPL
|
|
481
|
+
|
|
482
|
+
## Non-Interactive Mode
|
|
483
|
+
|
|
484
|
+
Non-interactive mode executes a single task and exits. Perfect for scripting and automation with structured NDJSON output.
|
|
485
|
+
|
|
486
|
+
### Basic Usage
|
|
487
|
+
|
|
488
|
+
**Provide prompt as argument**:
|
|
489
|
+
```bash
|
|
490
|
+
swarm run config.yml -p "Build a REST API for user management"
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
**Provide prompt via stdin**:
|
|
494
|
+
```bash
|
|
495
|
+
echo "Build a REST API for user management" | swarm run config.yml -p
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
**Use a heredoc for long prompts**:
|
|
499
|
+
```bash
|
|
500
|
+
swarm run config.yml -p "$(cat <<'EOF'
|
|
501
|
+
Build a REST API with the following features:
|
|
502
|
+
1. User registration and authentication
|
|
503
|
+
2. CRUD operations for user profiles
|
|
504
|
+
3. JWT token-based authorization
|
|
505
|
+
4. Input validation and error handling
|
|
506
|
+
EOF
|
|
507
|
+
)"
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### Understanding Output Formats
|
|
511
|
+
|
|
512
|
+
SwarmCLI supports two output formats: `human` (default) and `json` (NDJSON).
|
|
513
|
+
|
|
514
|
+
### Human Format (Default)
|
|
515
|
+
|
|
516
|
+
**Example**:
|
|
517
|
+
```bash
|
|
518
|
+
swarm run config.yml -p "What is 2 + 2?"
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
**Output**:
|
|
522
|
+
```
|
|
523
|
+
Swarm: Quick Start Assistant
|
|
524
|
+
Lead Agent: helper
|
|
525
|
+
Task: What is 2 + 2?
|
|
526
|
+
────────────────────────────────────────────────────────────
|
|
527
|
+
|
|
528
|
+
helper • thinking...
|
|
529
|
+
|
|
530
|
+
helper:
|
|
531
|
+
The answer is 4.
|
|
532
|
+
|
|
533
|
+
────────────────────────────────────────────────────────────
|
|
534
|
+
✓ Success
|
|
535
|
+
Duration: 1.23s • Cost: $0.0012 • Tokens: 245
|
|
536
|
+
────────────────────────────────────────────────────────────
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
The human format provides:
|
|
540
|
+
- **Header**: Swarm info and task
|
|
541
|
+
- **Progress indicators**: Shows what's happening
|
|
542
|
+
- **Agent responses**: Formatted and colored
|
|
543
|
+
- **Summary**: Duration, cost, and token usage
|
|
544
|
+
|
|
545
|
+
### JSON Output Format (NDJSON Event Stream)
|
|
546
|
+
|
|
547
|
+
**CRITICAL**: JSON output is **NDJSON** (newline-delimited JSON), not a single JSON object.
|
|
548
|
+
|
|
549
|
+
For scripting and automation, use JSON format which outputs **newline-delimited JSON (NDJSON)** - one event per line:
|
|
550
|
+
|
|
551
|
+
```bash
|
|
552
|
+
swarm run config.yml -p "What is 2 + 2?" --output-format json
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
**Output** (NDJSON - each line is a separate JSON event):
|
|
556
|
+
```json
|
|
557
|
+
{"type":"swarm_start","swarm_name":"Quick Start Assistant","lead_agent":"helper","prompt":"What is 2 + 2?","timestamp":"2024-01-15T10:30:00Z"}
|
|
558
|
+
{"type":"user_prompt","agent":"helper","model":"gpt-4","message_count":0,"timestamp":"2024-01-15T10:30:00Z"}
|
|
559
|
+
{"type":"agent_step","agent":"helper","model":"gpt-4","content":"","tool_calls":[{"id":"call_123","name":"think","arguments":{}}],"usage":{"prompt_tokens":50,"completion_tokens":10,"total_tokens":60,"cost":0.0003},"timestamp":"2024-01-15T10:30:01Z"}
|
|
560
|
+
{"type":"agent_stop","agent":"helper","model":"gpt-4","content":"The answer is 4.","tool_calls":[],"finish_reason":"stop","usage":{"prompt_tokens":60,"completion_tokens":5,"total_tokens":65,"cost":0.0003},"timestamp":"2024-01-15T10:30:02Z"}
|
|
561
|
+
{"type":"swarm_stop","swarm_name":"Quick Start Assistant","lead_agent":"helper","success":true,"duration":1.23,"total_cost":0.0012,"total_tokens":245,"agents_involved":["helper"],"timestamp":"2024-01-15T10:30:02Z"}
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
**CRITICAL UNDERSTANDING - NDJSON vs Regular JSON**:
|
|
565
|
+
|
|
566
|
+
❌ **NOT a single JSON object**:
|
|
567
|
+
```json
|
|
568
|
+
{
|
|
569
|
+
"events": [
|
|
570
|
+
{"type": "swarm_start", ...},
|
|
571
|
+
{"type": "agent_stop", ...}
|
|
572
|
+
]
|
|
573
|
+
}
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
✅ **NDJSON - one event per line**:
|
|
577
|
+
```
|
|
578
|
+
{"type":"swarm_start",...}
|
|
579
|
+
{"type":"agent_step",...}
|
|
580
|
+
{"type":"agent_stop",...}
|
|
581
|
+
{"type":"swarm_stop",...}
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### Why NDJSON?
|
|
585
|
+
|
|
586
|
+
**Key benefits**:
|
|
587
|
+
1. **Real-time streaming**: Events arrive as they happen (not buffered until completion)
|
|
588
|
+
2. **Line-by-line processing**: Easy to process incrementally with standard tools
|
|
589
|
+
3. **Memory efficient**: No need to load entire response into memory
|
|
590
|
+
4. **Tool friendly**: Works perfectly with `jq`, `grep`, `awk`, etc.
|
|
591
|
+
5. **Fault tolerant**: Partial results available even if process crashes
|
|
592
|
+
|
|
593
|
+
### NDJSON Event Types
|
|
594
|
+
|
|
595
|
+
Each line in NDJSON output is one of these event types:
|
|
596
|
+
|
|
597
|
+
| Event Type | Description | Key Fields |
|
|
598
|
+
|------------|-------------|------------|
|
|
599
|
+
| `swarm_start` | Swarm execution begins | `swarm_name`, `lead_agent`, `prompt` |
|
|
600
|
+
| `user_prompt` | User message sent to agent | `agent`, `model`, `message_count` |
|
|
601
|
+
| `agent_step` | Agent produces intermediate output | `agent`, `content`, `tool_calls`, `usage` |
|
|
602
|
+
| `agent_stop` | Agent completes its response | `agent`, `content`, `finish_reason`, `usage` |
|
|
603
|
+
| `tool_call` | Agent invokes a tool | `tool`, `arguments`, `tool_call_id` |
|
|
604
|
+
| `tool_result` | Tool returns result | `tool`, `result`, `tool_call_id` |
|
|
605
|
+
| `agent_delegation` | Agent delegates to another agent | `agent`, `delegate_to`, `tool_call_id` |
|
|
606
|
+
| `delegation_result` | Delegated agent completes | `agent`, `delegate_from`, `result` |
|
|
607
|
+
| `delegation_error` | Delegation fails | `agent`, `delegate_to`, `error_message` |
|
|
608
|
+
| `node_start` | Node execution begins (workflows) | `node_name`, `lead_agent` |
|
|
609
|
+
| `node_stop` | Node execution completes (workflows) | `node_name`, `success`, `duration` |
|
|
610
|
+
| `model_lookup_warning` | Unknown model in config | `agent`, `model`, `suggestions` |
|
|
611
|
+
| `context_limit_warning` | Context usage threshold crossed | `agent`, `threshold`, `current_usage` |
|
|
612
|
+
| `swarm_stop` | Swarm execution completes | `success`, `duration`, `total_cost`, `agents_involved` |
|
|
613
|
+
|
|
614
|
+
### Processing NDJSON with jq
|
|
615
|
+
|
|
616
|
+
`jq` is the standard tool for processing JSON. Here's how to work with NDJSON:
|
|
617
|
+
|
|
618
|
+
**Extract all agent responses**:
|
|
619
|
+
```bash
|
|
620
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
621
|
+
jq -c 'select(.type == "agent_stop") | .content'
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
**Output**:
|
|
625
|
+
```
|
|
626
|
+
"Here is the first response."
|
|
627
|
+
"Here is the second response."
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
**Calculate total cost from events**:
|
|
631
|
+
```bash
|
|
632
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
633
|
+
jq -s '[.[] | select(.usage) | .usage.cost] | add'
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
**Output**:
|
|
637
|
+
```
|
|
638
|
+
0.0156
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
**Get final success status**:
|
|
642
|
+
```bash
|
|
643
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
644
|
+
jq -c 'select(.type == "swarm_stop") | .success'
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
**Output**:
|
|
648
|
+
```
|
|
649
|
+
true
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
**Extract just the final content**:
|
|
653
|
+
```bash
|
|
654
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
655
|
+
jq -c 'select(.type == "agent_stop") | .content' | tail -1
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
**Output**:
|
|
659
|
+
```
|
|
660
|
+
"The answer is 4."
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
**Track costs in real-time**:
|
|
664
|
+
```bash
|
|
665
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
666
|
+
jq -c 'select(.usage) | {agent, cost: .usage.cost}'
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
**Output** (streaming as events arrive):
|
|
670
|
+
```
|
|
671
|
+
{"agent":"helper","cost":0.0003}
|
|
672
|
+
{"agent":"helper","cost":0.0003}
|
|
673
|
+
{"agent":"helper","cost":0.0006}
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
**Filter tool calls**:
|
|
677
|
+
```bash
|
|
678
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
679
|
+
jq -c 'select(.type == "tool_call") | {tool, arguments}'
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
**Get all agents involved**:
|
|
683
|
+
```bash
|
|
684
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
685
|
+
jq -c 'select(.type == "swarm_stop") | .agents_involved'
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
**Output**:
|
|
689
|
+
```
|
|
690
|
+
["architect","coder","reviewer"]
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
### Processing NDJSON in Bash Scripts
|
|
694
|
+
|
|
695
|
+
**Real-time event processing**:
|
|
696
|
+
```bash
|
|
697
|
+
#!/bin/bash
|
|
698
|
+
# process-events.sh - Process NDJSON events as they arrive
|
|
699
|
+
|
|
700
|
+
swarm run config.yml -p "Task" --output-format json | while IFS= read -r event; do
|
|
701
|
+
type=$(echo "$event" | jq -r '.type')
|
|
702
|
+
|
|
703
|
+
case $type in
|
|
704
|
+
swarm_start)
|
|
705
|
+
swarm_name=$(echo "$event" | jq -r '.swarm_name')
|
|
706
|
+
echo "🚀 Starting swarm: $swarm_name"
|
|
707
|
+
;;
|
|
708
|
+
agent_step)
|
|
709
|
+
agent=$(echo "$event" | jq -r '.agent')
|
|
710
|
+
cost=$(echo "$event" | jq -r '.usage.cost')
|
|
711
|
+
echo "💭 $agent thinking (cost: \$$cost)"
|
|
712
|
+
;;
|
|
713
|
+
tool_call)
|
|
714
|
+
tool=$(echo "$event" | jq -r '.tool')
|
|
715
|
+
echo "🔧 Calling tool: $tool"
|
|
716
|
+
;;
|
|
717
|
+
agent_stop)
|
|
718
|
+
agent=$(echo "$event" | jq -r '.agent')
|
|
719
|
+
content=$(echo "$event" | jq -r '.content')
|
|
720
|
+
echo "✓ $agent: $content"
|
|
721
|
+
;;
|
|
722
|
+
swarm_stop)
|
|
723
|
+
success=$(echo "$event" | jq -r '.success')
|
|
724
|
+
total_cost=$(echo "$event" | jq -r '.total_cost')
|
|
725
|
+
duration=$(echo "$event" | jq -r '.duration')
|
|
726
|
+
|
|
727
|
+
if [ "$success" = "true" ]; then
|
|
728
|
+
echo "✓ Success! Cost: \$$total_cost, Duration: ${duration}s"
|
|
729
|
+
else
|
|
730
|
+
echo "✗ Failed! Duration: ${duration}s"
|
|
731
|
+
exit 1
|
|
732
|
+
fi
|
|
733
|
+
;;
|
|
734
|
+
esac
|
|
735
|
+
done
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
**Collecting results**:
|
|
739
|
+
```bash
|
|
740
|
+
#!/bin/bash
|
|
741
|
+
# collect-results.sh - Collect all events into structured output
|
|
742
|
+
|
|
743
|
+
output_file="results.json"
|
|
744
|
+
|
|
745
|
+
# Collect all events into JSON array
|
|
746
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
747
|
+
jq -s '.' > "$output_file"
|
|
748
|
+
|
|
749
|
+
# Extract summary information
|
|
750
|
+
total_cost=$(jq '[.[] | select(.usage) | .usage.cost] | add' "$output_file")
|
|
751
|
+
success=$(jq '.[-1].success' "$output_file")
|
|
752
|
+
agents=$(jq '.[-1].agents_involved' "$output_file")
|
|
753
|
+
|
|
754
|
+
echo "Summary:"
|
|
755
|
+
echo " Success: $success"
|
|
756
|
+
echo " Total Cost: \$$total_cost"
|
|
757
|
+
echo " Agents: $agents"
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
### Processing NDJSON in Ruby
|
|
761
|
+
|
|
762
|
+
```ruby
|
|
763
|
+
#!/usr/bin/env ruby
|
|
764
|
+
# process-ndjson.rb - Process NDJSON output in Ruby
|
|
765
|
+
|
|
766
|
+
require 'json'
|
|
767
|
+
require 'open3'
|
|
768
|
+
|
|
769
|
+
cmd = "swarm run config.yml -p 'Task' --output-format json"
|
|
770
|
+
total_cost = 0.0
|
|
771
|
+
|
|
772
|
+
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
|
|
773
|
+
stdout.each_line do |line|
|
|
774
|
+
event = JSON.parse(line)
|
|
775
|
+
|
|
776
|
+
case event['type']
|
|
777
|
+
when 'swarm_start'
|
|
778
|
+
puts "🚀 Starting: #{event['swarm_name']}"
|
|
779
|
+
when 'agent_step'
|
|
780
|
+
cost = event.dig('usage', 'cost') || 0.0
|
|
781
|
+
total_cost += cost
|
|
782
|
+
puts "💭 #{event['agent']} (cost: $#{cost})"
|
|
783
|
+
when 'agent_stop'
|
|
784
|
+
puts "✓ #{event['agent']}: #{event['content']}"
|
|
785
|
+
when 'swarm_stop'
|
|
786
|
+
puts "\n📊 Summary:"
|
|
787
|
+
puts " Success: #{event['success']}"
|
|
788
|
+
puts " Duration: #{event['duration']}s"
|
|
789
|
+
puts " Total Cost: $#{event['total_cost']}"
|
|
790
|
+
puts " Agents: #{event['agents_involved'].join(', ')}"
|
|
791
|
+
end
|
|
792
|
+
end
|
|
793
|
+
end
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
### Useful Flags
|
|
797
|
+
|
|
798
|
+
**Quiet mode** - Suppress progress output (only show final result):
|
|
799
|
+
```bash
|
|
800
|
+
swarm run config.yml -p "Task" --quiet
|
|
801
|
+
```
|
|
802
|
+
|
|
803
|
+
**Truncate mode** - Truncate long outputs for concise view:
|
|
804
|
+
```bash
|
|
805
|
+
swarm run config.yml -p "Summarize all files" --truncate
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
**Verbose mode** - Show additional debug information:
|
|
809
|
+
```bash
|
|
810
|
+
swarm run config.yml -p "Task" --verbose
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
### Exit Codes
|
|
814
|
+
|
|
815
|
+
SwarmCLI uses standard exit codes:
|
|
816
|
+
|
|
817
|
+
| Exit Code | Meaning |
|
|
818
|
+
|-----------|---------|
|
|
819
|
+
| `0` | Success |
|
|
820
|
+
| `1` | Error (configuration, execution, etc.) |
|
|
821
|
+
| `130` | User cancelled (Ctrl+C) |
|
|
822
|
+
|
|
823
|
+
**Use in scripts**:
|
|
824
|
+
```bash
|
|
825
|
+
if swarm run config.yml -p "Task" --quiet; then
|
|
826
|
+
echo "✓ Success!"
|
|
827
|
+
else
|
|
828
|
+
echo "✗ Failed with exit code $?"
|
|
829
|
+
exit 1
|
|
830
|
+
fi
|
|
831
|
+
```
|
|
832
|
+
|
|
833
|
+
### Piping and Redirection
|
|
834
|
+
|
|
835
|
+
**Pipe prompt from file**:
|
|
836
|
+
```bash
|
|
837
|
+
cat prompt.txt | swarm run config.yml -p
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
**Redirect output to file**:
|
|
841
|
+
```bash
|
|
842
|
+
swarm run config.yml -p "Generate report" > report.txt 2>&1
|
|
843
|
+
```
|
|
844
|
+
|
|
845
|
+
**Save JSON events to file**:
|
|
846
|
+
```bash
|
|
847
|
+
swarm run config.yml -p "Task" --output-format json > events.ndjson
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
**Process saved NDJSON file**:
|
|
851
|
+
```bash
|
|
852
|
+
cat events.ndjson | jq -c 'select(.type == "agent_stop")'
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
**Chain with other commands**:
|
|
856
|
+
```bash
|
|
857
|
+
# Get list of files, then process each
|
|
858
|
+
ls *.rb | xargs -I {} swarm run config.yml -p "Analyze {}" --quiet
|
|
859
|
+
|
|
860
|
+
# Process multiple prompts from file
|
|
861
|
+
cat prompts.txt | while read prompt; do
|
|
862
|
+
swarm run config.yml -p "$prompt" --quiet
|
|
863
|
+
done
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
**Combine with jq for JSON processing**:
|
|
867
|
+
```bash
|
|
868
|
+
# Extract final agent response
|
|
869
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
870
|
+
jq -c 'select(.type == "agent_stop")' | tail -1 | jq -r '.content'
|
|
871
|
+
|
|
872
|
+
# Track costs in real-time
|
|
873
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
874
|
+
jq -c 'select(.usage) | {agent, cost: .usage.cost}'
|
|
875
|
+
```
|
|
876
|
+
|
|
877
|
+
## Configuration Files
|
|
878
|
+
|
|
879
|
+
SwarmCLI works with both YAML and Ruby DSL configuration files.
|
|
880
|
+
|
|
881
|
+
### YAML Configuration
|
|
882
|
+
|
|
883
|
+
Create a file with `.yml` or `.yaml` extension:
|
|
884
|
+
|
|
885
|
+
**Example** (`team.yml`):
|
|
886
|
+
```yaml
|
|
887
|
+
version: 2
|
|
888
|
+
swarm:
|
|
889
|
+
name: "Development Team"
|
|
890
|
+
lead: architect
|
|
891
|
+
|
|
892
|
+
agents:
|
|
893
|
+
architect:
|
|
894
|
+
description: "Lead architect coordinating the team"
|
|
895
|
+
model: "gpt-4"
|
|
896
|
+
system_prompt: |
|
|
897
|
+
You are the lead architect.
|
|
898
|
+
Break down tasks and delegate to specialists.
|
|
899
|
+
tools:
|
|
900
|
+
- Write
|
|
901
|
+
- Edit
|
|
902
|
+
delegates_to:
|
|
903
|
+
- coder
|
|
904
|
+
- reviewer
|
|
905
|
+
|
|
906
|
+
coder:
|
|
907
|
+
description: "Writes clean, maintainable code"
|
|
908
|
+
model: "gpt-4"
|
|
909
|
+
system_prompt: "You are an expert programmer."
|
|
910
|
+
tools:
|
|
911
|
+
- Write
|
|
912
|
+
- Edit
|
|
913
|
+
|
|
914
|
+
reviewer:
|
|
915
|
+
description: "Reviews code for quality"
|
|
916
|
+
model: "claude-sonnet-4"
|
|
917
|
+
system_prompt: "You review code for bugs and improvements."
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
**Use it**:
|
|
921
|
+
```bash
|
|
922
|
+
swarm run team.yml
|
|
923
|
+
```
|
|
924
|
+
|
|
925
|
+
### Ruby DSL Configuration
|
|
926
|
+
|
|
927
|
+
Create a file with `.rb` extension:
|
|
928
|
+
|
|
929
|
+
**Example** (`team.rb`):
|
|
930
|
+
```ruby
|
|
931
|
+
SwarmSDK.build do
|
|
932
|
+
name "Development Team"
|
|
933
|
+
lead :architect
|
|
934
|
+
|
|
935
|
+
agent :architect do
|
|
936
|
+
description "Lead architect coordinating the team"
|
|
937
|
+
model "gpt-4"
|
|
938
|
+
system_prompt "You are the lead architect. Break down tasks and delegate to specialists."
|
|
939
|
+
tools :Write, :Edit
|
|
940
|
+
delegates_to :coder, :reviewer
|
|
941
|
+
end
|
|
942
|
+
|
|
943
|
+
agent :coder do
|
|
944
|
+
description "Writes clean, maintainable code"
|
|
945
|
+
model "gpt-4"
|
|
946
|
+
system_prompt "You are an expert programmer."
|
|
947
|
+
tools :Write, :Edit
|
|
948
|
+
end
|
|
949
|
+
|
|
950
|
+
agent :reviewer do
|
|
951
|
+
description "Reviews code for quality"
|
|
952
|
+
model "claude-sonnet-4"
|
|
953
|
+
system_prompt "You review code for bugs and improvements."
|
|
954
|
+
end
|
|
955
|
+
end
|
|
956
|
+
```
|
|
957
|
+
|
|
958
|
+
**Use it**:
|
|
959
|
+
```bash
|
|
960
|
+
swarm run team.rb
|
|
961
|
+
```
|
|
962
|
+
|
|
963
|
+
### When to Use Which Format
|
|
964
|
+
|
|
965
|
+
**Use YAML when**:
|
|
966
|
+
- You prefer declarative configuration
|
|
967
|
+
- Your team is more familiar with YAML
|
|
968
|
+
- You want simpler, more readable configs
|
|
969
|
+
- You're defining shell-based hooks
|
|
970
|
+
|
|
971
|
+
**Use Ruby DSL when**:
|
|
972
|
+
- You need dynamic configuration (variables, conditionals)
|
|
973
|
+
- You want IDE autocomplete and type checking
|
|
974
|
+
- You're writing hooks as Ruby blocks
|
|
975
|
+
- You need programmatic agent generation
|
|
976
|
+
|
|
977
|
+
**Both formats work identically with SwarmCLI** - choose what fits your workflow.
|
|
978
|
+
|
|
979
|
+
## Common Workflows
|
|
980
|
+
|
|
981
|
+
### Workflow 1: Exploratory Development
|
|
982
|
+
|
|
983
|
+
Use interactive mode to explore and iterate:
|
|
984
|
+
|
|
985
|
+
```bash
|
|
986
|
+
swarm run dev-team.yml
|
|
987
|
+
```
|
|
988
|
+
|
|
989
|
+
```
|
|
990
|
+
You ❯ What files are in src/?
|
|
991
|
+
# Agent lists files
|
|
992
|
+
|
|
993
|
+
You ❯ Read main.rb and explain what it does
|
|
994
|
+
# Agent reads and explains
|
|
995
|
+
|
|
996
|
+
You ❯ Refactor the long function on line 45
|
|
997
|
+
# Agent refactors code
|
|
998
|
+
|
|
999
|
+
You ❯ /exit
|
|
1000
|
+
```
|
|
1001
|
+
|
|
1002
|
+
**Why this works**: Interactive mode preserves context, so each message builds on previous ones. The agent remembers what files you discussed and what changes were made.
|
|
1003
|
+
|
|
1004
|
+
### Workflow 2: Automated Code Review in CI/CD
|
|
1005
|
+
|
|
1006
|
+
Use non-interactive mode with NDJSON output for automated reviews:
|
|
1007
|
+
|
|
1008
|
+
```bash
|
|
1009
|
+
#!/bin/bash
|
|
1010
|
+
# ci-review.sh - Automated code review for CI/CD
|
|
1011
|
+
|
|
1012
|
+
FILES=$(git diff --name-only main...HEAD | grep '\.rb$')
|
|
1013
|
+
|
|
1014
|
+
exit_code=0
|
|
1015
|
+
|
|
1016
|
+
for file in $FILES; do
|
|
1017
|
+
echo "Reviewing $file..."
|
|
1018
|
+
|
|
1019
|
+
# Run review and extract final response
|
|
1020
|
+
content=$(swarm run reviewer.yml -p "Review $file for bugs and style issues" \
|
|
1021
|
+
--output-format json | \
|
|
1022
|
+
jq -c 'select(.type == "agent_stop")' | tail -1 | jq -r '.content')
|
|
1023
|
+
|
|
1024
|
+
# Check if review succeeded
|
|
1025
|
+
if [ $? -eq 0 ]; then
|
|
1026
|
+
echo "$content" > "reviews/$file.txt"
|
|
1027
|
+
echo "✓ Review complete"
|
|
1028
|
+
|
|
1029
|
+
# Check for critical issues in response
|
|
1030
|
+
if echo "$content" | grep -q "CRITICAL\|ERROR\|SECURITY"; then
|
|
1031
|
+
echo "✗ Critical issues found in $file"
|
|
1032
|
+
exit_code=1
|
|
1033
|
+
fi
|
|
1034
|
+
else
|
|
1035
|
+
echo "✗ Review failed for $file"
|
|
1036
|
+
exit_code=1
|
|
1037
|
+
fi
|
|
1038
|
+
done
|
|
1039
|
+
|
|
1040
|
+
exit $exit_code
|
|
1041
|
+
```
|
|
1042
|
+
|
|
1043
|
+
**Why this works**: Non-interactive mode with NDJSON output is perfect for CI/CD. Structured output is easy to parse, and exit codes integrate seamlessly with CI systems.
|
|
1044
|
+
|
|
1045
|
+
### Workflow 3: Batch Processing with Real-Time Cost Tracking
|
|
1046
|
+
|
|
1047
|
+
Process multiple items with streaming cost monitoring:
|
|
1048
|
+
|
|
1049
|
+
```bash
|
|
1050
|
+
#!/bin/bash
|
|
1051
|
+
# batch-process.sh - Process issues with real-time cost tracking
|
|
1052
|
+
|
|
1053
|
+
total_cost=0
|
|
1054
|
+
|
|
1055
|
+
while IFS= read -r issue; do
|
|
1056
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1057
|
+
echo "Processing: $issue"
|
|
1058
|
+
|
|
1059
|
+
# Process with real-time event monitoring
|
|
1060
|
+
swarm run analyzer.yml -p "Analyze: $issue" --output-format json | \
|
|
1061
|
+
while IFS= read -r event; do
|
|
1062
|
+
type=$(echo "$event" | jq -r '.type')
|
|
1063
|
+
|
|
1064
|
+
case $type in
|
|
1065
|
+
agent_step)
|
|
1066
|
+
cost=$(echo "$event" | jq -r '.usage.cost // 0')
|
|
1067
|
+
if [ "$cost" != "0" ]; then
|
|
1068
|
+
echo " 💭 Cost so far: \$$cost"
|
|
1069
|
+
fi
|
|
1070
|
+
;;
|
|
1071
|
+
tool_call)
|
|
1072
|
+
tool=$(echo "$event" | jq -r '.tool')
|
|
1073
|
+
echo " 🔧 Using tool: $tool"
|
|
1074
|
+
;;
|
|
1075
|
+
swarm_stop)
|
|
1076
|
+
cost=$(echo "$event" | jq -r '.total_cost')
|
|
1077
|
+
success=$(echo "$event" | jq -r '.success')
|
|
1078
|
+
content=$(echo "$event" | jq -r '.content // ""')
|
|
1079
|
+
|
|
1080
|
+
# Save result
|
|
1081
|
+
echo "{\"issue\": \"$issue\", \"analysis\": \"$content\", \"cost\": $cost}" >> results.json
|
|
1082
|
+
|
|
1083
|
+
# Update running total
|
|
1084
|
+
total_cost=$(echo "$total_cost + $cost" | bc)
|
|
1085
|
+
|
|
1086
|
+
if [ "$success" = "true" ]; then
|
|
1087
|
+
echo " ✓ Complete. Cost: \$$cost. Total so far: \$$total_cost"
|
|
1088
|
+
else
|
|
1089
|
+
echo " ✗ Failed. Cost: \$$cost"
|
|
1090
|
+
fi
|
|
1091
|
+
;;
|
|
1092
|
+
esac
|
|
1093
|
+
done
|
|
1094
|
+
done < issues.txt
|
|
1095
|
+
|
|
1096
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1097
|
+
echo "📊 Final Summary"
|
|
1098
|
+
echo " Issues processed: $(wc -l < issues.txt)"
|
|
1099
|
+
echo " Total cost: \$$total_cost"
|
|
1100
|
+
```
|
|
1101
|
+
|
|
1102
|
+
**Why this works**: NDJSON streaming lets you process events in real-time. You can monitor progress, track costs, and respond to events as they happen - perfect for long-running batch operations.
|
|
1103
|
+
|
|
1104
|
+
### Workflow 4: Multi-Stage Pipeline
|
|
1105
|
+
|
|
1106
|
+
Combine different modes for a complete workflow:
|
|
1107
|
+
|
|
1108
|
+
```bash
|
|
1109
|
+
#!/bin/bash
|
|
1110
|
+
# pipeline.sh - Multi-stage development pipeline
|
|
1111
|
+
|
|
1112
|
+
set -e # Exit on any error
|
|
1113
|
+
|
|
1114
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1115
|
+
echo "Stage 1: Planning (Interactive)"
|
|
1116
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1117
|
+
|
|
1118
|
+
# Interactive planning session
|
|
1119
|
+
swarm run planner.yml "Plan a REST API for user management"
|
|
1120
|
+
|
|
1121
|
+
echo ""
|
|
1122
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1123
|
+
echo "Stage 2: Implementation (Non-Interactive)"
|
|
1124
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1125
|
+
|
|
1126
|
+
# Implement in non-interactive mode
|
|
1127
|
+
swarm run coder.yml -p "Implement the planned API" --quiet
|
|
1128
|
+
|
|
1129
|
+
echo ""
|
|
1130
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1131
|
+
echo "Stage 3: Review (Non-Interactive with JSON)"
|
|
1132
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1133
|
+
|
|
1134
|
+
# Review with structured output
|
|
1135
|
+
swarm run reviewer.yml -p "Review the implementation" --output-format json | \
|
|
1136
|
+
jq -c 'select(.type == "swarm_stop")' | tail -1 > review-result.json
|
|
1137
|
+
|
|
1138
|
+
success=$(jq -r '.success' review-result.json)
|
|
1139
|
+
cost=$(jq -r '.total_cost' review-result.json)
|
|
1140
|
+
agents=$(jq -r '.agents_involved | join(", ")' review-result.json)
|
|
1141
|
+
|
|
1142
|
+
echo ""
|
|
1143
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1144
|
+
echo "Pipeline Summary"
|
|
1145
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1146
|
+
echo " Status: $success"
|
|
1147
|
+
echo " Review Cost: \$$cost"
|
|
1148
|
+
echo " Agents Used: $agents"
|
|
1149
|
+
|
|
1150
|
+
if [ "$success" = "true" ]; then
|
|
1151
|
+
echo " ✓ Pipeline complete!"
|
|
1152
|
+
exit 0
|
|
1153
|
+
else
|
|
1154
|
+
echo " ✗ Pipeline failed!"
|
|
1155
|
+
exit 1
|
|
1156
|
+
fi
|
|
1157
|
+
```
|
|
1158
|
+
|
|
1159
|
+
**Why this works**: Different stages benefit from different modes. Planning is interactive for human input, implementation is automated, and review provides structured output for downstream processing.
|
|
1160
|
+
|
|
1161
|
+
### Workflow 5: Real-Time Monitoring Dashboard
|
|
1162
|
+
|
|
1163
|
+
Monitor swarm execution with live updates:
|
|
1164
|
+
|
|
1165
|
+
```bash
|
|
1166
|
+
#!/bin/bash
|
|
1167
|
+
# monitor.sh - Real-time monitoring dashboard
|
|
1168
|
+
|
|
1169
|
+
# Colors
|
|
1170
|
+
GREEN='\033[0;32m'
|
|
1171
|
+
YELLOW='\033[1;33m'
|
|
1172
|
+
RED='\033[0;31m'
|
|
1173
|
+
BLUE='\033[0;34m'
|
|
1174
|
+
NC='\033[0m' # No Color
|
|
1175
|
+
|
|
1176
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1177
|
+
echo "🚀 Swarm Execution Monitor"
|
|
1178
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1179
|
+
echo ""
|
|
1180
|
+
|
|
1181
|
+
running_cost=0
|
|
1182
|
+
step_count=0
|
|
1183
|
+
tool_calls=0
|
|
1184
|
+
|
|
1185
|
+
swarm run config.yml -p "$1" --output-format json | while IFS= read -r event; do
|
|
1186
|
+
type=$(echo "$event" | jq -r '.type')
|
|
1187
|
+
timestamp=$(echo "$event" | jq -r '.timestamp' | cut -d'T' -f2 | cut -d'.' -f1)
|
|
1188
|
+
|
|
1189
|
+
case $type in
|
|
1190
|
+
swarm_start)
|
|
1191
|
+
swarm_name=$(echo "$event" | jq -r '.swarm_name')
|
|
1192
|
+
lead=$(echo "$event" | jq -r '.lead_agent')
|
|
1193
|
+
echo -e "${BLUE}[$timestamp]${NC} 🚀 Started: $swarm_name (lead: $lead)"
|
|
1194
|
+
;;
|
|
1195
|
+
agent_step)
|
|
1196
|
+
agent=$(echo "$event" | jq -r '.agent')
|
|
1197
|
+
cost=$(echo "$event" | jq -r '.usage.cost // 0')
|
|
1198
|
+
tokens=$(echo "$event" | jq -r '.usage.total_tokens // 0')
|
|
1199
|
+
|
|
1200
|
+
if [ "$cost" != "0" ]; then
|
|
1201
|
+
running_cost=$(echo "$running_cost + $cost" | bc)
|
|
1202
|
+
step_count=$((step_count + 1))
|
|
1203
|
+
echo -e "${YELLOW}[$timestamp]${NC} 💭 $agent • step $step_count • $tokens tokens • +\$$cost (total: \$$running_cost)"
|
|
1204
|
+
fi
|
|
1205
|
+
;;
|
|
1206
|
+
tool_call)
|
|
1207
|
+
tool=$(echo "$event" | jq -r '.tool')
|
|
1208
|
+
tool_calls=$((tool_calls + 1))
|
|
1209
|
+
echo -e "${BLUE}[$timestamp]${NC} 🔧 Tool: $tool"
|
|
1210
|
+
;;
|
|
1211
|
+
agent_delegation)
|
|
1212
|
+
agent=$(echo "$event" | jq -r '.agent')
|
|
1213
|
+
to=$(echo "$event" | jq -r '.delegate_to')
|
|
1214
|
+
echo -e "${BLUE}[$timestamp]${NC} 👉 Delegation: $agent → $to"
|
|
1215
|
+
;;
|
|
1216
|
+
agent_stop)
|
|
1217
|
+
agent=$(echo "$event" | jq -r '.agent')
|
|
1218
|
+
reason=$(echo "$event" | jq -r '.finish_reason')
|
|
1219
|
+
echo -e "${GREEN}[$timestamp]${NC} ✓ $agent complete ($reason)"
|
|
1220
|
+
;;
|
|
1221
|
+
swarm_stop)
|
|
1222
|
+
success=$(echo "$event" | jq -r '.success')
|
|
1223
|
+
duration=$(echo "$event" | jq -r '.duration')
|
|
1224
|
+
total_cost=$(echo "$event" | jq -r '.total_cost')
|
|
1225
|
+
agents=$(echo "$event" | jq -r '.agents_involved | join(", ")')
|
|
1226
|
+
|
|
1227
|
+
echo ""
|
|
1228
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1229
|
+
echo "📊 Execution Complete"
|
|
1230
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
1231
|
+
|
|
1232
|
+
if [ "$success" = "true" ]; then
|
|
1233
|
+
echo -e " Status: ${GREEN}✓ Success${NC}"
|
|
1234
|
+
else
|
|
1235
|
+
echo -e " Status: ${RED}✗ Failed${NC}"
|
|
1236
|
+
fi
|
|
1237
|
+
|
|
1238
|
+
echo " Duration: ${duration}s"
|
|
1239
|
+
echo " Total Cost: \$$total_cost"
|
|
1240
|
+
echo " Steps: $step_count"
|
|
1241
|
+
echo " Tool Calls: $tool_calls"
|
|
1242
|
+
echo " Agents: $agents"
|
|
1243
|
+
;;
|
|
1244
|
+
esac
|
|
1245
|
+
done
|
|
1246
|
+
```
|
|
1247
|
+
|
|
1248
|
+
**Use it**:
|
|
1249
|
+
```bash
|
|
1250
|
+
./monitor.sh "Build a user authentication system"
|
|
1251
|
+
```
|
|
1252
|
+
|
|
1253
|
+
**Why this works**: NDJSON streaming enables real-time monitoring. You see each event as it happens, providing insight into agent behavior, costs, and progress.
|
|
1254
|
+
|
|
1255
|
+
## Common Pitfalls and Solutions
|
|
1256
|
+
|
|
1257
|
+
### Pitfall 1: Wrong Gem Name
|
|
1258
|
+
|
|
1259
|
+
**Error**:
|
|
1260
|
+
```bash
|
|
1261
|
+
# ❌ Wrong gem name
|
|
1262
|
+
gem install swarm-sdk # Wrong!
|
|
1263
|
+
gem install swarmcore # Wrong!
|
|
1264
|
+
gem install swarm-cli # Wrong (hyphen instead of underscore)!
|
|
1265
|
+
```
|
|
1266
|
+
|
|
1267
|
+
**Solution**:
|
|
1268
|
+
```bash
|
|
1269
|
+
# ✅ Correct gem name (underscore, not hyphen)
|
|
1270
|
+
gem install swarm_cli
|
|
1271
|
+
|
|
1272
|
+
# This automatically installs:
|
|
1273
|
+
# - swarm_cli (the CLI)
|
|
1274
|
+
# - swarm_sdk (the library)
|
|
1275
|
+
```
|
|
1276
|
+
|
|
1277
|
+
### Pitfall 2: Wrong Executable Name
|
|
1278
|
+
|
|
1279
|
+
**Error**:
|
|
1280
|
+
```bash
|
|
1281
|
+
# ❌ Wrong executable name
|
|
1282
|
+
swarm_cli run config.yml # Wrong!
|
|
1283
|
+
swarmcli run config.yml # Wrong!
|
|
1284
|
+
```
|
|
1285
|
+
|
|
1286
|
+
**Solution**:
|
|
1287
|
+
```bash
|
|
1288
|
+
# ✅ Correct executable name
|
|
1289
|
+
swarm run config.yml
|
|
1290
|
+
```
|
|
1291
|
+
|
|
1292
|
+
### Pitfall 3: Wrong Ruby Version
|
|
1293
|
+
|
|
1294
|
+
**Error**:
|
|
1295
|
+
```bash
|
|
1296
|
+
# Using Ruby 3.1 or earlier
|
|
1297
|
+
ruby -v
|
|
1298
|
+
# => ruby 3.1.0
|
|
1299
|
+
|
|
1300
|
+
gem install swarm_cli
|
|
1301
|
+
# => ERROR: swarm_cli requires Ruby >= 3.2.0
|
|
1302
|
+
```
|
|
1303
|
+
|
|
1304
|
+
**Solution**:
|
|
1305
|
+
```bash
|
|
1306
|
+
# ✅ Use Ruby 3.2.0 or higher
|
|
1307
|
+
rbenv install 3.2.0
|
|
1308
|
+
rbenv global 3.2.0
|
|
1309
|
+
|
|
1310
|
+
# Or with rvm
|
|
1311
|
+
rvm install 3.2.0
|
|
1312
|
+
rvm use 3.2.0
|
|
1313
|
+
|
|
1314
|
+
# Verify
|
|
1315
|
+
ruby -v
|
|
1316
|
+
# => ruby 3.2.0 (or higher)
|
|
1317
|
+
|
|
1318
|
+
# Now install
|
|
1319
|
+
gem install swarm_cli
|
|
1320
|
+
```
|
|
1321
|
+
|
|
1322
|
+
### Pitfall 4: Mixing Interactive and Non-Interactive Flags
|
|
1323
|
+
|
|
1324
|
+
**Error**:
|
|
1325
|
+
```bash
|
|
1326
|
+
# ❌ Can't use -p flag without a prompt
|
|
1327
|
+
swarm run config.yml -p
|
|
1328
|
+
```
|
|
1329
|
+
|
|
1330
|
+
**Output**:
|
|
1331
|
+
```
|
|
1332
|
+
Error: Non-interactive mode (-p) requires a prompt (provide as argument or via stdin)
|
|
1333
|
+
```
|
|
1334
|
+
|
|
1335
|
+
**Solution**:
|
|
1336
|
+
```bash
|
|
1337
|
+
# ✅ Provide prompt as argument
|
|
1338
|
+
swarm run config.yml -p "Your task"
|
|
1339
|
+
|
|
1340
|
+
# ✅ Or provide via stdin
|
|
1341
|
+
echo "Your task" | swarm run config.yml -p
|
|
1342
|
+
```
|
|
1343
|
+
|
|
1344
|
+
### Pitfall 5: Using JSON Format in Interactive Mode
|
|
1345
|
+
|
|
1346
|
+
**Error**:
|
|
1347
|
+
```bash
|
|
1348
|
+
# ❌ JSON format doesn't work with REPL
|
|
1349
|
+
swarm run config.yml --output-format json
|
|
1350
|
+
```
|
|
1351
|
+
|
|
1352
|
+
**Output**:
|
|
1353
|
+
```
|
|
1354
|
+
Error: Interactive mode is not compatible with --output-format json
|
|
1355
|
+
```
|
|
1356
|
+
|
|
1357
|
+
**Solution**:
|
|
1358
|
+
```bash
|
|
1359
|
+
# ✅ Use JSON only in non-interactive mode
|
|
1360
|
+
swarm run config.yml -p "Task" --output-format json
|
|
1361
|
+
|
|
1362
|
+
# ✅ Or use default human format in interactive mode
|
|
1363
|
+
swarm run config.yml
|
|
1364
|
+
```
|
|
1365
|
+
|
|
1366
|
+
### Pitfall 6: Expecting Single JSON Object Instead of NDJSON
|
|
1367
|
+
|
|
1368
|
+
**CRITICAL PITFALL**: This is the most common mistake when working with JSON output.
|
|
1369
|
+
|
|
1370
|
+
**Error**:
|
|
1371
|
+
```bash
|
|
1372
|
+
# ❌ Trying to parse as single JSON object
|
|
1373
|
+
result=$(swarm run config.yml -p "Task" --output-format json)
|
|
1374
|
+
echo "$result" | jq '.content'
|
|
1375
|
+
|
|
1376
|
+
# Output:
|
|
1377
|
+
# parse error: Expected value at line 2, column 1
|
|
1378
|
+
```
|
|
1379
|
+
|
|
1380
|
+
**Why it fails**: `jq` expects a single JSON object by default, but SwarmCLI outputs NDJSON (one JSON object per line).
|
|
1381
|
+
|
|
1382
|
+
**What you're getting** (NDJSON):
|
|
1383
|
+
```
|
|
1384
|
+
{"type":"swarm_start","swarm_name":"Test",...}
|
|
1385
|
+
{"type":"agent_step","agent":"helper",...}
|
|
1386
|
+
{"type":"agent_stop","agent":"helper",...}
|
|
1387
|
+
{"type":"swarm_stop","success":true,...}
|
|
1388
|
+
```
|
|
1389
|
+
|
|
1390
|
+
**What you're expecting** (single JSON):
|
|
1391
|
+
```json
|
|
1392
|
+
{
|
|
1393
|
+
"swarm_name": "Test",
|
|
1394
|
+
"content": "...",
|
|
1395
|
+
"success": true
|
|
1396
|
+
}
|
|
1397
|
+
```
|
|
1398
|
+
|
|
1399
|
+
**Solutions**:
|
|
1400
|
+
|
|
1401
|
+
**✅ Solution 1: Parse NDJSON line by line**
|
|
1402
|
+
```bash
|
|
1403
|
+
# Extract final agent response
|
|
1404
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
1405
|
+
jq -c 'select(.type == "agent_stop")' | tail -1 | jq -r '.content'
|
|
1406
|
+
```
|
|
1407
|
+
|
|
1408
|
+
**✅ Solution 2: Collect all events into array**
|
|
1409
|
+
```bash
|
|
1410
|
+
# Use jq -s to slurp all lines into array
|
|
1411
|
+
result=$(swarm run config.yml -p "Task" --output-format json | jq -s '.')
|
|
1412
|
+
echo "$result" | jq '.[-1].content'
|
|
1413
|
+
```
|
|
1414
|
+
|
|
1415
|
+
**✅ Solution 3: Filter specific event type**
|
|
1416
|
+
```bash
|
|
1417
|
+
# Get success status from final event
|
|
1418
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
1419
|
+
jq -c 'select(.type == "swarm_stop")' | tail -1 | jq -r '.success'
|
|
1420
|
+
```
|
|
1421
|
+
|
|
1422
|
+
**✅ Solution 4: Process line by line in bash**
|
|
1423
|
+
```bash
|
|
1424
|
+
swarm run config.yml -p "Task" --output-format json | while IFS= read -r event; do
|
|
1425
|
+
type=$(echo "$event" | jq -r '.type')
|
|
1426
|
+
if [ "$type" = "swarm_stop" ]; then
|
|
1427
|
+
success=$(echo "$event" | jq -r '.success')
|
|
1428
|
+
echo "Success: $success"
|
|
1429
|
+
fi
|
|
1430
|
+
done
|
|
1431
|
+
```
|
|
1432
|
+
|
|
1433
|
+
**✅ Solution 5: Save to file and process**
|
|
1434
|
+
```bash
|
|
1435
|
+
# Save NDJSON to file
|
|
1436
|
+
swarm run config.yml -p "Task" --output-format json > events.ndjson
|
|
1437
|
+
|
|
1438
|
+
# Process saved file
|
|
1439
|
+
cat events.ndjson | jq -c 'select(.type == "agent_stop")'
|
|
1440
|
+
|
|
1441
|
+
# Or collect into array
|
|
1442
|
+
jq -s '.' events.ndjson > events-array.json
|
|
1443
|
+
```
|
|
1444
|
+
|
|
1445
|
+
### Pitfall 7: Configuration File Not Found
|
|
1446
|
+
|
|
1447
|
+
**Error**:
|
|
1448
|
+
```bash
|
|
1449
|
+
# ❌ File doesn't exist
|
|
1450
|
+
swarm run nonexistent.yml
|
|
1451
|
+
```
|
|
1452
|
+
|
|
1453
|
+
**Output**:
|
|
1454
|
+
```
|
|
1455
|
+
Error: Configuration file not found: nonexistent.yml
|
|
1456
|
+
```
|
|
1457
|
+
|
|
1458
|
+
**Solution**:
|
|
1459
|
+
```bash
|
|
1460
|
+
# ✅ Check the file exists
|
|
1461
|
+
ls config.yml
|
|
1462
|
+
|
|
1463
|
+
# ✅ Use absolute or correct relative path
|
|
1464
|
+
swarm run ./config.yml
|
|
1465
|
+
swarm run /full/path/to/config.yml
|
|
1466
|
+
|
|
1467
|
+
# ✅ Check your current directory
|
|
1468
|
+
pwd
|
|
1469
|
+
ls *.yml
|
|
1470
|
+
```
|
|
1471
|
+
|
|
1472
|
+
### Pitfall 8: Missing API Key
|
|
1473
|
+
|
|
1474
|
+
**Error**:
|
|
1475
|
+
```bash
|
|
1476
|
+
swarm run config.yml -p "Task"
|
|
1477
|
+
```
|
|
1478
|
+
|
|
1479
|
+
**Output**:
|
|
1480
|
+
```
|
|
1481
|
+
Fatal error: No API key found for provider 'openai'
|
|
1482
|
+
```
|
|
1483
|
+
|
|
1484
|
+
**Solution**:
|
|
1485
|
+
```bash
|
|
1486
|
+
# ✅ Set API key as environment variable
|
|
1487
|
+
export OPENAI_API_KEY="sk-your-key-here"
|
|
1488
|
+
swarm run config.yml -p "Task"
|
|
1489
|
+
|
|
1490
|
+
# ✅ Or use .env file
|
|
1491
|
+
echo "OPENAI_API_KEY=sk-your-key-here" > .env
|
|
1492
|
+
swarm run config.yml -p "Task"
|
|
1493
|
+
|
|
1494
|
+
# ✅ Verify API key is set
|
|
1495
|
+
echo $OPENAI_API_KEY
|
|
1496
|
+
```
|
|
1497
|
+
|
|
1498
|
+
### Pitfall 9: Forgetting to Exit Interactive Mode
|
|
1499
|
+
|
|
1500
|
+
**Issue**: Leaving the REPL running in the background consumes resources and may incur costs.
|
|
1501
|
+
|
|
1502
|
+
**Solution**:
|
|
1503
|
+
```
|
|
1504
|
+
# Always exit properly
|
|
1505
|
+
You ❯ /exit
|
|
1506
|
+
|
|
1507
|
+
# Or press Ctrl+D
|
|
1508
|
+
|
|
1509
|
+
# Or press Ctrl+C (will show cancellation message)
|
|
1510
|
+
```
|
|
1511
|
+
|
|
1512
|
+
**Tip**: The session summary shows you exactly what was consumed, helping you track usage.
|
|
1513
|
+
|
|
1514
|
+
### Pitfall 10: Using Wrong jq Flags for NDJSON
|
|
1515
|
+
|
|
1516
|
+
**Error**:
|
|
1517
|
+
```bash
|
|
1518
|
+
# ❌ Using jq without -c flag loses event boundaries
|
|
1519
|
+
swarm run config.yml -p "Task" --output-format json | jq .
|
|
1520
|
+
|
|
1521
|
+
# Output: Pretty-printed JSON that's no longer valid NDJSON
|
|
1522
|
+
```
|
|
1523
|
+
|
|
1524
|
+
**Solution**:
|
|
1525
|
+
```bash
|
|
1526
|
+
# ✅ Use -c (compact) flag to preserve NDJSON format
|
|
1527
|
+
swarm run config.yml -p "Task" --output-format json | jq -c .
|
|
1528
|
+
|
|
1529
|
+
# ✅ Use -c when filtering
|
|
1530
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
1531
|
+
jq -c 'select(.type == "agent_stop")'
|
|
1532
|
+
```
|
|
1533
|
+
|
|
1534
|
+
## Next Steps
|
|
1535
|
+
|
|
1536
|
+
Congratulations! You've learned how to use SwarmCLI effectively.
|
|
1537
|
+
|
|
1538
|
+
### Dive Deeper
|
|
1539
|
+
|
|
1540
|
+
**Core Documentation**:
|
|
1541
|
+
- **[Getting Started with SwarmSDK](getting-started.md)** - Learn to write swarm configurations
|
|
1542
|
+
- **[Complete Tutorial](complete-tutorial.md)** - Master all SwarmSDK features
|
|
1543
|
+
- **[Rails Integration](rails-integration.md)** - Use SwarmSDK in Rails applications
|
|
1544
|
+
|
|
1545
|
+
**Advanced Topics**:
|
|
1546
|
+
- **[Hooks Complete Guide](hooks-complete-guide.md)** - Master hooks system
|
|
1547
|
+
- **[Node Workflows](node-workflows-guide.md)** - Build multi-stage pipelines
|
|
1548
|
+
- **[Performance Tuning](performance-tuning.md)** - Optimize speed and costs
|
|
1549
|
+
|
|
1550
|
+
### Key Concepts to Explore
|
|
1551
|
+
|
|
1552
|
+
**Interactive vs Non-Interactive**: Understand when to use each mode for maximum productivity.
|
|
1553
|
+
|
|
1554
|
+
**NDJSON Event Stream**: Master real-time event processing for monitoring and automation.
|
|
1555
|
+
|
|
1556
|
+
**Configuration Management**: Learn to organize and reuse swarm configurations across projects.
|
|
1557
|
+
|
|
1558
|
+
**Performance Optimization**: Discover techniques for faster execution and lower costs.
|
|
1559
|
+
|
|
1560
|
+
## Where to Get Help
|
|
1561
|
+
|
|
1562
|
+
- **Documentation**: [SwarmSDK Guides](../README.md)
|
|
1563
|
+
- **Examples**: [Example Configurations](../../../examples/v2/)
|
|
1564
|
+
- **Issues**: [GitHub Issues](https://github.com/parruda/claude-swarm/issues)
|
|
1565
|
+
|
|
1566
|
+
## Summary
|
|
1567
|
+
|
|
1568
|
+
You've learned:
|
|
1569
|
+
|
|
1570
|
+
✅ **What SwarmCLI is** - A separate gem (`swarm_cli`) that provides CLI for SwarmSDK
|
|
1571
|
+
|
|
1572
|
+
✅ **Installation** - `gem install swarm_cli` (automatically installs `swarm_sdk`)
|
|
1573
|
+
|
|
1574
|
+
✅ **Executable name** - Use `swarm` command (not `swarm_cli`)
|
|
1575
|
+
|
|
1576
|
+
✅ **Ruby requirement** - Ruby 3.2.0 or higher required
|
|
1577
|
+
|
|
1578
|
+
✅ **Execution modes** - Interactive (REPL) for conversations, non-interactive for automation
|
|
1579
|
+
|
|
1580
|
+
✅ **Commands** - `run`, `migrate`, `mcp serve`, and `mcp tools`
|
|
1581
|
+
|
|
1582
|
+
✅ **Interactive features** - REPL commands, tab completion, context preservation, session summaries
|
|
1583
|
+
|
|
1584
|
+
✅ **Non-interactive features** - NDJSON event streaming, real-time monitoring, scripting support
|
|
1585
|
+
|
|
1586
|
+
✅ **NDJSON format** - Newline-delimited JSON (one event per line), not single JSON object
|
|
1587
|
+
|
|
1588
|
+
✅ **Processing NDJSON** - Use `jq -c`, `jq -s`, or line-by-line bash processing
|
|
1589
|
+
|
|
1590
|
+
✅ **Configuration files** - Both YAML and Ruby DSL support
|
|
1591
|
+
|
|
1592
|
+
✅ **Common workflows** - Exploratory development, automated reviews, batch processing, pipelines, monitoring
|
|
1593
|
+
|
|
1594
|
+
**Next**: [Getting Started with SwarmSDK →](getting-started.md)
|
|
1595
|
+
|
|
1596
|
+
---
|
|
1597
|
+
|
|
1598
|
+
## Quick Reference Card
|
|
1599
|
+
|
|
1600
|
+
```bash
|
|
1601
|
+
# ════════════════════════════════════════════════════════════
|
|
1602
|
+
# INSTALLATION
|
|
1603
|
+
# ════════════════════════════════════════════════════════════
|
|
1604
|
+
|
|
1605
|
+
gem install swarm_cli # Installs swarm_cli + swarm_sdk
|
|
1606
|
+
# Executable: swarm (not swarm_cli)
|
|
1607
|
+
# Requires: Ruby >= 3.2.0
|
|
1608
|
+
|
|
1609
|
+
# ════════════════════════════════════════════════════════════
|
|
1610
|
+
# INTERACTIVE MODE (REPL)
|
|
1611
|
+
# ════════════════════════════════════════════════════════════
|
|
1612
|
+
|
|
1613
|
+
swarm run config.yml # Start REPL
|
|
1614
|
+
swarm run config.yml "Initial message" # REPL with initial message
|
|
1615
|
+
echo "Message" | swarm run config.yml # REPL with piped input
|
|
1616
|
+
|
|
1617
|
+
# REPL Commands (type in REPL):
|
|
1618
|
+
# /help - Show help
|
|
1619
|
+
# /history - Show conversation history
|
|
1620
|
+
# /clear - Clear screen
|
|
1621
|
+
# /exit - Exit (or Ctrl+D)
|
|
1622
|
+
|
|
1623
|
+
# ════════════════════════════════════════════════════════════
|
|
1624
|
+
# NON-INTERACTIVE MODE
|
|
1625
|
+
# ════════════════════════════════════════════════════════════
|
|
1626
|
+
|
|
1627
|
+
swarm run config.yml -p "Task" # One-shot execution
|
|
1628
|
+
echo "Task" | swarm run config.yml -p # From stdin
|
|
1629
|
+
swarm run config.yml -p "Task" --quiet # Quiet mode (no progress)
|
|
1630
|
+
|
|
1631
|
+
# ════════════════════════════════════════════════════════════
|
|
1632
|
+
# JSON OUTPUT (NDJSON FORMAT)
|
|
1633
|
+
# ════════════════════════════════════════════════════════════
|
|
1634
|
+
|
|
1635
|
+
# CRITICAL: Output is NDJSON (newline-delimited JSON)
|
|
1636
|
+
# - Each line is a complete JSON event
|
|
1637
|
+
# - NOT a single JSON object
|
|
1638
|
+
# - Process line by line, not as whole
|
|
1639
|
+
|
|
1640
|
+
swarm run config.yml -p "Task" --output-format json
|
|
1641
|
+
|
|
1642
|
+
# Parse NDJSON (extract final agent response):
|
|
1643
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
1644
|
+
jq -c 'select(.type == "agent_stop")' | tail -1 | jq -r '.content'
|
|
1645
|
+
|
|
1646
|
+
# Track costs in real-time:
|
|
1647
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
1648
|
+
jq -c 'select(.usage) | {agent, cost: .usage.cost}'
|
|
1649
|
+
|
|
1650
|
+
# Get success status:
|
|
1651
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
1652
|
+
jq -c 'select(.type == "swarm_stop")' | tail -1 | jq -r '.success'
|
|
1653
|
+
|
|
1654
|
+
# Collect all events into array:
|
|
1655
|
+
swarm run config.yml -p "Task" --output-format json | jq -s '.'
|
|
1656
|
+
|
|
1657
|
+
# Process line by line in bash:
|
|
1658
|
+
swarm run config.yml -p "Task" --output-format json | while IFS= read -r event; do
|
|
1659
|
+
type=$(echo "$event" | jq -r '.type')
|
|
1660
|
+
# Process $event...
|
|
1661
|
+
done
|
|
1662
|
+
|
|
1663
|
+
# ════════════════════════════════════════════════════════════
|
|
1664
|
+
# OTHER COMMANDS
|
|
1665
|
+
# ════════════════════════════════════════════════════════════
|
|
1666
|
+
|
|
1667
|
+
swarm migrate old.yml --output new.yml # Migrate v1 to v2
|
|
1668
|
+
swarm mcp serve config.yml # Start MCP server
|
|
1669
|
+
swarm mcp tools # Expose all tools
|
|
1670
|
+
swarm mcp tools Read Write Edit # Expose specific tools
|
|
1671
|
+
|
|
1672
|
+
# ════════════════════════════════════════════════════════════
|
|
1673
|
+
# USEFUL FLAGS
|
|
1674
|
+
# ════════════════════════════════════════════════════════════
|
|
1675
|
+
|
|
1676
|
+
--output-format json # NDJSON event stream (non-interactive only)
|
|
1677
|
+
--quiet # Suppress progress output
|
|
1678
|
+
--truncate # Truncate long outputs
|
|
1679
|
+
--verbose # Show debug information
|
|
1680
|
+
|
|
1681
|
+
# ════════════════════════════════════════════════════════════
|
|
1682
|
+
# CONFIGURATION FILES
|
|
1683
|
+
# ════════════════════════════════════════════════════════════
|
|
1684
|
+
|
|
1685
|
+
# YAML format:
|
|
1686
|
+
# config.yml or config.yaml
|
|
1687
|
+
|
|
1688
|
+
# Ruby DSL format:
|
|
1689
|
+
# config.rb
|
|
1690
|
+
|
|
1691
|
+
# Both formats work identically with SwarmCLI
|
|
1692
|
+
|
|
1693
|
+
# ════════════════════════════════════════════════════════════
|
|
1694
|
+
# EXIT CODES
|
|
1695
|
+
# ════════════════════════════════════════════════════════════
|
|
1696
|
+
|
|
1697
|
+
# 0 - Success
|
|
1698
|
+
# 1 - Error (configuration, execution, etc.)
|
|
1699
|
+
# 130 - User cancelled (Ctrl+C)
|
|
1700
|
+
|
|
1701
|
+
# ════════════════════════════════════════════════════════════
|
|
1702
|
+
# NDJSON EVENT TYPES
|
|
1703
|
+
# ════════════════════════════════════════════════════════════
|
|
1704
|
+
|
|
1705
|
+
# swarm_start - Swarm execution begins
|
|
1706
|
+
# user_prompt - User message sent to agent
|
|
1707
|
+
# agent_step - Agent produces intermediate output
|
|
1708
|
+
# agent_stop - Agent completes response
|
|
1709
|
+
# tool_call - Agent invokes a tool
|
|
1710
|
+
# tool_result - Tool returns result
|
|
1711
|
+
# agent_delegation - Agent delegates to another agent
|
|
1712
|
+
# delegation_result - Delegated agent completes
|
|
1713
|
+
# delegation_error - Delegation fails
|
|
1714
|
+
# node_start - Node execution begins (workflows)
|
|
1715
|
+
# node_stop - Node execution completes (workflows)
|
|
1716
|
+
# model_lookup_warning - Unknown model in config
|
|
1717
|
+
# context_limit_warning - Context usage threshold crossed
|
|
1718
|
+
# swarm_stop - Swarm execution completes
|
|
1719
|
+
|
|
1720
|
+
# ════════════════════════════════════════════════════════════
|
|
1721
|
+
# COMMON PATTERNS
|
|
1722
|
+
# ════════════════════════════════════════════════════════════
|
|
1723
|
+
|
|
1724
|
+
# Extract final content:
|
|
1725
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
1726
|
+
jq -c 'select(.type == "agent_stop")' | tail -1 | jq -r '.content'
|
|
1727
|
+
|
|
1728
|
+
# Calculate total cost:
|
|
1729
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
1730
|
+
jq -s '[.[] | select(.usage) | .usage.cost] | add'
|
|
1731
|
+
|
|
1732
|
+
# Filter tool calls:
|
|
1733
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
1734
|
+
jq -c 'select(.type == "tool_call") | {tool, arguments}'
|
|
1735
|
+
|
|
1736
|
+
# Get all agents involved:
|
|
1737
|
+
swarm run config.yml -p "Task" --output-format json | \
|
|
1738
|
+
jq -c 'select(.type == "swarm_stop")' | tail -1 | jq -r '.agents_involved'
|
|
1739
|
+
|
|
1740
|
+
# Save to file and process later:
|
|
1741
|
+
swarm run config.yml -p "Task" --output-format json > events.ndjson
|
|
1742
|
+
cat events.ndjson | jq -c 'select(.type == "agent_stop")'
|
|
1743
|
+
```
|
|
1744
|
+
|
|
1745
|
+
**Remember**: JSON output is **NDJSON** (newline-delimited JSON), not a single JSON object!
|