@cogitator-ai/next 0.2.0
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 +369 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +4 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/retry.d.ts +3 -0
- package/dist/client/retry.d.ts.map +1 -0
- package/dist/client/retry.js +47 -0
- package/dist/client/retry.js.map +1 -0
- package/dist/client/sse-parser.d.ts +3 -0
- package/dist/client/sse-parser.d.ts.map +1 -0
- package/dist/client/sse-parser.js +39 -0
- package/dist/client/sse-parser.js.map +1 -0
- package/dist/client/use-agent.d.ts +3 -0
- package/dist/client/use-agent.d.ts.map +1 -0
- package/dist/client/use-agent.js +53 -0
- package/dist/client/use-agent.js.map +1 -0
- package/dist/client/use-chat-state.d.ts +52 -0
- package/dist/client/use-chat-state.d.ts.map +1 -0
- package/dist/client/use-chat-state.js +68 -0
- package/dist/client/use-chat-state.js.map +1 -0
- package/dist/client/use-chat.d.ts +3 -0
- package/dist/client/use-chat.d.ts.map +1 -0
- package/dist/client/use-chat.js +215 -0
- package/dist/client/use-chat.js.map +1 -0
- package/dist/handlers/agent.d.ts +4 -0
- package/dist/handlers/agent.d.ts.map +1 -0
- package/dist/handlers/agent.js +76 -0
- package/dist/handlers/agent.js.map +1 -0
- package/dist/handlers/chat.d.ts +4 -0
- package/dist/handlers/chat.d.ts.map +1 -0
- package/dist/handlers/chat.js +124 -0
- package/dist/handlers/chat.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/streaming/encoder.d.ts +4 -0
- package/dist/streaming/encoder.d.ts.map +1 -0
- package/dist/streaming/encoder.js +15 -0
- package/dist/streaming/encoder.js.map +1 -0
- package/dist/streaming/protocol.d.ts +64 -0
- package/dist/streaming/protocol.d.ts.map +1 -0
- package/dist/streaming/protocol.js +31 -0
- package/dist/streaming/protocol.js.map +1 -0
- package/dist/streaming/stream-writer.d.ts +19 -0
- package/dist/streaming/stream-writer.d.ts.map +1 -0
- package/dist/streaming/stream-writer.js +57 -0
- package/dist/streaming/stream-writer.js.map +1 -0
- package/dist/types.d.ts +97 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
# @cogitator-ai/next
|
|
2
|
+
|
|
3
|
+
Next.js App Router integration for Cogitator AI runtime. Provides streaming chat handlers and React hooks compatible with the Vercel AI SDK protocol.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @cogitator-ai/next @cogitator-ai/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### 1. Create API Route
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
// app/api/chat/route.ts
|
|
17
|
+
import { Cogitator, Agent, tool } from '@cogitator-ai/core';
|
|
18
|
+
import { createChatHandler } from '@cogitator-ai/next';
|
|
19
|
+
import { z } from 'zod';
|
|
20
|
+
|
|
21
|
+
const cogitator = new Cogitator({
|
|
22
|
+
backend: { type: 'openai', apiKey: process.env.OPENAI_API_KEY! },
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const agent = new Agent({
|
|
26
|
+
name: 'assistant',
|
|
27
|
+
instructions: 'You are a helpful assistant.',
|
|
28
|
+
tools: [
|
|
29
|
+
tool({
|
|
30
|
+
name: 'get_weather',
|
|
31
|
+
description: 'Get weather for a location',
|
|
32
|
+
parameters: z.object({ location: z.string() }),
|
|
33
|
+
execute: async ({ location }) => `Weather in ${location}: 72°F, sunny`,
|
|
34
|
+
}),
|
|
35
|
+
],
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export const POST = createChatHandler(cogitator, agent);
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 2. Use in Client Component
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
'use client';
|
|
45
|
+
|
|
46
|
+
import { useCogitatorChat } from '@cogitator-ai/next/client';
|
|
47
|
+
|
|
48
|
+
export function Chat() {
|
|
49
|
+
const { messages, input, setInput, send, isLoading } = useCogitatorChat({
|
|
50
|
+
api: '/api/chat',
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<div>
|
|
55
|
+
{messages.map((m) => (
|
|
56
|
+
<div key={m.id}>
|
|
57
|
+
<strong>{m.role}:</strong> {m.content}
|
|
58
|
+
</div>
|
|
59
|
+
))}
|
|
60
|
+
|
|
61
|
+
<form
|
|
62
|
+
onSubmit={(e) => {
|
|
63
|
+
e.preventDefault();
|
|
64
|
+
send();
|
|
65
|
+
}}
|
|
66
|
+
>
|
|
67
|
+
<input
|
|
68
|
+
value={input}
|
|
69
|
+
onChange={(e) => setInput(e.target.value)}
|
|
70
|
+
placeholder="Type a message..."
|
|
71
|
+
disabled={isLoading}
|
|
72
|
+
/>
|
|
73
|
+
<button type="submit" disabled={isLoading}>
|
|
74
|
+
Send
|
|
75
|
+
</button>
|
|
76
|
+
</form>
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Server Handlers
|
|
83
|
+
|
|
84
|
+
### `createChatHandler`
|
|
85
|
+
|
|
86
|
+
Creates a streaming chat handler compatible with AI SDK protocol.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { createChatHandler } from '@cogitator-ai/next';
|
|
90
|
+
|
|
91
|
+
export const POST = createChatHandler(cogitator, agent, {
|
|
92
|
+
// Custom input parsing
|
|
93
|
+
parseInput: async (req) => {
|
|
94
|
+
const body = await req.json();
|
|
95
|
+
return {
|
|
96
|
+
messages: body.messages,
|
|
97
|
+
threadId: body.threadId,
|
|
98
|
+
metadata: body.metadata,
|
|
99
|
+
};
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
// Pre-processing hook
|
|
103
|
+
beforeRun: async (req, input) => {
|
|
104
|
+
console.log('Starting chat with', input.messages.length, 'messages');
|
|
105
|
+
return { userId: 'user-123' }; // Merged into context
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
// Post-processing hook
|
|
109
|
+
afterRun: async (result) => {
|
|
110
|
+
console.log('Chat completed:', result.output);
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
// Request timeout
|
|
114
|
+
maxDuration: 30000,
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### `createAgentHandler`
|
|
119
|
+
|
|
120
|
+
Creates a batch (non-streaming) handler for long-running tasks.
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import { createAgentHandler } from '@cogitator-ai/next';
|
|
124
|
+
|
|
125
|
+
export const POST = createAgentHandler(cogitator, researchAgent, {
|
|
126
|
+
parseInput: async (req) => {
|
|
127
|
+
const body = await req.json();
|
|
128
|
+
return {
|
|
129
|
+
input: body.query,
|
|
130
|
+
context: body.context,
|
|
131
|
+
threadId: body.threadId,
|
|
132
|
+
};
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Response format:
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"output": "Research results...",
|
|
142
|
+
"threadId": "thread-abc",
|
|
143
|
+
"usage": {
|
|
144
|
+
"inputTokens": 150,
|
|
145
|
+
"outputTokens": 500,
|
|
146
|
+
"totalTokens": 650
|
|
147
|
+
},
|
|
148
|
+
"toolCalls": [...]
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Client Hooks
|
|
153
|
+
|
|
154
|
+
### `useCogitatorChat`
|
|
155
|
+
|
|
156
|
+
Full-featured chat hook with streaming support.
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
const {
|
|
160
|
+
// State
|
|
161
|
+
messages, // ChatMessage[]
|
|
162
|
+
input, // string
|
|
163
|
+
isLoading, // boolean
|
|
164
|
+
error, // Error | null
|
|
165
|
+
threadId, // string | undefined
|
|
166
|
+
|
|
167
|
+
// Actions
|
|
168
|
+
setInput, // (value: string) => void
|
|
169
|
+
send, // (input?: string, metadata?: Record<string, unknown>) => Promise<void>
|
|
170
|
+
stop, // () => void
|
|
171
|
+
reload, // () => Promise<void>
|
|
172
|
+
setThreadId, // (id: string) => void
|
|
173
|
+
|
|
174
|
+
// Message management
|
|
175
|
+
appendMessage, // (message: ChatMessage) => void
|
|
176
|
+
clearMessages, // () => void
|
|
177
|
+
setMessages, // (messages: ChatMessage[]) => void
|
|
178
|
+
} = useCogitatorChat({
|
|
179
|
+
api: '/api/chat',
|
|
180
|
+
threadId: 'optional-thread-id',
|
|
181
|
+
initialMessages: [],
|
|
182
|
+
headers: { 'X-Custom-Header': 'value' },
|
|
183
|
+
|
|
184
|
+
// Callbacks
|
|
185
|
+
onError: (error) => console.error(error),
|
|
186
|
+
onFinish: (message) => console.log('Done:', message),
|
|
187
|
+
onToolCall: (toolCall) => console.log('Tool called:', toolCall.name),
|
|
188
|
+
onToolResult: (result) => console.log('Tool result:', result),
|
|
189
|
+
|
|
190
|
+
// Retry configuration
|
|
191
|
+
retry: {
|
|
192
|
+
maxRetries: 3,
|
|
193
|
+
delay: 1000,
|
|
194
|
+
backoff: 'exponential', // 1s, 2s, 4s
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
#### Sending with Metadata
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
// Basic send
|
|
203
|
+
await send('Hello!');
|
|
204
|
+
|
|
205
|
+
// Send with metadata (passed to server)
|
|
206
|
+
await send('Analyze this', {
|
|
207
|
+
userId: 'user-123',
|
|
208
|
+
priority: 'high',
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Send using input state
|
|
212
|
+
setInput('My message');
|
|
213
|
+
await send();
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
#### Message Management
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
// Add a system message
|
|
220
|
+
appendMessage({
|
|
221
|
+
id: crypto.randomUUID(),
|
|
222
|
+
role: 'system',
|
|
223
|
+
content: 'Context updated.',
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// Clear conversation
|
|
227
|
+
clearMessages();
|
|
228
|
+
|
|
229
|
+
// Replace all messages
|
|
230
|
+
setMessages([{ id: '1', role: 'user', content: 'New conversation' }]);
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### `useCogitatorAgent`
|
|
234
|
+
|
|
235
|
+
Hook for non-streaming batch requests (research, analysis, etc).
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
const {
|
|
239
|
+
run, // (input: AgentInput) => Promise<void>
|
|
240
|
+
result, // AgentResponse | null
|
|
241
|
+
isLoading, // boolean
|
|
242
|
+
error, // Error | null
|
|
243
|
+
reset, // () => void
|
|
244
|
+
} = useCogitatorAgent({
|
|
245
|
+
api: '/api/research',
|
|
246
|
+
headers: { Authorization: 'Bearer token' },
|
|
247
|
+
|
|
248
|
+
onError: (error) => console.error(error),
|
|
249
|
+
onSuccess: (result) => console.log('Done:', result.output),
|
|
250
|
+
|
|
251
|
+
retry: {
|
|
252
|
+
maxRetries: 2,
|
|
253
|
+
delay: 2000,
|
|
254
|
+
backoff: 'linear',
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// Execute
|
|
259
|
+
await run({
|
|
260
|
+
input: 'Research AI trends in 2025',
|
|
261
|
+
context: { focus: 'enterprise' },
|
|
262
|
+
threadId: 'research-session-1',
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// Access result
|
|
266
|
+
console.log(result?.output);
|
|
267
|
+
console.log(result?.toolCalls);
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Streaming Protocol
|
|
271
|
+
|
|
272
|
+
The package implements Vercel AI SDK v5 streaming protocol:
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
0:{"type":"start","messageId":"msg-1"}
|
|
276
|
+
1:{"type":"text-start","id":"text-1"}
|
|
277
|
+
2:{"type":"text-delta","id":"text-1","delta":"Hello"}
|
|
278
|
+
2:{"type":"text-delta","id":"text-1","delta":" world"}
|
|
279
|
+
3:{"type":"text-end","id":"text-1"}
|
|
280
|
+
4:{"type":"tool-call-start","id":"tool-1","toolName":"get_weather"}
|
|
281
|
+
5:{"type":"tool-call-delta","id":"tool-1","argsText":"{\"location\":"}
|
|
282
|
+
5:{"type":"tool-call-delta","id":"tool-1","argsText":"\"NYC\"}"}
|
|
283
|
+
6:{"type":"tool-call-end","id":"tool-1"}
|
|
284
|
+
7:{"type":"tool-result","id":"tool-1","toolCallId":"tool-1","result":"72°F"}
|
|
285
|
+
8:{"type":"finish","messageId":"msg-1","usage":{...}}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Types
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
interface ChatMessage {
|
|
292
|
+
id: string;
|
|
293
|
+
role: 'user' | 'assistant' | 'system';
|
|
294
|
+
content: string;
|
|
295
|
+
toolCalls?: ToolCall[];
|
|
296
|
+
metadata?: Record<string, unknown>;
|
|
297
|
+
createdAt?: Date;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
interface AgentInput {
|
|
301
|
+
input: string;
|
|
302
|
+
context?: Record<string, unknown>;
|
|
303
|
+
threadId?: string;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
interface AgentResponse {
|
|
307
|
+
output: string;
|
|
308
|
+
threadId: string;
|
|
309
|
+
usage: {
|
|
310
|
+
inputTokens: number;
|
|
311
|
+
outputTokens: number;
|
|
312
|
+
totalTokens: number;
|
|
313
|
+
};
|
|
314
|
+
toolCalls: ToolCall[];
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
interface RetryConfig {
|
|
318
|
+
maxRetries?: number; // default: 0
|
|
319
|
+
delay?: number; // default: 1000ms
|
|
320
|
+
backoff?: 'linear' | 'exponential';
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Error Handling
|
|
325
|
+
|
|
326
|
+
Both hooks provide error state and callbacks:
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
const { error, isLoading } = useCogitatorChat({
|
|
330
|
+
api: '/api/chat',
|
|
331
|
+
onError: (err) => {
|
|
332
|
+
toast.error(err.message);
|
|
333
|
+
},
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
if (error) {
|
|
337
|
+
return <div>Error: {error.message}</div>;
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
With retry enabled, transient errors (network, 502/503/504) are automatically retried:
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
useCogitatorChat({
|
|
345
|
+
api: '/api/chat',
|
|
346
|
+
retry: {
|
|
347
|
+
maxRetries: 3,
|
|
348
|
+
delay: 1000,
|
|
349
|
+
backoff: 'exponential',
|
|
350
|
+
},
|
|
351
|
+
});
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## Cancellation
|
|
355
|
+
|
|
356
|
+
Stop ongoing requests with the `stop()` function:
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
const { send, stop, isLoading } = useCogitatorChat({ api: '/api/chat' });
|
|
360
|
+
|
|
361
|
+
// Cancel current request
|
|
362
|
+
if (isLoading) {
|
|
363
|
+
stop();
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## License
|
|
368
|
+
|
|
369
|
+
MIT
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { useCogitatorChat } from './use-chat.js';
|
|
2
|
+
export { useCogitatorAgent } from './use-agent.js';
|
|
3
|
+
export type { ChatMessage, ToolCall, UseChatOptions, UseChatReturn, AgentInput, AgentResponse, UseAgentOptions, UseAgentReturn, RetryConfig, ToolResultEvent, } from '../types.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,YAAY,EACV,WAAW,EACX,QAAQ,EACR,cAAc,EACd,aAAa,EACb,UAAU,EACV,aAAa,EACb,eAAe,EACf,cAAc,EACd,WAAW,EACX,eAAe,GAChB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/client/retry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA+B/C,wBAAsB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAoBzF"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const DEFAULT_RETRY_CONFIG = {
|
|
2
|
+
maxRetries: 0,
|
|
3
|
+
delay: 1000,
|
|
4
|
+
backoff: 'exponential',
|
|
5
|
+
};
|
|
6
|
+
function getDelay(attempt, config) {
|
|
7
|
+
if (config.backoff === 'linear') {
|
|
8
|
+
return config.delay * attempt;
|
|
9
|
+
}
|
|
10
|
+
return config.delay * Math.pow(2, attempt - 1);
|
|
11
|
+
}
|
|
12
|
+
function sleep(ms) {
|
|
13
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
14
|
+
}
|
|
15
|
+
function isRetryableError(error) {
|
|
16
|
+
if (error instanceof Error) {
|
|
17
|
+
if (error.name === 'AbortError')
|
|
18
|
+
return false;
|
|
19
|
+
const message = error.message.toLowerCase();
|
|
20
|
+
if (message.includes('network') || message.includes('fetch'))
|
|
21
|
+
return true;
|
|
22
|
+
if (message.includes('timeout'))
|
|
23
|
+
return true;
|
|
24
|
+
if (message.includes('502') || message.includes('503') || message.includes('504'))
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
export async function withRetry(fn, config) {
|
|
30
|
+
const cfg = { ...DEFAULT_RETRY_CONFIG, ...config };
|
|
31
|
+
let lastError;
|
|
32
|
+
for (let attempt = 0; attempt <= cfg.maxRetries; attempt++) {
|
|
33
|
+
try {
|
|
34
|
+
return await fn();
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
lastError = error;
|
|
38
|
+
if (attempt === cfg.maxRetries || !isRetryableError(error)) {
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
const delay = getDelay(attempt + 1, cfg);
|
|
42
|
+
await sleep(delay);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
throw lastError;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/client/retry.ts"],"names":[],"mappings":"AAEA,MAAM,oBAAoB,GAA0B;IAClD,UAAU,EAAE,CAAC;IACb,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,aAAa;CACvB,CAAC;AAEF,SAAS,QAAQ,CAAC,OAAe,EAAE,MAA6B;IAC9D,IAAI,MAAM,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC;IAChC,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,KAAK,CAAC;QAE9C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC5C,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1E,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC;QAC7C,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;IACjG,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,EAAoB,EAAE,MAAoB;IAC3E,MAAM,GAAG,GAAG,EAAE,GAAG,oBAAoB,EAAE,GAAG,MAAM,EAAE,CAAC;IAEnD,IAAI,SAAkB,CAAC;IACvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;QAC3D,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,GAAG,KAAK,CAAC;YAElB,IAAI,OAAO,KAAK,GAAG,CAAC,UAAU,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3D,MAAM,KAAK,CAAC;YACd,CAAC;YAED,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;YACzC,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,MAAM,SAAS,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse-parser.d.ts","sourceRoot":"","sources":["../../src/client/sse-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,wBAAuB,cAAc,CACnC,MAAM,EAAE,2BAA2B,CAAC,UAAU,CAAC,GAC9C,cAAc,CAAC,WAAW,CAAC,CAsC7B"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export async function* parseSSEStream(reader) {
|
|
2
|
+
const decoder = new TextDecoder();
|
|
3
|
+
let buffer = '';
|
|
4
|
+
while (true) {
|
|
5
|
+
const { done, value } = await reader.read();
|
|
6
|
+
if (done)
|
|
7
|
+
break;
|
|
8
|
+
buffer += decoder.decode(value, { stream: true });
|
|
9
|
+
const lines = buffer.split('\n');
|
|
10
|
+
buffer = lines.pop() ?? '';
|
|
11
|
+
for (const line of lines) {
|
|
12
|
+
const trimmed = line.trim();
|
|
13
|
+
if (!trimmed || trimmed.startsWith(':'))
|
|
14
|
+
continue;
|
|
15
|
+
if (trimmed.startsWith('data: ')) {
|
|
16
|
+
const data = trimmed.slice(6);
|
|
17
|
+
if (data === '[DONE]')
|
|
18
|
+
return;
|
|
19
|
+
try {
|
|
20
|
+
yield JSON.parse(data);
|
|
21
|
+
}
|
|
22
|
+
catch { }
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (buffer.trim()) {
|
|
27
|
+
const trimmed = buffer.trim();
|
|
28
|
+
if (trimmed.startsWith('data: ')) {
|
|
29
|
+
const data = trimmed.slice(6);
|
|
30
|
+
if (data !== '[DONE]') {
|
|
31
|
+
try {
|
|
32
|
+
yield JSON.parse(data);
|
|
33
|
+
}
|
|
34
|
+
catch { }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=sse-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse-parser.js","sourceRoot":"","sources":["../../src/client/sse-parser.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,cAAc,CACnC,MAA+C;IAE/C,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,IAAI;YAAE,MAAM;QAEhB,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;QAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YAElD,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC9B,IAAI,IAAI,KAAK,QAAQ;oBAAE,OAAO;gBAE9B,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAC;gBACxC,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QAClB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC9B,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAC;gBACxC,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-agent.d.ts","sourceRoot":"","sources":["../../src/client/use-agent.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAA6B,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG9F,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CAyD1E"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useState, useCallback } from 'react';
|
|
3
|
+
import { withRetry } from './retry.js';
|
|
4
|
+
export function useCogitatorAgent(options) {
|
|
5
|
+
const { api, headers, onError, onSuccess, retry } = options;
|
|
6
|
+
const [result, setResult] = useState(null);
|
|
7
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
8
|
+
const [error, setError] = useState(null);
|
|
9
|
+
const run = useCallback(async (input) => {
|
|
10
|
+
setIsLoading(true);
|
|
11
|
+
setError(null);
|
|
12
|
+
const executeRequest = async () => {
|
|
13
|
+
const response = await fetch(api, {
|
|
14
|
+
method: 'POST',
|
|
15
|
+
headers: {
|
|
16
|
+
'Content-Type': 'application/json',
|
|
17
|
+
...headers,
|
|
18
|
+
},
|
|
19
|
+
body: JSON.stringify(input),
|
|
20
|
+
});
|
|
21
|
+
if (!response.ok) {
|
|
22
|
+
const errorText = await response.text().catch(() => 'Unknown error');
|
|
23
|
+
throw new Error(`Request failed: ${response.status} - ${errorText}`);
|
|
24
|
+
}
|
|
25
|
+
return response.json();
|
|
26
|
+
};
|
|
27
|
+
try {
|
|
28
|
+
const data = await withRetry(executeRequest, retry);
|
|
29
|
+
setResult(data);
|
|
30
|
+
onSuccess?.(data);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
34
|
+
setError(e);
|
|
35
|
+
onError?.(e);
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
setIsLoading(false);
|
|
39
|
+
}
|
|
40
|
+
}, [api, headers, onError, onSuccess, retry]);
|
|
41
|
+
const reset = useCallback(() => {
|
|
42
|
+
setResult(null);
|
|
43
|
+
setError(null);
|
|
44
|
+
}, []);
|
|
45
|
+
return {
|
|
46
|
+
run,
|
|
47
|
+
result,
|
|
48
|
+
isLoading,
|
|
49
|
+
error,
|
|
50
|
+
reset,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=use-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-agent.js","sourceRoot":"","sources":["../../src/client/use-agent.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,UAAU,iBAAiB,CAAC,OAAwB;IACxD,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAE5D,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAuB,IAAI,CAAC,CAAC;IACjE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,MAAM,GAAG,GAAG,WAAW,CACrB,KAAK,EAAE,KAAiB,EAAiB,EAAE;QACzC,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEf,MAAM,cAAc,GAAG,KAAK,IAA4B,EAAE;YACxD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,GAAG,OAAO;iBACX;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;aAC5B,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC;gBACrE,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,CAAC,MAAM,MAAM,SAAS,EAAE,CAAC,CAAC;YACvE,CAAC;YAED,OAAO,QAAQ,CAAC,IAAI,EAA4B,CAAC;QACnD,CAAC,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;YACpD,SAAS,CAAC,IAAI,CAAC,CAAC;YAChB,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9D,QAAQ,CAAC,CAAC,CAAC,CAAC;YACZ,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QACf,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,EACD,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAC1C,CAAC;IAEF,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QAC7B,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO;QACL,GAAG;QACH,MAAM;QACN,SAAS;QACT,KAAK;QACL,KAAK;KACN,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ChatMessage, ToolCall } from '../types.js';
|
|
2
|
+
export interface ChatState {
|
|
3
|
+
messages: ChatMessage[];
|
|
4
|
+
input: string;
|
|
5
|
+
isLoading: boolean;
|
|
6
|
+
error: Error | null;
|
|
7
|
+
threadId: string | undefined;
|
|
8
|
+
currentMessageId: string | null;
|
|
9
|
+
currentContent: string;
|
|
10
|
+
currentToolCalls: ToolCall[];
|
|
11
|
+
}
|
|
12
|
+
export type ChatAction = {
|
|
13
|
+
type: 'SET_INPUT';
|
|
14
|
+
payload: string;
|
|
15
|
+
} | {
|
|
16
|
+
type: 'SET_THREAD_ID';
|
|
17
|
+
payload: string;
|
|
18
|
+
} | {
|
|
19
|
+
type: 'START_LOADING';
|
|
20
|
+
} | {
|
|
21
|
+
type: 'STOP_LOADING';
|
|
22
|
+
} | {
|
|
23
|
+
type: 'SET_ERROR';
|
|
24
|
+
payload: Error | null;
|
|
25
|
+
} | {
|
|
26
|
+
type: 'ADD_USER_MESSAGE';
|
|
27
|
+
payload: ChatMessage;
|
|
28
|
+
} | {
|
|
29
|
+
type: 'APPEND_MESSAGE';
|
|
30
|
+
payload: ChatMessage;
|
|
31
|
+
} | {
|
|
32
|
+
type: 'START_ASSISTANT_MESSAGE';
|
|
33
|
+
payload: string;
|
|
34
|
+
} | {
|
|
35
|
+
type: 'APPEND_CONTENT';
|
|
36
|
+
payload: string;
|
|
37
|
+
} | {
|
|
38
|
+
type: 'ADD_TOOL_CALL';
|
|
39
|
+
payload: ToolCall;
|
|
40
|
+
} | {
|
|
41
|
+
type: 'FINISH_ASSISTANT_MESSAGE';
|
|
42
|
+
} | {
|
|
43
|
+
type: 'REMOVE_LAST_MESSAGE';
|
|
44
|
+
} | {
|
|
45
|
+
type: 'SET_MESSAGES';
|
|
46
|
+
payload: ChatMessage[];
|
|
47
|
+
} | {
|
|
48
|
+
type: 'CLEAR_MESSAGES';
|
|
49
|
+
};
|
|
50
|
+
export declare function chatReducer(state: ChatState, action: ChatAction): ChatState;
|
|
51
|
+
export declare function createInitialState(initialMessages?: ChatMessage[], threadId?: string): ChatState;
|
|
52
|
+
//# sourceMappingURL=use-chat-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-chat-state.d.ts","sourceRoot":"","sources":["../../src/client/use-chat-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,QAAQ,EAAE,CAAC;CAC9B;AAED,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,KAAK,GAAG,IAAI,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,yBAAyB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,0BAA0B,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,qBAAqB,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,WAAW,EAAE,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE/B,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,CAqE3E;AAED,wBAAgB,kBAAkB,CAAC,eAAe,CAAC,EAAE,WAAW,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAWhG"}
|