@deltakit/react 0.1.0 → 0.1.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 +144 -0
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# @deltakit/react
|
|
2
|
+
|
|
3
|
+
React hook for building streaming chat UIs over Server-Sent Events (SSE). Manages the entire lifecycle -- state, network requests, SSE parsing, cancellation, and event handling -- in a single `useStreamChat` hook.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @deltakit/react
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Requires React 18+ and a backend endpoint that streams SSE.
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { useStreamChat } from "@deltakit/react";
|
|
17
|
+
|
|
18
|
+
function Chat() {
|
|
19
|
+
const { messages, isLoading, sendMessage } = useStreamChat({
|
|
20
|
+
api: "/api/chat",
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div>
|
|
25
|
+
{messages.map((msg) => (
|
|
26
|
+
<div key={msg.id}>
|
|
27
|
+
<strong>{msg.role}:</strong>{" "}
|
|
28
|
+
{msg.parts
|
|
29
|
+
.filter((p) => p.type === "text")
|
|
30
|
+
.map((p) => p.text)
|
|
31
|
+
.join("")}
|
|
32
|
+
</div>
|
|
33
|
+
))}
|
|
34
|
+
|
|
35
|
+
{isLoading && <span>Thinking...</span>}
|
|
36
|
+
|
|
37
|
+
<form
|
|
38
|
+
onSubmit={(e) => {
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
const input = e.currentTarget.elements.namedItem("message") as HTMLInputElement;
|
|
41
|
+
sendMessage(input.value);
|
|
42
|
+
input.value = "";
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
<input name="message" placeholder="Type a message..." />
|
|
46
|
+
<button type="submit" disabled={isLoading}>Send</button>
|
|
47
|
+
</form>
|
|
48
|
+
</div>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## API
|
|
54
|
+
|
|
55
|
+
### `useStreamChat(options)`
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
const {
|
|
59
|
+
messages, // Message[] -- live-updating conversation
|
|
60
|
+
isLoading, // boolean -- true while streaming
|
|
61
|
+
error, // Error | null -- latest error
|
|
62
|
+
sendMessage, // (text: string) => void -- send and start streaming
|
|
63
|
+
stop, // () => void -- abort current stream
|
|
64
|
+
setMessages, // React setState -- direct state control
|
|
65
|
+
} = useStreamChat({
|
|
66
|
+
api: "/api/chat", // Required. SSE endpoint URL
|
|
67
|
+
initialMessages: [], // Pre-populate conversation (e.g. from DB)
|
|
68
|
+
headers: {}, // Extra fetch headers (e.g. Authorization)
|
|
69
|
+
body: {}, // Extra POST body fields
|
|
70
|
+
onEvent: (event, helpers) => {}, // Custom event handler (replaces default)
|
|
71
|
+
onFinish: (messages) => {}, // Stream ended
|
|
72
|
+
onMessage: (message) => {}, // New message added
|
|
73
|
+
onError: (error) => {}, // Fetch/stream error
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Event Helpers
|
|
78
|
+
|
|
79
|
+
When using `onEvent`, you receive helpers for mutating message state during streaming:
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
onEvent: (event, { appendText, appendPart, setMessages }) => {
|
|
83
|
+
switch (event.type) {
|
|
84
|
+
case "text_delta":
|
|
85
|
+
appendText(event.delta);
|
|
86
|
+
break;
|
|
87
|
+
case "tool_call":
|
|
88
|
+
appendPart({
|
|
89
|
+
type: "tool_call",
|
|
90
|
+
tool_name: event.tool_name,
|
|
91
|
+
argument: event.argument,
|
|
92
|
+
callId: event.call_id,
|
|
93
|
+
});
|
|
94
|
+
break;
|
|
95
|
+
case "tool_result":
|
|
96
|
+
// Use setMessages for complex mutations
|
|
97
|
+
setMessages((prev) =>
|
|
98
|
+
prev.map((msg) => ({
|
|
99
|
+
...msg,
|
|
100
|
+
parts: msg.parts.map((p) =>
|
|
101
|
+
p.type === "tool_call" && p.callId === event.call_id
|
|
102
|
+
? { ...p, result: event.output }
|
|
103
|
+
: p
|
|
104
|
+
),
|
|
105
|
+
}))
|
|
106
|
+
);
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Custom Content Parts
|
|
113
|
+
|
|
114
|
+
Extend with custom types using generics:
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
type ImagePart = { type: "image"; url: string };
|
|
118
|
+
type MyPart = ContentPart | ImagePart;
|
|
119
|
+
|
|
120
|
+
const { messages } = useStreamChat<MyPart>({
|
|
121
|
+
api: "/api/chat",
|
|
122
|
+
onEvent: (event, { appendPart }) => {
|
|
123
|
+
if (event.type === "image") {
|
|
124
|
+
appendPart({ type: "image", url: event.url });
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Re-exports from `@deltakit/core`
|
|
131
|
+
|
|
132
|
+
This package re-exports everything from `@deltakit/core`, so you only need one import:
|
|
133
|
+
|
|
134
|
+
- `parseSSEStream` -- SSE stream parser
|
|
135
|
+
- `fromOpenAiAgents` -- OpenAI Agents SDK history converter
|
|
136
|
+
- All types: `Message`, `ContentPart`, `TextPart`, `ToolCallPart`, `ReasoningPart`, `SSEEvent`, `TextDeltaEvent`, `ToolCallEvent`, `ToolResultEvent`
|
|
137
|
+
|
|
138
|
+
## Documentation
|
|
139
|
+
|
|
140
|
+
Full documentation, guides, and examples at [deltakit.dev](https://deltakit.dev).
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deltakit/react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "DeltaKit React bindings",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"dist"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@deltakit/core": "0.1.
|
|
31
|
+
"@deltakit/core": "0.1.1"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/react": "^18.3.18",
|