@rickydata/react 0.1.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.cjs +968 -0
- package/dist/index.d.cts +603 -0
- package/dist/index.d.ts +603 -0
- package/dist/index.js +917 -0
- package/package.json +36 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,917 @@
|
|
|
1
|
+
// src/providers/RickyDataProvider.tsx
|
|
2
|
+
import { createContext, useContext, useMemo } from "react";
|
|
3
|
+
import { AgentClient } from "rickydata/agent";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
var RickyDataContext = createContext(null);
|
|
6
|
+
function RickyDataProvider({ config, client, children }) {
|
|
7
|
+
const agentClient = useMemo(() => {
|
|
8
|
+
if (client) return client;
|
|
9
|
+
if (!config) throw new Error("RickyDataProvider requires either `config` or `client`");
|
|
10
|
+
return new AgentClient({
|
|
11
|
+
tokenGetter: config.getAuthToken,
|
|
12
|
+
gatewayUrl: config.gatewayUrl
|
|
13
|
+
});
|
|
14
|
+
}, [client, config?.getAuthToken, config?.gatewayUrl]);
|
|
15
|
+
return /* @__PURE__ */ jsx(RickyDataContext.Provider, { value: agentClient, children });
|
|
16
|
+
}
|
|
17
|
+
function useRickyData() {
|
|
18
|
+
const ctx = useContext(RickyDataContext);
|
|
19
|
+
if (!ctx) {
|
|
20
|
+
throw new Error("useRickyData must be used within a <RickyDataProvider>");
|
|
21
|
+
}
|
|
22
|
+
return ctx;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/hooks/agents.ts
|
|
26
|
+
import { useQuery } from "@tanstack/react-query";
|
|
27
|
+
var agentKeys = {
|
|
28
|
+
all: ["agents"],
|
|
29
|
+
lists: () => [...agentKeys.all, "list"],
|
|
30
|
+
details: () => [...agentKeys.all, "detail"],
|
|
31
|
+
detail: (id) => [...agentKeys.details(), id]
|
|
32
|
+
};
|
|
33
|
+
function useAgents() {
|
|
34
|
+
const client = useRickyData();
|
|
35
|
+
return useQuery({
|
|
36
|
+
queryKey: agentKeys.lists(),
|
|
37
|
+
queryFn: () => client.listAgents(),
|
|
38
|
+
staleTime: 5 * 60 * 1e3
|
|
39
|
+
// 5 min
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function useAgent(agentId) {
|
|
43
|
+
const client = useRickyData();
|
|
44
|
+
return useQuery({
|
|
45
|
+
queryKey: agentKeys.detail(agentId),
|
|
46
|
+
queryFn: () => client.getAgent(agentId),
|
|
47
|
+
enabled: !!agentId
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/hooks/apikey.ts
|
|
52
|
+
import { useQuery as useQuery2, useMutation, useQueryClient } from "@tanstack/react-query";
|
|
53
|
+
var apiKeyKeys = {
|
|
54
|
+
all: ["apikey"],
|
|
55
|
+
status: () => [...apiKeyKeys.all, "status"],
|
|
56
|
+
openai: () => [...apiKeyKeys.all, "openai"]
|
|
57
|
+
};
|
|
58
|
+
function useApiKeyStatus() {
|
|
59
|
+
const client = useRickyData();
|
|
60
|
+
return useQuery2({
|
|
61
|
+
queryKey: apiKeyKeys.status(),
|
|
62
|
+
queryFn: () => client.getApiKeyStatus(),
|
|
63
|
+
staleTime: 3e4
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function useSetApiKey() {
|
|
67
|
+
const client = useRickyData();
|
|
68
|
+
const queryClient = useQueryClient();
|
|
69
|
+
return useMutation({
|
|
70
|
+
mutationFn: (apiKey) => client.setApiKey(apiKey),
|
|
71
|
+
onSuccess: () => {
|
|
72
|
+
queryClient.invalidateQueries({ queryKey: apiKeyKeys.status() });
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function useDeleteApiKey() {
|
|
77
|
+
const client = useRickyData();
|
|
78
|
+
const queryClient = useQueryClient();
|
|
79
|
+
return useMutation({
|
|
80
|
+
mutationFn: () => client.deleteApiKey(),
|
|
81
|
+
onSuccess: () => {
|
|
82
|
+
queryClient.invalidateQueries({ queryKey: apiKeyKeys.status() });
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function useOpenAIApiKeyStatus() {
|
|
87
|
+
const client = useRickyData();
|
|
88
|
+
return useQuery2({
|
|
89
|
+
queryKey: apiKeyKeys.openai(),
|
|
90
|
+
queryFn: () => client.getOpenAIApiKeyStatus(),
|
|
91
|
+
staleTime: 3e4
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function useSetOpenAIApiKey() {
|
|
95
|
+
const client = useRickyData();
|
|
96
|
+
const queryClient = useQueryClient();
|
|
97
|
+
return useMutation({
|
|
98
|
+
mutationFn: (apiKey) => client.storeOpenAIApiKey(apiKey),
|
|
99
|
+
onSuccess: () => {
|
|
100
|
+
queryClient.invalidateQueries({ queryKey: apiKeyKeys.openai() });
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// src/hooks/balance.ts
|
|
106
|
+
import { useQuery as useQuery3 } from "@tanstack/react-query";
|
|
107
|
+
var balanceKeys = {
|
|
108
|
+
all: ["wallet-balance"],
|
|
109
|
+
balance: () => [...balanceKeys.all, "balance"],
|
|
110
|
+
transactions: (limit, offset) => [...balanceKeys.all, "transactions", { limit, offset }]
|
|
111
|
+
};
|
|
112
|
+
function useWalletBalance(opts) {
|
|
113
|
+
const client = useRickyData();
|
|
114
|
+
const query = useQuery3({
|
|
115
|
+
queryKey: balanceKeys.balance(),
|
|
116
|
+
queryFn: () => client.getWalletBalance(),
|
|
117
|
+
staleTime: opts?.staleTime ?? 6e4,
|
|
118
|
+
enabled: opts?.enabled !== false
|
|
119
|
+
});
|
|
120
|
+
const balance = query.data?.availableBalance ?? "0";
|
|
121
|
+
const num = parseFloat(balance);
|
|
122
|
+
const balanceDisplay = isNaN(num) ? "$0.00" : num >= 0.01 ? `$${num.toFixed(2)}` : num > 0 ? `$${num.toFixed(4)}` : "$0.00";
|
|
123
|
+
return {
|
|
124
|
+
...query,
|
|
125
|
+
balance,
|
|
126
|
+
balanceDisplay,
|
|
127
|
+
depositAddress: query.data?.unifiedDepositAddress,
|
|
128
|
+
agentSpends: query.data?.agentSpends,
|
|
129
|
+
refresh: () => query.refetch()
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function useWalletTransactions(limit, offset) {
|
|
133
|
+
const client = useRickyData();
|
|
134
|
+
return useQuery3({
|
|
135
|
+
queryKey: balanceKeys.transactions(limit, offset),
|
|
136
|
+
queryFn: () => client.getWalletTransactions(limit, offset),
|
|
137
|
+
staleTime: 3e4
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// src/hooks/sessions.ts
|
|
142
|
+
import { useQuery as useQuery4, useMutation as useMutation2, useQueryClient as useQueryClient2 } from "@tanstack/react-query";
|
|
143
|
+
var sessionKeys = {
|
|
144
|
+
all: ["sessions"],
|
|
145
|
+
lists: (agentId) => [...sessionKeys.all, "list", agentId],
|
|
146
|
+
details: () => [...sessionKeys.all, "detail"],
|
|
147
|
+
detail: (agentId, sessionId) => [...sessionKeys.details(), agentId, sessionId]
|
|
148
|
+
};
|
|
149
|
+
function useSessions(agentId) {
|
|
150
|
+
const client = useRickyData();
|
|
151
|
+
return useQuery4({
|
|
152
|
+
queryKey: sessionKeys.lists(agentId),
|
|
153
|
+
queryFn: () => client.listSessions(agentId),
|
|
154
|
+
enabled: !!agentId,
|
|
155
|
+
staleTime: 3e4
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
function useSession(agentId, sessionId) {
|
|
159
|
+
const client = useRickyData();
|
|
160
|
+
return useQuery4({
|
|
161
|
+
queryKey: sessionKeys.detail(agentId, sessionId),
|
|
162
|
+
queryFn: () => client.getSession(agentId, sessionId),
|
|
163
|
+
enabled: !!agentId && !!sessionId
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
function useDeleteSession() {
|
|
167
|
+
const client = useRickyData();
|
|
168
|
+
const queryClient = useQueryClient2();
|
|
169
|
+
return useMutation2({
|
|
170
|
+
mutationFn: ({ agentId, sessionId }) => client.deleteSession(agentId, sessionId),
|
|
171
|
+
onSuccess: (_data, { agentId }) => {
|
|
172
|
+
queryClient.invalidateQueries({ queryKey: sessionKeys.lists(agentId) });
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// src/hooks/wallet-settings.ts
|
|
178
|
+
import { useQuery as useQuery5, useMutation as useMutation3, useQueryClient as useQueryClient3 } from "@tanstack/react-query";
|
|
179
|
+
var walletSettingsKeys = {
|
|
180
|
+
all: ["wallet-settings"],
|
|
181
|
+
settings: () => [...walletSettingsKeys.all, "current"]
|
|
182
|
+
};
|
|
183
|
+
function useWalletSettings() {
|
|
184
|
+
const client = useRickyData();
|
|
185
|
+
const queryClient = useQueryClient3();
|
|
186
|
+
const query = useQuery5({
|
|
187
|
+
queryKey: walletSettingsKeys.settings(),
|
|
188
|
+
queryFn: () => client.getWalletSettings(),
|
|
189
|
+
staleTime: 6e4
|
|
190
|
+
});
|
|
191
|
+
const mutation = useMutation3({
|
|
192
|
+
mutationFn: (settings) => client.updateWalletSettings(settings),
|
|
193
|
+
onSuccess: (data) => {
|
|
194
|
+
queryClient.setQueryData(walletSettingsKeys.settings(), data);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
return {
|
|
198
|
+
...query,
|
|
199
|
+
settings: query.data,
|
|
200
|
+
updateSettings: mutation.mutateAsync,
|
|
201
|
+
isUpdating: mutation.isPending
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// src/hooks/secrets.ts
|
|
206
|
+
import { useState, useEffect, useCallback } from "react";
|
|
207
|
+
function useSecrets({ agentId, mcpServers = [] }) {
|
|
208
|
+
const client = useRickyData();
|
|
209
|
+
const [sections, setSections] = useState([]);
|
|
210
|
+
const [loading, setLoading] = useState(true);
|
|
211
|
+
const fetchRequirements = useCallback(async () => {
|
|
212
|
+
setLoading(true);
|
|
213
|
+
const result = [];
|
|
214
|
+
try {
|
|
215
|
+
const { configured } = await client.getApiKeyStatus();
|
|
216
|
+
if (!configured) {
|
|
217
|
+
result.push({
|
|
218
|
+
id: "anthropic",
|
|
219
|
+
label: "Anthropic API Key",
|
|
220
|
+
keys: ["ANTHROPIC_API_KEY"],
|
|
221
|
+
configuredKeys: [],
|
|
222
|
+
save: async (secrets) => {
|
|
223
|
+
const key = secrets["ANTHROPIC_API_KEY"];
|
|
224
|
+
if (key) await client.setApiKey(key);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
} catch {
|
|
229
|
+
}
|
|
230
|
+
try {
|
|
231
|
+
const status = await client.getAgentSecretStatus(agentId);
|
|
232
|
+
if (status.missingRequired.length > 0) {
|
|
233
|
+
result.push({
|
|
234
|
+
id: `agent-${agentId}`,
|
|
235
|
+
label: "Agent Secrets",
|
|
236
|
+
keys: status.missingRequired,
|
|
237
|
+
configuredKeys: status.configuredSecrets,
|
|
238
|
+
save: async (secrets) => {
|
|
239
|
+
await client.storeAgentSecrets(agentId, secrets);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
} catch {
|
|
244
|
+
}
|
|
245
|
+
if (mcpServers.length > 0) {
|
|
246
|
+
try {
|
|
247
|
+
const reqs = await client.getMcpRequirements(agentId);
|
|
248
|
+
for (const server of reqs.servers) {
|
|
249
|
+
const missing = server.missing || server.required.filter((k) => !server.configured?.includes(k));
|
|
250
|
+
if (missing.length > 0) {
|
|
251
|
+
result.push({
|
|
252
|
+
id: `mcp-${server.serverId}`,
|
|
253
|
+
label: `MCP: ${server.name || server.serverId}`,
|
|
254
|
+
keys: missing,
|
|
255
|
+
configuredKeys: server.configured || [],
|
|
256
|
+
save: async (secrets) => {
|
|
257
|
+
await client.storeMcpSecrets(server.serverId, secrets);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
} catch {
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
setSections(result);
|
|
266
|
+
setLoading(false);
|
|
267
|
+
}, [client, agentId, mcpServers.join(",")]);
|
|
268
|
+
useEffect(() => {
|
|
269
|
+
fetchRequirements();
|
|
270
|
+
}, [fetchRequirements]);
|
|
271
|
+
return {
|
|
272
|
+
sections,
|
|
273
|
+
loading,
|
|
274
|
+
allConfigured: !loading && sections.length === 0,
|
|
275
|
+
refresh: fetchRequirements
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// src/hooks/chat.ts
|
|
280
|
+
import { useState as useState2, useCallback as useCallback2, useRef, useEffect as useEffect2 } from "react";
|
|
281
|
+
import { streamSSEEvents } from "rickydata/agent";
|
|
282
|
+
function useAgentChat({
|
|
283
|
+
agentId,
|
|
284
|
+
model = "haiku",
|
|
285
|
+
resumeSessionId
|
|
286
|
+
}) {
|
|
287
|
+
const client = useRickyData();
|
|
288
|
+
const [messages, setMessages] = useState2([]);
|
|
289
|
+
const [messagesLoading, setMessagesLoading] = useState2(!!resumeSessionId);
|
|
290
|
+
const [sending, setSending] = useState2(false);
|
|
291
|
+
const [sessionId, setSessionId] = useState2(resumeSessionId || null);
|
|
292
|
+
const [streamingPhase, setStreamingPhase] = useState2("idle");
|
|
293
|
+
const [activeTools, setActiveTools] = useState2([]);
|
|
294
|
+
const [apiKeyConfigured, setApiKeyConfigured] = useState2(null);
|
|
295
|
+
const modelRef = useRef(model);
|
|
296
|
+
modelRef.current = model;
|
|
297
|
+
useEffect2(() => {
|
|
298
|
+
let cancelled = false;
|
|
299
|
+
client.getApiKeyStatus().then(({ configured }) => {
|
|
300
|
+
if (!cancelled) setApiKeyConfigured(configured);
|
|
301
|
+
}).catch(() => {
|
|
302
|
+
if (!cancelled) setApiKeyConfigured(false);
|
|
303
|
+
});
|
|
304
|
+
return () => {
|
|
305
|
+
cancelled = true;
|
|
306
|
+
};
|
|
307
|
+
}, [client]);
|
|
308
|
+
useEffect2(() => {
|
|
309
|
+
if (!resumeSessionId) return;
|
|
310
|
+
let cancelled = false;
|
|
311
|
+
client.getSession(agentId, resumeSessionId).then((session) => {
|
|
312
|
+
if (cancelled) return;
|
|
313
|
+
const msgs = session.messages.map((m, i) => ({
|
|
314
|
+
id: `restored-${i}`,
|
|
315
|
+
role: m.role === "user" ? "user" : "agent",
|
|
316
|
+
content: m.content,
|
|
317
|
+
timestamp: m.timestamp || session.createdAt
|
|
318
|
+
}));
|
|
319
|
+
setMessages(msgs);
|
|
320
|
+
setMessagesLoading(false);
|
|
321
|
+
}).catch(() => {
|
|
322
|
+
if (!cancelled) setMessagesLoading(false);
|
|
323
|
+
});
|
|
324
|
+
return () => {
|
|
325
|
+
cancelled = true;
|
|
326
|
+
};
|
|
327
|
+
}, [client, agentId, resumeSessionId]);
|
|
328
|
+
const sendMessage = useCallback2(async (text) => {
|
|
329
|
+
if (!text.trim() || sending) return;
|
|
330
|
+
if (apiKeyConfigured === false) {
|
|
331
|
+
setMessages((prev) => [...prev, {
|
|
332
|
+
id: `msg-${Date.now()}-error`,
|
|
333
|
+
role: "agent",
|
|
334
|
+
content: "Anthropic API key required. Configure ANTHROPIC_API_KEY before chatting.",
|
|
335
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
336
|
+
}]);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
const userMessage = {
|
|
340
|
+
id: `msg-${Date.now()}`,
|
|
341
|
+
role: "user",
|
|
342
|
+
content: text.trim(),
|
|
343
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
344
|
+
};
|
|
345
|
+
setMessages((prev) => [...prev, userMessage]);
|
|
346
|
+
setSending(true);
|
|
347
|
+
try {
|
|
348
|
+
let sid = sessionId;
|
|
349
|
+
if (!sid) {
|
|
350
|
+
const session = await client.createSession(agentId, modelRef.current);
|
|
351
|
+
sid = session.id;
|
|
352
|
+
setSessionId(sid);
|
|
353
|
+
}
|
|
354
|
+
const response = await client.chatRaw(agentId, sid, text.trim(), modelRef.current);
|
|
355
|
+
let textAccum = "";
|
|
356
|
+
const toolExecutions = [];
|
|
357
|
+
let messageCost = "";
|
|
358
|
+
let toolIdCounter = 0;
|
|
359
|
+
const streamingMsgId = `agent-streaming-${Date.now()}`;
|
|
360
|
+
setActiveTools([]);
|
|
361
|
+
setStreamingPhase("idle");
|
|
362
|
+
await streamSSEEvents(response, (event) => {
|
|
363
|
+
switch (event.type) {
|
|
364
|
+
case "text":
|
|
365
|
+
setStreamingPhase("streaming");
|
|
366
|
+
setActiveTools([]);
|
|
367
|
+
textAccum += event.data;
|
|
368
|
+
setMessages((prev) => {
|
|
369
|
+
const existing = prev.find((m) => m.id === streamingMsgId);
|
|
370
|
+
if (!existing) {
|
|
371
|
+
return [...prev, {
|
|
372
|
+
id: streamingMsgId,
|
|
373
|
+
role: "agent",
|
|
374
|
+
content: textAccum,
|
|
375
|
+
toolExecutions: toolExecutions.length > 0 ? [...toolExecutions] : void 0,
|
|
376
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
377
|
+
}];
|
|
378
|
+
}
|
|
379
|
+
return prev.map(
|
|
380
|
+
(m) => m.id === streamingMsgId ? { ...m, content: textAccum, toolExecutions: toolExecutions.length > 0 ? [...toolExecutions] : void 0 } : m
|
|
381
|
+
);
|
|
382
|
+
});
|
|
383
|
+
break;
|
|
384
|
+
case "tool_call": {
|
|
385
|
+
const data = event.data;
|
|
386
|
+
const displayName = data.displayName || data.name.split("__").pop() || data.name;
|
|
387
|
+
toolExecutions.push({
|
|
388
|
+
id: data.id || `tool-${++toolIdCounter}`,
|
|
389
|
+
name: data.name,
|
|
390
|
+
displayName,
|
|
391
|
+
args: data.args
|
|
392
|
+
});
|
|
393
|
+
setActiveTools((prev) => [...prev, displayName]);
|
|
394
|
+
setStreamingPhase("tools");
|
|
395
|
+
break;
|
|
396
|
+
}
|
|
397
|
+
case "tool_result": {
|
|
398
|
+
const resultData = event.data;
|
|
399
|
+
const resultContent = resultData.result ?? resultData.content;
|
|
400
|
+
let matched = false;
|
|
401
|
+
if (resultData.id) {
|
|
402
|
+
const idx = toolExecutions.findIndex((t) => t.id === resultData.id);
|
|
403
|
+
if (idx !== -1) {
|
|
404
|
+
toolExecutions[idx].result = { content: resultContent, isError: resultData.isError };
|
|
405
|
+
matched = true;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
if (!matched) {
|
|
409
|
+
for (let i = toolExecutions.length - 1; i >= 0; i--) {
|
|
410
|
+
if (toolExecutions[i].name === resultData.name && !toolExecutions[i].result) {
|
|
411
|
+
toolExecutions[i].result = { content: resultContent, isError: resultData.isError };
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
break;
|
|
417
|
+
}
|
|
418
|
+
case "done":
|
|
419
|
+
if (event.data.cost) messageCost = event.data.cost;
|
|
420
|
+
break;
|
|
421
|
+
case "error":
|
|
422
|
+
textAccum += `
|
|
423
|
+
|
|
424
|
+
Error: ${event.data.message}`;
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
setMessages((prev) => {
|
|
429
|
+
const withoutStreaming = prev.filter((m) => m.id !== streamingMsgId);
|
|
430
|
+
return [...withoutStreaming, {
|
|
431
|
+
id: `msg-${Date.now()}-agent`,
|
|
432
|
+
role: "agent",
|
|
433
|
+
content: textAccum || "(No response)",
|
|
434
|
+
toolExecutions: toolExecutions.length > 0 ? [...toolExecutions] : void 0,
|
|
435
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
436
|
+
costUSD: messageCost || void 0
|
|
437
|
+
}];
|
|
438
|
+
});
|
|
439
|
+
} catch (err) {
|
|
440
|
+
const errStatus = typeof err === "object" && err !== null && "status" in err ? err.status : 0;
|
|
441
|
+
const errMessage = err instanceof Error ? err.message : String(err);
|
|
442
|
+
if (errStatus === 402) {
|
|
443
|
+
setMessages((prev) => [...prev, {
|
|
444
|
+
id: `msg-${Date.now()}-error`,
|
|
445
|
+
role: "agent",
|
|
446
|
+
content: "Insufficient balance. Please deposit funds to continue.",
|
|
447
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
448
|
+
}]);
|
|
449
|
+
} else if (errStatus === 404 || /session not found|not found/i.test(errMessage)) {
|
|
450
|
+
setSessionId(null);
|
|
451
|
+
setMessages((prev) => [...prev, {
|
|
452
|
+
id: `msg-${Date.now()}-error`,
|
|
453
|
+
role: "agent",
|
|
454
|
+
content: "Session expired. Starting a new conversation...",
|
|
455
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
456
|
+
}]);
|
|
457
|
+
} else if (errStatus === 401 || /unauthorized|authentication|invalid.*token|expired.*token/i.test(errMessage)) {
|
|
458
|
+
setSessionId(null);
|
|
459
|
+
setMessages((prev) => [...prev, {
|
|
460
|
+
id: `msg-${Date.now()}-error`,
|
|
461
|
+
role: "agent",
|
|
462
|
+
content: "Re-authenticating... please send again.",
|
|
463
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
464
|
+
}]);
|
|
465
|
+
} else if (errStatus === 400 && /anthropic api key|required/i.test(errMessage)) {
|
|
466
|
+
setApiKeyConfigured(false);
|
|
467
|
+
setMessages((prev) => [...prev, {
|
|
468
|
+
id: `msg-${Date.now()}-error`,
|
|
469
|
+
role: "agent",
|
|
470
|
+
content: errMessage,
|
|
471
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
472
|
+
}]);
|
|
473
|
+
} else {
|
|
474
|
+
setMessages((prev) => [...prev, {
|
|
475
|
+
id: `msg-${Date.now()}-error`,
|
|
476
|
+
role: "agent",
|
|
477
|
+
content: `Error: ${errMessage}`,
|
|
478
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
479
|
+
}]);
|
|
480
|
+
}
|
|
481
|
+
} finally {
|
|
482
|
+
setSending(false);
|
|
483
|
+
setStreamingPhase("idle");
|
|
484
|
+
setActiveTools([]);
|
|
485
|
+
}
|
|
486
|
+
}, [client, agentId, sending, sessionId, apiKeyConfigured]);
|
|
487
|
+
const refreshApiKeyStatus = useCallback2(() => {
|
|
488
|
+
client.getApiKeyStatus().then(({ configured }) => setApiKeyConfigured(configured)).catch(() => {
|
|
489
|
+
});
|
|
490
|
+
}, [client]);
|
|
491
|
+
const prevApiKeyRef = useRef(apiKeyConfigured);
|
|
492
|
+
useEffect2(() => {
|
|
493
|
+
if (prevApiKeyRef.current === false && apiKeyConfigured === true) {
|
|
494
|
+
setMessages((prev) => [...prev, {
|
|
495
|
+
id: `msg-${Date.now()}-system`,
|
|
496
|
+
role: "agent",
|
|
497
|
+
content: "API key configured successfully! You can start chatting now.",
|
|
498
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
499
|
+
}]);
|
|
500
|
+
}
|
|
501
|
+
prevApiKeyRef.current = apiKeyConfigured;
|
|
502
|
+
}, [apiKeyConfigured]);
|
|
503
|
+
const clearChat = useCallback2(() => {
|
|
504
|
+
setMessages([]);
|
|
505
|
+
setSessionId(null);
|
|
506
|
+
setStreamingPhase("idle");
|
|
507
|
+
setActiveTools([]);
|
|
508
|
+
}, []);
|
|
509
|
+
return {
|
|
510
|
+
messages,
|
|
511
|
+
messagesLoading,
|
|
512
|
+
sending,
|
|
513
|
+
sessionId,
|
|
514
|
+
streamingPhase,
|
|
515
|
+
activeTools,
|
|
516
|
+
apiKeyConfigured,
|
|
517
|
+
sendMessage,
|
|
518
|
+
clearChat,
|
|
519
|
+
refreshApiKeyStatus
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// src/components/SecretForm.tsx
|
|
524
|
+
import { useState as useState3 } from "react";
|
|
525
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
526
|
+
var container = {
|
|
527
|
+
display: "flex",
|
|
528
|
+
flexDirection: "column",
|
|
529
|
+
gap: "12px"
|
|
530
|
+
};
|
|
531
|
+
var labelStyle = {
|
|
532
|
+
display: "block",
|
|
533
|
+
fontSize: "12px",
|
|
534
|
+
fontWeight: 500,
|
|
535
|
+
fontFamily: "monospace",
|
|
536
|
+
color: "#9ca3af",
|
|
537
|
+
marginBottom: "4px"
|
|
538
|
+
};
|
|
539
|
+
var configuredBadge = {
|
|
540
|
+
marginLeft: "6px",
|
|
541
|
+
color: "#10b981",
|
|
542
|
+
fontFamily: "sans-serif"
|
|
543
|
+
};
|
|
544
|
+
var inputWrapper = {
|
|
545
|
+
position: "relative"
|
|
546
|
+
};
|
|
547
|
+
var inputStyle = {
|
|
548
|
+
width: "100%",
|
|
549
|
+
padding: "8px 36px 8px 12px",
|
|
550
|
+
fontSize: "14px",
|
|
551
|
+
fontFamily: "monospace",
|
|
552
|
+
borderRadius: "8px",
|
|
553
|
+
border: "1px solid rgba(255,255,255,0.1)",
|
|
554
|
+
backgroundColor: "#1f2937",
|
|
555
|
+
color: "#fff",
|
|
556
|
+
outline: "none",
|
|
557
|
+
boxSizing: "border-box"
|
|
558
|
+
};
|
|
559
|
+
var toggleBtn = {
|
|
560
|
+
position: "absolute",
|
|
561
|
+
right: "8px",
|
|
562
|
+
top: "50%",
|
|
563
|
+
transform: "translateY(-50%)",
|
|
564
|
+
padding: "4px",
|
|
565
|
+
background: "none",
|
|
566
|
+
border: "none",
|
|
567
|
+
color: "#9ca3af",
|
|
568
|
+
cursor: "pointer",
|
|
569
|
+
fontSize: "14px"
|
|
570
|
+
};
|
|
571
|
+
var feedbackBase = {
|
|
572
|
+
display: "flex",
|
|
573
|
+
alignItems: "center",
|
|
574
|
+
gap: "8px",
|
|
575
|
+
padding: "8px",
|
|
576
|
+
borderRadius: "8px",
|
|
577
|
+
fontSize: "12px"
|
|
578
|
+
};
|
|
579
|
+
var feedbackSuccess = {
|
|
580
|
+
...feedbackBase,
|
|
581
|
+
backgroundColor: "rgba(16,185,129,0.1)",
|
|
582
|
+
border: "1px solid rgba(16,185,129,0.2)",
|
|
583
|
+
color: "#34d399"
|
|
584
|
+
};
|
|
585
|
+
var feedbackError = {
|
|
586
|
+
...feedbackBase,
|
|
587
|
+
backgroundColor: "rgba(239,68,68,0.1)",
|
|
588
|
+
border: "1px solid rgba(239,68,68,0.2)",
|
|
589
|
+
color: "#f87171"
|
|
590
|
+
};
|
|
591
|
+
var btnRow = {
|
|
592
|
+
display: "flex",
|
|
593
|
+
alignItems: "center",
|
|
594
|
+
justifyContent: "space-between"
|
|
595
|
+
};
|
|
596
|
+
var saveBtn = {
|
|
597
|
+
display: "inline-flex",
|
|
598
|
+
alignItems: "center",
|
|
599
|
+
gap: "6px",
|
|
600
|
+
padding: "6px 12px",
|
|
601
|
+
fontSize: "12px",
|
|
602
|
+
fontWeight: 500,
|
|
603
|
+
borderRadius: "6px",
|
|
604
|
+
border: "none",
|
|
605
|
+
backgroundColor: "#6366f1",
|
|
606
|
+
color: "#fff",
|
|
607
|
+
cursor: "pointer",
|
|
608
|
+
transition: "opacity 0.15s"
|
|
609
|
+
};
|
|
610
|
+
var cancelBtn = {
|
|
611
|
+
padding: "6px 12px",
|
|
612
|
+
fontSize: "12px",
|
|
613
|
+
fontWeight: 500,
|
|
614
|
+
borderRadius: "6px",
|
|
615
|
+
border: "none",
|
|
616
|
+
background: "none",
|
|
617
|
+
color: "#9ca3af",
|
|
618
|
+
cursor: "pointer"
|
|
619
|
+
};
|
|
620
|
+
var deleteBtn = {
|
|
621
|
+
display: "inline-flex",
|
|
622
|
+
alignItems: "center",
|
|
623
|
+
gap: "4px",
|
|
624
|
+
padding: "6px 10px",
|
|
625
|
+
fontSize: "12px",
|
|
626
|
+
fontWeight: 500,
|
|
627
|
+
borderRadius: "6px",
|
|
628
|
+
border: "none",
|
|
629
|
+
background: "none",
|
|
630
|
+
color: "#f87171",
|
|
631
|
+
cursor: "pointer"
|
|
632
|
+
};
|
|
633
|
+
function SecretForm({ secretKeys, configuredKeys, onSave, onDelete, onClose, className }) {
|
|
634
|
+
const [values, setValues] = useState3(() => {
|
|
635
|
+
const init = {};
|
|
636
|
+
for (const key of secretKeys) init[key] = "";
|
|
637
|
+
return init;
|
|
638
|
+
});
|
|
639
|
+
const [showValues, setShowValues] = useState3({});
|
|
640
|
+
const [saving, setSaving] = useState3(false);
|
|
641
|
+
const [deleting, setDeleting] = useState3(false);
|
|
642
|
+
const [feedback, setFeedback] = useState3(null);
|
|
643
|
+
const hasAnyValue = Object.values(values).some((v) => v.trim().length > 0);
|
|
644
|
+
const handleSave = async () => {
|
|
645
|
+
const secrets = {};
|
|
646
|
+
for (const [key, val] of Object.entries(values)) {
|
|
647
|
+
if (val.trim()) secrets[key] = val.trim();
|
|
648
|
+
}
|
|
649
|
+
if (Object.keys(secrets).length === 0) return;
|
|
650
|
+
setSaving(true);
|
|
651
|
+
setFeedback(null);
|
|
652
|
+
try {
|
|
653
|
+
await onSave(secrets);
|
|
654
|
+
setFeedback({ type: "success", message: "Secrets saved successfully." });
|
|
655
|
+
setValues((prev) => {
|
|
656
|
+
const next = { ...prev };
|
|
657
|
+
for (const k of Object.keys(next)) next[k] = "";
|
|
658
|
+
return next;
|
|
659
|
+
});
|
|
660
|
+
if (onClose) setTimeout(onClose, 800);
|
|
661
|
+
} catch (err) {
|
|
662
|
+
setFeedback({ type: "error", message: err instanceof Error ? err.message : "Failed to save." });
|
|
663
|
+
} finally {
|
|
664
|
+
setSaving(false);
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
const handleDelete = async () => {
|
|
668
|
+
if (!onDelete) return;
|
|
669
|
+
setDeleting(true);
|
|
670
|
+
setFeedback(null);
|
|
671
|
+
try {
|
|
672
|
+
await onDelete();
|
|
673
|
+
setFeedback({ type: "success", message: "Secrets removed." });
|
|
674
|
+
if (onClose) setTimeout(onClose, 800);
|
|
675
|
+
} catch (err) {
|
|
676
|
+
setFeedback({ type: "error", message: err instanceof Error ? err.message : "Failed to remove." });
|
|
677
|
+
} finally {
|
|
678
|
+
setDeleting(false);
|
|
679
|
+
}
|
|
680
|
+
};
|
|
681
|
+
return /* @__PURE__ */ jsxs("div", { style: container, className, children: [
|
|
682
|
+
secretKeys.map((key) => {
|
|
683
|
+
const isVisible = showValues[key] ?? false;
|
|
684
|
+
const isConfigured = configuredKeys.includes(key);
|
|
685
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
686
|
+
/* @__PURE__ */ jsxs("label", { style: labelStyle, children: [
|
|
687
|
+
key,
|
|
688
|
+
isConfigured && /* @__PURE__ */ jsx2("span", { style: configuredBadge, children: "(configured)" })
|
|
689
|
+
] }),
|
|
690
|
+
/* @__PURE__ */ jsxs("div", { style: inputWrapper, children: [
|
|
691
|
+
/* @__PURE__ */ jsx2(
|
|
692
|
+
"input",
|
|
693
|
+
{
|
|
694
|
+
type: isVisible ? "text" : "password",
|
|
695
|
+
value: values[key],
|
|
696
|
+
onChange: (e) => setValues((prev) => ({ ...prev, [key]: e.target.value })),
|
|
697
|
+
placeholder: isConfigured ? "Enter new value to update" : "Enter value",
|
|
698
|
+
style: inputStyle
|
|
699
|
+
}
|
|
700
|
+
),
|
|
701
|
+
/* @__PURE__ */ jsx2(
|
|
702
|
+
"button",
|
|
703
|
+
{
|
|
704
|
+
type: "button",
|
|
705
|
+
onClick: () => setShowValues((prev) => ({ ...prev, [key]: !isVisible })),
|
|
706
|
+
style: toggleBtn,
|
|
707
|
+
"aria-label": isVisible ? "Hide" : "Show",
|
|
708
|
+
children: isVisible ? "\u{1F441}\uFE0F\u200D\u{1F5E8}\uFE0F" : "\u{1F441}\uFE0F"
|
|
709
|
+
}
|
|
710
|
+
)
|
|
711
|
+
] })
|
|
712
|
+
] }, key);
|
|
713
|
+
}),
|
|
714
|
+
feedback && /* @__PURE__ */ jsxs("div", { style: feedback.type === "success" ? feedbackSuccess : feedbackError, children: [
|
|
715
|
+
feedback.type === "success" ? "\u2713" : "\u26A0",
|
|
716
|
+
" ",
|
|
717
|
+
feedback.message
|
|
718
|
+
] }),
|
|
719
|
+
/* @__PURE__ */ jsxs("div", { style: btnRow, children: [
|
|
720
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
721
|
+
/* @__PURE__ */ jsx2(
|
|
722
|
+
"button",
|
|
723
|
+
{
|
|
724
|
+
onClick: handleSave,
|
|
725
|
+
disabled: saving || !hasAnyValue,
|
|
726
|
+
style: { ...saveBtn, opacity: saving || !hasAnyValue ? 0.4 : 1 },
|
|
727
|
+
children: saving ? "Saving..." : "Save Keys"
|
|
728
|
+
}
|
|
729
|
+
),
|
|
730
|
+
onClose && /* @__PURE__ */ jsx2("button", { onClick: onClose, style: cancelBtn, children: "Cancel" })
|
|
731
|
+
] }),
|
|
732
|
+
onDelete && configuredKeys.length > 0 && /* @__PURE__ */ jsx2("button", { onClick: handleDelete, disabled: deleting, style: deleteBtn, children: deleting ? "..." : "\u{1F5D1} Remove" })
|
|
733
|
+
] })
|
|
734
|
+
] });
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
// src/components/SecretOrchestrator.tsx
|
|
738
|
+
import { useState as useState4, useEffect as useEffect3 } from "react";
|
|
739
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
740
|
+
var wrapper = {
|
|
741
|
+
display: "flex",
|
|
742
|
+
flexDirection: "column",
|
|
743
|
+
gap: "8px"
|
|
744
|
+
};
|
|
745
|
+
var loadingBox = {
|
|
746
|
+
display: "flex",
|
|
747
|
+
alignItems: "center",
|
|
748
|
+
gap: "8px",
|
|
749
|
+
padding: "12px",
|
|
750
|
+
borderRadius: "12px",
|
|
751
|
+
border: "1px solid rgba(245,158,11,0.2)",
|
|
752
|
+
backgroundColor: "rgba(31,41,55,0.8)",
|
|
753
|
+
fontSize: "12px",
|
|
754
|
+
color: "#fcd34d"
|
|
755
|
+
};
|
|
756
|
+
var sectionBox = {
|
|
757
|
+
borderRadius: "12px",
|
|
758
|
+
border: "1px solid rgba(245,158,11,0.2)",
|
|
759
|
+
backgroundColor: "rgba(31,41,55,0.8)",
|
|
760
|
+
overflow: "hidden"
|
|
761
|
+
};
|
|
762
|
+
var headerBtn = {
|
|
763
|
+
width: "100%",
|
|
764
|
+
display: "flex",
|
|
765
|
+
alignItems: "center",
|
|
766
|
+
gap: "8px",
|
|
767
|
+
padding: "12px 16px",
|
|
768
|
+
textAlign: "left",
|
|
769
|
+
background: "none",
|
|
770
|
+
border: "none",
|
|
771
|
+
cursor: "pointer",
|
|
772
|
+
color: "inherit"
|
|
773
|
+
};
|
|
774
|
+
var headerLabel = {
|
|
775
|
+
flex: 1,
|
|
776
|
+
fontSize: "12px",
|
|
777
|
+
fontWeight: 500,
|
|
778
|
+
color: "#fcd34d"
|
|
779
|
+
};
|
|
780
|
+
var bodyBox = {
|
|
781
|
+
padding: "0 16px 16px"
|
|
782
|
+
};
|
|
783
|
+
function SecretOrchestrator({
|
|
784
|
+
agentId,
|
|
785
|
+
mcpServers,
|
|
786
|
+
onAllConfigured,
|
|
787
|
+
className,
|
|
788
|
+
compact
|
|
789
|
+
}) {
|
|
790
|
+
const { sections, loading, allConfigured, refresh } = useSecrets({ agentId, mcpServers });
|
|
791
|
+
const [expandedId, setExpandedId] = useState4(null);
|
|
792
|
+
useEffect3(() => {
|
|
793
|
+
if (sections.length > 0 && expandedId === null) {
|
|
794
|
+
setExpandedId(sections[0].id);
|
|
795
|
+
}
|
|
796
|
+
}, [sections, expandedId]);
|
|
797
|
+
useEffect3(() => {
|
|
798
|
+
if (allConfigured) onAllConfigured?.();
|
|
799
|
+
}, [allConfigured, onAllConfigured]);
|
|
800
|
+
if (loading) {
|
|
801
|
+
return /* @__PURE__ */ jsxs2("div", { style: loadingBox, className, children: [
|
|
802
|
+
/* @__PURE__ */ jsx3("span", { style: { animation: "spin 1s linear infinite" }, children: "\u21BB" }),
|
|
803
|
+
"Checking configuration requirements..."
|
|
804
|
+
] });
|
|
805
|
+
}
|
|
806
|
+
if (sections.length === 0) return null;
|
|
807
|
+
return /* @__PURE__ */ jsx3("div", { style: wrapper, className, children: sections.map((section) => {
|
|
808
|
+
const isExpanded = expandedId === section.id;
|
|
809
|
+
return /* @__PURE__ */ jsxs2("div", { style: sectionBox, children: [
|
|
810
|
+
/* @__PURE__ */ jsxs2(
|
|
811
|
+
"button",
|
|
812
|
+
{
|
|
813
|
+
onClick: () => setExpandedId(isExpanded ? null : section.id),
|
|
814
|
+
style: headerBtn,
|
|
815
|
+
children: [
|
|
816
|
+
/* @__PURE__ */ jsx3("span", { style: { color: "#f59e0b" }, children: "\u26A0" }),
|
|
817
|
+
/* @__PURE__ */ jsxs2("span", { style: headerLabel, children: [
|
|
818
|
+
section.label,
|
|
819
|
+
" required"
|
|
820
|
+
] }),
|
|
821
|
+
/* @__PURE__ */ jsx3("span", { style: { color: "#6b7280", fontSize: "12px" }, children: isExpanded ? "\u25BC" : "\u25B6" })
|
|
822
|
+
]
|
|
823
|
+
}
|
|
824
|
+
),
|
|
825
|
+
isExpanded && /* @__PURE__ */ jsx3("div", { style: bodyBox, children: /* @__PURE__ */ jsx3(
|
|
826
|
+
SecretForm,
|
|
827
|
+
{
|
|
828
|
+
secretKeys: section.keys,
|
|
829
|
+
configuredKeys: section.configuredKeys,
|
|
830
|
+
onSave: async (secrets) => {
|
|
831
|
+
await section.save(secrets);
|
|
832
|
+
refresh();
|
|
833
|
+
},
|
|
834
|
+
onClose: compact ? void 0 : () => setExpandedId(null)
|
|
835
|
+
}
|
|
836
|
+
) })
|
|
837
|
+
] }, section.id);
|
|
838
|
+
}) });
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// src/components/WalletChip.tsx
|
|
842
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
843
|
+
var chipStyle = {
|
|
844
|
+
display: "inline-flex",
|
|
845
|
+
alignItems: "center",
|
|
846
|
+
gap: "6px",
|
|
847
|
+
padding: "4px 10px",
|
|
848
|
+
borderRadius: "9999px",
|
|
849
|
+
backgroundColor: "rgba(255,255,255,0.08)",
|
|
850
|
+
border: "1px solid rgba(255,255,255,0.1)",
|
|
851
|
+
fontSize: "12px",
|
|
852
|
+
fontFamily: "monospace",
|
|
853
|
+
color: "#d1d5db",
|
|
854
|
+
cursor: "default",
|
|
855
|
+
transition: "background-color 0.15s"
|
|
856
|
+
};
|
|
857
|
+
var chipClickable = {
|
|
858
|
+
...chipStyle,
|
|
859
|
+
cursor: "pointer"
|
|
860
|
+
};
|
|
861
|
+
var balanceBadge = {
|
|
862
|
+
padding: "1px 6px",
|
|
863
|
+
borderRadius: "9999px",
|
|
864
|
+
backgroundColor: "rgba(99,102,241,0.2)",
|
|
865
|
+
color: "#a5b4fc",
|
|
866
|
+
fontSize: "11px",
|
|
867
|
+
fontFamily: "sans-serif",
|
|
868
|
+
fontWeight: 500
|
|
869
|
+
};
|
|
870
|
+
function truncateAddress(address) {
|
|
871
|
+
if (address.length <= 10) return address;
|
|
872
|
+
return `${address.slice(0, 6)}...${address.slice(-4)}`;
|
|
873
|
+
}
|
|
874
|
+
function WalletChip({ address, balanceDisplay, displayName, onPress, className }) {
|
|
875
|
+
const Tag = onPress ? "button" : "div";
|
|
876
|
+
const style = onPress ? chipClickable : chipStyle;
|
|
877
|
+
return /* @__PURE__ */ jsxs3(
|
|
878
|
+
Tag,
|
|
879
|
+
{
|
|
880
|
+
onClick: onPress,
|
|
881
|
+
style: { ...style, ...onPress ? { border: "1px solid rgba(255,255,255,0.1)", background: "rgba(255,255,255,0.08)" } : {} },
|
|
882
|
+
className,
|
|
883
|
+
...Tag === "button" ? { type: "button" } : {},
|
|
884
|
+
children: [
|
|
885
|
+
/* @__PURE__ */ jsx4("span", { children: displayName || truncateAddress(address) }),
|
|
886
|
+
balanceDisplay && /* @__PURE__ */ jsx4("span", { style: balanceBadge, children: balanceDisplay })
|
|
887
|
+
]
|
|
888
|
+
}
|
|
889
|
+
);
|
|
890
|
+
}
|
|
891
|
+
export {
|
|
892
|
+
RickyDataProvider,
|
|
893
|
+
SecretForm,
|
|
894
|
+
SecretOrchestrator,
|
|
895
|
+
WalletChip,
|
|
896
|
+
agentKeys,
|
|
897
|
+
apiKeyKeys,
|
|
898
|
+
balanceKeys,
|
|
899
|
+
sessionKeys,
|
|
900
|
+
useAgent,
|
|
901
|
+
useAgentChat,
|
|
902
|
+
useAgents,
|
|
903
|
+
useApiKeyStatus,
|
|
904
|
+
useDeleteApiKey,
|
|
905
|
+
useDeleteSession,
|
|
906
|
+
useOpenAIApiKeyStatus,
|
|
907
|
+
useRickyData,
|
|
908
|
+
useSecrets,
|
|
909
|
+
useSession,
|
|
910
|
+
useSessions,
|
|
911
|
+
useSetApiKey,
|
|
912
|
+
useSetOpenAIApiKey,
|
|
913
|
+
useWalletBalance,
|
|
914
|
+
useWalletSettings,
|
|
915
|
+
useWalletTransactions,
|
|
916
|
+
walletSettingsKeys
|
|
917
|
+
};
|