diff options
| author | Adam Malczewski <[email protected]> | 2026-06-12 20:38:57 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-12 20:38:57 +0900 |
| commit | b74357495e443ff6011531d296560caff9398a14 (patch) | |
| tree | 63aafc3ef6ced7cc2ec59ad66c788ecae74db295 /src/app/App.svelte | |
| parent | aa8b086cd2ec47038e5b35d2295260114651bf8f (diff) | |
| download | dispatch-web-b74357495e443ff6011531d296560caff9398a14.tar.gz dispatch-web-b74357495e443ff6011531d296560caff9398a14.zip | |
feat(chat): reasoning-effort selector — sticky per-conversation thinking-depth knob
Consume the backend's reasoning-effort handoff ([email protected] ReasoningEffort +
[email protected] GET/PUT /conversations/:id/reasoning-effort,
ChatRequest.reasoningEffort): a 5-level selector in the sidebar Model view,
under the provider + model dropdowns. null renders as 'high (default)' per
the server-owned resolution chain; PUT on change (effective next turn);
error + revert on 400; per-conversation re-mount incl. drafts (the draft id
survives promotion, so an effort set on a draft applies from turn 1).
Re-mirrored .dispatch references; GLOSSARY 'reasoning effort'; handoff
updated. 616 tests green; live curl probe passed.
Diffstat (limited to 'src/app/App.svelte')
| -rw-r--r-- | src/app/App.svelte | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/app/App.svelte b/src/app/App.svelte index 4c5a82b..dffa937 100644 --- a/src/app/App.svelte +++ b/src/app/App.svelte @@ -1,4 +1,5 @@ <script lang="ts"> + import type { ReasoningEffort } from "@dispatch/transport-contract"; import type { InvokeMessage } from "@dispatch/ui-contract"; import { tick } from "svelte"; import Table from "../components/Table.svelte"; @@ -12,6 +13,8 @@ Composer, manifest as chatManifest, ModelSelector, + ReasoningEffortSelector, + type ReasoningEffortSaveResult, } from "../features/chat"; import { manifest as conversationCacheManifest } from "../features/conversation-cache"; import { manifest as markdownManifest } from "../features/markdown"; @@ -154,6 +157,17 @@ : { ok: false, error: result.error }; } + // Adapt the store's reasoning-effort result to the chat feature's port. + async function saveReasoningEffort( + level: ReasoningEffort, + ): Promise<ReasoningEffortSaveResult | null> { + const result = await store.setReasoningEffort(level); + if (result === null) return null; + return result.ok + ? { ok: true, reasoningEffort: result.reasoningEffort } + : { ok: false, error: result.error }; + } + // Adapt the store's cwd/LSP results to the workspace feature's ports. async function saveCwd(cwd: string): Promise<CwdSaveResult | null> { const result = await store.setCwd(cwd); @@ -295,10 +309,11 @@ {#if kind === "model"} <div class="flex flex-col gap-3"> <ModelSelector models={store.models} selected={store.activeModel} onSelect={handleSelectModel} /> - <!-- Keyed on the workspace conversation (active tab OR draft) so the input - re-mounts per conversation — incl. switching between drafts — and can't - bleed across tabs. Editable for a draft too (cwd applies from turn 1). --> + <!-- Keyed on the workspace conversation (active tab OR draft) so the inputs + re-mount per conversation — incl. switching between drafts — and can't + bleed across tabs. Editable for a draft too (cwd + effort apply from turn 1). --> {#key store.currentConversationId} + <ReasoningEffortSelector persisted={store.reasoningEffort} save={saveReasoningEffort} /> <CwdField cwd={store.cwd} canEdit={true} save={saveCwd} /> {/key} </div> |
