veryfront 0.0.33 → 0.0.34
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/index.js +6 -2
- package/dist/ai/index.js.map +4 -4
- package/dist/ai/react.js +63 -12
- package/dist/ai/react.js.map +2 -2
- package/dist/cli.js +197 -18
- package/dist/components.js +4 -2
- package/dist/components.js.map +2 -2
- package/dist/config.js.map +1 -1
- package/dist/data.js +1 -1
- package/dist/data.js.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/dist/ai/react.js
CHANGED
|
@@ -62,16 +62,48 @@ function useChat(options) {
|
|
|
62
62
|
options.onResponse(response);
|
|
63
63
|
}
|
|
64
64
|
if (response.body) {
|
|
65
|
+
const streamingMessageId = `msg_${Date.now()}`;
|
|
66
|
+
let hasAddedStreamingMessage = false;
|
|
65
67
|
await handleStreamingResponse(
|
|
66
68
|
response.body,
|
|
69
|
+
// onMessage - when streaming is complete
|
|
67
70
|
(assistantMessage) => {
|
|
68
|
-
setMessages((prev) =>
|
|
71
|
+
setMessages((prev) => {
|
|
72
|
+
if (hasAddedStreamingMessage) {
|
|
73
|
+
return prev.map(
|
|
74
|
+
(m) => m.id === streamingMessageId ? assistantMessage : m
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
return [...prev, assistantMessage];
|
|
78
|
+
});
|
|
69
79
|
if (options.onFinish) {
|
|
70
80
|
options.onFinish(assistantMessage);
|
|
71
81
|
}
|
|
72
82
|
},
|
|
83
|
+
// onData - for data events
|
|
73
84
|
(partialData) => {
|
|
74
85
|
setData(partialData);
|
|
86
|
+
},
|
|
87
|
+
// onUpdate - for real-time streaming updates
|
|
88
|
+
(partialContent, messageId) => {
|
|
89
|
+
if (!hasAddedStreamingMessage) {
|
|
90
|
+
hasAddedStreamingMessage = true;
|
|
91
|
+
setMessages((prev) => [
|
|
92
|
+
...prev,
|
|
93
|
+
{
|
|
94
|
+
id: messageId || streamingMessageId,
|
|
95
|
+
role: "assistant",
|
|
96
|
+
content: partialContent,
|
|
97
|
+
timestamp: Date.now()
|
|
98
|
+
}
|
|
99
|
+
]);
|
|
100
|
+
} else {
|
|
101
|
+
setMessages(
|
|
102
|
+
(prev) => prev.map(
|
|
103
|
+
(m) => m.id === (messageId || streamingMessageId) ? { ...m, content: partialContent } : m
|
|
104
|
+
)
|
|
105
|
+
);
|
|
106
|
+
}
|
|
75
107
|
}
|
|
76
108
|
);
|
|
77
109
|
}
|
|
@@ -149,36 +181,55 @@ function useChat(options) {
|
|
|
149
181
|
handleSubmit
|
|
150
182
|
};
|
|
151
183
|
}
|
|
152
|
-
async function handleStreamingResponse(body, onMessage, onData) {
|
|
184
|
+
async function handleStreamingResponse(body, onMessage, onData, onUpdate) {
|
|
153
185
|
const reader = body.getReader();
|
|
154
186
|
const decoder = new TextDecoder();
|
|
155
187
|
let accumulatedText = "";
|
|
188
|
+
let messageId = `msg_${Date.now()}`;
|
|
156
189
|
while (true) {
|
|
157
190
|
const { done, value } = await reader.read();
|
|
158
|
-
if (done)
|
|
191
|
+
if (done) {
|
|
159
192
|
break;
|
|
193
|
+
}
|
|
160
194
|
const chunk = decoder.decode(value, { stream: true });
|
|
161
195
|
const lines = chunk.split("\n").filter((line) => line.trim());
|
|
162
196
|
for (const line of lines) {
|
|
163
197
|
if (line.startsWith("data: ")) {
|
|
164
198
|
const data = line.slice(6);
|
|
165
199
|
if (data === "[DONE]") {
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
try {
|
|
169
|
-
const parsed = JSON.parse(data);
|
|
170
|
-
if (parsed.type === "chunk") {
|
|
171
|
-
accumulatedText += parsed.content;
|
|
172
|
-
} else if (parsed.type === "status") {
|
|
200
|
+
if (accumulatedText) {
|
|
173
201
|
const assistantMessage = {
|
|
174
|
-
id:
|
|
202
|
+
id: messageId,
|
|
175
203
|
role: "assistant",
|
|
176
204
|
content: accumulatedText,
|
|
177
205
|
timestamp: Date.now()
|
|
178
206
|
};
|
|
179
207
|
onMessage(assistantMessage);
|
|
180
|
-
}
|
|
208
|
+
}
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
const parsed = JSON.parse(data);
|
|
213
|
+
if (parsed.type === "data") {
|
|
181
214
|
onData(parsed.data);
|
|
215
|
+
} else if (parsed.type === "start") {
|
|
216
|
+
messageId = parsed.messageId || `msg_${Date.now()}`;
|
|
217
|
+
accumulatedText = "";
|
|
218
|
+
} else if (parsed.type === "text-delta") {
|
|
219
|
+
accumulatedText += parsed.textDelta || "";
|
|
220
|
+
if (onUpdate) {
|
|
221
|
+
onUpdate(accumulatedText, messageId);
|
|
222
|
+
}
|
|
223
|
+
} else if (parsed.type === "finish") {
|
|
224
|
+
if (accumulatedText) {
|
|
225
|
+
const assistantMessage = {
|
|
226
|
+
id: messageId,
|
|
227
|
+
role: "assistant",
|
|
228
|
+
content: accumulatedText,
|
|
229
|
+
timestamp: Date.now()
|
|
230
|
+
};
|
|
231
|
+
onMessage(assistantMessage);
|
|
232
|
+
}
|
|
182
233
|
}
|
|
183
234
|
} catch {
|
|
184
235
|
}
|
package/dist/ai/react.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/ai/react/hooks/use-chat.ts", "../../../src/core/errors/veryfront-error.ts", "../../../src/ai/react/hooks/use-agent.ts", "../../../src/ai/react/hooks/use-completion.ts", "../../../src/ai/react/hooks/use-streaming.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * useChat Hook - Layer 1 (Headless)\n *\n * Complete chat state management with zero UI.\n * Build any interface you want.\n *\n * NOTE: In production, this could leverage Vercel AI SDK's useChat\n * for battle-tested implementation. This is a simplified reference implementation.\n */\n\nimport { useCallback, useRef, useState } from \"react\";\nimport type { Message } from \"../../types/agent.ts\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\nexport interface UseChatOptions {\n /** API endpoint for chat */\n api: string;\n\n /** Initial messages */\n initialMessages?: Message[];\n\n /** Additional data to send */\n body?: Record<string, unknown>;\n\n /** Custom headers */\n headers?: Record<string, string>;\n\n /** Credentials mode */\n credentials?: RequestCredentials;\n\n /** Callback when response received */\n onResponse?: (response: Response) => void;\n\n /** Callback when message finished */\n onFinish?: (message: Message) => void;\n\n /** Callback when error occurs */\n onError?: (error: Error) => void;\n}\n\nexport interface UseChatResult {\n /** Message history */\n messages: Message[];\n\n /** Current input value */\n input: string;\n\n /** Loading state */\n isLoading: boolean;\n\n /** Error state */\n error: Error | null;\n\n /** Set input value */\n setInput: (input: string) => void;\n\n /** Add a message and get response */\n append: (message: Omit<Message, \"id\" | \"timestamp\">) => Promise<void>;\n\n /** Retry last message */\n reload: () => Promise<void>;\n\n /** Stop generation */\n stop: () => void;\n\n /** Manually set messages */\n setMessages: (messages: Message[]) => void;\n\n /** Additional data from server */\n data?: unknown;\n\n /** Handle input change */\n handleInputChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;\n\n /** Handle form submit */\n handleSubmit: (e: React.FormEvent) => Promise<void>;\n}\n\n/**\n * useChat hook for managing chat state\n */\nexport function useChat(options: UseChatOptions): UseChatResult {\n const [messages, setMessages] = useState<Message[]>(\n options.initialMessages || [],\n );\n const [input, setInput] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [data, setData] = useState<unknown>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n /**\n * Append a message and get AI response\n */\n const append = useCallback(\n async (message: Omit<Message, \"id\" | \"timestamp\">) => {\n const userMessage: Message = {\n ...message,\n id: `msg_${Date.now()}`,\n timestamp: Date.now(),\n };\n\n // Add user message\n setMessages((prev) => [...prev, userMessage]);\n setIsLoading(true);\n setError(null);\n\n // Create abort controller\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n // Call API\n const response = await fetch(options.api, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n credentials: options.credentials,\n body: JSON.stringify({\n messages: [...messages, userMessage],\n ...options.body,\n }),\n signal: abortController.signal,\n });\n\n if (!response.ok) {\n throw toError(createError({\n type: \"agent\",\n message: `API error: ${response.status}`,\n }));\n }\n\n if (options.onResponse) {\n options.onResponse(response);\n }\n\n // Handle streaming response\n if (response.body) {\n await handleStreamingResponse(\n response.body,\n (assistantMessage) => {\n setMessages((prev) => [...prev, assistantMessage]);\n\n if (options.onFinish) {\n options.onFinish(assistantMessage);\n }\n },\n (partialData) => {\n setData(partialData);\n },\n );\n }\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n // Request was aborted, ignore\n return;\n }\n\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n\n if (options.onError) {\n options.onError(error);\n }\n } finally {\n setIsLoading(false);\n abortControllerRef.current = null;\n }\n },\n [messages, options],\n );\n\n /**\n * Reload last message\n */\n const reload = useCallback(async () => {\n if (messages.length === 0) return;\n\n // Remove last assistant message and re-send user message\n const lastUserMessageIndex = messages.findLastIndex((m) => m.role === \"user\");\n\n if (lastUserMessageIndex === -1) return;\n\n const messagesToKeep = messages.slice(0, lastUserMessageIndex);\n const lastUserMessage = messages[lastUserMessageIndex];\n\n // Early return already handled undefined case above\n if (!lastUserMessage) return;\n\n setMessages(messagesToKeep);\n\n await append({\n role: lastUserMessage.role,\n content: lastUserMessage.content,\n });\n }, [messages, append]);\n\n /**\n * Stop generation\n */\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n setIsLoading(false);\n }, []);\n\n /**\n * Handle input change\n */\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n setInput(e.target.value);\n },\n [],\n );\n\n /**\n * Handle form submit\n */\n const handleSubmit = useCallback(\n async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!input.trim() || isLoading) return;\n\n const messageContent = input;\n setInput(\"\");\n\n await append({\n role: \"user\",\n content: messageContent,\n });\n },\n [input, isLoading, append],\n );\n\n return {\n messages,\n input,\n isLoading,\n error,\n setInput,\n append,\n reload,\n stop,\n setMessages,\n data,\n handleInputChange,\n handleSubmit,\n };\n}\n\n/**\n * Handle streaming response from server\n */\nasync function handleStreamingResponse(\n body: ReadableStream,\n onMessage: (message: Message) => void,\n onData: (data: unknown) => void,\n): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let accumulatedText = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\n\").filter((line) => line.trim());\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n const data = line.slice(6);\n\n if (data === \"[DONE]\") {\n continue;\n }\n\n try {\n const parsed = JSON.parse(data);\n\n if (parsed.type === \"chunk\") {\n accumulatedText += parsed.content;\n } else if (parsed.type === \"status\") {\n // Stream completed\n const assistantMessage: Message = {\n id: `msg_${Date.now()}`,\n role: \"assistant\",\n content: accumulatedText,\n timestamp: Date.now(),\n };\n onMessage(assistantMessage);\n } else if (parsed.type === \"data\") {\n onData(parsed.data);\n }\n } catch {\n // Skip invalid JSON\n }\n }\n }\n }\n}\n", "export interface BuildContext {\n file?: string;\n line?: number;\n column?: number;\n moduleId?: string;\n phase?: \"parse\" | \"transform\" | \"bundle\" | \"optimize\";\n}\n\nexport interface APIContext {\n endpoint?: string;\n method?: string;\n statusCode?: number;\n headers?: Record<string, string>;\n}\n\nexport interface RenderContext {\n component?: string;\n route?: string;\n phase?: \"server\" | \"client\" | \"hydration\";\n props?: unknown;\n}\n\nexport interface ConfigContext {\n configFile?: string;\n field?: string;\n value?: unknown;\n expected?: string;\n}\n\nexport interface AgentContext {\n agentId?: string;\n intent?: string;\n timeout?: number;\n}\n\nexport interface FileContext {\n path?: string;\n operation?: \"read\" | \"write\" | \"delete\" | \"mkdir\";\n permissions?: string;\n}\n\nexport interface NetworkContext {\n url?: string;\n timeout?: number;\n retryCount?: number;\n}\n\nexport type VeryfrontError =\n | { type: \"build\"; message: string; context?: BuildContext }\n | { type: \"api\"; message: string; context?: APIContext }\n | { type: \"render\"; message: string; context?: RenderContext }\n | { type: \"config\"; message: string; context?: ConfigContext }\n | { type: \"agent\"; message: string; context?: AgentContext }\n | { type: \"file\"; message: string; context?: FileContext }\n | { type: \"network\"; message: string; context?: NetworkContext }\n | { type: \"permission\"; message: string; context?: FileContext }\n | { type: \"not_supported\"; message: string; feature?: string };\n\nexport function createError(error: VeryfrontError): VeryfrontError {\n return error;\n}\n\nexport function isBuildError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"build\" }> {\n return error.type === \"build\";\n}\n\nexport function isAPIError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"api\" }> {\n return error.type === \"api\";\n}\n\nexport function isRenderError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"render\" }> {\n return error.type === \"render\";\n}\n\nexport function isConfigError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"config\" }> {\n return error.type === \"config\";\n}\n\nexport function isAgentError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"agent\" }> {\n return error.type === \"agent\";\n}\n\nexport function isFileError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"file\" }> {\n return error.type === \"file\";\n}\n\nexport function isNetworkError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"network\" }> {\n return error.type === \"network\";\n}\n\nexport function toError(veryfrontError: VeryfrontError): Error {\n const error = new Error(veryfrontError.message);\n error.name = `VeryfrontError[${veryfrontError.type}]`;\n Object.defineProperty(error, \"context\", {\n value: veryfrontError,\n enumerable: false,\n configurable: true,\n });\n return error;\n}\n\nexport function fromError(error: unknown): VeryfrontError | null {\n if (error && typeof error === \"object\" && \"context\" in error) {\n // Safe access after 'in' check\n const context = (error as Record<string, unknown>).context;\n if (\n context &&\n typeof context === \"object\" &&\n \"type\" in context &&\n \"message\" in context\n ) {\n return context as VeryfrontError;\n }\n }\n return null;\n}\n\nexport function logError(\n error: VeryfrontError,\n logger?: { error: (msg: string, ...args: unknown[]) => void },\n): void {\n const log = logger || console;\n const context = \"context\" in error ? error.context || {} : {};\n log.error(`[${error.type}] ${error.message}`, context);\n}\n", "/**\n * useAgent Hook - Layer 1 (Headless)\n *\n * Agent orchestration with tool execution visualization.\n */\n\nimport { useCallback, useRef, useState } from \"react\";\nimport type { AgentStatus, Message, ToolCall } from \"../../types/agent.ts\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\nexport interface UseAgentOptions {\n /** Agent ID or endpoint */\n agent: string;\n\n /** Callback when tool is called */\n onToolCall?: (toolCall: ToolCall) => void;\n\n /** Callback when tool result received */\n onToolResult?: (toolCall: ToolCall, result: unknown) => void;\n\n /** Callback when error occurs */\n onError?: (error: Error) => void;\n}\n\nexport interface UseAgentResult {\n /** Message history */\n messages: Message[];\n\n /** Active tool calls */\n toolCalls: ToolCall[];\n\n /** Agent status */\n status: AgentStatus;\n\n /** Thinking/reasoning text */\n thinking?: string;\n\n /** Invoke the agent */\n invoke: (input: string) => Promise<void>;\n\n /** Stop agent execution */\n stop: () => void;\n\n /** Loading state */\n isLoading: boolean;\n\n /** Error state */\n error: Error | null;\n}\n\n/**\n * useAgent hook for agent orchestration\n */\nexport function useAgent(options: UseAgentOptions): UseAgentResult {\n const [messages, setMessages] = useState<Message[]>([]);\n const [toolCalls, setToolCalls] = useState<ToolCall[]>([]);\n const [status, setStatus] = useState<AgentStatus>(\"idle\");\n const [thinking, setThinking] = useState<string | undefined>();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n /**\n * Invoke the agent\n */\n const invoke = useCallback(\n async (input: string) => {\n setIsLoading(true);\n setError(null);\n setStatus(\"thinking\");\n setToolCalls([]);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n // Call agent API\n const response = await fetch(`/api/agents/${options.agent}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n input,\n messages,\n }),\n signal: abortController.signal,\n });\n\n if (!response.ok) {\n throw toError(createError({\n type: \"agent\",\n message: `Agent error: ${response.status}`,\n }));\n }\n\n // Parse response\n const data = await response.json();\n\n // Update state\n setMessages(data.messages || []);\n setToolCalls(data.toolCalls || []);\n setStatus(data.status || \"completed\");\n setThinking(data.thinking);\n\n // Call callbacks for tool calls\n if (data.toolCalls && options.onToolCall) {\n data.toolCalls.forEach((tc: ToolCall) => {\n options.onToolCall!(tc);\n\n if (tc.result && options.onToolResult) {\n options.onToolResult(tc, tc.result);\n }\n });\n }\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n return;\n }\n\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n setStatus(\"error\");\n\n if (options.onError) {\n options.onError(error);\n }\n } finally {\n setIsLoading(false);\n abortControllerRef.current = null;\n }\n },\n [messages, options],\n );\n\n /**\n * Stop agent execution\n */\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n setIsLoading(false);\n setStatus(\"idle\");\n }, []);\n\n return {\n messages,\n toolCalls,\n status,\n thinking,\n invoke,\n stop,\n isLoading,\n error,\n };\n}\n", "/**\n * useCompletion Hook - Layer 1 (Headless)\n *\n * Single text completion with streaming support.\n */\n\nimport { useCallback, useRef, useState } from \"react\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\nexport interface UseCompletionOptions {\n /** API endpoint for completion */\n api: string;\n\n /** Additional data to send */\n body?: Record<string, unknown>;\n\n /** Custom headers */\n headers?: Record<string, string>;\n\n /** Callback when response received */\n onResponse?: (response: Response) => void;\n\n /** Callback when completion finished */\n onFinish?: (completion: string) => void;\n\n /** Callback when error occurs */\n onError?: (error: Error) => void;\n}\n\nexport interface UseCompletionResult {\n /** Generated completion text */\n completion: string;\n\n /** Loading state */\n isLoading: boolean;\n\n /** Error state */\n error: Error | null;\n\n /** Complete a prompt */\n complete: (prompt: string) => Promise<void>;\n\n /** Stop generation */\n stop: () => void;\n\n /** Set completion manually */\n setCompletion: (completion: string) => void;\n}\n\n/**\n * useCompletion hook for single text generation\n */\nexport function useCompletion(\n options: UseCompletionOptions,\n): UseCompletionResult {\n const [completion, setCompletion] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n /**\n * Complete a prompt\n */\n const complete = useCallback(\n async (prompt: string) => {\n setIsLoading(true);\n setError(null);\n setCompletion(\"\");\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n // Call API\n const response = await fetch(options.api, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n body: JSON.stringify({\n prompt,\n ...options.body,\n }),\n signal: abortController.signal,\n });\n\n if (!response.ok) {\n throw toError(createError({\n type: \"agent\",\n message: `API error: ${response.status}`,\n }));\n }\n\n if (options.onResponse) {\n options.onResponse(response);\n }\n\n // Handle streaming response\n if (response.body) {\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let accumulatedText = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n accumulatedText += chunk;\n setCompletion(accumulatedText);\n }\n\n if (options.onFinish) {\n options.onFinish(accumulatedText);\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n return;\n }\n\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n\n if (options.onError) {\n options.onError(error);\n }\n } finally {\n setIsLoading(false);\n abortControllerRef.current = null;\n }\n },\n [options],\n );\n\n /**\n * Stop generation\n */\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n setIsLoading(false);\n }, []);\n\n return {\n completion,\n isLoading,\n error,\n complete,\n stop,\n setCompletion,\n };\n}\n", "/**\n * useStreaming Hook - Layer 1 (Headless)\n *\n * Low-level streaming control for custom implementations.\n */\n\nimport { useCallback, useRef, useState } from \"react\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\nexport interface UseStreamingOptions {\n /** URL to stream from */\n url: string;\n\n /** Callback for each chunk */\n onChunk?: (chunk: string) => void;\n\n /** Callback when stream completes */\n onComplete?: () => void;\n\n /** Callback when error occurs */\n onError?: (error: Error) => void;\n}\n\nexport interface UseStreamingResult {\n /** Streaming data */\n data: string;\n\n /** Streaming state */\n isStreaming: boolean;\n\n /** Error state */\n error: Error | null;\n\n /** Start streaming */\n start: (body?: Record<string, unknown>) => Promise<void>;\n\n /** Stop streaming */\n stop: () => void;\n\n /** Reset data */\n reset: () => void;\n}\n\n/**\n * useStreaming hook for low-level streaming control\n */\nexport function useStreaming(\n options: UseStreamingOptions,\n): UseStreamingResult {\n const [data, setData] = useState(\"\");\n const [isStreaming, setIsStreaming] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n /**\n * Start streaming\n */\n const start = useCallback(\n async (body?: Record<string, unknown>) => {\n setIsStreaming(true);\n setError(null);\n setData(\"\");\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n const response = await fetch(options.url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: abortController.signal,\n });\n\n if (!response.ok) {\n throw toError(createError({\n type: \"agent\",\n message: `Streaming error: ${response.status}`,\n }));\n }\n\n if (!response.body) {\n throw toError(createError({\n type: \"agent\",\n message: \"No response body\",\n }));\n }\n\n // Read stream\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let accumulatedData = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n accumulatedData += chunk;\n setData(accumulatedData);\n\n if (options.onChunk) {\n options.onChunk(chunk);\n }\n }\n\n if (options.onComplete) {\n options.onComplete();\n }\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n return;\n }\n\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n\n if (options.onError) {\n options.onError(error);\n }\n } finally {\n setIsStreaming(false);\n abortControllerRef.current = null;\n }\n },\n [options],\n );\n\n /**\n * Stop streaming\n */\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n setIsStreaming(false);\n }, []);\n\n /**\n * Reset data\n */\n const reset = useCallback(() => {\n setData(\"\");\n setError(null);\n }, []);\n\n return {\n data,\n isStreaming,\n error,\n start,\n stop,\n reset,\n };\n}\n"],
|
|
5
|
-
"mappings": ";AAUA,SAAS,aAAa,QAAQ,gBAAgB;;;ACgDvC,SAAS,YAAY,OAAuC;AACjE,SAAO;AACT;AA4CO,SAAS,QAAQ,gBAAuC;AAC7D,QAAM,QAAQ,IAAI,MAAM,eAAe,OAAO;AAC9C,QAAM,OAAO,kBAAkB,eAAe,IAAI;AAClD,SAAO,eAAe,OAAO,WAAW;AAAA,IACtC,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,cAAc;AAAA,EAChB,CAAC;AACD,SAAO;AACT;;;ADhCO,SAAS,QAAQ,SAAwC;AAC9D,QAAM,CAAC,UAAU,WAAW,IAAI;AAAA,IAC9B,QAAQ,mBAAmB,CAAC;AAAA,EAC9B;AACA,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,EAAE;AACrC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAuB,IAAI;AACrD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAkB,IAAI;AAC9C,QAAM,qBAAqB,OAA+B,IAAI;AAK9D,QAAM,SAAS;AAAA,IACb,OAAO,YAA+C;AACpD,YAAM,cAAuB;AAAA,QAC3B,GAAG;AAAA,QACH,IAAI,OAAO,KAAK,IAAI,CAAC;AAAA,QACrB,WAAW,KAAK,IAAI;AAAA,MACtB;AAGA,kBAAY,CAAC,SAAS,CAAC,GAAG,MAAM,WAAW,CAAC;AAC5C,mBAAa,IAAI;AACjB,eAAS,IAAI;AAGb,YAAM,kBAAkB,IAAI,gBAAgB;AAC5C,yBAAmB,UAAU;AAE7B,UAAI;AAEF,cAAM,WAAW,MAAM,MAAM,QAAQ,KAAK;AAAA,UACxC,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,GAAG,QAAQ;AAAA,UACb;AAAA,UACA,aAAa,QAAQ;AAAA,UACrB,MAAM,KAAK,UAAU;AAAA,YACnB,UAAU,CAAC,GAAG,UAAU,WAAW;AAAA,YACnC,GAAG,QAAQ;AAAA,UACb,CAAC;AAAA,UACD,QAAQ,gBAAgB;AAAA,QAC1B,CAAC;AAED,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,QAAQ,YAAY;AAAA,YACxB,MAAM;AAAA,YACN,SAAS,cAAc,SAAS,MAAM;AAAA,UACxC,CAAC,CAAC;AAAA,QACJ;AAEA,YAAI,QAAQ,YAAY;AACtB,kBAAQ,WAAW,QAAQ;AAAA,QAC7B;AAGA,YAAI,SAAS,MAAM;
|
|
4
|
+
"sourcesContent": ["/**\n * useChat Hook - Layer 1 (Headless)\n *\n * Complete chat state management with zero UI.\n * Build any interface you want.\n *\n * NOTE: In production, this could leverage Vercel AI SDK's useChat\n * for battle-tested implementation. This is a simplified reference implementation.\n */\n\nimport { useCallback, useRef, useState } from \"react\";\nimport type { Message } from \"../../types/agent.ts\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\nexport interface UseChatOptions {\n /** API endpoint for chat */\n api: string;\n\n /** Initial messages */\n initialMessages?: Message[];\n\n /** Additional data to send */\n body?: Record<string, unknown>;\n\n /** Custom headers */\n headers?: Record<string, string>;\n\n /** Credentials mode */\n credentials?: RequestCredentials;\n\n /** Callback when response received */\n onResponse?: (response: Response) => void;\n\n /** Callback when message finished */\n onFinish?: (message: Message) => void;\n\n /** Callback when error occurs */\n onError?: (error: Error) => void;\n}\n\nexport interface UseChatResult {\n /** Message history */\n messages: Message[];\n\n /** Current input value */\n input: string;\n\n /** Loading state */\n isLoading: boolean;\n\n /** Error state */\n error: Error | null;\n\n /** Set input value */\n setInput: (input: string) => void;\n\n /** Add a message and get response */\n append: (message: Omit<Message, \"id\" | \"timestamp\">) => Promise<void>;\n\n /** Retry last message */\n reload: () => Promise<void>;\n\n /** Stop generation */\n stop: () => void;\n\n /** Manually set messages */\n setMessages: (messages: Message[]) => void;\n\n /** Additional data from server */\n data?: unknown;\n\n /** Handle input change */\n handleInputChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;\n\n /** Handle form submit */\n handleSubmit: (e: React.FormEvent) => Promise<void>;\n}\n\n/**\n * useChat hook for managing chat state\n */\nexport function useChat(options: UseChatOptions): UseChatResult {\n const [messages, setMessages] = useState<Message[]>(\n options.initialMessages || [],\n );\n const [input, setInput] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [data, setData] = useState<unknown>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n /**\n * Append a message and get AI response\n */\n const append = useCallback(\n async (message: Omit<Message, \"id\" | \"timestamp\">) => {\n const userMessage: Message = {\n ...message,\n id: `msg_${Date.now()}`,\n timestamp: Date.now(),\n };\n\n // Add user message\n setMessages((prev) => [...prev, userMessage]);\n setIsLoading(true);\n setError(null);\n\n // Create abort controller\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n // Call API\n const response = await fetch(options.api, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n credentials: options.credentials,\n body: JSON.stringify({\n messages: [...messages, userMessage],\n ...options.body,\n }),\n signal: abortController.signal,\n });\n\n if (!response.ok) {\n throw toError(createError({\n type: \"agent\",\n message: `API error: ${response.status}`,\n }));\n }\n\n if (options.onResponse) {\n options.onResponse(response);\n }\n\n // Handle streaming response\n if (response.body) {\n // Create a placeholder message ID for streaming\n const streamingMessageId = `msg_${Date.now()}`;\n let hasAddedStreamingMessage = false;\n\n await handleStreamingResponse(\n response.body,\n // onMessage - when streaming is complete\n (assistantMessage) => {\n // Replace the streaming message with the final message\n setMessages((prev) => {\n // If we had a streaming message, replace it\n if (hasAddedStreamingMessage) {\n return prev.map((m) =>\n m.id === streamingMessageId ? assistantMessage : m\n );\n }\n // Otherwise just add it\n return [...prev, assistantMessage];\n });\n\n if (options.onFinish) {\n options.onFinish(assistantMessage);\n }\n },\n // onData - for data events\n (partialData) => {\n setData(partialData);\n },\n // onUpdate - for real-time streaming updates\n (partialContent, messageId) => {\n if (!hasAddedStreamingMessage) {\n // Add the streaming message for the first time\n hasAddedStreamingMessage = true;\n setMessages((prev) => [\n ...prev,\n {\n id: messageId || streamingMessageId,\n role: \"assistant\" as const,\n content: partialContent,\n timestamp: Date.now(),\n },\n ]);\n } else {\n // Update the streaming message content\n setMessages((prev) =>\n prev.map((m) =>\n m.id === (messageId || streamingMessageId)\n ? { ...m, content: partialContent }\n : m\n )\n );\n }\n },\n );\n }\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n // Request was aborted, ignore\n return;\n }\n\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n\n if (options.onError) {\n options.onError(error);\n }\n } finally {\n setIsLoading(false);\n abortControllerRef.current = null;\n }\n },\n [messages, options],\n );\n\n /**\n * Reload last message\n */\n const reload = useCallback(async () => {\n if (messages.length === 0) return;\n\n // Remove last assistant message and re-send user message\n const lastUserMessageIndex = messages.findLastIndex((m) => m.role === \"user\");\n\n if (lastUserMessageIndex === -1) return;\n\n const messagesToKeep = messages.slice(0, lastUserMessageIndex);\n const lastUserMessage = messages[lastUserMessageIndex];\n\n // Early return already handled undefined case above\n if (!lastUserMessage) return;\n\n setMessages(messagesToKeep);\n\n await append({\n role: lastUserMessage.role,\n content: lastUserMessage.content,\n });\n }, [messages, append]);\n\n /**\n * Stop generation\n */\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n setIsLoading(false);\n }, []);\n\n /**\n * Handle input change\n */\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n setInput(e.target.value);\n },\n [],\n );\n\n /**\n * Handle form submit\n */\n const handleSubmit = useCallback(\n async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!input.trim() || isLoading) return;\n\n const messageContent = input;\n setInput(\"\");\n\n await append({\n role: \"user\",\n content: messageContent,\n });\n },\n [input, isLoading, append],\n );\n\n return {\n messages,\n input,\n isLoading,\n error,\n setInput,\n append,\n reload,\n stop,\n setMessages,\n data,\n handleInputChange,\n handleSubmit,\n };\n}\n\n/**\n * Handle streaming response from server\n * Uses Vercel AI SDK data stream format\n */\nasync function handleStreamingResponse(\n body: ReadableStream,\n onMessage: (message: Message) => void,\n onData: (data: unknown) => void,\n onUpdate?: (partialContent: string, messageId: string) => void,\n): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let accumulatedText = \"\";\n let messageId = `msg_${Date.now()}`;\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\n\").filter((line) => line.trim());\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n const data = line.slice(6);\n\n if (data === \"[DONE]\") {\n // Stream finished - create the assistant message\n if (accumulatedText) {\n const assistantMessage: Message = {\n id: messageId,\n role: \"assistant\",\n content: accumulatedText,\n timestamp: Date.now(),\n };\n onMessage(assistantMessage);\n }\n continue;\n }\n\n try {\n const parsed = JSON.parse(data);\n\n if (parsed.type === \"data\") {\n onData(parsed.data);\n } else if (parsed.type === \"start\") {\n // New message starting\n messageId = parsed.messageId || `msg_${Date.now()}`;\n accumulatedText = \"\";\n } else if (parsed.type === \"text-delta\") {\n // Text chunk - accumulate and update UI\n accumulatedText += parsed.textDelta || \"\";\n // Call onUpdate to show text progressively\n if (onUpdate) {\n onUpdate(accumulatedText, messageId);\n }\n } else if (parsed.type === \"finish\") {\n // Stream completed\n if (accumulatedText) {\n const assistantMessage: Message = {\n id: messageId,\n role: \"assistant\",\n content: accumulatedText,\n timestamp: Date.now(),\n };\n onMessage(assistantMessage);\n }\n }\n } catch {\n // Skip invalid JSON\n }\n }\n }\n }\n}\n", "export interface BuildContext {\n file?: string;\n line?: number;\n column?: number;\n moduleId?: string;\n phase?: \"parse\" | \"transform\" | \"bundle\" | \"optimize\";\n}\n\nexport interface APIContext {\n endpoint?: string;\n method?: string;\n statusCode?: number;\n headers?: Record<string, string>;\n}\n\nexport interface RenderContext {\n component?: string;\n route?: string;\n phase?: \"server\" | \"client\" | \"hydration\";\n props?: unknown;\n}\n\nexport interface ConfigContext {\n configFile?: string;\n field?: string;\n value?: unknown;\n expected?: string;\n}\n\nexport interface AgentContext {\n agentId?: string;\n intent?: string;\n timeout?: number;\n}\n\nexport interface FileContext {\n path?: string;\n operation?: \"read\" | \"write\" | \"delete\" | \"mkdir\";\n permissions?: string;\n}\n\nexport interface NetworkContext {\n url?: string;\n timeout?: number;\n retryCount?: number;\n}\n\nexport type VeryfrontError =\n | { type: \"build\"; message: string; context?: BuildContext }\n | { type: \"api\"; message: string; context?: APIContext }\n | { type: \"render\"; message: string; context?: RenderContext }\n | { type: \"config\"; message: string; context?: ConfigContext }\n | { type: \"agent\"; message: string; context?: AgentContext }\n | { type: \"file\"; message: string; context?: FileContext }\n | { type: \"network\"; message: string; context?: NetworkContext }\n | { type: \"permission\"; message: string; context?: FileContext }\n | { type: \"not_supported\"; message: string; feature?: string };\n\nexport function createError(error: VeryfrontError): VeryfrontError {\n return error;\n}\n\nexport function isBuildError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"build\" }> {\n return error.type === \"build\";\n}\n\nexport function isAPIError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"api\" }> {\n return error.type === \"api\";\n}\n\nexport function isRenderError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"render\" }> {\n return error.type === \"render\";\n}\n\nexport function isConfigError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"config\" }> {\n return error.type === \"config\";\n}\n\nexport function isAgentError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"agent\" }> {\n return error.type === \"agent\";\n}\n\nexport function isFileError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"file\" }> {\n return error.type === \"file\";\n}\n\nexport function isNetworkError(\n error: VeryfrontError,\n): error is Extract<VeryfrontError, { type: \"network\" }> {\n return error.type === \"network\";\n}\n\nexport function toError(veryfrontError: VeryfrontError): Error {\n const error = new Error(veryfrontError.message);\n error.name = `VeryfrontError[${veryfrontError.type}]`;\n Object.defineProperty(error, \"context\", {\n value: veryfrontError,\n enumerable: false,\n configurable: true,\n });\n return error;\n}\n\nexport function fromError(error: unknown): VeryfrontError | null {\n if (error && typeof error === \"object\" && \"context\" in error) {\n // Safe access after 'in' check\n const context = (error as Record<string, unknown>).context;\n if (\n context &&\n typeof context === \"object\" &&\n \"type\" in context &&\n \"message\" in context\n ) {\n return context as VeryfrontError;\n }\n }\n return null;\n}\n\nexport function logError(\n error: VeryfrontError,\n logger?: { error: (msg: string, ...args: unknown[]) => void },\n): void {\n const log = logger || console;\n const context = \"context\" in error ? error.context || {} : {};\n log.error(`[${error.type}] ${error.message}`, context);\n}\n", "/**\n * useAgent Hook - Layer 1 (Headless)\n *\n * Agent orchestration with tool execution visualization.\n */\n\nimport { useCallback, useRef, useState } from \"react\";\nimport type { AgentStatus, Message, ToolCall } from \"../../types/agent.ts\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\nexport interface UseAgentOptions {\n /** Agent ID or endpoint */\n agent: string;\n\n /** Callback when tool is called */\n onToolCall?: (toolCall: ToolCall) => void;\n\n /** Callback when tool result received */\n onToolResult?: (toolCall: ToolCall, result: unknown) => void;\n\n /** Callback when error occurs */\n onError?: (error: Error) => void;\n}\n\nexport interface UseAgentResult {\n /** Message history */\n messages: Message[];\n\n /** Active tool calls */\n toolCalls: ToolCall[];\n\n /** Agent status */\n status: AgentStatus;\n\n /** Thinking/reasoning text */\n thinking?: string;\n\n /** Invoke the agent */\n invoke: (input: string) => Promise<void>;\n\n /** Stop agent execution */\n stop: () => void;\n\n /** Loading state */\n isLoading: boolean;\n\n /** Error state */\n error: Error | null;\n}\n\n/**\n * useAgent hook for agent orchestration\n */\nexport function useAgent(options: UseAgentOptions): UseAgentResult {\n const [messages, setMessages] = useState<Message[]>([]);\n const [toolCalls, setToolCalls] = useState<ToolCall[]>([]);\n const [status, setStatus] = useState<AgentStatus>(\"idle\");\n const [thinking, setThinking] = useState<string | undefined>();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n /**\n * Invoke the agent\n */\n const invoke = useCallback(\n async (input: string) => {\n setIsLoading(true);\n setError(null);\n setStatus(\"thinking\");\n setToolCalls([]);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n // Call agent API\n const response = await fetch(`/api/agents/${options.agent}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n input,\n messages,\n }),\n signal: abortController.signal,\n });\n\n if (!response.ok) {\n throw toError(createError({\n type: \"agent\",\n message: `Agent error: ${response.status}`,\n }));\n }\n\n // Parse response\n const data = await response.json();\n\n // Update state\n setMessages(data.messages || []);\n setToolCalls(data.toolCalls || []);\n setStatus(data.status || \"completed\");\n setThinking(data.thinking);\n\n // Call callbacks for tool calls\n if (data.toolCalls && options.onToolCall) {\n data.toolCalls.forEach((tc: ToolCall) => {\n options.onToolCall!(tc);\n\n if (tc.result && options.onToolResult) {\n options.onToolResult(tc, tc.result);\n }\n });\n }\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n return;\n }\n\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n setStatus(\"error\");\n\n if (options.onError) {\n options.onError(error);\n }\n } finally {\n setIsLoading(false);\n abortControllerRef.current = null;\n }\n },\n [messages, options],\n );\n\n /**\n * Stop agent execution\n */\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n setIsLoading(false);\n setStatus(\"idle\");\n }, []);\n\n return {\n messages,\n toolCalls,\n status,\n thinking,\n invoke,\n stop,\n isLoading,\n error,\n };\n}\n", "/**\n * useCompletion Hook - Layer 1 (Headless)\n *\n * Single text completion with streaming support.\n */\n\nimport { useCallback, useRef, useState } from \"react\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\nexport interface UseCompletionOptions {\n /** API endpoint for completion */\n api: string;\n\n /** Additional data to send */\n body?: Record<string, unknown>;\n\n /** Custom headers */\n headers?: Record<string, string>;\n\n /** Callback when response received */\n onResponse?: (response: Response) => void;\n\n /** Callback when completion finished */\n onFinish?: (completion: string) => void;\n\n /** Callback when error occurs */\n onError?: (error: Error) => void;\n}\n\nexport interface UseCompletionResult {\n /** Generated completion text */\n completion: string;\n\n /** Loading state */\n isLoading: boolean;\n\n /** Error state */\n error: Error | null;\n\n /** Complete a prompt */\n complete: (prompt: string) => Promise<void>;\n\n /** Stop generation */\n stop: () => void;\n\n /** Set completion manually */\n setCompletion: (completion: string) => void;\n}\n\n/**\n * useCompletion hook for single text generation\n */\nexport function useCompletion(\n options: UseCompletionOptions,\n): UseCompletionResult {\n const [completion, setCompletion] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n /**\n * Complete a prompt\n */\n const complete = useCallback(\n async (prompt: string) => {\n setIsLoading(true);\n setError(null);\n setCompletion(\"\");\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n // Call API\n const response = await fetch(options.api, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n body: JSON.stringify({\n prompt,\n ...options.body,\n }),\n signal: abortController.signal,\n });\n\n if (!response.ok) {\n throw toError(createError({\n type: \"agent\",\n message: `API error: ${response.status}`,\n }));\n }\n\n if (options.onResponse) {\n options.onResponse(response);\n }\n\n // Handle streaming response\n if (response.body) {\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let accumulatedText = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n accumulatedText += chunk;\n setCompletion(accumulatedText);\n }\n\n if (options.onFinish) {\n options.onFinish(accumulatedText);\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n return;\n }\n\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n\n if (options.onError) {\n options.onError(error);\n }\n } finally {\n setIsLoading(false);\n abortControllerRef.current = null;\n }\n },\n [options],\n );\n\n /**\n * Stop generation\n */\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n setIsLoading(false);\n }, []);\n\n return {\n completion,\n isLoading,\n error,\n complete,\n stop,\n setCompletion,\n };\n}\n", "/**\n * useStreaming Hook - Layer 1 (Headless)\n *\n * Low-level streaming control for custom implementations.\n */\n\nimport { useCallback, useRef, useState } from \"react\";\nimport { createError, toError } from \"../../../core/errors/veryfront-error.ts\";\n\nexport interface UseStreamingOptions {\n /** URL to stream from */\n url: string;\n\n /** Callback for each chunk */\n onChunk?: (chunk: string) => void;\n\n /** Callback when stream completes */\n onComplete?: () => void;\n\n /** Callback when error occurs */\n onError?: (error: Error) => void;\n}\n\nexport interface UseStreamingResult {\n /** Streaming data */\n data: string;\n\n /** Streaming state */\n isStreaming: boolean;\n\n /** Error state */\n error: Error | null;\n\n /** Start streaming */\n start: (body?: Record<string, unknown>) => Promise<void>;\n\n /** Stop streaming */\n stop: () => void;\n\n /** Reset data */\n reset: () => void;\n}\n\n/**\n * useStreaming hook for low-level streaming control\n */\nexport function useStreaming(\n options: UseStreamingOptions,\n): UseStreamingResult {\n const [data, setData] = useState(\"\");\n const [isStreaming, setIsStreaming] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n /**\n * Start streaming\n */\n const start = useCallback(\n async (body?: Record<string, unknown>) => {\n setIsStreaming(true);\n setError(null);\n setData(\"\");\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n const response = await fetch(options.url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: abortController.signal,\n });\n\n if (!response.ok) {\n throw toError(createError({\n type: \"agent\",\n message: `Streaming error: ${response.status}`,\n }));\n }\n\n if (!response.body) {\n throw toError(createError({\n type: \"agent\",\n message: \"No response body\",\n }));\n }\n\n // Read stream\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let accumulatedData = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n accumulatedData += chunk;\n setData(accumulatedData);\n\n if (options.onChunk) {\n options.onChunk(chunk);\n }\n }\n\n if (options.onComplete) {\n options.onComplete();\n }\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n return;\n }\n\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n\n if (options.onError) {\n options.onError(error);\n }\n } finally {\n setIsStreaming(false);\n abortControllerRef.current = null;\n }\n },\n [options],\n );\n\n /**\n * Stop streaming\n */\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n setIsStreaming(false);\n }, []);\n\n /**\n * Reset data\n */\n const reset = useCallback(() => {\n setData(\"\");\n setError(null);\n }, []);\n\n return {\n data,\n isStreaming,\n error,\n start,\n stop,\n reset,\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["error", "useCallback", "useRef", "useState", "useState", "useRef", "useCallback", "error", "useCallback", "useRef", "useState", "useState", "useRef", "useCallback", "error", "useCallback", "useRef", "useState", "useState", "useRef", "useCallback", "error"]
|
|
7
7
|
}
|