opencode-swarm 5.1.5 → 5.1.6

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/dist/index.js CHANGED
@@ -13706,9 +13706,8 @@ function resolveGuardrailsConfig(base, agentName) {
13706
13706
  }
13707
13707
  const baseName = stripKnownSwarmPrefix(agentName);
13708
13708
  const builtInLookup = DEFAULT_AGENT_PROFILES[baseName];
13709
- const effectiveName = builtInLookup ? baseName : ORCHESTRATOR_NAME;
13710
- const builtIn = DEFAULT_AGENT_PROFILES[effectiveName];
13711
- const userProfile = base.profiles?.[effectiveName] ?? base.profiles?.[baseName] ?? base.profiles?.[agentName];
13709
+ const builtIn = builtInLookup;
13710
+ const userProfile = base.profiles?.[baseName] ?? base.profiles?.[agentName];
13712
13711
  if (!builtIn && !userProfile) {
13713
13712
  return base;
13714
13713
  }
@@ -15046,6 +15045,7 @@ function startAgentSession(sessionId, agentName, staleDurationMs = 7200000) {
15046
15045
  agentName,
15047
15046
  startTime: now,
15048
15047
  lastToolCallTime: now,
15048
+ lastAgentEventTime: now,
15049
15049
  toolCallCount: 0,
15050
15050
  consecutiveErrors: 0,
15051
15051
  recentToolCalls: [],
@@ -15075,6 +15075,7 @@ function ensureAgentSession(sessionId, agentName) {
15075
15075
  session.hardLimitHit = false;
15076
15076
  session.lastSuccessTime = now;
15077
15077
  session.delegationActive = false;
15078
+ session.lastAgentEventTime = now;
15078
15079
  }
15079
15080
  session.lastToolCallTime = now;
15080
15081
  return session;
@@ -15086,6 +15087,12 @@ function ensureAgentSession(sessionId, agentName) {
15086
15087
  }
15087
15088
  return session;
15088
15089
  }
15090
+ function updateAgentEventTime(sessionId) {
15091
+ const session = swarmState.agentSessions.get(sessionId);
15092
+ if (session) {
15093
+ session.lastAgentEventTime = Date.now();
15094
+ }
15095
+ }
15089
15096
 
15090
15097
  // src/commands/benchmark.ts
15091
15098
  var CI = {
@@ -16733,6 +16740,7 @@ ${originalText}`;
16733
16740
  // src/hooks/delegation-tracker.ts
16734
16741
  function createDelegationTrackerHook(config2) {
16735
16742
  return async (input, _output) => {
16743
+ const now = Date.now();
16736
16744
  if (!input.agent || input.agent === "") {
16737
16745
  const session2 = swarmState.agentSessions.get(input.sessionID);
16738
16746
  if (session2) {
@@ -16740,18 +16748,21 @@ function createDelegationTrackerHook(config2) {
16740
16748
  }
16741
16749
  swarmState.activeAgent.set(input.sessionID, ORCHESTRATOR_NAME);
16742
16750
  ensureAgentSession(input.sessionID, ORCHESTRATOR_NAME);
16751
+ updateAgentEventTime(input.sessionID);
16743
16752
  return;
16744
16753
  }
16745
16754
  const agentName = input.agent;
16746
16755
  const previousAgent = swarmState.activeAgent.get(input.sessionID);
16747
16756
  swarmState.activeAgent.set(input.sessionID, agentName);
16757
+ const strippedAgent = stripKnownSwarmPrefix(agentName);
16758
+ const isArchitect = strippedAgent === ORCHESTRATOR_NAME;
16748
16759
  const session = ensureAgentSession(input.sessionID, agentName);
16749
- session.delegationActive = true;
16760
+ session.delegationActive = !isArchitect;
16750
16761
  if (config2.hooks?.delegation_tracker === true && previousAgent && previousAgent !== agentName) {
16751
16762
  const entry = {
16752
16763
  from: previousAgent,
16753
16764
  to: agentName,
16754
- timestamp: Date.now()
16765
+ timestamp: now
16755
16766
  };
16756
16767
  if (!swarmState.delegationChains.has(input.sessionID)) {
16757
16768
  swarmState.delegationChains.set(input.sessionID, []);
@@ -16792,6 +16803,9 @@ function createGuardrailsHooks(config2) {
16792
16803
  return;
16793
16804
  }
16794
16805
  const agentConfig = resolveGuardrailsConfig(config2, session.agentName);
16806
+ if (agentConfig.max_duration_minutes === 0 && agentConfig.max_tool_calls === 0) {
16807
+ return;
16808
+ }
16795
16809
  if (session.hardLimitHit) {
16796
16810
  throw new Error("\uD83D\uDED1 CIRCUIT BREAKER: Agent blocked. Hard limit was previously triggered. Stop making tool calls and return your progress summary.");
16797
16811
  }
@@ -30165,7 +30179,7 @@ var OpenCodeSwarm = async (ctx) => {
30165
30179
  if (session && activeAgent && activeAgent !== ORCHESTRATOR_NAME) {
30166
30180
  const stripActive = stripKnownSwarmPrefix(activeAgent);
30167
30181
  if (stripActive !== ORCHESTRATOR_NAME) {
30168
- const staleDelegation = !session.delegationActive || Date.now() - session.lastToolCallTime > 1e4;
30182
+ const staleDelegation = !session.delegationActive || Date.now() - session.lastAgentEventTime > 1e4;
30169
30183
  if (staleDelegation) {
30170
30184
  swarmState.activeAgent.set(input.sessionID, ORCHESTRATOR_NAME);
30171
30185
  ensureAgentSession(input.sessionID, ORCHESTRATOR_NAME);
@@ -30175,7 +30189,21 @@ var OpenCodeSwarm = async (ctx) => {
30175
30189
  await guardrailsHooks.toolBefore(input, output);
30176
30190
  await safeHook(activityHooks.toolBefore)(input, output);
30177
30191
  },
30178
- "tool.execute.after": composeHandlers(activityHooks.toolAfter, guardrailsHooks.toolAfter, toolSummarizerHook),
30192
+ "tool.execute.after": async (input, output) => {
30193
+ await activityHooks.toolAfter(input, output);
30194
+ await guardrailsHooks.toolAfter(input, output);
30195
+ await toolSummarizerHook?.(input, output);
30196
+ if (input.tool === "task") {
30197
+ const sessionId = input.sessionID;
30198
+ swarmState.activeAgent.set(sessionId, ORCHESTRATOR_NAME);
30199
+ ensureAgentSession(sessionId, ORCHESTRATOR_NAME);
30200
+ const session = swarmState.agentSessions.get(sessionId);
30201
+ if (session) {
30202
+ session.delegationActive = false;
30203
+ session.lastAgentEventTime = Date.now();
30204
+ }
30205
+ }
30206
+ },
30179
30207
  "chat.message": safeHook(delegationHandler)
30180
30208
  };
30181
30209
  };
package/dist/state.d.ts CHANGED
@@ -43,6 +43,8 @@ export interface AgentSessionState {
43
43
  startTime: number;
44
44
  /** Timestamp of most recent tool call (for stale session eviction) */
45
45
  lastToolCallTime: number;
46
+ /** Timestamp of most recent agent identity event (chat.message sets/changes identity) */
47
+ lastAgentEventTime: number;
46
48
  /** Total tool calls in this session */
47
49
  toolCallCount: number;
48
50
  /** Consecutive errors (reset on success) */
@@ -114,3 +116,9 @@ export declare function getAgentSession(sessionId: string): AgentSessionState |
114
116
  * @returns The AgentSessionState
115
117
  */
116
118
  export declare function ensureAgentSession(sessionId: string, agentName?: string): AgentSessionState;
119
+ /**
120
+ * Update only the agent event timestamp (for stale detection).
121
+ * Does NOT change agent name or reset guardrail state.
122
+ * @param sessionId - The session identifier
123
+ */
124
+ export declare function updateAgentEventTime(sessionId: string): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "5.1.5",
3
+ "version": "5.1.6",
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",