Skip to content

Commit 480c37b

Browse files
committed
feat(pilot): workflow-driven AI agent for MCP Mesh
Pilot is an event-driven workflow executor that serves as the central AI brain for the MCP ecosystem. Key features: - Event-driven: Subscribes to user.message.received, publishes agent.response.* - Workflow-based: Declarative JSON workflows define execution patterns - Full mesh access: Uses all connected MCPs as tools - MCP Tasks protocol: Persistent task tracking and status - Conversation support: Long-running threads with memory Built-in workflows: - fast-router: Routes to direct response, tool call, or async workflow - conversation: Long-running conversation with history - direct-execution: Execute with all tools, no routing - execute-multi-step: Complex multi-step tasks MCP Tools: - WORKFLOW_START, MESSAGE, CONVERSATION_START/END - TASK_GET, TASK_RESULT, TASK_LIST, TASK_CANCEL - WORKFLOW_LIST, WORKFLOW_GET, WORKFLOW_CREATE - ON_EVENTS for mesh event subscription Works with mesh-bridge for WhatsApp, CLI, and other interfaces.
1 parent 85a5400 commit 480c37b

31 files changed

Lines changed: 8423 additions & 0 deletions

bun.lock

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"object-storage",
3131
"openrouter",
3232
"perplexity",
33+
"pilot",
3334
"pinecone",
3435
"readonly-sql",
3536
"registry",

pilot/AGENTS.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Pilot Agent Guidelines
2+
3+
## Debugging Complex AI Flows
4+
5+
When debugging multi-step workflows, LLM calls, or async task execution where terminal logs may be truncated or lost:
6+
7+
**Use temporary file-based logging** to capture the full picture:
8+
9+
```typescript
10+
const fs = await import("fs");
11+
const logPath = "/tmp/pilot-debug.log";
12+
const log = (msg: string) => {
13+
const line = `[${new Date().toISOString()}] ${msg}\n`;
14+
fs.appendFileSync(logPath, line);
15+
console.error(msg); // Also emit to stderr for STDIO capture
16+
};
17+
18+
log(`🔍 LLM CALL: model=${modelId}, messages=${messages.length}`);
19+
log(`📝 PROMPT: ${prompt.slice(0, 300)}`);
20+
const result = await callLLM(...);
21+
log(`📤 RESULT: text=${!!result.text} (${result.text?.length || 0} chars)`);
22+
```
23+
24+
This technique is essential when:
25+
- Pilot runs as STDIO subprocess (Mesh only captures stderr)
26+
- Terminal output is truncated or scrolling
27+
- Async callbacks (setTimeout) fire after parent logs
28+
- You need timestamps to trace execution order across concurrent flows
29+
30+
**Always use `console.error` instead of `console.log`** in Pilot - Mesh's STDIO transport only pipes stderr to the main console.
31+
32+
Remember to clean up debug logging before committing.
33+
34+
## Common Gotchas
35+
36+
### Model ID Resolution
37+
When spawning child workflows via `start_task`, always pass the resolved model IDs from the parent config:
38+
39+
```typescript
40+
// ❌ Wrong - passes literal strings
41+
config: { fastModel: "fast", smartModel: "smart" }
42+
43+
// ✅ Correct - passes actual model IDs
44+
config: { fastModel: config.fastModel, smartModel: config.smartModel }
45+
```
46+
47+
### STDIO Logging
48+
Pilot runs as an STDIO process under Mesh. Only `stderr` is captured:
49+
- Use `console.error()` for debug output
50+
- `console.log()` output will be lost
51+

0 commit comments

Comments
 (0)