@oh-my-pi/pi-coding-agent 17.0.1 → 17.0.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 (179) hide show
  1. package/CHANGELOG.md +162 -40
  2. package/dist/cli.js +4559 -4543
  3. package/dist/types/advisor/config.d.ts +14 -6
  4. package/dist/types/advisor/runtime.d.ts +20 -11
  5. package/dist/types/autolearn/controller.d.ts +1 -0
  6. package/dist/types/config/model-discovery.d.ts +17 -0
  7. package/dist/types/config/model-resolver.d.ts +6 -2
  8. package/dist/types/config/settings-schema.d.ts +39 -10
  9. package/dist/types/config/settings.d.ts +50 -0
  10. package/dist/types/cursor.d.ts +11 -0
  11. package/dist/types/discovery/helpers.d.ts +5 -2
  12. package/dist/types/eval/agent-bridge.d.ts +7 -19
  13. package/dist/types/exec/bash-executor.d.ts +2 -0
  14. package/dist/types/extensibility/extensions/managed-timers.d.ts +15 -0
  15. package/dist/types/extensibility/extensions/runner.d.ts +7 -0
  16. package/dist/types/extensibility/extensions/types.d.ts +18 -0
  17. package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +55 -1
  18. package/dist/types/extensibility/shared-events.d.ts +6 -0
  19. package/dist/types/extensibility/utils.d.ts +2 -2
  20. package/dist/types/lsp/client.d.ts +2 -0
  21. package/dist/types/lsp/types.d.ts +3 -0
  22. package/dist/types/mcp/transports/stdio.d.ts +42 -1
  23. package/dist/types/modes/components/advisor-config.d.ts +8 -1
  24. package/dist/types/modes/components/agent-hub.d.ts +15 -0
  25. package/dist/types/modes/components/hook-editor.d.ts +7 -0
  26. package/dist/types/modes/components/model-hub.d.ts +5 -2
  27. package/dist/types/modes/components/session-selector.d.ts +2 -0
  28. package/dist/types/modes/controllers/command-controller.d.ts +8 -0
  29. package/dist/types/modes/controllers/selector-controller.d.ts +3 -1
  30. package/dist/types/modes/print-mode.d.ts +1 -1
  31. package/dist/types/modes/warp-events.d.ts +24 -0
  32. package/dist/types/modes/warp-events.test.d.ts +1 -0
  33. package/dist/types/plan-mode/model-transition.d.ts +47 -0
  34. package/dist/types/plan-mode/model-transition.test.d.ts +1 -0
  35. package/dist/types/registry/agent-lifecycle.d.ts +26 -1
  36. package/dist/types/registry/persisted-agents.d.ts +3 -0
  37. package/dist/types/sdk.d.ts +27 -5
  38. package/dist/types/session/agent-session.d.ts +34 -10
  39. package/dist/types/session/session-entries.d.ts +6 -1
  40. package/dist/types/session/session-history-format.d.ts +10 -0
  41. package/dist/types/session/session-manager.d.ts +19 -0
  42. package/dist/types/slash-commands/helpers/active-oauth-account.d.ts +9 -0
  43. package/dist/types/task/executor.d.ts +26 -1
  44. package/dist/types/task/index.d.ts +1 -1
  45. package/dist/types/task/label.d.ts +1 -1
  46. package/dist/types/task/parallel.d.ts +14 -0
  47. package/dist/types/task/structured-subagent.d.ts +111 -0
  48. package/dist/types/task/types.d.ts +51 -0
  49. package/dist/types/telemetry-export.d.ts +34 -9
  50. package/dist/types/tools/approval.d.ts +8 -0
  51. package/dist/types/tools/bash.d.ts +2 -0
  52. package/dist/types/tools/essential-tools.d.ts +29 -0
  53. package/dist/types/tools/fetch.d.ts +4 -5
  54. package/dist/types/tools/hub/messaging.d.ts +5 -1
  55. package/dist/types/tools/image-gen.d.ts +2 -1
  56. package/dist/types/tools/index.d.ts +17 -1
  57. package/dist/types/tools/todo.d.ts +31 -0
  58. package/dist/types/tools/xdev.d.ts +11 -2
  59. package/dist/types/tui/tree-list.d.ts +7 -0
  60. package/dist/types/utils/markit.d.ts +11 -0
  61. package/dist/types/utils/title-generator.d.ts +2 -1
  62. package/dist/types/web/search/providers/kimi.d.ts +4 -1
  63. package/dist/types/web/search/types.d.ts +1 -1
  64. package/package.json +21 -16
  65. package/src/advisor/__tests__/advisor.test.ts +1304 -42
  66. package/src/advisor/__tests__/config.test.ts +58 -2
  67. package/src/advisor/config.ts +76 -24
  68. package/src/advisor/runtime.ts +445 -92
  69. package/src/autolearn/controller.ts +23 -28
  70. package/src/cli/file-processor.ts +1 -2
  71. package/src/cli.ts +5 -1
  72. package/src/config/model-discovery.ts +81 -21
  73. package/src/config/model-registry.ts +25 -6
  74. package/src/config/model-resolver.ts +14 -7
  75. package/src/config/settings-schema.ts +46 -9
  76. package/src/config/settings.ts +405 -25
  77. package/src/cursor.ts +20 -3
  78. package/src/debug/report-bundle.ts +40 -4
  79. package/src/discovery/helpers.ts +28 -5
  80. package/src/eval/__tests__/agent-bridge.test.ts +133 -47
  81. package/src/eval/__tests__/prelude-agent.test.ts +29 -0
  82. package/src/eval/agent-bridge.ts +104 -477
  83. package/src/eval/jl/prelude.jl +7 -6
  84. package/src/eval/js/shared/prelude.txt +5 -4
  85. package/src/eval/py/prelude.py +11 -39
  86. package/src/eval/rb/prelude.rb +5 -6
  87. package/src/exec/bash-executor.ts +14 -5
  88. package/src/extensibility/custom-tools/loader.ts +3 -3
  89. package/src/extensibility/custom-tools/wrapper.ts +2 -1
  90. package/src/extensibility/extensions/loader.ts +3 -3
  91. package/src/extensibility/extensions/managed-timers.ts +83 -0
  92. package/src/extensibility/extensions/runner.ts +26 -0
  93. package/src/extensibility/extensions/types.ts +18 -0
  94. package/src/extensibility/extensions/wrapper.ts +2 -1
  95. package/src/extensibility/hooks/loader.ts +3 -3
  96. package/src/extensibility/legacy-pi-coding-agent-shim.ts +149 -8
  97. package/src/extensibility/plugins/legacy-pi-compat.ts +225 -22
  98. package/src/extensibility/plugins/manager.ts +2 -2
  99. package/src/extensibility/shared-events.ts +6 -0
  100. package/src/extensibility/utils.ts +91 -25
  101. package/src/irc/bus.ts +22 -3
  102. package/src/launch/broker.ts +3 -2
  103. package/src/launch/client.ts +2 -2
  104. package/src/launch/presence.ts +2 -2
  105. package/src/lsp/client.ts +58 -1
  106. package/src/lsp/index.ts +62 -6
  107. package/src/lsp/types.ts +3 -0
  108. package/src/main.ts +11 -8
  109. package/src/mcp/manager.ts +9 -3
  110. package/src/mcp/oauth-flow.ts +20 -0
  111. package/src/mcp/transports/stdio.test.ts +269 -1
  112. package/src/mcp/transports/stdio.ts +255 -24
  113. package/src/modes/components/advisor-config.ts +65 -3
  114. package/src/modes/components/agent-hub.ts +1 -72
  115. package/src/modes/components/ask-dialog.ts +1 -1
  116. package/src/modes/components/bash-execution.ts +7 -3
  117. package/src/modes/components/eval-execution.ts +3 -1
  118. package/src/modes/components/hook-editor.ts +18 -3
  119. package/src/modes/components/model-hub.ts +138 -42
  120. package/src/modes/components/session-selector.ts +4 -0
  121. package/src/modes/components/status-line/component.test.ts +1 -0
  122. package/src/modes/components/status-line/segments.ts +21 -6
  123. package/src/modes/controllers/command-controller.ts +167 -47
  124. package/src/modes/controllers/event-controller.ts +5 -0
  125. package/src/modes/controllers/extension-ui-controller.ts +4 -22
  126. package/src/modes/controllers/input-controller.ts +12 -12
  127. package/src/modes/controllers/selector-controller.ts +191 -31
  128. package/src/modes/interactive-mode.ts +169 -62
  129. package/src/modes/print-mode.ts +3 -3
  130. package/src/modes/rpc/host-tools.ts +2 -1
  131. package/src/modes/rpc/rpc-mode.ts +19 -4
  132. package/src/modes/warp-events.test.ts +794 -0
  133. package/src/modes/warp-events.ts +232 -0
  134. package/src/plan-mode/model-transition.test.ts +60 -0
  135. package/src/plan-mode/model-transition.ts +51 -0
  136. package/src/prompts/system/system-prompt.md +1 -1
  137. package/src/prompts/tools/eval.md +5 -2
  138. package/src/prompts/tools/read.md +1 -1
  139. package/src/prompts/tools/task.md +12 -8
  140. package/src/prompts/tools/write.md +1 -1
  141. package/src/registry/agent-lifecycle.ts +133 -18
  142. package/src/registry/persisted-agents.ts +74 -0
  143. package/src/sdk.ts +343 -122
  144. package/src/session/agent-session.ts +1359 -368
  145. package/src/session/session-entries.ts +6 -1
  146. package/src/session/session-history-format.ts +20 -5
  147. package/src/session/session-manager.ts +57 -0
  148. package/src/session/streaming-output.ts +41 -1
  149. package/src/slash-commands/builtin-registry.ts +7 -0
  150. package/src/slash-commands/helpers/active-oauth-account.ts +16 -0
  151. package/src/system-prompt.ts +7 -2
  152. package/src/task/executor.ts +100 -22
  153. package/src/task/index.ts +258 -429
  154. package/src/task/label.ts +2 -0
  155. package/src/task/parallel.ts +43 -0
  156. package/src/task/persisted-revive.ts +19 -7
  157. package/src/task/structured-subagent.ts +642 -0
  158. package/src/task/types.ts +58 -0
  159. package/src/telemetry-export.ts +453 -97
  160. package/src/tools/__tests__/eval-description.test.ts +1 -1
  161. package/src/tools/approval.ts +11 -0
  162. package/src/tools/bash.ts +71 -38
  163. package/src/tools/essential-tools.ts +45 -0
  164. package/src/tools/fetch.ts +28 -105
  165. package/src/tools/gh.ts +169 -2
  166. package/src/tools/hub/messaging.ts +16 -3
  167. package/src/tools/image-gen.ts +69 -7
  168. package/src/tools/index.ts +50 -15
  169. package/src/tools/path-utils.ts +1 -0
  170. package/src/tools/read.ts +62 -29
  171. package/src/tools/todo.ts +126 -13
  172. package/src/tools/write.ts +22 -4
  173. package/src/tools/xdev.ts +14 -3
  174. package/src/tui/tree-list.ts +39 -0
  175. package/src/utils/markit.ts +12 -0
  176. package/src/utils/title-generator.ts +15 -4
  177. package/src/utils/zip.ts +16 -1
  178. package/src/web/search/providers/kimi.ts +18 -12
  179. package/src/web/search/types.ts +6 -1
@@ -24,7 +24,7 @@ import type { ConfiguredThinkingLevel } from "../thinking.js";
24
24
  import type { ContextFileEntry } from "../tools/index.js";
25
25
  import type { EventBus } from "../utils/event-bus.js";
26
26
  import type { WorkspaceTree } from "../workspace-tree.js";
27
- import { type AgentDefinition, type AgentProgress, type SingleResult, type YieldItem } from "./types.js";
27
+ import { type AgentDefinition, type AgentProgress, type SingleResult, type StructuredSubagentOutput, type StructuredSubagentSchemaMode, type StructuredSubagentSchemaSource, type YieldItem } from "./types.js";
28
28
  export type { YieldItem } from "./types.js";
29
29
  /**
30
30
  * Soft per-agent request budgets (assistant requests per run). Crossing the
@@ -78,7 +78,12 @@ export interface ExecutorOptions {
78
78
  */
79
79
  parentActiveModelPattern?: string;
80
80
  thinkingLevel?: ConfiguredThinkingLevel;
81
+ /** Schema used to validate the final structured completion. */
81
82
  outputSchema?: unknown;
83
+ /** Enforcement policy for {@link outputSchema}; defaults to legacy permissive behavior. */
84
+ outputSchemaMode?: StructuredSubagentSchemaMode;
85
+ /** Origin of the selected schema, preserved in {@link SingleResult.structuredOutput}. */
86
+ outputSchemaSource?: StructuredSubagentSchemaSource;
82
87
  /**
83
88
  * Caller supplied a schema that supersedes the agent's native output prompt.
84
89
  * Eval `agent(..., schema=...)` sets this so built-in agents ignore stale yield labels.
@@ -93,7 +98,20 @@ export interface ExecutorOptions {
93
98
  * watchdog is already suspended for the call's duration.
94
99
  */
95
100
  maxRuntimeMs?: number;
101
+ /** Include IRC only when the invocation policy permits collaboration. */
102
+ enableIrc?: boolean;
96
103
  enableLsp?: boolean;
104
+ /**
105
+ * Enable MCP capabilities for this child. `false` suppresses both inherited
106
+ * MCP proxy tools and session MCP discovery; it never consults the
107
+ * process-global MCP manager. Defaults to `true`.
108
+ */
109
+ enableMCP?: boolean;
110
+ /**
111
+ * Limit the child to its explicit host tool names and the required yield
112
+ * tool, suppressing discovered and always-included capabilities.
113
+ */
114
+ restrictToolNames?: boolean;
97
115
  signal?: AbortSignal;
98
116
  onProgress?: (progress: AgentProgress) => void;
99
117
  /**
@@ -183,6 +201,8 @@ interface FinalizeSubprocessOutputArgs {
183
201
  signalAborted: boolean;
184
202
  yieldItems?: YieldItem[];
185
203
  outputSchema: unknown;
204
+ outputSchemaMode?: StructuredSubagentSchemaMode;
205
+ outputSchemaSource?: StructuredSubagentSchemaSource;
186
206
  lastAssistantText?: string;
187
207
  }
188
208
  interface FinalizeSubprocessOutputResult {
@@ -191,6 +211,7 @@ interface FinalizeSubprocessOutputResult {
191
211
  stderr: string;
192
212
  abortedViaYield: boolean;
193
213
  hasYield: boolean;
214
+ structuredOutput?: StructuredSubagentOutput;
194
215
  }
195
216
  export declare const SUBAGENT_WARNING_SCHEMA_OVERRIDDEN = "SYSTEM WARNING: Subagent exhausted schema-retry budget; result was accepted despite failing the output schema.";
196
217
  export declare const SUBAGENT_WARNING_NULL_YIELD = "SYSTEM WARNING: Subagent called yield with null data.";
@@ -230,6 +251,10 @@ export interface FollowUpTurnOptions {
230
251
  message: string;
231
252
  index?: number;
232
253
  description?: string;
254
+ /** Structured-output state retained from the original invocation. */
255
+ outputSchema?: unknown;
256
+ outputSchemaMode?: StructuredSubagentSchemaMode;
257
+ outputSchemaSource?: StructuredSubagentSchemaSource;
233
258
  signal?: AbortSignal;
234
259
  onProgress?: (progress: AgentProgress) => void;
235
260
  eventBus?: EventBus;
@@ -64,7 +64,7 @@ export declare class TaskTool implements AgentTool<TaskToolSchemaInstance, TaskT
64
64
  readonly formatApprovalDetails: (args: unknown) => string[];
65
65
  readonly label = "Task";
66
66
  readonly summary = "Spawn subagents to complete delegated tasks";
67
- readonly strict = true;
67
+ readonly strict = false;
68
68
  readonly loadMode = "essential";
69
69
  readonly renderResult: typeof renderResult;
70
70
  readonly mergeCallAndResult = true;
@@ -1,4 +1,4 @@
1
1
  import type { ModelRegistry } from "../config/model-registry.js";
2
2
  import type { Settings } from "../config/settings.js";
3
3
  /** Compresses a delegated assignment into a one-sentence UI label via the tiny title model — fired by the executor spawn path because the task wire schema no longer carries a `description`; null on empty input or failure. */
4
- export declare function generateTaskLabel(assignment: string, registry: ModelRegistry, settings: Settings, sessionId?: string): Promise<string | null>;
4
+ export declare function generateTaskLabel(assignment: string, registry: ModelRegistry, settings: Settings, sessionId?: string, signal?: AbortSignal): Promise<string | null>;
@@ -23,6 +23,20 @@ export interface ParallelResult<R> {
23
23
  * @param signal - Optional abort signal to stop scheduling new work
24
24
  */
25
25
  export declare function mapWithConcurrencyLimit<T, R>(items: T[], concurrency: number, fn: (item: T, index: number, signal: AbortSignal) => Promise<R>, signal?: AbortSignal): Promise<ParallelResult<R>>;
26
+ /** Result of a concurrency-limited operation that waits for every launched item. */
27
+ export interface ParallelSettledResult<R> {
28
+ /** Settled results in original input order; absent entries were never launched after cancellation. */
29
+ results: (PromiseSettledResult<R> | undefined)[];
30
+ /** Whether cancellation prevented scheduling all items. */
31
+ aborted: boolean;
32
+ }
33
+ /**
34
+ * Execute items with a concurrency limit without failing fast. Rejections are
35
+ * captured at their input position and already launched siblings always settle
36
+ * before this function returns. Cancellation stops new launches but preserves
37
+ * the settled state of every item that began.
38
+ */
39
+ export declare function mapWithConcurrencyLimitAllSettled<T, R>(items: T[], concurrency: number, fn: (item: T, index: number, signal: AbortSignal) => Promise<R>, signal?: AbortSignal): Promise<ParallelSettledResult<R>>;
26
40
  /**
27
41
  * Simple counting semaphore for limiting concurrency across independently-scheduled async work.
28
42
  *
@@ -0,0 +1,111 @@
1
+ import type { ToolSession } from "../tools/index.js";
2
+ import { type DiscoveryResult } from "./discovery.js";
3
+ import { type AgentDefinition, type AgentProgress, type SingleResult, type StructuredSubagentOutput } from "./types.js";
4
+ /** Validation behavior requested for an effective output schema. */
5
+ export type StructuredSubagentSchemaMode = "permissive" | "strict";
6
+ /** Where an effective output schema came from. */
7
+ export type StructuredSubagentSchemaSource = "caller" | "agent" | "session" | "none";
8
+ /** Final structured completion metadata returned for a schema-bearing run. */
9
+ export type StructuredSubagentSchemaResult = StructuredSubagentOutput;
10
+ /** A schema validation or extraction error attached to structured completion metadata. */
11
+ export type StructuredSubagentSchemaError = NonNullable<StructuredSubagentOutput["error"]>;
12
+ /** A selected schema paired with its source and enforcement mode. */
13
+ export interface StructuredSubagentSchemaResolution {
14
+ schema: unknown;
15
+ source: StructuredSubagentSchemaSource;
16
+ mode: StructuredSubagentSchemaMode;
17
+ outputSchemaOverridesAgent: boolean;
18
+ }
19
+ /** Isolation controls shared by the task and eval surfaces. */
20
+ export interface StructuredSubagentIsolationControls {
21
+ requested?: boolean;
22
+ merge?: "patch" | "branch";
23
+ apply?: boolean;
24
+ }
25
+ /** Identity and presentation metadata supplied by the calling surface. */
26
+ export interface StructuredSubagentIdentity {
27
+ /** A previously reserved output/registry id. */
28
+ id?: string;
29
+ /** Stable user-facing label used when allocating a new id. */
30
+ label?: string;
31
+ }
32
+ /** One normalized child invocation. */
33
+ export interface StructuredSubagentRequest {
34
+ session: ToolSession;
35
+ invocationKind: "task" | "eval";
36
+ assignment: string;
37
+ context?: string;
38
+ agent?: string;
39
+ model?: string | string[];
40
+ /** Presence, rather than truthiness, makes this the highest-priority schema. */
41
+ outputSchema?: unknown;
42
+ schemaMode?: StructuredSubagentSchemaMode;
43
+ identity?: StructuredSubagentIdentity;
44
+ index?: number;
45
+ parentToolCallId?: string;
46
+ detached?: boolean;
47
+ invokedAt?: number;
48
+ acquiredAt?: number;
49
+ isolation?: StructuredSubagentIsolationControls;
50
+ /** The parent agent name forbidden from recursively spawning itself. */
51
+ blockedAgent?: string;
52
+ /** Preserve a completed temporary artifacts directory for an agent:// handle. */
53
+ retainArtifacts?: boolean;
54
+ /** Task UI agents keep live registry references; eval one-shots normally do not. */
55
+ keepAlive?: boolean;
56
+ /** Task subagents share their parent's eval kernel; eval bridge children must not. */
57
+ shareEvalSession?: boolean;
58
+ /** Task frontends may inherit LSP; eval frontends normally set this false. */
59
+ enableLsp?: boolean;
60
+ /** Explicitly pass false for plan mode or invocation kinds that must not use IRC. */
61
+ enableIrc?: boolean;
62
+ /** `0` disables executor wall-clock timeout. Undefined inherits settings. */
63
+ maxRuntimeMs?: number;
64
+ signal?: AbortSignal;
65
+ onProgress?: (progress: AgentProgress) => void;
66
+ }
67
+ /** A normalized preflight result, reusable by tests and adapters. */
68
+ export interface EffectiveSubagentPolicy {
69
+ discovery: DiscoveryResult;
70
+ agentName: string;
71
+ agent: AgentDefinition;
72
+ effectiveAgent: AgentDefinition;
73
+ modelOverride?: string | string[];
74
+ parentActiveModelPattern?: string;
75
+ schema: StructuredSubagentSchemaResolution;
76
+ planMode: boolean;
77
+ isIsolated: boolean;
78
+ mergeMode: "patch" | "branch";
79
+ applyChanges: boolean;
80
+ enableLsp: boolean;
81
+ enableIrc: boolean;
82
+ }
83
+ /** Settled child execution plus data needed by the frontends' own rendering. */
84
+ export interface StructuredSubagentResult {
85
+ result: SingleResult;
86
+ policy: EffectiveSubagentPolicy;
87
+ mergeSummary: string;
88
+ changesApplied: boolean | null;
89
+ artifactsDir: string;
90
+ temporaryArtifacts: boolean;
91
+ }
92
+ /** Machine-readable failure category so adapters can retain their native errors. */
93
+ export declare class StructuredSubagentError extends Error {
94
+ readonly kind: "preflight" | "isolation" | "execution";
95
+ constructor(kind: "preflight" | "isolation" | "execution", message: string, options?: ErrorOptions);
96
+ }
97
+ /**
98
+ * Resolve every policy shared by task and eval before allocating artifacts or
99
+ * dispatching work. Callers translate {@link StructuredSubagentError} into
100
+ * their own wire-level error surface.
101
+ */
102
+ export declare function resolveEffectiveSubagentPolicy(request: StructuredSubagentRequest): Promise<EffectiveSubagentPolicy>;
103
+ /** Reserve a session-global agent id only after preflight has succeeded. */
104
+ export declare function reserveStructuredSubagentId(session: ToolSession, identity: StructuredSubagentIdentity | undefined): Promise<string>;
105
+ /**
106
+ * Execute a validated subagent. Preflight errors occur before any artifact
107
+ * lease or child dispatch; callers keep responsibility for their result text.
108
+ */
109
+ export declare function runStructuredSubagent(request: StructuredSubagentRequest): Promise<StructuredSubagentResult>;
110
+ /** Build the recovery suffix used by adapters after an isolated failure. */
111
+ export declare function buildStructuredSubagentRecoveryHint(result: SingleResult, artifactsDir: string): Promise<string>;
@@ -5,6 +5,32 @@ import type { ConfiguredThinkingLevel } from "../thinking.js";
5
5
  import type { NestedRepoPatch } from "./worktree.js";
6
6
  /** Source of an agent definition */
7
7
  export type AgentSource = "bundled" | "user" | "project";
8
+ /**
9
+ * Enforcement policy for a structured subagent output schema.
10
+ *
11
+ * `permissive` preserves legacy retry-budget overrides; `strict` turns every
12
+ * invalid final payload, including an exhausted retry override, into a failed
13
+ * `schema_violation` result.
14
+ */
15
+ export type StructuredSubagentSchemaMode = "permissive" | "strict";
16
+ /** Origin of the schema selected for a structured subagent invocation. */
17
+ export type StructuredSubagentSchemaSource = "caller" | "agent" | "session" | "none";
18
+ /** Final validation state of a structured subagent invocation. */
19
+ export type StructuredSubagentValidationStatus = "valid" | "invalid" | "unavailable";
20
+ /**
21
+ * Parsed structured completion and its schema-validation metadata.
22
+ *
23
+ * `data` is present whenever a payload could be assembled or parsed, even when
24
+ * strict validation rejects it. `error` explains unavailable or invalid
25
+ * validation without requiring consumers to parse presentation text.
26
+ */
27
+ export interface StructuredSubagentOutput {
28
+ source: StructuredSubagentSchemaSource;
29
+ mode: StructuredSubagentSchemaMode;
30
+ status: StructuredSubagentValidationStatus;
31
+ data?: unknown;
32
+ error?: string;
33
+ }
8
34
  /** Maximum output bytes per agent */
9
35
  export declare const MAX_OUTPUT_BYTES: number;
10
36
  /** Maximum output lines per agent */
@@ -57,6 +83,8 @@ export declare const taskItemSchema: import("arktype/internal/variants/object.ts
57
83
  name?: string | undefined;
58
84
  agent: import("arktype/internal/attributes.ts").Default<string, "task">;
59
85
  task: string;
86
+ outputSchema?: unknown;
87
+ schemaMode?: "permissive" | "strict" | undefined;
60
88
  }, {}>;
61
89
  /** Single task item. Fields are optional defensively: args stream in token by token. */
62
90
  export interface TaskItem {
@@ -66,6 +94,10 @@ export interface TaskItem {
66
94
  agent?: string;
67
95
  /** The work; required by the schema. */
68
96
  task?: string;
97
+ /** Caller-provided output schema; its presence overrides the selected agent's schema. */
98
+ outputSchema?: unknown;
99
+ /** Validation behavior for a caller-provided or inherited output schema. */
100
+ schemaMode?: "permissive" | "strict";
69
101
  /** Run this spawn in an isolated worktree (batch form; flat form carries it top-level). */
70
102
  isolated?: boolean;
71
103
  }
@@ -73,23 +105,31 @@ export declare const taskSchema: import("arktype/internal/variants/object.ts").O
73
105
  name?: string | undefined;
74
106
  agent: import("arktype/internal/attributes.ts").Default<string, "task">;
75
107
  task: string;
108
+ outputSchema?: unknown;
109
+ schemaMode?: "permissive" | "strict" | undefined;
76
110
  isolated?: boolean | undefined;
77
111
  }, {}>;
78
112
  declare const ALL_TASK_SCHEMAS: readonly [import("arktype/internal/variants/object.ts").ObjectType<{
79
113
  name?: string | undefined;
80
114
  agent: import("arktype/internal/attributes.ts").Default<string, "task">;
81
115
  task: string;
116
+ outputSchema?: unknown;
117
+ schemaMode?: "permissive" | "strict" | undefined;
82
118
  isolated?: boolean | undefined;
83
119
  }, {}>, import("arktype/internal/variants/object.ts").ObjectType<{
84
120
  name?: string | undefined;
85
121
  agent: import("arktype/internal/attributes.ts").Default<string, "task">;
86
122
  task: string;
123
+ outputSchema?: unknown;
124
+ schemaMode?: "permissive" | "strict" | undefined;
87
125
  }, {}>, import("arktype/internal/variants/object.ts").ObjectType<{
88
126
  context: string;
89
127
  tasks: {
90
128
  name?: string | undefined;
91
129
  agent: import("arktype/internal/attributes.ts").Default<string, "task">;
92
130
  task: string;
131
+ outputSchema?: unknown;
132
+ schemaMode?: "permissive" | "strict" | undefined;
93
133
  isolated?: boolean | undefined;
94
134
  }[];
95
135
  }, {}>, import("arktype/internal/variants/object.ts").ObjectType<{
@@ -98,6 +138,8 @@ declare const ALL_TASK_SCHEMAS: readonly [import("arktype/internal/variants/obje
98
138
  name?: string | undefined;
99
139
  agent: import("arktype/internal/attributes.ts").Default<string, "task">;
100
140
  task: string;
141
+ outputSchema?: unknown;
142
+ schemaMode?: "permissive" | "strict" | undefined;
101
143
  }[];
102
144
  }, {}>];
103
145
  type DynamicTaskSchema = (typeof ALL_TASK_SCHEMAS)[number];
@@ -126,6 +168,10 @@ export interface TaskParams {
126
168
  agent?: string;
127
169
  /** The work (flat form). */
128
170
  task?: string;
171
+ /** Caller-provided output schema; its presence overrides the selected agent's schema. */
172
+ outputSchema?: unknown;
173
+ /** Validation behavior for a caller-provided or inherited output schema. */
174
+ schemaMode?: "permissive" | "strict";
129
175
  /** Batch form (`task.batch`): one subagent per item. */
130
176
  tasks?: TaskItem[];
131
177
  /** Batch form: shared background prepended to every assignment; required by the batch schema. */
@@ -294,6 +340,11 @@ export interface SingleResult {
294
340
  output: string;
295
341
  stderr: string;
296
342
  truncated: boolean;
343
+ /**
344
+ * Parsed structured completion and validation metadata, when this invocation
345
+ * selected an output schema or strict schema mode.
346
+ */
347
+ structuredOutput?: StructuredSubagentOutput;
297
348
  durationMs: number;
298
349
  /** Cumulative input + output + cacheWrite tokens across all turns. Excludes cacheRead (re-reads cached context every turn, making cumulative sum misleading). */
299
350
  tokens: number;
@@ -1,19 +1,44 @@
1
1
  /**
2
- * Whether {@link initTelemetryExport} registered a real provider. The CLI uses
3
- * this to decide whether to switch on the agent loop's telemetry config — there
4
- * is no point emitting spans into a no-op tracer.
2
+ * OTLP telemetry export bootstrap.
3
+ *
4
+ * oh-my-pi's agent core (`@oh-my-pi/pi-agent-core`) emits OpenTelemetry GenAI
5
+ * spans through the global `@opentelemetry/api` tracer, and exposes run-level
6
+ * callbacks for metrics/log pipelines. This module registers the OTLP/proto
7
+ * trace, log, and metric SDK providers when the standard `OTEL_*` endpoint env
8
+ * vars are set so `omp` can be observed by any OTLP collector without vendor
9
+ * coupling.
10
+ *
11
+ * Only the `http/protobuf` transport is supported — an
12
+ * `OTEL_EXPORTER_OTLP*_PROTOCOL` of `grpc` or `http/json` declines rather than
13
+ * misrouting protobuf payloads. The exporter line is pinned to the 0.218/2.7
14
+ * family validated under Bun; the 1.x OTLP line deadlocks when its
15
+ * `req.on("close")` handler fires after a successful export.
16
+ */
17
+ import type { AgentTelemetryConfig } from "@oh-my-pi/pi-agent-core";
18
+ /**
19
+ * Whether {@link initTelemetryExport} registered any real OTLP signal provider.
20
+ * The CLI uses this to decide whether to switch on the agent loop's telemetry
21
+ * hooks; metrics and structured logs need those callbacks even when traces are
22
+ * disabled.
5
23
  */
6
24
  export declare function isTelemetryExportEnabled(): boolean;
7
25
  /**
8
- * Register the global TracerProvider + OTLP exporter when an OTLP endpoint is
9
- * configured via env. Idempotent, and a no-op when no endpoint is set (or when
10
- * the OTEL kill-switches are engaged), so it is safe to call unconditionally at
11
- * startup.
26
+ * Merge OTLP metrics/log hooks into an existing agent telemetry config.
27
+ *
28
+ * The caller still owns content-capture policy, cost estimation, and custom
29
+ * attributes. This only appends host-level metrics/log forwarding for the
30
+ * providers registered by {@link initTelemetryExport}.
31
+ */
32
+ export declare function createTelemetryExportConfig(config: AgentTelemetryConfig | undefined): AgentTelemetryConfig | undefined;
33
+ /**
34
+ * Register global trace/log/meter providers when OTLP endpoints are configured
35
+ * through env. Idempotent, and a no-op when no signal has an endpoint (or when
36
+ * the OTEL kill-switches are engaged), so startup can call it unconditionally.
12
37
  */
13
38
  export declare function initTelemetryExport(): Promise<void>;
14
39
  /**
15
- * Flush any buffered spans to the exporter. No-op when export is disabled.
40
+ * Flush buffered spans, log records, and metrics. No-op when export is disabled.
16
41
  * Hosts embedding the agent can call this at natural boundaries (e.g. the end
17
- * of a turn) so traces surface promptly rather than on the batch interval.
42
+ * of a turn) so telemetry surfaces promptly rather than on the batch interval.
18
43
  */
19
44
  export declare function flushTelemetryExport(): Promise<void>;
@@ -17,6 +17,14 @@ export interface ResolvedApproval {
17
17
  reason?: string;
18
18
  override: boolean;
19
19
  }
20
+ /**
21
+ * Evaluate a tool's own approval declaration against `args` and return the
22
+ * resulting capability tier, defaulting to `exec` when the tool omits an
23
+ * approval. Unlike reading `tool.approval` directly, this runs function-valued
24
+ * approvals — the write tool's `xd://` gate uses it to take a mounted device's
25
+ * argument-dependent tier instead of falling back to `exec`.
26
+ */
27
+ export declare function resolveToolTier(tool: ApprovalSubject, args: unknown): ToolTier;
20
28
  /**
21
29
  * Resolve approval policy for a tool call.
22
30
  *
@@ -76,6 +76,8 @@ export interface BashToolDetails {
76
76
  wallTimeMs?: number;
77
77
  /** Exit code of a command that ran to completion but failed (non-zero). */
78
78
  exitCode?: number;
79
+ /** True when the command was killed by its timeout deadline (not a failure). */
80
+ timedOut?: boolean;
79
81
  terminalId?: string;
80
82
  async?: {
81
83
  state: "running" | "completed" | "failed";
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Canonical set of built-in tools that must stay top-level.
3
+ *
4
+ * These are the coding essentials the model always needs directly in its
5
+ * callable schema. `read`/`write` are additionally the `xd://` transport
6
+ * (`read xd://` lists devices, `write xd://<tool>` executes them), so demoting
7
+ * them under xdev makes every mounted device unreachable.
8
+ *
9
+ * Adapter boundaries (extension `registerTool`, SDK custom tools, RPC host
10
+ * tools) default an omitted `loadMode` to `"discoverable"`. A UI-only
11
+ * re-register of a built-in — e.g. wrapping `read`/`write`/`bash`/`edit`/`glob`
12
+ * to customize rendering — would then silently demote it to `discoverable` and,
13
+ * with `tools.xdev` on, unmount it from the top-level schema (issue #5764).
14
+ * {@link defaultLoadModeForToolName} pins these names to `"essential"` when the
15
+ * definition omits `loadMode`, so re-registering a built-in never demotes it.
16
+ */
17
+ import type { ToolLoadMode } from "@oh-my-pi/pi-agent-core";
18
+ /**
19
+ * Built-in tool names whose classes declare `loadMode = "essential"`. Kept in
20
+ * sync with the tool classes by `essential-tools.test.ts` (drift guard).
21
+ */
22
+ export declare const ESSENTIAL_BUILTIN_TOOL_NAMES: Record<string, true>;
23
+ /**
24
+ * Resolve a tool's presentation mode at an adapter boundary. An explicit
25
+ * `declared` mode always wins. When omitted, known essential built-in names
26
+ * default to `"essential"` (so a re-register never demotes them); everything
27
+ * else defaults to `"discoverable"`.
28
+ */
29
+ export declare function defaultLoadModeForToolName(name: string, declared?: ToolLoadMode): ToolLoadMode;
@@ -53,22 +53,21 @@ export interface ReadUrlToolDetails {
53
53
  notes: string[];
54
54
  meta?: OutputMeta;
55
55
  }
56
- interface ReadUrlCacheEntry {
56
+ interface ReadUrlEntry {
57
57
  artifactId?: string;
58
58
  artifactPath?: string;
59
- contentPath?: string;
60
59
  details: ReadUrlToolDetails;
61
60
  image?: FetchImagePayload;
62
61
  output: string;
63
62
  content: string;
64
63
  }
65
- export declare function loadReadUrlCacheEntry(session: ToolSession, params: {
64
+ /** Fetch and render a URL for a read or search operation. */
65
+ export declare function fetchReadUrl(session: ToolSession, params: {
66
66
  path: string;
67
67
  raw?: boolean;
68
68
  }, signal?: AbortSignal, options?: {
69
69
  ensureArtifact?: boolean;
70
- preferCached?: boolean;
71
- }): Promise<ReadUrlCacheEntry>;
70
+ }): Promise<ReadUrlEntry>;
72
71
  /** Materialize rendered URL body text to a local file for tools that require filesystem paths. */
73
72
  export declare function materializeReadUrlToFile(session: ToolSession, params: {
74
73
  path: string;
@@ -32,7 +32,11 @@ export declare function resolveMessageTimeoutMs(settings: Settings, explicit?: n
32
32
  export declare function drainPendingInbox(registry: AgentRegistry, senderId: string, from?: string): IrcMessage | undefined;
33
33
  /** `wait` result carrying a consumed message. */
34
34
  export declare function messageResult(senderId: string, waited: IrcMessage): AgentToolResult<CoordinationDetails>;
35
- export declare function executeList(registry: AgentRegistry, senderId: string): AgentToolResult<CoordinationDetails>;
35
+ /**
36
+ * List every addressable peer, restoring parked refs from disk when a resumed
37
+ * session has no in-memory roster.
38
+ */
39
+ export declare function executeList(registry: AgentRegistry, senderId: string): Promise<AgentToolResult<CoordinationDetails>>;
36
40
  export interface HubSendParams {
37
41
  to?: string;
38
42
  message?: string;
@@ -2,7 +2,7 @@ import { type Model } from "@oh-my-pi/pi-ai";
2
2
  import { type ModelRegistry } from "../config/model-registry.js";
3
3
  import type { CustomTool } from "../extensibility/custom-tools/types.js";
4
4
  export type ImageProvider = "antigravity" | "gemini" | "openai" | "openai-codex" | "openrouter" | "xai";
5
- export type ImageProviderPreference = Exclude<ImageProvider, "openai-codex"> | "auto";
5
+ export type ImageProviderPreference = ImageProvider | "auto";
6
6
  declare const responseModalitySchema: import("arktype/internal/variants/string.ts").StringType<"IMAGE" | "TEXT", {}>;
7
7
  export declare const imageGenSchema: import("arktype/internal/variants/object.ts").ObjectType<{
8
8
  subject: string;
@@ -20,6 +20,7 @@ export declare const imageGenSchema: import("arktype/internal/variants/object.ts
20
20
  data?: string | undefined;
21
21
  mime_type?: string | undefined;
22
22
  }[] | undefined;
23
+ provider?: "antigravity" | "auto" | "gemini" | "openai" | "openai-codex" | "openrouter" | "xai" | undefined;
23
24
  }, {}>;
24
25
  export type ImageGenParams = typeof imageGenSchema.infer;
25
26
  export type GeminiResponseModality = typeof responseModalitySchema.infer;
@@ -20,6 +20,7 @@ import type { CustomMessage } from "../session/messages.js";
20
20
  import type { UsageStatistics } from "../session/session-entries.js";
21
21
  import type { ToolChoiceQueue } from "../session/tool-choice-queue.js";
22
22
  import type { AgentOutputManager } from "../task/output-manager.js";
23
+ import { type StructuredSubagentSchemaMode } from "../task/types.js";
23
24
  import type { EventBus } from "../utils/event-bus.js";
24
25
  import type { WorkspaceTree } from "../workspace-tree.js";
25
26
  import { type BuiltinToolName, type HiddenToolName } from "./builtin-names.js";
@@ -40,6 +41,7 @@ export * from "./bash.js";
40
41
  export * from "./browser.js";
41
42
  export * from "./checkpoint.js";
42
43
  export * from "./debug.js";
44
+ export * from "./essential-tools.js";
43
45
  export * from "./eval.js";
44
46
  export * from "./eval-backends.js";
45
47
  export * from "./gh.js";
@@ -143,17 +145,31 @@ export interface ToolSession {
143
145
  customToolPaths?: ToolPathWithSource[];
144
146
  /** Whether LSP integrations are enabled */
145
147
  enableLsp?: boolean;
148
+ /** Whether this invocation may expose IRC. `false` removes it even for subagents. */
149
+ enableIrc?: boolean;
150
+ /**
151
+ * Whether MCP capabilities may be forwarded to child sessions. `false`
152
+ * prohibits inherited-manager and process-global MCP fallback.
153
+ */
154
+ enableMCP?: boolean;
146
155
  /** Whether an edit-capable tool is available in this session (controls hashline output) */
147
156
  hasEditTool?: boolean;
148
157
  /** Event bus for tool/extension communication */
149
158
  eventBus?: EventBus;
150
- /** Output schema for structured completion (subagents) */
159
+ /** Output schema for structured completion (subagents). */
151
160
  outputSchema?: unknown;
161
+ /** Enforcement policy for {@link outputSchema}; defaults to legacy permissive behavior. */
162
+ outputSchemaMode?: StructuredSubagentSchemaMode;
152
163
  /** Whether to include the yield tool by default */
153
164
  requireYieldTool?: boolean;
154
165
  /** Session starts with a prewalk hand-off armed. Keeps `todo` in yield-gated
155
166
  * (subagent) registries: the prewalk plan nudge + todo gate need it. */
156
167
  prewalkArmed?: boolean;
168
+ /**
169
+ * Constrain the active set to the caller's explicit built-in names (plus a
170
+ * required yield tool). Suppresses automatic tool-set expansion.
171
+ */
172
+ restrictToolNames?: boolean;
157
173
  /** Task recursion depth (0 = top-level, 1 = first child, etc.) */
158
174
  taskDepth?: number;
159
175
  /** Get shared eval executor session ID. Subagents inherit this to share JS/Python/Ruby/Julia state. */
@@ -57,6 +57,35 @@ export declare function getLatestTodoPhasesFromEntries(entries: SessionEntry[]):
57
57
  * the contained side.
58
58
  */
59
59
  export declare function todoMatchesAnyDescription(content: string, descriptions: readonly string[]): boolean;
60
+ /** Result of {@link selectCollapsedTodos}: the rows to render plus an optional
61
+ * summary line (empty string ⇒ no summary row). */
62
+ export interface CollapsedTodoSelection<T> {
63
+ items: T[];
64
+ summary: string;
65
+ }
66
+ /**
67
+ * Walking-viewport selection for a phase's collapsed todo preview (#5873).
68
+ *
69
+ * Policy, applied to `tasks` in todo order:
70
+ * 1. While the phase has open work, completed/abandoned tasks are omitted. A
71
+ * phase with no open tasks left falls back to its closed tasks so the sticky
72
+ * HUD's closed-todo persistence still has something to render.
73
+ * 2. Every active task (in-progress, or pending matched to a live subagent) is
74
+ * placed at the head in stable todo order — never dropped for lying outside
75
+ * an ordinary window.
76
+ * 3. Remaining rows up to `cap` are filled with the pending tasks that follow
77
+ * the first active one, in todo order (falling back to leading pending tasks
78
+ * when no active task exists), so a freshly-promoted task leads the preview.
79
+ * 4. When active tasks alone exceed `cap`, only the first `cap` active tasks are
80
+ * shown and the summary counts the hidden *active* todos, never replacing
81
+ * them with unrelated pending rows.
82
+ *
83
+ * The summary otherwise counts the remaining tasks in the display base. Returns
84
+ * the whole base with an empty summary when it already fits.
85
+ */
86
+ export declare function selectCollapsedTodos<T extends {
87
+ status: TodoStatus;
88
+ }>(tasks: T[], isMatched: (task: T) => boolean, cap: number): CollapsedTodoSelection<T>;
60
89
  /** Apply an array of `todo`-style ops to existing phases. Used by /todo slash command. */
61
90
  export declare function applyOpsToPhases(currentPhases: TodoPhase[], ops: TodoParams[]): {
62
91
  phases: TodoPhase[];
@@ -111,6 +140,8 @@ export declare function formatPhaseDisplayName(name: string, oneBasedIndex: numb
111
140
  export declare const TODO_STRIKE_HOLD_FRAMES = 2;
112
141
  export declare const TODO_STRIKE_REVEAL_FRAMES = 12;
113
142
  export declare const TODO_STRIKE_TOTAL_FRAMES: number;
143
+ /** Wire the live-subagent description source for {@link todoToolRenderer}. */
144
+ export declare function setActiveTodoDescriptionsProvider(provider: () => readonly string[]): void;
114
145
  export declare const todoToolRenderer: {
115
146
  renderCall(args: TodoRenderArgs, options: RenderResultOptions, uiTheme: Theme): Component;
116
147
  renderResult(result: {
@@ -37,11 +37,20 @@ import type { ToolRenderer } from "./renderers.js";
37
37
  * behind dispatch.
38
38
  */
39
39
  export declare const XDEV_KEEP_TOP_LEVEL: Record<string, true>;
40
+ /**
41
+ * Tools that carry the `xd://` transport itself and therefore can never be
42
+ * mounted as devices: `read xd://` lists/documents devices and
43
+ * `write xd://<tool>` executes them. Demoting either leaves every mounted
44
+ * device unreachable (issue #5764), so they stay top-level regardless of a
45
+ * declared `loadMode`.
46
+ */
47
+ export declare const XDEV_TRANSPORT_TOOLS: Record<string, true>;
40
48
  /**
41
49
  * Whether an enabled tool is presented under `xd://` (rather than top-level)
42
50
  * while the `xd://` transport is active. Discoverable tools mount unless they
43
- * are pinned top-level by {@link XDEV_KEEP_TOP_LEVEL}; essential tools never do.
44
- * The caller gates this on the transport being active (a session-owned
51
+ * are pinned top-level by {@link XDEV_KEEP_TOP_LEVEL} or carry the transport
52
+ * itself ({@link XDEV_TRANSPORT_TOOLS}); essential tools never do. The caller
53
+ * gates this on the transport being active (a session-owned
45
54
  * {@link XdevRegistry} existing).
46
55
  */
47
56
  export declare function isMountableUnderXdev(tool: {
@@ -13,6 +13,13 @@ export interface TreeListOptions<T> {
13
13
  maxCollapsedLines?: number;
14
14
  itemType?: string;
15
15
  truncateFrom?: "start" | "end";
16
+ /** Caller-supplied trailing summary line. When set (and not expanded),
17
+ * `renderTreeList` renders exactly the provided `items` (the caller has
18
+ * already applied its own selection/cap) and appends this text as the
19
+ * final `└` row, with the last item using `├`. Empty string renders the
20
+ * items with no summary. Bypasses the built-in truncation/`maxCollapsed`
21
+ * path. */
22
+ trailingSummary?: string;
16
23
  /** Called once per item with `isLast: false` during budget calculation;
17
24
  * line count MUST NOT vary based on `isLast`. */
18
25
  renderItem: (item: T, context: TreeContext) => string | string[];