@agentick/react 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Agentick Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,275 @@
1
+ # @agentick/react
2
+
3
+ React bindings for Agentick. Provides hooks around `@agentick/client` for building chat interfaces and real-time AI applications.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @agentick/react
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```tsx
14
+ import { AgentickProvider, useSession, useStreamingText, useContextInfo } from "@agentick/react";
15
+
16
+ function Chat() {
17
+ const { send } = useSession({ sessionId: "my-session", autoSubscribe: true });
18
+ const { text, isStreaming } = useStreamingText();
19
+ const { contextInfo } = useContextInfo();
20
+
21
+ return (
22
+ <div>
23
+ <div className="response">
24
+ {text}
25
+ {isStreaming && <span className="cursor">|</span>}
26
+ </div>
27
+
28
+ {contextInfo && (
29
+ <div className="context-bar">
30
+ <span>{contextInfo.modelName}</span>
31
+ <span>{contextInfo.utilization?.toFixed(1)}% context used</span>
32
+ </div>
33
+ )}
34
+
35
+ <button onClick={() => send("Hello!")}>Send</button>
36
+ </div>
37
+ );
38
+ }
39
+
40
+ export function App() {
41
+ return (
42
+ <AgentickProvider clientConfig={{ baseUrl: "/api" }}>
43
+ <Chat />
44
+ </AgentickProvider>
45
+ );
46
+ }
47
+ ```
48
+
49
+ ## Hooks
50
+
51
+ ### `useSession(options?)`
52
+
53
+ Session management hook. Returns methods for sending messages and managing subscriptions.
54
+
55
+ ```tsx
56
+ const {
57
+ sessionId, // Current session ID
58
+ isSubscribed, // Whether subscribed to session events
59
+ subscribe, // Subscribe to session events
60
+ unsubscribe, // Unsubscribe from session events
61
+ send, // Send a message
62
+ abort, // Abort current execution
63
+ close, // Close the session
64
+ accessor, // Direct SessionAccessor for advanced use
65
+ } = useSession({
66
+ sessionId: "my-session", // Optional - creates ephemeral session if omitted
67
+ autoSubscribe: true, // Auto-subscribe on mount
68
+ });
69
+
70
+ // Send a simple text message
71
+ await send("Hello!");
72
+
73
+ // Send with full message structure
74
+ await send({
75
+ message: {
76
+ role: "user",
77
+ content: [{ type: "text", text: "Hello!" }],
78
+ },
79
+ });
80
+ ```
81
+
82
+ ### `useStreamingText(options?)`
83
+
84
+ Subscribe to streaming text from model responses. Automatically accumulates text deltas.
85
+
86
+ ```tsx
87
+ const {
88
+ text, // Accumulated text from current response
89
+ isStreaming, // Whether currently receiving text
90
+ clear, // Clear accumulated text
91
+ } = useStreamingText({
92
+ enabled: true, // Enable/disable subscription
93
+ });
94
+
95
+ // Display with typing indicator
96
+ <div>
97
+ {text}
98
+ {isStreaming && <span className="cursor">|</span>}
99
+ </div>
100
+ ```
101
+
102
+ ### `useContextInfo(options?)`
103
+
104
+ Subscribe to context utilization information. Updated after each model response with token usage and model capabilities.
105
+
106
+ ```tsx
107
+ const {
108
+ contextInfo, // Latest context info (null before first response)
109
+ clear, // Clear context info
110
+ } = useContextInfo({
111
+ sessionId: "my-session", // Optional - filter by session
112
+ enabled: true, // Enable/disable subscription
113
+ });
114
+
115
+ if (contextInfo) {
116
+ console.log(contextInfo.modelId); // "gpt-4o" | "claude-3-5-sonnet" | etc.
117
+ console.log(contextInfo.modelName); // Human-readable name
118
+ console.log(contextInfo.provider); // "openai" | "anthropic" | etc.
119
+ console.log(contextInfo.contextWindow); // Total context window size
120
+ console.log(contextInfo.inputTokens); // Input tokens this tick
121
+ console.log(contextInfo.outputTokens); // Output tokens this tick
122
+ console.log(contextInfo.totalTokens); // Total tokens this tick
123
+ console.log(contextInfo.utilization); // Context utilization % (0-100)
124
+ console.log(contextInfo.maxOutputTokens); // Max output tokens for model
125
+ console.log(contextInfo.supportsVision); // Model supports vision
126
+ console.log(contextInfo.supportsToolUse); // Model supports tools
127
+ console.log(contextInfo.isReasoningModel);// Extended thinking model
128
+
129
+ // Cumulative usage across all ticks in execution
130
+ console.log(contextInfo.cumulativeUsage?.inputTokens);
131
+ console.log(contextInfo.cumulativeUsage?.outputTokens);
132
+ console.log(contextInfo.cumulativeUsage?.ticks);
133
+ }
134
+ ```
135
+
136
+ #### ContextInfo Interface
137
+
138
+ ```typescript
139
+ interface ContextInfo {
140
+ modelId: string; // Model identifier (e.g., "gpt-4o")
141
+ modelName?: string; // Human-readable name
142
+ provider?: string; // Provider name
143
+ contextWindow?: number; // Context window size in tokens
144
+ inputTokens: number; // Input tokens this tick
145
+ outputTokens: number; // Output tokens this tick
146
+ totalTokens: number; // Total tokens this tick
147
+ utilization?: number; // Context utilization % (0-100)
148
+ maxOutputTokens?: number; // Max output tokens
149
+ supportsVision?: boolean; // Vision capability
150
+ supportsToolUse?: boolean; // Tool use capability
151
+ isReasoningModel?: boolean;// Extended thinking capability
152
+ tick: number; // Current tick number
153
+ cumulativeUsage?: {
154
+ inputTokens: number;
155
+ outputTokens: number;
156
+ totalTokens: number;
157
+ ticks: number;
158
+ };
159
+ }
160
+ ```
161
+
162
+ ### `useEvents(options?)`
163
+
164
+ Subscribe to raw stream events. Use for advanced event handling.
165
+
166
+ ```tsx
167
+ const {
168
+ event, // Latest event
169
+ clear, // Clear current event
170
+ } = useEvents({
171
+ sessionId: "my-session", // Optional - filter by session
172
+ filter: ["tool_call", "tool_result"], // Optional - filter by event type
173
+ enabled: true,
174
+ });
175
+
176
+ useEffect(() => {
177
+ if (event?.type === "tool_call") {
178
+ console.log("Tool called:", event.name);
179
+ }
180
+ }, [event]);
181
+ ```
182
+
183
+ ### `useConnection()`
184
+
185
+ Connection state for the SSE transport.
186
+
187
+ ```tsx
188
+ const {
189
+ state, // "disconnected" | "connecting" | "connected"
190
+ isConnected, // Convenience boolean
191
+ isConnecting, // Convenience boolean
192
+ } = useConnection();
193
+
194
+ <div className={`status ${isConnected ? "online" : "offline"}`}>
195
+ {isConnected ? "Connected" : "Disconnected"}
196
+ </div>
197
+ ```
198
+
199
+ ### `useConnectionState()`
200
+
201
+ Alias for `useConnection()`. Returns just the connection state string.
202
+
203
+ ```tsx
204
+ const state = useConnectionState(); // "disconnected" | "connecting" | "connected"
205
+ ```
206
+
207
+ ### `useClient()`
208
+
209
+ Direct access to the underlying `AgentickClient` for advanced use cases.
210
+
211
+ ```tsx
212
+ const client = useClient();
213
+
214
+ // Direct client access
215
+ const session = client.session("my-session");
216
+ const channel = session.channel("custom");
217
+ channel.publish("event", { data: "value" });
218
+ ```
219
+
220
+ ## Provider
221
+
222
+ ### `AgentickProvider`
223
+
224
+ Wraps your app to provide the Agentick client context.
225
+
226
+ ```tsx
227
+ <AgentickProvider
228
+ clientConfig={{
229
+ baseUrl: "https://api.example.com", // Required - API base URL
230
+ token: "auth-token", // Optional - auth token
231
+ }}
232
+ >
233
+ <App />
234
+ </AgentickProvider>
235
+ ```
236
+
237
+ ## Types
238
+
239
+ All hooks are fully typed. Import types from the package:
240
+
241
+ ```typescript
242
+ import type {
243
+ // Provider types
244
+ AgentickProviderProps,
245
+ AgentickContextValue,
246
+ TransportConfig,
247
+
248
+ // Hook types
249
+ UseConnectionOptions,
250
+ UseConnectionResult,
251
+ UseSessionOptions,
252
+ UseSessionResult,
253
+ UseEventsOptions,
254
+ UseEventsResult,
255
+ UseStreamingTextOptions,
256
+ UseStreamingTextResult,
257
+ UseContextInfoOptions,
258
+ UseContextInfoResult,
259
+ ContextInfo,
260
+
261
+ // Re-exported from @agentick/client
262
+ AgentickClient,
263
+ ConnectionState,
264
+ StreamEvent,
265
+ SessionAccessor,
266
+ SendInput,
267
+ ClientExecutionHandle,
268
+ SessionStreamEvent,
269
+ ClientTransport,
270
+ } from "@agentick/react";
271
+ ```
272
+
273
+ ## License
274
+
275
+ MIT
@@ -0,0 +1,90 @@
1
+ /**
2
+ * React context for Agentick client.
3
+ *
4
+ * @module @agentick/react/context
5
+ */
6
+ import type { AgentickProviderProps, AgentickContextValue } from "./types";
7
+ export declare const AgentickContext: import("react").Context<AgentickContextValue | null>;
8
+ /**
9
+ * Provider for Agentick client context.
10
+ *
11
+ * Either provide a pre-configured client or clientConfig to create one.
12
+ *
13
+ * @example With client config
14
+ * ```tsx
15
+ * import { AgentickProvider } from '@agentick/react';
16
+ *
17
+ * function App() {
18
+ * return (
19
+ * <AgentickProvider
20
+ * clientConfig={{
21
+ * baseUrl: 'https://api.example.com',
22
+ * token: 'my-token',
23
+ * }}
24
+ * >
25
+ * <Chat />
26
+ * </AgentickProvider>
27
+ * );
28
+ * }
29
+ * ```
30
+ *
31
+ * @example With pre-configured client
32
+ * ```tsx
33
+ * import { AgentickProvider } from '@agentick/react';
34
+ * import { createClient } from '@agentick/client';
35
+ *
36
+ * const client = createClient({
37
+ * baseUrl: 'https://api.example.com',
38
+ * token: 'my-token',
39
+ * });
40
+ *
41
+ * function App() {
42
+ * return (
43
+ * <AgentickProvider client={client}>
44
+ * <Chat />
45
+ * </AgentickProvider>
46
+ * );
47
+ * }
48
+ * ```
49
+ *
50
+ * @example Multiple agents with separate instances
51
+ * ```tsx
52
+ * // Each provider creates its own client and connection
53
+ * function App() {
54
+ * return (
55
+ * <div className="dashboard">
56
+ * <AgentickProvider clientConfig={{ baseUrl: '/api/support-agent' }}>
57
+ * <SupportChat />
58
+ * </AgentickProvider>
59
+ *
60
+ * <AgentickProvider clientConfig={{ baseUrl: '/api/sales-agent' }}>
61
+ * <SalesChat />
62
+ * </AgentickProvider>
63
+ * </div>
64
+ * );
65
+ * }
66
+ * ```
67
+ *
68
+ * @example Sharing a client between components
69
+ * ```tsx
70
+ * // Create one client, share across multiple providers
71
+ * const sharedClient = createClient({ baseUrl: '/api/agent' });
72
+ *
73
+ * function App() {
74
+ * return (
75
+ * <>
76
+ * <AgentickProvider client={sharedClient}>
77
+ * <MainChat />
78
+ * </AgentickProvider>
79
+ *
80
+ * {/* Both providers share the same client and connection * /}
81
+ * <AgentickProvider client={sharedClient}>
82
+ * <ChatSidebar />
83
+ * </AgentickProvider>
84
+ * </>
85
+ * );
86
+ * }
87
+ * ```
88
+ */
89
+ export declare function AgentickProvider({ client: providedClient, clientConfig, children, }: AgentickProviderProps): import("react/jsx-runtime").JSX.Element;
90
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAM3E,eAAO,MAAM,eAAe,sDAAmD,CAAC;AAMhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EAAE,cAAc,EACtB,YAAY,EACZ,QAAQ,GACT,EAAE,qBAAqB,2CA2BvB"}
@@ -0,0 +1,120 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * React context for Agentick client.
4
+ *
5
+ * @module @agentick/react/context
6
+ */
7
+ import { createContext, useMemo, useEffect } from "react";
8
+ import { createClient } from "@agentick/client";
9
+ // ============================================================================
10
+ // Context
11
+ // ============================================================================
12
+ export const AgentickContext = createContext(null);
13
+ // ============================================================================
14
+ // Provider
15
+ // ============================================================================
16
+ /**
17
+ * Provider for Agentick client context.
18
+ *
19
+ * Either provide a pre-configured client or clientConfig to create one.
20
+ *
21
+ * @example With client config
22
+ * ```tsx
23
+ * import { AgentickProvider } from '@agentick/react';
24
+ *
25
+ * function App() {
26
+ * return (
27
+ * <AgentickProvider
28
+ * clientConfig={{
29
+ * baseUrl: 'https://api.example.com',
30
+ * token: 'my-token',
31
+ * }}
32
+ * >
33
+ * <Chat />
34
+ * </AgentickProvider>
35
+ * );
36
+ * }
37
+ * ```
38
+ *
39
+ * @example With pre-configured client
40
+ * ```tsx
41
+ * import { AgentickProvider } from '@agentick/react';
42
+ * import { createClient } from '@agentick/client';
43
+ *
44
+ * const client = createClient({
45
+ * baseUrl: 'https://api.example.com',
46
+ * token: 'my-token',
47
+ * });
48
+ *
49
+ * function App() {
50
+ * return (
51
+ * <AgentickProvider client={client}>
52
+ * <Chat />
53
+ * </AgentickProvider>
54
+ * );
55
+ * }
56
+ * ```
57
+ *
58
+ * @example Multiple agents with separate instances
59
+ * ```tsx
60
+ * // Each provider creates its own client and connection
61
+ * function App() {
62
+ * return (
63
+ * <div className="dashboard">
64
+ * <AgentickProvider clientConfig={{ baseUrl: '/api/support-agent' }}>
65
+ * <SupportChat />
66
+ * </AgentickProvider>
67
+ *
68
+ * <AgentickProvider clientConfig={{ baseUrl: '/api/sales-agent' }}>
69
+ * <SalesChat />
70
+ * </AgentickProvider>
71
+ * </div>
72
+ * );
73
+ * }
74
+ * ```
75
+ *
76
+ * @example Sharing a client between components
77
+ * ```tsx
78
+ * // Create one client, share across multiple providers
79
+ * const sharedClient = createClient({ baseUrl: '/api/agent' });
80
+ *
81
+ * function App() {
82
+ * return (
83
+ * <>
84
+ * <AgentickProvider client={sharedClient}>
85
+ * <MainChat />
86
+ * </AgentickProvider>
87
+ *
88
+ * {/* Both providers share the same client and connection * /}
89
+ * <AgentickProvider client={sharedClient}>
90
+ * <ChatSidebar />
91
+ * </AgentickProvider>
92
+ * </>
93
+ * );
94
+ * }
95
+ * ```
96
+ */
97
+ export function AgentickProvider({ client: providedClient, clientConfig, children, }) {
98
+ // Create client from config if not provided
99
+ const client = useMemo(() => {
100
+ if (providedClient) {
101
+ return providedClient;
102
+ }
103
+ if (!clientConfig) {
104
+ throw new Error("AgentickProvider requires either a client or clientConfig prop");
105
+ }
106
+ return createClient(clientConfig);
107
+ }, [providedClient, clientConfig]);
108
+ // Cleanup on unmount (only if we created the client)
109
+ useEffect(() => {
110
+ // Only destroy if we created it (not provided)
111
+ if (!providedClient) {
112
+ return () => {
113
+ client.destroy();
114
+ };
115
+ }
116
+ }, [client, providedClient]);
117
+ const value = useMemo(() => ({ client }), [client]);
118
+ return _jsx(AgentickContext.Provider, { value: value, children: children });
119
+ }
120
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,+EAA+E;AAC/E,UAAU;AACV,+EAA+E;AAE/E,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAA8B,IAAI,CAAC,CAAC;AAEhF,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,MAAM,EAAE,cAAc,EACtB,YAAY,EACZ,QAAQ,GACc;IACtB,4CAA4C;IAC5C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE;QAC1B,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,cAAc,CAAC;QACxB,CAAC;QAED,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACpF,CAAC;QAED,OAAO,YAAY,CAAC,YAAY,CAAC,CAAC;IACpC,CAAC,EAAE,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC,CAAC;IAEnC,qDAAqD;IACrD,SAAS,CAAC,GAAG,EAAE;QACb,+CAA+C;QAC/C,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO,GAAG,EAAE;gBACV,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,CAAC,CAAC;QACJ,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;IAE7B,MAAM,KAAK,GAAG,OAAO,CAAuB,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAE1E,OAAO,KAAC,eAAe,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAA4B,CAAC;AACvF,CAAC"}