@antipopp/agno-react 0.1.0 → 0.2.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.
package/dist/index.d.mts CHANGED
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React from 'react';
3
3
  import { AgnoClient } from '@antipopp/agno-client';
4
4
  import * as _antipopp_agno_types from '@antipopp/agno-types';
5
- import { AgnoClientConfig, ChatMessage, ClientState, SessionEntry, AgentDetails, TeamDetails, ToolCall } from '@antipopp/agno-types';
5
+ import { AgnoClientConfig, ToolCall, ChatMessage, ClientState, SessionEntry, AgentDetails, TeamDetails } from '@antipopp/agno-types';
6
6
  export { AgentDetails, AgnoClientConfig, ChatMessage, ClientState, RunEvent, SessionEntry, TeamDetails, ToolCall } from '@antipopp/agno-types';
7
7
 
8
8
  interface AgnoProviderProps {
@@ -18,50 +18,6 @@ declare function AgnoProvider({ config, children }: AgnoProviderProps): react_js
18
18
  */
19
19
  declare function useAgnoClient(): AgnoClient;
20
20
 
21
- /**
22
- * Main hook for chat interactions
23
- * Provides messages, state, and methods to interact with the agent
24
- */
25
- declare function useAgnoChat(): {
26
- messages: ChatMessage[];
27
- sendMessage: (message: string | FormData, options?: {
28
- headers?: Record<string, string>;
29
- }) => Promise<void>;
30
- clearMessages: () => void;
31
- isStreaming: boolean;
32
- isPaused: boolean;
33
- error: string | undefined;
34
- state: ClientState;
35
- };
36
-
37
- /**
38
- * Hook for session management
39
- */
40
- declare function useAgnoSession(): {
41
- sessions: SessionEntry[];
42
- currentSessionId: string | undefined;
43
- loadSession: (sessionId: string) => Promise<ChatMessage[]>;
44
- fetchSessions: () => Promise<SessionEntry[]>;
45
- isLoading: boolean;
46
- error: string | undefined;
47
- };
48
-
49
- /**
50
- * Hook for common actions like initialization, fetching agents/teams
51
- */
52
- declare function useAgnoActions(): {
53
- initialize: () => Promise<{
54
- agents: AgentDetails[];
55
- teams: TeamDetails[];
56
- }>;
57
- checkStatus: () => Promise<boolean>;
58
- fetchAgents: () => Promise<AgentDetails[]>;
59
- fetchTeams: () => Promise<TeamDetails[]>;
60
- updateConfig: (updates: Partial<Parameters<(updates: Partial<_antipopp_agno_types.AgnoClientConfig>) => void>[0]>) => void;
61
- isInitializing: boolean;
62
- error: string | undefined;
63
- };
64
-
65
21
  /**
66
22
  * Tool handler function type
67
23
  */
@@ -77,7 +33,7 @@ interface ToolExecutionEvent {
77
33
  /**
78
34
  * Hook for handling frontend tool execution (HITL)
79
35
  *
80
- * @param handlers - Map of tool names to handler functions
36
+ * @param handlers - Map of tool names to handler functions (local handlers)
81
37
  * @param autoExecute - Whether to automatically execute tools when paused (default: true)
82
38
  *
83
39
  * @example
@@ -96,7 +52,7 @@ interface ToolExecutionEvent {
96
52
  * const { isPaused, isExecuting, pendingTools } = useAgnoToolExecution(toolHandlers);
97
53
  * ```
98
54
  */
99
- declare function useAgnoToolExecution(handlers: Record<string, ToolHandler>, autoExecute?: boolean): {
55
+ declare function useAgnoToolExecution(handlers?: Record<string, ToolHandler>, autoExecute?: boolean): {
100
56
  /** Whether the run is currently paused awaiting tool execution */
101
57
  isPaused: boolean;
102
58
  /** Whether tools are currently being executed */
@@ -113,4 +69,90 @@ declare function useAgnoToolExecution(handlers: Record<string, ToolHandler>, aut
113
69
  executionError: string | undefined;
114
70
  };
115
71
 
116
- export { AgnoProvider, type AgnoProviderProps, type ToolExecutionEvent, type ToolHandler, useAgnoActions, useAgnoChat, useAgnoClient, useAgnoSession, useAgnoToolExecution };
72
+ /**
73
+ * Context value for tool handler registry
74
+ */
75
+ interface ToolHandlerContextValue {
76
+ handlers: Record<string, ToolHandler>;
77
+ registerHandler: (name: string, handler: ToolHandler) => void;
78
+ unregisterHandler: (name: string) => void;
79
+ }
80
+ interface ToolHandlerProviderProps {
81
+ handlers?: Record<string, ToolHandler>;
82
+ children: React.ReactNode;
83
+ }
84
+ /**
85
+ * Provider component that manages global tool handlers
86
+ *
87
+ * @example
88
+ * ```tsx
89
+ * const globalHandlers = {
90
+ * fill_form: async (args) => {
91
+ * // Implementation
92
+ * return { success: true };
93
+ * }
94
+ * };
95
+ *
96
+ * <ToolHandlerProvider handlers={globalHandlers}>
97
+ * <App />
98
+ * </ToolHandlerProvider>
99
+ * ```
100
+ */
101
+ declare function ToolHandlerProvider({ handlers: initialHandlers, children }: ToolHandlerProviderProps): react_jsx_runtime.JSX.Element;
102
+ /**
103
+ * Hook to access global tool handlers
104
+ *
105
+ * @returns Tool handler context value or null if not within ToolHandlerProvider
106
+ *
107
+ * @example
108
+ * ```tsx
109
+ * const { handlers, registerHandler } = useToolHandlers() || { handlers: {} };
110
+ * ```
111
+ */
112
+ declare function useToolHandlers(): ToolHandlerContextValue | null;
113
+
114
+ /**
115
+ * Main hook for chat interactions
116
+ * Provides messages, state, and methods to interact with the agent
117
+ */
118
+ declare function useAgnoChat(): {
119
+ messages: ChatMessage[];
120
+ sendMessage: (message: string | FormData, options?: {
121
+ headers?: Record<string, string>;
122
+ }) => Promise<void>;
123
+ clearMessages: () => void;
124
+ isStreaming: boolean;
125
+ isPaused: boolean;
126
+ error: string | undefined;
127
+ state: ClientState;
128
+ };
129
+
130
+ /**
131
+ * Hook for session management
132
+ */
133
+ declare function useAgnoSession(): {
134
+ sessions: SessionEntry[];
135
+ currentSessionId: string | undefined;
136
+ loadSession: (sessionId: string) => Promise<ChatMessage[]>;
137
+ fetchSessions: () => Promise<SessionEntry[]>;
138
+ isLoading: boolean;
139
+ error: string | undefined;
140
+ };
141
+
142
+ /**
143
+ * Hook for common actions like initialization, fetching agents/teams
144
+ */
145
+ declare function useAgnoActions(): {
146
+ initialize: () => Promise<{
147
+ agents: AgentDetails[];
148
+ teams: TeamDetails[];
149
+ }>;
150
+ checkStatus: () => Promise<boolean>;
151
+ fetchAgents: () => Promise<AgentDetails[]>;
152
+ fetchTeams: () => Promise<TeamDetails[]>;
153
+ updateConfig: (updates: Partial<Parameters<(updates: Partial<_antipopp_agno_types.AgnoClientConfig>) => void>[0]>) => void;
154
+ isInitializing: boolean;
155
+ error: string | undefined;
156
+ };
157
+
158
+ export { AgnoProvider, type AgnoProviderProps, type ToolExecutionEvent, type ToolHandler, type ToolHandlerContextValue, ToolHandlerProvider, type ToolHandlerProviderProps, useAgnoActions, useAgnoChat, useAgnoClient, useAgnoSession, useAgnoToolExecution, useToolHandlers };
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React from 'react';
3
3
  import { AgnoClient } from '@antipopp/agno-client';
4
4
  import * as _antipopp_agno_types from '@antipopp/agno-types';
5
- import { AgnoClientConfig, ChatMessage, ClientState, SessionEntry, AgentDetails, TeamDetails, ToolCall } from '@antipopp/agno-types';
5
+ import { AgnoClientConfig, ToolCall, ChatMessage, ClientState, SessionEntry, AgentDetails, TeamDetails } from '@antipopp/agno-types';
6
6
  export { AgentDetails, AgnoClientConfig, ChatMessage, ClientState, RunEvent, SessionEntry, TeamDetails, ToolCall } from '@antipopp/agno-types';
7
7
 
8
8
  interface AgnoProviderProps {
@@ -18,50 +18,6 @@ declare function AgnoProvider({ config, children }: AgnoProviderProps): react_js
18
18
  */
19
19
  declare function useAgnoClient(): AgnoClient;
20
20
 
21
- /**
22
- * Main hook for chat interactions
23
- * Provides messages, state, and methods to interact with the agent
24
- */
25
- declare function useAgnoChat(): {
26
- messages: ChatMessage[];
27
- sendMessage: (message: string | FormData, options?: {
28
- headers?: Record<string, string>;
29
- }) => Promise<void>;
30
- clearMessages: () => void;
31
- isStreaming: boolean;
32
- isPaused: boolean;
33
- error: string | undefined;
34
- state: ClientState;
35
- };
36
-
37
- /**
38
- * Hook for session management
39
- */
40
- declare function useAgnoSession(): {
41
- sessions: SessionEntry[];
42
- currentSessionId: string | undefined;
43
- loadSession: (sessionId: string) => Promise<ChatMessage[]>;
44
- fetchSessions: () => Promise<SessionEntry[]>;
45
- isLoading: boolean;
46
- error: string | undefined;
47
- };
48
-
49
- /**
50
- * Hook for common actions like initialization, fetching agents/teams
51
- */
52
- declare function useAgnoActions(): {
53
- initialize: () => Promise<{
54
- agents: AgentDetails[];
55
- teams: TeamDetails[];
56
- }>;
57
- checkStatus: () => Promise<boolean>;
58
- fetchAgents: () => Promise<AgentDetails[]>;
59
- fetchTeams: () => Promise<TeamDetails[]>;
60
- updateConfig: (updates: Partial<Parameters<(updates: Partial<_antipopp_agno_types.AgnoClientConfig>) => void>[0]>) => void;
61
- isInitializing: boolean;
62
- error: string | undefined;
63
- };
64
-
65
21
  /**
66
22
  * Tool handler function type
67
23
  */
@@ -77,7 +33,7 @@ interface ToolExecutionEvent {
77
33
  /**
78
34
  * Hook for handling frontend tool execution (HITL)
79
35
  *
80
- * @param handlers - Map of tool names to handler functions
36
+ * @param handlers - Map of tool names to handler functions (local handlers)
81
37
  * @param autoExecute - Whether to automatically execute tools when paused (default: true)
82
38
  *
83
39
  * @example
@@ -96,7 +52,7 @@ interface ToolExecutionEvent {
96
52
  * const { isPaused, isExecuting, pendingTools } = useAgnoToolExecution(toolHandlers);
97
53
  * ```
98
54
  */
99
- declare function useAgnoToolExecution(handlers: Record<string, ToolHandler>, autoExecute?: boolean): {
55
+ declare function useAgnoToolExecution(handlers?: Record<string, ToolHandler>, autoExecute?: boolean): {
100
56
  /** Whether the run is currently paused awaiting tool execution */
101
57
  isPaused: boolean;
102
58
  /** Whether tools are currently being executed */
@@ -113,4 +69,90 @@ declare function useAgnoToolExecution(handlers: Record<string, ToolHandler>, aut
113
69
  executionError: string | undefined;
114
70
  };
115
71
 
116
- export { AgnoProvider, type AgnoProviderProps, type ToolExecutionEvent, type ToolHandler, useAgnoActions, useAgnoChat, useAgnoClient, useAgnoSession, useAgnoToolExecution };
72
+ /**
73
+ * Context value for tool handler registry
74
+ */
75
+ interface ToolHandlerContextValue {
76
+ handlers: Record<string, ToolHandler>;
77
+ registerHandler: (name: string, handler: ToolHandler) => void;
78
+ unregisterHandler: (name: string) => void;
79
+ }
80
+ interface ToolHandlerProviderProps {
81
+ handlers?: Record<string, ToolHandler>;
82
+ children: React.ReactNode;
83
+ }
84
+ /**
85
+ * Provider component that manages global tool handlers
86
+ *
87
+ * @example
88
+ * ```tsx
89
+ * const globalHandlers = {
90
+ * fill_form: async (args) => {
91
+ * // Implementation
92
+ * return { success: true };
93
+ * }
94
+ * };
95
+ *
96
+ * <ToolHandlerProvider handlers={globalHandlers}>
97
+ * <App />
98
+ * </ToolHandlerProvider>
99
+ * ```
100
+ */
101
+ declare function ToolHandlerProvider({ handlers: initialHandlers, children }: ToolHandlerProviderProps): react_jsx_runtime.JSX.Element;
102
+ /**
103
+ * Hook to access global tool handlers
104
+ *
105
+ * @returns Tool handler context value or null if not within ToolHandlerProvider
106
+ *
107
+ * @example
108
+ * ```tsx
109
+ * const { handlers, registerHandler } = useToolHandlers() || { handlers: {} };
110
+ * ```
111
+ */
112
+ declare function useToolHandlers(): ToolHandlerContextValue | null;
113
+
114
+ /**
115
+ * Main hook for chat interactions
116
+ * Provides messages, state, and methods to interact with the agent
117
+ */
118
+ declare function useAgnoChat(): {
119
+ messages: ChatMessage[];
120
+ sendMessage: (message: string | FormData, options?: {
121
+ headers?: Record<string, string>;
122
+ }) => Promise<void>;
123
+ clearMessages: () => void;
124
+ isStreaming: boolean;
125
+ isPaused: boolean;
126
+ error: string | undefined;
127
+ state: ClientState;
128
+ };
129
+
130
+ /**
131
+ * Hook for session management
132
+ */
133
+ declare function useAgnoSession(): {
134
+ sessions: SessionEntry[];
135
+ currentSessionId: string | undefined;
136
+ loadSession: (sessionId: string) => Promise<ChatMessage[]>;
137
+ fetchSessions: () => Promise<SessionEntry[]>;
138
+ isLoading: boolean;
139
+ error: string | undefined;
140
+ };
141
+
142
+ /**
143
+ * Hook for common actions like initialization, fetching agents/teams
144
+ */
145
+ declare function useAgnoActions(): {
146
+ initialize: () => Promise<{
147
+ agents: AgentDetails[];
148
+ teams: TeamDetails[];
149
+ }>;
150
+ checkStatus: () => Promise<boolean>;
151
+ fetchAgents: () => Promise<AgentDetails[]>;
152
+ fetchTeams: () => Promise<TeamDetails[]>;
153
+ updateConfig: (updates: Partial<Parameters<(updates: Partial<_antipopp_agno_types.AgnoClientConfig>) => void>[0]>) => void;
154
+ isInitializing: boolean;
155
+ error: string | undefined;
156
+ };
157
+
158
+ export { AgnoProvider, type AgnoProviderProps, type ToolExecutionEvent, type ToolHandler, type ToolHandlerContextValue, ToolHandlerProvider, type ToolHandlerProviderProps, useAgnoActions, useAgnoChat, useAgnoClient, useAgnoSession, useAgnoToolExecution, useToolHandlers };
package/dist/index.js CHANGED
@@ -21,11 +21,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
23
  AgnoProvider: () => AgnoProvider,
24
+ ToolHandlerProvider: () => ToolHandlerProvider,
24
25
  useAgnoActions: () => useAgnoActions,
25
26
  useAgnoChat: () => useAgnoChat,
26
27
  useAgnoClient: () => useAgnoClient,
27
28
  useAgnoSession: () => useAgnoSession,
28
- useAgnoToolExecution: () => useAgnoToolExecution
29
+ useAgnoToolExecution: () => useAgnoToolExecution,
30
+ useToolHandlers: () => useToolHandlers
29
31
  });
30
32
  module.exports = __toCommonJS(src_exports);
31
33
 
@@ -51,14 +53,40 @@ function useAgnoClient() {
51
53
  return client;
52
54
  }
53
55
 
54
- // src/hooks/useAgnoChat.ts
56
+ // src/context/ToolHandlerContext.tsx
55
57
  var import_react2 = require("react");
58
+ var import_jsx_runtime2 = require("react/jsx-runtime");
59
+ var ToolHandlerContext = (0, import_react2.createContext)(null);
60
+ function ToolHandlerProvider({ handlers: initialHandlers = {}, children }) {
61
+ const [handlers, setHandlers] = (0, import_react2.useState)(initialHandlers);
62
+ const registerHandler = (0, import_react2.useCallback)((name, handler) => {
63
+ setHandlers((prev) => ({ ...prev, [name]: handler }));
64
+ }, []);
65
+ const unregisterHandler = (0, import_react2.useCallback)((name) => {
66
+ setHandlers((prev) => {
67
+ const { [name]: _, ...rest } = prev;
68
+ return rest;
69
+ });
70
+ }, []);
71
+ const value = {
72
+ handlers,
73
+ registerHandler,
74
+ unregisterHandler
75
+ };
76
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ToolHandlerContext.Provider, { value, children });
77
+ }
78
+ function useToolHandlers() {
79
+ return (0, import_react2.useContext)(ToolHandlerContext);
80
+ }
81
+
82
+ // src/hooks/useAgnoChat.ts
83
+ var import_react3 = require("react");
56
84
  function useAgnoChat() {
57
85
  const client = useAgnoClient();
58
- const [messages, setMessages] = (0, import_react2.useState)(client.getMessages());
59
- const [state, setState] = (0, import_react2.useState)(client.getState());
60
- const [error, setError] = (0, import_react2.useState)();
61
- (0, import_react2.useEffect)(() => {
86
+ const [messages, setMessages] = (0, import_react3.useState)(client.getMessages());
87
+ const [state, setState] = (0, import_react3.useState)(client.getState());
88
+ const [error, setError] = (0, import_react3.useState)();
89
+ (0, import_react3.useEffect)(() => {
62
90
  const handleMessageUpdate = (updatedMessages) => {
63
91
  console.log("[useAgnoChat] message:update event received, messages:", updatedMessages.length);
64
92
  setMessages(updatedMessages);
@@ -89,7 +117,7 @@ function useAgnoChat() {
89
117
  client.off("state:change", handleStateChange);
90
118
  };
91
119
  }, [client]);
92
- const sendMessage = (0, import_react2.useCallback)(
120
+ const sendMessage = (0, import_react3.useCallback)(
93
121
  async (message, options) => {
94
122
  setError(void 0);
95
123
  try {
@@ -102,7 +130,7 @@ function useAgnoChat() {
102
130
  },
103
131
  [client]
104
132
  );
105
- const clearMessages = (0, import_react2.useCallback)(() => {
133
+ const clearMessages = (0, import_react3.useCallback)(() => {
106
134
  client.clearMessages();
107
135
  setMessages([]);
108
136
  setError(void 0);
@@ -119,16 +147,16 @@ function useAgnoChat() {
119
147
  }
120
148
 
121
149
  // src/hooks/useAgnoSession.ts
122
- var import_react3 = require("react");
150
+ var import_react4 = require("react");
123
151
  function useAgnoSession() {
124
152
  const client = useAgnoClient();
125
- const [sessions, setSessions] = (0, import_react3.useState)([]);
126
- const [currentSessionId, setCurrentSessionId] = (0, import_react3.useState)(
153
+ const [sessions, setSessions] = (0, import_react4.useState)([]);
154
+ const [currentSessionId, setCurrentSessionId] = (0, import_react4.useState)(
127
155
  client.getConfig().sessionId
128
156
  );
129
- const [isLoading, setIsLoading] = (0, import_react3.useState)(false);
130
- const [error, setError] = (0, import_react3.useState)();
131
- (0, import_react3.useEffect)(() => {
157
+ const [isLoading, setIsLoading] = (0, import_react4.useState)(false);
158
+ const [error, setError] = (0, import_react4.useState)();
159
+ (0, import_react4.useEffect)(() => {
132
160
  const handleSessionLoaded = (sessionId) => {
133
161
  setCurrentSessionId(sessionId);
134
162
  };
@@ -152,7 +180,7 @@ function useAgnoSession() {
152
180
  client.off("state:change", handleStateChange);
153
181
  };
154
182
  }, [client]);
155
- const loadSession = (0, import_react3.useCallback)(
183
+ const loadSession = (0, import_react4.useCallback)(
156
184
  async (sessionId) => {
157
185
  setIsLoading(true);
158
186
  setError(void 0);
@@ -170,7 +198,7 @@ function useAgnoSession() {
170
198
  },
171
199
  [client]
172
200
  );
173
- const fetchSessions = (0, import_react3.useCallback)(async () => {
201
+ const fetchSessions = (0, import_react4.useCallback)(async () => {
174
202
  setIsLoading(true);
175
203
  setError(void 0);
176
204
  try {
@@ -196,12 +224,12 @@ function useAgnoSession() {
196
224
  }
197
225
 
198
226
  // src/hooks/useAgnoActions.ts
199
- var import_react4 = require("react");
227
+ var import_react5 = require("react");
200
228
  function useAgnoActions() {
201
229
  const client = useAgnoClient();
202
- const [isInitializing, setIsInitializing] = (0, import_react4.useState)(false);
203
- const [error, setError] = (0, import_react4.useState)();
204
- const initialize = (0, import_react4.useCallback)(async () => {
230
+ const [isInitializing, setIsInitializing] = (0, import_react5.useState)(false);
231
+ const [error, setError] = (0, import_react5.useState)();
232
+ const initialize = (0, import_react5.useCallback)(async () => {
205
233
  setIsInitializing(true);
206
234
  setError(void 0);
207
235
  try {
@@ -215,7 +243,7 @@ function useAgnoActions() {
215
243
  setIsInitializing(false);
216
244
  }
217
245
  }, [client]);
218
- const checkStatus = (0, import_react4.useCallback)(async () => {
246
+ const checkStatus = (0, import_react5.useCallback)(async () => {
219
247
  setError(void 0);
220
248
  try {
221
249
  return await client.checkStatus();
@@ -225,7 +253,7 @@ function useAgnoActions() {
225
253
  return false;
226
254
  }
227
255
  }, [client]);
228
- const fetchAgents = (0, import_react4.useCallback)(async () => {
256
+ const fetchAgents = (0, import_react5.useCallback)(async () => {
229
257
  setError(void 0);
230
258
  try {
231
259
  return await client.fetchAgents();
@@ -235,7 +263,7 @@ function useAgnoActions() {
235
263
  throw err;
236
264
  }
237
265
  }, [client]);
238
- const fetchTeams = (0, import_react4.useCallback)(async () => {
266
+ const fetchTeams = (0, import_react5.useCallback)(async () => {
239
267
  setError(void 0);
240
268
  try {
241
269
  return await client.fetchTeams();
@@ -245,7 +273,7 @@ function useAgnoActions() {
245
273
  throw err;
246
274
  }
247
275
  }, [client]);
248
- const updateConfig = (0, import_react4.useCallback)(
276
+ const updateConfig = (0, import_react5.useCallback)(
249
277
  (updates) => {
250
278
  client.updateConfig(updates);
251
279
  },
@@ -263,16 +291,32 @@ function useAgnoActions() {
263
291
  }
264
292
 
265
293
  // src/hooks/useAgnoToolExecution.ts
266
- var import_react5 = require("react");
267
- function useAgnoToolExecution(handlers, autoExecute = true) {
294
+ var import_react6 = require("react");
295
+ function useAgnoToolExecution(handlers = {}, autoExecute = true) {
268
296
  const client = useAgnoClient();
269
- const [pendingTools, setPendingTools] = (0, import_react5.useState)([]);
270
- const [isPaused, setIsPaused] = (0, import_react5.useState)(false);
271
- const [isExecuting, setIsExecuting] = (0, import_react5.useState)(false);
272
- const [executionError, setExecutionError] = (0, import_react5.useState)();
273
- (0, import_react5.useEffect)(() => {
297
+ const toolHandlerContext = useToolHandlers();
298
+ const mergedHandlers = (0, import_react6.useMemo)(() => {
299
+ const globalHandlers = toolHandlerContext?.handlers || {};
300
+ return { ...globalHandlers, ...handlers };
301
+ }, [toolHandlerContext?.handlers, handlers]);
302
+ const [pendingTools, setPendingTools] = (0, import_react6.useState)([]);
303
+ const [isPaused, setIsPaused] = (0, import_react6.useState)(false);
304
+ const [isExecuting, setIsExecuting] = (0, import_react6.useState)(false);
305
+ const [executionError, setExecutionError] = (0, import_react6.useState)();
306
+ (0, import_react6.useEffect)(() => {
274
307
  const handleRunPaused = (event) => {
275
- console.log("[useAgnoToolExecution] Run paused, tools:", event.tools);
308
+ console.log("[useAgnoToolExecution] Run paused event received");
309
+ console.log("[useAgnoToolExecution] Event:", event);
310
+ console.log("[useAgnoToolExecution] Tools:", event.tools);
311
+ console.log("[useAgnoToolExecution] Number of tools:", event.tools?.length);
312
+ event.tools?.forEach((tool, idx) => {
313
+ console.log(`[useAgnoToolExecution] Tool ${idx}:`, {
314
+ name: tool.tool_name,
315
+ id: tool.tool_call_id,
316
+ args_type: typeof tool.tool_args,
317
+ args: tool.tool_args
318
+ });
319
+ });
276
320
  setIsPaused(true);
277
321
  setPendingTools(event.tools);
278
322
  setExecutionError(void 0);
@@ -291,7 +335,7 @@ function useAgnoToolExecution(handlers, autoExecute = true) {
291
335
  client.off("run:continued", handleRunContinued);
292
336
  };
293
337
  }, [client]);
294
- const executeAndContinue = (0, import_react5.useCallback)(async () => {
338
+ const executeAndContinue = (0, import_react6.useCallback)(async () => {
295
339
  if (!isPaused || pendingTools.length === 0) {
296
340
  console.warn("[useAgnoToolExecution] Cannot execute: no pending tools");
297
341
  return;
@@ -302,7 +346,7 @@ function useAgnoToolExecution(handlers, autoExecute = true) {
302
346
  console.log("[useAgnoToolExecution] Executing", pendingTools.length, "tools");
303
347
  const updatedTools = await Promise.all(
304
348
  pendingTools.map(async (tool) => {
305
- const handler = handlers[tool.tool_name];
349
+ const handler = mergedHandlers[tool.tool_name];
306
350
  if (!handler) {
307
351
  console.warn(`[useAgnoToolExecution] No handler for tool: ${tool.tool_name}`);
308
352
  return {
@@ -340,12 +384,12 @@ function useAgnoToolExecution(handlers, autoExecute = true) {
340
384
  setIsExecuting(false);
341
385
  throw error;
342
386
  }
343
- }, [client, handlers, isPaused, pendingTools]);
344
- const executeTools = (0, import_react5.useCallback)(
387
+ }, [client, mergedHandlers, isPaused, pendingTools]);
388
+ const executeTools = (0, import_react6.useCallback)(
345
389
  async (tools) => {
346
390
  return Promise.all(
347
391
  tools.map(async (tool) => {
348
- const handler = handlers[tool.tool_name];
392
+ const handler = mergedHandlers[tool.tool_name];
349
393
  if (!handler)
350
394
  return tool;
351
395
  try {
@@ -365,9 +409,9 @@ function useAgnoToolExecution(handlers, autoExecute = true) {
365
409
  })
366
410
  );
367
411
  },
368
- [handlers]
412
+ [mergedHandlers]
369
413
  );
370
- const continueWithResults = (0, import_react5.useCallback)(
414
+ const continueWithResults = (0, import_react6.useCallback)(
371
415
  async (tools) => {
372
416
  if (!isPaused) {
373
417
  throw new Error("No paused run to continue");
@@ -382,7 +426,7 @@ function useAgnoToolExecution(handlers, autoExecute = true) {
382
426
  },
383
427
  [client, isPaused]
384
428
  );
385
- (0, import_react5.useEffect)(() => {
429
+ (0, import_react6.useEffect)(() => {
386
430
  if (autoExecute && isPaused && !isExecuting && pendingTools.length > 0) {
387
431
  console.log("[useAgnoToolExecution] Auto-executing tools");
388
432
  executeAndContinue();
@@ -408,9 +452,11 @@ function useAgnoToolExecution(handlers, autoExecute = true) {
408
452
  // Annotate the CommonJS export names for ESM import in node:
409
453
  0 && (module.exports = {
410
454
  AgnoProvider,
455
+ ToolHandlerProvider,
411
456
  useAgnoActions,
412
457
  useAgnoChat,
413
458
  useAgnoClient,
414
459
  useAgnoSession,
415
- useAgnoToolExecution
460
+ useAgnoToolExecution,
461
+ useToolHandlers
416
462
  });
package/dist/index.mjs CHANGED
@@ -20,13 +20,39 @@ function useAgnoClient() {
20
20
  return client;
21
21
  }
22
22
 
23
+ // src/context/ToolHandlerContext.tsx
24
+ import { createContext as createContext2, useContext as useContext2, useState, useCallback } from "react";
25
+ import { jsx as jsx2 } from "react/jsx-runtime";
26
+ var ToolHandlerContext = createContext2(null);
27
+ function ToolHandlerProvider({ handlers: initialHandlers = {}, children }) {
28
+ const [handlers, setHandlers] = useState(initialHandlers);
29
+ const registerHandler = useCallback((name, handler) => {
30
+ setHandlers((prev) => ({ ...prev, [name]: handler }));
31
+ }, []);
32
+ const unregisterHandler = useCallback((name) => {
33
+ setHandlers((prev) => {
34
+ const { [name]: _, ...rest } = prev;
35
+ return rest;
36
+ });
37
+ }, []);
38
+ const value = {
39
+ handlers,
40
+ registerHandler,
41
+ unregisterHandler
42
+ };
43
+ return /* @__PURE__ */ jsx2(ToolHandlerContext.Provider, { value, children });
44
+ }
45
+ function useToolHandlers() {
46
+ return useContext2(ToolHandlerContext);
47
+ }
48
+
23
49
  // src/hooks/useAgnoChat.ts
24
- import { useState, useEffect as useEffect2, useCallback } from "react";
50
+ import { useState as useState2, useEffect as useEffect2, useCallback as useCallback2 } from "react";
25
51
  function useAgnoChat() {
26
52
  const client = useAgnoClient();
27
- const [messages, setMessages] = useState(client.getMessages());
28
- const [state, setState] = useState(client.getState());
29
- const [error, setError] = useState();
53
+ const [messages, setMessages] = useState2(client.getMessages());
54
+ const [state, setState] = useState2(client.getState());
55
+ const [error, setError] = useState2();
30
56
  useEffect2(() => {
31
57
  const handleMessageUpdate = (updatedMessages) => {
32
58
  console.log("[useAgnoChat] message:update event received, messages:", updatedMessages.length);
@@ -58,7 +84,7 @@ function useAgnoChat() {
58
84
  client.off("state:change", handleStateChange);
59
85
  };
60
86
  }, [client]);
61
- const sendMessage = useCallback(
87
+ const sendMessage = useCallback2(
62
88
  async (message, options) => {
63
89
  setError(void 0);
64
90
  try {
@@ -71,7 +97,7 @@ function useAgnoChat() {
71
97
  },
72
98
  [client]
73
99
  );
74
- const clearMessages = useCallback(() => {
100
+ const clearMessages = useCallback2(() => {
75
101
  client.clearMessages();
76
102
  setMessages([]);
77
103
  setError(void 0);
@@ -88,15 +114,15 @@ function useAgnoChat() {
88
114
  }
89
115
 
90
116
  // src/hooks/useAgnoSession.ts
91
- import { useState as useState2, useEffect as useEffect3, useCallback as useCallback2 } from "react";
117
+ import { useState as useState3, useEffect as useEffect3, useCallback as useCallback3 } from "react";
92
118
  function useAgnoSession() {
93
119
  const client = useAgnoClient();
94
- const [sessions, setSessions] = useState2([]);
95
- const [currentSessionId, setCurrentSessionId] = useState2(
120
+ const [sessions, setSessions] = useState3([]);
121
+ const [currentSessionId, setCurrentSessionId] = useState3(
96
122
  client.getConfig().sessionId
97
123
  );
98
- const [isLoading, setIsLoading] = useState2(false);
99
- const [error, setError] = useState2();
124
+ const [isLoading, setIsLoading] = useState3(false);
125
+ const [error, setError] = useState3();
100
126
  useEffect3(() => {
101
127
  const handleSessionLoaded = (sessionId) => {
102
128
  setCurrentSessionId(sessionId);
@@ -121,7 +147,7 @@ function useAgnoSession() {
121
147
  client.off("state:change", handleStateChange);
122
148
  };
123
149
  }, [client]);
124
- const loadSession = useCallback2(
150
+ const loadSession = useCallback3(
125
151
  async (sessionId) => {
126
152
  setIsLoading(true);
127
153
  setError(void 0);
@@ -139,7 +165,7 @@ function useAgnoSession() {
139
165
  },
140
166
  [client]
141
167
  );
142
- const fetchSessions = useCallback2(async () => {
168
+ const fetchSessions = useCallback3(async () => {
143
169
  setIsLoading(true);
144
170
  setError(void 0);
145
171
  try {
@@ -165,12 +191,12 @@ function useAgnoSession() {
165
191
  }
166
192
 
167
193
  // src/hooks/useAgnoActions.ts
168
- import { useState as useState3, useCallback as useCallback3 } from "react";
194
+ import { useState as useState4, useCallback as useCallback4 } from "react";
169
195
  function useAgnoActions() {
170
196
  const client = useAgnoClient();
171
- const [isInitializing, setIsInitializing] = useState3(false);
172
- const [error, setError] = useState3();
173
- const initialize = useCallback3(async () => {
197
+ const [isInitializing, setIsInitializing] = useState4(false);
198
+ const [error, setError] = useState4();
199
+ const initialize = useCallback4(async () => {
174
200
  setIsInitializing(true);
175
201
  setError(void 0);
176
202
  try {
@@ -184,7 +210,7 @@ function useAgnoActions() {
184
210
  setIsInitializing(false);
185
211
  }
186
212
  }, [client]);
187
- const checkStatus = useCallback3(async () => {
213
+ const checkStatus = useCallback4(async () => {
188
214
  setError(void 0);
189
215
  try {
190
216
  return await client.checkStatus();
@@ -194,7 +220,7 @@ function useAgnoActions() {
194
220
  return false;
195
221
  }
196
222
  }, [client]);
197
- const fetchAgents = useCallback3(async () => {
223
+ const fetchAgents = useCallback4(async () => {
198
224
  setError(void 0);
199
225
  try {
200
226
  return await client.fetchAgents();
@@ -204,7 +230,7 @@ function useAgnoActions() {
204
230
  throw err;
205
231
  }
206
232
  }, [client]);
207
- const fetchTeams = useCallback3(async () => {
233
+ const fetchTeams = useCallback4(async () => {
208
234
  setError(void 0);
209
235
  try {
210
236
  return await client.fetchTeams();
@@ -214,7 +240,7 @@ function useAgnoActions() {
214
240
  throw err;
215
241
  }
216
242
  }, [client]);
217
- const updateConfig = useCallback3(
243
+ const updateConfig = useCallback4(
218
244
  (updates) => {
219
245
  client.updateConfig(updates);
220
246
  },
@@ -232,16 +258,32 @@ function useAgnoActions() {
232
258
  }
233
259
 
234
260
  // src/hooks/useAgnoToolExecution.ts
235
- import { useState as useState4, useEffect as useEffect4, useCallback as useCallback4 } from "react";
236
- function useAgnoToolExecution(handlers, autoExecute = true) {
261
+ import { useState as useState5, useEffect as useEffect4, useCallback as useCallback5, useMemo as useMemo2 } from "react";
262
+ function useAgnoToolExecution(handlers = {}, autoExecute = true) {
237
263
  const client = useAgnoClient();
238
- const [pendingTools, setPendingTools] = useState4([]);
239
- const [isPaused, setIsPaused] = useState4(false);
240
- const [isExecuting, setIsExecuting] = useState4(false);
241
- const [executionError, setExecutionError] = useState4();
264
+ const toolHandlerContext = useToolHandlers();
265
+ const mergedHandlers = useMemo2(() => {
266
+ const globalHandlers = toolHandlerContext?.handlers || {};
267
+ return { ...globalHandlers, ...handlers };
268
+ }, [toolHandlerContext?.handlers, handlers]);
269
+ const [pendingTools, setPendingTools] = useState5([]);
270
+ const [isPaused, setIsPaused] = useState5(false);
271
+ const [isExecuting, setIsExecuting] = useState5(false);
272
+ const [executionError, setExecutionError] = useState5();
242
273
  useEffect4(() => {
243
274
  const handleRunPaused = (event) => {
244
- console.log("[useAgnoToolExecution] Run paused, tools:", event.tools);
275
+ console.log("[useAgnoToolExecution] Run paused event received");
276
+ console.log("[useAgnoToolExecution] Event:", event);
277
+ console.log("[useAgnoToolExecution] Tools:", event.tools);
278
+ console.log("[useAgnoToolExecution] Number of tools:", event.tools?.length);
279
+ event.tools?.forEach((tool, idx) => {
280
+ console.log(`[useAgnoToolExecution] Tool ${idx}:`, {
281
+ name: tool.tool_name,
282
+ id: tool.tool_call_id,
283
+ args_type: typeof tool.tool_args,
284
+ args: tool.tool_args
285
+ });
286
+ });
245
287
  setIsPaused(true);
246
288
  setPendingTools(event.tools);
247
289
  setExecutionError(void 0);
@@ -260,7 +302,7 @@ function useAgnoToolExecution(handlers, autoExecute = true) {
260
302
  client.off("run:continued", handleRunContinued);
261
303
  };
262
304
  }, [client]);
263
- const executeAndContinue = useCallback4(async () => {
305
+ const executeAndContinue = useCallback5(async () => {
264
306
  if (!isPaused || pendingTools.length === 0) {
265
307
  console.warn("[useAgnoToolExecution] Cannot execute: no pending tools");
266
308
  return;
@@ -271,7 +313,7 @@ function useAgnoToolExecution(handlers, autoExecute = true) {
271
313
  console.log("[useAgnoToolExecution] Executing", pendingTools.length, "tools");
272
314
  const updatedTools = await Promise.all(
273
315
  pendingTools.map(async (tool) => {
274
- const handler = handlers[tool.tool_name];
316
+ const handler = mergedHandlers[tool.tool_name];
275
317
  if (!handler) {
276
318
  console.warn(`[useAgnoToolExecution] No handler for tool: ${tool.tool_name}`);
277
319
  return {
@@ -309,12 +351,12 @@ function useAgnoToolExecution(handlers, autoExecute = true) {
309
351
  setIsExecuting(false);
310
352
  throw error;
311
353
  }
312
- }, [client, handlers, isPaused, pendingTools]);
313
- const executeTools = useCallback4(
354
+ }, [client, mergedHandlers, isPaused, pendingTools]);
355
+ const executeTools = useCallback5(
314
356
  async (tools) => {
315
357
  return Promise.all(
316
358
  tools.map(async (tool) => {
317
- const handler = handlers[tool.tool_name];
359
+ const handler = mergedHandlers[tool.tool_name];
318
360
  if (!handler)
319
361
  return tool;
320
362
  try {
@@ -334,9 +376,9 @@ function useAgnoToolExecution(handlers, autoExecute = true) {
334
376
  })
335
377
  );
336
378
  },
337
- [handlers]
379
+ [mergedHandlers]
338
380
  );
339
- const continueWithResults = useCallback4(
381
+ const continueWithResults = useCallback5(
340
382
  async (tools) => {
341
383
  if (!isPaused) {
342
384
  throw new Error("No paused run to continue");
@@ -376,9 +418,11 @@ function useAgnoToolExecution(handlers, autoExecute = true) {
376
418
  }
377
419
  export {
378
420
  AgnoProvider,
421
+ ToolHandlerProvider,
379
422
  useAgnoActions,
380
423
  useAgnoChat,
381
424
  useAgnoClient,
382
425
  useAgnoSession,
383
- useAgnoToolExecution
426
+ useAgnoToolExecution,
427
+ useToolHandlers
384
428
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antipopp/agno-react",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "React hooks for Agno client with frontend tool execution (HITL) support",
5
5
  "author": "antipopp",
6
6
  "license": "MIT",
@@ -34,8 +34,8 @@
34
34
  "README.md"
35
35
  ],
36
36
  "dependencies": {
37
- "@antipopp/agno-client": "0.1.0",
38
- "@antipopp/agno-types": "0.1.0"
37
+ "@antipopp/agno-client": "0.2.0",
38
+ "@antipopp/agno-types": "0.2.0"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "react": "^18.0.0"