pi-crew 0.1.46 → 0.1.49
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/CHANGELOG.md +97 -0
- package/agents/analyst.md +11 -11
- package/agents/critic.md +11 -11
- package/agents/executor.md +11 -11
- package/agents/explorer.md +11 -11
- package/agents/planner.md +11 -11
- package/agents/reviewer.md +11 -11
- package/agents/security-reviewer.md +11 -11
- package/agents/test-engineer.md +11 -11
- package/agents/verifier.md +11 -11
- package/agents/writer.md +11 -11
- package/docs/next-upgrade-roadmap.md +117 -42
- package/docs/refactor-tasks-phase3.md +394 -394
- package/docs/refactor-tasks-phase4.md +564 -564
- package/docs/refactor-tasks-phase5.md +402 -402
- package/docs/refactor-tasks-phase6.md +662 -662
- package/docs/research/AGENT-EXECUTION-ARCHITECTURE.md +261 -0
- package/docs/research/AGENT-LIFECYCLE-COMPARISON.md +111 -0
- package/docs/research/AUDIT_OH_MY_PI.md +261 -0
- package/docs/research/AUDIT_PI_CREW.md +457 -0
- package/docs/research/CAVEMAN-DEEP-RESEARCH.md +281 -0
- package/docs/research/COMPARISON_OH_MY_PI_VS_PI_CREW.md +264 -0
- package/docs/research/DEEP-RESEARCH-PI-POWERBAR.md +343 -0
- package/docs/research/DEEP_RESEARCH_SUBAGENT_ARCHITECTURE.md +480 -0
- package/docs/research/GAP_CLOSURE_IMPLEMENTATION_PLAN.md +354 -0
- package/docs/research/IMPLEMENTATION_PLAN.md +385 -0
- package/docs/research/LIVE-SESSION-PRODUCTION-READY-PLAN.md +502 -0
- package/docs/research/OH-MY-PI-DEEP-RESEARCH-v14.7.6.md +266 -0
- package/docs/research/REMAINING-GAPS-PLAN.md +363 -0
- package/docs/research/SESSION-SUMMARY-2026-05-08.md +146 -0
- package/docs/research/UI-RESPONSIVENESS-AUDIT.md +173 -0
- package/docs/research-awesome-agent-skills-distillation.md +100 -100
- package/docs/research-extension-examples.md +297 -297
- package/docs/research-extension-system.md +324 -324
- package/docs/research-oh-my-pi-distillation.md +56 -9
- package/docs/research-optimization-plan.md +548 -548
- package/docs/research-phase10-distillation.md +198 -198
- package/docs/research-phase11-distillation.md +201 -201
- package/docs/research-pi-coding-agent.md +357 -357
- package/docs/research-source-pi-crew-reference.md +174 -174
- package/docs/runtime-flow.md +148 -148
- package/docs/source-runtime-refactor-map.md +107 -107
- package/index.ts +6 -6
- package/package.json +99 -98
- package/schema.json +8 -0
- package/skills/async-worker-recovery/SKILL.md +42 -42
- package/skills/context-artifact-hygiene/SKILL.md +52 -52
- package/skills/delegation-patterns/SKILL.md +54 -54
- package/skills/mailbox-interactive/SKILL.md +40 -40
- package/skills/model-routing-context/SKILL.md +39 -39
- package/skills/multi-perspective-review/SKILL.md +58 -58
- package/skills/observability-reliability/SKILL.md +41 -41
- package/skills/orchestration/SKILL.md +157 -0
- package/skills/ownership-session-security/SKILL.md +41 -41
- package/skills/pi-extension-lifecycle/SKILL.md +39 -39
- package/skills/requirements-to-task-packet/SKILL.md +63 -63
- package/skills/resource-discovery-config/SKILL.md +41 -41
- package/skills/runtime-state-reader/SKILL.md +44 -44
- package/skills/secure-agent-orchestration-review/SKILL.md +45 -45
- package/skills/state-mutation-locking/SKILL.md +42 -42
- package/skills/systematic-debugging/SKILL.md +67 -67
- package/skills/ui-render-performance/SKILL.md +39 -39
- package/skills/verification-before-done/SKILL.md +57 -57
- package/skills/worktree-isolation/SKILL.md +39 -39
- package/src/agents/agent-config.ts +6 -0
- package/src/agents/agent-search.ts +98 -0
- package/src/agents/agent-serializer.ts +4 -0
- package/src/agents/discover-agents.ts +17 -4
- package/src/config/config.ts +24 -0
- package/src/config/defaults.ts +11 -0
- package/src/extension/autonomous-policy.ts +26 -33
- package/src/extension/cross-extension-rpc.ts +82 -82
- package/src/extension/help.ts +1 -0
- package/src/extension/management.ts +5 -0
- package/src/extension/register.ts +58 -13
- package/src/extension/registration/commands.ts +33 -1
- package/src/extension/registration/compaction-guard.ts +125 -125
- package/src/extension/registration/team-tool.ts +6 -4
- package/src/extension/run-bundle-schema.ts +89 -89
- package/src/extension/run-index.ts +24 -18
- package/src/extension/run-maintenance.ts +68 -62
- package/src/extension/team-tool/api.ts +23 -2
- package/src/extension/team-tool/cancel.ts +86 -11
- package/src/extension/team-tool/context.ts +3 -0
- package/src/extension/team-tool/handle-settings.ts +188 -188
- package/src/extension/team-tool/inspect.ts +41 -41
- package/src/extension/team-tool/intent-policy.ts +42 -0
- package/src/extension/team-tool/lifecycle-actions.ts +47 -18
- package/src/extension/team-tool/parallel-dispatch.ts +156 -0
- package/src/extension/team-tool/plan.ts +19 -19
- package/src/extension/team-tool/respond.ts +10 -2
- package/src/extension/team-tool/run.ts +3 -2
- package/src/extension/team-tool/status.ts +1 -1
- package/src/extension/team-tool-types.ts +1 -0
- package/src/extension/team-tool.ts +13 -3
- package/src/hooks/registry.ts +61 -0
- package/src/hooks/types.ts +41 -0
- package/src/i18n.ts +184 -184
- package/src/observability/exporters/otlp-exporter.ts +77 -77
- package/src/prompt/prompt-runtime.ts +72 -72
- package/src/runtime/agent-control.ts +108 -2
- package/src/runtime/agent-memory.ts +72 -72
- package/src/runtime/agent-observability.ts +114 -114
- package/src/runtime/async-marker.ts +26 -26
- package/src/runtime/async-runner.ts +3 -1
- package/src/runtime/attention-events.ts +28 -28
- package/src/runtime/background-runner.ts +19 -0
- package/src/runtime/cancellation-token.ts +89 -0
- package/src/runtime/cancellation.ts +61 -51
- package/src/runtime/capability-inventory.ts +116 -0
- package/src/runtime/child-pi.ts +2 -1
- package/src/runtime/code-summary.ts +247 -0
- package/src/runtime/completion-guard.ts +190 -190
- package/src/runtime/crash-recovery.ts +181 -0
- package/src/runtime/crew-agent-records.ts +35 -7
- package/src/runtime/crew-agent-runtime.ts +1 -0
- package/src/runtime/custom-tools/irc-tool.ts +201 -0
- package/src/runtime/custom-tools/submit-result-tool.ts +90 -0
- package/src/runtime/delivery-coordinator.ts +3 -1
- package/src/runtime/direct-run.ts +35 -35
- package/src/runtime/effectiveness.ts +81 -76
- package/src/runtime/event-stream-bridge.ts +90 -0
- package/src/runtime/foreground-control.ts +82 -82
- package/src/runtime/green-contract.ts +46 -46
- package/src/runtime/group-join.ts +106 -106
- package/src/runtime/heartbeat-gradient.ts +28 -28
- package/src/runtime/heartbeat-watcher.ts +124 -124
- package/src/runtime/live-agent-control.ts +88 -88
- package/src/runtime/live-agent-manager.ts +78 -2
- package/src/runtime/live-control-realtime.ts +36 -36
- package/src/runtime/live-extension-bridge.ts +150 -0
- package/src/runtime/live-irc.ts +92 -0
- package/src/runtime/live-session-health.ts +100 -0
- package/src/runtime/live-session-runtime.ts +297 -7
- package/src/runtime/mcp-proxy.ts +113 -0
- package/src/runtime/notebook-helpers.ts +90 -0
- package/src/runtime/orphan-sentinel.ts +7 -0
- package/src/runtime/output-validator.ts +187 -0
- package/src/runtime/parallel-research.ts +44 -44
- package/src/runtime/parallel-utils.ts +57 -0
- package/src/runtime/parent-guard.ts +80 -0
- package/src/runtime/pi-json-output.ts +111 -111
- package/src/runtime/policy-engine.ts +79 -79
- package/src/runtime/progress-event-coalescer.ts +43 -43
- package/src/runtime/prose-compressor.ts +164 -0
- package/src/runtime/recovery-recipes.ts +74 -74
- package/src/runtime/result-extractor.ts +121 -0
- package/src/runtime/role-permission.ts +39 -39
- package/src/runtime/runtime-resolver.ts +1 -4
- package/src/runtime/semaphore.ts +131 -0
- package/src/runtime/sensitive-paths.ts +92 -0
- package/src/runtime/session-resources.ts +25 -25
- package/src/runtime/session-snapshot.ts +59 -59
- package/src/runtime/session-usage.ts +79 -79
- package/src/runtime/sidechain-output.ts +29 -29
- package/src/runtime/stream-preview.ts +177 -0
- package/src/runtime/subagent-manager.ts +3 -2
- package/src/runtime/subprocess-tool-registry.ts +67 -0
- package/src/runtime/supervisor-contact.ts +59 -59
- package/src/runtime/task-display.ts +38 -38
- package/src/runtime/task-output-context.ts +59 -9
- package/src/runtime/task-runner/capabilities.ts +78 -78
- package/src/runtime/task-runner/live-executor.ts +2 -0
- package/src/runtime/task-runner/progress.ts +119 -119
- package/src/runtime/task-runner/prompt-builder.ts +70 -8
- package/src/runtime/task-runner/prompt-pipeline.ts +64 -64
- package/src/runtime/task-runner/result-utils.ts +14 -14
- package/src/runtime/task-runner/run-projection.ts +104 -0
- package/src/runtime/task-runner/state-helpers.ts +22 -22
- package/src/runtime/task-runner.ts +75 -4
- package/src/runtime/team-runner.ts +60 -8
- package/src/runtime/worker-heartbeat.ts +21 -21
- package/src/runtime/worker-startup.ts +57 -57
- package/src/runtime/workspace-tree.ts +298 -0
- package/src/runtime/yield-handler.ts +189 -0
- package/src/schema/config-schema.ts +6 -0
- package/src/schema/team-tool-schema.ts +11 -1
- package/src/skills/discover-skills.ts +67 -0
- package/src/state/active-run-registry.ts +4 -2
- package/src/state/artifact-store.ts +4 -1
- package/src/state/atomic-write.ts +50 -1
- package/src/state/blob-store.ts +117 -0
- package/src/state/contracts.ts +1 -0
- package/src/state/event-log-rotation.ts +158 -0
- package/src/state/event-log.ts +52 -2
- package/src/state/mailbox.ts +87 -7
- package/src/state/state-store.ts +24 -4
- package/src/state/task-claims.ts +44 -44
- package/src/state/types.ts +20 -0
- package/src/state/usage.ts +29 -29
- package/src/subagents/async-entry.ts +1 -1
- package/src/subagents/index.ts +3 -3
- package/src/subagents/live/control.ts +1 -1
- package/src/subagents/live/manager.ts +1 -1
- package/src/subagents/live/realtime.ts +1 -1
- package/src/subagents/live/session-runtime.ts +1 -1
- package/src/subagents/manager.ts +1 -1
- package/src/subagents/spawn.ts +1 -1
- package/src/teams/team-serializer.ts +38 -38
- package/src/types/diff.d.ts +18 -18
- package/src/ui/agent-management-overlay.ts +144 -0
- package/src/ui/crew-footer.ts +101 -101
- package/src/ui/crew-select-list.ts +111 -111
- package/src/ui/crew-widget.ts +11 -2
- package/src/ui/dashboard-panes/cancellation-pane.ts +43 -0
- package/src/ui/dashboard-panes/capability-pane.ts +60 -0
- package/src/ui/dashboard-panes/mailbox-pane.ts +35 -11
- package/src/ui/dashboard-panes/metrics-pane.ts +34 -34
- package/src/ui/dynamic-border.ts +25 -25
- package/src/ui/layout-primitives.ts +106 -106
- package/src/ui/live-run-sidebar.ts +4 -0
- package/src/ui/loaders.ts +158 -158
- package/src/ui/powerbar-publisher.ts +77 -15
- package/src/ui/render-coalescer.ts +51 -0
- package/src/ui/render-diff.ts +119 -119
- package/src/ui/render-scheduler.ts +143 -143
- package/src/ui/run-dashboard.ts +4 -0
- package/src/ui/run-event-bus.ts +209 -0
- package/src/ui/run-snapshot-cache.ts +68 -16
- package/src/ui/snapshot-types.ts +8 -0
- package/src/ui/spinner.ts +17 -17
- package/src/ui/status-colors.ts +58 -58
- package/src/ui/syntax-highlight.ts +116 -116
- package/src/ui/transcript-entries.ts +258 -0
- package/src/utils/atomic-write.ts +33 -33
- package/src/utils/completion-dedupe.ts +63 -63
- package/src/utils/frontmatter.ts +68 -68
- package/src/utils/git.ts +262 -262
- package/src/utils/ids.ts +17 -12
- package/src/utils/incremental-reader.ts +104 -0
- package/src/utils/names.ts +27 -27
- package/src/utils/redaction.ts +44 -44
- package/src/utils/safe-paths.ts +47 -47
- package/src/utils/scan-cache.ts +137 -0
- package/src/utils/sleep.ts +32 -32
- package/src/utils/sse-parser.ts +134 -0
- package/src/utils/task-name-generator.ts +337 -0
- package/src/utils/visual.ts +33 -2
- package/src/workflows/validate-workflow.ts +40 -40
- package/src/worktree/branch-freshness.ts +45 -45
- package/src/worktree/cleanup.ts +2 -1
- package/teams/default.team.md +12 -12
- package/teams/fast-fix.team.md +11 -11
- package/teams/implementation.team.md +18 -18
- package/teams/parallel-research.team.md +14 -14
- package/teams/research.team.md +11 -11
- package/teams/review.team.md +12 -12
- package/workflows/default.workflow.md +29 -29
- package/workflows/fast-fix.workflow.md +22 -22
- package/workflows/implementation.workflow.md +38 -38
- package/workflows/parallel-research.workflow.md +46 -46
- package/workflows/research.workflow.md +22 -22
- package/workflows/review.workflow.md +30 -30
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
# 🔬 Deep Research: Oh-My-Pi Subagent Architecture
|
|
2
|
+
|
|
3
|
+
> **Nguồn**: Đọc sâu trực tiếp source code oh-my-pi v14.7.3 + 6 parallel research agents (4 explorer shards + 1 analyst + 1 writer)
|
|
4
|
+
> **Mục đích**: Hiểu cách hoạt động subagent, giao tiếp giữa các subagent, và UI hiển thị
|
|
5
|
+
> **Files đã kiểm tra**: 16 files chính (~8000+ dòng code)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Subagent Lifecycle & Execution
|
|
10
|
+
|
|
11
|
+
### 1.1 Architecture Overview
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
┌─────────────────────────────────────────────────────────┐
|
|
15
|
+
│ Main Session │
|
|
16
|
+
│ (AgentSession) │
|
|
17
|
+
│ ├─ TaskTool.execute() │
|
|
18
|
+
│ │ ├─ #executeSync() ← sequential/sync path │
|
|
19
|
+
│ │ └─ execute() async ← async background path │
|
|
20
|
+
│ │ │
|
|
21
|
+
│ │ ┌─────────────┐ ┌─────────────┐ │
|
|
22
|
+
│ │ │ runSubprocess│ │ runSubprocess│ ← parallel │
|
|
23
|
+
│ │ │ (task 0) │ │ (task 1) │ via │
|
|
24
|
+
│ │ │ AgentSession│ │ AgentSession│ Semaphore │
|
|
25
|
+
│ │ │ + Events │ │ + Events │ + mapWith... │
|
|
26
|
+
│ │ └─────────────┘ └─────────────┘ │
|
|
27
|
+
│ └─ EventBus │
|
|
28
|
+
│ ├─ task:subagent:event (raw events) │
|
|
29
|
+
│ ├─ task:subagent:progress (aggregated) │
|
|
30
|
+
│ └─ task:subagent:lifecycle (start/end) │
|
|
31
|
+
└─────────────────────────────────────────────────────────┘
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 1.2 In-Process Execution Model (KHÔNG phải child process!)
|
|
35
|
+
|
|
36
|
+
**Key insight**: Oh-my-pi subagents chạy **in-process** (cùng process), KHÔNG spawn child process như pi-crew.
|
|
37
|
+
|
|
38
|
+
**File**: `packages/coding-agent/src/task/executor.ts` (~1291 lines)
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
// executor.ts — runSubprocess creates an AgentSession IN-PROCESS
|
|
42
|
+
const { session } = await createAgentSession({
|
|
43
|
+
cwd: worktree ?? cwd,
|
|
44
|
+
authStorage, modelRegistry, settings: subagentSettings,
|
|
45
|
+
model, thinkingLevel: effectiveThinkingLevel,
|
|
46
|
+
toolNames, // ← restricted tool set
|
|
47
|
+
systemPrompt: ..., // ← composed prompt
|
|
48
|
+
sessionManager, // ← in-memory or file-backed
|
|
49
|
+
hasUI: false, // ← no UI for subagents
|
|
50
|
+
spawns: spawnsEnv, // ← recursion control
|
|
51
|
+
taskDepth: childDepth,
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 1.3 Agent Definition & Discovery
|
|
56
|
+
|
|
57
|
+
**File**: `packages/coding-agent/src/task/agents.ts`
|
|
58
|
+
|
|
59
|
+
- **Bundled agents**: Embedded via `import ... with { type: "text" }` (Bun compile-time)
|
|
60
|
+
- explore, plan, designer, reviewer, librarian, task, quick_task
|
|
61
|
+
- **User agents**: `~/.omp/agent/agents/*.md`
|
|
62
|
+
- **Project agents**: `.omp/agents/*.md`
|
|
63
|
+
- **Frontmatter** (YAML): `name, description, tools?, spawns?, model?, thinkingLevel?, blocking?, output?`
|
|
64
|
+
|
|
65
|
+
**File**: `packages/coding-agent/src/task/types.ts`
|
|
66
|
+
```typescript
|
|
67
|
+
interface AgentDefinition {
|
|
68
|
+
name: string;
|
|
69
|
+
description: string;
|
|
70
|
+
systemPrompt: string;
|
|
71
|
+
tools?: string[]; // ← tool whitelist
|
|
72
|
+
spawns?: string[] | "*"; // ← recursion control
|
|
73
|
+
model?: string[]; // ← model pattern override
|
|
74
|
+
thinkingLevel?: ThinkingLevel;
|
|
75
|
+
blocking?: boolean; // ← prevent async execution
|
|
76
|
+
output?: unknown; // ← JTD output schema
|
|
77
|
+
source: AgentSource;
|
|
78
|
+
filePath?: string;
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 1.4 System Prompt Construction
|
|
83
|
+
|
|
84
|
+
**File**: `packages/coding-agent/src/task/executor.ts`
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
Subagent system prompt = template.render(subagentSystemPromptTemplate, {
|
|
88
|
+
base: defaultPrompt, // ← Pi's default system prompt
|
|
89
|
+
agent: agent.systemPrompt, // ← agent-specific instructions
|
|
90
|
+
worktree: worktree ?? "", // ← isolation directory
|
|
91
|
+
outputSchema: ..., // ← expected output format
|
|
92
|
+
contextFile: ..., // ← parent conversation context
|
|
93
|
+
ircPeers: ..., // ← visible IRC peers
|
|
94
|
+
ircSelfId: ..., // ← self agent ID for IRC
|
|
95
|
+
})
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 1.5 Tool Access Control
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
// Restricted tool set from agent definition
|
|
102
|
+
let toolNames: string[] | undefined;
|
|
103
|
+
if (agent.tools && agent.tools.length > 0) {
|
|
104
|
+
toolNames = agent.tools;
|
|
105
|
+
// Auto-include task tool if spawns defined
|
|
106
|
+
if (agent.spawns !== undefined && !toolNames.includes("task") && !atMaxDepth) {
|
|
107
|
+
toolNames = [...toolNames, "task"];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Recursion depth limit
|
|
112
|
+
const maxRecursionDepth = settings.get("task.maxRecursionDepth") ?? 2;
|
|
113
|
+
if (atMaxDepth && toolNames?.includes("task")) {
|
|
114
|
+
toolNames = toolNames.filter(name => name !== "task");
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 1.6 Yield Tool Pattern (Critical!)
|
|
119
|
+
|
|
120
|
+
Subagents **MUST** call `yield` tool to submit results:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
// executor.ts — yield enforcement
|
|
124
|
+
const MAX_YIELD_RETRIES = 3;
|
|
125
|
+
while (!yieldCalled && retryCount < MAX_YIELD_RETRIES && !abortSignal.aborted) {
|
|
126
|
+
const reminder = prompt.render(submitReminderTemplate, {
|
|
127
|
+
retryCount, maxRetries: MAX_YIELD_RETRIES,
|
|
128
|
+
});
|
|
129
|
+
await session.prompt(reminder, {
|
|
130
|
+
attribution: "agent",
|
|
131
|
+
...(reminderToolChoice ? { toolChoice: reminderToolChoice } : {}),
|
|
132
|
+
});
|
|
133
|
+
await session.waitForIdle();
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
If subagent exits without calling yield → warning + potential exitCode=1.
|
|
138
|
+
|
|
139
|
+
### 1.7 Progress Tracking
|
|
140
|
+
|
|
141
|
+
**Coalesced progress updates** (150ms debounce):
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
const PROGRESS_COALESCE_MS = 150;
|
|
145
|
+
|
|
146
|
+
// Events tracked per-subagent:
|
|
147
|
+
progress.currentTool = event.toolName;
|
|
148
|
+
progress.currentToolArgs = extractToolArgsPreview(event.args);
|
|
149
|
+
progress.recentTools.unshift({ tool, args, endMs });
|
|
150
|
+
progress.tokens += getUsageTokens(messageUsage);
|
|
151
|
+
progress.recentOutput = lines.slice(-8).reverse(); // 8 recent output lines
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### 1.8 Isolation Modes
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
type IsolationMode = "worktree" | "fuse-overlay" | "fuse-projfs" | "none";
|
|
158
|
+
type MergeMode = "patch" | "branch" | "none";
|
|
159
|
+
type CommitStyle = "ai" | "simple";
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
- **worktree**: Git worktree per task → capture patch or branch
|
|
163
|
+
- **fuse-overlay**: FUSE filesystem overlay (fast copy-on-write)
|
|
164
|
+
- **fuse-projfs**: Windows ProjFS overlay
|
|
165
|
+
- **none**: No isolation, in-place editing
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 2. Inter-Subagent Communication
|
|
170
|
+
|
|
171
|
+
### 2.1 IRC Tool — Agent-to-Agent Messaging
|
|
172
|
+
|
|
173
|
+
**File**: `packages/coding-agent/src/tools/irc.ts`
|
|
174
|
+
|
|
175
|
+
Oh-my-pi has a full **IRC-like messaging system** between agents:
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
┌──────────────┐ irc.send ┌──────────────┐
|
|
179
|
+
│ Agent A │ ─────────────→ │ Agent B │
|
|
180
|
+
│ (subagent) │ message │ (subagent) │
|
|
181
|
+
│ │ ←───────────── │ │
|
|
182
|
+
│ │ auto-reply │ │
|
|
183
|
+
└──────────────┘ └──────────────┘
|
|
184
|
+
↓ ↓
|
|
185
|
+
relay to Main relay to Main
|
|
186
|
+
(display only) (display only)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Operations**:
|
|
190
|
+
- `op: "list"` → list visible peers
|
|
191
|
+
- `op: "send"` → send message to peer or broadcast ("all")
|
|
192
|
+
- `awaitReply: true/false` → DM auto-replies, broadcast doesn't
|
|
193
|
+
|
|
194
|
+
### 2.2 AgentRegistry — Global Process Registry
|
|
195
|
+
|
|
196
|
+
**File**: `packages/coding-agent/src/registry/agent-registry.ts`
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
class AgentRegistry {
|
|
200
|
+
// Process-global singleton
|
|
201
|
+
static global(): AgentRegistry;
|
|
202
|
+
|
|
203
|
+
register(input: RegisterInput): AgentRef; // register at creation
|
|
204
|
+
unregister(id: string): void; // remove on dispose
|
|
205
|
+
setStatus(id: string, AgentStatus): void;
|
|
206
|
+
listVisibleTo(id: string): AgentRef[]; // peers visible to caller
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
- Main agent: id="0-Main", kind="main"
|
|
211
|
+
- Subagents: id="0-TaskName", kind="sub", parentId="0-Main"
|
|
212
|
+
|
|
213
|
+
### 2.3 Ephemeral Side-Channel (Anti-Deadlock!)
|
|
214
|
+
|
|
215
|
+
**File**: `packages/coding-agent/src/session/agent-session.ts`
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
async respondAsBackground(args): Promise<{ replyText: string | null }> {
|
|
219
|
+
// 1. Create incoming record (irc:incoming)
|
|
220
|
+
// 2. Forward to Main UI for display (relay)
|
|
221
|
+
// 3. Run ephemeral turn: snapshot current model+history, no tools, no persistence
|
|
222
|
+
// → avoids deadlock with recipient's in-flight tool calls
|
|
223
|
+
// 4. Create reply record (irc:autoreply)
|
|
224
|
+
// 5. Queue both records for injection into recipient's history (deferred until idle)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async runEphemeralTurn(args): Promise<{ replyText, assistantMessage }> {
|
|
228
|
+
// Snapshot includes in-flight streaming text!
|
|
229
|
+
const snapshot = this.#buildEphemeralSnapshot(args.promptText);
|
|
230
|
+
const llmMessages = await this.convertMessagesToLlm(snapshot, args.signal);
|
|
231
|
+
// ... stream response, no tools, no history mutation
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**Key design**: The side-channel does NOT require the recipient's main loop to be free. It takes a snapshot of the current history (including any in-flight streaming text) and generates a reply in parallel.
|
|
236
|
+
|
|
237
|
+
### 2.4 IRC Relay to Main
|
|
238
|
+
|
|
239
|
+
All IRC exchanges are **relayed to the main agent's UI** (display-only, not persisted to main's history):
|
|
240
|
+
|
|
241
|
+
```
|
|
242
|
+
Subagent A sends to Subagent B:
|
|
243
|
+
→ Main UI shows: [IRC `AgentA` → `AgentB`] message...
|
|
244
|
+
→ Main UI shows: [IRC `AgentB` → (auto) `AgentA`] reply...
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### 2.5 EventBus Channels
|
|
248
|
+
|
|
249
|
+
Three channels for subagent events:
|
|
250
|
+
|
|
251
|
+
| Channel | Purpose | Payload |
|
|
252
|
+
|---------|---------|---------|
|
|
253
|
+
| `task:subagent:event` | Raw agent events (tool calls, messages) | `{ index, agent, event }` |
|
|
254
|
+
| `task:subagent:progress` | Aggregated progress (debounced 150ms) | `SubagentProgressPayload` |
|
|
255
|
+
| `task:subagent:lifecycle` | Start/end transitions | `SubagentLifecyclePayload` |
|
|
256
|
+
|
|
257
|
+
### 2.6 Communication Summary
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
Method │ Direction │ Persistence │ Use Case
|
|
261
|
+
────────────────┼───────────────────┼──────────────────┼──────────────────
|
|
262
|
+
IRC tool │ peer ↔ peer │ queued on idle │ Coordination
|
|
263
|
+
EventBus │ child → parent │ in-memory only │ Progress tracking
|
|
264
|
+
Session file │ child → parent │ .jsonl on disk │ Transcript
|
|
265
|
+
Artifacts │ child → parent │ files on disk │ Output/patches
|
|
266
|
+
Context file │ parent → child │ .md on disk │ Parent context
|
|
267
|
+
Yield tool │ child → parent │ in output │ Submit results
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## 3. TUI/UI Rendering for Subagents
|
|
273
|
+
|
|
274
|
+
### 3.1 Session Observer Registry
|
|
275
|
+
|
|
276
|
+
**File**: `packages/coding-agent/src/modes/session-observer-registry.ts`
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
SessionObserverRegistry
|
|
280
|
+
├─ subscribeToEventBus(eventBus)
|
|
281
|
+
│ ├─ on(TASK_SUBAGENT_LIFECYCLE_CHANNEL) → track start/end
|
|
282
|
+
│ └─ on(TASK_SUBAGENT_PROGRESS_CHANNEL) → update progress
|
|
283
|
+
├─ onChange(callback) → notify UI to re-render
|
|
284
|
+
├─ getSessions() → sorted list [main, ...subagents]
|
|
285
|
+
└─ getActiveSubagentCount()
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Tracks `ObservableSession[]`:
|
|
289
|
+
```typescript
|
|
290
|
+
interface ObservableSession {
|
|
291
|
+
id: string;
|
|
292
|
+
kind: "main" | "subagent";
|
|
293
|
+
label: string;
|
|
294
|
+
agent?: string;
|
|
295
|
+
status: "active" | "completed" | "failed" | "aborted";
|
|
296
|
+
sessionFile?: string; // ← JSONL transcript path
|
|
297
|
+
lastUpdate: number;
|
|
298
|
+
progress?: AgentProgress; // ← latest progress snapshot
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### 3.2 Session Observer Overlay (Main UI Component)
|
|
303
|
+
|
|
304
|
+
**File**: `packages/coding-agent/src/modes/components/session-observer-overlay.ts` (~824 lines)
|
|
305
|
+
|
|
306
|
+
**Architecture**:
|
|
307
|
+
```
|
|
308
|
+
┌─ DynamicBorder ──────────────────────────────────────────┐
|
|
309
|
+
│ Session Observer > Subagent #0 │
|
|
310
|
+
│ fix-security-bug [active] explorer │
|
|
311
|
+
├──────────────────────────────────────────────────────────┤
|
|
312
|
+
│ │
|
|
313
|
+
│ ▶ ▸ bash │
|
|
314
|
+
│ npm run test │
|
|
315
|
+
│ ✓ done │
|
|
316
|
+
│ │
|
|
317
|
+
│ ▸ read │
|
|
318
|
+
│ path: src/auth.ts │
|
|
319
|
+
│ ✓ 24 lines │
|
|
320
|
+
│ │
|
|
321
|
+
│ ▶ Response │
|
|
322
|
+
│ I found the security issue in... │
|
|
323
|
+
│ │
|
|
324
|
+
├──────────────────────────────────────────────────────────┤
|
|
325
|
+
│ 12 tools · 8.5k tokens · 2m 34s [1-45/89] │
|
|
326
|
+
│ j/k:scroll Enter:expand [/]/←→:cycle Esc:close │
|
|
327
|
+
└─ DynamicBorder ──────────────────────────────────────────┘
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**Key UI Features**:
|
|
331
|
+
|
|
332
|
+
1. **Auto-jump to most recent active subagent** on open
|
|
333
|
+
2. **Incremental transcript loading**: reads JSONL file incrementally (`readFileIncremental`) — only reads new bytes since last render
|
|
334
|
+
3. **Entry-based selection**: each thinking/text/toolCall/user block is a selectable entry
|
|
335
|
+
4. **Expand/collapse**: Enter toggles expanded view per entry
|
|
336
|
+
5. **Breadcrumb navigation**: for nested sub-agents (subagent spawning subagent)
|
|
337
|
+
6. **Cycle agents**: `]`/`[` or ←→ to switch between subagents
|
|
338
|
+
7. **Auto-scroll**: stays at bottom unless user manually scrolled up
|
|
339
|
+
8. **Markdown rendering**: expanded entries use `Markdown` component for rich formatting
|
|
340
|
+
9. **Smart scrolling**: entries larger than viewport only snap when completely out of view
|
|
341
|
+
|
|
342
|
+
### 3.3 Anti-Flicker Techniques
|
|
343
|
+
|
|
344
|
+
1. **Progress coalescing** (150ms debounce in executor.ts):
|
|
345
|
+
```typescript
|
|
346
|
+
const PROGRESS_COALESCE_MS = 150;
|
|
347
|
+
// Only emit progress if 150ms elapsed since last emit
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
2. **Incremental file reading** (only new bytes):
|
|
351
|
+
```typescript
|
|
352
|
+
readFileIncremental(filePath, fromByte) → { text, newSize }
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
3. **Viewport-based rendering**: only renders visible lines in viewport, pads rest
|
|
356
|
+
4. **Rebuild on state change only**: content rebuilt only when selection/expansion changes
|
|
357
|
+
|
|
358
|
+
### 3.4 Agent Dashboard (Configuration UI)
|
|
359
|
+
|
|
360
|
+
**File**: `packages/coding-agent/src/modes/components/agent-dashboard.ts` (~1120 lines)
|
|
361
|
+
|
|
362
|
+
Two-column layout for managing agents:
|
|
363
|
+
- Left: agent list with search/filter by source (All/Project/User/Bundled)
|
|
364
|
+
- Right: inspector showing model resolution, overrides, file path
|
|
365
|
+
- Can create new agents via AI generation (architect agent)
|
|
366
|
+
- Toggle enable/disable, model override per agent
|
|
367
|
+
|
|
368
|
+
### 3.5 Render Chain for Subagent Progress
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
AgentEvent (in subagent session)
|
|
372
|
+
→ processEvent() [executor.ts]
|
|
373
|
+
→ AgentProgress updated in-memory
|
|
374
|
+
→ scheduleProgress() with 150ms coalesce
|
|
375
|
+
→ EventBus.emit(TASK_SUBAGENT_PROGRESS_CHANNEL)
|
|
376
|
+
→ SessionObserverRegistry updates ObservableSession
|
|
377
|
+
→ onChange listeners fire
|
|
378
|
+
→ UI re-renders observer overlay
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### 3.6 Streaming Text Display
|
|
382
|
+
|
|
383
|
+
From executor.ts `processEvent`:
|
|
384
|
+
```typescript
|
|
385
|
+
case "message_update":
|
|
386
|
+
if (assistantEvent.type === "text_delta") {
|
|
387
|
+
appendRecentOutputTail(assistantEvent.delta); // incremental
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
The observer overlay reads the full JSONL transcript from disk, so it shows the complete conversation, not just the last delta.
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## 4. Steering & Follow-up (Từ agent research)
|
|
396
|
+
|
|
397
|
+
### 4.1 Steering Mechanism
|
|
398
|
+
|
|
399
|
+
**Files**: `packages/agent/src/agent.ts` (line 220-580), `packages/agent/src/agent-loop.ts`
|
|
400
|
+
|
|
401
|
+
```
|
|
402
|
+
agent.steer(message) → thêm vào #steeringQueue
|
|
403
|
+
agent.followUp(message) → thêm vào #followUpQueue
|
|
404
|
+
|
|
405
|
+
Agent Loop:
|
|
406
|
+
while (true) { // outer loop: follow-ups
|
|
407
|
+
while (hasMoreToolCalls || pendingMessages) { // inner loop
|
|
408
|
+
// inject pending messages từ steering queue
|
|
409
|
+
// check interruptMode: "immediate" (sau mỗi tool) hoặc "wait" (đợi turn xong)
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
Hai chế độ interrupt:
|
|
415
|
+
- `"immediate"`: kiểm tra steering queue sau mỗi tool call → phản hồi nhanh
|
|
416
|
+
- `"wait"`: đợi turn hiện tại hoàn tất → không gián đoạn
|
|
417
|
+
|
|
418
|
+
### 4.2 render.ts — Task Tool TUI Rendering (~1020 lines)
|
|
419
|
+
|
|
420
|
+
**File**: `packages/coding-agent/src/task/render.ts`
|
|
421
|
+
|
|
422
|
+
Component hiển thị kết quả task tool trong main session transcript:
|
|
423
|
+
- `renderCall()`: Hiển thị khi parent gọi task tool (tóm tắt agent, tasks, isolation mode)
|
|
424
|
+
- `renderResult()`: Hiển thị kết quả khi subagent hoàn thành
|
|
425
|
+
- Per-task status indicators (✓/✗/⊘)
|
|
426
|
+
- Duration, token counts
|
|
427
|
+
- Truncated output previews
|
|
428
|
+
- Patch/merge summaries
|
|
429
|
+
- Usage aggregation across all subagents
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
## 5. Key Differences from pi-crew
|
|
434
|
+
|
|
435
|
+
| Aspect | oh-my-pi | pi-crew |
|
|
436
|
+
|--------|----------|---------|
|
|
437
|
+
| Execution model | In-process (AgentSession) | Child process (pi CLI) |
|
|
438
|
+
| Communication | IRC tool + EventBus | File-based (manifest, artifacts) |
|
|
439
|
+
| Progress | Real-time EventBus (150ms coalesce) | Post-hoc file reading |
|
|
440
|
+
| UI | Full overlay with transcript | Powerbar segments |
|
|
441
|
+
| Isolation | worktree/fuse-overlay/patch | worktree (planned) |
|
|
442
|
+
| Tool control | Agent frontmatter `tools[]` | Agent frontmatter (new) |
|
|
443
|
+
| Output | yield tool (enforced) | exit code + stdout |
|
|
444
|
+
| Recursion | maxRecursionDepth + spawns[] | N/A |
|
|
445
|
+
| Streaming | AgentEvent subscription | JSON stdout parsing |
|
|
446
|
+
| Steering | steer()/followUp() queues | cancel/respond commands |
|
|
447
|
+
| Agent registry | Process-global singleton | Per-run manifest |
|
|
448
|
+
|
|
449
|
+
## 6. Applicable Patterns for pi-crew
|
|
450
|
+
|
|
451
|
+
### Priority 1 (High Impact — Giảm flicker UI)
|
|
452
|
+
1. **Progress coalescing** → 150ms debounce cho task progress events (tránh render quá nhiều)
|
|
453
|
+
2. **Incremental transcript reading** → chỉ đọc bytes mới từ file JSONL, không đọc lại toàn bộ
|
|
454
|
+
3. **In-process event bus** → thay thế post-hoc file reading bằng real-time events (nếu chuyển sang in-process)
|
|
455
|
+
|
|
456
|
+
### Priority 2 (Medium Impact — Tăng khả năng coordination)
|
|
457
|
+
4. **Yield tool enforcement** → structured output submission thay vì parse stdout
|
|
458
|
+
5. **IRC-like messaging** → inter-subagent coordination (anti-deadlock side-channel)
|
|
459
|
+
6. **Ephemeral side-channel** → respondAsBackground() không cần recipient idle
|
|
460
|
+
|
|
461
|
+
### Priority 3 (Polish — UX tốt hơn)
|
|
462
|
+
7. **Entry-based observer** → expand/collapse per tool call trong transcript viewer
|
|
463
|
+
8. **Breadcrumb navigation** → nested subagent exploration (subagent spawn subagent)
|
|
464
|
+
9. **Auto-scroll with manual override** → stay at bottom unless user scrolled up
|
|
465
|
+
10. **Semaphore-based concurrency** → Semaphore class với acquire/release thay vì Promise.all limitation
|
|
466
|
+
11. **Context file sharing** → parent ghi context.md, child đọc được ngay
|
|
467
|
+
12. **MCP proxy tools** → subagent dùng lại parent's MCP connections không cần reconnect
|
|
468
|
+
|
|
469
|
+
## 7. Nguồn dữ liệu
|
|
470
|
+
|
|
471
|
+
Báo cáo này được tổng hợp từ:
|
|
472
|
+
- **Đọc trực tiếp**: executor.ts (1291 lines), types.ts (277 lines), agent-dashboard.ts (1120 lines), session-observer-overlay.ts (824 lines), agent-session.ts (partial), irc.ts, agent-registry.ts, session-observer-registry.ts, task/index.ts (1274 lines)
|
|
473
|
+
- **Research team**: 6 parallel agents (4 explorer shards + 1 analyst synthesis + 1 writer)
|
|
474
|
+
- 01_discover: Tổng quan kiến trúc
|
|
475
|
+
- 02_explore-shard-1: Steering & TUI pipeline
|
|
476
|
+
- 03_explore-shard-2: Lifecycle + Communication chi tiết
|
|
477
|
+
- 04_explore-shard-3: pi-subagents + isolation
|
|
478
|
+
- 05_synthesize: Tổng hợp phân tích
|
|
479
|
+
- 06_write: Báo cáo cuối cùng
|
|
480
|
+
- **Total tokens**: input=446K, output=41K, cacheRead=6.4M
|