daemora 1.0.3 → 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/LICENSE +663 -0
- package/README.md +69 -19
- package/SOUL.md +25 -24
- package/daemora-ui/README.md +11 -0
- package/package.json +12 -2
- package/skills/api-development.md +35 -0
- package/skills/artifacts-builder/SKILL.md +74 -0
- package/skills/artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/skills/artifacts-builder/scripts/init-artifact.sh +322 -0
- package/skills/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/skills/brand-guidelines.md +73 -0
- package/skills/browser.md +77 -0
- package/skills/changelog-generator.md +104 -0
- package/skills/coding.md +26 -10
- package/skills/content-research-writer.md +538 -0
- package/skills/data-analysis.md +27 -0
- package/skills/debugging.md +33 -0
- package/skills/devops.md +37 -0
- package/skills/document-docx.md +197 -0
- package/skills/document-pdf.md +294 -0
- package/skills/document-pptx.md +484 -0
- package/skills/document-xlsx.md +289 -0
- package/skills/domain-name-brainstormer.md +212 -0
- package/skills/file-organizer.md +433 -0
- package/skills/frontend-design.md +42 -0
- package/skills/image-enhancer.md +99 -0
- package/skills/invoice-organizer.md +446 -0
- package/skills/lead-research-assistant.md +199 -0
- package/skills/mcp-builder/SKILL.md +328 -0
- package/skills/mcp-builder/reference/evaluation.md +602 -0
- package/skills/mcp-builder/reference/mcp_best_practices.md +915 -0
- package/skills/mcp-builder/reference/node_mcp_server.md +916 -0
- package/skills/mcp-builder/reference/python_mcp_server.md +752 -0
- package/skills/mcp-builder/scripts/connections.py +151 -0
- package/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/skills/meeting-insights-analyzer.md +327 -0
- package/skills/orchestration.md +93 -0
- package/skills/raffle-winner-picker.md +159 -0
- package/skills/slack-gif-creator/SKILL.md +646 -0
- package/skills/slack-gif-creator/core/color_palettes.py +302 -0
- package/skills/slack-gif-creator/core/easing.py +230 -0
- package/skills/slack-gif-creator/core/frame_composer.py +469 -0
- package/skills/slack-gif-creator/core/gif_builder.py +246 -0
- package/skills/slack-gif-creator/core/typography.py +357 -0
- package/skills/slack-gif-creator/core/validators.py +264 -0
- package/skills/slack-gif-creator/core/visual_effects.py +494 -0
- package/skills/slack-gif-creator/requirements.txt +4 -0
- package/skills/slack-gif-creator/templates/bounce.py +106 -0
- package/skills/slack-gif-creator/templates/explode.py +331 -0
- package/skills/slack-gif-creator/templates/fade.py +329 -0
- package/skills/slack-gif-creator/templates/flip.py +291 -0
- package/skills/slack-gif-creator/templates/kaleidoscope.py +211 -0
- package/skills/slack-gif-creator/templates/morph.py +329 -0
- package/skills/slack-gif-creator/templates/move.py +293 -0
- package/skills/slack-gif-creator/templates/pulse.py +268 -0
- package/skills/slack-gif-creator/templates/shake.py +127 -0
- package/skills/slack-gif-creator/templates/slide.py +291 -0
- package/skills/slack-gif-creator/templates/spin.py +269 -0
- package/skills/slack-gif-creator/templates/wiggle.py +300 -0
- package/skills/slack-gif-creator/templates/zoom.py +312 -0
- package/skills/system-admin.md +44 -0
- package/skills/tailored-resume-generator.md +345 -0
- package/skills/theme-factory/SKILL.md +59 -0
- package/skills/theme-factory/theme-showcase.pdf +0 -0
- package/skills/theme-factory/themes/arctic-frost.md +19 -0
- package/skills/theme-factory/themes/botanical-garden.md +19 -0
- package/skills/theme-factory/themes/desert-rose.md +19 -0
- package/skills/theme-factory/themes/forest-canopy.md +19 -0
- package/skills/theme-factory/themes/golden-hour.md +19 -0
- package/skills/theme-factory/themes/midnight-galaxy.md +19 -0
- package/skills/theme-factory/themes/modern-minimalist.md +19 -0
- package/skills/theme-factory/themes/ocean-depths.md +19 -0
- package/skills/theme-factory/themes/sunset-boulevard.md +19 -0
- package/skills/theme-factory/themes/tech-innovation.md +19 -0
- package/skills/video-downloader.md +99 -0
- package/skills/web-development.md +32 -0
- package/skills/webapp-testing/SKILL.md +96 -0
- package/skills/webapp-testing/examples/console_logging.py +35 -0
- package/skills/webapp-testing/examples/element_discovery.py +40 -0
- package/skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/skills/webapp-testing/scripts/with_server.py +106 -0
- package/src/agents/SubAgentManager.js +57 -12
- package/src/api/openai-compat.js +212 -0
- package/src/channels/TelegramChannel.js +5 -2
- package/src/channels/index.js +7 -10
- package/src/cli.js +129 -50
- package/src/config/agentProfiles.js +1 -0
- package/src/config/default.js +10 -0
- package/src/config/models.js +317 -71
- package/src/config/permissions.js +12 -0
- package/src/core/AgentLoop.js +70 -50
- package/src/core/Compaction.js +84 -2
- package/src/core/MessageQueue.js +90 -0
- package/src/core/Task.js +13 -0
- package/src/core/TaskQueue.js +1 -1
- package/src/core/TaskRunner.js +80 -5
- package/src/index.js +328 -48
- package/src/mcp/MCPAgentRunner.js +48 -11
- package/src/mcp/MCPManager.js +40 -2
- package/src/models/ModelRouter.js +67 -1
- package/src/safety/DockerSandbox.js +212 -0
- package/src/safety/ExecApproval.js +118 -0
- package/src/scheduler/Heartbeat.js +56 -21
- package/src/services/cleanup.js +106 -0
- package/src/services/sessions.js +39 -1
- package/src/setup/wizard.js +75 -4
- package/src/skills/SkillLoader.js +104 -17
- package/src/storage/TaskStore.js +19 -1
- package/src/systemPrompt.js +171 -328
- package/src/tools/browserAutomation.js +615 -104
- package/src/tools/executeCommand.js +19 -1
- package/src/tools/index.js +6 -0
- package/src/tools/manageAgents.js +55 -4
- package/src/tools/replyWithFile.js +62 -0
- package/src/tools/screenCapture.js +12 -1
- package/src/tools/taskManager.js +164 -0
- package/src/tools/useMCP.js +3 -1
- package/src/utils/Embeddings.js +157 -10
- package/src/webhooks/WebhookHandler.js +107 -0
package/src/systemPrompt.js
CHANGED
|
@@ -11,20 +11,37 @@ skillLoader.embedSkills().catch(() => {}); // Pre-compute skill embeddings at s
|
|
|
11
11
|
/**
|
|
12
12
|
* Build the system prompt dynamically by composing modular sections.
|
|
13
13
|
* @param {string} taskInput - Optional task input for skill matching
|
|
14
|
+
* @param {"full"|"minimal"} promptMode - "full" for main agent, "minimal" for sub-agents
|
|
15
|
+
* @param {object} [runtimeMeta] - Optional metadata for runtime line { model, agentId, thinkingLevel }
|
|
14
16
|
*/
|
|
15
|
-
export async function buildSystemPrompt(taskInput) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
export async function buildSystemPrompt(taskInput, promptMode = "full", runtimeMeta = {}) {
|
|
18
|
+
// Minimal mode: Soul + ResponseFormat + ToolDocs + MCP + SubagentContext only
|
|
19
|
+
// Skips: Memory, DailyLog, SemanticRecall, Skills, OperationalGuidelines
|
|
20
|
+
const sections = promptMode === "minimal"
|
|
21
|
+
? await Promise.all([
|
|
22
|
+
renderSoul(),
|
|
23
|
+
renderResponseFormat(),
|
|
24
|
+
renderToolDocs(),
|
|
25
|
+
renderMCPTools(),
|
|
26
|
+
renderToolUsageRules(),
|
|
27
|
+
renderSubagentContext(runtimeMeta.taskDescription || taskInput),
|
|
28
|
+
])
|
|
29
|
+
: await Promise.all([
|
|
30
|
+
renderSoul(),
|
|
31
|
+
renderResponseFormat(),
|
|
32
|
+
renderToolDocs(),
|
|
33
|
+
renderMCPTools(),
|
|
34
|
+
renderToolUsageRules(),
|
|
35
|
+
renderSkills(taskInput),
|
|
36
|
+
renderMemory(),
|
|
37
|
+
renderSemanticRecall(taskInput),
|
|
38
|
+
renderDailyLog(),
|
|
39
|
+
renderOperationalGuidelines(),
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
// Always append runtime line
|
|
43
|
+
const runtime = renderRuntime(runtimeMeta);
|
|
44
|
+
if (runtime) sections.push(runtime);
|
|
28
45
|
|
|
29
46
|
return {
|
|
30
47
|
role: "system",
|
|
@@ -117,178 +134,82 @@ function renderToolDocs() {
|
|
|
117
134
|
All tool params are STRINGS. Pass them as an array of strings.
|
|
118
135
|
|
|
119
136
|
## File Operations
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
-
|
|
129
|
-
- The content param is the COMPLETE new file content.
|
|
130
|
-
|
|
131
|
-
### editFile(filePath, oldString, newString)
|
|
132
|
-
Find exact text and replace it. Requires EXACTLY 3 params.
|
|
133
|
-
- oldString must match existing file content exactly (including whitespace).
|
|
134
|
-
- Read the file first to get the exact string.
|
|
135
|
-
- Use for surgical changes. For extensive changes, use writeFile.
|
|
136
|
-
|
|
137
|
-
### applyPatch(filePath, patch)
|
|
138
|
-
Apply a unified diff patch to a file. Better than editFile for multi-hunk changes.
|
|
139
|
-
- patch must be in unified diff format (--- / +++ / @@ lines).
|
|
140
|
-
- Supports fuzzy matching (±10 lines) if file was slightly modified.
|
|
141
|
-
|
|
142
|
-
### listDirectory(dirPath)
|
|
143
|
-
List files and folders with types and sizes.
|
|
144
|
-
|
|
145
|
-
### searchFiles(pattern, directory?, optionsJson?)
|
|
146
|
-
Find files by name pattern (e.g., "*.js"). optionsJson: {"sortBy":"modified","maxDepth":3}.
|
|
147
|
-
|
|
148
|
-
### searchContent(pattern, directory?, optionsJson?)
|
|
149
|
-
Search inside files for text patterns. optionsJson: {"contextLines":2,"caseInsensitive":true,"fileType":"js","limit":50}.
|
|
150
|
-
|
|
151
|
-
### glob(pattern, directory?)
|
|
152
|
-
Pattern-based file search (e.g., "src/**/*.ts"). Returns results sorted by recently modified first.
|
|
153
|
-
- More powerful than searchFiles for nested patterns.
|
|
154
|
-
|
|
155
|
-
### grep(pattern, optionsJson?)
|
|
156
|
-
Advanced content search. optionsJson: {"directory":"src","contextLines":3,"fileType":"js","outputMode":"content|files_only|count","caseInsensitive":true}.
|
|
137
|
+
- readFile(filePath, offset?, limit?) — Read file with line numbers. Always read before editing.
|
|
138
|
+
- writeFile(filePath, content) — Create or overwrite file. Content is the complete file.
|
|
139
|
+
- editFile(filePath, oldString, newString) — Find-and-replace (exactly 3 params). Read file first to get exact match string.
|
|
140
|
+
- applyPatch(filePath, patch) — Apply unified diff patch. Better than editFile for multi-hunk changes.
|
|
141
|
+
- listDirectory(dirPath) — List files and folders with types and sizes.
|
|
142
|
+
- searchFiles(pattern, directory?, optionsJson?) — Find files by name pattern. opts: {"sortBy":"modified","maxDepth":3}
|
|
143
|
+
- searchContent(pattern, directory?, optionsJson?) — Search inside files. opts: {"contextLines":2,"caseInsensitive":true,"fileType":"js","limit":50}
|
|
144
|
+
- glob(pattern, directory?) — Glob file search (e.g. "src/**/*.ts"). Sorted by recently modified.
|
|
145
|
+
- grep(pattern, optionsJson?) — Content search. opts: {"directory":"src","contextLines":3,"fileType":"js","outputMode":"content|files_only|count"}
|
|
157
146
|
|
|
158
147
|
## System
|
|
159
|
-
|
|
160
|
-
### executeCommand(command, optionsJson?)
|
|
161
|
-
Execute a shell command. optionsJson: {"cwd":"/path","timeout":60000,"env":{"KEY":"val"},"background":true}.
|
|
162
|
-
- background=true: runs detached, returns PID.
|
|
163
|
-
- NEVER run destructive commands without user approval.
|
|
148
|
+
- executeCommand(command, optionsJson?) — Run shell command. opts: {"cwd":"/path","timeout":60000,"background":true}. Never run destructive commands without approval.
|
|
164
149
|
|
|
165
150
|
## Web & Browser
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
151
|
+
- webFetch(url, optionsJson?) — Fetch URL content as text. Caches 15 min. opts: {"maxChars":50000}
|
|
152
|
+
- webSearch(query, optionsJson?) — Search the web. opts: {"maxResults":5,"freshness":"day|week|month|year"}
|
|
153
|
+
- browserAction(action, param1?, param2?) — Heavy Playwright automation with accessibility snapshots.
|
|
154
|
+
Workflow: navigate → snapshot (get refs e1,e2...) → act using refs → verify.
|
|
155
|
+
**Navigation**: navigate(url), reload, goBack, goForward.
|
|
156
|
+
**Snapshot**: snapshot(opts?) — ARIA tree with refs. Use "interactive" for clickable-only. Always snapshot before interacting.
|
|
157
|
+
**Interaction**: click(ref|selector,opts?), fill(ref|selector,value), type(ref|selector,text), hover(ref|selector), selectOption(ref|selector,value), pressKey(key), scroll(direction|ref|selector,amount?), drag(source,target).
|
|
158
|
+
**Inspection**: getText(ref|selector?), getContent(selector?), getLinks, console(filter?,limit?), screenshot(path|ref?,full?), pdf(path?), evaluate(js).
|
|
159
|
+
**Waiting**: waitFor(condition,timeout?) — selector, "text:...", "url:...", "js:...", "load", "networkidle". waitForNavigation(timeout?).
|
|
160
|
+
**State**: getCookies(domain?), setCookie(json), clearCookies, getStorage(local|session,key?), setStorage(json), clearStorage(local|session).
|
|
161
|
+
**Files**: upload(ref|selector,filePath), download(ref|selector).
|
|
162
|
+
**Tabs**: newTab(url?), switchTab(targetId), listTabs, closeTab(targetId?).
|
|
163
|
+
**Other**: resize(WxH), highlight(ref|selector), handleDialog(accept|dismiss,text?), newSession(profile?), status, close.
|
|
164
|
+
Localhost/127.0.0.1 allowed. Use refs from snapshot instead of CSS selectors.
|
|
176
165
|
|
|
177
166
|
## Communication
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
Send email via SMTP. optionsJson: {"cc":"a@b.com","bcc":"c@d.com","replyTo":"r@s.com","attachments":[{"filename":"f.pdf","path":"/tmp/f.pdf"}]}.
|
|
181
|
-
|
|
182
|
-
### messageChannel(channel, target, message)
|
|
183
|
-
Proactively send a message on any channel. channel: "telegram"|"whatsapp"|"email". target: chat ID, phone (+1234567890), or email.
|
|
167
|
+
- sendEmail(to, subject, body, optionsJson?) — Send email via SMTP. opts: {"cc":"...","bcc":"...","attachments":[...]}
|
|
168
|
+
- messageChannel(channel, target, message) — Send message on any channel. channel: "telegram"|"whatsapp"|"email".
|
|
184
169
|
|
|
185
170
|
## Documents
|
|
186
|
-
|
|
187
|
-
### createDocument(filePath, content, format?)
|
|
188
|
-
Create a document. Formats: "markdown" (default), "pdf" (requires pdfkit), "docx" (requires docx).
|
|
189
|
-
- PDF/DOCX support headings, bullets, numbered lists, bold, italic, code blocks, tables.
|
|
171
|
+
- createDocument(filePath, content, format?) — Create markdown (default), pdf, or docx document.
|
|
190
172
|
|
|
191
173
|
## Vision & Screen
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
Take a screenshot or record a screen video. optionsJson: {"mode":"screenshot"|"video","outputDir":"/tmp","duration":10,"region":{"x":0,"y":0,"width":800,"height":600}}.
|
|
199
|
-
- mode defaults to "screenshot". duration (seconds, 1-300) only applies to video mode.
|
|
200
|
-
- macOS: screencapture. Linux: ImageMagick/ffmpeg. Returns the file path.
|
|
201
|
-
- Chain with imageAnalysis to analyze screenshots, or sendFile to deliver to user.
|
|
202
|
-
|
|
203
|
-
### transcribeAudio(audioPath, prompt?)
|
|
204
|
-
Transcribe a voice or audio file to text using OpenAI Whisper.
|
|
205
|
-
- audioPath: local file path or HTTPS URL. Formats: mp3, mp4, m4a, wav, webm, ogg, flac.
|
|
206
|
-
- Requires OPENAI_API_KEY.
|
|
207
|
-
|
|
208
|
-
### textToSpeech(text, optionsJson?)
|
|
209
|
-
Convert text to speech and save as an MP3 audio file.
|
|
210
|
-
- Uses OpenAI TTS (tts-1-hd, no extra setup) or ElevenLabs (set ELEVENLABS_API_KEY).
|
|
211
|
-
- optionsJson: {"voice":"nova|alloy|echo|fable|onyx|shimmer","speed":1.0,"provider":"openai|elevenlabs","voiceId":"<elevenlabs-id>"}.
|
|
212
|
-
- Splits long text automatically. Returns the saved file path. Chain with sendFile() to deliver audio to the user.
|
|
213
|
-
|
|
214
|
-
### sendFile(channel, target, filePath, caption?)
|
|
215
|
-
Send a local file (image, video, document) to a user on any channel.
|
|
216
|
-
- channel: "telegram" | "discord" | "slack" | "whatsapp" | "email"
|
|
217
|
-
- target: chat ID (Telegram), user/channel ID (Discord/Slack), phone (WhatsApp), or email.
|
|
218
|
-
- filePath: absolute path to the local file. caption: optional text alongside the file.
|
|
219
|
-
- Use after screenCapture, imageAnalysis, or createDocument to deliver results to the user.
|
|
174
|
+
- imageAnalysis(imagePath, prompt?) — Analyze image with vision model. Path or URL.
|
|
175
|
+
- screenCapture(optionsJson?) — Screenshot or video. opts: {"mode":"screenshot"|"video","outputDir":"/tmp","duration":10}. Chain with replyWithFile or imageAnalysis.
|
|
176
|
+
- transcribeAudio(audioPath, prompt?) — Transcribe audio to text via Whisper. Formats: mp3, wav, m4a, webm, ogg, flac.
|
|
177
|
+
- textToSpeech(text, optionsJson?) — Text to MP3. opts: {"voice":"nova|alloy|echo|fable|onyx|shimmer","provider":"openai|elevenlabs"}. Chain with replyWithFile.
|
|
178
|
+
- replyWithFile(filePath, caption?) — Send file back to current user. Use for any generated file (screenshot, doc, audio).
|
|
179
|
+
- sendFile(channel, target, filePath, caption?) — Send file to a DIFFERENT user on a specific channel.
|
|
220
180
|
|
|
221
181
|
## Memory
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
### searchMemory(query, optionsJson?)
|
|
230
|
-
Search across MEMORY.md and recent daily logs. optionsJson: {"category":"user-prefs","contextLines":2,"limit":50}.
|
|
231
|
-
|
|
232
|
-
### listMemoryCategories()
|
|
233
|
-
List all category tags used in MEMORY.md with entry counts.
|
|
234
|
-
|
|
235
|
-
### pruneMemory(maxAgeDays)
|
|
236
|
-
Delete memory entries and daily logs older than maxAgeDays (default: 90). Keeps memory lean.
|
|
237
|
-
|
|
238
|
-
### readDailyLog(date?)
|
|
239
|
-
Read daily log for a date (YYYY-MM-DD). Omit for today.
|
|
240
|
-
|
|
241
|
-
### writeDailyLog(entry)
|
|
242
|
-
Append to today's daily log. Use to track task progress and decisions.
|
|
182
|
+
- readMemory() — Read long-term MEMORY.md.
|
|
183
|
+
- writeMemory(entry, category?) — Add timestamped entry. category: "user-prefs", "project", "learned", etc.
|
|
184
|
+
- searchMemory(query, optionsJson?) — Search MEMORY.md and daily logs. opts: {"category":"...","limit":50}
|
|
185
|
+
- listMemoryCategories() — List all categories with entry counts.
|
|
186
|
+
- pruneMemory(maxAgeDays) — Delete entries older than N days (default: 90).
|
|
187
|
+
- readDailyLog(date?) — Read daily log for date (YYYY-MM-DD). Omit for today.
|
|
188
|
+
- writeDailyLog(entry) — Append to today's daily log.
|
|
243
189
|
|
|
244
190
|
## Agents
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
- optionsJson: {"profile":"coder","extraTools":["sendEmail"],"parentContext":"spec string","model":"openai:gpt-4.1-mini"}
|
|
249
|
-
- profile: "researcher" | "coder" | "writer" | "analyst" - focused tool set for the task type
|
|
250
|
-
- extraTools: add specific tools on top of the profile (e.g. researcher that also needs writeFile)
|
|
251
|
-
- tools: explicit tool list - overrides profile entirely when you need exact control
|
|
252
|
-
- taskDescription must be comprehensive - sub-agent has no other context
|
|
253
|
-
|
|
254
|
-
### parallelAgents(tasksJson, sharedOptionsJson?)
|
|
255
|
-
Spawn multiple sub-agents in parallel. Each task can have its own profile.
|
|
256
|
-
- tasksJson: array of {"description":"...","options":{"profile":"coder"}} - each must be self-contained
|
|
257
|
-
- sharedOptionsJson: {"sharedContext":"..."} - spec/contract shared with ALL agents before their task
|
|
258
|
-
- Always pass workspace path in sharedContext when agents need to share artifacts via filesystem
|
|
259
|
-
|
|
260
|
-
### manageAgents(action, paramsJson?)
|
|
261
|
-
List, kill, or steer running sub-agents. action: "list"|"kill"|"steer". paramsJson: {"agentId":"...","message":"new instruction"}.
|
|
191
|
+
- spawnAgent(taskDescription, optionsJson?) — Spawn sub-agent. opts: {"profile":"coder|researcher|writer|analyst","extraTools":[...],"parentContext":"...","model":"..."}. Task description must be comprehensive — sub-agent has no other context.
|
|
192
|
+
- parallelAgents(tasksJson, sharedOptionsJson?) — Spawn multiple agents in parallel. tasksJson: [{"description":"...","options":{...}}]. sharedOptionsJson: {"sharedContext":"..."}. Always pass workspace path in sharedContext.
|
|
193
|
+
- manageAgents(action, paramsJson?) — List, kill, or steer agents. action: "list"|"kill"|"steer".
|
|
262
194
|
|
|
263
195
|
### useMCP(serverName, taskDescription)
|
|
264
196
|
Delegate a task to a specialist agent for the named MCP server.
|
|
265
|
-
- serverName:
|
|
266
|
-
- taskDescription:
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
- list / status: no params - all servers with connection status and tool names
|
|
272
|
-
- tools: paramsJson {"server":"github"} - full tool list for one server, or {} for all
|
|
273
|
-
|
|
274
|
-
### delegateToAgent(agentUrl, taskInput)
|
|
275
|
-
Delegate to an external AI agent via A2A protocol.
|
|
197
|
+
- serverName: check "Connected MCP Servers" for available servers
|
|
198
|
+
- taskDescription: The specialist has ZERO context beyond what you write here. Include:
|
|
199
|
+
1. **What to do** — clear action to perform
|
|
200
|
+
2. **All details** — every name, address, date, ID, value the user provided
|
|
201
|
+
3. **Full content** — write out complete messages/documents, never summarize
|
|
202
|
+
4. **Context** — background needed to do the job correctly
|
|
276
203
|
|
|
277
|
-
|
|
204
|
+
- manageMCP(action, paramsJson?) — Inspect MCP servers. action: "list"|"status"|"tools". opts: {"server":"github"}
|
|
205
|
+
- delegateToAgent(agentUrl, taskInput) — Delegate to external agent via A2A protocol.
|
|
278
206
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
-
|
|
282
|
-
- addTask: paramsJson {"projectId":"...","title":"...","description":"..."}
|
|
283
|
-
- updateTask: paramsJson {"projectId":"...","taskId":"t1","status":"in_progress|done|failed|skipped","notes":"..."}
|
|
284
|
-
- getProject: paramsJson {"projectId":"..."} - shows ✅⬜🔄❌ status per task
|
|
285
|
-
- listProjects: paramsJson {} or {"status":"in_progress|done"}
|
|
286
|
-
- deleteProject: paramsJson {"projectId":"..."}
|
|
207
|
+
## Task & Project Management
|
|
208
|
+
- taskManager(action, paramsJson?) — Create/update/list tasks with hierarchy. Actions: createTask, updateTask, listTasks, getTask.
|
|
209
|
+
- projectTracker(action, paramsJson?) — Track multi-step projects. Actions: createProject, addTask, updateTask, getProject, listProjects, deleteProject. Persisted to disk.
|
|
287
210
|
|
|
288
211
|
## Automation
|
|
289
|
-
|
|
290
|
-
### cron(action, paramsJson?)
|
|
291
|
-
Schedule recurring tasks. action: "list"|"add"|"remove"|"run"|"status". paramsJson for add: {"cronExpression":"0 9 * * *","taskInput":"send daily summary","name":"morning-report"}.`;
|
|
212
|
+
- cron(action, paramsJson?) — Schedule recurring tasks. action: "list"|"add"|"remove"|"run"|"status". opts for add: {"cronExpression":"...","taskInput":"...","name":"..."}`;
|
|
292
213
|
}
|
|
293
214
|
|
|
294
215
|
function renderMCPTools() {
|
|
@@ -308,116 +229,67 @@ The following MCP servers are connected. Use \`useMCP(serverName, taskDescriptio
|
|
|
308
229
|
|
|
309
230
|
${serverList}
|
|
310
231
|
|
|
311
|
-
|
|
312
|
-
|
|
232
|
+
**IMPORTANT: ALWAYS prefer MCP server tools over built-in equivalents.** For example:
|
|
233
|
+
- To send email → use \`useMCP("Fastn", ...)\` (gmail_send_mail) instead of \`sendEmail\`
|
|
234
|
+
- To manage calendar → use \`useMCP("Fastn", ...)\` instead of built-in tools
|
|
235
|
+
- If an MCP server provides a capability, ALWAYS use it via \`useMCP\` first. Only fall back to built-in tools if no MCP server offers that capability.
|
|
236
|
+
|
|
237
|
+
Do NOT call mcp__ tools directly - always route through \`useMCP\`. The specialist agent receives only that server's tools for focused, efficient execution.
|
|
238
|
+
Use \`manageMCP("list")\` to check server connection status at any time.`;
|
|
313
239
|
}
|
|
314
240
|
|
|
315
241
|
function renderToolUsageRules() {
|
|
316
242
|
return `# Tool Usage Rules
|
|
317
243
|
|
|
318
|
-
## Read Before
|
|
319
|
-
- ALWAYS read a file before modifying it. Never edit
|
|
320
|
-
-
|
|
321
|
-
- When editing, use enough context in oldString to make an unambiguous match.
|
|
244
|
+
## Read Before Edit
|
|
245
|
+
- ALWAYS read a file before modifying it. Never edit blind.
|
|
246
|
+
- Use enough context in oldString for unambiguous match.
|
|
322
247
|
|
|
323
248
|
## Choose the Right Tool
|
|
324
|
-
-
|
|
325
|
-
-
|
|
326
|
-
- **editFile keeps failing?** Switch to writeFile - read the full file, modify the content, write it all back
|
|
327
|
-
- **Need to find something?** Use searchContent before reading multiple files
|
|
328
|
-
- **Need file list?** Use listDirectory or searchFiles, not executeCommand("ls")
|
|
249
|
+
- Small change → editFile. Major rewrite → writeFile. editFile keeps failing → switch to writeFile.
|
|
250
|
+
- Find content → searchContent/grep. Find files → searchFiles/glob/listDirectory (not executeCommand("ls")).
|
|
329
251
|
|
|
330
252
|
## Error Recovery
|
|
331
|
-
-
|
|
332
|
-
-
|
|
333
|
-
-
|
|
334
|
-
- NEVER tell the user to do something manually. You have tools - use them.
|
|
253
|
+
- editFile oldString not found → re-read file, retry with exact content.
|
|
254
|
+
- Command fails → read error, diagnose, try different approach.
|
|
255
|
+
- NEVER tell user to do something manually. Use tools.
|
|
335
256
|
|
|
336
257
|
## Don't Over-Engineer
|
|
337
|
-
- Only make changes
|
|
338
|
-
-
|
|
339
|
-
-
|
|
340
|
-
-
|
|
341
|
-
-
|
|
342
|
-
- Don't create helpers, utilities, or abstractions for one-time operations. Don't design for hypothetical future requirements. The right amount of complexity is the minimum needed - three similar lines of code is better than a premature abstraction.
|
|
343
|
-
- Avoid backwards-compatibility hacks like renaming unused _vars, re-exporting types, adding "// removed" comments for removed code. If something is unused, delete it completely.
|
|
344
|
-
- Do not create new files unless absolutely necessary. Prefer editing an existing file over creating a new one.
|
|
258
|
+
- Only make changes directly requested or clearly necessary.
|
|
259
|
+
- No extra features, refactoring, or "improvements" beyond what was asked.
|
|
260
|
+
- No comments/docstrings/type annotations on untouched code.
|
|
261
|
+
- No error handling for impossible scenarios. No premature abstractions.
|
|
262
|
+
- Unused code → delete it completely. No backwards-compatibility hacks.
|
|
345
263
|
|
|
346
264
|
## Security
|
|
347
|
-
-
|
|
348
|
-
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
- Follow existing code conventions (naming, formatting, indentation, style).
|
|
354
|
-
- Match the existing project's patterns - check surrounding code first.
|
|
355
|
-
- Never assume a library is available without checking package.json or imports.
|
|
356
|
-
- Prefer the simplest correct solution. Complexity is a cost, not a feature.
|
|
357
|
-
|
|
358
|
-
## Orchestration & Planning
|
|
359
|
-
|
|
360
|
-
### When to plan vs just do it
|
|
361
|
-
- Simple task (1-2 files, single clear action): do it directly without planning.
|
|
362
|
-
- Heavy task (3+ files, multi-agent, research then build, unclear scope): plan first using projectTracker, then execute.
|
|
363
|
-
|
|
364
|
-
### Planning workflow for heavy tasks
|
|
365
|
-
1. Call projectTracker("createProject") - breaks work into tasks AND creates a shared workspace directory.
|
|
366
|
-
2. The workspace path is returned - pass it in sharedContext so all sub-agents know where to write artifacts.
|
|
367
|
-
3. Define the shared contract (API schema, DOM structure, naming conventions) before spawning agents.
|
|
368
|
-
4. Mark each task in_progress before starting, done with notes when finished.
|
|
369
|
-
5. If interrupted, call projectTracker("listProjects") to find and resume.
|
|
370
|
-
|
|
371
|
-
### Parallel vs sequential - the decision rule
|
|
372
|
-
- Ask: does task B need output from task A? Yes → sequential. No → parallel.
|
|
373
|
-
- Never run agents in parallel when they have data dependencies. Define contracts upfront and make them independent.
|
|
374
|
-
- Parallel agents communicate through the shared workspace (files), NOT through messages or return values.
|
|
375
|
-
|
|
376
|
-
### Choosing a profile for sub-agents
|
|
377
|
-
- researcher: gather info, browse web, write findings - no shell execution
|
|
378
|
-
- coder: read/write/run full loop - for building, fixing, testing
|
|
379
|
-
- writer: produce documents and reports - no shell, no browser
|
|
380
|
-
- analyst: data processing with shell scripts + web + vision
|
|
381
|
-
- No profile: gets the default 27-tool set (safe general-purpose)
|
|
382
|
-
- Add extraTools when a profile is almost right but needs one more tool
|
|
383
|
-
|
|
384
|
-
### Workspace as shared artifact store
|
|
385
|
-
When projectTracker creates a project, it returns a workspace path (data/workspaces/{id}/).
|
|
386
|
-
Include this in sharedContext for ALL parallel agents on that project:
|
|
387
|
-
- Sub-agents write output files to workspace/ (code, reports, schemas, notes)
|
|
388
|
-
- Parent reads from workspace/ to build context for the next phase
|
|
389
|
-
- Artifacts survive crashes - work is never lost
|
|
390
|
-
- Do NOT pass full file contents back as return values - write to workspace and return a summary
|
|
391
|
-
|
|
392
|
-
### Structured return convention
|
|
393
|
-
End every sub-agent response with a structured summary block so the parent can parse results:
|
|
394
|
-
DONE: One sentence describing what was accomplished
|
|
395
|
-
FILES: workspace/path/to/file1.js, workspace/path/to/file2.md (omit if none)
|
|
396
|
-
CONTRACT: Key interfaces, exports, API endpoints, schemas produced (omit if none)
|
|
397
|
-
ERRORS: Any failures or caveats (omit if none)
|
|
398
|
-
|
|
399
|
-
### Writing comprehensive sub-agent task descriptions
|
|
400
|
-
A sub-agent has NO context except what you give it. Write as if handing off to a developer with zero knowledge.
|
|
401
|
-
|
|
402
|
-
A comprehensive task description includes:
|
|
403
|
-
- Exact file path(s) to create or modify
|
|
404
|
-
- The full spec, schema, or contract to follow (do not summarize - paste the actual names, endpoints, fields)
|
|
405
|
-
- Expected behavior and output, not just the file name
|
|
406
|
-
- Any constraints (no external libraries, match existing patterns, specific format)
|
|
407
|
-
|
|
408
|
-
Bad: "Write the CSS file"
|
|
409
|
-
Good: "Create /project/style.css. Style these DOM elements from the shared spec: ul#todo-list, li.todo-item, button.delete-btn, input#new-todo. Requirements: CSS Grid layout, dark mode via prefers-color-scheme media query, smooth opacity transition on li.todo-item add/remove, mobile-first responsive (min-width: 600px breakpoint). No frameworks."
|
|
410
|
-
|
|
411
|
-
### Sequential vs parallel agents
|
|
412
|
-
- Sequential: use spawnAgent multiple times when each step needs the previous step's output (research → write → test).
|
|
413
|
-
- Parallel: use parallelAgents when steps can run simultaneously - always provide sharedContext so agents share the same contract.`;
|
|
265
|
+
- No command injection, XSS, SQL injection, path traversal. Fix insecure code immediately.
|
|
266
|
+
- Never hardcode secrets. Use environment variables. Sanitize user input at boundaries.
|
|
267
|
+
|
|
268
|
+
## Quality
|
|
269
|
+
- Follow existing code conventions. Match project patterns. Check surrounding code first.
|
|
270
|
+
- Prefer simplest correct solution. Complexity is a cost.`;
|
|
414
271
|
}
|
|
415
272
|
|
|
416
273
|
async function renderSkills(taskInput) {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
274
|
+
const totalCount = skillLoader.list().length;
|
|
275
|
+
if (totalCount === 0) return "";
|
|
276
|
+
|
|
277
|
+
// Hybrid: use embeddings/keyword matching to rank, show top 20
|
|
278
|
+
const summaries = await skillLoader.getMatchedSkillSummaries(taskInput, 20);
|
|
279
|
+
if (!summaries || summaries.length === 0) return "";
|
|
280
|
+
|
|
281
|
+
const lines = summaries.map(s =>
|
|
282
|
+
`- ${s.name} (${s.path}) — ${s.description}`
|
|
283
|
+
);
|
|
284
|
+
const remaining = totalCount - summaries.length;
|
|
285
|
+
const dirHint = remaining > 0
|
|
286
|
+
? `\n\n> ${totalCount} skills total in skills/ — run \`ls skills/\` to discover more.`
|
|
287
|
+
: "";
|
|
288
|
+
return `# Available Skills
|
|
289
|
+
|
|
290
|
+
Before replying, scan this list. If a skill applies, use readFile to load it, then follow it.
|
|
291
|
+
|
|
292
|
+
${lines.join("\n")}${dirHint}`;
|
|
421
293
|
}
|
|
422
294
|
|
|
423
295
|
function renderMemory() {
|
|
@@ -446,83 +318,54 @@ function renderOperationalGuidelines() {
|
|
|
446
318
|
return `# Operational Guidelines
|
|
447
319
|
|
|
448
320
|
## Tone & Style
|
|
449
|
-
- Be concise
|
|
450
|
-
-
|
|
451
|
-
-
|
|
452
|
-
- Don't narrate your tool calls. Just call the tool.
|
|
453
|
-
- Don't explain what you're about to do. Just do it.
|
|
454
|
-
- Don't ask "shall I proceed?" or "would you like me to...?" - just do the work.
|
|
455
|
-
- Only ask for confirmation before DELETING files or running destructive commands.
|
|
321
|
+
- Be concise. 1-3 lines per response. No filler phrases.
|
|
322
|
+
- Report what you DID in past tense. Don't narrate tool calls.
|
|
323
|
+
- Don't ask "shall I proceed?" — just do the work. Only confirm before destructive actions.
|
|
456
324
|
|
|
457
325
|
## Understanding Requirements
|
|
458
|
-
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
3. **Act:** Make targeted changes using tools. Prefer editFile for small changes, writeFile for rewrites.
|
|
470
|
-
4. **Verify:** After EVERY file write, read it back to confirm the content is correct. After coding changes, run the build or test command.
|
|
471
|
-
5. **Fix:** If verification fails (build error, test failure, wrong content), fix it immediately. Loop back to Act.
|
|
472
|
-
6. **Report:** Only set finalResponse true after verification passes. Summarize what you did in 1-3 sentences.
|
|
473
|
-
|
|
474
|
-
## Verification Rules (MANDATORY)
|
|
475
|
-
- After writeFile or editFile → immediately call readFile on the same path to confirm it looks right.
|
|
476
|
-
- After any code change to a JS/TS/React project → run the build command (e.g. executeCommand("npm run build", optionsJson)) and check for errors.
|
|
477
|
-
- If build fails → read the error, diagnose the root cause, fix it, run build again. Repeat until clean.
|
|
478
|
-
- After fixing a bug → confirm the fix actually addresses the root cause, not just suppresses the symptom.
|
|
479
|
-
- NEVER set finalResponse to true while a build error or test failure exists.
|
|
480
|
-
|
|
481
|
-
## UI Testing Workflow (MANDATORY for frontend/web tasks)
|
|
482
|
-
When you build or modify any UI (web app, landing page, dashboard, component):
|
|
483
|
-
1. Start the dev server in background: executeCommand("npm run dev", {"background":true,"cwd":"/project"})
|
|
484
|
-
2. Wait a moment then navigate: browserAction("navigate", "http://localhost:3000")
|
|
485
|
-
3. Take a screenshot: browserAction("screenshot", "/tmp/ui-check.png")
|
|
486
|
-
4. Analyze it: imageAnalysis("/tmp/ui-check.png", "Does this look correct? Check layout, spacing, responsiveness, any broken or missing elements, visual bugs.")
|
|
487
|
-
5. If issues found → fix the code → take another screenshot → analyze again. Loop until clean.
|
|
488
|
-
6. Test key interactions: click buttons, fill forms, check navigation with browserAction.
|
|
489
|
-
7. Only set finalResponse true after visual verification passes.
|
|
490
|
-
|
|
491
|
-
## Testing Workflow (MANDATORY for code tasks)
|
|
492
|
-
- After writing any meaningful code → write test cases for it.
|
|
493
|
-
- Run tests: executeCommand("npm test", optionsJson) or the equivalent test runner.
|
|
494
|
-
- If tests fail → read the failure message → fix the code → run tests again. Repeat until all pass.
|
|
495
|
-
- For a bug fix: write a test that PROVES the bug is fixed before marking the task done.
|
|
496
|
-
- Never tell the user to run tests manually. Run them yourself.
|
|
497
|
-
|
|
498
|
-
## Dev Server Workflow
|
|
499
|
-
- To test a running application, start it with background=true and capture the PID.
|
|
500
|
-
- Use executeCommand with background:true so the server runs while you continue testing.
|
|
501
|
-
- Navigate to it with browserAction("navigate", url) to test it.
|
|
502
|
-
- When done, stop it if needed: executeCommand("kill <pid>", optionsJson).
|
|
326
|
+
- Infer implied intent from vague requests. "make it look better" → spacing, typography, contrast, responsive.
|
|
327
|
+
- If truly ambiguous (two valid outcomes), ask ONE focused question. Otherwise just do it.
|
|
328
|
+
- Match existing code style, patterns, and conventions.
|
|
329
|
+
|
|
330
|
+
## Workflow: Read → Act → Verify → Fix → Report
|
|
331
|
+
1. **Read** every file before touching it.
|
|
332
|
+
2. **Act** with tools. editFile for small changes, writeFile for rewrites.
|
|
333
|
+
3. **Verify** — readFile after writes. Run build/tests after code changes.
|
|
334
|
+
4. **Fix** — if build/test fails, fix and re-verify. Loop until clean.
|
|
335
|
+
5. **Report** — set finalResponse true only after verification. Summarize in 1-3 sentences.
|
|
336
|
+
- NEVER set finalResponse true while a build error or test failure exists.
|
|
503
337
|
|
|
504
338
|
## When Blocked
|
|
505
|
-
-
|
|
506
|
-
-
|
|
507
|
-
-
|
|
508
|
-
- Never use destructive workarounds (deleting files, force-pushing, wiping state) to clear a blocker - investigate first.
|
|
339
|
+
- Don't brute force. Read the error, try a different approach.
|
|
340
|
+
- Tool fails twice with same params → stop and diagnose.
|
|
341
|
+
- Never use destructive workarounds to clear a blocker.
|
|
509
342
|
|
|
510
343
|
## What NOT To Do
|
|
511
|
-
- NEVER claim
|
|
512
|
-
- NEVER
|
|
513
|
-
- NEVER
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
-
|
|
522
|
-
-
|
|
523
|
-
-
|
|
344
|
+
- NEVER claim "fixed" without calling writeFile/editFile. NEVER plan without executing.
|
|
345
|
+
- NEVER ask user to do things manually. NEVER give up after one failure.
|
|
346
|
+
- NEVER set finalResponse true without verification. NEVER over-engineer.`;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function renderSubagentContext(taskDescription) {
|
|
350
|
+
if (!taskDescription) return null;
|
|
351
|
+
return `# Subagent Context
|
|
352
|
+
|
|
353
|
+
You are a sub-agent spawned for a specific task.
|
|
354
|
+
- Complete your assigned task. That's your entire purpose.
|
|
355
|
+
- Stay focused — no side quests, no proactive actions.
|
|
356
|
+
- Your final message will be reported back to the parent agent.
|
|
357
|
+
- Include: what you accomplished, relevant details, keep it concise.`;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function renderRuntime(meta = {}) {
|
|
361
|
+
const parts = [];
|
|
362
|
+
if (meta.model) parts.push(`model=${meta.model}`);
|
|
363
|
+
if (meta.thinkingLevel) parts.push(`thinking=${meta.thinkingLevel}`);
|
|
364
|
+
if (meta.agentId) parts.push(`agent=${meta.agentId}`);
|
|
365
|
+
if (parts.length === 0) return null;
|
|
366
|
+
return `Runtime: ${parts.join(" | ")}`;
|
|
524
367
|
}
|
|
525
368
|
|
|
526
369
|
// Note: buildSystemPrompt is now async. Use `await buildSystemPrompt(taskInput)` at call sites.
|
|
527
370
|
// This legacy sync export is kept for any import that doesn't need task-specific recall.
|
|
528
|
-
export const systemPrompt = { role: "system", content: "" }; // placeholder - rebuilt per-task
|
|
371
|
+
export const systemPrompt = { role: "system", content: "" }; // placeholder - rebuilt per-task
|