@remnic/bench 9.6.10 → 9.6.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +11 -0
- package/dist/index.js +292 -12
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -131,6 +131,17 @@ interface BenchMemoryAdapter {
|
|
|
131
131
|
store(sessionId: string, messages: Message[], control?: BenchPhaseControl): Promise<void>;
|
|
132
132
|
recall(sessionId: string, query: string, budgetChars?: number, options?: BenchRecallOptions, control?: BenchPhaseControl): Promise<string>;
|
|
133
133
|
search(query: string, limit: number, sessionId?: string, control?: BenchPhaseControl): Promise<SearchResult[]>;
|
|
134
|
+
/**
|
|
135
|
+
* Optional explicit-correction surface (issue #1584 plan item 2a). Routes a
|
|
136
|
+
* natural-language correction through the system's correction contract
|
|
137
|
+
* (plan + confirmed apply) instead of a plain turn store. Resolves
|
|
138
|
+
* `{ applied: false }` when the planner produced no applicable actions so
|
|
139
|
+
* the caller can fall back to the turn path. Adapters without an explicit
|
|
140
|
+
* correction surface omit this method entirely.
|
|
141
|
+
*/
|
|
142
|
+
correct?(sessionId: string, text: string, at?: string, control?: BenchPhaseControl): Promise<{
|
|
143
|
+
applied: boolean;
|
|
144
|
+
}>;
|
|
134
145
|
reset(sessionId?: string, control?: BenchPhaseControl): Promise<void>;
|
|
135
146
|
getStats(sessionId?: string, control?: BenchPhaseControl): Promise<MemoryStats>;
|
|
136
147
|
/** Wait for background summarization (e.g. LCM) to finish after store(). */
|
package/dist/index.js
CHANGED
|
@@ -620,6 +620,7 @@ import {
|
|
|
620
620
|
buildExplicitCueRecallSection,
|
|
621
621
|
buildTrajectoryAnalysisRecallSection,
|
|
622
622
|
collectExplicitTurnReferences,
|
|
623
|
+
EngramAccessService,
|
|
623
624
|
expandTildePath,
|
|
624
625
|
normalizeTurnExpansionEnd,
|
|
625
626
|
Orchestrator,
|
|
@@ -1131,6 +1132,27 @@ function benchCoreMemoryTier(memory) {
|
|
|
1131
1132
|
function benchCoreMemorySource(sessionId) {
|
|
1132
1133
|
return `bench-replay-${createHash("sha256").update(sessionId).digest("hex").slice(0, 16)}`;
|
|
1133
1134
|
}
|
|
1135
|
+
function resolveSessionScopedCorrectionDecision(plan, ownedIds, phase) {
|
|
1136
|
+
const actionTargets = [];
|
|
1137
|
+
for (const action of plan.actions) {
|
|
1138
|
+
if (action.kind === "supersede") actionTargets.push(action.loserId);
|
|
1139
|
+
else if (action.kind !== "redaction_rule") actionTargets.push(action.memoryId);
|
|
1140
|
+
}
|
|
1141
|
+
const foreignIds = actionTargets.filter((id) => !ownedIds.has(id));
|
|
1142
|
+
if (phase === "initial") {
|
|
1143
|
+
const ownedAffected = plan.affected.filter((entry) => ownedIds.has(entry.memoryId));
|
|
1144
|
+
if (plan.affected.length > 0 && ownedAffected.length === 0) {
|
|
1145
|
+
return { kind: "no-owned-target" };
|
|
1146
|
+
}
|
|
1147
|
+
if (ownedAffected.length < plan.affected.length) {
|
|
1148
|
+
return { kind: "replan", targetIds: ownedAffected.map((entry) => entry.memoryId) };
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
if (foreignIds.length > 0) {
|
|
1152
|
+
return { kind: "foreign-actions", foreignIds };
|
|
1153
|
+
}
|
|
1154
|
+
return { kind: "proceed" };
|
|
1155
|
+
}
|
|
1134
1156
|
function benchEntityStructuredFactSourceDir(memoryDir) {
|
|
1135
1157
|
return path.join(memoryDir, "state", "bench-entity-structured-facts");
|
|
1136
1158
|
}
|
|
@@ -1837,6 +1859,16 @@ function createAdapterFactory(mode) {
|
|
|
1837
1859
|
coreReplayChain = coreReplayChain.catch(() => void 0).then(() => trackedCleanup).catch(() => void 0);
|
|
1838
1860
|
void trackedCleanup;
|
|
1839
1861
|
};
|
|
1862
|
+
let correctionAccess;
|
|
1863
|
+
const getCorrectionAccess = () => {
|
|
1864
|
+
if (!correctionAccess || correctionAccess.orchestrator !== state.orchestrator) {
|
|
1865
|
+
correctionAccess = {
|
|
1866
|
+
service: new EngramAccessService(state.orchestrator),
|
|
1867
|
+
orchestrator: state.orchestrator
|
|
1868
|
+
};
|
|
1869
|
+
}
|
|
1870
|
+
return correctionAccess.service;
|
|
1871
|
+
};
|
|
1840
1872
|
return {
|
|
1841
1873
|
async store(sessionId, messages, control) {
|
|
1842
1874
|
throwIfBenchPhaseAborted(control, "store");
|
|
@@ -2381,6 +2413,71 @@ ${expanded.map((message) => `[${message.role}]: ${message.content}`).join("\n")}
|
|
|
2381
2413
|
});
|
|
2382
2414
|
sessionTurnCounters.clear();
|
|
2383
2415
|
},
|
|
2416
|
+
async correct(sessionId, text, _at, control) {
|
|
2417
|
+
throwIfBenchPhaseAborted(control, "correct");
|
|
2418
|
+
sessionId = normalizeBenchSessionId(sessionId);
|
|
2419
|
+
const access2 = getCorrectionAccess();
|
|
2420
|
+
const discardPlan = async (planId) => {
|
|
2421
|
+
await access2.correctionDiscard(planId, { sessionKey: sessionId }).catch(() => void 0);
|
|
2422
|
+
};
|
|
2423
|
+
let plan = await withBenchPhaseAbort(
|
|
2424
|
+
access2.correctionPlan({ text, sessionKey: sessionId }),
|
|
2425
|
+
control,
|
|
2426
|
+
"correct"
|
|
2427
|
+
);
|
|
2428
|
+
const sessionSource = benchCoreMemorySource(sessionId);
|
|
2429
|
+
const owned = new Set(
|
|
2430
|
+
(await readBenchCoreMemories(state.orchestrator)).filter((memory) => memory.frontmatter.source === sessionSource).map((memory) => memory.frontmatter.id)
|
|
2431
|
+
);
|
|
2432
|
+
let replanned = false;
|
|
2433
|
+
const decision = resolveSessionScopedCorrectionDecision(plan, owned, "initial");
|
|
2434
|
+
if (decision.kind === "no-owned-target") {
|
|
2435
|
+
await discardPlan(plan.planId);
|
|
2436
|
+
return { applied: false };
|
|
2437
|
+
}
|
|
2438
|
+
if (decision.kind === "replan") {
|
|
2439
|
+
await discardPlan(plan.planId);
|
|
2440
|
+
replanned = true;
|
|
2441
|
+
plan = await withBenchPhaseAbort(
|
|
2442
|
+
access2.correctionPlan({
|
|
2443
|
+
text,
|
|
2444
|
+
sessionKey: sessionId,
|
|
2445
|
+
targetIds: decision.targetIds
|
|
2446
|
+
}),
|
|
2447
|
+
control,
|
|
2448
|
+
"correct"
|
|
2449
|
+
);
|
|
2450
|
+
}
|
|
2451
|
+
const finalDecision = resolveSessionScopedCorrectionDecision(
|
|
2452
|
+
plan,
|
|
2453
|
+
owned,
|
|
2454
|
+
replanned ? "replanned" : "initial"
|
|
2455
|
+
);
|
|
2456
|
+
if (finalDecision.kind === "foreign-actions") {
|
|
2457
|
+
await discardPlan(plan.planId);
|
|
2458
|
+
throw new Error(
|
|
2459
|
+
`correction plan drafts actions against ${finalDecision.foreignIds.length} foreign-session memory(ies) (${finalDecision.foreignIds.join(", ")}) \u2014 the bench harness cannot scope this correction; refusing to apply or mismeasure`
|
|
2460
|
+
);
|
|
2461
|
+
}
|
|
2462
|
+
if (plan.actions.length === 0) {
|
|
2463
|
+
await discardPlan(plan.planId);
|
|
2464
|
+
if (replanned || plan.affected.length > 0) {
|
|
2465
|
+
throw new Error(
|
|
2466
|
+
`correction planner drafted no applicable action (${replanned ? "re-planned with explicit session-owned targets" : `${plan.affected.length} candidate(s) located`}; warnings: ${plan.warnings.join("; ") || "none"}) \u2014 refusing to measure the turn path as contract behavior`
|
|
2467
|
+
);
|
|
2468
|
+
}
|
|
2469
|
+
return { applied: false };
|
|
2470
|
+
}
|
|
2471
|
+
const outcome = await withBenchPhaseAbort(
|
|
2472
|
+
access2.correctionApply(plan.planId, {
|
|
2473
|
+
confirm: true,
|
|
2474
|
+
sessionKey: sessionId
|
|
2475
|
+
}),
|
|
2476
|
+
control,
|
|
2477
|
+
"correct"
|
|
2478
|
+
);
|
|
2479
|
+
return { applied: outcome.status === "applied" };
|
|
2480
|
+
},
|
|
2384
2481
|
async drain(control) {
|
|
2385
2482
|
throwIfBenchPhaseAborted(control, "drain");
|
|
2386
2483
|
const engine = getEngine();
|
|
@@ -3328,6 +3425,16 @@ function createTimeoutGuardedAdapter(adapter, options) {
|
|
|
3328
3425
|
drainTimeoutMs
|
|
3329
3426
|
);
|
|
3330
3427
|
}
|
|
3428
|
+
if (adapter.correct) {
|
|
3429
|
+
wrapped.correct = (sessionId, text, at, control) => phaseTimeoutMs === void 0 ? adapter.correct(sessionId, text, at, control) : run(`correct session=${sessionId}`, async (signal) => {
|
|
3430
|
+
const merged = mergeBenchPhaseControl(signal, control);
|
|
3431
|
+
try {
|
|
3432
|
+
return await adapter.correct(sessionId, text, at, merged.control);
|
|
3433
|
+
} finally {
|
|
3434
|
+
merged.cleanup();
|
|
3435
|
+
}
|
|
3436
|
+
});
|
|
3437
|
+
}
|
|
3331
3438
|
if (adapter.responder) {
|
|
3332
3439
|
wrapped.responder = phaseTimeoutMs === void 0 ? adapter.responder : wrapResponder(adapter.responder, run);
|
|
3333
3440
|
}
|
|
@@ -7041,7 +7148,9 @@ var ClaudeCliProvider = class {
|
|
|
7041
7148
|
try {
|
|
7042
7149
|
const request = this.buildRunRequest(prompt, opts, tempDir);
|
|
7043
7150
|
const result = await this.runClaudeCli(request);
|
|
7044
|
-
|
|
7151
|
+
const payload = parseClaudeCliJsonResult(result.stdout);
|
|
7152
|
+
const salvageableDespiteExit = !result.stderr.includes("Claude CLI timed out") && !result.stderr.includes("Claude CLI aborted by benchmark timeout") && result.signal === null && !isClaudeCliErrorFlagSet(payload.is_error) && typeof payload.result === "string" && payload.result.trim().length > 0;
|
|
7153
|
+
if (result.status !== 0 && !salvageableDespiteExit) {
|
|
7045
7154
|
if (isClaudeUsageLimitSignal(`${result.stderr}
|
|
7046
7155
|
${result.stdout}`)) {
|
|
7047
7156
|
await sleepBeforeUsageLimitRetry({
|
|
@@ -7055,8 +7164,9 @@ ${result.stdout}`)) {
|
|
|
7055
7164
|
continue;
|
|
7056
7165
|
}
|
|
7057
7166
|
const exitLabel = result.signal ? `signal ${result.signal}` : `exit ${result.status ?? "unknown"}`;
|
|
7167
|
+
const stdoutHead = result.stdout.trim().slice(0, 300);
|
|
7058
7168
|
const error = new Error(
|
|
7059
|
-
`Claude CLI completion failed (${exitLabel}): ${summarizeProcessOutput(result.stderr, result.stdout)}`
|
|
7169
|
+
`Claude CLI completion failed (${exitLabel}): ${stdoutHead.length > 0 ? `head=${JSON.stringify(stdoutHead)} tail=` : ""}${summarizeProcessOutput(result.stderr, result.stdout)}`
|
|
7060
7170
|
);
|
|
7061
7171
|
if (transientAttempt < maxAttempts && isRetryableClaudeCliResult(result)) {
|
|
7062
7172
|
await sleepBeforeClaudeCliRetry({
|
|
@@ -7071,7 +7181,11 @@ ${result.stdout}`)) {
|
|
|
7071
7181
|
}
|
|
7072
7182
|
throw error;
|
|
7073
7183
|
}
|
|
7074
|
-
|
|
7184
|
+
if (result.stderr.includes("Claude CLI timed out") || result.stderr.includes("Claude CLI aborted by benchmark timeout")) {
|
|
7185
|
+
throw new Error(
|
|
7186
|
+
`Claude CLI completion was killed (timeout/abort): ${summarizeProcessOutput(result.stderr, result.stdout)}`
|
|
7187
|
+
);
|
|
7188
|
+
}
|
|
7075
7189
|
if (isClaudeCliErrorFlagSet(payload.is_error)) {
|
|
7076
7190
|
if (isClaudeUsageLimitSignal(
|
|
7077
7191
|
`${result.stderr}
|
|
@@ -7208,6 +7322,7 @@ function buildClaudeCompletionPrompt(userPrompt) {
|
|
|
7208
7322
|
].join("\n");
|
|
7209
7323
|
}
|
|
7210
7324
|
var CLAUDE_CLI_MAX_OUTPUT_TOKENS_ENV = "CLAUDE_CODE_MAX_OUTPUT_TOKENS";
|
|
7325
|
+
var CLAUDE_CLI_OUTPUT_TOKENS_ENV_FLOOR = 4096;
|
|
7211
7326
|
function buildIsolatedClaudeEnv(config, maxTokens) {
|
|
7212
7327
|
const env = {};
|
|
7213
7328
|
for (const [key, value] of Object.entries(process.env)) {
|
|
@@ -7222,7 +7337,9 @@ function buildIsolatedClaudeEnv(config, maxTokens) {
|
|
|
7222
7337
|
env.ANTHROPIC_BASE_URL = config.baseUrl.trim();
|
|
7223
7338
|
}
|
|
7224
7339
|
if (typeof maxTokens === "number" && Number.isFinite(maxTokens) && maxTokens > 0) {
|
|
7225
|
-
env[CLAUDE_CLI_MAX_OUTPUT_TOKENS_ENV] = String(
|
|
7340
|
+
env[CLAUDE_CLI_MAX_OUTPUT_TOKENS_ENV] = String(
|
|
7341
|
+
Math.max(Math.floor(maxTokens), CLAUDE_CLI_OUTPUT_TOKENS_ENV_FLOOR)
|
|
7342
|
+
);
|
|
7226
7343
|
}
|
|
7227
7344
|
return env;
|
|
7228
7345
|
}
|
|
@@ -7262,6 +7379,18 @@ function parseClaudeCliJsonResult(stdout) {
|
|
|
7262
7379
|
}
|
|
7263
7380
|
return parsed;
|
|
7264
7381
|
} catch {
|
|
7382
|
+
const lines = trimmed.split(/\r?\n/);
|
|
7383
|
+
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
7384
|
+
const line = lines[index].trim();
|
|
7385
|
+
if (!line.startsWith("{") || !line.endsWith("}")) continue;
|
|
7386
|
+
try {
|
|
7387
|
+
const parsed = JSON.parse(line);
|
|
7388
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
7389
|
+
return parsed;
|
|
7390
|
+
}
|
|
7391
|
+
} catch {
|
|
7392
|
+
}
|
|
7393
|
+
}
|
|
7265
7394
|
return { is_error: true, error: trimmed.slice(-1e3) };
|
|
7266
7395
|
}
|
|
7267
7396
|
}
|
|
@@ -31955,6 +32084,142 @@ function computeMetricBundle(args) {
|
|
|
31955
32084
|
}
|
|
31956
32085
|
|
|
31957
32086
|
// src/benchmarks/remnic/memcorrect/adapters.ts
|
|
32087
|
+
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
32088
|
+
"the",
|
|
32089
|
+
"a",
|
|
32090
|
+
"an",
|
|
32091
|
+
"is",
|
|
32092
|
+
"are",
|
|
32093
|
+
"was",
|
|
32094
|
+
"were",
|
|
32095
|
+
"to",
|
|
32096
|
+
"of",
|
|
32097
|
+
"for",
|
|
32098
|
+
"and",
|
|
32099
|
+
"or",
|
|
32100
|
+
"but",
|
|
32101
|
+
"in",
|
|
32102
|
+
"on",
|
|
32103
|
+
"at",
|
|
32104
|
+
"by",
|
|
32105
|
+
"it",
|
|
32106
|
+
"my",
|
|
32107
|
+
"your",
|
|
32108
|
+
"we",
|
|
32109
|
+
"you",
|
|
32110
|
+
"i",
|
|
32111
|
+
"me",
|
|
32112
|
+
"this",
|
|
32113
|
+
"that",
|
|
32114
|
+
"with",
|
|
32115
|
+
"from",
|
|
32116
|
+
"not",
|
|
32117
|
+
"have",
|
|
32118
|
+
"has",
|
|
32119
|
+
"do",
|
|
32120
|
+
"does",
|
|
32121
|
+
"did",
|
|
32122
|
+
"be",
|
|
32123
|
+
"been",
|
|
32124
|
+
"being",
|
|
32125
|
+
"will",
|
|
32126
|
+
"would",
|
|
32127
|
+
"should",
|
|
32128
|
+
"could",
|
|
32129
|
+
"can",
|
|
32130
|
+
"may",
|
|
32131
|
+
"might",
|
|
32132
|
+
"must",
|
|
32133
|
+
"shall",
|
|
32134
|
+
"if",
|
|
32135
|
+
"then",
|
|
32136
|
+
"than",
|
|
32137
|
+
"so",
|
|
32138
|
+
"as",
|
|
32139
|
+
"go",
|
|
32140
|
+
"going",
|
|
32141
|
+
"forward",
|
|
32142
|
+
"instead",
|
|
32143
|
+
"last",
|
|
32144
|
+
"month",
|
|
32145
|
+
"now",
|
|
32146
|
+
"their",
|
|
32147
|
+
"them",
|
|
32148
|
+
"they",
|
|
32149
|
+
"he",
|
|
32150
|
+
"she",
|
|
32151
|
+
"his",
|
|
32152
|
+
"her",
|
|
32153
|
+
"got",
|
|
32154
|
+
"noting",
|
|
32155
|
+
"noted",
|
|
32156
|
+
"what",
|
|
32157
|
+
"setting",
|
|
32158
|
+
"preference",
|
|
32159
|
+
"update",
|
|
32160
|
+
"actually",
|
|
32161
|
+
"back",
|
|
32162
|
+
"went",
|
|
32163
|
+
"consider",
|
|
32164
|
+
"decided",
|
|
32165
|
+
"might",
|
|
32166
|
+
"someone",
|
|
32167
|
+
"asked",
|
|
32168
|
+
"mentioned",
|
|
32169
|
+
"said",
|
|
32170
|
+
"should",
|
|
32171
|
+
"change",
|
|
32172
|
+
"wrong",
|
|
32173
|
+
"saying",
|
|
32174
|
+
"record",
|
|
32175
|
+
"oh",
|
|
32176
|
+
"by",
|
|
32177
|
+
"way",
|
|
32178
|
+
"project"
|
|
32179
|
+
]);
|
|
32180
|
+
function tokenize4(text) {
|
|
32181
|
+
const matches = text.toLowerCase().match(/[a-z0-9][a-z0-9-]*/g);
|
|
32182
|
+
return (matches ?? []).filter((t) => !STOP_WORDS.has(t));
|
|
32183
|
+
}
|
|
32184
|
+
function termFrequencies(tokens) {
|
|
32185
|
+
const tf = /* @__PURE__ */ new Map();
|
|
32186
|
+
for (const token of tokens) {
|
|
32187
|
+
tf.set(token, (tf.get(token) ?? 0) + 1);
|
|
32188
|
+
}
|
|
32189
|
+
return tf;
|
|
32190
|
+
}
|
|
32191
|
+
var PromptOnlyBaselineAdapter = class {
|
|
32192
|
+
label = "prompt-only-baseline";
|
|
32193
|
+
turns = [];
|
|
32194
|
+
async reset() {
|
|
32195
|
+
this.turns = [];
|
|
32196
|
+
}
|
|
32197
|
+
async ingestTurn(sessionKey, role, text, at) {
|
|
32198
|
+
this.turns.push({ sessionKey, role, text, at });
|
|
32199
|
+
}
|
|
32200
|
+
async recall(query, sessionKey) {
|
|
32201
|
+
const queryTf = termFrequencies(tokenize4(query));
|
|
32202
|
+
if (queryTf.size === 0) return [];
|
|
32203
|
+
const scored = this.turns.filter((turn) => turn.sessionKey === sessionKey).map((turn) => {
|
|
32204
|
+
const turnTf = termFrequencies(tokenize4(turn.text));
|
|
32205
|
+
let overlap = 0;
|
|
32206
|
+
for (const [term, qCount] of queryTf) {
|
|
32207
|
+
const tCount = turnTf.get(term);
|
|
32208
|
+
if (tCount !== void 0) overlap += qCount * tCount;
|
|
32209
|
+
}
|
|
32210
|
+
return { turn, overlap };
|
|
32211
|
+
}).filter((entry) => entry.overlap > 0).sort((a, b) => {
|
|
32212
|
+
if (b.overlap !== a.overlap) return b.overlap - a.overlap;
|
|
32213
|
+
return this.turns.indexOf(b.turn) - this.turns.indexOf(a.turn);
|
|
32214
|
+
}).slice(0, 5).map((entry) => entry.turn.text);
|
|
32215
|
+
return scored;
|
|
32216
|
+
}
|
|
32217
|
+
async correct(text, sessionKey) {
|
|
32218
|
+
await this.ingestTurn(sessionKey, "user", text, (/* @__PURE__ */ new Date()).toISOString());
|
|
32219
|
+
}
|
|
32220
|
+
async runMaintenance() {
|
|
32221
|
+
}
|
|
32222
|
+
};
|
|
31958
32223
|
function createRemnicMemCorrectAdapter(adapter, options = {}) {
|
|
31959
32224
|
const label = options.label ?? "remnic-native";
|
|
31960
32225
|
const sessionPrefix = options.sessionPrefix ?? "memcorrect";
|
|
@@ -31975,7 +32240,12 @@ function createRemnicMemCorrectAdapter(adapter, options = {}) {
|
|
|
31975
32240
|
return trimmed.split(/\n\s*\n/).map((s) => s.trim()).filter((s) => s.length > 0);
|
|
31976
32241
|
},
|
|
31977
32242
|
async correct(text, sessionKey, at) {
|
|
31978
|
-
|
|
32243
|
+
const scopedSession = `${sessionPrefix}:${sessionKey}`;
|
|
32244
|
+
if (adapter.correct) {
|
|
32245
|
+
const outcome = await adapter.correct(scopedSession, text, at);
|
|
32246
|
+
if (outcome.applied) return;
|
|
32247
|
+
}
|
|
32248
|
+
await adapter.store(scopedSession, [
|
|
31979
32249
|
{ role: "user", content: text, timestamp: at }
|
|
31980
32250
|
]);
|
|
31981
32251
|
},
|
|
@@ -32023,7 +32293,17 @@ var FULL_OPTIONS2 = {
|
|
|
32023
32293
|
};
|
|
32024
32294
|
function resolveAdapter(options) {
|
|
32025
32295
|
const override = options.benchmarkOptions?.["adapter"];
|
|
32026
|
-
if (
|
|
32296
|
+
if (typeof override === "string") {
|
|
32297
|
+
if (override === "prompt-only") {
|
|
32298
|
+
const adapter = new PromptOnlyBaselineAdapter();
|
|
32299
|
+
return { adapter, adapterLabel: adapter.label };
|
|
32300
|
+
}
|
|
32301
|
+
if (override !== "remnic") {
|
|
32302
|
+
throw new Error(
|
|
32303
|
+
`memcorrect-v1 adapter must be one of ["remnic", "prompt-only"] (or an in-process MemCorrectSystemAdapter object); received "${override}"`
|
|
32304
|
+
);
|
|
32305
|
+
}
|
|
32306
|
+
} else if (override && typeof override === "object" && "reset" in override && "ingestTurn" in override && "recall" in override) {
|
|
32027
32307
|
const adapter = override;
|
|
32028
32308
|
return { adapter, adapterLabel: adapter.label ?? "custom" };
|
|
32029
32309
|
}
|
|
@@ -32980,7 +33260,7 @@ function assemblePack(task, condition, contract, injectSkills) {
|
|
|
32980
33260
|
};
|
|
32981
33261
|
}
|
|
32982
33262
|
function classifySkillTrigger(skill, task) {
|
|
32983
|
-
const taskTokens =
|
|
33263
|
+
const taskTokens = tokenize5(task.prompt + " " + task.subjectKeywords.join(" "));
|
|
32984
33264
|
const taskSet = new Set(taskTokens);
|
|
32985
33265
|
const appliesHits = skill.appliesWhen.filter((k) => taskSet.has(k));
|
|
32986
33266
|
const blocksHits = skill.doesNotApplyWhen.filter((k) => taskSet.has(k));
|
|
@@ -33001,7 +33281,7 @@ function classifySkillTrigger(skill, task) {
|
|
|
33001
33281
|
}
|
|
33002
33282
|
return { considered, injected: false, reason: "no trigger overlap" };
|
|
33003
33283
|
}
|
|
33004
|
-
function
|
|
33284
|
+
function tokenize5(text) {
|
|
33005
33285
|
return text.toLowerCase().replace(/[^a-z0-9\s-]/g, " ").split(/\s+/).filter((t) => t.length > 0);
|
|
33006
33286
|
}
|
|
33007
33287
|
function rankCandidates(pack, task, sourceItems) {
|
|
@@ -36703,7 +36983,7 @@ var PROCEDURAL_REAL_SCENARIOS_SMOKE = [
|
|
|
36703
36983
|
];
|
|
36704
36984
|
|
|
36705
36985
|
// src/security/extraction-attack/tokenize.ts
|
|
36706
|
-
function
|
|
36986
|
+
function tokenize6(text) {
|
|
36707
36987
|
return text.toLowerCase().split(/[^a-z0-9]+/u).filter((t) => t.length > 2);
|
|
36708
36988
|
}
|
|
36709
36989
|
|
|
@@ -36745,7 +37025,7 @@ function createSeededRng2(seed) {
|
|
|
36745
37025
|
}
|
|
36746
37026
|
};
|
|
36747
37027
|
}
|
|
36748
|
-
var tokenizeContent =
|
|
37028
|
+
var tokenizeContent = tokenize6;
|
|
36749
37029
|
function recoveryTokensFor(memory) {
|
|
36750
37030
|
if (memory.tokens && memory.tokens.length > 0) {
|
|
36751
37031
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -37224,11 +37504,11 @@ function createSyntheticTarget(options) {
|
|
|
37224
37504
|
}
|
|
37225
37505
|
const normalized = memories.map((m) => ({
|
|
37226
37506
|
memory: m,
|
|
37227
|
-
tokens: new Set((m.tokens ??
|
|
37507
|
+
tokens: new Set((m.tokens ?? tokenize6(m.content)).map((t) => t.toLowerCase()))
|
|
37228
37508
|
}));
|
|
37229
37509
|
return {
|
|
37230
37510
|
async recall(query, recallOptions) {
|
|
37231
|
-
const qTokens =
|
|
37511
|
+
const qTokens = tokenize6(query);
|
|
37232
37512
|
if (qTokens.length === 0) return [];
|
|
37233
37513
|
const requestedNs = recallOptions?.namespace;
|
|
37234
37514
|
if (enforceNamespaceAcl && requestedNs !== void 0 && requestedNs !== allowedNamespace) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/bench",
|
|
3
|
-
"version": "9.6.
|
|
3
|
+
"version": "9.6.12",
|
|
4
4
|
"description": "Retrieval latency ladder benchmarks + CI regression gates for @remnic/core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"hyparquet": "^1.25.7",
|
|
38
38
|
"yaml": "^2.4.2",
|
|
39
|
-
"@remnic/coding-graph": "^9.6.
|
|
40
|
-
"@remnic/core": "^9.6.
|
|
39
|
+
"@remnic/coding-graph": "^9.6.12",
|
|
40
|
+
"@remnic/core": "^9.6.12"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"tsup": "^8.5.1",
|