@sinas/sdk 0.2.0 → 0.2.2
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/{chunk-EV5ARSUJ.js → chunk-HIZX5BQ5.js} +9 -2
- package/dist/chunk-HIZX5BQ5.js.map +1 -0
- package/dist/client.cjs +8 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +1 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.js +1 -1
- package/dist/index.cjs +111 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +104 -7
- package/dist/index.js.map +1 -1
- package/dist/sinas-sdk.umd.js +111 -7
- package/dist/sinas-sdk.umd.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-EV5ARSUJ.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/useQuery.ts","../src/hooks/context.ts","../src/hooks/useExecute.ts","../src/hooks/useStateStore.ts","../src/hooks/useChat.ts","../src/hooks/useSinas.ts"],"sourcesContent":["import React from 'react';\nimport { executeQuery } from '../client/queries';\nimport { useClient } from './context';\nimport type { QueryResult } from '../client/types';\n\nexport interface UseQueryOptions {\n enabled?: boolean;\n refetchInterval?: number | null;\n}\n\nexport interface UseQueryResult {\n data: Record<string, unknown>[] | null;\n loading: boolean;\n error: string | null;\n rowCount: number | null;\n refetch: (overrideInput?: Record<string, unknown>) => Promise<QueryResult | undefined>;\n}\n\nexport function useQuery(\n ref: string,\n input: Record<string, unknown> = {},\n options: UseQueryOptions = {}\n): UseQueryResult {\n const client = useClient();\n const { enabled = true, refetchInterval = null } = options;\n\n const [data, setData] = React.useState<Record<string, unknown>[] | null>(null);\n const [loading, setLoading] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n const [rowCount, setRowCount] = React.useState<number | null>(null);\n\n const abortRef = React.useRef<AbortController | null>(null);\n const inputJson = JSON.stringify(input);\n\n const execute = React.useCallback(\n async (overrideInput?: Record<string, unknown>) => {\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n setLoading(true);\n setError(null);\n try {\n const result = await executeQuery(\n client,\n ref,\n overrideInput || JSON.parse(inputJson)\n );\n if (!controller.signal.aborted) {\n setData(result.data || null);\n setRowCount(result.rowCount ?? result.affectedRows ?? null);\n }\n return result;\n } catch (e) {\n if (!controller.signal.aborted) {\n setError((e as Error).message);\n }\n } finally {\n if (!controller.signal.aborted) {\n setLoading(false);\n }\n }\n },\n [client, ref, inputJson]\n );\n\n React.useEffect(() => {\n if (enabled) {\n execute();\n }\n return () => {\n abortRef.current?.abort();\n };\n }, [enabled, execute]);\n\n React.useEffect(() => {\n if (refetchInterval && enabled) {\n const id = setInterval(execute, refetchInterval);\n return () => clearInterval(id);\n }\n }, [refetchInterval, enabled, execute]);\n\n return { data, loading, error, rowCount, refetch: execute };\n}\n","import React from 'react';\nimport { SinasClient } from '../client/SinasClient';\n\nconst SinasContext = React.createContext<SinasClient | null>(null);\n\nexport interface SinasProviderProps {\n client?: SinasClient;\n children: React.ReactNode;\n}\n\nexport function SinasProvider({ client, children }: SinasProviderProps) {\n const value = React.useMemo(() => client || new SinasClient(), [client]);\n return React.createElement(SinasContext.Provider, { value }, children);\n}\n\nexport function useClient(): SinasClient {\n const client = React.useContext(SinasContext);\n if (client) return client;\n // Fallback: create a default client using window globals\n return defaultClient;\n}\n\nconst defaultClient = new SinasClient();\n","import React from 'react';\nimport { executeFunction } from '../client/functions';\nimport { useClient } from './context';\nimport type { FunctionResult } from '../client/types';\n\nexport interface UseExecuteResult {\n execute: (input?: Record<string, unknown>, timeout?: number) => Promise<FunctionResult | undefined>;\n result: unknown;\n loading: boolean;\n error: string | null;\n executionId: string | null;\n}\n\nexport function useExecute(ref: string): UseExecuteResult {\n const client = useClient();\n\n const [result, setResult] = React.useState<unknown>(null);\n const [loading, setLoading] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n const [executionId, setExecutionId] = React.useState<string | null>(null);\n\n const execute = React.useCallback(\n async (input: Record<string, unknown> = {}, timeout?: number) => {\n setLoading(true);\n setError(null);\n try {\n const data = await executeFunction(client, ref, input, timeout);\n setResult(data.result);\n setExecutionId(data.executionId);\n if (data.status === 'error') {\n setError(data.error || 'Function execution failed');\n } else if (data.status === 'timeout') {\n setError('Function execution timed out');\n }\n return data;\n } catch (e) {\n setError((e as Error).message);\n } finally {\n setLoading(false);\n }\n },\n [client, ref]\n );\n\n return { execute, result, loading, error, executionId };\n}\n","import React from 'react';\nimport { stateGet, stateSet, stateDelete, stateList } from '../client/states';\nimport { useClient } from './context';\nimport type { StateListResult } from '../client/types';\n\nexport interface UseStateStoreOptions {\n visibility?: 'private' | 'shared';\n}\n\nexport interface UseStateStoreResult {\n value: unknown;\n loading: boolean;\n error: string | null;\n save: (value: unknown, opts?: UseStateStoreOptions) => Promise<void>;\n remove: () => Promise<void>;\n refetch: () => Promise<void>;\n list: () => Promise<StateListResult | undefined>;\n}\n\nexport function useStateStore(ns: string, key?: string): UseStateStoreResult {\n const client = useClient();\n\n const [value, setValue] = React.useState<unknown>(null);\n const [loading, setLoading] = React.useState(true);\n const [error, setError] = React.useState<string | null>(null);\n\n const load = React.useCallback(async () => {\n if (!key) {\n setLoading(false);\n return;\n }\n setLoading(true);\n setError(null);\n try {\n const result = await stateGet(client, ns, key);\n if (result.found) {\n setValue(result.value);\n } else {\n setValue(null);\n }\n } catch (e) {\n setError((e as Error).message);\n } finally {\n setLoading(false);\n }\n }, [client, ns, key]);\n\n const save = React.useCallback(\n async (newValue: unknown, opts?: UseStateStoreOptions) => {\n if (!key) throw new Error('Cannot save without a key');\n setValue(newValue);\n setError(null);\n try {\n await stateSet(client, ns, key, newValue, opts?.visibility);\n } catch (e) {\n setError((e as Error).message);\n throw e;\n }\n },\n [client, ns, key]\n );\n\n const remove = React.useCallback(async () => {\n if (!key) throw new Error('Cannot delete without a key');\n setValue(null);\n setError(null);\n try {\n await stateDelete(client, ns, key);\n } catch (e) {\n setError((e as Error).message);\n throw e;\n }\n }, [client, ns, key]);\n\n const list = React.useCallback(async () => {\n setError(null);\n try {\n return await stateList(client, ns);\n } catch (e) {\n setError((e as Error).message);\n }\n }, [client, ns]);\n\n React.useEffect(() => {\n load();\n }, [load]);\n\n return { value, loading, error, save, remove, refetch: load, list };\n}\n","import React from 'react';\nimport { createChat, getChat, streamMessage, approveToolCall, streamFromChannel } from '../client/chat';\nimport { useClient } from './context';\nimport type { ChatMessageFull, ApprovalRequest, SSEChunk, MessageContent } from '../client/types';\n\nexport interface ChatSessionMessage extends ChatMessageFull {\n /** True while streaming content is being appended */\n streaming?: boolean;\n}\n\nexport interface UseChatResult {\n chatId: string | null;\n messages: ChatSessionMessage[];\n loading: boolean;\n streaming: boolean;\n error: string | null;\n pendingApprovals: ApprovalRequest[];\n send: (content: MessageContent) => void;\n approve: (toolCallId: string) => void;\n reject: (toolCallId: string) => void;\n stop: () => void;\n clearError: () => void;\n}\n\nexport interface UseChatOptions {\n chatId?: string;\n input?: Record<string, unknown>;\n}\n\nexport function useChat(\n agentRef: string,\n options?: UseChatOptions,\n): UseChatResult {\n const client = useClient();\n\n const [chatId, setChatId] = React.useState<string | null>(options?.chatId ?? null);\n const [messages, setMessages] = React.useState<ChatSessionMessage[]>([]);\n const [loading, setLoading] = React.useState(false);\n const [streaming, setStreaming] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n const [pendingApprovals, setPendingApprovals] = React.useState<ApprovalRequest[]>([]);\n\n const abortRef = React.useRef<AbortController | null>(null);\n const chatIdRef = React.useRef<string | null>(chatId);\n chatIdRef.current = chatId;\n\n // Load existing chat on mount if chatId provided\n React.useEffect(() => {\n if (!options?.chatId) return;\n let cancelled = false;\n\n setLoading(true);\n getChat(client, options.chatId)\n .then((detail) => {\n if (cancelled) return;\n setChatId(detail.id);\n setMessages(detail.messages);\n })\n .catch((e) => {\n if (cancelled) return;\n setError((e as Error).message);\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n\n return () => { cancelled = true; };\n }, [client, options?.chatId]);\n\n // Cleanup on unmount\n React.useEffect(() => {\n return () => {\n abortRef.current?.abort();\n };\n }, []);\n\n const handleStreamChunks = React.useCallback(\n (assistantId: string) => (chunk: SSEChunk) => {\n if (chunk.event === 'message') {\n try {\n const parsed = JSON.parse(chunk.data);\n if (parsed.content) {\n setMessages((prev) =>\n prev.map((m) =>\n m.id === assistantId\n ? { ...m, content: (m.content || '') + parsed.content }\n : m,\n ),\n );\n }\n } catch {\n // Non-JSON content chunk — append raw data\n setMessages((prev) =>\n prev.map((m) =>\n m.id === assistantId\n ? { ...m, content: (m.content || '') + chunk.data }\n : m,\n ),\n );\n }\n } else if (chunk.event === 'approval_required') {\n try {\n const parsed = JSON.parse(chunk.data) as ApprovalRequest;\n setPendingApprovals((prev) => [...prev, parsed]);\n } catch {\n // ignore malformed approval events\n }\n } else if (chunk.event === 'error') {\n try {\n const parsed = JSON.parse(chunk.data);\n setError(parsed.error || 'Stream error');\n } catch {\n setError(chunk.data || 'Stream error');\n }\n }\n },\n [],\n );\n\n const refreshMessages = React.useCallback(\n async (id: string) => {\n try {\n const detail = await getChat(client, id);\n setMessages(detail.messages);\n } catch {\n // Refresh is best-effort — streaming content already visible\n }\n },\n [client],\n );\n\n const send = React.useCallback(\n (content: MessageContent) => {\n const doSend = async () => {\n let activeChatId = chatIdRef.current;\n\n // Auto-create chat on first send\n if (!activeChatId) {\n setLoading(true);\n setError(null);\n try {\n const result = await createChat(client, agentRef, options?.input);\n activeChatId = result.id;\n setChatId(result.id);\n chatIdRef.current = result.id;\n } catch (e) {\n setError((e as Error).message);\n setLoading(false);\n return;\n }\n setLoading(false);\n }\n\n abortRef.current?.abort();\n setStreaming(true);\n setError(null);\n setPendingApprovals([]);\n\n // Add user message optimistically\n const displayContent = typeof content === 'string' ? content : JSON.stringify(content);\n const userMsg: ChatSessionMessage = {\n id: `tmp-user-${Date.now()}`,\n chatId: activeChatId,\n role: 'user',\n content: displayContent,\n toolCalls: null,\n toolCallId: null,\n name: null,\n createdAt: new Date().toISOString(),\n };\n setMessages((prev) => [...prev, userMsg]);\n\n // Add empty assistant message to accumulate streaming content\n const assistantId = `tmp-assistant-${Date.now()}`;\n const assistantMsg: ChatSessionMessage = {\n id: assistantId,\n chatId: activeChatId,\n role: 'assistant',\n content: '',\n toolCalls: null,\n toolCallId: null,\n name: null,\n createdAt: new Date().toISOString(),\n streaming: true,\n };\n setMessages((prev) => [...prev, assistantMsg]);\n\n const controller = streamMessage(\n client,\n activeChatId,\n content,\n handleStreamChunks(assistantId),\n () => {\n setStreaming(false);\n // Refresh to get authoritative server state (tool calls, tool responses)\n refreshMessages(activeChatId!);\n },\n (err: Error) => {\n setError(err.message);\n setStreaming(false);\n },\n );\n\n abortRef.current = controller;\n };\n\n doSend();\n },\n [client, agentRef, options?.input, handleStreamChunks, refreshMessages],\n );\n\n const handleApproval = React.useCallback(\n (toolCallId: string, approved: boolean) => {\n const currentChatId = chatIdRef.current;\n if (!currentChatId) return;\n\n setPendingApprovals((prev) => prev.filter((a) => a.toolCallId !== toolCallId));\n setStreaming(true);\n setError(null);\n\n // Add placeholder assistant message for the resumed stream\n const assistantId = `tmp-resume-${Date.now()}`;\n if (approved) {\n const assistantMsg: ChatSessionMessage = {\n id: assistantId,\n chatId: currentChatId,\n role: 'assistant',\n content: '',\n toolCalls: null,\n toolCallId: null,\n name: null,\n createdAt: new Date().toISOString(),\n streaming: true,\n };\n setMessages((prev) => [...prev, assistantMsg]);\n }\n\n (async () => {\n try {\n const result = await approveToolCall(client, currentChatId, toolCallId, approved);\n\n if (!approved) {\n setStreaming(false);\n refreshMessages(currentChatId);\n return;\n }\n\n // Connect to resume stream\n const controller = streamFromChannel(\n client,\n currentChatId,\n result.channelId,\n handleStreamChunks(assistantId),\n () => {\n setStreaming(false);\n refreshMessages(currentChatId);\n },\n (err: Error) => {\n setError(err.message);\n setStreaming(false);\n },\n );\n\n abortRef.current = controller;\n } catch (e) {\n setError((e as Error).message);\n setStreaming(false);\n }\n })();\n },\n [client, handleStreamChunks, refreshMessages],\n );\n\n const approve = React.useCallback(\n (toolCallId: string) => handleApproval(toolCallId, true),\n [handleApproval],\n );\n\n const reject = React.useCallback(\n (toolCallId: string) => handleApproval(toolCallId, false),\n [handleApproval],\n );\n\n const stop = React.useCallback(() => {\n abortRef.current?.abort();\n abortRef.current = null;\n setStreaming(false);\n }, []);\n\n const clearError = React.useCallback(() => {\n setError(null);\n }, []);\n\n return {\n chatId,\n messages,\n loading,\n streaming,\n error,\n pendingApprovals,\n send,\n approve,\n reject,\n stop,\n clearError,\n };\n}\n","import { useClient } from './context';\nimport { useQuery } from './useQuery';\nimport { useExecute } from './useExecute';\nimport { useStateStore } from './useStateStore';\nimport { useChat } from './useChat';\nimport type { SinasConfig } from '../client/types';\nimport type { SinasClient } from '../client/SinasClient';\n\nexport interface UseSinasResult {\n config: SinasConfig;\n input: Record<string, unknown>;\n client: SinasClient;\n useQuery: typeof useQuery;\n useExecute: typeof useExecute;\n useStateStore: typeof useStateStore;\n useChat: typeof useChat;\n}\n\nexport function useSinas(): UseSinasResult {\n const client = useClient();\n\n return {\n config: client.getConfig(),\n input: client.getInput(),\n client,\n useQuery,\n useExecute,\n useStateStore,\n useChat,\n };\n}\n"],"mappings":"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","names":["React","React","React","React","React","React","React","React"]}
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useQuery.ts","../src/hooks/context.ts","../src/hooks/useExecute.ts","../src/hooks/useStateStore.ts","../src/hooks/useChat.ts","../src/hooks/useSinas.ts"],"sourcesContent":["import React from 'react';\nimport { executeQuery } from '../client/queries';\nimport { useClient } from './context';\nimport type { QueryResult } from '../client/types';\n\nexport interface UseQueryOptions {\n enabled?: boolean;\n refetchInterval?: number | null;\n}\n\nexport interface UseQueryResult {\n data: Record<string, unknown>[] | null;\n loading: boolean;\n error: string | null;\n rowCount: number | null;\n refetch: (overrideInput?: Record<string, unknown>) => Promise<QueryResult | undefined>;\n}\n\nexport function useQuery(\n ref: string,\n input: Record<string, unknown> = {},\n options: UseQueryOptions = {}\n): UseQueryResult {\n const client = useClient();\n const { enabled = true, refetchInterval = null } = options;\n\n const [data, setData] = React.useState<Record<string, unknown>[] | null>(null);\n const [loading, setLoading] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n const [rowCount, setRowCount] = React.useState<number | null>(null);\n\n const abortRef = React.useRef<AbortController | null>(null);\n const inputJson = JSON.stringify(input);\n\n const execute = React.useCallback(\n async (overrideInput?: Record<string, unknown>) => {\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n setLoading(true);\n setError(null);\n try {\n const result = await executeQuery(\n client,\n ref,\n overrideInput || JSON.parse(inputJson)\n );\n if (!controller.signal.aborted) {\n setData(result.data || null);\n setRowCount(result.rowCount ?? result.affectedRows ?? null);\n }\n return result;\n } catch (e) {\n if (!controller.signal.aborted) {\n setError((e as Error).message);\n }\n } finally {\n if (!controller.signal.aborted) {\n setLoading(false);\n }\n }\n },\n [client, ref, inputJson]\n );\n\n React.useEffect(() => {\n if (enabled) {\n execute();\n }\n return () => {\n abortRef.current?.abort();\n };\n }, [enabled, execute]);\n\n React.useEffect(() => {\n if (refetchInterval && enabled) {\n const id = setInterval(execute, refetchInterval);\n return () => clearInterval(id);\n }\n }, [refetchInterval, enabled, execute]);\n\n return { data, loading, error, rowCount, refetch: execute };\n}\n","import React from 'react';\nimport { SinasClient } from '../client/SinasClient';\n\nconst SinasContext = React.createContext<SinasClient | null>(null);\n\nexport interface SinasProviderProps {\n client?: SinasClient;\n children: React.ReactNode;\n}\n\nexport function SinasProvider({ client, children }: SinasProviderProps) {\n const value = React.useMemo(() => client || new SinasClient(), [client]);\n return React.createElement(SinasContext.Provider, { value }, children);\n}\n\nexport function useClient(): SinasClient {\n const client = React.useContext(SinasContext);\n if (client) return client;\n // Fallback: create a default client using window globals\n return defaultClient;\n}\n\nconst defaultClient = new SinasClient();\n","import React from 'react';\nimport { executeFunction } from '../client/functions';\nimport { useClient } from './context';\nimport type { FunctionResult } from '../client/types';\n\nexport interface UseExecuteResult {\n execute: (input?: Record<string, unknown>, timeout?: number) => Promise<FunctionResult | undefined>;\n result: unknown;\n loading: boolean;\n error: string | null;\n executionId: string | null;\n}\n\nexport function useExecute(ref: string): UseExecuteResult {\n const client = useClient();\n\n const [result, setResult] = React.useState<unknown>(null);\n const [loading, setLoading] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n const [executionId, setExecutionId] = React.useState<string | null>(null);\n\n const execute = React.useCallback(\n async (input: Record<string, unknown> = {}, timeout?: number) => {\n setLoading(true);\n setError(null);\n try {\n const data = await executeFunction(client, ref, input, timeout);\n setResult(data.result);\n setExecutionId(data.executionId);\n if (data.status === 'error') {\n setError(data.error || 'Function execution failed');\n } else if (data.status === 'timeout') {\n setError('Function execution timed out');\n }\n return data;\n } catch (e) {\n setError((e as Error).message);\n } finally {\n setLoading(false);\n }\n },\n [client, ref]\n );\n\n return { execute, result, loading, error, executionId };\n}\n","import React from 'react';\nimport { stateGet, stateSet, stateDelete, stateList } from '../client/states';\nimport { useClient } from './context';\nimport type { StateListResult } from '../client/types';\n\nexport interface UseStateStoreOptions {\n visibility?: 'private' | 'shared';\n}\n\nexport interface UseStateStoreResult {\n value: unknown;\n loading: boolean;\n error: string | null;\n save: (value: unknown, opts?: UseStateStoreOptions) => Promise<void>;\n remove: () => Promise<void>;\n refetch: () => Promise<void>;\n list: () => Promise<StateListResult | undefined>;\n}\n\nexport function useStateStore(ns: string, key?: string): UseStateStoreResult {\n const client = useClient();\n\n const [value, setValue] = React.useState<unknown>(null);\n const [loading, setLoading] = React.useState(true);\n const [error, setError] = React.useState<string | null>(null);\n\n const load = React.useCallback(async () => {\n if (!key) {\n setLoading(false);\n return;\n }\n setLoading(true);\n setError(null);\n try {\n const result = await stateGet(client, ns, key);\n if (result.found) {\n setValue(result.value);\n } else {\n setValue(null);\n }\n } catch (e) {\n setError((e as Error).message);\n } finally {\n setLoading(false);\n }\n }, [client, ns, key]);\n\n const save = React.useCallback(\n async (newValue: unknown, opts?: UseStateStoreOptions) => {\n if (!key) throw new Error('Cannot save without a key');\n setValue(newValue);\n setError(null);\n try {\n await stateSet(client, ns, key, newValue, opts?.visibility);\n } catch (e) {\n setError((e as Error).message);\n throw e;\n }\n },\n [client, ns, key]\n );\n\n const remove = React.useCallback(async () => {\n if (!key) throw new Error('Cannot delete without a key');\n setValue(null);\n setError(null);\n try {\n await stateDelete(client, ns, key);\n } catch (e) {\n setError((e as Error).message);\n throw e;\n }\n }, [client, ns, key]);\n\n const list = React.useCallback(async () => {\n setError(null);\n try {\n return await stateList(client, ns);\n } catch (e) {\n setError((e as Error).message);\n }\n }, [client, ns]);\n\n React.useEffect(() => {\n load();\n }, [load]);\n\n return { value, loading, error, save, remove, refetch: load, list };\n}\n","import React from 'react';\nimport { createChat, getChat, streamMessage, approveToolCall, streamFromChannel } from '../client/chat';\nimport { useClient } from './context';\nimport type { ChatMessageFull, ApprovalRequest, SSEChunk, MessageContent } from '../client/types';\n\nexport interface ChatSessionMessage extends ChatMessageFull {\n /** True while streaming content is being appended */\n streaming?: boolean;\n}\n\nexport interface ToolStatus {\n toolCallId: string;\n name: string;\n description: string;\n status: 'running' | 'complete';\n}\n\nexport interface UseChatResult {\n chatId: string | null;\n messages: ChatSessionMessage[];\n loading: boolean;\n streaming: boolean;\n error: string | null;\n pendingApprovals: ApprovalRequest[];\n toolStatus: ToolStatus[];\n send: (content: MessageContent) => void;\n approve: (toolCallId: string) => void;\n reject: (toolCallId: string) => void;\n stop: () => void;\n clearError: () => void;\n}\n\nexport interface UseChatOptions {\n chatId?: string;\n input?: Record<string, unknown>;\n}\n\nexport function useChat(\n agentRef: string,\n options?: UseChatOptions,\n): UseChatResult {\n const client = useClient();\n\n const [chatId, setChatId] = React.useState<string | null>(options?.chatId ?? null);\n const [messages, setMessages] = React.useState<ChatSessionMessage[]>([]);\n const [loading, setLoading] = React.useState(false);\n const [streaming, setStreaming] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n const [pendingApprovals, setPendingApprovals] = React.useState<ApprovalRequest[]>([]);\n const [toolStatus, setToolStatus] = React.useState<ToolStatus[]>([]);\n\n const abortRef = React.useRef<AbortController | null>(null);\n const chatIdRef = React.useRef<string | null>(chatId);\n chatIdRef.current = chatId;\n const activeAssistantIdRef = React.useRef<string>('');\n\n // Load existing chat on mount if chatId provided\n React.useEffect(() => {\n if (!options?.chatId) return;\n let cancelled = false;\n\n setLoading(true);\n getChat(client, options.chatId)\n .then((detail) => {\n if (cancelled) return;\n setChatId(detail.id);\n setMessages(detail.messages);\n if (detail.pendingApprovals?.length) {\n setPendingApprovals(detail.pendingApprovals);\n }\n })\n .catch((e) => {\n if (cancelled) return;\n setError((e as Error).message);\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n\n return () => { cancelled = true; };\n }, [client, options?.chatId]);\n\n // Cleanup on unmount\n React.useEffect(() => {\n return () => {\n abortRef.current?.abort();\n };\n }, []);\n\n const handleStreamChunks = React.useCallback(\n (chunk: SSEChunk) => {\n if (chunk.event === 'message') {\n try {\n const parsed = JSON.parse(chunk.data);\n if (parsed.content) {\n const targetId = activeAssistantIdRef.current;\n setMessages((prev) =>\n prev.map((m) =>\n m.id === targetId\n ? { ...m, content: (m.content || '') + parsed.content }\n : m,\n ),\n );\n }\n } catch {\n // Non-JSON content chunk — append raw data\n const targetId = activeAssistantIdRef.current;\n setMessages((prev) =>\n prev.map((m) =>\n m.id === targetId\n ? { ...m, content: (m.content || '') + chunk.data }\n : m,\n ),\n );\n }\n } else if (chunk.event === 'tool_start') {\n try {\n const parsed = JSON.parse(chunk.data);\n setToolStatus((prev) => [\n ...prev,\n { toolCallId: parsed.tool_call_id, name: parsed.name, description: parsed.description, status: 'running' },\n ]);\n // Insert tool call message before the streaming placeholder so\n // the \"Thinking...\" / status text stays at the bottom during execution.\n const placeholderId = activeAssistantIdRef.current;\n const toolCallMsg: ChatSessionMessage = {\n id: `tmp-tc-${parsed.tool_call_id}`,\n chatId: chatIdRef.current || '',\n role: 'assistant',\n content: null,\n toolCalls: [{\n id: parsed.tool_call_id,\n type: 'function',\n function: { name: parsed.name, arguments: parsed.arguments || '{}' },\n }],\n toolCallId: null,\n name: null,\n createdAt: new Date().toISOString(),\n };\n setMessages((prev) => {\n // Skip if a message for this tool call already exists (e.g. after approval\n // refresh replaced tmp IDs with server IDs, but tool call content is the same)\n const alreadyExists = prev.some((m) =>\n m.toolCalls?.some((tc) => tc.id === parsed.tool_call_id),\n );\n if (alreadyExists) return prev;\n const idx = prev.findIndex((m) => m.id === placeholderId);\n if (idx >= 0) {\n const next = [...prev];\n next.splice(idx, 0, toolCallMsg);\n return next;\n }\n return [...prev, toolCallMsg];\n });\n } catch {\n // ignore malformed tool_start events\n }\n } else if (chunk.event === 'tool_end') {\n try {\n const parsed = JSON.parse(chunk.data);\n setToolStatus((prev) =>\n prev.map((t) => t.toolCallId === parsed.tool_call_id ? { ...t, status: 'complete' } : t),\n );\n // Inject tool result message before the streaming placeholder\n if (parsed.result !== undefined) {\n const placeholderId = activeAssistantIdRef.current;\n const toolResultMsg: ChatSessionMessage = {\n id: `tmp-tr-${parsed.tool_call_id}`,\n chatId: chatIdRef.current || '',\n role: 'tool',\n content: typeof parsed.result === 'string' ? parsed.result : JSON.stringify(parsed.result),\n toolCalls: null,\n toolCallId: parsed.tool_call_id,\n name: parsed.name,\n createdAt: new Date().toISOString(),\n };\n setMessages((prev) => {\n const idx = prev.findIndex((m) => m.id === placeholderId);\n if (idx >= 0) {\n const next = [...prev];\n next.splice(idx, 0, toolResultMsg);\n return next;\n }\n return [...prev, toolResultMsg];\n });\n }\n } catch {\n // ignore malformed tool_end events\n }\n } else if (chunk.event === 'approval_required') {\n try {\n const raw = JSON.parse(chunk.data);\n const parsed: ApprovalRequest = {\n type: raw.type,\n toolCallId: raw.tool_call_id,\n functionNamespace: raw.function_namespace,\n functionName: raw.function_name,\n arguments: raw.arguments,\n };\n setPendingApprovals((prev) => [...prev, parsed]);\n } catch {\n // ignore malformed approval events\n }\n } else if (chunk.event === 'error') {\n try {\n const parsed = JSON.parse(chunk.data);\n setError(parsed.error || 'Stream error');\n } catch {\n setError(chunk.data || 'Stream error');\n }\n }\n },\n [],\n );\n\n const refreshMessages = React.useCallback(\n async (id: string) => {\n try {\n const detail = await getChat(client, id);\n setMessages(detail.messages);\n if (detail.pendingApprovals?.length) {\n setPendingApprovals(detail.pendingApprovals);\n }\n } catch {\n // Refresh is best-effort — streaming content already visible\n }\n },\n [client],\n );\n\n const send = React.useCallback(\n (content: MessageContent) => {\n const doSend = async () => {\n let activeChatId = chatIdRef.current;\n\n // Auto-create chat on first send\n if (!activeChatId) {\n setLoading(true);\n setError(null);\n try {\n const result = await createChat(client, agentRef, options?.input);\n activeChatId = result.id;\n setChatId(result.id);\n chatIdRef.current = result.id;\n } catch (e) {\n setError((e as Error).message);\n setLoading(false);\n return;\n }\n setLoading(false);\n }\n\n abortRef.current?.abort();\n setStreaming(true);\n setError(null);\n setPendingApprovals([]);\n setToolStatus([]);\n\n // Add user message optimistically\n const displayContent = typeof content === 'string' ? content : JSON.stringify(content);\n const userMsg: ChatSessionMessage = {\n id: `tmp-user-${Date.now()}`,\n chatId: activeChatId,\n role: 'user',\n content: displayContent,\n toolCalls: null,\n toolCallId: null,\n name: null,\n createdAt: new Date().toISOString(),\n };\n setMessages((prev) => [...prev, userMsg]);\n\n // Add empty assistant message to accumulate streaming content\n const assistantId = `tmp-assistant-${Date.now()}`;\n activeAssistantIdRef.current = assistantId;\n const assistantMsg: ChatSessionMessage = {\n id: assistantId,\n chatId: activeChatId,\n role: 'assistant',\n content: '',\n toolCalls: null,\n toolCallId: null,\n name: null,\n createdAt: new Date().toISOString(),\n streaming: true,\n };\n setMessages((prev) => [...prev, assistantMsg]);\n\n const controller = streamMessage(\n client,\n activeChatId,\n content,\n handleStreamChunks,\n () => {\n setStreaming(false);\n setToolStatus([]);\n // Remove empty streaming placeholders before server refresh replaces everything\n setMessages((prev) =>\n prev.filter(\n (m) => !(m.streaming && m.role === 'assistant' && !m.content && !m.toolCalls),\n ),\n );\n // Refresh to get authoritative server state (tool calls, tool responses)\n refreshMessages(activeChatId!);\n },\n (err: Error) => {\n setError(err.message);\n setStreaming(false);\n setToolStatus([]);\n },\n );\n\n abortRef.current = controller;\n };\n\n doSend();\n },\n [client, agentRef, options?.input, handleStreamChunks, refreshMessages],\n );\n\n const handleApproval = React.useCallback(\n (toolCallId: string, approved: boolean) => {\n const currentChatId = chatIdRef.current;\n if (!currentChatId) return;\n\n setPendingApprovals((prev) => prev.filter((a) => a.toolCallId !== toolCallId));\n setStreaming(true);\n setError(null);\n\n // Add placeholder assistant message for the resumed stream\n const assistantId = `tmp-resume-${Date.now()}`;\n activeAssistantIdRef.current = assistantId;\n if (approved) {\n const assistantMsg: ChatSessionMessage = {\n id: assistantId,\n chatId: currentChatId,\n role: 'assistant',\n content: '',\n toolCalls: null,\n toolCallId: null,\n name: null,\n createdAt: new Date().toISOString(),\n streaming: true,\n };\n setMessages((prev) => [...prev, assistantMsg]);\n }\n\n (async () => {\n try {\n const result = await approveToolCall(client, currentChatId, toolCallId, approved);\n\n if (!approved) {\n setStreaming(false);\n refreshMessages(currentChatId);\n return;\n }\n\n // Connect to resume stream\n const controller = streamFromChannel(\n client,\n currentChatId,\n result.channelId,\n handleStreamChunks,\n () => {\n setStreaming(false);\n setToolStatus([]);\n refreshMessages(currentChatId);\n },\n (err: Error) => {\n setError(err.message);\n setStreaming(false);\n setToolStatus([]);\n },\n );\n\n abortRef.current = controller;\n } catch (e) {\n setError((e as Error).message);\n setStreaming(false);\n }\n })();\n },\n [client, handleStreamChunks, refreshMessages],\n );\n\n const approve = React.useCallback(\n (toolCallId: string) => handleApproval(toolCallId, true),\n [handleApproval],\n );\n\n const reject = React.useCallback(\n (toolCallId: string) => handleApproval(toolCallId, false),\n [handleApproval],\n );\n\n const stop = React.useCallback(() => {\n abortRef.current?.abort();\n abortRef.current = null;\n setStreaming(false);\n }, []);\n\n const clearError = React.useCallback(() => {\n setError(null);\n }, []);\n\n return {\n chatId,\n messages,\n loading,\n streaming,\n error,\n pendingApprovals,\n toolStatus,\n send,\n approve,\n reject,\n stop,\n clearError,\n };\n}\n","import { useClient } from './context';\nimport { useQuery } from './useQuery';\nimport { useExecute } from './useExecute';\nimport { useStateStore } from './useStateStore';\nimport { useChat } from './useChat';\nimport type { SinasConfig } from '../client/types';\nimport type { SinasClient } from '../client/SinasClient';\n\nexport interface UseSinasResult {\n config: SinasConfig;\n input: Record<string, unknown>;\n client: SinasClient;\n useQuery: typeof useQuery;\n useExecute: typeof useExecute;\n useStateStore: typeof useStateStore;\n useChat: typeof useChat;\n}\n\nexport function useSinas(): UseSinasResult {\n const client = useClient();\n\n return {\n config: client.getConfig(),\n input: client.getInput(),\n client,\n useQuery,\n useExecute,\n useStateStore,\n useChat,\n };\n}\n"],"mappings":"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","names":["React","React","React","React","React","React","React","React"]}
|
package/dist/sinas-sdk.umd.js
CHANGED
|
@@ -306,7 +306,14 @@ var SinasSDK = (() => {
|
|
|
306
306
|
agentNamespace: data.agent_namespace,
|
|
307
307
|
agentName: data.agent_name,
|
|
308
308
|
title: data.title,
|
|
309
|
-
messages: (data.messages || []).map(mapMessage)
|
|
309
|
+
messages: (data.messages || []).map(mapMessage),
|
|
310
|
+
pendingApprovals: (data.pending_approvals || []).map((pa) => ({
|
|
311
|
+
type: "approval_required",
|
|
312
|
+
toolCallId: pa.tool_call_id,
|
|
313
|
+
functionNamespace: pa.function_namespace,
|
|
314
|
+
functionName: pa.function_name,
|
|
315
|
+
arguments: pa.arguments || {}
|
|
316
|
+
}))
|
|
310
317
|
};
|
|
311
318
|
}
|
|
312
319
|
async function approveToolCall(client, chatId, toolCallId, approved) {
|
|
@@ -634,9 +641,11 @@ var SinasSDK = (() => {
|
|
|
634
641
|
const [streaming, setStreaming] = import_react5.default.useState(false);
|
|
635
642
|
const [error, setError] = import_react5.default.useState(null);
|
|
636
643
|
const [pendingApprovals, setPendingApprovals] = import_react5.default.useState([]);
|
|
644
|
+
const [toolStatus, setToolStatus] = import_react5.default.useState([]);
|
|
637
645
|
const abortRef = import_react5.default.useRef(null);
|
|
638
646
|
const chatIdRef = import_react5.default.useRef(chatId);
|
|
639
647
|
chatIdRef.current = chatId;
|
|
648
|
+
const activeAssistantIdRef = import_react5.default.useRef("");
|
|
640
649
|
import_react5.default.useEffect(() => {
|
|
641
650
|
if (!options?.chatId) return;
|
|
642
651
|
let cancelled = false;
|
|
@@ -645,6 +654,9 @@ var SinasSDK = (() => {
|
|
|
645
654
|
if (cancelled) return;
|
|
646
655
|
setChatId(detail.id);
|
|
647
656
|
setMessages(detail.messages);
|
|
657
|
+
if (detail.pendingApprovals?.length) {
|
|
658
|
+
setPendingApprovals(detail.pendingApprovals);
|
|
659
|
+
}
|
|
648
660
|
}).catch((e) => {
|
|
649
661
|
if (cancelled) return;
|
|
650
662
|
setError(e.message);
|
|
@@ -661,27 +673,103 @@ var SinasSDK = (() => {
|
|
|
661
673
|
};
|
|
662
674
|
}, []);
|
|
663
675
|
const handleStreamChunks = import_react5.default.useCallback(
|
|
664
|
-
(
|
|
676
|
+
(chunk) => {
|
|
665
677
|
if (chunk.event === "message") {
|
|
666
678
|
try {
|
|
667
679
|
const parsed = JSON.parse(chunk.data);
|
|
668
680
|
if (parsed.content) {
|
|
681
|
+
const targetId = activeAssistantIdRef.current;
|
|
669
682
|
setMessages(
|
|
670
683
|
(prev) => prev.map(
|
|
671
|
-
(m) => m.id ===
|
|
684
|
+
(m) => m.id === targetId ? { ...m, content: (m.content || "") + parsed.content } : m
|
|
672
685
|
)
|
|
673
686
|
);
|
|
674
687
|
}
|
|
675
688
|
} catch {
|
|
689
|
+
const targetId = activeAssistantIdRef.current;
|
|
676
690
|
setMessages(
|
|
677
691
|
(prev) => prev.map(
|
|
678
|
-
(m) => m.id ===
|
|
692
|
+
(m) => m.id === targetId ? { ...m, content: (m.content || "") + chunk.data } : m
|
|
679
693
|
)
|
|
680
694
|
);
|
|
681
695
|
}
|
|
682
|
-
} else if (chunk.event === "
|
|
696
|
+
} else if (chunk.event === "tool_start") {
|
|
683
697
|
try {
|
|
684
698
|
const parsed = JSON.parse(chunk.data);
|
|
699
|
+
setToolStatus((prev) => [
|
|
700
|
+
...prev,
|
|
701
|
+
{ toolCallId: parsed.tool_call_id, name: parsed.name, description: parsed.description, status: "running" }
|
|
702
|
+
]);
|
|
703
|
+
const placeholderId = activeAssistantIdRef.current;
|
|
704
|
+
const toolCallMsg = {
|
|
705
|
+
id: `tmp-tc-${parsed.tool_call_id}`,
|
|
706
|
+
chatId: chatIdRef.current || "",
|
|
707
|
+
role: "assistant",
|
|
708
|
+
content: null,
|
|
709
|
+
toolCalls: [{
|
|
710
|
+
id: parsed.tool_call_id,
|
|
711
|
+
type: "function",
|
|
712
|
+
function: { name: parsed.name, arguments: parsed.arguments || "{}" }
|
|
713
|
+
}],
|
|
714
|
+
toolCallId: null,
|
|
715
|
+
name: null,
|
|
716
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
717
|
+
};
|
|
718
|
+
setMessages((prev) => {
|
|
719
|
+
const alreadyExists = prev.some(
|
|
720
|
+
(m) => m.toolCalls?.some((tc) => tc.id === parsed.tool_call_id)
|
|
721
|
+
);
|
|
722
|
+
if (alreadyExists) return prev;
|
|
723
|
+
const idx = prev.findIndex((m) => m.id === placeholderId);
|
|
724
|
+
if (idx >= 0) {
|
|
725
|
+
const next = [...prev];
|
|
726
|
+
next.splice(idx, 0, toolCallMsg);
|
|
727
|
+
return next;
|
|
728
|
+
}
|
|
729
|
+
return [...prev, toolCallMsg];
|
|
730
|
+
});
|
|
731
|
+
} catch {
|
|
732
|
+
}
|
|
733
|
+
} else if (chunk.event === "tool_end") {
|
|
734
|
+
try {
|
|
735
|
+
const parsed = JSON.parse(chunk.data);
|
|
736
|
+
setToolStatus(
|
|
737
|
+
(prev) => prev.map((t) => t.toolCallId === parsed.tool_call_id ? { ...t, status: "complete" } : t)
|
|
738
|
+
);
|
|
739
|
+
if (parsed.result !== void 0) {
|
|
740
|
+
const placeholderId = activeAssistantIdRef.current;
|
|
741
|
+
const toolResultMsg = {
|
|
742
|
+
id: `tmp-tr-${parsed.tool_call_id}`,
|
|
743
|
+
chatId: chatIdRef.current || "",
|
|
744
|
+
role: "tool",
|
|
745
|
+
content: typeof parsed.result === "string" ? parsed.result : JSON.stringify(parsed.result),
|
|
746
|
+
toolCalls: null,
|
|
747
|
+
toolCallId: parsed.tool_call_id,
|
|
748
|
+
name: parsed.name,
|
|
749
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
750
|
+
};
|
|
751
|
+
setMessages((prev) => {
|
|
752
|
+
const idx = prev.findIndex((m) => m.id === placeholderId);
|
|
753
|
+
if (idx >= 0) {
|
|
754
|
+
const next = [...prev];
|
|
755
|
+
next.splice(idx, 0, toolResultMsg);
|
|
756
|
+
return next;
|
|
757
|
+
}
|
|
758
|
+
return [...prev, toolResultMsg];
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
} catch {
|
|
762
|
+
}
|
|
763
|
+
} else if (chunk.event === "approval_required") {
|
|
764
|
+
try {
|
|
765
|
+
const raw = JSON.parse(chunk.data);
|
|
766
|
+
const parsed = {
|
|
767
|
+
type: raw.type,
|
|
768
|
+
toolCallId: raw.tool_call_id,
|
|
769
|
+
functionNamespace: raw.function_namespace,
|
|
770
|
+
functionName: raw.function_name,
|
|
771
|
+
arguments: raw.arguments
|
|
772
|
+
};
|
|
685
773
|
setPendingApprovals((prev) => [...prev, parsed]);
|
|
686
774
|
} catch {
|
|
687
775
|
}
|
|
@@ -701,6 +789,9 @@ var SinasSDK = (() => {
|
|
|
701
789
|
try {
|
|
702
790
|
const detail = await getChat(client, id);
|
|
703
791
|
setMessages(detail.messages);
|
|
792
|
+
if (detail.pendingApprovals?.length) {
|
|
793
|
+
setPendingApprovals(detail.pendingApprovals);
|
|
794
|
+
}
|
|
704
795
|
} catch {
|
|
705
796
|
}
|
|
706
797
|
},
|
|
@@ -729,6 +820,7 @@ var SinasSDK = (() => {
|
|
|
729
820
|
setStreaming(true);
|
|
730
821
|
setError(null);
|
|
731
822
|
setPendingApprovals([]);
|
|
823
|
+
setToolStatus([]);
|
|
732
824
|
const displayContent = typeof content === "string" ? content : JSON.stringify(content);
|
|
733
825
|
const userMsg = {
|
|
734
826
|
id: `tmp-user-${Date.now()}`,
|
|
@@ -742,6 +834,7 @@ var SinasSDK = (() => {
|
|
|
742
834
|
};
|
|
743
835
|
setMessages((prev) => [...prev, userMsg]);
|
|
744
836
|
const assistantId = `tmp-assistant-${Date.now()}`;
|
|
837
|
+
activeAssistantIdRef.current = assistantId;
|
|
745
838
|
const assistantMsg = {
|
|
746
839
|
id: assistantId,
|
|
747
840
|
chatId: activeChatId,
|
|
@@ -758,14 +851,21 @@ var SinasSDK = (() => {
|
|
|
758
851
|
client,
|
|
759
852
|
activeChatId,
|
|
760
853
|
content,
|
|
761
|
-
handleStreamChunks
|
|
854
|
+
handleStreamChunks,
|
|
762
855
|
() => {
|
|
763
856
|
setStreaming(false);
|
|
857
|
+
setToolStatus([]);
|
|
858
|
+
setMessages(
|
|
859
|
+
(prev) => prev.filter(
|
|
860
|
+
(m) => !(m.streaming && m.role === "assistant" && !m.content && !m.toolCalls)
|
|
861
|
+
)
|
|
862
|
+
);
|
|
764
863
|
refreshMessages(activeChatId);
|
|
765
864
|
},
|
|
766
865
|
(err) => {
|
|
767
866
|
setError(err.message);
|
|
768
867
|
setStreaming(false);
|
|
868
|
+
setToolStatus([]);
|
|
769
869
|
}
|
|
770
870
|
);
|
|
771
871
|
abortRef.current = controller;
|
|
@@ -782,6 +882,7 @@ var SinasSDK = (() => {
|
|
|
782
882
|
setStreaming(true);
|
|
783
883
|
setError(null);
|
|
784
884
|
const assistantId = `tmp-resume-${Date.now()}`;
|
|
885
|
+
activeAssistantIdRef.current = assistantId;
|
|
785
886
|
if (approved) {
|
|
786
887
|
const assistantMsg = {
|
|
787
888
|
id: assistantId,
|
|
@@ -808,14 +909,16 @@ var SinasSDK = (() => {
|
|
|
808
909
|
client,
|
|
809
910
|
currentChatId,
|
|
810
911
|
result.channelId,
|
|
811
|
-
handleStreamChunks
|
|
912
|
+
handleStreamChunks,
|
|
812
913
|
() => {
|
|
813
914
|
setStreaming(false);
|
|
915
|
+
setToolStatus([]);
|
|
814
916
|
refreshMessages(currentChatId);
|
|
815
917
|
},
|
|
816
918
|
(err) => {
|
|
817
919
|
setError(err.message);
|
|
818
920
|
setStreaming(false);
|
|
921
|
+
setToolStatus([]);
|
|
819
922
|
}
|
|
820
923
|
);
|
|
821
924
|
abortRef.current = controller;
|
|
@@ -850,6 +953,7 @@ var SinasSDK = (() => {
|
|
|
850
953
|
streaming,
|
|
851
954
|
error,
|
|
852
955
|
pendingApprovals,
|
|
956
|
+
toolStatus,
|
|
853
957
|
send,
|
|
854
958
|
approve,
|
|
855
959
|
reject,
|