@oh-my-pi/pi-ai 16.3.6 → 16.3.7

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 (226) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/types/api-registry.d.ts +1 -1
  3. package/dist/types/auth-broker/client.d.ts +2 -2
  4. package/dist/types/auth-broker/discover.d.ts +1 -1
  5. package/dist/types/auth-broker/index.d.ts +7 -7
  6. package/dist/types/auth-broker/refresher.d.ts +1 -1
  7. package/dist/types/auth-broker/remote-store.d.ts +6 -6
  8. package/dist/types/auth-broker/server.d.ts +1 -1
  9. package/dist/types/auth-broker/snapshot-cache.d.ts +1 -1
  10. package/dist/types/auth-broker/types.d.ts +2 -2
  11. package/dist/types/auth-gateway/index.d.ts +3 -3
  12. package/dist/types/auth-gateway/server.d.ts +3 -3
  13. package/dist/types/auth-gateway/types.d.ts +1 -1
  14. package/dist/types/auth-retry.d.ts +2 -2
  15. package/dist/types/auth-storage.d.ts +6 -6
  16. package/dist/types/dialect/anthropic.d.ts +1 -1
  17. package/dist/types/dialect/catalog.d.ts +1 -1
  18. package/dist/types/dialect/coercion.d.ts +1 -1
  19. package/dist/types/dialect/deepseek.d.ts +1 -1
  20. package/dist/types/dialect/demotion.d.ts +16 -14
  21. package/dist/types/dialect/examples.d.ts +1 -1
  22. package/dist/types/dialect/factory.d.ts +1 -1
  23. package/dist/types/dialect/gemini.d.ts +1 -1
  24. package/dist/types/dialect/gemma.d.ts +1 -1
  25. package/dist/types/dialect/glm.d.ts +1 -1
  26. package/dist/types/dialect/harmony.d.ts +1 -1
  27. package/dist/types/dialect/hermes.d.ts +1 -1
  28. package/dist/types/dialect/history.d.ts +2 -2
  29. package/dist/types/dialect/index.d.ts +11 -11
  30. package/dist/types/dialect/inventory.d.ts +1 -1
  31. package/dist/types/dialect/kimi.d.ts +1 -1
  32. package/dist/types/dialect/minimax.d.ts +1 -1
  33. package/dist/types/dialect/owned-stream.d.ts +2 -2
  34. package/dist/types/dialect/qwen3.d.ts +1 -1
  35. package/dist/types/dialect/rendering.d.ts +2 -2
  36. package/dist/types/dialect/thinking.d.ts +1 -1
  37. package/dist/types/dialect/types.d.ts +1 -1
  38. package/dist/types/dialect/xml.d.ts +1 -1
  39. package/dist/types/error/classes.d.ts +1 -1
  40. package/dist/types/error/finalize.d.ts +3 -3
  41. package/dist/types/error/flags.d.ts +1 -1
  42. package/dist/types/error/format.d.ts +1 -1
  43. package/dist/types/error/index.d.ts +13 -13
  44. package/dist/types/error/provider.d.ts +1 -1
  45. package/dist/types/error/rate-limit.d.ts +1 -1
  46. package/dist/types/index.d.ts +47 -47
  47. package/dist/types/provider-details.d.ts +1 -1
  48. package/dist/types/providers/amazon-bedrock.d.ts +1 -1
  49. package/dist/types/providers/anthropic-client.d.ts +3 -3
  50. package/dist/types/providers/anthropic-messages-server-schema.d.ts +1 -1
  51. package/dist/types/providers/anthropic-messages-server.d.ts +2 -2
  52. package/dist/types/providers/anthropic-wire.d.ts +1 -1
  53. package/dist/types/providers/anthropic.d.ts +3 -3
  54. package/dist/types/providers/aws-credentials.d.ts +2 -2
  55. package/dist/types/providers/azure-openai-responses.d.ts +2 -2
  56. package/dist/types/providers/cursor.d.ts +18 -3
  57. package/dist/types/providers/devin.d.ts +1 -1
  58. package/dist/types/providers/error-message.d.ts +1 -1
  59. package/dist/types/providers/github-copilot-headers.d.ts +1 -1
  60. package/dist/types/providers/gitlab-duo-workflow.d.ts +2 -2
  61. package/dist/types/providers/gitlab-duo.d.ts +2 -2
  62. package/dist/types/providers/google-auth.d.ts +1 -1
  63. package/dist/types/providers/google-gemini-cli.d.ts +6 -4
  64. package/dist/types/providers/google-interactions.d.ts +3 -3
  65. package/dist/types/providers/google-shared.d.ts +7 -5
  66. package/dist/types/providers/google-vertex.d.ts +2 -2
  67. package/dist/types/providers/google.d.ts +2 -2
  68. package/dist/types/providers/kimi.d.ts +3 -3
  69. package/dist/types/providers/mock.d.ts +2 -2
  70. package/dist/types/providers/ollama.d.ts +1 -1
  71. package/dist/types/providers/openai-anthropic-shim.d.ts +2 -2
  72. package/dist/types/providers/openai-chat-server-schema.d.ts +1 -1
  73. package/dist/types/providers/openai-chat-server.d.ts +2 -2
  74. package/dist/types/providers/openai-codex/request-transformer.d.ts +1 -1
  75. package/dist/types/providers/openai-codex/response-handler.d.ts +1 -1
  76. package/dist/types/providers/openai-codex-responses.d.ts +3 -3
  77. package/dist/types/providers/openai-completions.d.ts +3 -3
  78. package/dist/types/providers/openai-reasoning-fallback.d.ts +1 -1
  79. package/dist/types/providers/openai-responses-server-schema.d.ts +1 -1
  80. package/dist/types/providers/openai-responses-server.d.ts +2 -2
  81. package/dist/types/providers/openai-responses.d.ts +5 -5
  82. package/dist/types/providers/openai-shared.d.ts +10 -9
  83. package/dist/types/providers/pi-native-client.d.ts +1 -1
  84. package/dist/types/providers/pi-native-server.d.ts +2 -2
  85. package/dist/types/providers/register-builtins.d.ts +3 -3
  86. package/dist/types/providers/synthetic.d.ts +3 -3
  87. package/dist/types/providers/transform-messages.d.ts +1 -1
  88. package/dist/types/providers/vision-guard.d.ts +1 -1
  89. package/dist/types/registry/alibaba-coding-plan.d.ts +1 -1
  90. package/dist/types/registry/anthropic.d.ts +1 -1
  91. package/dist/types/registry/api-key-login.d.ts +1 -1
  92. package/dist/types/registry/api-key-validation.d.ts +1 -1
  93. package/dist/types/registry/baseten.d.ts +2 -2
  94. package/dist/types/registry/cerebras.d.ts +2 -2
  95. package/dist/types/registry/cloudflare-ai-gateway.d.ts +1 -1
  96. package/dist/types/registry/coreweave.d.ts +2 -2
  97. package/dist/types/registry/cursor.d.ts +1 -1
  98. package/dist/types/registry/deepseek.d.ts +1 -1
  99. package/dist/types/registry/devin.d.ts +1 -1
  100. package/dist/types/registry/firepass.d.ts +2 -2
  101. package/dist/types/registry/fireworks.d.ts +2 -2
  102. package/dist/types/registry/github-copilot.d.ts +1 -1
  103. package/dist/types/registry/gitlab-duo-workflow.d.ts +1 -1
  104. package/dist/types/registry/gitlab-duo.d.ts +1 -1
  105. package/dist/types/registry/google-antigravity.d.ts +1 -1
  106. package/dist/types/registry/google-gemini-cli.d.ts +1 -1
  107. package/dist/types/registry/huggingface.d.ts +2 -2
  108. package/dist/types/registry/index.d.ts +4 -4
  109. package/dist/types/registry/kagi.d.ts +1 -1
  110. package/dist/types/registry/kilo.d.ts +1 -1
  111. package/dist/types/registry/kimi-code.d.ts +1 -1
  112. package/dist/types/registry/litellm.d.ts +1 -1
  113. package/dist/types/registry/llama-cpp.d.ts +1 -1
  114. package/dist/types/registry/lm-studio.d.ts +1 -1
  115. package/dist/types/registry/minimax-code-cn.d.ts +1 -1
  116. package/dist/types/registry/minimax-code.d.ts +1 -1
  117. package/dist/types/registry/moonshot.d.ts +2 -2
  118. package/dist/types/registry/nanogpt.d.ts +2 -2
  119. package/dist/types/registry/nvidia.d.ts +1 -1
  120. package/dist/types/registry/oauth/anthropic.d.ts +3 -3
  121. package/dist/types/registry/oauth/callback-server.d.ts +1 -1
  122. package/dist/types/registry/oauth/cursor.d.ts +1 -1
  123. package/dist/types/registry/oauth/devin.d.ts +1 -1
  124. package/dist/types/registry/oauth/github-copilot.d.ts +2 -2
  125. package/dist/types/registry/oauth/gitlab-duo-workflow.d.ts +2 -2
  126. package/dist/types/registry/oauth/gitlab-duo.d.ts +1 -1
  127. package/dist/types/registry/oauth/google-antigravity.d.ts +1 -1
  128. package/dist/types/registry/oauth/google-gemini-cli.d.ts +1 -1
  129. package/dist/types/registry/oauth/google-oauth-shared.d.ts +2 -2
  130. package/dist/types/registry/oauth/index.d.ts +2 -2
  131. package/dist/types/registry/oauth/kimi.d.ts +1 -1
  132. package/dist/types/registry/oauth/minimax-code.d.ts +2 -2
  133. package/dist/types/registry/oauth/openai-codex.d.ts +1 -1
  134. package/dist/types/registry/oauth/opencode.d.ts +1 -1
  135. package/dist/types/registry/oauth/perplexity.d.ts +1 -1
  136. package/dist/types/registry/oauth/types.d.ts +2 -2
  137. package/dist/types/registry/oauth/wafer.d.ts +1 -1
  138. package/dist/types/registry/oauth/xai-oauth.d.ts +3 -3
  139. package/dist/types/registry/oauth/xiaomi.d.ts +1 -1
  140. package/dist/types/registry/ollama-cloud.d.ts +1 -1
  141. package/dist/types/registry/ollama.d.ts +1 -1
  142. package/dist/types/registry/openai-codex-device.d.ts +1 -1
  143. package/dist/types/registry/openai-codex.d.ts +1 -1
  144. package/dist/types/registry/opencode-go.d.ts +1 -1
  145. package/dist/types/registry/opencode-zen.d.ts +1 -1
  146. package/dist/types/registry/openrouter.d.ts +2 -2
  147. package/dist/types/registry/parallel.d.ts +1 -1
  148. package/dist/types/registry/perplexity.d.ts +2 -2
  149. package/dist/types/registry/qianfan.d.ts +2 -2
  150. package/dist/types/registry/qwen-portal.d.ts +1 -1
  151. package/dist/types/registry/registry.d.ts +69 -69
  152. package/dist/types/registry/sakana.d.ts +2 -2
  153. package/dist/types/registry/synthetic.d.ts +2 -2
  154. package/dist/types/registry/tavily.d.ts +1 -1
  155. package/dist/types/registry/together.d.ts +1 -1
  156. package/dist/types/registry/types.d.ts +1 -1
  157. package/dist/types/registry/umans.d.ts +2 -2
  158. package/dist/types/registry/venice.d.ts +2 -2
  159. package/dist/types/registry/vercel-ai-gateway.d.ts +1 -1
  160. package/dist/types/registry/vllm.d.ts +1 -1
  161. package/dist/types/registry/wafer-serverless.d.ts +1 -1
  162. package/dist/types/registry/xai-oauth.d.ts +1 -1
  163. package/dist/types/registry/xiaomi-token-plan-ams.d.ts +1 -1
  164. package/dist/types/registry/xiaomi-token-plan-cn.d.ts +1 -1
  165. package/dist/types/registry/xiaomi-token-plan-sgp.d.ts +1 -1
  166. package/dist/types/registry/xiaomi.d.ts +1 -1
  167. package/dist/types/registry/zai.d.ts +2 -2
  168. package/dist/types/registry/zenmux.d.ts +2 -2
  169. package/dist/types/registry/zhipu-coding-plan.d.ts +2 -2
  170. package/dist/types/stream.d.ts +6 -6
  171. package/dist/types/types.d.ts +24 -21
  172. package/dist/types/usage/claude.d.ts +1 -1
  173. package/dist/types/usage/gemini.d.ts +1 -1
  174. package/dist/types/usage/github-copilot.d.ts +1 -1
  175. package/dist/types/usage/google-antigravity.d.ts +1 -1
  176. package/dist/types/usage/kimi.d.ts +1 -1
  177. package/dist/types/usage/minimax-code.d.ts +1 -1
  178. package/dist/types/usage/ollama.d.ts +1 -1
  179. package/dist/types/usage/openai-codex-reset.d.ts +1 -1
  180. package/dist/types/usage/openai-codex.d.ts +1 -1
  181. package/dist/types/usage/opencode-go.d.ts +1 -1
  182. package/dist/types/usage/zai.d.ts +1 -1
  183. package/dist/types/usage.d.ts +1 -1
  184. package/dist/types/utils/block-symbols.d.ts +15 -0
  185. package/dist/types/utils/empty-completion-retry.d.ts +2 -2
  186. package/dist/types/utils/event-stream.d.ts +1 -1
  187. package/dist/types/utils/harmony-leak.d.ts +1 -1
  188. package/dist/types/utils/http-inspector.d.ts +19 -0
  189. package/dist/types/utils/leaked-thinking-stream.d.ts +1 -1
  190. package/dist/types/utils/openai-http.d.ts +3 -9
  191. package/dist/types/utils/provider-response.d.ts +1 -1
  192. package/dist/types/utils/proxy.d.ts +1 -1
  193. package/dist/types/utils/request-debug.d.ts +1 -1
  194. package/dist/types/utils/retry.d.ts +1 -1
  195. package/dist/types/utils/schema/equality.d.ts +1 -1
  196. package/dist/types/utils/schema/index.d.ts +15 -15
  197. package/dist/types/utils/schema/normalize.d.ts +2 -2
  198. package/dist/types/utils/schema/spill.d.ts +1 -1
  199. package/dist/types/utils/schema/wire.d.ts +1 -1
  200. package/dist/types/utils/sse-debug.d.ts +1 -1
  201. package/dist/types/utils/thinking-loop.d.ts +2 -2
  202. package/dist/types/utils/tool-call-loop-guard.d.ts +1 -1
  203. package/dist/types/utils/tool-choice.d.ts +1 -1
  204. package/dist/types/utils/validation.d.ts +1 -1
  205. package/dist/types/utils.d.ts +14 -2
  206. package/package.json +4 -4
  207. package/src/dialect/demotion.ts +18 -19
  208. package/src/error/rate-limit.ts +1 -1
  209. package/src/providers/azure-openai-responses.ts +3 -2
  210. package/src/providers/cursor.ts +36 -0
  211. package/src/providers/google-gemini-cli.ts +12 -3
  212. package/src/providers/google-shared.ts +3 -1
  213. package/src/providers/mock.ts +10 -3
  214. package/src/providers/openai-codex-responses.ts +47 -39
  215. package/src/providers/openai-completions.ts +48 -9
  216. package/src/providers/openai-responses.ts +37 -23
  217. package/src/providers/openai-shared.ts +145 -26
  218. package/src/providers/transform-messages.ts +63 -9
  219. package/src/registry/oauth/wafer.ts +1 -1
  220. package/src/stream.ts +6 -0
  221. package/src/types.ts +27 -3
  222. package/src/utils/block-symbols.ts +18 -0
  223. package/src/utils/http-inspector.ts +32 -4
  224. package/src/utils/openai-http.ts +6 -9
  225. package/src/utils/retry-after.ts +12 -1
  226. package/src/utils.ts +78 -0
@@ -24,8 +24,11 @@ import type { FetchImpl } from "../types";
24
24
  import type { CapturedHttpErrorResponse } from "./http-inspector";
25
25
 
26
26
  /**
27
- * Total attempts when the caller has no first-event deadline armed. The
28
- * removed SDK clients ran `maxRetries: 5`, i.e. 6 requests.
27
+ * Total attempts (initial + retries). Parity with the removed SDK clients'
28
+ * `maxRetries: 5`, i.e. 6 requests. Callers arming a first-event watchdog
29
+ * stay bounded: the watchdog aborts the request `signal`, which
30
+ * `fetchWithRetry` races on every attempt and every backoff sleep, so
31
+ * transient 408/429/5xx retries can never extend the caller's deadline.
29
32
  */
30
33
  const DEFAULT_MAX_ATTEMPTS = 6;
31
34
 
@@ -39,12 +42,6 @@ export interface OpenAIStreamRequestInit {
39
42
  body: unknown;
40
43
  signal: AbortSignal;
41
44
  fetch?: FetchImpl;
42
- /**
43
- * Total attempts (initial + retries). Defaults to {@link DEFAULT_MAX_ATTEMPTS}.
44
- * Pass `1` when a first-event watchdog is armed so retries cannot silently
45
- * extend the caller's deadline (mirrors the old `maxRetries: 0` hint).
46
- */
47
- maxAttempts?: number;
48
45
  /** Raw wire-frame observer (`onSseEvent` debug pipeline). */
49
46
  onSseEvent?: SseEventObserver;
50
47
  }
@@ -71,7 +68,7 @@ export async function postOpenAIStream<TEvent>(init: OpenAIStreamRequestInit): P
71
68
  body: JSON.stringify(init.body),
72
69
  signal: init.signal,
73
70
  fetch: init.fetch,
74
- maxAttempts: init.maxAttempts ?? DEFAULT_MAX_ATTEMPTS,
71
+ maxAttempts: DEFAULT_MAX_ATTEMPTS,
75
72
  // Bun's native fetch enforces a hard ~300s pre-response timeout (issue #2422).
76
73
  // Cold large-context streams legitimately exceed it; the caller's
77
74
  // `firstEventTimeoutMs`/`AbortSignal` already govern stuck requests.
@@ -19,11 +19,14 @@ export function formatErrorMessageWithRetryAfter(error: unknown, headers?: Heade
19
19
  export function getRetryAfterMsFromHeaders(headers: HeadersLike): number | undefined {
20
20
  if (!headers) return undefined;
21
21
 
22
+ const retryAfterMs = parseRetryAfterMsHeader(getHeaderValue(headers, "retry-after-ms"));
22
23
  const retryAfter = parseRetryAfterHeader(getHeaderValue(headers, "retry-after"));
23
24
  const resetMs = parseResetHeader(getHeaderValue(headers, "x-ratelimit-reset-ms"), "ms");
24
25
  const resetSeconds = parseResetHeader(getHeaderValue(headers, "x-ratelimit-reset"), "s");
25
26
 
26
- const candidates = [retryAfter, resetMs, resetSeconds].filter((value): value is number => value !== undefined);
27
+ const candidates = [retryAfterMs, retryAfter, resetMs, resetSeconds].filter(
28
+ (value): value is number => value !== undefined,
29
+ );
27
30
  if (candidates.length === 0) return undefined;
28
31
  return Math.max(...candidates);
29
32
  }
@@ -59,6 +62,14 @@ function getHeaderValue(headers: Headers | Record<string, string | undefined>, n
59
62
  return undefined;
60
63
  }
61
64
 
65
+ /** `retry-after-ms` (Anthropic-style): a plain millisecond delta. */
66
+ function parseRetryAfterMsHeader(value: string | undefined): number | undefined {
67
+ if (!value) return undefined;
68
+ const ms = Number(value.trim());
69
+ if (!Number.isFinite(ms) || ms <= 0) return undefined;
70
+ return Math.ceil(ms);
71
+ }
72
+
62
73
  function parseRetryAfterHeader(value: string | undefined): number | undefined {
63
74
  if (!value) return undefined;
64
75
  const trimmed = value.trim();
package/src/utils.ts CHANGED
@@ -3,6 +3,7 @@ import type { ResponseInput, ResponseInputItem } from "./providers/openai-respon
3
3
  import type { CacheRetention, OpenAIResponsesHistoryPayload, ProviderPayload } from "./types";
4
4
 
5
5
  type OpenAIResponsesReplayItem = ResponseInput[number];
6
+ const NON_WHITESPACE_RE = /\S/;
6
7
 
7
8
  export { isRecord } from "@oh-my-pi/pi-utils";
8
9
  export function normalizeSystemPrompts(systemPrompt: readonly string[] | string | undefined | null): string[] {
@@ -72,6 +73,83 @@ export function sanitizeOpenAIResponsesHistoryItemsForReplay(items: Array<Record
72
73
  });
73
74
  }
74
75
 
76
+ /**
77
+ * Sanitize assistant-native Responses history for replay.
78
+ *
79
+ * Returns `undefined` for hidden-empty turns that only contain reasoning and an
80
+ * empty assistant message, allowing callers to rebuild visible transcript
81
+ * history instead of replaying stale native state.
82
+ */
83
+ export function sanitizeOpenAIResponsesAssistantHistoryItemsForReplay(
84
+ items: Array<Record<string, unknown>>,
85
+ ): ResponseInput | undefined {
86
+ const sanitized = sanitizeOpenAIResponsesHistoryItemsForReplay(items);
87
+ let hasReplayableAssistantOutput = false;
88
+
89
+ for (const item of sanitized) {
90
+ if (item.type === "reasoning") continue;
91
+ if (item.type !== "message" || item.role !== "assistant") {
92
+ hasReplayableAssistantOutput = true;
93
+ break;
94
+ }
95
+ if (typeof item.content === "string") {
96
+ if (NON_WHITESPACE_RE.test(item.content)) {
97
+ hasReplayableAssistantOutput = true;
98
+ break;
99
+ }
100
+ continue;
101
+ }
102
+ for (const part of item.content) {
103
+ if (part.type === "output_text" && NON_WHITESPACE_RE.test(part.text)) {
104
+ hasReplayableAssistantOutput = true;
105
+ break;
106
+ }
107
+ if (part.type === "refusal" && NON_WHITESPACE_RE.test(part.refusal)) {
108
+ hasReplayableAssistantOutput = true;
109
+ break;
110
+ }
111
+ }
112
+ if (hasReplayableAssistantOutput) break;
113
+ }
114
+
115
+ return hasReplayableAssistantOutput ? sanitized : undefined;
116
+ }
117
+
118
+ /**
119
+ * Drop hidden-only fallback assistant replay after a native Responses snapshot is rejected.
120
+ */
121
+ export function sanitizeOpenAIResponsesAssistantFallbackItemsForReplay(items: ResponseInput): ResponseInput {
122
+ const sanitized: ResponseInput = [];
123
+
124
+ for (const item of items) {
125
+ if (item.type === "reasoning") continue;
126
+ if (item.type !== "message" || item.role !== "assistant") {
127
+ sanitized.push(item);
128
+ continue;
129
+ }
130
+
131
+ let hasVisibleText = false;
132
+ if (typeof item.content === "string") {
133
+ hasVisibleText = NON_WHITESPACE_RE.test(item.content);
134
+ } else {
135
+ for (const part of item.content) {
136
+ if (part.type === "output_text" && NON_WHITESPACE_RE.test(part.text)) {
137
+ hasVisibleText = true;
138
+ break;
139
+ }
140
+ if (part.type === "refusal" && NON_WHITESPACE_RE.test(part.refusal)) {
141
+ hasVisibleText = true;
142
+ break;
143
+ }
144
+ }
145
+ }
146
+
147
+ if (hasVisibleText) sanitized.push(item);
148
+ }
149
+
150
+ return sanitized;
151
+ }
152
+
75
153
  function sanitizeOpenAIResponsesHistoryItemForReplay(
76
154
  item: Record<string, unknown>,
77
155
  normalizedCallIds: Map<string, string>,