Implement comprehensive tool call rendering with state persistence

- Implement tool-specific rendering for all 14 tool types (read, edit, write, bash, webfetch, todowrite, task, etc.)
- Each tool shows contextually relevant information (file previews, diffs, command output, todo lists)
- Add metadata-driven content display using preview, diff, output, and todos from tool state
- Implement status-based rendering (pending, running, completed, error) with animations
- Create global state store for expandable items (tool calls and reasoning sections)
- Fix state persistence: expanded tool calls and reasoning sections remain expanded when new messages arrive
- Fix scroll position preservation during live message updates
- Fix reasoning toggle loop by replacing native details element with custom expandable
- Add comprehensive documentation in TOOL_CALL_IMPLEMENTATION.md
- Reduce font sizes for better readability in expanded tool content
- Add proper keying to For loops to prevent component recreation
- Match TUI patterns for tool names, actions, and content formatting
This commit is contained in:
Shantur Rathore
2025-10-23 01:18:25 +01:00
parent fa77b4e82e
commit d7f619486e
15 changed files with 3059 additions and 106 deletions

View File

@@ -5,6 +5,7 @@ import SessionPicker from "./components/session-picker"
import InstanceTabs from "./components/instance-tabs"
import SessionTabs from "./components/session-tabs"
import MessageStream from "./components/message-stream"
import PromptInput from "./components/prompt-input"
import {
hasInstances,
isSelectingFolder,
@@ -35,10 +36,11 @@ import {
activeParentSessionId,
getParentSessions,
loadMessages,
sendMessage,
} from "./stores/sessions"
import { setupTabKeyboardShortcuts } from "./lib/keyboard"
const SessionMessages: Component<{
const SessionView: Component<{
sessionId: string
activeSessions: Map<string, Session>
instanceId: string
@@ -52,6 +54,10 @@ const SessionMessages: Component<{
}
})
async function handleSendMessage(prompt: string) {
await sendMessage(props.instanceId, props.sessionId, prompt)
}
return (
<Show
when={session()}
@@ -61,7 +67,17 @@ const SessionMessages: Component<{
</div>
}
>
{(s) => <MessageStream sessionId={s().id} messages={s().messages || []} messagesInfo={s().messagesInfo} />}
{(s) => (
<div class="session-view">
<MessageStream
instanceId={props.instanceId}
sessionId={s().id}
messages={s().messages || []}
messagesInfo={s().messagesInfo}
/>
<PromptInput instanceId={props.instanceId} sessionId={s().id} onSend={handleSendMessage} />
</div>
)}
</Show>
)
}
@@ -213,7 +229,7 @@ const App: Component = () => {
</div>
}
>
<SessionMessages
<SessionView
sessionId={activeSessionIdForInstance()!}
activeSessions={activeSessions()}
instanceId={activeInstance()!.id}