opencode-swarm 7.32.2 → 7.32.3
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/cli/index.js +27 -3
- package/dist/config/schema.d.ts +14 -0
- package/dist/index.js +218 -29
- package/dist/memory/config.d.ts +7 -0
- package/dist/memory/gateway.d.ts +3 -1
- package/dist/memory/index.d.ts +1 -1
- package/dist/memory/injector.d.ts +1 -1
- package/dist/memory/local-jsonl-provider.d.ts +5 -0
- package/dist/memory/prompt-block.d.ts +1 -0
- package/dist/memory/provider.d.ts +6 -0
- package/dist/memory/run-log.d.ts +1 -1
- package/dist/memory/scoring.d.ts +12 -0
- package/dist/memory/types.d.ts +19 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -34,7 +34,7 @@ var package_default;
|
|
|
34
34
|
var init_package = __esm(() => {
|
|
35
35
|
package_default = {
|
|
36
36
|
name: "opencode-swarm",
|
|
37
|
-
version: "7.32.
|
|
37
|
+
version: "7.32.3",
|
|
38
38
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
39
39
|
main: "dist/index.js",
|
|
40
40
|
types: "dist/index.d.ts",
|
|
@@ -17331,8 +17331,32 @@ var init_schema = __esm(() => {
|
|
|
17331
17331
|
recall: exports_external.object({
|
|
17332
17332
|
defaultMaxItems: exports_external.number().int().min(1).max(20).default(8),
|
|
17333
17333
|
defaultTokenBudget: exports_external.number().int().min(100).max(5000).default(1200),
|
|
17334
|
-
minScore: exports_external.number().min(0).max(1).default(0.05)
|
|
17335
|
-
|
|
17334
|
+
minScore: exports_external.number().min(0).max(1).default(0.05),
|
|
17335
|
+
injection: exports_external.object({
|
|
17336
|
+
enabled: exports_external.boolean().default(true),
|
|
17337
|
+
minScore: exports_external.number().min(0).max(1).default(0.25),
|
|
17338
|
+
requireQuerySignal: exports_external.boolean().default(true),
|
|
17339
|
+
maxItems: exports_external.number().int().min(1).max(20).default(6),
|
|
17340
|
+
tokenBudget: exports_external.number().int().min(100).max(5000).default(1000)
|
|
17341
|
+
}).default({
|
|
17342
|
+
enabled: true,
|
|
17343
|
+
minScore: 0.25,
|
|
17344
|
+
requireQuerySignal: true,
|
|
17345
|
+
maxItems: 6,
|
|
17346
|
+
tokenBudget: 1000
|
|
17347
|
+
})
|
|
17348
|
+
}).default({
|
|
17349
|
+
defaultMaxItems: 8,
|
|
17350
|
+
defaultTokenBudget: 1200,
|
|
17351
|
+
minScore: 0.05,
|
|
17352
|
+
injection: {
|
|
17353
|
+
enabled: true,
|
|
17354
|
+
minScore: 0.25,
|
|
17355
|
+
requireQuerySignal: true,
|
|
17356
|
+
maxItems: 6,
|
|
17357
|
+
tokenBudget: 1000
|
|
17358
|
+
}
|
|
17359
|
+
}),
|
|
17336
17360
|
writes: exports_external.object({
|
|
17337
17361
|
mode: exports_external.literal("propose").default("propose")
|
|
17338
17362
|
}).default({ mode: "propose" }),
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -510,6 +510,13 @@ export declare const MemoryConfigSchema: z.ZodObject<{
|
|
|
510
510
|
defaultMaxItems: z.ZodDefault<z.ZodNumber>;
|
|
511
511
|
defaultTokenBudget: z.ZodDefault<z.ZodNumber>;
|
|
512
512
|
minScore: z.ZodDefault<z.ZodNumber>;
|
|
513
|
+
injection: z.ZodDefault<z.ZodObject<{
|
|
514
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
515
|
+
minScore: z.ZodDefault<z.ZodNumber>;
|
|
516
|
+
requireQuerySignal: z.ZodDefault<z.ZodBoolean>;
|
|
517
|
+
maxItems: z.ZodDefault<z.ZodNumber>;
|
|
518
|
+
tokenBudget: z.ZodDefault<z.ZodNumber>;
|
|
519
|
+
}, z.core.$strip>>;
|
|
513
520
|
}, z.core.$strip>>;
|
|
514
521
|
writes: z.ZodDefault<z.ZodObject<{
|
|
515
522
|
mode: z.ZodDefault<z.ZodLiteral<"propose">>;
|
|
@@ -1161,6 +1168,13 @@ export declare const PluginConfigSchema: z.ZodObject<{
|
|
|
1161
1168
|
defaultMaxItems: z.ZodDefault<z.ZodNumber>;
|
|
1162
1169
|
defaultTokenBudget: z.ZodDefault<z.ZodNumber>;
|
|
1163
1170
|
minScore: z.ZodDefault<z.ZodNumber>;
|
|
1171
|
+
injection: z.ZodDefault<z.ZodObject<{
|
|
1172
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
1173
|
+
minScore: z.ZodDefault<z.ZodNumber>;
|
|
1174
|
+
requireQuerySignal: z.ZodDefault<z.ZodBoolean>;
|
|
1175
|
+
maxItems: z.ZodDefault<z.ZodNumber>;
|
|
1176
|
+
tokenBudget: z.ZodDefault<z.ZodNumber>;
|
|
1177
|
+
}, z.core.$strip>>;
|
|
1164
1178
|
}, z.core.$strip>>;
|
|
1165
1179
|
writes: z.ZodDefault<z.ZodObject<{
|
|
1166
1180
|
mode: z.ZodDefault<z.ZodLiteral<"propose">>;
|
package/dist/index.js
CHANGED
|
@@ -48,7 +48,7 @@ var package_default;
|
|
|
48
48
|
var init_package = __esm(() => {
|
|
49
49
|
package_default = {
|
|
50
50
|
name: "opencode-swarm",
|
|
51
|
-
version: "7.32.
|
|
51
|
+
version: "7.32.3",
|
|
52
52
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
53
53
|
main: "dist/index.js",
|
|
54
54
|
types: "dist/index.d.ts",
|
|
@@ -15544,8 +15544,32 @@ var init_schema = __esm(() => {
|
|
|
15544
15544
|
recall: exports_external.object({
|
|
15545
15545
|
defaultMaxItems: exports_external.number().int().min(1).max(20).default(8),
|
|
15546
15546
|
defaultTokenBudget: exports_external.number().int().min(100).max(5000).default(1200),
|
|
15547
|
-
minScore: exports_external.number().min(0).max(1).default(0.05)
|
|
15548
|
-
|
|
15547
|
+
minScore: exports_external.number().min(0).max(1).default(0.05),
|
|
15548
|
+
injection: exports_external.object({
|
|
15549
|
+
enabled: exports_external.boolean().default(true),
|
|
15550
|
+
minScore: exports_external.number().min(0).max(1).default(0.25),
|
|
15551
|
+
requireQuerySignal: exports_external.boolean().default(true),
|
|
15552
|
+
maxItems: exports_external.number().int().min(1).max(20).default(6),
|
|
15553
|
+
tokenBudget: exports_external.number().int().min(100).max(5000).default(1000)
|
|
15554
|
+
}).default({
|
|
15555
|
+
enabled: true,
|
|
15556
|
+
minScore: 0.25,
|
|
15557
|
+
requireQuerySignal: true,
|
|
15558
|
+
maxItems: 6,
|
|
15559
|
+
tokenBudget: 1000
|
|
15560
|
+
})
|
|
15561
|
+
}).default({
|
|
15562
|
+
defaultMaxItems: 8,
|
|
15563
|
+
defaultTokenBudget: 1200,
|
|
15564
|
+
minScore: 0.05,
|
|
15565
|
+
injection: {
|
|
15566
|
+
enabled: true,
|
|
15567
|
+
minScore: 0.25,
|
|
15568
|
+
requireQuerySignal: true,
|
|
15569
|
+
maxItems: 6,
|
|
15570
|
+
tokenBudget: 1000
|
|
15571
|
+
}
|
|
15572
|
+
}),
|
|
15549
15573
|
writes: exports_external.object({
|
|
15550
15574
|
mode: exports_external.literal("propose").default("propose")
|
|
15551
15575
|
}).default({ mode: "propose" }),
|
|
@@ -97574,7 +97598,14 @@ var DEFAULT_MEMORY_CONFIG = {
|
|
|
97574
97598
|
recall: {
|
|
97575
97599
|
defaultMaxItems: 8,
|
|
97576
97600
|
defaultTokenBudget: 1200,
|
|
97577
|
-
minScore: 0.05
|
|
97601
|
+
minScore: 0.05,
|
|
97602
|
+
injection: {
|
|
97603
|
+
enabled: true,
|
|
97604
|
+
minScore: 0.25,
|
|
97605
|
+
requireQuerySignal: true,
|
|
97606
|
+
maxItems: 6,
|
|
97607
|
+
tokenBudget: 1000
|
|
97608
|
+
}
|
|
97578
97609
|
},
|
|
97579
97610
|
writes: {
|
|
97580
97611
|
mode: "propose"
|
|
@@ -97605,7 +97636,11 @@ function resolveMemoryConfig(input) {
|
|
|
97605
97636
|
...input ?? {},
|
|
97606
97637
|
recall: {
|
|
97607
97638
|
...DEFAULT_MEMORY_CONFIG.recall,
|
|
97608
|
-
...input?.recall ?? {}
|
|
97639
|
+
...input?.recall ?? {},
|
|
97640
|
+
injection: {
|
|
97641
|
+
...DEFAULT_MEMORY_CONFIG.recall.injection,
|
|
97642
|
+
...input?.recall?.injection ?? {}
|
|
97643
|
+
}
|
|
97609
97644
|
},
|
|
97610
97645
|
writes: {
|
|
97611
97646
|
...DEFAULT_MEMORY_CONFIG.writes,
|
|
@@ -97887,6 +97922,24 @@ function validateMemoryProposal(proposal) {
|
|
|
97887
97922
|
function tokenize(text) {
|
|
97888
97923
|
return new Set(text.toLowerCase().replace(/[^\w\s-]/g, " ").split(/\s+/).map((token) => token.trim()).filter(Boolean));
|
|
97889
97924
|
}
|
|
97925
|
+
function normalizeKindText(kind) {
|
|
97926
|
+
return kind.replace(/_/g, " ");
|
|
97927
|
+
}
|
|
97928
|
+
function collectMetadataStrings(metadata2, keys) {
|
|
97929
|
+
const values = [];
|
|
97930
|
+
for (const key of keys) {
|
|
97931
|
+
const value = metadata2[key];
|
|
97932
|
+
if (typeof value === "string")
|
|
97933
|
+
values.push(value);
|
|
97934
|
+
if (Array.isArray(value)) {
|
|
97935
|
+
for (const item of value) {
|
|
97936
|
+
if (typeof item === "string")
|
|
97937
|
+
values.push(item);
|
|
97938
|
+
}
|
|
97939
|
+
}
|
|
97940
|
+
}
|
|
97941
|
+
return values;
|
|
97942
|
+
}
|
|
97890
97943
|
function overlap(a, b) {
|
|
97891
97944
|
if (a.size === 0 || b.size === 0)
|
|
97892
97945
|
return 0;
|
|
@@ -97924,37 +97977,101 @@ function sameScope(a, b) {
|
|
|
97924
97977
|
function scopeAllowed(recordScope, allowedScopes) {
|
|
97925
97978
|
return allowedScopes.some((scope) => sameScope(recordScope, scope));
|
|
97926
97979
|
}
|
|
97927
|
-
function
|
|
97928
|
-
if (!request.includeExpired && isExpired2(record3))
|
|
97929
|
-
return null;
|
|
97980
|
+
function scoreMemoryRecordDetailed(record3, request) {
|
|
97981
|
+
if (!request.includeExpired && isExpired2(record3)) {
|
|
97982
|
+
return { item: null, skipReason: "filtered" };
|
|
97983
|
+
}
|
|
97930
97984
|
if (record3.supersededBy)
|
|
97931
|
-
return null;
|
|
97932
|
-
if (record3.metadata.deleted === true)
|
|
97933
|
-
return null;
|
|
97934
|
-
|
|
97935
|
-
|
|
97936
|
-
|
|
97937
|
-
|
|
97938
|
-
|
|
97985
|
+
return { item: null, skipReason: "filtered" };
|
|
97986
|
+
if (record3.metadata.deleted === true) {
|
|
97987
|
+
return { item: null, skipReason: "filtered" };
|
|
97988
|
+
}
|
|
97989
|
+
if (!scopeAllowed(record3.scope, request.scopes)) {
|
|
97990
|
+
return { item: null, skipReason: "filtered" };
|
|
97991
|
+
}
|
|
97992
|
+
if (request.kinds && !request.kinds.includes(record3.kind)) {
|
|
97993
|
+
return { item: null, skipReason: "filtered" };
|
|
97994
|
+
}
|
|
97995
|
+
const queryTokens = request.mode === "injection" && request.task ? tokenize(request.task) : tokenize(request.query);
|
|
97939
97996
|
const textTokens = tokenize(record3.text);
|
|
97940
97997
|
const tagTokens = tokenize(record3.tags.join(" "));
|
|
97998
|
+
const fileTokens = tokenize([
|
|
97999
|
+
record3.source.filePath,
|
|
98000
|
+
...collectMetadataStrings(record3.metadata, [
|
|
98001
|
+
"file",
|
|
98002
|
+
"filePath",
|
|
98003
|
+
"files",
|
|
98004
|
+
"touchedFiles"
|
|
98005
|
+
])
|
|
98006
|
+
].filter((value) => typeof value === "string").join(" "));
|
|
98007
|
+
const symbolTokens = tokenize(collectMetadataStrings(record3.metadata, ["symbol", "symbols"]).join(" "));
|
|
98008
|
+
const kindQueryOverlap = overlap(queryTokens, tokenize(normalizeKindText(record3.kind)));
|
|
97941
98009
|
const textOverlap = overlap(queryTokens, textTokens);
|
|
97942
98010
|
const tagOverlap = overlap(queryTokens, tagTokens);
|
|
97943
|
-
const
|
|
98011
|
+
const fileOverlap = overlap(queryTokens, fileTokens);
|
|
98012
|
+
const symbolOverlap = overlap(queryTokens, symbolTokens);
|
|
98013
|
+
const kindMatch = request.kinds?.includes(record3.kind) ?? false;
|
|
98014
|
+
const scopeMatch = scopeAllowed(record3.scope, request.scopes);
|
|
98015
|
+
const hasQuerySignal = textOverlap > 0 || tagOverlap > 0 || fileOverlap > 0 || symbolOverlap > 0 || kindQueryOverlap > 0;
|
|
98016
|
+
if (request.mode === "injection" && request.requireQuerySignal !== false && !hasQuerySignal) {
|
|
98017
|
+
return { item: null, skipReason: "no_signal" };
|
|
98018
|
+
}
|
|
98019
|
+
const score = textOverlap * 0.45 + tagOverlap * 0.2 + fileOverlap * 0.05 + symbolOverlap * 0.05 + scopeSpecificityBoost(record3.scope) * 0.15 + kindProfileBoost(record3.kind, request) * 0.1 + record3.confidence * 0.1;
|
|
97944
98020
|
const reasonParts = [
|
|
97945
98021
|
textOverlap > 0 ? `text_overlap=${textOverlap.toFixed(2)}` : null,
|
|
97946
98022
|
tagOverlap > 0 ? `tag_overlap=${tagOverlap.toFixed(2)}` : null,
|
|
98023
|
+
fileOverlap > 0 ? `file_overlap=${fileOverlap.toFixed(2)}` : null,
|
|
98024
|
+
symbolOverlap > 0 ? `symbol_overlap=${symbolOverlap.toFixed(2)}` : null,
|
|
98025
|
+
kindQueryOverlap > 0 ? `kind_query=${kindQueryOverlap.toFixed(2)}` : null,
|
|
97947
98026
|
`scope=${record3.scope.type}`,
|
|
97948
98027
|
`confidence=${record3.confidence.toFixed(2)}`
|
|
97949
98028
|
].filter(Boolean);
|
|
97950
98029
|
return {
|
|
97951
|
-
|
|
97952
|
-
|
|
97953
|
-
|
|
98030
|
+
item: {
|
|
98031
|
+
record: record3,
|
|
98032
|
+
score,
|
|
98033
|
+
reason: reasonParts.join(", "),
|
|
98034
|
+
signals: {
|
|
98035
|
+
textOverlap,
|
|
98036
|
+
tagOverlap,
|
|
98037
|
+
fileOverlap,
|
|
98038
|
+
symbolOverlap,
|
|
98039
|
+
kindMatch,
|
|
98040
|
+
scopeMatch
|
|
98041
|
+
}
|
|
98042
|
+
}
|
|
97954
98043
|
};
|
|
97955
98044
|
}
|
|
97956
|
-
function
|
|
97957
|
-
|
|
98045
|
+
function scoreMemoryRecordsWithDiagnostics(records, request) {
|
|
98046
|
+
const minScore = request.minScore ?? 0;
|
|
98047
|
+
const diagnostics = {
|
|
98048
|
+
candidateCount: records.length,
|
|
98049
|
+
preScoredFilteredCount: 0,
|
|
98050
|
+
scoredCount: 0,
|
|
98051
|
+
returnedCount: 0,
|
|
98052
|
+
noSignalCount: 0,
|
|
98053
|
+
belowThresholdCount: 0
|
|
98054
|
+
};
|
|
98055
|
+
const items = [];
|
|
98056
|
+
for (const record3 of records) {
|
|
98057
|
+
const result = scoreMemoryRecordDetailed(record3, request);
|
|
98058
|
+
if (!result.item) {
|
|
98059
|
+
if (result.skipReason === "filtered")
|
|
98060
|
+
diagnostics.preScoredFilteredCount++;
|
|
98061
|
+
if (result.skipReason === "no_signal")
|
|
98062
|
+
diagnostics.noSignalCount++;
|
|
98063
|
+
continue;
|
|
98064
|
+
}
|
|
98065
|
+
diagnostics.scoredCount++;
|
|
98066
|
+
if (result.item.score < minScore) {
|
|
98067
|
+
diagnostics.belowThresholdCount++;
|
|
98068
|
+
continue;
|
|
98069
|
+
}
|
|
98070
|
+
items.push(result.item);
|
|
98071
|
+
}
|
|
98072
|
+
items.sort((a, b) => b.score - a.score || a.record.id.localeCompare(b.record.id));
|
|
98073
|
+
diagnostics.returnedCount = items.length;
|
|
98074
|
+
return { items, diagnostics };
|
|
97958
98075
|
}
|
|
97959
98076
|
|
|
97960
98077
|
// src/memory/local-jsonl-provider.ts
|
|
@@ -98030,13 +98147,23 @@ class LocalJsonlMemoryProvider {
|
|
|
98030
98147
|
await this.audit("delete", id, reason);
|
|
98031
98148
|
}
|
|
98032
98149
|
async recall(request) {
|
|
98150
|
+
return (await this.recallWithDiagnostics(request)).items;
|
|
98151
|
+
}
|
|
98152
|
+
async recallWithDiagnostics(request) {
|
|
98033
98153
|
await this.initialize();
|
|
98034
98154
|
const records = await this.list({
|
|
98035
98155
|
scopes: request.scopes,
|
|
98036
98156
|
kinds: request.kinds,
|
|
98037
98157
|
includeExpired: request.includeExpired
|
|
98038
98158
|
});
|
|
98039
|
-
|
|
98159
|
+
const result = scoreMemoryRecordsWithDiagnostics(records, request);
|
|
98160
|
+
return {
|
|
98161
|
+
items: result.items.slice(0, request.maxItems),
|
|
98162
|
+
diagnostics: {
|
|
98163
|
+
...result.diagnostics,
|
|
98164
|
+
returnedCount: Math.min(result.diagnostics.returnedCount, request.maxItems)
|
|
98165
|
+
}
|
|
98166
|
+
};
|
|
98040
98167
|
}
|
|
98041
98168
|
async recordRecallUsage(event) {
|
|
98042
98169
|
await this.initialize();
|
|
@@ -98241,7 +98368,8 @@ function toRecallBundle(input) {
|
|
|
98241
98368
|
generatedAt: input.generatedAt,
|
|
98242
98369
|
items: block.items,
|
|
98243
98370
|
tokenEstimate: block.tokenEstimate,
|
|
98244
|
-
promptBlock: block.promptBlock
|
|
98371
|
+
promptBlock: block.promptBlock,
|
|
98372
|
+
diagnostics: input.diagnostics
|
|
98245
98373
|
};
|
|
98246
98374
|
}
|
|
98247
98375
|
|
|
@@ -98302,20 +98430,29 @@ class MemoryGateway {
|
|
|
98302
98430
|
query,
|
|
98303
98431
|
task: input.task,
|
|
98304
98432
|
agentRole: this.context.agentRole,
|
|
98433
|
+
mode: input.mode ?? "manual",
|
|
98305
98434
|
scopes,
|
|
98306
98435
|
kinds: input.kinds,
|
|
98307
98436
|
maxItems,
|
|
98308
98437
|
tokenBudget,
|
|
98309
98438
|
minScore: input.minScore ?? this.config.recall.minScore,
|
|
98439
|
+
requireQuerySignal: input.requireQuerySignal,
|
|
98310
98440
|
includeExpired: input.includeExpired
|
|
98311
98441
|
};
|
|
98312
|
-
const
|
|
98442
|
+
const recallResult = this.provider.recallWithDiagnostics ? await this.provider.recallWithDiagnostics(request) : { items: await this.provider.recall(request) };
|
|
98313
98443
|
const bundle = toRecallBundle({
|
|
98314
98444
|
id: createBundleId(query, generatedAt),
|
|
98315
98445
|
query,
|
|
98316
98446
|
generatedAt,
|
|
98317
|
-
items:
|
|
98318
|
-
tokenBudget
|
|
98447
|
+
items: recallResult.items,
|
|
98448
|
+
tokenBudget,
|
|
98449
|
+
diagnostics: recallResult.diagnostics ? {
|
|
98450
|
+
injectionSkipReason: input.mode === "injection" ? resolveInjectionSkipReason(recallResult.diagnostics) : undefined,
|
|
98451
|
+
candidateCount: recallResult.diagnostics.candidateCount,
|
|
98452
|
+
preScoredFilteredCount: recallResult.diagnostics.preScoredFilteredCount,
|
|
98453
|
+
noSignalCount: recallResult.diagnostics.noSignalCount,
|
|
98454
|
+
belowThresholdCount: recallResult.diagnostics.belowThresholdCount
|
|
98455
|
+
} : undefined
|
|
98319
98456
|
});
|
|
98320
98457
|
await this.provider.recordRecallUsage?.({
|
|
98321
98458
|
bundleId: bundle.id,
|
|
@@ -98503,6 +98640,19 @@ function validateRequestedScopes(requested, allowed) {
|
|
|
98503
98640
|
}
|
|
98504
98641
|
return requested;
|
|
98505
98642
|
}
|
|
98643
|
+
function resolveInjectionSkipReason(diagnostics) {
|
|
98644
|
+
if (diagnostics.returnedCount > 0)
|
|
98645
|
+
return;
|
|
98646
|
+
if (diagnostics.candidateCount === 0)
|
|
98647
|
+
return "no_results";
|
|
98648
|
+
const signalEligibleCount = diagnostics.candidateCount - diagnostics.preScoredFilteredCount;
|
|
98649
|
+
if (signalEligibleCount > 0 && diagnostics.noSignalCount > 0 && diagnostics.noSignalCount >= signalEligibleCount) {
|
|
98650
|
+
return "no_signal";
|
|
98651
|
+
}
|
|
98652
|
+
if (diagnostics.belowThresholdCount > 0)
|
|
98653
|
+
return "below_threshold";
|
|
98654
|
+
return "no_results";
|
|
98655
|
+
}
|
|
98506
98656
|
function scopeKey(scope) {
|
|
98507
98657
|
return JSON.stringify({
|
|
98508
98658
|
type: scope.type,
|
|
@@ -98897,8 +99047,15 @@ async function recallForAgent(input) {
|
|
|
98897
99047
|
agentId: input.agentId,
|
|
98898
99048
|
runId: input.sessionID
|
|
98899
99049
|
}, { config: input.config });
|
|
98900
|
-
|
|
99050
|
+
const resolvedConfig = resolveMemoryConfig(input.config);
|
|
99051
|
+
if (!gateway.isEnabled()) {
|
|
99052
|
+
await logInjectionSkipped(input, "disabled");
|
|
98901
99053
|
return null;
|
|
99054
|
+
}
|
|
99055
|
+
if (!resolvedConfig.recall.injection.enabled) {
|
|
99056
|
+
await logInjectionSkipped(input, "disabled");
|
|
99057
|
+
return null;
|
|
99058
|
+
}
|
|
98902
99059
|
const scopes = gateway.deriveAllowedScopes();
|
|
98903
99060
|
const planInput = {
|
|
98904
99061
|
userGoal: compactText(input.userGoal),
|
|
@@ -98909,6 +99066,8 @@ async function recallForAgent(input) {
|
|
|
98909
99066
|
touchedFiles: extractTouchedFiles(input.agentTask)
|
|
98910
99067
|
};
|
|
98911
99068
|
const plan = buildMemoryRecallPlan(planInput, { scopes });
|
|
99069
|
+
plan.maxItems = resolvedConfig.recall.injection.maxItems;
|
|
99070
|
+
plan.tokenBudget = resolvedConfig.recall.injection.tokenBudget;
|
|
98912
99071
|
await input.appendRunLog(input.directory, input.sessionID, {
|
|
98913
99072
|
event: "recall_requested",
|
|
98914
99073
|
runId: input.sessionID ?? "unknown",
|
|
@@ -98924,10 +99083,13 @@ async function recallForAgent(input) {
|
|
|
98924
99083
|
const recallInput = {
|
|
98925
99084
|
query: plan.query,
|
|
98926
99085
|
task: planInput.agentTask,
|
|
99086
|
+
mode: "injection",
|
|
98927
99087
|
scopes: plan.scopes,
|
|
98928
99088
|
kinds: plan.kinds,
|
|
98929
99089
|
maxItems: plan.maxItems,
|
|
98930
|
-
tokenBudget: plan.tokenBudget
|
|
99090
|
+
tokenBudget: plan.tokenBudget,
|
|
99091
|
+
minScore: resolvedConfig.recall.injection.minScore,
|
|
99092
|
+
requireQuerySignal: resolvedConfig.recall.injection.requireQuerySignal
|
|
98931
99093
|
};
|
|
98932
99094
|
const bundle = await gateway.recall(recallInput);
|
|
98933
99095
|
await input.appendRunLog(input.directory, input.sessionID, {
|
|
@@ -98940,8 +99102,31 @@ async function recallForAgent(input) {
|
|
|
98940
99102
|
scores: bundle.items.map((item) => item.score),
|
|
98941
99103
|
tokenEstimate: bundle.tokenEstimate
|
|
98942
99104
|
});
|
|
99105
|
+
if (bundle.items.length === 0) {
|
|
99106
|
+
await logInjectionSkipped(input, bundle.diagnostics?.injectionSkipReason ?? "no_results", bundle);
|
|
99107
|
+
}
|
|
98943
99108
|
return { bundle, scopes };
|
|
98944
99109
|
}
|
|
99110
|
+
async function logInjectionSkipped(input, reason, bundle) {
|
|
99111
|
+
await input.appendRunLog(input.directory, input.sessionID, {
|
|
99112
|
+
event: "prompt_injection_skipped",
|
|
99113
|
+
runId: input.sessionID ?? "unknown",
|
|
99114
|
+
agentRole: input.agentRole,
|
|
99115
|
+
agentId: input.agentId,
|
|
99116
|
+
bundleId: bundle?.id,
|
|
99117
|
+
memoryIds: bundle?.items.map((item) => item.record.id),
|
|
99118
|
+
scores: bundle?.items.map((item) => item.score),
|
|
99119
|
+
tokenEstimate: bundle?.tokenEstimate,
|
|
99120
|
+
rejectionReason: reason,
|
|
99121
|
+
metadata: {
|
|
99122
|
+
reason,
|
|
99123
|
+
candidateCount: bundle?.diagnostics?.candidateCount,
|
|
99124
|
+
preScoredFilteredCount: bundle?.diagnostics?.preScoredFilteredCount,
|
|
99125
|
+
noSignalCount: bundle?.diagnostics?.noSignalCount,
|
|
99126
|
+
belowThresholdCount: bundle?.diagnostics?.belowThresholdCount
|
|
99127
|
+
}
|
|
99128
|
+
});
|
|
99129
|
+
}
|
|
98945
99130
|
function parseTaskToolInput(input) {
|
|
98946
99131
|
const record3 = input;
|
|
98947
99132
|
const rawTool = typeof record3.tool === "string" ? record3.tool : undefined;
|
|
@@ -114893,6 +115078,10 @@ var swarm_memory_recall = createSwarmTool({
|
|
|
114893
115078
|
memory_ids: bundle.items.map((item) => item.record.id),
|
|
114894
115079
|
total: bundle.items.length,
|
|
114895
115080
|
token_estimate: bundle.tokenEstimate,
|
|
115081
|
+
signals: bundle.items.map((item) => ({
|
|
115082
|
+
memory_id: item.record.id,
|
|
115083
|
+
...item.signals
|
|
115084
|
+
})),
|
|
114896
115085
|
prompt_block: bundle.promptBlock
|
|
114897
115086
|
}, null, 2);
|
|
114898
115087
|
}
|
package/dist/memory/config.d.ts
CHANGED
|
@@ -7,6 +7,13 @@ export interface MemoryConfig {
|
|
|
7
7
|
defaultMaxItems: number;
|
|
8
8
|
defaultTokenBudget: number;
|
|
9
9
|
minScore: number;
|
|
10
|
+
injection: {
|
|
11
|
+
enabled: boolean;
|
|
12
|
+
minScore: number;
|
|
13
|
+
requireQuerySignal: boolean;
|
|
14
|
+
maxItems: number;
|
|
15
|
+
tokenBudget: number;
|
|
16
|
+
};
|
|
10
17
|
};
|
|
11
18
|
writes: {
|
|
12
19
|
mode: 'propose';
|
package/dist/memory/gateway.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type MemoryConfig } from './config';
|
|
2
2
|
import type { MemoryProposalStore, MemoryProvider } from './provider';
|
|
3
|
-
import type { MemoryContext, MemoryKind, MemoryProposal, MemoryRecord, MemoryScopeRef, MemorySource, RecallBundle } from './types';
|
|
3
|
+
import type { MemoryContext, MemoryKind, MemoryProposal, MemoryRecord, MemoryScopeRef, MemorySource, RecallBundle, RecallMode } from './types';
|
|
4
4
|
export interface MemoryGatewayOptions {
|
|
5
5
|
config?: Partial<MemoryConfig>;
|
|
6
6
|
provider?: MemoryProvider & Partial<MemoryProposalStore>;
|
|
@@ -18,11 +18,13 @@ export interface ProposeMemoryInput {
|
|
|
18
18
|
export interface RecallMemoryInput {
|
|
19
19
|
query: string;
|
|
20
20
|
task?: string;
|
|
21
|
+
mode?: RecallMode;
|
|
21
22
|
scopes?: MemoryScopeRef[];
|
|
22
23
|
kinds?: MemoryKind[];
|
|
23
24
|
maxItems?: number;
|
|
24
25
|
tokenBudget?: number;
|
|
25
26
|
minScore?: number;
|
|
27
|
+
requireQuerySignal?: boolean;
|
|
26
28
|
includeExpired?: boolean;
|
|
27
29
|
}
|
|
28
30
|
export declare class MemoryGateway {
|
package/dist/memory/index.d.ts
CHANGED
|
@@ -12,4 +12,4 @@ export { findSecrets, redactSecrets } from './redaction';
|
|
|
12
12
|
export { MEMORY_RECALL_PROFILES, type MemoryRecallProfile, normalizeMemoryAgentRole, resolveMemoryRecallProfile, } from './role-profiles';
|
|
13
13
|
export { appendMemoryRunLog, sanitizeRunId } from './run-log';
|
|
14
14
|
export { computeMemoryContentHash, createBundleId, createMemoryId, createProposalId, isExpired, normalizeMemoryText, validateMemoryProposal, validateMemoryRecordRules, } from './schema';
|
|
15
|
-
export type { MemoryContext, MemoryKind, MemoryListFilter, MemoryProposal, MemoryRecord, MemoryScopeRef, MemoryScopeType, RecallBundle, RecallRequest, RecallResultItem, } from './types';
|
|
15
|
+
export type { MemoryContext, MemoryKind, MemoryListFilter, MemoryProposal, MemoryRecord, MemoryScopeRef, MemoryScopeType, RecallBundle, RecallInjectionSkipReason, RecallMode, RecallRequest, RecallResultItem, } from './types';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type MemoryConfig } from './config';
|
|
2
2
|
import type { MemoryProposalStore, MemoryProvider, MemoryRecallUsageEvent } from './provider';
|
|
3
|
+
import type { RecallScoringDiagnostics } from './scoring';
|
|
3
4
|
import type { MemoryListFilter, MemoryProposal, MemoryRecord, RecallRequest, RecallResultItem } from './types';
|
|
4
5
|
export declare class LocalJsonlMemoryProvider implements MemoryProvider, MemoryProposalStore {
|
|
5
6
|
readonly name = "local-jsonl";
|
|
@@ -15,6 +16,10 @@ export declare class LocalJsonlMemoryProvider implements MemoryProvider, MemoryP
|
|
|
15
16
|
get(id: string): Promise<MemoryRecord | null>;
|
|
16
17
|
delete(id: string, reason?: string): Promise<void>;
|
|
17
18
|
recall(request: RecallRequest): Promise<RecallResultItem[]>;
|
|
19
|
+
recallWithDiagnostics(request: RecallRequest): Promise<{
|
|
20
|
+
items: RecallResultItem[];
|
|
21
|
+
diagnostics: RecallScoringDiagnostics;
|
|
22
|
+
}>;
|
|
18
23
|
recordRecallUsage(event: MemoryRecallUsageEvent): Promise<void>;
|
|
19
24
|
list(filter?: MemoryListFilter): Promise<MemoryRecord[]>;
|
|
20
25
|
createProposal(proposal: MemoryProposal): Promise<MemoryProposal>;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
import type { RecallScoringDiagnostics } from './scoring';
|
|
1
2
|
import type { MemoryListFilter, MemoryProposal, MemoryRecord, RecallRequest, RecallResultItem } from './types';
|
|
3
|
+
export interface MemoryRecallResult {
|
|
4
|
+
items: RecallResultItem[];
|
|
5
|
+
diagnostics?: RecallScoringDiagnostics;
|
|
6
|
+
}
|
|
2
7
|
export interface MemoryRecallUsageEvent {
|
|
3
8
|
bundleId: string;
|
|
4
9
|
query: string;
|
|
@@ -18,6 +23,7 @@ export interface MemoryProvider {
|
|
|
18
23
|
get(id: string): Promise<MemoryRecord | null>;
|
|
19
24
|
delete(id: string, reason?: string): Promise<void>;
|
|
20
25
|
recall(request: RecallRequest): Promise<RecallResultItem[]>;
|
|
26
|
+
recallWithDiagnostics?(request: RecallRequest): Promise<MemoryRecallResult>;
|
|
21
27
|
recordRecallUsage?(event: MemoryRecallUsageEvent): Promise<void>;
|
|
22
28
|
list(filter: MemoryListFilter): Promise<MemoryRecord[]>;
|
|
23
29
|
}
|
package/dist/memory/run-log.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type MemoryRunLogEventName = 'recall_requested' | 'recall_returned' | 'prompt_injected' | 'proposal_created' | 'proposal_rejected_by_validation';
|
|
1
|
+
export type MemoryRunLogEventName = 'recall_requested' | 'recall_returned' | 'prompt_injection_skipped' | 'prompt_injected' | 'proposal_created' | 'proposal_rejected_by_validation';
|
|
2
2
|
export interface MemoryRunLogEvent {
|
|
3
3
|
event: MemoryRunLogEventName;
|
|
4
4
|
runId: string;
|
package/dist/memory/scoring.d.ts
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import type { MemoryRecord, MemoryScopeRef, RecallRequest, RecallResultItem } from './types';
|
|
2
|
+
export interface RecallScoringDiagnostics {
|
|
3
|
+
candidateCount: number;
|
|
4
|
+
preScoredFilteredCount: number;
|
|
5
|
+
scoredCount: number;
|
|
6
|
+
returnedCount: number;
|
|
7
|
+
noSignalCount: number;
|
|
8
|
+
belowThresholdCount: number;
|
|
9
|
+
}
|
|
2
10
|
export declare function sameScope(a: MemoryScopeRef, b: MemoryScopeRef): boolean;
|
|
3
11
|
export declare function scopeAllowed(recordScope: MemoryScopeRef, allowedScopes: MemoryScopeRef[]): boolean;
|
|
4
12
|
export declare function scoreMemoryRecord(record: MemoryRecord, request: RecallRequest): RecallResultItem | null;
|
|
5
13
|
export declare function scoreMemoryRecords(records: MemoryRecord[], request: RecallRequest): RecallResultItem[];
|
|
14
|
+
export declare function scoreMemoryRecordsWithDiagnostics(records: MemoryRecord[], request: RecallRequest): {
|
|
15
|
+
items: RecallResultItem[];
|
|
16
|
+
diagnostics: RecallScoringDiagnostics;
|
|
17
|
+
};
|
package/dist/memory/types.d.ts
CHANGED
|
@@ -56,15 +56,19 @@ export interface MemoryProposal {
|
|
|
56
56
|
createdAt: string;
|
|
57
57
|
metadata: Record<string, unknown>;
|
|
58
58
|
}
|
|
59
|
+
export type RecallMode = 'manual' | 'injection' | 'curator' | 'evaluation';
|
|
60
|
+
export type RecallInjectionSkipReason = 'disabled' | 'no_signal' | 'below_threshold' | 'no_results';
|
|
59
61
|
export interface RecallRequest {
|
|
60
62
|
query: string;
|
|
61
63
|
task?: string;
|
|
62
64
|
agentRole?: string;
|
|
65
|
+
mode?: RecallMode;
|
|
63
66
|
scopes: MemoryScopeRef[];
|
|
64
67
|
kinds?: MemoryKind[];
|
|
65
68
|
maxItems: number;
|
|
66
69
|
tokenBudget: number;
|
|
67
70
|
minScore?: number;
|
|
71
|
+
requireQuerySignal?: boolean;
|
|
68
72
|
includeExpired?: boolean;
|
|
69
73
|
includePendingProposals?: boolean;
|
|
70
74
|
}
|
|
@@ -72,6 +76,14 @@ export interface RecallResultItem {
|
|
|
72
76
|
record: MemoryRecord;
|
|
73
77
|
score: number;
|
|
74
78
|
reason: string;
|
|
79
|
+
signals: {
|
|
80
|
+
textOverlap: number;
|
|
81
|
+
tagOverlap: number;
|
|
82
|
+
fileOverlap?: number;
|
|
83
|
+
symbolOverlap?: number;
|
|
84
|
+
kindMatch: boolean;
|
|
85
|
+
scopeMatch: boolean;
|
|
86
|
+
};
|
|
75
87
|
}
|
|
76
88
|
export interface RecallBundle {
|
|
77
89
|
id: string;
|
|
@@ -80,6 +92,13 @@ export interface RecallBundle {
|
|
|
80
92
|
items: RecallResultItem[];
|
|
81
93
|
tokenEstimate: number;
|
|
82
94
|
promptBlock: string;
|
|
95
|
+
diagnostics?: {
|
|
96
|
+
injectionSkipReason?: RecallInjectionSkipReason;
|
|
97
|
+
candidateCount?: number;
|
|
98
|
+
preScoredFilteredCount?: number;
|
|
99
|
+
noSignalCount?: number;
|
|
100
|
+
belowThresholdCount?: number;
|
|
101
|
+
};
|
|
83
102
|
}
|
|
84
103
|
export interface MemoryContext {
|
|
85
104
|
directory: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.32.
|
|
3
|
+
"version": "7.32.3",
|
|
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",
|