opencode-swarm 3.2.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ import type { SMEDomainConfig } from './base';
2
+ export declare const aiSMEConfig: SMEDomainConfig;
@@ -29,6 +29,7 @@ export declare const PluginConfigSchema: z.ZodObject<{
29
29
  }, z.core.$strip>>>;
30
30
  }, z.core.$strip>>>;
31
31
  max_iterations: z.ZodDefault<z.ZodNumber>;
32
+ qa_retry_limit: z.ZodDefault<z.ZodNumber>;
32
33
  multi_domain_sme: z.ZodDefault<z.ZodBoolean>;
33
34
  auto_detect_domains: z.ZodDefault<z.ZodBoolean>;
34
35
  inject_phase_reminders: z.ZodDefault<z.ZodBoolean>;
package/dist/index.js CHANGED
@@ -13759,9 +13759,10 @@ var PluginConfigSchema = exports_external.object({
13759
13759
  agents: exports_external.record(exports_external.string(), AgentOverrideConfigSchema).optional(),
13760
13760
  swarms: exports_external.record(exports_external.string(), SwarmConfigSchema).optional(),
13761
13761
  max_iterations: exports_external.number().min(1).max(10).default(5),
13762
+ qa_retry_limit: exports_external.number().min(1).max(10).default(3),
13762
13763
  multi_domain_sme: exports_external.boolean().default(true),
13763
13764
  auto_detect_domains: exports_external.boolean().default(true),
13764
- inject_phase_reminders: exports_external.boolean().default(false)
13765
+ inject_phase_reminders: exports_external.boolean().default(true)
13765
13766
  });
13766
13767
  // src/config/loader.ts
13767
13768
  import * as fs from "fs";
@@ -13812,9 +13813,10 @@ function loadPluginConfig(directory) {
13812
13813
  const projectConfigPath = path.join(directory, ".opencode", CONFIG_FILENAME);
13813
13814
  let config2 = loadConfigFromPath(userConfigPath) ?? {
13814
13815
  max_iterations: 5,
13816
+ qa_retry_limit: 3,
13815
13817
  multi_domain_sme: true,
13816
13818
  auto_detect_domains: true,
13817
- inject_phase_reminders: false
13819
+ inject_phase_reminders: true
13818
13820
  };
13819
13821
  const projectConfig = loadConfigFromPath(projectConfigPath);
13820
13822
  if (projectConfig) {
@@ -13850,6 +13852,11 @@ function loadAgentPrompt(agentName) {
13850
13852
  // src/agents/architect.ts
13851
13853
  var ARCHITECT_PROMPT = `You are Architect - orchestrator of a multi-agent swarm.
13852
13854
 
13855
+ ## IDENTITY
13856
+
13857
+ Swarm: {{SWARM_ID}}
13858
+ Your agents: {{AGENT_PREFIX}}explorer, {{AGENT_PREFIX}}coder, {{AGENT_PREFIX}}sme_*, etc.
13859
+
13853
13860
  ## ROLE
13854
13861
 
13855
13862
  You THINK. Subagents DO. You have the largest context window and strongest reasoning. Subagents have smaller contexts and weaker reasoning. Your job:
@@ -13860,19 +13867,19 @@ You THINK. Subagents DO. You have the largest context window and strongest reaso
13860
13867
 
13861
13868
  ## RULES
13862
13869
 
13863
- 1. DELEGATE all coding to @coder. You do NOT write code.
13870
+ 1. DELEGATE all coding to @{{AGENT_PREFIX}}coder. You do NOT write code.
13864
13871
  2. ONE agent per message. Send, STOP, wait for response.
13865
- 3. ONE task per @coder call. Never batch.
13866
- 4. Fallback: Only code yourself after 3 @coder failures on same task.
13872
+ 3. ONE task per @{{AGENT_PREFIX}}coder call. Never batch.
13873
+ 4. Fallback: Only code yourself after {{QA_RETRY_LIMIT}} @{{AGENT_PREFIX}}coder failures on same task.
13867
13874
 
13868
13875
  ## AGENTS
13869
13876
 
13870
- @explorer - Codebase analysis
13871
- @sme_[domain] - Domain expertise (windows, powershell, python, oracle, network, security, linux, vmware, azure, active_directory, ui_ux, web, database, devops, api)
13872
- @coder - Implementation (one task at a time)
13873
- @test_engineer - Test generation
13874
- @security_reviewer - Vulnerability review
13875
- @auditor - Correctness verification
13877
+ @{{AGENT_PREFIX}}explorer - Codebase analysis
13878
+ @{{AGENT_PREFIX}}sme_[domain] - Domain expertise (windows, powershell, python, oracle, network, security, linux, vmware, azure, active_directory, ui_ux, web, database, devops, api, ai)
13879
+ @{{AGENT_PREFIX}}coder - Implementation (one task at a time)
13880
+ @{{AGENT_PREFIX}}test_engineer - Test generation
13881
+ @{{AGENT_PREFIX}}security_reviewer - Vulnerability review
13882
+ @{{AGENT_PREFIX}}auditor - Correctness verification
13876
13883
 
13877
13884
  SMEs advise only. QA agents review only. Neither writes code.
13878
13885
 
@@ -13880,7 +13887,7 @@ SMEs advise only. QA agents review only. Neither writes code.
13880
13887
 
13881
13888
  All delegations use this structure:
13882
13889
 
13883
- @agent
13890
+ @{{AGENT_PREFIX}}[agent]
13884
13891
  TASK: [single objective]
13885
13892
  FILE: [path] (if applicable)
13886
13893
  INPUT: [what to analyze/use]
@@ -13889,36 +13896,36 @@ CONSTRAINT: [what NOT to do]
13889
13896
 
13890
13897
  Examples:
13891
13898
 
13892
- @explorer
13899
+ @{{AGENT_PREFIX}}explorer
13893
13900
  TASK: Analyze codebase for auth implementation
13894
13901
  INPUT: Focus on src/auth/, src/middleware/
13895
13902
  OUTPUT: Structure, frameworks, key files, relevant SME domains
13896
13903
 
13897
- @sme_security
13904
+ @{{AGENT_PREFIX}}sme_security
13898
13905
  TASK: Review auth patterns
13899
13906
  INPUT: src/auth/login.ts, src/auth/session.ts
13900
13907
  OUTPUT: Security considerations, recommended patterns
13901
13908
  CONSTRAINT: Focus on auth only, not general code style
13902
13909
 
13903
- @coder
13910
+ @{{AGENT_PREFIX}}coder
13904
13911
  TASK: Add input validation to login
13905
13912
  FILE: src/auth/login.ts
13906
13913
  INPUT: Validate email format, password >= 8 chars
13907
13914
  OUTPUT: Modified file
13908
13915
  CONSTRAINT: Do not modify other functions
13909
13916
 
13910
- @security_reviewer
13917
+ @{{AGENT_PREFIX}}security_reviewer
13911
13918
  TASK: Review login validation
13912
13919
  FILE: src/auth/login.ts
13913
13920
  OUTPUT: RISK [LOW|MEDIUM|HIGH|CRITICAL], issues with line numbers
13914
13921
 
13915
- @auditor
13922
+ @{{AGENT_PREFIX}}auditor
13916
13923
  TASK: Verify login validation
13917
13924
  FILE: src/auth/login.ts
13918
13925
  INPUT: Must validate email format, password >= 8 chars
13919
13926
  OUTPUT: APPROVED or REJECTED with specific issues
13920
13927
 
13921
- @test_engineer
13928
+ @{{AGENT_PREFIX}}test_engineer
13922
13929
  TASK: Generate login validation tests
13923
13930
  FILE: src/auth/login.ts
13924
13931
  OUTPUT: Test file at src/auth/login.test.ts
@@ -13926,19 +13933,24 @@ OUTPUT: Test file at src/auth/login.test.ts
13926
13933
  ## WORKFLOW
13927
13934
 
13928
13935
  ### Phase 0: Resume Check
13929
- If .swarm/plan.md exists \u2192 Read plan.md + context.md, resume at current task
13930
- If not \u2192 New project, proceed to Phase 1
13936
+ If .swarm/plan.md exists:
13937
+ 1. Read plan.md header for "Swarm:" field
13938
+ 2. If Swarm field missing or matches "{{SWARM_ID}}" \u2192 Resume at current task
13939
+ 3. If Swarm field differs (e.g., plan says "local" but you are "default"):
13940
+ - STOP and warn user: "This project was created by [other] swarm. The cached context references different agents. Options: (1) Continue - I will re-consult SMEs with my agents, (2) Abort - switch to the correct architect"
13941
+ - If user continues: Delete SME Cache section from context.md, update plan.md Swarm field to "{{SWARM_ID}}"
13942
+ If .swarm/plan.md does not exist \u2192 New project, proceed to Phase 1
13931
13943
 
13932
13944
  ### Phase 1: Clarify
13933
13945
  Ambiguous request \u2192 Ask up to 3 questions, wait for answers
13934
13946
  Clear request \u2192 Phase 2
13935
13947
 
13936
13948
  ### Phase 2: Discover
13937
- Delegate to @explorer. Wait for response.
13949
+ Delegate to @{{AGENT_PREFIX}}explorer. Wait for response.
13938
13950
 
13939
13951
  ### Phase 3: Consult SMEs
13940
13952
  Check .swarm/context.md for cached guidance first.
13941
- Call 1-3 relevant SMEs based on @explorer findings.
13953
+ Call 1-3 relevant SMEs based on @{{AGENT_PREFIX}}explorer findings.
13942
13954
  ONE SME at a time. Wait between each.
13943
13955
  Cache guidance in context.md.
13944
13956
 
@@ -13954,18 +13966,18 @@ Create .swarm/context.md:
13954
13966
  ### Phase 5: Execute
13955
13967
  For each task (respecting dependencies):
13956
13968
 
13957
- 5a. @coder - Implement (MANDATORY)
13958
- 5b. @security_reviewer - Review
13959
- 5c. @auditor - Verify
13969
+ 5a. @{{AGENT_PREFIX}}coder - Implement (MANDATORY)
13970
+ 5b. @{{AGENT_PREFIX}}security_reviewer - Review
13971
+ 5c. @{{AGENT_PREFIX}}auditor - Verify
13960
13972
  5d. Result:
13961
13973
  - APPROVED \u2192 5e
13962
- - REJECTED (attempt 1-2) \u2192 Feedback to @coder, retry
13963
- - REJECTED (attempt 3) \u2192 Escalate, handle directly
13964
- 5e. @test_engineer - Generate tests
13974
+ - REJECTED (attempt < {{QA_RETRY_LIMIT}}) \u2192 Feedback to @{{AGENT_PREFIX}}coder, retry
13975
+ - REJECTED (attempt {{QA_RETRY_LIMIT}}) \u2192 Escalate, handle directly
13976
+ 5e. @{{AGENT_PREFIX}}test_engineer - Generate tests
13965
13977
  5f. Update plan.md [x], proceed to next task
13966
13978
 
13967
13979
  ### Phase 6: Phase Complete
13968
- 1. @explorer - Rescan
13980
+ 1. @{{AGENT_PREFIX}}explorer - Rescan
13969
13981
  2. Update context.md
13970
13982
  3. Summarize to user
13971
13983
  4. Ask: "Ready for Phase [N+1]?"
@@ -13978,6 +13990,7 @@ Mark [BLOCKED] in plan.md, skip to next unblocked task, inform user.
13978
13990
  .swarm/plan.md:
13979
13991
  \`\`\`
13980
13992
  # [Project]
13993
+ Swarm: {{SWARM_ID}}
13981
13994
  Phase: [N] | Updated: [date]
13982
13995
 
13983
13996
  ## Phase 1 [COMPLETE]
@@ -13992,6 +14005,7 @@ Phase: [N] | Updated: [date]
13992
14005
  .swarm/context.md:
13993
14006
  \`\`\`
13994
14007
  # Context
14008
+ Swarm: {{SWARM_ID}}
13995
14009
 
13996
14010
  ## Decisions
13997
14011
  - [decision]: [rationale]
@@ -14336,6 +14350,20 @@ var activeDirectorySMEConfig = {
14336
14350
  - ADSI/DirectoryServices .NET`
14337
14351
  };
14338
14352
 
14353
+ // src/agents/sme/ai.ts
14354
+ var aiSMEConfig = {
14355
+ domain: "ai",
14356
+ description: "AI/LLM systems and prompt engineering",
14357
+ guidance: `- Prompt engineering (CoT, few-shot, structured output)
14358
+ - Context window management, token optimization
14359
+ - Model selection tradeoffs (cost, latency, capability)
14360
+ - Agent orchestration patterns (delegation, handoff)
14361
+ - RAG architectures, embedding strategies
14362
+ - Fine-tuning vs prompting decisions
14363
+ - Safety/alignment considerations
14364
+ - Tool use and function calling patterns`
14365
+ };
14366
+
14339
14367
  // src/agents/sme/api.ts
14340
14368
  var apiSMEConfig = {
14341
14369
  domain: "api",
@@ -14549,7 +14577,8 @@ var SME_CONFIGS = {
14549
14577
  web: webSMEConfig,
14550
14578
  database: databaseSMEConfig,
14551
14579
  devops: devopsSMEConfig,
14552
- api: apiSMEConfig
14580
+ api: apiSMEConfig,
14581
+ ai: aiSMEConfig
14553
14582
  };
14554
14583
  var AGENT_TO_DOMAIN = {
14555
14584
  sme_windows: "windows",
@@ -14566,7 +14595,8 @@ var AGENT_TO_DOMAIN = {
14566
14595
  sme_web: "web",
14567
14596
  sme_database: "database",
14568
14597
  sme_devops: "devops",
14569
- sme_api: "api"
14598
+ sme_api: "api",
14599
+ sme_ai: "ai"
14570
14600
  };
14571
14601
  function createAllSMEAgents(getModel, loadPrompt) {
14572
14602
  return Object.entries(AGENT_TO_DOMAIN).map(([agentName, domain2]) => {
@@ -14621,11 +14651,12 @@ function applyOverrides(agent, swarmAgents, swarmPrefix) {
14621
14651
  }
14622
14652
  return agent;
14623
14653
  }
14624
- function createSwarmAgents(swarmId, swarmConfig, isDefault) {
14654
+ function createSwarmAgents(swarmId, swarmConfig, isDefault, pluginConfig) {
14625
14655
  const agents = [];
14626
14656
  const swarmAgents = swarmConfig.agents;
14627
14657
  const prefix = isDefault ? "" : `${swarmId}_`;
14628
14658
  const swarmPrefix = isDefault ? undefined : swarmId;
14659
+ const qaRetryLimit = pluginConfig?.qa_retry_limit ?? 3;
14629
14660
  const getModel = (baseName) => getModelForAgent(baseName, swarmAgents, swarmPrefix);
14630
14661
  const getPrompts = (name) => loadAgentPrompt(name);
14631
14662
  const prefixName = (name) => `${prefix}${name}`;
@@ -14634,22 +14665,19 @@ function createSwarmAgents(swarmId, swarmConfig, isDefault) {
14634
14665
  const architectPrompts = getPrompts("architect");
14635
14666
  const architect = createArchitectAgent(getModel("architect"), architectPrompts.prompt, architectPrompts.appendPrompt);
14636
14667
  architect.name = prefixName("architect");
14668
+ const swarmName = swarmConfig.name || swarmId;
14669
+ const swarmIdentity = isDefault ? "default" : swarmId;
14670
+ const agentPrefix = prefix;
14671
+ architect.config.prompt = architect.config.prompt?.replace(/\{\{SWARM_ID\}\}/g, swarmIdentity).replace(/\{\{AGENT_PREFIX\}\}/g, agentPrefix).replace(/\{\{QA_RETRY_LIMIT\}\}/g, String(qaRetryLimit));
14637
14672
  if (!isDefault) {
14638
- const swarmName = swarmConfig.name || swarmId;
14639
14673
  architect.description = `[${swarmName}] ${architect.description}`;
14640
- const swarmHeader = `
14641
- ## \u26A0\uFE0F YOU ARE THE ${swarmName.toUpperCase()} SWARM ARCHITECT
14642
-
14643
- Your agents all have the "${swarmId}_" prefix. You MUST use this prefix when delegating:
14644
- - Use @${prefix}explorer, NOT @explorer
14645
- - Use @${prefix}coder, NOT @coder
14646
- - Use @${prefix}sme_security, NOT @sme_security
14647
- - etc.
14674
+ const swarmHeader = `## \u26A0\uFE0F YOU ARE THE ${swarmName.toUpperCase()} SWARM ARCHITECT
14648
14675
 
14649
- If you call an agent WITHOUT the "${swarmId}_" prefix, you will be calling the WRONG swarm's agents!
14676
+ Your agents all have the "${swarmId}_" prefix. You MUST use this prefix when delegating.
14677
+ If you call an agent WITHOUT the "${swarmId}_" prefix, you will call the WRONG swarm's agents!
14650
14678
 
14651
14679
  `;
14652
- architect.config.prompt = swarmHeader + (architect.config.prompt?.replace(/@explorer/g, `@${prefix}explorer`).replace(/@coder/g, `@${prefix}coder`).replace(/@test_engineer/g, `@${prefix}test_engineer`).replace(/@security_reviewer/g, `@${prefix}security_reviewer`).replace(/@auditor/g, `@${prefix}auditor`).replace(/@sme_(\w+)/g, `@${prefix}sme_$1`).replace(/@sme_\[(\w+)\]/g, `@${prefix}sme_[$1]`) || "");
14680
+ architect.config.prompt = swarmHeader + architect.config.prompt;
14653
14681
  }
14654
14682
  agents.push(applyOverrides(architect, swarmAgents, swarmPrefix));
14655
14683
  }
@@ -14702,7 +14730,7 @@ function createAgents(config2) {
14702
14730
  for (const swarmId of swarmIds) {
14703
14731
  const swarmConfig = swarms[swarmId];
14704
14732
  const isDefault = swarmId === defaultSwarmId;
14705
- const swarmAgents = createSwarmAgents(swarmId, swarmConfig, isDefault);
14733
+ const swarmAgents = createSwarmAgents(swarmId, swarmConfig, isDefault, config2);
14706
14734
  allAgents.push(...swarmAgents);
14707
14735
  }
14708
14736
  } else {
@@ -14710,7 +14738,7 @@ function createAgents(config2) {
14710
14738
  name: "Default",
14711
14739
  agents: config2?.agents
14712
14740
  };
14713
- const swarmAgents = createSwarmAgents("default", legacySwarmConfig, true);
14741
+ const swarmAgents = createSwarmAgents("default", legacySwarmConfig, true, config2);
14714
14742
  allAgents.push(...swarmAgents);
14715
14743
  }
14716
14744
  return allAgents;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
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",