summaryrefslogtreecommitdiffhomepage
path: root/src/app
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-29 12:13:10 +0900
committerAdam Malczewski <[email protected]>2026-06-29 12:13:10 +0900
commit6861a10c30039b4086f11e2b5bfc515844d8a7b3 (patch)
tree882e84589dac93524e3f6feea047f0ec3e4a5184 /src/app
parentc1082294dd98cadfecda58d854174610659cadec (diff)
parent129bb3be45e1446ce4219d7f656ed0ed6f93a29f (diff)
downloaddispatch-web-6861a10c30039b4086f11e2b5bfc515844d8a7b3.tar.gz
dispatch-web-6861a10c30039b4086f11e2b5bfc515844d8a7b3.zip
Merge branch 'feature/cancel-queued-message' into predev
# Conflicts: # backend-handoff.md
Diffstat (limited to 'src/app')
-rw-r--r--src/app/App.svelte10
-rw-r--r--src/app/store.svelte.ts18
2 files changed, 27 insertions, 1 deletions
diff --git a/src/app/App.svelte b/src/app/App.svelte
index f87eddb..f0cd7ec 100644
--- a/src/app/App.svelte
+++ b/src/app/App.svelte
@@ -297,6 +297,10 @@
store.queueMessage(text);
}
+ function handleCancelQueuedMessage(messageId: string) {
+ store.cancelQueuedMessage(messageId);
+ }
+
function handleStop() {
store.stopGeneration();
}
@@ -647,7 +651,11 @@
the generic SurfaceView (dispatches on rendererId, never surface id);
only shown when the queue is non-empty — an idle queue is hidden. -->
<div class="px-4 pt-2">
- <SurfaceView spec={messageQueueSpec} onInvoke={handleInvoke} />
+ <SurfaceView
+ spec={messageQueueSpec}
+ onInvoke={handleInvoke}
+ onCancelQueuedMessage={handleCancelQueuedMessage}
+ />
</div>
{/if}
diff --git a/src/app/store.svelte.ts b/src/app/store.svelte.ts
index e0491ab..629e6c6 100644
--- a/src/app/store.svelte.ts
+++ b/src/app/store.svelte.ts
@@ -215,6 +215,15 @@ export interface AppStore {
* wants to add input — the server owns the idle-vs-generating decision.
*/
queueMessage(text: string): void;
+ /**
+ * Cancel (remove) a single queued steering message by id so it never runs
+ * (`chat.queue.cancel` WS op). Fire-and-forget + idempotent: the
+ * message-queue surface update reconciles the queue UI (the cancelled message
+ * leaves the snapshot). Targets the focused conversation's queue. The caller
+ * optimistically hides the row; a cancel of an already-drained / unknown
+ * message is a silent server no-op (nothing to roll back).
+ */
+ cancelQueuedMessage(messageId: string): void;
selectModel(model: string): void;
newDraft(): void;
/** Switch the active workspace (on route change) + reset to a fresh draft in it. */
@@ -1413,6 +1422,15 @@ export function createAppStore(opts?: CreateAppStoreOptions): AppStore {
activeChat.queueMessage(text);
},
+ cancelQueuedMessage(messageId: string): void {
+ // Fire-and-forget + idempotent. The message-queue surface (conversation-
+ // scoped) reconciles the queue UI — the cancelled row leaves the snapshot.
+ // A cancel of an already-drained / unknown message is a silent no-op, so
+ // there is no local state to roll back. Delegates to the focused
+ // conversation's chat store, which owns the conversationId + transport.
+ activeChat.cancelQueuedMessage(messageId);
+ },
+
selectModel(model: string): void {
activeModel = model;
const activeId = tabsStore.activeConversationId;