@inetafrica/open-claudia 3.4.15 → 3.4.16
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/CHANGELOG.md +6 -0
- package/core/runner.js +11 -1
- package/core/system-prompt.js +10 -6
- package/package.json +1 -1
- package/test-provider-language.js +2 -1
- package/test-provider-recall.js +46 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.4.16
|
|
4
|
+
|
|
5
|
+
- Start live-call answer generation without waiting for an auxiliary memory-relevance model. Calls keep local matches from the current utterance, bounded spoken history, and full policy; context-only keyword matches remain excluded without a relevance judgment. Ordinary chat filtering and explicit on-demand recall are unchanged.
|
|
6
|
+
- Log live-call provider preparation, prompt readiness, process start and completion with elapsed time, so recognition delay can be distinguished from reply startup and generation.
|
|
7
|
+
- Reproduce the call-path regression through the actual prompt builder and classic matcher, covering both configured recall engines, context-only exclusions, ordinary chat filtering and on-demand recall.
|
|
8
|
+
|
|
3
9
|
## 3.4.15
|
|
4
10
|
|
|
5
11
|
- Preserve complete Kazee speech turns with protocol-2 segment matching, bounded pending finals, and cancellation when speech resumes during an endpoint decision. Keep compatibility with older speech servers, including a delayed protocol-ready message.
|
package/core/runner.js
CHANGED
|
@@ -1936,6 +1936,10 @@ function createStreamPreview({ state, store }) {
|
|
|
1936
1936
|
|
|
1937
1937
|
function createForegroundService({ state, store, stopTyping, capture, ownsAdmissionLock, persistCapture = true }) {
|
|
1938
1938
|
const callSpeechLeases = new Map();
|
|
1939
|
+
const callStage = (stage, runContext) => {
|
|
1940
|
+
if (capture || runContext?.liveCall !== true) return;
|
|
1941
|
+
console.log(`${new Date().toISOString()} Kazee call provider: stage=${stage} run=${runContext.runId} elapsed=${Math.max(0, Date.now() - runContext.admittedAt)}ms`);
|
|
1942
|
+
};
|
|
1939
1943
|
const persistEffects = !capture || persistCapture;
|
|
1940
1944
|
const preview = capture ? null : createStreamPreview({ state, store });
|
|
1941
1945
|
// Chat-visibility + learning-signal layer (skill/pack/tool announcements,
|
|
@@ -1946,7 +1950,10 @@ function createForegroundService({ state, store, stopTyping, capture, ownsAdmiss
|
|
|
1946
1950
|
getStore: () => store,
|
|
1947
1951
|
isObsolete: () => obsoleteCallTurn(store),
|
|
1948
1952
|
resolveProvider: resolveForegroundProvider,
|
|
1949
|
-
buildTurnPrompt,
|
|
1953
|
+
buildTurnPrompt(prompt, opts) {
|
|
1954
|
+
callStage("preparing", opts.runContext);
|
|
1955
|
+
return buildTurnPrompt(prompt, opts);
|
|
1956
|
+
},
|
|
1950
1957
|
buildInvocation(provider, context) {
|
|
1951
1958
|
if (context.purpose === "compact-seed" && typeof provider.buildCompactionInvocation === "function") {
|
|
1952
1959
|
return provider.buildCompactionInvocation(context);
|
|
@@ -1969,6 +1976,7 @@ function createForegroundService({ state, store, stopTyping, capture, ownsAdmiss
|
|
|
1969
1976
|
persistSession: persistEffects ? ((result, runContext) => persistForegroundSession(result, runContext, state)) : null,
|
|
1970
1977
|
deliver: capture ? null : (result, runContext) => deliverForegroundResult(result, runContext, state),
|
|
1971
1978
|
onSpawn(proc, runContext) {
|
|
1979
|
+
callStage("started", runContext);
|
|
1972
1980
|
callSpeechLeases.get(runContext.runId)?.activate();
|
|
1973
1981
|
state.runningProcess = proc;
|
|
1974
1982
|
if (ownsAdmissionLock) state.preparingRun = false;
|
|
@@ -1980,10 +1988,12 @@ function createForegroundService({ state, store, stopTyping, capture, ownsAdmiss
|
|
|
1980
1988
|
return true;
|
|
1981
1989
|
},
|
|
1982
1990
|
onPromptBundle(bundle, runContext) {
|
|
1991
|
+
callStage("prompt-ready", runContext);
|
|
1983
1992
|
if (!observer || runContext.purpose !== "foreground") return;
|
|
1984
1993
|
observer.onRecallSurfaced(bundle.recallMetadata);
|
|
1985
1994
|
},
|
|
1986
1995
|
onEvent(event, runContext) {
|
|
1996
|
+
if (event.type === "result" || event.type === "error") callStage("finished", runContext);
|
|
1987
1997
|
if (event.type === "result" || event.type === "error") callSpeechLeases.get(runContext.runId)?.close();
|
|
1988
1998
|
// Streaming text reads as "typing"; tool work re-enters "thinking" so
|
|
1989
1999
|
// the chip doesn't decay to a stale "typing" through long tool stretches.
|
package/core/system-prompt.js
CHANGED
|
@@ -997,6 +997,10 @@ async function filterMatches(userText, contextText, packMatches, entityMatches,
|
|
|
997
997
|
packMatches: packMatches.filter((m) => m.origin === "user"),
|
|
998
998
|
entityMatches: entityMatches.filter((m) => m.origin === "user"),
|
|
999
999
|
});
|
|
1000
|
+
// The classic engine still uses an auxiliary model. On a live call that
|
|
1001
|
+
// adds seconds before the answering model can even start. Keep the local
|
|
1002
|
+
// user-keyword baseline; context-only hits still need a relevance judge.
|
|
1003
|
+
if (opts.liveCall === true) return failOpen();
|
|
1000
1004
|
if (packMatches.length === 0 && entityMatches.length === 0) {
|
|
1001
1005
|
return { packMatches, entityMatches };
|
|
1002
1006
|
}
|
|
@@ -1176,12 +1180,12 @@ async function buildOptionalRecallContext(prompt, opts = {}) {
|
|
|
1176
1180
|
const budget = memoryRecallBudget();
|
|
1177
1181
|
const settings = promptState(opts).settings || {};
|
|
1178
1182
|
const recall = require("./recall");
|
|
1179
|
-
//
|
|
1180
|
-
//
|
|
1181
|
-
//
|
|
1182
|
-
|
|
1183
|
+
// Calls use classic matching with the auxiliary relevance model disabled
|
|
1184
|
+
// below. Merely selecting classic still waits on that model. Explicit ask
|
|
1185
|
+
// mode continues to retrieve memory on demand.
|
|
1186
|
+
const liveCall = opts.runContext?.liveCall ?? (currentAdapter()?.liveCall === true);
|
|
1183
1187
|
const activeName = recall.activeEngineName(settings);
|
|
1184
|
-
const engineName =
|
|
1188
|
+
const engineName = liveCall === true && activeName === "discoverer" ? "classic" : activeName;
|
|
1185
1189
|
const engine = recall.getEngine(engineName);
|
|
1186
1190
|
const recallOpts = { ...opts, recallCollector: collector };
|
|
1187
1191
|
const recallProvider = promptRunIdentity({ ...opts, state: promptState(opts) }).provider;
|
|
@@ -1194,7 +1198,7 @@ async function buildOptionalRecallContext(prompt, opts = {}) {
|
|
|
1194
1198
|
context,
|
|
1195
1199
|
packMatches,
|
|
1196
1200
|
entityMatches,
|
|
1197
|
-
{ provider: recallProvider },
|
|
1201
|
+
{ provider: recallProvider, liveCall },
|
|
1198
1202
|
),
|
|
1199
1203
|
logRecall,
|
|
1200
1204
|
buildPackBlock: (matches, recallBudget, engineOpts) => buildPackBlock(matches, recallBudget, { ...recallOpts, ...(engineOpts || {}) }),
|
package/package.json
CHANGED
|
@@ -468,7 +468,8 @@ assert.match(pkg.description, /provider-agnostic coding-agent harness/i);
|
|
|
468
468
|
// 3.4.13: Codex usage accounting fix — Sumeet approved the three-bug fix on 2026-09-05 ("Yes");
|
|
469
469
|
// prepared 2026-09-06 for his release go. Rollout-based Codex context, per-turn ledger, sub-agent + quota accounting.
|
|
470
470
|
// 3.4.15: conversation flow and checked sentence speech; authorized calling rollout, 2026-09-05/06.
|
|
471
|
-
|
|
471
|
+
// 3.4.16: remove the auxiliary recall-model delay from live replies; Sumeet's approved calling rollout, 2026-09-05/06.
|
|
472
|
+
assert.strictEqual(pkg.version, "3.4.16", "release version must remain unchanged without explicit approval");
|
|
472
473
|
for (const keyword of ["claude", "codex", "coding-agent", "provider-agnostic"]) {
|
|
473
474
|
assert.ok(pkg.keywords.includes(keyword), `package keyword missing: ${keyword}`);
|
|
474
475
|
}
|
package/test-provider-recall.js
CHANGED
|
@@ -253,6 +253,52 @@ async function main() {
|
|
|
253
253
|
recall.getEngine = originalGetEngine;
|
|
254
254
|
assert.strictEqual(admittedProvider, "codex");
|
|
255
255
|
|
|
256
|
+
// Real call prompt -> classic matcher -> relevance filter. A second model
|
|
257
|
+
// must not hold a live reply; context-only hits still require a judge and
|
|
258
|
+
// cannot be promoted just because calls use the local keyword baseline.
|
|
259
|
+
const packsLib = require("./core/packs");
|
|
260
|
+
const entitiesLib = require("./core/entities");
|
|
261
|
+
const transcriptsLib = require("./core/transcripts");
|
|
262
|
+
const filterLib = require("./core/recall-filter");
|
|
263
|
+
const saved = { matchPacks: packsLib.matchPacks, matchEntities: entitiesLib.matchEntities,
|
|
264
|
+
recentTranscriptText: transcriptsLib.recentTranscriptText, judgeRelevance: filterLib.judgeRelevance };
|
|
265
|
+
const { chatContext } = require("./core/context");
|
|
266
|
+
let judgeCalls = 0;
|
|
267
|
+
try {
|
|
268
|
+
packsLib.matchPacks = text => [{ dir: text === "Current deployment" ? "current-topic" : "stale-chat-topic", score: 10 }];
|
|
269
|
+
entitiesLib.matchEntities = () => [];
|
|
270
|
+
transcriptsLib.recentTranscriptText = () => "Earlier unrelated chat discussion";
|
|
271
|
+
filterLib.judgeRelevance = async () => { judgeCalls++; return new Set(["pack:current-topic", "pack:stale-chat-topic"]); };
|
|
272
|
+
for (const recallEngine of ["discoverer", "classic"]) {
|
|
273
|
+
const callRecall = await chatContext.run({ adapter: { type: "kazee", liveCall: true } }, () =>
|
|
274
|
+
systemPrompt.buildOptionalRecallContext("Current deployment", {
|
|
275
|
+
state: { ...mutableState, settings: { backend: "codex", recallEngine } },
|
|
276
|
+
runContext: { provider: "codex", liveCall: true, purpose: "foreground", project: { name: "project-a", dir: root }, runId: `call-${recallEngine}` },
|
|
277
|
+
}));
|
|
278
|
+
assert.strictEqual(judgeCalls, 0, "live call must reach answer generation without a second model for recall");
|
|
279
|
+
assert.deepStrictEqual(callRecall.metadata.packDirs, ["current-topic"], "retain current-topic keyword memory, exclude stale context-only matches");
|
|
280
|
+
}
|
|
281
|
+
const ordinaryRecall = await chatContext.run({ adapter: { type: "kazee" } }, () =>
|
|
282
|
+
systemPrompt.buildOptionalRecallContext("Current deployment", {
|
|
283
|
+
state: { ...mutableState, settings: { backend: "codex", recallEngine: "classic" } },
|
|
284
|
+
runContext: { provider: "codex", purpose: "foreground", project: { name: "project-a", dir: root }, runId: "ordinary-classic" },
|
|
285
|
+
}));
|
|
286
|
+
assert.strictEqual(judgeCalls, 1, "ordinary chat retains its model-based relevance filter");
|
|
287
|
+
assert.deepStrictEqual(ordinaryRecall.metadata.packDirs, ["current-topic", "stale-chat-topic"]);
|
|
288
|
+
const askRecall = await chatContext.run({ adapter: { type: "kazee", liveCall: true } }, () =>
|
|
289
|
+
systemPrompt.buildOptionalRecallContext("Current deployment", {
|
|
290
|
+
state: { ...mutableState, settings: { backend: "codex", recallEngine: "ask" } },
|
|
291
|
+
runContext: { provider: "codex", liveCall: true, purpose: "foreground", project: { name: "project-a", dir: root }, runId: "call-ask" },
|
|
292
|
+
}));
|
|
293
|
+
assert.strictEqual(askRecall.metadata.engine, "ask", "explicit on-demand recall remains on-demand during calls");
|
|
294
|
+
assert.strictEqual(judgeCalls, 1);
|
|
295
|
+
} finally {
|
|
296
|
+
packsLib.matchPacks = saved.matchPacks;
|
|
297
|
+
entitiesLib.matchEntities = saved.matchEntities;
|
|
298
|
+
transcriptsLib.recentTranscriptText = saved.recentTranscriptText;
|
|
299
|
+
filterLib.judgeRelevance = saved.judgeRelevance;
|
|
300
|
+
}
|
|
301
|
+
|
|
256
302
|
// ── compaction recall policy: the summary meta-turn skips recall entirely;
|
|
257
303
|
// the seed turn matches on the runner-supplied recallQuery (condensed
|
|
258
304
|
// brief + task titles), never the seed prompt's boilerplate ──
|