fix(system-agent): replace expired QR prompt

This commit is contained in:
jesse-merhi
2026-08-12 13:30:23 +10:00
parent 8e933b4529
commit 5d95f3e2e6
2 changed files with 35 additions and 4 deletions
+25
View File
@@ -342,6 +342,31 @@ describe("SystemAgentChatEngine wizard", () => {
expect(engine.hasPendingQrCode()).toBe(true);
await engine.handle("cancel");
});
it("replaces scan instructions when the QR expires before its first projection", async () => {
vi.useFakeTimers();
vi.setSystemTime(1_800_000_000_000);
const engine = createQrEngine(async (_channel, prompter) => {
await prompter.qrCode?.({
title: "Link a device",
message: "Scan this QR code and approve the device.",
text: QR_TEXT,
dismissed: new Promise<void>(() => {}),
expiresAtMs: 1_800_000_000_000,
});
});
const prompt = await engine.handle("connect telegram");
expect(prompt.text).toBe(
"This setup QR code expired. Setup is still finishing the attempt automatically.",
);
expect(prompt.text).not.toContain("Scan");
expect(prompt.step).toBeUndefined();
expect(prompt.wizardSettling).toBe(true);
await engine.handle("cancel");
});
it("recommends the confirm option matching the initial value", async () => {
let enabled: boolean | undefined;
const engine = new SystemAgentChatEngine({
+10 -4
View File
@@ -100,6 +100,8 @@ type ActiveWizardBridge = {
const log = createSubsystemLogger("system-agent/chat-wizard-host");
const SYSTEM_AGENT_HOSTED_WIZARD_TIMEOUT_MS = 25 * 60 * 1000;
const WIZARD_CANCEL_HINT = "Say `cancel` to stop this setup.";
const WIZARD_QR_EXPIRED_MESSAGE =
"This setup QR code expired. Setup is still finishing the attempt automatically.";
let hostedRuntimePromise: Promise<HostedRuntime> | undefined;
function loadHostedRuntime(): Promise<HostedRuntime> {
@@ -147,10 +149,14 @@ export class ChatWizardHost {
decorateReply(reply: SystemAgentChatReply): SystemAgentChatReply {
this.expireActiveQrIfNeeded();
const step = this.bridge?.step ?? null;
const completedReply =
reply.text && step && step.type !== "qr" && wizardStepAwaitsInput(step)
? { ...reply, text: `${reply.text}\n${WIZARD_CANCEL_HINT}` }
const projectedReply =
this.bridge?.qrExpired === true && this.bridge.session.hasExternalQrPresentationOwner()
? { ...reply, text: WIZARD_QR_EXPIRED_MESSAGE }
: reply;
const completedReply =
projectedReply.text && step && step.type !== "qr" && wizardStepAwaitsInput(step)
? { ...projectedReply, text: `${projectedReply.text}\n${WIZARD_CANCEL_HINT}` }
: projectedReply;
const question = wizardStepChatQuestion(step);
const clientStep = step
? sanitizeWizardStepForClient(
@@ -241,7 +247,7 @@ export class ChatWizardHost {
if (bridge.qrExpired) {
if (bridge.session.hasExternalQrPresentationOwner()) {
return {
text: "This setup QR code expired. Setup is still finishing the attempt automatically.",
text: WIZARD_QR_EXPIRED_MESSAGE,
configWritten: false,
};
}