@oh-my-pi/pi-ai 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.
package/CHANGELOG.md CHANGED
@@ -2,9 +2,28 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [17.1.1] - 2026-07-24
6
+
7
+ ### Added
8
+
9
+ - Added `setCodexAttestationProvider` API for injecting `x-oai-attestation` headers in ChatGPT-OAuth Codex requests
10
+ - Added OAuth account session pinning and active status tracking in storage
11
+ - Added OpenAI Responses native computer-use transport, including batched actions and exact `computer_call`/`computer_call_output` replay with pending/acknowledged safety checks and `image_url`/`file_id` output references. Models without native support receive the same action surface as a regular function tool; provider-specific tool-choice forcing is used where supported.
12
+ - Added `PI_CODEX_RESPONSES_LITE` to override the catalog-selected Codex Responses transport for diagnostics (`1`/`true` forces Lite; `0`/`false` forces the standard body).
13
+ - Added caller-owned `cachedContent` on `google-generative-ai` and `google-vertex` GenerateContent options: pass an opaque cache resource name through the shared builder (blank values rejected); no create/refresh/delete lifecycle and no guessed model/project/location validation; existing `cachedContentTokenCount` → `Usage.cacheRead` normalization is unchanged.
14
+ - Added Anthropic extra-usage reporting across `omp usage`, interactive `/usage`, and ACP `/usage`: the OAuth usage endpoint's authoritative `spend` payload (or legacy `extra_usage` fallback when absent) is normalized into a `Claude Extra Usage` USD row; capped accounts show limit/remaining/fractions and status, while uncapped spend exposes only its absolute used amount—rendered as `$… used` in CLI/TUI and `123.45 usd used` in ACP—without a fabricated cap, percentage, or status. ([#5575](https://github.com/can1357/oh-my-pi/issues/5575))
15
+ - Added process-scoped OAuth account pools for trusted auth-broker clients via `OMP_AUTH_BROKER_ACCOUNT_POOL_FILE`, consistently filtering snapshots, streaming updates, refreshes, and usage reports to selected OAuth identities while leaving API-key credentials and the shared encrypted snapshot cache unrestricted.
16
+ - Added opt-in Vercel AI Gateway automatic prompt caching for OpenAI Chat Completions while preserving `only` and `order` routing preferences.
17
+ - Added Vercel AI Gateway Responses cache anchors and cache lifetimes, emitted only with automatic caching.
18
+ - Added opt-in OpenAI GPT-5.6 explicit prompt-cache controls for Responses and Chat Completions. Existing requests remain implicit; the policy marks at most one existing stable-history block and is rejected locally on unsupported explicit routes.
19
+ - Forwarded `statefulResponses` through `streamSimple`, so diagnostic callers can explicitly disable OpenAI Responses `previous_response_id` chaining.
20
+ - Added native QwenCloud Token Plan API-key login, model discovery, and an optional interactive console-Cookie prompt for 5-hour and 7-day quota reporting ([#6151](https://github.com/can1357/oh-my-pi/issues/6151)).
21
+ - Added model-scoped usage health and same-provider reselection for native coding-plan credential pools, preserving OAuth/login-pool precedence, scoped broker blocks, sibling rotation state, and conservative unknown-account handling while excluding ordinary configured API keys ([#5018](https://github.com/can1357/oh-my-pi/issues/5018)).
22
+
5
23
  ### Fixed
6
24
 
7
25
  - Fixed stateful OpenAI Responses explicit cache breakpoints being restored onto edited historical messages, ensuring full replays recompute the latest stable cache boundary.
26
+ - Fixed ChatGPT Codex standard and Lite transports rejecting or hiding native computer-use payloads by unrolling the tool definition, forced choice, `computer_call`, and `computer_call_output` into ordinary function-tool forms.
8
27
 
9
28
  ## [17.1.0] - 2026-07-24
10
29
 
@@ -1,5 +1,5 @@
1
1
  import type { Effort } from "@oh-my-pi/pi-catalog/effort";
2
- import type { AssistantMessage, AssistantMessageEventStream, CacheRetention, Context, ServiceTier, TokenTaskBudget } from "../types.js";
2
+ import type { AssistantMessage, AssistantMessageEventStream, CacheRetention, Context, OpenAIResponseInclude, ServiceTier, TokenTaskBudget } from "../types.js";
3
3
  /**
4
4
  * Wire types for the omp auth-gateway.
5
5
  *
@@ -14,6 +14,8 @@ import type { AssistantMessage, AssistantMessageEventStream, CacheRetention, Con
14
14
  export declare const DEFAULT_AUTH_GATEWAY_BIND = "127.0.0.1:4000";
15
15
  export type AuthGatewayToolChoice = "auto" | "none" | "required" | {
16
16
  name: string;
17
+ } | {
18
+ type: "computer";
17
19
  };
18
20
  export interface AuthGatewayParsedRequestOptions {
19
21
  maxOutputTokens?: number;
@@ -39,6 +41,8 @@ export interface AuthGatewayParsedRequestOptions {
39
41
  toolChoice?: AuthGatewayToolChoice;
40
42
  /** OpenAI `parallel_tool_calls`. */
41
43
  parallelToolCalls?: boolean;
44
+ /** OpenAI Responses fields requested in the response payload. */
45
+ include?: OpenAIResponseInclude[];
42
46
  /** Effort-level reasoning request (OpenAI Responses / Chat `reasoning_effort`). */
43
47
  reasoning?: Effort;
44
48
  /** Force-disable reasoning (Anthropic `thinking: { type: "disabled" }`). */
@@ -573,6 +573,8 @@ export interface OAuthAccountSummary {
573
573
  /** Organization/workspace the credential is scoped to (Anthropic/ChatGPT multi-subscription). */
574
574
  orgId?: string;
575
575
  orgName?: string;
576
+ /** True when this account is the session-sticky OAuth credential requested by `listOAuthAccounts`. */
577
+ active: boolean;
576
578
  }
577
579
  export interface InvalidateCredentialMatchingOptions {
578
580
  signal?: AbortSignal;
@@ -957,8 +959,20 @@ export declare class AuthStorage {
957
959
  * order, WITHOUT refreshing any token. The array position (0-based) is the
958
960
  * selector accepted by {@link AuthStorage.getOAuthAccessAt}; a "pick the Nth
959
961
  * account" UI should render `position + 1`.
962
+ *
963
+ * When `sessionId` is supplied, the session-sticky OAuth credential is marked
964
+ * `active`. No account is active before that session has resolved or pinned a
965
+ * credential.
966
+ */
967
+ listOAuthAccounts(provider: string, sessionId?: string): OAuthAccountSummary[];
968
+ /**
969
+ * Pin one stored OAuth account as this session's preferred credential.
970
+ *
971
+ * The durable credential id keeps the pin stable across credential refreshes,
972
+ * storage reordering, and process restarts. Normal auth retry and usage-limit
973
+ * handling may still route around an unavailable account.
960
974
  */
961
- listOAuthAccounts(provider: string): OAuthAccountSummary[];
975
+ pinSessionOAuthAccount(provider: string, sessionId: string, credentialId: number): boolean;
962
976
  /**
963
977
  * Resolve every stored OAuth credential for `provider` independently.
964
978
  *
@@ -35,6 +35,10 @@ export interface InputItem {
35
35
  name?: string;
36
36
  output?: unknown;
37
37
  arguments?: unknown;
38
+ action?: unknown;
39
+ actions?: unknown;
40
+ pending_safety_checks?: unknown;
41
+ acknowledged_safety_checks?: unknown;
38
42
  /** `additional_tools` developer item payload (Responses Lite). */
39
43
  tools?: unknown;
40
44
  }
@@ -65,8 +69,10 @@ export interface RequestBody {
65
69
  }
66
70
  /**
67
71
  * Resolve whether a Codex request uses the Responses Lite transport: an
68
- * explicit option wins, otherwise the model's catalog flag (codex-rs
69
- * `model_info.use_responses_lite`) decides.
72
+ * explicit option wins, then the `PI_CODEX_RESPONSES_LITE` env override
73
+ * (`1`/`true` forces Lite, `0`/`false` forces the full Responses body),
74
+ * otherwise the model's catalog flag (codex-rs `model_info.use_responses_lite`)
75
+ * decides.
70
76
  */
71
77
  export declare function resolveCodexResponsesLite(model: Model<"openai-codex-responses">, requested: boolean | undefined): boolean;
72
78
  /**
@@ -7,7 +7,6 @@ export interface OpenAICodexResponsesOptions extends StreamOptions {
7
7
  /** `reasoning.context` replay scope; defaults to `all_turns` when unset. The `all_turns` value is gated to gpt-5.4+ Codex models — older ids reject it, so it is suppressed and `context` omitted. */
8
8
  reasoningContext?: CodexReasoningContext;
9
9
  textVerbosity?: "low" | "medium" | "high";
10
- include?: string[];
11
10
  codexMode?: boolean;
12
11
  toolChoice?: ToolChoice;
13
12
  preferWebsockets?: boolean;
@@ -64,6 +63,28 @@ export declare function createOpenAICodexCompactionRequestContext(options: {
64
63
  context: CodexCompactionContext | undefined;
65
64
  implementation: "responses" | "responses_compaction_v2" | "responses_compact";
66
65
  }): CodexCompactionRequestContext | undefined;
66
+ /**
67
+ * Host integration boundary for just-in-time `x-oai-attestation` header
68
+ * values (codex-rs `AttestationProvider`). Resolves to the full header value
69
+ * — an `{"v":1,"s":0,"t":"v1.…"}` envelope — or `undefined` when no
70
+ * attestation should be sent.
71
+ */
72
+ export type CodexAttestationProvider = () => Promise<string | undefined>;
73
+ /**
74
+ * Install the process-wide attestation hook consulted for upstream Codex
75
+ * requests (codex-rs stores its provider on `ModelClient` construction). The
76
+ * hook is only consulted for ChatGPT-OAuth credentials and runs just-in-time
77
+ * per request; WebSocket handshakes resolve once per connection because the
78
+ * header is connection-scoped there.
79
+ */
80
+ export declare function setCodexAttestationProvider(provider: CodexAttestationProvider | undefined): void;
81
+ /**
82
+ * Resolve the `x-oai-attestation` header value for one upstream request.
83
+ * Gated on ChatGPT-OAuth credentials (a Codex JWT carries `chatgpt_account_id`;
84
+ * codex-rs gates on `auth.is_chatgpt_auth()`). A throwing hook degrades to no
85
+ * header rather than failing the request.
86
+ */
87
+ export declare function getCodexAttestationHeader(accountId: string | undefined): Promise<string | undefined>;
67
88
  type CodexTransport = "sse" | "websocket";
68
89
  /** Shape of the Codex request sent on the latest provider turn. */
69
90
  export interface OpenAICodexTurnRequestDiagnostics {
@@ -10,7 +10,7 @@
10
10
  import type { EasyInputMessage, ResponseCreateParams, ResponseFunctionToolCall, ResponseInputContent, ResponseInputItem, ResponseOutputMessage, ResponseReasoningItem, Tool as ResponsesTool } from "./openai-responses-wire.js";
11
11
  declare const inputImageBlockSchema: import("arktype/internal/variants/object.ts").ObjectType<{
12
12
  type: "input_image";
13
- detail?: "auto" | "high" | "low" | undefined;
13
+ detail?: "auto" | "high" | "low" | "original" | undefined;
14
14
  image_url?: string | undefined;
15
15
  file_id?: string | undefined;
16
16
  }, {}>;
@@ -19,6 +19,7 @@ declare const inputFileBlockSchema: import("arktype/internal/variants/object.ts"
19
19
  file_id?: string | undefined;
20
20
  filename?: string | undefined;
21
21
  file_data?: string | undefined;
22
+ file_url?: string | undefined;
22
23
  }, {}>;
23
24
  declare const outputRefusalSchema: import("arktype/internal/variants/object.ts").ObjectType<{
24
25
  type: "refusal";
@@ -36,6 +37,117 @@ declare const customToolCallOutputItemSchema: import("arktype/internal/variants/
36
37
  call_id: string;
37
38
  output: string;
38
39
  }, {}>;
40
+ declare const computerCallItemSchema: import("arktype/internal/variants/object.ts").ObjectType<{
41
+ type: "computer_call";
42
+ id: string;
43
+ call_id: string;
44
+ action?: {
45
+ type: "click";
46
+ button: "back" | "forward" | "left" | "right" | "wheel";
47
+ x: number;
48
+ y: number;
49
+ keys?: string[] | null | undefined;
50
+ } | {
51
+ type: "double_click";
52
+ x: number;
53
+ y: number;
54
+ keys: string[] | null;
55
+ } | {
56
+ type: "drag";
57
+ path: {
58
+ x: number;
59
+ y: number;
60
+ }[];
61
+ keys?: string[] | null | undefined;
62
+ } | {
63
+ type: "keypress";
64
+ keys: string[];
65
+ } | {
66
+ type: "move";
67
+ x: number;
68
+ y: number;
69
+ keys?: string[] | null | undefined;
70
+ } | {
71
+ type: "screenshot";
72
+ } | {
73
+ type: "scroll";
74
+ x: number;
75
+ y: number;
76
+ scroll_x: number;
77
+ scroll_y: number;
78
+ keys?: string[] | null | undefined;
79
+ } | {
80
+ type: "type";
81
+ text: string;
82
+ } | {
83
+ type: "wait";
84
+ } | undefined;
85
+ actions?: ({
86
+ type: "click";
87
+ button: "back" | "forward" | "left" | "right" | "wheel";
88
+ x: number;
89
+ y: number;
90
+ keys?: string[] | null | undefined;
91
+ } | {
92
+ type: "double_click";
93
+ x: number;
94
+ y: number;
95
+ keys: string[] | null;
96
+ } | {
97
+ type: "drag";
98
+ path: {
99
+ x: number;
100
+ y: number;
101
+ }[];
102
+ keys?: string[] | null | undefined;
103
+ } | {
104
+ type: "keypress";
105
+ keys: string[];
106
+ } | {
107
+ type: "move";
108
+ x: number;
109
+ y: number;
110
+ keys?: string[] | null | undefined;
111
+ } | {
112
+ type: "screenshot";
113
+ } | {
114
+ type: "scroll";
115
+ x: number;
116
+ y: number;
117
+ scroll_x: number;
118
+ scroll_y: number;
119
+ keys?: string[] | null | undefined;
120
+ } | {
121
+ type: "type";
122
+ text: string;
123
+ } | {
124
+ type: "wait";
125
+ })[] | undefined;
126
+ pending_safety_checks: {
127
+ id: string;
128
+ code?: string | null | undefined;
129
+ message?: string | null | undefined;
130
+ }[];
131
+ status: "completed" | "in_progress" | "incomplete";
132
+ }, {}>;
133
+ declare const computerCallOutputItemSchema: import("arktype/internal/variants/object.ts").ObjectType<{
134
+ type: "computer_call_output";
135
+ id?: string | null | undefined;
136
+ call_id: string;
137
+ output: {
138
+ type: "computer_screenshot";
139
+ image_url: string;
140
+ } | {
141
+ type: "computer_screenshot";
142
+ file_id: string;
143
+ };
144
+ acknowledged_safety_checks?: {
145
+ id: string;
146
+ code?: string | null | undefined;
147
+ message?: string | null | undefined;
148
+ }[] | null | undefined;
149
+ status?: "completed" | "failed" | "in_progress" | "incomplete" | null | undefined;
150
+ }, {}>;
39
151
  /**
40
152
  * Direct mapping to standard types.
41
153
  */
@@ -50,7 +162,7 @@ export declare const inputItemSchema: import("arktype/internal/variants/object.t
50
162
  text: string;
51
163
  } | {
52
164
  type: "input_image";
53
- detail?: "auto" | "high" | "low" | undefined;
165
+ detail?: "auto" | "high" | "low" | "original" | undefined;
54
166
  image_url?: string | undefined;
55
167
  file_id?: string | undefined;
56
168
  } | {
@@ -58,6 +170,7 @@ export declare const inputItemSchema: import("arktype/internal/variants/object.t
58
170
  file_id?: string | undefined;
59
171
  filename?: string | undefined;
60
172
  file_data?: string | undefined;
173
+ file_url?: string | undefined;
61
174
  })[] | undefined;
62
175
  } | {
63
176
  type?: "message" | undefined;
@@ -70,7 +183,7 @@ export declare const inputItemSchema: import("arktype/internal/variants/object.t
70
183
  text: string;
71
184
  } | {
72
185
  type: "input_image";
73
- detail?: "auto" | "high" | "low" | undefined;
186
+ detail?: "auto" | "high" | "low" | "original" | undefined;
74
187
  image_url?: string | undefined;
75
188
  file_id?: string | undefined;
76
189
  } | {
@@ -78,6 +191,7 @@ export declare const inputItemSchema: import("arktype/internal/variants/object.t
78
191
  file_id?: string | undefined;
79
192
  filename?: string | undefined;
80
193
  file_data?: string | undefined;
194
+ file_url?: string | undefined;
81
195
  })[] | undefined;
82
196
  } | {
83
197
  type?: "message" | undefined;
@@ -135,6 +249,115 @@ export declare const inputItemSchema: import("arktype/internal/variants/object.t
135
249
  type: "custom_tool_call_output";
136
250
  call_id: string;
137
251
  output: string;
252
+ } | {
253
+ type: "computer_call";
254
+ id: string;
255
+ call_id: string;
256
+ action?: {
257
+ type: "click";
258
+ button: "back" | "forward" | "left" | "right" | "wheel";
259
+ x: number;
260
+ y: number;
261
+ keys?: string[] | null | undefined;
262
+ } | {
263
+ type: "double_click";
264
+ x: number;
265
+ y: number;
266
+ keys: string[] | null;
267
+ } | {
268
+ type: "drag";
269
+ path: {
270
+ x: number;
271
+ y: number;
272
+ }[];
273
+ keys?: string[] | null | undefined;
274
+ } | {
275
+ type: "keypress";
276
+ keys: string[];
277
+ } | {
278
+ type: "move";
279
+ x: number;
280
+ y: number;
281
+ keys?: string[] | null | undefined;
282
+ } | {
283
+ type: "screenshot";
284
+ } | {
285
+ type: "scroll";
286
+ x: number;
287
+ y: number;
288
+ scroll_x: number;
289
+ scroll_y: number;
290
+ keys?: string[] | null | undefined;
291
+ } | {
292
+ type: "type";
293
+ text: string;
294
+ } | {
295
+ type: "wait";
296
+ } | undefined;
297
+ actions?: ({
298
+ type: "click";
299
+ button: "back" | "forward" | "left" | "right" | "wheel";
300
+ x: number;
301
+ y: number;
302
+ keys?: string[] | null | undefined;
303
+ } | {
304
+ type: "double_click";
305
+ x: number;
306
+ y: number;
307
+ keys: string[] | null;
308
+ } | {
309
+ type: "drag";
310
+ path: {
311
+ x: number;
312
+ y: number;
313
+ }[];
314
+ keys?: string[] | null | undefined;
315
+ } | {
316
+ type: "keypress";
317
+ keys: string[];
318
+ } | {
319
+ type: "move";
320
+ x: number;
321
+ y: number;
322
+ keys?: string[] | null | undefined;
323
+ } | {
324
+ type: "screenshot";
325
+ } | {
326
+ type: "scroll";
327
+ x: number;
328
+ y: number;
329
+ scroll_x: number;
330
+ scroll_y: number;
331
+ keys?: string[] | null | undefined;
332
+ } | {
333
+ type: "type";
334
+ text: string;
335
+ } | {
336
+ type: "wait";
337
+ })[] | undefined;
338
+ pending_safety_checks: {
339
+ id: string;
340
+ code?: string | null | undefined;
341
+ message?: string | null | undefined;
342
+ }[];
343
+ status: "completed" | "in_progress" | "incomplete";
344
+ } | {
345
+ type: "computer_call_output";
346
+ id?: string | null | undefined;
347
+ call_id: string;
348
+ output: {
349
+ type: "computer_screenshot";
350
+ image_url: string;
351
+ } | {
352
+ type: "computer_screenshot";
353
+ file_id: string;
354
+ };
355
+ acknowledged_safety_checks?: {
356
+ id: string;
357
+ code?: string | null | undefined;
358
+ message?: string | null | undefined;
359
+ }[] | null | undefined;
360
+ status?: "completed" | "failed" | "in_progress" | "incomplete" | null | undefined;
138
361
  } | {
139
362
  type: string;
140
363
  }, {}>;
@@ -147,6 +370,8 @@ export type OpenAIResponsesFunctionCallOutputItem = ResponseInputItem.FunctionCa
147
370
  /** Inferred shape of the custom tool call input item (no canonical SDK alias). */
148
371
  export type OpenAIResponsesCustomToolCallItem = typeof customToolCallItemSchema.infer;
149
372
  export type OpenAIResponsesCustomToolCallOutputItem = typeof customToolCallOutputItemSchema.infer;
373
+ export type OpenAIResponsesComputerCallItem = typeof computerCallItemSchema.infer;
374
+ export type OpenAIResponsesComputerCallOutputItem = typeof computerCallOutputItemSchema.infer;
150
375
  export type OpenAIResponsesInputImageBlock = typeof inputImageBlockSchema.infer;
151
376
  export type OpenAIResponsesInputFileBlock = typeof inputFileBlockSchema.infer;
152
377
  export type OpenAIResponsesOutputRefusalBlock = typeof outputRefusalSchema.infer;
@@ -166,7 +391,7 @@ export declare const toolChoiceSchema: import("arktype").BaseType<"auto" | "none
166
391
  type: "custom";
167
392
  name: string;
168
393
  } | {
169
- type: "code_interpreter" | "computer_use_preview" | "file_search" | "image_generation" | "mcp" | "web_search_preview";
394
+ type: "code_interpreter" | "computer" | "computer_use_preview" | "file_search" | "image_generation" | "mcp" | "web_search_preview";
170
395
  } | {
171
396
  type: "allowed_tools";
172
397
  mode: "auto" | "required";
@@ -193,7 +418,7 @@ export declare const openaiResponsesRequestSchema: import("arktype/internal/vari
193
418
  text: string;
194
419
  } | {
195
420
  type: "input_image";
196
- detail?: "auto" | "high" | "low" | undefined;
421
+ detail?: "auto" | "high" | "low" | "original" | undefined;
197
422
  image_url?: string | undefined;
198
423
  file_id?: string | undefined;
199
424
  } | {
@@ -201,6 +426,7 @@ export declare const openaiResponsesRequestSchema: import("arktype/internal/vari
201
426
  file_id?: string | undefined;
202
427
  filename?: string | undefined;
203
428
  file_data?: string | undefined;
429
+ file_url?: string | undefined;
204
430
  })[] | undefined;
205
431
  } | {
206
432
  type?: "message" | undefined;
@@ -213,7 +439,7 @@ export declare const openaiResponsesRequestSchema: import("arktype/internal/vari
213
439
  text: string;
214
440
  } | {
215
441
  type: "input_image";
216
- detail?: "auto" | "high" | "low" | undefined;
442
+ detail?: "auto" | "high" | "low" | "original" | undefined;
217
443
  image_url?: string | undefined;
218
444
  file_id?: string | undefined;
219
445
  } | {
@@ -221,6 +447,7 @@ export declare const openaiResponsesRequestSchema: import("arktype/internal/vari
221
447
  file_id?: string | undefined;
222
448
  filename?: string | undefined;
223
449
  file_data?: string | undefined;
450
+ file_url?: string | undefined;
224
451
  })[] | undefined;
225
452
  } | {
226
453
  type?: "message" | undefined;
@@ -278,6 +505,115 @@ export declare const openaiResponsesRequestSchema: import("arktype/internal/vari
278
505
  type: "custom_tool_call_output";
279
506
  call_id: string;
280
507
  output: string;
508
+ } | {
509
+ type: "computer_call";
510
+ id: string;
511
+ call_id: string;
512
+ action?: {
513
+ type: "click";
514
+ button: "back" | "forward" | "left" | "right" | "wheel";
515
+ x: number;
516
+ y: number;
517
+ keys?: string[] | null | undefined;
518
+ } | {
519
+ type: "double_click";
520
+ x: number;
521
+ y: number;
522
+ keys: string[] | null;
523
+ } | {
524
+ type: "drag";
525
+ path: {
526
+ x: number;
527
+ y: number;
528
+ }[];
529
+ keys?: string[] | null | undefined;
530
+ } | {
531
+ type: "keypress";
532
+ keys: string[];
533
+ } | {
534
+ type: "move";
535
+ x: number;
536
+ y: number;
537
+ keys?: string[] | null | undefined;
538
+ } | {
539
+ type: "screenshot";
540
+ } | {
541
+ type: "scroll";
542
+ x: number;
543
+ y: number;
544
+ scroll_x: number;
545
+ scroll_y: number;
546
+ keys?: string[] | null | undefined;
547
+ } | {
548
+ type: "type";
549
+ text: string;
550
+ } | {
551
+ type: "wait";
552
+ } | undefined;
553
+ actions?: ({
554
+ type: "click";
555
+ button: "back" | "forward" | "left" | "right" | "wheel";
556
+ x: number;
557
+ y: number;
558
+ keys?: string[] | null | undefined;
559
+ } | {
560
+ type: "double_click";
561
+ x: number;
562
+ y: number;
563
+ keys: string[] | null;
564
+ } | {
565
+ type: "drag";
566
+ path: {
567
+ x: number;
568
+ y: number;
569
+ }[];
570
+ keys?: string[] | null | undefined;
571
+ } | {
572
+ type: "keypress";
573
+ keys: string[];
574
+ } | {
575
+ type: "move";
576
+ x: number;
577
+ y: number;
578
+ keys?: string[] | null | undefined;
579
+ } | {
580
+ type: "screenshot";
581
+ } | {
582
+ type: "scroll";
583
+ x: number;
584
+ y: number;
585
+ scroll_x: number;
586
+ scroll_y: number;
587
+ keys?: string[] | null | undefined;
588
+ } | {
589
+ type: "type";
590
+ text: string;
591
+ } | {
592
+ type: "wait";
593
+ })[] | undefined;
594
+ pending_safety_checks: {
595
+ id: string;
596
+ code?: string | null | undefined;
597
+ message?: string | null | undefined;
598
+ }[];
599
+ status: "completed" | "in_progress" | "incomplete";
600
+ } | {
601
+ type: "computer_call_output";
602
+ id?: string | null | undefined;
603
+ call_id: string;
604
+ output: {
605
+ type: "computer_screenshot";
606
+ image_url: string;
607
+ } | {
608
+ type: "computer_screenshot";
609
+ file_id: string;
610
+ };
611
+ acknowledged_safety_checks?: {
612
+ id: string;
613
+ code?: string | null | undefined;
614
+ message?: string | null | undefined;
615
+ }[] | null | undefined;
616
+ status?: "completed" | "failed" | "in_progress" | "incomplete" | null | undefined;
281
617
  } | {
282
618
  type: string;
283
619
  })[] | undefined;
@@ -290,6 +626,8 @@ export declare const openaiResponsesRequestSchema: import("arktype/internal/vari
290
626
  [x: string]: unknown;
291
627
  } | undefined;
292
628
  strict?: boolean | undefined;
629
+ } | {
630
+ type: "computer";
293
631
  } | {
294
632
  type: string;
295
633
  })[] | undefined;
@@ -300,7 +638,7 @@ export declare const openaiResponsesRequestSchema: import("arktype/internal/vari
300
638
  type: "custom";
301
639
  name: string;
302
640
  } | {
303
- type: "code_interpreter" | "computer_use_preview" | "file_search" | "image_generation" | "mcp" | "web_search_preview";
641
+ type: "code_interpreter" | "computer" | "computer_use_preview" | "file_search" | "image_generation" | "mcp" | "web_search_preview";
304
642
  } | {
305
643
  type: "allowed_tools";
306
644
  mode: "auto" | "required";
@@ -328,7 +666,7 @@ export declare const openaiResponsesRequestSchema: import("arktype/internal/vari
328
666
  presence_penalty?: number | undefined;
329
667
  frequency_penalty?: number | undefined;
330
668
  background?: unknown;
331
- include?: unknown;
669
+ include?: string[] | null | undefined;
332
670
  prompt?: unknown;
333
671
  safety_identifier?: unknown;
334
672
  text?: unknown;
@@ -1,13 +1,13 @@
1
1
  import type { Effort } from "@oh-my-pi/pi-catalog/effort";
2
2
  import type { OpenAICompat, OpenAIReasoningDisableMode, OpenAIStreamMarkupHealingPattern, OpenRouterRouting, ResolvedOpenAICompat, ResolvedOpenAIResponsesCompat, ResolvedOpenAISharedCompat, VercelGatewayRouting } from "@oh-my-pi/pi-catalog/types";
3
- import { type Api, type AssistantMessage, type CacheRetention, type Context, type ImageContent, type Message, type MessageAttribution, type Model, type ServiceTier, type StopReason, type StreamOptions, type TextContent, type TextSignatureV1, type ThinkingContent, type Tool, type ToolCall, type ToolResultMessage, type Usage } from "../types.js";
3
+ import { type Api, type AssistantMessage, type CacheRetention, type ComputerToolCallMetadata, type Context, type ImageContent, type Message, type MessageAttribution, type Model, type ServiceTier, type StopReason, type StreamOptions, type TextContent, type TextSignatureV1, type ThinkingContent, type Tool, type ToolCall, type ToolResultMessage, type Usage } from "../types.js";
4
4
  export type { OpenAIPromptCacheOptions } from "../types.js";
5
5
  import { kStreamingLastParseLen, kStreamingPartialJson } from "../utils/block-symbols.js";
6
6
  import type { AssistantMessageEventStream } from "../utils/event-stream.js";
7
7
  import type { CapturedHttpErrorResponse } from "../utils/http-inspector.js";
8
8
  import type { ChatCompletionCreateParamsStreaming } from "./openai-chat-wire.js";
9
9
  import type { InputItem } from "./openai-codex/request-transformer.js";
10
- import type { ResponseContentPartAddedEvent, ResponseCreateParamsStreaming, ResponseInput, ResponseInputContent, ResponseInputItem, ResponseOutputItem, ResponseOutputMessage, ResponseReasoningItem, ResponseStatus, ResponseStreamEvent } from "./openai-responses-wire.js";
10
+ import type { ResponseComputerToolCall, ResponseContentPartAddedEvent, ResponseCreateParamsStreaming, ResponseInput, ResponseInputContent, ResponseInputItem, ResponseOutputItem, ResponseOutputMessage, ResponseReasoningItem, ResponseStatus, ResponseStreamEvent } from "./openai-responses-wire.js";
11
11
  /**
12
12
  * Keyless-provider sentinel. Custom providers configured with `auth: none`
13
13
  * (models.yml) have no credential, so the coding-agent resolves their API key
@@ -356,6 +356,8 @@ export declare function normalizeResponsesToolCallIdForTransform(id: string, mod
356
356
  export declare function collectKnownCallIds(messages: ResponseInput): Set<string>;
357
357
  /** Scan replay items for call_ids that were originally custom tool calls. */
358
358
  export declare function collectCustomCallIds(messages: ResponseInput): Set<string>;
359
+ /** Scan replay items for call_ids that were originally native computer calls. */
360
+ export declare function collectComputerCallIds(messages: ResponseInput): Set<string>;
359
361
  /**
360
362
  * Convert orphan `function_call_output` / `custom_tool_call_output` items —
361
363
  * those whose `call_id` has no matching preceding `function_call` /
@@ -413,9 +415,9 @@ export interface BuildResponsesInputOptions<TApi extends Api> {
413
415
  preserveAssistantMessageIds?: boolean;
414
416
  }
415
417
  export declare function buildResponsesInput<TApi extends Api>(options: BuildResponsesInputOptions<TApi>): ResponseInput;
416
- export declare function convertResponsesAssistantMessage<TApi extends Api>(assistantMsg: AssistantMessage, model: Model<TApi>, msgIndex: number, knownCallIds: Set<string>, includeThinkingSignatures?: boolean, customCallIds?: Set<string>, preserveMessageIds?: boolean, supportsCustomToolCalls?: boolean, customToolWireNameMap?: ReadonlyMap<string, string>): ResponseInput;
418
+ export declare function convertResponsesAssistantMessage<TApi extends Api>(assistantMsg: AssistantMessage, model: Model<TApi>, msgIndex: number, knownCallIds: Set<string>, includeThinkingSignatures?: boolean, customCallIds?: Set<string>, preserveMessageIds?: boolean, supportsCustomToolCalls?: boolean, customToolWireNameMap?: ReadonlyMap<string, string>, computerCallIds?: Set<string>): ResponseInput;
417
419
  /** Appends one tool result while keeping consecutive outputs ahead of its synthetic image messages. */
418
- export declare function appendResponsesToolResultMessages<TApi extends Api>(messages: ResponseInput, toolResult: ToolResultMessage, model: Model<TApi>, strictResponsesPairing: boolean, supportsImageDetailOriginal: boolean, knownCallIds: ReadonlySet<string>, customCallIds?: ReadonlySet<string>, supportsCustomToolCalls?: boolean): void;
420
+ export declare function appendResponsesToolResultMessages<TApi extends Api>(messages: ResponseInput, toolResult: ToolResultMessage, model: Model<TApi>, strictResponsesPairing: boolean, supportsImageDetailOriginal: boolean, knownCallIds: ReadonlySet<string>, customCallIds?: ReadonlySet<string>, supportsCustomToolCalls?: boolean, computerCallIds?: ReadonlySet<string>): void;
419
421
  /**
420
422
  * Per-block accumulation helpers shared by the two Responses decode loops —
421
423
  * {@link processResponsesStream} (generic Responses) and the Codex stream
@@ -495,8 +497,10 @@ export interface ProcessResponsesStreamOptions {
495
497
  */
496
498
  requestServiceTier?: ServiceTier;
497
499
  }
500
+ export declare function computerCallMetadata(item: ResponseComputerToolCall): ComputerToolCallMetadata;
498
501
  export declare function processResponsesStream<TApi extends Api>(openaiStream: AsyncIterable<ResponseStreamEvent>, output: AssistantMessage, stream: AssistantMessageEventStream, model: Model<TApi>, options?: ProcessResponsesStreamOptions): Promise<void>;
499
502
  export declare function mapOpenAIResponsesStopReason(status: ResponseStatus | undefined): StopReason;
503
+ export declare function hasExecutableIncompleteResponsesToolCalls(output: AssistantMessage): boolean;
500
504
  /**
501
505
  * Finalize any streamed toolCall block whose `output_item.done` never arrived
502
506
  * (lossy proxy, or a terminal event that raced the per-item done): parse the