pi-crew 0.1.51 → 0.2.0
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 +56 -1
- package/README.md +176 -781
- 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 +70 -11
- package/agents/writer.md +11 -11
- package/docs/actions-reference.md +595 -0
- package/docs/commands-reference.md +347 -0
- package/docs/runtime-flow.md +148 -148
- package/index.ts +6 -6
- package/package.json +99 -99
- 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 -157
- 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/adapters/claude-adapter.ts +25 -0
- package/src/adapters/codex-adapter.ts +21 -0
- package/src/adapters/cursor-adapter.ts +17 -0
- package/src/adapters/export-util.ts +137 -0
- package/src/adapters/index.ts +15 -0
- package/src/adapters/registry.ts +18 -0
- package/src/adapters/types.ts +23 -0
- package/src/agents/agent-config.ts +2 -0
- package/src/agents/agent-search.ts +98 -98
- package/src/agents/discover-agents.ts +2 -1
- package/src/config/config.ts +13 -1
- package/src/config/drift-detector.ts +211 -0
- package/src/config/markers.ts +327 -0
- package/src/config/resilient-parser.ts +108 -0
- package/src/config/suggestions.ts +74 -0
- package/src/extension/cross-extension-rpc.ts +103 -94
- package/src/extension/project-init.ts +21 -1
- package/src/extension/register.ts +45 -14
- package/src/extension/registration/commands.ts +77 -8
- package/src/extension/registration/subagent-tools.ts +10 -1
- package/src/extension/registration/team-tool.ts +10 -1
- package/src/extension/registration/viewers.ts +48 -34
- package/src/extension/run-bundle-schema.ts +89 -89
- package/src/extension/run-import.ts +25 -1
- package/src/extension/run-index.ts +5 -1
- package/src/extension/run-maintenance.ts +142 -68
- package/src/extension/team-manager-command.ts +10 -1
- package/src/extension/team-tool/doctor.ts +28 -3
- package/src/extension/team-tool/handle-settings.ts +195 -188
- package/src/extension/team-tool/inspect.ts +41 -41
- package/src/extension/team-tool/intent-policy.ts +42 -42
- package/src/extension/team-tool/lifecycle-actions.ts +27 -8
- package/src/extension/team-tool/plan.ts +19 -19
- package/src/extension/team-tool/run.ts +12 -1
- package/src/extension/team-tool.ts +11 -1
- package/src/i18n.ts +184 -184
- package/src/observability/exporters/otlp-exporter.ts +92 -77
- package/src/prompt/prompt-runtime.ts +72 -72
- 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/attention-events.ts +28 -28
- package/src/runtime/auto-resume.ts +100 -0
- package/src/runtime/background-runner.ts +11 -1
- package/src/runtime/cancellation-token.ts +89 -89
- package/src/runtime/cancellation.ts +61 -61
- package/src/runtime/capability-inventory.ts +116 -116
- package/src/runtime/child-pi.ts +7 -2
- package/src/runtime/compaction-summary.ts +271 -0
- package/src/runtime/completion-guard.ts +190 -190
- package/src/runtime/crash-recovery.ts +33 -0
- package/src/runtime/delta-conflict.ts +360 -0
- package/src/runtime/direct-run.ts +35 -35
- 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/iteration-hooks.ts +262 -0
- package/src/runtime/live-agent-control.ts +88 -88
- package/src/runtime/live-control-realtime.ts +36 -36
- package/src/runtime/live-extension-bridge.ts +150 -150
- package/src/runtime/live-irc.ts +92 -92
- package/src/runtime/live-session-health.ts +100 -100
- package/src/runtime/loop-gates.ts +129 -0
- package/src/runtime/metric-parser.ts +40 -0
- package/src/runtime/notebook-helpers.ts +90 -90
- package/src/runtime/orphan-sentinel.ts +7 -7
- package/src/runtime/parallel-research.ts +44 -44
- package/src/runtime/phase-progress.ts +217 -0
- package/src/runtime/pi-args.ts +38 -11
- package/src/runtime/pi-json-output.ts +111 -111
- package/src/runtime/pi-spawn.ts +57 -7
- package/src/runtime/policy-engine.ts +79 -79
- package/src/runtime/post-checks.ts +122 -0
- package/src/runtime/progress-event-coalescer.ts +43 -43
- package/src/runtime/prose-compressor.ts +164 -164
- package/src/runtime/recovery-recipes.ts +74 -74
- package/src/runtime/result-extractor.ts +121 -121
- package/src/runtime/role-permission.ts +39 -39
- package/src/runtime/sensitive-paths.ts +2 -2
- 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 -177
- package/src/runtime/supervisor-contact.ts +59 -59
- package/src/runtime/task-display.ts +38 -38
- package/src/runtime/task-graph.ts +207 -0
- package/src/runtime/task-quality.ts +207 -0
- package/src/runtime/task-runner/capabilities.ts +78 -78
- package/src/runtime/task-runner/live-executor.ts +7 -1
- package/src/runtime/task-runner/progress.ts +119 -119
- 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 +103 -103
- package/src/runtime/task-runner/state-helpers.ts +22 -22
- package/src/runtime/team-runner.ts +117 -7
- package/src/runtime/worker-heartbeat.ts +21 -21
- package/src/runtime/worker-startup.ts +57 -57
- package/src/runtime/workflow-state.ts +187 -0
- package/src/runtime/workspace-tree.ts +298 -298
- package/src/schema/config-schema.ts +11 -0
- package/src/schema/validation-types.ts +148 -0
- package/src/skills/skill-templates.ts +374 -0
- package/src/state/active-run-registry.ts +35 -11
- package/src/state/atomic-write.ts +33 -26
- package/src/state/contracts.ts +1 -0
- package/src/state/event-reconstructor.ts +217 -0
- package/src/state/locks.ts +2 -13
- package/src/state/mailbox.ts +4 -3
- package/src/state/state-store.ts +32 -14
- package/src/state/task-claims.ts +44 -44
- package/src/state/types.ts +9 -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/crew-footer.ts +101 -101
- package/src/ui/crew-select-list.ts +111 -111
- package/src/ui/crew-widget.ts +5 -2
- package/src/ui/dashboard-panes/cancellation-pane.ts +42 -42
- package/src/ui/dashboard-panes/capability-pane.ts +59 -59
- package/src/ui/dashboard-panes/mailbox-pane.ts +35 -35
- package/src/ui/dashboard-panes/metrics-pane.ts +34 -34
- package/src/ui/dashboard-panes/progress-pane.ts +11 -0
- package/src/ui/dynamic-border.ts +25 -25
- package/src/ui/layout-primitives.ts +106 -106
- package/src/ui/loaders.ts +158 -158
- package/src/ui/render-coalescer.ts +51 -51
- package/src/ui/render-diff.ts +119 -119
- package/src/ui/render-scheduler.ts +143 -143
- package/src/ui/run-action-dispatcher.ts +10 -1
- 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 -258
- 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 -17
- package/src/utils/incremental-reader.ts +104 -104
- 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 +136 -136
- package/src/utils/sleep.ts +40 -26
- package/src/utils/task-name-generator.ts +337 -337
- package/src/workflows/validate-workflow.ts +40 -40
- package/src/worktree/branch-freshness.ts +45 -45
- 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 +30 -29
- package/workflows/fast-fix.workflow.md +23 -22
- package/workflows/implementation.workflow.md +43 -43
- package/workflows/parallel-research.workflow.md +46 -46
- package/workflows/research.workflow.md +22 -22
- package/workflows/review.workflow.md +30 -30
- package/docs/refactor-tasks-phase3.md +0 -394
- package/docs/refactor-tasks-phase4.md +0 -564
- package/docs/refactor-tasks-phase5.md +0 -402
- package/docs/refactor-tasks-phase6.md +0 -662
- package/docs/refactor-tasks.md +0 -1484
- package/docs/research/AGENT-EXECUTION-ARCHITECTURE.md +0 -261
- package/docs/research/AGENT-LIFECYCLE-COMPARISON.md +0 -111
- package/docs/research/AUDIT_OH_MY_PI.md +0 -261
- package/docs/research/AUDIT_PI_CREW.md +0 -457
- package/docs/research/CAVEMAN-DEEP-RESEARCH.md +0 -281
- package/docs/research/COMPARISON_OH_MY_PI_VS_PI_CREW.md +0 -264
- package/docs/research/DEEP-RESEARCH-PI-POWERBAR.md +0 -343
- package/docs/research/DEEP_RESEARCH_SUBAGENT_ARCHITECTURE.md +0 -480
- package/docs/research/GAP_CLOSURE_IMPLEMENTATION_PLAN.md +0 -354
- package/docs/research/IMPLEMENTATION_PLAN.md +0 -385
- package/docs/research/LIVE-SESSION-PRODUCTION-READY-PLAN.md +0 -502
- package/docs/research/OH-MY-PI-DEEP-RESEARCH-v14.7.6.md +0 -266
- package/docs/research/REMAINING-GAPS-PLAN.md +0 -363
- package/docs/research/SESSION-SUMMARY-2026-05-08.md +0 -146
- package/docs/research/UI-RESPONSIVENESS-AUDIT.md +0 -173
- package/docs/research-awesome-agent-skills-distillation.md +0 -100
- package/docs/research-extension-examples.md +0 -297
- package/docs/research-extension-system.md +0 -324
- package/docs/research-oh-my-pi-distillation.md +0 -369
- package/docs/research-optimization-plan.md +0 -548
- package/docs/research-phase10-distillation.md +0 -199
- package/docs/research-phase11-distillation.md +0 -201
- package/docs/research-phase8-operator-experience-plan.md +0 -819
- package/docs/research-phase9-observability-reliability-plan.md +0 -1190
- package/docs/research-pi-coding-agent.md +0 -357
- package/docs/research-source-pi-crew-reference.md +0 -174
- package/docs/research-ui-optimization-plan.md +0 -480
- package/docs/source-runtime-refactor-map.md +0 -107
- package/src/utils/atomic-write.ts +0 -33
|
@@ -1,150 +1,150 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* G5: Extension runner bridge for live-session workers.
|
|
3
|
-
*
|
|
4
|
-
* Bridges pi-crew's extension lifecycle with the Pi SDK session's
|
|
5
|
-
* extension runner. Verified against actual SDK API surface:
|
|
6
|
-
*
|
|
7
|
-
* Session methods:
|
|
8
|
-
* - sendCustomMessage(message, options?)
|
|
9
|
-
* - sendUserMessage(content, options?)
|
|
10
|
-
* - getActiveToolNames() / setActiveToolsByName()
|
|
11
|
-
* - getAllTools() / getToolDefinition()
|
|
12
|
-
* - steer(text) / prompt(text, options?)
|
|
13
|
-
* - abort()
|
|
14
|
-
* - getContextUsage()
|
|
15
|
-
* - bindExtensions()
|
|
16
|
-
* - compact()
|
|
17
|
-
* - getSessionStats()
|
|
18
|
-
*
|
|
19
|
-
* ExtensionRunner methods:
|
|
20
|
-
* - initialize(apis, host)
|
|
21
|
-
* - emit(event)
|
|
22
|
-
* - hasHandlers(eventType)
|
|
23
|
-
* - getAllRegisteredTools()
|
|
24
|
-
* - onError(listener)
|
|
25
|
-
* - shutdown()
|
|
26
|
-
*
|
|
27
|
-
* ExtensionContext actions (via registerTool):
|
|
28
|
-
* - sendMessage / sendUserMessage / appendEntry / setLabel
|
|
29
|
-
* - setActiveTools / getActiveTools / getAllTools
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
import type { YieldResult } from "./yield-handler.ts";
|
|
33
|
-
|
|
34
|
-
export interface ExtensionBridgeApis {
|
|
35
|
-
sendMessage: (message: unknown, options?: Record<string, unknown>) => void;
|
|
36
|
-
sendUserMessage: (content: unknown, options?: Record<string, unknown>) => void;
|
|
37
|
-
appendEntry: (customType: string, data: unknown) => void;
|
|
38
|
-
setLabel: (targetId: string, label: string) => void;
|
|
39
|
-
getActiveTools: () => string[];
|
|
40
|
-
getAllTools: () => string[];
|
|
41
|
-
setActiveTools: (toolNames: string[]) => void;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface ExtensionHostApis {
|
|
45
|
-
getModel: () => unknown;
|
|
46
|
-
isIdle: () => boolean;
|
|
47
|
-
abort: () => void;
|
|
48
|
-
hasPendingMessages: () => boolean;
|
|
49
|
-
shutdown: () => void;
|
|
50
|
-
getContextUsage: () => unknown;
|
|
51
|
-
getSystemPrompt: () => string;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Pi SDK session-like object with the methods we need.
|
|
56
|
-
* Verified against actual `createAgentSession().session` prototype.
|
|
57
|
-
*/
|
|
58
|
-
interface PiSdkSession {
|
|
59
|
-
sendCustomMessage: (message: unknown, options?: Record<string, unknown>) => void;
|
|
60
|
-
sendUserMessage: (content: unknown, options?: Record<string, unknown>) => void;
|
|
61
|
-
getActiveToolNames: () => string[];
|
|
62
|
-
getAllTools: () => string[];
|
|
63
|
-
setActiveToolsByName: (toolNames: string[]) => void;
|
|
64
|
-
steer: (text: string) => Promise<void>;
|
|
65
|
-
prompt: (text: string, options?: Record<string, unknown>) => Promise<void>;
|
|
66
|
-
abort: () => void | Promise<void>;
|
|
67
|
-
getContextUsage: () => unknown;
|
|
68
|
-
subscribe: (listener: (event: unknown) => void) => () => void;
|
|
69
|
-
bindExtensions: (bindings?: Record<string, unknown>) => Promise<void>;
|
|
70
|
-
compact: (options?: unknown) => void;
|
|
71
|
-
getSessionStats: () => unknown;
|
|
72
|
-
isStreaming?: boolean;
|
|
73
|
-
model?: unknown;
|
|
74
|
-
systemPrompt?: string;
|
|
75
|
-
pendingMessageCount?: number;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Build extension bridge APIs from a Pi SDK session.
|
|
80
|
-
* Returns null if the session doesn't support extension running.
|
|
81
|
-
*/
|
|
82
|
-
export function buildExtensionBridge(session: PiSdkSession): { apis: ExtensionBridgeApis; host: ExtensionHostApis } | null {
|
|
83
|
-
if (typeof session.sendCustomMessage !== "function") return null;
|
|
84
|
-
|
|
85
|
-
return {
|
|
86
|
-
apis: {
|
|
87
|
-
sendMessage: (message, options) => {
|
|
88
|
-
try {
|
|
89
|
-
session.sendCustomMessage(message, options);
|
|
90
|
-
} catch {
|
|
91
|
-
/* non-blocking */
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
sendUserMessage: (content, options) => {
|
|
95
|
-
try {
|
|
96
|
-
session.sendUserMessage(content, options);
|
|
97
|
-
} catch {
|
|
98
|
-
/* non-blocking */
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
appendEntry: () => {
|
|
102
|
-
// appendEntry requires sessionManager access which isn't directly on session
|
|
103
|
-
// This is a no-op placeholder; extensions that rely on it will gracefully degrade
|
|
104
|
-
},
|
|
105
|
-
setLabel: () => {
|
|
106
|
-
// setLabel requires sessionManager access — no-op placeholder
|
|
107
|
-
},
|
|
108
|
-
getActiveTools: () => {
|
|
109
|
-
try {
|
|
110
|
-
return session.getActiveToolNames();
|
|
111
|
-
} catch {
|
|
112
|
-
return [];
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
getAllTools: () => {
|
|
116
|
-
try {
|
|
117
|
-
return session.getAllTools();
|
|
118
|
-
} catch {
|
|
119
|
-
return session.getActiveToolNames();
|
|
120
|
-
}
|
|
121
|
-
},
|
|
122
|
-
setActiveTools: (toolNames) => {
|
|
123
|
-
try {
|
|
124
|
-
session.setActiveToolsByName(toolNames);
|
|
125
|
-
} catch {
|
|
126
|
-
/* ignore */
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
host: {
|
|
131
|
-
getModel: () => session.model,
|
|
132
|
-
isIdle: () => !session.isStreaming,
|
|
133
|
-
abort: () => {
|
|
134
|
-
void session.abort();
|
|
135
|
-
},
|
|
136
|
-
hasPendingMessages: () => (session.pendingMessageCount ?? 0) > 0,
|
|
137
|
-
shutdown: () => {
|
|
138
|
-
/* no-op for live-session — caller manages session lifecycle */
|
|
139
|
-
},
|
|
140
|
-
getContextUsage: () => {
|
|
141
|
-
try {
|
|
142
|
-
return session.getContextUsage();
|
|
143
|
-
} catch {
|
|
144
|
-
return undefined;
|
|
145
|
-
}
|
|
146
|
-
},
|
|
147
|
-
getSystemPrompt: () => session.systemPrompt ?? "",
|
|
148
|
-
},
|
|
149
|
-
};
|
|
150
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* G5: Extension runner bridge for live-session workers.
|
|
3
|
+
*
|
|
4
|
+
* Bridges pi-crew's extension lifecycle with the Pi SDK session's
|
|
5
|
+
* extension runner. Verified against actual SDK API surface:
|
|
6
|
+
*
|
|
7
|
+
* Session methods:
|
|
8
|
+
* - sendCustomMessage(message, options?)
|
|
9
|
+
* - sendUserMessage(content, options?)
|
|
10
|
+
* - getActiveToolNames() / setActiveToolsByName()
|
|
11
|
+
* - getAllTools() / getToolDefinition()
|
|
12
|
+
* - steer(text) / prompt(text, options?)
|
|
13
|
+
* - abort()
|
|
14
|
+
* - getContextUsage()
|
|
15
|
+
* - bindExtensions()
|
|
16
|
+
* - compact()
|
|
17
|
+
* - getSessionStats()
|
|
18
|
+
*
|
|
19
|
+
* ExtensionRunner methods:
|
|
20
|
+
* - initialize(apis, host)
|
|
21
|
+
* - emit(event)
|
|
22
|
+
* - hasHandlers(eventType)
|
|
23
|
+
* - getAllRegisteredTools()
|
|
24
|
+
* - onError(listener)
|
|
25
|
+
* - shutdown()
|
|
26
|
+
*
|
|
27
|
+
* ExtensionContext actions (via registerTool):
|
|
28
|
+
* - sendMessage / sendUserMessage / appendEntry / setLabel
|
|
29
|
+
* - setActiveTools / getActiveTools / getAllTools
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import type { YieldResult } from "./yield-handler.ts";
|
|
33
|
+
|
|
34
|
+
export interface ExtensionBridgeApis {
|
|
35
|
+
sendMessage: (message: unknown, options?: Record<string, unknown>) => void;
|
|
36
|
+
sendUserMessage: (content: unknown, options?: Record<string, unknown>) => void;
|
|
37
|
+
appendEntry: (customType: string, data: unknown) => void;
|
|
38
|
+
setLabel: (targetId: string, label: string) => void;
|
|
39
|
+
getActiveTools: () => string[];
|
|
40
|
+
getAllTools: () => string[];
|
|
41
|
+
setActiveTools: (toolNames: string[]) => void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface ExtensionHostApis {
|
|
45
|
+
getModel: () => unknown;
|
|
46
|
+
isIdle: () => boolean;
|
|
47
|
+
abort: () => void;
|
|
48
|
+
hasPendingMessages: () => boolean;
|
|
49
|
+
shutdown: () => void;
|
|
50
|
+
getContextUsage: () => unknown;
|
|
51
|
+
getSystemPrompt: () => string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Pi SDK session-like object with the methods we need.
|
|
56
|
+
* Verified against actual `createAgentSession().session` prototype.
|
|
57
|
+
*/
|
|
58
|
+
interface PiSdkSession {
|
|
59
|
+
sendCustomMessage: (message: unknown, options?: Record<string, unknown>) => void;
|
|
60
|
+
sendUserMessage: (content: unknown, options?: Record<string, unknown>) => void;
|
|
61
|
+
getActiveToolNames: () => string[];
|
|
62
|
+
getAllTools: () => string[];
|
|
63
|
+
setActiveToolsByName: (toolNames: string[]) => void;
|
|
64
|
+
steer: (text: string) => Promise<void>;
|
|
65
|
+
prompt: (text: string, options?: Record<string, unknown>) => Promise<void>;
|
|
66
|
+
abort: () => void | Promise<void>;
|
|
67
|
+
getContextUsage: () => unknown;
|
|
68
|
+
subscribe: (listener: (event: unknown) => void) => () => void;
|
|
69
|
+
bindExtensions: (bindings?: Record<string, unknown>) => Promise<void>;
|
|
70
|
+
compact: (options?: unknown) => void;
|
|
71
|
+
getSessionStats: () => unknown;
|
|
72
|
+
isStreaming?: boolean;
|
|
73
|
+
model?: unknown;
|
|
74
|
+
systemPrompt?: string;
|
|
75
|
+
pendingMessageCount?: number;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Build extension bridge APIs from a Pi SDK session.
|
|
80
|
+
* Returns null if the session doesn't support extension running.
|
|
81
|
+
*/
|
|
82
|
+
export function buildExtensionBridge(session: PiSdkSession): { apis: ExtensionBridgeApis; host: ExtensionHostApis } | null {
|
|
83
|
+
if (typeof session.sendCustomMessage !== "function") return null;
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
apis: {
|
|
87
|
+
sendMessage: (message, options) => {
|
|
88
|
+
try {
|
|
89
|
+
session.sendCustomMessage(message, options);
|
|
90
|
+
} catch {
|
|
91
|
+
/* non-blocking */
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
sendUserMessage: (content, options) => {
|
|
95
|
+
try {
|
|
96
|
+
session.sendUserMessage(content, options);
|
|
97
|
+
} catch {
|
|
98
|
+
/* non-blocking */
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
appendEntry: () => {
|
|
102
|
+
// appendEntry requires sessionManager access which isn't directly on session
|
|
103
|
+
// This is a no-op placeholder; extensions that rely on it will gracefully degrade
|
|
104
|
+
},
|
|
105
|
+
setLabel: () => {
|
|
106
|
+
// setLabel requires sessionManager access — no-op placeholder
|
|
107
|
+
},
|
|
108
|
+
getActiveTools: () => {
|
|
109
|
+
try {
|
|
110
|
+
return session.getActiveToolNames();
|
|
111
|
+
} catch {
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
getAllTools: () => {
|
|
116
|
+
try {
|
|
117
|
+
return session.getAllTools();
|
|
118
|
+
} catch {
|
|
119
|
+
return session.getActiveToolNames();
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
setActiveTools: (toolNames) => {
|
|
123
|
+
try {
|
|
124
|
+
session.setActiveToolsByName(toolNames);
|
|
125
|
+
} catch {
|
|
126
|
+
/* ignore */
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
host: {
|
|
131
|
+
getModel: () => session.model,
|
|
132
|
+
isIdle: () => !session.isStreaming,
|
|
133
|
+
abort: () => {
|
|
134
|
+
void session.abort();
|
|
135
|
+
},
|
|
136
|
+
hasPendingMessages: () => (session.pendingMessageCount ?? 0) > 0,
|
|
137
|
+
shutdown: () => {
|
|
138
|
+
/* no-op for live-session — caller manages session lifecycle */
|
|
139
|
+
},
|
|
140
|
+
getContextUsage: () => {
|
|
141
|
+
try {
|
|
142
|
+
return session.getContextUsage();
|
|
143
|
+
} catch {
|
|
144
|
+
return undefined;
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
getSystemPrompt: () => session.systemPrompt ?? "",
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
package/src/runtime/live-irc.ts
CHANGED
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phase 7: Inter-agent communication for live-session workers.
|
|
3
|
-
*
|
|
4
|
-
* Provides IRC-like messaging between live-session workers, adapted from
|
|
5
|
-
* oh-my-pi's IrcTool pattern. Uses the existing LiveAgentHandle manager
|
|
6
|
-
* for message routing.
|
|
7
|
-
*
|
|
8
|
-
* Features:
|
|
9
|
-
* - DM: Send a message to a specific agent
|
|
10
|
-
* - Broadcast: Send a message to all live agents
|
|
11
|
-
* - Side-channel: Non-blocking message injection (via pendingFollowUps)
|
|
12
|
-
*
|
|
13
|
-
* For child-process workers, messages fall back to file-based mailbox.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
export type IrcOperation = "send" | "list";
|
|
17
|
-
|
|
18
|
-
export interface IrcMessage {
|
|
19
|
-
from: string;
|
|
20
|
-
to: string;
|
|
21
|
-
content: string;
|
|
22
|
-
timestamp: string;
|
|
23
|
-
/** Whether the sender expects a reply. */
|
|
24
|
-
awaitReply?: boolean;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface IrcSendMessage {
|
|
28
|
-
op: IrcOperation;
|
|
29
|
-
/** Target agent ID or "all" for broadcast. */
|
|
30
|
-
to: string;
|
|
31
|
-
/** Message content. */
|
|
32
|
-
message: string;
|
|
33
|
-
/** Whether to wait for a reply (default: true for DM, false for broadcast). */
|
|
34
|
-
awaitReply?: boolean;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface IrcListResult {
|
|
38
|
-
peers: Array<{ id: string; name: string; status: string }>;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Build IRC peer roster for injection into system prompt.
|
|
43
|
-
* Lists all currently live agents except the caller.
|
|
44
|
-
*/
|
|
45
|
-
export function renderIrcPeerRoster(selfId: string, peers: Array<{ agentId: string; status: string }>): string {
|
|
46
|
-
const visible = peers.filter((p) => p.agentId !== selfId && (p.status === "running" || p.status === "idle"));
|
|
47
|
-
if (visible.length === 0) return "- (no other live agents)";
|
|
48
|
-
return visible.map((peer) => `- \`${peer.agentId}\` (${peer.status})`).join("\n");
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Build the IRC system prompt section for a live-session worker.
|
|
53
|
-
*/
|
|
54
|
-
export function buildIrcSystemSection(selfId: string, peers: Array<{ agentId: string; status: string }>): string {
|
|
55
|
-
const roster = renderIrcPeerRoster(selfId, peers);
|
|
56
|
-
return [
|
|
57
|
-
"## Inter-Agent Communication",
|
|
58
|
-
`Your agent ID: \`${selfId}\``,
|
|
59
|
-
"You can send messages to other live agents via the `irc` tool.",
|
|
60
|
-
"Available peers:",
|
|
61
|
-
roster,
|
|
62
|
-
].join("\n");
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Route an IRC message to the appropriate agent(s).
|
|
67
|
-
* Returns the list of agent IDs that received the message.
|
|
68
|
-
*/
|
|
69
|
-
export function routeIrcMessage(
|
|
70
|
-
message: IrcSendMessage,
|
|
71
|
-
selfId: string,
|
|
72
|
-
routing: {
|
|
73
|
-
sendDm: (agentId: string, content: string) => void;
|
|
74
|
-
broadcast: (content: string, excludeId: string) => string[];
|
|
75
|
-
},
|
|
76
|
-
): { deliveredTo: string[]; error?: string } {
|
|
77
|
-
if (!message.to || !message.message?.trim()) {
|
|
78
|
-
return { deliveredTo: [], error: "Missing 'to' (agent ID or 'all') and 'message' fields." };
|
|
79
|
-
}
|
|
80
|
-
if (message.to === selfId) {
|
|
81
|
-
return { deliveredTo: [], error: "Cannot send a message to yourself." };
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (message.to === "all") {
|
|
85
|
-
const recipients = routing.broadcast(message.message, selfId);
|
|
86
|
-
return { deliveredTo: recipients };
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// DM to specific agent
|
|
90
|
-
routing.sendDm(message.to, message.message);
|
|
91
|
-
return { deliveredTo: [message.to] };
|
|
92
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Phase 7: Inter-agent communication for live-session workers.
|
|
3
|
+
*
|
|
4
|
+
* Provides IRC-like messaging between live-session workers, adapted from
|
|
5
|
+
* oh-my-pi's IrcTool pattern. Uses the existing LiveAgentHandle manager
|
|
6
|
+
* for message routing.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - DM: Send a message to a specific agent
|
|
10
|
+
* - Broadcast: Send a message to all live agents
|
|
11
|
+
* - Side-channel: Non-blocking message injection (via pendingFollowUps)
|
|
12
|
+
*
|
|
13
|
+
* For child-process workers, messages fall back to file-based mailbox.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export type IrcOperation = "send" | "list";
|
|
17
|
+
|
|
18
|
+
export interface IrcMessage {
|
|
19
|
+
from: string;
|
|
20
|
+
to: string;
|
|
21
|
+
content: string;
|
|
22
|
+
timestamp: string;
|
|
23
|
+
/** Whether the sender expects a reply. */
|
|
24
|
+
awaitReply?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface IrcSendMessage {
|
|
28
|
+
op: IrcOperation;
|
|
29
|
+
/** Target agent ID or "all" for broadcast. */
|
|
30
|
+
to: string;
|
|
31
|
+
/** Message content. */
|
|
32
|
+
message: string;
|
|
33
|
+
/** Whether to wait for a reply (default: true for DM, false for broadcast). */
|
|
34
|
+
awaitReply?: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface IrcListResult {
|
|
38
|
+
peers: Array<{ id: string; name: string; status: string }>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Build IRC peer roster for injection into system prompt.
|
|
43
|
+
* Lists all currently live agents except the caller.
|
|
44
|
+
*/
|
|
45
|
+
export function renderIrcPeerRoster(selfId: string, peers: Array<{ agentId: string; status: string }>): string {
|
|
46
|
+
const visible = peers.filter((p) => p.agentId !== selfId && (p.status === "running" || p.status === "idle"));
|
|
47
|
+
if (visible.length === 0) return "- (no other live agents)";
|
|
48
|
+
return visible.map((peer) => `- \`${peer.agentId}\` (${peer.status})`).join("\n");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Build the IRC system prompt section for a live-session worker.
|
|
53
|
+
*/
|
|
54
|
+
export function buildIrcSystemSection(selfId: string, peers: Array<{ agentId: string; status: string }>): string {
|
|
55
|
+
const roster = renderIrcPeerRoster(selfId, peers);
|
|
56
|
+
return [
|
|
57
|
+
"## Inter-Agent Communication",
|
|
58
|
+
`Your agent ID: \`${selfId}\``,
|
|
59
|
+
"You can send messages to other live agents via the `irc` tool.",
|
|
60
|
+
"Available peers:",
|
|
61
|
+
roster,
|
|
62
|
+
].join("\n");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Route an IRC message to the appropriate agent(s).
|
|
67
|
+
* Returns the list of agent IDs that received the message.
|
|
68
|
+
*/
|
|
69
|
+
export function routeIrcMessage(
|
|
70
|
+
message: IrcSendMessage,
|
|
71
|
+
selfId: string,
|
|
72
|
+
routing: {
|
|
73
|
+
sendDm: (agentId: string, content: string) => void;
|
|
74
|
+
broadcast: (content: string, excludeId: string) => string[];
|
|
75
|
+
},
|
|
76
|
+
): { deliveredTo: string[]; error?: string } {
|
|
77
|
+
if (!message.to || !message.message?.trim()) {
|
|
78
|
+
return { deliveredTo: [], error: "Missing 'to' (agent ID or 'all') and 'message' fields." };
|
|
79
|
+
}
|
|
80
|
+
if (message.to === selfId) {
|
|
81
|
+
return { deliveredTo: [], error: "Cannot send a message to yourself." };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (message.to === "all") {
|
|
85
|
+
const recipients = routing.broadcast(message.message, selfId);
|
|
86
|
+
return { deliveredTo: recipients };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// DM to specific agent
|
|
90
|
+
routing.sendDm(message.to, message.message);
|
|
91
|
+
return { deliveredTo: [message.to] };
|
|
92
|
+
}
|