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