Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3813,6 +3813,7 @@ Begin by analyzing the query and planning your research approach.`;
}

if (useInkUi && inkController) {
inkController.addToolCall(name, input as Record<string, unknown>);
inkController.setStatus({ activity: 'tool', activityDetail: name });
} else if (workerStatusUI) {
workerStatusUI.setAgentActivity('tool', name);
Expand Down Expand Up @@ -3848,13 +3849,11 @@ Begin by analyzing the query and planning your research approach.`;
}
}
console.log();
} else if (isError && inkController) {
const preview = result.length > 200 ? `${result.slice(0, 200)}...` : result;
inkController.addMessage('system', `Tool error (${name}): ${preview}`);
}
if (useInkUi && inkController) {
} else if (inkController) {
inkController.addToolResult(name, result, isError, durationMs);
inkController.setStatus({ activity: 'thinking', activityDetail: null });
} else if (workerStatusUI) {
}
if (!useInkUi && workerStatusUI) {
workerStatusUI.setAgentActivity('thinking', null);
}
},
Expand Down
24 changes: 11 additions & 13 deletions src/ui/ink/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -624,23 +624,13 @@ export function InkApp({ controller, onSubmit, onExit, history, completer }: Ink
const activityPanel = useMemo(() => {
const hasWorkers = workerList.length > 0;
const hasReaders = readerList.length > 0;
const hasActivity = status.activity && status.activity !== 'idle';
const hasConfirmation = Boolean(confirmation);

if (!hasWorkers && !hasReaders && !hasActivity && !hasConfirmation) {
return {
lines: [] as ActivityLine[],
maxStart: 0,
scrollStep: 0,
total: 0,
};
}

const nodes: TreeNode[] = [];
const detailMax = Math.max(24, contentWidth - 10);
const activityLabel = formatActivity(status);
const active = status.activity && status.activity !== 'idle';
const spinner = hasActiveProgress ? `${SPINNER_FRAMES[spinnerFrame]} ` : '';
const spinner = hasActiveProgress ? `${SPINNER_FRAMES[spinnerFrame]} ` : ' ';
const agentColor =
status.activity === 'confirm' ? 'yellow' : status.activity === 'tool' ? 'magenta' : 'cyan';

Expand Down Expand Up @@ -761,12 +751,20 @@ export function InkApp({ controller, onSubmit, onExit, history, completer }: Ink
});
}

const treeLines = renderTree(nodes, contentWidth);

// Ensure minimum height to prevent layout jumping
const minHeight = 3;
const paddingNeeded = Math.max(0, minHeight - 1 - treeLines.length);
const padding: ActivityLine[] = Array.from({ length: paddingNeeded }, () => ({ text: '', dim: true }));

const allLines: ActivityLine[] = [
{ text: 'Activity', dim: true },
...renderTree(nodes, contentWidth),
...treeLines,
...padding,
];

const maxHeight = Math.max(3, Math.min(allLines.length, Math.floor((stdout.rows ?? 24) / 3)));
const maxHeight = Math.max(minHeight, Math.min(allLines.length, Math.floor((stdout.rows ?? 24) / 3)));
const maxStart = Math.max(0, allLines.length - maxHeight);
const offset = clamp(activityScrollOffset, 0, maxStart);
const start = offset;
Expand Down
18 changes: 18 additions & 0 deletions src/ui/ink/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,24 @@ export class InkUiController extends EventEmitter {
this.emit('messageChunk', { id, chunk });
}

addToolCall(name: string, input: Record<string, unknown>): void {
const preview = JSON.stringify(input);
const truncated = preview.length > 100 ? preview.slice(0, 100) + '...' : preview;
this.addMessage('system', `📎 ${name}\n${truncated}`);
}

addToolResult(name: string, result: string, isError: boolean, durationMs: number): void {
const icon = isError ? '❌' : '✓';
const durationStr = `${(durationMs / 1000).toFixed(1)}s`;
if (isError) {
const preview = result.length > 200 ? `${result.slice(0, 200)}...` : result;
this.addMessage('system', `${icon} ${name} Error (${durationStr})\n${preview}`);
} else {
const lines = result.split('\n').length;
this.addMessage('system', `${icon} ${name} (${lines} lines, ${durationStr})`);
}
}

addWorkerLog(workerId: string, log: LogMessage): void {
const entry: UiWorkerLog = {
id: `l${++this.logCounter}`,
Expand Down
Loading