@feardread/fear 1.0.4 → 1.0.5
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/libs/builder/builder.js +30 -0
- package/package.json +1 -1
- package/routes/builder.js +361 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
async function webSearch(query) {
|
|
4
|
+
// Implement web search functionality
|
|
5
|
+
console.log('Searching for:', query);
|
|
6
|
+
return { results: [] };
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const fs = require('fs').promises;
|
|
10
|
+
|
|
11
|
+
async function readFile(path) {
|
|
12
|
+
try {
|
|
13
|
+
const content = await fs.readFile(path, 'utf8');
|
|
14
|
+
return { success: true, content };
|
|
15
|
+
} catch (error) {
|
|
16
|
+
return { success: false, error: error.message };
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function queryDatabase(query) {
|
|
21
|
+
// Implement database query functionality
|
|
22
|
+
console.log('Querying database:', query);
|
|
23
|
+
return { rows: [] };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = function () {
|
|
27
|
+
return {
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
const anthropic = new Anthropic({
|
|
4
|
+
apiKey: process.env.ANTHROPIC_API_KEY || ''
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
const AGENT_CONFIG = {
|
|
8
|
+
name: 'home work assistant',
|
|
9
|
+
description: 'helps me organize calls and client files',
|
|
10
|
+
personality: 'professional',
|
|
11
|
+
model: 'claude-sonnet-4-20250514'
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const SYSTEM_PROMPT = `You are ${AGENT_CONFIG.name}, ${AGENT_CONFIG.description}.
|
|
15
|
+
Your primary function is: organize clients and files.
|
|
16
|
+
Personality: ${AGENT_CONFIG.personality}.
|
|
17
|
+
Available tools: web_search, file_read, database
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
module.exports = (fear) => {
|
|
23
|
+
const router = fear.createRouter();
|
|
24
|
+
const logger = fear.getLogger();
|
|
25
|
+
const handler = fear.getHandler();
|
|
26
|
+
|
|
27
|
+
router.post('/generate', handler.async((req, res) => {
|
|
28
|
+
const { formData } = req.body;
|
|
29
|
+
|
|
30
|
+
const toolImplementations = {
|
|
31
|
+
web_search: `
|
|
32
|
+
async function webSearch(query) {
|
|
33
|
+
// Implement web search functionality
|
|
34
|
+
console.log('Searching for:', query);
|
|
35
|
+
return { results: [] };
|
|
36
|
+
}`,
|
|
37
|
+
file_read: `
|
|
38
|
+
const fs = require('fs').promises;
|
|
39
|
+
|
|
40
|
+
async function readFile(path) {
|
|
41
|
+
try {
|
|
42
|
+
const content = await fs.readFile(path, 'utf8');
|
|
43
|
+
return { success: true, content };
|
|
44
|
+
} catch (error) {
|
|
45
|
+
return { success: false, error: error.message };
|
|
46
|
+
}
|
|
47
|
+
}`,
|
|
48
|
+
calculator: `
|
|
49
|
+
function calculate(expression) {
|
|
50
|
+
try {
|
|
51
|
+
return { result: eval(expression) };
|
|
52
|
+
} catch (error) {
|
|
53
|
+
return { error: 'Invalid expression' };
|
|
54
|
+
}
|
|
55
|
+
}`,
|
|
56
|
+
database: `
|
|
57
|
+
async function queryDatabase(query) {
|
|
58
|
+
// Implement database query functionality
|
|
59
|
+
console.log('Querying database:', query);
|
|
60
|
+
return { rows: [] };
|
|
61
|
+
}`
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const selectedTools = (formData.tools || []).map(t => toolImplementations[t] || '').join('\n');
|
|
65
|
+
const chatRoute = `
|
|
66
|
+
router.post('/chat', handler.async((req, res) => {
|
|
67
|
+
const { message, conversationHistory = [] } = req.body;
|
|
68
|
+
const messages = [
|
|
69
|
+
...conversationHistory,
|
|
70
|
+
{ role: 'user', content: message }
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
return anthropic.messages.create({
|
|
74
|
+
model: AGENT_CONFIG.model,
|
|
75
|
+
max_tokens: 1024,
|
|
76
|
+
system: SYSTEM_PROMPT,
|
|
77
|
+
messages: messages
|
|
78
|
+
})
|
|
79
|
+
.then((response) => {
|
|
80
|
+
const assistantMessage = response.content[0].text;
|
|
81
|
+
return handler.success(res, {
|
|
82
|
+
success: true,
|
|
83
|
+
output: assistantMessage,
|
|
84
|
+
conversationHistory: [
|
|
85
|
+
...messages,
|
|
86
|
+
{ role: 'assistant', content: assistantMessage }
|
|
87
|
+
]
|
|
88
|
+
})
|
|
89
|
+
})
|
|
90
|
+
.catch((error) => {
|
|
91
|
+
logger.error('Error:', error);
|
|
92
|
+
return handler.error(res, {
|
|
93
|
+
success: false,
|
|
94
|
+
error: error.message
|
|
95
|
+
})
|
|
96
|
+
});
|
|
97
|
+
}));`;
|
|
98
|
+
const serverCode = `// ${formData.agentName || 'Custom AI Agent'}
|
|
99
|
+
// Generated by AI Agent Builder
|
|
100
|
+
// ${formData.agentDescription || 'No description provided'}
|
|
101
|
+
|
|
102
|
+
require('dotenv').config();
|
|
103
|
+
const Fear = require('@feardread/fear');
|
|
104
|
+
const Anthropic = require('@anthropic-ai/sdk');
|
|
105
|
+
|
|
106
|
+
const app = express();
|
|
107
|
+
app.use(express.json());
|
|
108
|
+
app.use(express.static('public'));
|
|
109
|
+
|
|
110
|
+
const anthropic = new Anthropic({
|
|
111
|
+
apiKey: process.env.ANTHROPIC_API_KEY || '${formData.apiKey || ''}'
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const AGENT_CONFIG = {
|
|
115
|
+
name: '${formData.agentName || 'Custom Agent'}',
|
|
116
|
+
description: '${formData.agentDescription || 'AI Assistant'}',
|
|
117
|
+
personality: '${formData.personality || 'professional'}',
|
|
118
|
+
model: '${formData.model || 'claude-sonnet-4-20250514'}'
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const SYSTEM_PROMPT = \`You are \${AGENT_CONFIG.name}, \${AGENT_CONFIG.description}.
|
|
122
|
+
Your primary function is: ${formData.primaryFunction || 'assist users with their requests'}.
|
|
123
|
+
Personality: \${AGENT_CONFIG.personality}.
|
|
124
|
+
${(formData.tools || []).length > 0 ? `Available tools: ${formData.tools.join(', ')}` : ''}
|
|
125
|
+
\`;
|
|
126
|
+
${selectedTools}
|
|
127
|
+
${chatRoute}
|
|
128
|
+
// Serve the frontend
|
|
129
|
+
app.get('/', (req, res) => {
|
|
130
|
+
res.send(\`
|
|
131
|
+
<!DOCTYPE html>
|
|
132
|
+
<html>
|
|
133
|
+
<head>
|
|
134
|
+
<title>\${AGENT_CONFIG.name}</title>
|
|
135
|
+
<style>
|
|
136
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
137
|
+
body {
|
|
138
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
139
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
140
|
+
min-height: 100vh;
|
|
141
|
+
display: flex;
|
|
142
|
+
justify-content: center;
|
|
143
|
+
align-items: center;
|
|
144
|
+
padding: 20px;
|
|
145
|
+
}
|
|
146
|
+
.container {
|
|
147
|
+
background: white;
|
|
148
|
+
border-radius: 20px;
|
|
149
|
+
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
|
|
150
|
+
width: 100%;
|
|
151
|
+
max-width: 800px;
|
|
152
|
+
height: 600px;
|
|
153
|
+
display: flex;
|
|
154
|
+
flex-direction: column;
|
|
155
|
+
}
|
|
156
|
+
.header {
|
|
157
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
158
|
+
color: white;
|
|
159
|
+
padding: 20px;
|
|
160
|
+
border-radius: 20px 20px 0 0;
|
|
161
|
+
text-align: center;
|
|
162
|
+
}
|
|
163
|
+
.chat-container {
|
|
164
|
+
flex: 1;
|
|
165
|
+
overflow-y: auto;
|
|
166
|
+
padding: 20px;
|
|
167
|
+
display: flex;
|
|
168
|
+
flex-direction: column;
|
|
169
|
+
gap: 15px;
|
|
170
|
+
}
|
|
171
|
+
.message {
|
|
172
|
+
padding: 12px 16px;
|
|
173
|
+
border-radius: 12px;
|
|
174
|
+
max-width: 70%;
|
|
175
|
+
word-wrap: break-word;
|
|
176
|
+
}
|
|
177
|
+
.user-message {
|
|
178
|
+
background: #667eea;
|
|
179
|
+
color: white;
|
|
180
|
+
align-self: flex-end;
|
|
181
|
+
}
|
|
182
|
+
.assistant-message {
|
|
183
|
+
background: #f0f0f0;
|
|
184
|
+
color: #333;
|
|
185
|
+
align-self: flex-start;
|
|
186
|
+
}
|
|
187
|
+
.input-container {
|
|
188
|
+
padding: 20px;
|
|
189
|
+
border-top: 1px solid #eee;
|
|
190
|
+
display: flex;
|
|
191
|
+
gap: 10px;
|
|
192
|
+
}
|
|
193
|
+
input {
|
|
194
|
+
flex: 1;
|
|
195
|
+
padding: 12px;
|
|
196
|
+
border: 2px solid #ddd;
|
|
197
|
+
border-radius: 10px;
|
|
198
|
+
font-size: 16px;
|
|
199
|
+
}
|
|
200
|
+
button {
|
|
201
|
+
padding: 12px 24px;
|
|
202
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
203
|
+
color: white;
|
|
204
|
+
border: none;
|
|
205
|
+
border-radius: 10px;
|
|
206
|
+
cursor: pointer;
|
|
207
|
+
font-size: 16px;
|
|
208
|
+
font-weight: 600;
|
|
209
|
+
}
|
|
210
|
+
button:hover { opacity: 0.9; }
|
|
211
|
+
button:disabled {
|
|
212
|
+
opacity: 0.5;
|
|
213
|
+
cursor: not-allowed;
|
|
214
|
+
}
|
|
215
|
+
</style>
|
|
216
|
+
</head>
|
|
217
|
+
<body>
|
|
218
|
+
<div class="container">
|
|
219
|
+
<div class="header">
|
|
220
|
+
<h1>\${AGENT_CONFIG.name}</h1>
|
|
221
|
+
<p>\${AGENT_CONFIG.description}</p>
|
|
222
|
+
</div>
|
|
223
|
+
<div class="chat-container" id="chatContainer"></div>
|
|
224
|
+
<div class="input-container">
|
|
225
|
+
<input type="text" id="messageInput" placeholder="Type your message..." />
|
|
226
|
+
<button onclick="sendMessage()" id="sendBtn">Send</button>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
|
|
230
|
+
<script>
|
|
231
|
+
let conversationHistory = [];
|
|
232
|
+
|
|
233
|
+
async function sendMessage() {
|
|
234
|
+
const input = document.getElementById('messageInput');
|
|
235
|
+
const message = input.value.trim();
|
|
236
|
+
if (!message) return;
|
|
237
|
+
|
|
238
|
+
const sendBtn = document.getElementById('sendBtn');
|
|
239
|
+
sendBtn.disabled = true;
|
|
240
|
+
|
|
241
|
+
addMessage(message, 'user');
|
|
242
|
+
input.value = '';
|
|
243
|
+
|
|
244
|
+
try {
|
|
245
|
+
const response = await fetch('/chat', {
|
|
246
|
+
method: 'POST',
|
|
247
|
+
headers: { 'Content-Type': 'application/json' },
|
|
248
|
+
body: JSON.stringify({ message, conversationHistory })
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
const data = await response.json();
|
|
252
|
+
|
|
253
|
+
if (data.success) {
|
|
254
|
+
addMessage(data.response, 'assistant');
|
|
255
|
+
conversationHistory = data.conversationHistory;
|
|
256
|
+
} else {
|
|
257
|
+
addMessage('Error: ' + data.error, 'assistant');
|
|
258
|
+
}
|
|
259
|
+
} catch (error) {
|
|
260
|
+
addMessage('Error: ' + error.message, 'assistant');
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
sendBtn.disabled = false;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function addMessage(text, type) {
|
|
267
|
+
const container = document.getElementById('chatContainer');
|
|
268
|
+
const div = document.createElement('div');
|
|
269
|
+
div.className = \`message \${type}-message\`;
|
|
270
|
+
div.textContent = text;
|
|
271
|
+
container.appendChild(div);
|
|
272
|
+
container.scrollTop = container.scrollHeight;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
document.getElementById('messageInput').addEventListener('keypress', (e) => {
|
|
276
|
+
if (e.key === 'Enter') sendMessage();
|
|
277
|
+
});
|
|
278
|
+
</script>
|
|
279
|
+
</body>
|
|
280
|
+
</html>
|
|
281
|
+
\`);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
const PORT = process.env.PORT || ${formData.port || '3000'};
|
|
285
|
+
app.listen(PORT, () => {
|
|
286
|
+
console.log(\`🤖 \${AGENT_CONFIG.name} running on http://localhost:\${PORT}\`);
|
|
287
|
+
console.log(\`📝 Description: \${AGENT_CONFIG.description}\`);
|
|
288
|
+
console.log(\`🎭 Personality: \${AGENT_CONFIG.personality}\`);
|
|
289
|
+
});
|
|
290
|
+
`;
|
|
291
|
+
|
|
292
|
+
const packageJson = {
|
|
293
|
+
name: (formData.agentName || 'custom-ai-agent').toLowerCase().replace(/\s+/g, '-'),
|
|
294
|
+
version: '1.0.0',
|
|
295
|
+
description: formData.agentDescription || 'Custom AI Agent',
|
|
296
|
+
main: 'server.js',
|
|
297
|
+
scripts: {
|
|
298
|
+
start: 'node server.js',
|
|
299
|
+
dev: 'nodemon server.js'
|
|
300
|
+
},
|
|
301
|
+
dependencies: {
|
|
302
|
+
'@feardread/fear': '^*',
|
|
303
|
+
'@anthropic-ai/sdk': '^0.32.0',
|
|
304
|
+
'express': '^4.18.2',
|
|
305
|
+
'dotenv': '^16.3.1'
|
|
306
|
+
},
|
|
307
|
+
devDependencies: {
|
|
308
|
+
'nodemon': '^3.0.1'
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
const readme = `# ${formData.agentName || 'Custom AI Agent'}
|
|
313
|
+
|
|
314
|
+
${formData.agentDescription || 'AI Agent generated by AI Agent Builder'}
|
|
315
|
+
|
|
316
|
+
## Setup
|
|
317
|
+
|
|
318
|
+
1. Install dependencies:
|
|
319
|
+
\`\`\`bash
|
|
320
|
+
npm install
|
|
321
|
+
\`\`\`
|
|
322
|
+
|
|
323
|
+
2. Create a \`.env\` file:
|
|
324
|
+
\`\`\`
|
|
325
|
+
ANTHROPIC_API_KEY=your_api_key_here
|
|
326
|
+
PORT=${formData.port || '3000'}
|
|
327
|
+
\`\`\`
|
|
328
|
+
|
|
329
|
+
3. Run the agent:
|
|
330
|
+
\`\`\`bash
|
|
331
|
+
npm start
|
|
332
|
+
\`\`\`
|
|
333
|
+
|
|
334
|
+
4. Open http://localhost:${formData.port || '3000'} in your browser
|
|
335
|
+
|
|
336
|
+
## Features
|
|
337
|
+
|
|
338
|
+
- **Primary Function**: ${formData.primaryFunction || 'General assistance'}
|
|
339
|
+
- **Personality**: ${formData.personality || 'professional'}
|
|
340
|
+
- **Model**: ${formData.model || 'claude-sonnet-4-20250514'}
|
|
341
|
+
${(formData.tools || []).length > 0 ? `- **Tools**: ${formData.tools.join(', ')}` : ''}
|
|
342
|
+
|
|
343
|
+
## Configuration
|
|
344
|
+
|
|
345
|
+
Edit the \`AGENT_CONFIG\` object in \`server.js\` to customize the agent's behavior.
|
|
346
|
+
`;
|
|
347
|
+
const envExample = `ANTHROPIC_API_KEY=your_api_key_here\nPORT=${formData.port || '3000'}`;
|
|
348
|
+
|
|
349
|
+
return handler.success(res, {
|
|
350
|
+
success: true,
|
|
351
|
+
files: {
|
|
352
|
+
'server.js': serverCode,
|
|
353
|
+
'package.json': JSON.stringify(packageJson, null, 2),
|
|
354
|
+
'README.md': readme,
|
|
355
|
+
'.env.example': envExample
|
|
356
|
+
}
|
|
357
|
+
})
|
|
358
|
+
}));
|
|
359
|
+
|
|
360
|
+
return router;
|
|
361
|
+
}
|