singularity-forge/src/resources/extensions/sf/tests/auto-completion-nudge.test.ts
Mikael Hugo f98a1e360e batch: codex-rescue session output (multiple in-flight tasks)
Combined output of multiple parallel codex-rescue runs that produced
working-tree edits but didn't commit. Tasks contributing:

- prefs: per-provider model allow-list (provider_model_allow) — manual
- TUI scroll + unresponsive (a7884d1a / bt3fpn4y2)
- planningMeeting required (aa09e904 / br127l763)
- Logs UX 4-pack (a5c65314 / btcplhu7f)
- Gate auto-resolve + completion nudge (ae4c8b64 / bw1w1fjkp)
- sf_task_complete atomic + retry (a7a079b4 / b20cy5owv)
- Multi-model meeting + minimax M2.7 + draft promotion (a756faac / task-moifjknd-lwjc98)
- Per-role slice prompts (a94c3e1a)
- Per-role vision-meeting prompts (afd165a0 / task-moifple5-lcwtjl)
- Schema sweep (ac994b1e / task-moifq7pu-83coqz)
- Flow audit (ad26ecfd / bttj4vrqm)

Typecheck passes. Tests not run as a full suite — spot-check after merge.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: OpenAI Codex <noreply@openai.com>
2026-04-28 11:52:42 +02:00

68 lines
2.6 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import type { AgentMessage } from "@singularity-forge/pi-agent-core";
import {
applyCompletionNudgeTemperature,
getCompletionNudgeStateForTest,
maybeInjectCompletionNudgeMessage,
recordCompletionNudgeToolCall,
resetCompletionNudgeState,
} from "../auto-completion-nudge.ts";
type CustomTestMessage = Extract<AgentMessage, { role: "custom" }> & { content: string };
function baseMessages(): AgentMessage[] {
return [{
role: "user",
content: [{ type: "text", text: "complete slice" }],
timestamp: Date.now(),
}];
}
test("completion nudge injects reminder after N tool calls without sf_complete_slice", () => {
resetCompletionNudgeState("complete-slice", "M001/S01", 3);
recordCompletionNudgeToolCall("read");
recordCompletionNudgeToolCall("grep");
assert.equal(maybeInjectCompletionNudgeMessage(baseMessages()).length, 1);
recordCompletionNudgeToolCall("bash");
const messages = maybeInjectCompletionNudgeMessage(baseMessages());
assert.equal(messages.length, 2);
const nudge = messages[1];
assert.equal(nudge.role, "custom");
assert.match(String(nudge.content), /You've performed 3 tool calls of investigation/);
assert.match(String(nudge.content), /call sf_complete_slice/);
});
test("completion nudge does not inject after sf_complete_slice is called", () => {
resetCompletionNudgeState("complete-slice", "M001/S01", 3);
recordCompletionNudgeToolCall("read");
recordCompletionNudgeToolCall("grep");
recordCompletionNudgeToolCall("sf_complete_slice");
recordCompletionNudgeToolCall("bash");
const messages = maybeInjectCompletionNudgeMessage(baseMessages());
assert.equal(messages.length, 1);
assert.equal(getCompletionNudgeStateForTest().completionCalled, true);
});
test("completion nudge injects stronger message at 2N and lowers temperature", () => {
resetCompletionNudgeState("complete-slice", "M001/S01", 2);
recordCompletionNudgeToolCall("read");
recordCompletionNudgeToolCall("grep");
maybeInjectCompletionNudgeMessage(baseMessages());
recordCompletionNudgeToolCall("bash");
recordCompletionNudgeToolCall("read");
const messages = maybeInjectCompletionNudgeMessage(baseMessages());
assert.equal(messages.length, 2);
const nudge = messages[1] as CustomTestMessage;
assert.match(String(nudge.content), /without calling sf_complete_slice/);
const payload = { temperature: 0.9, generationConfig: { temperature: 0.8 } };
applyCompletionNudgeTemperature(payload);
assert.equal(payload.temperature, 0.2);
assert.equal(payload.generationConfig.temperature, 0.2);
});