@oh-my-pi/pi-coding-agent 17.1.0 → 17.1.2

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 (196) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/dist/cli.js +6325 -4420
  3. package/dist/types/cli/bench-cli.d.ts +1 -0
  4. package/dist/types/config/model-resolver.d.ts +6 -3
  5. package/dist/types/config/settings-schema.d.ts +62 -0
  6. package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +3 -0
  7. package/dist/types/launch/broker-list-order.test.d.ts +1 -0
  8. package/dist/types/live/attestation.d.ts +2 -0
  9. package/dist/types/live/controller.d.ts +10 -2
  10. package/dist/types/live/protocol.d.ts +1 -1
  11. package/dist/types/live/transport.d.ts +6 -19
  12. package/dist/types/live/visualizer.d.ts +8 -11
  13. package/dist/types/modes/components/assistant-message.d.ts +1 -0
  14. package/dist/types/modes/components/custom-message.d.ts +1 -1
  15. package/dist/types/modes/components/message-frame.d.ts +8 -4
  16. package/dist/types/modes/components/session-account-selector.d.ts +11 -0
  17. package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
  18. package/dist/types/modes/interactive-mode.d.ts +3 -6
  19. package/dist/types/modes/types.d.ts +9 -5
  20. package/dist/types/modes/utils/ui-helpers.d.ts +1 -6
  21. package/dist/types/session/agent-session-types.d.ts +8 -1
  22. package/dist/types/session/agent-session.d.ts +20 -1
  23. package/dist/types/session/auth-storage.d.ts +1 -1
  24. package/dist/types/session/eval-runner.d.ts +2 -0
  25. package/dist/types/session/messages.d.ts +2 -0
  26. package/dist/types/session/session-tools.d.ts +15 -0
  27. package/dist/types/session/streaming-output.d.ts +8 -0
  28. package/dist/types/slash-commands/helpers/session-pin.d.ts +9 -0
  29. package/dist/types/stt/index.d.ts +0 -2
  30. package/dist/types/stt/stt-controller.d.ts +7 -0
  31. package/dist/types/task/executor.d.ts +3 -1
  32. package/dist/types/task/structured-subagent.d.ts +3 -0
  33. package/dist/types/task/types.d.ts +11 -11
  34. package/dist/types/thinking.d.ts +13 -0
  35. package/dist/types/tiny/title-client.d.ts +10 -0
  36. package/dist/types/tools/builtin-names.d.ts +1 -1
  37. package/dist/types/tools/computer/protocol.d.ts +43 -0
  38. package/dist/types/tools/computer/supervisor.d.ts +32 -0
  39. package/dist/types/tools/computer/worker-entry.d.ts +1 -0
  40. package/dist/types/tools/computer/worker.d.ts +15 -0
  41. package/dist/types/tools/computer-renderer.d.ts +22 -0
  42. package/dist/types/tools/computer.d.ts +71 -0
  43. package/dist/types/tools/context.d.ts +2 -0
  44. package/dist/types/tools/default-renderer.d.ts +21 -0
  45. package/dist/types/tools/eval-format/index.d.ts +7 -0
  46. package/dist/types/tools/eval-format/javascript.d.ts +2 -0
  47. package/dist/types/tools/eval-format/julia.d.ts +2 -0
  48. package/dist/types/tools/eval-format/python.d.ts +2 -0
  49. package/dist/types/tools/eval-format/ruby.d.ts +2 -0
  50. package/dist/types/tools/index.d.ts +2 -0
  51. package/dist/types/tools/resolve.d.ts +7 -0
  52. package/dist/types/tools/todo.d.ts +4 -1
  53. package/dist/types/tts/streaming-player.d.ts +10 -43
  54. package/dist/types/utils/tools-manager.d.ts +1 -2
  55. package/dist/types/web/search/providers/base.d.ts +16 -0
  56. package/dist/types/web/search/providers/brave.d.ts +2 -0
  57. package/dist/types/web/search/providers/firecrawl.d.ts +2 -0
  58. package/dist/types/web/search/providers/gemini.d.ts +3 -0
  59. package/dist/types/web/search/providers/jina.d.ts +2 -0
  60. package/dist/types/web/search/providers/kagi.d.ts +2 -0
  61. package/dist/types/web/search/providers/kimi.d.ts +2 -0
  62. package/dist/types/web/search/providers/parallel.d.ts +2 -0
  63. package/dist/types/web/search/providers/perplexity.d.ts +3 -0
  64. package/dist/types/web/search/providers/searxng.d.ts +10 -0
  65. package/dist/types/web/search/providers/tavily.d.ts +8 -0
  66. package/dist/types/web/search/query.d.ts +190 -0
  67. package/package.json +12 -12
  68. package/src/cli/args.ts +1 -0
  69. package/src/cli/bench-cli.ts +12 -1
  70. package/src/cli/setup-cli.ts +2 -14
  71. package/src/cli/web-search-cli.ts +7 -0
  72. package/src/cli.ts +8 -0
  73. package/src/config/model-registry.ts +6 -0
  74. package/src/config/model-resolver.ts +17 -6
  75. package/src/config/settings-schema.ts +66 -0
  76. package/src/debug/raw-sse-buffer.ts +157 -30
  77. package/src/eval/executor-base.ts +1 -0
  78. package/src/eval/js/executor.ts +2 -0
  79. package/src/exec/bash-executor.ts +1 -0
  80. package/src/export/share.ts +4 -3
  81. package/src/extensibility/extensions/wrapper.ts +68 -12
  82. package/src/extensibility/legacy-pi-coding-agent-shim.ts +7 -1
  83. package/src/launch/broker-list-order.test.ts +89 -0
  84. package/src/launch/broker.ts +49 -8
  85. package/src/live/attestation.ts +91 -0
  86. package/src/live/controller.ts +76 -23
  87. package/src/live/protocol.test.ts +3 -3
  88. package/src/live/protocol.ts +1 -1
  89. package/src/live/transport.ts +72 -140
  90. package/src/live/visualizer.ts +114 -134
  91. package/src/modes/components/assistant-message.ts +7 -2
  92. package/src/modes/components/custom-message.ts +4 -1
  93. package/src/modes/components/message-frame.ts +14 -8
  94. package/src/modes/components/session-account-selector.ts +62 -0
  95. package/src/modes/components/tool-execution.ts +17 -110
  96. package/src/modes/controllers/input-controller.ts +55 -47
  97. package/src/modes/controllers/live-command-controller.ts +82 -5
  98. package/src/modes/controllers/selector-controller.ts +62 -0
  99. package/src/modes/interactive-mode.ts +79 -5
  100. package/src/modes/types.ts +10 -4
  101. package/src/modes/utils/ui-helpers.ts +7 -8
  102. package/src/prompts/system/computer-safety.md +14 -0
  103. package/src/prompts/system/resolve-device-reminder.md +1 -1
  104. package/src/prompts/system/workflow-notice.md +1 -1
  105. package/src/prompts/tools/ast-edit.md +1 -0
  106. package/src/prompts/tools/bash.md +1 -0
  107. package/src/prompts/tools/computer.md +26 -0
  108. package/src/prompts/tools/eval.md +2 -2
  109. package/src/prompts/tools/task.md +5 -2
  110. package/src/prompts/tools/web-search.md +2 -0
  111. package/src/sdk.ts +13 -4
  112. package/src/session/agent-session-types.ts +9 -0
  113. package/src/session/agent-session.ts +70 -0
  114. package/src/session/auth-storage.ts +1 -0
  115. package/src/session/eval-runner.ts +5 -0
  116. package/src/session/messages.ts +3 -0
  117. package/src/session/queued-messages.ts +7 -1
  118. package/src/session/session-tools.ts +37 -0
  119. package/src/session/streaming-output.ts +52 -5
  120. package/src/slash-commands/builtin-registry.ts +165 -9
  121. package/src/slash-commands/helpers/session-pin.ts +44 -0
  122. package/src/stt/downloader.ts +0 -2
  123. package/src/stt/index.ts +0 -2
  124. package/src/stt/stt-controller.ts +57 -146
  125. package/src/system-prompt.ts +4 -0
  126. package/src/task/executor.ts +17 -9
  127. package/src/task/index.ts +14 -34
  128. package/src/task/structured-subagent.ts +4 -0
  129. package/src/task/types.ts +15 -13
  130. package/src/thinking.ts +27 -0
  131. package/src/tiny/title-client.ts +22 -0
  132. package/src/tools/ast-edit.ts +4 -1
  133. package/src/tools/bash-interactive.ts +90 -86
  134. package/src/tools/bash.ts +13 -0
  135. package/src/tools/browser/render.ts +2 -1
  136. package/src/tools/builtin-names.ts +1 -0
  137. package/src/tools/computer/protocol.ts +28 -0
  138. package/src/tools/computer/supervisor.ts +258 -0
  139. package/src/tools/computer/worker-entry.ts +25 -0
  140. package/src/tools/computer/worker.ts +135 -0
  141. package/src/tools/computer-renderer.ts +108 -0
  142. package/src/tools/computer.ts +433 -0
  143. package/src/tools/context.ts +2 -0
  144. package/src/tools/default-renderer.ts +139 -0
  145. package/src/tools/essential-tools.ts +1 -0
  146. package/src/tools/eval-format/index.ts +24 -0
  147. package/src/tools/eval-format/javascript.ts +952 -0
  148. package/src/tools/eval-format/julia.ts +446 -0
  149. package/src/tools/eval-format/python.ts +544 -0
  150. package/src/tools/eval-format/ruby.ts +380 -0
  151. package/src/tools/eval-render.ts +12 -6
  152. package/src/tools/index.ts +5 -0
  153. package/src/tools/renderers.ts +2 -0
  154. package/src/tools/resolve.ts +10 -1
  155. package/src/tools/todo.ts +58 -6
  156. package/src/tools/xdev.ts +54 -26
  157. package/src/tts/streaming-player.ts +81 -340
  158. package/src/utils/clipboard.ts +1 -30
  159. package/src/utils/mac-file-urls.applescript +37 -0
  160. package/src/utils/tool-choice.ts +14 -0
  161. package/src/utils/tools-manager.ts +1 -19
  162. package/src/web/search/index.ts +28 -5
  163. package/src/web/search/providers/anthropic.ts +62 -4
  164. package/src/web/search/providers/base.ts +16 -0
  165. package/src/web/search/providers/brave.ts +30 -3
  166. package/src/web/search/providers/codex.ts +14 -1
  167. package/src/web/search/providers/duckduckgo.ts +23 -1
  168. package/src/web/search/providers/ecosia.ts +5 -1
  169. package/src/web/search/providers/exa.ts +28 -1
  170. package/src/web/search/providers/firecrawl.ts +37 -3
  171. package/src/web/search/providers/gemini.ts +12 -2
  172. package/src/web/search/providers/google.ts +2 -1
  173. package/src/web/search/providers/jina.ts +31 -8
  174. package/src/web/search/providers/kagi.ts +10 -1
  175. package/src/web/search/providers/kimi.ts +16 -1
  176. package/src/web/search/providers/mojeek.ts +14 -1
  177. package/src/web/search/providers/parallel.ts +48 -2
  178. package/src/web/search/providers/perplexity.ts +94 -6
  179. package/src/web/search/providers/searxng.ts +145 -9
  180. package/src/web/search/providers/startpage.ts +8 -2
  181. package/src/web/search/providers/synthetic.ts +7 -1
  182. package/src/web/search/providers/tavily.ts +52 -3
  183. package/src/web/search/providers/tinyfish.ts +6 -1
  184. package/src/web/search/providers/xai.ts +49 -2
  185. package/src/web/search/providers/zai.ts +19 -1
  186. package/src/web/search/query.ts +850 -0
  187. package/dist/types/stt/recorder.d.ts +0 -30
  188. package/dist/types/stt/transcriber.d.ts +0 -14
  189. package/dist/types/stt/wav.d.ts +0 -29
  190. package/dist/types/tts/player.d.ts +0 -32
  191. package/src/live/audio-worklet.txt +0 -59
  192. package/src/live/browser-runtime.txt +0 -221
  193. package/src/stt/recorder.ts +0 -551
  194. package/src/stt/transcriber.ts +0 -60
  195. package/src/stt/wav.ts +0 -173
  196. package/src/tts/player.ts +0 -137
@@ -21,6 +21,7 @@ export interface BenchCommandArgs {
21
21
  }
22
22
  export interface BenchModelRegistry {
23
23
  getAll(): Model<Api>[];
24
+ getAvailable(): Model<Api>[];
24
25
  getApiKey(model: Model<Api>, sessionId?: string): Promise<string | undefined>;
25
26
  resolver(model: ApiKeyResolverModel, sessionId?: string): ApiKeyResolver;
26
27
  hasConfiguredAuth?(model: Model<Api>): boolean;
@@ -78,7 +78,7 @@ export interface ModelMatchPreferences {
78
78
  deprioritizeProviders?: string[];
79
79
  }
80
80
  export type ModelLookupRegistry = Pick<ModelRegistry, "getAvailable">;
81
- type CliModelRegistry = Pick<ModelRegistry, "getAll">;
81
+ type CliModelRegistry = Pick<ModelRegistry, "getAll" | "getAvailable">;
82
82
  type InitialModelRegistry = Pick<ModelRegistry, "getAvailable" | "find">;
83
83
  type RestorableModelRegistry = Pick<ModelRegistry, "getAvailable" | "find" | "getApiKey">;
84
84
  export declare function getModelMatchPreferences(settings?: Partial<Pick<Settings, "get" | "getStorage">>): ModelMatchPreferences;
@@ -279,13 +279,16 @@ export interface ResolveCliModelResult {
279
279
  /**
280
280
  * Resolve a single model from CLI flags.
281
281
  *
282
- * Exact model names take precedence over configured role names.
282
+ * Explicit `provider/id` references and authenticated bare ids take precedence
283
+ * over configured role names, which in turn take precedence over an
284
+ * unauthenticated catalog-only id (so a bundled `cursor/default` never shadows a
285
+ * configured `modelRoles.default`).
283
286
  */
284
287
  export declare function resolveCliModel(options: {
285
288
  cliProvider?: string;
286
289
  cliModel?: string;
287
290
  modelRegistry: CliModelRegistry;
288
- /** Authenticated models to prefer for unqualified selectors; omit to preserve catalog-order behavior. */
291
+ /** Authenticated models to prefer for unqualified selectors; defaults to the registry's authenticated set. */
289
292
  availableModels?: Model<Api>[];
290
293
  settings?: Settings;
291
294
  preferences?: ModelMatchPreferences;
@@ -3934,6 +3934,64 @@ export declare const SETTINGS_SCHEMA: {
3934
3934
  readonly description: "Enable the inspect_image tool, delegating image understanding to a vision-capable model";
3935
3935
  };
3936
3936
  };
3937
+ readonly "computer.enabled": {
3938
+ readonly type: "boolean";
3939
+ readonly default: false;
3940
+ readonly ui: {
3941
+ readonly tab: "tools";
3942
+ readonly group: "Available Tools";
3943
+ readonly label: "Computer";
3944
+ readonly description: "Enable native host-desktop screenshots and input for OpenAI computer use";
3945
+ };
3946
+ };
3947
+ readonly "computer.backend": {
3948
+ readonly type: "enum";
3949
+ readonly values: readonly ["auto", "native"];
3950
+ readonly default: "auto";
3951
+ readonly ui: {
3952
+ readonly tab: "tools";
3953
+ readonly group: "Computer";
3954
+ readonly label: "Computer Backend";
3955
+ readonly description: "Select automatic or explicit platform-native desktop capture and input";
3956
+ readonly options: readonly [{
3957
+ readonly value: "auto";
3958
+ readonly label: "Auto";
3959
+ }, {
3960
+ readonly value: "native";
3961
+ readonly label: "Native";
3962
+ }];
3963
+ };
3964
+ };
3965
+ readonly "computer.display": {
3966
+ readonly type: "string";
3967
+ readonly default: "all";
3968
+ readonly ui: {
3969
+ readonly tab: "tools";
3970
+ readonly group: "Computer";
3971
+ readonly label: "Computer Display";
3972
+ readonly description: "Composite all displays or select a native display id";
3973
+ };
3974
+ };
3975
+ readonly "computer.maxWidth": {
3976
+ readonly type: "number";
3977
+ readonly default: 1920;
3978
+ readonly ui: {
3979
+ readonly tab: "tools";
3980
+ readonly group: "Computer";
3981
+ readonly label: "Computer Screenshot Width";
3982
+ readonly description: "Maximum composite screenshot width in pixels";
3983
+ };
3984
+ };
3985
+ readonly "computer.maxHeight": {
3986
+ readonly type: "number";
3987
+ readonly default: 1200;
3988
+ readonly ui: {
3989
+ readonly tab: "tools";
3990
+ readonly group: "Computer";
3991
+ readonly label: "Computer Screenshot Height";
3992
+ readonly description: "Maximum composite screenshot height in pixels";
3993
+ };
3994
+ };
3937
3995
  readonly "checkpoint.enabled": {
3938
3996
  readonly type: "boolean";
3939
3997
  readonly default: false;
@@ -5753,6 +5811,10 @@ export declare const SETTINGS_SCHEMA: {
5753
5811
  readonly type: "string";
5754
5812
  readonly default: undefined;
5755
5813
  };
5814
+ readonly "searxng.engines": {
5815
+ readonly type: "string";
5816
+ readonly default: undefined;
5817
+ };
5756
5818
  readonly "searxng.language": {
5757
5819
  readonly type: "string";
5758
5820
  readonly default: undefined;
@@ -12,6 +12,7 @@
12
12
  * the same module identity as a direct `@oh-my-pi/pi-coding-agent` import.
13
13
  */
14
14
  import { type AuthCredential, type TSchema } from "@oh-my-pi/pi-ai";
15
+ import { type Keybinding } from "@oh-my-pi/pi-tui";
15
16
  import type { PromptTemplate } from "../config/prompt-templates.js";
16
17
  import { Settings } from "../config/settings.js";
17
18
  import type { CreateAgentSessionOptions, CreateAgentSessionResult, LoadExtensionsResult } from "../sdk.js";
@@ -75,6 +76,8 @@ export interface LsOperations {
75
76
  export interface LsToolOptions {
76
77
  operations?: LsOperations;
77
78
  }
79
+ /** Format the active shortcut for legacy extensions that render keybinding hints. */
80
+ export declare function keyText(action: Keybinding): string;
78
81
  /** Parse frontmatter using the historical Pi package-root helper. */
79
82
  export interface ParsedFrontmatter<T extends Record<string, unknown> = Record<string, unknown>> {
80
83
  frontmatter: T;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ /** Generates the Codex DeviceCheck attestation envelope sent as `x-oai-attestation` on ChatGPT-OAuth requests. */
2
+ export declare function generateCodexAttestation(): Promise<string | undefined>;
@@ -1,6 +1,14 @@
1
1
  import type { AssistantMessage } from "@oh-my-pi/pi-ai";
2
2
  import type { AgentSession } from "../session/agent-session.js";
3
- import type { LivePhase, LiveTranscript } from "./visualizer.js";
3
+ import type { LivePhase } from "./visualizer.js";
4
+ /** Incremental or final transcript for one realtime conversational turn. */
5
+ export interface LiveTranscript {
6
+ role: "user" | "assistant";
7
+ text: string;
8
+ /** Monotonic role-local turn number used to coalesce streaming updates. */
9
+ turn: number;
10
+ final: boolean;
11
+ }
4
12
  /** UI notifications emitted during a live session. */
5
13
  export interface LiveSessionCallbacks {
6
14
  /** Reports connection and activity phase changes. */
@@ -20,7 +28,7 @@ export interface LiveSessionControllerOptions {
20
28
  callbacks: LiveSessionCallbacks;
21
29
  /** Extracts visible assistant text using the caller's normal UI rules. */
22
30
  extractAssistantText(message: AssistantMessage): string;
23
- /** Realtime output voice, defaulting to marin. */
31
+ /** Realtime output voice, defaulting to sol. */
24
32
  voice?: string;
25
33
  }
26
34
  /** Coordinates the realtime conversational surface with normal AgentSession turns. */
@@ -1,5 +1,5 @@
1
1
  /** Frameless Bidi model used by Codex Desktop live calls. */
2
- export declare const LIVE_MODEL: "gpt-live-1-boulder-alpha";
2
+ export declare const LIVE_MODEL: "gpt-live-1-codex";
3
3
  /** Maximum UTF-8 payload size accepted by each context append. */
4
4
  export declare const CONTEXT_CHUNK_BYTES = 500;
5
5
  /** Semantic stream selected for appended Frameless Bidi context. */
@@ -1,17 +1,5 @@
1
1
  import { type AuthStorage } from "@oh-my-pi/pi-ai";
2
2
  import { type LiveClientMessage, type LiveServerEvent } from "./protocol.js";
3
- type BrowserLiveApi = {
4
- start(workletSource: string): Promise<string>;
5
- acceptAnswer(sdp: string): Promise<void>;
6
- waitForOpen(): Promise<void>;
7
- send(payload: string): void;
8
- pushAudio(payload: string): void;
9
- setMuted(muted: boolean): void;
10
- close(): Promise<void>;
11
- };
12
- declare global {
13
- var ompCodexLive: BrowserLiveApi;
14
- }
15
3
  /** Callbacks emitted by the live WebRTC transport. */
16
4
  export interface LiveTransportCallbacks {
17
5
  onEvent(event: LiveServerEvent): void;
@@ -26,23 +14,22 @@ export interface LiveTransportOptions {
26
14
  callbacks: LiveTransportCallbacks;
27
15
  signal?: AbortSignal;
28
16
  }
29
- /** Extracts the server-assigned `rtc_<uuid>` call ID from a signaling Location header. */
17
+ /** Extracts the server-assigned `rtc_*` call ID from a signaling Location header. */
30
18
  export declare function parseLiveCallId(location: string | null): string | undefined;
31
19
  /** Builds the Frameless Bidi sideband WebSocket URL for an accepted Codex call. */
32
20
  export declare function buildLiveSidebandUrl(callId: string): string;
33
- /** Headless-Chromium WebRTC transport for a Codex Frameless Bidi live session. */
21
+ /** Native WebRTC transport for a Codex Frameless Bidi live session. */
34
22
  export declare class CodexLiveTransport {
35
23
  #private;
36
24
  constructor(options: LiveTransportOptions);
37
- /** Establish the browser peer, perform Codex signaling, and wait for the data channel. */
25
+ /** Establish the native peer, perform Codex signaling, and wait for the data channel. */
38
26
  connect(): Promise<void>;
39
27
  /** Serialize one Frameless Bidi control message onto the call's sideband WebSocket. */
40
28
  send(message: LiveClientMessage): Promise<void>;
41
- /** Queue 16 kHz mono Float32 PCM for continuous browser-side resampling and playback. */
29
+ /** Queue 16 kHz mono Float32 PCM for native Opus transmission. */
42
30
  pushAudio(samples: Float32Array): void;
43
- /** Enable or disable the browser audio source and discard queued input when muted. */
31
+ /** Enable or disable the native audio source and discard partial input when muted. */
44
32
  setMuted(muted: boolean): Promise<void>;
45
- /** Stop audio, WebRTC, the page, and Chromium. Safe to call repeatedly. */
33
+ /** Stop sideband signaling and the native WebRTC media peer. Safe to call repeatedly. */
46
34
  close(): Promise<void>;
47
35
  }
48
- export {};
@@ -1,11 +1,6 @@
1
1
  import { type Component } from "@oh-my-pi/pi-tui";
2
2
  /** Distinct states of a realtime call connection. */
3
3
  export type LivePhase = "connecting" | "listening" | "working" | "speaking" | "muted" | "error";
4
- /** A transcribed turn in the realtime call. */
5
- export interface LiveTranscript {
6
- role: "user" | "assistant";
7
- text: string;
8
- }
9
4
  /** Configuration callbacks for user interactions in the visualizer. */
10
5
  export interface LiveVisualizerOptions {
11
6
  onStop(): void;
@@ -18,16 +13,18 @@ export declare class LiveVisualizer implements Component {
18
13
  constructor(options: LiveVisualizerOptions);
19
14
  /** Updates the current call phase. */
20
15
  setPhase(phase: LivePhase): void;
21
- /** Updates the current input and output volume levels (0..1). */
22
- setLevels(input: number, output: number): void;
23
- /** Updates the latest transcript fragment. */
24
- setTranscript(transcript: LiveTranscript | undefined): void;
25
- /** Updates the animation frame for spinners and waveforms. */
16
+ /** Updates the microphone volume level (0..1). */
17
+ setInputLevel(level: number): void;
18
+ /** Advances the spectrum animation and its peak decay. */
26
19
  setFrame(frame: number): void;
20
+ /** Updates the user's streaming voice transcript. */
21
+ setTranscript(text: string): void;
22
+ /** Clears the user's voice transcript row. */
23
+ clearTranscript(): void;
27
24
  /** Processes user keypresses. */
28
25
  handleInput(data: string): void;
29
26
  /** Clears the render cache. */
30
27
  invalidate(): void;
31
- /** Renders the visualizer into a fixed array of rows at the given width. */
28
+ /** Renders the microphone spectrum into a compact fixed-height panel. */
32
29
  render(width: number): readonly string[];
33
30
  }
@@ -14,6 +14,7 @@ export declare class AssistantMessageComponent extends Container {
14
14
  private readonly thinkingRenderers;
15
15
  private readonly imageBudget?;
16
16
  private proseOnlyThinking;
17
+ setTextColorTransform(transform?: (text: string) => string): void;
17
18
  constructor(message?: AssistantMessage, hideThinkingBlock?: boolean, onImageUpdate?: (() => void) | undefined, thinkingRenderers?: readonly AssistantThinkingRenderer[], imageBudget?: ImageBudget | undefined, proseOnlyThinking?: boolean);
18
19
  /**
19
20
  * Show or clear the slim cache-invalidation divider above this turn. Set at
@@ -1,6 +1,6 @@
1
1
  import { Container } from "@oh-my-pi/pi-tui";
2
2
  import type { MessageRenderer } from "../../extensibility/extensions/types.js";
3
- import type { CustomMessage } from "../../session/messages.js";
3
+ import { type CustomMessage } from "../../session/messages.js";
4
4
  /**
5
5
  * Component that renders a custom message entry from extensions.
6
6
  * Uses distinct styling to differentiate from user messages.
@@ -9,7 +9,7 @@
9
9
  */
10
10
  import type { TextContent } from "@oh-my-pi/pi-ai";
11
11
  import type { Box, Component } from "@oh-my-pi/pi-tui";
12
- import { type Theme } from "../../modes/theme/theme.js";
12
+ import { type Theme, type ThemeColor } from "../../modes/theme/theme.js";
13
13
  /** Message shape consumed by the shared frame. */
14
14
  export interface FramedMessage {
15
15
  customType: string;
@@ -31,14 +31,18 @@ export interface RebuildFrameOptions<M extends FramedMessage> {
31
31
  expanded: boolean;
32
32
  /** Icon glyph shown before the customType in the default header (e.g. a hook/extension icon). */
33
33
  icon?: string;
34
+ /** Hide the default type header while retaining the message body. */
35
+ hideHeader?: boolean;
36
+ /** Semantic color for the outline, defaulting to the muted border. */
37
+ borderColor?: ThemeColor;
34
38
  /** Collapse the markdown body to this many lines when `expanded` is false. Omit to never collapse. */
35
39
  collapseAfterLines?: number;
36
40
  customRenderer?: FramedRenderer<M>;
37
41
  }
38
42
  /**
39
43
  * Attempt the custom renderer; on failure or undefined return, populate `box`
40
- * with the default outlined card an `icon customType` header + markdown body
41
- * and return undefined. When the custom renderer succeeds, return its Component
42
- * so the caller can mount it and skip the default box.
44
+ * with the configured outline, optional type header, and markdown body. When
45
+ * the custom renderer succeeds, return its Component so the caller can mount
46
+ * it and skip the default box.
43
47
  */
44
48
  export declare function renderFramedMessage<M extends FramedMessage>(opts: RebuildFrameOptions<M>): Component | undefined;
@@ -0,0 +1,11 @@
1
+ import { Container, type SgrMouseEvent } from "@oh-my-pi/pi-tui";
2
+ import type { SessionPinAccount } from "../../slash-commands/helpers/session-pin.js";
3
+ /** Account picker opened by `/session pin` for the current model provider. */
4
+ export declare class SessionAccountSelectorComponent extends Container {
5
+ #private;
6
+ constructor(providerName: string, accounts: readonly SessionPinAccount[], onSelect: (account: SessionPinAccount) => void, onCancel: () => void);
7
+ /** Forward keyboard navigation and cancellation when the wrapper owns focus. */
8
+ handleInput(keyData: string): void;
9
+ /** Route mouse selection through the title rows into the account list. */
10
+ routeMouse(event: SgrMouseEvent, line: number, col: number): void;
11
+ }
@@ -55,6 +55,7 @@ export declare class SelectorController {
55
55
  }): Promise<boolean>;
56
56
  handleSessionDeleteCommand(): Promise<void>;
57
57
  showOAuthSelector(mode: "login" | "logout", providerId?: string): Promise<void>;
58
+ showSessionPinSelector(): Promise<void>;
58
59
  showResetUsageSelector(): Promise<void>;
59
60
  showDebugSelector(): Promise<void>;
60
61
  showAgentHub(observers: SessionObserverRegistry, options?: {
@@ -36,7 +36,7 @@ import { type LoopLimitRuntime } from "./loop-limit.js";
36
36
  import { OAuthManualInputManager } from "./oauth-manual-input.js";
37
37
  import { type ObservableSession } from "./session-observer-registry.js";
38
38
  import type { Theme } from "./theme/theme.js";
39
- import type { CompactionQueuedMessage, InteractiveModeContext, InteractiveModeInitOptions, InteractiveSelectorDialogOptions, SubmittedUserInput, TodoItem, TodoPhase } from "./types.js";
39
+ import type { CompactionQueuedMessage, InteractiveModeContext, InteractiveModeInitOptions, InteractiveSelectorDialogOptions, RenderSessionContextOptions, SubmittedUserInput, TodoItem, TodoPhase } from "./types.js";
40
40
  /**
41
41
  * Editor max-height cap for a terminal of `terminalRows` rows.
42
42
  *
@@ -309,11 +309,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
309
309
  imageLinks?: readonly (string | undefined)[];
310
310
  reuseSettledComponent?: boolean;
311
311
  }): Component[];
312
- renderSessionContext(sessionContext: SessionContext, options?: {
313
- updateFooter?: boolean;
314
- populateHistory?: boolean;
315
- reuseSettledComponents?: boolean;
316
- }): void;
312
+ renderSessionContext(sessionContext: SessionContext, options?: RenderSessionContextOptions): void;
317
313
  renderInitialMessages(options?: {
318
314
  preserveExistingChat?: boolean;
319
315
  clearTerminalHistory?: boolean;
@@ -376,6 +372,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
376
372
  handleResumeSession(sessionPath: string): Promise<void>;
377
373
  handleSessionDeleteCommand(): Promise<void>;
378
374
  showOAuthSelector(mode: "login" | "logout", providerId?: string): Promise<void>;
375
+ showSessionPinSelector(): Promise<void>;
379
376
  showResetUsageSelector(): Promise<void>;
380
377
  showProviderSetup(): Promise<void>;
381
378
  showHookConfirm(title: string, message: string): Promise<boolean>;
@@ -77,6 +77,13 @@ export interface InteractiveModeInitOptions {
77
77
  clearInitialTerminalHistory?: boolean;
78
78
  }
79
79
  export type InteractiveSelectorDialogOptions = ExtensionUIDialogOptions & Pick<HookSelectorOptions, "disabledIndices">;
80
+ export interface RenderSessionContextOptions {
81
+ updateFooter?: boolean;
82
+ populateHistory?: boolean;
83
+ reuseSettledComponents?: boolean;
84
+ /** Tool calls whose existing live component remains the sole render owner across a rebuild. */
85
+ preservedLiveToolCallIds?: ReadonlySet<string>;
86
+ }
80
87
  export interface InteractiveModeContext {
81
88
  ui: TUI;
82
89
  chatContainer: TranscriptContainer;
@@ -284,11 +291,7 @@ export interface InteractiveModeContext {
284
291
  imageLinks?: readonly (string | undefined)[];
285
292
  reuseSettledComponent?: boolean;
286
293
  }): Component[];
287
- renderSessionContext(sessionContext: SessionContext, options?: {
288
- updateFooter?: boolean;
289
- populateHistory?: boolean;
290
- reuseSettledComponents?: boolean;
291
- }): void;
294
+ renderSessionContext(sessionContext: SessionContext, options?: RenderSessionContextOptions): void;
292
295
  renderInitialMessages(options?: {
293
296
  preserveExistingChat?: boolean;
294
297
  clearTerminalHistory?: boolean;
@@ -358,6 +361,7 @@ export interface InteractiveModeContext {
358
361
  handleResumeSession(sessionPath: string): Promise<void>;
359
362
  handleSessionDeleteCommand(): Promise<void>;
360
363
  showOAuthSelector(mode: "login" | "logout", providerId?: string): Promise<void>;
364
+ showSessionPinSelector(): Promise<void>;
361
365
  showResetUsageSelector(): Promise<void>;
362
366
  showProviderSetup(): Promise<void>;
363
367
  showHookConfirm(title: string, message: string): Promise<boolean>;
@@ -1,7 +1,7 @@
1
1
  import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
2
2
  import type { AssistantMessage, ImageContent, Message } from "@oh-my-pi/pi-ai";
3
3
  import { type Component } from "@oh-my-pi/pi-tui";
4
- import type { InteractiveModeContext } from "../../modes/types.js";
4
+ import type { InteractiveModeContext, RenderSessionContextOptions } from "../../modes/types.js";
5
5
  import type { SessionContext } from "../../session/session-context.js";
6
6
  interface RenderInitialMessagesOptions {
7
7
  preserveExistingChat?: boolean;
@@ -12,11 +12,6 @@ type AddMessageOptions = {
12
12
  imageLinks?: readonly (string | undefined)[];
13
13
  reuseSettledComponent?: boolean;
14
14
  };
15
- type RenderSessionContextOptions = {
16
- updateFooter?: boolean;
17
- populateHistory?: boolean;
18
- reuseSettledComponents?: boolean;
19
- };
20
15
  export declare class UiHelpers {
21
16
  #private;
22
17
  private ctx;
@@ -1,5 +1,5 @@
1
1
  import type { Agent, AgentMessage, AgentTool, StreamFn, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
2
- import type { Context, ImageContent, Message, MessageAttribution, Model, ServiceTierByFamily, SimpleStreamOptions, ToolChoice } from "@oh-my-pi/pi-ai";
2
+ import type { Context, ImageContent, Message, MessageAttribution, Model, OAuthAccountSummary, ServiceTierByFamily, SimpleStreamOptions, ToolChoice } from "@oh-my-pi/pi-ai";
3
3
  import type { postmortem } from "@oh-my-pi/pi-utils";
4
4
  import type { AdvisorConfig } from "../advisor/index.js";
5
5
  import type { AsyncJob, AsyncJobDeliveryState, AsyncJobManager } from "../async/index.js";
@@ -117,6 +117,8 @@ export interface AgentSessionConfig {
117
117
  memoryTaskDepth?: number;
118
118
  /** Creates built-in memory tools for the current backend. */
119
119
  createMemoryTools?: () => Promise<AgentTool[]>;
120
+ /** Creates the built-in `computer` tool for session-scoped runtime enablement (see {@link AgentSession.setComputerToolEnabled}). */
121
+ createComputerTool?: () => Promise<AgentTool | null>;
120
122
  /** Model registry for API key resolution and model discovery. */
121
123
  modelRegistry: ModelRegistry;
122
124
  /** Tool registry for LSP and settings. */
@@ -301,6 +303,11 @@ export interface SessionStats {
301
303
  cost: number;
302
304
  contextUsage?: ContextUsage;
303
305
  }
306
+ /** Stored OAuth accounts available to the current model provider. */
307
+ export interface SessionOAuthAccountList {
308
+ provider: string;
309
+ accounts: OAuthAccountSummary[];
310
+ }
304
311
  /** IDs for a newly created session and the session it replaced. */
305
312
  export interface FreshSessionResult {
306
313
  previousSessionId: string;
@@ -48,7 +48,7 @@ import { type PlanProposalHandler } from "../tools/resolve.js";
48
48
  import type { TodoPhase } from "../tools/todo.js";
49
49
  import type { VibeModeState } from "../vibe/state.js";
50
50
  import type { AgentSessionEventListener } from "./agent-session-events.js";
51
- import type { AgentSessionConfig, AgentSessionDisposeOptions, AsyncJobSnapshot, CommandMetadataChangedListener, ContextUsageBreakdown, FollowUpOptions, FreshSessionResult, HandoffResult, ModelCycleResult, Prewalk, PromptOptions, ResolvedRoleModel, RestoredQueuedMessage, RoleModelCycle, RoleModelCycleResult, SessionHandoffOptions, SessionStats, UsageFallbackConfirmation } from "./agent-session-types.js";
51
+ import type { AgentSessionConfig, AgentSessionDisposeOptions, AsyncJobSnapshot, CommandMetadataChangedListener, ContextUsageBreakdown, FollowUpOptions, FreshSessionResult, HandoffResult, ModelCycleResult, Prewalk, PromptOptions, ResolvedRoleModel, RestoredQueuedMessage, RoleModelCycle, RoleModelCycleResult, SessionHandoffOptions, SessionOAuthAccountList, SessionStats, UsageFallbackConfirmation } from "./agent-session-types.js";
52
52
  import type { ClientBridge } from "./client-bridge.js";
53
53
  import { type CustomMessage, type CustomMessagePayload } from "./messages.js";
54
54
  import { type AdvisorStats } from "./session-advisors.js";
@@ -272,6 +272,17 @@ export declare class AgentSession {
272
272
  setActiveToolsByName(toolNames: string[]): Promise<void>;
273
273
  /** Restores an exact top-level versus `xd://` tool partition. */
274
274
  setActiveToolPresentation(toolNames: string[], mountedToolNames: string[]): Promise<void>;
275
+ /**
276
+ * Session-scoped enable/disable for the settings-gated `computer` tool.
277
+ *
278
+ * Enabling builds the tool through {@link AgentSessionConfig.createComputerTool}
279
+ * on first use and activates it; disabling drops it from the active set while
280
+ * keeping the registry entry so repeated toggles reuse one desktop controller.
281
+ *
282
+ * @returns false when enabling was requested but this session cannot build the
283
+ * tool (e.g. restricted child sessions have no factory).
284
+ */
285
+ setComputerToolEnabled(enabled: boolean): Promise<boolean>;
275
286
  /** Cancels the local rollout-memory startup owned by this session. */
276
287
  cancelLocalMemoryStartup(): void;
277
288
  /** Starts a new local rollout-memory generation and cancels its predecessor. */
@@ -352,6 +363,7 @@ export declare class AgentSession {
352
363
  /** Current session ID */
353
364
  get sessionId(): string;
354
365
  getEvalSessionId(): string | null;
366
+ getEvalKernelOwnerId(): string;
355
367
  /** Current session display name, if set */
356
368
  get sessionName(): string | undefined;
357
369
  /** Scoped models for cycling (from --models flag) */
@@ -864,6 +876,13 @@ export declare class AgentSession {
864
876
  fetchUsageReports(signal?: AbortSignal): Promise<UsageReport[] | null>;
865
877
  /** Models whose live `/usage` reports map to a quantitative provider scope. */
866
878
  getUsageReportingModelSelectors(reports: readonly UsageReport[]): string[];
879
+ /** List stored OAuth accounts for the current model provider and mark this session's active account. */
880
+ listCurrentProviderOAuthAccounts(): Promise<SessionOAuthAccountList | undefined>;
881
+ /**
882
+ * Pin a stored OAuth account to the current model provider for this session.
883
+ * Returns false while streaming or when the credential is no longer available.
884
+ */
885
+ pinCurrentProviderOAuthAccount(credentialId: number): boolean;
867
886
  /**
868
887
  * Redeem one saved Codex rate-limit reset for a specific account, injecting
869
888
  * the provider base URL like {@link AgentSession.fetchUsageReports}. Powers
@@ -2,6 +2,6 @@
2
2
  * Re-exports from @oh-my-pi/pi-ai.
3
3
  * All credential storage types and the AuthStorage class now live in the ai package.
4
4
  */
5
- export type { ApiKeyCredential, AuthCredential, AuthCredentialEntry, AuthCredentialStore, AuthStorageData, AuthStorageOptions, CredentialOrigin, CredentialOriginKind, OAuthAccountIdentity, OAuthCredential, ResetCreditAccountStatus, ResetCreditRedeemOutcome, ResetCreditTarget, SerializedAuthStorage, StoredAuthCredential, } from "@oh-my-pi/pi-ai";
5
+ export type { ApiKeyCredential, AuthCredential, AuthCredentialEntry, AuthCredentialStore, AuthStorageData, AuthStorageOptions, CredentialOrigin, CredentialOriginKind, OAuthAccountIdentity, OAuthAccountSummary, OAuthCredential, ResetCreditAccountStatus, ResetCreditRedeemOutcome, ResetCreditTarget, SerializedAuthStorage, StoredAuthCredential, } from "@oh-my-pi/pi-ai";
6
6
  export { AuthStorage, REMOTE_REFRESH_SENTINEL, SqliteAuthCredentialStore } from "@oh-my-pi/pi-ai";
7
7
  export type { SnapshotResponse } from "@oh-my-pi/pi-ai/auth-broker/types";
@@ -38,6 +38,8 @@ export declare class EvalRunner {
38
38
  get isRunning(): boolean;
39
39
  /** Whether Python results are waiting for a safe persistence boundary. */
40
40
  get hasPendingMessages(): boolean;
41
+ /** Returns the stable owner shared by eval and session-owned tools. */
42
+ getKernelOwnerId(): string;
41
43
  /** Returns the eval session shared with the Python backend. */
42
44
  getSessionId(): string | null;
43
45
  /** Flushes deferred Python results into agent state and persistence. */
@@ -36,6 +36,8 @@ export declare function buildReplanTitleContext(messages: AgentMessage[]): strin
36
36
  export declare function didSessionMessagesChange(previousMessages: AgentMessage[], nextMessages: AgentMessage[]): boolean;
37
37
  /** Fallback type for extension-injected messages that omit a custom type. */
38
38
  export declare const DEFAULT_CUSTOM_MESSAGE_TYPE = "custom-message";
39
+ /** Custom message carrying a coding request delegated by the live voice model. */
40
+ export declare const LIVE_DELEGATION_MESSAGE_TYPE = "live-delegation";
39
41
  /** Content shape accepted for extension-injected messages. */
40
42
  export type CustomMessageContent = string | (TextContent | ImageContent)[];
41
43
  /** Public input accepted by `pi.sendMessage` and `AgentSession.sendCustomMessage`. */
@@ -38,6 +38,7 @@ interface SessionToolsOptions {
38
38
  autoApprove?: boolean;
39
39
  toolRegistry?: Map<string, AgentTool>;
40
40
  createVibeTools?: () => AgentTool[];
41
+ createComputerTool?: () => Promise<AgentTool | null>;
41
42
  builtInToolNames?: Iterable<string>;
42
43
  presentationPinnedToolNames?: ReadonlySet<string>;
43
44
  ensureWriteRegistered?: () => Promise<boolean>;
@@ -126,6 +127,20 @@ export declare class SessionTools {
126
127
  setActiveToolPresentation(toolNames: string[], mountedToolNames: string[]): Promise<void>;
127
128
  /** Replaces memory-backend tools while preserving unrelated selections. */
128
129
  replaceMemoryTools(tools: AgentTool[]): Promise<void>;
130
+ /**
131
+ * Session-scoped enable/disable for the settings-gated `computer` tool.
132
+ *
133
+ * `createTools` derives the built-in slate once at session start, so a runtime
134
+ * `computer.enabled` override alone never changes the active tools. Enabling
135
+ * builds the tool through the config factory on first use (later toggles reuse
136
+ * the registry entry, so only one desktop controller is ever registered) and
137
+ * activates it; disabling drops it from the active set while keeping the
138
+ * registry entry. Takes effect before the next model call.
139
+ *
140
+ * @returns false when enabling was requested but this session cannot build the
141
+ * tool (e.g. restricted child sessions have no factory).
142
+ */
143
+ setComputerToolEnabled(enabled: boolean): Promise<boolean>;
129
144
  /** Rebuilds the stable base prompt for the current tools and model. */
130
145
  refreshBaseSystemPrompt(): Promise<void>;
131
146
  /** Applies one-turn memory prompt injection before an agent run. */
@@ -213,6 +213,14 @@ export declare class OutputSink {
213
213
  */
214
214
  replace(text: string): void;
215
215
  dump(notice?: string): Promise<OutputSummary>;
216
+ /**
217
+ * Release the artifact spill descriptor on an exit path that skips
218
+ * {@link dump} — a thrown error or abort. Idempotent and safe in a
219
+ * `finally`: if {@link dump} already ran this is a no-op, otherwise it
220
+ * flushes the capped tail and closes the sink so the descriptor is not
221
+ * leaked until a later unrelated read hits `EMFILE` (issue #6463).
222
+ */
223
+ dispose(): Promise<void>;
216
224
  }
217
225
  /**
218
226
  * Format a truncation notice for tail-truncated output (bash, python, ssh).
@@ -0,0 +1,9 @@
1
+ import type { OAuthAccountSummary } from "../../session/auth-storage.js";
2
+ /** Stored OAuth account rendered and matched by `/session pin`. */
3
+ export interface SessionPinAccount extends OAuthAccountSummary {
4
+ label: string;
5
+ }
6
+ /** Add stable user-facing labels to provider account summaries. */
7
+ export declare function toSessionPinAccounts(accounts: readonly OAuthAccountSummary[]): SessionPinAccount[];
8
+ /** Match a `/session pin` selector by 1-based position or exact account identity. */
9
+ export declare function matchSessionPinAccounts(accounts: readonly SessionPinAccount[], selector: string): SessionPinAccount[];
@@ -4,5 +4,3 @@ export * from "./downloader.js";
4
4
  export * from "./models.js";
5
5
  export * from "./stt-controller.js";
6
6
  export * from "./submit-trigger.js";
7
- export * from "./transcriber.js";
8
- export * from "./wav.js";
@@ -15,8 +15,15 @@ interface Editor {
15
15
  submit(): void;
16
16
  deleteBeforeCursor(count: number): void;
17
17
  }
18
+ interface CaptureHandle {
19
+ stop(): void;
20
+ }
21
+ type CaptureFactory = (onAudio: (error: Error | null, samples: Float32Array) => void) => CaptureHandle;
22
+ /** Coordinates native microphone capture with incremental local transcription. */
18
23
  export declare class STTController {
19
24
  #private;
25
+ /** Creates a controller; tests may replace the hardware capture boundary. */
26
+ constructor(createCapture?: CaptureFactory);
20
27
  get state(): SttState;
21
28
  toggle(editor: Editor, options: ToggleOptions): Promise<void>;
22
29
  dispose(): void;
@@ -21,7 +21,7 @@ import { type AgentReviver } from "../registry/agent-lifecycle.js";
21
21
  import type { AgentSession } from "../session/agent-session.js";
22
22
  import type { ArtifactManager } from "../session/artifacts.js";
23
23
  import type { AuthStorage } from "../session/auth-storage.js";
24
- import type { ConfiguredThinkingLevel } from "../thinking.js";
24
+ import { type ConfiguredThinkingLevel, type TaskEffort } from "../thinking.js";
25
25
  import type { ContextFileEntry } from "../tools/index.js";
26
26
  import type { EventBus } from "../utils/event-bus.js";
27
27
  import type { WorkspaceTree } from "../workspace-tree.js";
@@ -81,6 +81,8 @@ export interface ExecutorOptions {
81
81
  */
82
82
  parentActiveModelPattern?: string;
83
83
  thinkingLevel?: ConfiguredThinkingLevel;
84
+ /** Caller-requested coarse effort (`lo`/`med`/`hi`); maps onto the resolved model's supported thinking range and wins over {@link thinkingLevel}. */
85
+ effort?: TaskEffort;
84
86
  /** Schema used to validate the final structured completion. */
85
87
  outputSchema?: unknown;
86
88
  /** Enforcement policy for {@link outputSchema}; defaults to legacy permissive behavior. */