epsimo-agent 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/LICENSE +21 -0
- package/SKILL.md +85 -0
- package/assets/example_asset.txt +24 -0
- package/epsimo/__init__.py +3 -0
- package/epsimo/__main__.py +4 -0
- package/epsimo/auth.py +143 -0
- package/epsimo/cli.py +586 -0
- package/epsimo/client.py +53 -0
- package/epsimo/resources/assistants.py +47 -0
- package/epsimo/resources/credits.py +16 -0
- package/epsimo/resources/db.py +31 -0
- package/epsimo/resources/files.py +39 -0
- package/epsimo/resources/projects.py +30 -0
- package/epsimo/resources/threads.py +83 -0
- package/epsimo/templates/components/AuthModal/AuthModal.module.css +39 -0
- package/epsimo/templates/components/AuthModal/AuthModal.tsx +138 -0
- package/epsimo/templates/components/BuyCredits/BuyCreditsModal.module.css +96 -0
- package/epsimo/templates/components/BuyCredits/BuyCreditsModal.tsx +132 -0
- package/epsimo/templates/components/BuyCredits/CreditsDisplay.tsx +101 -0
- package/epsimo/templates/components/ThreadChat/ThreadChat.module.css +551 -0
- package/epsimo/templates/components/ThreadChat/ThreadChat.tsx +862 -0
- package/epsimo/templates/components/ThreadChat/components/ToolRenderers.module.css +509 -0
- package/epsimo/templates/components/ThreadChat/components/ToolRenderers.tsx +322 -0
- package/epsimo/templates/next-mvp/app/globals.css.tmpl +20 -0
- package/epsimo/templates/next-mvp/app/layout.tsx.tmpl +22 -0
- package/epsimo/templates/next-mvp/app/page.module.css.tmpl +84 -0
- package/epsimo/templates/next-mvp/app/page.tsx.tmpl +43 -0
- package/epsimo/templates/next-mvp/epsimo.yaml.tmpl +12 -0
- package/epsimo/templates/next-mvp/package.json.tmpl +26 -0
- package/epsimo/tools/library.yaml +51 -0
- package/package.json +27 -0
- package/references/api_reference.md +34 -0
- package/references/virtual_db_guide.md +57 -0
- package/requirements.txt +2 -0
- package/scripts/assistant.py +165 -0
- package/scripts/auth.py +195 -0
- package/scripts/credits.py +107 -0
- package/scripts/debug_run.py +41 -0
- package/scripts/example.py +19 -0
- package/scripts/files.py +73 -0
- package/scripts/find_thread.py +55 -0
- package/scripts/project.py +60 -0
- package/scripts/run.py +75 -0
- package/scripts/test_all_skills.py +387 -0
- package/scripts/test_sdk.py +83 -0
- package/scripts/test_streaming.py +167 -0
- package/scripts/test_vdb.py +65 -0
- package/scripts/thread.py +77 -0
- package/scripts/verify_skill.py +87 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import React, { useState, useEffect } from 'react';
|
|
4
|
+
import styles from './ToolRenderers.module.css';
|
|
5
|
+
|
|
6
|
+
export interface ToolCall {
|
|
7
|
+
id: string;
|
|
8
|
+
function?: {
|
|
9
|
+
name: string;
|
|
10
|
+
arguments: string;
|
|
11
|
+
};
|
|
12
|
+
name?: string;
|
|
13
|
+
type?: string;
|
|
14
|
+
args?: any;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Tool icon mapping for common tools
|
|
18
|
+
const getToolIcon = (name: string): string => {
|
|
19
|
+
const lowerName = name.toLowerCase();
|
|
20
|
+
if (lowerName.includes('search') || lowerName.includes('tavily') || lowerName.includes('duckduckgo')) return '🔍';
|
|
21
|
+
if (lowerName.includes('weather')) return '🌤️';
|
|
22
|
+
if (lowerName.includes('calculator') || lowerName.includes('math')) return '🧮';
|
|
23
|
+
if (lowerName.includes('database') || lowerName.includes('sql')) return '🗄️';
|
|
24
|
+
if (lowerName.includes('file') || lowerName.includes('document')) return '📄';
|
|
25
|
+
if (lowerName.includes('image') || lowerName.includes('dall')) return '🎨';
|
|
26
|
+
if (lowerName.includes('code') || lowerName.includes('python')) return '💻';
|
|
27
|
+
if (lowerName.includes('email') || lowerName.includes('mail')) return '📧';
|
|
28
|
+
if (lowerName.includes('calendar') || lowerName.includes('schedule')) return '📅';
|
|
29
|
+
if (lowerName.includes('retrieval') || lowerName.includes('rag')) return '📚';
|
|
30
|
+
if (lowerName.includes('api') || lowerName.includes('http')) return '🌐';
|
|
31
|
+
if (lowerName.includes('user') || lowerName.includes('account')) return '👤';
|
|
32
|
+
return '⚡';
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Format tool name for display
|
|
36
|
+
const formatToolName = (name: string): string => {
|
|
37
|
+
return name
|
|
38
|
+
.replace(/_/g, ' ')
|
|
39
|
+
.replace(/([A-Z])/g, ' $1')
|
|
40
|
+
.replace(/\s+/g, ' ')
|
|
41
|
+
.trim()
|
|
42
|
+
.split(' ')
|
|
43
|
+
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
44
|
+
.join(' ');
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Collapsible JSON viewer
|
|
48
|
+
const JsonViewer = ({ data, defaultExpanded = false }: { data: any; defaultExpanded?: boolean }) => {
|
|
49
|
+
const [isExpanded, setIsExpanded] = useState(defaultExpanded);
|
|
50
|
+
|
|
51
|
+
let displayData = data;
|
|
52
|
+
if (typeof data === 'string') {
|
|
53
|
+
try {
|
|
54
|
+
displayData = JSON.parse(data);
|
|
55
|
+
} catch {
|
|
56
|
+
displayData = data;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const formatted = typeof displayData === 'string'
|
|
61
|
+
? displayData
|
|
62
|
+
: JSON.stringify(displayData, null, 2);
|
|
63
|
+
|
|
64
|
+
const lineCount = formatted.split('\n').length;
|
|
65
|
+
const isLong = lineCount > 5 || formatted.length > 200;
|
|
66
|
+
|
|
67
|
+
if (!isLong) {
|
|
68
|
+
return <pre className={styles.jsonContent}>{formatted}</pre>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<div className={styles.jsonViewer}>
|
|
73
|
+
<pre className={`${styles.jsonContent} ${!isExpanded ? styles.collapsed : ''}`}>
|
|
74
|
+
{formatted}
|
|
75
|
+
</pre>
|
|
76
|
+
<button
|
|
77
|
+
className={styles.expandButton}
|
|
78
|
+
onClick={() => setIsExpanded(!isExpanded)}
|
|
79
|
+
>
|
|
80
|
+
{isExpanded ? 'Show less' : 'Show more'}
|
|
81
|
+
</button>
|
|
82
|
+
</div>
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// Modern Tool Card Component
|
|
87
|
+
export const ToolCard = ({
|
|
88
|
+
toolCall,
|
|
89
|
+
response,
|
|
90
|
+
isExecuting = false,
|
|
91
|
+
status = 'pending'
|
|
92
|
+
}: {
|
|
93
|
+
toolCall: any;
|
|
94
|
+
response?: any;
|
|
95
|
+
isExecuting?: boolean;
|
|
96
|
+
status?: 'pending' | 'running' | 'success' | 'error';
|
|
97
|
+
}) => {
|
|
98
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
99
|
+
const [showArgs, setShowArgs] = useState(false);
|
|
100
|
+
|
|
101
|
+
const name = toolCall.function?.name || toolCall.name || toolCall.tool || "Unknown Tool";
|
|
102
|
+
const icon = getToolIcon(name);
|
|
103
|
+
const displayName = formatToolName(name);
|
|
104
|
+
|
|
105
|
+
// Parse arguments
|
|
106
|
+
let args: any = {};
|
|
107
|
+
const rawArgs = toolCall.function?.arguments || toolCall.args || toolCall.arguments || toolCall.input;
|
|
108
|
+
if (rawArgs) {
|
|
109
|
+
try {
|
|
110
|
+
args = typeof rawArgs === 'string' ? JSON.parse(rawArgs) : rawArgs;
|
|
111
|
+
} catch {
|
|
112
|
+
args = { input: rawArgs };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Get a summary of the args for preview
|
|
117
|
+
const argsSummary = Object.entries(args)
|
|
118
|
+
.slice(0, 2)
|
|
119
|
+
.map(([key, value]) => {
|
|
120
|
+
const strValue = typeof value === 'string' ? value : JSON.stringify(value);
|
|
121
|
+
return strValue.length > 30 ? strValue.substring(0, 30) + '...' : strValue;
|
|
122
|
+
})
|
|
123
|
+
.join(', ');
|
|
124
|
+
|
|
125
|
+
const currentStatus = isExecuting ? 'running' : (response ? 'success' : status);
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<div className={`${styles.toolCard} ${styles[`status_${currentStatus}`]}`}>
|
|
129
|
+
<div
|
|
130
|
+
className={styles.toolHeader}
|
|
131
|
+
onClick={() => setIsExpanded(!isExpanded)}
|
|
132
|
+
>
|
|
133
|
+
<div className={styles.toolHeaderLeft}>
|
|
134
|
+
<div className={`${styles.statusIndicator} ${styles[`indicator_${currentStatus}`]}`}>
|
|
135
|
+
{currentStatus === 'running' ? (
|
|
136
|
+
<div className={styles.pulsingDot} />
|
|
137
|
+
) : currentStatus === 'success' ? (
|
|
138
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3">
|
|
139
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
140
|
+
</svg>
|
|
141
|
+
) : currentStatus === 'error' ? (
|
|
142
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3">
|
|
143
|
+
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
144
|
+
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
145
|
+
</svg>
|
|
146
|
+
) : (
|
|
147
|
+
<div className={styles.pendingDot} />
|
|
148
|
+
)}
|
|
149
|
+
</div>
|
|
150
|
+
<span className={styles.toolIcon}>{icon}</span>
|
|
151
|
+
<span className={styles.toolName}>{displayName}</span>
|
|
152
|
+
</div>
|
|
153
|
+
|
|
154
|
+
<div className={styles.toolHeaderRight}>
|
|
155
|
+
{argsSummary && !isExpanded && (
|
|
156
|
+
<span className={styles.argsSummary}>{argsSummary}</span>
|
|
157
|
+
)}
|
|
158
|
+
<svg
|
|
159
|
+
className={`${styles.chevron} ${isExpanded ? styles.chevronExpanded : ''}`}
|
|
160
|
+
width="16"
|
|
161
|
+
height="16"
|
|
162
|
+
viewBox="0 0 24 24"
|
|
163
|
+
fill="none"
|
|
164
|
+
stroke="currentColor"
|
|
165
|
+
strokeWidth="2"
|
|
166
|
+
>
|
|
167
|
+
<polyline points="6 9 12 15 18 9"></polyline>
|
|
168
|
+
</svg>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
{isExpanded && (
|
|
173
|
+
<div className={styles.toolBody}>
|
|
174
|
+
{/* Arguments Section */}
|
|
175
|
+
{Object.keys(args).length > 0 && (
|
|
176
|
+
<div className={styles.toolSection}>
|
|
177
|
+
<button
|
|
178
|
+
className={styles.sectionHeader}
|
|
179
|
+
onClick={(e) => { e.stopPropagation(); setShowArgs(!showArgs); }}
|
|
180
|
+
>
|
|
181
|
+
<span className={styles.sectionTitle}>Input</span>
|
|
182
|
+
<svg
|
|
183
|
+
className={`${styles.miniChevron} ${showArgs ? styles.chevronExpanded : ''}`}
|
|
184
|
+
width="12"
|
|
185
|
+
height="12"
|
|
186
|
+
viewBox="0 0 24 24"
|
|
187
|
+
fill="none"
|
|
188
|
+
stroke="currentColor"
|
|
189
|
+
strokeWidth="2"
|
|
190
|
+
>
|
|
191
|
+
<polyline points="6 9 12 15 18 9"></polyline>
|
|
192
|
+
</svg>
|
|
193
|
+
</button>
|
|
194
|
+
{showArgs && (
|
|
195
|
+
<div className={styles.sectionContent}>
|
|
196
|
+
<JsonViewer data={args} />
|
|
197
|
+
</div>
|
|
198
|
+
)}
|
|
199
|
+
</div>
|
|
200
|
+
)}
|
|
201
|
+
|
|
202
|
+
{/* Status/Progress Section */}
|
|
203
|
+
{currentStatus === 'running' && (
|
|
204
|
+
<div className={styles.runningStatus}>
|
|
205
|
+
<div className={styles.progressBar}>
|
|
206
|
+
<div className={styles.progressFill} />
|
|
207
|
+
</div>
|
|
208
|
+
<span className={styles.runningText}>Searching...</span>
|
|
209
|
+
</div>
|
|
210
|
+
)}
|
|
211
|
+
|
|
212
|
+
{/* Response Section */}
|
|
213
|
+
{response && (
|
|
214
|
+
<div className={styles.toolSection}>
|
|
215
|
+
<div className={styles.sectionHeader}>
|
|
216
|
+
<span className={styles.sectionTitle}>Output</span>
|
|
217
|
+
</div>
|
|
218
|
+
<div className={styles.sectionContent}>
|
|
219
|
+
<JsonViewer data={response} defaultExpanded={true} />
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
)}
|
|
223
|
+
</div>
|
|
224
|
+
)}
|
|
225
|
+
</div>
|
|
226
|
+
);
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
// Legacy components for backward compatibility
|
|
230
|
+
export const ToolRequest = ({ toolCall }: { toolCall: any }) => {
|
|
231
|
+
return <ToolCard toolCall={toolCall} status="pending" />;
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
export const ToolResponse = ({ content }: { content: string | any }) => {
|
|
235
|
+
let displayContent = content;
|
|
236
|
+
if (content && typeof content === 'object') {
|
|
237
|
+
displayContent = content.output || content.result || content.content || content;
|
|
238
|
+
}
|
|
239
|
+
if (typeof displayContent !== 'string') {
|
|
240
|
+
try {
|
|
241
|
+
displayContent = JSON.stringify(displayContent, null, 2);
|
|
242
|
+
} catch {
|
|
243
|
+
displayContent = String(displayContent);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return (
|
|
248
|
+
<div className={styles.legacyResponse}>
|
|
249
|
+
<div className={styles.responseHeader}>
|
|
250
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
251
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
252
|
+
</svg>
|
|
253
|
+
<span>Result</span>
|
|
254
|
+
</div>
|
|
255
|
+
<div className={styles.responseContent}>
|
|
256
|
+
<pre>{displayContent}</pre>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
);
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
export const ToolExecuting = ({ name }: { name: string }) => {
|
|
263
|
+
const icon = getToolIcon(name);
|
|
264
|
+
const displayName = formatToolName(name);
|
|
265
|
+
|
|
266
|
+
return (
|
|
267
|
+
<div className={styles.executingCard}>
|
|
268
|
+
<div className={styles.executingHeader}>
|
|
269
|
+
<div className={styles.pulsingDot} />
|
|
270
|
+
<span className={styles.toolIcon}>{icon}</span>
|
|
271
|
+
<span className={styles.executingName}>{displayName}</span>
|
|
272
|
+
</div>
|
|
273
|
+
<div className={styles.executingProgress}>
|
|
274
|
+
<div className={styles.progressBar}>
|
|
275
|
+
<div className={styles.progressFill} />
|
|
276
|
+
</div>
|
|
277
|
+
</div>
|
|
278
|
+
</div>
|
|
279
|
+
);
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
// Tool Usage Container - groups tool calls together
|
|
283
|
+
export const ToolUsageContainer = ({
|
|
284
|
+
toolCalls,
|
|
285
|
+
toolResponses = {},
|
|
286
|
+
currentTool = null
|
|
287
|
+
}: {
|
|
288
|
+
toolCalls: any[];
|
|
289
|
+
toolResponses?: Record<string, any>;
|
|
290
|
+
currentTool?: string | null;
|
|
291
|
+
}) => {
|
|
292
|
+
if (!toolCalls || toolCalls.length === 0) return null;
|
|
293
|
+
|
|
294
|
+
return (
|
|
295
|
+
<div className={styles.toolUsageContainer}>
|
|
296
|
+
<div className={styles.toolUsageHeader}>
|
|
297
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
298
|
+
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"></path>
|
|
299
|
+
</svg>
|
|
300
|
+
<span>Using {toolCalls.length} tool{toolCalls.length > 1 ? 's' : ''}</span>
|
|
301
|
+
</div>
|
|
302
|
+
<div className={styles.toolCardList}>
|
|
303
|
+
{toolCalls.map((toolCall, index) => {
|
|
304
|
+
const toolId = toolCall.id || `tool-${index}`;
|
|
305
|
+
const toolName = toolCall.function?.name || toolCall.name || '';
|
|
306
|
+
const isRunning = currentTool === toolName;
|
|
307
|
+
const response = toolResponses[toolId];
|
|
308
|
+
|
|
309
|
+
return (
|
|
310
|
+
<ToolCard
|
|
311
|
+
key={toolId}
|
|
312
|
+
toolCall={toolCall}
|
|
313
|
+
response={response}
|
|
314
|
+
isExecuting={isRunning}
|
|
315
|
+
status={response ? 'success' : (isRunning ? 'running' : 'pending')}
|
|
316
|
+
/>
|
|
317
|
+
);
|
|
318
|
+
})}
|
|
319
|
+
</div>
|
|
320
|
+
</div>
|
|
321
|
+
);
|
|
322
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--background: #000;
|
|
3
|
+
--foreground: #fff;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
* {
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
padding: 0;
|
|
9
|
+
margin: 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
body {
|
|
13
|
+
background: var(--background);
|
|
14
|
+
color: var(--foreground);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
a {
|
|
18
|
+
color: inherit;
|
|
19
|
+
text-decoration: none;
|
|
20
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { Inter } from "next/font/google";
|
|
3
|
+
import "./globals.css";
|
|
4
|
+
|
|
5
|
+
const inter = Inter({ subsets: ["latin"] });
|
|
6
|
+
|
|
7
|
+
export const metadata: Metadata = {
|
|
8
|
+
title: "{{PROJECT_NAME}} - Powered by Epsimo",
|
|
9
|
+
description: "Epsimo AI Agent MVP application",
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default function RootLayout({
|
|
13
|
+
children,
|
|
14
|
+
}: Readonly<{
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
}>) {
|
|
17
|
+
return (
|
|
18
|
+
<html lang="en">
|
|
19
|
+
<body className={inter.className}>{children}</body>
|
|
20
|
+
</html>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
.main {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
height: 100vh;
|
|
5
|
+
background: #000;
|
|
6
|
+
color: #fff;
|
|
7
|
+
font-family: var(--font-inter);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.header {
|
|
11
|
+
padding: 2rem;
|
|
12
|
+
border-bottom: 1px solid #222;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.header h1 {
|
|
16
|
+
margin: 0;
|
|
17
|
+
font-size: 1.5rem;
|
|
18
|
+
background: linear-gradient(90deg, #fff, #888);
|
|
19
|
+
-webkit-background-clip: text;
|
|
20
|
+
-webkit-text-fill-color: transparent;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.titleGroup {
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
gap: 1rem;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.version {
|
|
30
|
+
font-size: 0.7rem;
|
|
31
|
+
background: #222;
|
|
32
|
+
padding: 0.2rem 0.5rem;
|
|
33
|
+
border-radius: 4px;
|
|
34
|
+
color: #888;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.header p {
|
|
38
|
+
margin: 0.5rem 0 0;
|
|
39
|
+
font-size: 0.9rem;
|
|
40
|
+
color: #666;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.content {
|
|
44
|
+
flex: 1;
|
|
45
|
+
display: flex;
|
|
46
|
+
overflow: hidden;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.sidebar {
|
|
50
|
+
width: 300px;
|
|
51
|
+
border-right: 1px solid #222;
|
|
52
|
+
padding: 1.5rem;
|
|
53
|
+
display: flex;
|
|
54
|
+
flex-direction: column;
|
|
55
|
+
gap: 1rem;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.sidebar h3 {
|
|
59
|
+
font-size: 0.9rem;
|
|
60
|
+
text-transform: uppercase;
|
|
61
|
+
color: #444;
|
|
62
|
+
letter-spacing: 0.05rem;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.hint {
|
|
66
|
+
font-size: 0.8rem;
|
|
67
|
+
color: #666;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.dbPreview {
|
|
71
|
+
flex: 1;
|
|
72
|
+
background: #111;
|
|
73
|
+
border-radius: 8px;
|
|
74
|
+
padding: 1rem;
|
|
75
|
+
font-family: monospace;
|
|
76
|
+
font-size: 0.8rem;
|
|
77
|
+
color: #0f0;
|
|
78
|
+
overflow: auto;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.chatSection {
|
|
82
|
+
flex: 1;
|
|
83
|
+
height: 100%;
|
|
84
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { ThreadChat } from "@/components/epsimo";
|
|
5
|
+
import styles from "./page.module.css";
|
|
6
|
+
|
|
7
|
+
export default function Home() {
|
|
8
|
+
const [appState, setAppState] = useState<any>(null);
|
|
9
|
+
|
|
10
|
+
// Example: Listening for changes in the Virtual Database
|
|
11
|
+
// In a real app, you would fetch this on a timer or after a message
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
console.log("Tip: Use client.db.get_all() from the SDK to read structured thread state!");
|
|
14
|
+
}, []);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<main className={styles.main}>
|
|
18
|
+
<header className={styles.header}>
|
|
19
|
+
<div className={styles.titleGroup}>
|
|
20
|
+
<h1>{{PROJECT_NAME}}</h1>
|
|
21
|
+
<span className={styles.version}>v0.1.0</span>
|
|
22
|
+
</div>
|
|
23
|
+
<p>AI-Powered MVP built with Epsimo Agent Framework</p>
|
|
24
|
+
</header>
|
|
25
|
+
|
|
26
|
+
<div className={styles.content}>
|
|
27
|
+
<aside className={styles.sidebar}>
|
|
28
|
+
<h3>Project Memory</h3>
|
|
29
|
+
<p className={styles.hint}>Structured data written by the agent will appear here.</p>
|
|
30
|
+
<div className={styles.dbPreview}>
|
|
31
|
+
{appState ? JSON.stringify(appState, null, 2) : "DB Empty..."}
|
|
32
|
+
</div>
|
|
33
|
+
</aside>
|
|
34
|
+
|
|
35
|
+
<section className={styles.chatSection}>
|
|
36
|
+
<ThreadChat
|
|
37
|
+
assistantId="{{ASSISTANT_ID}}"
|
|
38
|
+
/>
|
|
39
|
+
</section>
|
|
40
|
+
</div>
|
|
41
|
+
</main>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Epsimo Agent Configuration
|
|
2
|
+
name: "{{PROJECT_NAME}}"
|
|
3
|
+
|
|
4
|
+
assistants:
|
|
5
|
+
- name: "mvp-assistant"
|
|
6
|
+
model: "gpt-4o"
|
|
7
|
+
instructions: |
|
|
8
|
+
You are the core intelligence for {{PROJECT_NAME}}.
|
|
9
|
+
You help users achieve their goals by using the tools available to you.
|
|
10
|
+
tools:
|
|
11
|
+
- type: "retrieval"
|
|
12
|
+
- type: "ddg_search"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PROJECT_SLUG}}",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "next dev",
|
|
7
|
+
"build": "next build",
|
|
8
|
+
"start": "next start",
|
|
9
|
+
"lint": "next lint"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"react": "^18",
|
|
13
|
+
"react-dom": "^18",
|
|
14
|
+
"next": "14.2.3",
|
|
15
|
+
"react-markdown": "^9.0.1",
|
|
16
|
+
"lucide-react": "^0.378.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"typescript": "^5",
|
|
20
|
+
"@types/node": "^20",
|
|
21
|
+
"@types/react": "^18",
|
|
22
|
+
"@types/react-dom": "^18",
|
|
23
|
+
"eslint": "^8",
|
|
24
|
+
"eslint-config-next": "14.2.3"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Epsimo Tool Library
|
|
2
|
+
# Reusable tool schemas for rapid development
|
|
3
|
+
|
|
4
|
+
database_sync:
|
|
5
|
+
type: "function"
|
|
6
|
+
name: "update_database"
|
|
7
|
+
description: "Persist structured JSON data to the conversation state for long-term memory."
|
|
8
|
+
parameters:
|
|
9
|
+
type: "object"
|
|
10
|
+
properties:
|
|
11
|
+
key:
|
|
12
|
+
type: "string"
|
|
13
|
+
description: "The data category (e.g. 'user_info', 'preferences')"
|
|
14
|
+
value:
|
|
15
|
+
type: "object"
|
|
16
|
+
description: "The JSON data to store"
|
|
17
|
+
required: ["key", "value"]
|
|
18
|
+
|
|
19
|
+
web_search_tavily:
|
|
20
|
+
type: "search_tavily"
|
|
21
|
+
name: "Search"
|
|
22
|
+
description: "Advanced search with source attribution."
|
|
23
|
+
config:
|
|
24
|
+
max_results: 5
|
|
25
|
+
|
|
26
|
+
web_search_ddg:
|
|
27
|
+
type: "ddg_search"
|
|
28
|
+
name: "Quick Search"
|
|
29
|
+
description: "Fast web search for simple queries."
|
|
30
|
+
|
|
31
|
+
retrieval_optimized:
|
|
32
|
+
type: "retrieval"
|
|
33
|
+
name: "Knowledge Base"
|
|
34
|
+
description: "Search in uploaded documents."
|
|
35
|
+
config:
|
|
36
|
+
top_k: 5
|
|
37
|
+
score_threshold: 0.7
|
|
38
|
+
|
|
39
|
+
task_management:
|
|
40
|
+
type: "function"
|
|
41
|
+
name: "manage_task"
|
|
42
|
+
description: "Track and update user tasks."
|
|
43
|
+
parameters:
|
|
44
|
+
type: "object"
|
|
45
|
+
properties:
|
|
46
|
+
action:
|
|
47
|
+
type: "string"
|
|
48
|
+
enum: ["create", "update", "delete", "list"]
|
|
49
|
+
details:
|
|
50
|
+
type: "object"
|
|
51
|
+
required: ["action", "details"]
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "epsimo-agent",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Comprehensive framework for building AI applications using EpsimoAI. Manage agents, projects, threads, and persistent state (Virtual Database).",
|
|
5
|
+
"author": "EpsimoAI",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "SKILL.md",
|
|
8
|
+
"files": [
|
|
9
|
+
"SKILL.md",
|
|
10
|
+
"scripts/",
|
|
11
|
+
"epsimo/",
|
|
12
|
+
"references/",
|
|
13
|
+
"assets/",
|
|
14
|
+
"requirements.txt"
|
|
15
|
+
],
|
|
16
|
+
"keywords": [
|
|
17
|
+
"skill",
|
|
18
|
+
"ai",
|
|
19
|
+
"agent",
|
|
20
|
+
"epsimo",
|
|
21
|
+
"llm"
|
|
22
|
+
],
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/epsimo-ai/epsimo-agent.git"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Reference Documentation for Epsimo Agent
|
|
2
|
+
|
|
3
|
+
This is a placeholder for detailed reference documentation.
|
|
4
|
+
Replace with actual reference content or delete if not needed.
|
|
5
|
+
|
|
6
|
+
Example real reference docs from other skills:
|
|
7
|
+
- product-management/references/communication.md - Comprehensive guide for status updates
|
|
8
|
+
- product-management/references/context_building.md - Deep-dive on gathering context
|
|
9
|
+
- bigquery/references/ - API references and query examples
|
|
10
|
+
|
|
11
|
+
## When Reference Docs Are Useful
|
|
12
|
+
|
|
13
|
+
Reference docs are ideal for:
|
|
14
|
+
- Comprehensive API documentation
|
|
15
|
+
- Detailed workflow guides
|
|
16
|
+
- Complex multi-step processes
|
|
17
|
+
- Information too lengthy for main SKILL.md
|
|
18
|
+
- Content that's only needed for specific use cases
|
|
19
|
+
|
|
20
|
+
## Structure Suggestions
|
|
21
|
+
|
|
22
|
+
### API Reference Example
|
|
23
|
+
- Overview
|
|
24
|
+
- Authentication
|
|
25
|
+
- Endpoints with examples
|
|
26
|
+
- Error codes
|
|
27
|
+
- Rate limits
|
|
28
|
+
|
|
29
|
+
### Workflow Guide Example
|
|
30
|
+
- Prerequisites
|
|
31
|
+
- Step-by-step instructions
|
|
32
|
+
- Common patterns
|
|
33
|
+
- Troubleshooting
|
|
34
|
+
- Best practices
|