dexto 1.5.0 → 1.5.2
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/dist/cli/commands/interactive-commands/command-parser.d.ts +1 -1
- package/dist/cli/commands/interactive-commands/command-parser.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/command-parser.js +11 -1
- package/dist/cli/commands/interactive-commands/general-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/general-commands.js +63 -0
- package/dist/cli/commands/interactive-commands/system/system-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/system/system-commands.js +3 -2
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +163 -28
- package/dist/cli/ink-cli/components/ResourceAutocomplete.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/ResourceAutocomplete.js +8 -2
- package/dist/cli/ink-cli/components/TextBufferInput.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/TextBufferInput.js +24 -6
- package/dist/cli/ink-cli/components/chat/Header.js +1 -1
- package/dist/cli/ink-cli/components/chat/MessageItem.d.ts +3 -1
- package/dist/cli/ink-cli/components/chat/MessageItem.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/chat/MessageItem.js +37 -10
- package/dist/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.js +1 -1
- package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.js +3 -3
- package/dist/cli/ink-cli/components/modes/StaticCLI.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/modes/StaticCLI.js +10 -3
- package/dist/cli/ink-cli/components/overlays/CustomModelWizard.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/overlays/CustomModelWizard.js +19 -8
- package/dist/cli/ink-cli/components/overlays/LogLevelSelector.js +1 -1
- package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.d.ts +2 -1
- package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.js +64 -2
- package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.js +44 -1
- package/dist/cli/ink-cli/components/overlays/custom-model-wizard/types.d.ts +6 -0
- package/dist/cli/ink-cli/components/overlays/custom-model-wizard/types.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/renderers/GenericRenderer.js +1 -1
- package/dist/cli/ink-cli/components/renderers/SearchRenderer.js +1 -1
- package/dist/cli/ink-cli/components/shared/MarkdownText.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/shared/MarkdownText.js +4 -4
- package/dist/cli/ink-cli/constants/processingPhrases.d.ts.map +1 -1
- package/dist/cli/ink-cli/constants/processingPhrases.js +58 -48
- package/dist/cli/ink-cli/constants/tips.d.ts.map +1 -1
- package/dist/cli/ink-cli/constants/tips.js +33 -32
- package/dist/cli/ink-cli/containers/InputContainer.d.ts.map +1 -1
- package/dist/cli/ink-cli/containers/InputContainer.js +18 -11
- package/dist/cli/ink-cli/containers/OverlayContainer.d.ts.map +1 -1
- package/dist/cli/ink-cli/containers/OverlayContainer.js +26 -3
- package/dist/cli/ink-cli/hooks/useAgentEvents.d.ts +8 -1
- package/dist/cli/ink-cli/hooks/useAgentEvents.d.ts.map +1 -1
- package/dist/cli/ink-cli/hooks/useAgentEvents.js +144 -6
- package/dist/cli/ink-cli/hooks/useCLIState.d.ts.map +1 -1
- package/dist/cli/ink-cli/hooks/useCLIState.js +17 -1
- package/dist/cli/ink-cli/hooks/useTokenCounter.d.ts +11 -7
- package/dist/cli/ink-cli/hooks/useTokenCounter.d.ts.map +1 -1
- package/dist/cli/ink-cli/hooks/useTokenCounter.js +41 -18
- package/dist/cli/ink-cli/services/processStream.d.ts.map +1 -1
- package/dist/cli/ink-cli/services/processStream.js +20 -8
- package/dist/cli/ink-cli/state/types.d.ts +2 -2
- package/dist/cli/ink-cli/state/types.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/messageFormatting.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/messageFormatting.js +92 -5
- package/dist/index.js +24 -3
- package/package.json +7 -7
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
3
|
* MessageItem Component
|
|
4
4
|
* Displays a single message with visual hierarchy
|
|
@@ -6,6 +6,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
6
6
|
*/
|
|
7
7
|
import { memo } from 'react';
|
|
8
8
|
import { Box, Text } from 'ink';
|
|
9
|
+
import wrapAnsi from 'wrap-ansi';
|
|
9
10
|
import { ConfigBox, StatsBox, HelpBox, SessionListBox, SessionHistoryBox, LogConfigBox, ShortcutsBox, SyspromptBox, } from './styled-boxes/index.js';
|
|
10
11
|
import { ToolResultRenderer } from '../renderers/index.js';
|
|
11
12
|
import { MarkdownText } from '../shared/MarkdownText.js';
|
|
@@ -36,7 +37,7 @@ function formatDuration(ms) {
|
|
|
36
37
|
* Memoization with custom comparator prevents re-renders when message array changes
|
|
37
38
|
* but individual message content hasn't changed.
|
|
38
39
|
*/
|
|
39
|
-
export const MessageItem = memo(({ message }) => {
|
|
40
|
+
export const MessageItem = memo(({ message, terminalWidth = 80 }) => {
|
|
40
41
|
// Check for styled message first
|
|
41
42
|
if (message.styledType && message.styledData) {
|
|
42
43
|
switch (message.styledType) {
|
|
@@ -55,8 +56,11 @@ export const MessageItem = memo(({ message }) => {
|
|
|
55
56
|
case 'run-summary': {
|
|
56
57
|
const data = message.styledData;
|
|
57
58
|
const durationStr = formatDuration(data.durationMs);
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
// Only show tokens when >= 1000, using K notation
|
|
60
|
+
const tokensStr = data.totalTokens >= 1000
|
|
61
|
+
? `, Used ${(data.totalTokens / 1000).toFixed(1)}K tokens`
|
|
62
|
+
: '';
|
|
63
|
+
return (_jsx(Box, { marginTop: 1, marginBottom: 1, width: terminalWidth, children: _jsxs(Text, { color: "gray", children: ["\u2500 Worked for ", durationStr, tokensStr, " \u2500"] }) }));
|
|
60
64
|
}
|
|
61
65
|
case 'shortcuts':
|
|
62
66
|
return _jsx(ShortcutsBox, { data: message.styledData });
|
|
@@ -65,8 +69,18 @@ export const MessageItem = memo(({ message }) => {
|
|
|
65
69
|
}
|
|
66
70
|
}
|
|
67
71
|
// User message: '>' prefix with gray background
|
|
72
|
+
// Properly wrap text accounting for prefix "> " (2 chars) and paddingX={1} (2 chars total)
|
|
68
73
|
if (message.role === 'user') {
|
|
69
|
-
|
|
74
|
+
const prefix = '> ';
|
|
75
|
+
const paddingChars = 2; // paddingX={1} = 1 char on each side
|
|
76
|
+
const availableWidth = Math.max(20, terminalWidth - prefix.length - paddingChars);
|
|
77
|
+
const wrappedContent = wrapAnsi(message.content, availableWidth, {
|
|
78
|
+
hard: true,
|
|
79
|
+
wordWrap: true,
|
|
80
|
+
trim: false,
|
|
81
|
+
});
|
|
82
|
+
const lines = wrappedContent.split('\n');
|
|
83
|
+
return (_jsx(Box, { flexDirection: "column", marginTop: 2, marginBottom: 1, width: terminalWidth, children: _jsx(Box, { flexDirection: "column", paddingX: 1, backgroundColor: "gray", children: lines.map((line, i) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "green", children: i === 0 ? prefix : ' ' }), _jsx(Text, { color: "white", children: line })] }, i))) }) }));
|
|
70
84
|
}
|
|
71
85
|
// Assistant message: Gray circle indicator (unless continuation)
|
|
72
86
|
// IMPORTANT: width="100%" is required to prevent Ink layout failures on large content.
|
|
@@ -75,12 +89,12 @@ export const MessageItem = memo(({ message }) => {
|
|
|
75
89
|
if (message.role === 'assistant') {
|
|
76
90
|
// Continuation messages: no indicator, just content
|
|
77
91
|
if (message.isContinuation) {
|
|
78
|
-
return (_jsx(Box, { flexDirection: "column", width:
|
|
92
|
+
return (_jsx(Box, { flexDirection: "column", width: terminalWidth, children: _jsx(MarkdownText, { children: message.content || '' }) }));
|
|
79
93
|
}
|
|
80
94
|
// Regular assistant message: bullet prefix inline with first line
|
|
81
95
|
// Text wraps at terminal width - wrapped lines may start at column 0
|
|
82
96
|
// This is simpler and avoids mid-word splitting issues with Ink's wrap
|
|
83
|
-
return (_jsx(Box, { flexDirection: "column", marginTop: 1, width:
|
|
97
|
+
return (_jsx(Box, { flexDirection: "column", marginTop: 1, width: terminalWidth, children: _jsx(MarkdownText, { bulletPrefix: "\u23FA ", children: message.content || '' }) }));
|
|
84
98
|
}
|
|
85
99
|
// Tool message: Animated icon based on status
|
|
86
100
|
// - Running: green spinner + "Running..."
|
|
@@ -95,10 +109,22 @@ export const MessageItem = memo(({ message }) => {
|
|
|
95
109
|
const parenIndex = message.content.indexOf('(');
|
|
96
110
|
const toolName = parenIndex > 0 ? message.content.slice(0, parenIndex) : message.content;
|
|
97
111
|
const toolArgs = parenIndex > 0 ? message.content.slice(parenIndex) : '';
|
|
98
|
-
|
|
112
|
+
// Build the full tool header text for wrapping
|
|
113
|
+
const statusSuffix = isRunning ? ' Running...' : isPending ? ' Waiting...' : '';
|
|
114
|
+
const fullToolText = `${toolName}${toolArgs}${statusSuffix}`;
|
|
115
|
+
// ToolIcon takes 2 chars ("● "), so available width is terminalWidth - 2
|
|
116
|
+
const iconWidth = 2;
|
|
117
|
+
const availableWidth = Math.max(20, terminalWidth - iconWidth);
|
|
118
|
+
const wrappedToolText = wrapAnsi(fullToolText, availableWidth, {
|
|
119
|
+
hard: true,
|
|
120
|
+
wordWrap: true,
|
|
121
|
+
trim: false,
|
|
122
|
+
});
|
|
123
|
+
const toolLines = wrappedToolText.split('\n');
|
|
124
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, width: terminalWidth, children: [toolLines.map((line, i) => (_jsxs(Box, { flexDirection: "row", children: [i === 0 ? (_jsx(ToolIcon, { status: message.toolStatus || 'finished', isError: message.isError ?? false })) : (_jsx(Text, { children: ' ' })), _jsx(Text, { children: i === 0 ? (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, children: line.slice(0, toolName.length) }), _jsx(Text, { children: line.slice(toolName.length) })] })) : (line) })] }, i))), hasStructuredDisplay ? (_jsx(ToolResultRenderer, { display: message.toolDisplayData, content: message.toolContent })) : (message.toolResult && (_jsx(Box, { flexDirection: "column", children: _jsxs(Text, { color: "gray", children: [" \u23BF ", message.toolResult] }) })))] }));
|
|
99
125
|
}
|
|
100
126
|
// System message: Compact gray text
|
|
101
|
-
return (_jsx(Box, { flexDirection: "column", marginBottom: 1, width:
|
|
127
|
+
return (_jsx(Box, { flexDirection: "column", marginBottom: 1, width: terminalWidth, children: _jsx(Text, { color: "gray", children: message.content }) }));
|
|
102
128
|
},
|
|
103
129
|
// Custom comparator: only re-render if message content actually changed
|
|
104
130
|
(prev, next) => {
|
|
@@ -113,6 +139,7 @@ export const MessageItem = memo(({ message }) => {
|
|
|
113
139
|
prev.message.isContinuation === next.message.isContinuation &&
|
|
114
140
|
prev.message.isError === next.message.isError &&
|
|
115
141
|
prev.message.toolDisplayData === next.message.toolDisplayData &&
|
|
116
|
-
prev.message.toolContent === next.message.toolContent
|
|
142
|
+
prev.message.toolContent === next.message.toolContent &&
|
|
143
|
+
prev.terminalWidth === next.terminalWidth);
|
|
117
144
|
});
|
|
118
145
|
MessageItem.displayName = 'MessageItem';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LogConfigBox.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGnE,UAAU,iBAAiB;IACvB,IAAI,EAAE,mBAAmB,CAAC;CAC7B;AAED,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"LogConfigBox.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGnE,UAAU,iBAAiB;IACvB,IAAI,EAAE,mBAAmB,CAAC;CAC7B;AAED,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,iBAAiB,2CA8BvD"}
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
3
|
import { StyledBox, StyledRow, StyledListItem } from './StyledBox.js';
|
|
4
4
|
export function LogConfigBox({ data }) {
|
|
5
|
-
return (_jsxs(StyledBox, { title: "Logging Configuration", children: [_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StyledRow, { label: "Current level", value: data.currentLevel, valueColor: "green" }), data.logFile && _jsx(StyledRow, { label: "Log file", value: data.logFile })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Available levels (least to most verbose):" }), data.availableLevels.map((level) => {
|
|
5
|
+
return (_jsxs(StyledBox, { title: "Logging Configuration", children: [_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StyledRow, { label: "Current level", value: data.currentLevel, valueColor: "green" }), data.logFile && process.env.DEXTO_PRIVACY_MODE !== 'true' && (_jsx(StyledRow, { label: "Log file", value: data.logFile }))] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Available levels (least to most verbose):" }), data.availableLevels.map((level) => {
|
|
6
6
|
const isCurrent = level === data.currentLevel;
|
|
7
7
|
return (_jsx(StyledListItem, { icon: isCurrent ? '>' : ' ', text: level, isActive: isCurrent }, level));
|
|
8
8
|
})] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "Use /log <level> to change level" }) })] }));
|
|
@@ -94,7 +94,7 @@ export function AlternateBufferCLI({ agent, initialSessionId, startupInfo, onSel
|
|
|
94
94
|
return () => clearTimeout(timer);
|
|
95
95
|
}, [selectionHintVisible]);
|
|
96
96
|
// Get terminal dimensions - updates on resize
|
|
97
|
-
const { rows: terminalHeight } = useTerminalSize();
|
|
97
|
+
const { rows: terminalHeight, columns: terminalWidth } = useTerminalSize();
|
|
98
98
|
// Build list data: header as first item, then finalized + pending + dequeued buffer
|
|
99
99
|
// In alternate buffer mode, everything is re-rendered anyway, so we combine all
|
|
100
100
|
// Order: finalized messages → pending/streaming → dequeued user messages (guarantees order)
|
|
@@ -119,8 +119,8 @@ export function AlternateBufferCLI({ agent, initialSessionId, startupInfo, onSel
|
|
|
119
119
|
if (item.type === 'header') {
|
|
120
120
|
return (_jsx(Header, { modelName: session.modelName, sessionId: session.id || undefined, hasActiveSession: session.hasActiveSession, startupInfo: startupInfo }));
|
|
121
121
|
}
|
|
122
|
-
return _jsx(MessageItem, { message: item.message });
|
|
123
|
-
}, [session.modelName, session.id, session.hasActiveSession, startupInfo]);
|
|
122
|
+
return _jsx(MessageItem, { message: item.message, terminalWidth: terminalWidth });
|
|
123
|
+
}, [session.modelName, session.id, session.hasActiveSession, startupInfo, terminalWidth]);
|
|
124
124
|
// Smart height estimation based on item type and content
|
|
125
125
|
const estimateItemHeight = useCallback((index) => {
|
|
126
126
|
const item = listData[index];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StaticCLI.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/modes/StaticCLI.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAM9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAkBxD,UAAU,cAAc;IACpB,KAAK,EAAE,UAAU,CAAC;IAClB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,WAAW,CAAC;IACzB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,SAAS,CAAC,EACtB,KAAK,EACL,gBAAgB,EAChB,WAAW,EACX,YAAmB,GACtB,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"StaticCLI.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/modes/StaticCLI.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAM9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAkBxD,UAAU,cAAc;IACpB,KAAK,EAAE,UAAU,CAAC;IAClB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,WAAW,CAAC;IACzB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,SAAS,CAAC,EACtB,KAAK,EACL,gBAAgB,EAChB,WAAW,EACX,YAAmB,GACtB,EAAE,cAAc,2CAoNhB"}
|
|
@@ -87,9 +87,16 @@ export function StaticCLI({ agent, initialSessionId, startupInfo, useStreaming =
|
|
|
87
87
|
const staticItems = useMemo(() => {
|
|
88
88
|
const items = [
|
|
89
89
|
_jsx(Header, { modelName: session.modelName, sessionId: session.id || undefined, hasActiveSession: session.hasActiveSession, startupInfo: startupInfo }, "header"),
|
|
90
|
-
...visibleMessages.map((msg) => _jsx(MessageItem, { message: msg }, msg.id)),
|
|
90
|
+
...visibleMessages.map((msg) => (_jsx(MessageItem, { message: msg, terminalWidth: terminalWidth }, msg.id))),
|
|
91
91
|
];
|
|
92
92
|
return items;
|
|
93
|
-
}, [
|
|
94
|
-
|
|
93
|
+
}, [
|
|
94
|
+
visibleMessages,
|
|
95
|
+
session.modelName,
|
|
96
|
+
session.id,
|
|
97
|
+
session.hasActiveSession,
|
|
98
|
+
startupInfo,
|
|
99
|
+
terminalWidth,
|
|
100
|
+
]);
|
|
101
|
+
return (_jsxs(Box, { flexDirection: "column", width: terminalWidth, children: [_jsx(Static, { items: staticItems, children: (item) => item }, staticRemountKey), pendingMessages.map((message) => (_jsx(MessageItem, { message: message, terminalWidth: terminalWidth }, message.id))), dequeuedBuffer.map((message) => (_jsx(MessageItem, { message: message, terminalWidth: terminalWidth }, message.id))), _jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [_jsx(StatusBar, { agent: agent, isProcessing: ui.isProcessing, isThinking: ui.isThinking, approvalQueueCount: approvalQueue.length, copyModeEnabled: ui.copyModeEnabled, isAwaitingApproval: approval !== null }), _jsx(QueuedMessagesDisplay, { messages: queuedMessages }), _jsx(InputContainer, { ref: inputContainerRef, buffer: buffer, input: input, ui: ui, session: session, approval: approval, queuedMessages: queuedMessages, setInput: setInput, setUi: setUi, setSession: setSession, setMessages: setMessages, setPendingMessages: setPendingMessages, setDequeuedBuffer: setDequeuedBuffer, setQueuedMessages: setQueuedMessages, setApproval: setApproval, setApprovalQueue: setApprovalQueue, agent: agent, inputService: inputService, useStreaming: useStreaming }), _jsx(OverlayContainer, { ref: overlayContainerRef, ui: ui, input: input, session: session, approval: approval, setInput: setInput, setUi: setUi, setSession: setSession, setMessages: setMessages, setApproval: setApproval, setApprovalQueue: setApprovalQueue, agent: agent, inputService: inputService, buffer: buffer, refreshStatic: refreshStatic, onSubmitPromptCommand: handleSubmitPromptCommand }), ui.exitWarningShown && (_jsxs(Box, { paddingX: 1, children: [_jsx(Text, { color: "yellowBright", bold: true, children: "\u26A0 Press Ctrl+C again to exit" }), _jsx(Text, { color: "gray", children: " (or press any key to cancel)" })] })), _jsx(Footer, { modelName: session.modelName, cwd: process.cwd(), autoApproveEdits: ui.autoApproveEdits }), ui.historySearch.isActive && (_jsx(HistorySearchBar, { query: ui.historySearch.query, hasMatch: historySearchHasMatch }))] })] }));
|
|
95
102
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomModelWizard.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/CustomModelWizard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,EAIH,KAAK,WAAW,EAMnB,MAAM,yBAAyB,CAAC;AAmBjC,UAAU,sBAAsB;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,uEAAuE;IACvE,YAAY,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,uBAAuB;IACpC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED;;;GAGG;AACH,QAAA,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"CustomModelWizard.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/CustomModelWizard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,EAIH,KAAK,WAAW,EAMnB,MAAM,yBAAyB,CAAC;AAmBjC,UAAU,sBAAsB;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,uEAAuE;IACvE,YAAY,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,uBAAuB;IACpC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED;;;GAGG;AACH,QAAA,MAAM,iBAAiB,wGAwYtB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -37,8 +37,17 @@ const CustomModelWizard = forwardRef(function CustomModelWizard({ isVisible, onC
|
|
|
37
37
|
const localModelWizardRef = useRef(null);
|
|
38
38
|
// Get provider config (data-driven, no conditionals)
|
|
39
39
|
const providerConfig = selectedProvider ? getProviderConfig(selectedProvider) : null;
|
|
40
|
-
const
|
|
41
|
-
|
|
40
|
+
const allWizardSteps = providerConfig?.steps ?? [];
|
|
41
|
+
/**
|
|
42
|
+
* Get visible steps based on current values.
|
|
43
|
+
* Steps with a condition function are only shown if the condition returns true.
|
|
44
|
+
*/
|
|
45
|
+
const getVisibleSteps = useCallback((currentValues) => {
|
|
46
|
+
return allWizardSteps.filter((step) => !step.condition || step.condition(currentValues));
|
|
47
|
+
}, [allWizardSteps]);
|
|
48
|
+
// Current visible steps based on accumulated values
|
|
49
|
+
const visibleSteps = getVisibleSteps(values);
|
|
50
|
+
const currentStepConfig = visibleSteps[currentStep];
|
|
42
51
|
// Reset when becoming visible
|
|
43
52
|
useEffect(() => {
|
|
44
53
|
if (isVisible) {
|
|
@@ -117,15 +126,17 @@ const CustomModelWizard = forwardRef(function CustomModelWizard({ isVisible, onC
|
|
|
117
126
|
setValues(newValues);
|
|
118
127
|
setError(null);
|
|
119
128
|
setCurrentInput('');
|
|
129
|
+
// Get updated visible steps with new values
|
|
130
|
+
const updatedVisibleSteps = getVisibleSteps(newValues);
|
|
120
131
|
// Check if we're done
|
|
121
|
-
if (currentStep >=
|
|
132
|
+
if (currentStep >= updatedVisibleSteps.length - 1) {
|
|
122
133
|
await saveModel(newValues);
|
|
123
134
|
}
|
|
124
135
|
else {
|
|
125
136
|
const nextStep = currentStep + 1;
|
|
126
137
|
setCurrentStep(nextStep);
|
|
127
138
|
// Pre-populate next step from stored values (for edit mode)
|
|
128
|
-
const nextStepConfig =
|
|
139
|
+
const nextStepConfig = updatedVisibleSteps[nextStep];
|
|
129
140
|
const nextValue = nextStepConfig ? newValues[nextStepConfig.field] : undefined;
|
|
130
141
|
setCurrentInput(nextValue ?? '');
|
|
131
142
|
}
|
|
@@ -133,11 +144,11 @@ const CustomModelWizard = forwardRef(function CustomModelWizard({ isVisible, onC
|
|
|
133
144
|
currentInput,
|
|
134
145
|
currentStep,
|
|
135
146
|
currentStepConfig,
|
|
147
|
+
getVisibleSteps,
|
|
136
148
|
isSaving,
|
|
137
149
|
isValidating,
|
|
138
150
|
selectedProvider,
|
|
139
151
|
values,
|
|
140
|
-
wizardSteps,
|
|
141
152
|
]);
|
|
142
153
|
/**
|
|
143
154
|
* Build and save the model using provider config's buildModel function.
|
|
@@ -191,7 +202,7 @@ const CustomModelWizard = forwardRef(function CustomModelWizard({ isVisible, onC
|
|
|
191
202
|
if (currentStep > 0) {
|
|
192
203
|
setCurrentStep(currentStep - 1);
|
|
193
204
|
// Restore previous value
|
|
194
|
-
const prevStep =
|
|
205
|
+
const prevStep = visibleSteps[currentStep - 1];
|
|
195
206
|
if (prevStep) {
|
|
196
207
|
setCurrentInput(values[prevStep.field] || '');
|
|
197
208
|
}
|
|
@@ -205,7 +216,7 @@ const CustomModelWizard = forwardRef(function CustomModelWizard({ isVisible, onC
|
|
|
205
216
|
else {
|
|
206
217
|
onClose();
|
|
207
218
|
}
|
|
208
|
-
}, [currentStep, onClose, selectedProvider, values,
|
|
219
|
+
}, [currentStep, onClose, selectedProvider, values, visibleSteps]);
|
|
209
220
|
// Handle keyboard input
|
|
210
221
|
useImperativeHandle(ref, () => ({
|
|
211
222
|
handleInput: (input, key) => {
|
|
@@ -281,6 +292,6 @@ const CustomModelWizard = forwardRef(function CustomModelWizard({ isVisible, onC
|
|
|
281
292
|
// Wizard steps screen for other providers
|
|
282
293
|
if (!currentStepConfig || !providerConfig)
|
|
283
294
|
return null;
|
|
284
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1, marginTop: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, color: "green", children: isEditing ? 'Edit Custom Model' : 'Add Custom Model' }), _jsxs(Text, { color: "gray", children: [' ', "(", providerConfig.displayName, ") Step ", currentStep + 1, "/",
|
|
295
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1, marginTop: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, color: "green", children: isEditing ? 'Edit Custom Model' : 'Add Custom Model' }), _jsxs(Text, { color: "gray", children: [' ', "(", providerConfig.displayName, ") Step ", currentStep + 1, "/", visibleSteps.length] })] }), providerConfig.setupInfo && currentStep === 0 && (_jsx(SetupInfoBanner, { title: providerConfig.setupInfo.title, description: providerConfig.setupInfo.description, docsUrl: providerConfig.setupInfo.docsUrl })), _jsx(WizardStepInput, { step: currentStepConfig, currentInput: currentInput, error: error, isValidating: isValidating, isSaving: isSaving, additionalContent: currentStepConfig.field === 'apiKey' ? (_jsx(ApiKeyStep, { provider: selectedProvider })) : undefined }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "gray", children: ["Enter to continue \u2022 Esc to", ' ', currentStep > 0 ? 'go back' : 'back to provider'] }) })] }));
|
|
285
296
|
});
|
|
286
297
|
export default CustomModelWizard;
|
|
@@ -54,6 +54,6 @@ const LogLevelSelector = forwardRef(function LogLevelSelector({ isVisible, onSel
|
|
|
54
54
|
const handleSelect = (option) => {
|
|
55
55
|
onSelect(option.level);
|
|
56
56
|
};
|
|
57
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(BaseSelector, { ref: baseSelectorRef, items: levels, isVisible: isVisible, isLoading: false, selectedIndex: selectedIndex, onSelectIndex: setSelectedIndex, onSelect: handleSelect, onClose: onClose, formatItem: formatItem, title: "Select Log Level", borderColor: "yellowBright", emptyMessage: "No log levels available" }), logFilePath && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "gray", children: ["\uD83D\uDCC1 Log file: ", logFilePath] }) }))] }));
|
|
57
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(BaseSelector, { ref: baseSelectorRef, items: levels, isVisible: isVisible, isLoading: false, selectedIndex: selectedIndex, onSelectIndex: setSelectedIndex, onSelect: handleSelect, onClose: onClose, formatItem: formatItem, title: "Select Log Level", borderColor: "yellowBright", emptyMessage: "No log levels available" }), logFilePath && process.env.DEXTO_PRIVACY_MODE !== 'true' && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "gray", children: ["\uD83D\uDCC1 Log file: ", logFilePath] }) }))] }));
|
|
58
58
|
});
|
|
59
59
|
export default LogLevelSelector;
|
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
import type { Key } from '../../hooks/useInputOrchestrator.js';
|
|
8
8
|
import type { DextoAgent, LLMProvider } from '@dexto/core';
|
|
9
9
|
import { type CustomModel } from '@dexto/agent-management';
|
|
10
|
+
type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
|
|
10
11
|
interface ModelSelectorProps {
|
|
11
12
|
isVisible: boolean;
|
|
12
|
-
onSelectModel: (provider: LLMProvider, model: string, displayName?: string, baseURL?: string) => void;
|
|
13
|
+
onSelectModel: (provider: LLMProvider, model: string, displayName?: string, baseURL?: string, reasoningEffort?: ReasoningEffort) => void;
|
|
13
14
|
onClose: () => void;
|
|
14
15
|
onAddCustomModel: () => void;
|
|
15
16
|
onEditCustomModel: (model: CustomModel) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModelSelectorRefactored.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/ModelSelectorRefactored.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ModelSelectorRefactored.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/ModelSelectorRefactored.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO3D,OAAO,EAIH,KAAK,WAAW,EACnB,MAAM,yBAAyB,CAAC;AAEjC,KAAK,eAAe,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhF,UAAU,kBAAkB;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,CACX,QAAQ,EAAE,WAAW,EACrB,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM,EAChB,eAAe,CAAC,EAAE,eAAe,KAChC,IAAI,CAAC;IACV,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,iBAAiB,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAChD,KAAK,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAChC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAiDD;;GAEG;AACH,QAAA,MAAM,aAAa,oHA4rBjB,CAAC;AAEH,eAAe,aAAa,CAAC"}
|
|
@@ -7,12 +7,30 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
7
7
|
*/
|
|
8
8
|
import { useState, useEffect, forwardRef, useRef, useImperativeHandle, useMemo, useCallback, } from 'react';
|
|
9
9
|
import { Box, Text } from 'ink';
|
|
10
|
-
import { listOllamaModels, DEFAULT_OLLAMA_URL, getLocalModelById } from '@dexto/core';
|
|
10
|
+
import { listOllamaModels, DEFAULT_OLLAMA_URL, getLocalModelById, isReasoningCapableModel, } from '@dexto/core';
|
|
11
11
|
import { loadCustomModels, deleteCustomModel, getAllInstalledModels, } from '@dexto/agent-management';
|
|
12
12
|
function isAddCustomOption(item) {
|
|
13
13
|
return 'type' in item && item.type === 'add-custom';
|
|
14
14
|
}
|
|
15
15
|
const MAX_VISIBLE_ITEMS = 10;
|
|
16
|
+
// Reasoning effort options - defined at module scope to avoid recreation on each render
|
|
17
|
+
const REASONING_EFFORT_OPTIONS = [
|
|
18
|
+
{
|
|
19
|
+
value: 'auto',
|
|
20
|
+
label: 'Auto',
|
|
21
|
+
description: 'Let the model decide (recommended for most tasks)',
|
|
22
|
+
},
|
|
23
|
+
{ value: 'none', label: 'None', description: 'No reasoning, fastest responses' },
|
|
24
|
+
{ value: 'minimal', label: 'Minimal', description: 'Barely any reasoning, very fast' },
|
|
25
|
+
{ value: 'low', label: 'Low', description: 'Light reasoning, fast responses' },
|
|
26
|
+
{
|
|
27
|
+
value: 'medium',
|
|
28
|
+
label: 'Medium',
|
|
29
|
+
description: 'Balanced reasoning (OpenAI recommended)',
|
|
30
|
+
},
|
|
31
|
+
{ value: 'high', label: 'High', description: 'Thorough reasoning for complex tasks' },
|
|
32
|
+
{ value: 'xhigh', label: 'Extra High', description: 'Maximum quality, slower/costlier' },
|
|
33
|
+
];
|
|
16
34
|
/**
|
|
17
35
|
* Model selector with search and custom model support
|
|
18
36
|
*/
|
|
@@ -27,6 +45,9 @@ const ModelSelector = forwardRef(function ModelSelector({ isVisible, onSelectMod
|
|
|
27
45
|
const [pendingDeleteConfirm, setPendingDeleteConfirm] = useState(false);
|
|
28
46
|
const selectedIndexRef = useRef(selectedIndex);
|
|
29
47
|
const deleteTimeoutRef = useRef(null);
|
|
48
|
+
// Reasoning effort sub-step state
|
|
49
|
+
const [pendingReasoningModel, setPendingReasoningModel] = useState(null);
|
|
50
|
+
const [reasoningEffortIndex, setReasoningEffortIndex] = useState(0); // Default to 'Auto' (index 0)
|
|
30
51
|
// Keep ref in sync
|
|
31
52
|
selectedIndexRef.current = selectedIndex;
|
|
32
53
|
// Clear delete confirmation timeout on unmount
|
|
@@ -48,6 +69,8 @@ const ModelSelector = forwardRef(function ModelSelector({ isVisible, onSelectMod
|
|
|
48
69
|
setScrollOffset(0);
|
|
49
70
|
setCustomModelAction(null);
|
|
50
71
|
setPendingDeleteConfirm(false);
|
|
72
|
+
setPendingReasoningModel(null);
|
|
73
|
+
setReasoningEffortIndex(0); // Default to 'Auto'
|
|
51
74
|
if (deleteTimeoutRef.current) {
|
|
52
75
|
clearTimeout(deleteTimeoutRef.current);
|
|
53
76
|
deleteTimeoutRef.current = null;
|
|
@@ -256,6 +279,30 @@ const ModelSelector = forwardRef(function ModelSelector({ isVisible, onSelectMod
|
|
|
256
279
|
handleInput: (input, key) => {
|
|
257
280
|
if (!isVisible)
|
|
258
281
|
return false;
|
|
282
|
+
// Handle reasoning effort sub-step
|
|
283
|
+
if (pendingReasoningModel) {
|
|
284
|
+
if (key.escape) {
|
|
285
|
+
// Go back to model selection
|
|
286
|
+
setPendingReasoningModel(null);
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
if (key.upArrow) {
|
|
290
|
+
setReasoningEffortIndex((prev) => prev > 0 ? prev - 1 : REASONING_EFFORT_OPTIONS.length - 1);
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
if (key.downArrow) {
|
|
294
|
+
setReasoningEffortIndex((prev) => prev < REASONING_EFFORT_OPTIONS.length - 1 ? prev + 1 : 0);
|
|
295
|
+
return true;
|
|
296
|
+
}
|
|
297
|
+
if (key.return) {
|
|
298
|
+
const selectedOption = REASONING_EFFORT_OPTIONS[reasoningEffortIndex];
|
|
299
|
+
const reasoningEffort = selectedOption?.value === 'auto' ? undefined : selectedOption?.value;
|
|
300
|
+
onSelectModel(pendingReasoningModel.provider, pendingReasoningModel.name, pendingReasoningModel.displayName, pendingReasoningModel.baseURL, reasoningEffort);
|
|
301
|
+
setPendingReasoningModel(null);
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
return true; // Consume all input in reasoning effort mode
|
|
305
|
+
}
|
|
259
306
|
// Escape always works
|
|
260
307
|
if (key.escape) {
|
|
261
308
|
// If in action mode, just clear it first
|
|
@@ -408,7 +455,13 @@ const ModelSelector = forwardRef(function ModelSelector({ isVisible, onSelectMod
|
|
|
408
455
|
}
|
|
409
456
|
return true;
|
|
410
457
|
}
|
|
411
|
-
// Normal selection
|
|
458
|
+
// Normal selection - check if reasoning-capable
|
|
459
|
+
if (isReasoningCapableModel(item.name)) {
|
|
460
|
+
// Show reasoning effort sub-step
|
|
461
|
+
setPendingReasoningModel(item);
|
|
462
|
+
setReasoningEffortIndex(0); // Default to 'Auto'
|
|
463
|
+
return true;
|
|
464
|
+
}
|
|
412
465
|
onSelectModel(item.provider, item.name, item.displayName, item.baseURL);
|
|
413
466
|
return true;
|
|
414
467
|
}
|
|
@@ -426,12 +479,21 @@ const ModelSelector = forwardRef(function ModelSelector({ isVisible, onSelectMod
|
|
|
426
479
|
pendingDeleteConfirm,
|
|
427
480
|
customModels,
|
|
428
481
|
handleDeleteCustomModel,
|
|
482
|
+
pendingReasoningModel,
|
|
483
|
+
reasoningEffortIndex,
|
|
429
484
|
]);
|
|
430
485
|
if (!isVisible)
|
|
431
486
|
return null;
|
|
432
487
|
if (isLoading) {
|
|
433
488
|
return (_jsx(Box, { paddingX: 0, paddingY: 0, children: _jsx(Text, { color: "gray", children: "Loading models..." }) }));
|
|
434
489
|
}
|
|
490
|
+
// Reasoning effort sub-step UI
|
|
491
|
+
if (pendingReasoningModel) {
|
|
492
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { paddingX: 0, paddingY: 0, children: _jsx(Text, { color: "cyan", bold: true, children: "Configure Reasoning Effort" }) }), _jsx(Box, { paddingX: 0, paddingY: 0, children: _jsxs(Text, { color: "gray", children: ["for ", pendingReasoningModel.displayName || pendingReasoningModel.name] }) }), _jsx(Box, { paddingX: 0, paddingY: 0, children: _jsx(Text, { color: "gray", children: "\u2191\u2193 navigate, Enter select, Esc back" }) }), _jsx(Box, { paddingX: 0, paddingY: 0, children: _jsx(Text, { color: "gray", children: '─'.repeat(50) }) }), REASONING_EFFORT_OPTIONS.map((option, index) => {
|
|
493
|
+
const isSelected = index === reasoningEffortIndex;
|
|
494
|
+
return (_jsxs(Box, { paddingX: 0, paddingY: 0, children: [_jsxs(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: [isSelected ? '› ' : ' ', option.label] }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', children: [' ', "- ", option.description] })] }, option.value));
|
|
495
|
+
})] }));
|
|
496
|
+
}
|
|
435
497
|
const visibleItems = filteredItems.slice(scrollOffset, scrollOffset + MAX_VISIBLE_ITEMS);
|
|
436
498
|
const hasCustomModels = customModels.length > 0;
|
|
437
499
|
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { paddingX: 0, paddingY: 0, children: _jsxs(Text, { color: "cyan", bold: true, children: ["Select Model (", selectedIndex + 1, "/", filteredItems.length, ")"] }) }), _jsxs(Box, { paddingX: 0, paddingY: 0, children: [_jsx(Text, { color: "gray", children: "\u2191\u2193 navigate, Enter select, Esc close" }), hasCustomModels && _jsx(Text, { color: "gray", children: ", \u2192\u2190 for custom actions" })] }), _jsxs(Box, { paddingX: 0, paddingY: 0, children: [_jsx(Text, { color: "gray", children: "\uD83D\uDD0D " }), _jsx(Text, { color: searchQuery ? 'white' : 'gray', children: searchQuery || 'Type to search...' }), _jsx(Text, { color: "cyan", children: "\u258C" })] }), _jsx(Box, { paddingX: 0, paddingY: 0, children: _jsx(Text, { color: "gray", children: '─'.repeat(50) }) }), visibleItems.map((item, visibleIndex) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-config.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAe,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"provider-config.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAe,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAQhF,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;AA4D7D;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,mBAAmB,EAAE,cAAc,CA4XxE,CAAC;AAEF;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,cAAc,CAE/E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,CAGtE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,SAAS,mBAAmB,EAAE,CAEtE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,OAAO,CAEzE;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACpC,QAAQ,EAAE,mBAAmB,EAC7B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAMxB"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Each provider has its own config with display name, description, steps, and model builder.
|
|
4
4
|
*/
|
|
5
5
|
import { CUSTOM_MODEL_PROVIDERS } from '@dexto/agent-management';
|
|
6
|
-
import { lookupOpenRouterModel, refreshOpenRouterModelCache, getLocalModelById } from '@dexto/core';
|
|
6
|
+
import { lookupOpenRouterModel, refreshOpenRouterModelCache, getLocalModelById, isReasoningCapableModel, } from '@dexto/core';
|
|
7
7
|
import { validators } from './types.js';
|
|
8
8
|
import * as fs from 'fs';
|
|
9
9
|
import * as os from 'os';
|
|
@@ -36,6 +36,29 @@ const DISPLAY_NAME_STEP = {
|
|
|
36
36
|
placeholder: 'e.g., My Custom Model',
|
|
37
37
|
required: false,
|
|
38
38
|
};
|
|
39
|
+
/**
|
|
40
|
+
* Common reasoning effort step - for OpenAI reasoning models (o1, o3, codex, gpt-5.x).
|
|
41
|
+
* Only shown when the model name indicates reasoning capability.
|
|
42
|
+
*/
|
|
43
|
+
const REASONING_EFFORT_STEP = {
|
|
44
|
+
field: 'reasoningEffort',
|
|
45
|
+
label: 'Reasoning Effort (optional)',
|
|
46
|
+
placeholder: 'none | minimal | low | medium | high | xhigh (blank for auto)',
|
|
47
|
+
required: false,
|
|
48
|
+
validate: (value) => {
|
|
49
|
+
if (!value?.trim())
|
|
50
|
+
return null;
|
|
51
|
+
const validValues = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh'];
|
|
52
|
+
if (!validValues.includes(value.toLowerCase())) {
|
|
53
|
+
return `Invalid reasoning effort. Use: ${validValues.join(', ')}`;
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
},
|
|
57
|
+
condition: (values) => {
|
|
58
|
+
const modelName = values.name || '';
|
|
59
|
+
return isReasoningCapableModel(modelName);
|
|
60
|
+
},
|
|
61
|
+
};
|
|
39
62
|
/**
|
|
40
63
|
* Provider configuration registry.
|
|
41
64
|
* Keys are CustomModelProvider values.
|
|
@@ -61,6 +84,7 @@ export const PROVIDER_CONFIGS = {
|
|
|
61
84
|
},
|
|
62
85
|
{ ...DISPLAY_NAME_STEP, placeholder: 'e.g., My Local Llama 3' },
|
|
63
86
|
MAX_INPUT_TOKENS_STEP,
|
|
87
|
+
REASONING_EFFORT_STEP,
|
|
64
88
|
API_KEY_STEP,
|
|
65
89
|
],
|
|
66
90
|
buildModel: (values, provider) => {
|
|
@@ -77,6 +101,10 @@ export const PROVIDER_CONFIGS = {
|
|
|
77
101
|
if (values.maxInputTokens?.trim()) {
|
|
78
102
|
model.maxInputTokens = parseInt(values.maxInputTokens, 10);
|
|
79
103
|
}
|
|
104
|
+
if (values.reasoningEffort?.trim()) {
|
|
105
|
+
model.reasoningEffort =
|
|
106
|
+
values.reasoningEffort.toLowerCase();
|
|
107
|
+
}
|
|
80
108
|
return model;
|
|
81
109
|
},
|
|
82
110
|
},
|
|
@@ -92,6 +120,7 @@ export const PROVIDER_CONFIGS = {
|
|
|
92
120
|
validate: validators.slashFormat,
|
|
93
121
|
},
|
|
94
122
|
{ ...DISPLAY_NAME_STEP, placeholder: 'e.g., Claude 3.5 Sonnet' },
|
|
123
|
+
REASONING_EFFORT_STEP,
|
|
95
124
|
{
|
|
96
125
|
...API_KEY_STEP,
|
|
97
126
|
placeholder: 'Saved as OPENROUTER_API_KEY if not set, otherwise per-model',
|
|
@@ -105,6 +134,10 @@ export const PROVIDER_CONFIGS = {
|
|
|
105
134
|
if (values.displayName?.trim()) {
|
|
106
135
|
model.displayName = values.displayName.trim();
|
|
107
136
|
}
|
|
137
|
+
if (values.reasoningEffort?.trim()) {
|
|
138
|
+
model.reasoningEffort =
|
|
139
|
+
values.reasoningEffort.toLowerCase();
|
|
140
|
+
}
|
|
108
141
|
return model;
|
|
109
142
|
},
|
|
110
143
|
asyncValidation: {
|
|
@@ -141,6 +174,7 @@ export const PROVIDER_CONFIGS = {
|
|
|
141
174
|
validate: validators.slashFormat,
|
|
142
175
|
},
|
|
143
176
|
{ ...DISPLAY_NAME_STEP, placeholder: 'e.g., GPT-4o via Glama' },
|
|
177
|
+
REASONING_EFFORT_STEP,
|
|
144
178
|
{
|
|
145
179
|
...API_KEY_STEP,
|
|
146
180
|
placeholder: 'Saved as GLAMA_API_KEY if not set, otherwise per-model',
|
|
@@ -154,6 +188,10 @@ export const PROVIDER_CONFIGS = {
|
|
|
154
188
|
if (values.displayName?.trim()) {
|
|
155
189
|
model.displayName = values.displayName.trim();
|
|
156
190
|
}
|
|
191
|
+
if (values.reasoningEffort?.trim()) {
|
|
192
|
+
model.reasoningEffort =
|
|
193
|
+
values.reasoningEffort.toLowerCase();
|
|
194
|
+
}
|
|
157
195
|
return model;
|
|
158
196
|
},
|
|
159
197
|
},
|
|
@@ -177,6 +215,7 @@ export const PROVIDER_CONFIGS = {
|
|
|
177
215
|
},
|
|
178
216
|
{ ...DISPLAY_NAME_STEP, placeholder: 'e.g., My LiteLLM GPT-4' },
|
|
179
217
|
MAX_INPUT_TOKENS_STEP,
|
|
218
|
+
REASONING_EFFORT_STEP,
|
|
180
219
|
{
|
|
181
220
|
...API_KEY_STEP,
|
|
182
221
|
placeholder: 'Saved as LITELLM_API_KEY if not set, otherwise per-model',
|
|
@@ -196,6 +235,10 @@ export const PROVIDER_CONFIGS = {
|
|
|
196
235
|
if (values.maxInputTokens?.trim()) {
|
|
197
236
|
model.maxInputTokens = parseInt(values.maxInputTokens, 10);
|
|
198
237
|
}
|
|
238
|
+
if (values.reasoningEffort?.trim()) {
|
|
239
|
+
model.reasoningEffort =
|
|
240
|
+
values.reasoningEffort.toLowerCase();
|
|
241
|
+
}
|
|
199
242
|
return model;
|
|
200
243
|
},
|
|
201
244
|
},
|
|
@@ -12,6 +12,12 @@ export interface WizardStep {
|
|
|
12
12
|
placeholder: string;
|
|
13
13
|
required: boolean;
|
|
14
14
|
validate?: (value: string) => string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Optional condition to determine if this step should be shown.
|
|
17
|
+
* Takes the current accumulated values and returns true if the step should be shown.
|
|
18
|
+
* If omitted, the step is always shown.
|
|
19
|
+
*/
|
|
20
|
+
condition?: (values: Record<string, string>) => boolean;
|
|
15
21
|
}
|
|
16
22
|
/**
|
|
17
23
|
* Props passed to each provider-specific wizard component.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/ink-cli/components/overlays/custom-model-wizard/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,wCAAwC,CAAC;AAElE;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/ink-cli/components/overlays/custom-model-wizard/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,wCAAwC,CAAC;AAElE;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC5C;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC;CAC3D;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,8CAA8C;IAC9C,YAAY,EAAE,OAAO,CAAC;IACtB,uCAAuC;IACvC,QAAQ,EAAE,OAAO,CAAC;IAClB,8CAA8C;IAC9C,SAAS,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,sDAAsD;IACtD,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;IAClD,sCAAsC;IACtC,QAAQ,EAAE,MAAM,UAAU,EAAE,CAAC;IAC7B,8BAA8B;IAC9B,oBAAoB,EAAE,MAAM,UAAU,GAAG,SAAS,CAAC;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,kDAAkD;IAClD,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,mBAAmB,KAAK,WAAW,CAAC;IAC3F,oDAAoD;IACpD,eAAe,CAAC,EAAE;QACd,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;KACvD,CAAC;IACF,sDAAsD;IACtD,SAAS,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACL;AAED;;GAEG;AACH,eAAO,MAAM,UAAU;sBACD,MAAM,MAAM,GAAG,MAAM;aAE9B,MAAM;wBAaK,MAAM;qBAOT,MAAM;CAK1B,CAAC"}
|
|
@@ -22,5 +22,5 @@ export function GenericRenderer({ content, maxLines = 15 }) {
|
|
|
22
22
|
const line = lines[0];
|
|
23
23
|
return (_jsxs(Text, { color: "gray", children: [' ⎿ ', line.slice(0, 80), line.length > 80 ? '...' : ''] }));
|
|
24
24
|
}
|
|
25
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: [' ⎿ ', displayLines.length, " lines"] }), displayLines.map((line, i) => (_jsxs(Text, { color: "gray", wrap: "truncate", children: ['
|
|
25
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: [' ⎿ ', displayLines.length, " lines"] }), displayLines.map((line, i) => (_jsxs(Text, { color: "gray", wrap: "truncate", children: [' ⎿ ', line] }, i))), truncated && (_jsxs(Text, { color: "gray", children: [' ⎿ ', "... ", lines.length - maxLines, " more lines"] }))] }));
|
|
26
26
|
}
|
|
@@ -8,5 +8,5 @@ export function SearchRenderer({ data, maxMatches = 5 }) {
|
|
|
8
8
|
const { pattern, matches, totalMatches, truncated: dataTruncated } = data;
|
|
9
9
|
const displayMatches = matches.slice(0, maxMatches);
|
|
10
10
|
const truncated = dataTruncated || matches.length > maxMatches;
|
|
11
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: [' ⎿ ', totalMatches, " match", totalMatches !== 1 ? 'es' : '', " for \"", pattern, "\"", truncated && ' (truncated)'] }), displayMatches.map((match, i) => (_jsxs(Text, { color: "gray", children: ['
|
|
11
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: [' ⎿ ', totalMatches, " match", totalMatches !== 1 ? 'es' : '', " for \"", pattern, "\"", truncated && ' (truncated)'] }), displayMatches.map((match, i) => (_jsxs(Text, { color: "gray", wrap: "truncate", children: [' ⎿ ', match.file, match.line > 0 && `:${match.line}`] }, i))), matches.length > maxMatches && (_jsxs(Text, { color: "gray", children: [' ⎿ ', "... ", matches.length - maxMatches, " more"] }))] }));
|
|
12
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownText.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/shared/MarkdownText.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAwB,MAAM,OAAO,CAAC;AAU7C,UAAU,aAAa;IACnB,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,eAAe,GAAG,MAAM,GAAG,KAAK,CAAC;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,iBAAS,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAuE1D;
|
|
1
|
+
{"version":3,"file":"MarkdownText.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/shared/MarkdownText.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAwB,MAAM,OAAO,CAAC;AAU7C,UAAU,aAAa;IACnB,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,eAAe,GAAG,MAAM,GAAG,KAAK,CAAC;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,iBAAS,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAuE1D;AAyID,UAAU,iBAAiB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAkED,QAAA,MAAM,YAAY,+CAA6B,CAAC;AAMhD,UAAU,iBAAiB;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AA4RD,eAAO,MAAM,YAAY,+CAA6B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,CAAC"}
|
|
@@ -168,12 +168,12 @@ const WrappedParagraphInternal = ({ text, defaultColor, bulletPrefix, isFirstPar
|
|
|
168
168
|
return wrapped.split('\n');
|
|
169
169
|
}, [text, defaultColor, bulletPrefix, isFirstParagraph, terminalWidth]);
|
|
170
170
|
// Calculate indent for continuation lines (spaces to align with first line content)
|
|
171
|
-
|
|
171
|
+
// All lines get indentation when bulletPrefix is provided, for consistent left margin
|
|
172
|
+
const indentSpaces = bulletPrefix ? ' '.repeat(stringWidth(bulletPrefix)) : '';
|
|
172
173
|
return (_jsx(_Fragment, { children: wrappedLines.map((line, i) => {
|
|
173
174
|
const isFirstLine = i === 0;
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
: continuationIndent;
|
|
175
|
+
// First line of first paragraph gets bullet, all other lines get space indent
|
|
176
|
+
const prefix = isFirstLine && isFirstParagraph && bulletPrefix ? bulletPrefix : indentSpaces;
|
|
177
177
|
return (_jsx(Box, { children: _jsxs(Text, { children: [prefix, line] }) }, i));
|
|
178
178
|
}) }));
|
|
179
179
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processingPhrases.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/constants/processingPhrases.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"processingPhrases.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/constants/processingPhrases.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAiErC,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAGxC"}
|