From b97a88f22e53d7fbd72976573961f0648b33ec04 Mon Sep 17 00:00:00 2001 From: Yichen Jiang Date: Mon, 19 Oct 2026 23:03:43 +0800 Subject: [PATCH] refactor(web): share the composer's failed-send settlement Reference serialization and transport failures dispatched the same sink-settled failure inline; route both through one failSink method so the duplication gate passes. --- .../src/client/input/facade.ts | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/client/ui-conversation/src/client/input/facade.ts b/packages/client/ui-conversation/src/client/input/facade.ts index cbbfc42800..95291a81ff 100644 --- a/packages/client/ui-conversation/src/client/input/facade.ts +++ b/packages/client/ui-conversation/src/client/input/facade.ts @@ -709,12 +709,7 @@ export class SessionInputShell implements SessionInput { out += draft.slice(cursor) this.settleSink(attempt, this.deps.defaultSink(out.trim(), attachmentIds, mode, attempt.signal)) }, - (error: unknown) => { - if (this.dead(attempt)) return - this.dispatchRun(({ - type: 'sink-settled', attempt, ok: false, command: this.projection.command, message: errorText(error), - })) - }, + (error: unknown) => { this.failSink(attempt, error) }, ) } @@ -744,15 +739,18 @@ export class SessionInputShell implements SessionInput { } this.dispatchRun(({ type: 'sink-settled', attempt, ok: accepted, command: this.projection.command, outcome })) }, - (error: unknown) => { - if (this.dead(attempt)) return - this.dispatchRun(({ - type: 'sink-settled', attempt, ok: false, command: this.projection.command, message: errorText(error), - })) - }, + (error: unknown) => { this.failSink(attempt, error) }, ) } + /** Settle a send that ended without a Host outcome; the draft stays for correction. */ + private failSink(attempt: SubmitAttempt, error: unknown): void { + if (this.dead(attempt)) return + this.dispatchRun(({ + type: 'sink-settled', attempt, ok: false, command: this.projection.command, message: errorText(error), + })) + } + /** Enter adjudication: poll the session controller; failure = notice + draft retained (never a silent downgrade). */ private adjudicate(attempt: SubmitAttempt, draft: string): void { const inputTriggers = this.deps.inputTriggers?.()