Unify TUI slash commands and harden tool inventory responses

This commit is contained in:
William Valentin
2026-02-21 12:39:27 -08:00
parent e9cb1d7c1a
commit b09bfc8373
16 changed files with 505 additions and 21 deletions
+47 -1
View File
@@ -3,7 +3,7 @@ import { Box, Text, useApp, useInput } from 'ink';
import { StatusBar } from './StatusBar.js';
import { MessageList } from './MessageList.js';
import { InputBar } from './InputBar.js';
import { parseCommand, getHelpText, resolveModelAlias, getCommandCompletions } from '../commands.js';
import { parseCommand, getHelpText, resolveModelAlias, getCommandCompletions, isToolInventoryQuery } from '../commands.js';
import type { Message, ModelClient, TokenUsage } from '../../../models/types.js';
import type { ModelRouter } from '../../../models/router.js';
import type { ManagedSession } from '../../../session/index.js';
@@ -59,6 +59,9 @@ export interface AppProps {
modelProviderConfigs?: Partial<Record<ModelProvider, ModelConfig>>;
contextThresholdPct?: number;
onTransfer?: (target: string) => string | void;
onTools?: () => string;
onResearch?: (task: string) => Promise<string> | string;
onCouncil?: (task: string) => Promise<string> | string;
onExit?: () => void;
}
@@ -76,6 +79,9 @@ export function App({
modelProviderConfigs,
contextThresholdPct,
onTransfer,
onTools,
onResearch,
onCouncil,
onExit,
}: AppProps): React.ReactElement {
const ensureTimestamp = useCallback((message: Message): Message => ({
@@ -603,6 +609,41 @@ export function App({
return;
}
case 'tools': {
if (!onTools) {
pushAssistantMessage('Tools command is not available in this TUI mode.');
return;
}
pushAssistantMessage(onTools());
return;
}
case 'research': {
if (!command.task.trim()) {
pushAssistantMessage('Usage: /research <question or task>');
return;
}
if (!onResearch) {
pushAssistantMessage('Research command is not available in this TUI mode.');
return;
}
pushAssistantMessage(await onResearch(command.task));
return;
}
case 'council': {
if (!command.task.trim()) {
pushAssistantMessage('Usage: /council <question or task>');
return;
}
if (!onCouncil) {
pushAssistantMessage('Council command is not available in this TUI mode.');
return;
}
pushAssistantMessage(await onCouncil(command.task));
return;
}
case 'pair': {
if (!pairingManager) {
pushAssistantMessage('Pairing not enabled. Set pairing.enabled: true in config.');
@@ -695,6 +736,11 @@ export function App({
}
setScrollOffset(0);
if (onTools && isToolInventoryQuery(command.content)) {
pushAssistantMessage(onTools());
return;
}
setIsStreaming(true);
setStreamingContent('');
toolLinesRef.current = [];