@leing2021/super-pi 0.23.9 → 0.23.10

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.
@@ -4,12 +4,22 @@
4
4
  * Features:
5
5
  * - Recursion depth guard (PI_SUBAGENT_DEPTH / PI_SUBAGENT_MAX_DEPTH)
6
6
  * - Optional context slimming via --no-skills flag
7
+ * - Live TUI updates via onUpdate callback + SingleResult details
7
8
  */
8
9
 
9
10
  import {
10
11
  checkSubagentDepth,
11
12
  getChildDepthEnv,
12
13
  } from "./subagent-depth-guard"
14
+ import {
15
+ type SingleResult,
16
+ getFinalOutput,
17
+ invokeRunner,
18
+ } from "./subagent-events"
19
+
20
+ // ---------------------------------------------------------------------------
21
+ // Public types
22
+ // ---------------------------------------------------------------------------
13
23
 
14
24
  export interface SubagentTask {
15
25
  agent: string
@@ -24,22 +34,47 @@ export interface SubagentInput {
24
34
  inheritSkills?: boolean
25
35
  }
26
36
 
27
- export interface SubagentResult {
37
+ export interface SubagentLiveDetails {
28
38
  mode: "single" | "chain"
29
- outputs: string[]
39
+ results: SingleResult[]
30
40
  }
31
41
 
42
+ /** @deprecated Use SubagentLiveRunner instead */
43
+ export type SubagentRunner = (
44
+ prompt: string,
45
+ options?: SubagentExecOptions,
46
+ ) => Promise<string>
47
+
32
48
  export interface SubagentExecOptions {
33
49
  /** Extra CLI flags to pass to the child pi process */
34
50
  extraFlags?: string[]
35
51
  /** Environment variables to inject into the child process */
36
52
  extraEnv?: Record<string, string>
53
+ /** Callback for live TUI partial updates */
54
+ onUpdate?: (partial: SingleResult) => void
37
55
  }
38
56
 
39
- export type SubagentRunner = (
57
+ /**
58
+ * Live runner that returns a structured SingleResult and supports
59
+ * onUpdate for partial progress.
60
+ */
61
+ export type SubagentLiveRunner = (
40
62
  prompt: string,
41
- options?: SubagentExecOptions,
42
- ) => Promise<string>
63
+ options?: SubagentLiveExecOptions,
64
+ ) => Promise<SingleResult>
65
+
66
+ export type SubagentLiveExecOptions = SubagentExecOptions
67
+
68
+ export interface SubagentLiveResult {
69
+ mode: "single" | "chain"
70
+ results: SingleResult[]
71
+ /** @deprecated Backward compat: final text output per step */
72
+ outputs?: string[]
73
+ }
74
+
75
+ // ---------------------------------------------------------------------------
76
+ // Pipeline stage guard
77
+ // ---------------------------------------------------------------------------
43
78
 
44
79
  const PIPELINE_STAGE_SKILLS = new Set([
45
80
  "01-brainstorm",
@@ -58,10 +93,26 @@ export function assertNonPipelineStageSkill(agent: string, toolName: string): vo
58
93
  }
59
94
  }
60
95
 
96
+ // ---------------------------------------------------------------------------
97
+ // Tool factory
98
+ // ---------------------------------------------------------------------------
99
+
61
100
  export function createSubagentTool() {
62
101
  return {
63
- name: "ce_subagent",
64
- async execute(input: SubagentInput, runner: SubagentRunner): Promise<SubagentResult> {
102
+ name: "ce_subagent" as const,
103
+
104
+ /**
105
+ * Execute the subagent tool.
106
+ *
107
+ * Supports two runner signatures:
108
+ * - SubagentLiveRunner (preferred): returns SingleResult, supports onUpdate
109
+ * - SubagentRunner (legacy): returns string, no onUpdate
110
+ */
111
+ async execute(
112
+ input: SubagentInput,
113
+ runner: SubagentLiveRunner | SubagentRunner,
114
+ toolCtx?: { onUpdate?: (details: SubagentLiveDetails) => void },
115
+ ): Promise<SubagentLiveResult> {
65
116
  // Recursion depth guard
66
117
  const depthCheck = checkSubagentDepth()
67
118
  if (!depthCheck.allowed) {
@@ -80,46 +131,71 @@ export function createSubagentTool() {
80
131
  if (hasSingle) {
81
132
  assertNonPipelineStageSkill(input.agent!, "ce_subagent")
82
133
  const prompt = buildPrompt(input.agent!, input.task!)
83
- const output = await runner(prompt, execOptions)
134
+
135
+ const liveOptions: SubagentLiveExecOptions = {
136
+ ...execOptions,
137
+ onUpdate: (partial: SingleResult) => {
138
+ if (toolCtx?.onUpdate) {
139
+ toolCtx.onUpdate({ mode: "single", results: [partial] })
140
+ }
141
+ },
142
+ }
143
+
144
+ const result = await invokeRunner(runner, prompt, liveOptions)
145
+ result.agent = input.agent!
146
+ result.task = input.task!
84
147
  return {
85
148
  mode: "single",
86
- outputs: [output],
149
+ results: [result],
150
+ outputs: [getFinalOutput(result.messages)],
87
151
  }
88
152
  }
89
153
 
90
- const outputs: string[] = []
154
+ // Chain mode
155
+ const results: SingleResult[] = []
91
156
  let previous = ""
92
157
 
93
158
  for (const task of input.chain ?? []) {
94
159
  assertNonPipelineStageSkill(task.agent, "ce_subagent")
95
160
  const prompt = buildPrompt(task.agent, task.task.replace(/\{previous\}/g, previous))
96
- const output = await runner(prompt, execOptions)
97
- outputs.push(output)
98
- previous = output
161
+
162
+ const liveOptions: SubagentLiveExecOptions = {
163
+ ...execOptions,
164
+ onUpdate: (partial: SingleResult) => {
165
+ if (toolCtx?.onUpdate) {
166
+ toolCtx.onUpdate({ mode: "chain", results: [...results, partial] })
167
+ }
168
+ },
169
+ }
170
+
171
+ const result = await invokeRunner(runner, prompt, liveOptions)
172
+ result.agent = task.agent
173
+ result.task = task.task
174
+ results.push(result)
175
+ previous = getFinalOutput(result.messages)
99
176
  }
100
177
 
101
178
  return {
102
179
  mode: "chain",
103
- outputs,
180
+ results,
181
+ outputs: results.map(r => getFinalOutput(r.messages)),
104
182
  }
105
183
  },
106
184
  }
107
185
  }
108
186
 
109
- /**
110
- * Build exec options based on subagent configuration.
111
- * Controls context inheritance and recursion depth.
112
- */
113
- function buildExecOptions(inheritSkills?: boolean): SubagentExecOptions {
187
+ // ---------------------------------------------------------------------------
188
+ // Helpers
189
+ // ---------------------------------------------------------------------------
190
+
191
+ function buildExecOptions(inheritSkills?: boolean): { extraFlags?: string[]; extraEnv: Record<string, string> } {
114
192
  const flags: string[] = []
115
193
  const env: Record<string, string> = {}
116
194
 
117
- // Context slimming: skip skills inheritance when explicitly disabled
118
195
  if (inheritSkills === false) {
119
196
  flags.push("--no-skills")
120
197
  }
121
198
 
122
- // Recursion depth: pass incremented depth to child process
123
199
  Object.assign(env, getChildDepthEnv())
124
200
 
125
201
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leing2021/super-pi",
3
- "version": "0.23.9",
3
+ "version": "0.23.10",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Pi-native Compound Engineering package for iterative development workflows",