veryfront 0.0.68 → 0.0.69
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/dist/ai/components.js +12 -8
- package/dist/ai/components.js.map +2 -2
- package/dist/ai/dev.js +9 -3
- package/dist/ai/dev.js.map +1 -1
- package/dist/ai/index.js +3028 -3019
- package/dist/ai/index.js.map +4 -4
- package/dist/ai/production.js +14 -20
- package/dist/ai/production.js.map +1 -1
- package/dist/ai/react.js +242 -91
- package/dist/ai/react.js.map +2 -2
- package/dist/ai/workflow.js +34 -48
- package/dist/ai/workflow.js.map +1 -1
- package/dist/cli.js +1013 -609
- package/dist/components.js +4119 -251
- package/dist/components.js.map +4 -4
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/data.js +21 -26
- package/dist/data.js.map +1 -1
- package/dist/index.js +4163 -292
- package/dist/index.js.map +4 -4
- package/dist/oauth/handlers.js +6 -7
- package/dist/oauth/handlers.js.map +1 -1
- package/dist/oauth/index.js +6 -7
- package/dist/oauth/index.js.map +1 -1
- package/dist/oauth/providers.js +0 -3
- package/dist/oauth/providers.js.map +1 -1
- package/dist/oauth/token-store.js +6 -4
- package/dist/oauth/token-store.js.map +1 -1
- package/package.json +2 -2
package/dist/ai/react.js
CHANGED
|
@@ -47,12 +47,32 @@ function useChat(options) {
|
|
|
47
47
|
const [error, setError] = useState(null);
|
|
48
48
|
const [data, setData] = useState(null);
|
|
49
49
|
const abortControllerRef = useRef(null);
|
|
50
|
-
const
|
|
50
|
+
const pendingToolOutputsRef = useRef(/* @__PURE__ */ new Map());
|
|
51
|
+
const addToolOutput = useCallback((output) => {
|
|
52
|
+
pendingToolOutputsRef.current.set(output.toolCallId, output);
|
|
53
|
+
setMessages(
|
|
54
|
+
(prev) => prev.map((msg) => ({
|
|
55
|
+
...msg,
|
|
56
|
+
parts: msg.parts.map((part) => {
|
|
57
|
+
if (part.type === "tool-call" && part.toolCallId === output.toolCallId) {
|
|
58
|
+
return {
|
|
59
|
+
...part,
|
|
60
|
+
state: output.state || "output-available",
|
|
61
|
+
output: output.output,
|
|
62
|
+
errorText: output.errorText
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return part;
|
|
66
|
+
})
|
|
67
|
+
}))
|
|
68
|
+
);
|
|
69
|
+
}, []);
|
|
70
|
+
const sendMessage = useCallback(
|
|
51
71
|
async (message) => {
|
|
52
72
|
const userMessage = {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
73
|
+
id: generateClientId("msg"),
|
|
74
|
+
role: "user",
|
|
75
|
+
parts: [{ type: "text", text: message.text }]
|
|
56
76
|
};
|
|
57
77
|
setMessages((prev) => [...prev, userMessage]);
|
|
58
78
|
setIsLoading(true);
|
|
@@ -79,62 +99,43 @@ function useChat(options) {
|
|
|
79
99
|
message: `API error: ${response.status}`
|
|
80
100
|
}));
|
|
81
101
|
}
|
|
82
|
-
|
|
83
|
-
options.onResponse(response);
|
|
84
|
-
}
|
|
102
|
+
options.onResponse?.(response);
|
|
85
103
|
if (response.body) {
|
|
86
|
-
const streamingMessageId =
|
|
104
|
+
const streamingMessageId = generateClientId("msg");
|
|
87
105
|
let hasAddedStreamingMessage = false;
|
|
88
|
-
await handleStreamingResponse(
|
|
89
|
-
|
|
90
|
-
// onMessage - when streaming is complete
|
|
91
|
-
(assistantMessage) => {
|
|
106
|
+
await handleStreamingResponse(response.body, {
|
|
107
|
+
onMessage: (assistantMessage) => {
|
|
92
108
|
setMessages((prev) => {
|
|
93
109
|
if (hasAddedStreamingMessage) {
|
|
94
110
|
return prev.map((m) => m.id === streamingMessageId ? assistantMessage : m);
|
|
95
111
|
}
|
|
96
112
|
return [...prev, assistantMessage];
|
|
97
113
|
});
|
|
98
|
-
|
|
99
|
-
options.onFinish(assistantMessage);
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
// onData - for data events
|
|
103
|
-
(partialData) => {
|
|
104
|
-
setData(partialData);
|
|
114
|
+
options.onFinish?.(assistantMessage);
|
|
105
115
|
},
|
|
106
|
-
|
|
107
|
-
(
|
|
116
|
+
onData: setData,
|
|
117
|
+
onUpdate: (parts, messageId) => {
|
|
118
|
+
const id = messageId || streamingMessageId;
|
|
108
119
|
if (!hasAddedStreamingMessage) {
|
|
109
120
|
hasAddedStreamingMessage = true;
|
|
110
|
-
setMessages((prev) => [
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
content: partialContent,
|
|
116
|
-
timestamp: Date.now()
|
|
117
|
-
}
|
|
118
|
-
]);
|
|
121
|
+
setMessages((prev) => [...prev, {
|
|
122
|
+
id,
|
|
123
|
+
role: "assistant",
|
|
124
|
+
parts
|
|
125
|
+
}]);
|
|
119
126
|
} else {
|
|
120
|
-
setMessages(
|
|
121
|
-
(prev) => prev.map(
|
|
122
|
-
(m) => m.id === (messageId || streamingMessageId) ? { ...m, content: partialContent } : m
|
|
123
|
-
)
|
|
124
|
-
);
|
|
127
|
+
setMessages((prev) => prev.map((m) => m.id === id ? { ...m, parts } : m));
|
|
125
128
|
}
|
|
126
|
-
}
|
|
127
|
-
|
|
129
|
+
},
|
|
130
|
+
onToolCall: options.onToolCall
|
|
131
|
+
});
|
|
128
132
|
}
|
|
129
133
|
} catch (err) {
|
|
130
|
-
if (err instanceof Error && err.name === "AbortError")
|
|
134
|
+
if (err instanceof Error && err.name === "AbortError")
|
|
131
135
|
return;
|
|
132
|
-
}
|
|
133
136
|
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
134
137
|
setError(error2);
|
|
135
|
-
|
|
136
|
-
options.onError(error2);
|
|
137
|
-
}
|
|
138
|
+
options.onError?.(error2);
|
|
138
139
|
} finally {
|
|
139
140
|
setIsLoading(false);
|
|
140
141
|
abortControllerRef.current = null;
|
|
@@ -145,19 +146,18 @@ function useChat(options) {
|
|
|
145
146
|
const reload = useCallback(async () => {
|
|
146
147
|
if (messages.length === 0)
|
|
147
148
|
return;
|
|
148
|
-
const
|
|
149
|
-
if (
|
|
149
|
+
const lastUserIndex = messages.findLastIndex((m) => m.role === "user");
|
|
150
|
+
if (lastUserIndex === -1)
|
|
150
151
|
return;
|
|
151
|
-
const
|
|
152
|
-
const lastUserMessage = messages[lastUserMessageIndex];
|
|
152
|
+
const lastUserMessage = messages[lastUserIndex];
|
|
153
153
|
if (!lastUserMessage)
|
|
154
154
|
return;
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
});
|
|
160
|
-
}, [messages,
|
|
155
|
+
const textPart = lastUserMessage.parts.find((p) => p.type === "text");
|
|
156
|
+
if (!textPart)
|
|
157
|
+
return;
|
|
158
|
+
setMessages(messages.slice(0, lastUserIndex));
|
|
159
|
+
await sendMessage({ text: textPart.text });
|
|
160
|
+
}, [messages, sendMessage]);
|
|
161
161
|
const stop = useCallback(() => {
|
|
162
162
|
if (abortControllerRef.current) {
|
|
163
163
|
abortControllerRef.current.abort();
|
|
@@ -176,14 +176,11 @@ function useChat(options) {
|
|
|
176
176
|
e.preventDefault();
|
|
177
177
|
if (!input.trim() || isLoading)
|
|
178
178
|
return;
|
|
179
|
-
const
|
|
179
|
+
const text = input;
|
|
180
180
|
setInput("");
|
|
181
|
-
await
|
|
182
|
-
role: "user",
|
|
183
|
-
content: messageContent
|
|
184
|
-
});
|
|
181
|
+
await sendMessage({ text });
|
|
185
182
|
},
|
|
186
|
-
[input, isLoading,
|
|
183
|
+
[input, isLoading, sendMessage]
|
|
187
184
|
);
|
|
188
185
|
return {
|
|
189
186
|
messages,
|
|
@@ -191,20 +188,52 @@ function useChat(options) {
|
|
|
191
188
|
isLoading,
|
|
192
189
|
error,
|
|
193
190
|
setInput,
|
|
194
|
-
|
|
191
|
+
sendMessage,
|
|
195
192
|
reload,
|
|
196
193
|
stop,
|
|
197
194
|
setMessages,
|
|
195
|
+
addToolOutput,
|
|
198
196
|
data,
|
|
199
197
|
handleInputChange,
|
|
200
198
|
handleSubmit
|
|
201
199
|
};
|
|
202
200
|
}
|
|
203
|
-
async function handleStreamingResponse(body,
|
|
201
|
+
async function handleStreamingResponse(body, callbacks) {
|
|
202
|
+
const { onMessage, onData, onUpdate, onToolCall } = callbacks;
|
|
204
203
|
const reader = body.getReader();
|
|
205
204
|
const decoder = new TextDecoder();
|
|
206
|
-
|
|
207
|
-
let
|
|
205
|
+
const textBlocks = /* @__PURE__ */ new Map();
|
|
206
|
+
let currentTextId = "";
|
|
207
|
+
let messageId = "";
|
|
208
|
+
const toolCalls = /* @__PURE__ */ new Map();
|
|
209
|
+
const reasoningBlocks = /* @__PURE__ */ new Map();
|
|
210
|
+
const messageParts = [];
|
|
211
|
+
const buildCurrentParts = () => {
|
|
212
|
+
const parts = [];
|
|
213
|
+
for (const [, block] of textBlocks) {
|
|
214
|
+
if (block.text) {
|
|
215
|
+
parts.push({ type: "text", text: block.text, state: block.state });
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
for (const [, reasoning] of reasoningBlocks) {
|
|
219
|
+
parts.push({
|
|
220
|
+
type: "reasoning",
|
|
221
|
+
text: reasoning.text,
|
|
222
|
+
state: reasoning.isComplete ? "done" : "streaming"
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
for (const [, tool] of toolCalls) {
|
|
226
|
+
parts.push({
|
|
227
|
+
type: "tool-call",
|
|
228
|
+
toolCallId: tool.toolCallId,
|
|
229
|
+
toolName: tool.toolName,
|
|
230
|
+
state: tool.state,
|
|
231
|
+
input: tool.input,
|
|
232
|
+
output: tool.output
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
return parts;
|
|
236
|
+
};
|
|
208
237
|
while (true) {
|
|
209
238
|
const { done, value } = await reader.read();
|
|
210
239
|
if (done) {
|
|
@@ -215,40 +244,152 @@ async function handleStreamingResponse(body, onMessage, onData, onUpdate) {
|
|
|
215
244
|
for (const line of lines) {
|
|
216
245
|
if (line.startsWith("data: ")) {
|
|
217
246
|
const data = line.slice(6);
|
|
218
|
-
if (data === "[DONE]") {
|
|
219
|
-
if (accumulatedText) {
|
|
220
|
-
const assistantMessage = {
|
|
221
|
-
id: messageId,
|
|
222
|
-
role: "assistant",
|
|
223
|
-
content: accumulatedText,
|
|
224
|
-
timestamp: Date.now()
|
|
225
|
-
};
|
|
226
|
-
onMessage(assistantMessage);
|
|
227
|
-
}
|
|
228
|
-
continue;
|
|
229
|
-
}
|
|
230
247
|
try {
|
|
231
248
|
const parsed = JSON.parse(data);
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
249
|
+
switch (parsed.type) {
|
|
250
|
+
case "start":
|
|
251
|
+
messageId = parsed.messageId || generateClientId("msg");
|
|
252
|
+
textBlocks.clear();
|
|
253
|
+
toolCalls.clear();
|
|
254
|
+
reasoningBlocks.clear();
|
|
255
|
+
messageParts.length = 0;
|
|
256
|
+
break;
|
|
257
|
+
case "start-step":
|
|
258
|
+
break;
|
|
259
|
+
case "finish-step":
|
|
260
|
+
break;
|
|
261
|
+
case "text-start":
|
|
262
|
+
currentTextId = parsed.id || generateClientId("text");
|
|
263
|
+
textBlocks.set(currentTextId, { text: "", state: "streaming" });
|
|
264
|
+
break;
|
|
265
|
+
case "text-delta": {
|
|
266
|
+
const textId = parsed.id || currentTextId || "default";
|
|
267
|
+
const delta = parsed.delta || "";
|
|
268
|
+
if (!textBlocks.has(textId)) {
|
|
269
|
+
textBlocks.set(textId, { text: "", state: "streaming" });
|
|
270
|
+
currentTextId = textId;
|
|
271
|
+
}
|
|
272
|
+
const block = textBlocks.get(textId);
|
|
273
|
+
block.text += delta;
|
|
274
|
+
onUpdate?.(buildCurrentParts(), messageId);
|
|
275
|
+
break;
|
|
241
276
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
277
|
+
case "text-end": {
|
|
278
|
+
const textId = parsed.id || currentTextId;
|
|
279
|
+
const block = textBlocks.get(textId);
|
|
280
|
+
if (block) {
|
|
281
|
+
block.state = "done";
|
|
282
|
+
if (block.text) {
|
|
283
|
+
messageParts.push({ type: "text", text: block.text, state: "done" });
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
case "tool-input-start": {
|
|
289
|
+
const toolCallId = parsed.toolCallId || generateClientId("tool");
|
|
290
|
+
const toolCall = {
|
|
291
|
+
toolCallId,
|
|
292
|
+
toolName: parsed.toolName || "unknown",
|
|
293
|
+
inputText: "",
|
|
294
|
+
state: "input-streaming"
|
|
249
295
|
};
|
|
250
|
-
|
|
296
|
+
toolCalls.set(toolCallId, toolCall);
|
|
297
|
+
onUpdate?.(buildCurrentParts(), messageId);
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
case "tool-input-delta": {
|
|
301
|
+
const toolCallId = parsed.toolCallId;
|
|
302
|
+
const toolCall = toolCalls.get(toolCallId);
|
|
303
|
+
if (toolCall) {
|
|
304
|
+
toolCall.inputText += parsed.inputTextDelta || parsed.delta || "";
|
|
305
|
+
onUpdate?.(buildCurrentParts(), messageId);
|
|
306
|
+
}
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
case "tool-input-available": {
|
|
310
|
+
const toolCallId = parsed.toolCallId;
|
|
311
|
+
const toolCall = toolCalls.get(toolCallId);
|
|
312
|
+
if (toolCall) {
|
|
313
|
+
toolCall.input = parsed.input;
|
|
314
|
+
toolCall.toolName = parsed.toolName || toolCall.toolName;
|
|
315
|
+
toolCall.state = "input-available";
|
|
316
|
+
onToolCall?.({
|
|
317
|
+
toolCall: {
|
|
318
|
+
toolCallId,
|
|
319
|
+
toolName: toolCall.toolName,
|
|
320
|
+
input: toolCall.input
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
messageParts.push({
|
|
324
|
+
type: "tool-call",
|
|
325
|
+
toolCallId,
|
|
326
|
+
toolName: toolCall.toolName,
|
|
327
|
+
state: "input-available",
|
|
328
|
+
input: toolCall.input
|
|
329
|
+
});
|
|
330
|
+
onUpdate?.(buildCurrentParts(), messageId);
|
|
331
|
+
}
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
case "tool-output-available": {
|
|
335
|
+
const toolCallId = parsed.toolCallId;
|
|
336
|
+
const toolCall = toolCalls.get(toolCallId);
|
|
337
|
+
if (toolCall) {
|
|
338
|
+
toolCall.output = parsed.output;
|
|
339
|
+
toolCall.state = "output-available";
|
|
340
|
+
messageParts.push({
|
|
341
|
+
type: "tool-result",
|
|
342
|
+
toolCallId,
|
|
343
|
+
toolName: toolCall.toolName,
|
|
344
|
+
result: toolCall.output
|
|
345
|
+
});
|
|
346
|
+
onUpdate?.(buildCurrentParts(), messageId);
|
|
347
|
+
}
|
|
348
|
+
break;
|
|
251
349
|
}
|
|
350
|
+
case "reasoning-start": {
|
|
351
|
+
const reasoningId = parsed.id || generateClientId("reasoning");
|
|
352
|
+
const reasoning = {
|
|
353
|
+
id: reasoningId,
|
|
354
|
+
text: "",
|
|
355
|
+
isComplete: false
|
|
356
|
+
};
|
|
357
|
+
reasoningBlocks.set(reasoningId, reasoning);
|
|
358
|
+
onUpdate?.(buildCurrentParts(), messageId);
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
case "reasoning-delta": {
|
|
362
|
+
const reasoningId = parsed.id;
|
|
363
|
+
const reasoning = reasoningBlocks.get(reasoningId);
|
|
364
|
+
if (reasoning) {
|
|
365
|
+
reasoning.text += parsed.delta || "";
|
|
366
|
+
onUpdate?.(buildCurrentParts(), messageId);
|
|
367
|
+
}
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
case "reasoning-end": {
|
|
371
|
+
const reasoningId = parsed.id;
|
|
372
|
+
const reasoning = reasoningBlocks.get(reasoningId);
|
|
373
|
+
if (reasoning) {
|
|
374
|
+
reasoning.isComplete = true;
|
|
375
|
+
messageParts.push({
|
|
376
|
+
type: "reasoning",
|
|
377
|
+
text: reasoning.text,
|
|
378
|
+
state: "done"
|
|
379
|
+
});
|
|
380
|
+
onUpdate?.(buildCurrentParts(), messageId);
|
|
381
|
+
}
|
|
382
|
+
break;
|
|
383
|
+
}
|
|
384
|
+
case "finish": {
|
|
385
|
+
if (messageParts.length > 0 || textBlocks.size > 0) {
|
|
386
|
+
onMessage(createAssistantMessage(messageId, messageParts));
|
|
387
|
+
}
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
case "data":
|
|
391
|
+
onData(parsed.data || parsed.value);
|
|
392
|
+
break;
|
|
252
393
|
}
|
|
253
394
|
} catch {
|
|
254
395
|
}
|
|
@@ -256,6 +397,16 @@ async function handleStreamingResponse(body, onMessage, onData, onUpdate) {
|
|
|
256
397
|
}
|
|
257
398
|
}
|
|
258
399
|
}
|
|
400
|
+
function createAssistantMessage(messageId, parts) {
|
|
401
|
+
return {
|
|
402
|
+
id: messageId || generateClientId("msg"),
|
|
403
|
+
role: "assistant",
|
|
404
|
+
parts
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
function generateClientId(prefix) {
|
|
408
|
+
return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
409
|
+
}
|
|
259
410
|
|
|
260
411
|
// src/ai/react/hooks/use-agent.ts
|
|
261
412
|
import { useCallback as useCallback2, useRef as useRef2, useState as useState2 } from "react";
|