opencode-swarm 5.0.3 → 5.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.
- package/dist/index.js +36 -18
- package/dist/state.d.ts +13 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15955,11 +15955,11 @@ var swarmState = {
|
|
|
15955
15955
|
pendingEvents: 0,
|
|
15956
15956
|
agentSessions: new Map
|
|
15957
15957
|
};
|
|
15958
|
-
function startAgentSession(sessionId, agentName, staleDurationMs =
|
|
15958
|
+
function startAgentSession(sessionId, agentName, staleDurationMs = 7200000) {
|
|
15959
15959
|
const now = Date.now();
|
|
15960
15960
|
const staleIds = [];
|
|
15961
15961
|
for (const [id, session] of swarmState.agentSessions) {
|
|
15962
|
-
if (now - session.
|
|
15962
|
+
if (now - session.lastToolCallTime > staleDurationMs) {
|
|
15963
15963
|
staleIds.push(id);
|
|
15964
15964
|
}
|
|
15965
15965
|
}
|
|
@@ -15969,6 +15969,7 @@ function startAgentSession(sessionId, agentName, staleDurationMs = 3600000) {
|
|
|
15969
15969
|
const sessionState = {
|
|
15970
15970
|
agentName,
|
|
15971
15971
|
startTime: now,
|
|
15972
|
+
lastToolCallTime: now,
|
|
15972
15973
|
toolCallCount: 0,
|
|
15973
15974
|
consecutiveErrors: 0,
|
|
15974
15975
|
recentToolCalls: [],
|
|
@@ -15980,6 +15981,24 @@ function startAgentSession(sessionId, agentName, staleDurationMs = 3600000) {
|
|
|
15980
15981
|
function getAgentSession(sessionId) {
|
|
15981
15982
|
return swarmState.agentSessions.get(sessionId);
|
|
15982
15983
|
}
|
|
15984
|
+
function ensureAgentSession(sessionId, agentName) {
|
|
15985
|
+
const now = Date.now();
|
|
15986
|
+
let session = swarmState.agentSessions.get(sessionId);
|
|
15987
|
+
if (session) {
|
|
15988
|
+
if (agentName && session.agentName === "unknown") {
|
|
15989
|
+
session.agentName = agentName;
|
|
15990
|
+
session.startTime = now;
|
|
15991
|
+
}
|
|
15992
|
+
session.lastToolCallTime = now;
|
|
15993
|
+
return session;
|
|
15994
|
+
}
|
|
15995
|
+
startAgentSession(sessionId, agentName ?? "unknown");
|
|
15996
|
+
session = swarmState.agentSessions.get(sessionId);
|
|
15997
|
+
if (!session) {
|
|
15998
|
+
throw new Error(`Failed to create guardrail session for ${sessionId}`);
|
|
15999
|
+
}
|
|
16000
|
+
return session;
|
|
16001
|
+
}
|
|
15983
16002
|
|
|
15984
16003
|
// src/hooks/agent-activity.ts
|
|
15985
16004
|
function createAgentActivityHooks(config2, directory) {
|
|
@@ -16208,6 +16227,7 @@ function createDelegationTrackerHook(config2) {
|
|
|
16208
16227
|
}
|
|
16209
16228
|
const previousAgent = swarmState.activeAgent.get(input.sessionID);
|
|
16210
16229
|
swarmState.activeAgent.set(input.sessionID, input.agent);
|
|
16230
|
+
ensureAgentSession(input.sessionID, input.agent);
|
|
16211
16231
|
if (config2.hooks?.delegation_tracker === true && previousAgent && previousAgent !== input.agent) {
|
|
16212
16232
|
const entry = {
|
|
16213
16233
|
from: previousAgent,
|
|
@@ -16234,22 +16254,8 @@ function createGuardrailsHooks(config2) {
|
|
|
16234
16254
|
}
|
|
16235
16255
|
return {
|
|
16236
16256
|
toolBefore: async (input, output) => {
|
|
16237
|
-
|
|
16238
|
-
|
|
16239
|
-
const agentName = swarmState.activeAgent.get(input.sessionID) ?? "unknown";
|
|
16240
|
-
startAgentSession(input.sessionID, agentName);
|
|
16241
|
-
session = getAgentSession(input.sessionID);
|
|
16242
|
-
if (!session) {
|
|
16243
|
-
warn(`Failed to create session for ${input.sessionID}`);
|
|
16244
|
-
return;
|
|
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
|
-
}
|
|
16252
|
-
}
|
|
16257
|
+
const agentName = swarmState.activeAgent.get(input.sessionID);
|
|
16258
|
+
const session = ensureAgentSession(input.sessionID, agentName);
|
|
16253
16259
|
const agentConfig = resolveGuardrailsConfig(config2, session.agentName);
|
|
16254
16260
|
if (session.hardLimitHit) {
|
|
16255
16261
|
throw new Error("\uD83D\uDED1 CIRCUIT BREAKER: Agent blocked. Hard limit was previously triggered. Stop making tool calls and return your progress summary.");
|
|
@@ -16279,10 +16285,22 @@ function createGuardrailsHooks(config2) {
|
|
|
16279
16285
|
const elapsedMinutes = (Date.now() - session.startTime) / 60000;
|
|
16280
16286
|
if (session.toolCallCount >= agentConfig.max_tool_calls) {
|
|
16281
16287
|
session.hardLimitHit = true;
|
|
16288
|
+
warn("Circuit breaker: tool call limit hit", {
|
|
16289
|
+
sessionID: input.sessionID,
|
|
16290
|
+
agentName: session.agentName,
|
|
16291
|
+
resolvedMaxCalls: agentConfig.max_tool_calls,
|
|
16292
|
+
currentCalls: session.toolCallCount
|
|
16293
|
+
});
|
|
16282
16294
|
throw new Error(`\uD83D\uDED1 CIRCUIT BREAKER: Tool call limit reached (${session.toolCallCount}/${agentConfig.max_tool_calls}). Stop making tool calls and return your progress summary.`);
|
|
16283
16295
|
}
|
|
16284
16296
|
if (elapsedMinutes >= agentConfig.max_duration_minutes) {
|
|
16285
16297
|
session.hardLimitHit = true;
|
|
16298
|
+
warn("Circuit breaker: duration limit hit", {
|
|
16299
|
+
sessionID: input.sessionID,
|
|
16300
|
+
agentName: session.agentName,
|
|
16301
|
+
resolvedMaxMinutes: agentConfig.max_duration_minutes,
|
|
16302
|
+
elapsedMinutes: Math.floor(elapsedMinutes)
|
|
16303
|
+
});
|
|
16286
16304
|
throw new Error(`\uD83D\uDED1 CIRCUIT BREAKER: Duration limit reached (${Math.floor(elapsedMinutes)} min). Stop making tool calls and return your progress summary.`);
|
|
16287
16305
|
}
|
|
16288
16306
|
if (repetitionCount >= agentConfig.max_repetitions) {
|
package/dist/state.d.ts
CHANGED
|
@@ -41,6 +41,8 @@ export interface AgentSessionState {
|
|
|
41
41
|
agentName: string;
|
|
42
42
|
/** Date.now() when session started */
|
|
43
43
|
startTime: number;
|
|
44
|
+
/** Timestamp of most recent tool call (for stale session eviction) */
|
|
45
|
+
lastToolCallTime: number;
|
|
44
46
|
/** Total tool calls in this session */
|
|
45
47
|
toolCallCount: number;
|
|
46
48
|
/** Consecutive errors (reset on success) */
|
|
@@ -82,7 +84,7 @@ export declare function resetSwarmState(): void;
|
|
|
82
84
|
* Also removes any stale sessions older than staleDurationMs.
|
|
83
85
|
* @param sessionId - The session identifier
|
|
84
86
|
* @param agentName - The agent associated with this session
|
|
85
|
-
* @param staleDurationMs - Age threshold for stale session eviction (default:
|
|
87
|
+
* @param staleDurationMs - Age threshold for stale session eviction (default: 120 min)
|
|
86
88
|
*/
|
|
87
89
|
export declare function startAgentSession(sessionId: string, agentName: string, staleDurationMs?: number): void;
|
|
88
90
|
/**
|
|
@@ -96,3 +98,13 @@ export declare function endAgentSession(sessionId: string): void;
|
|
|
96
98
|
* @returns The AgentSessionState or undefined if not found
|
|
97
99
|
*/
|
|
98
100
|
export declare function getAgentSession(sessionId: string): AgentSessionState | undefined;
|
|
101
|
+
/**
|
|
102
|
+
* Ensure a guardrail session exists for the given sessionID.
|
|
103
|
+
* If one exists and agentName is provided and different, update it.
|
|
104
|
+
* If none exists, create one.
|
|
105
|
+
* Always updates lastToolCallTime.
|
|
106
|
+
* @param sessionId - The session identifier
|
|
107
|
+
* @param agentName - Optional agent name (if known)
|
|
108
|
+
* @returns The AgentSessionState
|
|
109
|
+
*/
|
|
110
|
+
export declare function ensureAgentSession(sessionId: string, agentName?: string): AgentSessionState;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.4",
|
|
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",
|