@hsafa/ui-sdk 0.3.3 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +133 -2
- package/dist/index.cjs +23 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +572 -20
- package/dist/index.d.ts +572 -20
- package/dist/index.js +23 -23
- package/dist/index.js.map +1 -1
- package/docs/CUSTOM_UI_EXAMPLES.md +309 -0
- package/docs/DYNAMIC_PAGE_SCHEMAS.md +261 -0
- package/docs/HEADLESS_QUICK_REFERENCE.md +426 -0
- package/docs/HEADLESS_USAGE.md +682 -0
- package/docs/MIGRATION_TO_HEADLESS.md +408 -0
- package/docs/README.md +43 -71
- package/docs/handbook/00-Overview.md +69 -0
- package/docs/handbook/01-Quickstart.md +133 -0
- package/docs/handbook/02-Architecture.md +75 -0
- package/docs/handbook/03-Components-and-Hooks.md +81 -0
- package/docs/handbook/04-Streaming-and-Transport.md +73 -0
- package/docs/handbook/05-Tools-and-UI.md +73 -0
- package/docs/handbook/06-Storage-and-History.md +63 -0
- package/docs/handbook/07-Dynamic-Pages.md +49 -0
- package/docs/handbook/08-Server-Integration.md +84 -0
- package/docs/handbook/09-Agent-Studio-Client.md +40 -0
- package/docs/handbook/10-Examples-and-Recipes.md +154 -0
- package/docs/handbook/11-API-Reference-Map.md +48 -0
- package/docs/handbook/README.md +24 -0
- package/examples/custom-tools-example.tsx +401 -0
- package/examples/custom-ui-customizations-example.tsx +543 -0
- package/examples/dynamic-page-example.tsx +380 -0
- package/examples/headless-chat-example.tsx +537 -0
- package/examples/minimal-headless-example.tsx +142 -0
- package/package.json +3 -2
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# 08 — Server Integration
|
|
2
|
+
|
|
3
|
+
This document explains the server contract expected by the SDK and how the provided server module implements it.
|
|
4
|
+
|
|
5
|
+
## Endpoints
|
|
6
|
+
|
|
7
|
+
- `POST /api/run/:agentId`
|
|
8
|
+
- Consumes Vercel AI SDK v5 UI messages from the client.
|
|
9
|
+
- Streams NDJSON events back to the client.
|
|
10
|
+
- `POST /api/uploads`
|
|
11
|
+
- Receives file uploads and returns JSON: `{ id, name, url, mimeType, size }`.
|
|
12
|
+
|
|
13
|
+
## Request/response contract
|
|
14
|
+
|
|
15
|
+
- Client uses `DefaultChatTransport` via `createHsafaTransport(baseUrl, agentId, chatId)` and posts:
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"messages": [ /* UIMessage[] (AI SDK v5) */ ],
|
|
19
|
+
"chatId": "chat_...", // injected by the SDK
|
|
20
|
+
"...extra": {}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
- Server streams NDJSON produced from `toUIMessageStream()` and wraps it using `createUIMessageStreamResponse()`.
|
|
24
|
+
|
|
25
|
+
## Reference implementation
|
|
26
|
+
|
|
27
|
+
File: `server/src/modules/agents/run-agent-handler.ts`
|
|
28
|
+
|
|
29
|
+
Key steps:
|
|
30
|
+
1) Parse body; extract `uiMessages` (AI SDK v5 messages).
|
|
31
|
+
2) Load agent definition from Prisma (`agent`, `flowNodes`, `flowEdges`).
|
|
32
|
+
3) Resolve nodes: model, system prompt(s), prompt(s), temperature, MCP, tool nodes.
|
|
33
|
+
4) Build model factory; gather tool model factories from node API keys.
|
|
34
|
+
5) `convertToModelMessages(uiMessages)` → model messages.
|
|
35
|
+
6) `streamText({ model, tools, messages, ... })` using Vercel AI SDK.
|
|
36
|
+
7) Convert to UI stream: `toUIMessageStream({ originalMessages: uiMessages })`.
|
|
37
|
+
8) Send `createUIMessageStreamResponse({ stream, originalMessages: uiMessages })`.
|
|
38
|
+
9) Cleanup MCP clients after stream consumption.
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
// Example usage in a Next.js route
|
|
42
|
+
export const runtime = 'edge';
|
|
43
|
+
export async function POST(req: NextRequest, ctx: { params: { id: string } }) {
|
|
44
|
+
return handleRunAgentRequest(req, ctx);
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Tools on the server
|
|
49
|
+
|
|
50
|
+
- Tool nodes are collected from the agent graph (`run-core/tools.ts`, `run-core/tools/*`).
|
|
51
|
+
- MCP (Model Context Protocol) tools are created in `run-core/mcp.ts` from `custom_mcp` or legacy `mcp_*` nodes.
|
|
52
|
+
- The final `tools` map merges MCP tools and regular tools, namespaced to avoid collisions.
|
|
53
|
+
|
|
54
|
+
### Model providers
|
|
55
|
+
|
|
56
|
+
- The server supports multiple providers via `run-core/models.ts`.
|
|
57
|
+
- The agent’s model node selects provider, model name, and API key.
|
|
58
|
+
|
|
59
|
+
### System prompt
|
|
60
|
+
|
|
61
|
+
- Built from nodes in `run-core/prompts.ts` (also merges available tool info and MCP configuration).
|
|
62
|
+
|
|
63
|
+
### Error handling
|
|
64
|
+
|
|
65
|
+
- All stream errors are emitted as `{ type: 'error', errorText }` events to the client.
|
|
66
|
+
- Handler returns `500` with JSON for pre-stream errors.
|
|
67
|
+
|
|
68
|
+
## Security and performance
|
|
69
|
+
|
|
70
|
+
- Use Edge runtime for lower latency streaming (`export const runtime = 'edge'`).
|
|
71
|
+
- Validate API keys and user access when loading agents.
|
|
72
|
+
- Consider rate-limiting and auth for `/api/run/:agentId`.
|
|
73
|
+
|
|
74
|
+
## Customizing the server
|
|
75
|
+
|
|
76
|
+
- Add new tools in `run-core/tools/` and wire them in `run-core/tools.ts`.
|
|
77
|
+
- Extend prompts and templates in `run-core/prompts.ts`.
|
|
78
|
+
- Add model providers or tweak options in `run-core/models.ts`.
|
|
79
|
+
|
|
80
|
+
## Relationship to the client
|
|
81
|
+
|
|
82
|
+
- Client `HsafaChat`/`useHsafaAgent` expects standard AI SDK v5 semantics.
|
|
83
|
+
- Frontend-only tools and UI components are resolved on the client side (`onToolCall`).
|
|
84
|
+
- Server tools must be declared and available in the `tools` map.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# 09 — Agent Studio (Client)
|
|
2
|
+
|
|
3
|
+
This SDK is designed to consume agents authored in the Agent Studio UI (the flow builder). This document explains how the Studio relates to the runtime and the SDK.
|
|
4
|
+
|
|
5
|
+
## Location
|
|
6
|
+
|
|
7
|
+
- Studio root: `client/src/features/agent/`
|
|
8
|
+
- Page: `AgentPage.tsx`
|
|
9
|
+
- Canvas & flow: `components/AgentFlow.tsx`, `components/AgentFlowCanvas.tsx`
|
|
10
|
+
- Nodes: `components/nodes/*`
|
|
11
|
+
- Hooks: `hooks/useAgentFlow.ts`, `hooks/useStreamingPersistence.ts`
|
|
12
|
+
- Lib: `lib/*`
|
|
13
|
+
|
|
14
|
+
## What the Studio produces
|
|
15
|
+
|
|
16
|
+
- A graph of nodes/edges persisted to the backend (Prisma `agent`, `flowNodes`, `flowEdges`).
|
|
17
|
+
- Node types include model selection, system/prompt nodes, temperature, tool nodes, and MCP nodes.
|
|
18
|
+
- Tool nodes may carry provider-specific API keys used by the server to build model factories.
|
|
19
|
+
|
|
20
|
+
## Server consumption
|
|
21
|
+
|
|
22
|
+
- File: `server/src/modules/agents/run-agent-handler.ts`
|
|
23
|
+
- Loads the saved agent by id.
|
|
24
|
+
- Filters/expands nodes and edges.
|
|
25
|
+
- Renders node data (with templating) into a runtime configuration.
|
|
26
|
+
- Builds model/tools/MCP stacks before streaming.
|
|
27
|
+
|
|
28
|
+
## SDK relationship
|
|
29
|
+
|
|
30
|
+
- The SDK is agnostic of how the agent was authored; it only expects the server to implement the `/api/run/:agentId` contract.
|
|
31
|
+
- Dynamic pages and UI components can be leveraged by the agent if the Studio emits the proper tool calls during execution.
|
|
32
|
+
|
|
33
|
+
## Extending the Studio
|
|
34
|
+
|
|
35
|
+
- Add/modify nodes under `client/src/features/agent/components/nodes/*`.
|
|
36
|
+
- Persist new node data fields; ensure `run-core` interprets them accordingly.
|
|
37
|
+
- For new tools, implement:
|
|
38
|
+
- Studio node for configuration (client),
|
|
39
|
+
- Tool implementation in `server/src/modules/agents/run-core/tools/` (server),
|
|
40
|
+
- Optional frontend tool/UI in the SDK if needed.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# 10 — Examples & Recipes
|
|
2
|
+
|
|
3
|
+
Practical snippets for common tasks using the SDK.
|
|
4
|
+
|
|
5
|
+
## Minimal chat page
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { HsafaProvider, HsafaChat } from '@hsafa/ui-sdk';
|
|
9
|
+
|
|
10
|
+
export default function Page() {
|
|
11
|
+
return (
|
|
12
|
+
<HsafaProvider baseUrl="">
|
|
13
|
+
<HsafaChat agentId="my-agent" theme="dark" />
|
|
14
|
+
</HsafaProvider>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Custom tool and UI component
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { HsafaProvider, HsafaChat } from '@hsafa/ui-sdk';
|
|
23
|
+
|
|
24
|
+
const tools = {
|
|
25
|
+
add: async ({ a, b }: any) => ({ sum: a + b })
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
function ProductCard({ name, price }: { name: string; price: number }) {
|
|
29
|
+
return <div>{name}: ${price}</div>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default function Page() {
|
|
33
|
+
return (
|
|
34
|
+
<HsafaProvider baseUrl="">
|
|
35
|
+
<HsafaChat agentId="my-agent" HsafaTools={tools} HsafaUI={{ ProductCard }} />
|
|
36
|
+
</HsafaProvider>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Headless custom UI
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
import { useHsafaAgent } from '@hsafa/ui-sdk';
|
|
45
|
+
|
|
46
|
+
export function MyChat() {
|
|
47
|
+
const agent = useHsafaAgent({ agentId: 'my-agent', baseUrl: '' });
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<div>
|
|
51
|
+
<div style={{ height: 320, overflow: 'auto' }}>
|
|
52
|
+
{agent.messages.map((m) => (
|
|
53
|
+
<pre key={m.id}>{JSON.stringify(m, null, 2)}</pre>
|
|
54
|
+
))}
|
|
55
|
+
</div>
|
|
56
|
+
<input
|
|
57
|
+
value={agent.input}
|
|
58
|
+
onChange={(e) => agent.setInput(e.target.value)}
|
|
59
|
+
onKeyDown={(e) => e.key === 'Enter' && agent.sendMessage()}
|
|
60
|
+
/>
|
|
61
|
+
<button disabled={agent.isLoading} onClick={() => agent.sendMessage()}>
|
|
62
|
+
Send
|
|
63
|
+
</button>
|
|
64
|
+
<button onClick={() => agent.stop()}>Stop</button>
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Chat history with `useChatStorage`
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
import { useChatStorage, useHsafaAgent } from '@hsafa/ui-sdk';
|
|
74
|
+
|
|
75
|
+
export function ChatWithHistory() {
|
|
76
|
+
const agent = useHsafaAgent({ agentId: 'my-agent', baseUrl: '' });
|
|
77
|
+
const storage = useChatStorage({
|
|
78
|
+
agentId: 'my-agent',
|
|
79
|
+
chatId: agent.chatId,
|
|
80
|
+
messages: agent.messages,
|
|
81
|
+
isLoading: agent.isLoading,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<div style={{ display: 'flex', gap: 16 }}>
|
|
86
|
+
<aside>
|
|
87
|
+
{storage.chatList.map((c) => (
|
|
88
|
+
<div key={c.id}>
|
|
89
|
+
<button onClick={() => storage.switchToChat(c.id, agent.setMessages)}>{c.title}</button>
|
|
90
|
+
</div>
|
|
91
|
+
))}
|
|
92
|
+
</aside>
|
|
93
|
+
<main style={{ flex: 1 }}>
|
|
94
|
+
{/* ... render your UI, inputs, etc. ... */}
|
|
95
|
+
</main>
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Dynamic page tools enabled
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
import { HsafaProvider, HsafaChat } from '@hsafa/ui-sdk';
|
|
105
|
+
import type { DynamicPageTypeConfig } from '@hsafa/ui-sdk';
|
|
106
|
+
|
|
107
|
+
const types: DynamicPageTypeConfig[] = [
|
|
108
|
+
// your type configs here
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
export default function Page() {
|
|
112
|
+
return (
|
|
113
|
+
<HsafaProvider baseUrl="">
|
|
114
|
+
<HsafaChat agentId="dp-agent" dynamicPageTypes={types} />
|
|
115
|
+
</HsafaProvider>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## File uploads
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
import { useFileUploadHook } from '@hsafa/ui-sdk';
|
|
124
|
+
|
|
125
|
+
function Uploader() {
|
|
126
|
+
const { attachments, uploading, fileInputRef, handleFileSelection, handleRemoveAttachment } = useFileUploadHook('');
|
|
127
|
+
return (
|
|
128
|
+
<div>
|
|
129
|
+
<input ref={fileInputRef} type="file" multiple onChange={(e) => handleFileSelection(e.target.files, () => {})} />
|
|
130
|
+
{uploading ? 'Uploading...' : null}
|
|
131
|
+
<ul>
|
|
132
|
+
{attachments.map((a) => (
|
|
133
|
+
<li key={a.id}>
|
|
134
|
+
{a.name} <button onClick={() => handleRemoveAttachment(a.id)}>x</button>
|
|
135
|
+
</li>
|
|
136
|
+
))}
|
|
137
|
+
</ul>
|
|
138
|
+
</div>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Server route (Next.js edge)
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
// app/api/run/[id]/route.ts
|
|
147
|
+
import { NextRequest } from 'next/server';
|
|
148
|
+
import { handleRunAgentRequest } from '@/server/src/modules/agents/run-agent-handler';
|
|
149
|
+
|
|
150
|
+
export const runtime = 'edge';
|
|
151
|
+
export async function POST(req: NextRequest, { params }: { params: { id: string } }) {
|
|
152
|
+
return handleRunAgentRequest(req as any, { params } as any);
|
|
153
|
+
}
|
|
154
|
+
```
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# 11 — API Reference Map
|
|
2
|
+
|
|
3
|
+
Use this as a directory to the TypeDoc API and key source files.
|
|
4
|
+
|
|
5
|
+
## TypeDoc (generated)
|
|
6
|
+
|
|
7
|
+
- `sdk/docs/api/README.md` (entry)
|
|
8
|
+
- Common pages:
|
|
9
|
+
- `sdk/docs/api/functions/HsafaChat.md`
|
|
10
|
+
- `sdk/docs/api/functions/HsafaProvider.md`
|
|
11
|
+
- `sdk/docs/api/functions/useHsafaAgent.md`
|
|
12
|
+
- `sdk/docs/api/functions/useChatStorage.md`
|
|
13
|
+
- `sdk/docs/api/functions/useFileUploadHook.md`
|
|
14
|
+
|
|
15
|
+
## Source references
|
|
16
|
+
|
|
17
|
+
- Provider: `sdk/src/providers/HsafaProvider.tsx`
|
|
18
|
+
- Chat component: `sdk/src/components/HsafaChat.tsx`
|
|
19
|
+
- Hooks:
|
|
20
|
+
- `sdk/src/hooks/useHsafaAgent.ts`
|
|
21
|
+
- `sdk/src/hooks/useChatStorage.ts`
|
|
22
|
+
- `sdk/src/hooks/useFileUploadHook.ts`
|
|
23
|
+
- `sdk/src/hooks/useMessageEditor.ts`
|
|
24
|
+
- `sdk/src/hooks/useAutoScroll.ts`
|
|
25
|
+
- Tools & UI:
|
|
26
|
+
- `sdk/src/components/hsafa-chat/utils/transport.ts`
|
|
27
|
+
- `sdk/src/components/hsafa-chat/utils/builtInTools.ts`
|
|
28
|
+
- `sdk/src/components/hsafa-chat/utils/builtInUI.tsx`
|
|
29
|
+
- `sdk/src/components/hsafa-chat/utils/renderUserForm.ts`
|
|
30
|
+
- `sdk/src/components/hsafa-chat/hooks/useStreamingToolInput.ts`
|
|
31
|
+
- Dynamic pages:
|
|
32
|
+
- `sdk/src/components/dynamic-page/DynamicPage.tsx`
|
|
33
|
+
- `sdk/src/components/dynamic-page/useDynamicPage.ts`
|
|
34
|
+
- `sdk/src/components/dynamic-page/tools.ts`
|
|
35
|
+
- `sdk/src/components/dynamic-page/operations.ts`
|
|
36
|
+
- `sdk/src/components/dynamic-page/storage.ts`
|
|
37
|
+
- `sdk/src/components/dynamic-page/types.ts`
|
|
38
|
+
- Types:
|
|
39
|
+
- `sdk/src/types/chat.ts`
|
|
40
|
+
- `sdk/src/types/messages.ts`
|
|
41
|
+
|
|
42
|
+
## Related server code
|
|
43
|
+
|
|
44
|
+
- Server entry: `server/src/modules/agents/run-agent-handler.ts`
|
|
45
|
+
- Server core: `server/src/modules/agents/run-core/*`
|
|
46
|
+
- Agent CRUD: `server/src/modules/agents/agent-service.ts`
|
|
47
|
+
|
|
48
|
+
See also the high-level guide: `sdk/docs/README.md`.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Hsafa UI SDK Handbook
|
|
2
|
+
|
|
3
|
+
This handbook consolidates everything you need to use, extend, and integrate the Hsafa UI SDK across the client and server.
|
|
4
|
+
|
|
5
|
+
- Audience: Frontend engineers, full‑stack engineers, and integrators
|
|
6
|
+
- Scope: SDK architecture, APIs, hooks, tools, dynamic pages, persistence, transport, server contract, and examples
|
|
7
|
+
- Related: `sdk/docs/README.md` (Advanced Guide), `sdk/docs/api/` (TypeDoc)
|
|
8
|
+
|
|
9
|
+
## Contents
|
|
10
|
+
|
|
11
|
+
- 00-Overview.md — high-level architecture and repository map
|
|
12
|
+
- 01-Quickstart.md — install and minimal setup (UI and headless)
|
|
13
|
+
- 02-Architecture.md — layers, flows, and data contracts
|
|
14
|
+
- 03-Components-and-Hooks.md — exported components/types/hooks with usage
|
|
15
|
+
- 04-Streaming-and-Transport.md — Vercel AI SDK v5, tool calls, UI stream
|
|
16
|
+
- 05-Tools-and-UI.md — built-in tools and registering custom UI/actions
|
|
17
|
+
- 06-Storage-and-History.md — local persistence and history management
|
|
18
|
+
- 07-Dynamic-Pages.md — dynamic page system, tools, and storage
|
|
19
|
+
- 08-Server-Integration.md — `/api/run/:agentId`, run-core, and MCP/tools
|
|
20
|
+
- 09-Agent-Studio-Client.md — client Agent Studio overview and relation
|
|
21
|
+
- 10-Examples-and-Recipes.md — common tasks and full snippets
|
|
22
|
+
- 11-API-Reference-Map.md — pointers to TypeDoc and source files
|
|
23
|
+
|
|
24
|
+
If something is missing, open an issue or PR with suggested additions.
|