wave-code 0.11.7 → 0.12.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.
Files changed (40) hide show
  1. package/dist/components/ChatInterface.d.ts.map +1 -1
  2. package/dist/components/ChatInterface.js +2 -3
  3. package/dist/components/InputBox.d.ts.map +1 -1
  4. package/dist/components/InputBox.js +6 -2
  5. package/dist/components/MessageBlockItem.d.ts.map +1 -1
  6. package/dist/components/MessageBlockItem.js +2 -1
  7. package/dist/components/MessageList.d.ts +1 -2
  8. package/dist/components/MessageList.d.ts.map +1 -1
  9. package/dist/components/MessageList.js +4 -3
  10. package/dist/components/ModelSelector.d.ts +9 -0
  11. package/dist/components/ModelSelector.d.ts.map +1 -0
  12. package/dist/components/ModelSelector.js +34 -0
  13. package/dist/components/SlashDisplay.d.ts +9 -0
  14. package/dist/components/SlashDisplay.d.ts.map +1 -0
  15. package/dist/components/SlashDisplay.js +20 -0
  16. package/dist/constants/commands.d.ts.map +1 -1
  17. package/dist/constants/commands.js +6 -0
  18. package/dist/contexts/useChat.d.ts +4 -0
  19. package/dist/contexts/useChat.d.ts.map +1 -1
  20. package/dist/contexts/useChat.js +26 -0
  21. package/dist/hooks/useInputManager.d.ts +2 -0
  22. package/dist/hooks/useInputManager.d.ts.map +1 -1
  23. package/dist/hooks/useInputManager.js +8 -0
  24. package/dist/managers/inputHandlers.d.ts.map +1 -1
  25. package/dist/managers/inputHandlers.js +6 -0
  26. package/dist/managers/inputReducer.d.ts +5 -0
  27. package/dist/managers/inputReducer.d.ts.map +1 -1
  28. package/dist/managers/inputReducer.js +7 -0
  29. package/package.json +2 -2
  30. package/src/components/ChatInterface.tsx +0 -4
  31. package/src/components/InputBox.tsx +17 -0
  32. package/src/components/MessageBlockItem.tsx +5 -5
  33. package/src/components/MessageList.tsx +3 -7
  34. package/src/components/ModelSelector.tsx +109 -0
  35. package/src/components/SlashDisplay.tsx +70 -0
  36. package/src/constants/commands.ts +6 -0
  37. package/src/contexts/useChat.tsx +33 -0
  38. package/src/hooks/useInputManager.ts +10 -0
  39. package/src/managers/inputHandlers.ts +5 -0
  40. package/src/managers/inputReducer.ts +10 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ChatInterface.d.ts","sourceRoot":"","sources":["../../src/components/ChatInterface.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AActE,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAyKjC,CAAC"}
1
+ {"version":3,"file":"ChatInterface.d.ts","sourceRoot":"","sources":["../../src/components/ChatInterface.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AActE,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAqKjC,CAAC"}
@@ -16,8 +16,7 @@ export const ChatInterface = () => {
16
16
  const [selectorHeight, setSelectorHeight] = useState(0);
17
17
  const [dynamicBlocksHeight, setDynamicBlocksHeight] = useState(0);
18
18
  const [isConfirmationTooTall, setIsConfirmationTooTall] = useState(false);
19
- const { messages, isLoading, isCommandRunning, isCompressing, sendMessage, abortMessage, mcpServers, connectMcpServer, disconnectMcpServer, isExpanded, sessionId, latestTotalTokens, slashCommands, hasSlashCommand, isConfirmationVisible, confirmingTool, handleConfirmationDecision, handleConfirmationCancel: originalHandleConfirmationCancel, setWasLastDetailsTooTall, version, workdir, getModelConfig, btwState, } = useChat();
20
- const model = getModelConfig().model;
19
+ const { messages, isLoading, isCommandRunning, isCompressing, sendMessage, abortMessage, mcpServers, connectMcpServer, disconnectMcpServer, isExpanded, sessionId, latestTotalTokens, slashCommands, hasSlashCommand, isConfirmationVisible, confirmingTool, handleConfirmationDecision, handleConfirmationCancel: originalHandleConfirmationCancel, setWasLastDetailsTooTall, version, workdir, btwState, } = useChat();
21
20
  const displayMessages = messages;
22
21
  const handleDetailsHeightMeasured = useCallback((height) => {
23
22
  setDetailsHeight(height);
@@ -76,5 +75,5 @@ export const ChatInterface = () => {
76
75
  ]);
77
76
  if (!sessionId)
78
77
  return null;
79
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(MessageList, { messages: displayMessages, isExpanded: isExpanded, forceStatic: isConfirmationVisible && isConfirmationTooTall, version: version, workdir: workdir, model: model, onDynamicBlocksHeightMeasured: handleDynamicBlocksHeightMeasured }), !isConfirmationVisible && !isExpanded && (_jsxs(_Fragment, { children: [_jsx(BtwDisplay, { btwState: btwState }), (isLoading || isCommandRunning || isCompressing) && (_jsx(LoadingIndicator, { isLoading: isLoading, isCommandRunning: isCommandRunning, isCompressing: isCompressing, latestTotalTokens: latestTotalTokens })), _jsx(TaskList, {}), _jsx(QueuedMessageList, {}), _jsx(InputBox, { isLoading: isLoading, isCommandRunning: isCommandRunning, sendMessage: sendMessage, abortMessage: abortMessage, mcpServers: mcpServers, connectMcpServer: connectMcpServer, disconnectMcpServer: disconnectMcpServer, slashCommands: slashCommands, hasSlashCommand: hasSlashCommand })] })), isConfirmationVisible && (_jsxs(_Fragment, { children: [_jsx(ConfirmationDetails, { toolName: confirmingTool.name, toolInput: confirmingTool.input, planContent: confirmingTool.planContent, isExpanded: isExpanded, onHeightMeasured: handleDetailsHeightMeasured, isStatic: isConfirmationTooTall }), _jsx(ConfirmationSelector, { toolName: confirmingTool.name, toolInput: confirmingTool.input, suggestedPrefix: confirmingTool.suggestedPrefix, hidePersistentOption: confirmingTool.hidePersistentOption, isExpanded: isExpanded, onDecision: wrappedHandleConfirmationDecision, onCancel: handleConfirmationCancel, onAbort: abortMessage, onHeightMeasured: handleSelectorHeightMeasured })] }))] }));
78
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(MessageList, { messages: displayMessages, isExpanded: isExpanded, forceStatic: isConfirmationVisible && isConfirmationTooTall, version: version, workdir: workdir, onDynamicBlocksHeightMeasured: handleDynamicBlocksHeightMeasured }), !isConfirmationVisible && !isExpanded && (_jsxs(_Fragment, { children: [_jsx(BtwDisplay, { btwState: btwState }), (isLoading || isCommandRunning || isCompressing) && (_jsx(LoadingIndicator, { isLoading: isLoading, isCommandRunning: isCommandRunning, isCompressing: isCompressing, latestTotalTokens: latestTotalTokens })), _jsx(TaskList, {}), _jsx(QueuedMessageList, {}), _jsx(InputBox, { isLoading: isLoading, isCommandRunning: isCommandRunning, sendMessage: sendMessage, abortMessage: abortMessage, mcpServers: mcpServers, connectMcpServer: connectMcpServer, disconnectMcpServer: disconnectMcpServer, slashCommands: slashCommands, hasSlashCommand: hasSlashCommand })] })), isConfirmationVisible && (_jsxs(_Fragment, { children: [_jsx(ConfirmationDetails, { toolName: confirmingTool.name, toolInput: confirmingTool.input, planContent: confirmingTool.planContent, isExpanded: isExpanded, onHeightMeasured: handleDetailsHeightMeasured, isStatic: isConfirmationTooTall }), _jsx(ConfirmationSelector, { toolName: confirmingTool.name, toolInput: confirmingTool.input, suggestedPrefix: confirmingTool.suggestedPrefix, hidePersistentOption: confirmingTool.hidePersistentOption, isExpanded: isExpanded, onDecision: wrappedHandleConfirmationDecision, onCancel: handleConfirmationCancel, onAbort: abortMessage, onHeightMeasured: handleSelectorHeightMeasured })] }))] }));
80
79
  };
@@ -1 +1 @@
1
- {"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAgBzC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,sBAAsB,mDACe,CAAC;AAEnD,eAAO,MAAM,6BAA6B,QAGzC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,EAClD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACjC,IAAI,CAAC;IACV,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAE1B,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/D,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAClD;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA0P5C,CAAC"}
1
+ {"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAiBzC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,sBAAsB,mDACe,CAAC;AAEnD,eAAO,MAAM,6BAA6B,QAGzC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,EAClD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACjC,IAAI,CAAC;IACV,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAE1B,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/D,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAClD;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA0Q5C,CAAC"}
@@ -11,13 +11,14 @@ import { RewindCommand } from "./RewindCommand.js";
11
11
  import { HelpView } from "./HelpView.js";
12
12
  import { StatusCommand } from "./StatusCommand.js";
13
13
  import { PluginManagerShell } from "./PluginManagerShell.js";
14
+ import { ModelSelector } from "./ModelSelector.js";
14
15
  import { StatusLine } from "./StatusLine.js";
15
16
  import { useInputManager } from "../hooks/useInputManager.js";
16
17
  import { useChat } from "../contexts/useChat.js";
17
18
  export const INPUT_PLACEHOLDER_TEXT = "Type your message (use /help for more info)...";
18
19
  export const INPUT_PLACEHOLDER_TEXT_PREFIX = INPUT_PLACEHOLDER_TEXT.substring(0, 10);
19
20
  export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mcpServers = [], connectMcpServer = async () => false, disconnectMcpServer = async () => false, slashCommands = [], hasSlashCommand = () => false, }) => {
20
- const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, allowBypassInCycle: chatAllowBypassInCycle, handleRewindSelect, backgroundCurrentTask, messages, getFullMessageThread, sessionId, workingDirectory, askBtw, btwState: chatBtwState, setBtwState: setChatBtwState, } = useChat();
21
+ const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, allowBypassInCycle: chatAllowBypassInCycle, handleRewindSelect, backgroundCurrentTask, messages, getFullMessageThread, sessionId, workingDirectory, askBtw, btwState: chatBtwState, setBtwState: setChatBtwState, currentModel, configuredModels, setModel, } = useChat();
21
22
  // Input manager with all input state and functionality (including images)
22
23
  const { inputText, cursorPosition,
23
24
  // Image management
@@ -29,7 +30,7 @@ export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mc
29
30
  // History search
30
31
  showHistorySearch, historySearchQuery,
31
32
  // Task/MCP Manager
32
- showBackgroundTaskManager, showMcpManager, showRewindManager, showHelp, showStatusCommand, showPluginManager, setShowBackgroundTaskManager, setShowMcpManager, setShowRewindManager, setShowHelp, setShowStatusCommand, setShowPluginManager,
33
+ showBackgroundTaskManager, showMcpManager, showRewindManager, showHelp, showStatusCommand, showPluginManager, showModelSelector, setShowBackgroundTaskManager, setShowMcpManager, setShowRewindManager, setShowHelp, setShowStatusCommand, setShowPluginManager, setShowModelSelector,
33
34
  // Permission mode
34
35
  permissionMode, setPermissionMode, setAllowBypassInCycle,
35
36
  // BTW state
@@ -100,6 +101,9 @@ export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mc
100
101
  if (showPluginManager) {
101
102
  return _jsx(PluginManagerShell, { onCancel: () => setShowPluginManager(false) });
102
103
  }
104
+ if (showModelSelector) {
105
+ return (_jsx(ModelSelector, { onCancel: () => setShowModelSelector(false), currentModel: currentModel, configuredModels: configuredModels, onSelectModel: setModel }));
106
+ }
103
107
  return (_jsxs(Box, { flexDirection: "column", children: [showFileSelector && (_jsx(FileSelector, { files: filteredFiles, searchQuery: searchQuery, isLoading: isFileSearching, onSelect: handleFileSelect, onCancel: handleCancelFileSelect })), showCommandSelector && (_jsx(CommandSelector, { searchQuery: commandSearchQuery, onSelect: handleCommandSelect, onInsert: handleCommandInsert, onCancel: handleCancelCommandSelect, commands: slashCommands })), showHistorySearch && (_jsx(HistorySearch, { searchQuery: historySearchQuery, onSelect: handleHistorySearchSelect, onCancel: handleCancelHistorySearch })), showBackgroundTaskManager && (_jsx(BackgroundTaskManager, { onCancel: () => setShowBackgroundTaskManager(false) })), showMcpManager && (_jsx(McpManager, { onCancel: () => setShowMcpManager(false), servers: mcpServers, onConnectServer: connectMcpServer, onDisconnectServer: disconnectMcpServer })), showBackgroundTaskManager ||
104
108
  showMcpManager ||
105
109
  showRewindManager ||
@@ -1 +1 @@
1
- {"version":3,"file":"MessageBlockItem.d.ts","sourceRoot":"","sources":["../../src/components/MessageBlockItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAQ5D,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,gBAAgB,GAAI,6CAK9B,qBAAqB,4CAiEvB,CAAC"}
1
+ {"version":3,"file":"MessageBlockItem.d.ts","sourceRoot":"","sources":["../../src/components/MessageBlockItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAS5D,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,gBAAgB,GAAI,6CAK9B,qBAAqB,4CAgEvB,CAAC"}
@@ -2,10 +2,11 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Box, Text } from "ink";
3
3
  import { MessageSource } from "wave-agent-sdk";
4
4
  import { BangDisplay } from "./BangDisplay.js";
5
+ import { SlashDisplay } from "./SlashDisplay.js";
5
6
  import { ToolDisplay } from "./ToolDisplay.js";
6
7
  import { CompressDisplay } from "./CompressDisplay.js";
7
8
  import { ReasoningDisplay } from "./ReasoningDisplay.js";
8
9
  import { Markdown } from "./Markdown.js";
9
10
  export const MessageBlockItem = ({ block, message, isExpanded, paddingTop = 0, }) => {
10
- return (_jsxs(Box, { flexDirection: "column", paddingTop: paddingTop, children: [block.type === "text" && block.content.trim() && (_jsxs(Box, { children: [block.customCommandContent && (_jsxs(Text, { color: "cyan", bold: true, children: ["$", " "] })), block.source === MessageSource.HOOK && (_jsxs(Text, { color: "magenta", bold: true, children: ["~", " "] })), message.role === "user" || isExpanded ? (_jsx(Text, { backgroundColor: message.role === "user" ? "gray" : undefined, color: "white", children: block.content })) : (_jsx(Markdown, { children: block.content }))] })), block.type === "error" && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", block.content] }) })), block.type === "bang" && (_jsx(BangDisplay, { block: block, isExpanded: isExpanded })), block.type === "tool" && (_jsx(ToolDisplay, { block: block, isExpanded: isExpanded })), block.type === "image" && (_jsxs(Box, { children: [_jsx(Text, { color: "magenta", bold: true, children: "# Image" }), block.imageUrls && block.imageUrls.length > 0 && (_jsxs(Text, { color: "gray", dimColor: true, children: [" ", "(", block.imageUrls.length, ")"] }))] })), block.type === "compress" && (_jsx(CompressDisplay, { block: block, isExpanded: isExpanded })), block.type === "reasoning" && (_jsx(ReasoningDisplay, { block: block, isExpanded: isExpanded }))] }));
11
+ return (_jsxs(Box, { flexDirection: "column", paddingTop: paddingTop, children: [block.type === "text" && block.content.trim() && (_jsxs(Box, { children: [block.source === MessageSource.HOOK && (_jsxs(Text, { color: "magenta", bold: true, children: ["~", " "] })), message.role === "user" || isExpanded ? (_jsx(Text, { backgroundColor: message.role === "user" ? "gray" : undefined, color: "white", children: block.content })) : (_jsx(Markdown, { children: block.content }))] })), block.type === "slash" && (_jsx(SlashDisplay, { block: block, isExpanded: isExpanded })), block.type === "error" && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", block.content] }) })), block.type === "bang" && (_jsx(BangDisplay, { block: block, isExpanded: isExpanded })), block.type === "tool" && (_jsx(ToolDisplay, { block: block, isExpanded: isExpanded })), block.type === "image" && (_jsxs(Box, { children: [_jsx(Text, { color: "magenta", bold: true, children: "# Image" }), block.imageUrls && block.imageUrls.length > 0 && (_jsxs(Text, { color: "gray", dimColor: true, children: [" ", "(", block.imageUrls.length, ")"] }))] })), block.type === "compress" && (_jsx(CompressDisplay, { block: block, isExpanded: isExpanded })), block.type === "reasoning" && (_jsx(ReasoningDisplay, { block: block, isExpanded: isExpanded }))] }));
11
12
  };
@@ -6,8 +6,7 @@ export interface MessageListProps {
6
6
  forceStatic?: boolean;
7
7
  version?: string;
8
8
  workdir?: string;
9
- model?: string;
10
9
  onDynamicBlocksHeightMeasured?: (height: number) => void;
11
10
  }
12
- export declare const MessageList: React.MemoExoticComponent<({ messages, isExpanded, forceStatic, version, workdir, model, onDynamicBlocksHeightMeasured, }: MessageListProps) => import("react/jsx-runtime").JSX.Element>;
11
+ export declare const MessageList: React.MemoExoticComponent<({ messages, isExpanded, forceStatic, version, workdir, onDynamicBlocksHeightMeasured, }: MessageListProps) => import("react/jsx-runtime").JSX.Element>;
13
12
  //# sourceMappingURL=MessageList.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkC,MAAM,OAAO,CAAC;AAGvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG9C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6BAA6B,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AAED,eAAO,MAAM,WAAW,6HASnB,gBAAgB,6CAoHpB,CAAC"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkC,MAAM,OAAO,CAAC;AAGvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG9C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6BAA6B,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AAED,eAAO,MAAM,WAAW,sHAQnB,gBAAgB,6CAkHpB,CAAC"}
@@ -3,8 +3,8 @@ import React, { useLayoutEffect, useRef } from "react";
3
3
  import os from "os";
4
4
  import { Box, Text, Static, measureElement } from "ink";
5
5
  import { MessageBlockItem } from "./MessageBlockItem.js";
6
- export const MessageList = React.memo(({ messages, isExpanded = false, forceStatic = false, version, workdir, model, onDynamicBlocksHeightMeasured, }) => {
7
- const welcomeMessage = (_jsxs(Box, { flexDirection: "column", paddingTop: 1, children: [_jsxs(Text, { color: "gray", children: ["WAVE", version ? ` v${version}` : "", model ? ` • ${model}` : ""] }), workdir && (_jsx(Text, { color: "gray", wrap: "truncate-middle", children: workdir.replace(os.homedir(), "~") }))] }));
6
+ export const MessageList = React.memo(({ messages, isExpanded = false, forceStatic = false, version, workdir, onDynamicBlocksHeightMeasured, }) => {
7
+ const welcomeMessage = (_jsxs(Box, { flexDirection: "column", paddingTop: 1, children: [_jsxs(Text, { color: "gray", children: ["WAVE", version ? ` v${version}` : ""] }), workdir && (_jsx(Text, { color: "gray", wrap: "truncate-middle", children: workdir.replace(os.homedir(), "~") }))] }));
8
8
  // Limit messages to prevent long rendering times
9
9
  const maxMessages = 10;
10
10
  // Filter out meta messages
@@ -24,7 +24,8 @@ export const MessageList = React.memo(({ messages, isExpanded = false, forceStat
24
24
  const { block } = item;
25
25
  const isDynamic = !forceStatic &&
26
26
  ((block.type === "tool" && block.stage === "running") ||
27
- (block.type === "bang" && block.isRunning));
27
+ (block.type === "bang" && block.isRunning) ||
28
+ (block.type === "slash" && block.stage === "running"));
28
29
  return { ...item, isDynamic };
29
30
  });
30
31
  const staticBlocks = blocksWithStatus.filter((b) => !b.isDynamic);
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ export interface ModelSelectorProps {
3
+ onCancel: () => void;
4
+ currentModel: string;
5
+ configuredModels: string[];
6
+ onSelectModel: (model: string) => void;
7
+ }
8
+ export declare const ModelSelector: React.FC<ModelSelectorProps>;
9
+ //# sourceMappingURL=ModelSelector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelSelector.d.ts","sourceRoot":"","sources":["../../src/components/ModelSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAkGtD,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Box, Text, useInput } from "ink";
4
+ export const ModelSelector = ({ onCancel, currentModel, configuredModels, onSelectModel, }) => {
5
+ const [selectedIndex, setSelectedIndex] = useState(() => {
6
+ const index = configuredModels.indexOf(currentModel);
7
+ return index !== -1 ? index : 0;
8
+ });
9
+ useInput((_input, key) => {
10
+ if (key.return) {
11
+ if (configuredModels.length > 0) {
12
+ onSelectModel(configuredModels[selectedIndex]);
13
+ }
14
+ onCancel();
15
+ return;
16
+ }
17
+ if (key.escape) {
18
+ onCancel();
19
+ return;
20
+ }
21
+ if (key.upArrow) {
22
+ setSelectedIndex((prev) => Math.max(0, prev - 1));
23
+ return;
24
+ }
25
+ if (key.downArrow) {
26
+ setSelectedIndex((prev) => Math.min(configuredModels.length - 1, prev + 1));
27
+ return;
28
+ }
29
+ });
30
+ if (configuredModels.length === 0) {
31
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "Select AI Model" }), _jsx(Text, { children: "No models configured" }), _jsx(Text, { dimColor: true, children: "Press Escape to close" })] }));
32
+ }
33
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsx(Text, { color: "cyan", bold: true, children: "Select AI Model" }) }), _jsx(Text, { dimColor: true, children: "Select a model to use for the current session" }), configuredModels.map((model, index) => (_jsx(Box, { children: _jsxs(Text, { color: index === selectedIndex ? "black" : "white", backgroundColor: index === selectedIndex ? "cyan" : undefined, children: [index === selectedIndex ? "▶ " : " ", model, model === currentModel ? (_jsx(Text, { color: "green", children: " (current)" })) : ("")] }) }, model))), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "\u2191/\u2193 to select \u00B7 Enter to confirm \u00B7 Esc to cancel" }) })] }));
34
+ };
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import type { SlashBlock } from "wave-agent-sdk";
3
+ interface SlashDisplayProps {
4
+ block: SlashBlock;
5
+ isExpanded?: boolean;
6
+ }
7
+ export declare const SlashDisplay: React.FC<SlashDisplayProps>;
8
+ export {};
9
+ //# sourceMappingURL=SlashDisplay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlashDisplay.d.ts","sourceRoot":"","sources":["../../src/components/SlashDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,UAAU,iBAAiB;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA4DpD,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ export const SlashDisplay = ({ block, isExpanded = false, }) => {
4
+ const { command, args, stage, shortResult, error, result } = block;
5
+ const getStatusColor = () => {
6
+ switch (stage) {
7
+ case "running":
8
+ return "yellow";
9
+ case "success":
10
+ return "green";
11
+ case "error":
12
+ return "red";
13
+ case "aborted":
14
+ return "gray";
15
+ default:
16
+ return "white";
17
+ }
18
+ };
19
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: getStatusColor(), children: "/ " }), _jsx(Text, { color: "white", children: command }), args && _jsxs(Text, { color: "gray", children: [" ", args] })] }), !isExpanded && shortResult && !error && (_jsx(Box, { paddingLeft: 2, flexDirection: "column", children: shortResult.split("\n").map((line, index) => (_jsx(Text, { color: "gray", children: line }, index))) })), isExpanded && result && (_jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Result:" }), _jsx(Text, { color: "white", children: result })] })), error && (_jsx(Box, { paddingLeft: 2, children: _jsxs(Text, { color: "red", children: ["Error: ", typeof error === "string" ? error : String(error)] }) }))] }));
20
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/constants/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,eAAO,MAAM,kBAAkB,EAAE,YAAY,EA4C5C,CAAC"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/constants/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,eAAO,MAAM,kBAAkB,EAAE,YAAY,EAkD5C,CAAC"}
@@ -41,4 +41,10 @@ export const AVAILABLE_COMMANDS = [
41
41
  description: "Ask a side question without tool use",
42
42
  handler: () => { }, // Handler here won't be used, actual processing is in the hook
43
43
  },
44
+ {
45
+ id: "model",
46
+ name: "model",
47
+ description: "Switch between configured AI models",
48
+ handler: () => { }, // Handler here won't be used, actual processing is in the hook
49
+ },
44
50
  ];
@@ -25,6 +25,10 @@ export interface ChatContextType {
25
25
  askBtw: (question: string) => Promise<string>;
26
26
  abortMessage: () => void;
27
27
  latestTotalTokens: number;
28
+ currentModel: string;
29
+ configuredModels: string[];
30
+ getConfiguredModels: () => string[];
31
+ setModel: (model: string) => void;
28
32
  mcpServers: McpServerStatus[];
29
33
  connectMcpServer: (serverName: string) => Promise<boolean>;
30
34
  disconnectMcpServer: (serverName: string) => Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"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"}
@@ -31,6 +31,8 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
31
31
  const [sessionId, setSessionId] = useState("");
32
32
  const [isCommandRunning, setIsCommandRunning] = useState(false);
33
33
  const [isCompressing, setIsCompressing] = useState(false);
34
+ const [currentModel, setCurrentModelState] = useState("");
35
+ const [configuredModels, setConfiguredModels] = useState([]);
34
36
  // MCP State
35
37
  const [mcpServers, setMcpServers] = useState([]);
36
38
  // Background tasks state
@@ -142,6 +144,12 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
142
144
  onPermissionModeChange: (mode) => {
143
145
  setPermissionModeState(mode);
144
146
  },
147
+ onModelChange: (model) => {
148
+ setCurrentModelState(model);
149
+ },
150
+ onConfiguredModelsChange: (models) => {
151
+ setConfiguredModels(models);
152
+ },
145
153
  };
146
154
  try {
147
155
  // Create the permission callback inside the try block to access showConfirmation
@@ -187,6 +195,8 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
187
195
  setIsCompressing(agent.isCompressing);
188
196
  setPermissionModeState(agent.getPermissionMode());
189
197
  setWorkingDirectory(agent.workingDirectory);
198
+ setCurrentModelState(agent.getModelConfig().model);
199
+ setConfiguredModels(agent.getConfiguredModels());
190
200
  // Get initial MCP servers state
191
201
  const mcpServers = agent.getMcpServers?.() || [];
192
202
  setMcpServers(mcpServers);
@@ -406,6 +416,18 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
406
416
  }
407
417
  return agentRef.current.getModelConfig();
408
418
  }, []);
419
+ const getConfiguredModels = useCallback(() => {
420
+ if (!agentRef.current) {
421
+ return [];
422
+ }
423
+ return agentRef.current.getConfiguredModels();
424
+ }, []);
425
+ const setModel = useCallback((model) => {
426
+ if (agentRef.current) {
427
+ agentRef.current.setModel(model);
428
+ setCurrentModelState(model);
429
+ }
430
+ }, []);
409
431
  // Listen for Ctrl+O hotkey to toggle collapse/expand state and ESC to cancel confirmation
410
432
  useInput((input, key) => {
411
433
  if (key.ctrl && input === "o") {
@@ -463,6 +485,10 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
463
485
  askBtw,
464
486
  abortMessage,
465
487
  latestTotalTokens,
488
+ currentModel,
489
+ configuredModels,
490
+ getConfiguredModels,
491
+ setModel,
466
492
  isCompressing,
467
493
  mcpServers,
468
494
  connectMcpServer,
@@ -20,6 +20,7 @@ export declare const useInputManager: (callbacks?: Partial<InputManagerCallbacks
20
20
  showHelp: boolean;
21
21
  showStatusCommand: boolean;
22
22
  showPluginManager: boolean;
23
+ showModelSelector: boolean;
23
24
  permissionMode: PermissionMode;
24
25
  attachedImages: import("../managers/inputReducer.js").AttachedImage[];
25
26
  btwState: import("../managers/inputReducer.js").BtwState;
@@ -58,6 +59,7 @@ export declare const useInputManager: (callbacks?: Partial<InputManagerCallbacks
58
59
  setShowHelp: (show: boolean) => void;
59
60
  setShowStatusCommand: (show: boolean) => void;
60
61
  setShowPluginManager: (show: boolean) => void;
62
+ setShowModelSelector: (show: boolean) => void;
61
63
  setPermissionMode: (mode: PermissionMode) => void;
62
64
  setAllowBypassInCycle: (allow: boolean) => void;
63
65
  setBtwState: (payload: Partial<import("../managers/inputReducer.js").BtwState>) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"useInputManager.d.ts","sourceRoot":"","sources":["../../src/hooks/useInputManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAGL,qBAAqB,EACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,cAAc,EACd,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAGxB,eAAO,MAAM,eAAe,GAC1B,YAAW,OAAO,CAAC,qBAAqB,CAAM;;;;;;;;;;;;;;;;;;;;;;;+BAsLA,MAAM;;;;;qCAoBA,MAAM;iCAIV,MAAM;;;;;mCAaJ,MAAM;oCAIL,MAAM;wCAIF,MAAM;mCAIX,MAAM;;;;mCASN,MAAM;;;;;sCAkCH,MAAM;uCAIL,MAAM;uCAQN,WAAW;;iCAQjB,MAAM;yCAYE,OAAO;8BAIlB,OAAO;iCAIJ,OAAO;wBAIhB,OAAO;iCAIE,OAAO;iCAIP,OAAO;8BAIV,cAAc;mCAKT,OAAO;2BAK7C,OAAO,CAAC,OAAO,6BAA6B,EAAE,QAAQ,CAAC;0BAU1B,MAAM,YAAY,MAAM;2BAIvB,MAAM;;;8BAYH,MAAM;mCAW/B,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;uCAYnB,MAAM;;yBAajD,MAAM,OACR,GAAG,kBACQ,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,gBACvD,MAAM,IAAI;yBA3GY,MAAM;kCAIG,MAAM;;CA4MxD,CAAC"}
1
+ {"version":3,"file":"useInputManager.d.ts","sourceRoot":"","sources":["../../src/hooks/useInputManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAGL,qBAAqB,EACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,cAAc,EACd,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAGxB,eAAO,MAAM,eAAe,GAC1B,YAAW,OAAO,CAAC,qBAAqB,CAAM;;;;;;;;;;;;;;;;;;;;;;;;+BA0LA,MAAM;;;;;qCAoBA,MAAM;iCAIV,MAAM;;;;;mCAaJ,MAAM;oCAIL,MAAM;wCAIF,MAAM;mCAIX,MAAM;;;;mCASN,MAAM;;;;;sCAkCH,MAAM;uCAIL,MAAM;uCAQN,WAAW;;iCAQjB,MAAM;yCAYE,OAAO;8BAIlB,OAAO;iCAIJ,OAAO;wBAIhB,OAAO;iCAIE,OAAO;iCAIP,OAAO;iCAIP,OAAO;8BAIV,cAAc;mCAKT,OAAO;2BAK7C,OAAO,CAAC,OAAO,6BAA6B,EAAE,QAAQ,CAAC;0BAU1B,MAAM,YAAY,MAAM;2BAIvB,MAAM;;;8BAYH,MAAM;mCAW/B,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;uCAYnB,MAAM;;yBAajD,MAAM,OACR,GAAG,kBACQ,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,gBACvD,MAAM,IAAI;yBA/GY,MAAM;kCAIG,MAAM;;CAkNxD,CAAC"}
@@ -100,6 +100,9 @@ export const useInputManager = (callbacks = {}) => {
100
100
  useEffect(() => {
101
101
  callbacksRef.current.onPluginManagerStateChange?.(state.showPluginManager);
102
102
  }, [state.showPluginManager]);
103
+ useEffect(() => {
104
+ callbacksRef.current.onModelSelectorStateChange?.(state.showModelSelector);
105
+ }, [state.showModelSelector]);
103
106
  useEffect(() => {
104
107
  callbacksRef.current.onImagesStateChange?.(state.attachedImages);
105
108
  }, [state.attachedImages]);
@@ -238,6 +241,9 @@ export const useInputManager = (callbacks = {}) => {
238
241
  const setShowPluginManager = useCallback((show) => {
239
242
  dispatch({ type: "SET_SHOW_PLUGIN_MANAGER", payload: show });
240
243
  }, []);
244
+ const setShowModelSelector = useCallback((show) => {
245
+ dispatch({ type: "SET_SHOW_MODEL_SELECTOR", payload: show });
246
+ }, []);
241
247
  const setPermissionMode = useCallback((mode) => {
242
248
  dispatch({ type: "SET_PERMISSION_MODE", payload: mode });
243
249
  callbacksRef.current.onPermissionModeChange?.(mode);
@@ -300,6 +306,7 @@ export const useInputManager = (callbacks = {}) => {
300
306
  showHelp: state.showHelp,
301
307
  showStatusCommand: state.showStatusCommand,
302
308
  showPluginManager: state.showPluginManager,
309
+ showModelSelector: state.showModelSelector,
303
310
  permissionMode: state.permissionMode,
304
311
  attachedImages: state.attachedImages,
305
312
  btwState: state.btwState,
@@ -335,6 +342,7 @@ export const useInputManager = (callbacks = {}) => {
335
342
  setShowHelp,
336
343
  setShowStatusCommand,
337
344
  setShowPluginManager,
345
+ setShowModelSelector,
338
346
  setPermissionMode,
339
347
  setAllowBypassInCycle,
340
348
  setBtwState,
@@ -1 +1 @@
1
- {"version":3,"file":"inputHandlers.d.ts","sourceRoot":"","sources":["../../src/managers/inputHandlers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inputHandlers.d.ts","sourceRoot":"","sources":["../../src/managers/inputHandlers.ts"],"names":[],"mappings":"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"}
@@ -268,6 +268,9 @@ export const handleCommandSelect = (state, dispatch, callbacks, command) => {
268
268
  else if (command === "plugin") {
269
269
  dispatch({ type: "SET_SHOW_PLUGIN_MANAGER", payload: true });
270
270
  }
271
+ else if (command === "model") {
272
+ dispatch({ type: "SET_SHOW_MODEL_SELECTOR", payload: true });
273
+ }
271
274
  else if (command === "btw") {
272
275
  dispatch({
273
276
  type: "SET_BTW_STATE",
@@ -545,6 +548,7 @@ export const handleInput = async (state, dispatch, callbacks, input, key, clearI
545
548
  state.showHelp ||
546
549
  state.showStatusCommand ||
547
550
  state.showPluginManager ||
551
+ state.showModelSelector ||
548
552
  state.btwState.isActive)) {
549
553
  callbacks.onAbortMessage?.();
550
554
  return true;
@@ -563,6 +567,7 @@ export const handleInput = async (state, dispatch, callbacks, input, key, clearI
563
567
  state.showHelp ||
564
568
  state.showStatusCommand ||
565
569
  state.showPluginManager ||
570
+ state.showModelSelector ||
566
571
  state.btwState.isActive) {
567
572
  if (state.showBackgroundTaskManager ||
568
573
  state.showMcpManager ||
@@ -570,6 +575,7 @@ export const handleInput = async (state, dispatch, callbacks, input, key, clearI
570
575
  state.showHelp ||
571
576
  state.showStatusCommand ||
572
577
  state.showPluginManager ||
578
+ state.showModelSelector ||
573
579
  state.btwState.isActive) {
574
580
  return true;
575
581
  }
@@ -22,6 +22,7 @@ export interface InputManagerCallbacks {
22
22
  onHelpStateChange?: (show: boolean) => void;
23
23
  onStatusCommandStateChange?: (show: boolean) => void;
24
24
  onPluginManagerStateChange?: (show: boolean) => void;
25
+ onModelSelectorStateChange?: (show: boolean) => void;
25
26
  onImagesStateChange?: (images: AttachedImage[]) => void;
26
27
  onSendMessage?: (content: string, images?: Array<{
27
28
  path: string;
@@ -64,6 +65,7 @@ export interface InputState {
64
65
  showHelp: boolean;
65
66
  showStatusCommand: boolean;
66
67
  showPluginManager: boolean;
68
+ showModelSelector: boolean;
67
69
  permissionMode: PermissionMode;
68
70
  allowBypassInCycle: boolean;
69
71
  selectorJustUsed: boolean;
@@ -147,6 +149,9 @@ export type InputAction = {
147
149
  } | {
148
150
  type: "SET_SHOW_PLUGIN_MANAGER";
149
151
  payload: boolean;
152
+ } | {
153
+ type: "SET_SHOW_MODEL_SELECTOR";
154
+ payload: boolean;
150
155
  } | {
151
156
  type: "SET_PERMISSION_MODE";
152
157
  payload: PermissionMode;
@@ -1 +1 @@
1
- {"version":3,"file":"inputReducer.d.ts","sourceRoot":"","sources":["../../src/managers/inputReducer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inputReducer.d.ts","sourceRoot":"","sources":["../../src/managers/inputReducer.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,7 @@ export const initialState = {
20
20
  showHelp: false,
21
21
  showStatusCommand: false,
22
22
  showPluginManager: false,
23
+ showModelSelector: false,
23
24
  permissionMode: "default",
24
25
  allowBypassInCycle: false,
25
26
  selectorJustUsed: false,
@@ -199,6 +200,12 @@ export function inputReducer(state, action) {
199
200
  showPluginManager: action.payload,
200
201
  selectorJustUsed: !action.payload ? true : state.selectorJustUsed,
201
202
  };
203
+ case "SET_SHOW_MODEL_SELECTOR":
204
+ return {
205
+ ...state,
206
+ showModelSelector: action.payload,
207
+ selectorJustUsed: !action.payload ? true : state.selectorJustUsed,
208
+ };
202
209
  case "SET_PERMISSION_MODE":
203
210
  return { ...state, permissionMode: action.payload };
204
211
  case "SET_ALLOW_BYPASS_IN_CYCLE":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-code",
3
- "version": "0.11.7",
3
+ "version": "0.12.0",
4
4
  "description": "CLI-based code assistant powered by AI, built with React and Ink",
5
5
  "repository": {
6
6
  "type": "git",
@@ -42,7 +42,7 @@
42
42
  "semver": "^7.7.4",
43
43
  "yargs": "^17.7.2",
44
44
  "zod": "^3.23.8",
45
- "wave-agent-sdk": "0.11.7"
45
+ "wave-agent-sdk": "0.12.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/react": "^19.1.8",
@@ -41,12 +41,9 @@ export const ChatInterface: React.FC = () => {
41
41
  setWasLastDetailsTooTall,
42
42
  version,
43
43
  workdir,
44
- getModelConfig,
45
44
  btwState,
46
45
  } = useChat();
47
46
 
48
- const model = getModelConfig().model;
49
-
50
47
  const displayMessages = messages;
51
48
 
52
49
  const handleDetailsHeightMeasured = useCallback((height: number) => {
@@ -125,7 +122,6 @@ export const ChatInterface: React.FC = () => {
125
122
  forceStatic={isConfirmationVisible && isConfirmationTooTall}
126
123
  version={version}
127
124
  workdir={workdir}
128
- model={model}
129
125
  onDynamicBlocksHeightMeasured={handleDynamicBlocksHeightMeasured}
130
126
  />
131
127
 
@@ -10,6 +10,7 @@ import { RewindCommand } from "./RewindCommand.js";
10
10
  import { HelpView } from "./HelpView.js";
11
11
  import { StatusCommand } from "./StatusCommand.js";
12
12
  import { PluginManagerShell } from "./PluginManagerShell.js";
13
+ import { ModelSelector } from "./ModelSelector.js";
13
14
  import { StatusLine } from "./StatusLine.js";
14
15
  import { useInputManager } from "../hooks/useInputManager.js";
15
16
  import { useChat } from "../contexts/useChat.js";
@@ -65,6 +66,9 @@ export const InputBox: React.FC<InputBoxProps> = ({
65
66
  askBtw,
66
67
  btwState: chatBtwState,
67
68
  setBtwState: setChatBtwState,
69
+ currentModel,
70
+ configuredModels,
71
+ setModel,
68
72
  } = useChat();
69
73
 
70
74
  // Input manager with all input state and functionality (including images)
@@ -99,12 +103,14 @@ export const InputBox: React.FC<InputBoxProps> = ({
99
103
  showHelp,
100
104
  showStatusCommand,
101
105
  showPluginManager,
106
+ showModelSelector,
102
107
  setShowBackgroundTaskManager,
103
108
  setShowMcpManager,
104
109
  setShowRewindManager,
105
110
  setShowHelp,
106
111
  setShowStatusCommand,
107
112
  setShowPluginManager,
113
+ setShowModelSelector,
108
114
  // Permission mode
109
115
  permissionMode,
110
116
  setPermissionMode,
@@ -205,6 +211,17 @@ export const InputBox: React.FC<InputBoxProps> = ({
205
211
  return <PluginManagerShell onCancel={() => setShowPluginManager(false)} />;
206
212
  }
207
213
 
214
+ if (showModelSelector) {
215
+ return (
216
+ <ModelSelector
217
+ onCancel={() => setShowModelSelector(false)}
218
+ currentModel={currentModel}
219
+ configuredModels={configuredModels}
220
+ onSelectModel={setModel}
221
+ />
222
+ );
223
+ }
224
+
208
225
  return (
209
226
  <Box flexDirection="column">
210
227
  {showFileSelector && (
@@ -3,6 +3,7 @@ import { Box, Text } from "ink";
3
3
  import type { Message, MessageBlock } from "wave-agent-sdk";
4
4
  import { MessageSource } from "wave-agent-sdk";
5
5
  import { BangDisplay } from "./BangDisplay.js";
6
+ import { SlashDisplay } from "./SlashDisplay.js";
6
7
  import { ToolDisplay } from "./ToolDisplay.js";
7
8
  import { CompressDisplay } from "./CompressDisplay.js";
8
9
  import { ReasoningDisplay } from "./ReasoningDisplay.js";
@@ -25,11 +26,6 @@ export const MessageBlockItem = ({
25
26
  <Box flexDirection="column" paddingTop={paddingTop}>
26
27
  {block.type === "text" && block.content.trim() && (
27
28
  <Box>
28
- {block.customCommandContent && (
29
- <Text color="cyan" bold>
30
- ${" "}
31
- </Text>
32
- )}
33
29
  {block.source === MessageSource.HOOK && (
34
30
  <Text color="magenta" bold>
35
31
  ~{" "}
@@ -48,6 +44,10 @@ export const MessageBlockItem = ({
48
44
  </Box>
49
45
  )}
50
46
 
47
+ {block.type === "slash" && (
48
+ <SlashDisplay block={block} isExpanded={isExpanded} />
49
+ )}
50
+
51
51
  {block.type === "error" && (
52
52
  <Box>
53
53
  <Text color="red">Error: {block.content}</Text>
@@ -10,7 +10,6 @@ export interface MessageListProps {
10
10
  forceStatic?: boolean;
11
11
  version?: string;
12
12
  workdir?: string;
13
- model?: string;
14
13
  onDynamicBlocksHeightMeasured?: (height: number) => void;
15
14
  }
16
15
 
@@ -21,15 +20,11 @@ export const MessageList = React.memo(
21
20
  forceStatic = false,
22
21
  version,
23
22
  workdir,
24
- model,
25
23
  onDynamicBlocksHeightMeasured,
26
24
  }: MessageListProps) => {
27
25
  const welcomeMessage = (
28
26
  <Box flexDirection="column" paddingTop={1}>
29
- <Text color="gray">
30
- WAVE{version ? ` v${version}` : ""}
31
- {model ? ` • ${model}` : ""}
32
- </Text>
27
+ <Text color="gray">WAVE{version ? ` v${version}` : ""}</Text>
33
28
  {workdir && (
34
29
  <Text color="gray" wrap="truncate-middle">
35
30
  {workdir.replace(os.homedir(), "~")}
@@ -61,7 +56,8 @@ export const MessageList = React.memo(
61
56
  const isDynamic =
62
57
  !forceStatic &&
63
58
  ((block.type === "tool" && block.stage === "running") ||
64
- (block.type === "bang" && block.isRunning));
59
+ (block.type === "bang" && block.isRunning) ||
60
+ (block.type === "slash" && block.stage === "running"));
65
61
  return { ...item, isDynamic };
66
62
  });
67
63
 
@@ -0,0 +1,109 @@
1
+ import React, { useState } from "react";
2
+ import { Box, Text, useInput } from "ink";
3
+
4
+ export interface ModelSelectorProps {
5
+ onCancel: () => void;
6
+ currentModel: string;
7
+ configuredModels: string[];
8
+ onSelectModel: (model: string) => void;
9
+ }
10
+
11
+ export const ModelSelector: React.FC<ModelSelectorProps> = ({
12
+ onCancel,
13
+ currentModel,
14
+ configuredModels,
15
+ onSelectModel,
16
+ }) => {
17
+ const [selectedIndex, setSelectedIndex] = useState(() => {
18
+ const index = configuredModels.indexOf(currentModel);
19
+ return index !== -1 ? index : 0;
20
+ });
21
+
22
+ useInput((_input, key) => {
23
+ if (key.return) {
24
+ if (configuredModels.length > 0) {
25
+ onSelectModel(configuredModels[selectedIndex]);
26
+ }
27
+ onCancel();
28
+ return;
29
+ }
30
+
31
+ if (key.escape) {
32
+ onCancel();
33
+ return;
34
+ }
35
+
36
+ if (key.upArrow) {
37
+ setSelectedIndex((prev) => Math.max(0, prev - 1));
38
+ return;
39
+ }
40
+
41
+ if (key.downArrow) {
42
+ setSelectedIndex((prev) =>
43
+ Math.min(configuredModels.length - 1, prev + 1),
44
+ );
45
+ return;
46
+ }
47
+ });
48
+
49
+ if (configuredModels.length === 0) {
50
+ return (
51
+ <Box
52
+ flexDirection="column"
53
+ borderStyle="single"
54
+ borderColor="cyan"
55
+ borderBottom={false}
56
+ borderLeft={false}
57
+ borderRight={false}
58
+ paddingTop={1}
59
+ >
60
+ <Text color="cyan" bold>
61
+ Select AI Model
62
+ </Text>
63
+ <Text>No models configured</Text>
64
+ <Text dimColor>Press Escape to close</Text>
65
+ </Box>
66
+ );
67
+ }
68
+
69
+ return (
70
+ <Box
71
+ flexDirection="column"
72
+ borderStyle="single"
73
+ borderColor="cyan"
74
+ borderBottom={false}
75
+ borderLeft={false}
76
+ borderRight={false}
77
+ paddingTop={1}
78
+ gap={1}
79
+ >
80
+ <Box>
81
+ <Text color="cyan" bold>
82
+ Select AI Model
83
+ </Text>
84
+ </Box>
85
+ <Text dimColor>Select a model to use for the current session</Text>
86
+
87
+ {configuredModels.map((model, index) => (
88
+ <Box key={model}>
89
+ <Text
90
+ color={index === selectedIndex ? "black" : "white"}
91
+ backgroundColor={index === selectedIndex ? "cyan" : undefined}
92
+ >
93
+ {index === selectedIndex ? "▶ " : " "}
94
+ {model}
95
+ {model === currentModel ? (
96
+ <Text color="green"> (current)</Text>
97
+ ) : (
98
+ ""
99
+ )}
100
+ </Text>
101
+ </Box>
102
+ ))}
103
+
104
+ <Box marginTop={1}>
105
+ <Text dimColor>↑/↓ to select · Enter to confirm · Esc to cancel</Text>
106
+ </Box>
107
+ </Box>
108
+ );
109
+ };
@@ -0,0 +1,70 @@
1
+ import React from "react";
2
+ import { Box, Text } from "ink";
3
+ import type { SlashBlock } from "wave-agent-sdk";
4
+
5
+ interface SlashDisplayProps {
6
+ block: SlashBlock;
7
+ isExpanded?: boolean;
8
+ }
9
+
10
+ export const SlashDisplay: React.FC<SlashDisplayProps> = ({
11
+ block,
12
+ isExpanded = false,
13
+ }) => {
14
+ const { command, args, stage, shortResult, error, result } = block;
15
+
16
+ const getStatusColor = () => {
17
+ switch (stage) {
18
+ case "running":
19
+ return "yellow";
20
+ case "success":
21
+ return "green";
22
+ case "error":
23
+ return "red";
24
+ case "aborted":
25
+ return "gray";
26
+ default:
27
+ return "white";
28
+ }
29
+ };
30
+
31
+ return (
32
+ <Box flexDirection="column">
33
+ <Box>
34
+ <Text color={getStatusColor()}>/ </Text>
35
+ <Text color="white">{command}</Text>
36
+ {args && <Text color="gray"> {args}</Text>}
37
+ </Box>
38
+
39
+ {/* Display shortResult in collapsed state */}
40
+ {!isExpanded && shortResult && !error && (
41
+ <Box paddingLeft={2} flexDirection="column">
42
+ {shortResult.split("\n").map((line, index) => (
43
+ <Text key={index} color="gray">
44
+ {line}
45
+ </Text>
46
+ ))}
47
+ </Box>
48
+ )}
49
+
50
+ {/* Display complete result in expanded state */}
51
+ {isExpanded && result && (
52
+ <Box paddingLeft={2} flexDirection="column">
53
+ <Text color="cyan" bold>
54
+ Result:
55
+ </Text>
56
+ <Text color="white">{result}</Text>
57
+ </Box>
58
+ )}
59
+
60
+ {/* Error information always displayed */}
61
+ {error && (
62
+ <Box paddingLeft={2}>
63
+ <Text color="red">
64
+ Error: {typeof error === "string" ? error : String(error)}
65
+ </Text>
66
+ </Box>
67
+ )}
68
+ </Box>
69
+ );
70
+ };
@@ -44,4 +44,10 @@ export const AVAILABLE_COMMANDS: SlashCommand[] = [
44
44
  description: "Ask a side question without tool use",
45
45
  handler: () => {}, // Handler here won't be used, actual processing is in the hook
46
46
  },
47
+ {
48
+ id: "model",
49
+ name: "model",
50
+ description: "Switch between configured AI models",
51
+ handler: () => {}, // Handler here won't be used, actual processing is in the hook
52
+ },
47
53
  ];
@@ -54,6 +54,11 @@ export interface ChatContextType {
54
54
  askBtw: (question: string) => Promise<string>;
55
55
  abortMessage: () => void;
56
56
  latestTotalTokens: number;
57
+ // Model functionality
58
+ currentModel: string;
59
+ configuredModels: string[];
60
+ getConfiguredModels: () => string[];
61
+ setModel: (model: string) => void;
57
62
  // MCP functionality
58
63
  mcpServers: McpServerStatus[];
59
64
  connectMcpServer: (serverName: string) => Promise<boolean>;
@@ -176,6 +181,8 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
176
181
  const [sessionId, setSessionId] = useState("");
177
182
  const [isCommandRunning, setIsCommandRunning] = useState(false);
178
183
  const [isCompressing, setIsCompressing] = useState(false);
184
+ const [currentModel, setCurrentModelState] = useState("");
185
+ const [configuredModels, setConfiguredModels] = useState<string[]>([]);
179
186
 
180
187
  // MCP State
181
188
  const [mcpServers, setMcpServers] = useState<McpServerStatus[]>([]);
@@ -357,6 +364,12 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
357
364
  onPermissionModeChange: (mode) => {
358
365
  setPermissionModeState(mode);
359
366
  },
367
+ onModelChange: (model) => {
368
+ setCurrentModelState(model);
369
+ },
370
+ onConfiguredModelsChange: (models) => {
371
+ setConfiguredModels(models);
372
+ },
360
373
  };
361
374
 
362
375
  try {
@@ -414,6 +427,8 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
414
427
  setIsCompressing(agent.isCompressing);
415
428
  setPermissionModeState(agent.getPermissionMode());
416
429
  setWorkingDirectory(agent.workingDirectory);
430
+ setCurrentModelState(agent.getModelConfig().model);
431
+ setConfiguredModels(agent.getConfiguredModels());
417
432
 
418
433
  // Get initial MCP servers state
419
434
  const mcpServers = agent.getMcpServers?.() || [];
@@ -672,6 +687,20 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
672
687
  return agentRef.current.getModelConfig();
673
688
  }, []);
674
689
 
690
+ const getConfiguredModels = useCallback(() => {
691
+ if (!agentRef.current) {
692
+ return [];
693
+ }
694
+ return agentRef.current.getConfiguredModels();
695
+ }, []);
696
+
697
+ const setModel = useCallback((model: string) => {
698
+ if (agentRef.current) {
699
+ agentRef.current.setModel(model);
700
+ setCurrentModelState(model);
701
+ }
702
+ }, []);
703
+
675
704
  // Listen for Ctrl+O hotkey to toggle collapse/expand state and ESC to cancel confirmation
676
705
  useInput((input, key) => {
677
706
  if (key.ctrl && input === "o") {
@@ -729,6 +758,10 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
729
758
  askBtw,
730
759
  abortMessage,
731
760
  latestTotalTokens,
761
+ currentModel,
762
+ configuredModels,
763
+ getConfiguredModels,
764
+ setModel,
732
765
  isCompressing,
733
766
  mcpServers,
734
767
  connectMcpServer,
@@ -149,6 +149,10 @@ export const useInputManager = (
149
149
  callbacksRef.current.onPluginManagerStateChange?.(state.showPluginManager);
150
150
  }, [state.showPluginManager]);
151
151
 
152
+ useEffect(() => {
153
+ callbacksRef.current.onModelSelectorStateChange?.(state.showModelSelector);
154
+ }, [state.showModelSelector]);
155
+
152
156
  useEffect(() => {
153
157
  callbacksRef.current.onImagesStateChange?.(state.attachedImages);
154
158
  }, [state.attachedImages]);
@@ -343,6 +347,10 @@ export const useInputManager = (
343
347
  dispatch({ type: "SET_SHOW_PLUGIN_MANAGER", payload: show });
344
348
  }, []);
345
349
 
350
+ const setShowModelSelector = useCallback((show: boolean) => {
351
+ dispatch({ type: "SET_SHOW_MODEL_SELECTOR", payload: show });
352
+ }, []);
353
+
346
354
  const setPermissionMode = useCallback((mode: PermissionMode) => {
347
355
  dispatch({ type: "SET_PERMISSION_MODE", payload: mode });
348
356
  callbacksRef.current.onPermissionModeChange?.(mode);
@@ -452,6 +460,7 @@ export const useInputManager = (
452
460
  showHelp: state.showHelp,
453
461
  showStatusCommand: state.showStatusCommand,
454
462
  showPluginManager: state.showPluginManager,
463
+ showModelSelector: state.showModelSelector,
455
464
  permissionMode: state.permissionMode,
456
465
  attachedImages: state.attachedImages,
457
466
  btwState: state.btwState,
@@ -493,6 +502,7 @@ export const useInputManager = (
493
502
  setShowHelp,
494
503
  setShowStatusCommand,
495
504
  setShowPluginManager,
505
+ setShowModelSelector,
496
506
  setPermissionMode,
497
507
  setAllowBypassInCycle,
498
508
  setBtwState,
@@ -370,6 +370,8 @@ export const handleCommandSelect = (
370
370
  dispatch({ type: "SET_SHOW_STATUS_COMMAND", payload: true });
371
371
  } else if (command === "plugin") {
372
372
  dispatch({ type: "SET_SHOW_PLUGIN_MANAGER", payload: true });
373
+ } else if (command === "model") {
374
+ dispatch({ type: "SET_SHOW_MODEL_SELECTOR", payload: true });
373
375
  } else if (command === "btw") {
374
376
  dispatch({
375
377
  type: "SET_BTW_STATE",
@@ -754,6 +756,7 @@ export const handleInput = async (
754
756
  state.showHelp ||
755
757
  state.showStatusCommand ||
756
758
  state.showPluginManager ||
759
+ state.showModelSelector ||
757
760
  state.btwState.isActive
758
761
  )
759
762
  ) {
@@ -782,6 +785,7 @@ export const handleInput = async (
782
785
  state.showHelp ||
783
786
  state.showStatusCommand ||
784
787
  state.showPluginManager ||
788
+ state.showModelSelector ||
785
789
  state.btwState.isActive
786
790
  ) {
787
791
  if (
@@ -791,6 +795,7 @@ export const handleInput = async (
791
795
  state.showHelp ||
792
796
  state.showStatusCommand ||
793
797
  state.showPluginManager ||
798
+ state.showModelSelector ||
794
799
  state.btwState.isActive
795
800
  ) {
796
801
  return true;
@@ -40,6 +40,7 @@ export interface InputManagerCallbacks {
40
40
  onHelpStateChange?: (show: boolean) => void;
41
41
  onStatusCommandStateChange?: (show: boolean) => void;
42
42
  onPluginManagerStateChange?: (show: boolean) => void;
43
+ onModelSelectorStateChange?: (show: boolean) => void;
43
44
  onImagesStateChange?: (images: AttachedImage[]) => void;
44
45
  onSendMessage?: (
45
46
  content: string,
@@ -84,6 +85,7 @@ export interface InputState {
84
85
  showHelp: boolean;
85
86
  showStatusCommand: boolean;
86
87
  showPluginManager: boolean;
88
+ showModelSelector: boolean;
87
89
  permissionMode: PermissionMode;
88
90
  allowBypassInCycle: boolean;
89
91
  selectorJustUsed: boolean;
@@ -120,6 +122,7 @@ export const initialState: InputState = {
120
122
  showHelp: false,
121
123
  showStatusCommand: false,
122
124
  showPluginManager: false,
125
+ showModelSelector: false,
123
126
  permissionMode: "default",
124
127
  allowBypassInCycle: false,
125
128
  selectorJustUsed: false,
@@ -163,6 +166,7 @@ export type InputAction =
163
166
  | { type: "SET_SHOW_HELP"; payload: boolean }
164
167
  | { type: "SET_SHOW_STATUS_COMMAND"; payload: boolean }
165
168
  | { type: "SET_SHOW_PLUGIN_MANAGER"; payload: boolean }
169
+ | { type: "SET_SHOW_MODEL_SELECTOR"; payload: boolean }
166
170
  | { type: "SET_PERMISSION_MODE"; payload: PermissionMode }
167
171
  | { type: "SET_ALLOW_BYPASS_IN_CYCLE"; payload: boolean }
168
172
  | { type: "SET_SELECTOR_JUST_USED"; payload: boolean }
@@ -358,6 +362,12 @@ export function inputReducer(
358
362
  showPluginManager: action.payload,
359
363
  selectorJustUsed: !action.payload ? true : state.selectorJustUsed,
360
364
  };
365
+ case "SET_SHOW_MODEL_SELECTOR":
366
+ return {
367
+ ...state,
368
+ showModelSelector: action.payload,
369
+ selectorJustUsed: !action.payload ? true : state.selectorJustUsed,
370
+ };
361
371
  case "SET_PERMISSION_MODE":
362
372
  return { ...state, permissionMode: action.payload };
363
373
  case "SET_ALLOW_BYPASS_IN_CYCLE":