@deepseek-harness-tui/dsh-tui 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -21
- package/bin/dsh-tui.js +115 -25
- package/cordis.patch.yml +69 -17
- package/cordis.yml +50 -12
- package/lib/types/activityPrefs.d.ts +1 -1
- package/lib/types/activityPrefs.js +3 -3
- package/lib/types/cc/figures.d.ts +27 -20
- package/lib/types/cc/figures.d.ts.map +1 -1
- package/lib/types/cc/figures.js +43 -34
- package/lib/types/cc/format.d.ts +18 -9
- package/lib/types/cc/format.d.ts.map +1 -1
- package/lib/types/cc/format.js +26 -18
- package/lib/types/cc/markdown.d.ts +31 -16
- package/lib/types/cc/markdown.d.ts.map +1 -1
- package/lib/types/cc/markdown.js +283 -260
- package/lib/types/cc/terminal.d.ts +10 -7
- package/lib/types/cc/terminal.d.ts.map +1 -1
- package/lib/types/cc/terminal.js +62 -50
- package/lib/types/command-trees.d.ts +3 -0
- package/lib/types/command-trees.d.ts.map +1 -0
- package/lib/types/command-trees.js +4 -0
- package/lib/types/commands.d.ts +37 -1
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +68 -3
- package/lib/types/components/ActivityLine.d.ts +1 -1
- package/lib/types/components/ActivityLine.d.ts.map +1 -1
- package/lib/types/components/ActivityPicker.d.ts.map +1 -1
- package/lib/types/components/ActivityPicker.js +3 -4
- package/lib/types/components/BtwPanel.d.ts +16 -0
- package/lib/types/components/BtwPanel.d.ts.map +1 -0
- package/lib/types/components/BtwPanel.js +47 -0
- package/lib/types/components/CommandSuggestions.d.ts +4 -2
- package/lib/types/components/CommandSuggestions.d.ts.map +1 -1
- package/lib/types/components/CommandSuggestions.js +2 -2
- package/lib/types/components/EffortSlider.d.ts +15 -0
- package/lib/types/components/EffortSlider.d.ts.map +1 -0
- package/lib/types/components/EffortSlider.js +17 -0
- package/lib/types/components/GoalTodoPanel.d.ts +1 -1
- package/lib/types/components/GoalTodoPanel.d.ts.map +1 -1
- package/lib/types/components/HelpMenu.d.ts +5 -2
- package/lib/types/components/HelpMenu.d.ts.map +1 -1
- package/lib/types/components/HelpMenu.js +8 -3
- package/lib/types/components/HistorySearchDialog.d.ts +1 -1
- package/lib/types/components/HistorySearchDialog.d.ts.map +1 -1
- package/lib/types/components/HistorySearchDialog.js +21 -10
- package/lib/types/components/InterruptedByUser.d.ts +2 -2
- package/lib/types/components/InterruptedByUser.d.ts.map +1 -1
- package/lib/types/components/InterruptedByUser.js +4 -3
- package/lib/types/components/LoadedContextPanel.d.ts +1 -1
- package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +2 -1
- package/lib/types/components/Markdown.d.ts +11 -11
- package/lib/types/components/Markdown.d.ts.map +1 -1
- package/lib/types/components/Markdown.js +63 -57
- package/lib/types/components/MarkdownTable.d.ts +1 -1
- package/lib/types/components/MarkdownTable.js +2 -2
- package/lib/types/components/MessageList.d.ts +10 -2
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +17 -10
- package/lib/types/components/ModelPicker.d.ts +4 -1
- package/lib/types/components/ModelPicker.d.ts.map +1 -1
- package/lib/types/components/ModelPicker.js +16 -4
- package/lib/types/components/OverlayAbove.d.ts +20 -0
- package/lib/types/components/OverlayAbove.d.ts.map +1 -0
- package/lib/types/components/OverlayAbove.js +18 -0
- package/lib/types/components/PresetPicker.d.ts +1 -1
- package/lib/types/components/PresetPicker.d.ts.map +1 -1
- package/lib/types/components/PresetPicker.js +2 -3
- package/lib/types/components/PromptInput.d.ts +5 -4
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +186 -39
- package/lib/types/components/ResumePicker.d.ts +15 -4
- package/lib/types/components/ResumePicker.d.ts.map +1 -1
- package/lib/types/components/ResumePicker.js +25 -9
- package/lib/types/components/RewindPicker.d.ts +1 -1
- package/lib/types/components/RewindPicker.d.ts.map +1 -1
- package/lib/types/components/RewindPicker.js +14 -5
- package/lib/types/components/SearchBox.d.ts +1 -1
- package/lib/types/components/SearchBox.js +1 -1
- package/lib/types/components/Spinner/GlimmerMessage.d.ts +1 -2
- package/lib/types/components/Spinner/GlimmerMessage.d.ts.map +1 -1
- package/lib/types/components/Spinner/GlimmerMessage.js +1 -2
- package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts +1 -1
- package/lib/types/components/Spinner/SpinnerAnimationRow.js +2 -2
- package/lib/types/components/Spinner/SpinnerGlyph.d.ts +1 -1
- package/lib/types/components/Spinner/SpinnerGlyph.js +1 -1
- package/lib/types/components/Spinner/spinnerUtils.d.ts +13 -18
- package/lib/types/components/Spinner/spinnerUtils.d.ts.map +1 -1
- package/lib/types/components/Spinner/spinnerUtils.js +67 -71
- package/lib/types/components/Spinner/useStalledAnimation.d.ts +1 -2
- package/lib/types/components/Spinner/useStalledAnimation.d.ts.map +1 -1
- package/lib/types/components/Spinner/useStalledAnimation.js +1 -2
- package/lib/types/components/StreamingMarkdown.d.ts +1 -1
- package/lib/types/components/StreamingMarkdown.js +1 -1
- package/lib/types/components/ThemePicker.d.ts +13 -9
- package/lib/types/components/ThemePicker.d.ts.map +1 -1
- package/lib/types/components/ThemePicker.js +21 -15
- package/lib/types/components/ThinkingToggle.d.ts +1 -1
- package/lib/types/components/ThinkingToggle.d.ts.map +1 -1
- package/lib/types/components/ThinkingToggle.js +8 -8
- package/lib/types/components/ToolUseLoader.d.ts +1 -1
- package/lib/types/components/ToolUseLoader.js +1 -1
- package/lib/types/components/WorkingSpinner.d.ts +2 -2
- package/lib/types/components/WorkingSpinner.js +2 -2
- package/lib/types/components/WorkspaceFlowPicker.d.ts +15 -0
- package/lib/types/components/WorkspaceFlowPicker.d.ts.map +1 -0
- package/lib/types/components/WorkspaceFlowPicker.js +19 -0
- package/lib/types/components/WorkspacePicker.d.ts +9 -0
- package/lib/types/components/WorkspacePicker.d.ts.map +1 -0
- package/lib/types/components/WorkspacePicker.js +13 -0
- package/lib/types/components/approvals/ApprovalPanel.d.ts +1 -1
- package/lib/types/components/approvals/ApprovalPanel.d.ts.map +1 -1
- package/lib/types/components/approvals/ApprovalPanel.js +2 -1
- package/lib/types/components/design-system/Byline.d.ts +1 -1
- package/lib/types/components/design-system/Byline.js +1 -1
- package/lib/types/components/design-system/Divider.d.ts +1 -1
- package/lib/types/components/design-system/Divider.js +1 -1
- package/lib/types/components/design-system/HintLine.d.ts +12 -0
- package/lib/types/components/design-system/HintLine.d.ts.map +1 -0
- package/lib/types/components/design-system/HintLine.js +15 -0
- package/lib/types/components/design-system/KeyboardShortcutHint.d.ts +1 -1
- package/lib/types/components/design-system/KeyboardShortcutHint.js +1 -1
- package/lib/types/components/design-system/ListItem.d.ts +2 -2
- package/lib/types/components/design-system/ListItem.d.ts.map +1 -1
- package/lib/types/components/design-system/ListItem.js +35 -3
- package/lib/types/components/design-system/LoadingState.d.ts +1 -2
- package/lib/types/components/design-system/LoadingState.d.ts.map +1 -1
- package/lib/types/components/design-system/LoadingState.js +1 -2
- package/lib/types/components/design-system/Pane.d.ts +2 -2
- package/lib/types/components/design-system/Pane.js +2 -2
- package/lib/types/components/design-system/ProgressBar.d.ts +1 -2
- package/lib/types/components/design-system/ProgressBar.d.ts.map +1 -1
- package/lib/types/components/design-system/ProgressBar.js +1 -2
- package/lib/types/components/design-system/StatusIcon.d.ts +2 -2
- package/lib/types/components/design-system/StatusIcon.js +2 -2
- package/lib/types/components/design-system/ThemeProvider.d.ts +1 -1
- package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -1
- package/lib/types/components/design-system/ThemeProvider.js +87 -26
- package/lib/types/components/design-system/ThemedBox.d.ts +1 -1
- package/lib/types/components/design-system/ThemedBox.js +1 -1
- package/lib/types/components/design-system/ThemedText.d.ts +2 -2
- package/lib/types/components/design-system/ThemedText.js +2 -2
- package/lib/types/components/listWindow.d.ts +26 -0
- package/lib/types/components/listWindow.d.ts.map +1 -0
- package/lib/types/components/listWindow.js +47 -0
- package/lib/types/components/messages/AssistantTextMessage.d.ts +1 -2
- package/lib/types/components/messages/AssistantTextMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantTextMessage.js +1 -2
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts +2 -2
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantThinkingMessage.js +6 -6
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +12 -4
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +9 -5
- package/lib/types/components/messages/MessageMetadata.d.ts +1 -1
- package/lib/types/components/messages/MessageMetadata.js +1 -1
- package/lib/types/components/messages/UserPromptMessage.d.ts +1 -1
- package/lib/types/components/messages/UserPromptMessage.js +1 -1
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts +5 -1
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
- package/lib/types/components/questions/AskUserQuestionPanel.js +11 -9
- package/lib/types/components/questions/PlanReviewPanel.d.ts +1 -1
- package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
- package/lib/types/components/questions/PlanReviewPanel.js +3 -2
- package/lib/types/components/trajectory/HotspotView.d.ts +14 -0
- package/lib/types/components/trajectory/HotspotView.d.ts.map +1 -0
- package/lib/types/components/trajectory/HotspotView.js +83 -0
- package/lib/types/components/trajectory/Inspector.d.ts +31 -0
- package/lib/types/components/trajectory/Inspector.d.ts.map +1 -0
- package/lib/types/components/trajectory/Inspector.js +67 -0
- package/lib/types/components/trajectory/Ledger.d.ts +20 -0
- package/lib/types/components/trajectory/Ledger.d.ts.map +1 -0
- package/lib/types/components/trajectory/Ledger.js +112 -0
- package/lib/types/components/trajectory/MiniWake.d.ts +24 -0
- package/lib/types/components/trajectory/MiniWake.d.ts.map +1 -0
- package/lib/types/components/trajectory/MiniWake.js +99 -0
- package/lib/types/components/trajectory/WaveBand.d.ts +33 -0
- package/lib/types/components/trajectory/WaveBand.d.ts.map +1 -0
- package/lib/types/components/trajectory/WaveBand.js +145 -0
- package/lib/types/customTheme.d.ts +6 -6
- package/lib/types/customTheme.d.ts.map +1 -1
- package/lib/types/customTheme.js +15 -12
- package/lib/types/dsh-adapter/approvals.d.ts.map +1 -0
- package/lib/types/{channel.d.ts → dsh-adapter/channel.d.ts} +184 -43
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -0
- package/lib/types/{channel.js → dsh-adapter/channel.js} +972 -201
- package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -0
- package/lib/types/{childStderr.js → dsh-adapter/childStderr.js} +1 -1
- package/lib/types/dsh-adapter/command-trees.d.ts +27 -0
- package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -0
- package/lib/types/dsh-adapter/command-trees.js +42 -0
- package/lib/types/dsh-adapter/compat/index.d.ts +22 -0
- package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -0
- package/lib/types/{compat → dsh-adapter/compat}/index.js +7 -4
- package/lib/types/dsh-adapter/compat/sessionLog.d.ts +86 -0
- package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/sessionLog.js +347 -0
- package/lib/types/dsh-adapter/contract.d.ts +20 -0
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -0
- package/lib/types/dsh-adapter/contract.js +109 -0
- package/lib/types/dsh-adapter/index.d.ts +80 -0
- package/lib/types/dsh-adapter/index.d.ts.map +1 -0
- package/lib/types/dsh-adapter/index.js +45 -0
- package/lib/types/dsh-adapter/invariant.d.ts.map +1 -0
- package/lib/types/dsh-adapter/packaged-skills.d.ts.map +1 -0
- package/lib/types/{plugin.d.ts → dsh-adapter/plugin.d.ts} +17 -0
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -0
- package/lib/types/{plugin.js → dsh-adapter/plugin.js} +280 -80
- package/lib/types/dsh-adapter/presets.d.ts.map +1 -0
- package/lib/types/dsh-adapter/providerWizard.d.ts +91 -0
- package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -0
- package/lib/types/dsh-adapter/providerWizard.js +332 -0
- package/lib/types/{questions.d.ts → dsh-adapter/questions.d.ts} +7 -2
- package/lib/types/dsh-adapter/questions.d.ts.map +1 -0
- package/lib/types/{questions.js → dsh-adapter/questions.js} +15 -7
- package/lib/types/dsh-adapter/sideQuestion.d.ts +38 -0
- package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sideQuestion.js +69 -0
- package/lib/types/dsh-adapter/trajectory/aggregate.d.ts +46 -0
- package/lib/types/dsh-adapter/trajectory/aggregate.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/aggregate.js +207 -0
- package/lib/types/dsh-adapter/trajectory/guards.d.ts +177 -0
- package/lib/types/dsh-adapter/trajectory/guards.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/guards.js +235 -0
- package/lib/types/dsh-adapter/trajectory/index.d.ts +16 -0
- package/lib/types/dsh-adapter/trajectory/index.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/index.js +15 -0
- package/lib/types/dsh-adapter/trajectory/inspect.d.ts +40 -0
- package/lib/types/dsh-adapter/trajectory/inspect.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/inspect.js +160 -0
- package/lib/types/dsh-adapter/trajectory/projection.d.ts +128 -0
- package/lib/types/dsh-adapter/trajectory/projection.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/projection.js +653 -0
- package/lib/types/dsh-adapter/trajectory/types.d.ts +232 -0
- package/lib/types/dsh-adapter/trajectory/types.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/types.js +70 -0
- package/lib/types/dsh-adapter/trajectory/wave.d.ts +45 -0
- package/lib/types/dsh-adapter/trajectory/wave.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/wave.js +210 -0
- package/lib/types/dsh-adapter/types.d.ts +23 -0
- package/lib/types/dsh-adapter/types.d.ts.map +1 -0
- package/lib/types/dsh-adapter/types.js +1 -0
- package/lib/types/dsh-adapter/workspace.d.ts +22 -0
- package/lib/types/dsh-adapter/workspace.d.ts.map +1 -0
- package/lib/types/dsh-adapter/workspace.js +16 -0
- package/lib/types/dsh-adapter/workspaces.d.ts +118 -0
- package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -0
- package/lib/types/dsh-adapter/workspaces.js +290 -0
- package/lib/types/effortPrefs.d.ts +1 -1
- package/lib/types/effortPrefs.js +3 -3
- package/lib/types/history.js +2 -2
- package/lib/types/hooks/useBlink.d.ts +1 -1
- package/lib/types/hooks/useBlink.js +1 -1
- package/lib/types/i18n.d.ts +977 -36
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +307 -30
- package/lib/types/index.d.ts +1 -69
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +3 -31
- package/lib/types/ink/components/App.d.ts.map +1 -1
- package/lib/types/ink/components/App.js +33 -19
- package/lib/types/ink/dom.d.ts +15 -0
- package/lib/types/ink/dom.d.ts.map +1 -1
- package/lib/types/ink/dom.js +32 -0
- package/lib/types/ink/hooks/use-input.d.ts.map +1 -1
- package/lib/types/ink/hooks/use-input.js +8 -0
- package/lib/types/ink/hooks/use-terminal-size.d.ts +1 -1
- package/lib/types/ink/hooks/use-terminal-size.js +1 -1
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +109 -28
- package/lib/types/ink/input-suppression.d.ts +20 -0
- package/lib/types/ink/input-suppression.d.ts.map +1 -0
- package/lib/types/ink/input-suppression.js +26 -0
- package/lib/types/ink/log-update.js +21 -6
- package/lib/types/ink/parse-keypress.d.ts +31 -0
- package/lib/types/ink/parse-keypress.d.ts.map +1 -1
- package/lib/types/ink/parse-keypress.js +442 -8
- package/lib/types/ink/terminal-querier.d.ts +5 -1
- package/lib/types/ink/terminal-querier.d.ts.map +1 -1
- package/lib/types/ink/terminal-querier.js +27 -3
- package/lib/types/ink/terminal.d.ts +18 -0
- package/lib/types/ink/terminal.d.ts.map +1 -1
- package/lib/types/ink/terminal.js +32 -4
- package/lib/types/ink/termio/csi.d.ts +10 -0
- package/lib/types/ink/termio/csi.d.ts.map +1 -1
- package/lib/types/ink/termio/csi.js +20 -0
- package/lib/types/ink/termio/tokenize.js +10 -0
- package/lib/types/modelPrefs.d.ts +1 -1
- package/lib/types/modelPrefs.js +3 -3
- package/lib/types/presetPrefs.d.ts +1 -1
- package/lib/types/presetPrefs.js +3 -3
- package/lib/types/screens/Chat.d.ts +20 -4
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +655 -55
- package/lib/types/screens/StatusLine.d.ts +17 -2
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +12 -4
- package/lib/types/screens/TrajectoryScene.d.ts +16 -0
- package/lib/types/screens/TrajectoryScene.d.ts.map +1 -0
- package/lib/types/screens/TrajectoryScene.js +305 -0
- package/lib/types/sessionHistory.d.ts +9 -1
- package/lib/types/sessionHistory.d.ts.map +1 -1
- package/lib/types/sessionHistory.js +56 -16
- package/lib/types/sessionModes.d.ts +29 -0
- package/lib/types/sessionModes.d.ts.map +1 -0
- package/lib/types/sessionModes.js +45 -0
- package/lib/types/theme.d.ts +27 -3
- package/lib/types/theme.d.ts.map +1 -1
- package/lib/types/theme.js +48 -4
- package/lib/types/themePrefs.d.ts +3 -3
- package/lib/types/themePrefs.js +5 -5
- package/lib/types/trajectory/format.d.ts +100 -0
- package/lib/types/trajectory/format.d.ts.map +1 -0
- package/lib/types/trajectory/format.js +213 -0
- package/lib/types/trajectory/motion.d.ts +99 -0
- package/lib/types/trajectory/motion.d.ts.map +1 -0
- package/lib/types/trajectory/motion.js +143 -0
- package/lib/types/trajectory/query.d.ts +83 -0
- package/lib/types/trajectory/query.d.ts.map +1 -0
- package/lib/types/trajectory/query.js +187 -0
- package/lib/types/trajectoryPrefs.d.ts +36 -0
- package/lib/types/trajectoryPrefs.d.ts.map +1 -0
- package/lib/types/trajectoryPrefs.js +65 -0
- package/lib/types/update.d.ts +3 -3
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +18 -7
- package/lib/types/utils/clipboard.d.ts +101 -29
- package/lib/types/utils/clipboard.d.ts.map +1 -1
- package/lib/types/utils/clipboard.js +533 -55
- package/lib/types/utils/debug.d.ts +1 -1
- package/lib/types/utils/debug.js +2 -2
- package/lib/types/utils/execFileNoThrow.d.ts.map +1 -1
- package/lib/types/utils/execFileNoThrow.js +16 -6
- package/lib/types/utils/externalEditor.d.ts +115 -0
- package/lib/types/utils/externalEditor.d.ts.map +1 -0
- package/lib/types/utils/externalEditor.js +270 -0
- package/lib/types/utils/fullscreen.d.ts +2 -2
- package/lib/types/utils/fullscreen.js +3 -3
- package/lib/types/utils/loaded-context.d.ts +1 -1
- package/lib/types/utils/loaded-context.d.ts.map +1 -1
- package/lib/types/utils/modifiers.d.ts +24 -0
- package/lib/types/utils/modifiers.d.ts.map +1 -1
- package/lib/types/utils/modifiers.js +27 -0
- package/lib/types/utils/paths.d.ts +45 -0
- package/lib/types/utils/paths.d.ts.map +1 -0
- package/lib/types/utils/paths.js +69 -0
- package/lib/types/utils/shellQuote.d.ts +14 -0
- package/lib/types/utils/shellQuote.d.ts.map +1 -0
- package/lib/types/utils/shellQuote.js +39 -0
- package/lib/types/utils/workspaceRoot.d.ts +21 -0
- package/lib/types/utils/workspaceRoot.d.ts.map +1 -0
- package/lib/types/utils/workspaceRoot.js +47 -0
- package/lib/types/workspaces.d.ts +3 -0
- package/lib/types/workspaces.d.ts.map +1 -0
- package/lib/types/workspaces.js +4 -0
- package/package.json +26 -8
- package/lib/types/approvals.d.ts.map +0 -1
- package/lib/types/channel.d.ts.map +0 -1
- package/lib/types/childStderr.d.ts.map +0 -1
- package/lib/types/compat/index.d.ts +0 -20
- package/lib/types/compat/index.d.ts.map +0 -1
- package/lib/types/compat/sessionLog.d.ts +0 -40
- package/lib/types/compat/sessionLog.d.ts.map +0 -1
- package/lib/types/compat/sessionLog.js +0 -226
- package/lib/types/invariant.d.ts.map +0 -1
- package/lib/types/packaged-skills.d.ts.map +0 -1
- package/lib/types/plugin.d.ts.map +0 -1
- package/lib/types/presets.d.ts.map +0 -1
- package/lib/types/questions.d.ts.map +0 -1
- /package/lib/types/{approvals.d.ts → dsh-adapter/approvals.d.ts} +0 -0
- /package/lib/types/{approvals.js → dsh-adapter/approvals.js} +0 -0
- /package/lib/types/{childStderr.d.ts → dsh-adapter/childStderr.d.ts} +0 -0
- /package/lib/types/{invariant.d.ts → dsh-adapter/invariant.d.ts} +0 -0
- /package/lib/types/{invariant.js → dsh-adapter/invariant.js} +0 -0
- /package/lib/types/{packaged-skills.d.ts → dsh-adapter/packaged-skills.d.ts} +0 -0
- /package/lib/types/{packaged-skills.js → dsh-adapter/packaged-skills.js} +0 -0
- /package/lib/types/{presets.d.ts → dsh-adapter/presets.d.ts} +0 -0
- /package/lib/types/{presets.js → dsh-adapter/presets.js} +0 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/provider` wizard — interactively adds an LLM provider route at runtime.
|
|
3
|
+
*
|
|
4
|
+
* The wizard is a sequence of `QuestionStore` asks (the same panel the
|
|
5
|
+
* model-facing `ask_user_question` tool uses), so it needs no UI state of
|
|
6
|
+
* its own. All side effects go through {@link ProviderSetupHost}, which the
|
|
7
|
+
* channel implements over the dsh settings/credentials/llm seams:
|
|
8
|
+
*
|
|
9
|
+
* profile → settings `llm-pi-ai.providers.<route>` (dsh-llm-pi-ai watches
|
|
10
|
+
* the section and registers the route without a restart)
|
|
11
|
+
* key → credentials store (`~/.dsh/.credentials.yaml`, 0600), named by
|
|
12
|
+
* the derived `<ROUTE>_API_KEY` env-style ref the profile's
|
|
13
|
+
* `apiKeyEnv` points at
|
|
14
|
+
*
|
|
15
|
+
* The module is React-free so `scripts/verify-provider-wizard.mjs` can drive
|
|
16
|
+
* it headless with a stubbed host and scripted answers.
|
|
17
|
+
*/
|
|
18
|
+
import { t } from '../i18n.js';
|
|
19
|
+
import { UserQuestionError, } from '@deepseek-ai/dsh-user-questions';
|
|
20
|
+
/** Route id rule shared with the dsh configuration surface (web Models page). */
|
|
21
|
+
export const PROVIDER_ROUTE_ID = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
|
|
22
|
+
/** Wire protocols dsh-llm-pi-ai can serve on a manually declared route. */
|
|
23
|
+
export const PROVIDER_PROTOCOLS = [
|
|
24
|
+
'openai-completions',
|
|
25
|
+
'openai-responses',
|
|
26
|
+
'anthropic-messages',
|
|
27
|
+
];
|
|
28
|
+
/**
|
|
29
|
+
* Derive the credential ref for a route, matching the official web UI
|
|
30
|
+
* convention so TUI- and web-added providers resolve the same key.
|
|
31
|
+
*/
|
|
32
|
+
export function deriveKeyRef(route) {
|
|
33
|
+
return `${route.toUpperCase().replace(/[^A-Z0-9]+/g, '_')}_API_KEY`;
|
|
34
|
+
}
|
|
35
|
+
/** Max attempts for validated free-text prompts before giving up. */
|
|
36
|
+
const MAX_RETRY = 3;
|
|
37
|
+
function answerText(answer, id) {
|
|
38
|
+
return answer.answers.find(item => item.id === id)?.custom?.trim() ?? '';
|
|
39
|
+
}
|
|
40
|
+
function answerSelected(answer, id) {
|
|
41
|
+
return answer.answers.find(item => item.id === id)?.selected ?? [];
|
|
42
|
+
}
|
|
43
|
+
function optionQuestion(id, question, options, extra) {
|
|
44
|
+
const item = {
|
|
45
|
+
id,
|
|
46
|
+
question,
|
|
47
|
+
header: '/provider',
|
|
48
|
+
options: options.map(option => ({ ...option })),
|
|
49
|
+
...(extra?.detail !== undefined ? { detail: extra.detail } : {}),
|
|
50
|
+
...(extra?.multiSelect ? { multiSelect: true } : {}),
|
|
51
|
+
...(extra?.hideCustomInput ? { hideCustomInput: true } : {}),
|
|
52
|
+
};
|
|
53
|
+
return item;
|
|
54
|
+
}
|
|
55
|
+
function textQuestion(id, question, detail) {
|
|
56
|
+
return {
|
|
57
|
+
id,
|
|
58
|
+
question,
|
|
59
|
+
header: '/provider',
|
|
60
|
+
...(detail !== undefined ? { detail } : {}),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Run the add-provider wizard. Resolves 'cancelled' when the user dismisses
|
|
65
|
+
* any question (Esc) — nothing has been written at that point by design:
|
|
66
|
+
* all asks complete before the first side effect.
|
|
67
|
+
*/
|
|
68
|
+
export async function runProviderWizard(deps) {
|
|
69
|
+
const { host, ask, notify, pushLocal } = deps;
|
|
70
|
+
try {
|
|
71
|
+
// ── 1. mode ────────────────────────────────────────────────────────
|
|
72
|
+
const modeAnswer = await ask({
|
|
73
|
+
questions: [optionQuestion('mode', t('provider-q-mode'), [
|
|
74
|
+
{ label: t('provider-opt-catalog'), description: t('provider-opt-catalog-desc') },
|
|
75
|
+
{ label: t('provider-opt-custom'), description: t('provider-opt-custom-desc') },
|
|
76
|
+
], { hideCustomInput: true })],
|
|
77
|
+
});
|
|
78
|
+
const isCatalog = answerSelected(modeAnswer, 'mode')[0] === t('provider-opt-catalog');
|
|
79
|
+
// ── 2. route ───────────────────────────────────────────────────────
|
|
80
|
+
let route = '';
|
|
81
|
+
if (isCatalog) {
|
|
82
|
+
const candidates = host.listCatalogProviders();
|
|
83
|
+
if (candidates.length > 0) {
|
|
84
|
+
const otherLabel = t('provider-opt-other-route');
|
|
85
|
+
const catalogAnswer = await ask({
|
|
86
|
+
questions: [optionQuestion('catalog', t('provider-q-catalog'), [
|
|
87
|
+
...candidates.map(candidate => ({
|
|
88
|
+
label: candidate.provider,
|
|
89
|
+
description: candidate.displayName,
|
|
90
|
+
})),
|
|
91
|
+
{ label: otherLabel, description: t('provider-opt-other-route-desc') },
|
|
92
|
+
], { hideCustomInput: true })],
|
|
93
|
+
});
|
|
94
|
+
const pick = answerSelected(catalogAnswer, 'catalog')[0];
|
|
95
|
+
if (pick !== undefined && pick !== otherLabel)
|
|
96
|
+
route = pick;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (route === '') {
|
|
100
|
+
route = await promptRouteId(ask, notify);
|
|
101
|
+
if (route === '')
|
|
102
|
+
return 'cancelled';
|
|
103
|
+
}
|
|
104
|
+
// ── 3. API key (own batch so redact covers exactly the secret) ─────
|
|
105
|
+
const keyAnswer = await ask({
|
|
106
|
+
questions: [textQuestion('apikey', t('provider-q-apikey'), t('provider-q-apikey-detail'))],
|
|
107
|
+
}, { redact: true });
|
|
108
|
+
const apiKey = answerText(keyAnswer, 'apikey');
|
|
109
|
+
// ── 4. endpoint / protocol ─────────────────────────────────────────
|
|
110
|
+
let baseURL;
|
|
111
|
+
let api;
|
|
112
|
+
if (isCatalog) {
|
|
113
|
+
const choiceAnswer = await ask({
|
|
114
|
+
questions: [optionQuestion('baseurl-choice', t('provider-q-baseurl-choice'), [
|
|
115
|
+
{ label: t('provider-opt-baseurl-skip') },
|
|
116
|
+
{ label: t('provider-opt-baseurl-input') },
|
|
117
|
+
], { hideCustomInput: true })],
|
|
118
|
+
});
|
|
119
|
+
if (answerSelected(choiceAnswer, 'baseurl-choice')[0] === t('provider-opt-baseurl-input')) {
|
|
120
|
+
const urlAnswer = await ask({
|
|
121
|
+
questions: [textQuestion('baseurl', t('provider-q-baseurl'))],
|
|
122
|
+
});
|
|
123
|
+
baseURL = answerText(urlAnswer, 'baseurl');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
const endpointAnswer = await ask({
|
|
128
|
+
questions: [
|
|
129
|
+
textQuestion('baseurl', t('provider-q-baseurl')),
|
|
130
|
+
optionQuestion('protocol', t('provider-q-protocol'), [
|
|
131
|
+
{ label: 'openai-completions', description: t('provider-protocol-completions-desc') },
|
|
132
|
+
{ label: 'openai-responses', description: t('provider-protocol-responses-desc') },
|
|
133
|
+
{ label: 'anthropic-messages', description: t('provider-protocol-anthropic-desc') },
|
|
134
|
+
], { hideCustomInput: true }),
|
|
135
|
+
],
|
|
136
|
+
});
|
|
137
|
+
baseURL = answerText(endpointAnswer, 'baseurl');
|
|
138
|
+
api = answerSelected(endpointAnswer, 'protocol')[0];
|
|
139
|
+
}
|
|
140
|
+
// ── 5. model discovery (draft credential, nothing persisted) ───────
|
|
141
|
+
notify(t('provider-discovery-running'));
|
|
142
|
+
const discovered = await host.discoverModels({
|
|
143
|
+
...(isCatalog ? { provider: route } : {}),
|
|
144
|
+
...(baseURL !== undefined && baseURL !== '' ? { baseURL } : {}),
|
|
145
|
+
...(api !== undefined ? { api } : {}),
|
|
146
|
+
apiKey,
|
|
147
|
+
}).catch(() => []);
|
|
148
|
+
// ── 6. model selection ─────────────────────────────────────────────
|
|
149
|
+
let models = [];
|
|
150
|
+
let discoveredById = new Map();
|
|
151
|
+
if (discovered.length > 0) {
|
|
152
|
+
discoveredById = new Map(discovered.map(model => [model.id, model]));
|
|
153
|
+
const modelsAnswer = await ask({
|
|
154
|
+
questions: [optionQuestion('models', t('provider-q-models'), discovered.map(model => ({
|
|
155
|
+
label: model.id,
|
|
156
|
+
description: [
|
|
157
|
+
model.name ?? '',
|
|
158
|
+
model.contextWindow !== undefined ? `${model.contextWindow}` : '',
|
|
159
|
+
].filter(part => part !== '').join(' · ') || undefined,
|
|
160
|
+
})), { multiSelect: true })],
|
|
161
|
+
});
|
|
162
|
+
models = mergeModelIds(answerSelected(modelsAnswer, 'models'), answerText(modelsAnswer, 'models'));
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
notify(t('provider-discovery-failed'), { color: 'warning' });
|
|
166
|
+
for (let attempt = 0; attempt < MAX_RETRY && models.length === 0; attempt += 1) {
|
|
167
|
+
const fallbackAnswer = await ask({
|
|
168
|
+
questions: [textQuestion('models-fallback', t('provider-q-models-fallback'))],
|
|
169
|
+
});
|
|
170
|
+
models = mergeModelIds([], answerText(fallbackAnswer, 'models-fallback'));
|
|
171
|
+
if (models.length === 0)
|
|
172
|
+
notify(t('provider-models-required'), { color: 'warning' });
|
|
173
|
+
}
|
|
174
|
+
if (models.length === 0)
|
|
175
|
+
return 'cancelled';
|
|
176
|
+
}
|
|
177
|
+
if (!isCatalog && models.length === 0) {
|
|
178
|
+
// A manual route without models fails the adapter validation; the
|
|
179
|
+
// loops above should prevent this, but guard before writing.
|
|
180
|
+
notify(t('provider-models-required'), { color: 'error' });
|
|
181
|
+
return 'cancelled';
|
|
182
|
+
}
|
|
183
|
+
// ── 7. confirm ─────────────────────────────────────────────────────
|
|
184
|
+
const ref = deriveKeyRef(route);
|
|
185
|
+
const shadowed = host.envShadows(ref);
|
|
186
|
+
const summaryLines = buildSummaryLines({
|
|
187
|
+
route, ref, shadowed, baseURL, api, models, isCatalog,
|
|
188
|
+
});
|
|
189
|
+
const detail = host.routeExists(route)
|
|
190
|
+
? `${summaryLines.join('\n')}\n${t('provider-route-exists-warning')}`
|
|
191
|
+
: summaryLines.join('\n');
|
|
192
|
+
const confirmAnswer = await ask({
|
|
193
|
+
questions: [optionQuestion('confirm', t('provider-q-confirm'), [
|
|
194
|
+
{ label: t('provider-opt-confirm-write') },
|
|
195
|
+
{ label: t('provider-opt-confirm-cancel') },
|
|
196
|
+
], { detail, hideCustomInput: true })],
|
|
197
|
+
});
|
|
198
|
+
if (answerSelected(confirmAnswer, 'confirm')[0] !== t('provider-opt-confirm-write')) {
|
|
199
|
+
notify(t('provider-cancelled'));
|
|
200
|
+
return 'cancelled';
|
|
201
|
+
}
|
|
202
|
+
// ── 8. persist: credential first (rollbackable), then the profile ──
|
|
203
|
+
let wroteCredential = false;
|
|
204
|
+
let previousCredential;
|
|
205
|
+
if (!shadowed) {
|
|
206
|
+
// Capture any pre-existing value BEFORE overwriting: when the profile
|
|
207
|
+
// write below fails, rollback must restore it — an unconditional unset
|
|
208
|
+
// would destroy the old key of the route being overwritten.
|
|
209
|
+
previousCredential = await host.readCredential(ref);
|
|
210
|
+
await host.writeCredential(ref, apiKey);
|
|
211
|
+
wroteCredential = true;
|
|
212
|
+
}
|
|
213
|
+
const profile = buildProfile({ isCatalog, ref, baseURL, api, models, discoveredById });
|
|
214
|
+
try {
|
|
215
|
+
await host.writeProfile(route, profile);
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
if (wroteCredential) {
|
|
219
|
+
try {
|
|
220
|
+
if (previousCredential !== undefined) {
|
|
221
|
+
await host.writeCredential(ref, previousCredential);
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
await host.removeCredential(ref);
|
|
225
|
+
}
|
|
226
|
+
notify(t('provider-rollback-ok'));
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
notify(t('provider-rollback-failed'), { color: 'warning' });
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const err = error instanceof Error ? error.message : String(error);
|
|
233
|
+
notify(t('provider-write-failed', { err }), { color: 'error', timeoutMs: 8000 });
|
|
234
|
+
return 'failed';
|
|
235
|
+
}
|
|
236
|
+
// ── 9. success: transcript summary + optional live switch ──────────
|
|
237
|
+
pushLocal('/provider', [
|
|
238
|
+
...summaryLines,
|
|
239
|
+
...(deps.working() || models.length === 0
|
|
240
|
+
? [t('provider-switch-hint')]
|
|
241
|
+
: []),
|
|
242
|
+
]);
|
|
243
|
+
notify(t('provider-success', { route }), { color: 'success' });
|
|
244
|
+
if (!deps.working() && models.length > 0) {
|
|
245
|
+
const target = models[0];
|
|
246
|
+
const switchAnswer = await ask({
|
|
247
|
+
questions: [optionQuestion('switch', t('provider-q-switch'), [
|
|
248
|
+
{ label: t('provider-opt-switch-now', { model: target }) },
|
|
249
|
+
{ label: t('provider-opt-switch-keep') },
|
|
250
|
+
], { hideCustomInput: true })],
|
|
251
|
+
});
|
|
252
|
+
if (answerSelected(switchAnswer, 'switch')[0] === t('provider-opt-switch-now', { model: target })) {
|
|
253
|
+
await deps.switchModel(route, target);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return 'added';
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
if (error instanceof UserQuestionError) {
|
|
260
|
+
notify(t('provider-cancelled'));
|
|
261
|
+
return 'cancelled';
|
|
262
|
+
}
|
|
263
|
+
const err = error instanceof Error ? error.message : String(error);
|
|
264
|
+
notify(t('provider-write-failed', { err }), { color: 'error', timeoutMs: 8000 });
|
|
265
|
+
return 'failed';
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/** Prompt for a route id until it validates or the retry budget runs out. */
|
|
269
|
+
async function promptRouteId(ask, notify) {
|
|
270
|
+
for (let attempt = 0; attempt < MAX_RETRY; attempt += 1) {
|
|
271
|
+
const answer = await ask({
|
|
272
|
+
questions: [textQuestion('route-id', t('provider-q-route-id'), t('provider-q-route-id-detail'))],
|
|
273
|
+
});
|
|
274
|
+
const route = answerText(answer, 'route-id');
|
|
275
|
+
if (PROVIDER_ROUTE_ID.test(route))
|
|
276
|
+
return route;
|
|
277
|
+
notify(t('provider-route-id-invalid'), { color: 'warning' });
|
|
278
|
+
}
|
|
279
|
+
return '';
|
|
280
|
+
}
|
|
281
|
+
/** Merge multi-select picks with comma/space-separated custom input, deduped. */
|
|
282
|
+
function mergeModelIds(selected, custom) {
|
|
283
|
+
const ids = [...selected];
|
|
284
|
+
for (const piece of custom.split(/[,,\s]+/)) {
|
|
285
|
+
const id = piece.trim();
|
|
286
|
+
if (id !== '' && !ids.includes(id))
|
|
287
|
+
ids.push(id);
|
|
288
|
+
}
|
|
289
|
+
return ids;
|
|
290
|
+
}
|
|
291
|
+
function buildSummaryLines(input) {
|
|
292
|
+
const lines = [t('provider-line-route', { route: input.route })];
|
|
293
|
+
lines.push(input.shadowed
|
|
294
|
+
? t('provider-line-keyref-env', { ref: input.ref })
|
|
295
|
+
: t('provider-line-keyref', { ref: input.ref }));
|
|
296
|
+
if (input.baseURL !== undefined && input.baseURL !== '') {
|
|
297
|
+
lines.push(t('provider-line-baseurl', { url: input.baseURL }));
|
|
298
|
+
}
|
|
299
|
+
if (input.api !== undefined)
|
|
300
|
+
lines.push(t('provider-line-protocol', { api: input.api }));
|
|
301
|
+
lines.push(input.models.length > 0
|
|
302
|
+
? t('provider-line-models', { models: input.models.join(', ') })
|
|
303
|
+
: t('provider-line-models-catalog'));
|
|
304
|
+
return lines;
|
|
305
|
+
}
|
|
306
|
+
function buildProfile(input) {
|
|
307
|
+
const profile = { apiKeyEnv: input.ref };
|
|
308
|
+
if (input.baseURL !== undefined && input.baseURL !== '')
|
|
309
|
+
profile['baseURL'] = input.baseURL;
|
|
310
|
+
if (input.isCatalog) {
|
|
311
|
+
// `models` replaces the catalog when present; omit it to keep the whole
|
|
312
|
+
// catalog served.
|
|
313
|
+
if (input.models.length > 0) {
|
|
314
|
+
profile['models'] = input.models.map(id => ({ id }));
|
|
315
|
+
}
|
|
316
|
+
return profile;
|
|
317
|
+
}
|
|
318
|
+
profile['api'] = input.api;
|
|
319
|
+
profile['models'] = input.models.map(id => {
|
|
320
|
+
const discovered = input.discoveredById.get(id);
|
|
321
|
+
return {
|
|
322
|
+
id,
|
|
323
|
+
...(discovered?.contextWindow !== undefined
|
|
324
|
+
? { contextWindow: discovered.contextWindow }
|
|
325
|
+
: {}),
|
|
326
|
+
...(discovered?.maxTokens !== undefined
|
|
327
|
+
? { maxTokens: discovered.maxTokens }
|
|
328
|
+
: {}),
|
|
329
|
+
};
|
|
330
|
+
});
|
|
331
|
+
return profile;
|
|
332
|
+
}
|
|
@@ -74,12 +74,17 @@ export declare class QuestionStore {
|
|
|
74
74
|
private rebuildSnapshot;
|
|
75
75
|
/**
|
|
76
76
|
* Provider entry point — called by `ctx.userQuestions.ask()` when the
|
|
77
|
-
* model runs the `ask_user_question` tool.
|
|
77
|
+
* model runs the `ask_user_question` tool, and by local wizards (e.g.
|
|
78
|
+
* `/provider`) driving the same panel.
|
|
78
79
|
* @param request - The ask request: questions plus optional abort signal.
|
|
80
|
+
* @param options - `redact` hides answer text from the transcript summary
|
|
81
|
+
* (use for batches that collect secrets such as API keys).
|
|
79
82
|
* @returns A promise settling with the collected answers when the user
|
|
80
83
|
* submits the batch, or rejecting when the ask is interrupted.
|
|
81
84
|
*/
|
|
82
|
-
ask(request: AskUserQuestionRequest
|
|
85
|
+
ask(request: AskUserQuestionRequest, options?: {
|
|
86
|
+
redact?: boolean;
|
|
87
|
+
}): Promise<AskUserQuestionAnswer>;
|
|
83
88
|
/** Advance to the next queued ask, if any. */
|
|
84
89
|
private startNext;
|
|
85
90
|
/**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"questions.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/questions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAEL,KAAK,qBAAqB,EAE1B,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAA;AAExC;mEACmE;AACnE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAsBD,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAA;IACtC,yCAAyC;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,oCAAoC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAClC;AAqCD;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwB;IAC9C,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAClD,OAAO,CAAC,QAAQ,CAAI;IACpB,yEAAyE;IACzE,OAAO,CAAC,SAAS,CAAwB;IACzC;;;OAGG;IACH,OAAO,CAAC,aAAa,CAAgC;IAErD;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAO3C;;;OAGG;IACH,WAAW,IAAI,gBAAgB,GAAG,IAAI;IAItC;;;OAGG;IACH,aAAa,IAAI,eAAe,EAAE;IAMlC,OAAO,CAAC,IAAI;IAIZ,sEAAsE;IACtE,OAAO,CAAC,eAAe;IAgBvB;;;;;;;;;OASG;IACH,GAAG,CAAC,OAAO,EAAE,sBAAsB,EAC/B,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA8BnE,8CAA8C;IAC9C,OAAO,CAAC,SAAS;IAOjB;;;;OAIG;IACH,aAAa,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI;IAwBjD,6DAA6D;IAC7D,aAAa,IAAI,IAAI;IAUrB,+DAA+D;IAC/D,SAAS,IAAI,IAAI;IASjB,wEAAwE;IACxE,OAAO,CAAC,MAAM;IAOd,yEAAyE;IACzE,OAAO,CAAC,IAAI;CAMb"}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* arrive one at a time in practice (the tool blocks until answered), but
|
|
12
12
|
* concurrent asks from subagents are drained FIFO.
|
|
13
13
|
*/
|
|
14
|
-
import { t } from '
|
|
14
|
+
import { t } from '../i18n.js';
|
|
15
15
|
import { UserQuestionError, } from '@deepseek-ai/dsh-user-questions';
|
|
16
16
|
const ASK_ABORTED = 'ASK_ABORTED';
|
|
17
17
|
/**
|
|
@@ -30,10 +30,14 @@ function clip(text, max = 140) {
|
|
|
30
30
|
function buildSummary(pending) {
|
|
31
31
|
const lines = pending.answers.map(answer => {
|
|
32
32
|
const question = pending.request.questions.find(q => q.id === answer.id);
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
const text = pending.redact
|
|
34
|
+
? '••••••'
|
|
35
|
+
: (() => {
|
|
36
|
+
const labels = answer.selected.join('、');
|
|
37
|
+
return answer.custom !== undefined && answer.custom !== ''
|
|
38
|
+
? labels === '' ? answer.custom : `${labels}:${answer.custom}`
|
|
39
|
+
: labels;
|
|
40
|
+
})();
|
|
37
41
|
return `· ${question?.question ?? answer.id} → ${clip(text)}`;
|
|
38
42
|
});
|
|
39
43
|
const total = pending.request.questions.length;
|
|
@@ -109,18 +113,22 @@ export class QuestionStore {
|
|
|
109
113
|
}
|
|
110
114
|
/**
|
|
111
115
|
* Provider entry point — called by `ctx.userQuestions.ask()` when the
|
|
112
|
-
* model runs the `ask_user_question` tool.
|
|
116
|
+
* model runs the `ask_user_question` tool, and by local wizards (e.g.
|
|
117
|
+
* `/provider`) driving the same panel.
|
|
113
118
|
* @param request - The ask request: questions plus optional abort signal.
|
|
119
|
+
* @param options - `redact` hides answer text from the transcript summary
|
|
120
|
+
* (use for batches that collect secrets such as API keys).
|
|
114
121
|
* @returns A promise settling with the collected answers when the user
|
|
115
122
|
* submits the batch, or rejecting when the ask is interrupted.
|
|
116
123
|
*/
|
|
117
|
-
ask(request) {
|
|
124
|
+
ask(request, options) {
|
|
118
125
|
return new Promise((resolve, reject) => {
|
|
119
126
|
const pending = {
|
|
120
127
|
request,
|
|
121
128
|
batchId: ++this.batchSeq,
|
|
122
129
|
index: 0,
|
|
123
130
|
answers: [],
|
|
131
|
+
...(options?.redact ? { redact: true } : {}),
|
|
124
132
|
resolve,
|
|
125
133
|
reject,
|
|
126
134
|
onAbort: () => {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Side Question (`/btw`) — CC's btw.tsx/sideQuestion.ts semantics on the
|
|
3
|
+
* dsh call primitives: a single-turn, TOOL-LESS LLM call replaying the
|
|
4
|
+
* live session's derived history (prompt-cache reuse, compaction-style
|
|
5
|
+
* auxiliary call) plus one wrapped user message. The answer never enters
|
|
6
|
+
* the session log — it is pure UI state in the Chat screen.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import { type StreamChunk } from '@deepseek-ai/dsh-llm';
|
|
11
|
+
/**
|
|
12
|
+
* Wrap a side question with the single-response, no-tools contract (CC's
|
|
13
|
+
* wording): a lightweight instance sharing the conversation context, the
|
|
14
|
+
* main agent uninterrupted, no promises of action, no looking things up.
|
|
15
|
+
*/
|
|
16
|
+
export declare function wrapSideQuestion(question: string): string;
|
|
17
|
+
/** Outcome of one side question: the visible text answer, or an error. */
|
|
18
|
+
export interface SideQuestionOutcome {
|
|
19
|
+
answer: string | null;
|
|
20
|
+
error?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Run one side-question call: stream the assembled options, fold chunks
|
|
24
|
+
* through the shared BlockAssembler, and surface the assembled text
|
|
25
|
+
* blocks as the answer. `onText` receives visible text deltas only
|
|
26
|
+
* (reasoning deltas are ignored — a side question wants the quick answer).
|
|
27
|
+
*/
|
|
28
|
+
export declare function runSideQuestion(params: {
|
|
29
|
+
/** `ctx.llm.stream` (bound); the options below pass through verbatim. */
|
|
30
|
+
stream: (options: object) => AsyncIterable<StreamChunk>;
|
|
31
|
+
/** Assembled GenerateOptions — no `tools` field, ever. */
|
|
32
|
+
options: object;
|
|
33
|
+
/** Streaming display hook (text deltas only). */
|
|
34
|
+
onText?: (delta: string) => void;
|
|
35
|
+
/** Cancellation: aborting yields `{answer: null}` with no error text. */
|
|
36
|
+
signal?: AbortSignal;
|
|
37
|
+
}): Promise<SideQuestionOutcome>;
|
|
38
|
+
//# sourceMappingURL=sideQuestion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sideQuestion.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/sideQuestion.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAEvE;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmBzD;AAED,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC5C,yEAAyE;IACzE,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,aAAa,CAAC,WAAW,CAAC,CAAA;IACvD,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAA;IACf,iDAAiD;IACjD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,yEAAyE;IACzE,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAuB/B"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Side Question (`/btw`) — CC's btw.tsx/sideQuestion.ts semantics on the
|
|
3
|
+
* dsh call primitives: a single-turn, TOOL-LESS LLM call replaying the
|
|
4
|
+
* live session's derived history (prompt-cache reuse, compaction-style
|
|
5
|
+
* auxiliary call) plus one wrapped user message. The answer never enters
|
|
6
|
+
* the session log — it is pure UI state in the Chat screen.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import { BlockAssembler } from '@deepseek-ai/dsh-llm';
|
|
11
|
+
/**
|
|
12
|
+
* Wrap a side question with the single-response, no-tools contract (CC's
|
|
13
|
+
* wording): a lightweight instance sharing the conversation context, the
|
|
14
|
+
* main agent uninterrupted, no promises of action, no looking things up.
|
|
15
|
+
*/
|
|
16
|
+
export function wrapSideQuestion(question) {
|
|
17
|
+
return `<system-reminder>This is a side question from the user. You must answer this question directly in a single response.
|
|
18
|
+
|
|
19
|
+
IMPORTANT CONTEXT:
|
|
20
|
+
- You are a separate, lightweight agent spawned to answer this one question
|
|
21
|
+
- The main agent is NOT interrupted - it continues working independently in the background
|
|
22
|
+
- You share the conversation context but are a completely separate instance
|
|
23
|
+
- Do NOT reference being interrupted or what you were "previously doing" - that framing is incorrect
|
|
24
|
+
|
|
25
|
+
CRITICAL CONSTRAINTS:
|
|
26
|
+
- You have NO tools available - you cannot read files, run commands, search, or take any actions
|
|
27
|
+
- This is a one-off response - there will be no follow-up turns
|
|
28
|
+
- You can ONLY provide information based on what you already know from the conversation context
|
|
29
|
+
- NEVER say things like "Let me try...", "I'll now...", "Let me check...", or promise to take any action
|
|
30
|
+
- If you don't know the answer, say so - do not offer to look it up or investigate
|
|
31
|
+
|
|
32
|
+
Simply answer the question with the information you have.</system-reminder>
|
|
33
|
+
|
|
34
|
+
${question}`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Run one side-question call: stream the assembled options, fold chunks
|
|
38
|
+
* through the shared BlockAssembler, and surface the assembled text
|
|
39
|
+
* blocks as the answer. `onText` receives visible text deltas only
|
|
40
|
+
* (reasoning deltas are ignored — a side question wants the quick answer).
|
|
41
|
+
*/
|
|
42
|
+
export async function runSideQuestion(params) {
|
|
43
|
+
const { stream, options, onText, signal } = params;
|
|
44
|
+
const assembler = new BlockAssembler();
|
|
45
|
+
try {
|
|
46
|
+
for await (const chunk of stream(options)) {
|
|
47
|
+
assembler.push(chunk);
|
|
48
|
+
if (chunk.type === 'text-delta' && chunk.text)
|
|
49
|
+
onText?.(chunk.text);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
if (signal?.aborted)
|
|
54
|
+
return { answer: null };
|
|
55
|
+
return { answer: null, error: error instanceof Error ? error.message : String(error) };
|
|
56
|
+
}
|
|
57
|
+
const finish = assembler.finish;
|
|
58
|
+
if (finish.kind === 'error' || finish.kind === 'aborted') {
|
|
59
|
+
return { answer: null, error: finish.failure.message };
|
|
60
|
+
}
|
|
61
|
+
const answer = assembler.blocks()
|
|
62
|
+
.filter((block) => block.type === 'text')
|
|
63
|
+
.map(block => block.text)
|
|
64
|
+
.join('')
|
|
65
|
+
.trim();
|
|
66
|
+
if (answer === '')
|
|
67
|
+
return { answer: null, error: 'No response received' };
|
|
68
|
+
return { answer };
|
|
69
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trajectory aggregate — the hotspot view's data and the session totals.
|
|
3
|
+
*
|
|
4
|
+
* The ledger answers "what happened, in order". This module answers the other
|
|
5
|
+
* question a long session raises: **where did the time go**. Chronological
|
|
6
|
+
* order is the worst order for that, so everything here is grouped and ranked
|
|
7
|
+
* instead: cost per tool, cost per model phase (decode vs. waiting for the
|
|
8
|
+
* first token vs. retry backoff), cost per turn.
|
|
9
|
+
*
|
|
10
|
+
* Three details make the numbers trustworthy rather than merely plausible:
|
|
11
|
+
*
|
|
12
|
+
* - **Own duration only.** A turn's cost is its own bracket, never the sum of
|
|
13
|
+
* its children — summing both would double-count every tool inside it.
|
|
14
|
+
* - **No fabricated spans.** A step that produced no `assistant/chunk` (the
|
|
15
|
+
* request failed, or the log predates chunk capture) contributes no TTFT and
|
|
16
|
+
* no decode sample rather than a zero that would drag the average down.
|
|
17
|
+
* - **Bursts expand.** A folded run is one ledger row but N calls; the counts
|
|
18
|
+
* and totals here are over calls, so `count` matches what actually ran.
|
|
19
|
+
*/
|
|
20
|
+
import type { HotspotRow, HotspotSort, TrajAggregate, TrajNode } from './types.js';
|
|
21
|
+
import type { TrajBuild } from './projection.js';
|
|
22
|
+
/**
|
|
23
|
+
* Visit every logical call in ledger order, expanding burst rows.
|
|
24
|
+
*
|
|
25
|
+
* @param nodes - The folded ledger.
|
|
26
|
+
* @param visit - Receives each call node plus the ledger index of the row it
|
|
27
|
+
* is displayed under (the burst row's index, for folded members).
|
|
28
|
+
*/
|
|
29
|
+
export declare function forEachCall(nodes: readonly TrajNode[], visit: (node: TrajNode, ledgerIndex: number) => void): void;
|
|
30
|
+
/**
|
|
31
|
+
* Rank hotspot rows by the active sort key.
|
|
32
|
+
*
|
|
33
|
+
* Ties break on label so the order is total — an unstable order would make
|
|
34
|
+
* rows jump between frames while the session streams.
|
|
35
|
+
*/
|
|
36
|
+
export declare function sortRows(rows: readonly HotspotRow[], sort: HotspotSort): HotspotRow[];
|
|
37
|
+
/**
|
|
38
|
+
* Derive the hotspot groups and session totals from a projection.
|
|
39
|
+
*
|
|
40
|
+
* @param build - The current projection.
|
|
41
|
+
* @param sort - Ranking key for the tool and turn groups.
|
|
42
|
+
* @returns Ranked groups plus the counters the scene header and status badge
|
|
43
|
+
* read. Pure: nothing here mutates the build.
|
|
44
|
+
*/
|
|
45
|
+
export declare function aggregate(build: TrajBuild, sort?: HotspotSort): TrajAggregate;
|
|
46
|
+
//# sourceMappingURL=aggregate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregate.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/trajectory/aggregate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAA0B,MAAM,YAAY,CAAA;AAC1G,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAK5D;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,QAAQ,EAAE,EAC1B,KAAK,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,GACnD,IAAI,CASN;AAqCD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,EAAE,CAIrF;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,GAAE,WAAwB,GAAG,aAAa,CAuGzF"}
|