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

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 (112) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/cli.js +3686 -4013
  3. package/dist/types/config/settings-schema.d.ts +58 -0
  4. package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +3 -0
  5. package/dist/types/live/attestation.d.ts +2 -0
  6. package/dist/types/live/controller.d.ts +10 -2
  7. package/dist/types/live/protocol.d.ts +1 -1
  8. package/dist/types/live/transport.d.ts +6 -19
  9. package/dist/types/live/visualizer.d.ts +8 -11
  10. package/dist/types/modes/components/assistant-message.d.ts +1 -0
  11. package/dist/types/modes/components/custom-message.d.ts +1 -1
  12. package/dist/types/modes/components/message-frame.d.ts +8 -4
  13. package/dist/types/modes/components/session-account-selector.d.ts +11 -0
  14. package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
  15. package/dist/types/modes/interactive-mode.d.ts +1 -0
  16. package/dist/types/modes/types.d.ts +1 -0
  17. package/dist/types/session/agent-session-types.d.ts +8 -1
  18. package/dist/types/session/agent-session.d.ts +20 -1
  19. package/dist/types/session/auth-storage.d.ts +1 -1
  20. package/dist/types/session/eval-runner.d.ts +2 -0
  21. package/dist/types/session/messages.d.ts +2 -0
  22. package/dist/types/session/session-tools.d.ts +15 -0
  23. package/dist/types/session/streaming-output.d.ts +8 -0
  24. package/dist/types/slash-commands/helpers/session-pin.d.ts +9 -0
  25. package/dist/types/stt/index.d.ts +0 -2
  26. package/dist/types/stt/stt-controller.d.ts +7 -0
  27. package/dist/types/tiny/title-client.d.ts +10 -0
  28. package/dist/types/tools/builtin-names.d.ts +1 -1
  29. package/dist/types/tools/computer/protocol.d.ts +43 -0
  30. package/dist/types/tools/computer/supervisor.d.ts +32 -0
  31. package/dist/types/tools/computer/worker-entry.d.ts +1 -0
  32. package/dist/types/tools/computer/worker.d.ts +15 -0
  33. package/dist/types/tools/computer-renderer.d.ts +22 -0
  34. package/dist/types/tools/computer.d.ts +71 -0
  35. package/dist/types/tools/context.d.ts +2 -0
  36. package/dist/types/tools/default-renderer.d.ts +21 -0
  37. package/dist/types/tools/index.d.ts +2 -0
  38. package/dist/types/tts/streaming-player.d.ts +10 -43
  39. package/dist/types/utils/tools-manager.d.ts +1 -2
  40. package/package.json +12 -12
  41. package/src/cli/args.ts +1 -0
  42. package/src/cli/setup-cli.ts +2 -14
  43. package/src/cli.ts +8 -0
  44. package/src/config/model-registry.ts +6 -0
  45. package/src/config/settings-schema.ts +61 -0
  46. package/src/eval/executor-base.ts +1 -0
  47. package/src/eval/js/executor.ts +2 -0
  48. package/src/exec/bash-executor.ts +1 -0
  49. package/src/extensibility/extensions/wrapper.ts +68 -12
  50. package/src/extensibility/legacy-pi-coding-agent-shim.ts +7 -1
  51. package/src/live/attestation.ts +91 -0
  52. package/src/live/controller.ts +76 -23
  53. package/src/live/protocol.test.ts +3 -3
  54. package/src/live/protocol.ts +1 -1
  55. package/src/live/transport.ts +72 -140
  56. package/src/live/visualizer.ts +114 -134
  57. package/src/modes/components/assistant-message.ts +7 -2
  58. package/src/modes/components/custom-message.ts +4 -1
  59. package/src/modes/components/message-frame.ts +14 -8
  60. package/src/modes/components/session-account-selector.ts +62 -0
  61. package/src/modes/components/tool-execution.ts +17 -110
  62. package/src/modes/controllers/input-controller.ts +47 -39
  63. package/src/modes/controllers/live-command-controller.ts +82 -5
  64. package/src/modes/controllers/selector-controller.ts +62 -0
  65. package/src/modes/interactive-mode.ts +19 -0
  66. package/src/modes/types.ts +1 -0
  67. package/src/prompts/system/computer-safety.md +14 -0
  68. package/src/prompts/tools/computer.md +26 -0
  69. package/src/sdk.ts +5 -0
  70. package/src/session/agent-session-types.ts +9 -0
  71. package/src/session/agent-session.ts +56 -0
  72. package/src/session/auth-storage.ts +1 -0
  73. package/src/session/eval-runner.ts +5 -0
  74. package/src/session/messages.ts +3 -0
  75. package/src/session/session-tools.ts +37 -0
  76. package/src/session/streaming-output.ts +52 -5
  77. package/src/slash-commands/builtin-registry.ts +165 -9
  78. package/src/slash-commands/helpers/session-pin.ts +44 -0
  79. package/src/stt/downloader.ts +0 -2
  80. package/src/stt/index.ts +0 -2
  81. package/src/stt/stt-controller.ts +57 -146
  82. package/src/system-prompt.ts +4 -0
  83. package/src/tiny/title-client.ts +22 -0
  84. package/src/tools/bash-interactive.ts +90 -86
  85. package/src/tools/builtin-names.ts +1 -0
  86. package/src/tools/computer/protocol.ts +28 -0
  87. package/src/tools/computer/supervisor.ts +258 -0
  88. package/src/tools/computer/worker-entry.ts +25 -0
  89. package/src/tools/computer/worker.ts +135 -0
  90. package/src/tools/computer-renderer.ts +108 -0
  91. package/src/tools/computer.ts +433 -0
  92. package/src/tools/context.ts +2 -0
  93. package/src/tools/default-renderer.ts +139 -0
  94. package/src/tools/essential-tools.ts +1 -0
  95. package/src/tools/index.ts +5 -0
  96. package/src/tools/renderers.ts +2 -0
  97. package/src/tools/xdev.ts +54 -26
  98. package/src/tts/streaming-player.ts +81 -340
  99. package/src/utils/clipboard.ts +1 -30
  100. package/src/utils/mac-file-urls.applescript +37 -0
  101. package/src/utils/tool-choice.ts +14 -0
  102. package/src/utils/tools-manager.ts +1 -19
  103. package/dist/types/stt/recorder.d.ts +0 -30
  104. package/dist/types/stt/transcriber.d.ts +0 -14
  105. package/dist/types/stt/wav.d.ts +0 -29
  106. package/dist/types/tts/player.d.ts +0 -32
  107. package/src/live/audio-worklet.txt +0 -59
  108. package/src/live/browser-runtime.txt +0 -221
  109. package/src/stt/recorder.ts +0 -551
  110. package/src/stt/transcriber.ts +0 -60
  111. package/src/stt/wav.ts +0 -173
  112. package/src/tts/player.ts +0 -137
@@ -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;
@@ -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,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?: {
@@ -376,6 +376,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
376
376
  handleResumeSession(sessionPath: string): Promise<void>;
377
377
  handleSessionDeleteCommand(): Promise<void>;
378
378
  showOAuthSelector(mode: "login" | "logout", providerId?: string): Promise<void>;
379
+ showSessionPinSelector(): Promise<void>;
379
380
  showResetUsageSelector(): Promise<void>;
380
381
  showProviderSetup(): Promise<void>;
381
382
  showHookConfirm(title: string, message: string): Promise<boolean>;
@@ -358,6 +358,7 @@ export interface InteractiveModeContext {
358
358
  handleResumeSession(sessionPath: string): Promise<void>;
359
359
  handleSessionDeleteCommand(): Promise<void>;
360
360
  showOAuthSelector(mode: "login" | "logout", providerId?: string): Promise<void>;
361
+ showSessionPinSelector(): Promise<void>;
361
362
  showResetUsageSelector(): Promise<void>;
362
363
  showProviderSetup(): Promise<void>;
363
364
  showHookConfirm(title: string, message: string): Promise<boolean>;
@@ -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;
@@ -50,6 +50,16 @@ export declare class TinyTitleClient {
50
50
  #private;
51
51
  constructor(spawnWorker?: () => RefCountedWorkerHandle<TinyTitleWorkerInbound, TinyTitleWorkerOutbound>);
52
52
  onProgress(listener: (event: TinyTitleProgressEvent) => void): () => void;
53
+ /**
54
+ * Spawn the tiny-model worker ahead of first use without loading any model.
55
+ * Called from idle TUI startup so the first {@link generate} reuses a live,
56
+ * unref'd subprocess instead of paying subprocess-spawn latency on the submit
57
+ * hot path (issue #6462). No-ops for online / non-local keys and for models
58
+ * already marked failed. A no-op `ping` round-trips the transport to fault in
59
+ * the worker's module graph; no pending request is registered, so
60
+ * {@link #syncWorkerRef} leaves the worker unref'd and idle sessions still exit.
61
+ */
62
+ prewarm(modelKey: string): void;
53
63
  generate(modelKey: string, message: string, signal?: AbortSignal): Promise<string | null>;
54
64
  generate(modelKey: string, message: string, options?: TinyTitleGenerateOptions): Promise<string | null>;
55
65
  complete(modelKey: string, prompt: string, options?: {
@@ -1,4 +1,4 @@
1
- export declare const BUILTIN_TOOL_NAMES: readonly ["read", "bash", "edit", "ast_grep", "ast_edit", "ask", "debug", "eval", "github", "glob", "grep", "lsp", "inspect_image", "browser", "checkpoint", "rewind", "task", "hub", "todo", "web_search", "write", "memory_edit", "retain", "recall", "reflect", "learn", "manage_skill"];
1
+ export declare const BUILTIN_TOOL_NAMES: readonly ["read", "bash", "edit", "ast_grep", "ast_edit", "ask", "debug", "eval", "github", "glob", "grep", "lsp", "inspect_image", "browser", "computer", "checkpoint", "rewind", "task", "hub", "todo", "web_search", "write", "memory_edit", "retain", "recall", "reflect", "learn", "manage_skill"];
2
2
  export type BuiltinToolName = (typeof BUILTIN_TOOL_NAMES)[number];
3
3
  /** Hidden built-ins: constructible and `--tools`-addressable, but never part of the default active set. */
4
4
  export declare const HIDDEN_TOOL_NAMES: readonly ["yield", "goal"];
@@ -0,0 +1,43 @@
1
+ import type { DesktopAction, DesktopCapabilities, DesktopCapture, DesktopSessionOptions } from "@oh-my-pi/pi-natives";
2
+ export declare const COMPUTER_WORKER_ARG = "__omp_worker_computer";
3
+ export type ComputerWorkerInbound = {
4
+ type: "ping";
5
+ id: string;
6
+ } | {
7
+ type: "init";
8
+ options: DesktopSessionOptions;
9
+ } | {
10
+ type: "execute";
11
+ id: string;
12
+ actions: DesktopAction[];
13
+ } | {
14
+ type: "close";
15
+ };
16
+ export type ComputerWorkerOutbound = {
17
+ type: "pong";
18
+ id: string;
19
+ } | {
20
+ type: "ready";
21
+ capabilities: DesktopCapabilities;
22
+ } | {
23
+ type: "result";
24
+ id: string;
25
+ capture: DesktopCapture;
26
+ capabilities: DesktopCapabilities;
27
+ } | {
28
+ type: "error";
29
+ id?: string;
30
+ error: ComputerWorkerError;
31
+ } | {
32
+ type: "closed";
33
+ };
34
+ export interface ComputerWorkerError {
35
+ name: string;
36
+ message: string;
37
+ stack?: string;
38
+ }
39
+ export interface ComputerWorkerTransport {
40
+ send(message: ComputerWorkerOutbound, transfer?: Bun.Transferable[]): void;
41
+ onMessage(handler: (message: ComputerWorkerInbound) => void): () => void;
42
+ close(): void;
43
+ }
@@ -0,0 +1,32 @@
1
+ import type { DesktopAction, DesktopCapabilities, DesktopCapture, DesktopSessionOptions } from "@oh-my-pi/pi-natives";
2
+ import { type ComputerWorkerInbound, type ComputerWorkerOutbound } from "./protocol.js";
3
+ export interface ComputerController {
4
+ readonly capabilities: DesktopCapabilities | undefined;
5
+ execute(actions: DesktopAction[], signal?: AbortSignal): Promise<DesktopCapture>;
6
+ close(): Promise<void>;
7
+ }
8
+ export interface ComputerWorkerHandle {
9
+ send(message: ComputerWorkerInbound): void;
10
+ onMessage(handler: (message: ComputerWorkerOutbound) => void): () => void;
11
+ onError(handler: (error: Error) => void): () => void;
12
+ terminate(): Promise<void>;
13
+ }
14
+ export interface ComputerSupervisorTimeouts {
15
+ startMs: number;
16
+ closeMs: number;
17
+ }
18
+ export type ComputerWorkerFactory = () => ComputerWorkerHandle;
19
+ export declare function spawnComputerWorker(): ComputerWorkerHandle;
20
+ export declare class ComputerSupervisor implements ComputerController {
21
+ #private;
22
+ private readonly options;
23
+ private readonly createWorker;
24
+ private readonly timeouts;
25
+ constructor(options: DesktopSessionOptions, createWorker?: ComputerWorkerFactory, timeouts?: ComputerSupervisorTimeouts);
26
+ get capabilities(): DesktopCapabilities | undefined;
27
+ execute(actions: DesktopAction[], signal?: AbortSignal): Promise<DesktopCapture>;
28
+ close(): Promise<void>;
29
+ }
30
+ export declare function registerComputerController(ownerId: string | undefined, controller: ComputerController): () => void;
31
+ export declare function releaseComputerSessionsForOwner(ownerId: string | undefined): Promise<void>;
32
+ export declare function smokeTestComputerWorker(timeoutMs?: number): Promise<void>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ import { type DesktopAction, type DesktopCapture, DesktopSession, type DesktopSessionOptions } from "@oh-my-pi/pi-natives";
2
+ import type { ComputerWorkerTransport } from "./protocol.js";
3
+ export interface NativeDesktopSession {
4
+ readonly capabilities: DesktopSession["capabilities"];
5
+ capture(): Promise<DesktopCapture>;
6
+ execute(actions: DesktopAction[]): Promise<DesktopCapture>;
7
+ close(): Promise<void>;
8
+ }
9
+ export type NativeDesktopSessionFactory = (options: DesktopSessionOptions) => NativeDesktopSession;
10
+ export declare class ComputerWorkerCore {
11
+ #private;
12
+ private readonly transport;
13
+ private readonly createSession;
14
+ constructor(transport: ComputerWorkerTransport, createSession?: NativeDesktopSessionFactory);
15
+ }
@@ -0,0 +1,22 @@
1
+ import type { Component } from "@oh-my-pi/pi-tui";
2
+ import type { RenderResultOptions } from "../extensibility/custom-tools/types.js";
3
+ import type { Theme } from "../modes/theme/theme.js";
4
+ interface ComputerRenderArgs {
5
+ actions?: Array<{
6
+ type?: unknown;
7
+ }>;
8
+ }
9
+ interface ComputerRenderResult {
10
+ content: Array<{
11
+ type: string;
12
+ text?: string;
13
+ }>;
14
+ details?: unknown;
15
+ isError?: boolean;
16
+ }
17
+ export declare const computerToolRenderer: {
18
+ mergeCallAndResult: boolean;
19
+ renderCall(args: ComputerRenderArgs, _options: RenderResultOptions, theme: Theme): Component;
20
+ renderResult(result: ComputerRenderResult, options: RenderResultOptions, theme: Theme, args?: ComputerRenderArgs): Component;
21
+ };
22
+ export {};