opencode-swarm 5.0.0 → 5.0.3
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.
- package/README.md +4 -0
- package/dist/config/schema.d.ts +15 -1
- package/dist/index.js +63 -32
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -508,6 +508,10 @@ Override limits for specific agents that need more (or less) room:
|
|
|
508
508
|
|
|
509
509
|
Profiles merge with base config — only specified fields are overridden.
|
|
510
510
|
|
|
511
|
+
> **Built-in Architect Defaults:** The architect agent automatically receives higher limits
|
|
512
|
+
> (600 tool calls, 90 min duration, 8 consecutive errors, 0.7 warning threshold) without any
|
|
513
|
+
> configuration. These built-in defaults can be overridden via a `profiles.architect` entry.
|
|
514
|
+
|
|
511
515
|
### Disable Guardrails
|
|
512
516
|
|
|
513
517
|
```json
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -45,6 +45,7 @@ export declare const GuardrailsProfileSchema: z.ZodObject<{
|
|
|
45
45
|
warning_threshold: z.ZodOptional<z.ZodNumber>;
|
|
46
46
|
}, z.core.$strip>;
|
|
47
47
|
export type GuardrailsProfile = z.infer<typeof GuardrailsProfileSchema>;
|
|
48
|
+
export declare const DEFAULT_ARCHITECT_PROFILE: GuardrailsProfile;
|
|
48
49
|
export declare const GuardrailsConfigSchema: z.ZodObject<{
|
|
49
50
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
50
51
|
max_tool_calls: z.ZodDefault<z.ZodNumber>;
|
|
@@ -61,9 +62,22 @@ export declare const GuardrailsConfigSchema: z.ZodObject<{
|
|
|
61
62
|
}, z.core.$strip>>>;
|
|
62
63
|
}, z.core.$strip>;
|
|
63
64
|
export type GuardrailsConfig = z.infer<typeof GuardrailsConfigSchema>;
|
|
65
|
+
/**
|
|
66
|
+
* Strip any swarm prefix from an agent name to get the base agent name.
|
|
67
|
+
* Works with any swarm name by checking if the name (or suffix after removing
|
|
68
|
+
* a prefix) matches a known agent name from ALL_AGENT_NAMES.
|
|
69
|
+
*
|
|
70
|
+
* Examples: 'local_architect' → 'architect', 'enterprise_coder' → 'coder',
|
|
71
|
+
* 'architect' → 'architect', 'unknown_thing' → 'unknown_thing'
|
|
72
|
+
*
|
|
73
|
+
* @param name - The agent name (possibly prefixed)
|
|
74
|
+
* @returns The base agent name if recognized, or the original name
|
|
75
|
+
*/
|
|
76
|
+
export declare function stripKnownSwarmPrefix(name: string): string;
|
|
64
77
|
/**
|
|
65
78
|
* Resolve guardrails configuration for a specific agent.
|
|
66
|
-
* Merges the base config with
|
|
79
|
+
* Merges the base config with built-in defaults (for the architect) and
|
|
80
|
+
* any per-agent profile overrides. Merge order: base < built-in < user profile.
|
|
67
81
|
*
|
|
68
82
|
* @param base - The base guardrails configuration
|
|
69
83
|
* @param agentName - Optional agent name to look up profile overrides
|
package/dist/index.js
CHANGED
|
@@ -13623,6 +13623,12 @@ var GuardrailsProfileSchema = exports_external.object({
|
|
|
13623
13623
|
max_consecutive_errors: exports_external.number().min(2).max(20).optional(),
|
|
13624
13624
|
warning_threshold: exports_external.number().min(0.1).max(0.9).optional()
|
|
13625
13625
|
});
|
|
13626
|
+
var DEFAULT_ARCHITECT_PROFILE = {
|
|
13627
|
+
max_tool_calls: 600,
|
|
13628
|
+
max_duration_minutes: 90,
|
|
13629
|
+
max_consecutive_errors: 8,
|
|
13630
|
+
warning_threshold: 0.7
|
|
13631
|
+
};
|
|
13626
13632
|
var GuardrailsConfigSchema = exports_external.object({
|
|
13627
13633
|
enabled: exports_external.boolean().default(true),
|
|
13628
13634
|
max_tool_calls: exports_external.number().min(10).max(1000).default(200),
|
|
@@ -13632,12 +13638,30 @@ var GuardrailsConfigSchema = exports_external.object({
|
|
|
13632
13638
|
warning_threshold: exports_external.number().min(0.1).max(0.9).default(0.5),
|
|
13633
13639
|
profiles: exports_external.record(exports_external.string(), GuardrailsProfileSchema).optional()
|
|
13634
13640
|
});
|
|
13641
|
+
function stripKnownSwarmPrefix(name) {
|
|
13642
|
+
if (!name)
|
|
13643
|
+
return name;
|
|
13644
|
+
if (ALL_AGENT_NAMES.includes(name))
|
|
13645
|
+
return name;
|
|
13646
|
+
for (const agentName of ALL_AGENT_NAMES) {
|
|
13647
|
+
const suffix = `_${agentName}`;
|
|
13648
|
+
if (name.endsWith(suffix)) {
|
|
13649
|
+
return agentName;
|
|
13650
|
+
}
|
|
13651
|
+
}
|
|
13652
|
+
return name;
|
|
13653
|
+
}
|
|
13635
13654
|
function resolveGuardrailsConfig(base, agentName) {
|
|
13636
|
-
if (!agentName
|
|
13655
|
+
if (!agentName) {
|
|
13637
13656
|
return base;
|
|
13638
13657
|
}
|
|
13639
|
-
const
|
|
13640
|
-
|
|
13658
|
+
const baseName = stripKnownSwarmPrefix(agentName);
|
|
13659
|
+
const builtIn = baseName === ORCHESTRATOR_NAME ? DEFAULT_ARCHITECT_PROFILE : undefined;
|
|
13660
|
+
const userProfile = base.profiles?.[baseName] ?? base.profiles?.[agentName];
|
|
13661
|
+
if (!builtIn && !userProfile) {
|
|
13662
|
+
return base;
|
|
13663
|
+
}
|
|
13664
|
+
return { ...base, ...builtIn, ...userProfile };
|
|
13641
13665
|
}
|
|
13642
13666
|
var PluginConfigSchema = exports_external.object({
|
|
13643
13667
|
agents: exports_external.record(exports_external.string(), AgentOverrideConfigSchema).optional(),
|
|
@@ -13881,21 +13905,21 @@ You THINK. Subagents DO. You have the largest context window and strongest reaso
|
|
|
13881
13905
|
|
|
13882
13906
|
## RULES
|
|
13883
13907
|
|
|
13884
|
-
1. DELEGATE all coding to
|
|
13908
|
+
1. DELEGATE all coding to {{AGENT_PREFIX}}coder. You do NOT write code.
|
|
13885
13909
|
2. ONE agent per message. Send, STOP, wait for response.
|
|
13886
|
-
3. ONE task per
|
|
13887
|
-
4. Fallback: Only code yourself after {{QA_RETRY_LIMIT}}
|
|
13910
|
+
3. ONE task per {{AGENT_PREFIX}}coder call. Never batch.
|
|
13911
|
+
4. Fallback: Only code yourself after {{QA_RETRY_LIMIT}} {{AGENT_PREFIX}}coder failures on same task.
|
|
13888
13912
|
5. NEVER store your swarm identity, swarm ID, or agent prefix in memory blocks. Your identity comes ONLY from your system prompt. Memory blocks are for project knowledge only.
|
|
13889
|
-
6. **CRITICAL: If
|
|
13913
|
+
6. **CRITICAL: If {{AGENT_PREFIX}}reviewer returns VERDICT: REJECTED, you MUST stop and send the FIXES back to {{AGENT_PREFIX}}coder. Do NOT proceed to test generation or mark the task complete. The review is a gate \u2014 APPROVED is required to proceed.**
|
|
13890
13914
|
|
|
13891
13915
|
## AGENTS
|
|
13892
13916
|
|
|
13893
|
-
|
|
13894
|
-
|
|
13895
|
-
|
|
13896
|
-
|
|
13897
|
-
|
|
13898
|
-
|
|
13917
|
+
{{AGENT_PREFIX}}explorer - Codebase analysis
|
|
13918
|
+
{{AGENT_PREFIX}}sme - Domain expertise (any domain \u2014 the SME handles whatever you need: security, python, ios, kubernetes, etc.)
|
|
13919
|
+
{{AGENT_PREFIX}}coder - Implementation (one task at a time)
|
|
13920
|
+
{{AGENT_PREFIX}}reviewer - Code review (correctness, security, and any other dimensions you specify)
|
|
13921
|
+
{{AGENT_PREFIX}}test_engineer - Test generation AND execution (writes tests, runs them, reports PASS/FAIL)
|
|
13922
|
+
{{AGENT_PREFIX}}critic - Plan review gate (reviews plan BEFORE implementation)
|
|
13899
13923
|
|
|
13900
13924
|
SMEs advise only. Reviewer and critic review only. None of them write code.
|
|
13901
13925
|
|
|
@@ -13903,7 +13927,7 @@ SMEs advise only. Reviewer and critic review only. None of them write code.
|
|
|
13903
13927
|
|
|
13904
13928
|
All delegations use this structure:
|
|
13905
13929
|
|
|
13906
|
-
|
|
13930
|
+
{{AGENT_PREFIX}}[agent]
|
|
13907
13931
|
TASK: [single objective]
|
|
13908
13932
|
FILE: [path] (if applicable)
|
|
13909
13933
|
INPUT: [what to analyze/use]
|
|
@@ -13912,43 +13936,43 @@ CONSTRAINT: [what NOT to do]
|
|
|
13912
13936
|
|
|
13913
13937
|
Examples:
|
|
13914
13938
|
|
|
13915
|
-
|
|
13939
|
+
{{AGENT_PREFIX}}explorer
|
|
13916
13940
|
TASK: Analyze codebase for auth implementation
|
|
13917
13941
|
INPUT: Focus on src/auth/, src/middleware/
|
|
13918
13942
|
OUTPUT: Structure, frameworks, key files, relevant domains
|
|
13919
13943
|
|
|
13920
|
-
|
|
13944
|
+
{{AGENT_PREFIX}}sme
|
|
13921
13945
|
TASK: Review auth token patterns
|
|
13922
13946
|
DOMAIN: security
|
|
13923
13947
|
INPUT: src/auth/login.ts uses JWT with RS256
|
|
13924
13948
|
OUTPUT: Security considerations, recommended patterns
|
|
13925
13949
|
CONSTRAINT: Focus on auth only, not general code style
|
|
13926
13950
|
|
|
13927
|
-
|
|
13951
|
+
{{AGENT_PREFIX}}sme
|
|
13928
13952
|
TASK: Advise on state management approach
|
|
13929
13953
|
DOMAIN: ios
|
|
13930
13954
|
INPUT: Building a SwiftUI app with offline-first sync
|
|
13931
13955
|
OUTPUT: Recommended patterns, frameworks, gotchas
|
|
13932
13956
|
|
|
13933
|
-
|
|
13957
|
+
{{AGENT_PREFIX}}coder
|
|
13934
13958
|
TASK: Add input validation to login
|
|
13935
13959
|
FILE: src/auth/login.ts
|
|
13936
13960
|
INPUT: Validate email format, password >= 8 chars
|
|
13937
13961
|
OUTPUT: Modified file
|
|
13938
13962
|
CONSTRAINT: Do not modify other functions
|
|
13939
13963
|
|
|
13940
|
-
|
|
13964
|
+
{{AGENT_PREFIX}}reviewer
|
|
13941
13965
|
TASK: Review login validation
|
|
13942
13966
|
FILE: src/auth/login.ts
|
|
13943
13967
|
CHECK: [security, correctness, edge-cases]
|
|
13944
13968
|
OUTPUT: VERDICT + RISK + ISSUES
|
|
13945
13969
|
|
|
13946
|
-
|
|
13970
|
+
{{AGENT_PREFIX}}test_engineer
|
|
13947
13971
|
TASK: Generate and run login validation tests
|
|
13948
13972
|
FILE: src/auth/login.ts
|
|
13949
13973
|
OUTPUT: Test file at src/auth/login.test.ts + VERDICT: PASS/FAIL with failure details
|
|
13950
13974
|
|
|
13951
|
-
|
|
13975
|
+
{{AGENT_PREFIX}}critic
|
|
13952
13976
|
TASK: Review plan for user authentication feature
|
|
13953
13977
|
PLAN: [paste the plan.md content]
|
|
13954
13978
|
CONTEXT: [codebase summary from explorer]
|
|
@@ -13974,7 +13998,7 @@ Ambiguous request \u2192 Ask up to 3 questions, wait for answers
|
|
|
13974
13998
|
Clear request \u2192 Phase 2
|
|
13975
13999
|
|
|
13976
14000
|
### Phase 2: Discover
|
|
13977
|
-
Delegate to
|
|
14001
|
+
Delegate to {{AGENT_PREFIX}}explorer. Wait for response.
|
|
13978
14002
|
For complex tasks, make a second explorer call focused on risk/gap analysis:
|
|
13979
14003
|
- Hidden requirements, unstated assumptions, scope risks
|
|
13980
14004
|
- Existing patterns that the implementation must follow
|
|
@@ -13982,7 +14006,7 @@ For complex tasks, make a second explorer call focused on risk/gap analysis:
|
|
|
13982
14006
|
### Phase 3: Consult SMEs
|
|
13983
14007
|
Check .swarm/context.md for cached guidance first.
|
|
13984
14008
|
Identify 1-3 relevant domains from the task requirements.
|
|
13985
|
-
Call
|
|
14009
|
+
Call {{AGENT_PREFIX}}sme once per domain, serially. Max 3 SME calls per project phase.
|
|
13986
14010
|
Re-consult if a new domain emerges or if significant changes require fresh evaluation.
|
|
13987
14011
|
Cache guidance in context.md.
|
|
13988
14012
|
|
|
@@ -13996,7 +14020,7 @@ Create .swarm/context.md:
|
|
|
13996
14020
|
- Decisions, patterns, SME cache, file map
|
|
13997
14021
|
|
|
13998
14022
|
### Phase 4.5: Critic Gate
|
|
13999
|
-
Delegate plan to
|
|
14023
|
+
Delegate plan to {{AGENT_PREFIX}}critic for review BEFORE any implementation begins.
|
|
14000
14024
|
- Send the full plan.md content and codebase context summary
|
|
14001
14025
|
- **APPROVED** \u2192 Proceed to Phase 5
|
|
14002
14026
|
- **NEEDS_REVISION** \u2192 Revise the plan based on critic feedback, then resubmit (max 2 revision cycles)
|
|
@@ -14005,18 +14029,18 @@ Delegate plan to @{{AGENT_PREFIX}}critic for review BEFORE any implementation be
|
|
|
14005
14029
|
### Phase 5: Execute
|
|
14006
14030
|
For each task (respecting dependencies):
|
|
14007
14031
|
|
|
14008
|
-
5a.
|
|
14009
|
-
5b.
|
|
14032
|
+
5a. {{AGENT_PREFIX}}coder - Implement (MANDATORY)
|
|
14033
|
+
5b. {{AGENT_PREFIX}}reviewer - Review (specify CHECK dimensions relevant to the change)
|
|
14010
14034
|
5c. **GATE - Check VERDICT:**
|
|
14011
14035
|
- **APPROVED** \u2192 Proceed to 5d
|
|
14012
|
-
- **REJECTED** (attempt < {{QA_RETRY_LIMIT}}) \u2192 STOP. Send FIXES to
|
|
14036
|
+
- **REJECTED** (attempt < {{QA_RETRY_LIMIT}}) \u2192 STOP. Send FIXES to {{AGENT_PREFIX}}coder with specific changes. Retry from 5a. Do NOT proceed to 5d.
|
|
14013
14037
|
- **REJECTED** (attempt {{QA_RETRY_LIMIT}}) \u2192 STOP. Escalate to user or handle directly.
|
|
14014
|
-
5d.
|
|
14015
|
-
5e. If test VERDICT is FAIL \u2192 Send failures to
|
|
14038
|
+
5d. {{AGENT_PREFIX}}test_engineer - Generate AND run tests (ONLY if 5c = APPROVED). Expect VERDICT: PASS/FAIL.
|
|
14039
|
+
5e. If test VERDICT is FAIL \u2192 Send failures to {{AGENT_PREFIX}}coder for fixes, then re-run from 5b.
|
|
14016
14040
|
5f. Update plan.md [x], proceed to next task (ONLY if tests PASS)
|
|
14017
14041
|
|
|
14018
14042
|
### Phase 6: Phase Complete
|
|
14019
|
-
1.
|
|
14043
|
+
1. {{AGENT_PREFIX}}explorer - Rescan
|
|
14020
14044
|
2. Update context.md
|
|
14021
14045
|
3. Summarize to user
|
|
14022
14046
|
4. Ask: "Ready for Phase [N+1]?"
|
|
@@ -16212,12 +16236,19 @@ function createGuardrailsHooks(config2) {
|
|
|
16212
16236
|
toolBefore: async (input, output) => {
|
|
16213
16237
|
let session = getAgentSession(input.sessionID);
|
|
16214
16238
|
if (!session) {
|
|
16215
|
-
|
|
16239
|
+
const agentName = swarmState.activeAgent.get(input.sessionID) ?? "unknown";
|
|
16240
|
+
startAgentSession(input.sessionID, agentName);
|
|
16216
16241
|
session = getAgentSession(input.sessionID);
|
|
16217
16242
|
if (!session) {
|
|
16218
16243
|
warn(`Failed to create session for ${input.sessionID}`);
|
|
16219
16244
|
return;
|
|
16220
16245
|
}
|
|
16246
|
+
} else if (session.agentName === "unknown") {
|
|
16247
|
+
const activeAgentName = swarmState.activeAgent.get(input.sessionID);
|
|
16248
|
+
if (activeAgentName) {
|
|
16249
|
+
session.agentName = activeAgentName;
|
|
16250
|
+
session.startTime = Date.now();
|
|
16251
|
+
}
|
|
16221
16252
|
}
|
|
16222
16253
|
const agentConfig = resolveGuardrailsConfig(config2, session.agentName);
|
|
16223
16254
|
if (session.hardLimitHit) {
|
|
@@ -16457,7 +16488,7 @@ function extractAgentContext(contextContent, activeAgent, maxChars) {
|
|
|
16457
16488
|
const activitySection = activityMatch[1].trim();
|
|
16458
16489
|
if (!activitySection || activitySection === "No tool activity recorded yet.")
|
|
16459
16490
|
return null;
|
|
16460
|
-
const agentName = activeAgent
|
|
16491
|
+
const agentName = stripKnownSwarmPrefix(activeAgent);
|
|
16461
16492
|
let contextSummary;
|
|
16462
16493
|
switch (agentName) {
|
|
16463
16494
|
case "coder":
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.3",
|
|
4
4
|
"description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|