@topce/pizx 0.5.0 → 0.6.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/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ![pizx — zx fork with native Pi AI integration](github-social-banner.png)
6
6
 
7
- > **zx fork with native Pi AI integration** — 15 template tags for shell scripting, AI text generation, coding agents, agentic patterns, communication, and orchestration topologies.
7
+ > **zx fork with native Pi AI integration** — 15 agent pattern tags (plus shell and AI core) for shell scripting, AI text generation, coding agents, agentic patterns, multi-agent communication, and orchestration topologies.
8
8
 
9
9
  ## Quick Start
10
10
 
@@ -87,6 +87,27 @@ await fleet`review all files in src/`
87
87
  > `pi` (alias for `π`), `Pi` (alias for `Π`), `fleet` (alias for `Φ`), `ralph` (alias for `Ρ`),
88
88
  > `pipeline` (alias for `Λ`), etc. — use whichever style you prefer. See [full mapping](#english-aliases) below.
89
89
 
90
+ ### Global Access (pizx/globals)
91
+
92
+ Import the `pizx/globals` module to make **all tags and English aliases** available without explicit imports — matching the `#!/usr/bin/env pizx` shebang experience inside scripts loaded via `import()`:
93
+
94
+ ```js
95
+ import '@topce/pizx/globals'
96
+
97
+ // All Greek tags are available without imports:
98
+ const answer = await π`explain async/await`
99
+ await Π`fix the lint issues`
100
+ await Φ`review all files`
101
+
102
+ // English aliases too:
103
+ const docs = await fleet`check all .ts files`
104
+ const plan = await orchestrator`design the architecture`
105
+
106
+ // Helpers:
107
+ configurePi({ model: 'anthropic/claude-sonnet-4-5' })
108
+ closeAgent()
109
+ ```
110
+
90
111
  ### CLI Quick Queries
91
112
 
92
113
  ```bash
@@ -193,7 +214,10 @@ await Ω({ system: 'You are a senior security architect.' })`design an auth syst
193
214
 
194
215
  ### Quality Validation
195
216
 
196
- All 15 patterns support an optional `qualityCheck` flag. When enabled, the pattern runs a post-execution LLM review that scores the final output (0.0–1.0), provides an assessment, and recommends improvements:
217
+ 12 patterns support an optional `qualityCheck` flag. When enabled, the pattern runs a post-execution LLM review that scores the final output (0.0–1.0), provides an assessment, and recommends improvements:
218
+
219
+ Supported by: `Ω` (Orchestrator), `Φ` (Fleet), `Σ` (Subagents), `Δ` (Debate), `Λ` (Pipeline), `Θ` (Thread), `Μ` (Memory), `Β` (Broadcast), `Γ` (Graph), `Ν` (Nu/Team), `Χ` (Chi/Learn), `Τ` (Tau/Store).
220
+ Not applicable to: `Ρ` (Ralph Loop — has its own review phase), `Α` (Adaptive), `Ψ` (Critique).
197
221
 
198
222
  ```js
199
223
  const result = await Ω({ qualityCheck: true })`design the system architecture`
@@ -219,7 +243,32 @@ await Ω({ confirm: true })`design the system`
219
243
  // → "Proceed? [Y/n] "
220
244
  ```
221
245
 
222
- Supported by: `Ω`, `Σ`, `Φ`, `Λ` (more patterns coming).
246
+ Supported by: `Ω`, `Σ`, `Φ`, `Λ`.
247
+
248
+ ### Agent Mode (File Tools for Any Pattern)
249
+
250
+ By default, all patterns (except `Pi` and `ralph`) use **text generation** — they can read files only if you pass content in via template interpolation. `ralph` already uses coding agent tools when `useTools: true` (default).
251
+
252
+ Set `mode: 'agent'` to give every subtask the same **coding agent tools** as `Pi`:
253
+
254
+ ```js
255
+ // Fleet workers can read files
256
+ await fleet({ mode: 'agent' })`read package.json and analyze the project`
257
+
258
+ // Pipeline stages can edit code
259
+ await pipeline({ mode: 'agent' })`read src/ and refactor the error handling`
260
+
261
+ // Orchestrator workers can run commands
262
+ await orchestrator({ mode: 'agent' })`check the test coverage and report gaps`
263
+
264
+ // Debate perspectives can research the codebase
265
+ await debate({ mode: 'agent' })`read the architecture docs and debate the design`
266
+ ```
267
+
268
+ Available tools: `read`, `bash`, `edit`, `write`, `grep`, `ls`.
269
+
270
+ Supported by: all patterns (`fleet`, `orchestrator`, `pipeline`, `debate`, `subagent`, `critique`, `thread`, `memory`, `broadcast`, `adaptive`, `graph`, `team`, `learn`, `store`).
271
+ Not applicable to: `pi`/`π` (always text), `Pi`/`Π` and `ralph` (already use coding agent).
223
272
 
224
273
  ### Option Chaining & Quiet Mode
225
274
 
@@ -234,7 +283,7 @@ await Θ({ agents: 4, turns: 3 })`debate the architecture`
234
283
  await Γ({ graph: { nodes: [...], edges: [...] } })`execute workflow`
235
284
  ```
236
285
 
237
- ### Timeout & Retry
286
+ ### Timeout, Retry & API Key
238
287
 
239
288
  All tags accept `timeoutMs` and `maxRetries` to control LLM call resilience. When unset, the provider SDK defaults apply (typically 10 min timeout, 2 retries).
240
289
 
@@ -249,6 +298,23 @@ await π({ timeoutMs: 15000 })`summarize this document`
249
298
  configurePi({ timeoutMs: 60000, maxRetries: 3 })
250
299
  ```
251
300
 
301
+ Use `apiKey` to specify a provider API key directly, bypassing environment variable lookup:
302
+
303
+ ```js
304
+ await π({ apiKey: 'sk-...' })`analyze this data`
305
+ await Ω({ apiKey: 'sk-...' })`design the system`
306
+ ```
307
+
308
+ ### Streaming (π.stream)
309
+
310
+ For real-time streaming, use `π.stream` as an async generator:
311
+
312
+ ```js
313
+ for await (const chunk of π.stream`tell me a long story`) {
314
+ process.stdout.write(chunk)
315
+ }
316
+ ```
317
+
252
318
  ### Token, Cost & Phase Tracking
253
319
 
254
320
  Every pattern output and π call includes an execution trace with token usage, cost, and a structured phase log. All collected automatically — no extra flags needed.
@@ -326,6 +392,9 @@ All tags accept `system` (replaces default) and `appendSystemPrompt` (appended a
326
392
  // π: custom system prompt
327
393
  await π({ system: 'You are a security auditor' })`review this code`
328
394
 
395
+ // π: with appendSystemPrompt
396
+ await π({ appendSystemPrompt: 'Respond in JSON format' })`list all .ts files`
397
+
329
398
  // Π: set system prompt and append extra instructions
330
399
  await Π({ system: 'You are a test engineer', appendSystemPrompt: 'Write tests first' })`add tests for auth`
331
400
 
@@ -333,6 +402,15 @@ await Π({ system: 'You are a test engineer', appendSystemPrompt: 'Write tests f
333
402
  await Ω({ system: 'Prioritize security over performance' })`design login flow`
334
403
  ```
335
404
 
405
+ ### closeAgent()
406
+
407
+ Dispose the shared Pi coding agent session (`Π`). Useful in long-running scripts or tests to reset state:
408
+
409
+ ```js
410
+ import { closeAgent } from '@topce/pizx'
411
+ await closeAgent() // dispose shared agent session
412
+ ```
413
+
336
414
  ### Thinking Budgets
337
415
 
338
416
  Fine-grained token budgets per reasoning level. Passes through to providers via `thinkingBudgets`.
@@ -381,15 +459,15 @@ pizx --help # Print help
381
459
  **Options:**
382
460
  - `-p, --prompt <text>` — Run a quick pi-ai query (no script needed)
383
461
  - `-m, --model <id>` — Specify AI model to use
384
- - `--quiet` — Suppress output except errors
385
- - `--shell <path>` — Shell to use (default: auto-detect)
462
+ - `-q, --quiet` — Suppress status output
463
+ - `--system <text>` — System context for pi-ai (print mode only)
386
464
 
387
465
  ## Commands
388
466
 
389
467
  ```bash
390
468
  npm run build # Build (JS + DTS)
391
469
  npm run check # Lint and format with Biome
392
- npm test # 223 unit tests (no network)
470
+ npm test # 311 unit tests (no network)
393
471
  npm run test:integration # Integration tests (requires Pi credentials)
394
472
  npm run test:quality # Run qualityCheck example
395
473
  npm run test:confirm # Run confirm gate example
@@ -409,10 +487,40 @@ See [`examples/`](examples/) for runnable examples of every pattern and feature:
409
487
  - [`hello-pizx.mjs`](examples/hello-pizx.mjs) — Basic script with shell + AI
410
488
  - [`basic-pi.mjs`](examples/basic-pi.mjs) — π text generation
411
489
  - [`basic-capital-pi.mjs`](examples/basic-capital-pi.mjs) — Π coding agent
412
- - [`pattern-ralph.mjs`](examples/pattern-ralph.mjs) — Ralph Loop
490
+ - [`quick-ask.mjs`](examples/quick-ask.mjs) — Quick π query
491
+ - [`ralph-loop.mjs`](examples/ralph-loop.mjs) — Ralph Loop (detailed)
492
+ - [`pattern-ralph.mjs`](examples/pattern-ralph.mjs) — Ralph Loop (concise)
413
493
  - [`pattern-fleet.mjs`](examples/pattern-fleet.mjs) — Fleet parallel execution
494
+ - [`pattern-subagent.mjs`](examples/pattern-subagent.mjs) — Subagents delegation
414
495
  - [`pattern-debate.mjs`](examples/pattern-debate.mjs) — Multi-perspective debate
415
- - ... and more for every pattern
496
+ - [`pattern-orchestrator.mjs`](examples/pattern-orchestrator.mjs) Orchestrator
497
+ - [`pattern-pipeline.mjs`](examples/pattern-pipeline.mjs) — Pipeline chain
498
+ - [`pattern-critique.mjs`](examples/pattern-critique.mjs) — Critique loop
499
+ - [`pattern-thread.mjs`](examples/pattern-thread.mjs) — Thread conversation
500
+ - [`pattern-memory.mjs`](examples/pattern-memory.mjs) — Memory blackboard
501
+ - [`pattern-broadcast.mjs`](examples/pattern-broadcast.mjs) — Broadcast messaging
502
+ - [`pattern-adaptive.mjs`](examples/pattern-adaptive.mjs) — Adaptive workflow
503
+ - [`pattern-graph.mjs`](examples/pattern-graph.mjs) — DAG execution
504
+ - [`pattern-nu.mjs`](examples/pattern-nu.mjs) — Self-organizing teams
505
+ - [`pattern-chi.mjs`](examples/pattern-chi.mjs) — Cross-agent learning
506
+ - [`pattern-tau.mjs`](examples/pattern-tau.mjs) — Tool-mediated store
507
+ - [`pattern-five-whys.mjs`](examples/pattern-five-whys.mjs) — Five Whys analysis
508
+ - [`pattern-tracking.mjs`](examples/pattern-tracking.mjs) — Token/cost tracking
509
+ - [`pattern-quality.mjs`](examples/pattern-quality.mjs) — Quality check demo
510
+ - [`pattern-timeout-retry.mjs`](examples/pattern-timeout-retry.mjs) — Timeout & retry demo
511
+ - [`pattern-system-propagation.mjs`](examples/pattern-system-propagation.mjs) — System prompt propagation
512
+
513
+ ### English Aliases Examples
514
+
515
+ See [`english-examples/`](english-examples/) for runnable examples using all English aliases:
516
+
517
+ - [`english-hello.mjs`](english-examples/english-hello.mjs) — Hello world with English aliases
518
+ - [`english-fleet.mjs`](english-examples/english-fleet.mjs) — Fleet via English aliases
519
+ - [`english-debate.mjs`](english-examples/english-debate.mjs) — Debate via English aliases
520
+ - [`english-orchestrator.mjs`](english-examples/english-orchestrator.mjs) — Orchestrator via English aliases
521
+ - [`english-pipeline.mjs`](english-examples/english-pipeline.mjs) — Pipeline via English aliases
522
+ - [`english-all-patterns.mjs`](english-examples/english-all-patterns.mjs) — All patterns via English aliases
523
+ - [`english-import-verify.mjs`](english-examples/english-import-verify.mjs) — Verify all imports
416
524
 
417
525
  ### New Feature Demos
418
526
 
package/dist/cli.js CHANGED
@@ -101,6 +101,7 @@ function loadPiAuth() {
101
101
  // src/patterns/types.ts
102
102
  import { createInterface } from "node:readline";
103
103
  import { completeSimple } from "@earendil-works/pi-ai";
104
+ import { createAgentSession } from "@earendil-works/pi-coding-agent";
104
105
 
105
106
  // src/model-picker.ts
106
107
  import {
@@ -393,6 +394,40 @@ ${skillContext}` : skillContext;
393
394
  }
394
395
  return text.trim();
395
396
  }
397
+ async function executeTask(prompt, opts = {}) {
398
+ if (opts.mode === "agent") {
399
+ return runAgentTask(prompt, opts);
400
+ }
401
+ return ask(prompt, opts);
402
+ }
403
+ async function runAgentTask(prompt, opts) {
404
+ const model = pickModel(opts.model);
405
+ if (!model) throw new Error("pizx/patterns: No AI models configured. Run `pi auth login` first.");
406
+ const tools = ["read", "bash", "edit", "write", "grep", "ls"];
407
+ const { session } = await createAgentSession({
408
+ tools,
409
+ ...model ? { model } : {}
410
+ });
411
+ try {
412
+ await session.sendUserMessage(prompt);
413
+ const messages = session.messages;
414
+ for (let i = messages.length - 1; i >= 0; i--) {
415
+ const msg = messages[i];
416
+ if (msg?.role !== "assistant") continue;
417
+ const c = "content" in msg ? msg.content : void 0;
418
+ if (typeof c === "string") return c.trim();
419
+ if (Array.isArray(c)) {
420
+ const texts = c.filter(
421
+ (block) => typeof block === "object" && block !== null && "type" in block && "text" in block
422
+ ).map((block) => block.text);
423
+ if (texts.length > 0) return texts.join("\n").trim();
424
+ }
425
+ }
426
+ return "";
427
+ } finally {
428
+ session.dispose();
429
+ }
430
+ }
396
431
  var QUALITY_REVIEW_SYSTEM = `You are a quality assurance reviewer. Evaluate the final deliverable against the original request.
397
432
 
398
433
  Output format:
@@ -496,7 +531,7 @@ async function execute(pieces, args, opts) {
496
531
  `);
497
532
  }
498
533
  if (!opts.quiet) process.stderr.write(" \u2192 Planning...\n");
499
- const planText = await ask(goal, {
534
+ const planText = await executeTask(goal, {
500
535
  ...opts,
501
536
  model: plannerModel,
502
537
  thinkingLevel: "high",
@@ -529,12 +564,12 @@ async function execute(pieces, args, opts) {
529
564
  if (!opts.quiet)
530
565
  process.stderr.write(` \u2192 Step ${executionStep}: ${currentStep.slice(0, 60)}...
531
566
  `);
532
- const result = await ask(currentStep, {
567
+ const result = await executeTask(currentStep, {
533
568
  ...opts,
534
569
  model: workerModel,
535
570
  system: mergeSystem(opts.system, EXECUTE_SYSTEM)
536
571
  });
537
- const evaluation = await ask(
572
+ const evaluation = await executeTask(
538
573
  `Goal: ${goal}
539
574
  Step executed: ${currentStep}
540
575
  Result: ${result}
@@ -738,7 +773,7 @@ async function execute2(pieces, args, opts) {
738
773
  const broadcastResults = await Promise.allSettled(
739
774
  roles.map(async (role) => {
740
775
  const prompt = WORKER_PROMPT.replace("{role}", role).replace("{question}", question);
741
- const text = await ask(prompt, { ...opts, model: workerModel });
776
+ const text = await executeTask(prompt, { ...opts, model: workerModel });
742
777
  return new BroadcastResponse(role, text, true);
743
778
  })
744
779
  );
@@ -754,7 +789,7 @@ async function execute2(pieces, args, opts) {
754
789
  if (!opts.quiet) process.stderr.write(" \u2192 Synthesizing responses...\n");
755
790
  const responsesText = responses.map((wr) => `--- ${wr.role} ---
756
791
  ${wr.response}`).join("\n\n");
757
- const synthesis = await ask(
792
+ const synthesis = await executeTask(
758
793
  `Original question:
759
794
  ${question}
760
795
 
@@ -875,7 +910,7 @@ async function execute3(pieces, args, opts) {
875
910
  process.stderr.write(`\u03A7: Cross-Agent Learning \u2014 analyzing ${label}
876
911
  `);
877
912
  }
878
- const response = await ask(input, {
913
+ const response = await executeTask(input, {
879
914
  ...opts,
880
915
  model: plannerModel,
881
916
  system: mergeSystem(opts.system, ANALYSIS_SYSTEM)
@@ -951,12 +986,16 @@ async function execute4(pieces, args, opts) {
951
986
  for (let r = 0; r < rounds; r++) {
952
987
  if (r === 0) {
953
988
  if (!opts.quiet) process.stderr.write(" \u2192 Generating initial content...\n");
954
- currentContent = await ask(prompt, { ...opts, model: workerModel, system: opts.system });
989
+ currentContent = await executeTask(prompt, {
990
+ ...opts,
991
+ model: workerModel,
992
+ system: opts.system
993
+ });
955
994
  } else {
956
995
  if (!opts.quiet) process.stderr.write(` \u2192 Improving (round ${r + 1})...
957
996
  `);
958
997
  const prevCritique = critiqueRounds[r - 1]?.critique ?? "";
959
- currentContent = await ask(
998
+ currentContent = await executeTask(
960
999
  `Original request: ${prompt}
961
1000
 
962
1001
  Critique:
@@ -971,7 +1010,7 @@ Revise the content based on the critique.`,
971
1010
  }
972
1011
  if (!opts.quiet) process.stderr.write(` \u2192 Critiquing (round ${r + 1})...
973
1012
  `);
974
- const critique2 = await ask(currentContent, {
1013
+ const critique2 = await executeTask(currentContent, {
975
1014
  ...opts,
976
1015
  model: plannerModel,
977
1016
  system: mergeSystem(opts.system, CRITIQUE_SYSTEM)
@@ -1102,7 +1141,7 @@ Refine your position. Address the counter-arguments directly. Strengthen your ar
1102
1141
  `;
1103
1142
  }
1104
1143
  if (!opts.quiet) process.stderr.write(" \u2192 Synthesizing perspectives...\n");
1105
- const conclusion = await ask(
1144
+ const conclusion = await executeTask(
1106
1145
  `${debateHistory}
1107
1146
 
1108
1147
  Synthesize a balanced conclusion from the full debate above. Weigh the evidence from all rounds.`,
@@ -1178,7 +1217,7 @@ function describeTask(task) {
1178
1217
  return task;
1179
1218
  }
1180
1219
  var FLEET_SYSTEM = `You are a focused task specialist. Complete the assigned task concisely and accurately. Output only the result \u2014 no commentary about being an AI.`;
1181
- async function executeTask(task, opts, workerModel) {
1220
+ async function executeFleetTask(task, opts, workerModel) {
1182
1221
  if (typeof task === "function") {
1183
1222
  try {
1184
1223
  const text = await task("");
@@ -1189,7 +1228,7 @@ async function executeTask(task, opts, workerModel) {
1189
1228
  }
1190
1229
  const model = workerModel ?? opts.model;
1191
1230
  try {
1192
- const text = await ask(task, {
1231
+ const text = await executeTask(task, {
1193
1232
  ...opts,
1194
1233
  model,
1195
1234
  system: mergeSystem(opts.system, FLEET_SYSTEM)
@@ -1223,7 +1262,7 @@ async function execute6(pieces, args, opts) {
1223
1262
  for (let i = 0; i < tasks.length; i += concurrency) {
1224
1263
  const batch = tasks.slice(i, i + concurrency);
1225
1264
  const batchResults = await Promise.allSettled(
1226
- batch.map((task) => executeTask(task, opts, workerModel))
1265
+ batch.map((task) => executeFleetTask(task, opts, workerModel))
1227
1266
  );
1228
1267
  batchResults.forEach((r, idx) => {
1229
1268
  if (r.status === "fulfilled") {
@@ -1370,7 +1409,7 @@ ${depResults}
1370
1409
  Your task: ${node.task}`;
1371
1410
  }
1372
1411
  }
1373
- const text = await ask(context, {
1412
+ const text = await executeTask(context, {
1374
1413
  ...opts,
1375
1414
  model: workerModel,
1376
1415
  system: mergeSystem(opts.system, NODE_SYSTEM)
@@ -1465,7 +1504,7 @@ async function execute8(pieces, args, opts) {
1465
1504
  const roundResults = await Promise.allSettled(
1466
1505
  roles.map(async (role) => {
1467
1506
  const prompt = buildWriterPrompt(role, topic, blackboard);
1468
- const text = await ask(prompt, { ...opts, model: workerModel });
1507
+ const text = await executeTask(prompt, { ...opts, model: workerModel });
1469
1508
  return { role, text };
1470
1509
  })
1471
1510
  );
@@ -1479,7 +1518,7 @@ async function execute8(pieces, args, opts) {
1479
1518
  }
1480
1519
  }
1481
1520
  if (!opts.quiet) process.stderr.write(" \u2192 Consolidating findings...\n");
1482
- const synthesis = await ask(
1521
+ const synthesis = await executeTask(
1483
1522
  `Topic: ${topic}
1484
1523
 
1485
1524
  Blackboard findings:
@@ -1570,7 +1609,7 @@ async function negotiateRoles(task, opts) {
1570
1609
  const min = opts.minAgents ?? 2;
1571
1610
  const max = opts.maxAgents ?? 5;
1572
1611
  const prompt = NEGOTIATE_SYSTEM.replace("{min}", String(min)).replace("{max}", String(max));
1573
- const response = await ask(`Task: ${task}
1612
+ const response = await executeTask(`Task: ${task}
1574
1613
 
1575
1614
  ${prompt}`, {
1576
1615
  ...opts,
@@ -1602,7 +1641,7 @@ async function decideWorkflow(roles, task, opts) {
1602
1641
  if (roles.length <= 1)
1603
1642
  return { workflow: "parallel", reasoning: "Single role \u2014 no dependencies." };
1604
1643
  const rolesText = roles.map((r, i) => `${i + 1}. ${r.name}: ${r.goal}`).join("\n");
1605
- const response = await ask(
1644
+ const response = await executeTask(
1606
1645
  `Task: ${task}
1607
1646
 
1608
1647
  Roles:
@@ -1632,7 +1671,7 @@ async function executeRoles(roles, task, workflow, opts) {
1632
1671
  if (workflow === "sequential") {
1633
1672
  let context = task;
1634
1673
  for (const role of roles) {
1635
- const output = await ask(context, {
1674
+ const output = await executeTask(context, {
1636
1675
  ...opts,
1637
1676
  model: workerModel,
1638
1677
  system: mergeSystem(opts.system, EXECUTE_SYSTEM2(role))
@@ -1800,7 +1839,7 @@ async function execute10(pieces, args, opts) {
1800
1839
  }
1801
1840
  if (!opts.quiet) process.stderr.write(" \u2192 Planning...\n");
1802
1841
  const planStart = Date.now();
1803
- const planText = await ask(request, {
1842
+ const planText = await executeTask(request, {
1804
1843
  ...opts,
1805
1844
  model: plannerModel,
1806
1845
  thinkingLevel: "high",
@@ -1865,7 +1904,7 @@ async function execute10(pieces, args, opts) {
1865
1904
  const workerTexts = workerResults.map((wr, i) => `Task ${i + 1}: ${wr.task}
1866
1905
  Result: ${wr.output}`).join("\n\n");
1867
1906
  const synthStart = Date.now();
1868
- const synthesis = await ask(
1907
+ const synthesis = await executeTask(
1869
1908
  `Original request:
1870
1909
  ${request}
1871
1910
 
@@ -2016,7 +2055,7 @@ async function execute11(pieces, args, opts) {
2016
2055
  } else {
2017
2056
  const prompt = customPrompt ?? generateStagePrompt(stage, currentInput, i === 0);
2018
2057
  const systemMessage = i === 0 ? `You are a specialist executing stage ${i + 1}: ${stage}. Focus only on this stage's output.` : `You are a specialist executing stage ${i + 1}: ${stage}. Process the previous stage's output according to your instructions. Maintain all important information from previous stages.`;
2019
- output = await ask(prompt, {
2058
+ output = await executeTask(prompt, {
2020
2059
  ...opts,
2021
2060
  model: workerModel,
2022
2061
  system: mergeSystem(opts.system, systemMessage)
@@ -2038,7 +2077,7 @@ ${sr.output.slice(0, 200)}${sr.output.length > 200 ? "..." : ""}`
2038
2077
  var \u039B = createPatternTag(defaults11, execute11);
2039
2078
 
2040
2079
  // src/patterns/ralph.ts
2041
- import { createAgentSession } from "@earendil-works/pi-coding-agent";
2080
+ import { createAgentSession as createAgentSession2 } from "@earendil-works/pi-coding-agent";
2042
2081
  var defaults12 = {
2043
2082
  maxIterations: 5,
2044
2083
  useTools: true,
@@ -2064,7 +2103,7 @@ async function executeWithTools(goal, opts) {
2064
2103
  `pizx/\u03A1: model not found: "${opts.model}". Run \`pi models\` to see available models.`
2065
2104
  );
2066
2105
  }
2067
- const { session } = await createAgentSession({
2106
+ const { session } = await createAgentSession2({
2068
2107
  tools: ["read", "bash", "edit", "write", "grep", "ls"],
2069
2108
  ...agentModel ? { model: agentModel } : {}
2070
2109
  });
@@ -2114,13 +2153,13 @@ async function execute12(pieces, args, opts) {
2114
2153
  `);
2115
2154
  }
2116
2155
  if (!opts.quiet) process.stderr.write(" \u2192 Analyzing...\n");
2117
- const analysis = await ask(currentGoal, {
2156
+ const analysis = await executeTask(currentGoal, {
2118
2157
  ...opts,
2119
2158
  model: plannerModel,
2120
2159
  system: mergeSystem(opts.system, ANALYSIS_SYSTEM2)
2121
2160
  });
2122
2161
  if (!opts.quiet) process.stderr.write(" \u2192 Planning...\n");
2123
- const plan = await ask(
2162
+ const plan = await executeTask(
2124
2163
  `Goal: ${currentGoal}
2125
2164
 
2126
2165
  Analysis: ${analysis}
@@ -2135,7 +2174,7 @@ ${plan}
2135
2174
  Goal: ${currentGoal}`, {
2136
2175
  ...opts,
2137
2176
  model: workerModel
2138
- }) : await ask(`Implement this plan:
2177
+ }) : await executeTask(`Implement this plan:
2139
2178
  ${plan}
2140
2179
 
2141
2180
  Goal: ${currentGoal}`, {
@@ -2143,19 +2182,22 @@ Goal: ${currentGoal}`, {
2143
2182
  model: workerModel
2144
2183
  });
2145
2184
  if (!opts.quiet) process.stderr.write(" \u2192 Reviewing...\n");
2146
- const review = await ask(`Plan:
2185
+ const review = await executeTask(
2186
+ `Plan:
2147
2187
  ${plan}
2148
2188
 
2149
2189
  Result:
2150
2190
  ${result}
2151
2191
 
2152
- Review the implementation.`, {
2153
- ...opts,
2154
- model: plannerModel,
2155
- maxTokens: 1024,
2156
- thinkingLevel: "high",
2157
- system: mergeSystem(opts.system, REVIEW_SYSTEM)
2158
- });
2192
+ Review the implementation.`,
2193
+ {
2194
+ ...opts,
2195
+ model: plannerModel,
2196
+ maxTokens: 1024,
2197
+ thinkingLevel: "high",
2198
+ system: mergeSystem(opts.system, REVIEW_SYSTEM)
2199
+ }
2200
+ );
2159
2201
  const shouldContinue = review.includes("ITERATE") && !review.includes("DONE");
2160
2202
  iterations.push({
2161
2203
  iteration,
@@ -2224,7 +2266,7 @@ var DECOMPOSE_SYSTEM = `You are a task decomposition specialist. Break down comp
2224
2266
  var SYNTHESIS_SYSTEM5 = `You are a synthesis specialist. Combine the results from multiple sub-agent analyses into a coherent, comprehensive answer. Identify patterns, conflicts, and gaps.`;
2225
2267
  async function decomposeTask(task, opts) {
2226
2268
  if (opts.subdomains && opts.subdomains.length > 0) return opts.subdomains;
2227
- const result = await ask(
2269
+ const result = await executeTask(
2228
2270
  `Decompose this task into ${opts.maxSubTasks ?? 4} independent sub-tasks that can be worked on in parallel:
2229
2271
 
2230
2272
  ${task}
@@ -2314,7 +2356,7 @@ async function execute13(pieces, args, opts) {
2314
2356
  const subResultsText = subResults.map((sr, i) => `Sub-task ${i + 1}: ${sr.subTask}
2315
2357
  Result: ${sr.text}`).join("\n\n");
2316
2358
  const synthStart = Date.now();
2317
- const synthesis = await ask(
2359
+ const synthesis = await executeTask(
2318
2360
  `Original task:
2319
2361
  ${task}
2320
2362
 
@@ -2432,7 +2474,7 @@ var CONSOLIDATE_SYSTEM = `You are a research director. Consolidate the structure
2432
2474
  async function defineSchema(task, opts) {
2433
2475
  const agentCount = opts.agents ?? 3;
2434
2476
  const prompt = SCHEMA_SYSTEM.replace("{agentCount}", String(agentCount));
2435
- const response = await ask(`Task: ${task}
2477
+ const response = await executeTask(`Task: ${task}
2436
2478
 
2437
2479
  ${prompt}`, {
2438
2480
  ...opts,
@@ -2487,7 +2529,7 @@ async function executeRound(roles, assignments, store2, round, opts) {
2487
2529
  const storeText = formatStore(store2);
2488
2530
  const systemPrompt = isWrite ? WRITE_SYSTEM(role, keysStr).replace("{store}", storeText) : UPDATE_SYSTEM(role, keysStr).replace("{store}", storeText);
2489
2531
  const task = isWrite ? `Write your initial findings to your assigned keys: ${keysStr}` : `Review the shared context and update your entries for keys: ${keysStr}`;
2490
- const response = await ask(task, {
2532
+ const response = await executeTask(task, {
2491
2533
  ...opts,
2492
2534
  model: workerModel,
2493
2535
  system: mergeSystem(opts.system, systemPrompt)
@@ -2658,7 +2700,7 @@ async function execute15(pieces, args, opts) {
2658
2700
  for (let a = 0; a < roles.length; a++) {
2659
2701
  const role = roles[a] ?? `Agent ${a + 1}`;
2660
2702
  const prompt = buildThreadPrompt(role, thread2);
2661
- const response = await ask(prompt, { ...opts, model: workerModel });
2703
+ const response = await executeTask(prompt, { ...opts, model: workerModel });
2662
2704
  messages.push(new ThreadMessage(role, turn, response));
2663
2705
  thread2 += `
2664
2706
  [${role}] (Turn ${turn}): ${response}
@@ -2666,7 +2708,7 @@ async function execute15(pieces, args, opts) {
2666
2708
  }
2667
2709
  }
2668
2710
  if (!opts.quiet) process.stderr.write(" \u2192 Synthesizing conclusion...\n");
2669
- const conclusion = await ask(
2711
+ const conclusion = await executeTask(
2670
2712
  `Topic: ${topic}
2671
2713
 
2672
2714
  Conversation thread:
@@ -2881,7 +2923,7 @@ var \u03C0 = makePi();
2881
2923
 
2882
2924
  // src/pi-agent.ts
2883
2925
  import {
2884
- createAgentSession as createAgentSession2,
2926
+ createAgentSession as createAgentSession3,
2885
2927
  DefaultResourceLoader
2886
2928
  } from "@earendil-works/pi-coding-agent";
2887
2929
  var _agentDefaults = {
@@ -2946,7 +2988,7 @@ async function getSession(opts) {
2946
2988
  loader.extendResources({ skillPaths });
2947
2989
  }
2948
2990
  }
2949
- const result = await createAgentSession2({
2991
+ const result = await createAgentSession3({
2950
2992
  cwd: opts.cwd,
2951
2993
  thinkingLevel: opts.thinkingLevel,
2952
2994
  tools: opts.tools,