opencode-swarm 7.104.0 → 7.106.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.
- package/.opencode/skills/commit-pr/SKILL.md +15 -7
- package/.opencode/skills/swarm-pr-feedback/SKILL.md +7 -0
- package/.opencode/skills/swarm-pr-review/SKILL.md +6 -0
- package/.opencode/skills/swarm-pr-subscribe/SKILL.md +176 -0
- package/dist/background/pr-event-delivery.d.ts +107 -0
- package/dist/background/pr-event-subscribers.d.ts +36 -7
- package/dist/cli/{config-doctor-5m8z8jeg.js → config-doctor-cntnpyvj.js} +2 -2
- package/dist/cli/{guardrail-explain-2zat1bxh.js → guardrail-explain-fvjc90wa.js} +5 -5
- package/dist/cli/{guardrail-log-zhshjbpk.js → guardrail-log-fsc85hwa.js} +3 -3
- package/dist/cli/{index-t1vfvtg9.js → index-2560cctg.js} +34 -1
- package/dist/cli/{index-fk8ta8zw.js → index-7dtekwvd.js} +2 -2
- package/dist/cli/{index-5tywmqeh.js → index-esg1554h.js} +1 -1
- package/dist/cli/{index-n3ys2eny.js → index-f4yjypa4.js} +21113 -20999
- package/dist/cli/{index-kcbcy6wq.js → index-fxtrk7y8.js} +1 -1
- package/dist/cli/{index-0derejrq.js → index-w8dzxnx4.js} +1 -1
- package/dist/cli/{index-e7nhwa9k.js → index-z4t3w4xf.js} +6 -6
- package/dist/cli/index.js +4 -4
- package/dist/cli/{schema-yxkdx5g5.js → schema-vw2ffhe9.js} +1 -1
- package/dist/commands/close.d.ts +2 -0
- package/dist/commands/pr-subscribe.d.ts +5 -3
- package/dist/commands/registry.d.ts +4 -4
- package/dist/config/bundled-skills.d.ts +1 -1
- package/dist/config/schema.d.ts +46 -0
- package/dist/hooks/pr-auto-subscribe.d.ts +51 -0
- package/dist/index.js +547 -506
- package/dist/memory/config.d.ts +48 -0
- package/dist/memory/finalize-reward-sweep.d.ts +132 -0
- package/dist/memory/gateway.d.ts +0 -1
- package/dist/memory/index.d.ts +1 -2
- package/dist/memory/injector.d.ts +11 -0
- package/dist/memory/local-jsonl-provider.d.ts +3 -1
- package/dist/memory/maintenance.d.ts +16 -4
- package/dist/memory/provider.d.ts +42 -47
- package/dist/memory/q-learning.d.ts +62 -0
- package/dist/memory/reward-capture.d.ts +119 -0
- package/dist/memory/schema.d.ts +9 -9
- package/dist/memory/scoring.d.ts +60 -5
- package/dist/memory/sqlite-provider.d.ts +5 -53
- package/dist/memory/types.d.ts +25 -5
- package/dist/state.d.ts +9 -2
- package/dist/tools/convene-council.d.ts +0 -2
- package/dist/tools/submit-phase-council-verdicts.d.ts +0 -1
- package/dist/tools/swarm-memory-recall.d.ts +2 -0
- package/dist/tools/write-final-council-evidence.d.ts +2 -2
- package/package.json +2 -1
- package/dist/memory/reward.d.ts +0 -39
package/dist/memory/schema.d.ts
CHANGED
|
@@ -3,19 +3,19 @@ import type { CuratorMemoryDecision, MemoryKind, MemoryPatch, MemoryProposal, Me
|
|
|
3
3
|
export declare const MemoryScopeTypeSchema: z.ZodEnum<{
|
|
4
4
|
agent: "agent";
|
|
5
5
|
project: "project";
|
|
6
|
-
workspace: "workspace";
|
|
7
|
-
run: "run";
|
|
8
6
|
global_user: "global_user";
|
|
7
|
+
workspace: "workspace";
|
|
9
8
|
repository: "repository";
|
|
9
|
+
run: "run";
|
|
10
10
|
}>;
|
|
11
11
|
export declare const MemoryScopeRefSchema: z.ZodObject<{
|
|
12
12
|
type: z.ZodEnum<{
|
|
13
13
|
agent: "agent";
|
|
14
14
|
project: "project";
|
|
15
|
-
workspace: "workspace";
|
|
16
|
-
run: "run";
|
|
17
15
|
global_user: "global_user";
|
|
16
|
+
workspace: "workspace";
|
|
18
17
|
repository: "repository";
|
|
18
|
+
run: "run";
|
|
19
19
|
}>;
|
|
20
20
|
userId: z.ZodOptional<z.ZodString>;
|
|
21
21
|
workspaceId: z.ZodOptional<z.ZodString>;
|
|
@@ -63,10 +63,10 @@ export declare const MemoryRecordSchema: z.ZodObject<{
|
|
|
63
63
|
type: z.ZodEnum<{
|
|
64
64
|
agent: "agent";
|
|
65
65
|
project: "project";
|
|
66
|
-
workspace: "workspace";
|
|
67
|
-
run: "run";
|
|
68
66
|
global_user: "global_user";
|
|
67
|
+
workspace: "workspace";
|
|
69
68
|
repository: "repository";
|
|
69
|
+
run: "run";
|
|
70
70
|
}>;
|
|
71
71
|
userId: z.ZodOptional<z.ZodString>;
|
|
72
72
|
workspaceId: z.ZodOptional<z.ZodString>;
|
|
@@ -142,10 +142,10 @@ export declare const MemoryProposalSchema: z.ZodObject<{
|
|
|
142
142
|
type: z.ZodEnum<{
|
|
143
143
|
agent: "agent";
|
|
144
144
|
project: "project";
|
|
145
|
-
workspace: "workspace";
|
|
146
|
-
run: "run";
|
|
147
145
|
global_user: "global_user";
|
|
146
|
+
workspace: "workspace";
|
|
148
147
|
repository: "repository";
|
|
148
|
+
run: "run";
|
|
149
149
|
}>;
|
|
150
150
|
userId: z.ZodOptional<z.ZodString>;
|
|
151
151
|
workspaceId: z.ZodOptional<z.ZodString>;
|
|
@@ -218,8 +218,8 @@ export declare const MemoryProposalSchema: z.ZodObject<{
|
|
|
218
218
|
pending: "pending";
|
|
219
219
|
rejected: "rejected";
|
|
220
220
|
approved: "approved";
|
|
221
|
-
applied: "applied";
|
|
222
221
|
superseded: "superseded";
|
|
222
|
+
applied: "applied";
|
|
223
223
|
}>;
|
|
224
224
|
reviewer: z.ZodOptional<z.ZodEnum<{
|
|
225
225
|
user: "user";
|
package/dist/memory/scoring.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { QLearningConfig } from './config';
|
|
1
2
|
import type { MemoryRecord, MemoryScopeRef, RecallRequest, RecallResultItem } from './types';
|
|
2
3
|
export interface RecallScoringDiagnostics {
|
|
3
4
|
candidateCount: number;
|
|
@@ -6,6 +7,14 @@ export interface RecallScoringDiagnostics {
|
|
|
6
7
|
returnedCount: number;
|
|
7
8
|
noSignalCount: number;
|
|
8
9
|
belowThresholdCount: number;
|
|
10
|
+
/** Count of records skipped via the A.6 low-q suppression filter (FR-006/SC-007). */
|
|
11
|
+
suppressedLowQCount: number;
|
|
12
|
+
/**
|
|
13
|
+
* 0 or 1 — whether the C.1 active-exploration layer resurfaced a
|
|
14
|
+
* suppressed candidate this recall (FR-014/SC-016). At most one per
|
|
15
|
+
* recall by design; see `scoreMemoryRecordsWithDiagnostics`.
|
|
16
|
+
*/
|
|
17
|
+
exploredCount: number;
|
|
9
18
|
fusionActive?: boolean;
|
|
10
19
|
}
|
|
11
20
|
/**
|
|
@@ -14,6 +23,14 @@ export interface RecallScoringDiagnostics {
|
|
|
14
23
|
* are calibrated against these weights.
|
|
15
24
|
*
|
|
16
25
|
* Pinned by tests/unit/memory/scoring.test.ts to detect drift.
|
|
26
|
+
*
|
|
27
|
+
* A.5 note: the learned-utility (q-value) term is intentionally NOT part of
|
|
28
|
+
* this static table. Its weight is `qLearning.qValueBoostWeight` (config,
|
|
29
|
+
* default 0.10) so it stays user-tunable, and its contribution is CENTERED
|
|
30
|
+
* on the neutral q-value (see `NEUTRAL_Q_VALUE`) rather than a flat add — a
|
|
31
|
+
* neutral-q record contributes 0, so the max score impact is
|
|
32
|
+
* `±0.10 * 0.5 = ±0.05`, not a flat `+0.10`. It only affects ranking order,
|
|
33
|
+
* never the `minScore` inclusion cutoff (FR-005 / SC-006).
|
|
17
34
|
*/
|
|
18
35
|
export declare const SCORING_WEIGHTS: {
|
|
19
36
|
readonly textOverlap: 0.38;
|
|
@@ -26,7 +43,6 @@ export declare const SCORING_WEIGHTS: {
|
|
|
26
43
|
readonly roleBoost: 0.05;
|
|
27
44
|
readonly confidence: 0.08;
|
|
28
45
|
};
|
|
29
|
-
export declare const DEFAULT_MEMORY_Q_VALUE = 0.5;
|
|
30
46
|
export declare function tokenize(text: string): Set<string>;
|
|
31
47
|
/**
|
|
32
48
|
* True Jaccard similarity |A∩B| / |A∪B| over two token sets. Distinct from the
|
|
@@ -74,10 +90,49 @@ export declare function importanceScore(input: {
|
|
|
74
90
|
}, weights: ImportanceWeights): number;
|
|
75
91
|
export declare function sameScope(a: MemoryScopeRef, b: MemoryScopeRef): boolean;
|
|
76
92
|
export declare function scopeAllowed(recordScope: MemoryScopeRef, allowedScopes: MemoryScopeRef[]): boolean;
|
|
77
|
-
export declare function scoreMemoryRecord(record: MemoryRecord, request: RecallRequest): RecallResultItem | null;
|
|
78
|
-
export declare function
|
|
79
|
-
export
|
|
80
|
-
|
|
93
|
+
export declare function scoreMemoryRecord(record: MemoryRecord, request: RecallRequest, qLearningConfig?: QLearningConfig): RecallResultItem | null;
|
|
94
|
+
export declare function scoreMemoryRecords(records: MemoryRecord[], request: RecallRequest, qLearningConfig?: QLearningConfig): RecallResultItem[];
|
|
95
|
+
export interface ScoreMemoryRecordsOptions {
|
|
96
|
+
/**
|
|
97
|
+
* RNG seam for the C.1 active-exploration draw (FR-014/SC-016). Defaults
|
|
98
|
+
* to `Math.random`. Tests inject a deterministic function — `() => 0`
|
|
99
|
+
* forces exploration (for any `explorationRate > 0`), `() => 0.99` forces
|
|
100
|
+
* none (for the default `explorationRate` of 0.05) — so exploration is
|
|
101
|
+
* unit-testable without depending on real randomness.
|
|
102
|
+
*/
|
|
103
|
+
random?: () => number;
|
|
104
|
+
}
|
|
105
|
+
export declare function scoreMemoryRecordsWithDiagnostics(records: MemoryRecord[], request: RecallRequest, qLearningConfig?: QLearningConfig, options?: ScoreMemoryRecordsOptions): {
|
|
81
106
|
items: RecallResultItem[];
|
|
82
107
|
diagnostics: RecallScoringDiagnostics;
|
|
83
108
|
};
|
|
109
|
+
/**
|
|
110
|
+
* Applies the recall `maxItems` cap ADDITIVELY with respect to the C.1
|
|
111
|
+
* active-exploration item (FR-014/SC-016 reviewer fix). Normal (non-explored)
|
|
112
|
+
* items are capped at `maxItems` in their existing order; the single
|
|
113
|
+
* `explored: true` item (if present in `items`) is then appended AFTER the
|
|
114
|
+
* cap, beyond `maxItems`.
|
|
115
|
+
*
|
|
116
|
+
* This guarantees bounded exploration can never evict a legitimate ranked
|
|
117
|
+
* hit: a recall can return at most `maxItems` normal hits plus (at most) one
|
|
118
|
+
* explored item — never fewer normal hits because an explored candidate
|
|
119
|
+
* displaced one within the cap. Every provider recall-slicing site
|
|
120
|
+
* (`sqlite-provider.ts`, `local-jsonl-provider.ts`) must use this helper
|
|
121
|
+
* instead of a plain `.slice(0, maxItems)` so exploration stays additive
|
|
122
|
+
* everywhere `maxItems` is enforced.
|
|
123
|
+
*
|
|
124
|
+
* SCOPE OF THE GUARANTEE (reviewer note, known limitation G-3): additivity is
|
|
125
|
+
* strict at THIS slice. On the opt-in embeddings/RRF fusion path the explored
|
|
126
|
+
* item participates in `fuseRankings` as an ordinary lexical candidate BEFORE
|
|
127
|
+
* this slice (`sqlite-provider.ts`), and because exploration deliberately picks
|
|
128
|
+
* the highest-baseScore suppressed record, it can out-rank a normal hit by one
|
|
129
|
+
* lexical position; after `minMaxNormalise` a normal item sitting exactly on
|
|
130
|
+
* the fusion `minScore` boundary can then fall below the Stage-5 re-gate
|
|
131
|
+
* BECAUSE the explored item was present. That is a marginal RRF reshuffle
|
|
132
|
+
* upstream of the slice, not an eviction at the slice. Making additivity strict
|
|
133
|
+
* through fusion too would require excluding `explored` items from
|
|
134
|
+
* `fuseRankings` and re-injecting them only here — deferred with G-1/G-2 to the
|
|
135
|
+
* injection-path/fusion enhancement (fixing it alone is moot while G-2 gates
|
|
136
|
+
* the dominant injection path).
|
|
137
|
+
*/
|
|
138
|
+
export declare function sliceRecallItemsWithExploration(items: RecallResultItem[], maxItems: number): RecallResultItem[];
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type MemoryConfig } from './config';
|
|
2
|
-
import type { EmbeddingProvider } from './embeddings/types';
|
|
3
2
|
import { type JsonlMigrationReport } from './jsonl-migration';
|
|
4
|
-
import type { MemoryCompactOptions, MemoryCompactResult, MemoryProposalStore, MemoryProvider,
|
|
3
|
+
import type { MemoryCompactOptions, MemoryCompactResult, MemoryProposalStore, MemoryProvider, MemoryRecallUsageEvent, MemoryRecallUsageFilter, MemoryRewardEvent, MemoryRewardEventFilter, MemoryTransaction } from './provider';
|
|
5
4
|
import type { RecallScoringDiagnostics } from './scoring';
|
|
6
5
|
import type { AppliedMemoryChange, MemoryListFilter, MemoryProposal, MemoryRecord, RecallRequest, RecallResultItem, ResolvedCuratorMemoryDecision } from './types';
|
|
7
6
|
interface Migration {
|
|
@@ -33,27 +32,13 @@ export declare class SQLiteMemoryProvider implements MemoryProvider, MemoryPropo
|
|
|
33
32
|
private lastAutomaticJsonlMigration;
|
|
34
33
|
private recallCountSinceLastCompaction;
|
|
35
34
|
private isCompacting;
|
|
36
|
-
/**
|
|
37
|
-
* _internals DI seam for testing. Exposes key methods so tests can inject
|
|
38
|
-
* failures without touching the module-level mock surface.
|
|
39
|
-
*/
|
|
40
|
-
readonly _internals: {
|
|
41
|
-
writeMemory: (record: MemoryRecord) => void;
|
|
42
|
-
/**
|
|
43
|
-
* Test-only seam: inject a fake embedding provider so propagation's
|
|
44
|
-
* cosine-similarity path can be exercised without the real
|
|
45
|
-
* `@xenova/transformers` model dependency. Must be called AFTER
|
|
46
|
-
* `initialize()` (which may otherwise construct/overwrite the real
|
|
47
|
-
* provider when `embeddings.enabled` is true).
|
|
48
|
-
*/
|
|
49
|
-
setEmbeddingProvider: (provider: EmbeddingProvider | null) => void;
|
|
50
|
-
};
|
|
51
35
|
constructor(rootDirectory: string, config?: Partial<MemoryConfig>);
|
|
52
36
|
private databasePath;
|
|
53
37
|
initialize(): Promise<void>;
|
|
54
38
|
private doInitialize;
|
|
55
39
|
upsert(record: MemoryRecord): Promise<MemoryRecord>;
|
|
56
40
|
get(id: string): Promise<MemoryRecord | null>;
|
|
41
|
+
withTransaction<T>(fn: (tx: MemoryTransaction) => Promise<T> | T): Promise<T>;
|
|
57
42
|
delete(id: string, reason?: string): Promise<void>;
|
|
58
43
|
recall(request: RecallRequest): Promise<RecallResultItem[]>;
|
|
59
44
|
recallWithDiagnostics(request: RecallRequest): Promise<{
|
|
@@ -62,8 +47,8 @@ export declare class SQLiteMemoryProvider implements MemoryProvider, MemoryPropo
|
|
|
62
47
|
}>;
|
|
63
48
|
recordRecallUsage(event: MemoryRecallUsageEvent): Promise<void>;
|
|
64
49
|
listRecallUsage(filter?: MemoryRecallUsageFilter): Promise<MemoryRecallUsageEvent[]>;
|
|
65
|
-
|
|
66
|
-
|
|
50
|
+
appendRewardEvent(event: Omit<MemoryRewardEvent, 'id'>): Promise<void>;
|
|
51
|
+
listRewardEvents(filter?: MemoryRewardEventFilter): Promise<MemoryRewardEvent[]>;
|
|
67
52
|
list(filter?: MemoryListFilter): Promise<MemoryRecord[]>;
|
|
68
53
|
createProposal(proposal: MemoryProposal): Promise<MemoryProposal>;
|
|
69
54
|
listProposals(filter?: {
|
|
@@ -91,40 +76,6 @@ export declare class SQLiteMemoryProvider implements MemoryProvider, MemoryPropo
|
|
|
91
76
|
proposals: number;
|
|
92
77
|
}>;
|
|
93
78
|
compactMaintenance(options?: MemoryCompactOptions): Promise<MemoryCompactResult>;
|
|
94
|
-
/**
|
|
95
|
-
* Find, across the given candidate session/run ids, the most recent
|
|
96
|
-
* recall-usage bundle for EACH distinct matching id (exact match only —
|
|
97
|
-
* no unscoped time-window fallback, which would risk rewarding an
|
|
98
|
-
* unrelated task/session's recall bundle). Every distinct matched runId
|
|
99
|
-
* contributes its own latest bundle, so a council review informed by
|
|
100
|
-
* several sessions (e.g. dispatched council-member sub-agents) rewards
|
|
101
|
-
* all of their recalls, not just one.
|
|
102
|
-
*/
|
|
103
|
-
private matchingRecallUsageRows;
|
|
104
|
-
private updateMemoryQValue;
|
|
105
|
-
/**
|
|
106
|
-
* Select soft-propagation targets among recently-recalled, same-scope
|
|
107
|
-
* memories via two independent qualifying paths (issue #1467 O-004):
|
|
108
|
-
* lexical token-overlap (Jaccard, gated additionally on same `kind`), OR
|
|
109
|
-
* embedding cosine similarity when `embeddings.enabled` and a provider is
|
|
110
|
-
* available (not gated on `kind` — semantic similarity can legitimately
|
|
111
|
-
* cross kinds). A candidate qualifies if EITHER path clears its
|
|
112
|
-
* threshold; the higher of the two scores is used for fanout-cap
|
|
113
|
-
* ranking. When embeddings are disabled (the default), this reduces to
|
|
114
|
-
* the original token-overlap-only behavior with no extra cost.
|
|
115
|
-
*/
|
|
116
|
-
private findPropagationTargets;
|
|
117
|
-
/**
|
|
118
|
-
* Embed `text` (cache-first, same pattern as the recall-time query
|
|
119
|
-
* embedding lookup) for use in propagation's cosine-similarity path.
|
|
120
|
-
* Returns null on any embedding failure or when no provider is
|
|
121
|
-
* configured — callers must treat that as "no cosine signal available"
|
|
122
|
-
* and fall back to the token-overlap path rather than throwing, since
|
|
123
|
-
* this is a best-effort enhancement to an already-approximate feature.
|
|
124
|
-
*/
|
|
125
|
-
private getCachedEmbeddingForPropagation;
|
|
126
|
-
private recentlyRecalledMemoryIds;
|
|
127
|
-
private listRecallUsageSync;
|
|
128
79
|
hasMigration(name: string): boolean;
|
|
129
80
|
markMigration(version: number, name: string): void;
|
|
130
81
|
private selectRecallCandidates;
|
|
@@ -132,6 +83,7 @@ export declare class SQLiteMemoryProvider implements MemoryProvider, MemoryPropo
|
|
|
132
83
|
private selectDenseCandidates;
|
|
133
84
|
private runMigrations;
|
|
134
85
|
private backfillScopeKeys;
|
|
86
|
+
private backfillRecallRunIds;
|
|
135
87
|
private initializeFtsIndex;
|
|
136
88
|
private initializeVecExtension;
|
|
137
89
|
private recreateFtsIndex;
|
package/dist/memory/types.d.ts
CHANGED
|
@@ -31,7 +31,6 @@ export interface MemoryRecord {
|
|
|
31
31
|
updatedAt: string;
|
|
32
32
|
lastAccessedAt?: string;
|
|
33
33
|
expiresAt?: string;
|
|
34
|
-
qValue?: number;
|
|
35
34
|
supersedes?: string[];
|
|
36
35
|
supersededBy?: string;
|
|
37
36
|
contentHash: string;
|
|
@@ -143,12 +142,15 @@ export interface RecallRequest {
|
|
|
143
142
|
maxItems: number;
|
|
144
143
|
tokenBudget: number;
|
|
145
144
|
minScore?: number;
|
|
146
|
-
qValueBoostWeight?: number;
|
|
147
|
-
suppressionThreshold?: number;
|
|
148
|
-
includeLowQ?: boolean;
|
|
149
145
|
requireQuerySignal?: boolean;
|
|
150
146
|
includeExpired?: boolean;
|
|
151
147
|
includePendingProposals?: boolean;
|
|
148
|
+
/**
|
|
149
|
+
* Opt in to include memories suppressed for low learned utility (q-value
|
|
150
|
+
* below `qLearning.suppressionThreshold`). Default recall omits them;
|
|
151
|
+
* suppression never deletes or tombstones the underlying record.
|
|
152
|
+
*/
|
|
153
|
+
includeLowQ?: boolean;
|
|
152
154
|
}
|
|
153
155
|
export interface RecallResultItem {
|
|
154
156
|
record: MemoryRecord;
|
|
@@ -159,10 +161,17 @@ export interface RecallResultItem {
|
|
|
159
161
|
tagOverlap: number;
|
|
160
162
|
fileOverlap?: number;
|
|
161
163
|
symbolOverlap?: number;
|
|
162
|
-
qValue?: number;
|
|
163
164
|
kindMatch: boolean;
|
|
164
165
|
scopeMatch: boolean;
|
|
165
166
|
};
|
|
167
|
+
/**
|
|
168
|
+
* C.1 (FR-014/SC-016): true when this item was an otherwise-suppressed
|
|
169
|
+
* low-q memory (qValue < `qLearning.suppressionThreshold`) resurfaced by
|
|
170
|
+
* the bounded active-exploration layer in
|
|
171
|
+
* `scoreMemoryRecordsWithDiagnostics`, rather than a normal recall hit.
|
|
172
|
+
* Absent/undefined for every normal (non-explored) item.
|
|
173
|
+
*/
|
|
174
|
+
explored?: boolean;
|
|
166
175
|
}
|
|
167
176
|
export interface RecallBundle {
|
|
168
177
|
id: string;
|
|
@@ -185,6 +194,17 @@ export interface MemoryContext {
|
|
|
185
194
|
agentRole?: string;
|
|
186
195
|
agentId?: string;
|
|
187
196
|
runId?: string;
|
|
197
|
+
/**
|
|
198
|
+
* Task/phase unit-of-work identity (e.g. plan task id "1.1"). ADDITIVE join
|
|
199
|
+
* key recorded alongside `runId` on recall-usage rows so reward attribution
|
|
200
|
+
* (B.2) and the finalize sweep (B.6) can join memories to the unit of work
|
|
201
|
+
* they were recalled for — independent of session id. NULL/undefined when a
|
|
202
|
+
* trustworthy id cannot be resolved at recording time; the system then
|
|
203
|
+
* degrades to today's session-scoped (`runId`) behavior. Never defaulted to
|
|
204
|
+
* sessionID — that would repopulate the exact session-scoped value this
|
|
205
|
+
* escapes.
|
|
206
|
+
*/
|
|
207
|
+
unitId?: string;
|
|
188
208
|
}
|
|
189
209
|
export interface MemoryListFilter {
|
|
190
210
|
scopes?: MemoryScopeRef[];
|
package/dist/state.d.ts
CHANGED
|
@@ -137,6 +137,13 @@ export interface AgentSessionState {
|
|
|
137
137
|
* quorumSize: 1 — conservative; forces a fresh council run.
|
|
138
138
|
*/
|
|
139
139
|
quorumSize: number;
|
|
140
|
+
/**
|
|
141
|
+
* A.4 dedup guard: set true once the positive council reward
|
|
142
|
+
* (EMA step on session-recalled memories) has fired for this task.
|
|
143
|
+
* Ensures the reward is applied at most once per task even if the
|
|
144
|
+
* APPROVE→complete path is re-entered.
|
|
145
|
+
*/
|
|
146
|
+
rewarded?: boolean;
|
|
140
147
|
}>;
|
|
141
148
|
/**
|
|
142
149
|
* Per-(task,round) required council members for the next submission attempt.
|
|
@@ -334,9 +341,9 @@ export declare const swarmState: {
|
|
|
334
341
|
phase?: string;
|
|
335
342
|
generatedAt: number;
|
|
336
343
|
}>;
|
|
337
|
-
/** v2: dedup set for ack records. Key = `${sessionId}|${id}|${result}`.
|
|
344
|
+
/** v2: dedup set for ack records. Key = `${sessionId}|${id}|${result}|${dayKey}`.
|
|
338
345
|
* Prevents the chat.messages.transform path AND a knowledge_ack tool call
|
|
339
|
-
* from double-counting the same ack within a session. FIFO-capped —
|
|
346
|
+
* from double-counting the same ack within a session-day. FIFO-capped —
|
|
340
347
|
* see addKnowledgeAckDedup. */
|
|
341
348
|
knowledgeAckDedup: Set<string>;
|
|
342
349
|
/**
|
|
@@ -49,9 +49,7 @@ export declare const ArgsSchema: z.ZodObject<{
|
|
|
49
49
|
criteriaAssessed: z.ZodArray<z.ZodString>;
|
|
50
50
|
criteriaUnmet: z.ZodArray<z.ZodString>;
|
|
51
51
|
durationMs: z.ZodNumber;
|
|
52
|
-
sessionId: z.ZodOptional<z.ZodString>;
|
|
53
52
|
}, z.core.$strip>>;
|
|
54
53
|
working_directory: z.ZodOptional<z.ZodString>;
|
|
55
|
-
provenanceSessionId: z.ZodOptional<z.ZodString>;
|
|
56
54
|
}, z.core.$strip>;
|
|
57
55
|
export declare const submit_council_verdicts: ReturnType<typeof tool>;
|
|
@@ -35,7 +35,6 @@ export declare const ArgsSchema: z.ZodObject<{
|
|
|
35
35
|
criteriaAssessed: z.ZodArray<z.ZodString>;
|
|
36
36
|
criteriaUnmet: z.ZodArray<z.ZodString>;
|
|
37
37
|
durationMs: z.ZodNumber;
|
|
38
|
-
sessionId: z.ZodOptional<z.ZodString>;
|
|
39
38
|
}, z.core.$strip>>;
|
|
40
39
|
working_directory: z.ZodOptional<z.ZodString>;
|
|
41
40
|
provenanceAgentName: z.ZodOptional<z.ZodString>;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { loadPluginConfigWithMeta } from '../config';
|
|
2
2
|
import { createMemoryGateway } from '../memory';
|
|
3
|
+
import { getAgentSession } from '../state';
|
|
3
4
|
import { createSwarmTool } from './create-tool';
|
|
4
5
|
export declare const swarm_memory_recall: ReturnType<typeof createSwarmTool>;
|
|
5
6
|
export declare const _internals: {
|
|
6
7
|
loadPluginConfigWithMeta: typeof loadPluginConfigWithMeta;
|
|
7
8
|
createMemoryGateway: typeof createMemoryGateway;
|
|
9
|
+
getAgentSession: typeof getAgentSession;
|
|
8
10
|
};
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* five-member CouncilMemberVerdict objects used by phase council, synthesized
|
|
6
6
|
* at completed-project scope.
|
|
7
7
|
*/
|
|
8
|
-
import type { ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
8
|
+
import type { ToolContext, ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
9
9
|
import { z } from 'zod';
|
|
10
10
|
import type { CouncilMemberVerdict } from '../council/types';
|
|
11
11
|
export declare const ArgsSchema: z.ZodObject<{
|
|
@@ -60,7 +60,7 @@ export interface WriteFinalCouncilEvidenceArgs {
|
|
|
60
60
|
* Execute the write_final_council_evidence tool.
|
|
61
61
|
* Validates input, synthesizes project-scoped council evidence, and writes it.
|
|
62
62
|
*/
|
|
63
|
-
export declare function executeWriteFinalCouncilEvidence(args: unknown, directory: string): Promise<string>;
|
|
63
|
+
export declare function executeWriteFinalCouncilEvidence(args: unknown, directory: string, ctx?: ToolContext): Promise<string>;
|
|
64
64
|
/**
|
|
65
65
|
* Tool definition for write_final_council_evidence.
|
|
66
66
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.106.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",
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
".opencode/skills/design-docs",
|
|
56
56
|
".opencode/skills/swarm-pr-review",
|
|
57
57
|
".opencode/skills/swarm-pr-feedback",
|
|
58
|
+
".opencode/skills/swarm-pr-subscribe",
|
|
58
59
|
".opencode/skills/issue-ingest",
|
|
59
60
|
".opencode/skills/plan",
|
|
60
61
|
".opencode/skills/critic-gate",
|
package/dist/memory/reward.d.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { CouncilVerdict } from '../council/types';
|
|
2
|
-
import { type MemoryConfig } from './config';
|
|
3
|
-
import type { MemoryRecallRewardInput, MemoryRecallRewardResult, MemoryTaskOutcome } from './provider';
|
|
4
|
-
export declare function councilVerdictToMemoryOutcome(verdict: CouncilVerdict): MemoryTaskOutcome;
|
|
5
|
-
/**
|
|
6
|
-
* Resolve the set of session/run ids whose recall-usage bundles should
|
|
7
|
-
* receive a council-verdict reward, deduplicated and order-preserving.
|
|
8
|
-
*
|
|
9
|
-
* `trustedSessionIds` are host/runtime-derived (e.g. `ctx.sessionID`) and are
|
|
10
|
-
* always included when present — they cannot be spoofed by tool-call
|
|
11
|
-
* arguments. `untrustedSessionIds` are caller-supplied strings (e.g. a
|
|
12
|
-
* `provenanceSessionId` arg or a per-verdict `sessionId` reported by the
|
|
13
|
-
* architect) and are included ONLY when `isKnownSession` returns true — an
|
|
14
|
-
* arbitrary, made-up string is silently dropped rather than trusted as a
|
|
15
|
-
* reward-targeting key.
|
|
16
|
-
*
|
|
17
|
-
* Important scope limitation: `isKnownSession` (backed by `getAgentSession`)
|
|
18
|
-
* proves only that the id belongs to SOME currently-tracked session
|
|
19
|
-
* process-wide — it does NOT prove that session actually participated in
|
|
20
|
-
* THIS council review. There is no swarmId/taskId cross-check available on
|
|
21
|
-
* `AgentSessionState` today, so a hallucinated or copied session id that
|
|
22
|
-
* happens to match a real, unrelated, concurrently-running session's id
|
|
23
|
-
* would still be accepted here. The blast radius is bounded to Q-value
|
|
24
|
-
* corruption of that other session's recalled memories (not privilege
|
|
25
|
-
* escalation or data exfiltration), but this is a real residual gap, not a
|
|
26
|
-
* complete fix — closing it fully requires a session→task ownership
|
|
27
|
-
* registry that does not exist in this codebase yet.
|
|
28
|
-
*
|
|
29
|
-
* A bare swarm identifier is never a valid session id substitute and must
|
|
30
|
-
* never be passed into either list.
|
|
31
|
-
*/
|
|
32
|
-
export declare function resolveRewardRunIds(input: {
|
|
33
|
-
trustedSessionIds: Array<string | undefined>;
|
|
34
|
-
untrustedSessionIds: Array<string | undefined>;
|
|
35
|
-
isKnownSession: (sessionId: string) => boolean;
|
|
36
|
-
}): string[];
|
|
37
|
-
export declare function applyRecallRewardForCouncil(directory: string, configInput: Partial<MemoryConfig> | undefined, input: Omit<MemoryRecallRewardInput, 'outcome'> & {
|
|
38
|
-
verdict: CouncilVerdict;
|
|
39
|
-
}): Promise<MemoryRecallRewardResult>;
|