pi-crew 0.1.45 → 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.
Files changed (178) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/README.md +5 -5
  3. package/agents/analyst.md +11 -11
  4. package/agents/critic.md +11 -11
  5. package/agents/executor.md +11 -11
  6. package/agents/explorer.md +11 -11
  7. package/agents/planner.md +11 -11
  8. package/agents/reviewer.md +11 -11
  9. package/agents/security-reviewer.md +11 -11
  10. package/agents/test-engineer.md +11 -11
  11. package/agents/verifier.md +11 -11
  12. package/agents/writer.md +11 -11
  13. package/docs/next-upgrade-roadmap.md +808 -0
  14. package/docs/research/AGENT-EXECUTION-ARCHITECTURE.md +261 -0
  15. package/docs/research/AGENT-LIFECYCLE-COMPARISON.md +111 -0
  16. package/docs/research/AUDIT_OH_MY_PI.md +261 -0
  17. package/docs/research/AUDIT_PI_CREW.md +457 -0
  18. package/docs/research/CAVEMAN-DEEP-RESEARCH.md +281 -0
  19. package/docs/research/COMPARISON_OH_MY_PI_VS_PI_CREW.md +264 -0
  20. package/docs/research/DEEP-RESEARCH-PI-POWERBAR.md +343 -0
  21. package/docs/research/DEEP_RESEARCH_SUBAGENT_ARCHITECTURE.md +480 -0
  22. package/docs/research/GAP_CLOSURE_IMPLEMENTATION_PLAN.md +354 -0
  23. package/docs/research/IMPLEMENTATION_PLAN.md +385 -0
  24. package/docs/research/LIVE-SESSION-PRODUCTION-READY-PLAN.md +502 -0
  25. package/docs/research/OH-MY-PI-DEEP-RESEARCH-v14.7.6.md +266 -0
  26. package/docs/research/REMAINING-GAPS-PLAN.md +363 -0
  27. package/docs/research/SESSION-SUMMARY-2026-05-08.md +146 -0
  28. package/docs/research/UI-RESPONSIVENESS-AUDIT.md +173 -0
  29. package/docs/research-awesome-agent-skills-distillation.md +100 -0
  30. package/docs/research-oh-my-pi-distillation.md +369 -0
  31. package/docs/source-runtime-refactor-map.md +24 -0
  32. package/docs/usage.md +3 -3
  33. package/install.mjs +52 -8
  34. package/package.json +99 -98
  35. package/schema.json +10 -1
  36. package/skills/async-worker-recovery/SKILL.md +42 -0
  37. package/skills/context-artifact-hygiene/SKILL.md +52 -0
  38. package/skills/delegation-patterns/SKILL.md +54 -0
  39. package/skills/mailbox-interactive/SKILL.md +40 -0
  40. package/skills/model-routing-context/SKILL.md +39 -0
  41. package/skills/multi-perspective-review/SKILL.md +58 -0
  42. package/skills/observability-reliability/SKILL.md +41 -0
  43. package/skills/orchestration/SKILL.md +157 -0
  44. package/skills/ownership-session-security/SKILL.md +41 -0
  45. package/skills/pi-extension-lifecycle/SKILL.md +39 -0
  46. package/skills/requirements-to-task-packet/SKILL.md +63 -0
  47. package/skills/resource-discovery-config/SKILL.md +41 -0
  48. package/skills/runtime-state-reader/SKILL.md +44 -0
  49. package/skills/secure-agent-orchestration-review/SKILL.md +45 -0
  50. package/skills/state-mutation-locking/SKILL.md +42 -0
  51. package/skills/systematic-debugging/SKILL.md +67 -0
  52. package/skills/ui-render-performance/SKILL.md +39 -0
  53. package/skills/verification-before-done/SKILL.md +57 -0
  54. package/skills/worktree-isolation/SKILL.md +39 -0
  55. package/src/agents/agent-config.ts +6 -0
  56. package/src/agents/agent-search.ts +98 -0
  57. package/src/agents/agent-serializer.ts +38 -34
  58. package/src/agents/discover-agents.ts +29 -15
  59. package/src/config/config.ts +72 -24
  60. package/src/config/defaults.ts +25 -0
  61. package/src/extension/autonomous-policy.ts +26 -33
  62. package/src/extension/help.ts +1 -0
  63. package/src/extension/management.ts +5 -0
  64. package/src/extension/project-init.ts +62 -2
  65. package/src/extension/register.ts +69 -22
  66. package/src/extension/registration/commands.ts +64 -25
  67. package/src/extension/registration/compaction-guard.ts +1 -1
  68. package/src/extension/registration/subagent-helpers.ts +8 -0
  69. package/src/extension/registration/subagent-tools.ts +149 -148
  70. package/src/extension/registration/team-tool.ts +14 -10
  71. package/src/extension/run-index.ts +35 -21
  72. package/src/extension/run-maintenance.ts +30 -5
  73. package/src/extension/team-tool/api.ts +47 -9
  74. package/src/extension/team-tool/cancel.ts +109 -5
  75. package/src/extension/team-tool/context.ts +8 -0
  76. package/src/extension/team-tool/intent-policy.ts +42 -0
  77. package/src/extension/team-tool/lifecycle-actions.ts +120 -79
  78. package/src/extension/team-tool/parallel-dispatch.ts +156 -0
  79. package/src/extension/team-tool/respond.ts +46 -18
  80. package/src/extension/team-tool/run.ts +55 -12
  81. package/src/extension/team-tool/status.ts +13 -2
  82. package/src/extension/team-tool-types.ts +3 -0
  83. package/src/extension/team-tool.ts +45 -14
  84. package/src/hooks/registry.ts +61 -0
  85. package/src/hooks/types.ts +41 -0
  86. package/src/observability/event-to-metric.ts +8 -1
  87. package/src/runtime/agent-control.ts +169 -63
  88. package/src/runtime/async-runner.ts +3 -1
  89. package/src/runtime/background-runner.ts +78 -53
  90. package/src/runtime/cancellation-token.ts +89 -0
  91. package/src/runtime/cancellation.ts +61 -0
  92. package/src/runtime/capability-inventory.ts +116 -0
  93. package/src/runtime/child-pi.ts +458 -444
  94. package/src/runtime/code-summary.ts +247 -0
  95. package/src/runtime/crash-recovery.ts +182 -0
  96. package/src/runtime/crew-agent-records.ts +70 -10
  97. package/src/runtime/crew-agent-runtime.ts +1 -0
  98. package/src/runtime/custom-tools/irc-tool.ts +201 -0
  99. package/src/runtime/custom-tools/submit-result-tool.ts +90 -0
  100. package/src/runtime/deadletter.ts +1 -0
  101. package/src/runtime/delivery-coordinator.ts +48 -25
  102. package/src/runtime/effectiveness.ts +81 -0
  103. package/src/runtime/event-stream-bridge.ts +90 -0
  104. package/src/runtime/live-agent-control.ts +2 -1
  105. package/src/runtime/live-agent-manager.ts +179 -85
  106. package/src/runtime/live-control-realtime.ts +1 -1
  107. package/src/runtime/live-extension-bridge.ts +150 -0
  108. package/src/runtime/live-irc.ts +92 -0
  109. package/src/runtime/live-session-health.ts +100 -0
  110. package/src/runtime/live-session-runtime.ts +599 -305
  111. package/src/runtime/manifest-cache.ts +17 -2
  112. package/src/runtime/mcp-proxy.ts +113 -0
  113. package/src/runtime/model-fallback.ts +6 -4
  114. package/src/runtime/notebook-helpers.ts +90 -0
  115. package/src/runtime/orphan-sentinel.ts +7 -0
  116. package/src/runtime/output-validator.ts +187 -0
  117. package/src/runtime/parallel-utils.ts +57 -0
  118. package/src/runtime/parent-guard.ts +80 -0
  119. package/src/runtime/pi-args.ts +18 -3
  120. package/src/runtime/process-status.ts +5 -1
  121. package/src/runtime/prose-compressor.ts +164 -0
  122. package/src/runtime/result-extractor.ts +121 -0
  123. package/src/runtime/retry-executor.ts +81 -64
  124. package/src/runtime/runtime-resolver.ts +23 -10
  125. package/src/runtime/semaphore.ts +131 -0
  126. package/src/runtime/sensitive-paths.ts +92 -0
  127. package/src/runtime/skill-instructions.ts +222 -0
  128. package/src/runtime/stale-reconciler.ts +4 -14
  129. package/src/runtime/stream-preview.ts +177 -0
  130. package/src/runtime/subagent-manager.ts +6 -2
  131. package/src/runtime/subprocess-tool-registry.ts +67 -0
  132. package/src/runtime/task-output-context.ts +177 -127
  133. package/src/runtime/task-runner/capabilities.ts +78 -0
  134. package/src/runtime/task-runner/live-executor.ts +107 -101
  135. package/src/runtime/task-runner/prompt-builder.ts +72 -8
  136. package/src/runtime/task-runner/prompt-pipeline.ts +64 -0
  137. package/src/runtime/task-runner/run-projection.ts +104 -0
  138. package/src/runtime/task-runner.ts +115 -5
  139. package/src/runtime/team-runner.ts +134 -19
  140. package/src/runtime/workspace-tree.ts +298 -0
  141. package/src/runtime/yield-handler.ts +189 -0
  142. package/src/schema/config-schema.ts +7 -0
  143. package/src/schema/team-tool-schema.ts +14 -4
  144. package/src/skills/discover-skills.ts +67 -0
  145. package/src/state/active-run-registry.ts +167 -0
  146. package/src/state/artifact-store.ts +4 -1
  147. package/src/state/atomic-write.ts +50 -1
  148. package/src/state/blob-store.ts +117 -0
  149. package/src/state/contracts.ts +2 -1
  150. package/src/state/event-log-rotation.ts +158 -0
  151. package/src/state/event-log.ts +52 -2
  152. package/src/state/mailbox.ts +129 -9
  153. package/src/state/state-store.ts +32 -5
  154. package/src/state/types.ts +64 -2
  155. package/src/teams/team-config.ts +1 -0
  156. package/src/ui/agent-management-overlay.ts +144 -0
  157. package/src/ui/crew-widget.ts +15 -5
  158. package/src/ui/dashboard-panes/cancellation-pane.ts +43 -0
  159. package/src/ui/dashboard-panes/capability-pane.ts +60 -0
  160. package/src/ui/dashboard-panes/mailbox-pane.ts +35 -11
  161. package/src/ui/dashboard-panes/progress-pane.ts +2 -0
  162. package/src/ui/live-run-sidebar.ts +4 -0
  163. package/src/ui/powerbar-publisher.ts +77 -15
  164. package/src/ui/render-coalescer.ts +51 -0
  165. package/src/ui/run-dashboard.ts +4 -0
  166. package/src/ui/run-event-bus.ts +209 -0
  167. package/src/ui/run-snapshot-cache.ts +78 -18
  168. package/src/ui/snapshot-types.ts +10 -0
  169. package/src/ui/transcript-entries.ts +258 -0
  170. package/src/utils/ids.ts +5 -0
  171. package/src/utils/incremental-reader.ts +104 -0
  172. package/src/utils/paths.ts +4 -2
  173. package/src/utils/scan-cache.ts +137 -0
  174. package/src/utils/sse-parser.ts +134 -0
  175. package/src/utils/task-name-generator.ts +337 -0
  176. package/src/utils/visual.ts +33 -2
  177. package/src/workflows/workflow-config.ts +1 -0
  178. package/src/worktree/cleanup.ts +2 -1
@@ -0,0 +1,266 @@
1
+ # oh-my-pi Deep Research — v14.7.6 (2026-05-08)
2
+
3
+ **Pull**: `df07e8a5a..7632117de` (55 files, +906/-249 lines)
4
+ **Scope**: Phân tích toàn diện tất cả modules, đặc biệt new features
5
+
6
+ ---
7
+
8
+ ## 🔴 CRITICAL: oh-my-pi là IN-PROCESS, không phải child process
9
+
10
+ ```typescript
11
+ // executor.ts line 961
12
+ const { session } = await createAgentSession({ ... });
13
+ await session.prompt(task, { attribution: "agent" });
14
+ // → Subagent chạy TRONG CÙNG PROCESS với parent!
15
+ // → Parent chết → child chết ngay lập tức (OS guarantee)
16
+ // → KHÔNG cần sentinel, watchdog, hay parent-guard gì cả
17
+ ```
18
+
19
+ **Đây là lý do oh-my-pi không cần orphan cleanup:**
20
+ - oh-my-pi: `Agent` objects in-process → process.exit() = all dead
21
+ - pi-crew: Worker processes separate → need parent-guard
22
+
23
+ **pi-crew KHÔNG THỂ** đổi sang in-process vì:
24
+ - Extension-based architecture (cannot embed in Pi's process)
25
+ - pi-crew is a Pi extension, not a built-in
26
+ - Must remain child-process for isolation
27
+
28
+ → **parent-guard.ts là giải pháp ĐÚNG cho pi-crew**
29
+
30
+ ---
31
+
32
+ ## 📦 New Features trong v14.7.x
33
+
34
+ ### 1. `agentsMdSearch` + `workspaceTree` Passthrough
35
+ ```typescript
36
+ // sdk.ts - Subagents inherit pre-scanned workspace data
37
+ createAgentSession({
38
+ agentsMdSearch: resolvedAgentsMdSearch, // skip re-scan
39
+ workspaceTree: resolvedWorkspaceTree, // skip re-scan
40
+ });
41
+ ```
42
+ - **Lợi ích**: Subagent startup nhanh hơn (không scan lại filesystem)
43
+ - **pi-crew cần**: Pass `AGENTS.md` content + workspace tree qua env/args
44
+
45
+ ### 2. `loop-limit.ts` — Iteration/Duration Limits
46
+ ```typescript
47
+ // /loop 10 hoặc /loop 10m
48
+ parseLoopLimitArgs("10m") // → { kind: "duration", durationMs: 600_000 }
49
+ parseLoopLimitArgs("3") // → { kind: "iterations", iterations: 3 }
50
+
51
+ consumeLoopLimitIteration(limit); // returns false when exhausted
52
+ isLoopDurationExpired(limit); // checks duration deadline
53
+ ```
54
+ - **Auto-submit**: 800ms delay after each turn, Esc cancels iteration
55
+ - **pi-crew có thể dùng**: Giới hạn số lần agent auto-repeat
56
+
57
+ ### 3. `hideThinkingSummary` trong provider config
58
+ ```typescript
59
+ // sdk.ts line 1655
60
+ hideThinkingSummary: settings.get("hideThinkingBlock"),
61
+ ```
62
+ - **pi-crew cần**: Pass qua `modelConfig.hideThinkingSummary`
63
+
64
+ ### 4. `rewriteStaticImports()` — ESM trong Code Eval
65
+ ```typescript
66
+ // context-manager.ts - Tự động rewrite:
67
+ import { foo } from "bar"; // → const { foo } = await import("bar");
68
+ import * as ns from "x"; // → const ns = await import("x");
69
+ import default from "y"; // → const default = (await import("y")).default;
70
+ ```
71
+ - User có thể paste ESM imports verbatim trong code eval
72
+ - **pi-crew chưa có**: JS executor cần integrate
73
+
74
+ ### 5. `openai-completions-compat.ts` — 30+ Provider Handling
75
+ - Handles: Cerebras, Zai, Kilo, DeepSeek V4, Alibaba, Qwen, GitHub Copilot, Zenmux
76
+ - `detectOpenAICompat()` — auto-detect strict mode support
77
+ - `detectStrictModeSupport()` — provider + URL matching
78
+ - **pi-crew nên**: Học cách detect model capabilities từ provider
79
+
80
+ ### 6. `scrubProcessEnv()` — macOS malloc fix
81
+ ```typescript
82
+ // procmgr.ts
83
+ export function scrubProcessEnv(): void {
84
+ delete process.env.MallocStackLogging;
85
+ delete process.env.MallocStackLoggingNoCompact;
86
+ }
87
+ ```
88
+ - Fixes stderr spam từ macOS debug-attach shells
89
+ - **pi-crew nên**: Add vào `child-pi.ts` hoặc `background-runner.ts`
90
+
91
+ ### 7. Fetch URL line selector syntax change
92
+ ```
93
+ # TRƯỚC: https://example.com:L50
94
+ # SAU: https://example.com/:50
95
+ # hoặc: https://example.com/:50-100
96
+ # hoặc: https://example.com/:raw
97
+ ```
98
+ - **pi-crew nên**: Cập nhật fetch tool để hỗ trợ `:50` thay vì `L50`
99
+
100
+ ### 8. Abort race optimization
101
+ ```typescript
102
+ // agent-loop.ts - Single abort race per event
103
+ const abortRacePromise = new Promise<void>(resolve => {
104
+ abortSignal.addEventListener("abort", () => resolve(), { once: true });
105
+ });
106
+ await Promise.race([iterator.next(), abortRacePromise]);
107
+ ```
108
+ - Thay vì add/remove listener cho mỗi event → dùng 1 race promise
109
+ - **pi-crew nên**: Học pattern này cho AbortSignal handling
110
+
111
+ ---
112
+
113
+ ## 🎯 Architecture Patterns từ oh-my-pi
114
+
115
+ ### 1. Async Job Delivery (pi-crew đang làm G4)
116
+ ```typescript
117
+ // sdk.ts line 938
118
+ await session.sendCustomMessage(
119
+ { customType: "async-result", content: message, ... },
120
+ { deliverAs: "followUp", triggerTurn: true }
121
+ );
122
+ ```
123
+ - ✅ pi-crew đã làm tương tự trong G4 (`sendCustomMessage` với `deliverAs: "followUp"`)
124
+
125
+ ### 2. Yield Enforcement
126
+ ```typescript
127
+ // executor.ts - toolChoice to force yield
128
+ await session.prompt(reminder, {
129
+ toolChoice: buildNamedToolChoice(["yield"])
130
+ });
131
+ ```
132
+ - ✅ pi-crew đã làm trong G6 (setActiveToolsByName trước reminder)
133
+
134
+ ### 3. Semaphore Pattern
135
+ ```typescript
136
+ // parallel.ts
137
+ const semaphore = new Semaphore(maxConcurrency);
138
+ await semaphore.acquire();
139
+ // ... do work
140
+ semaphore.release();
141
+ ```
142
+ - ✅ pi-crew đã implement trong Phase 6
143
+
144
+ ### 4. mapWithConcurrencyLimit Fail-Fast
145
+ ```typescript
146
+ // parallel.ts
147
+ mapWithConcurrencyLimit(tasks, max, runTask, signal);
148
+ ```
149
+ - On first error → abort all workers via internal AbortController
150
+ - ✅ pi-crew đã implement fail-fast trong Phase 6
151
+
152
+ ### 5. Session Disposal Timeout
153
+ ```typescript
154
+ // executor.ts
155
+ untilAborted(AbortSignal.timeout(5000), () => session.dispose());
156
+ ```
157
+ - Drain with timeout → force dispose
158
+ - **pi-crew cần**: Thêm timeout cho session disposal
159
+
160
+ ---
161
+
162
+ ## 📊 Parity Update
163
+
164
+ | Feature | oh-my-pi | pi-crew | Status |
165
+ |---------|----------|---------|--------|
166
+ | In-process execution | ✅ | ❌ (child processes) | pi-crew cần parent-guard |
167
+ | agentsMdSearch passthrough | ✅ | ❌ | Ghi nhớ |
168
+ | workspaceTree passthrough | ✅ | ❌ | Ghi nhớ |
169
+ | Loop limit (/loop) | ✅ | ❌ | Low priority |
170
+ | rewriteStaticImports | ✅ | ❌ | JS executor |
171
+ | hideThinkingSummary | ✅ | ❌ | Model config |
172
+ | Async job delivery | ✅ | ✅ | Done (G4) |
173
+ | Yield enforcement | ✅ | ✅ | Done (G6) |
174
+ | Semaphore fail-fast | ✅ | ✅ | Done (Phase 6) |
175
+ | scrubProcessEnv | ✅ | ❌ | Nice to have |
176
+ | Abort race optimization | ✅ | Partial | Low priority |
177
+
178
+ ---
179
+
180
+ ## 🎯 Action Items từ Research Mới
181
+
182
+ ### P0 (Highest Priority)
183
+ 1. ✅ **parent-guard.ts** — ĐÃ LÀM, đúng design
184
+ 2. ✅ **purgeStaleActiveRunIndex** — ĐÃ LÀM, đúng design
185
+
186
+ ### P1 (High Value)
187
+ 3. **scrubProcessEnv()** — Add vào background-runner.ts
188
+ ```typescript
189
+ // Remove macOS malloc vars
190
+ delete process.env.MallocStackLogging;
191
+ delete process.env.MallocStackLoggingNoCompact;
192
+ ```
193
+
194
+ ### P2 (Medium Value)
195
+ 4. **Fetch URL syntax** — Cập nhật `:50` thay vì `L50`
196
+ 5. **rewriteStaticImports** — JS executor enhancement
197
+
198
+ ### P3 (Nice to Have)
199
+ 6. **Abort race optimization** — Đã có trong abort-controller
200
+ 7. **Loop limit** — Low priority cho pi-crew
201
+
202
+ ---
203
+
204
+ ## 🔍 Chi Tiết Kỹ Thuật
205
+
206
+ ### oh-my-pi's Session Architecture (7500-line class!)
207
+ - `#handleAgentEvent` — single handler for all events
208
+ - TTSR (Time-Traveling Stream Rules) — pattern abort + inject
209
+ - Auto-compaction on `agent_end` when context > threshold
210
+ - Auto-retry với exponential backoff + model fallback
211
+ - Streaming edit abort for auto-generated files
212
+ - `#cancelPostPromptTasks()` — cleanup background tasks
213
+
214
+ ### TaskTool Dispatch Flow
215
+ ```
216
+ TaskTool.execute(tasks, signal, onUpdate)
217
+ → discoverAgents(cwd, scope)
218
+ → resolveIsolationBackend(worktree/fuse/projfs)
219
+ → for each task:
220
+ → ensureWorktree/ensureFuseOverlay/ensureProjfsOverlay
221
+ → createAgentSession()
222
+ → session.prompt(task, { attribution: "agent" })
223
+ → waitForIdle()
224
+ → check yieldCalled → retry up to 3x
225
+ → finalization (truncation, schema validation)
226
+ → cleanup isolation dir (finally block)
227
+ ```
228
+
229
+ ### Async Job Lifecycle
230
+ ```
231
+ register(type, label, run, options)
232
+ → AbortController + Job ID
233
+ → run() with signal + reportProgress
234
+ → on complete: job.status = "completed"
235
+ → delivery: sendCustomMessage({ deliverAs: "followUp" })
236
+ → eviction timer after retentionMs
237
+ ```
238
+
239
+ ---
240
+
241
+ ## 📝 Files Changed trong v14.7.x (New)
242
+
243
+ | File | Description |
244
+ |------|-------------|
245
+ | `modes/loop-limit.ts` | NEW — iteration/duration limits |
246
+ | `eval/js/context-manager.ts` | rewriteStaticImports, buildRequire |
247
+ | `tools/fetch.ts` | URL line range syntax change |
248
+ | `sdk.ts` | agentsMdSearch + workspaceTree passthrough |
249
+ | `agent.ts` | hideThinkingSummary |
250
+ | `providers/openai-completions-compat.ts` | 30+ provider compatibility |
251
+ | `providers/openai-completions.ts` | tool strict mode handling |
252
+ | `system-prompt.ts` | ordered systemPrompt arrays |
253
+ | `procmgr.ts` | scrubProcessEnv() |
254
+ | `interactive-mode.ts` | loop mode integration |
255
+
256
+ ---
257
+
258
+ ## ✅ Confirmation: pi-crew Design đúng
259
+
260
+ 1. **parent-guard.ts**: ĐÚNG — vì pi-crew dùng child processes, không thể in-process
261
+ 2. **purgeStaleActiveRunIndex**: ĐÚNG — cleanup file-level state
262
+ 3. **G4 Async IRC**: ĐÚNG — sendCustomMessage deliverAs pattern
263
+ 4. **G6 Yield Enforcement**: ĐÚNG — toolChoice workaround
264
+ 5. **Phase 6 Semaphore**: ĐÚNG — fail-fast pattern
265
+
266
+ **Không có gì phải thay đổi trong design hiện tại.**
@@ -0,0 +1,363 @@
1
+ # Remaining Gaps Plan — pi-crew Live-Session → Production Parity
2
+
3
+ > **Ngày tạo**: 2026-05-08
4
+ > **Prerequisite**: Phases 0-8 đã hoàn thành (991/994 tests pass, typecheck clean)
5
+ > **Mục tiêu**: Đóng 6 gap còn lại để đạt **≥90% parity** với oh-my-pi
6
+
7
+ ---
8
+
9
+ ## Gap Analysis Summary
10
+
11
+ | # | Gap | Parity | Effort | Priority | Status |
12
+ |---|-----|--------|--------|----------|--------|
13
+ | G1 | Custom Tool Injection (Yield + IRC) | **100%** | 3-4d | P0 | ✅ Done |
14
+ | G2 | MCP Proxy (functional) | **70%** | 3-5d | P1 | ✅ Done |
15
+ | G3 | AJV Schema Validation | **100%** | 2d | P2 | ✅ Done |
16
+ | G4 | respondAsBackground (non-blocking IRC) | **70%** | 5-7d | P3 | ✅ Done |
17
+ | G5 | Extension Runner Integration Test | **90%** | 2-3d | P2 | ✅ Done |
18
+ | G6 | toolChoice enforcement for yield | **80%** | 1-2d | P3 | ✅ Done |
19
+
20
+ ---
21
+
22
+ ## G1: Custom Tool Injection (Yield + IRC as real tools)
23
+
24
+ ### Vấn đề
25
+ - Workers chạy live-session **không thấy** `submit_result` tool hay `irc` tool
26
+ - oh-my-pi inject các tools này qua `createAgentSession({ customTools: [...] })`
27
+ - Pi SDK **có hỗ trợ**: `createAgentSession({ customTools: ToolDefinition[] })`
28
+
29
+ ### Pi SDK API đã xác nhận
30
+ ```typescript
31
+ // node_modules/@mariozechner/pi-coding-agent/dist/core/extensions/types.d.ts
32
+ interface ToolDefinition<TParams, TDetails, TState> {
33
+ name: string;
34
+ label: string;
35
+ description: string;
36
+ parameters: TSchema; // TypeBox schema
37
+ execute(toolCallId: string, params, signal, onUpdate, ctx): Promise<AgentToolResult>;
38
+ promptSnippet?: string;
39
+ promptGuidelines?: string[];
40
+ }
41
+
42
+ // Usage:
43
+ const session = await createAgentSession({
44
+ cwd,
45
+ customTools: [yieldTool, ircTool], // ← This is what oh-my-pi does
46
+ });
47
+ ```
48
+
49
+ ### Implementation Plan
50
+
51
+ #### Bước 1: Tạo `src/runtime/custom-tools/submit-result-tool.ts`
52
+ - Dùng `defineTool()` từ Pi SDK để tạo `submit_result` tool
53
+ - `parameters`: TypeBox schema `{ summary: string, artifacts?: Record<string,string>, structuredData?: object }`
54
+ - `execute()`: Lưu result vào callback/store, return success
55
+ - `promptSnippet`: "Submit your final result using submit_result"
56
+ - `promptGuidelines`: ["Always call submit_result when your task is complete"]
57
+
58
+ ```typescript
59
+ import { defineTool } from "@mariozechner/pi-coding-agent";
60
+ import { Type } from "@sinclair/typebox"; // already in SDK
61
+
62
+ export function createSubmitResultTool(onYield: (result: YieldResult) => void) {
63
+ return defineTool({
64
+ name: "submit_result",
65
+ label: "Submit Result",
66
+ description: "Submit your final result...",
67
+ parameters: Type.Object({
68
+ summary: Type.String({ description: "Summary of your work" }),
69
+ artifacts: Type.Optional(Type.Record(Type.String(), Type.String())),
70
+ structuredData: Type.Optional(Type.Record(Type.String(), Type.Unknown())),
71
+ }),
72
+ async execute(toolCallId, params, _signal, _onUpdate, _ctx) {
73
+ onYield({ summary: params.summary, artifacts: params.artifacts, structuredData: params.structuredData, toolCallId });
74
+ return { content: [{ type: "text", text: "Result submitted successfully." }] };
75
+ },
76
+ promptSnippet: "Submit your task result when done",
77
+ promptGuidelines: ["Always call submit_result when your task is complete"],
78
+ });
79
+ }
80
+ ```
81
+
82
+ #### Bước 2: Tạo `src/runtime/custom-tools/irc-tool.ts`
83
+ - `parameters`: TypeBox schema `{ op: "send"|"list", to?: string, message?: string, awaitReply?: boolean }`
84
+ - `execute()`:
85
+ - `op=list` → trả về danh sách live agents (từ `listLiveAgents()`)
86
+ - `op=send` → route qua `sendIrcMessage()` / `broadcastIrcMessage()`
87
+ - `promptSnippet`: "Send messages to other live agents"
88
+
89
+ #### Bước 3: Update `live-session-runtime.ts`
90
+ - Import custom tools, inject qua `createAgentSession({ customTools: [...] })`
91
+ - Khi `submit_result` execute → set `yieldResult` + resolve promise
92
+ - Giảm yield enforcement loop vì `submit_result` là tool thật → model sẽ gọi nó
93
+
94
+ #### Bước 4: Update yield enforcement
95
+ - Thay vì detect `isYieldEvent()` từ JSON events → dùng callback từ `submit_result` tool
96
+ - Vẫn giữ reminder loop như fallback
97
+
98
+ ### Files cần thay đổi
99
+ | File | Action |
100
+ |------|--------|
101
+ | `src/runtime/custom-tools/submit-result-tool.ts` | **NEW** |
102
+ | `src/runtime/custom-tools/irc-tool.ts` | **NEW** |
103
+ | `src/runtime/live-session-runtime.ts` | Update: inject customTools |
104
+ | `src/runtime/yield-handler.ts` | Update: callback-based yield detection |
105
+
106
+ ### Test strategy
107
+ - Unit test `createSubmitResultTool` → verify onYield callback
108
+ - Unit test `createIrcTool` → verify routing
109
+ - Integration test: `PI_CREW_MOCK_LIVE_SESSION` mock phải work với custom tools
110
+
111
+ ---
112
+
113
+ ## G2: MCP Proxy (Functional)
114
+
115
+ ### Vấn đề
116
+ - `mcp-proxy.ts` hiện tại chỉ là placeholder → `discoverMcpToolsForProxy()` return `[]`
117
+ - oh-my-pi dùng `mcpManager.getTools()` + `createMCPProxyTools()` → inject as custom tools
118
+ - Pi SDK **không expose** `MCPManager` trực tiếp, nhưng có MCP tools trong session
119
+
120
+ ### Probe cần làm
121
+ 1. Kiểm tra xem Pi SDK session có MCP tools sau `bindExtensions()` không
122
+ 2. Nếu có → dùng `session.getActiveToolNames()` + `getToolDefinition()` để discover
123
+ 3. Nếu không → cần tạo proxy tools với connection sharing
124
+
125
+ ### Implementation Plan
126
+
127
+ #### Bước 1: Probe MCP availability
128
+ ```typescript
129
+ // Sau session.bindExtensions()
130
+ const activeTools = session.getActiveToolNames();
131
+ const mcpTools = activeTools.filter(n => n.startsWith("mcp__") || n.includes("__"));
132
+ ```
133
+
134
+ #### Bước 2: Nếu MCP tools đã available
135
+ - Chỉ cần `enableMCP: true` (hoặc không set) trong `createAgentSession`
136
+ - MCP proxy không cần thiết → session tự discover
137
+
138
+ #### Bước 3: Nếu MCP tools không available
139
+ - Tạo proxy tools dùng `session.sendCustomMessage()` hoặc direct MCP call
140
+ - Inject qua `customTools` array
141
+
142
+ #### Bước 4: Connection sharing (nếu cần)
143
+ - Parse parent's `.pi/mcp.json` config
144
+ - Tạo MCP client connections trong parent process
145
+ - Share qua custom tool wrappers
146
+
147
+ ### Files cần thay đổi
148
+ | File | Action |
149
+ |------|--------|
150
+ | `src/runtime/mcp-proxy.ts` | **REWRITE** — functional discovery |
151
+ | `src/runtime/live-session-runtime.ts` | Update: use real MCP proxy |
152
+
153
+ ---
154
+
155
+ ## G3: AJV Schema Validation
156
+
157
+ ### Vấn đề
158
+ - `validateYieldData()` hiện tại chỉ check basic types + required fields
159
+ - oh-my-pi dùng AJV (`ajv = new Ajv({ allErrors: true, strict: false })`) + `jtdToJsonSchema()`
160
+ - Thiếu: nested properties, pattern, enum, min/max, additionalProperties
161
+
162
+ ### Implementation Plan
163
+
164
+ #### Bước 1: Thêm AJV dependency
165
+ ```bash
166
+ cd pi-crew && npm install ajv
167
+ ```
168
+
169
+ #### Bước 2: Update `validateYieldData()` trong `yield-handler.ts`
170
+ ```typescript
171
+ import Ajv from "ajv";
172
+
173
+ const ajv = new Ajv({ allErrors: true, strict: false, logger: false });
174
+
175
+ export function validateYieldData(data: unknown, schema: unknown): SchemaValidationResult {
176
+ if (!schema) return { valid: true };
177
+ try {
178
+ const validate = ajv.compile(schema as object);
179
+ const valid = validate(data);
180
+ if (!valid) {
181
+ return { valid: false, error: ajv.errorsText(validate.errors) };
182
+ }
183
+ return { valid: true };
184
+ } catch {
185
+ // Fallback to lightweight validation
186
+ return lightweightValidate(data, schema);
187
+ }
188
+ }
189
+ ```
190
+
191
+ #### Bước 3: JTD → JSON Schema conversion (optional)
192
+ - Port `jtdToJsonSchema()` từ oh-my-pi nếu output schema dùng JTD format
193
+ - Hoặc yêu cầu caller pass JSON Schema trực tiếp
194
+
195
+ ### Files cần thay đổi
196
+ | File | Action |
197
+ |------|--------|
198
+ | `src/runtime/yield-handler.ts` | Update: AJV validation |
199
+ | `package.json` | Add: ajv dependency |
200
+
201
+ ---
202
+
203
+ ## G4: respondAsBackground (Non-blocking IRC)
204
+
205
+ ### Vấn đề
206
+ - oh-my-pi dùng `session.respondAsBackground()` → gửi tin nhắn mà **không block** recipient
207
+ - pi-crew hiện tại dùng `session.prompt()` → **có thể block** nếu recipient đang streaming
208
+ - Pi SDK có `sendCustomMessage({ deliverAs: "followUp" })` và `sendUserMessage({ deliverAs: "steer" })`
209
+
210
+ ### Pi SDK API đã xác nhận
211
+ ```typescript
212
+ // ExtensionContext
213
+ sendMessage(message, options?: { triggerTurn?, deliverAs?: "steer" | "followUp" | "nextTurn" }): void;
214
+ sendUserMessage(content, options?: { deliverAs?: "steer" | "followUp" }): void;
215
+ ```
216
+
217
+ ### Implementation Plan
218
+
219
+ #### Bước 1: Thử `deliverAs` option
220
+ ```typescript
221
+ // Non-blocking message injection
222
+ session.sendCustomMessage?.(
223
+ { customType: "irc", content: `[DM from ${from}] ${message}` },
224
+ { deliverAs: "followUp", triggerTurn: false }
225
+ );
226
+ ```
227
+
228
+ #### Bước 2: Fallback chain
229
+ 1. `sendCustomMessage({ deliverAs: "followUp" })` — ideal
230
+ 2. `sendUserMessage({ deliverAs: "steer" })` — less ideal, interrupts streaming
231
+ 3. `session.steer(message)` — basic, waits for current turn
232
+ 4. `session.prompt(message)` — blocking, last resort
233
+
234
+ #### Bước 3: Reply-waiting
235
+ - Nếu `awaitReply=true`:
236
+ - Inject message (non-blocking)
237
+ - Subscribe to events, filter for reply from target
238
+ - Timeout after configurable period
239
+
240
+ ### Files cần thay đổi
241
+ | File | Action |
242
+ |------|--------|
243
+ | `src/runtime/live-agent-manager.ts` | Update: non-blocking delivery |
244
+ | `src/runtime/live-irc.ts` | Update: reply-waiting logic |
245
+
246
+ ---
247
+
248
+ ## G5: Extension Runner Integration Verification
249
+
250
+ ### Vấn đề
251
+ - `live-extension-bridge.ts` đã build API bridge nhưng chưa test với SDK thật
252
+ - Cần verify: `extensionRunner.initialize(apis, host)` có hoạt động không
253
+ - Cần verify: event emission lifecycle
254
+
255
+ ### Implementation Plan
256
+
257
+ #### Bước 1: Tạo integration test
258
+ ```typescript
259
+ // test/integration/live-extension-bridge.test.ts
260
+ import { createAgentSession } from "@mariozechner/pi-coding-agent";
261
+
262
+ test("extension bridge initializes with real session", async () => {
263
+ const session = await createAgentSession({ cwd: tmpdir() });
264
+ // Probe extensionRunner
265
+ const runner = (session as any).extensionRunner;
266
+ // Verify bridge APIs match
267
+ });
268
+ ```
269
+
270
+ #### Bước 2: Fix bridge APIs based on actual SDK shape
271
+ - `session.sessionManager` → check methods
272
+ - `session.model` → check getter
273
+ - `session.getContextUsage()` → check return type
274
+
275
+ #### Bước 3: Add extension lifecycle tests
276
+ - `session_start` event
277
+ - Tool registration via extension
278
+ - `session_shutdown` event
279
+
280
+ ### Files cần thay đổi
281
+ | File | Action |
282
+ |------|--------|
283
+ | `src/runtime/live-extension-bridge.ts` | Fix: match actual SDK API |
284
+ | `test/integration/` | **NEW**: integration tests |
285
+
286
+ ---
287
+
288
+ ## G6: toolChoice Enforcement for Yield
289
+
290
+ ### Vấn đề
291
+ - oh-my-pi dùng `buildNamedToolChoice("yield")` → ép model gọi yield tool
292
+ - Pi SDK `prompt()` **không có** `toolChoice` option
293
+ - Giải pháp thay thế: sử dụng system prompt + reminder
294
+
295
+ ### Probe cần làm
296
+ 1. Check nếu Pi SDK thêm `toolChoice` trong tương lai
297
+ 2. Check `session.setActiveToolsByName(["submit_result"])` trước reminder prompt
298
+
299
+ ### Implementation Plan
300
+
301
+ #### Workaround: Constrained tool set
302
+ ```typescript
303
+ // Trước khi gửi yield reminder:
304
+ const prevTools = session.getActiveToolNames();
305
+ session.setActiveToolsByName(["submit_result"]); // Chỉ cho tool này
306
+ await session.prompt(reminder, { source: "api" });
307
+ session.setActiveToolsByName(prevTools); // Restore
308
+ ```
309
+
310
+ #### Future: Khi SDK hỗ trợ toolChoice
311
+ ```typescript
312
+ await session.prompt(reminder, {
313
+ source: "api",
314
+ toolChoice: { type: "tool", name: "submit_result" }
315
+ });
316
+ ```
317
+
318
+ ### Files cần thay đổi
319
+ | File | Action |
320
+ |------|--------|
321
+ | `src/runtime/live-session-runtime.ts` | Update: constrained tool set before reminder |
322
+
323
+ ---
324
+
325
+ ## Execution Order
326
+
327
+ ```
328
+ Week 1: G1 (Custom Tool Injection) ← P0, unblocks G2+G4+G6
329
+ Week 1: G3 (AJV Schema Validation) ← P2, independent, quick
330
+ Week 2: G2 (MCP Proxy) ← P1, depends on G1's customTools pattern
331
+ Week 2: G6 (toolChoice Workaround) ← P3, depends on G1's submit_result tool
332
+ Week 2: G5 (Extension Runner Verify) ← P2, independent
333
+ Week 3: G4 (respondAsBackground) ← P3, depends on G1's IRC tool + G5's bridge
334
+ ```
335
+
336
+ ### Dependency Graph
337
+ ```
338
+ G1 ──► G2 (customTools pattern)
339
+ G1 ──► G4 (IRC tool delivery)
340
+ G1 ──► G6 (submit_result constraining)
341
+ G3 ──► (independent)
342
+ G5 ──► G4 (bridge APIs for sendCustomMessage)
343
+ ```
344
+
345
+ ### Expected Outcome After All Gaps
346
+ - **Parity**: ~90-95% với oh-my-pi
347
+ - **Yield**: 100% (real tool + AJV validation + toolChoice workaround)
348
+ - **IRC**: ~85% (real tool, delivery qua sendCustomMessage, reply-waiting)
349
+ - **MCP**: ~80% (proxy injection, connection sharing needs upstream)
350
+ - **Extensions**: ~90% (verified bridge, lifecycle tested)
351
+ - **Core unique**: 100% (fault isolation, file state, health monitoring, workflow DAG)
352
+
353
+ ---
354
+
355
+ ## Risks & Mitigations
356
+
357
+ | Risk | Probability | Impact | Mitigation |
358
+ |------|------------|--------|------------|
359
+ | Pi SDK `customTools` TypeBox import không compatible | Medium | High | Test ngay bước đầu; fallback: inline schema object |
360
+ | AJV bundle size | Low | Low | Tree-shake; AJV ~30KB gzipped |
361
+ | `sendCustomMessage` không hoạt động ở background | Medium | Medium | Fallback sang `steer()` |
362
+ | ExtensionRunner không expose cho live-session | Medium | Medium | Graceful degradation, keep bridge as framework |
363
+ | `defineTool` signature thay đổi trong SDK update | Low | High | Pin SDK version, test trước khi upgrade |