mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 00:13:28 +00:00
feat: add tui ui kit
This commit is contained in:
102
src/tui/components/chat-log.ts
Normal file
102
src/tui/components/chat-log.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { Container, Spacer, Text } from "@mariozechner/pi-tui";
|
||||
import { AssistantMessageComponent } from "./assistant-message.js";
|
||||
import { ToolExecutionComponent } from "./tool-execution.js";
|
||||
import { UserMessageComponent } from "./user-message.js";
|
||||
import { theme } from "../theme/theme.js";
|
||||
|
||||
export class ChatLog extends Container {
|
||||
private toolById = new Map<string, ToolExecutionComponent>();
|
||||
private streamingAssistant: AssistantMessageComponent | null = null;
|
||||
private streamingRunId: string | null = null;
|
||||
private toolsExpanded = false;
|
||||
|
||||
clearAll() {
|
||||
this.clear();
|
||||
this.toolById.clear();
|
||||
this.streamingAssistant = null;
|
||||
this.streamingRunId = null;
|
||||
}
|
||||
|
||||
addSystem(text: string) {
|
||||
this.addChild(new Spacer(1));
|
||||
this.addChild(new Text(theme.system(text), 1, 0));
|
||||
}
|
||||
|
||||
addUser(text: string) {
|
||||
this.addChild(new UserMessageComponent(text));
|
||||
}
|
||||
|
||||
startAssistant(text: string, runId?: string) {
|
||||
const component = new AssistantMessageComponent(text);
|
||||
this.streamingAssistant = component;
|
||||
this.streamingRunId = runId ?? null;
|
||||
this.addChild(component);
|
||||
return component;
|
||||
}
|
||||
|
||||
updateAssistant(text: string, runId?: string) {
|
||||
if (
|
||||
!this.streamingAssistant ||
|
||||
(runId && this.streamingRunId && runId !== this.streamingRunId)
|
||||
) {
|
||||
this.startAssistant(text, runId);
|
||||
return;
|
||||
}
|
||||
this.streamingAssistant.setText(text);
|
||||
}
|
||||
|
||||
finalizeAssistant(text: string, runId?: string) {
|
||||
if (
|
||||
this.streamingAssistant &&
|
||||
(!runId || runId === this.streamingRunId)
|
||||
) {
|
||||
this.streamingAssistant.setText(text);
|
||||
} else {
|
||||
this.startAssistant(text, runId);
|
||||
}
|
||||
this.streamingAssistant = null;
|
||||
this.streamingRunId = null;
|
||||
}
|
||||
|
||||
startTool(toolCallId: string, toolName: string, args: unknown) {
|
||||
const existing = this.toolById.get(toolCallId);
|
||||
if (existing) {
|
||||
existing.setArgs(args);
|
||||
return existing;
|
||||
}
|
||||
const component = new ToolExecutionComponent(toolName, args);
|
||||
component.setExpanded(this.toolsExpanded);
|
||||
this.toolById.set(toolCallId, component);
|
||||
this.addChild(component);
|
||||
return component;
|
||||
}
|
||||
|
||||
updateToolArgs(toolCallId: string, args: unknown) {
|
||||
const existing = this.toolById.get(toolCallId);
|
||||
if (!existing) return;
|
||||
existing.setArgs(args);
|
||||
}
|
||||
|
||||
updateToolResult(
|
||||
toolCallId: string,
|
||||
result: unknown,
|
||||
opts?: { isError?: boolean; partial?: boolean },
|
||||
) {
|
||||
const existing = this.toolById.get(toolCallId);
|
||||
if (!existing) return;
|
||||
if (opts?.partial) {
|
||||
existing.setPartialResult(result as Record<string, unknown>);
|
||||
return;
|
||||
}
|
||||
existing.setResult(result as Record<string, unknown>, {
|
||||
isError: opts?.isError,
|
||||
});
|
||||
}
|
||||
|
||||
setToolsExpanded(expanded: boolean) {
|
||||
this.toolsExpanded = expanded;
|
||||
for (const tool of this.toolById.values()) {
|
||||
tool.setExpanded(expanded);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user