@elizaos/client 1.5.5-alpha.10
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 +21 -0
- package/README.md +350 -0
- package/dist/assets/empty-module-CLMscLYw.js +1 -0
- package/dist/assets/main-BBZ_3lkn.css +5999 -0
- package/dist/assets/main-C5zNUkXH.js +7 -0
- package/dist/assets/main-Dz64ENQg.js +614 -0
- package/dist/assets/react-vendor-DM5m98rr.js +545 -0
- package/dist/assets/ui-vendor-BQCqNqg0.js +1 -0
- package/dist/elizaos-avatar.png +0 -0
- package/dist/elizaos-icon.png +0 -0
- package/dist/elizaos-logo-light.png +0 -0
- package/dist/elizaos.webp +0 -0
- package/dist/favicon.ico +0 -0
- package/dist/images/agents/agent1.png +0 -0
- package/dist/images/agents/agent2.png +0 -0
- package/dist/images/agents/agent3.png +0 -0
- package/dist/images/agents/agent4.png +0 -0
- package/dist/images/agents/agent5.png +0 -0
- package/dist/index.html +14 -0
- package/index.html +24 -0
- package/package.json +159 -0
- package/postcss.config.js +3 -0
- package/public/elizaos-avatar.png +0 -0
- package/public/elizaos-icon.png +0 -0
- package/public/elizaos-logo-light.png +0 -0
- package/public/elizaos.webp +0 -0
- package/public/favicon.ico +0 -0
- package/public/images/agents/agent1.png +0 -0
- package/public/images/agents/agent2.png +0 -0
- package/public/images/agents/agent3.png +0 -0
- package/public/images/agents/agent4.png +0 -0
- package/public/images/agents/agent5.png +0 -0
- package/src/App.tsx +222 -0
- package/src/components/AgentDetailsPanel.tsx +147 -0
- package/src/components/ChatInputArea.tsx +196 -0
- package/src/components/ChatMessageListComponent.tsx +139 -0
- package/src/components/actionTool.tsx +186 -0
- package/src/components/add-agent-card.tsx +77 -0
- package/src/components/agent-action-viewer.tsx +816 -0
- package/src/components/agent-avatar-stack.tsx +121 -0
- package/src/components/agent-card.cy.tsx +259 -0
- package/src/components/agent-card.tsx +177 -0
- package/src/components/agent-creator.tsx +142 -0
- package/src/components/agent-log-viewer.tsx +645 -0
- package/src/components/agent-memory-edit-overlay.tsx +461 -0
- package/src/components/agent-memory-viewer.tsx +504 -0
- package/src/components/agent-settings.tsx +270 -0
- package/src/components/agent-sidebar.tsx +178 -0
- package/src/components/api-key-dialog.tsx +113 -0
- package/src/components/app-sidebar.tsx +685 -0
- package/src/components/array-input.tsx +116 -0
- package/src/components/audio-recorder.tsx +292 -0
- package/src/components/avatar-panel.tsx +141 -0
- package/src/components/character-form.tsx +1138 -0
- package/src/components/chat.tsx +1813 -0
- package/src/components/combobox.tsx +187 -0
- package/src/components/confirmation-dialog.tsx +59 -0
- package/src/components/connection-error-banner.tsx +101 -0
- package/src/components/connection-status.cy.tsx +73 -0
- package/src/components/connection-status.tsx +155 -0
- package/src/components/copy-button.tsx +35 -0
- package/src/components/delete-button.tsx +24 -0
- package/src/components/env-settings.tsx +261 -0
- package/src/components/group-card.tsx +160 -0
- package/src/components/group-panel.tsx +543 -0
- package/src/components/input-copy.tsx +21 -0
- package/src/components/logs-page.tsx +41 -0
- package/src/components/media-content.tsx +385 -0
- package/src/components/memory-graph.tsx +170 -0
- package/src/components/missing-secrets-dialog.tsx +72 -0
- package/src/components/onboarding-tour.tsx +247 -0
- package/src/components/page-title.tsx +8 -0
- package/src/components/plugins-panel.tsx +383 -0
- package/src/components/profile-card.tsx +66 -0
- package/src/components/profile-overlay.tsx +283 -0
- package/src/components/retry-button.tsx +28 -0
- package/src/components/secret-panel.tsx +1505 -0
- package/src/components/server-management.tsx +264 -0
- package/src/components/split-button.tsx +148 -0
- package/src/components/stop-agent-button.tsx +99 -0
- package/src/components/ui/alert-dialog.cy.tsx +333 -0
- package/src/components/ui/alert-dialog.tsx +115 -0
- package/src/components/ui/alert.tsx +49 -0
- package/src/components/ui/avatar.cy.tsx +180 -0
- package/src/components/ui/avatar.tsx +57 -0
- package/src/components/ui/badge.cy.tsx +146 -0
- package/src/components/ui/badge.tsx +43 -0
- package/src/components/ui/button.cy.tsx +177 -0
- package/src/components/ui/button.tsx +56 -0
- package/src/components/ui/card.cy.tsx +160 -0
- package/src/components/ui/card.tsx +73 -0
- package/src/components/ui/chat/animated-markdown.tsx +59 -0
- package/src/components/ui/chat/chat-bubble.tsx +178 -0
- package/src/components/ui/chat/chat-container.tsx +51 -0
- package/src/components/ui/chat/chat-input.cy.tsx +169 -0
- package/src/components/ui/chat/chat-input.tsx +47 -0
- package/src/components/ui/chat/chat-message-list.tsx +61 -0
- package/src/components/ui/chat/chat-tts-button.tsx +199 -0
- package/src/components/ui/chat/code-block.tsx +79 -0
- package/src/components/ui/chat/expandable-chat.tsx +131 -0
- package/src/components/ui/chat/hooks/useAutoScroll.ts +86 -0
- package/src/components/ui/chat/markdown.tsx +209 -0
- package/src/components/ui/chat/message-loading.tsx +48 -0
- package/src/components/ui/checkbox.cy.tsx +170 -0
- package/src/components/ui/checkbox.tsx +30 -0
- package/src/components/ui/collapsible.cy.tsx +283 -0
- package/src/components/ui/collapsible.tsx +9 -0
- package/src/components/ui/command.cy.tsx +313 -0
- package/src/components/ui/command.tsx +143 -0
- package/src/components/ui/dialog.cy.tsx +279 -0
- package/src/components/ui/dialog.tsx +104 -0
- package/src/components/ui/dropdown-menu.cy.tsx +273 -0
- package/src/components/ui/dropdown-menu.tsx +281 -0
- package/src/components/ui/input.cy.tsx +82 -0
- package/src/components/ui/input.tsx +27 -0
- package/src/components/ui/label.cy.tsx +157 -0
- package/src/components/ui/label.tsx +19 -0
- package/src/components/ui/resizable.tsx +42 -0
- package/src/components/ui/scroll-area.cy.tsx +242 -0
- package/src/components/ui/scroll-area.tsx +46 -0
- package/src/components/ui/select.cy.tsx +277 -0
- package/src/components/ui/select.tsx +155 -0
- package/src/components/ui/separator.cy.tsx +145 -0
- package/src/components/ui/separator.tsx +29 -0
- package/src/components/ui/sheet.cy.tsx +324 -0
- package/src/components/ui/sheet.tsx +119 -0
- package/src/components/ui/sidebar.tsx +734 -0
- package/src/components/ui/skeleton.cy.tsx +149 -0
- package/src/components/ui/skeleton.tsx +17 -0
- package/src/components/ui/split-button.cy.tsx +274 -0
- package/src/components/ui/split-button.tsx +112 -0
- package/src/components/ui/switch.tsx +28 -0
- package/src/components/ui/tabs.cy.tsx +271 -0
- package/src/components/ui/tabs.tsx +53 -0
- package/src/components/ui/textarea.cy.tsx +136 -0
- package/src/components/ui/textarea.tsx +26 -0
- package/src/components/ui/toast.cy.tsx +209 -0
- package/src/components/ui/toast.tsx +126 -0
- package/src/components/ui/toaster.tsx +29 -0
- package/src/components/ui/tooltip.cy.tsx +244 -0
- package/src/components/ui/tooltip.tsx +30 -0
- package/src/config/agent-templates.ts +349 -0
- package/src/config/voice-models.ts +181 -0
- package/src/constants.ts +23 -0
- package/src/context/AuthContext.tsx +44 -0
- package/src/context/ConnectionContext.tsx +194 -0
- package/src/entry.tsx +9 -0
- package/src/hooks/__tests__/use-agent-tab-state.test.ts +137 -0
- package/src/hooks/__tests__/use-agent-update.test.tsx +250 -0
- package/src/hooks/__tests__/use-character-convert.test.ts +102 -0
- package/src/hooks/__tests__/use-panel-width-state.test.ts +243 -0
- package/src/hooks/__tests__/use-sidebar-state.test.ts +117 -0
- package/src/hooks/use-agent-management.ts +130 -0
- package/src/hooks/use-agent-tab-state.ts +74 -0
- package/src/hooks/use-agent-update.ts +469 -0
- package/src/hooks/use-character-convert.ts +138 -0
- package/src/hooks/use-confirmation.ts +55 -0
- package/src/hooks/use-delete-agent.ts +123 -0
- package/src/hooks/use-dm-channels.ts +198 -0
- package/src/hooks/use-elevenlabs-voices.ts +83 -0
- package/src/hooks/use-file-upload.ts +224 -0
- package/src/hooks/use-mobile.tsx +19 -0
- package/src/hooks/use-onboarding.tsx +49 -0
- package/src/hooks/use-panel-width-state.ts +147 -0
- package/src/hooks/use-partial-update.ts +288 -0
- package/src/hooks/use-plugin-details.ts +462 -0
- package/src/hooks/use-plugins.ts +119 -0
- package/src/hooks/use-query-hooks.ts +1263 -0
- package/src/hooks/use-server-agents.ts +62 -0
- package/src/hooks/use-server-version.tsx +47 -0
- package/src/hooks/use-sidebar-state.ts +50 -0
- package/src/hooks/use-socket-chat.ts +264 -0
- package/src/hooks/use-toast.ts +260 -0
- package/src/hooks/use-version.tsx +64 -0
- package/src/index.css +146 -0
- package/src/lib/api-client-config.ts +53 -0
- package/src/lib/api-type-mappers.ts +196 -0
- package/src/lib/export-utils.ts +123 -0
- package/src/lib/logger.ts +19 -0
- package/src/lib/media-utils.ts +170 -0
- package/src/lib/pca.test.ts +17 -0
- package/src/lib/pca.ts +52 -0
- package/src/lib/socketio-manager.ts +664 -0
- package/src/lib/utils.ts +168 -0
- package/src/main.tsx +16 -0
- package/src/mocks/empty-module.ts +12 -0
- package/src/mocks/node-module.ts +57 -0
- package/src/polyfills.ts +37 -0
- package/src/routes/agent-detail.tsx +30 -0
- package/src/routes/agent-list.tsx +27 -0
- package/src/routes/agent-settings.tsx +48 -0
- package/src/routes/character-detail.tsx +52 -0
- package/src/routes/character-form.tsx +79 -0
- package/src/routes/character-list.tsx +38 -0
- package/src/routes/chat.tsx +128 -0
- package/src/routes/createAgent.tsx +13 -0
- package/src/routes/group-new.tsx +50 -0
- package/src/routes/group.tsx +29 -0
- package/src/routes/home.tsx +218 -0
- package/src/routes/not-found.tsx +71 -0
- package/src/test/setup.ts +154 -0
- package/src/types/crypto-browserify.d.ts +4 -0
- package/src/types/index.ts +13 -0
- package/src/types/rooms.ts +8 -0
- package/src/types.ts +84 -0
- package/src/vite-env.d.ts +40 -0
- package/tailwind.config.ts +90 -0
- package/tsconfig.json +10 -0
- package/vite.config.ts +102 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { ToastAction } from '@/components/ui/toast';
|
|
2
|
+
import { useEffect, useCallback } from 'react';
|
|
3
|
+
import { NavLink } from 'react-router';
|
|
4
|
+
import semver from 'semver';
|
|
5
|
+
import { useToast } from './use-toast';
|
|
6
|
+
import { useServerVersion } from './use-server-version';
|
|
7
|
+
import clientLogger from '../lib/logger';
|
|
8
|
+
|
|
9
|
+
export default function useVersion() {
|
|
10
|
+
const { toast } = useToast();
|
|
11
|
+
const { data: versionInfo } = useServerVersion();
|
|
12
|
+
|
|
13
|
+
async function getLatestRelease(repo: string) {
|
|
14
|
+
const apiUrl = `https://api.github.com/repos/${repo}/releases/latest`;
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const response = await fetch(apiUrl, {
|
|
18
|
+
headers: {
|
|
19
|
+
Accept: 'application/vnd.github.v3+json',
|
|
20
|
+
'User-Agent': 'fetch-latest-release',
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`Failed to fetch latest release: ${response.status} ${response.statusText}`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const data = await response.json();
|
|
31
|
+
const latestVersion = data.tag_name;
|
|
32
|
+
return latestVersion;
|
|
33
|
+
} catch {}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const compareVersion = useCallback(async () => {
|
|
37
|
+
try {
|
|
38
|
+
const latestVersion = await getLatestRelease('elizaos/eliza');
|
|
39
|
+
const thisVersion = versionInfo?.version;
|
|
40
|
+
if (latestVersion && thisVersion) {
|
|
41
|
+
if (semver.gt(latestVersion.replace('v', ''), thisVersion.replace('v', ''))) {
|
|
42
|
+
toast({
|
|
43
|
+
variant: 'default',
|
|
44
|
+
title: `New version ${latestVersion} is available.`,
|
|
45
|
+
description: 'Visit GitHub for more information.',
|
|
46
|
+
action: (
|
|
47
|
+
<NavLink to="https://github.com/elizaos/eliza/releases" target="_blank">
|
|
48
|
+
<ToastAction altText="Update">Update</ToastAction>
|
|
49
|
+
</NavLink>
|
|
50
|
+
),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
} catch (e) {
|
|
55
|
+
clientLogger.error(`Unable to retrieve latest version from GitHub: ${e}`);
|
|
56
|
+
}
|
|
57
|
+
}, [toast, versionInfo?.version]);
|
|
58
|
+
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
compareVersion();
|
|
61
|
+
}, [compareVersion]);
|
|
62
|
+
|
|
63
|
+
return null;
|
|
64
|
+
}
|
package/src/index.css
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
@import 'tailwindcss';
|
|
2
|
+
@config "../tailwind.config.ts";
|
|
3
|
+
|
|
4
|
+
@custom-variant dark (&:is(.dark *));
|
|
5
|
+
|
|
6
|
+
@layer base {
|
|
7
|
+
:root {
|
|
8
|
+
--background: 0 0% 100%;
|
|
9
|
+
--foreground: 240 10% 3.9%;
|
|
10
|
+
--card: 0 0% 93%;
|
|
11
|
+
--card-foreground: 240 10% 3.9%;
|
|
12
|
+
--popover: 0 0% 100%;
|
|
13
|
+
--popover-foreground: 240 10% 3.9%;
|
|
14
|
+
--primary: 240 5.9% 10%;
|
|
15
|
+
--primary-foreground: 0 0% 98%;
|
|
16
|
+
--secondary: 240 4.8% 95.9%;
|
|
17
|
+
--secondary-foreground: 240 5.9% 10%;
|
|
18
|
+
--muted: 240 4.8% 95.9%;
|
|
19
|
+
--muted-foreground: 240 3.8% 46.1%;
|
|
20
|
+
--accent: 240 4.8% 97%;
|
|
21
|
+
--accent-foreground: 240 5.9% 10%;
|
|
22
|
+
--destructive: 0 84% 60%;
|
|
23
|
+
--destructive-foreground: 0 0% 98%;
|
|
24
|
+
--border: 240 5.9% 90%;
|
|
25
|
+
--input: 240 5.9% 90%;
|
|
26
|
+
--ring: 240 5.9% 10%;
|
|
27
|
+
--radius: 1rem;
|
|
28
|
+
--sidebar-background: 0 0% 98%;
|
|
29
|
+
--sidebar-foreground: 240 5.3% 26.1%;
|
|
30
|
+
--sidebar-primary: 240 5.9% 10%;
|
|
31
|
+
--sidebar-primary-foreground: 0 0% 98%;
|
|
32
|
+
--sidebar-accent: 240 4.8% 95.9%;
|
|
33
|
+
--sidebar-accent-foreground: 240 5.9% 10%;
|
|
34
|
+
--sidebar-border: 220 13% 91%;
|
|
35
|
+
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.dark {
|
|
39
|
+
--background: 0 0% 9%;
|
|
40
|
+
--foreground: 0 0% 98%;
|
|
41
|
+
--card: 0 0% 12%;
|
|
42
|
+
--card-foreground: 0 0% 98%;
|
|
43
|
+
--popover: 0 0% 14%;
|
|
44
|
+
--popover-foreground: 0 0% 98%;
|
|
45
|
+
--primary: 0 0% 98%;
|
|
46
|
+
--primary-foreground: 0 0% 10%;
|
|
47
|
+
--secondary: 0 0% 16%;
|
|
48
|
+
--secondary-foreground: 0 0% 98%;
|
|
49
|
+
--muted: 0 0% 16%;
|
|
50
|
+
--muted-foreground: 0 0% 64%;
|
|
51
|
+
--accent: 0 0% 16%;
|
|
52
|
+
--accent-foreground: 0 0% 98%;
|
|
53
|
+
--destructive: 0 84% 60%;
|
|
54
|
+
--destructive-foreground: 0 0% 98%;
|
|
55
|
+
--border: 0 0% 20%;
|
|
56
|
+
--input: 0 0% 14%;
|
|
57
|
+
--ring: 0 0% 83.9%;
|
|
58
|
+
--sidebar-background: 0 0% 12%;
|
|
59
|
+
--sidebar-foreground: 0 0% 95%;
|
|
60
|
+
--sidebar-primary: 224.3 76.3% 48%;
|
|
61
|
+
--sidebar-primary-foreground: 0 0% 100%;
|
|
62
|
+
--sidebar-accent: 0 0% 16%;
|
|
63
|
+
--sidebar-accent-foreground: 0 0% 95%;
|
|
64
|
+
--sidebar-border: 0 0% 20%;
|
|
65
|
+
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@layer base {
|
|
70
|
+
* {
|
|
71
|
+
@apply border-border;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
body {
|
|
75
|
+
@apply bg-background text-foreground;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.scrollbar-hide {
|
|
80
|
+
-ms-overflow-style: none;
|
|
81
|
+
/* IE and Edge */
|
|
82
|
+
scrollbar-width: none;
|
|
83
|
+
/* Firefox */
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.scrollbar-hide::-webkit-scrollbar {
|
|
87
|
+
display: none;
|
|
88
|
+
/* Chrome, Safari, Opera */
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* Custom scrollbar styles for visible scrollbars (like Railway) */
|
|
92
|
+
.scrollbar-visible {
|
|
93
|
+
overflow-x: auto;
|
|
94
|
+
overflow-y: hidden;
|
|
95
|
+
scrollbar-width: thin;
|
|
96
|
+
scrollbar-color: rgb(156, 163, 175) rgb(243, 244, 246);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.scrollbar-visible::-webkit-scrollbar {
|
|
100
|
+
height: 8px;
|
|
101
|
+
display: block;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.scrollbar-visible::-webkit-scrollbar-track {
|
|
105
|
+
background-color: rgb(243, 244, 246);
|
|
106
|
+
border-radius: 9999px;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.scrollbar-visible::-webkit-scrollbar-thumb {
|
|
110
|
+
background-color: rgb(156, 163, 175);
|
|
111
|
+
border-radius: 9999px;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.scrollbar-visible::-webkit-scrollbar-thumb:hover {
|
|
115
|
+
background-color: rgb(107, 114, 128);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* Dark mode styles */
|
|
119
|
+
.dark .scrollbar-visible {
|
|
120
|
+
scrollbar-color: rgb(75, 85, 99) rgb(31, 41, 55);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.dark .scrollbar-visible::-webkit-scrollbar-track {
|
|
124
|
+
background-color: rgb(31, 41, 55);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.dark .scrollbar-visible::-webkit-scrollbar-thumb {
|
|
128
|
+
background-color: rgb(75, 85, 99);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.dark .scrollbar-visible::-webkit-scrollbar-thumb:hover {
|
|
132
|
+
background-color: rgb(107, 114, 128);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@utility container {
|
|
136
|
+
margin-inline: auto;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
@layer base {
|
|
140
|
+
* {
|
|
141
|
+
@apply border-border outline-ring/50;
|
|
142
|
+
}
|
|
143
|
+
body {
|
|
144
|
+
@apply bg-background text-foreground;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { ElizaClient, type ApiClientConfig } from '@elizaos/api-client';
|
|
2
|
+
|
|
3
|
+
export function createApiClientConfig(): ApiClientConfig {
|
|
4
|
+
const getLocalStorageApiKey = () => `eliza-api-key-${window.location.origin}`;
|
|
5
|
+
const apiKey = localStorage.getItem(getLocalStorageApiKey());
|
|
6
|
+
|
|
7
|
+
const config: ApiClientConfig = {
|
|
8
|
+
baseUrl: window.location.origin,
|
|
9
|
+
timeout: 30000,
|
|
10
|
+
headers: {
|
|
11
|
+
Accept: 'application/json',
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// Only include apiKey if it exists (don't pass undefined)
|
|
16
|
+
if (apiKey) {
|
|
17
|
+
config.apiKey = apiKey;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return config;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Singleton instance
|
|
24
|
+
let elizaClientInstance: ElizaClient | null = null;
|
|
25
|
+
|
|
26
|
+
export function createElizaClient(): ElizaClient {
|
|
27
|
+
if (!elizaClientInstance) {
|
|
28
|
+
elizaClientInstance = ElizaClient.create(createApiClientConfig());
|
|
29
|
+
}
|
|
30
|
+
return elizaClientInstance;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function getElizaClient(): ElizaClient {
|
|
34
|
+
return createElizaClient();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Function to reset the singleton (useful for API key changes)
|
|
38
|
+
export function resetElizaClient(): void {
|
|
39
|
+
elizaClientInstance = null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function updateApiClientApiKey(newApiKey: string | null): void {
|
|
43
|
+
const getLocalStorageApiKey = () => `eliza-api-key-${window.location.origin}`;
|
|
44
|
+
|
|
45
|
+
if (newApiKey) {
|
|
46
|
+
localStorage.setItem(getLocalStorageApiKey(), newApiKey);
|
|
47
|
+
} else {
|
|
48
|
+
localStorage.removeItem(getLocalStorageApiKey());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Reset the singleton so it uses the new API key
|
|
52
|
+
resetElizaClient();
|
|
53
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Agent as ApiAgent,
|
|
3
|
+
AgentLog as ApiAgentLog,
|
|
4
|
+
Message as ApiMessage,
|
|
5
|
+
MessageChannel as ApiMessageChannel,
|
|
6
|
+
MessageServer as ApiMessageServer,
|
|
7
|
+
Memory as ApiMemory,
|
|
8
|
+
} from '@elizaos/api-client';
|
|
9
|
+
import { Agent, AgentStatus, UUID, ChannelType, Memory } from '@elizaos/core';
|
|
10
|
+
import type {
|
|
11
|
+
AgentWithStatus,
|
|
12
|
+
MessageChannel as ClientMessageChannel,
|
|
13
|
+
MessageServer as ClientMessageServer,
|
|
14
|
+
ServerMessage,
|
|
15
|
+
} from '../types';
|
|
16
|
+
import type { UiMessage } from '../hooks/use-query-hooks';
|
|
17
|
+
|
|
18
|
+
// Map API Agent status strings to core AgentStatus enum
|
|
19
|
+
export function mapApiStatusToEnum(status: 'active' | 'inactive' | 'stopped'): AgentStatus {
|
|
20
|
+
switch (status) {
|
|
21
|
+
case 'active':
|
|
22
|
+
return AgentStatus.ACTIVE;
|
|
23
|
+
case 'inactive':
|
|
24
|
+
case 'stopped': // Map stopped to inactive since core doesn't have STOPPED
|
|
25
|
+
return AgentStatus.INACTIVE;
|
|
26
|
+
default:
|
|
27
|
+
return AgentStatus.INACTIVE;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Map core AgentStatus enum to API status strings
|
|
32
|
+
export function mapEnumToApiStatus(status: AgentStatus): 'active' | 'inactive' | 'stopped' {
|
|
33
|
+
switch (status) {
|
|
34
|
+
case AgentStatus.ACTIVE:
|
|
35
|
+
return 'active';
|
|
36
|
+
case AgentStatus.INACTIVE:
|
|
37
|
+
return 'inactive';
|
|
38
|
+
default:
|
|
39
|
+
return 'inactive';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Convert API Agent to client AgentWithStatus
|
|
44
|
+
export function mapApiAgentToClient(apiAgent: ApiAgent): AgentWithStatus {
|
|
45
|
+
return {
|
|
46
|
+
...apiAgent,
|
|
47
|
+
id: apiAgent.id as UUID,
|
|
48
|
+
status: mapApiStatusToEnum(apiAgent.status),
|
|
49
|
+
createdAt:
|
|
50
|
+
apiAgent.createdAt instanceof Date
|
|
51
|
+
? apiAgent.createdAt.getTime()
|
|
52
|
+
: new Date(apiAgent.createdAt).getTime(),
|
|
53
|
+
updatedAt:
|
|
54
|
+
apiAgent.updatedAt instanceof Date
|
|
55
|
+
? apiAgent.updatedAt.getTime()
|
|
56
|
+
: new Date(apiAgent.updatedAt).getTime(),
|
|
57
|
+
} as AgentWithStatus;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Convert Date to string for API
|
|
61
|
+
export function dateToApiString(date: Date | string | number): string {
|
|
62
|
+
if (date instanceof Date) {
|
|
63
|
+
return date.toISOString();
|
|
64
|
+
}
|
|
65
|
+
if (typeof date === 'number') {
|
|
66
|
+
return new Date(date).toISOString();
|
|
67
|
+
}
|
|
68
|
+
return date;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Convert API date (Date object or string) to timestamp (ms)
|
|
72
|
+
export function apiDateToTimestamp(date: Date | string | number): number {
|
|
73
|
+
if (date instanceof Date) {
|
|
74
|
+
return date.getTime();
|
|
75
|
+
}
|
|
76
|
+
if (typeof date === 'string') {
|
|
77
|
+
return new Date(date).getTime();
|
|
78
|
+
}
|
|
79
|
+
return date;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Convert API date to string
|
|
83
|
+
export function apiDateToString(date: Date | string): string {
|
|
84
|
+
if (date instanceof Date) {
|
|
85
|
+
return date.toISOString();
|
|
86
|
+
}
|
|
87
|
+
return date;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Map API MessageChannel to client MessageChannel
|
|
91
|
+
export function mapApiChannelToClient(apiChannel: ApiMessageChannel): ClientMessageChannel {
|
|
92
|
+
return {
|
|
93
|
+
...apiChannel,
|
|
94
|
+
id: apiChannel.id as UUID,
|
|
95
|
+
messageServerId: apiChannel.messageServerId as UUID,
|
|
96
|
+
type: apiChannel.type as ChannelType,
|
|
97
|
+
createdAt: apiDateToString(apiChannel.createdAt),
|
|
98
|
+
updatedAt: apiDateToString(apiChannel.updatedAt),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Map API MessageServer to client MessageServer
|
|
103
|
+
export function mapApiServerToClient(apiServer: ApiMessageServer): ClientMessageServer {
|
|
104
|
+
return {
|
|
105
|
+
...apiServer,
|
|
106
|
+
id: apiServer.id as UUID,
|
|
107
|
+
createdAt: apiDateToString(apiServer.createdAt),
|
|
108
|
+
updatedAt: apiDateToString(apiServer.updatedAt),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Map array of API Servers to client MessageServers
|
|
113
|
+
export function mapApiServersToClient(apiServers: ApiMessageServer[]): ClientMessageServer[] {
|
|
114
|
+
return apiServers.map(mapApiServerToClient);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Map array of API Channels to client MessageChannels
|
|
118
|
+
export function mapApiChannelsToClient(apiChannels: ApiMessageChannel[]): ClientMessageChannel[] {
|
|
119
|
+
return apiChannels.map(mapApiChannelToClient);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Map API Message to UiMessage
|
|
123
|
+
export function mapApiMessageToUi(apiMessage: ApiMessage, serverId?: UUID): UiMessage {
|
|
124
|
+
// Ensure attachments are properly typed as Media[]
|
|
125
|
+
const attachments =
|
|
126
|
+
apiMessage.metadata?.attachments?.map((att: any) => ({
|
|
127
|
+
id: att.id || crypto.randomUUID(),
|
|
128
|
+
url: att.url,
|
|
129
|
+
title: att.title || att.name,
|
|
130
|
+
source: att.source,
|
|
131
|
+
description: att.description,
|
|
132
|
+
text: att.text,
|
|
133
|
+
contentType: att.contentType || att.type,
|
|
134
|
+
})) || undefined;
|
|
135
|
+
|
|
136
|
+
const messageType = apiMessage.sourceType;
|
|
137
|
+
const rawMessage = apiMessage.rawMessage;
|
|
138
|
+
return {
|
|
139
|
+
id: apiMessage.id as UUID,
|
|
140
|
+
text: apiMessage.content,
|
|
141
|
+
name: apiMessage.metadata?.authorDisplayName || apiMessage.metadata?.agentName || 'Unknown',
|
|
142
|
+
senderId: apiMessage.authorId as UUID,
|
|
143
|
+
isAgent: Boolean(apiMessage.metadata?.isAgent) || false,
|
|
144
|
+
createdAt: apiDateToTimestamp(apiMessage.createdAt),
|
|
145
|
+
channelId: apiMessage.channelId as UUID,
|
|
146
|
+
serverId: serverId || (apiMessage.metadata?.serverId as UUID),
|
|
147
|
+
prompt: apiMessage.metadata?.prompt,
|
|
148
|
+
attachments,
|
|
149
|
+
thought: apiMessage.metadata?.thought,
|
|
150
|
+
actions: apiMessage.metadata?.actions,
|
|
151
|
+
type: messageType,
|
|
152
|
+
rawMessage: rawMessage,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Map API AgentLog to client format
|
|
157
|
+
export function mapApiLogToClient(apiLog: ApiAgentLog): AgentLog {
|
|
158
|
+
return {
|
|
159
|
+
id: apiLog.id,
|
|
160
|
+
type: apiLog?.type || apiLog.body?.modelType,
|
|
161
|
+
timestamp: apiLog.timestamp ? apiDateToTimestamp(apiLog.timestamp) : undefined,
|
|
162
|
+
message: apiLog.message,
|
|
163
|
+
details: apiLog.details,
|
|
164
|
+
roomId: apiLog.roomId,
|
|
165
|
+
body: apiLog.body,
|
|
166
|
+
createdAt: apiLog.createdAt ? apiDateToTimestamp(apiLog.createdAt) : undefined,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Type for client-side AgentLog
|
|
171
|
+
export interface AgentLog {
|
|
172
|
+
id?: UUID;
|
|
173
|
+
type?: string;
|
|
174
|
+
timestamp?: number;
|
|
175
|
+
message?: string;
|
|
176
|
+
details?: string;
|
|
177
|
+
roomId?: UUID;
|
|
178
|
+
body?: any;
|
|
179
|
+
createdAt?: number;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Map API Memory to client Memory
|
|
183
|
+
export function mapApiMemoryToClient(apiMemory: ApiMemory): Memory {
|
|
184
|
+
return {
|
|
185
|
+
id: apiMemory.id as UUID,
|
|
186
|
+
entityId: (apiMemory.metadata?.entityId ||
|
|
187
|
+
apiMemory.metadata?.userId ||
|
|
188
|
+
apiMemory.agentId) as UUID,
|
|
189
|
+
agentId: apiMemory.agentId as UUID,
|
|
190
|
+
content: apiMemory.content,
|
|
191
|
+
embedding: apiMemory.embedding,
|
|
192
|
+
roomId: apiMemory.roomId as UUID,
|
|
193
|
+
createdAt: apiDateToTimestamp(apiMemory.createdAt),
|
|
194
|
+
unique: apiMemory.metadata?.unique,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { Agent } from '@elizaos/core';
|
|
2
|
+
|
|
3
|
+
export interface ExportResult {
|
|
4
|
+
success: boolean;
|
|
5
|
+
filename?: string;
|
|
6
|
+
error?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface ToastFunction {
|
|
10
|
+
(options: { title: string; description: string; variant?: 'default' | 'destructive' }): void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Sanitizes a filename by replacing non-alphanumeric characters with dashes
|
|
15
|
+
* and cleaning up multiple consecutive dashes
|
|
16
|
+
*/
|
|
17
|
+
export function sanitizeFilename(name: string): string {
|
|
18
|
+
return name
|
|
19
|
+
.replace(/[^a-zA-Z0-9]/g, '-') // Replace non-alphanumeric with dash
|
|
20
|
+
.replace(/-+/g, '-') // Replace multiple consecutive dashes with single dash
|
|
21
|
+
.replace(/^-|-$/g, '') // Remove leading/trailing dashes
|
|
22
|
+
.toLowerCase();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Converts an agent to character JSON data, excluding sensitive information
|
|
27
|
+
*/
|
|
28
|
+
export function agentToCharacterData(agent: Agent): Record<string, any> {
|
|
29
|
+
const characterData = {
|
|
30
|
+
id: agent.id,
|
|
31
|
+
name: agent.name,
|
|
32
|
+
username: agent.username,
|
|
33
|
+
system: agent.system,
|
|
34
|
+
templates: agent.templates,
|
|
35
|
+
bio: agent.bio,
|
|
36
|
+
messageExamples: agent.messageExamples,
|
|
37
|
+
postExamples: agent.postExamples,
|
|
38
|
+
topics: agent.topics,
|
|
39
|
+
adjectives: agent.adjectives,
|
|
40
|
+
knowledge: agent.knowledge,
|
|
41
|
+
plugins: agent.plugins,
|
|
42
|
+
settings: agent.settings ? { ...agent.settings } : undefined,
|
|
43
|
+
style: agent.style,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Remove secrets from settings if they exist
|
|
47
|
+
if (characterData.settings && 'secrets' in characterData.settings) {
|
|
48
|
+
const { secrets, ...settingsWithoutSecrets } = characterData.settings;
|
|
49
|
+
characterData.settings = settingsWithoutSecrets;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Remove undefined/null fields to keep JSON clean
|
|
53
|
+
return Object.fromEntries(
|
|
54
|
+
Object.entries(characterData).filter(([_, value]) => value !== undefined && value !== null)
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Generates a filename for the exported character
|
|
60
|
+
*/
|
|
61
|
+
export function generateExportFilename(agentName: string): string {
|
|
62
|
+
const date = new Date().toISOString().split('T')[0]; // YYYY-MM-DD format
|
|
63
|
+
const sanitizedName = sanitizeFilename(agentName || 'agent');
|
|
64
|
+
return `${sanitizedName}-${date}.json`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Creates and triggers a download of a JSON file
|
|
69
|
+
*/
|
|
70
|
+
export function downloadJsonFile(data: any, filename: string): void {
|
|
71
|
+
const blob = new Blob([JSON.stringify(data, null, 2)], {
|
|
72
|
+
type: 'application/json',
|
|
73
|
+
});
|
|
74
|
+
const url = URL.createObjectURL(blob);
|
|
75
|
+
const link = document.createElement('a');
|
|
76
|
+
link.href = url;
|
|
77
|
+
link.download = filename;
|
|
78
|
+
document.body.appendChild(link);
|
|
79
|
+
link.click();
|
|
80
|
+
document.body.removeChild(link);
|
|
81
|
+
URL.revokeObjectURL(url);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Exports an agent's character data as a JSON file download
|
|
86
|
+
* @param agent - The agent containing the character data to export
|
|
87
|
+
* @param toast - Optional toast function for notifications
|
|
88
|
+
* @returns Export result with success status and filename or error
|
|
89
|
+
*/
|
|
90
|
+
export function exportCharacterAsJson(agent: Agent, toast?: ToastFunction): ExportResult {
|
|
91
|
+
try {
|
|
92
|
+
const characterData = agentToCharacterData(agent);
|
|
93
|
+
const filename = generateExportFilename(agent.name);
|
|
94
|
+
|
|
95
|
+
downloadJsonFile(characterData, filename);
|
|
96
|
+
|
|
97
|
+
// Success notification
|
|
98
|
+
if (toast) {
|
|
99
|
+
toast({
|
|
100
|
+
title: 'Character Exported',
|
|
101
|
+
description: `${agent.name}'s character data has been downloaded as ${filename}`,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return { success: true, filename };
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error('Failed to export character:', error);
|
|
108
|
+
|
|
109
|
+
// Error notification
|
|
110
|
+
if (toast) {
|
|
111
|
+
toast({
|
|
112
|
+
title: 'Export Failed',
|
|
113
|
+
description: 'Failed to export character data. Please try again.',
|
|
114
|
+
variant: 'destructive',
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
success: false,
|
|
120
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { elizaLogger } from '@elizaos/core';
|
|
2
|
+
|
|
3
|
+
// Add client-specific context to logs
|
|
4
|
+
const clientLogger = {
|
|
5
|
+
info: (msg: string, ...args: any[]) => {
|
|
6
|
+
elizaLogger.info({ source: 'client' }, msg, ...args);
|
|
7
|
+
},
|
|
8
|
+
error: (msg: string, ...args: any[]) => {
|
|
9
|
+
elizaLogger.error({ source: 'client' }, msg, ...args);
|
|
10
|
+
},
|
|
11
|
+
warn: (msg: string, ...args: any[]) => {
|
|
12
|
+
elizaLogger.warn({ source: 'client' }, msg, ...args);
|
|
13
|
+
},
|
|
14
|
+
debug: (msg: string, ...args: any[]) => {
|
|
15
|
+
elizaLogger.debug({ source: 'client' }, msg, ...args);
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default clientLogger;
|