opencode-swarm 7.103.2 → 7.104.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/dist/cli/{config-doctor-4rxjsg22.js → config-doctor-5m8z8jeg.js} +2 -2
- package/dist/cli/{guardrail-explain-4pnnjmyb.js → guardrail-explain-2zat1bxh.js} +5 -5
- package/dist/cli/{guardrail-log-vg0atkrx.js → guardrail-log-zhshjbpk.js} +3 -3
- package/dist/cli/{index-9zb70qfe.js → index-0derejrq.js} +1 -1
- package/dist/cli/{index-h0h4qjmc.js → index-5tywmqeh.js} +1 -1
- package/dist/cli/{index-4fnw0ebs.js → index-e7nhwa9k.js} +8 -6
- package/dist/cli/{index-5xy6kv7p.js → index-fk8ta8zw.js} +2 -2
- package/dist/cli/{index-m9keg83x.js → index-kcbcy6wq.js} +1 -1
- package/dist/cli/{index-3ahcme4e.js → index-n3ys2eny.js} +655 -55
- package/dist/cli/{index-ga7et2xw.js → index-t1vfvtg9.js} +21 -0
- package/dist/cli/index.js +4 -4
- package/dist/cli/{schema-az0hgfv0.js → schema-yxkdx5g5.js} +1 -1
- package/dist/commands/index.d.ts +1 -1
- package/dist/commands/memory.d.ts +1 -0
- package/dist/commands/registry.d.ts +8 -0
- package/dist/config/schema.d.ts +22 -0
- package/dist/council/types.d.ts +9 -0
- package/dist/graph/import-extractor.d.ts +1 -1
- package/dist/hooks/knowledge-application.d.ts +2 -2
- package/dist/hooks/knowledge-events.d.ts +3 -0
- package/dist/index.js +79 -44
- package/dist/lang/symbol-visibility.d.ts +2 -0
- package/dist/memory/config.d.ts +20 -0
- package/dist/memory/gateway.d.ts +1 -0
- package/dist/memory/index.d.ts +2 -1
- package/dist/memory/maintenance.d.ts +4 -1
- package/dist/memory/provider-pool.d.ts +23 -0
- package/dist/memory/provider.d.ts +53 -0
- package/dist/memory/reward.d.ts +39 -0
- package/dist/memory/schema.d.ts +2 -0
- package/dist/memory/scoring.d.ts +2 -0
- package/dist/memory/sqlite-provider.d.ts +53 -1
- package/dist/memory/types.d.ts +5 -0
- package/dist/state.d.ts +2 -2
- package/dist/tools/convene-council.d.ts +2 -0
- package/dist/tools/repo-graph/builder.d.ts +4 -2
- package/dist/tools/submit-phase-council-verdicts.d.ts +1 -0
- package/dist/tools/symbols.d.ts +2 -0
- package/package.json +1 -1
|
@@ -57,7 +57,7 @@ import {
|
|
|
57
57
|
readDoctorArtifact,
|
|
58
58
|
removeStraySwarmDir,
|
|
59
59
|
runConfigDoctor
|
|
60
|
-
} from "./index-
|
|
60
|
+
} from "./index-5tywmqeh.js";
|
|
61
61
|
import {
|
|
62
62
|
AGENT_TOOL_MAP,
|
|
63
63
|
ALL_SUBAGENT_NAMES,
|
|
@@ -70,7 +70,7 @@ import {
|
|
|
70
70
|
TOOL_NAME_SET,
|
|
71
71
|
resolveExternalSkillsConfig,
|
|
72
72
|
stripKnownSwarmPrefix
|
|
73
|
-
} from "./index-
|
|
73
|
+
} from "./index-t1vfvtg9.js";
|
|
74
74
|
import {
|
|
75
75
|
MAX_TRANSIENT_RETRIES,
|
|
76
76
|
PlanSchema,
|
|
@@ -912,7 +912,7 @@ var init_executor = __esm(() => {
|
|
|
912
912
|
// package.json
|
|
913
913
|
var package_default = {
|
|
914
914
|
name: "opencode-swarm",
|
|
915
|
-
version: "7.
|
|
915
|
+
version: "7.104.0",
|
|
916
916
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
917
917
|
main: "dist/index.js",
|
|
918
918
|
types: "dist/index.d.ts",
|
|
@@ -3589,7 +3589,7 @@ function classifySwarmCommandToolUse(resolved) {
|
|
|
3589
3589
|
return { allowed: true };
|
|
3590
3590
|
return {
|
|
3591
3591
|
allowed: false,
|
|
3592
|
-
message: "Use `/swarm memory status`, `/swarm memory pending`, `/swarm memory recall-log`, `/swarm memory stale`, `/swarm memory export`, or `/swarm memory evaluate --json` through swarm_command. Memory import, migrate, and compact are intentionally excluded from chat-tool execution."
|
|
3592
|
+
message: "Use `/swarm memory status`, `/swarm memory pending`, `/swarm memory recall-log`, `/swarm memory value-log`, `/swarm memory stale`, `/swarm memory export`, or `/swarm memory evaluate --json` through swarm_command. Memory import, migrate, and compact are intentionally excluded from chat-tool execution."
|
|
3593
3593
|
};
|
|
3594
3594
|
}
|
|
3595
3595
|
if (canonicalKey === "memory evaluate") {
|
|
@@ -3625,7 +3625,7 @@ function classifySwarmCommandToolUse(resolved) {
|
|
|
3625
3625
|
message: "Usage through swarm_command: `/swarm sdd validate`, `/swarm sdd validate --json`, or `/swarm sdd validate --change <id>`."
|
|
3626
3626
|
};
|
|
3627
3627
|
}
|
|
3628
|
-
if (canonicalKey === "memory pending" || canonicalKey === "memory recall-log" || canonicalKey === "memory stale") {
|
|
3628
|
+
if (canonicalKey === "memory pending" || canonicalKey === "memory recall-log" || canonicalKey === "memory value-log" || canonicalKey === "memory stale") {
|
|
3629
3629
|
if (args.length === 0)
|
|
3630
3630
|
return { allowed: true };
|
|
3631
3631
|
if (args.length === 2 && args[0] === "--limit" && /^\d+$/.test(args[1])) {
|
|
@@ -13377,7 +13377,7 @@ async function runFinalizeStage(ctx) {
|
|
|
13377
13377
|
}
|
|
13378
13378
|
}
|
|
13379
13379
|
try {
|
|
13380
|
-
const { CuratorConfigSchema: CCS } = await import("./schema-
|
|
13380
|
+
const { CuratorConfigSchema: CCS } = await import("./schema-yxkdx5g5.js");
|
|
13381
13381
|
const { config: pmLoadedConfig } = _internals20.loadPluginConfigWithMeta(ctx.directory);
|
|
13382
13382
|
const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
|
|
13383
13383
|
if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
|
|
@@ -17203,7 +17203,7 @@ async function handleDoctorCommand(directory, args) {
|
|
|
17203
17203
|
const result = runConfigDoctor(config, directory);
|
|
17204
17204
|
let output;
|
|
17205
17205
|
if (enableAutoFix && result.hasAutoFixableIssues) {
|
|
17206
|
-
const { runConfigDoctorWithFixes } = await import("./config-doctor-
|
|
17206
|
+
const { runConfigDoctorWithFixes } = await import("./config-doctor-5m8z8jeg.js");
|
|
17207
17207
|
const fixResult = await runConfigDoctorWithFixes(directory, config, true);
|
|
17208
17208
|
output = formatDoctorMarkdown(fixResult.result);
|
|
17209
17209
|
} else {
|
|
@@ -20605,6 +20605,17 @@ var DEFAULT_CONSOLIDATION_CONFIG = {
|
|
|
20605
20605
|
autoApplyMinConfidence: 0.6,
|
|
20606
20606
|
decayHalfLifeDays: { ...DEFAULT_DECAY_HALF_LIFE_DAYS }
|
|
20607
20607
|
};
|
|
20608
|
+
var DEFAULT_MEMORY_LEARNING_CONFIG = {
|
|
20609
|
+
learningRate: 0.1,
|
|
20610
|
+
propagationFactor: 0.3,
|
|
20611
|
+
qValueBoostWeight: 0.1,
|
|
20612
|
+
suppressionThreshold: 0.15,
|
|
20613
|
+
promotionThreshold: 0.85,
|
|
20614
|
+
propagationTokenOverlapThreshold: 0.4,
|
|
20615
|
+
propagationEmbeddingCosineThreshold: 0.7,
|
|
20616
|
+
propagationFanout: 20,
|
|
20617
|
+
propagationLookbackDays: 30
|
|
20618
|
+
};
|
|
20608
20619
|
var DEFAULT_EMBEDDINGS_CONFIG = {
|
|
20609
20620
|
enabled: false,
|
|
20610
20621
|
model: "Xenova/all-MiniLM-L6-v2",
|
|
@@ -20643,6 +20654,7 @@ var DEFAULT_MEMORY_CONFIG = {
|
|
|
20643
20654
|
tokenBudget: 1000
|
|
20644
20655
|
}
|
|
20645
20656
|
},
|
|
20657
|
+
learning: { ...DEFAULT_MEMORY_LEARNING_CONFIG },
|
|
20646
20658
|
writes: {
|
|
20647
20659
|
mode: "propose"
|
|
20648
20660
|
},
|
|
@@ -20694,6 +20706,10 @@ function resolveMemoryConfig(input) {
|
|
|
20694
20706
|
...input?.recall?.injection ?? {}
|
|
20695
20707
|
}
|
|
20696
20708
|
},
|
|
20709
|
+
learning: {
|
|
20710
|
+
...DEFAULT_MEMORY_CONFIG.learning,
|
|
20711
|
+
...input?.learning ?? {}
|
|
20712
|
+
},
|
|
20697
20713
|
writes: {
|
|
20698
20714
|
...DEFAULT_MEMORY_CONFIG.writes,
|
|
20699
20715
|
...input?.writes ?? {}
|
|
@@ -20887,6 +20903,7 @@ var MemoryRecordSchema = exports_external.object({
|
|
|
20887
20903
|
updatedAt: exports_external.string().datetime(),
|
|
20888
20904
|
lastAccessedAt: exports_external.string().datetime().optional(),
|
|
20889
20905
|
expiresAt: exports_external.string().datetime().optional(),
|
|
20906
|
+
qValue: exports_external.number().min(0).max(1).optional(),
|
|
20890
20907
|
supersedes: exports_external.array(exports_external.string()).optional(),
|
|
20891
20908
|
supersededBy: exports_external.string().optional(),
|
|
20892
20909
|
contentHash: exports_external.string().regex(/^[a-f0-9]{64}$/),
|
|
@@ -21242,6 +21259,7 @@ var SCORING_WEIGHTS = {
|
|
|
21242
21259
|
roleBoost: 0.05,
|
|
21243
21260
|
confidence: 0.08
|
|
21244
21261
|
};
|
|
21262
|
+
var DEFAULT_MEMORY_Q_VALUE = 0.5;
|
|
21245
21263
|
function tokenize(text) {
|
|
21246
21264
|
return new Set(text.toLowerCase().replace(/[^\w\s-]/g, " ").split(/\s+/).map((token) => token.trim()).filter(Boolean));
|
|
21247
21265
|
}
|
|
@@ -21320,6 +21338,11 @@ function scoreMemoryRecordDetailed(record, request, context) {
|
|
|
21320
21338
|
if (record.metadata.deleted === true) {
|
|
21321
21339
|
return { item: null, skipReason: "filtered" };
|
|
21322
21340
|
}
|
|
21341
|
+
const qValue = memoryQValue(record);
|
|
21342
|
+
const suppressionThreshold = request.suppressionThreshold ?? 0;
|
|
21343
|
+
if (request.includeLowQ !== true && suppressionThreshold > 0 && qValue < suppressionThreshold) {
|
|
21344
|
+
return { item: null, skipReason: "filtered" };
|
|
21345
|
+
}
|
|
21323
21346
|
if (!scopeAllowed(record.scope, request.scopes)) {
|
|
21324
21347
|
return { item: null, skipReason: "filtered" };
|
|
21325
21348
|
}
|
|
@@ -21355,7 +21378,7 @@ function scoreMemoryRecordDetailed(record, request, context) {
|
|
|
21355
21378
|
if (request.mode === "injection" && request.requireQuerySignal !== false && !hasQuerySignal) {
|
|
21356
21379
|
return { item: null, skipReason: "no_signal" };
|
|
21357
21380
|
}
|
|
21358
|
-
const score = textOverlap * SCORING_WEIGHTS.textOverlap + tagOverlap * SCORING_WEIGHTS.tagOverlap + fileOverlap * SCORING_WEIGHTS.fileOverlap + symbolOverlap * SCORING_WEIGHTS.symbolOverlap + taskTermOverlap * SCORING_WEIGHTS.taskTermOverlap + scopeSpecificityBoost(record.scope) * SCORING_WEIGHTS.scopeSpecificityBoost + kindProfileBoost(record.kind, request) * SCORING_WEIGHTS.kindProfileBoost + roleBoost * SCORING_WEIGHTS.roleBoost + record.confidence * SCORING_WEIGHTS.confidence;
|
|
21381
|
+
const score = textOverlap * SCORING_WEIGHTS.textOverlap + tagOverlap * SCORING_WEIGHTS.tagOverlap + fileOverlap * SCORING_WEIGHTS.fileOverlap + symbolOverlap * SCORING_WEIGHTS.symbolOverlap + taskTermOverlap * SCORING_WEIGHTS.taskTermOverlap + scopeSpecificityBoost(record.scope) * SCORING_WEIGHTS.scopeSpecificityBoost + kindProfileBoost(record.kind, request) * SCORING_WEIGHTS.kindProfileBoost + roleBoost * SCORING_WEIGHTS.roleBoost + record.confidence * SCORING_WEIGHTS.confidence + (qValue - DEFAULT_MEMORY_Q_VALUE) * (request.qValueBoostWeight ?? 0);
|
|
21359
21382
|
const reasonParts = [
|
|
21360
21383
|
textOverlap > 0 ? `text_overlap=${textOverlap.toFixed(2)}` : null,
|
|
21361
21384
|
tagOverlap > 0 ? `tag_overlap=${tagOverlap.toFixed(2)}` : null,
|
|
@@ -21364,6 +21387,7 @@ function scoreMemoryRecordDetailed(record, request, context) {
|
|
|
21364
21387
|
taskTermOverlap > 0 ? `task_terms=${taskTermOverlap.toFixed(2)}` : null,
|
|
21365
21388
|
kindQueryOverlap > 0 ? `kind_query=${kindQueryOverlap.toFixed(2)}` : null,
|
|
21366
21389
|
roleBoost > 0 ? "role_profile" : null,
|
|
21390
|
+
request.qValueBoostWeight && request.qValueBoostWeight > 0 ? `q_value=${qValue.toFixed(2)}` : null,
|
|
21367
21391
|
`scope=${record.scope.type}`,
|
|
21368
21392
|
`confidence=${record.confidence.toFixed(2)}`
|
|
21369
21393
|
].filter(Boolean);
|
|
@@ -21377,12 +21401,26 @@ function scoreMemoryRecordDetailed(record, request, context) {
|
|
|
21377
21401
|
tagOverlap,
|
|
21378
21402
|
fileOverlap,
|
|
21379
21403
|
symbolOverlap,
|
|
21404
|
+
qValue,
|
|
21380
21405
|
kindMatch,
|
|
21381
21406
|
scopeMatch
|
|
21382
21407
|
}
|
|
21383
21408
|
}
|
|
21384
21409
|
};
|
|
21385
21410
|
}
|
|
21411
|
+
function memoryQValue(record) {
|
|
21412
|
+
if (typeof record.qValue === "number" && Number.isFinite(record.qValue)) {
|
|
21413
|
+
return clamp01(record.qValue);
|
|
21414
|
+
}
|
|
21415
|
+
const metadataValue = record.metadata.qValue;
|
|
21416
|
+
if (typeof metadataValue === "number" && Number.isFinite(metadataValue)) {
|
|
21417
|
+
return clamp01(metadataValue);
|
|
21418
|
+
}
|
|
21419
|
+
return DEFAULT_MEMORY_Q_VALUE;
|
|
21420
|
+
}
|
|
21421
|
+
function clamp01(value) {
|
|
21422
|
+
return Math.min(1, Math.max(0, value));
|
|
21423
|
+
}
|
|
21386
21424
|
function scoreMemoryRecordsWithDiagnostics(records, request) {
|
|
21387
21425
|
const minScore = request.minScore ?? 0;
|
|
21388
21426
|
const context = createScoringContext(request);
|
|
@@ -21453,6 +21491,14 @@ async function buildMemoryMaintenanceReport(provider, options = {}) {
|
|
|
21453
21491
|
});
|
|
21454
21492
|
const proposals = await loadMaintenanceProposals(provider, limit);
|
|
21455
21493
|
const recallUsage = provider.listRecallUsage ? await provider.listRecallUsage() : [];
|
|
21494
|
+
const suppressionValueLog = provider.listMemoryValueLog ? await provider.listMemoryValueLog({
|
|
21495
|
+
includeSuppressionCandidatesOnly: true,
|
|
21496
|
+
limit
|
|
21497
|
+
}) : [];
|
|
21498
|
+
const promotionValueLog = provider.listMemoryValueLog ? await provider.listMemoryValueLog({
|
|
21499
|
+
includePromotionCandidatesOnly: true,
|
|
21500
|
+
limit
|
|
21501
|
+
}) : [];
|
|
21456
21502
|
const usageByMemory = summarizeRecallByMemory(recallUsage);
|
|
21457
21503
|
const usageByRole = summarizeRecallByRole(recallUsage);
|
|
21458
21504
|
const activeMemories = memories.filter((memory) => isActiveMemory(memory, now));
|
|
@@ -21475,6 +21521,8 @@ async function buildMemoryMaintenanceReport(provider, options = {}) {
|
|
|
21475
21521
|
supersededMemories: supersededMemories.slice(0, limit),
|
|
21476
21522
|
supersededChains: buildSupersededChains(memories).slice(0, limit),
|
|
21477
21523
|
lowUtilityMemories: lowUtilityMemories.slice(0, limit),
|
|
21524
|
+
lowQValueMemories: suppressionValueLog.slice(0, limit),
|
|
21525
|
+
promotionCandidates: promotionValueLog.slice(0, limit),
|
|
21478
21526
|
neverRecalledMemories: neverRecalledMemories.slice(0, limit),
|
|
21479
21527
|
mostRecalledMemories: Array.from(usageByMemory.values()).sort((a, b) => b.count - a.count || b.lastRecalledAt.localeCompare(a.lastRecalledAt) || a.memoryId.localeCompare(b.memoryId)).slice(0, limit),
|
|
21480
21528
|
recallByAgentRole: Array.from(usageByRole.values()).sort((a, b) => b.count - a.count || a.agentRole.localeCompare(b.agentRole)).slice(0, limit),
|
|
@@ -22740,6 +22788,23 @@ var MIGRATIONS2 = [
|
|
|
22740
22788
|
value TEXT
|
|
22741
22789
|
);
|
|
22742
22790
|
`
|
|
22791
|
+
},
|
|
22792
|
+
{
|
|
22793
|
+
version: 7,
|
|
22794
|
+
name: "add_recall_learning_columns",
|
|
22795
|
+
sql: `
|
|
22796
|
+
ALTER TABLE memory_recall_usage ADD COLUMN q_value REAL DEFAULT 0.5;
|
|
22797
|
+
ALTER TABLE memory_recall_usage ADD COLUMN last_reward REAL;
|
|
22798
|
+
ALTER TABLE memory_recall_usage ADD COLUMN task_outcome TEXT;
|
|
22799
|
+
ALTER TABLE memory_recall_usage ADD COLUMN council_verdict_json TEXT;
|
|
22800
|
+
`
|
|
22801
|
+
},
|
|
22802
|
+
{
|
|
22803
|
+
version: 8,
|
|
22804
|
+
name: "add_recall_reward_idempotency_key",
|
|
22805
|
+
sql: `
|
|
22806
|
+
ALTER TABLE memory_recall_usage ADD COLUMN reward_key TEXT;
|
|
22807
|
+
`
|
|
22743
22808
|
}
|
|
22744
22809
|
];
|
|
22745
22810
|
|
|
@@ -22760,36 +22825,15 @@ class SQLiteMemoryProvider {
|
|
|
22760
22825
|
lastAutomaticJsonlMigration = null;
|
|
22761
22826
|
recallCountSinceLastCompaction = 0;
|
|
22762
22827
|
isCompacting = false;
|
|
22828
|
+
_internals = {
|
|
22829
|
+
writeMemory: (record) => this.writeMemory(record),
|
|
22830
|
+
setEmbeddingProvider: (provider) => {
|
|
22831
|
+
this.embeddingProvider = provider;
|
|
22832
|
+
}
|
|
22833
|
+
};
|
|
22763
22834
|
constructor(rootDirectory, config = {}) {
|
|
22764
22835
|
this.rootDirectory = rootDirectory;
|
|
22765
|
-
this.config =
|
|
22766
|
-
...DEFAULT_MEMORY_CONFIG,
|
|
22767
|
-
...config,
|
|
22768
|
-
sqlite: {
|
|
22769
|
-
...DEFAULT_MEMORY_CONFIG.sqlite,
|
|
22770
|
-
...config.sqlite ?? {}
|
|
22771
|
-
},
|
|
22772
|
-
recall: {
|
|
22773
|
-
...DEFAULT_MEMORY_CONFIG.recall,
|
|
22774
|
-
...config.recall ?? {},
|
|
22775
|
-
injection: {
|
|
22776
|
-
...DEFAULT_MEMORY_CONFIG.recall.injection,
|
|
22777
|
-
...config.recall?.injection ?? {}
|
|
22778
|
-
}
|
|
22779
|
-
},
|
|
22780
|
-
writes: {
|
|
22781
|
-
...DEFAULT_MEMORY_CONFIG.writes,
|
|
22782
|
-
...config.writes ?? {}
|
|
22783
|
-
},
|
|
22784
|
-
redaction: {
|
|
22785
|
-
...DEFAULT_MEMORY_CONFIG.redaction,
|
|
22786
|
-
...config.redaction ?? {}
|
|
22787
|
-
},
|
|
22788
|
-
maintenance: {
|
|
22789
|
-
...DEFAULT_MEMORY_CONFIG.maintenance,
|
|
22790
|
-
...config.maintenance ?? {}
|
|
22791
|
-
}
|
|
22792
|
-
};
|
|
22836
|
+
this.config = resolveMemoryConfig(config);
|
|
22793
22837
|
}
|
|
22794
22838
|
databasePath() {
|
|
22795
22839
|
const relativePath = this.config.sqlite.path.replace(/^\.swarm[/\\]?/, "");
|
|
@@ -23040,12 +23084,25 @@ class SQLiteMemoryProvider {
|
|
|
23040
23084
|
}
|
|
23041
23085
|
async recordRecallUsage(event) {
|
|
23042
23086
|
await this.initialize();
|
|
23087
|
+
const recalledRecords = event.memoryIds.map((id) => this.memories.get(id)).filter(isMemoryRecord);
|
|
23088
|
+
const qValue = typeof event.qValue === "number" && Number.isFinite(event.qValue) ? clamp012(event.qValue) : averageMemoryQValue(recalledRecords);
|
|
23089
|
+
const eventWithQValue = {
|
|
23090
|
+
...event,
|
|
23091
|
+
qValue
|
|
23092
|
+
};
|
|
23043
23093
|
this.requireDb().run(`INSERT INTO memory_recall_usage (
|
|
23044
23094
|
id,
|
|
23045
23095
|
bundle_id,
|
|
23046
23096
|
timestamp,
|
|
23047
|
-
usage_json
|
|
23048
|
-
|
|
23097
|
+
usage_json,
|
|
23098
|
+
q_value
|
|
23099
|
+
) VALUES (?, ?, ?, ?, ?)`, [
|
|
23100
|
+
randomUUID6(),
|
|
23101
|
+
event.bundleId,
|
|
23102
|
+
event.timestamp,
|
|
23103
|
+
JSON.stringify(eventWithQValue),
|
|
23104
|
+
qValue
|
|
23105
|
+
]);
|
|
23049
23106
|
this.recallCountSinceLastCompaction++;
|
|
23050
23107
|
const threshold = this.config.maintenance?.autoCompactEveryNRecalls ?? 50;
|
|
23051
23108
|
if (threshold > 0 && this.recallCountSinceLastCompaction >= threshold && !this.isCompacting) {
|
|
@@ -23072,24 +23129,163 @@ class SQLiteMemoryProvider {
|
|
|
23072
23129
|
}
|
|
23073
23130
|
async listRecallUsage(filter = {}) {
|
|
23074
23131
|
await this.initialize();
|
|
23075
|
-
const rows = typeof filter.limit === "number" ? this.requireDb().query(`SELECT usage_json
|
|
23132
|
+
const rows = typeof filter.limit === "number" ? this.requireDb().query(`SELECT id, usage_json, q_value, last_reward, task_outcome, council_verdict_json, reward_key
|
|
23076
23133
|
FROM memory_recall_usage
|
|
23077
23134
|
ORDER BY timestamp DESC
|
|
23078
|
-
LIMIT ?`).all(Math.max(1, Math.trunc(filter.limit))) : this.requireDb().query(`SELECT usage_json
|
|
23135
|
+
LIMIT ?`).all(Math.max(1, Math.trunc(filter.limit))) : this.requireDb().query(`SELECT id, usage_json, q_value, last_reward, task_outcome, council_verdict_json, reward_key
|
|
23079
23136
|
FROM memory_recall_usage
|
|
23080
23137
|
ORDER BY timestamp DESC
|
|
23081
23138
|
`).all();
|
|
23082
23139
|
const events = [];
|
|
23083
23140
|
for (const row of rows) {
|
|
23084
|
-
|
|
23085
|
-
|
|
23086
|
-
|
|
23087
|
-
events.push(parsed);
|
|
23088
|
-
}
|
|
23089
|
-
} catch {}
|
|
23141
|
+
const parsed = parseRecallUsageRow(row);
|
|
23142
|
+
if (parsed)
|
|
23143
|
+
events.push(parsed);
|
|
23090
23144
|
}
|
|
23091
23145
|
return events;
|
|
23092
23146
|
}
|
|
23147
|
+
async applyRecallReward(input) {
|
|
23148
|
+
await this.initialize();
|
|
23149
|
+
const matches = this.matchingRecallUsageRows(input.runIds);
|
|
23150
|
+
if (matches.length === 0) {
|
|
23151
|
+
return emptyRewardResult(input.outcome, "no_recall_usage_for_run");
|
|
23152
|
+
}
|
|
23153
|
+
const rewardKey = deriveRewardKey(input.verdictPayload);
|
|
23154
|
+
const pending = rewardKey === null ? matches : matches.filter((match) => match.rewardKey !== rewardKey);
|
|
23155
|
+
if (pending.length === 0) {
|
|
23156
|
+
const first = matches[0];
|
|
23157
|
+
return {
|
|
23158
|
+
success: true,
|
|
23159
|
+
bundleId: first?.event.bundleId,
|
|
23160
|
+
bundleIds: matches.map((match) => match.event.bundleId),
|
|
23161
|
+
outcome: input.outcome,
|
|
23162
|
+
memoryIds: uniqueStrings(matches.flatMap((match) => match.event.memoryIds)),
|
|
23163
|
+
reward: rewardForOutcome(input.outcome),
|
|
23164
|
+
updatedMemoryIds: [],
|
|
23165
|
+
propagatedMemoryIds: [],
|
|
23166
|
+
qValue: first?.event.qValue,
|
|
23167
|
+
reason: "already_rewarded"
|
|
23168
|
+
};
|
|
23169
|
+
}
|
|
23170
|
+
const reward = rewardForOutcome(input.outcome);
|
|
23171
|
+
const updatedAt = input.timestamp ?? new Date().toISOString();
|
|
23172
|
+
const sourceIds = uniqueStrings(pending.flatMap((match) => match.event.memoryIds));
|
|
23173
|
+
const directUpdates = new Map;
|
|
23174
|
+
const propagatedUpdates = new Map;
|
|
23175
|
+
for (const memoryId of sourceIds) {
|
|
23176
|
+
const nextQValue = this.updateMemoryQValue(memoryId, reward, updatedAt);
|
|
23177
|
+
if (nextQValue !== null) {
|
|
23178
|
+
directUpdates.set(memoryId, nextQValue);
|
|
23179
|
+
}
|
|
23180
|
+
}
|
|
23181
|
+
const promotionThreshold = this.config.learning.promotionThreshold;
|
|
23182
|
+
const promotionRecallThreshold = 5;
|
|
23183
|
+
const usageSummary = summarizeRecallUsage(this.listRecallUsageSync());
|
|
23184
|
+
for (const [memoryId, nextQValue] of directUpdates) {
|
|
23185
|
+
const memory = this.memories.get(memoryId);
|
|
23186
|
+
const recallCount = usageSummary.get(memoryId)?.count ?? 0;
|
|
23187
|
+
if (memory && memory.stability === "session" && nextQValue > promotionThreshold && recallCount > promotionRecallThreshold) {
|
|
23188
|
+
memory.stability = "durable";
|
|
23189
|
+
this._internals.writeMemory(memory);
|
|
23190
|
+
}
|
|
23191
|
+
}
|
|
23192
|
+
const propagationTargets = await this.findPropagationTargets(sourceIds);
|
|
23193
|
+
const db = this.requireDb();
|
|
23194
|
+
const verdictJson = truncateJsonPayload(input.verdictPayload);
|
|
23195
|
+
const result = db.transaction(() => {
|
|
23196
|
+
for (const targetId of propagationTargets) {
|
|
23197
|
+
const propagatedSignal = propagatedRewardSignal(reward, this.config.learning.propagationFactor);
|
|
23198
|
+
const nextQValue = this.updateMemoryQValue(targetId, propagatedSignal, updatedAt);
|
|
23199
|
+
if (nextQValue !== null) {
|
|
23200
|
+
propagatedUpdates.set(targetId, nextQValue);
|
|
23201
|
+
}
|
|
23202
|
+
}
|
|
23203
|
+
const updatedMemoryIds = [...directUpdates.keys()];
|
|
23204
|
+
const propagatedMemoryIds = [...propagatedUpdates.keys()];
|
|
23205
|
+
const combinedQValues = [
|
|
23206
|
+
...directUpdates.values(),
|
|
23207
|
+
...propagatedUpdates.values()
|
|
23208
|
+
];
|
|
23209
|
+
const qValue = combinedQValues.length > 0 ? averageNumbers(combinedQValues) : pending[0]?.event.qValue;
|
|
23210
|
+
for (const match of pending) {
|
|
23211
|
+
const updatedEvent = {
|
|
23212
|
+
...match.event,
|
|
23213
|
+
qValue,
|
|
23214
|
+
lastReward: reward,
|
|
23215
|
+
taskOutcome: input.outcome
|
|
23216
|
+
};
|
|
23217
|
+
db.run(`UPDATE memory_recall_usage
|
|
23218
|
+
SET usage_json = ?,
|
|
23219
|
+
q_value = ?,
|
|
23220
|
+
last_reward = ?,
|
|
23221
|
+
task_outcome = ?,
|
|
23222
|
+
council_verdict_json = ?,
|
|
23223
|
+
reward_key = ?
|
|
23224
|
+
WHERE id = ?`, [
|
|
23225
|
+
JSON.stringify(updatedEvent),
|
|
23226
|
+
qValue ?? null,
|
|
23227
|
+
reward,
|
|
23228
|
+
input.outcome,
|
|
23229
|
+
verdictJson,
|
|
23230
|
+
rewardKey,
|
|
23231
|
+
match.id
|
|
23232
|
+
]);
|
|
23233
|
+
}
|
|
23234
|
+
return {
|
|
23235
|
+
updatedMemoryIds,
|
|
23236
|
+
propagatedMemoryIds,
|
|
23237
|
+
qValue
|
|
23238
|
+
};
|
|
23239
|
+
})();
|
|
23240
|
+
for (const match of pending) {
|
|
23241
|
+
await this.event("recall", match.event.bundleId, `applied ${input.outcome} recall reward`);
|
|
23242
|
+
}
|
|
23243
|
+
return {
|
|
23244
|
+
success: true,
|
|
23245
|
+
bundleId: pending[0]?.event.bundleId,
|
|
23246
|
+
bundleIds: pending.map((match) => match.event.bundleId),
|
|
23247
|
+
outcome: input.outcome,
|
|
23248
|
+
memoryIds: sourceIds,
|
|
23249
|
+
reward,
|
|
23250
|
+
updatedMemoryIds: result.updatedMemoryIds,
|
|
23251
|
+
propagatedMemoryIds: result.propagatedMemoryIds,
|
|
23252
|
+
qValue: result.qValue
|
|
23253
|
+
};
|
|
23254
|
+
}
|
|
23255
|
+
async listMemoryValueLog(filter = {}) {
|
|
23256
|
+
await this.initialize();
|
|
23257
|
+
const usageSummary = summarizeRecallUsage(this.listRecallUsageSync());
|
|
23258
|
+
const threshold = this.config.learning.suppressionThreshold;
|
|
23259
|
+
const promotionThreshold = this.config.learning.promotionThreshold;
|
|
23260
|
+
const entries = Array.from(this.memories.values()).map((record) => {
|
|
23261
|
+
const recall = usageSummary.get(record.id);
|
|
23262
|
+
const qValue = memoryQValue(record);
|
|
23263
|
+
const recallCount = recall?.count ?? 0;
|
|
23264
|
+
return {
|
|
23265
|
+
memoryId: record.id,
|
|
23266
|
+
kind: record.kind,
|
|
23267
|
+
scopeKey: stableScopeKey(record.scope),
|
|
23268
|
+
textPreview: truncateText(record.text, 120),
|
|
23269
|
+
qValue,
|
|
23270
|
+
recallCount,
|
|
23271
|
+
lastRecalledAt: recall?.lastRecalledAt,
|
|
23272
|
+
lastReward: recall?.lastReward,
|
|
23273
|
+
taskOutcome: recall?.taskOutcome,
|
|
23274
|
+
promotionCandidate: qValue > promotionThreshold && recallCount > 5,
|
|
23275
|
+
suppressionCandidate: qValue < threshold
|
|
23276
|
+
};
|
|
23277
|
+
});
|
|
23278
|
+
const filtered = entries.filter((entry) => {
|
|
23279
|
+
if (filter.includePromotionCandidatesOnly) {
|
|
23280
|
+
return entry.promotionCandidate;
|
|
23281
|
+
}
|
|
23282
|
+
if (filter.includeSuppressionCandidatesOnly) {
|
|
23283
|
+
return entry.suppressionCandidate;
|
|
23284
|
+
}
|
|
23285
|
+
return true;
|
|
23286
|
+
}).sort((a, b) => (b.lastRecalledAt ?? "").localeCompare(a.lastRecalledAt ?? "") || b.qValue - a.qValue || a.memoryId.localeCompare(b.memoryId));
|
|
23287
|
+
return filtered.slice(0, Math.max(1, Math.trunc(filter.limit ?? 20)));
|
|
23288
|
+
}
|
|
23093
23289
|
async list(filter = {}) {
|
|
23094
23290
|
await this.initialize();
|
|
23095
23291
|
const db = this.requireDb();
|
|
@@ -23314,6 +23510,145 @@ class SQLiteMemoryProvider {
|
|
|
23314
23510
|
this.memories = new Map(kept.map((memory) => [memory.id, memory]));
|
|
23315
23511
|
return result;
|
|
23316
23512
|
}
|
|
23513
|
+
matchingRecallUsageRows(runIds) {
|
|
23514
|
+
const idSet = new Set(runIds.filter((id) => id.length > 0));
|
|
23515
|
+
if (idSet.size === 0)
|
|
23516
|
+
return [];
|
|
23517
|
+
const rows = this.requireDb().query(`SELECT id, usage_json, q_value, last_reward, task_outcome, council_verdict_json, reward_key
|
|
23518
|
+
FROM memory_recall_usage
|
|
23519
|
+
ORDER BY timestamp DESC
|
|
23520
|
+
LIMIT ?`).all(100);
|
|
23521
|
+
const matches = [];
|
|
23522
|
+
const seenRunIds = new Set;
|
|
23523
|
+
for (const row of rows) {
|
|
23524
|
+
if (!row.id)
|
|
23525
|
+
continue;
|
|
23526
|
+
const event = parseRecallUsageRow(row);
|
|
23527
|
+
if (!event?.runId || !idSet.has(event.runId))
|
|
23528
|
+
continue;
|
|
23529
|
+
if (seenRunIds.has(event.runId))
|
|
23530
|
+
continue;
|
|
23531
|
+
seenRunIds.add(event.runId);
|
|
23532
|
+
matches.push({ id: row.id, event, rewardKey: row.reward_key ?? null });
|
|
23533
|
+
}
|
|
23534
|
+
return matches;
|
|
23535
|
+
}
|
|
23536
|
+
updateMemoryQValue(memoryId, rewardSignal, updatedAt) {
|
|
23537
|
+
const current = this.memories.get(memoryId);
|
|
23538
|
+
if (!current)
|
|
23539
|
+
return null;
|
|
23540
|
+
if (current.metadata.deleted === true || current.supersededBy)
|
|
23541
|
+
return null;
|
|
23542
|
+
const eta = this.config.learning.learningRate;
|
|
23543
|
+
const nextQValue = clamp012((1 - eta) * memoryQValue(current) + eta * rewardSignal);
|
|
23544
|
+
const next = {
|
|
23545
|
+
...current,
|
|
23546
|
+
updatedAt,
|
|
23547
|
+
qValue: nextQValue
|
|
23548
|
+
};
|
|
23549
|
+
this.memories.set(memoryId, next);
|
|
23550
|
+
this.writeMemory(next);
|
|
23551
|
+
return nextQValue;
|
|
23552
|
+
}
|
|
23553
|
+
async findPropagationTargets(sourceMemoryIds) {
|
|
23554
|
+
const lookbackIds = this.recentlyRecalledMemoryIds(this.config.learning.propagationLookbackDays);
|
|
23555
|
+
if (lookbackIds.size === 0)
|
|
23556
|
+
return [];
|
|
23557
|
+
const sourceRecords = sourceMemoryIds.map((id) => this.memories.get(id)).filter(isMemoryRecord);
|
|
23558
|
+
if (sourceRecords.length === 0)
|
|
23559
|
+
return [];
|
|
23560
|
+
const targets = [];
|
|
23561
|
+
const sourceTokenSets = sourceRecords.map((record) => tokenizeText(record.text));
|
|
23562
|
+
const cosineEnabled = this.config.embeddings.enabled && Boolean(this.embeddingProvider);
|
|
23563
|
+
const cosineThreshold = this.config.learning.propagationEmbeddingCosineThreshold;
|
|
23564
|
+
const sourceVectors = cosineEnabled ? await Promise.all(sourceRecords.map((record) => this.getCachedEmbeddingForPropagation(record.text))) : [];
|
|
23565
|
+
for (const candidate of this.memories.values()) {
|
|
23566
|
+
if (sourceMemoryIds.includes(candidate.id))
|
|
23567
|
+
continue;
|
|
23568
|
+
if (!lookbackIds.has(candidate.id))
|
|
23569
|
+
continue;
|
|
23570
|
+
if (candidate.metadata.deleted === true || candidate.supersededBy)
|
|
23571
|
+
continue;
|
|
23572
|
+
const candidateTokens = tokenizeText(candidate.text);
|
|
23573
|
+
let bestOverlap = 0;
|
|
23574
|
+
let sameScopeAsAnySource = false;
|
|
23575
|
+
const sameScopeBySourceIndex = [];
|
|
23576
|
+
for (let i = 0;i < sourceRecords.length; i++) {
|
|
23577
|
+
const source = sourceRecords[i];
|
|
23578
|
+
const sameScope2 = stableScopeKey(candidate.scope) === stableScopeKey(source.scope);
|
|
23579
|
+
sameScopeBySourceIndex[i] = sameScope2;
|
|
23580
|
+
if (sameScope2)
|
|
23581
|
+
sameScopeAsAnySource = true;
|
|
23582
|
+
if (!sameScope2 || candidate.kind !== source.kind)
|
|
23583
|
+
continue;
|
|
23584
|
+
bestOverlap = Math.max(bestOverlap, jaccard(sourceTokenSets[i] ?? new Set, candidateTokens));
|
|
23585
|
+
}
|
|
23586
|
+
let bestCosine = 0;
|
|
23587
|
+
if (cosineEnabled && sameScopeAsAnySource) {
|
|
23588
|
+
const candidateVector = await this.getCachedEmbeddingForPropagation(candidate.text);
|
|
23589
|
+
if (candidateVector) {
|
|
23590
|
+
for (let i = 0;i < sourceVectors.length; i++) {
|
|
23591
|
+
if (!sameScopeBySourceIndex[i])
|
|
23592
|
+
continue;
|
|
23593
|
+
const sourceVector = sourceVectors[i];
|
|
23594
|
+
if (!sourceVector)
|
|
23595
|
+
continue;
|
|
23596
|
+
bestCosine = Math.max(bestCosine, cosineSimilarity(sourceVector, candidateVector));
|
|
23597
|
+
}
|
|
23598
|
+
}
|
|
23599
|
+
}
|
|
23600
|
+
const qualifiesByOverlap = bestOverlap >= this.config.learning.propagationTokenOverlapThreshold;
|
|
23601
|
+
const qualifiesByCosine = cosineEnabled && bestCosine >= cosineThreshold;
|
|
23602
|
+
if (qualifiesByOverlap || qualifiesByCosine) {
|
|
23603
|
+
targets.push({
|
|
23604
|
+
id: candidate.id,
|
|
23605
|
+
overlap: Math.max(bestOverlap, bestCosine)
|
|
23606
|
+
});
|
|
23607
|
+
}
|
|
23608
|
+
}
|
|
23609
|
+
return targets.sort((a, b) => b.overlap - a.overlap || a.id.localeCompare(b.id)).slice(0, this.config.learning.propagationFanout).map((target) => target.id);
|
|
23610
|
+
}
|
|
23611
|
+
async getCachedEmbeddingForPropagation(text) {
|
|
23612
|
+
if (!this.embeddingProvider)
|
|
23613
|
+
return null;
|
|
23614
|
+
const modelVersion = this.embeddingProvider.modelVersion;
|
|
23615
|
+
const normalized = normalizeMemoryText(text).toLowerCase();
|
|
23616
|
+
if (!normalized)
|
|
23617
|
+
return null;
|
|
23618
|
+
const cached = this.embeddingCache?.get(modelVersion, normalized)?.vector;
|
|
23619
|
+
if (cached)
|
|
23620
|
+
return cached;
|
|
23621
|
+
try {
|
|
23622
|
+
const vector = await this.embeddingProvider.embed(normalized);
|
|
23623
|
+
this.embeddingCache?.set(modelVersion, normalized, {
|
|
23624
|
+
vector,
|
|
23625
|
+
modelVersion,
|
|
23626
|
+
queryHash: normalized
|
|
23627
|
+
});
|
|
23628
|
+
return vector;
|
|
23629
|
+
} catch {
|
|
23630
|
+
return null;
|
|
23631
|
+
}
|
|
23632
|
+
}
|
|
23633
|
+
recentlyRecalledMemoryIds(lookbackDays) {
|
|
23634
|
+
const cutoffMs = Date.now() - Math.max(0, lookbackDays) * 24 * 60 * 60 * 1000;
|
|
23635
|
+
const memoryIds = new Set;
|
|
23636
|
+
for (const event of this.listRecallUsageSync(500)) {
|
|
23637
|
+
const timestamp = Date.parse(event.timestamp);
|
|
23638
|
+
if (Number.isFinite(timestamp) && timestamp < cutoffMs)
|
|
23639
|
+
continue;
|
|
23640
|
+
for (const memoryId of event.memoryIds)
|
|
23641
|
+
memoryIds.add(memoryId);
|
|
23642
|
+
}
|
|
23643
|
+
return memoryIds;
|
|
23644
|
+
}
|
|
23645
|
+
listRecallUsageSync(limit = 1000) {
|
|
23646
|
+
const rows = this.requireDb().query(`SELECT id, usage_json, q_value, last_reward, task_outcome, council_verdict_json, reward_key
|
|
23647
|
+
FROM memory_recall_usage
|
|
23648
|
+
ORDER BY timestamp DESC
|
|
23649
|
+
LIMIT ?`).all(Math.max(1, Math.trunc(limit)));
|
|
23650
|
+
return rows.map((row) => parseRecallUsageRow(row)).filter(isRecallUsageEvent);
|
|
23651
|
+
}
|
|
23317
23652
|
hasMigration(name) {
|
|
23318
23653
|
const row = this.requireDb().query("SELECT version, name FROM schema_migrations WHERE name = ? LIMIT 1").get(name);
|
|
23319
23654
|
return Boolean(row);
|
|
@@ -23413,7 +23748,13 @@ class SQLiteMemoryProvider {
|
|
|
23413
23748
|
continue;
|
|
23414
23749
|
const apply = db.transaction(() => {
|
|
23415
23750
|
for (const statement of splitSql(migration.sql)) {
|
|
23416
|
-
|
|
23751
|
+
try {
|
|
23752
|
+
db.run(statement);
|
|
23753
|
+
} catch (err) {
|
|
23754
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
23755
|
+
if (!/duplicate column name/i.test(message))
|
|
23756
|
+
throw err;
|
|
23757
|
+
}
|
|
23417
23758
|
}
|
|
23418
23759
|
db.run("INSERT INTO schema_migrations (version, name) VALUES (?, ?)", [
|
|
23419
23760
|
migration.version,
|
|
@@ -23845,6 +24186,178 @@ class SQLiteMemoryProvider {
|
|
|
23845
24186
|
return this.db;
|
|
23846
24187
|
}
|
|
23847
24188
|
}
|
|
24189
|
+
function averageMemoryQValue(records) {
|
|
24190
|
+
if (records.length === 0)
|
|
24191
|
+
return DEFAULT_MEMORY_Q_VALUE;
|
|
24192
|
+
return averageNumbers(records.map((record) => memoryQValue(record)));
|
|
24193
|
+
}
|
|
24194
|
+
function averageNumbers(values) {
|
|
24195
|
+
const finite = values.filter((value) => Number.isFinite(value));
|
|
24196
|
+
if (finite.length === 0)
|
|
24197
|
+
return DEFAULT_MEMORY_Q_VALUE;
|
|
24198
|
+
return finite.reduce((sum, value) => sum + value, 0) / finite.length;
|
|
24199
|
+
}
|
|
24200
|
+
function isMemoryRecord(record) {
|
|
24201
|
+
return record !== undefined;
|
|
24202
|
+
}
|
|
24203
|
+
function isRecallUsageEvent(event) {
|
|
24204
|
+
return event !== null;
|
|
24205
|
+
}
|
|
24206
|
+
function rewardForOutcome(outcome) {
|
|
24207
|
+
switch (outcome) {
|
|
24208
|
+
case "approved":
|
|
24209
|
+
return 1;
|
|
24210
|
+
case "rejected":
|
|
24211
|
+
return -1;
|
|
24212
|
+
case "concerns":
|
|
24213
|
+
case "unknown":
|
|
24214
|
+
return 0;
|
|
24215
|
+
}
|
|
24216
|
+
}
|
|
24217
|
+
function propagatedRewardSignal(reward, propagationFactor) {
|
|
24218
|
+
const factor = Math.max(0, Math.min(1, propagationFactor));
|
|
24219
|
+
return DEFAULT_MEMORY_Q_VALUE + factor * (reward - DEFAULT_MEMORY_Q_VALUE);
|
|
24220
|
+
}
|
|
24221
|
+
function emptyRewardResult(outcome, reason) {
|
|
24222
|
+
return {
|
|
24223
|
+
success: false,
|
|
24224
|
+
outcome,
|
|
24225
|
+
memoryIds: [],
|
|
24226
|
+
reward: rewardForOutcome(outcome),
|
|
24227
|
+
updatedMemoryIds: [],
|
|
24228
|
+
propagatedMemoryIds: [],
|
|
24229
|
+
reason
|
|
24230
|
+
};
|
|
24231
|
+
}
|
|
24232
|
+
function parseRecallUsageRow(row) {
|
|
24233
|
+
try {
|
|
24234
|
+
const parsed = JSON.parse(row.usage_json);
|
|
24235
|
+
if (!Array.isArray(parsed.memoryIds) || typeof parsed.query !== "string") {
|
|
24236
|
+
return null;
|
|
24237
|
+
}
|
|
24238
|
+
const event = { ...parsed };
|
|
24239
|
+
if (typeof row.q_value === "number" && Number.isFinite(row.q_value)) {
|
|
24240
|
+
event.qValue = clamp012(row.q_value);
|
|
24241
|
+
}
|
|
24242
|
+
if (typeof row.last_reward === "number" && Number.isFinite(row.last_reward)) {
|
|
24243
|
+
event.lastReward = row.last_reward;
|
|
24244
|
+
}
|
|
24245
|
+
const taskOutcome = normalizeTaskOutcome(row.task_outcome);
|
|
24246
|
+
if (taskOutcome)
|
|
24247
|
+
event.taskOutcome = taskOutcome;
|
|
24248
|
+
return event;
|
|
24249
|
+
} catch {
|
|
24250
|
+
return null;
|
|
24251
|
+
}
|
|
24252
|
+
}
|
|
24253
|
+
function normalizeTaskOutcome(value) {
|
|
24254
|
+
if (value === "approved" || value === "rejected" || value === "concerns" || value === "unknown") {
|
|
24255
|
+
return value;
|
|
24256
|
+
}
|
|
24257
|
+
return;
|
|
24258
|
+
}
|
|
24259
|
+
function truncateJsonPayload(value) {
|
|
24260
|
+
if (value === undefined)
|
|
24261
|
+
return null;
|
|
24262
|
+
let json;
|
|
24263
|
+
try {
|
|
24264
|
+
json = JSON.stringify(value);
|
|
24265
|
+
} catch (err) {
|
|
24266
|
+
return JSON.stringify({
|
|
24267
|
+
unserializable: true,
|
|
24268
|
+
reason: err instanceof Error ? err.message : String(err)
|
|
24269
|
+
});
|
|
24270
|
+
}
|
|
24271
|
+
const maxLength = 8192;
|
|
24272
|
+
if (json.length <= maxLength)
|
|
24273
|
+
return json;
|
|
24274
|
+
return JSON.stringify({
|
|
24275
|
+
truncated: true,
|
|
24276
|
+
preview: json.slice(0, maxLength - 32)
|
|
24277
|
+
});
|
|
24278
|
+
}
|
|
24279
|
+
function deriveRewardKey(verdictPayload) {
|
|
24280
|
+
if (!verdictPayload || typeof verdictPayload !== "object")
|
|
24281
|
+
return null;
|
|
24282
|
+
const payload = verdictPayload;
|
|
24283
|
+
const swarmId = payload.swarmId;
|
|
24284
|
+
const roundNumber = payload.roundNumber;
|
|
24285
|
+
const unit = payload.taskId ?? payload.phaseNumber;
|
|
24286
|
+
const unitOk = typeof unit === "string" || typeof unit === "number";
|
|
24287
|
+
const roundOk = typeof roundNumber === "string" || typeof roundNumber === "number";
|
|
24288
|
+
if (typeof swarmId !== "string" || swarmId.length === 0 || !unitOk || !roundOk) {
|
|
24289
|
+
return null;
|
|
24290
|
+
}
|
|
24291
|
+
return `${swarmId}:${unit}:${roundNumber}`;
|
|
24292
|
+
}
|
|
24293
|
+
function summarizeRecallUsage(events) {
|
|
24294
|
+
const summary = new Map;
|
|
24295
|
+
for (const event of events) {
|
|
24296
|
+
for (const memoryId of event.memoryIds) {
|
|
24297
|
+
const existing = summary.get(memoryId) ?? {
|
|
24298
|
+
count: 0,
|
|
24299
|
+
lastRecalledAt: event.timestamp
|
|
24300
|
+
};
|
|
24301
|
+
existing.count++;
|
|
24302
|
+
if (event.timestamp >= existing.lastRecalledAt) {
|
|
24303
|
+
existing.lastRecalledAt = event.timestamp;
|
|
24304
|
+
existing.lastReward = event.lastReward;
|
|
24305
|
+
existing.taskOutcome = event.taskOutcome;
|
|
24306
|
+
}
|
|
24307
|
+
summary.set(memoryId, existing);
|
|
24308
|
+
}
|
|
24309
|
+
}
|
|
24310
|
+
return summary;
|
|
24311
|
+
}
|
|
24312
|
+
function uniqueStrings(values) {
|
|
24313
|
+
return Array.from(new Set(values.filter((value) => value.length > 0)));
|
|
24314
|
+
}
|
|
24315
|
+
function truncateText(value, maxLength) {
|
|
24316
|
+
if (value.length <= maxLength)
|
|
24317
|
+
return value;
|
|
24318
|
+
return `${value.slice(0, maxLength - 3)}...`;
|
|
24319
|
+
}
|
|
24320
|
+
function tokenizeText(value) {
|
|
24321
|
+
const tokens = new Set;
|
|
24322
|
+
for (const match of value.toLowerCase().matchAll(/[a-z0-9_]{3,}/g)) {
|
|
24323
|
+
const token = match[0];
|
|
24324
|
+
if (!FTS_STOP_WORDS.has(token))
|
|
24325
|
+
tokens.add(token);
|
|
24326
|
+
}
|
|
24327
|
+
return tokens;
|
|
24328
|
+
}
|
|
24329
|
+
function jaccard(left, right) {
|
|
24330
|
+
if (left.size === 0 || right.size === 0)
|
|
24331
|
+
return 0;
|
|
24332
|
+
let intersection = 0;
|
|
24333
|
+
for (const token of left) {
|
|
24334
|
+
if (right.has(token))
|
|
24335
|
+
intersection++;
|
|
24336
|
+
}
|
|
24337
|
+
const union = left.size + right.size - intersection;
|
|
24338
|
+
return union > 0 ? intersection / union : 0;
|
|
24339
|
+
}
|
|
24340
|
+
function cosineSimilarity(a, b) {
|
|
24341
|
+
if (a.length === 0 || a.length !== b.length)
|
|
24342
|
+
return 0;
|
|
24343
|
+
let dot = 0;
|
|
24344
|
+
let normA = 0;
|
|
24345
|
+
let normB = 0;
|
|
24346
|
+
for (let i = 0;i < a.length; i++) {
|
|
24347
|
+
dot += a[i] * b[i];
|
|
24348
|
+
normA += a[i] * a[i];
|
|
24349
|
+
normB += b[i] * b[i];
|
|
24350
|
+
}
|
|
24351
|
+
if (normA === 0 || normB === 0)
|
|
24352
|
+
return 0;
|
|
24353
|
+
const similarity = dot / (Math.sqrt(normA) * Math.sqrt(normB));
|
|
24354
|
+
return Number.isFinite(similarity) ? similarity : 0;
|
|
24355
|
+
}
|
|
24356
|
+
function clamp012(value) {
|
|
24357
|
+
if (!Number.isFinite(value))
|
|
24358
|
+
return DEFAULT_MEMORY_Q_VALUE;
|
|
24359
|
+
return Math.min(1, Math.max(0, value));
|
|
24360
|
+
}
|
|
23848
24361
|
function splitSql(sql) {
|
|
23849
24362
|
const statements = [];
|
|
23850
24363
|
let current = "";
|
|
@@ -24154,6 +24667,21 @@ function resolvePoolKey(directory) {
|
|
|
24154
24667
|
return path47.resolve(directory);
|
|
24155
24668
|
}
|
|
24156
24669
|
}
|
|
24670
|
+
function evictAndClose(directory) {
|
|
24671
|
+
const key = resolvePoolKey(directory);
|
|
24672
|
+
const active = entriesByKey.get(key);
|
|
24673
|
+
if (active) {
|
|
24674
|
+
entriesByKey.delete(key);
|
|
24675
|
+
unlinkEntry(active);
|
|
24676
|
+
callRealClose(active.provider);
|
|
24677
|
+
}
|
|
24678
|
+
for (const deferred of [...deferredEntries]) {
|
|
24679
|
+
if (deferred.key === key) {
|
|
24680
|
+
deferredEntries.delete(deferred);
|
|
24681
|
+
callRealClose(deferred.provider);
|
|
24682
|
+
}
|
|
24683
|
+
}
|
|
24684
|
+
}
|
|
24157
24685
|
|
|
24158
24686
|
// src/memory/gateway.ts
|
|
24159
24687
|
function createConfiguredMemoryProvider(directory, config) {
|
|
@@ -24256,7 +24784,8 @@ async function evaluateMemoryRecallFixtures(options) {
|
|
|
24256
24784
|
} finally {
|
|
24257
24785
|
await provider.close?.();
|
|
24258
24786
|
if (!options.keepTempRoots) {
|
|
24259
|
-
|
|
24787
|
+
evictAndClose(tempRoot);
|
|
24788
|
+
await rmTempRoot(tempRoot);
|
|
24260
24789
|
}
|
|
24261
24790
|
}
|
|
24262
24791
|
}
|
|
@@ -24271,6 +24800,18 @@ async function evaluateMemoryRecallFixtures(options) {
|
|
|
24271
24800
|
runs
|
|
24272
24801
|
};
|
|
24273
24802
|
}
|
|
24803
|
+
async function rmTempRoot(tempRoot) {
|
|
24804
|
+
for (let attempt = 0;attempt < 10; attempt++) {
|
|
24805
|
+
try {
|
|
24806
|
+
await fs19.rm(tempRoot, { recursive: true, force: true });
|
|
24807
|
+
return;
|
|
24808
|
+
} catch (err) {
|
|
24809
|
+
if (attempt === 9)
|
|
24810
|
+
throw err;
|
|
24811
|
+
await new Promise((resolve13) => setTimeout(resolve13, 50));
|
|
24812
|
+
}
|
|
24813
|
+
}
|
|
24814
|
+
}
|
|
24274
24815
|
async function loadRecallEvaluationFixtures(fixtureDirectory) {
|
|
24275
24816
|
const entries = await fs19.readdir(fixtureDirectory, { withFileTypes: true });
|
|
24276
24817
|
const files = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
|
|
@@ -24585,6 +25126,7 @@ async function handleMemoryCommand(_directory, _args) {
|
|
|
24585
25126
|
"- `/swarm memory status` - show provider, SQLite path, JSONL files, and last migration report",
|
|
24586
25127
|
"- `/swarm memory pending` - show pending proposals and recent rejection reasons",
|
|
24587
25128
|
"- `/swarm memory recall-log` - summarize recall usage by agent role and memory ID",
|
|
25129
|
+
"- `/swarm memory value-log` - show recent Q-value, reward, suppression, and promotion signals",
|
|
24588
25130
|
"- `/swarm memory stale` - list expired scratch, superseded, deleted, and low-utility memories",
|
|
24589
25131
|
"- `/swarm memory compact` - dry-run compaction; pass `--confirm` to remove deleted, superseded, and expired scratch records",
|
|
24590
25132
|
"- `/swarm memory export` - export current memory and proposals to `.swarm/memory/export/*.jsonl`",
|
|
@@ -24679,10 +25221,12 @@ async function handleMemoryPendingCommand(directory, args) {
|
|
|
24679
25221
|
"## Swarm Memory Pending",
|
|
24680
25222
|
"",
|
|
24681
25223
|
`- Pending proposals shown: \`${report.pendingProposals.length}\``,
|
|
24682
|
-
`- Rejected proposal reasons shown: \`${report.rejectedProposalReasons.length}
|
|
25224
|
+
`- Rejected proposal reasons shown: \`${report.rejectedProposalReasons.length}\``,
|
|
25225
|
+
`- Promotion candidates shown: \`${report.promotionCandidates.length}\``
|
|
24683
25226
|
];
|
|
24684
25227
|
appendProposalLines(lines, "Pending proposals", report.pendingProposals);
|
|
24685
25228
|
appendProposalLines(lines, "Rejected proposal reasons", report.rejectedProposalReasons);
|
|
25229
|
+
appendValueLogLines(lines, "Promotion candidates", report.promotionCandidates);
|
|
24686
25230
|
return lines.join(`
|
|
24687
25231
|
`);
|
|
24688
25232
|
} finally {
|
|
@@ -24719,6 +25263,39 @@ async function handleMemoryRecallLogCommand(directory, args) {
|
|
|
24719
25263
|
await provider.close?.();
|
|
24720
25264
|
}
|
|
24721
25265
|
}
|
|
25266
|
+
async function handleMemoryValueLogCommand(directory, args) {
|
|
25267
|
+
const parsed = parseMaintenanceArgs(args, {
|
|
25268
|
+
usage: "Usage: /swarm memory value-log [--limit <n>]",
|
|
25269
|
+
allowConfirm: false
|
|
25270
|
+
});
|
|
25271
|
+
if ("error" in parsed)
|
|
25272
|
+
return parsed.error;
|
|
25273
|
+
const config = resolveCommandMemoryConfig(directory);
|
|
25274
|
+
const provider = createMaintenanceProvider(directory, config);
|
|
25275
|
+
try {
|
|
25276
|
+
await provider.initialize?.();
|
|
25277
|
+
if (!provider.listMemoryValueLog) {
|
|
25278
|
+
return "Memory provider does not support value-log reporting.";
|
|
25279
|
+
}
|
|
25280
|
+
const valueLog = await provider.listMemoryValueLog({ limit: parsed.limit });
|
|
25281
|
+
const promotionCandidates = valueLog.filter((entry) => entry.promotionCandidate);
|
|
25282
|
+
const suppressionCandidates = valueLog.filter((entry) => entry.suppressionCandidate);
|
|
25283
|
+
const lines = [
|
|
25284
|
+
"## Swarm Memory Value Log",
|
|
25285
|
+
"",
|
|
25286
|
+
`- Entries shown: \`${valueLog.length}\``,
|
|
25287
|
+
`- Promotion candidates shown: \`${promotionCandidates.length}\``,
|
|
25288
|
+
`- Suppression candidates shown: \`${suppressionCandidates.length}\``
|
|
25289
|
+
];
|
|
25290
|
+
appendValueLogLines(lines, "Recent Q-value updates", valueLog);
|
|
25291
|
+
appendValueLogLines(lines, "Promotion candidates", promotionCandidates);
|
|
25292
|
+
appendValueLogLines(lines, "Suppression candidates", suppressionCandidates);
|
|
25293
|
+
return lines.join(`
|
|
25294
|
+
`);
|
|
25295
|
+
} finally {
|
|
25296
|
+
await provider.close?.();
|
|
25297
|
+
}
|
|
25298
|
+
}
|
|
24722
25299
|
async function handleMemoryStaleCommand(directory, args) {
|
|
24723
25300
|
const parsed = parseMaintenanceArgs(args, {
|
|
24724
25301
|
usage: "Usage: /swarm memory stale [--limit <n>]",
|
|
@@ -24740,12 +25317,14 @@ async function handleMemoryStaleCommand(directory, args) {
|
|
|
24740
25317
|
`- Expired scratch memories shown: \`${report.expiredScratchMemories.length}\``,
|
|
24741
25318
|
`- Deleted tombstones shown: \`${report.deletedMemories.length}\``,
|
|
24742
25319
|
`- Superseded memories shown: \`${report.supersededMemories.length}\``,
|
|
24743
|
-
`- Low-utility memories shown: \`${report.lowUtilityMemories.length}
|
|
25320
|
+
`- Low-utility memories shown: \`${report.lowUtilityMemories.length}\``,
|
|
25321
|
+
`- Low-Q memories shown: \`${report.lowQValueMemories.length}\``
|
|
24744
25322
|
];
|
|
24745
25323
|
appendMemoryLines(lines, "Expired scratch memories", report.expiredScratchMemories);
|
|
24746
25324
|
appendMemoryLines(lines, "Deleted tombstones", report.deletedMemories);
|
|
24747
25325
|
appendSupersededChains(lines, report);
|
|
24748
25326
|
appendMemoryLines(lines, "Low-utility memories", report.lowUtilityMemories);
|
|
25327
|
+
appendValueLogLines(lines, "Low-Q memories", report.lowQValueMemories);
|
|
24749
25328
|
return lines.join(`
|
|
24750
25329
|
`);
|
|
24751
25330
|
} finally {
|
|
@@ -25022,6 +25601,19 @@ function appendRecallMemoryLines(lines, memories) {
|
|
|
25022
25601
|
lines.push(`- \`${memory.memoryId}\`: ${memory.count} hit(s), last=${memory.lastRecalledAt}, avgScore=${memory.averageScore.toFixed(3)}`);
|
|
25023
25602
|
}
|
|
25024
25603
|
}
|
|
25604
|
+
function appendValueLogLines(lines, title, entries) {
|
|
25605
|
+
lines.push("", `### ${title}`);
|
|
25606
|
+
if (entries.length === 0) {
|
|
25607
|
+
lines.push("- none");
|
|
25608
|
+
return;
|
|
25609
|
+
}
|
|
25610
|
+
for (const entry of entries) {
|
|
25611
|
+
const outcome = entry.taskOutcome ? ` outcome=${entry.taskOutcome}` : "";
|
|
25612
|
+
const reward = typeof entry.lastReward === "number" ? ` reward=${entry.lastReward.toFixed(2)}` : "";
|
|
25613
|
+
const last = entry.lastRecalledAt ? ` last=${entry.lastRecalledAt}` : "";
|
|
25614
|
+
lines.push(`- \`${entry.memoryId}\` ${entry.kind} q=${entry.qValue.toFixed(3)} recalls=${entry.recallCount}${reward}${outcome}${last} - ${entry.textPreview}`);
|
|
25615
|
+
}
|
|
25616
|
+
}
|
|
25025
25617
|
function appendSupersededChains(lines, report) {
|
|
25026
25618
|
lines.push("", "### Superseded chains");
|
|
25027
25619
|
if (report.supersededChains.length === 0) {
|
|
@@ -33373,7 +33965,7 @@ function buildDetailedHelp(commandName, entry) {
|
|
|
33373
33965
|
async function handleHelpCommand(ctx) {
|
|
33374
33966
|
const targetCommand = ctx.args.join(" ");
|
|
33375
33967
|
if (!targetCommand) {
|
|
33376
|
-
const { buildHelpText } = await import("./index-
|
|
33968
|
+
const { buildHelpText } = await import("./index-e7nhwa9k.js");
|
|
33377
33969
|
return buildHelpText();
|
|
33378
33970
|
}
|
|
33379
33971
|
const tokens = targetCommand.split(/\s+/);
|
|
@@ -33382,7 +33974,7 @@ async function handleHelpCommand(ctx) {
|
|
|
33382
33974
|
return _internals47.buildDetailedHelp(resolved.key, resolved.entry);
|
|
33383
33975
|
}
|
|
33384
33976
|
const similar = _internals47.findSimilarCommands(targetCommand);
|
|
33385
|
-
const { buildHelpText: fullHelp } = await import("./index-
|
|
33977
|
+
const { buildHelpText: fullHelp } = await import("./index-e7nhwa9k.js");
|
|
33386
33978
|
if (similar.length > 0) {
|
|
33387
33979
|
return `Command '/swarm ${targetCommand}' not found.
|
|
33388
33980
|
|
|
@@ -33515,7 +34107,7 @@ var COMMAND_REGISTRY = {
|
|
|
33515
34107
|
},
|
|
33516
34108
|
"guardrail explain": {
|
|
33517
34109
|
handler: async (ctx) => {
|
|
33518
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
34110
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-2zat1bxh.js");
|
|
33519
34111
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
33520
34112
|
},
|
|
33521
34113
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -33525,7 +34117,7 @@ var COMMAND_REGISTRY = {
|
|
|
33525
34117
|
},
|
|
33526
34118
|
"guardrail-log": {
|
|
33527
34119
|
handler: async (ctx) => {
|
|
33528
|
-
const { handleGuardrailLog } = await import("./guardrail-log-
|
|
34120
|
+
const { handleGuardrailLog } = await import("./guardrail-log-zhshjbpk.js");
|
|
33529
34121
|
return handleGuardrailLog(ctx.directory, ctx.args);
|
|
33530
34122
|
},
|
|
33531
34123
|
description: "Read the guardrail decision log (use --blocks-only for blocks)",
|
|
@@ -34184,6 +34776,14 @@ Subcommands:
|
|
|
34184
34776
|
category: "diagnostics",
|
|
34185
34777
|
toolPolicy: "agent"
|
|
34186
34778
|
},
|
|
34779
|
+
"memory value-log": {
|
|
34780
|
+
handler: (ctx) => handleMemoryValueLogCommand(ctx.directory, ctx.args),
|
|
34781
|
+
description: "Show Swarm memory Q-value and reward updates",
|
|
34782
|
+
subcommandOf: "memory",
|
|
34783
|
+
args: "--limit <n>",
|
|
34784
|
+
category: "diagnostics",
|
|
34785
|
+
toolPolicy: "agent"
|
|
34786
|
+
},
|
|
34187
34787
|
"memory compact": {
|
|
34188
34788
|
handler: (ctx) => handleMemoryCompactCommand(ctx.directory, ctx.args),
|
|
34189
34789
|
description: "Compact deleted, superseded, and expired scratch memories",
|
|
@@ -34459,4 +35059,4 @@ ${text}`;
|
|
|
34459
35059
|
};
|
|
34460
35060
|
}
|
|
34461
35061
|
|
|
34462
|
-
export { package_default, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, DC_SAFE_TARGETS, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcValidateTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleClarifyCommand, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS, _internals47 as _internals, resolveCommand };
|
|
35062
|
+
export { package_default, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, DC_SAFE_TARGETS, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcValidateTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleClarifyCommand, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryValueLogCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS, _internals47 as _internals, resolveCommand };
|