opencode-swarm 7.125.3 → 7.125.5
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/.opencode/skills/swarm-pr-feedback/SKILL.md +15 -0
- package/.opencode/skills/swarm-pr-review/SKILL.md +34 -0
- package/dist/cli/{config-doctor-rm1m07gz.js → config-doctor-akxywx0c.js} +2 -2
- package/dist/cli/{curation-policy-7pgdjt5w.js → curation-policy-62w2pwfz.js} +2 -2
- package/dist/cli/{curator-llm-factory-yq5vf298.js → curator-llm-factory-av2tcfy9.js} +12 -12
- package/dist/cli/{curator-arwm18td.js → curator-mhhvx2pw.js} +12 -12
- package/dist/cli/{guardrail-explain-mscq3veq.js → guardrail-explain-kqx2bczn.js} +13 -13
- package/dist/cli/{guardrail-log-6a2zxvtx.js → guardrail-log-222xyxfp.js} +3 -3
- package/dist/cli/{hive-promoter-q79naynh.js → hive-promoter-6mhnhrbx.js} +12 -12
- package/dist/cli/{index-7p6jkkat.js → index-0cdq55k0.js} +14 -14
- package/dist/cli/{index-vdfewvn5.js → index-0f45t7xy.js} +5 -5
- package/dist/cli/{index-45mvd5q7.js → index-1012f47p.js} +4 -4
- package/dist/cli/{index-rp5msv7n.js → index-1htanqp1.js} +1 -1
- package/dist/cli/{index-emzes7sj.js → index-4b1e5m0d.js} +2 -2
- package/dist/cli/{index-ambnwnmt.js → index-74xejn4v.js} +1 -1
- package/dist/cli/{index-x8entmky.js → index-ccfkfrew.js} +2 -2
- package/dist/cli/{index-xezv6tdw.js → index-dezgmvtw.js} +1 -1
- package/dist/cli/{index-8tjbq2ej.js → index-e315gwc9.js} +1 -1
- package/dist/cli/{index-fm4zfxnr.js → index-gbnpz7rh.js} +1 -1
- package/dist/cli/{index-01n43w2p.js → index-gd5w3ef8.js} +3 -3
- package/dist/cli/{index-pk099nqv.js → index-jt7hnr7q.js} +1 -1
- package/dist/cli/{index-4ycq2mrp.js → index-qzkcy22e.js} +1 -1
- package/dist/cli/{index-414r47r7.js → index-r1gdkn2d.js} +4 -0
- package/dist/cli/{index-m5e00g9s.js → index-s6hskqg6.js} +231 -98
- package/dist/cli/{index-sa3dgpmc.js → index-yq4s3q43.js} +2 -2
- package/dist/cli/index.js +12 -12
- package/dist/cli/{knowledge-escalator-gr8qd7kz.js → knowledge-escalator-h3hg7ek7.js} +3 -3
- package/dist/cli/{knowledge-events-q83g3f8z.js → knowledge-events-jtr66wxz.js} +1 -1
- package/dist/cli/{knowledge-store-qq3w5yt8.js → knowledge-store-69ttjjjs.js} +1 -1
- package/dist/cli/{knowledge-validator-7jhq8yam.js → knowledge-validator-yn06rh13.js} +4 -4
- package/dist/cli/{scan-cursor-fa5sy36q.js → scan-cursor-r0w2p5gz.js} +2 -2
- package/dist/cli/{schema-bw68my66.js → schema-69z8w1ka.js} +1 -1
- package/dist/cli/{skill-generator-ffc1agyw.js → skill-generator-a7xfyddq.js} +5 -5
- package/dist/commands/abort-pr-workflow.d.ts +17 -0
- package/dist/commands/registry.d.ts +8 -0
- package/dist/hooks/delegation-gate.d.ts +35 -0
- package/dist/hooks/pr-workflow-gate.d.ts +32 -0
- package/dist/hooks/pr-workflow-response-gate.d.ts +48 -0
- package/dist/hooks/shell-write-detect.d.ts +1 -1
- package/dist/index.js +100 -84
- package/dist/session/snapshot-writer.d.ts +9 -0
- package/dist/state.d.ts +15 -0
- package/dist/tools/abort-pr-workflow.d.ts +5 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/manifest.d.ts +1 -0
- package/dist/tools/tool-metadata.d.ts +4 -0
- package/dist/turbo/lean/reviewer.d.ts +2 -1
- package/dist/turbo/lean/runner.d.ts +2 -1
- package/dist/utils/model-dispatch-fallback.d.ts +71 -0
- package/dist/utils/provider-error-classification.d.ts +52 -0
- package/package.json +1 -1
|
@@ -76,6 +76,15 @@ export interface SerializedAgentSession {
|
|
|
76
76
|
* so older snapshots deserialize cleanly; the reader defaults to undefined.
|
|
77
77
|
*/
|
|
78
78
|
cachedCohortId?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Last observed `provider/model` for this (architect) session (#1896). Omitted
|
|
81
|
+
* when undefined for additive-only schema. MUST survive rehydration (it is NOT
|
|
82
|
+
* a transient-reset field) so a silent cross-interrupt model switch is
|
|
83
|
+
* detectable on resume.
|
|
84
|
+
*/
|
|
85
|
+
lastObservedModel?: string;
|
|
86
|
+
/** Provider id paired with lastObservedModel (#1896). Omitted when undefined. */
|
|
87
|
+
lastObservedProviderID?: string;
|
|
79
88
|
}
|
|
80
89
|
/**
|
|
81
90
|
* Minimal interface for serialized InvocationWindow
|
package/dist/state.d.ts
CHANGED
|
@@ -271,6 +271,21 @@ export interface AgentSessionState {
|
|
|
271
271
|
* failed); callers must handle the miss with a bounded fallback.
|
|
272
272
|
*/
|
|
273
273
|
cachedCohortId?: string;
|
|
274
|
+
/**
|
|
275
|
+
* The `provider/model` most recently OBSERVED on this (architect/primary)
|
|
276
|
+
* session's assistant turns (e.g. "anthropic/claude"). Persisted through
|
|
277
|
+
* snapshots and deliberately NOT reset on rehydration, so a silent model
|
|
278
|
+
* switch across an interrupt can be detected on resume by comparing the
|
|
279
|
+
* pre-interrupt observation with the first post-resume one. `undefined` until
|
|
280
|
+
* first observed.
|
|
281
|
+
*/
|
|
282
|
+
lastObservedModel?: string;
|
|
283
|
+
/** Provider id paired with `lastObservedModel` (#1896). */
|
|
284
|
+
lastObservedProviderID?: string;
|
|
285
|
+
/** One-shot guard: the resume model-change advisory has fired for this rehydration (#1896). */
|
|
286
|
+
resumeModelAdvisoryDone?: boolean;
|
|
287
|
+
/** One-shot guard: the config-vs-UI model advisory has fired for this session (#1896). */
|
|
288
|
+
configModelAdvisoryDone?: boolean;
|
|
274
289
|
}
|
|
275
290
|
export type NonTransientErrorCategory = 'shell_parse_error' | 'command_not_found' | 'sandbox_wrapper_failure' | 'general_permanent';
|
|
276
291
|
export interface NonTransientCircuitState {
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -86,6 +86,7 @@ export type { ClassifiedFailure, FailureClassification, FailureCluster, } from '
|
|
|
86
86
|
export { classifyAndCluster, classifyFailure, clusterFailures, } from '../test-impact/failure-classifier.js';
|
|
87
87
|
export type { FlakyTestEntry } from '../test-impact/flaky-detector.js';
|
|
88
88
|
export { computeFlakyScore, detectFlakyTests, isTestQuarantined, } from '../test-impact/flaky-detector.js';
|
|
89
|
+
export { abort_pr_workflow, executeAbortPrWorkflow, } from './abort-pr-workflow';
|
|
89
90
|
export { complete_pr_workflow, executeCompletePrWorkflow, } from './complete-pr-workflow';
|
|
90
91
|
export { epic_plan_waves } from './epic-plan-waves';
|
|
91
92
|
export { epic_record_divergence } from './epic-record-divergence';
|
package/dist/tools/manifest.d.ts
CHANGED
|
@@ -43,6 +43,7 @@ export declare const TOOL_MANIFEST: {
|
|
|
43
43
|
check_gate_status: () => ToolDefinition;
|
|
44
44
|
completion_verify: () => ToolDefinition;
|
|
45
45
|
complete_pr_workflow: () => ToolDefinition;
|
|
46
|
+
abort_pr_workflow: () => ToolDefinition;
|
|
46
47
|
run_pr_feedback_stage_a: () => ToolDefinition;
|
|
47
48
|
submit_council_verdicts: () => ToolDefinition;
|
|
48
49
|
submit_phase_council_verdicts: () => ToolDefinition;
|
|
@@ -103,6 +103,10 @@ export declare const TOOL_METADATA: {
|
|
|
103
103
|
description: string;
|
|
104
104
|
agents: "architect"[];
|
|
105
105
|
};
|
|
106
|
+
abort_pr_workflow: {
|
|
107
|
+
description: string;
|
|
108
|
+
agents: "architect"[];
|
|
109
|
+
};
|
|
106
110
|
run_pr_feedback_stage_a: {
|
|
107
111
|
description: string;
|
|
108
112
|
agents: "architect"[];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ModelOverride } from '../../utils/model-dispatch-fallback';
|
|
1
2
|
import { type LaneEvidence, listLaneEvidence, readPhaseEvidence, type ValidationArtifact } from './evidence';
|
|
2
3
|
import { readPersisted } from './state';
|
|
3
4
|
/**
|
|
@@ -102,7 +103,7 @@ export declare const _internals: {
|
|
|
102
103
|
compileReviewPackage: typeof compileReviewPackage;
|
|
103
104
|
parseReviewerVerdict: typeof parseReviewerVerdict;
|
|
104
105
|
writeReviewerEvidence: typeof writeReviewerEvidence;
|
|
105
|
-
dispatchReviewerAgent: (directory: string, pkg: ReviewPackage, agentName: string, timeoutMs: number, parentSessionId?: string) => Promise<string>;
|
|
106
|
+
dispatchReviewerAgent: (directory: string, pkg: ReviewPackage, agentName: string, timeoutMs: number, parentSessionId?: string, model?: ModelOverride) => Promise<string>;
|
|
106
107
|
resolveDefaultReviewerAgent: typeof resolveDefaultReviewerAgent;
|
|
107
108
|
listLaneEvidence: typeof listLaneEvidence;
|
|
108
109
|
readPhaseEvidence: typeof readPhaseEvidence;
|
|
@@ -21,6 +21,7 @@ import { loadFullAutoRunState } from '../../full-auto/state';
|
|
|
21
21
|
import { acquireLaneLocks, releaseLaneLocks } from '../../parallel/file-locks';
|
|
22
22
|
import { loadPlanJsonOnly } from '../../plan/manager';
|
|
23
23
|
import { ensureAgentSession, hasActiveFullAuto } from '../../state';
|
|
24
|
+
import { type ModelOverride } from '../../utils/model-dispatch-fallback';
|
|
24
25
|
import { writeLaneEvidence, writePhaseEvidence } from './evidence';
|
|
25
26
|
import { attemptMergeBackFromDirty, getMergeStrategy, mergeLaneBranch, postMergeCleanup, startupOrphanRecovery } from './merge-back';
|
|
26
27
|
import { planLeanTurboLanes } from './planner';
|
|
@@ -263,7 +264,7 @@ export declare class LeanTurboRunner {
|
|
|
263
264
|
* @param lane - Lane to dispatch
|
|
264
265
|
* @param agentName - Agent name to dispatch to
|
|
265
266
|
*/
|
|
266
|
-
dispatchLane(lane: LeanTurboLane, agentName: string, worktreeDirectory?: string): Promise<LaneDispatchResult>;
|
|
267
|
+
dispatchLane(lane: LeanTurboLane, agentName: string, worktreeDirectory?: string, model?: ModelOverride): Promise<LaneDispatchResult>;
|
|
267
268
|
/**
|
|
268
269
|
* Internal dispatch implementation (separated for timeout wrapping).
|
|
269
270
|
*/
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Issue #1896 (sub-issue 3): shared model-fallback dispatch helper.
|
|
3
|
+
*
|
|
4
|
+
* Before this, the ONLY place a role failed over to its configured
|
|
5
|
+
* `fallback_models` was the guardrails `toolAfter` hook (which fires on
|
|
6
|
+
* tool-result payloads). Every direct model-dispatch stage — critic oversight,
|
|
7
|
+
* lean-turbo reviewer, lane runner — called the provider directly and never
|
|
8
|
+
* failed over, so a role that hit its quota mid-run failed the stage outright.
|
|
9
|
+
*
|
|
10
|
+
* All those stages dispatch via `client.session.prompt({ body: { agent, model }})`,
|
|
11
|
+
* which accepts a per-call `model: {providerID, modelID}` override. This helper
|
|
12
|
+
* wraps such a dispatch with (a) bounded, per-model transient retry and (b)
|
|
13
|
+
* model-fallback advance — kept INDEPENDENT per AGENTS.md invariant #9. The
|
|
14
|
+
* fallback index is owned LOCALLY here: every stage dispatches into an ephemeral
|
|
15
|
+
* child session, so the only reachable `session.model_fallback_index` belongs to
|
|
16
|
+
* the parent orchestrator (a different agent) and must not be reused.
|
|
17
|
+
*
|
|
18
|
+
* The helper does NOT import `src/agents/index.ts` (avoids a heavy import cycle);
|
|
19
|
+
* the caller injects a `resolveFallback(index)` closure that wraps
|
|
20
|
+
* `resolveFallbackModel(baseRole, index, getSwarmAgents(swarmId))`.
|
|
21
|
+
*/
|
|
22
|
+
/** Per-call model override shape accepted by `client.session.prompt` body. */
|
|
23
|
+
export interface ModelOverride {
|
|
24
|
+
providerID: string;
|
|
25
|
+
modelID: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parse a `provider/model` string into the per-call override shape. Returns
|
|
29
|
+
* undefined for empty/blank input. Throws on a value with no provider or no
|
|
30
|
+
* model segment.
|
|
31
|
+
*/
|
|
32
|
+
export declare function parseModelString(model: string): ModelOverride | undefined;
|
|
33
|
+
export interface ModelFallbackResult<T> {
|
|
34
|
+
result: T;
|
|
35
|
+
/** undefined = the agent's registered/primary model; otherwise the `provider/model` string used. */
|
|
36
|
+
modelUsed?: string;
|
|
37
|
+
/** 0 = primary; 1.. = which configured fallback landed. */
|
|
38
|
+
fallbackIndex: number;
|
|
39
|
+
/** total dispatch attempts made (across models + same-model retries). */
|
|
40
|
+
attempts: number;
|
|
41
|
+
}
|
|
42
|
+
export interface DispatchWithModelFallbackOptions<T> {
|
|
43
|
+
/** Dispatch using `model` (undefined = the agent's registered/primary model). */
|
|
44
|
+
dispatch: (model: ModelOverride | undefined) => Promise<T>;
|
|
45
|
+
/**
|
|
46
|
+
* Resolve the 1-based fallback model as a `provider/model` string, or null
|
|
47
|
+
* when the fallback chain is exhausted. Typically wraps
|
|
48
|
+
* `resolveFallbackModel(baseRole, index, getSwarmAgents(swarmId))`.
|
|
49
|
+
*/
|
|
50
|
+
resolveFallback: (fallbackIndex: number) => string | null;
|
|
51
|
+
/** Classify a dispatch error: 'transient' → retry/failover; 'permanent' → throw immediately. */
|
|
52
|
+
classify: (error: unknown) => 'transient' | 'permanent';
|
|
53
|
+
/** Bounded transient retries on the SAME model before advancing (invariant #9 — independent of fallback). Default 1. */
|
|
54
|
+
maxTransientRetriesPerModel?: number;
|
|
55
|
+
/** Backoff before a same-model retry (NOT before a fallback advance). Default 2**(n-1)*1000 ms. */
|
|
56
|
+
backoffMs?: (retryAttempt: number) => number;
|
|
57
|
+
/** Notified when advancing to a fallback model (for advisory/telemetry). */
|
|
58
|
+
onFallback?: (info: {
|
|
59
|
+
toModel: string;
|
|
60
|
+
fallbackIndex: number;
|
|
61
|
+
}) => void;
|
|
62
|
+
/** DI for tests (avoid real waits). */
|
|
63
|
+
sleep?: (ms: number) => Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Try the primary model, then each configured fallback, retrying transient
|
|
67
|
+
* failures a bounded number of times per model. A permanent failure throws
|
|
68
|
+
* immediately (no retry, no advance). When every model is exhausted transiently,
|
|
69
|
+
* the last error is rethrown.
|
|
70
|
+
*/
|
|
71
|
+
export declare function dispatchWithModelFallback<T>(opts: DispatchWithModelFallbackOptions<T>): Promise<ModelFallbackResult<T>>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Issue #1896 (sub-issue 3): single source of truth for provider/model
|
|
3
|
+
* transient-error classification.
|
|
4
|
+
*
|
|
5
|
+
* Previously the same `TRANSIENT_MODEL_ERROR_PATTERN` + transient-status-code set
|
|
6
|
+
* was duplicated across `src/hooks/guardrails/index.ts`,
|
|
7
|
+
* `src/hooks/guardrails/messages-transform.ts`, and `src/full-auto/oversight.ts`,
|
|
8
|
+
* and NONE recognized provider quota / usage-limit exhaustion — so a role whose
|
|
9
|
+
* model hit its quota mid-run failed the stage outright instead of failing over
|
|
10
|
+
* to a configured fallback model.
|
|
11
|
+
*
|
|
12
|
+
* Design (see the plan critic's M1): QUOTA is a SEPARATE pattern and is combined
|
|
13
|
+
* ONLY inside {@link isTransientProviderError}, which is consumed exclusively by
|
|
14
|
+
* the model-DISPATCH classifiers (the failover helper + oversight/reviewer/runner
|
|
15
|
+
* dispatch paths). The narrow {@link TRANSIENT_MODEL_ERROR_PATTERN} (no quota) is
|
|
16
|
+
* what the guardrails tool-OUTPUT classifier keeps using, so a bash
|
|
17
|
+
* `Disk quota exceeded` (EDQUOT) in tool stdout can never be misread as a
|
|
18
|
+
* transient provider error and trigger a bogus model fallback.
|
|
19
|
+
*/
|
|
20
|
+
/** v6.33: Known HTTP status codes that indicate transient provider errors. */
|
|
21
|
+
export declare const TRANSIENT_STATUS_CODES: Set<number>;
|
|
22
|
+
/** Extracts a transient HTTP status code from an error message string. */
|
|
23
|
+
export declare function extractStatusCode(errorMsg: string): number | null;
|
|
24
|
+
/**
|
|
25
|
+
* v6.33: Regex for transient model/provider errors that should trigger bounded
|
|
26
|
+
* retry (and, in the dispatch paths, model fallback). Content is UNCHANGED from
|
|
27
|
+
* the historical duplicated definition — quota is intentionally NOT here (see the
|
|
28
|
+
* module doc + {@link QUOTA_ERROR_PATTERN}), so tool-output classifiers that
|
|
29
|
+
* import this keep byte-identical behavior.
|
|
30
|
+
*/
|
|
31
|
+
export declare const TRANSIENT_MODEL_ERROR_PATTERN: RegExp;
|
|
32
|
+
/**
|
|
33
|
+
* Issue #1896: provider quota / usage-limit / billing exhaustion — a class
|
|
34
|
+
* distinct from a transient blip. It is retryable after a wait AND fallback-
|
|
35
|
+
* eligible (a different configured model may have its own quota). Used ONLY on
|
|
36
|
+
* model-DISPATCH error strings via {@link isTransientProviderError}, never on
|
|
37
|
+
* tool stdout, so `Disk quota exceeded` shell output cannot false-trigger it.
|
|
38
|
+
*/
|
|
39
|
+
export declare const QUOTA_ERROR_PATTERN: RegExp;
|
|
40
|
+
/**
|
|
41
|
+
* True when a model-DISPATCH error is a transient provider failure OR a
|
|
42
|
+
* quota/rate-limit exhaustion — both are retry + model-fallback eligible.
|
|
43
|
+
* Do NOT use this on arbitrary tool output; use `TRANSIENT_MODEL_ERROR_PATTERN`
|
|
44
|
+
* directly there (quota tokens would false-positive on shell stdout).
|
|
45
|
+
*/
|
|
46
|
+
export declare function isTransientProviderError(signal: string): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* True when the dispatch error specifically indicates quota/usage-limit
|
|
49
|
+
* exhaustion. Used to tag the fallback advisory / telemetry reason as `'quota'`
|
|
50
|
+
* vs a generic transient failure.
|
|
51
|
+
*/
|
|
52
|
+
export declare function isQuotaError(signal: string): boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.125.
|
|
3
|
+
"version": "7.125.5",
|
|
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",
|