pi-agent-flow 1.8.1 → 1.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/README.md +4 -30
  2. package/agents/audit.md +1 -2
  3. package/agents/build.md +1 -0
  4. package/agents/craft.md +12 -8
  5. package/agents/debug.md +2 -2
  6. package/agents/ideas.md +1 -0
  7. package/agents/scout.md +1 -0
  8. package/dist/agents.d.ts +41 -0
  9. package/dist/agents.d.ts.map +1 -0
  10. package/dist/agents.js +283 -0
  11. package/dist/agents.js.map +1 -0
  12. package/dist/batch/batch-bash.d.ts +87 -0
  13. package/dist/batch/batch-bash.d.ts.map +1 -0
  14. package/dist/batch/batch-bash.js +369 -0
  15. package/dist/batch/batch-bash.js.map +1 -0
  16. package/dist/batch/constants.d.ts +100 -0
  17. package/dist/batch/constants.d.ts.map +1 -0
  18. package/dist/batch/constants.js +15 -0
  19. package/dist/batch/constants.js.map +1 -0
  20. package/dist/batch/execute.d.ts +21 -0
  21. package/dist/batch/execute.d.ts.map +1 -0
  22. package/dist/batch/execute.js +440 -0
  23. package/dist/batch/execute.js.map +1 -0
  24. package/dist/batch/fuzzy-edit.d.ts +29 -0
  25. package/dist/batch/fuzzy-edit.d.ts.map +1 -0
  26. package/dist/batch/fuzzy-edit.js +257 -0
  27. package/dist/batch/fuzzy-edit.js.map +1 -0
  28. package/dist/batch/index.d.ts +85 -0
  29. package/dist/batch/index.d.ts.map +1 -0
  30. package/dist/batch/index.js +422 -0
  31. package/dist/batch/index.js.map +1 -0
  32. package/dist/batch/render.d.ts +14 -0
  33. package/dist/batch/render.d.ts.map +1 -0
  34. package/dist/batch/render.js +74 -0
  35. package/dist/batch/render.js.map +1 -0
  36. package/dist/batch/symbols.d.ts +9 -0
  37. package/dist/batch/symbols.d.ts.map +1 -0
  38. package/dist/batch/symbols.js +310 -0
  39. package/dist/batch/symbols.js.map +1 -0
  40. package/dist/batch.d.ts +12 -0
  41. package/dist/batch.d.ts.map +1 -0
  42. package/dist/batch.js +11 -0
  43. package/dist/batch.js.map +1 -0
  44. package/dist/cli-args.d.ts +27 -0
  45. package/dist/cli-args.d.ts.map +1 -0
  46. package/dist/cli-args.js +265 -0
  47. package/dist/cli-args.js.map +1 -0
  48. package/dist/config.d.ts +58 -0
  49. package/dist/config.d.ts.map +1 -0
  50. package/dist/config.js +296 -0
  51. package/dist/config.js.map +1 -0
  52. package/dist/depth.d.ts +25 -0
  53. package/dist/depth.d.ts.map +1 -0
  54. package/dist/depth.js +160 -0
  55. package/dist/depth.js.map +1 -0
  56. package/dist/executor.d.ts +87 -0
  57. package/dist/executor.d.ts.map +1 -0
  58. package/dist/executor.js +295 -0
  59. package/dist/executor.js.map +1 -0
  60. package/dist/flow-prompt.d.ts +23 -0
  61. package/dist/flow-prompt.d.ts.map +1 -0
  62. package/dist/flow-prompt.js +99 -0
  63. package/dist/flow-prompt.js.map +1 -0
  64. package/dist/flow.d.ts +76 -0
  65. package/dist/flow.d.ts.map +1 -0
  66. package/dist/flow.js +704 -0
  67. package/dist/flow.js.map +1 -0
  68. package/dist/index.d.ts +10 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +327 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/reasoning-strip.d.ts +26 -0
  73. package/dist/reasoning-strip.d.ts.map +1 -0
  74. package/dist/reasoning-strip.js +58 -0
  75. package/dist/reasoning-strip.js.map +1 -0
  76. package/dist/render-utils.d.ts +42 -0
  77. package/dist/render-utils.d.ts.map +1 -0
  78. package/dist/render-utils.js +182 -0
  79. package/dist/render-utils.js.map +1 -0
  80. package/dist/render.d.ts +24 -0
  81. package/dist/render.d.ts.map +1 -0
  82. package/dist/render.js +409 -0
  83. package/dist/render.js.map +1 -0
  84. package/dist/runner-events.d.ts +59 -0
  85. package/dist/runner-events.d.ts.map +1 -0
  86. package/dist/runner-events.js +539 -0
  87. package/dist/runner-events.js.map +1 -0
  88. package/dist/session-mode.d.ts +10 -0
  89. package/dist/session-mode.d.ts.map +1 -0
  90. package/dist/session-mode.js +25 -0
  91. package/dist/session-mode.js.map +1 -0
  92. package/dist/settings-resolver.d.ts +28 -0
  93. package/dist/settings-resolver.d.ts.map +1 -0
  94. package/dist/settings-resolver.js +148 -0
  95. package/dist/settings-resolver.js.map +1 -0
  96. package/dist/sliding-prompt.d.ts +40 -0
  97. package/dist/sliding-prompt.d.ts.map +1 -0
  98. package/dist/sliding-prompt.js +121 -0
  99. package/dist/sliding-prompt.js.map +1 -0
  100. package/dist/snapshot.d.ts +29 -0
  101. package/dist/snapshot.d.ts.map +1 -0
  102. package/dist/snapshot.js +199 -0
  103. package/dist/snapshot.js.map +1 -0
  104. package/dist/structured-output.d.ts +36 -0
  105. package/dist/structured-output.d.ts.map +1 -0
  106. package/dist/structured-output.js +244 -0
  107. package/dist/structured-output.js.map +1 -0
  108. package/dist/timed-bash.d.ts +45 -0
  109. package/dist/timed-bash.d.ts.map +1 -0
  110. package/dist/timed-bash.js +219 -0
  111. package/dist/timed-bash.js.map +1 -0
  112. package/dist/tool-utils.d.ts +20 -0
  113. package/dist/tool-utils.d.ts.map +1 -0
  114. package/dist/tool-utils.js +38 -0
  115. package/dist/tool-utils.js.map +1 -0
  116. package/dist/transitions.d.ts +39 -0
  117. package/dist/transitions.d.ts.map +1 -0
  118. package/dist/transitions.js +59 -0
  119. package/dist/transitions.js.map +1 -0
  120. package/dist/types.d.ts +207 -0
  121. package/dist/types.d.ts.map +1 -0
  122. package/dist/types.js +143 -0
  123. package/dist/types.js.map +1 -0
  124. package/dist/web-tool.d.ts +35 -0
  125. package/dist/web-tool.d.ts.map +1 -0
  126. package/dist/web-tool.js +545 -0
  127. package/dist/web-tool.js.map +1 -0
  128. package/package.json +7 -5
  129. package/src/agents.ts +0 -299
  130. package/src/ambient.d.ts +0 -107
  131. package/src/batch/batch-bash.ts +0 -443
  132. package/src/batch/constants.ts +0 -128
  133. package/src/batch/execute.ts +0 -551
  134. package/src/batch/fuzzy-edit.ts +0 -323
  135. package/src/batch/index.ts +0 -494
  136. package/src/batch/render.ts +0 -81
  137. package/src/batch/symbols.ts +0 -341
  138. package/src/batch.ts +0 -28
  139. package/src/cli-args.ts +0 -315
  140. package/src/config.ts +0 -391
  141. package/src/executor.ts +0 -445
  142. package/src/flow.ts +0 -834
  143. package/src/hooks.ts +0 -294
  144. package/src/index.ts +0 -1132
  145. package/src/render-utils.ts +0 -205
  146. package/src/render.ts +0 -524
  147. package/src/runner-events.ts +0 -692
  148. package/src/session-mode.ts +0 -33
  149. package/src/sliding-prompt.ts +0 -144
  150. package/src/structured-output.ts +0 -195
  151. package/src/timed-bash.ts +0 -270
  152. package/src/transitions.ts +0 -86
  153. package/src/types.ts +0 -386
  154. package/src/web-tool.ts +0 -663
package/src/config.ts DELETED
@@ -1,391 +0,0 @@
1
- /**
2
- * Load flow model strategy configuration from Pi settings files.
3
- *
4
- * Reads global (~/.pi/agent/settings.json) and project (.pi/settings.json)
5
- * settings, with project overriding global for flowModelConfigs.
6
- */
7
-
8
- import * as fs from "node:fs";
9
- import * as os from "node:os";
10
- import * as path from "node:path";
11
- import { parseAgentSessionMode, type AgentSessionMode } from "./session-mode.js";
12
- import { type FlowTier } from "./agents.js";
13
-
14
-
15
- export interface FlowModelTierConfig {
16
- primary?: string;
17
- failover?: string[];
18
- }
19
-
20
- export type FlowModelStrategy = Partial<Record<FlowTier, FlowModelTierConfig>>;
21
- export type FlowModelConfigs = Record<string, FlowModelStrategy>;
22
-
23
- export interface LoadedFlowModelConfigs {
24
- selectedName: string;
25
- configs: FlowModelConfigs;
26
- strategy: FlowModelStrategy;
27
- }
28
-
29
- export interface FlowSettings {
30
- toolOptimize?: boolean;
31
- /** Whether to inject structured JSON output instructions into flow prompts. Default: true. */
32
- structuredOutput?: boolean;
33
- /** Maximum number of flows to execute concurrently. Default: 4. */
34
- maxConcurrency?: number;
35
- /** Whether to automatically queue follow-up flows based on hook transitions. Default: false. */
36
- autoTransition?: boolean;
37
- /** Default child-flow session mode. Default: "default" (600s). */
38
- sessionMode?: AgentSessionMode;
39
- }
40
-
41
- const BUILTIN_FLOW_MODEL_CONFIGS: FlowModelConfigs = {
42
- default: {},
43
- };
44
-
45
- const FLOW_TIERS: FlowTier[] = ["lite", "flash", "full"];
46
-
47
- function isPlainObject(value: unknown): value is Record<string, unknown> {
48
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
49
- }
50
-
51
- function readSettingsJson(filePath: string): Record<string, unknown> | null {
52
- try {
53
- const content = fs.readFileSync(filePath, "utf-8");
54
- return JSON.parse(content) as Record<string, unknown>;
55
- } catch {
56
- return null;
57
- }
58
- }
59
-
60
- export function getGlobalSettingsPath(): string {
61
- const agentDir = process.env["PI_CODING_AGENT_DIR"]?.trim() || path.join(os.homedir(), ".pi", "agent");
62
- return path.join(agentDir, "settings.json");
63
- }
64
-
65
- function getProjectSettingsPath(cwd: string): string {
66
- return path.join(cwd, ".pi", "settings.json");
67
- }
68
-
69
- export function normalizeFlowModeName(value: unknown): string | undefined {
70
- if (typeof value !== "string") return undefined;
71
- const normalized = value.trim();
72
- return normalized.length > 0 ? normalized : undefined;
73
- }
74
-
75
- function extractSelectedFlowModelConfigName(settings: Record<string, unknown> | null): string | undefined {
76
- if (!isPlainObject(settings)) return undefined;
77
- return normalizeFlowModeName(settings.flowModelConfig);
78
- }
79
-
80
- export function loadProjectFlowModelConfigName(cwd: string): string | undefined {
81
- return extractSelectedFlowModelConfigName(readSettingsJson(getProjectSettingsPath(cwd)));
82
- }
83
-
84
- export function writeGlobalFlowMode(mode: string): { path: string; previous?: string } {
85
- const normalized = normalizeFlowModeName(mode);
86
- if (!normalized) {
87
- throw new Error("Cannot update flow mode. Expected a non-empty mode name.");
88
- }
89
-
90
- const filePath = getGlobalSettingsPath();
91
- let settings: Record<string, unknown> = {};
92
-
93
- if (fs.existsSync(filePath)) {
94
- let parsed: unknown;
95
- try {
96
- parsed = JSON.parse(fs.readFileSync(filePath, "utf-8"));
97
- } catch (error) {
98
- throw new Error(`Cannot update flow mode because ${filePath} contains invalid JSON.`);
99
- }
100
- if (!isPlainObject(parsed)) {
101
- throw new Error(`Cannot update flow mode because ${filePath} must contain a JSON object.`);
102
- }
103
- settings = { ...parsed };
104
- }
105
-
106
- const previous = extractSelectedFlowModelConfigName(settings);
107
- settings.flowModelConfig = normalized;
108
-
109
- const dir = path.dirname(filePath);
110
- fs.mkdirSync(dir, { recursive: true });
111
- const tmpPath = path.join(dir, `.settings.json.${process.pid}.${Date.now()}.tmp`);
112
- fs.writeFileSync(tmpPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
113
- fs.renameSync(tmpPath, filePath);
114
-
115
- return {
116
- path: filePath,
117
- ...(previous !== undefined ? { previous } : {}),
118
- };
119
- }
120
-
121
- function normalizeFailoverList(
122
- value: unknown,
123
- sourceLabel: string,
124
- strategyName: string,
125
- tier: FlowTier,
126
- ): string[] | undefined {
127
- if (value === undefined) return undefined;
128
- if (!Array.isArray(value)) {
129
- console.warn(
130
- `[pi-agent-flow] Ignoring invalid ${sourceLabel}.flowModelConfigs.${strategyName}.${tier}.failover. Expected an array of strings.`,
131
- );
132
- return undefined;
133
- }
134
-
135
- const result: string[] = [];
136
- for (const item of value) {
137
- if (typeof item !== "string") {
138
- console.warn(
139
- `[pi-agent-flow] Ignoring invalid failover entry in ${sourceLabel}.flowModelConfigs.${strategyName}.${tier}. Expected a string.`,
140
- );
141
- continue;
142
- }
143
- const normalized = item.trim();
144
- if (!normalized) continue;
145
- result.push(normalized);
146
- }
147
- return result;
148
- }
149
-
150
- function extractFlowModelConfigs(settings: Record<string, unknown> | null, sourceLabel: string): FlowModelConfigs {
151
- if (!isPlainObject(settings)) return {};
152
- const rawConfigs = settings.flowModelConfigs;
153
- if (rawConfigs === undefined) return {};
154
- if (!isPlainObject(rawConfigs)) {
155
- console.warn(
156
- `[pi-agent-flow] Ignoring invalid ${sourceLabel}.flowModelConfigs. Expected an object map of strategy names.`,
157
- );
158
- return {};
159
- }
160
-
161
- const result: FlowModelConfigs = {};
162
- for (const [rawName, rawStrategy] of Object.entries(rawConfigs)) {
163
- const name = rawName.trim();
164
- if (!name) {
165
- console.warn(
166
- `[pi-agent-flow] Ignoring empty strategy name in ${sourceLabel}.flowModelConfigs.`,
167
- );
168
- continue;
169
- }
170
- if (!isPlainObject(rawStrategy)) {
171
- console.warn(
172
- `[pi-agent-flow] Ignoring invalid ${sourceLabel}.flowModelConfigs.${name}. Expected an object with lite/flash/full tiers.`,
173
- );
174
- continue;
175
- }
176
-
177
- const strategy: FlowModelStrategy = {};
178
- for (const tier of FLOW_TIERS) {
179
- const rawTier = rawStrategy[tier];
180
- if (rawTier === undefined) continue;
181
- if (!isPlainObject(rawTier)) {
182
- console.warn(
183
- `[pi-agent-flow] Ignoring invalid ${sourceLabel}.flowModelConfigs.${name}.${tier}. Expected { primary?: string, failover?: string[] }.`,
184
- );
185
- continue;
186
- }
187
-
188
- const tierConfig: FlowModelTierConfig = {};
189
- if (typeof rawTier.primary === "string") {
190
- const primary = rawTier.primary.trim();
191
- if (primary) tierConfig.primary = primary;
192
- } else if (rawTier.primary !== undefined) {
193
- console.warn(
194
- `[pi-agent-flow] Ignoring invalid ${sourceLabel}.flowModelConfigs.${name}.${tier}.primary. Expected a string.`,
195
- );
196
- }
197
-
198
- const failover = normalizeFailoverList(rawTier.failover, sourceLabel, name, tier);
199
- if (failover !== undefined) {
200
- tierConfig.failover = failover;
201
- }
202
-
203
- if (tierConfig.primary !== undefined || tierConfig.failover !== undefined) {
204
- strategy[tier] = tierConfig;
205
- }
206
- }
207
-
208
- result[name] = strategy;
209
- }
210
-
211
- return result;
212
- }
213
-
214
- function extractFlowSettings(settings: Record<string, unknown> | null): FlowSettings {
215
- if (!settings || typeof settings !== "object" || Array.isArray(settings)) {
216
- return {};
217
- }
218
- const flowSettings = settings.flowSettings;
219
- if (!flowSettings || typeof flowSettings !== "object" || Array.isArray(flowSettings)) {
220
- return {};
221
- }
222
- const obj = flowSettings as Record<string, unknown>;
223
- const result: FlowSettings = {};
224
- if (typeof obj.toolOptimize === "boolean") {
225
- result.toolOptimize = obj.toolOptimize;
226
- }
227
- if (typeof obj.structuredOutput === "boolean") {
228
- result.structuredOutput = obj.structuredOutput;
229
- }
230
- if (typeof obj.maxConcurrency === "number" && Number.isSafeInteger(obj.maxConcurrency) && obj.maxConcurrency >= 1) {
231
- result.maxConcurrency = obj.maxConcurrency;
232
- }
233
- if (typeof obj.autoTransition === "boolean") {
234
- result.autoTransition = obj.autoTransition;
235
- }
236
- const sessionMode = parseAgentSessionMode(obj.sessionMode);
237
- if (sessionMode !== undefined) {
238
- result.sessionMode = sessionMode;
239
- }
240
- return result;
241
- }
242
-
243
- function mergeFlowModelTierConfigs(
244
- base: FlowModelTierConfig | undefined,
245
- override: FlowModelTierConfig | undefined,
246
- ): FlowModelTierConfig | undefined {
247
- if (!base && !override) return undefined;
248
- return {
249
- ...(base?.primary !== undefined ? { primary: base.primary } : {}),
250
- ...(base?.failover !== undefined ? { failover: base.failover } : {}),
251
- ...(override?.primary !== undefined ? { primary: override.primary } : {}),
252
- ...(override?.failover !== undefined ? { failover: override.failover } : {}),
253
- };
254
- }
255
-
256
- function mergeFlowModelStrategies(
257
- base: FlowModelStrategy | undefined,
258
- override: FlowModelStrategy | undefined,
259
- ): FlowModelStrategy {
260
- const result: FlowModelStrategy = {};
261
- for (const tier of FLOW_TIERS) {
262
- const merged = mergeFlowModelTierConfigs(base?.[tier], override?.[tier]);
263
- if (merged) result[tier] = merged;
264
- }
265
- return result;
266
- }
267
-
268
- function mergeFlowModelConfigs(...configs: FlowModelConfigs[]): FlowModelConfigs {
269
- const result: FlowModelConfigs = {};
270
- for (const configSet of configs) {
271
- for (const [name, strategy] of Object.entries(configSet)) {
272
- result[name] = mergeFlowModelStrategies(result[name], strategy);
273
- }
274
- }
275
- return result;
276
- }
277
-
278
- /**
279
- * Load flowSettings from global and project settings.json.
280
- * Project overrides global (shallow merge per key).
281
- */
282
- export function loadFlowSettings(cwd: string): FlowSettings {
283
- const globalSettings = readSettingsJson(getGlobalSettingsPath());
284
- const globalFlowSettings = extractFlowSettings(globalSettings);
285
-
286
- const projectSettings = readSettingsJson(getProjectSettingsPath(cwd));
287
- const projectFlowSettings = extractFlowSettings(projectSettings);
288
-
289
- return {
290
- ...globalFlowSettings,
291
- ...projectFlowSettings,
292
- };
293
- }
294
-
295
- export function selectFlowModelStrategy(
296
- configs: FlowModelConfigs,
297
- requestedName?: string,
298
- ): LoadedFlowModelConfigs {
299
- const normalizedRequested = normalizeFlowModeName(requestedName) ?? "default";
300
- const strategy = configs[normalizedRequested];
301
- if (strategy) {
302
- return { selectedName: normalizedRequested, configs, strategy };
303
- }
304
-
305
- if (normalizedRequested !== "default") {
306
- console.warn(
307
- `[pi-agent-flow] Flow model config "${normalizedRequested}" not found. Falling back to "default".`,
308
- );
309
- }
310
- return {
311
- selectedName: "default",
312
- configs,
313
- strategy: configs.default ?? {},
314
- };
315
- }
316
-
317
- /**
318
- * Load flow model configs from global and project settings.json.
319
- * Project overrides global (shallow merge per strategy/tier).
320
- */
321
- export function loadFlowModelConfigs(cwd: string): LoadedFlowModelConfigs {
322
- const globalSettings = readSettingsJson(getGlobalSettingsPath());
323
- const globalConfigs = extractFlowModelConfigs(globalSettings, "global");
324
-
325
- const projectSettings = readSettingsJson(getProjectSettingsPath(cwd));
326
- const projectConfigs = extractFlowModelConfigs(projectSettings, "project");
327
-
328
- const configs = mergeFlowModelConfigs(BUILTIN_FLOW_MODEL_CONFIGS, globalConfigs, projectConfigs);
329
- const requestedName =
330
- extractSelectedFlowModelConfigName(projectSettings) ??
331
- extractSelectedFlowModelConfigName(globalSettings) ??
332
- "default";
333
-
334
- return selectFlowModelStrategy(configs, requestedName);
335
- }
336
-
337
- export function resolveFlowModelCandidates(opts: {
338
- tier: FlowTier;
339
- flowModel?: string;
340
- cliTierOverride?: string;
341
- strategy: FlowModelStrategy;
342
- fallbackModel?: string;
343
- }): { primary: string | undefined; candidates: string[] } {
344
- const unique = new Set<string>();
345
- const candidates: string[] = [];
346
-
347
- const add = (value: string | undefined) => {
348
- if (!value) return;
349
- const normalized = value.trim();
350
- if (!normalized || unique.has(normalized)) return;
351
- unique.add(normalized);
352
- candidates.push(normalized);
353
- };
354
-
355
- if (opts.flowModel) {
356
- add(opts.flowModel);
357
- return { primary: candidates[0], candidates };
358
- }
359
-
360
- if (opts.cliTierOverride) {
361
- add(opts.cliTierOverride);
362
- return { primary: candidates[0], candidates };
363
- }
364
-
365
- const tierConfig = opts.strategy[opts.tier];
366
- add(tierConfig?.primary);
367
- for (const model of tierConfig?.failover ?? []) add(model);
368
- add(opts.fallbackModel);
369
-
370
- return { primary: candidates[0], candidates };
371
- }
372
-
373
- export function formatFlowModelStrategy(modeName: string, strategy: FlowModelStrategy): string {
374
- const tiers: FlowTier[] = ["lite", "flash", "full"];
375
- const parts: string[] = [];
376
- for (const tier of tiers) {
377
- const config = strategy[tier];
378
- const hasPrimary = Boolean(config?.primary);
379
- const hasFailover = config?.failover && config.failover.length > 0;
380
- let value: string;
381
- if (hasPrimary) {
382
- value = config!.primary!;
383
- } else if (hasFailover) {
384
- value = `failover: ${config!.failover!.join(", ")}`;
385
- } else {
386
- value = "(default)";
387
- }
388
- parts.push(`${tier}: ${value}`);
389
- }
390
- return `mode: ${modeName} | ${parts.join(" · ")}`;
391
- }