mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-15 08:03:46 +00:00
docs: propose UI library approach inspired by Vercel/TanStack useChat
This commit is contained in:
parent
8a31519786
commit
1ca6ecb5e0
5 changed files with 113 additions and 0 deletions
1
.turbo
Symbolic link
1
.turbo
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
/home/nathan/sandbox-agent/.turbo
|
||||
1
dist
Symbolic link
1
dist
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
/home/nathan/sandbox-agent/dist
|
||||
1
node_modules
Symbolic link
1
node_modules
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
/home/nathan/sandbox-agent/node_modules
|
||||
109
research/ui-library-proposal.md
Normal file
109
research/ui-library-proposal.md
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
# Proposal: UI Library (useChat-style)
|
||||
|
||||
## Summary
|
||||
This proposes a component library modeled after Vercel AI SDK `useChat` and TanStack AI `useChat`, adapted to Sandbox Agent's universal event stream and HITL flows. The plan is headless-first, with React bindings and optional UI components.
|
||||
|
||||
## References Reviewed
|
||||
- Vercel AI SDK `useChat` API docs (transport-based, UIMessage parts, tool outputs).
|
||||
- TanStack AI `useChat` source (`packages/typescript/ai-react/src/use-chat.ts`) and types.
|
||||
|
||||
## Observations (Patterns to Copy)
|
||||
- Headless core + framework bindings.
|
||||
- Transport/connection abstraction; default transport with overrides.
|
||||
- Hook owns message state, status, and error; returns imperative helpers.
|
||||
- Message model is part-based (text, tool call/result, status, media, etc.).
|
||||
- Tool/HITL outputs are first-class actions.
|
||||
|
||||
## Proposal
|
||||
|
||||
### Package Structure
|
||||
1) `@sandbox-agent/ui-core`
|
||||
- Event to UI reducers.
|
||||
- Derive `UIMessage[]` with parts from universal events.
|
||||
- Shared types for message parts, permissions, questions, and status.
|
||||
|
||||
2) `@sandbox-agent/ui-react`
|
||||
- `useChat` hook on top of core store.
|
||||
- Stable API shape inspired by Vercel/TanStack.
|
||||
|
||||
3) `@sandbox-agent/ui-components` (optional)
|
||||
- Composable UI primitives that render content parts.
|
||||
- HITL UI components (permission and question prompts).
|
||||
|
||||
4) `@sandbox-agent/ui-transports`
|
||||
- `sdkTransport(client)` using the TypeScript SDK.
|
||||
- `sseTransport({ baseUrl, token })` for bare HTTP/SSE.
|
||||
- `turnTransport` for send + stream in one call.
|
||||
|
||||
### Message Model
|
||||
`UIMessage { id, role, status, parts[] }`
|
||||
|
||||
`parts[]` includes:
|
||||
- `text`
|
||||
- `tool_call`
|
||||
- `tool_result`
|
||||
- `file_ref` (diffs, actions)
|
||||
- `status`
|
||||
- `reasoning`
|
||||
- `image`
|
||||
|
||||
This aligns with `docs/building-chat-ui.mdx` and Vercel's `UIMessage.parts` concept.
|
||||
|
||||
### Headless Core API (Sketch)
|
||||
```ts
|
||||
type ChatTransport = {
|
||||
sendMessage: (sessionId: string, input: string) => Promise<void>
|
||||
streamEvents: (sessionId: string, opts: { offset: number }) => AsyncIterable<UniversalEvent>
|
||||
replyPermission: (sessionId: string, id: string, reply: "once" | "always" | "reject") => Promise<void>
|
||||
replyQuestion: (sessionId: string, id: string, answers: string[][]) => Promise<void>
|
||||
rejectQuestion: (sessionId: string, id: string) => Promise<void>
|
||||
terminate: (sessionId: string) => Promise<void>
|
||||
}
|
||||
|
||||
type ChatStore = {
|
||||
state: ChatState
|
||||
applyEvent: (event: UniversalEvent) => void
|
||||
subscribe: (listener: () => void) => () => void
|
||||
}
|
||||
|
||||
createChatStore({ transport, sessionId, initialEvents? })
|
||||
```
|
||||
|
||||
### React Hook API (Sketch)
|
||||
```ts
|
||||
const {
|
||||
messages,
|
||||
status,
|
||||
error,
|
||||
isLoading,
|
||||
sendMessage,
|
||||
stop,
|
||||
resume,
|
||||
clear,
|
||||
reloadLast,
|
||||
replyPermission,
|
||||
replyQuestion,
|
||||
rejectQuestion,
|
||||
addToolOutput,
|
||||
} = useChat({ sessionId, transport, initialMessages })
|
||||
```
|
||||
|
||||
Notes:
|
||||
- Status should map to: `ready | submitted | streaming | error` (Vercel-style).
|
||||
- `addToolOutput` is optional and only relevant when tools complete on the client.
|
||||
|
||||
### UI Components (Optional)
|
||||
- `MessagePartRenderer` with render props.
|
||||
- `ToolCall`, `ToolResult`, `FileDiff`, `StatusChip`, `Reasoning`, `ImagePart`.
|
||||
- `PermissionRequest`, `QuestionPrompt`.
|
||||
|
||||
## Why This Fits Sandbox Agent
|
||||
- Universal event stream already defines the canonical state.
|
||||
- HITL flows (permissions/questions) map directly to hook actions and components.
|
||||
- Inspector is a reference implementation; reducers can be extracted from it.
|
||||
|
||||
## Adoption Path
|
||||
1) Extract event reducers from Inspector into `@sandbox-agent/ui-core`.
|
||||
2) Implement `useChat` in `@sandbox-agent/ui-react` using a store and transport.
|
||||
3) Add UI components for content parts + HITL.
|
||||
4) Update `docs/building-chat-ui.mdx` with the new package usage.
|
||||
1
target
Symbolic link
1
target
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
/home/nathan/sandbox-agent/target
|
||||
Loading…
Add table
Add a link
Reference in a new issue