@better-agent/client 0.1.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/core/sse.ts","../src/core/client/errors.ts","../src/core/client/request.ts","../src/core/client/tool-submission.ts","../src/core/client/index.ts"],"sourcesContent":["import { Events } from \"@better-agent/core/events\";\nimport type { ClientEvent } from \"../types/client\";\n\nconst isEventType = (value: string): value is ClientEvent[\"type\"] =>\n Object.values(Events).includes(value as ClientEvent[\"type\"]);\n\ntype PendingSseFrame = {\n data: string;\n eventName?: string;\n id?: number;\n};\n\nconst resetFrame = (): PendingSseFrame => ({ data: \"\" });\n\n// Throw SSE `event: error` frames instead of yielding them.\nconst getSseErrorMessage = (data: string): string => {\n try {\n const parsed = JSON.parse(data) as { message?: unknown };\n if (typeof parsed.message === \"string\" && parsed.message.trim().length > 0) {\n return parsed.message;\n }\n } catch {}\n\n return data.trim().length > 0 ? data.trim() : \"Stream failed\";\n};\n\nconst parseFrame = (\n frame: PendingSseFrame,\n options: { onId?: (id: number) => void },\n): ClientEvent | null => {\n if (!frame.data) {\n return null;\n }\n\n const data = frame.data.replace(/\\n$/, \"\");\n if (frame.eventName === \"error\") {\n throw new Error(getSseErrorMessage(data));\n }\n\n try {\n const parsed = JSON.parse(data) as ClientEvent;\n if (!(parsed && typeof parsed === \"object\" && typeof parsed.type === \"string\")) {\n return null;\n }\n if (!isEventType(parsed.type)) {\n return null;\n }\n if (typeof frame.id === \"number\") {\n parsed.seq = frame.id;\n options.onId?.(frame.id);\n }\n return parsed;\n } catch {\n return null;\n }\n};\n\nexport async function* parseSse(\n body: ReadableStream<Uint8Array>,\n options: { onId?: (id: number) => void } = {},\n): AsyncIterable<ClientEvent> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let frame = resetFrame();\n\n while (true) {\n const chunk = await reader.read();\n const { done, value } = chunk;\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n for (;;) {\n const nl = buffer.indexOf(\"\\n\");\n if (nl < 0) break;\n\n const line = buffer.slice(0, nl).replace(/\\r$/, \"\");\n buffer = buffer.slice(nl + 1);\n\n // Blank line ends the frame.\n if (line === \"\") {\n const event = parseFrame(frame, options);\n frame = resetFrame();\n if (event) {\n yield event;\n }\n continue;\n }\n\n if (line.startsWith(\"event:\")) {\n frame.eventName = line.slice(6).trim();\n continue;\n }\n if (line.startsWith(\"id:\")) {\n const idValue = Number(line.slice(3).trim());\n frame.id = Number.isFinite(idValue) ? idValue : undefined;\n continue;\n }\n if (line.startsWith(\"data:\")) {\n frame.data += `${line.slice(5).trim()}\\n`;\n }\n }\n }\n\n const finalEvent = parseFrame(frame, options);\n if (finalEvent) {\n yield finalEvent;\n }\n}\n","import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport type { PrepareRequestContext } from \"../../types/client\";\n\ntype ParsedErrorBody = {\n error?: unknown;\n code?: unknown;\n message?: unknown;\n detail?: unknown;\n title?: unknown;\n status?: unknown;\n retryable?: unknown;\n traceId?: unknown;\n context?: unknown;\n issues?: unknown;\n trace?: unknown;\n};\n\nconst tryParseJson = (bodyText: string): ParsedErrorBody | null => {\n try {\n return JSON.parse(bodyText) as ParsedErrorBody;\n } catch {\n return null;\n }\n};\n\nconst parseErrorBody = (bodyText: string) => {\n let errorCodeFromBody: string | undefined;\n let errorMessageFromBody: string | undefined;\n let errorTitleFromBody: string | undefined;\n let errorStatusFromBody: number | undefined;\n let retryableFromBody: boolean | undefined;\n let traceIdFromBody: string | undefined;\n let issuesFromBody: unknown[] | undefined;\n let contextFromBody: Record<string, unknown> | undefined;\n let traceFromBody: Array<{ at: string; data?: Record<string, unknown> }> | undefined;\n\n if (bodyText.length > 0) {\n const parsed = tryParseJson(bodyText);\n if (parsed) {\n if (typeof parsed.code === \"string\") errorCodeFromBody = parsed.code;\n else if (typeof parsed.error === \"string\") errorCodeFromBody = parsed.error;\n if (typeof parsed.message === \"string\") errorMessageFromBody = parsed.message;\n else if (typeof parsed.detail === \"string\") errorMessageFromBody = parsed.detail;\n if (typeof parsed.title === \"string\") errorTitleFromBody = parsed.title;\n if (typeof parsed.status === \"number\") errorStatusFromBody = parsed.status;\n if (typeof parsed.retryable === \"boolean\") retryableFromBody = parsed.retryable;\n if (typeof parsed.traceId === \"string\") traceIdFromBody = parsed.traceId;\n if (Array.isArray(parsed.issues)) issuesFromBody = parsed.issues;\n if (typeof parsed.context === \"object\" && parsed.context !== null) {\n contextFromBody = parsed.context as Record<string, unknown>;\n }\n if (Array.isArray(parsed.trace)) {\n traceFromBody = parsed.trace as Array<{\n at: string;\n data?: Record<string, unknown>;\n }>;\n }\n }\n }\n\n return {\n errorCodeFromBody,\n errorMessageFromBody,\n errorTitleFromBody,\n errorStatusFromBody,\n retryableFromBody,\n traceIdFromBody,\n issuesFromBody,\n contextFromBody,\n traceFromBody,\n };\n};\n\nconst getContentType = (response: Response): string =>\n response.headers.get(\"content-type\")?.toLowerCase() ?? \"\";\n\nconst isHtmlResponse = (response: Response): boolean =>\n getContentType(response).includes(\"text/html\");\n\nconst truncateForContext = (value: string, maxLength = 300): string =>\n value.length <= maxLength ? value : `${value.slice(0, maxLength)}...`;\n\nexport const throwRequestError = async (params: {\n response: Response;\n operation: PrepareRequestContext[\"operation\"];\n at: string;\n context: Record<string, unknown>;\n}) => {\n const bodyText = (await params.response.text().catch(() => \"\")).trim();\n const {\n errorCodeFromBody,\n errorMessageFromBody,\n errorTitleFromBody,\n errorStatusFromBody,\n retryableFromBody,\n traceIdFromBody,\n issuesFromBody,\n contextFromBody,\n traceFromBody,\n } = parseErrorBody(bodyText);\n\n const fallbackDetail = isHtmlResponse(params.response)\n ? \"Server returned an HTML error page. This usually means a framework or dev-server failure before the API handler ran.\"\n : params.response.statusText || \"Unknown error\";\n\n const detail =\n errorMessageFromBody ??\n (bodyText.length > 0 && !isHtmlResponse(params.response) ? bodyText : undefined) ??\n fallbackDetail;\n\n const error = Object.assign(\n BetterAgentError.fromCode(\n errorCodeFromBody ??\n (params.response.status >= 500 || params.response.status === 429\n ? \"UPSTREAM_FAILED\"\n : \"BAD_REQUEST\"),\n detail,\n {\n title: errorTitleFromBody,\n status: errorStatusFromBody ?? params.response.status,\n retryable: retryableFromBody,\n traceId: traceIdFromBody,\n context: {\n ...params.context,\n operation: params.operation,\n status: params.response.status,\n ...(contextFromBody ?? {}),\n error: errorCodeFromBody,\n issues: issuesFromBody,\n ...(isHtmlResponse(params.response) && bodyText.length > 0\n ? {\n responseContentType: getContentType(params.response),\n responseBodySnippet: truncateForContext(bodyText),\n }\n : {}),\n },\n trace: [...(traceFromBody ?? []), { at: params.at }],\n },\n ),\n issuesFromBody ? { issues: issuesFromBody } : {},\n );\n\n throw error;\n};\n","import type { ClientConfig, HttpMethod, PrepareRequestContext } from \"../../types/client\";\n\nexport const mergeHeaders = (\n ...parts: Array<Headers | Record<string, string> | undefined>\n): Headers => {\n const merged = new Headers();\n for (const part of parts) {\n if (!part) continue;\n new Headers(part).forEach((value, key) => merged.set(key, value));\n }\n return merged;\n};\n\nexport const prepareRequest = async (\n advanced: ClientConfig[\"advanced\"] | undefined,\n context: PrepareRequestContext,\n): Promise<{\n url: string;\n method: HttpMethod;\n headers: Headers | Record<string, string>;\n body?: BodyInit | null;\n}> => {\n if (!advanced?.prepareRequest) {\n return {\n url: context.url,\n method: context.method,\n headers: context.headers,\n body: context.body,\n };\n }\n\n const prepared = await advanced.prepareRequest(context);\n if (!prepared) {\n return {\n url: context.url,\n method: context.method,\n headers: context.headers,\n body: context.body,\n };\n }\n\n return {\n url: prepared.url ?? context.url,\n method: prepared.method ?? context.method,\n headers: prepared.headers ?? context.headers,\n ...(prepared.body !== undefined\n ? { body: prepared.body }\n : context.body !== undefined\n ? { body: context.body }\n : {}),\n };\n};\n","import type { ClientConfig } from \"../../types/client\";\nimport { throwRequestError } from \"./errors\";\nimport { mergeHeaders, prepareRequest } from \"./request\";\n\ntype ToolSubmissionDeps = {\n advanced: ClientConfig[\"advanced\"] | undefined;\n baseURL: string;\n defaultHeaders?: Headers | Record<string, string>;\n doFetch: typeof fetch;\n secret?: string;\n toolSubmissionMaxAttempts: number;\n toolSubmissionRetryDelayMs: number;\n};\n\ntype SubmitToolResultParams = {\n agent: string;\n runId: string;\n toolCallId: string;\n result?: unknown;\n error?: string;\n};\n\ntype SubmitToolApprovalParams = {\n agent: string;\n runId: string;\n toolCallId: string;\n decision: \"approved\" | \"denied\";\n note?: string;\n actorId?: string;\n};\n\nconst sleep = async (ms: number) => {\n await new Promise((resolve) => setTimeout(resolve, ms));\n};\n\nexport const createToolSubmissionHandlers = (deps: ToolSubmissionDeps) => {\n const doFetch = deps.doFetch;\n const authHeaders = deps.secret ? { authorization: `Bearer ${deps.secret}` } : undefined;\n\n const submitToolResult = async (params: SubmitToolResultParams) => {\n const payload = JSON.stringify({\n runId: params.runId,\n toolCallId: params.toolCallId,\n ...(params.error !== undefined\n ? { status: \"error\", error: params.error }\n : { status: \"success\", result: params.result }),\n });\n\n for (let attempt = 1; attempt <= deps.toolSubmissionMaxAttempts; attempt++) {\n try {\n const prepared = await prepareRequest(deps.advanced, {\n operation: \"tool-result\",\n url: `${deps.baseURL}/${encodeURIComponent(params.agent)}/run/tool-result`,\n method: \"POST\",\n headers: mergeHeaders(\n authHeaders,\n { \"content-type\": \"application/json\" },\n deps.defaultHeaders,\n ),\n body: payload,\n });\n\n const res = await doFetch(prepared.url, {\n method: prepared.method,\n headers: prepared.headers,\n body: prepared.body,\n });\n\n if (res.ok) return;\n\n const isRetryable = res.status >= 500 || res.status === 429;\n\n if (!isRetryable || attempt === deps.toolSubmissionMaxAttempts) {\n await throwRequestError({\n response: res,\n operation: \"tool-result\",\n at: \"client.core.submitToolResult\",\n context: {\n agentName: params.agent,\n runId: params.runId,\n toolCallId: params.toolCallId,\n },\n });\n }\n\n await sleep(deps.toolSubmissionRetryDelayMs * attempt);\n } catch (error) {\n const wrapped =\n error instanceof Error\n ? error\n : new Error(\"Tool result submission failed.\", { cause: error });\n if (attempt === deps.toolSubmissionMaxAttempts) throw wrapped;\n await sleep(deps.toolSubmissionRetryDelayMs * attempt);\n }\n }\n };\n\n const submitToolApproval = async (params: SubmitToolApprovalParams) => {\n const payload = JSON.stringify({\n runId: params.runId,\n toolCallId: params.toolCallId,\n decision: params.decision,\n ...(params.note !== undefined ? { note: params.note } : {}),\n ...(params.actorId !== undefined ? { actorId: params.actorId } : {}),\n });\n\n for (let attempt = 1; attempt <= deps.toolSubmissionMaxAttempts; attempt++) {\n try {\n const prepared = await prepareRequest(deps.advanced, {\n operation: \"tool-approval\",\n url: `${deps.baseURL}/${encodeURIComponent(params.agent)}/run/tool-approval`,\n method: \"POST\",\n headers: mergeHeaders(\n authHeaders,\n { \"content-type\": \"application/json\" },\n deps.defaultHeaders,\n ),\n body: payload,\n });\n\n const res = await doFetch(prepared.url, {\n method: prepared.method,\n headers: prepared.headers,\n body: prepared.body,\n });\n\n if (res.ok) return;\n\n const isRetryable = res.status >= 500 || res.status === 429;\n if (!isRetryable || attempt === deps.toolSubmissionMaxAttempts) {\n await throwRequestError({\n response: res,\n operation: \"tool-approval\",\n at: \"client.core.submitToolApproval\",\n context: {\n agentName: params.agent,\n runId: params.runId,\n toolCallId: params.toolCallId,\n decision: params.decision,\n },\n });\n }\n\n await sleep(deps.toolSubmissionRetryDelayMs * attempt);\n } catch (error) {\n const wrapped =\n error instanceof Error\n ? error\n : new Error(\"Tool approval submission failed.\", { cause: error });\n if (attempt === deps.toolSubmissionMaxAttempts) throw wrapped;\n await sleep(deps.toolSubmissionRetryDelayMs * attempt);\n }\n }\n };\n\n return {\n submitToolApproval,\n submitToolResult,\n };\n};\n","import type {\n BetterAgentClient,\n ClientConfig,\n ReplayInput,\n RequestOptions,\n StreamRequestOptions,\n ToolCallContext,\n} from \"../../types/client\";\nimport type {\n AgentNameFromApp,\n ModalitiesForAgent,\n NormalizeClientApp,\n RunInputForAgent,\n} from \"../../types/client-type-helpers\";\nimport { parseSse } from \"../sse\";\nimport { throwRequestError } from \"./errors\";\nimport { mergeHeaders, prepareRequest } from \"./request\";\nimport { createToolSubmissionHandlers } from \"./tool-submission\";\n\n/**\n * Creates a Better Agent client.\n *\n * @param config Client configuration.\n * @returns A typed client.\n *\n * @example\n * ```ts\n * import { createClient } from \"@better-agent/client\";\n *\n * const client = createClient({\n * baseURL: \"http://localhost:3000/api\",\n * secret: \"dev_secret\",\n * });\n *\n * const result = await client.run(\"helloAgent\", {\n * input: \"Write one short sentence about TypeScript.\",\n * });\n * ```\n *\n * @example\n * ```ts\n * import type ba from \"./better-agent/server\";\n * import { createClient } from \"@better-agent/client\";\n *\n * const client = createClient<typeof ba>({\n * baseURL: \"http://localhost:3000/api\",\n * secret: \"dev_secret\",\n * toolHandlers: {\n * getClientTime: () => ({ now: new Date().toISOString() }),\n * },\n * });\n *\n * for await (const event of client.stream(\"helloAgent\", {\n * input: \"Use tools if needed.\",\n * })) {\n * console.log(event.type);\n * }\n * ```\n */\nexport const createClient = <TApp = unknown>(\n config: ClientConfig<TApp>,\n): BetterAgentClient<NormalizeClientApp<TApp>> => {\n type TClientApp = NormalizeClientApp<TApp>;\n\n const baseURL = config.baseURL.replace(/\\/$/, \"\");\n const doFetch = config.fetch ?? fetch;\n const advanced = config.advanced;\n const authHeaders = config.secret ? { authorization: `Bearer ${config.secret}` } : undefined;\n\n const toolSubmissionMaxAttempts = Math.max(\n 1,\n Math.floor(advanced?.toolSubmissionMaxAttempts ?? 3),\n );\n const toolSubmissionRetryDelayMs = Math.max(0, advanced?.toolSubmissionRetryDelayMs ?? 150);\n\n const { submitToolResult, submitToolApproval } = createToolSubmissionHandlers({\n advanced,\n baseURL,\n defaultHeaders: config.headers,\n doFetch,\n secret: config.secret,\n toolSubmissionMaxAttempts,\n toolSubmissionRetryDelayMs,\n });\n\n const client = {\n async run<\n TAgentName extends AgentNameFromApp<TClientApp>,\n const TModalities extends\n | ModalitiesForAgent<TClientApp, TAgentName>\n | undefined = undefined,\n >(\n agent: TAgentName,\n input: RunInputForAgent<TClientApp, TAgentName, TModalities>,\n options?: RequestOptions<TClientApp>,\n ) {\n const request = { agent, ...input };\n const prepared = await prepareRequest(advanced, {\n operation: \"run\",\n url: `${baseURL}/${encodeURIComponent(String(agent))}/run`,\n method: \"POST\",\n headers: mergeHeaders(\n authHeaders,\n { \"content-type\": \"application/json\" },\n config.headers,\n options?.headers,\n ),\n body: JSON.stringify(request),\n });\n\n const res = await doFetch(prepared.url, {\n method: prepared.method,\n headers: prepared.headers,\n ...(prepared.body !== undefined ? { body: prepared.body } : {}),\n signal: options?.signal ?? null,\n });\n options?.onResponse?.(res);\n if (!res.ok) {\n await throwRequestError({\n response: res,\n operation: \"run\",\n at: \"client.core.run\",\n context: { agentName: agent },\n });\n }\n\n return await res.json();\n },\n\n stream<\n TAgentName extends AgentNameFromApp<TClientApp>,\n const TModalities extends\n | ModalitiesForAgent<TClientApp, TAgentName>\n | undefined = undefined,\n >(\n agent: TAgentName,\n input: RunInputForAgent<TClientApp, TAgentName, TModalities>,\n options?: StreamRequestOptions<TClientApp>,\n ) {\n const request = { agent, ...input };\n\n return (async function* () {\n const pendingToolCalls = new Map<string, PendingToolCall>();\n const toolCallController = new AbortController();\n // Local tool handlers should stop when the stream ends or the caller aborts.\n const abortToolCalls = () => {\n if (!toolCallController.signal.aborted) toolCallController.abort();\n };\n\n const externalSignal = options?.signal;\n // Forward the caller's abort signal into the client-tool execution context.\n const onExternalAbort = () => abortToolCalls();\n if (externalSignal) {\n if (externalSignal.aborted) {\n abortToolCalls();\n } else {\n externalSignal.addEventListener(\"abort\", onExternalAbort, {\n once: true,\n });\n }\n }\n\n const processClientToolCall = async (\n toolCallKey: string,\n runId: string,\n toolCallId: string,\n ) => {\n const pending = pendingToolCalls.get(toolCallKey);\n // Execute each client tool once, and only after args are complete and approval allows it.\n if (\n !pending ||\n pending.submitted ||\n !pending.ended ||\n (pending.approvalState !== \"waiting\" &&\n pending.approvalState !== \"approved\")\n ) {\n return;\n }\n\n pending.submitted = true;\n\n let parsedArgs: unknown = {};\n try {\n parsedArgs = pending.argsJson ? JSON.parse(pending.argsJson) : {};\n } catch {\n await submitToolResult({\n agent: String(agent),\n runId,\n toolCallId,\n error: `Invalid client tool arguments for '${pending.toolName}'.`,\n });\n return;\n }\n\n const context: ToolCallContext<TClientApp> = {\n agent,\n runId,\n toolCallId,\n // Client tool handlers get a signal that is tied to the stream lifecycle.\n signal: toolCallController.signal,\n };\n\n const handler = resolveToolHandler(\n pending.toolName,\n options,\n config.toolHandlers,\n );\n if (!handler) {\n await submitToolResult({\n agent: String(agent),\n runId,\n toolCallId,\n error: `Missing client tool handler for '${pending.toolName}'.`,\n });\n return;\n }\n\n try {\n const result = await Promise.resolve(\n handler({\n toolName: pending.toolName,\n input: parsedArgs,\n context,\n }),\n );\n await submitToolResult({\n agent: String(agent),\n runId,\n toolCallId,\n result,\n });\n } catch (error) {\n await submitToolResult({\n agent: String(agent),\n runId,\n toolCallId,\n error:\n error instanceof Error\n ? error.message\n : \"Client tool handler failed.\",\n });\n }\n };\n\n try {\n const prepared = await prepareRequest(advanced, {\n operation: \"stream\",\n url: `${baseURL}/${encodeURIComponent(String(agent))}/run`,\n method: \"POST\",\n headers: mergeHeaders(\n authHeaders,\n {\n \"content-type\": \"application/json\",\n accept: \"text/event-stream\",\n },\n config.headers,\n options?.headers,\n ),\n body: JSON.stringify({ ...request, stream: true }),\n });\n\n const res = await doFetch(prepared.url, {\n method: prepared.method,\n headers: prepared.headers,\n body: prepared.body,\n signal: options?.signal ?? null,\n });\n options?.onResponse?.(res);\n if (!res.ok) {\n await throwRequestError({\n response: res,\n operation: \"stream\",\n at: \"client.core.stream\",\n context: { agentName: agent },\n });\n }\n\n if (!res.body) return;\n\n for await (const ev of parseSse(res.body)) {\n if (ev.type === \"TOOL_CALL_START\") {\n if (ev.toolTarget !== \"client\") {\n yield ev;\n continue;\n }\n if (typeof ev.runId === \"string\") {\n pendingToolCalls.set(getToolCallKey(ev.runId, ev.toolCallId), {\n toolName: ev.toolCallName,\n argsJson: \"\",\n ended: false,\n submitted: false,\n approvalState: \"waiting\",\n });\n }\n } else if (ev.type === \"TOOL_CALL_ARGS\") {\n if (typeof ev.runId !== \"string\") {\n yield ev;\n continue;\n }\n const pending = pendingToolCalls.get(\n getToolCallKey(ev.runId, ev.toolCallId),\n );\n if (pending) pending.argsJson += ev.delta;\n } else if (ev.type === \"TOOL_CALL_END\" && typeof ev.runId === \"string\") {\n const toolCallKey = getToolCallKey(ev.runId, ev.toolCallId);\n const pending = pendingToolCalls.get(toolCallKey);\n if (pending) {\n pending.ended = true;\n await processClientToolCall(toolCallKey, ev.runId, ev.toolCallId);\n }\n } else if (\n (ev.type === \"TOOL_APPROVAL_REQUIRED\" ||\n ev.type === \"TOOL_APPROVAL_UPDATED\") &&\n ev.toolTarget === \"client\" &&\n typeof ev.runId === \"string\"\n ) {\n const toolCallKey = getToolCallKey(ev.runId, ev.toolCallId);\n const pending = pendingToolCalls.get(toolCallKey);\n if (pending) {\n pending.approvalState =\n ev.state === \"approved\"\n ? \"approved\"\n : ev.state === \"requested\"\n ? \"requested\"\n : ev.state === \"denied\"\n ? \"denied\"\n : \"expired\";\n\n if (\n pending.approvalState === \"denied\" ||\n pending.approvalState === \"expired\"\n ) {\n pending.submitted = true;\n pendingToolCalls.delete(toolCallKey);\n } else if (pending.approvalState === \"approved\") {\n await processClientToolCall(\n toolCallKey,\n ev.runId,\n ev.toolCallId,\n );\n }\n }\n }\n\n if (\n ev.type === \"RUN_ABORTED\" ||\n ev.type === \"RUN_ERROR\" ||\n ev.type === \"RUN_FINISHED\"\n ) {\n // Once the run ends, any local tool work should stop and completed entries can be dropped.\n for (const [toolCallKey, pending] of pendingToolCalls) {\n if (pending.submitted) pendingToolCalls.delete(toolCallKey);\n }\n abortToolCalls();\n }\n\n yield ev;\n }\n } finally {\n abortToolCalls();\n if (externalSignal) {\n externalSignal.removeEventListener(\"abort\", onExternalAbort);\n }\n pendingToolCalls.clear();\n }\n })();\n },\n\n resumeStream<TAgentName extends AgentNameFromApp<TClientApp>>(\n agent: TAgentName,\n input: ReplayInput,\n options?: RequestOptions<TClientApp>,\n ) {\n return (async function* () {\n const searchParams = new URLSearchParams();\n searchParams.set(\"streamId\", input.streamId);\n\n const headers = mergeHeaders(\n authHeaders,\n { accept: \"text/event-stream\" },\n config.headers,\n options?.headers,\n );\n\n if (typeof input.afterSeq === \"number\") {\n headers.set(\"last-event-id\", String(input.afterSeq));\n }\n\n const prepared = await prepareRequest(advanced, {\n operation: \"resume-stream\",\n url: `${baseURL}/${encodeURIComponent(String(agent))}/stream-events/resume?${searchParams.toString()}`,\n method: \"GET\",\n headers,\n });\n\n const res = await doFetch(prepared.url, {\n method: prepared.method,\n headers: prepared.headers,\n ...(prepared.body !== undefined ? { body: prepared.body } : {}),\n signal: options?.signal ?? null,\n });\n options?.onResponse?.(res);\n if (res.status === 204) return;\n if (!res.ok) {\n await throwRequestError({\n response: res,\n operation: \"resume-stream\",\n at: \"client.core.resumeStream\",\n context: { agentName: agent },\n });\n }\n if (!res.body) return;\n\n for await (const ev of parseSse(res.body)) {\n yield ev;\n }\n })();\n },\n\n resumeConversation<TAgentName extends AgentNameFromApp<TClientApp>>(\n agent: TAgentName,\n input: { conversationId: string; afterSeq?: number },\n options?: RequestOptions<TClientApp>,\n ) {\n return (async function* () {\n const headers = mergeHeaders(\n authHeaders,\n { accept: \"text/event-stream\" },\n config.headers,\n options?.headers,\n );\n\n if (typeof input.afterSeq === \"number\") {\n headers.set(\"last-event-id\", String(input.afterSeq));\n }\n\n const prepared = await prepareRequest(advanced, {\n operation: \"resume-conversation\",\n url: `${baseURL}/${encodeURIComponent(String(agent))}/conversations/${encodeURIComponent(input.conversationId)}/resume`,\n method: \"GET\",\n headers,\n });\n\n const res = await doFetch(prepared.url, {\n method: prepared.method,\n headers: prepared.headers,\n ...(prepared.body !== undefined ? { body: prepared.body } : {}),\n signal: options?.signal ?? null,\n });\n options?.onResponse?.(res);\n if (res.status === 204) return;\n if (!res.ok) {\n await throwRequestError({\n response: res,\n operation: \"resume-conversation\",\n at: \"client.core.resumeConversation\",\n context: { agentName: agent, conversationId: input.conversationId },\n });\n }\n if (!res.body) return;\n\n for await (const ev of parseSse(res.body)) {\n yield ev;\n }\n })();\n },\n\n async loadConversation(\n agent: AgentNameFromApp<TClientApp>,\n conversationId: string,\n options?: RequestOptions<TClientApp>,\n ) {\n const prepared = await prepareRequest(advanced, {\n operation: \"load-conversation\",\n url: `${baseURL}/${encodeURIComponent(String(agent))}/conversations/${encodeURIComponent(conversationId)}`,\n method: \"GET\",\n headers: mergeHeaders(authHeaders, config.headers, options?.headers),\n });\n\n const res = await doFetch(prepared.url, {\n method: prepared.method,\n headers: prepared.headers,\n ...(prepared.body !== undefined ? { body: prepared.body } : {}),\n signal: options?.signal ?? null,\n });\n options?.onResponse?.(res);\n if (res.status === 204) {\n return null;\n }\n if (!res.ok) {\n await throwRequestError({\n response: res,\n operation: \"load-conversation\",\n at: \"client.core.loadConversation\",\n context: { agentName: agent, conversationId },\n });\n }\n\n return await res.json();\n },\n\n async abortRun(\n req: Parameters<BetterAgentClient<TClientApp>[\"abortRun\"]>[0],\n options?: Parameters<BetterAgentClient<TClientApp>[\"abortRun\"]>[1],\n ) {\n const prepared = await prepareRequest(advanced, {\n operation: \"abort-run\",\n url: `${baseURL}/${encodeURIComponent(String(req.agent))}/runs/${encodeURIComponent(req.runId)}/abort`,\n method: \"POST\",\n headers: mergeHeaders(authHeaders, config.headers, options?.headers),\n });\n\n const res = await doFetch(prepared.url, {\n method: prepared.method,\n headers: prepared.headers,\n ...(prepared.body !== undefined ? { body: prepared.body } : {}),\n signal: options?.signal ?? null,\n });\n options?.onResponse?.(res);\n if (res.status === 204) {\n return;\n }\n if (!res.ok) {\n await throwRequestError({\n response: res,\n operation: \"abort-run\",\n at: \"client.core.abortRun\",\n context: { agentName: req.agent, runId: req.runId },\n });\n }\n },\n\n async submitToolResult(\n req: Parameters<BetterAgentClient<TClientApp>[\"submitToolResult\"]>[0],\n ) {\n await submitToolResult({\n ...req,\n agent: String(req.agent),\n });\n },\n\n async submitToolApproval(\n req: Parameters<BetterAgentClient<TClientApp>[\"submitToolApproval\"]>[0],\n ) {\n await submitToolApproval({\n ...req,\n agent: String(req.agent),\n });\n },\n };\n\n return client as BetterAgentClient<TClientApp>;\n};\n\ntype PendingToolCall = {\n toolName: string;\n argsJson: string;\n ended: boolean;\n submitted: boolean;\n approvalState: \"waiting\" | \"requested\" | \"approved\" | \"denied\" | \"expired\";\n};\n\nconst getToolCallKey = (runId: string, toolCallId: string) => `${runId}:${toolCallId}`;\n\n// Resolve client tool handlers in request-first order, then normalize map handlers\n// to the same `{ toolName, input, context }` shape used by `onToolCall`.\nconst resolveToolHandler = <TClientApp>(\n toolName: string,\n options: StreamRequestOptions<TClientApp> | undefined,\n staticToolHandlers: ClientConfig<TClientApp>[\"toolHandlers\"] | undefined,\n) => {\n const requestHandler = options?.onToolCall;\n const requestToolHandlers = options?.toolHandlers as\n | Record<\n string,\n (input: unknown, context: ToolCallContext<TClientApp>) => unknown | Promise<unknown>\n >\n | undefined;\n const requestToolHandler = requestToolHandlers?.[toolName];\n const staticHandlers = staticToolHandlers as\n | Record<\n string,\n (input: unknown, context: ToolCallContext<TClientApp>) => unknown | Promise<unknown>\n >\n | undefined;\n const staticHandler = staticHandlers?.[toolName];\n\n return (\n requestHandler ??\n (requestToolHandler\n ? (params: {\n toolName: string;\n input: unknown;\n context: ToolCallContext<TClientApp>;\n }) => requestToolHandler(params.input, params.context)\n : undefined) ??\n (staticHandler\n ? (params: {\n toolName: string;\n input: unknown;\n context: ToolCallContext<TClientApp>;\n }) => staticHandler(params.input, params.context)\n : undefined)\n );\n};\n"],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ import { E as UIMessage, K as AgentNameFromApp, M as BetterAgentClient, Y as ModalitiesForAgent, b as PendingToolApproval, f as SendResult, i as ApproveToolCallParams, k as AgentClientError, l as RetryResult, m as SubmitInput, p as SetMessagesInput, r as AgentStatus, t as AgentChatControllerOptions, u as SendMessageInputForAgent } from "../controller-CJ79_cSR.mjs";
2
+
3
+ //#region src/preact/types.d.ts
4
+ /** Options for `useAgent`. */
5
+ type UseAgentOptions<TApp = unknown, TAgentName extends AgentNameFromApp<TApp> = AgentNameFromApp<TApp>> = AgentChatControllerOptions<TApp, TAgentName>;
6
+ /** Return type of `useAgent`. */
7
+ interface UseAgentResult<TApp = unknown, TAgentName extends AgentNameFromApp<TApp> = AgentNameFromApp<TApp>> {
8
+ /** Stable local chat id. */
9
+ id: string;
10
+ /** Conversation messages. */
11
+ messages: UIMessage[];
12
+ /** Current request status. */
13
+ status: AgentStatus;
14
+ /** Latest client error. */
15
+ error: AgentClientError | undefined;
16
+ /** Latest stream id. */
17
+ streamId: string | undefined;
18
+ /** Latest run id. */
19
+ runId: string | undefined;
20
+ /** Conversation id, when configured. */
21
+ conversationId: string | undefined;
22
+ /** True while a request is active. */
23
+ isLoading: boolean;
24
+ /** True while streaming events are being consumed. */
25
+ isStreaming: boolean;
26
+ /** Pending tool approvals. */
27
+ pendingToolApprovals: PendingToolApproval[];
28
+ /** Sends a message. */
29
+ sendMessage<const TModalities extends ModalitiesForAgent<TApp, TAgentName> | undefined = undefined>(input: SendMessageInputForAgent<TApp, TAgentName, TModalities>, options?: {
30
+ signal?: AbortSignal;
31
+ }): Promise<SendResult>;
32
+ /** Retries the most recent user message. */
33
+ regenerate(): Promise<void>;
34
+ /** Retries one user message. */
35
+ retryMessage(localId: string): Promise<RetryResult>;
36
+ /** Stops the active run or stream. */
37
+ stop(): void;
38
+ /** Resumes one stream. */
39
+ resumeStream(options: {
40
+ streamId: string;
41
+ afterSeq?: number;
42
+ }): Promise<void>;
43
+ /** Resumes the active conversation stream. */
44
+ resumeConversation(options?: {
45
+ afterSeq?: number;
46
+ }): Promise<void>;
47
+ /** Approves or denies a tool call. */
48
+ approveToolCall(params: ApproveToolCallParams): Promise<void>;
49
+ /** Clears the latest error. */
50
+ clearError(): void;
51
+ /** Resets local state. */
52
+ reset(): void;
53
+ /** Replaces the local messages. */
54
+ setMessages(input: SetMessagesInput): void;
55
+ }
56
+ //#endregion
57
+ //#region src/preact/useAgent.d.ts
58
+ /**
59
+ * Preact hook for talking to one Better Agent conversation.
60
+ *
61
+ * Returns chat state and chat actions.
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * const agent = useAgent(client, {
66
+ * agent: "assistant",
67
+ * conversationId: "conv_123",
68
+ * });
69
+ *
70
+ * await agent.sendMessage("Hello");
71
+ *
72
+ * console.log(agent.messages);
73
+ * console.log(agent.status);
74
+ * agent.stop();
75
+ * ```
76
+ *
77
+ * @example
78
+ * ```tsx
79
+ * function Chat() {
80
+ * const agent = useAgent(client, { agent: "assistant" });
81
+ *
82
+ * return (
83
+ * <div>
84
+ * {agent.messages.map((message) => (
85
+ * <div key={message.localId}>{message.role}</div>
86
+ * ))}
87
+ * <button onClick={() => agent.sendMessage("Hello")}>Send</button>
88
+ * </div>
89
+ * );
90
+ * }
91
+ * ```
92
+ */
93
+ declare const useAgent: <TApp = unknown, TAgentName extends AgentNameFromApp<TApp> = AgentNameFromApp<TApp>>(client: BetterAgentClient<TApp>, options: UseAgentOptions<TApp, TAgentName>) => UseAgentResult<TApp, TAgentName>;
94
+ //#endregion
95
+ export { type SetMessagesInput, type SubmitInput, type UseAgentOptions, type UseAgentResult, useAgent };
96
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/preact/types.ts","../../src/preact/useAgent.ts"],"mappings":";;;;KAgBY,eAAA,oCAEW,gBAAA,CAAiB,IAAA,IAAQ,gBAAA,CAAiB,IAAA,KAC7D,0BAAA,CAA2B,IAAA,EAAM,UAAA;;UAGpB,cAAA,oCAEM,gBAAA,CAAiB,IAAA,IAAQ,gBAAA,CAAiB,IAAA;EANjB;EAS5C,EAAA;EARiC;EAUjC,QAAA,EAAU,SAAA;EAVgB;EAY1B,MAAA,EAAQ,WAAA;EAdR;EAgBA,KAAA,EAAO,gBAAA;EAfY;EAiBnB,QAAA;EAjB4C;EAmB5C,KAAA;EAlBA;EAoBA,cAAA;EApBiC;EAsBjC,SAAA;EAtB2C;EAwB3C,WAAA;EArB2B;EAuB3B,oBAAA,EAAsB,mBAAA;EArBc;EAuBpC,WAAA,2BAC8B,kBAAA,CAAmB,IAAA,EAAM,UAAA,2BAEnD,KAAA,EAAO,wBAAA,CAAyB,IAAA,EAAM,UAAA,EAAY,WAAA,GAClD,OAAA;IAAY,MAAA,GAAS,WAAA;EAAA,IACtB,OAAA,CAAQ,UAAA;EAvBD;EAyBV,UAAA,IAAc,OAAA;EArBP;EAuBP,YAAA,CAAa,OAAA,WAAkB,OAAA,CAAQ,WAAA;EARU;EAUjD,IAAA;EAV8B;EAY9B,YAAA,CAAa,OAAA;IAAW,QAAA;IAAkB,QAAA;EAAA,IAAsB,OAAA;EATvC;EAWzB,kBAAA,CAAmB,OAAA;IAAY,QAAA;EAAA,IAAsB,OAAA;EANd;EAQvC,eAAA,CAAgB,MAAA,EAAQ,qBAAA,GAAwB,OAAA;EAJgB;EAMhE,UAAA;EAFwB;EAIxB,KAAA;EAEmB;EAAnB,WAAA,CAAY,KAAA,EAAO,gBAAA;AAAA;;;AAtDvB;;;;;;;;;;;;;;;;;;;;;;;AAMA;;;;;;;;;;;;AANA,cC8Ba,QAAA,sCAEU,gBAAA,CAAiB,IAAA,IAAK,gBAAA,CAAA,IAAA,GAAA,MAAA,EAEjC,iBAAA,CAAkB,IAAA,GAAK,OAAA,EACtB,eAAA,CAAgB,IAAA,EAAM,UAAA,MAChC,cAAA,CAAe,IAAA,EAAM,UAAA"}
@@ -0,0 +1,134 @@
1
+ import { t as AgentChatController } from "../controller-Cf_JhTdJ.mjs";
2
+ import { n as getLatestUserMessageId, r as normalizeSendInput, t as cloneControllerOptions } from "../utils-CiHUj_BW.mjs";
3
+ import { useEffect, useReducer, useRef } from "preact/hooks";
4
+
5
+ //#region src/preact/useAgent.ts
6
+ /**
7
+ * Preact hook for talking to one Better Agent conversation.
8
+ *
9
+ * Returns chat state and chat actions.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * const agent = useAgent(client, {
14
+ * agent: "assistant",
15
+ * conversationId: "conv_123",
16
+ * });
17
+ *
18
+ * await agent.sendMessage("Hello");
19
+ *
20
+ * console.log(agent.messages);
21
+ * console.log(agent.status);
22
+ * agent.stop();
23
+ * ```
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * function Chat() {
28
+ * const agent = useAgent(client, { agent: "assistant" });
29
+ *
30
+ * return (
31
+ * <div>
32
+ * {agent.messages.map((message) => (
33
+ * <div key={message.localId}>{message.role}</div>
34
+ * ))}
35
+ * <button onClick={() => agent.sendMessage("Hello")}>Send</button>
36
+ * </div>
37
+ * );
38
+ * }
39
+ * ```
40
+ */
41
+ const useAgent = (client, options) => {
42
+ const [, forceRender] = useReducer((count) => count + 1, 0);
43
+ const mountVersionRef = useRef(0);
44
+ const latestClientRef = useRef(client);
45
+ const latestOptionsRef = useRef(options);
46
+ latestClientRef.current = client;
47
+ latestOptionsRef.current = options;
48
+ const controllerRef = useRef(null);
49
+ if (!controllerRef.current) controllerRef.current = new AgentChatController(client, cloneControllerOptions(options));
50
+ const controller = controllerRef.current;
51
+ /** Pushes the latest client and options into the controller. */
52
+ const syncController = () => {
53
+ controller.updateClient(latestClientRef.current);
54
+ controller.updateOptions(cloneControllerOptions(latestOptionsRef.current));
55
+ };
56
+ useEffect(() => {
57
+ controller.updateClient(latestClientRef.current);
58
+ controller.updateOptions(cloneControllerOptions(latestOptionsRef.current));
59
+ }, [controller]);
60
+ useEffect(() => {
61
+ const handleControllerChange = () => forceRender(void 0);
62
+ return controller.subscribe(handleControllerChange);
63
+ }, [controller]);
64
+ useEffect(() => {
65
+ const mountVersion = ++mountVersionRef.current;
66
+ controller.updateClient(latestClientRef.current);
67
+ controller.updateOptions(cloneControllerOptions(latestOptionsRef.current));
68
+ controller.init();
69
+ return () => {
70
+ queueMicrotask(() => {
71
+ if (mountVersionRef.current !== mountVersion) return;
72
+ controller.destroy();
73
+ if (controllerRef.current === controller) controllerRef.current = null;
74
+ });
75
+ };
76
+ }, [controller]);
77
+ const snapshot = controller.getSnapshot();
78
+ return {
79
+ id: snapshot.id,
80
+ messages: snapshot.messages,
81
+ status: snapshot.status,
82
+ error: snapshot.error,
83
+ streamId: snapshot.streamId,
84
+ runId: snapshot.runId,
85
+ conversationId: snapshot.conversationId,
86
+ isLoading: snapshot.isLoading,
87
+ isStreaming: snapshot.isStreaming,
88
+ pendingToolApprovals: snapshot.pendingToolApprovals,
89
+ sendMessage: (input, requestOptions) => {
90
+ syncController();
91
+ return controller.sendMessage(normalizeSendInput(input), requestOptions);
92
+ },
93
+ regenerate: async () => {
94
+ syncController();
95
+ await controller.retryMessage(getLatestUserMessageId(controller));
96
+ },
97
+ retryMessage: (localId) => {
98
+ syncController();
99
+ return controller.retryMessage(localId);
100
+ },
101
+ stop: () => {
102
+ syncController();
103
+ controller.stop();
104
+ },
105
+ resumeStream: (resumeOptions) => {
106
+ syncController();
107
+ return controller.resumeStream(resumeOptions);
108
+ },
109
+ resumeConversation: (resumeOptions) => {
110
+ syncController();
111
+ return controller.resumeConversation(resumeOptions);
112
+ },
113
+ approveToolCall: (params) => {
114
+ syncController();
115
+ return controller.approveToolCall(params);
116
+ },
117
+ clearError: () => {
118
+ syncController();
119
+ controller.clearError();
120
+ },
121
+ reset: () => {
122
+ syncController();
123
+ controller.reset();
124
+ },
125
+ setMessages: (input) => {
126
+ syncController();
127
+ controller.setMessages(input);
128
+ }
129
+ };
130
+ };
131
+
132
+ //#endregion
133
+ export { useAgent };
134
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/preact/useAgent.ts"],"sourcesContent":["import { useEffect, useReducer, useRef } from \"preact/hooks\";\nimport { AgentChatController } from \"../core/controller\";\nimport {\n cloneControllerOptions,\n getLatestUserMessageId,\n normalizeSendInput,\n} from \"../framework-internals/utils\";\nimport type { BetterAgentClient } from \"../types/client\";\nimport type { AgentNameFromApp } from \"../types/client-type-helpers\";\nimport type { UseAgentOptions, UseAgentResult } from \"./types\";\n\n/**\n * Preact hook for talking to one Better Agent conversation.\n *\n * Returns chat state and chat actions.\n *\n * @example\n * ```tsx\n * const agent = useAgent(client, {\n * agent: \"assistant\",\n * conversationId: \"conv_123\",\n * });\n *\n * await agent.sendMessage(\"Hello\");\n *\n * console.log(agent.messages);\n * console.log(agent.status);\n * agent.stop();\n * ```\n *\n * @example\n * ```tsx\n * function Chat() {\n * const agent = useAgent(client, { agent: \"assistant\" });\n *\n * return (\n * <div>\n * {agent.messages.map((message) => (\n * <div key={message.localId}>{message.role}</div>\n * ))}\n * <button onClick={() => agent.sendMessage(\"Hello\")}>Send</button>\n * </div>\n * );\n * }\n * ```\n */\nexport const useAgent = <\n TApp = unknown,\n TAgentName extends AgentNameFromApp<TApp> = AgentNameFromApp<TApp>,\n>(\n client: BetterAgentClient<TApp>,\n options: UseAgentOptions<TApp, TAgentName>,\n): UseAgentResult<TApp, TAgentName> => {\n const [, forceRender] = useReducer((count: number) => count + 1, 0);\n const mountVersionRef = useRef(0);\n const latestClientRef = useRef(client);\n const latestOptionsRef = useRef(options);\n latestClientRef.current = client;\n latestOptionsRef.current = options;\n\n const controllerRef = useRef<AgentChatController<TApp, TAgentName> | null>(null);\n if (!controllerRef.current) {\n controllerRef.current = new AgentChatController<TApp, TAgentName>(\n client,\n cloneControllerOptions(options),\n );\n }\n const controller = controllerRef.current;\n\n /** Pushes the latest client and options into the controller. */\n const syncController = () => {\n controller.updateClient(latestClientRef.current);\n controller.updateOptions(\n cloneControllerOptions(latestOptionsRef.current) as UseAgentOptions<TApp, TAgentName>,\n );\n };\n\n useEffect(() => {\n controller.updateClient(latestClientRef.current);\n controller.updateOptions(\n cloneControllerOptions(latestOptionsRef.current) as UseAgentOptions<TApp, TAgentName>,\n );\n }, [controller]);\n\n useEffect(() => {\n const handleControllerChange = () => forceRender(undefined as never);\n return controller.subscribe(handleControllerChange);\n }, [controller]);\n\n useEffect(() => {\n const mountVersion = ++mountVersionRef.current;\n controller.updateClient(latestClientRef.current);\n controller.updateOptions(\n cloneControllerOptions(latestOptionsRef.current) as UseAgentOptions<TApp, TAgentName>,\n );\n controller.init();\n\n return () => {\n queueMicrotask(() => {\n if (mountVersionRef.current !== mountVersion) {\n return;\n }\n\n controller.destroy();\n if (controllerRef.current === controller) {\n controllerRef.current = null;\n }\n });\n };\n }, [controller]);\n\n const snapshot = controller.getSnapshot();\n\n return {\n id: snapshot.id,\n messages: snapshot.messages,\n status: snapshot.status,\n error: snapshot.error,\n streamId: snapshot.streamId,\n runId: snapshot.runId,\n conversationId: snapshot.conversationId,\n isLoading: snapshot.isLoading,\n isStreaming: snapshot.isStreaming,\n pendingToolApprovals: snapshot.pendingToolApprovals,\n sendMessage: (input, requestOptions) => {\n syncController();\n return controller.sendMessage(normalizeSendInput(input), requestOptions);\n },\n regenerate: async () => {\n syncController();\n await controller.retryMessage(getLatestUserMessageId(controller));\n },\n retryMessage: (localId) => {\n syncController();\n return controller.retryMessage(localId);\n },\n stop: () => {\n syncController();\n controller.stop();\n },\n resumeStream: (resumeOptions) => {\n syncController();\n return controller.resumeStream(resumeOptions);\n },\n resumeConversation: (resumeOptions) => {\n syncController();\n return controller.resumeConversation(resumeOptions);\n },\n approveToolCall: (params) => {\n syncController();\n return controller.approveToolCall(params);\n },\n clearError: () => {\n syncController();\n controller.clearError();\n },\n reset: () => {\n syncController();\n controller.reset();\n },\n setMessages: (input) => {\n syncController();\n controller.setMessages(input);\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CA,MAAa,YAIT,QACA,YACmC;CACnC,MAAM,GAAG,eAAe,YAAY,UAAkB,QAAQ,GAAG,EAAE;CACnE,MAAM,kBAAkB,OAAO,EAAE;CACjC,MAAM,kBAAkB,OAAO,OAAO;CACtC,MAAM,mBAAmB,OAAO,QAAQ;AACxC,iBAAgB,UAAU;AAC1B,kBAAiB,UAAU;CAE3B,MAAM,gBAAgB,OAAqD,KAAK;AAChF,KAAI,CAAC,cAAc,QACf,eAAc,UAAU,IAAI,oBACxB,QACA,uBAAuB,QAAQ,CAClC;CAEL,MAAM,aAAa,cAAc;;CAGjC,MAAM,uBAAuB;AACzB,aAAW,aAAa,gBAAgB,QAAQ;AAChD,aAAW,cACP,uBAAuB,iBAAiB,QAAQ,CACnD;;AAGL,iBAAgB;AACZ,aAAW,aAAa,gBAAgB,QAAQ;AAChD,aAAW,cACP,uBAAuB,iBAAiB,QAAQ,CACnD;IACF,CAAC,WAAW,CAAC;AAEhB,iBAAgB;EACZ,MAAM,+BAA+B,YAAY,OAAmB;AACpE,SAAO,WAAW,UAAU,uBAAuB;IACpD,CAAC,WAAW,CAAC;AAEhB,iBAAgB;EACZ,MAAM,eAAe,EAAE,gBAAgB;AACvC,aAAW,aAAa,gBAAgB,QAAQ;AAChD,aAAW,cACP,uBAAuB,iBAAiB,QAAQ,CACnD;AACD,aAAW,MAAM;AAEjB,eAAa;AACT,wBAAqB;AACjB,QAAI,gBAAgB,YAAY,aAC5B;AAGJ,eAAW,SAAS;AACpB,QAAI,cAAc,YAAY,WAC1B,eAAc,UAAU;KAE9B;;IAEP,CAAC,WAAW,CAAC;CAEhB,MAAM,WAAW,WAAW,aAAa;AAEzC,QAAO;EACH,IAAI,SAAS;EACb,UAAU,SAAS;EACnB,QAAQ,SAAS;EACjB,OAAO,SAAS;EAChB,UAAU,SAAS;EACnB,OAAO,SAAS;EAChB,gBAAgB,SAAS;EACzB,WAAW,SAAS;EACpB,aAAa,SAAS;EACtB,sBAAsB,SAAS;EAC/B,cAAc,OAAO,mBAAmB;AACpC,mBAAgB;AAChB,UAAO,WAAW,YAAY,mBAAmB,MAAM,EAAE,eAAe;;EAE5E,YAAY,YAAY;AACpB,mBAAgB;AAChB,SAAM,WAAW,aAAa,uBAAuB,WAAW,CAAC;;EAErE,eAAe,YAAY;AACvB,mBAAgB;AAChB,UAAO,WAAW,aAAa,QAAQ;;EAE3C,YAAY;AACR,mBAAgB;AAChB,cAAW,MAAM;;EAErB,eAAe,kBAAkB;AAC7B,mBAAgB;AAChB,UAAO,WAAW,aAAa,cAAc;;EAEjD,qBAAqB,kBAAkB;AACnC,mBAAgB;AAChB,UAAO,WAAW,mBAAmB,cAAc;;EAEvD,kBAAkB,WAAW;AACzB,mBAAgB;AAChB,UAAO,WAAW,gBAAgB,OAAO;;EAE7C,kBAAkB;AACd,mBAAgB;AAChB,cAAW,YAAY;;EAE3B,aAAa;AACT,mBAAgB;AAChB,cAAW,OAAO;;EAEtB,cAAc,UAAU;AACpB,mBAAgB;AAChB,cAAW,YAAY,MAAM;;EAEpC"}
@@ -0,0 +1,96 @@
1
+ import { E as UIMessage, K as AgentNameFromApp, M as BetterAgentClient, Y as ModalitiesForAgent, b as PendingToolApproval, f as SendResult, i as ApproveToolCallParams, k as AgentClientError, l as RetryResult, m as SubmitInput, p as SetMessagesInput, r as AgentStatus, t as AgentChatControllerOptions, u as SendMessageInputForAgent } from "../controller-CJ79_cSR.mjs";
2
+
3
+ //#region src/react/types.d.ts
4
+ /** Options for `useAgent`. */
5
+ type UseAgentOptions<TApp = unknown, TAgentName extends AgentNameFromApp<TApp> = AgentNameFromApp<TApp>> = AgentChatControllerOptions<TApp, TAgentName>;
6
+ /** Return type of `useAgent`. */
7
+ interface UseAgentResult<TApp = unknown, TAgentName extends AgentNameFromApp<TApp> = AgentNameFromApp<TApp>> {
8
+ /** Stable local chat id. */
9
+ id: string;
10
+ /** Conversation messages. */
11
+ messages: UIMessage[];
12
+ /** Current request status. */
13
+ status: AgentStatus;
14
+ /** Latest client error. */
15
+ error: AgentClientError | undefined;
16
+ /** Latest stream id. */
17
+ streamId: string | undefined;
18
+ /** Latest run id. */
19
+ runId: string | undefined;
20
+ /** Conversation id, when configured. */
21
+ conversationId: string | undefined;
22
+ /** True while a request is active. */
23
+ isLoading: boolean;
24
+ /** True while streaming events are being consumed. */
25
+ isStreaming: boolean;
26
+ /** Pending tool approvals. */
27
+ pendingToolApprovals: PendingToolApproval[];
28
+ /** Sends a message. */
29
+ sendMessage<const TModalities extends ModalitiesForAgent<TApp, TAgentName> | undefined = undefined>(input: SendMessageInputForAgent<TApp, TAgentName, TModalities>, options?: {
30
+ signal?: AbortSignal;
31
+ }): Promise<SendResult>;
32
+ /** Retries the most recent user message. */
33
+ regenerate(): Promise<void>;
34
+ /** Retries one user message. */
35
+ retryMessage(localId: string): Promise<RetryResult>;
36
+ /** Stops the active run or stream. */
37
+ stop(): void;
38
+ /** Resumes one stream. */
39
+ resumeStream(options: {
40
+ streamId: string;
41
+ afterSeq?: number;
42
+ }): Promise<void>;
43
+ /** Resumes the active conversation stream. */
44
+ resumeConversation(options?: {
45
+ afterSeq?: number;
46
+ }): Promise<void>;
47
+ /** Approves or denies a tool call. */
48
+ approveToolCall(params: ApproveToolCallParams): Promise<void>;
49
+ /** Clears the latest error. */
50
+ clearError(): void;
51
+ /** Resets local state. */
52
+ reset(): void;
53
+ /** Replaces the local messages. */
54
+ setMessages(input: SetMessagesInput): void;
55
+ }
56
+ //#endregion
57
+ //#region src/react/useAgent.d.ts
58
+ /**
59
+ * React hook for talking to one Better Agent conversation.
60
+ *
61
+ * Returns chat state and chat actions.
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * const agent = useAgent(client, {
66
+ * agent: "assistant",
67
+ * conversationId: "conv_123",
68
+ * });
69
+ *
70
+ * await agent.sendMessage("Hello");
71
+ *
72
+ * console.log(agent.messages);
73
+ * console.log(agent.status);
74
+ * agent.stop();
75
+ * ```
76
+ *
77
+ * @example
78
+ * ```tsx
79
+ * function Chat() {
80
+ * const agent = useAgent(client, { agent: "assistant" });
81
+ *
82
+ * return (
83
+ * <div>
84
+ * {agent.messages.map((message) => (
85
+ * <div key={message.localId}>{message.role}</div>
86
+ * ))}
87
+ * <button onClick={() => agent.sendMessage("Hello")}>Send</button>
88
+ * </div>
89
+ * );
90
+ * }
91
+ * ```
92
+ */
93
+ declare const useAgent: <TApp = unknown, TAgentName extends AgentNameFromApp<TApp> = AgentNameFromApp<TApp>>(client: BetterAgentClient<TApp>, options: UseAgentOptions<TApp, TAgentName>) => UseAgentResult<TApp, TAgentName>;
94
+ //#endregion
95
+ export { type SetMessagesInput, type SubmitInput, type UseAgentOptions, type UseAgentResult, useAgent };
96
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/react/types.ts","../../src/react/useAgent.ts"],"mappings":";;;;KAgBY,eAAA,oCAEW,gBAAA,CAAiB,IAAA,IAAQ,gBAAA,CAAiB,IAAA,KAC7D,0BAAA,CAA2B,IAAA,EAAM,UAAA;;UAGpB,cAAA,oCAEM,gBAAA,CAAiB,IAAA,IAAQ,gBAAA,CAAiB,IAAA;EANjB;EAS5C,EAAA;EARiC;EAUjC,QAAA,EAAU,SAAA;EAVgB;EAY1B,MAAA,EAAQ,WAAA;EAdR;EAgBA,KAAA,EAAO,gBAAA;EAfY;EAiBnB,QAAA;EAjB4C;EAmB5C,KAAA;EAlBA;EAoBA,cAAA;EApBiC;EAsBjC,SAAA;EAtB2C;EAwB3C,WAAA;EArB2B;EAuB3B,oBAAA,EAAsB,mBAAA;EArBc;EAwBpC,WAAA,2BAC8B,kBAAA,CAAmB,IAAA,EAAM,UAAA,2BAEnD,KAAA,EAAO,wBAAA,CAAyB,IAAA,EAAM,UAAA,EAAY,WAAA,GAClD,OAAA;IAAY,MAAA,GAAS,WAAA;EAAA,IACtB,OAAA,CAAQ,UAAA;EAxBD;EA0BV,UAAA,IAAc,OAAA;EAtBP;EAwBP,YAAA,CAAa,OAAA,WAAkB,OAAA,CAAQ,WAAA;EARU;EAUjD,IAAA;EAV8B;EAY9B,YAAA,CAAa,OAAA;IAAW,QAAA;IAAkB,QAAA;EAAA,IAAsB,OAAA;EATvC;EAWzB,kBAAA,CAAmB,OAAA;IAAY,QAAA;EAAA,IAAsB,OAAA;EANd;EAQvC,eAAA,CAAgB,MAAA,EAAQ,qBAAA,GAAwB,OAAA;EAJgB;EAMhE,UAAA;EAFwB;EAIxB,KAAA;EAEmB;EAAnB,WAAA,CAAY,KAAA,EAAO,gBAAA;AAAA;;;AAvDvB;;;;;;;;;;;;;;;;;;;;;;;AAMA;;;;;;;;;;;;AANA,cC8Ba,QAAA,sCAEU,gBAAA,CAAiB,IAAA,IAAK,gBAAA,CAAA,IAAA,GAAA,MAAA,EAEjC,iBAAA,CAAkB,IAAA,GAAK,OAAA,EACtB,eAAA,CAAgB,IAAA,EAAM,UAAA,MAChC,cAAA,CAAe,IAAA,EAAM,UAAA"}
@@ -0,0 +1,123 @@
1
+ import { t as AgentChatController } from "../controller-Cf_JhTdJ.mjs";
2
+ import { n as getLatestUserMessageId, r as normalizeSendInput, t as cloneControllerOptions } from "../utils-CiHUj_BW.mjs";
3
+ import { useEffect, useReducer, useRef } from "react";
4
+
5
+ //#region src/react/useAgent.ts
6
+ /**
7
+ * React hook for talking to one Better Agent conversation.
8
+ *
9
+ * Returns chat state and chat actions.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * const agent = useAgent(client, {
14
+ * agent: "assistant",
15
+ * conversationId: "conv_123",
16
+ * });
17
+ *
18
+ * await agent.sendMessage("Hello");
19
+ *
20
+ * console.log(agent.messages);
21
+ * console.log(agent.status);
22
+ * agent.stop();
23
+ * ```
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * function Chat() {
28
+ * const agent = useAgent(client, { agent: "assistant" });
29
+ *
30
+ * return (
31
+ * <div>
32
+ * {agent.messages.map((message) => (
33
+ * <div key={message.localId}>{message.role}</div>
34
+ * ))}
35
+ * <button onClick={() => agent.sendMessage("Hello")}>Send</button>
36
+ * </div>
37
+ * );
38
+ * }
39
+ * ```
40
+ */
41
+ const useAgent = (client, options) => {
42
+ const [, forceRender] = useReducer((count) => count + 1, 0);
43
+ const latestClientRef = useRef(client);
44
+ const latestOptionsRef = useRef(options);
45
+ latestClientRef.current = client;
46
+ latestOptionsRef.current = options;
47
+ const controllerRef = useRef(null);
48
+ const ensureController = () => {
49
+ if (!controllerRef.current) controllerRef.current = new AgentChatController(latestClientRef.current, cloneControllerOptions(latestOptionsRef.current));
50
+ return controllerRef.current;
51
+ };
52
+ const controller = ensureController();
53
+ const getController = () => {
54
+ const current = ensureController();
55
+ current.updateClient(latestClientRef.current);
56
+ current.updateOptions(cloneControllerOptions(latestOptionsRef.current));
57
+ return current;
58
+ };
59
+ useEffect(() => {
60
+ controller.updateClient(latestClientRef.current);
61
+ controller.updateOptions(cloneControllerOptions(latestOptionsRef.current));
62
+ }, [controller]);
63
+ useEffect(() => {
64
+ return controller.subscribe(forceRender);
65
+ }, [controller]);
66
+ useEffect(() => {
67
+ controller.updateClient(latestClientRef.current);
68
+ controller.updateOptions(cloneControllerOptions(latestOptionsRef.current));
69
+ controller.init();
70
+ return () => {
71
+ controller.destroy();
72
+ if (controllerRef.current === controller) controllerRef.current = null;
73
+ };
74
+ }, [controller]);
75
+ const snapshot = controller.getSnapshot();
76
+ return {
77
+ id: snapshot.id,
78
+ messages: snapshot.messages,
79
+ status: snapshot.status,
80
+ error: snapshot.error,
81
+ streamId: snapshot.streamId,
82
+ runId: snapshot.runId,
83
+ conversationId: snapshot.conversationId,
84
+ isLoading: snapshot.isLoading,
85
+ isStreaming: snapshot.isStreaming,
86
+ pendingToolApprovals: snapshot.pendingToolApprovals,
87
+ sendMessage: (input, requestOptions) => {
88
+ return getController().sendMessage(normalizeSendInput(input), requestOptions);
89
+ },
90
+ regenerate: async () => {
91
+ const current = getController();
92
+ await current.retryMessage(getLatestUserMessageId(current));
93
+ },
94
+ retryMessage: (localId) => {
95
+ return getController().retryMessage(localId);
96
+ },
97
+ stop: () => {
98
+ getController().stop();
99
+ },
100
+ resumeStream: (resumeOptions) => {
101
+ return getController().resumeStream(resumeOptions);
102
+ },
103
+ resumeConversation: (resumeOptions) => {
104
+ return getController().resumeConversation(resumeOptions);
105
+ },
106
+ approveToolCall: (params) => {
107
+ return getController().approveToolCall(params);
108
+ },
109
+ clearError: () => {
110
+ getController().clearError();
111
+ },
112
+ reset: () => {
113
+ getController().reset();
114
+ },
115
+ setMessages: (input) => {
116
+ getController().setMessages(input);
117
+ }
118
+ };
119
+ };
120
+
121
+ //#endregion
122
+ export { useAgent };
123
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/react/useAgent.ts"],"sourcesContent":["import { useEffect, useReducer, useRef } from \"react\";\nimport { AgentChatController } from \"../core/controller\";\nimport {\n cloneControllerOptions,\n getLatestUserMessageId,\n normalizeSendInput,\n} from \"../framework-internals/utils\";\nimport type { BetterAgentClient } from \"../types/client\";\nimport type { AgentNameFromApp } from \"../types/client-type-helpers\";\nimport type { UseAgentOptions, UseAgentResult } from \"./types\";\n\n/**\n * React hook for talking to one Better Agent conversation.\n *\n * Returns chat state and chat actions.\n *\n * @example\n * ```tsx\n * const agent = useAgent(client, {\n * agent: \"assistant\",\n * conversationId: \"conv_123\",\n * });\n *\n * await agent.sendMessage(\"Hello\");\n *\n * console.log(agent.messages);\n * console.log(agent.status);\n * agent.stop();\n * ```\n *\n * @example\n * ```tsx\n * function Chat() {\n * const agent = useAgent(client, { agent: \"assistant\" });\n *\n * return (\n * <div>\n * {agent.messages.map((message) => (\n * <div key={message.localId}>{message.role}</div>\n * ))}\n * <button onClick={() => agent.sendMessage(\"Hello\")}>Send</button>\n * </div>\n * );\n * }\n * ```\n */\nexport const useAgent = <\n TApp = unknown,\n TAgentName extends AgentNameFromApp<TApp> = AgentNameFromApp<TApp>,\n>(\n client: BetterAgentClient<TApp>,\n options: UseAgentOptions<TApp, TAgentName>,\n): UseAgentResult<TApp, TAgentName> => {\n const [, forceRender] = useReducer((count: number) => count + 1, 0);\n const latestClientRef = useRef(client);\n const latestOptionsRef = useRef(options);\n latestClientRef.current = client;\n latestOptionsRef.current = options;\n\n const controllerRef = useRef<AgentChatController<TApp, TAgentName> | null>(null);\n const ensureController = () => {\n if (!controllerRef.current) {\n controllerRef.current = new AgentChatController<TApp, TAgentName>(\n latestClientRef.current,\n cloneControllerOptions(latestOptionsRef.current),\n );\n }\n\n return controllerRef.current;\n };\n const controller = ensureController();\n\n const getController = () => {\n const current = ensureController();\n current.updateClient(latestClientRef.current);\n current.updateOptions(\n cloneControllerOptions(latestOptionsRef.current) as UseAgentOptions<TApp, TAgentName>,\n );\n return current;\n };\n\n useEffect(() => {\n controller.updateClient(latestClientRef.current);\n controller.updateOptions(\n cloneControllerOptions(latestOptionsRef.current) as UseAgentOptions<TApp, TAgentName>,\n );\n }, [controller]);\n\n useEffect(() => {\n return controller.subscribe(forceRender);\n }, [controller]);\n\n useEffect(() => {\n controller.updateClient(latestClientRef.current);\n controller.updateOptions(\n cloneControllerOptions(latestOptionsRef.current) as UseAgentOptions<TApp, TAgentName>,\n );\n controller.init();\n\n return () => {\n controller.destroy();\n if (controllerRef.current === controller) {\n controllerRef.current = null;\n }\n };\n }, [controller]);\n\n const snapshot = controller.getSnapshot();\n\n return {\n id: snapshot.id,\n messages: snapshot.messages,\n status: snapshot.status,\n error: snapshot.error,\n streamId: snapshot.streamId,\n runId: snapshot.runId,\n conversationId: snapshot.conversationId,\n isLoading: snapshot.isLoading,\n isStreaming: snapshot.isStreaming,\n pendingToolApprovals: snapshot.pendingToolApprovals,\n sendMessage: (input, requestOptions) => {\n return getController().sendMessage(normalizeSendInput(input), requestOptions);\n },\n regenerate: async () => {\n const current = getController();\n await current.retryMessage(getLatestUserMessageId(current));\n },\n retryMessage: (localId) => {\n return getController().retryMessage(localId);\n },\n stop: () => {\n getController().stop();\n },\n resumeStream: (resumeOptions) => {\n return getController().resumeStream(resumeOptions);\n },\n resumeConversation: (resumeOptions) => {\n return getController().resumeConversation(resumeOptions);\n },\n approveToolCall: (params) => {\n return getController().approveToolCall(params);\n },\n clearError: () => {\n getController().clearError();\n },\n reset: () => {\n getController().reset();\n },\n setMessages: (input) => {\n getController().setMessages(input);\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CA,MAAa,YAIT,QACA,YACmC;CACnC,MAAM,GAAG,eAAe,YAAY,UAAkB,QAAQ,GAAG,EAAE;CACnE,MAAM,kBAAkB,OAAO,OAAO;CACtC,MAAM,mBAAmB,OAAO,QAAQ;AACxC,iBAAgB,UAAU;AAC1B,kBAAiB,UAAU;CAE3B,MAAM,gBAAgB,OAAqD,KAAK;CAChF,MAAM,yBAAyB;AAC3B,MAAI,CAAC,cAAc,QACf,eAAc,UAAU,IAAI,oBACxB,gBAAgB,SAChB,uBAAuB,iBAAiB,QAAQ,CACnD;AAGL,SAAO,cAAc;;CAEzB,MAAM,aAAa,kBAAkB;CAErC,MAAM,sBAAsB;EACxB,MAAM,UAAU,kBAAkB;AAClC,UAAQ,aAAa,gBAAgB,QAAQ;AAC7C,UAAQ,cACJ,uBAAuB,iBAAiB,QAAQ,CACnD;AACD,SAAO;;AAGX,iBAAgB;AACZ,aAAW,aAAa,gBAAgB,QAAQ;AAChD,aAAW,cACP,uBAAuB,iBAAiB,QAAQ,CACnD;IACF,CAAC,WAAW,CAAC;AAEhB,iBAAgB;AACZ,SAAO,WAAW,UAAU,YAAY;IACzC,CAAC,WAAW,CAAC;AAEhB,iBAAgB;AACZ,aAAW,aAAa,gBAAgB,QAAQ;AAChD,aAAW,cACP,uBAAuB,iBAAiB,QAAQ,CACnD;AACD,aAAW,MAAM;AAEjB,eAAa;AACT,cAAW,SAAS;AACpB,OAAI,cAAc,YAAY,WAC1B,eAAc,UAAU;;IAGjC,CAAC,WAAW,CAAC;CAEhB,MAAM,WAAW,WAAW,aAAa;AAEzC,QAAO;EACH,IAAI,SAAS;EACb,UAAU,SAAS;EACnB,QAAQ,SAAS;EACjB,OAAO,SAAS;EAChB,UAAU,SAAS;EACnB,OAAO,SAAS;EAChB,gBAAgB,SAAS;EACzB,WAAW,SAAS;EACpB,aAAa,SAAS;EACtB,sBAAsB,SAAS;EAC/B,cAAc,OAAO,mBAAmB;AACpC,UAAO,eAAe,CAAC,YAAY,mBAAmB,MAAM,EAAE,eAAe;;EAEjF,YAAY,YAAY;GACpB,MAAM,UAAU,eAAe;AAC/B,SAAM,QAAQ,aAAa,uBAAuB,QAAQ,CAAC;;EAE/D,eAAe,YAAY;AACvB,UAAO,eAAe,CAAC,aAAa,QAAQ;;EAEhD,YAAY;AACR,kBAAe,CAAC,MAAM;;EAE1B,eAAe,kBAAkB;AAC7B,UAAO,eAAe,CAAC,aAAa,cAAc;;EAEtD,qBAAqB,kBAAkB;AACnC,UAAO,eAAe,CAAC,mBAAmB,cAAc;;EAE5D,kBAAkB,WAAW;AACzB,UAAO,eAAe,CAAC,gBAAgB,OAAO;;EAElD,kBAAkB;AACd,kBAAe,CAAC,YAAY;;EAEhC,aAAa;AACT,kBAAe,CAAC,OAAO;;EAE3B,cAAc,UAAU;AACpB,kBAAe,CAAC,YAAY,MAAM;;EAEzC"}