fix(tui): enable tool access in fullscreen mode via NativeAgent
Fullscreen TUI was calling modelClient directly, bypassing the NativeAgent tool loop entirely. Pass the agent through FullscreenTuiConfig → App and use agent.process() for message handling, which enables the full tool registry and executor.
This commit is contained in:
@@ -216,6 +216,7 @@ export function registerTuiCommand(program: Command): void {
|
||||
modelRouter,
|
||||
systemPrompt,
|
||||
model: config.models.default.model,
|
||||
agent,
|
||||
onExit: cleanup,
|
||||
});
|
||||
} else {
|
||||
@@ -259,6 +260,7 @@ export function registerTuiCommand(program: Command): void {
|
||||
modelRouter,
|
||||
systemPrompt,
|
||||
model: config.models.default.model,
|
||||
agent,
|
||||
onExit: cleanup,
|
||||
});
|
||||
return;
|
||||
|
||||
@@ -7,6 +7,7 @@ import { parseCommand, getHelpText, resolveModelAlias, getCommandCompletions } f
|
||||
import type { Message, ModelClient, TokenUsage } from '../../../models/types.js';
|
||||
import type { ModelRouter } from '../../../models/router.js';
|
||||
import type { ManagedSession } from '../../../session/index.js';
|
||||
import type { NativeAgent } from '../../../backends/native/agent.js';
|
||||
|
||||
export interface AppProps {
|
||||
session: ManagedSession;
|
||||
@@ -14,6 +15,7 @@ export interface AppProps {
|
||||
modelRouter?: ModelRouter;
|
||||
systemPrompt: string;
|
||||
model: string;
|
||||
agent?: NativeAgent;
|
||||
onExit?: () => void;
|
||||
}
|
||||
|
||||
@@ -23,6 +25,7 @@ export function App({
|
||||
modelRouter,
|
||||
systemPrompt,
|
||||
model,
|
||||
agent,
|
||||
onExit,
|
||||
}: AppProps): React.ReactElement {
|
||||
const { exit } = useApp();
|
||||
@@ -156,19 +159,33 @@ export function App({
|
||||
|
||||
if (command.type !== 'message' || isStreaming) return;
|
||||
|
||||
// Add user message
|
||||
// Add user message to UI (and session if no agent — agent adds it internally)
|
||||
const userMessage: Message = { role: 'user', content: command.content };
|
||||
const messageWithTimestamp = session.addMessage(userMessage);
|
||||
setMessages(prev => [...prev, messageWithTimestamp]);
|
||||
if (!agent) {
|
||||
const messageWithTimestamp = session.addMessage(userMessage);
|
||||
setMessages(prev => [...prev, messageWithTimestamp]);
|
||||
} else {
|
||||
setMessages(prev => [...prev, { ...userMessage, timestamp: Date.now() }]);
|
||||
}
|
||||
setScrollOffset(0); // Auto-scroll to bottom
|
||||
|
||||
// Stream response
|
||||
// Process response
|
||||
setIsStreaming(true);
|
||||
setStreamingContent('');
|
||||
abortRef.current = false;
|
||||
|
||||
try {
|
||||
if (modelClient.chatStream) {
|
||||
if (agent) {
|
||||
// agent.process() handles session history internally
|
||||
const response = await agent.process(command.content);
|
||||
|
||||
const usage = agent.getUsage();
|
||||
setTokenUsage({ inputTokens: usage.inputTokens, outputTokens: usage.outputTokens });
|
||||
|
||||
// Sync UI with session history (agent already added messages to session)
|
||||
setMessages(session.getHistory());
|
||||
} else if (modelClient.chatStream) {
|
||||
// Fallback: direct streaming without tools
|
||||
let fullContent = '';
|
||||
|
||||
for await (const event of modelClient.chatStream({
|
||||
@@ -199,7 +216,7 @@ export function App({
|
||||
const assistantWithTimestamp = session.addMessage(assistantMessage);
|
||||
setMessages(prev => [...prev, assistantWithTimestamp]);
|
||||
} else {
|
||||
// Fallback to non-streaming
|
||||
// Fallback: non-streaming without tools
|
||||
const response = await modelClient.chat({
|
||||
messages: session.getHistory(),
|
||||
system: systemPrompt,
|
||||
@@ -225,7 +242,7 @@ export function App({
|
||||
setIsStreaming(false);
|
||||
setStreamingContent('');
|
||||
}
|
||||
}, [isStreaming, session, modelClient, modelRouter, systemPrompt, exit, onExit, messages.length, tokenUsage]);
|
||||
}, [isStreaming, session, agent, modelClient, modelRouter, systemPrompt, exit, onExit, messages.length, tokenUsage]);
|
||||
|
||||
return (
|
||||
<Box flexDirection="column" height="100%">
|
||||
|
||||
@@ -4,6 +4,7 @@ import { App } from './components/index.js';
|
||||
import type { ManagedSession } from '../../session/index.js';
|
||||
import type { ModelClient } from '../../models/types.js';
|
||||
import type { ModelRouter } from '../../models/router.js';
|
||||
import type { NativeAgent } from '../../backends/native/agent.js';
|
||||
|
||||
export interface FullscreenTuiConfig {
|
||||
session: ManagedSession;
|
||||
@@ -11,6 +12,7 @@ export interface FullscreenTuiConfig {
|
||||
modelRouter?: ModelRouter;
|
||||
systemPrompt: string;
|
||||
model: string;
|
||||
agent?: NativeAgent;
|
||||
onExit?: () => void;
|
||||
}
|
||||
|
||||
@@ -27,6 +29,7 @@ export async function startFullscreenTui(config: FullscreenTuiConfig): Promise<v
|
||||
modelRouter: config.modelRouter,
|
||||
systemPrompt: config.systemPrompt,
|
||||
model: config.model,
|
||||
agent: config.agent,
|
||||
onExit: config.onExit,
|
||||
})
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user