@better-agent/client 0.1.0-canary.6 → 0.2.0-beta.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.
@@ -1,96 +1,28 @@
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";
1
+ import { M as BetterAgentClientAgentMemoryHandle, U as AgentHasMemory, W as AgentNameOf, a as AgentControllerOptions, c as AgentInterruptState, j as BetterAgentClientAgentHandle, l as AgentMessageInput, o as AgentControllerSnapshot, p as SendOptions, t as AgentController, u as AgentStreamResume } from "../controller-BkCxCUpn.mjs";
2
2
 
3
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;
4
+ interface UseAgentOptions<TApp = unknown, TName extends AgentNameOf<TApp> = AgentNameOf<TApp>> extends Pick<AgentControllerOptions<TApp, TName>, "context" | "threadId" | "toolHandlers" | "onEvent" | "onFinish" | "onError"> {
5
+ initialMessages?: AgentControllerOptions<TApp, TName>["initialMessages"];
6
+ initialState?: unknown;
7
+ resume?: AgentStreamResume;
8
+ initialInterruptState?: AgentInterruptState;
55
9
  }
10
+ type UseAgentResult<TApp = unknown, TName extends AgentNameOf<TApp> = AgentNameOf<TApp>> = AgentControllerSnapshot & {
11
+ sendMessage(input: AgentMessageInput, options?: SendOptions<TApp, TName>): Promise<void>;
12
+ stop(): void;
13
+ resume(input?: AgentStreamResume): Promise<void>;
14
+ approveToolCall(interruptId: string, metadata?: Record<string, unknown>): Promise<void>;
15
+ rejectToolCall(interruptId: string, metadata?: Record<string, unknown> | string): Promise<void>;
16
+ setMessages: AgentController<TApp, TName>["setMessages"];
17
+ } & (AgentHasMemory<TApp, TName> extends true ? {
18
+ loadMessages(threadId?: string): Promise<void>;
19
+ selectThread(threadId: string): Promise<void>;
20
+ clearThread(): void;
21
+ } : Record<never, never>);
56
22
  //#endregion
57
23
  //#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>;
24
+ declare function useAgent<TApp = unknown, TName extends AgentNameOf<TApp> = AgentNameOf<TApp>>(agent: BetterAgentClientAgentMemoryHandle<TApp, TName>, options?: UseAgentOptions<TApp, TName>): UseAgentResult<TApp, TName>;
25
+ declare function useAgent<TApp = unknown, TName extends AgentNameOf<TApp> = AgentNameOf<TApp>>(agent: BetterAgentClientAgentHandle<TApp, TName>, options?: UseAgentOptions<TApp, TName>): UseAgentResult<TApp, TName>;
94
26
  //#endregion
95
- export { type SetMessagesInput, type SubmitInput, type UseAgentOptions, type UseAgentResult, useAgent };
27
+ export { type UseAgentOptions, type UseAgentResult, useAgent };
96
28
  //# sourceMappingURL=index.d.mts.map
@@ -1 +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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/react/types.ts","../../src/react/useAgent.ts"],"mappings":";;;UAWiB,eAAA,+BAEC,WAAA,CAAY,IAAA,IAAQ,WAAA,CAAY,IAAA,WACxC,IAAA,CACF,sBAAA,CAAuB,IAAA,EAAM,KAAA;EAGjC,eAAA,GAAkB,sBAAA,CAAuB,IAAA,EAAM,KAAA;EAC/C,YAAA;EACA,MAAA,GAAS,iBAAA;EACT,qBAAA,GAAwB,mBAAA;AAAA;AAAA,KAGhB,cAAA,+BAEM,WAAA,CAAY,IAAA,IAAQ,WAAA,CAAY,IAAA,KAC9C,uBAAA;EACA,WAAA,CAAY,KAAA,EAAO,iBAAA,EAAmB,OAAA,GAAU,WAAA,CAAY,IAAA,EAAM,KAAA,IAAS,OAAA;EAC3E,IAAA;EACA,MAAA,CAAO,KAAA,GAAQ,iBAAA,GAAoB,OAAA;EACnC,eAAA,CAAgB,WAAA,UAAqB,QAAA,GAAW,MAAA,oBAA0B,OAAA;EAC1E,cAAA,CAAe,WAAA,UAAqB,QAAA,GAAW,MAAA,6BAAmC,OAAA;EAClF,WAAA,EAAa,eAAA,CAAgB,IAAA,EAAM,KAAA;AAAA,KAClC,cAAA,CAAe,IAAA,EAAM,KAAA;EAEZ,YAAA,CAAa,QAAA,YAAoB,OAAA;EACjC,YAAA,CAAa,QAAA,WAAmB,OAAA;EAChC,WAAA;AAAA,IAEJ,MAAA;;;iBC9BM,QAAA,+BAAuC,WAAA,CAAY,IAAA,IAAQ,WAAA,CAAY,IAAA,EAAA,CACnF,KAAA,EAAO,kCAAA,CAAmC,IAAA,EAAM,KAAA,GAChD,OAAA,GAAU,eAAA,CAAgB,IAAA,EAAM,KAAA,IACjC,cAAA,CAAe,IAAA,EAAM,KAAA;AAAA,iBACR,QAAA,+BAAuC,WAAA,CAAY,IAAA,IAAQ,WAAA,CAAY,IAAA,EAAA,CACnF,KAAA,EAAO,4BAAA,CAA6B,IAAA,EAAM,KAAA,GAC1C,OAAA,GAAU,eAAA,CAAgB,IAAA,EAAM,KAAA,IACjC,cAAA,CAAe,IAAA,EAAM,KAAA"}
@@ -1,122 +1,58 @@
1
- import { t as AgentChatController } from "../controller-BrBUfjhZ.mjs";
2
- import { n as getLatestUserMessageId, r as normalizeSendInput, t as cloneControllerOptions } from "../utils-CiHUj_BW.mjs";
3
- import { useEffect, useReducer, useRef } from "react";
1
+ import { n as createAgentController } from "../controller-xMlzSCc7.mjs";
2
+ import { useEffect, useMemo, useRef, useSyncExternalStore } from "react";
4
3
 
5
4
  //#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);
5
+ function useAgent(agent, options = {}) {
44
6
  const latestOptionsRef = useRef(options);
45
- latestClientRef.current = client;
46
7
  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]);
8
+ const toolHandlers = useMemo(() => new Proxy({}, { get(_target, key) {
9
+ return latestOptionsRef.current.toolHandlers?.[key];
10
+ } }), []);
11
+ const lifecycleHooks = useMemo(() => ({
12
+ onEvent: (event) => latestOptionsRef.current.onEvent?.(event),
13
+ onFinish: (finish) => latestOptionsRef.current.onFinish?.(finish),
14
+ onError: (error) => latestOptionsRef.current.onError?.(error)
15
+ }), []);
16
+ const controller = useMemo(() => {
17
+ return createAgentController(agent, {
18
+ initialMessages: options.initialMessages,
19
+ initialState: options.initialState,
20
+ initialInterruptState: options.initialInterruptState,
21
+ resume: options.resume,
22
+ context: options.context,
23
+ threadId: options.threadId,
24
+ toolHandlers,
25
+ onEvent: lifecycleHooks.onEvent,
26
+ onFinish: lifecycleHooks.onFinish,
27
+ onError: lifecycleHooks.onError
28
+ });
29
+ }, [
30
+ agent,
31
+ options.initialMessages,
32
+ options.initialState,
33
+ options.initialInterruptState,
34
+ options.resume,
35
+ options.context,
36
+ options.threadId,
37
+ toolHandlers,
38
+ lifecycleHooks
39
+ ]);
66
40
  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
- };
41
+ controller.start();
74
42
  }, [controller]);
75
- const snapshot = controller.getSnapshot();
76
43
  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
- }
44
+ ...useSyncExternalStore((listener) => controller.subscribe(listener), () => controller.getSnapshot(), () => controller.getSnapshot()),
45
+ sendMessage: (input, sendOptions) => controller.sendMessage(input, sendOptions),
46
+ stop: () => controller.stop(),
47
+ resume: (resume) => controller.resume(resume),
48
+ selectThread: (threadId) => controller.selectThread(threadId),
49
+ clearThread: () => controller.clearThread(),
50
+ loadMessages: (threadId) => controller.loadMessages(threadId),
51
+ approveToolCall: (interruptId, metadata) => controller.approveToolCall(interruptId, metadata),
52
+ rejectToolCall: (interruptId, metadata) => controller.rejectToolCall(interruptId, metadata),
53
+ setMessages: (messages) => controller.setMessages(messages)
118
54
  };
119
- };
55
+ }
120
56
 
121
57
  //#endregion
122
58
  export { useAgent };
@@ -1 +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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/react/useAgent.ts"],"sourcesContent":["import { useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport { createAgentController } from \"../core/controller\";\nimport type { AgentNameOf } from \"../core/inference\";\nimport type {\n AgentControllerOptions,\n BetterAgentClientAgentHandle,\n BetterAgentClientAgentMemoryHandle,\n} from \"../types\";\nimport type { UseAgentOptions, UseAgentResult } from \"./types\";\n\nexport function useAgent<TApp = unknown, TName extends AgentNameOf<TApp> = AgentNameOf<TApp>>(\n agent: BetterAgentClientAgentMemoryHandle<TApp, TName>,\n options?: UseAgentOptions<TApp, TName>,\n): UseAgentResult<TApp, TName>;\nexport function useAgent<TApp = unknown, TName extends AgentNameOf<TApp> = AgentNameOf<TApp>>(\n agent: BetterAgentClientAgentHandle<TApp, TName>,\n options?: UseAgentOptions<TApp, TName>,\n): UseAgentResult<TApp, TName>;\nexport function useAgent<TApp = unknown, TName extends AgentNameOf<TApp> = AgentNameOf<TApp>>(\n agent: BetterAgentClientAgentHandle<TApp, TName>,\n options: UseAgentOptions<TApp, TName> = {},\n): UseAgentResult<TApp, TName> {\n const latestOptionsRef = useRef(options);\n latestOptionsRef.current = options;\n\n const toolHandlers = useMemo<AgentControllerOptions<TApp, TName>[\"toolHandlers\"]>(\n () =>\n new Proxy(\n {},\n {\n get(_target, key) {\n const handlers = latestOptionsRef.current.toolHandlers as\n | Record<PropertyKey, unknown>\n | undefined;\n return handlers?.[key];\n },\n },\n ) as AgentControllerOptions<TApp, TName>[\"toolHandlers\"],\n [],\n );\n\n const lifecycleHooks = useMemo<\n Pick<AgentControllerOptions<TApp, TName>, \"onEvent\" | \"onFinish\" | \"onError\">\n >(\n () => ({\n onEvent: (event) => latestOptionsRef.current.onEvent?.(event),\n onFinish: (finish) => latestOptionsRef.current.onFinish?.(finish),\n onError: (error) => latestOptionsRef.current.onError?.(error),\n }),\n [],\n );\n\n const controller = useMemo(() => {\n const controllerOptions: AgentControllerOptions<TApp, TName> = {\n initialMessages: options.initialMessages,\n initialState: options.initialState,\n initialInterruptState: options.initialInterruptState,\n resume: options.resume,\n context: options.context,\n threadId: options.threadId,\n toolHandlers,\n onEvent: lifecycleHooks.onEvent,\n onFinish: lifecycleHooks.onFinish,\n onError: lifecycleHooks.onError,\n };\n return createAgentController<TApp, TName>(agent, controllerOptions);\n }, [\n agent,\n options.initialMessages,\n options.initialState,\n options.initialInterruptState,\n options.resume,\n options.context,\n options.threadId,\n toolHandlers,\n lifecycleHooks,\n ]);\n\n useEffect(() => {\n controller.start();\n }, [controller]);\n\n const snapshot = useSyncExternalStore(\n (listener) => controller.subscribe(listener),\n () => controller.getSnapshot(),\n () => controller.getSnapshot(),\n );\n\n return {\n ...snapshot,\n sendMessage: (input, sendOptions) => controller.sendMessage(input, sendOptions),\n stop: () => controller.stop(),\n resume: (resume) => controller.resume(resume),\n selectThread: (threadId) => controller.selectThread(threadId),\n clearThread: () => controller.clearThread(),\n loadMessages: (threadId) => controller.loadMessages(threadId),\n approveToolCall: (interruptId, metadata) =>\n controller.approveToolCall(interruptId, metadata),\n rejectToolCall: (interruptId, metadata) => controller.rejectToolCall(interruptId, metadata),\n setMessages: (messages) => controller.setMessages(messages),\n };\n}\n"],"mappings":";;;;AAkBA,SAAgB,SACZ,OACA,UAAwC,EAAE,EACf;CAC3B,MAAM,mBAAmB,OAAO,QAAQ;AACxC,kBAAiB,UAAU;CAE3B,MAAM,eAAe,cAEb,IAAI,MACA,EAAE,EACF,EACI,IAAI,SAAS,KAAK;AAId,SAHiB,iBAAiB,QAAQ,eAGxB;IAEzB,CACJ,EACL,EAAE,CACL;CAED,MAAM,iBAAiB,eAGZ;EACH,UAAU,UAAU,iBAAiB,QAAQ,UAAU,MAAM;EAC7D,WAAW,WAAW,iBAAiB,QAAQ,WAAW,OAAO;EACjE,UAAU,UAAU,iBAAiB,QAAQ,UAAU,MAAM;EAChE,GACD,EAAE,CACL;CAED,MAAM,aAAa,cAAc;AAa7B,SAAO,sBAAmC,OAZqB;GAC3D,iBAAiB,QAAQ;GACzB,cAAc,QAAQ;GACtB,uBAAuB,QAAQ;GAC/B,QAAQ,QAAQ;GAChB,SAAS,QAAQ;GACjB,UAAU,QAAQ;GAClB;GACA,SAAS,eAAe;GACxB,UAAU,eAAe;GACzB,SAAS,eAAe;GAC3B,CACkE;IACpE;EACC;EACA,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR;EACA;EACH,CAAC;AAEF,iBAAgB;AACZ,aAAW,OAAO;IACnB,CAAC,WAAW,CAAC;AAQhB,QAAO;EACH,GAPa,sBACZ,aAAa,WAAW,UAAU,SAAS,QACtC,WAAW,aAAa,QACxB,WAAW,aAAa,CACjC;EAIG,cAAc,OAAO,gBAAgB,WAAW,YAAY,OAAO,YAAY;EAC/E,YAAY,WAAW,MAAM;EAC7B,SAAS,WAAW,WAAW,OAAO,OAAO;EAC7C,eAAe,aAAa,WAAW,aAAa,SAAS;EAC7D,mBAAmB,WAAW,aAAa;EAC3C,eAAe,aAAa,WAAW,aAAa,SAAS;EAC7D,kBAAkB,aAAa,aAC3B,WAAW,gBAAgB,aAAa,SAAS;EACrD,iBAAiB,aAAa,aAAa,WAAW,eAAe,aAAa,SAAS;EAC3F,cAAc,aAAa,WAAW,YAAY,SAAS;EAC9D"}
@@ -1,99 +1,39 @@
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, p as SetMessagesInput, r as AgentStatus, t as AgentChatControllerOptions, u as SendMessageInputForAgent } from "../controller-CJ79_cSR.mjs";
1
+ import { M as BetterAgentClientAgentMemoryHandle, O as BetterAgentClientError, U as AgentHasMemory, W as AgentNameOf, a as AgentControllerOptions, c as AgentInterruptState, d as PendingClientTool, f as PendingToolApproval, j as BetterAgentClientAgentHandle, l as AgentMessageInput, p as SendOptions, s as AgentControllerStatus, t as AgentController, u as AgentStreamResume, w as UIMessage } from "../controller-BkCxCUpn.mjs";
2
2
  import { Accessor } from "solid-js";
3
3
 
4
4
  //#region src/solid/types.d.ts
5
- /** Plain value or Solid accessor. */
6
5
  type MaybeAccessor<T> = T | Accessor<T>;
7
- /** Options for `useAgent`. */
8
- type UseAgentOptions<TApp = unknown, TAgentName extends AgentNameFromApp<TApp> = AgentNameFromApp<TApp>> = AgentChatControllerOptions<TApp, TAgentName>;
9
- /** Return type of `useAgent`. */
10
- interface UseAgentResult<TApp = unknown, TAgentName extends AgentNameFromApp<TApp> = AgentNameFromApp<TApp>> {
11
- /** Stable local chat id. */
12
- id: Accessor<string>;
13
- /** Conversation messages. */
6
+ interface UseAgentOptions<TApp = unknown, TName extends AgentNameOf<TApp> = AgentNameOf<TApp>> extends Pick<AgentControllerOptions<TApp, TName>, "context" | "threadId" | "toolHandlers" | "onEvent" | "onFinish" | "onError"> {
7
+ initialMessages?: AgentControllerOptions<TApp, TName>["initialMessages"];
8
+ initialState?: unknown;
9
+ resume?: AgentStreamResume;
10
+ initialInterruptState?: AgentInterruptState;
11
+ }
12
+ type UseAgentResult<TApp = unknown, TName extends AgentNameOf<TApp> = AgentNameOf<TApp>> = {
14
13
  messages: Accessor<UIMessage[]>;
15
- /** Current request status. */
16
- status: Accessor<AgentStatus>;
17
- /** Latest client error. */
18
- error: Accessor<AgentClientError | undefined>;
19
- /** Latest stream id. */
20
- streamId: Accessor<string | undefined>;
21
- /** Latest run id. */
14
+ state: Accessor<unknown>;
15
+ status: Accessor<AgentControllerStatus>;
16
+ error: Accessor<BetterAgentClientError | undefined>;
22
17
  runId: Accessor<string | undefined>;
23
- /** Conversation id, when configured. */
24
- conversationId: Accessor<string | undefined>;
25
- /** True while a request is active. */
26
- isLoading: Accessor<boolean>;
27
- /** True while streaming events are being consumed. */
28
- isStreaming: Accessor<boolean>;
29
- /** Pending tool approvals. */
18
+ threadId: Accessor<string | undefined>;
19
+ isRunning: Accessor<boolean>;
20
+ pendingClientTools: Accessor<PendingClientTool[]>;
30
21
  pendingToolApprovals: Accessor<PendingToolApproval[]>;
31
- /** Sends a message. */
32
- sendMessage<const TModalities extends ModalitiesForAgent<TApp, TAgentName> | undefined = undefined>(input: SendMessageInputForAgent<TApp, TAgentName, TModalities>, options?: {
33
- signal?: AbortSignal;
34
- }): Promise<SendResult>;
35
- /** Retries the most recent user message. */
36
- regenerate(): Promise<void>;
37
- /** Retries one user message. */
38
- retryMessage(localId: string): Promise<RetryResult>;
39
- /** Stops the active run or stream. */
22
+ sendMessage(input: AgentMessageInput, options?: SendOptions<TApp, TName>): Promise<void>;
40
23
  stop(): void;
41
- /** Resumes one stream. */
42
- resumeStream(options: {
43
- streamId: string;
44
- afterSeq?: number;
45
- }): Promise<void>;
46
- /** Resumes the active conversation stream. */
47
- resumeConversation(options?: {
48
- afterSeq?: number;
49
- }): Promise<void>;
50
- /** Approves or denies a tool call. */
51
- approveToolCall(params: ApproveToolCallParams): Promise<void>;
52
- /** Clears the latest error. */
53
- clearError(): void;
54
- /** Resets local state. */
55
- reset(): void;
56
- /** Replaces the local messages. */
57
- setMessages(input: SetMessagesInput): void;
58
- }
24
+ resume(input?: AgentStreamResume): Promise<void>;
25
+ approveToolCall(interruptId: string, metadata?: Record<string, unknown>): Promise<void>;
26
+ rejectToolCall(interruptId: string, metadata?: Record<string, unknown> | string): Promise<void>;
27
+ setMessages: AgentController<TApp, TName>["setMessages"];
28
+ } & (AgentHasMemory<TApp, TName> extends true ? {
29
+ loadMessages(threadId?: string): Promise<void>;
30
+ selectThread(threadId: string): Promise<void>;
31
+ clearThread(): void;
32
+ } : Record<never, never>);
59
33
  //#endregion
60
34
  //#region src/solid/useAgent.d.ts
61
- /**
62
- * Solid primitive for talking to one Better Agent conversation.
63
- *
64
- * Returns reactive chat state and chat actions.
65
- *
66
- * @example
67
- * ```ts
68
- * const agent = useAgent(client, {
69
- * agent: "assistant",
70
- * conversationId: "conv_123",
71
- * });
72
- *
73
- * await agent.sendMessage("Hello");
74
- *
75
- * console.log(agent.messages());
76
- * console.log(agent.status());
77
- * agent.stop();
78
- * ```
79
- *
80
- * @example
81
- * ```tsx
82
- * function Chat() {
83
- * const agent = useAgent(client, { agent: "assistant" });
84
- *
85
- * return (
86
- * <div>
87
- * <For each={agent.messages()}>
88
- * {(message) => <div>{message.role}</div>}
89
- * </For>
90
- * <button onClick={() => agent.sendMessage("Hello")}>Send</button>
91
- * </div>
92
- * );
93
- * }
94
- * ```
95
- */
96
- declare function useAgent<TApp = unknown, TAgentName extends AgentNameFromApp<TApp> = AgentNameFromApp<TApp>>(client: MaybeAccessor<BetterAgentClient<TApp>>, options: MaybeAccessor<UseAgentOptions<TApp, TAgentName>>): UseAgentResult<TApp, TAgentName>;
35
+ declare function useAgent<TApp = unknown, TName extends AgentNameOf<TApp> = AgentNameOf<TApp>>(agent: BetterAgentClientAgentMemoryHandle<TApp, TName>, options?: MaybeAccessor<UseAgentOptions<TApp, TName> | undefined>): UseAgentResult<TApp, TName>;
36
+ declare function useAgent<TApp = unknown, TName extends AgentNameOf<TApp> = AgentNameOf<TApp>>(agent: BetterAgentClientAgentHandle<TApp, TName>, options?: MaybeAccessor<UseAgentOptions<TApp, TName> | undefined>): UseAgentResult<TApp, TName>;
97
37
  //#endregion
98
- export { type SetMessagesInput, type UseAgentOptions, type UseAgentResult, useAgent };
38
+ export { type MaybeAccessor, type UseAgentOptions, type UseAgentResult, useAgent };
99
39
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/solid/types.ts","../../src/solid/useAgent.ts"],"mappings":";;;;;KAiBY,aAAA,MAAmB,CAAA,GAAI,QAAA,CAAS,CAAA;;KAGhC,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;EAXvC;EActB,EAAA,EAAI,QAAA;EAd2B;EAgB/B,QAAA,EAAU,QAAA,CAAS,SAAA;EAhBsB;EAkBzC,MAAA,EAAQ,QAAA,CAAS,WAAA;EAfT;EAiBR,KAAA,EAAO,QAAA,CAAS,gBAAA;EAjBO;EAmBvB,QAAA,EAAU,QAAA;EAjBS;EAmBnB,KAAA,EAAO,QAAA;EAnBqC;EAqB5C,cAAA,EAAgB,QAAA;EApBiB;EAsBjC,SAAA,EAAW,QAAA;EAtBe;EAwB1B,WAAA,EAAa,QAAA;EA1Bb;EA4BA,oBAAA,EAAsB,QAAA,CAAS,mBAAA;EA3BZ;EA6BnB,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;EAjCX;EAmCA,UAAA,IAAc,OAAA;EAnCmB;EAqCjC,YAAA,CAAa,OAAA,WAAkB,OAAA,CAAQ,WAAA;EArCI;EAuC3C,IAAA;EApC2B;EAsC3B,YAAA,CAAa,OAAA;IAAW,QAAA;IAAkB,QAAA;EAAA,IAAsB,OAAA;EApCpB;EAsC5C,kBAAA,CAAmB,OAAA;IAAY,QAAA;EAAA,IAAsB,OAAA;EA/BpC;EAiCjB,eAAA,CAAgB,MAAA,EAAQ,qBAAA,GAAwB,OAAA;EA/BhC;EAiChB,UAAA;EA/BU;EAiCV,KAAA;EA7BgB;EA+BhB,WAAA,CAAY,KAAA,EAAO,gBAAA;AAAA;;;;AAzDvB;;;;;;;;;;;;;;AAGA;;;;;;;;;;;;;;;;;;;;iBC6BgB,QAAA,oCAEO,gBAAA,CAAiB,IAAA,IAAQ,gBAAA,CAAiB,IAAA,EAAA,CAE7D,MAAA,EAAQ,aAAA,CAAc,iBAAA,CAAkB,IAAA,IACxC,OAAA,EAAS,aAAA,CAAc,eAAA,CAAgB,IAAA,EAAM,UAAA,KAC9C,cAAA,CAAe,IAAA,EAAM,UAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/solid/types.ts","../../src/solid/useAgent.ts"],"mappings":";;;;KAgBY,aAAA,MAAmB,CAAA,GAAI,QAAA,CAAS,CAAA;AAAA,UAE3B,eAAA,+BAEC,WAAA,CAAY,IAAA,IAAQ,WAAA,CAAY,IAAA,WACxC,IAAA,CACF,sBAAA,CAAuB,IAAA,EAAM,KAAA;EAGjC,eAAA,GAAkB,sBAAA,CAAuB,IAAA,EAAM,KAAA;EAC/C,YAAA;EACA,MAAA,GAAS,iBAAA;EACT,qBAAA,GAAwB,mBAAA;AAAA;AAAA,KAGhB,cAAA,+BAA6C,WAAA,CAAY,IAAA,IAAQ,WAAA,CAAY,IAAA;EACrF,QAAA,EAAU,QAAA,CAAS,SAAA;EACnB,KAAA,EAAO,QAAA;EACP,MAAA,EAAQ,QAAA,CAAS,qBAAA;EACjB,KAAA,EAAO,QAAA,CAAS,sBAAA;EAChB,KAAA,EAAO,QAAA;EACP,QAAA,EAAU,QAAA;EACV,SAAA,EAAW,QAAA;EACX,kBAAA,EAAoB,QAAA,CAAS,iBAAA;EAC7B,oBAAA,EAAsB,QAAA,CAAS,mBAAA;EAC/B,WAAA,CAAY,KAAA,EAAO,iBAAA,EAAmB,OAAA,GAAU,WAAA,CAAY,IAAA,EAAM,KAAA,IAAS,OAAA;EAC3E,IAAA;EACA,MAAA,CAAO,KAAA,GAAQ,iBAAA,GAAoB,OAAA;EACnC,eAAA,CAAgB,WAAA,UAAqB,QAAA,GAAW,MAAA,oBAA0B,OAAA;EAC1E,cAAA,CAAe,WAAA,UAAqB,QAAA,GAAW,MAAA,6BAAmC,OAAA;EAClF,WAAA,EAAa,eAAA,CAAgB,IAAA,EAAM,KAAA;AAAA,KAClC,cAAA,CAAe,IAAA,EAAM,KAAA;EAEhB,YAAA,CAAa,QAAA,YAAoB,OAAA;EACjC,YAAA,CAAa,QAAA,WAAmB,OAAA;EAChC,WAAA;AAAA,IAEJ,MAAA;;;iBCxCU,QAAA,+BAAuC,WAAA,CAAY,IAAA,IAAQ,WAAA,CAAY,IAAA,EAAA,CACnF,KAAA,EAAO,kCAAA,CAAmC,IAAA,EAAM,KAAA,GAChD,OAAA,GAAU,aAAA,CAAc,eAAA,CAAgB,IAAA,EAAM,KAAA,iBAC/C,cAAA,CAAe,IAAA,EAAM,KAAA;AAAA,iBACR,QAAA,+BAAuC,WAAA,CAAY,IAAA,IAAQ,WAAA,CAAY,IAAA,EAAA,CACnF,KAAA,EAAO,4BAAA,CAA6B,IAAA,EAAM,KAAA,GAC1C,OAAA,GAAU,aAAA,CAAc,eAAA,CAAgB,IAAA,EAAM,KAAA,iBAC/C,cAAA,CAAe,IAAA,EAAM,KAAA"}