* feat: support OpenCode steer delivery / follow-up behavior settings Implements issue #1766 — steer delivery mode for mid-turn message insertion, replacing the old boolean queue-mode toggle with a tri-state follow-up behavior setting (Steer / Queue / Send immediately). - Plumbing: threaded optional delivery: 'steer' through sendMessage -> routeMessage -> opencodeClient.sendMessage -> promptAsync - Store: messageQueueStore stores followUpBehavior; migration from legacy queueModeEnabled persisted state - Settings: Chat -> Follow-up behavior shows three radio options using existing settings UI patterns - Composer: when session is busy, a floating queue button remains; force-sending a queued message (via chip click) uses delivery: 'steer' during a busy session; Steer button intentionally omitted — steer is available via the two-gesture path (Enter to queue -> chip to steer) - Keyboard: queue mode = Enter queues, Ctrl+Enter sends; otherwise Enter sends, Ctrl+Enter queues - Persistence: DesktopSettings, web settings payload, and server-side sanitizer handle the new key with legacy fallback - i18n: follow-up behavior section and option labels in all 9 locales plus new chat.chatInput.actions.queue label - Search: settings registry updated from chat.queue-mode to chat.follow-up-behavior Validation: type-check passes (no new errors), lint clean. * fix(#1766): make steer mode actually steer The followUpBehavior === 'steer' branch in handlePrimaryAction and the keyboard handler was a no-op — both fell into the else branch and sent without the delivery: 'steer' flag, so selecting 'Steer (insert into the running turn)' in settings produced identical behavior to 'Send immediately'. - handlePrimaryAction: when steer mode is selected and the session is busy, call handleSubmit({ delivery: 'steer' }) directly - Keyboard handler: in steer mode, Enter steers and Ctrl+Enter sends immediately (consistent with queue mode where Ctrl+Enter bypasses the special handling) Also removes the unused chat.chatInput.actions.queue i18n key from all 9 locales (it was a dead key after the Steer button was removed from the composer). Validation: type-check clean, lint clean. * refactor(#1766): flatten nested ternary in followUpBehavior resolution Replace nested ternary with explicit if/else chain per project code style (CONTRIBUTING.md). Import FollowUpBehavior type explicitly for the new let declaration. * feat(chat): drop redundant 'immediate' follow-up mode, keep Queue + Steer 'Immediate' was wire-identical to 'Steer' on a busy session: OpenCode only supports delivery 'steer' | 'queue' and defaults to 'steer', so an immediate send (no delivery flag) already steered into the running turn. The three-mode UI therefore exposed two settings that did the same thing. Collapse to two modes — Queue (unchanged: client-side queue with edit/reorder) and Steer. Any persisted/legacy 'immediate' (and legacy queueModeEnabled=false) now maps to 'steer', preserving prior behavior. Removes the immediate option, its keyboard branch, the i18n label across all locales, and narrows the followUpBehavior union to 'steer' | 'queue'. --------- Co-authored-by: Leonid Skorobogatyy <bash@opencode.itc.local> Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
committed by
GitHub
co-authored by
Leonid Skorobogatyy
Bohdan Triapitsyn
parent
c184ddf185
commit
f13f6d5540
@@ -1800,4 +1800,10 @@ export const settingsDict = {
|
||||
'settings.magicPrompts.page.toast.resetFailed': 'Failed to reset prompt',
|
||||
'settings.magicPrompts.page.toast.resetAllSuccess': 'All prompt overrides reset',
|
||||
'settings.magicPrompts.page.toast.resetAllFailed': 'Failed to reset all prompts',
|
||||
'settings.openchamber.visual.section.followUpBehavior': 'Follow-up behavior',
|
||||
'settings.openchamber.visual.section.followUpBehaviorAria': 'Follow-up behavior',
|
||||
'settings.openchamber.visual.field.followUpBehaviorAria': 'Follow-up behavior: {option}',
|
||||
'settings.openchamber.visual.field.followUpBehaviorDescription': 'Choose what happens when you press Enter on a follow-up message while the agent is still responding.',
|
||||
'settings.openchamber.visual.option.followUpBehavior.steer.label': 'Steer (insert into the running turn)',
|
||||
'settings.openchamber.visual.option.followUpBehavior.queue.label': 'Queue (deliver after the current turn)',
|
||||
} as const;
|
||||
|
||||
@@ -1800,4 +1800,10 @@ export const settingsDict = {
|
||||
"settings.promptTemplates.page.toast.created": "Plantilla creada",
|
||||
"settings.promptTemplates.page.toast.createFailed": "Error al crear la plantilla",
|
||||
"settings.promptTemplates.page.toast.saveUnexpectedError": "Ocurrió un error inesperado al guardar",
|
||||
"settings.openchamber.visual.section.followUpBehavior": "Follow-up behavior",
|
||||
"settings.openchamber.visual.section.followUpBehaviorAria": "Follow-up behavior",
|
||||
"settings.openchamber.visual.field.followUpBehaviorAria": "Follow-up behavior: {option}",
|
||||
"settings.openchamber.visual.field.followUpBehaviorDescription": "Choose what happens when you press Enter on a follow-up message while the agent is still responding.",
|
||||
"settings.openchamber.visual.option.followUpBehavior.steer.label": "Steer (insert into the running turn)",
|
||||
"settings.openchamber.visual.option.followUpBehavior.queue.label": "Queue (deliver after the current turn)",
|
||||
} as const;
|
||||
|
||||
@@ -1800,4 +1800,10 @@ export const settingsDict = {
|
||||
'settings.magicPrompts.page.toast.resetFailed': 'Échec de la réinitialisation du prompt',
|
||||
'settings.magicPrompts.page.toast.resetAllSuccess': 'Tous les prompts ont été réinitialisés',
|
||||
'settings.magicPrompts.page.toast.resetAllFailed': 'Échec de la réinitialisation de tous les prompts',
|
||||
'settings.openchamber.visual.section.followUpBehavior': 'Follow-up behavior',
|
||||
'settings.openchamber.visual.section.followUpBehaviorAria': 'Follow-up behavior',
|
||||
'settings.openchamber.visual.field.followUpBehaviorAria': 'Follow-up behavior: {option}',
|
||||
'settings.openchamber.visual.field.followUpBehaviorDescription': 'Choose what happens when you press Enter on a follow-up message while the agent is still responding.',
|
||||
'settings.openchamber.visual.option.followUpBehavior.steer.label': 'Steer (insert into the running turn)',
|
||||
'settings.openchamber.visual.option.followUpBehavior.queue.label': 'Queue (deliver after the current turn)',
|
||||
} as const;
|
||||
|
||||
@@ -1800,4 +1800,10 @@ export const settingsDict = {
|
||||
'settings.magicPrompts.page.toast.resetFailed': 'プロンプトのリセットに失敗しました',
|
||||
'settings.magicPrompts.page.toast.resetAllSuccess': 'すべてのプロンプト上書きをリセットしました',
|
||||
'settings.magicPrompts.page.toast.resetAllFailed': 'すべてのプロンプトのリセットに失敗しました',
|
||||
'settings.openchamber.visual.section.followUpBehavior': 'フォローアップの動作',
|
||||
'settings.openchamber.visual.section.followUpBehaviorAria': 'フォローアップの動作',
|
||||
'settings.openchamber.visual.field.followUpBehaviorAria': 'フォローアップの動作: {option}',
|
||||
'settings.openchamber.visual.field.followUpBehaviorDescription': 'エージェントが応答している間にフォローアップメッセージで Enter を押したときの動作を選択します。',
|
||||
'settings.openchamber.visual.option.followUpBehavior.steer.label': 'ステア(実行中のターンに挿入)',
|
||||
'settings.openchamber.visual.option.followUpBehavior.queue.label': 'キュー(現在のターンの後に送信)',
|
||||
} as const;
|
||||
|
||||
@@ -1800,4 +1800,10 @@ export const settingsDict = {
|
||||
'settings.promptTemplates.page.toast.created': '템플릿이 생성되었습니다',
|
||||
'settings.promptTemplates.page.toast.createFailed': '템플릿 생성 실패',
|
||||
'settings.promptTemplates.page.toast.saveUnexpectedError': '저장 중 예기치 않은 오류가 발생했습니다',
|
||||
'settings.openchamber.visual.section.followUpBehavior': 'Follow-up behavior',
|
||||
'settings.openchamber.visual.section.followUpBehaviorAria': 'Follow-up behavior',
|
||||
'settings.openchamber.visual.field.followUpBehaviorAria': 'Follow-up behavior: {option}',
|
||||
'settings.openchamber.visual.field.followUpBehaviorDescription': 'Choose what happens when you press Enter on a follow-up message while the agent is still responding.',
|
||||
'settings.openchamber.visual.option.followUpBehavior.steer.label': 'Steer (insert into the running turn)',
|
||||
'settings.openchamber.visual.option.followUpBehavior.queue.label': 'Queue (deliver after the current turn)',
|
||||
} as const;
|
||||
|
||||
@@ -1792,4 +1792,10 @@ export const settingsDict = {
|
||||
'settings.voice.page.field.ttsInputModeSanitized': 'Oczyszczony tekst',
|
||||
'settings.voice.page.field.ttsInputModeRaw': 'Surowy Markdown',
|
||||
'settings.window.description': 'Okno ustawień OpenChamber.',
|
||||
'settings.openchamber.visual.section.followUpBehavior': 'Follow-up behavior',
|
||||
'settings.openchamber.visual.section.followUpBehaviorAria': 'Follow-up behavior',
|
||||
'settings.openchamber.visual.field.followUpBehaviorAria': 'Follow-up behavior: {option}',
|
||||
'settings.openchamber.visual.field.followUpBehaviorDescription': 'Choose what happens when you press Enter on a follow-up message while the agent is still responding.',
|
||||
'settings.openchamber.visual.option.followUpBehavior.steer.label': 'Steer (insert into the running turn)',
|
||||
'settings.openchamber.visual.option.followUpBehavior.queue.label': 'Queue (deliver after the current turn)',
|
||||
};
|
||||
|
||||
@@ -1800,4 +1800,10 @@ export const settingsDict = {
|
||||
"settings.promptTemplates.page.toast.created": "Template criado",
|
||||
"settings.promptTemplates.page.toast.createFailed": "Falha ao criar template",
|
||||
"settings.promptTemplates.page.toast.saveUnexpectedError": "Ocorreu um erro inesperado ao salvar",
|
||||
"settings.openchamber.visual.section.followUpBehavior": "Follow-up behavior",
|
||||
"settings.openchamber.visual.section.followUpBehaviorAria": "Follow-up behavior",
|
||||
"settings.openchamber.visual.field.followUpBehaviorAria": "Follow-up behavior: {option}",
|
||||
"settings.openchamber.visual.field.followUpBehaviorDescription": "Choose what happens when you press Enter on a follow-up message while the agent is still responding.",
|
||||
"settings.openchamber.visual.option.followUpBehavior.steer.label": "Steer (insert into the running turn)",
|
||||
"settings.openchamber.visual.option.followUpBehavior.queue.label": "Queue (deliver after the current turn)",
|
||||
} as const;
|
||||
|
||||
@@ -1800,4 +1800,10 @@ export const settingsDict = {
|
||||
"settings.promptTemplates.page.toast.created": "Шаблон створено",
|
||||
"settings.promptTemplates.page.toast.createFailed": "Не вдалося створити шаблон",
|
||||
"settings.promptTemplates.page.toast.saveUnexpectedError": "Сталася неочікувана помилка під час збереження",
|
||||
"settings.openchamber.visual.section.followUpBehavior": "Follow-up behavior",
|
||||
"settings.openchamber.visual.section.followUpBehaviorAria": "Follow-up behavior",
|
||||
"settings.openchamber.visual.field.followUpBehaviorAria": "Follow-up behavior: {option}",
|
||||
"settings.openchamber.visual.field.followUpBehaviorDescription": "Choose what happens when you press Enter on a follow-up message while the agent is still responding.",
|
||||
"settings.openchamber.visual.option.followUpBehavior.steer.label": "Steer (insert into the running turn)",
|
||||
"settings.openchamber.visual.option.followUpBehavior.queue.label": "Queue (deliver after the current turn)",
|
||||
} as const;
|
||||
|
||||
@@ -1800,4 +1800,10 @@ export const settingsDict = {
|
||||
'settings.promptTemplates.page.toast.created': '模板已创建',
|
||||
'settings.promptTemplates.page.toast.createFailed': '创建模板失败',
|
||||
'settings.promptTemplates.page.toast.saveUnexpectedError': '保存时发生意外错误',
|
||||
'settings.openchamber.visual.section.followUpBehavior': 'Follow-up behavior',
|
||||
'settings.openchamber.visual.section.followUpBehaviorAria': 'Follow-up behavior',
|
||||
'settings.openchamber.visual.field.followUpBehaviorAria': 'Follow-up behavior: {option}',
|
||||
'settings.openchamber.visual.field.followUpBehaviorDescription': 'Choose what happens when you press Enter on a follow-up message while the agent is still responding.',
|
||||
'settings.openchamber.visual.option.followUpBehavior.steer.label': 'Steer (insert into the running turn)',
|
||||
'settings.openchamber.visual.option.followUpBehavior.queue.label': 'Queue (deliver after the current turn)',
|
||||
} as const;
|
||||
|
||||
@@ -1800,4 +1800,10 @@
|
||||
'settings.usage.sidebar.field.showPredictions': '顯示預測',
|
||||
'settings.view.home.cards.plugins.description': '管理 opencode 外掛',
|
||||
'settings.view.home.cards.plugins.title': '外掛',
|
||||
'settings.openchamber.visual.section.followUpBehavior': 'Follow-up behavior',
|
||||
'settings.openchamber.visual.section.followUpBehaviorAria': 'Follow-up behavior',
|
||||
'settings.openchamber.visual.field.followUpBehaviorAria': 'Follow-up behavior: {option}',
|
||||
'settings.openchamber.visual.field.followUpBehaviorDescription': 'Choose what happens when you press Enter on a follow-up message while the agent is still responding.',
|
||||
'settings.openchamber.visual.option.followUpBehavior.steer.label': 'Steer (insert into the running turn)',
|
||||
'settings.openchamber.visual.option.followUpBehavior.queue.label': 'Queue (deliver after the current turn)',
|
||||
} as const;
|
||||
|
||||
Reference in New Issue
Block a user