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.
- package/CHANGELOG.md +97 -0
- package/README.md +5 -5
- 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 +808 -0
- 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 -0
- package/docs/research-oh-my-pi-distillation.md +369 -0
- package/docs/source-runtime-refactor-map.md +24 -0
- package/docs/usage.md +3 -3
- package/install.mjs +52 -8
- package/package.json +99 -98
- package/schema.json +10 -1
- package/skills/async-worker-recovery/SKILL.md +42 -0
- package/skills/context-artifact-hygiene/SKILL.md +52 -0
- package/skills/delegation-patterns/SKILL.md +54 -0
- package/skills/mailbox-interactive/SKILL.md +40 -0
- package/skills/model-routing-context/SKILL.md +39 -0
- package/skills/multi-perspective-review/SKILL.md +58 -0
- package/skills/observability-reliability/SKILL.md +41 -0
- package/skills/orchestration/SKILL.md +157 -0
- package/skills/ownership-session-security/SKILL.md +41 -0
- package/skills/pi-extension-lifecycle/SKILL.md +39 -0
- package/skills/requirements-to-task-packet/SKILL.md +63 -0
- package/skills/resource-discovery-config/SKILL.md +41 -0
- package/skills/runtime-state-reader/SKILL.md +44 -0
- package/skills/secure-agent-orchestration-review/SKILL.md +45 -0
- package/skills/state-mutation-locking/SKILL.md +42 -0
- package/skills/systematic-debugging/SKILL.md +67 -0
- package/skills/ui-render-performance/SKILL.md +39 -0
- package/skills/verification-before-done/SKILL.md +57 -0
- package/skills/worktree-isolation/SKILL.md +39 -0
- package/src/agents/agent-config.ts +6 -0
- package/src/agents/agent-search.ts +98 -0
- package/src/agents/agent-serializer.ts +38 -34
- package/src/agents/discover-agents.ts +29 -15
- package/src/config/config.ts +72 -24
- package/src/config/defaults.ts +25 -0
- package/src/extension/autonomous-policy.ts +26 -33
- package/src/extension/help.ts +1 -0
- package/src/extension/management.ts +5 -0
- package/src/extension/project-init.ts +62 -2
- package/src/extension/register.ts +69 -22
- package/src/extension/registration/commands.ts +64 -25
- package/src/extension/registration/compaction-guard.ts +1 -1
- package/src/extension/registration/subagent-helpers.ts +8 -0
- package/src/extension/registration/subagent-tools.ts +149 -148
- package/src/extension/registration/team-tool.ts +14 -10
- package/src/extension/run-index.ts +35 -21
- package/src/extension/run-maintenance.ts +30 -5
- package/src/extension/team-tool/api.ts +47 -9
- package/src/extension/team-tool/cancel.ts +109 -5
- package/src/extension/team-tool/context.ts +8 -0
- package/src/extension/team-tool/intent-policy.ts +42 -0
- package/src/extension/team-tool/lifecycle-actions.ts +120 -79
- package/src/extension/team-tool/parallel-dispatch.ts +156 -0
- package/src/extension/team-tool/respond.ts +46 -18
- package/src/extension/team-tool/run.ts +55 -12
- package/src/extension/team-tool/status.ts +13 -2
- package/src/extension/team-tool-types.ts +3 -0
- package/src/extension/team-tool.ts +45 -14
- package/src/hooks/registry.ts +61 -0
- package/src/hooks/types.ts +41 -0
- package/src/observability/event-to-metric.ts +8 -1
- package/src/runtime/agent-control.ts +169 -63
- package/src/runtime/async-runner.ts +3 -1
- package/src/runtime/background-runner.ts +78 -53
- package/src/runtime/cancellation-token.ts +89 -0
- package/src/runtime/cancellation.ts +61 -0
- package/src/runtime/capability-inventory.ts +116 -0
- package/src/runtime/child-pi.ts +458 -444
- package/src/runtime/code-summary.ts +247 -0
- package/src/runtime/crash-recovery.ts +182 -0
- package/src/runtime/crew-agent-records.ts +70 -10
- 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/deadletter.ts +1 -0
- package/src/runtime/delivery-coordinator.ts +48 -25
- package/src/runtime/effectiveness.ts +81 -0
- package/src/runtime/event-stream-bridge.ts +90 -0
- package/src/runtime/live-agent-control.ts +2 -1
- package/src/runtime/live-agent-manager.ts +179 -85
- package/src/runtime/live-control-realtime.ts +1 -1
- 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 +599 -305
- package/src/runtime/manifest-cache.ts +17 -2
- package/src/runtime/mcp-proxy.ts +113 -0
- package/src/runtime/model-fallback.ts +6 -4
- 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-utils.ts +57 -0
- package/src/runtime/parent-guard.ts +80 -0
- package/src/runtime/pi-args.ts +18 -3
- package/src/runtime/process-status.ts +5 -1
- package/src/runtime/prose-compressor.ts +164 -0
- package/src/runtime/result-extractor.ts +121 -0
- package/src/runtime/retry-executor.ts +81 -64
- package/src/runtime/runtime-resolver.ts +23 -10
- package/src/runtime/semaphore.ts +131 -0
- package/src/runtime/sensitive-paths.ts +92 -0
- package/src/runtime/skill-instructions.ts +222 -0
- package/src/runtime/stale-reconciler.ts +4 -14
- package/src/runtime/stream-preview.ts +177 -0
- package/src/runtime/subagent-manager.ts +6 -2
- package/src/runtime/subprocess-tool-registry.ts +67 -0
- package/src/runtime/task-output-context.ts +177 -127
- package/src/runtime/task-runner/capabilities.ts +78 -0
- package/src/runtime/task-runner/live-executor.ts +107 -101
- package/src/runtime/task-runner/prompt-builder.ts +72 -8
- package/src/runtime/task-runner/prompt-pipeline.ts +64 -0
- package/src/runtime/task-runner/run-projection.ts +104 -0
- package/src/runtime/task-runner.ts +115 -5
- package/src/runtime/team-runner.ts +134 -19
- package/src/runtime/workspace-tree.ts +298 -0
- package/src/runtime/yield-handler.ts +189 -0
- package/src/schema/config-schema.ts +7 -0
- package/src/schema/team-tool-schema.ts +14 -4
- package/src/skills/discover-skills.ts +67 -0
- package/src/state/active-run-registry.ts +167 -0
- 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 +2 -1
- package/src/state/event-log-rotation.ts +158 -0
- package/src/state/event-log.ts +52 -2
- package/src/state/mailbox.ts +129 -9
- package/src/state/state-store.ts +32 -5
- package/src/state/types.ts +64 -2
- package/src/teams/team-config.ts +1 -0
- package/src/ui/agent-management-overlay.ts +144 -0
- package/src/ui/crew-widget.ts +15 -5
- 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/progress-pane.ts +2 -0
- package/src/ui/live-run-sidebar.ts +4 -0
- package/src/ui/powerbar-publisher.ts +77 -15
- package/src/ui/render-coalescer.ts +51 -0
- package/src/ui/run-dashboard.ts +4 -0
- package/src/ui/run-event-bus.ts +209 -0
- package/src/ui/run-snapshot-cache.ts +78 -18
- package/src/ui/snapshot-types.ts +10 -0
- package/src/ui/transcript-entries.ts +258 -0
- package/src/utils/ids.ts +5 -0
- package/src/utils/incremental-reader.ts +104 -0
- package/src/utils/paths.ts +4 -2
- package/src/utils/scan-cache.ts +137 -0
- 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/workflow-config.ts +1 -0
- package/src/worktree/cleanup.ts +2 -1
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
# Plan: Live-Session Production-Ready
|
|
2
|
+
|
|
3
|
+
**Ngày**: 2026-05-08
|
|
4
|
+
**Mục tiêu**: Đưa live-session từ **experimental** → **production-ready**, học hỏi tối ưu từ oh-my-pi, giữ cốt lõi pi-crew (fault isolation, file-based state, extension-based architecture).
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Tình trạng hiện tại
|
|
9
|
+
|
|
10
|
+
### pi-crew live-session (hiện tại)
|
|
11
|
+
- **Status**: `PI_CREW_ENABLE_EXPERIMENTAL_LIVE_SESSION=1` → experimental
|
|
12
|
+
- **Code**: `live-session-runtime.ts` (~300 dòng), `live-executor.ts` (~100 dòng)
|
|
13
|
+
- **Đã có**: `createAgentSession()` in-process, event subscription, sidechain output, turn limits, steer/abort qua polling, `LiveAgentHandle` manager
|
|
14
|
+
- **Thiếu**: Yield enforcement, output schema validation, MCP proxy, fail-fast, AbortSignal, schema-based yield tool, extension runner
|
|
15
|
+
|
|
16
|
+
### oh-my-pi executor (tham chiếu)
|
|
17
|
+
- **Code**: `executor.ts` (~1291 dòng), `parallel.ts` (~110 dòng), `yield.ts` (~170 dòng)
|
|
18
|
+
- **Đã có**: Yield enforcement (while loop + 3 reminders + `toolChoice`), output schema validation (AJV), MCP proxy tools, IRC inter-agent, fail-fast + AbortSignal, extension runner, subprocess tool registry with `renderInline`/`renderFinal`
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Nguyên tắc thiết kế
|
|
23
|
+
|
|
24
|
+
1. **Giữ pi-crew core**: File-based state, child-process isolation, event log, manifest-based lifecycle
|
|
25
|
+
2. **Học oh-my-pi patterns**: Yield enforcement, schema validation, fail-fast — nhưng adapt cho extension-based architecture
|
|
26
|
+
3. **Incremental**: Mỗi phase tự stand-alone, không cần phase sau để hoạt động
|
|
27
|
+
4. **Backward compatible**: child-process mode không bị ảnh hưởng, live-session là opt-in
|
|
28
|
+
5. **Test coverage**: Mỗi phase thêm test cho live-session path
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Phases
|
|
33
|
+
|
|
34
|
+
### Phase 0: Foundation — Loại bỏ experimental flag (2-3 ngày)
|
|
35
|
+
|
|
36
|
+
**Mục tiêu**: Live-session hoạt động ổn định không cần flag, graceful fallback khi SDK không có.
|
|
37
|
+
|
|
38
|
+
**Files thay đổi**:
|
|
39
|
+
| File | Thay đổi |
|
|
40
|
+
|------|----------|
|
|
41
|
+
| `src/runtime/runtime-resolver.ts` | Bỏ yêu cầu `PI_CREW_ENABLE_EXPERIMENTAL_LIVE_SESSION=1`, chỉ check SDK export |
|
|
42
|
+
| `src/runtime/live-session-runtime.ts` | Hardening error messages, thêm `reason` chi tiết hơn |
|
|
43
|
+
| `src/config/defaults.ts` | Thêm `liveSession` defaults (probe timeout, session options) |
|
|
44
|
+
|
|
45
|
+
**Chi tiết**:
|
|
46
|
+
```
|
|
47
|
+
resolveCrewRuntime():
|
|
48
|
+
- "auto" mode: thử probe live-session SDK, fallback child-process
|
|
49
|
+
- "live-session" mode: probe SDK, fail gracefully nếu không có
|
|
50
|
+
- KHÔNG cần env flag nữa
|
|
51
|
+
- Giữ PI_CREW_MOCK_LIVE_SESSION cho test
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Acceptance**:
|
|
55
|
+
- [ ] `runtime.mode=live-session` hoạt động không cần env flag
|
|
56
|
+
- [ ] Fallback sang child-process khi SDK không có + log rõ ràng
|
|
57
|
+
- [ ] `runtime.mode=auto` ưu tiên child-process (không breaking change)
|
|
58
|
+
- [ ] Typecheck pass, existing tests pass
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
### Phase 1: Yield Enforcement (3-5 ngày) 🔥 QUICK WIN
|
|
63
|
+
|
|
64
|
+
**Mục tiêu**: Live-session worker PHẢI gọi `submit_result` để hoàn thành, giống oh-my-pi.
|
|
65
|
+
|
|
66
|
+
**Học từ oh-my-pi**:
|
|
67
|
+
```typescript
|
|
68
|
+
// oh-my-pi executor.ts — pattern cốt lõi
|
|
69
|
+
const MAX_YIELD_RETRIES = 3;
|
|
70
|
+
while (!yieldCalled && retryCount < MAX_YIELD_RETRIES && !abortSignal.aborted) {
|
|
71
|
+
const reminder = prompt.render(submitReminderTemplate, { retryCount, maxRetries: MAX_YIELD_RETRIES });
|
|
72
|
+
await session.prompt(reminder, { toolChoice: buildNamedToolChoice("yield", session.model) });
|
|
73
|
+
await session.waitForIdle();
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**pi-crew adaptation**: pi-crew không có `toolChoice` API, nên dùng prompt-based reminder.
|
|
78
|
+
|
|
79
|
+
**Files thay đổi**:
|
|
80
|
+
| File | Thay đổi |
|
|
81
|
+
|------|----------|
|
|
82
|
+
| `src/runtime/live-session-runtime.ts` | Thêm yield enforcement loop sau `session.prompt()` |
|
|
83
|
+
| `src/runtime/yield-handler.ts` | Export `extractYieldFromLiveEvents()` helper |
|
|
84
|
+
| `src/runtime/task-runner/live-executor.ts` | Pass `collectedJsonEvents` cho yield check |
|
|
85
|
+
|
|
86
|
+
**Code sketch** — `live-session-runtime.ts`:
|
|
87
|
+
```typescript
|
|
88
|
+
// Sau session.prompt() + session idle
|
|
89
|
+
|
|
90
|
+
// --- Yield enforcement ---
|
|
91
|
+
const yieldConfig = input.runtimeConfig?.yield ?? DEFAULT_YIELD_CONFIG;
|
|
92
|
+
let yieldResult: YieldResult | undefined;
|
|
93
|
+
let yieldAttempts = 0;
|
|
94
|
+
|
|
95
|
+
// Check if yield already happened during initial prompt
|
|
96
|
+
const collectedEvents: Record<string, unknown>[] = [];
|
|
97
|
+
// (populated during session.subscribe callback)
|
|
98
|
+
|
|
99
|
+
if (yieldConfig.enabled) {
|
|
100
|
+
yieldResult = checkYieldInEvents(collectedEvents);
|
|
101
|
+
|
|
102
|
+
while (!yieldResult && yieldAttempts < yieldConfig.maxReminders && !input.signal?.aborted) {
|
|
103
|
+
yieldAttempts++;
|
|
104
|
+
const reminder = buildYieldReminder(yieldAttempts, yieldConfig.maxReminders, yieldConfig.reminderPrompt);
|
|
105
|
+
await session.prompt?.(reminder, { source: "api", expandPromptTemplates: false });
|
|
106
|
+
// Wait for session to process (poll-based)
|
|
107
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
108
|
+
yieldResult = checkYieldInNewEvents(/* incremental events */);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (!yieldResult && !input.signal?.aborted) {
|
|
112
|
+
// Emit attention event — worker didn't yield
|
|
113
|
+
input.onEvent?.({ type: "task.attention", reason: "no_yield", attempts: yieldAttempts });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Acceptance**:
|
|
119
|
+
- [ ] Live-session worker gọi `submit_result` → task completed
|
|
120
|
+
- [ ] Worker KHÔNG gọi `submit_result` → nhận reminder → gọi → completed
|
|
121
|
+
- [ ] Worker gọi sau 3 reminders → task.attention event + status needs_attention
|
|
122
|
+
- [ ] Child-process mode không bị ảnh hưởng
|
|
123
|
+
- [ ] Test: mock live-session + yield scenarios
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
### Phase 2: Output Schema Validation (2-3 ngày)
|
|
128
|
+
|
|
129
|
+
**Mục tiêu**: Worker submit result phải match output schema (nếu có), giống oh-my-pi YieldTool.
|
|
130
|
+
|
|
131
|
+
**Học từ oh-my-pi**:
|
|
132
|
+
- `YieldTool` nhận `outputSchema` từ session config
|
|
133
|
+
- Validate data bằng AJV (JTD → JSON Schema conversion)
|
|
134
|
+
- Schema validation failure → throw error, model tự retry
|
|
135
|
+
- After 2 failures → override, accept anyway
|
|
136
|
+
|
|
137
|
+
**pi-crew adaptation**: pi-crew dùng `structuredData` trong `submit_result`, không có dedicated YieldTool class.
|
|
138
|
+
|
|
139
|
+
**Files thay đổi**:
|
|
140
|
+
| File | Thay đổi |
|
|
141
|
+
|------|----------|
|
|
142
|
+
| `src/runtime/yield-handler.ts` | Thêm `validateYieldData()` với optional schema |
|
|
143
|
+
| `src/runtime/live-session-runtime.ts` | Pass schema từ agent config, validate trước khi accept |
|
|
144
|
+
| `src/agents/agent-config.ts` | Thêm `outputSchema?: unknown` field |
|
|
145
|
+
| `src/config/config.ts` | Thêm `yield.schemaValidation` config |
|
|
146
|
+
|
|
147
|
+
**Code sketch**:
|
|
148
|
+
```typescript
|
|
149
|
+
// yield-handler.ts
|
|
150
|
+
export function validateYieldData(data: unknown, schema: unknown): { valid: boolean; error?: string } {
|
|
151
|
+
if (!schema) return { valid: true };
|
|
152
|
+
// Convert JTD → JSON Schema if needed
|
|
153
|
+
// Validate with AJV (or lightweight alternative)
|
|
154
|
+
// Return validation result
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Acceptance**:
|
|
159
|
+
- [ ] Agent có `outputSchema` → submit_result data phải match
|
|
160
|
+
- [ ] Validation fail → reminder prompt với error details
|
|
161
|
+
- [ ] Sau 2 failures → accept anyway + warning
|
|
162
|
+
- [ ] Không có schema → không validate (backward compatible)
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
### Phase 3: AbortSignal & Graceful Cancellation (2-3 ngày)
|
|
167
|
+
|
|
168
|
+
**Mục tiêu**: Live-session hỗ trợ AbortSignal, cancellation, timeout — giống child-process mode.
|
|
169
|
+
|
|
170
|
+
**Học từ oh-my-pi**:
|
|
171
|
+
```typescript
|
|
172
|
+
// executor.ts
|
|
173
|
+
const abortController = new AbortController();
|
|
174
|
+
const abortSignal = abortController.signal;
|
|
175
|
+
signal.addEventListener("abort", onAbort, { once: true, signal: listenerSignal });
|
|
176
|
+
// Session abort → cleanup → return partial results
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**pi-crew hiện tại**: Đã có signal propagation (`input.signal → session.abort()`) nhưng:
|
|
180
|
+
- Không có timeout cho individual session operations
|
|
181
|
+
- Không return partial results
|
|
182
|
+
- Không có graceful cleanup sequence
|
|
183
|
+
|
|
184
|
+
**Files thay đổi**:
|
|
185
|
+
| File | Thay đổi |
|
|
186
|
+
|------|----------|
|
|
187
|
+
| `src/runtime/live-session-runtime.ts` | Thêm session timeout, partial results, cleanup sequence |
|
|
188
|
+
| `src/runtime/task-runner/live-executor.ts` | Handle partial results |
|
|
189
|
+
| `src/config/defaults.ts` | Thêm `liveSession.responseTimeoutMs` |
|
|
190
|
+
|
|
191
|
+
**Code sketch**:
|
|
192
|
+
```typescript
|
|
193
|
+
// live-session-runtime.ts
|
|
194
|
+
const SESSION_TIMEOUT_MS = runtimeConfig?.liveSession?.responseTimeoutMs ?? 300_000; // 5 min
|
|
195
|
+
|
|
196
|
+
// Wrap session.prompt with timeout
|
|
197
|
+
const promptPromise = session.prompt?.(effectivePrompt, ...);
|
|
198
|
+
const timeoutPromise = new Promise((_, reject) =>
|
|
199
|
+
setTimeout(() => reject(new Error("Session timeout")), SESSION_TIMEOUT_MS)
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
await Promise.race([promptPromise, timeoutPromise]);
|
|
204
|
+
} catch (error) {
|
|
205
|
+
if (error.message === "Session timeout") {
|
|
206
|
+
await session.abort?.();
|
|
207
|
+
return { available: true, exitCode: 1, stdout, stderr: "Session timeout", jsonEvents,
|
|
208
|
+
error: "Session timeout", partialOutput: stdout };
|
|
209
|
+
}
|
|
210
|
+
throw error;
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Acceptance**:
|
|
215
|
+
- [ ] Signal abort → session.abort() → partial results → clean exit
|
|
216
|
+
- [ ] Session timeout → abort → return partial results
|
|
217
|
+
- [ ] No zombie sessions sau abort
|
|
218
|
+
- [ ] Cleanup: unsubscribe, clearInterval, updateLiveAgentStatus
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
### Phase 4: MCP Proxy cho Live-Session (3-5 ngày)
|
|
223
|
+
|
|
224
|
+
**Mục tiêu**: Live-session worker dùng parent's MCP connections, không tự discover.
|
|
225
|
+
|
|
226
|
+
**Học từ oh-my-pi**:
|
|
227
|
+
```typescript
|
|
228
|
+
// executor.ts — createMCPProxyTools()
|
|
229
|
+
function createMCPProxyTools(mcpManager: MCPManager): CustomTool<TSchema>[] {
|
|
230
|
+
return mcpManager.getTools().map(tool => ({
|
|
231
|
+
name: tool.name,
|
|
232
|
+
execute: async (_id, params, _onUpdate, _ctx, signal) => {
|
|
233
|
+
const connection = await mcpManager.waitForConnection(serverName);
|
|
234
|
+
return callTool(connection, mcpToolName, params, { signal });
|
|
235
|
+
},
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**pi-crew challenge**: Pi SDK's `createAgentSession` không nhận `customTools`. Cần tìm API đúng.
|
|
241
|
+
|
|
242
|
+
**Approach**:
|
|
243
|
+
1. Probe SDK cho `bindExtensions` hoặc tool injection API
|
|
244
|
+
2. Nếu có: inject MCP proxy tools qua SDK API
|
|
245
|
+
3. Nếu không: dùng `setActiveToolsByName` + event interception
|
|
246
|
+
|
|
247
|
+
**Files thay đổi**:
|
|
248
|
+
| File | Thay đổi |
|
|
249
|
+
|------|----------|
|
|
250
|
+
| `src/runtime/live-session-runtime.ts` | Thêm MCP proxy tool injection |
|
|
251
|
+
| `src/runtime/mcp-proxy.ts` | NEW — Tạo MCP proxy tools từ parent's MCP config |
|
|
252
|
+
| `src/config/config.ts` | Thêm `runtime.liveSession.shareMcp: boolean` |
|
|
253
|
+
|
|
254
|
+
**Acceptance**:
|
|
255
|
+
- [ ] Live-session worker thấy parent's MCP tools
|
|
256
|
+
- [ ] MCP calls đi qua parent's connections
|
|
257
|
+
- [ ] MCP call failure → graceful error, không crash session
|
|
258
|
+
- [ ] Child-process mode không bị ảnh hưởng
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
### Phase 5: Extension Runner cho Live-Session (5-7 ngày) 🏗️
|
|
263
|
+
|
|
264
|
+
**Mục tiêu**: Live-session worker có đầy đủ extension lifecycle giống oh-my-pi.
|
|
265
|
+
|
|
266
|
+
**Học từ oh-my-pi**:
|
|
267
|
+
```typescript
|
|
268
|
+
// executor.ts — extension initialization
|
|
269
|
+
const extensionRunner = session.extensionRunner;
|
|
270
|
+
if (extensionRunner) {
|
|
271
|
+
extensionRunner.initialize({
|
|
272
|
+
sendMessage: (message, options) => session.sendCustomMessage(message, options),
|
|
273
|
+
sendUserMessage: (content, options) => session.sendUserMessage(content, options),
|
|
274
|
+
setActiveTools: (toolNames) => session.setActiveToolsByName(toolNames),
|
|
275
|
+
setModel: (model) => runExtensionSetModel(session, model),
|
|
276
|
+
// ... more APIs
|
|
277
|
+
}, { /* host API */ });
|
|
278
|
+
await extensionRunner.emit({ type: "session_start" });
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**pi-crew adaptation**: Pi SDK có `bindExtensions()` — cần probe capabilities.
|
|
283
|
+
|
|
284
|
+
**Files thay đổi**:
|
|
285
|
+
| File | Thay đổi |
|
|
286
|
+
|------|----------|
|
|
287
|
+
| `src/runtime/live-session-runtime.ts` | Thêm extension runner initialization |
|
|
288
|
+
| `src/runtime/live-extension-bridge.ts` | NEW — Bridge giữa pi-crew extension lifecycle và Pi SDK session |
|
|
289
|
+
|
|
290
|
+
**Acceptance**:
|
|
291
|
+
- [ ] Extensions load trong live-session worker
|
|
292
|
+
- [ ] Extension hooks fire đúng lifecycle
|
|
293
|
+
- [ ] Extension errors không crash session
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
### Phase 6: Semaphore + Fail-Fast cho Parallel Execution (2-3 ngày)
|
|
298
|
+
|
|
299
|
+
**Mục tiêu**: `mapConcurrent` trong live-session có fail-fast + AbortSignal, giống oh-my-pi.
|
|
300
|
+
|
|
301
|
+
**Học từ oh-my-pi**:
|
|
302
|
+
```typescript
|
|
303
|
+
// parallel.ts
|
|
304
|
+
const abortController = new AbortController();
|
|
305
|
+
const workerSignal = AbortSignal.any([signal, abortController.signal]);
|
|
306
|
+
const firstErrorPromise = new Promise<never>((_, reject) => { rejectFirst = reject; });
|
|
307
|
+
await Promise.race([Promise.all(workers), firstErrorPromise]);
|
|
308
|
+
// → fail-fast on first error
|
|
309
|
+
// → partial results on abort
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
**Files thay đổi**:
|
|
313
|
+
| File | Thay đổi |
|
|
314
|
+
|------|----------|
|
|
315
|
+
| `src/runtime/parallel-utils.ts` | Thêm `AbortSignal` support, fail-fast, partial results |
|
|
316
|
+
| `src/runtime/semaphore.ts` | NEW — Semaphore class (copy oh-my-pi pattern) |
|
|
317
|
+
| `src/runtime/team-runner.ts` | Pass AbortSignal cho parallel dispatch |
|
|
318
|
+
|
|
319
|
+
**Code sketch** — `semaphore.ts`:
|
|
320
|
+
```typescript
|
|
321
|
+
export class Semaphore {
|
|
322
|
+
#max: number;
|
|
323
|
+
#current = 0;
|
|
324
|
+
#queue: Array<() => void> = [];
|
|
325
|
+
|
|
326
|
+
constructor(max: number) { this.#max = Math.max(1, max); }
|
|
327
|
+
|
|
328
|
+
async acquire(): Promise<void> {
|
|
329
|
+
if (this.#current < this.#max) { this.#current++; return; }
|
|
330
|
+
const { promise, resolve } = Promise.withResolvers<void>();
|
|
331
|
+
this.#queue.push(resolve);
|
|
332
|
+
return promise;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
release(): void {
|
|
336
|
+
const next = this.#queue.shift();
|
|
337
|
+
if (next) next();
|
|
338
|
+
else this.#current--;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Acceptance**:
|
|
344
|
+
- [ ] `mapConcurrent` nhận optional `AbortSignal`
|
|
345
|
+
- [ ] First error → cancel remaining → throw
|
|
346
|
+
- [ ] External abort → return partial results
|
|
347
|
+
- [ ] Semaphore pattern cho cross-batch concurrency control
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
### Phase 7: Inter-Agent Communication (5-7 ngày) 🏗️
|
|
352
|
+
|
|
353
|
+
**Mục tiêu**: Live-session workers có thể communicate real-time (DM + broadcast), học từ oh-my-pi IRC.
|
|
354
|
+
|
|
355
|
+
**Học từ oh-my-pi**:
|
|
356
|
+
- `IrcTool` với `op: send/list`, `to: "agent-id" | "all"`
|
|
357
|
+
- `AgentRegistry` quản lý live agents
|
|
358
|
+
- `respondAsBackground()` — side-channel call không block recipient
|
|
359
|
+
|
|
360
|
+
**pi-crew adaptation**: pi-crew đã có `LiveAgentHandle` manager + `followUpLiveAgent()`. Cần:
|
|
361
|
+
1. Thêm `irc` tool vào live-session (via `setActiveToolsByName` hoặc custom tool)
|
|
362
|
+
2. Message routing qua `LiveAgentHandle.pendingFollowUps`
|
|
363
|
+
3. Broadcast qua `listLiveAgents()` → loop
|
|
364
|
+
|
|
365
|
+
**Files thay đổi**:
|
|
366
|
+
| File | Thay đổi |
|
|
367
|
+
|------|----------|
|
|
368
|
+
| `src/runtime/live-agent-manager.ts` | Thêm message routing, broadcast |
|
|
369
|
+
| `src/runtime/live-irc-tool.ts` | NEW — IRC tool cho live-session workers |
|
|
370
|
+
| `src/runtime/live-session-runtime.ts` | Inject IRC tool vào session |
|
|
371
|
+
|
|
372
|
+
**Acceptance**:
|
|
373
|
+
- [ ] Worker A gửi DM cho Worker B → B nhận message
|
|
374
|
+
- [ ] Broadcast → tất cả live workers nhận
|
|
375
|
+
- [ ] `respondAsBackground` → không block recipient
|
|
376
|
+
- [ ] Child-process workers dùng mailbox (không IRC)
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
### Phase 8: Monitoring & Observability (2-3 ngày)
|
|
381
|
+
|
|
382
|
+
**Mục tiêu**: Live-session có đầy đủ observability — health check, metrics, diagnostics.
|
|
383
|
+
|
|
384
|
+
**Files thay đổi**:
|
|
385
|
+
| File | Thay đổi |
|
|
386
|
+
|------|----------|
|
|
387
|
+
| `src/runtime/live-session-runtime.ts` | Thêm health metrics, session stats |
|
|
388
|
+
| `src/runtime/live-agent-manager.ts` | Thêm `getHealth()` method |
|
|
389
|
+
| `src/runtime/task-runner/live-executor.ts` | Emit observability events |
|
|
390
|
+
|
|
391
|
+
**Acceptance**:
|
|
392
|
+
- [ ] Session health endpoint: active/idle/error count
|
|
393
|
+
- [ ] Usage metrics: tokens per session, duration
|
|
394
|
+
- [ ] Heartbeat cho live-session workers
|
|
395
|
+
- [ ] Dashboard hiển thị live-session status
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
## Roadmap tổng quan
|
|
400
|
+
|
|
401
|
+
```
|
|
402
|
+
Phase 0: Remove Experimental Flag [2-3d] ← START HERE
|
|
403
|
+
Phase 1: Yield Enforcement [3-5d] ← QUICK WIN
|
|
404
|
+
Phase 2: Output Schema Validation [2-3d]
|
|
405
|
+
Phase 3: AbortSignal & Cancellation [2-3d]
|
|
406
|
+
───────────────────────────────────────────── ~3 weeks
|
|
407
|
+
Phase 4: MCP Proxy [3-5d]
|
|
408
|
+
Phase 5: Extension Runner [5-7d]
|
|
409
|
+
Phase 6: Semaphore + Fail-Fast [2-3d]
|
|
410
|
+
───────────────────────────────────────────── ~5 weeks
|
|
411
|
+
Phase 7: Inter-Agent Communication [5-7d]
|
|
412
|
+
Phase 8: Monitoring & Observability [2-3d]
|
|
413
|
+
───────────────────────────────────────────── ~7 weeks total
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Quick Wins (Phase 0-1, ~1 tuần)
|
|
417
|
+
- Loại bỏ experimental flag
|
|
418
|
+
- Yield enforcement
|
|
419
|
+
- → Live-session đã usable cho production workloads
|
|
420
|
+
|
|
421
|
+
### Medium-term (Phase 2-3, ~2 tuần thêm)
|
|
422
|
+
- Schema validation
|
|
423
|
+
- AbortSignal + graceful cancellation
|
|
424
|
+
- → Live-session đáng tin cậy như child-process
|
|
425
|
+
|
|
426
|
+
### Long-term (Phase 4-8, ~4 tuần thêm)
|
|
427
|
+
- MCP proxy, extension runner
|
|
428
|
+
- Semaphore + fail-fast
|
|
429
|
+
- IRC messaging, monitoring
|
|
430
|
+
- → Live-session **vượt** child-process cho trusted workloads
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## Priority Matrix
|
|
435
|
+
|
|
436
|
+
| Phase | Impact | Effort | Risk | Priority |
|
|
437
|
+
|-------|--------|--------|------|----------|
|
|
438
|
+
| 0: Remove experimental | 🔴 High | 🟢 Low | 🟢 Low | **P0 — Now** |
|
|
439
|
+
| 1: Yield enforcement | 🔴 High | 🟢 Low | 🟢 Low | **P0 — Now** |
|
|
440
|
+
| 3: AbortSignal | 🟡 Medium | 🟢 Low | 🟢 Low | **P1** |
|
|
441
|
+
| 2: Schema validation | 🟡 Medium | 🟡 Medium | 🟢 Low | **P1** |
|
|
442
|
+
| 6: Semaphore | 🟡 Medium | 🟢 Low | 🟢 Low | **P1** |
|
|
443
|
+
| 4: MCP proxy | 🔴 High | 🔴 High | 🟡 Medium | **P2** |
|
|
444
|
+
| 5: Extension runner | 🟡 Medium | 🔴 High | 🟡 Medium | **P2** |
|
|
445
|
+
| 7: IRC messaging | 🟡 Medium | 🟡 Medium | 🟡 Medium | **P3** |
|
|
446
|
+
| 8: Monitoring | 🟢 Low | 🟢 Low | 🟢 Low | **P3** |
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
## Rủi ro & Mitigation
|
|
451
|
+
|
|
452
|
+
| Rủi ro | Xác suất | Tác động | Mitigation |
|
|
453
|
+
|--------|----------|----------|------------|
|
|
454
|
+
| Pi SDK API thiếu (`toolChoice`, `customTools`, `extensionRunner`) | 🟡 Medium | 🔴 High | Probe SDK trước mỗi phase, fallback to prompt-based |
|
|
455
|
+
| Live-session crash cascade (no fault isolation) | 🟡 Medium | 🔴 High | Try-catch wrapper, session isolation, process-level guard |
|
|
456
|
+
| Performance regression (in-process memory pressure) | 🟢 Low | 🟡 Medium | Monitor memory, add session count limits |
|
|
457
|
+
| Breaking child-process mode | 🟢 Low | 🔴 High | Separate code paths, shared interfaces, test both |
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
## Testing Strategy
|
|
462
|
+
|
|
463
|
+
Mỗi phase thêm test theo pattern:
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
// Test pattern cho live-session
|
|
467
|
+
describe(`Phase N: Feature Name`, () => {
|
|
468
|
+
// Unit: mock session
|
|
469
|
+
test("yield enforcement loop triggers reminders", async () => {
|
|
470
|
+
const mockSession = { prompt: mock.fn(), subscribe: mock.fn(), ... };
|
|
471
|
+
// ... setup ...
|
|
472
|
+
const result = await runLiveSessionTask({ ... mockSession ... });
|
|
473
|
+
assert.equal(mockSession.prompt.callCount, 4); // 1 initial + 3 reminders
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
// Integration: mock SDK probe
|
|
477
|
+
test("schema validation rejects invalid data", async () => {
|
|
478
|
+
process.env.PI_CREW_MOCK_LIVE_SESSION = "success";
|
|
479
|
+
// ... test with schema ...
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
// E2E: full pipeline (if SDK available)
|
|
483
|
+
test.skip("full live-session pipeline with real SDK", async () => {
|
|
484
|
+
// Requires PI_CREW_ENABLE_EXPERIMENTAL_LIVE_SESSION=1
|
|
485
|
+
});
|
|
486
|
+
});
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
---
|
|
490
|
+
|
|
491
|
+
## Success Criteria — "Production Ready"
|
|
492
|
+
|
|
493
|
+
- [ ] **No experimental flag** — live-session works out of the box
|
|
494
|
+
- [ ] **Yield enforcement** — 100% tasks có structured output
|
|
495
|
+
- [ ] **Graceful degradation** — fallback sang child-process khi SDK không có
|
|
496
|
+
- [ ] **Cancellation** — abort signal dừng session trong <5s
|
|
497
|
+
- [ ] **No zombie sessions** — cleanup luôn chạy trong finally
|
|
498
|
+
- [ ] **Observability** — health check, usage metrics, diagnostics
|
|
499
|
+
- [ ] **Typecheck pass** — strict types, no `any`
|
|
500
|
+
- [ ] **Test coverage** — ≥80% cho live-session code paths
|
|
501
|
+
- [ ] **Performance** — live-session startup <100ms (vs child-process 2-5s)
|
|
502
|
+
- [ ] **Documentation** — README section cho live-session config
|