@oh-my-pi/pi-ai 16.3.5 → 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 (236) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/types/api-registry.d.ts +1 -1
  3. package/dist/types/auth-broker/client.d.ts +4 -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 +11 -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 +14 -2
  11. package/dist/types/auth-broker/wire-schemas.d.ts +46 -0
  12. package/dist/types/auth-gateway/index.d.ts +3 -3
  13. package/dist/types/auth-gateway/server.d.ts +3 -3
  14. package/dist/types/auth-gateway/types.d.ts +1 -1
  15. package/dist/types/auth-retry.d.ts +2 -2
  16. package/dist/types/auth-storage.d.ts +44 -6
  17. package/dist/types/dialect/anthropic.d.ts +1 -1
  18. package/dist/types/dialect/catalog.d.ts +1 -1
  19. package/dist/types/dialect/coercion.d.ts +1 -1
  20. package/dist/types/dialect/deepseek.d.ts +1 -1
  21. package/dist/types/dialect/demotion.d.ts +16 -14
  22. package/dist/types/dialect/examples.d.ts +1 -1
  23. package/dist/types/dialect/factory.d.ts +1 -1
  24. package/dist/types/dialect/gemini.d.ts +1 -1
  25. package/dist/types/dialect/gemma.d.ts +1 -1
  26. package/dist/types/dialect/glm.d.ts +1 -1
  27. package/dist/types/dialect/harmony.d.ts +1 -1
  28. package/dist/types/dialect/hermes.d.ts +1 -1
  29. package/dist/types/dialect/history.d.ts +2 -2
  30. package/dist/types/dialect/index.d.ts +11 -11
  31. package/dist/types/dialect/inventory.d.ts +1 -1
  32. package/dist/types/dialect/kimi.d.ts +1 -1
  33. package/dist/types/dialect/minimax.d.ts +1 -1
  34. package/dist/types/dialect/owned-stream.d.ts +2 -2
  35. package/dist/types/dialect/qwen3.d.ts +1 -1
  36. package/dist/types/dialect/rendering.d.ts +2 -2
  37. package/dist/types/dialect/thinking.d.ts +1 -1
  38. package/dist/types/dialect/types.d.ts +1 -1
  39. package/dist/types/dialect/xml.d.ts +1 -1
  40. package/dist/types/error/classes.d.ts +1 -1
  41. package/dist/types/error/finalize.d.ts +3 -3
  42. package/dist/types/error/flags.d.ts +1 -1
  43. package/dist/types/error/format.d.ts +1 -1
  44. package/dist/types/error/index.d.ts +13 -13
  45. package/dist/types/error/provider.d.ts +1 -1
  46. package/dist/types/error/rate-limit.d.ts +1 -1
  47. package/dist/types/index.d.ts +47 -47
  48. package/dist/types/provider-details.d.ts +1 -1
  49. package/dist/types/providers/amazon-bedrock.d.ts +1 -1
  50. package/dist/types/providers/anthropic-client.d.ts +3 -3
  51. package/dist/types/providers/anthropic-messages-server-schema.d.ts +1 -1
  52. package/dist/types/providers/anthropic-messages-server.d.ts +2 -2
  53. package/dist/types/providers/anthropic-wire.d.ts +1 -1
  54. package/dist/types/providers/anthropic.d.ts +3 -3
  55. package/dist/types/providers/aws-credentials.d.ts +2 -2
  56. package/dist/types/providers/azure-openai-responses.d.ts +2 -2
  57. package/dist/types/providers/cursor.d.ts +18 -3
  58. package/dist/types/providers/devin.d.ts +1 -1
  59. package/dist/types/providers/error-message.d.ts +1 -1
  60. package/dist/types/providers/github-copilot-headers.d.ts +1 -1
  61. package/dist/types/providers/gitlab-duo-workflow.d.ts +2 -2
  62. package/dist/types/providers/gitlab-duo.d.ts +2 -2
  63. package/dist/types/providers/google-auth.d.ts +1 -1
  64. package/dist/types/providers/google-gemini-cli.d.ts +6 -4
  65. package/dist/types/providers/google-interactions.d.ts +3 -3
  66. package/dist/types/providers/google-shared.d.ts +7 -5
  67. package/dist/types/providers/google-vertex.d.ts +2 -2
  68. package/dist/types/providers/google.d.ts +2 -2
  69. package/dist/types/providers/kimi.d.ts +3 -3
  70. package/dist/types/providers/mock.d.ts +2 -2
  71. package/dist/types/providers/ollama.d.ts +1 -1
  72. package/dist/types/providers/openai-anthropic-shim.d.ts +2 -2
  73. package/dist/types/providers/openai-chat-server-schema.d.ts +1 -1
  74. package/dist/types/providers/openai-chat-server.d.ts +2 -2
  75. package/dist/types/providers/openai-codex/request-transformer.d.ts +1 -1
  76. package/dist/types/providers/openai-codex/response-handler.d.ts +1 -1
  77. package/dist/types/providers/openai-codex-responses.d.ts +3 -3
  78. package/dist/types/providers/openai-completions.d.ts +3 -3
  79. package/dist/types/providers/openai-reasoning-fallback.d.ts +1 -1
  80. package/dist/types/providers/openai-responses-server-schema.d.ts +1 -1
  81. package/dist/types/providers/openai-responses-server.d.ts +2 -2
  82. package/dist/types/providers/openai-responses.d.ts +5 -5
  83. package/dist/types/providers/openai-shared.d.ts +10 -9
  84. package/dist/types/providers/pi-native-client.d.ts +1 -1
  85. package/dist/types/providers/pi-native-server.d.ts +2 -2
  86. package/dist/types/providers/register-builtins.d.ts +3 -3
  87. package/dist/types/providers/synthetic.d.ts +3 -3
  88. package/dist/types/providers/transform-messages.d.ts +1 -1
  89. package/dist/types/providers/vision-guard.d.ts +1 -1
  90. package/dist/types/registry/alibaba-coding-plan.d.ts +1 -1
  91. package/dist/types/registry/anthropic.d.ts +1 -1
  92. package/dist/types/registry/api-key-login.d.ts +1 -1
  93. package/dist/types/registry/api-key-validation.d.ts +1 -1
  94. package/dist/types/registry/baseten.d.ts +2 -2
  95. package/dist/types/registry/cerebras.d.ts +2 -2
  96. package/dist/types/registry/cloudflare-ai-gateway.d.ts +1 -1
  97. package/dist/types/registry/coreweave.d.ts +2 -2
  98. package/dist/types/registry/cursor.d.ts +1 -1
  99. package/dist/types/registry/deepseek.d.ts +1 -1
  100. package/dist/types/registry/devin.d.ts +1 -1
  101. package/dist/types/registry/firepass.d.ts +2 -2
  102. package/dist/types/registry/fireworks.d.ts +2 -2
  103. package/dist/types/registry/github-copilot.d.ts +1 -1
  104. package/dist/types/registry/gitlab-duo-workflow.d.ts +1 -1
  105. package/dist/types/registry/gitlab-duo.d.ts +1 -1
  106. package/dist/types/registry/google-antigravity.d.ts +1 -1
  107. package/dist/types/registry/google-gemini-cli.d.ts +1 -1
  108. package/dist/types/registry/huggingface.d.ts +2 -2
  109. package/dist/types/registry/index.d.ts +4 -4
  110. package/dist/types/registry/kagi.d.ts +1 -1
  111. package/dist/types/registry/kilo.d.ts +1 -1
  112. package/dist/types/registry/kimi-code.d.ts +1 -1
  113. package/dist/types/registry/litellm.d.ts +1 -1
  114. package/dist/types/registry/llama-cpp.d.ts +1 -1
  115. package/dist/types/registry/lm-studio.d.ts +1 -1
  116. package/dist/types/registry/minimax-code-cn.d.ts +1 -1
  117. package/dist/types/registry/minimax-code.d.ts +1 -1
  118. package/dist/types/registry/moonshot.d.ts +2 -2
  119. package/dist/types/registry/nanogpt.d.ts +2 -2
  120. package/dist/types/registry/nvidia.d.ts +1 -1
  121. package/dist/types/registry/oauth/anthropic.d.ts +3 -3
  122. package/dist/types/registry/oauth/callback-server.d.ts +1 -1
  123. package/dist/types/registry/oauth/cursor.d.ts +1 -1
  124. package/dist/types/registry/oauth/devin.d.ts +1 -1
  125. package/dist/types/registry/oauth/github-copilot.d.ts +2 -2
  126. package/dist/types/registry/oauth/gitlab-duo-workflow.d.ts +2 -2
  127. package/dist/types/registry/oauth/gitlab-duo.d.ts +1 -1
  128. package/dist/types/registry/oauth/google-antigravity.d.ts +1 -1
  129. package/dist/types/registry/oauth/google-gemini-cli.d.ts +1 -1
  130. package/dist/types/registry/oauth/google-oauth-shared.d.ts +2 -2
  131. package/dist/types/registry/oauth/index.d.ts +2 -2
  132. package/dist/types/registry/oauth/kimi.d.ts +1 -1
  133. package/dist/types/registry/oauth/minimax-code.d.ts +2 -2
  134. package/dist/types/registry/oauth/openai-codex.d.ts +1 -1
  135. package/dist/types/registry/oauth/opencode.d.ts +1 -1
  136. package/dist/types/registry/oauth/perplexity.d.ts +1 -1
  137. package/dist/types/registry/oauth/types.d.ts +2 -2
  138. package/dist/types/registry/oauth/wafer.d.ts +1 -1
  139. package/dist/types/registry/oauth/xai-oauth.d.ts +3 -3
  140. package/dist/types/registry/oauth/xiaomi.d.ts +1 -1
  141. package/dist/types/registry/ollama-cloud.d.ts +1 -1
  142. package/dist/types/registry/ollama.d.ts +1 -1
  143. package/dist/types/registry/openai-codex-device.d.ts +1 -1
  144. package/dist/types/registry/openai-codex.d.ts +1 -1
  145. package/dist/types/registry/opencode-go.d.ts +1 -1
  146. package/dist/types/registry/opencode-zen.d.ts +1 -1
  147. package/dist/types/registry/openrouter.d.ts +2 -2
  148. package/dist/types/registry/parallel.d.ts +1 -1
  149. package/dist/types/registry/perplexity.d.ts +2 -2
  150. package/dist/types/registry/qianfan.d.ts +2 -2
  151. package/dist/types/registry/qwen-portal.d.ts +1 -1
  152. package/dist/types/registry/registry.d.ts +69 -69
  153. package/dist/types/registry/sakana.d.ts +2 -2
  154. package/dist/types/registry/synthetic.d.ts +2 -2
  155. package/dist/types/registry/tavily.d.ts +1 -1
  156. package/dist/types/registry/together.d.ts +1 -1
  157. package/dist/types/registry/types.d.ts +1 -1
  158. package/dist/types/registry/umans.d.ts +2 -2
  159. package/dist/types/registry/venice.d.ts +2 -2
  160. package/dist/types/registry/vercel-ai-gateway.d.ts +1 -1
  161. package/dist/types/registry/vllm.d.ts +1 -1
  162. package/dist/types/registry/wafer-serverless.d.ts +1 -1
  163. package/dist/types/registry/xai-oauth.d.ts +1 -1
  164. package/dist/types/registry/xiaomi-token-plan-ams.d.ts +1 -1
  165. package/dist/types/registry/xiaomi-token-plan-cn.d.ts +1 -1
  166. package/dist/types/registry/xiaomi-token-plan-sgp.d.ts +1 -1
  167. package/dist/types/registry/xiaomi.d.ts +1 -1
  168. package/dist/types/registry/zai.d.ts +2 -2
  169. package/dist/types/registry/zenmux.d.ts +2 -2
  170. package/dist/types/registry/zhipu-coding-plan.d.ts +2 -2
  171. package/dist/types/stream.d.ts +6 -6
  172. package/dist/types/types.d.ts +40 -21
  173. package/dist/types/usage/claude.d.ts +1 -1
  174. package/dist/types/usage/gemini.d.ts +1 -1
  175. package/dist/types/usage/github-copilot.d.ts +1 -1
  176. package/dist/types/usage/google-antigravity.d.ts +1 -1
  177. package/dist/types/usage/kimi.d.ts +1 -1
  178. package/dist/types/usage/minimax-code.d.ts +1 -1
  179. package/dist/types/usage/ollama.d.ts +1 -1
  180. package/dist/types/usage/openai-codex-reset.d.ts +1 -1
  181. package/dist/types/usage/openai-codex.d.ts +1 -1
  182. package/dist/types/usage/opencode-go.d.ts +1 -1
  183. package/dist/types/usage/zai.d.ts +1 -1
  184. package/dist/types/usage.d.ts +1 -1
  185. package/dist/types/utils/block-symbols.d.ts +15 -0
  186. package/dist/types/utils/empty-completion-retry.d.ts +2 -2
  187. package/dist/types/utils/event-stream.d.ts +1 -1
  188. package/dist/types/utils/harmony-leak.d.ts +1 -1
  189. package/dist/types/utils/http-inspector.d.ts +19 -0
  190. package/dist/types/utils/leaked-thinking-stream.d.ts +1 -1
  191. package/dist/types/utils/openai-http.d.ts +3 -9
  192. package/dist/types/utils/provider-response.d.ts +1 -1
  193. package/dist/types/utils/proxy.d.ts +1 -1
  194. package/dist/types/utils/request-debug.d.ts +1 -1
  195. package/dist/types/utils/retry.d.ts +1 -1
  196. package/dist/types/utils/schema/equality.d.ts +1 -1
  197. package/dist/types/utils/schema/index.d.ts +15 -15
  198. package/dist/types/utils/schema/normalize.d.ts +7 -2
  199. package/dist/types/utils/schema/spill.d.ts +1 -1
  200. package/dist/types/utils/schema/wire.d.ts +1 -1
  201. package/dist/types/utils/sse-debug.d.ts +1 -1
  202. package/dist/types/utils/thinking-loop.d.ts +2 -2
  203. package/dist/types/utils/tool-call-loop-guard.d.ts +1 -1
  204. package/dist/types/utils/tool-choice.d.ts +1 -1
  205. package/dist/types/utils/validation.d.ts +1 -1
  206. package/dist/types/utils.d.ts +14 -2
  207. package/package.json +4 -4
  208. package/src/auth-broker/client.ts +41 -12
  209. package/src/auth-broker/remote-store.ts +189 -9
  210. package/src/auth-broker/server.ts +109 -7
  211. package/src/auth-broker/types.ts +22 -1
  212. package/src/auth-broker/wire-schemas.ts +22 -0
  213. package/src/auth-storage.ts +292 -22
  214. package/src/dialect/demotion.ts +18 -19
  215. package/src/error/rate-limit.ts +1 -1
  216. package/src/providers/azure-openai-responses.ts +3 -2
  217. package/src/providers/cursor.ts +36 -0
  218. package/src/providers/google-gemini-cli.ts +12 -3
  219. package/src/providers/google-shared.ts +3 -1
  220. package/src/providers/mock.ts +10 -3
  221. package/src/providers/ollama.ts +2 -2
  222. package/src/providers/openai-codex-responses.ts +47 -39
  223. package/src/providers/openai-completions.ts +48 -9
  224. package/src/providers/openai-responses.ts +37 -23
  225. package/src/providers/openai-shared.ts +145 -26
  226. package/src/providers/transform-messages.ts +63 -9
  227. package/src/registry/oauth/wafer.ts +1 -1
  228. package/src/stream.ts +6 -0
  229. package/src/types.ts +45 -3
  230. package/src/usage/claude.ts +28 -8
  231. package/src/utils/block-symbols.ts +18 -0
  232. package/src/utils/http-inspector.ts +32 -4
  233. package/src/utils/openai-http.ts +6 -9
  234. package/src/utils/retry-after.ts +12 -1
  235. package/src/utils/schema/normalize.ts +131 -0
  236. package/src/utils.ts +78 -0
@@ -5,25 +5,25 @@ import type { Effort } from "@oh-my-pi/pi-catalog/effort";
5
5
  import type { Api, FetchImpl, Model, Provider, ThinkingBudgets, Usage } from "@oh-my-pi/pi-catalog/types";
6
6
  import type { Type } from "arktype";
7
7
  import type { ZodType, z } from "zod/v4";
8
- import type { ApiKey } from "./auth-retry";
9
- import type { BedrockOptions } from "./providers/amazon-bedrock";
10
- import type { AnthropicOptions } from "./providers/anthropic";
11
- import type { FallbackParam, StopDetails } from "./providers/anthropic-wire";
12
- import type { AzureOpenAIResponsesOptions } from "./providers/azure-openai-responses";
13
- import type { CursorOptions } from "./providers/cursor";
14
- import type { DevinOptions } from "./providers/devin";
15
- import type { GitLabDuoWorkflowOptions } from "./providers/gitlab-duo-workflow";
16
- import type { GoogleOptions } from "./providers/google";
17
- import type { GoogleGeminiCliOptions } from "./providers/google-gemini-cli";
18
- import type { GoogleVertexOptions } from "./providers/google-vertex";
19
- import type { OllamaChatOptions } from "./providers/ollama";
20
- import type { OpenAICodexResponsesOptions } from "./providers/openai-codex-responses";
21
- import type { OpenAICompletionsOptions } from "./providers/openai-completions";
22
- import type { OpenAIResponsesOptions } from "./providers/openai-responses";
23
- import type { kStreamingPartialJson } from "./utils/block-symbols";
24
- import type { AssistantMessageEventStream } from "./utils/event-stream";
25
- export type { StopDetails } from "./providers/anthropic-wire";
26
- export type { AssistantMessageEventStream } from "./utils/event-stream";
8
+ import type { ApiKey } from "./auth-retry.js";
9
+ import type { BedrockOptions } from "./providers/amazon-bedrock.js";
10
+ import type { AnthropicOptions } from "./providers/anthropic.js";
11
+ import type { FallbackParam, StopDetails } from "./providers/anthropic-wire.js";
12
+ import type { AzureOpenAIResponsesOptions } from "./providers/azure-openai-responses.js";
13
+ import type { CursorOptions } from "./providers/cursor.js";
14
+ import type { DevinOptions } from "./providers/devin.js";
15
+ import type { GitLabDuoWorkflowOptions } from "./providers/gitlab-duo-workflow.js";
16
+ import type { GoogleOptions } from "./providers/google.js";
17
+ import type { GoogleGeminiCliOptions } from "./providers/google-gemini-cli.js";
18
+ import type { GoogleVertexOptions } from "./providers/google-vertex.js";
19
+ import type { OllamaChatOptions } from "./providers/ollama.js";
20
+ import type { OpenAICodexResponsesOptions } from "./providers/openai-codex-responses.js";
21
+ import type { OpenAICompletionsOptions } from "./providers/openai-completions.js";
22
+ import type { OpenAIResponsesOptions } from "./providers/openai-responses.js";
23
+ import type { kStreamingPartialJson } from "./utils/block-symbols.js";
24
+ import type { AssistantMessageEventStream } from "./utils/event-stream.js";
25
+ export type { StopDetails } from "./providers/anthropic-wire.js";
26
+ export type { AssistantMessageEventStream } from "./utils/event-stream.js";
27
27
  /**
28
28
  * Ceiling on the output-token count omp requests from any OpenAI-family endpoint
29
29
  * (openai-responses, azure/xai responses, and openai-completions). Mirrors
@@ -99,6 +99,7 @@ export type ServiceTierFamily = "openai" | "anthropic" | "google";
99
99
  * models mid-session.
100
100
  */
101
101
  export type ServiceTierByFamily = Partial<Record<ServiceTierFamily, ServiceTier>>;
102
+ type ServiceTierModel = Pick<Model, "provider" | "api" | "id">;
102
103
  /**
103
104
  * Classify a model into the service-tier family whose knob governs it, or
104
105
  * `undefined` when the model exposes no serving-priority control.
@@ -106,8 +107,10 @@ export type ServiceTierByFamily = Partial<Record<ServiceTierFamily, ServiceTier>
106
107
  * OpenRouter models are classified by id namespace (`anthropic/`, `google/`,
107
108
  * `openai/`); Claude on Bedrock/Vertex (api `anthropic-messages`) is the
108
109
  * anthropic family even though its provider is `amazon-bedrock`/`google-vertex`.
110
+ * Custom OpenAI-compatible relays that serve OpenAI model ids are OpenAI family
111
+ * too unless that provider owns a separate tier control such as Fireworks.
109
112
  */
110
- export declare function serviceTierFamily(model: Pick<Model, "provider" | "api" | "id">): ServiceTierFamily | undefined;
113
+ export declare function serviceTierFamily(model: ServiceTierModel): ServiceTierFamily | undefined;
111
114
  /**
112
115
  * Reduce a per-family tier map to the single wire tier for `model` — the entry
113
116
  * for the model's family, or `undefined` when the model has no family.
@@ -120,7 +123,7 @@ export declare function resolveModelServiceTier(tiers: ServiceTierByFamily | nul
120
123
  * Serverless realizes only its Priority serving path. Anthropic is absent — it
121
124
  * realizes `priority` via `speed: "fast"`, not a service-tier field.
122
125
  */
123
- export declare function shouldSendServiceTier(serviceTier: ServiceTier | null | undefined, provider: Provider | undefined): boolean;
126
+ export declare function shouldSendServiceTier(serviceTier: ServiceTier | null | undefined, target: Provider | ServiceTierModel | undefined): boolean;
124
127
  /**
125
128
  * True when `priority` will actually be realized on the wire for `model`.
126
129
  * Direct Anthropic realizes fast mode; OpenAI/Google/Fireworks emit the
@@ -493,6 +496,21 @@ export interface DeveloperMessage {
493
496
  providerPayload?: ProviderPayload;
494
497
  timestamp: number;
495
498
  }
499
+ export type AssistantRetryRecoveryKind = "credential" | "model" | "wait" | "plain";
500
+ export interface AssistantRetryRecovery {
501
+ kind: "auto-retry";
502
+ status: "recovered";
503
+ attempt: number;
504
+ recoveredAt: string;
505
+ recovery: AssistantRetryRecoveryKind;
506
+ note: string;
507
+ supersededBy?: {
508
+ timestamp: number;
509
+ responseId?: string;
510
+ provider: string;
511
+ model: string;
512
+ };
513
+ }
496
514
  export interface ContextSnapshot {
497
515
  promptTokens: number;
498
516
  nonMessageTokens: number;
@@ -505,6 +523,7 @@ export interface AssistantMessage {
505
523
  provider: Provider;
506
524
  model: string;
507
525
  contextSnapshot?: ContextSnapshot;
526
+ retryRecovery?: AssistantRetryRecovery;
508
527
  responseId?: string;
509
528
  /**
510
529
  * Name of the upstream provider an aggregator routed this request to, as
@@ -1,4 +1,4 @@
1
- import { type CredentialRankingStrategy, type UsageProvider, type UsageReport } from "../usage";
1
+ import { type CredentialRankingStrategy, type UsageProvider, type UsageReport } from "../usage.js";
2
2
  export declare function parseClaudeRateLimitHeaders(headers: Record<string, string>, now?: number): UsageReport | null;
3
3
  export declare const claudeUsageProvider: UsageProvider;
4
4
  export declare const claudeRankingStrategy: CredentialRankingStrategy;
@@ -1,2 +1,2 @@
1
- import type { UsageProvider } from "../usage";
1
+ import type { UsageProvider } from "../usage.js";
2
2
  export declare const googleGeminiCliUsageProvider: UsageProvider;
@@ -3,5 +3,5 @@
3
3
  *
4
4
  * Normalizes Copilot quota usage into the shared UsageReport schema.
5
5
  */
6
- import type { UsageProvider } from "../usage";
6
+ import type { UsageProvider } from "../usage.js";
7
7
  export declare const githubCopilotUsageProvider: UsageProvider;
@@ -1,4 +1,4 @@
1
- import type { CredentialRankingStrategy, UsageProvider } from "../usage";
1
+ import type { CredentialRankingStrategy, UsageProvider } from "../usage.js";
2
2
  export declare const antigravityUsageProvider: UsageProvider;
3
3
  /**
4
4
  * Antigravity quotas are returned per backend counter (Anthropic / Google /
@@ -1,2 +1,2 @@
1
- import type { UsageProvider } from "../usage";
1
+ import type { UsageProvider } from "../usage.js";
2
2
  export declare const kimiUsageProvider: UsageProvider;
@@ -1,2 +1,2 @@
1
- import type { UsageProvider } from "../usage";
1
+ import type { UsageProvider } from "../usage.js";
2
2
  export declare const minimaxCodeUsageProvider: UsageProvider;
@@ -1,4 +1,4 @@
1
- import type { UsageProvider } from "../usage";
1
+ import type { UsageProvider } from "../usage.js";
2
2
  /** Registers Ollama accounts with usage views even though no quota endpoint is exposed. */
3
3
  export declare const ollamaUsageProvider: UsageProvider;
4
4
  /** Registers Ollama Cloud accounts with usage views until a quota endpoint is available. */
@@ -18,7 +18,7 @@
18
18
  * (the `/usage reset` command + auto-redeem) and any out-of-band tooling can
19
19
  * share one wire contract.
20
20
  */
21
- import type { FetchImpl } from "../types";
21
+ import type { FetchImpl } from "../types.js";
22
22
  /** A single redeemable (or already-spent) saved reset. */
23
23
  export interface CodexResetCredit {
24
24
  /** Opaque credit id, e.g. `RateLimitResetCredit_…`. Pass to {@link consumeCodexResetCredit}. */
@@ -1,3 +1,3 @@
1
- import type { CredentialRankingStrategy, UsageProvider } from "../usage";
1
+ import type { CredentialRankingStrategy, UsageProvider } from "../usage.js";
2
2
  export declare const openaiCodexUsageProvider: UsageProvider;
3
3
  export declare const codexRankingStrategy: CredentialRankingStrategy;
@@ -1,2 +1,2 @@
1
- import type { UsageProvider } from "../usage";
1
+ import type { UsageProvider } from "../usage.js";
2
2
  export declare const opencodeGoUsageProvider: UsageProvider;
@@ -1,2 +1,2 @@
1
- import type { UsageProvider } from "../usage";
1
+ import type { UsageProvider } from "../usage.js";
2
2
  export declare const zaiUsageProvider: UsageProvider;
@@ -1,4 +1,4 @@
1
- import type { FetchImpl, Provider } from "./types";
1
+ import type { FetchImpl, Provider } from "./types.js";
2
2
  export type UsageUnit = "percent" | "tokens" | "requests" | "usd" | "minutes" | "bytes" | "unknown";
3
3
  export type UsageStatus = "ok" | "warning" | "exhausted" | "unknown";
4
4
  /** Time window for a limit (e.g. 5h, 7d, monthly). */
@@ -34,3 +34,18 @@ export declare const kCursorExecResolved: unique symbol;
34
34
  export type CursorExecResolvedCarrier = object & {
35
35
  [kCursorExecResolved]?: true;
36
36
  };
37
+ /**
38
+ * Marks a text block synthesized by cross-model thinking demotion in
39
+ * `transformMessages`. Converters that flatten adjacent text blocks into one
40
+ * string (openai-completions) insert a paragraph separator after marked
41
+ * blocks; unmarked adjacent blocks keep their original byte sequence.
42
+ * Symbol-keyed so the marker never persists across the JSONL round-trip and
43
+ * never reaches the wire.
44
+ */
45
+ export declare const kDemotedThinking: unique symbol;
46
+ /** Carries the demoted-thinking marker without exposing a string-keyed property. */
47
+ export type DemotedThinkingCarrier = object & {
48
+ [kDemotedThinking]?: boolean;
49
+ };
50
+ /** True for text blocks synthesized by cross-model thinking demotion. */
51
+ export declare function isDemotedThinking(block: DemotedThinkingCarrier | null | undefined): boolean;
@@ -1,5 +1,5 @@
1
- import type { AssistantMessage, Context } from "../types";
2
- import { AssistantMessageEventStream } from "./event-stream";
1
+ import type { AssistantMessage, Context } from "../types.js";
2
+ import { AssistantMessageEventStream } from "./event-stream.js";
3
3
  export declare const MAX_EMPTY_COMPLETION_RETRIES = 2;
4
4
  export declare const EMPTY_COMPLETION_BASE_DELAY_MS = 500;
5
5
  /**
@@ -1,4 +1,4 @@
1
- import type { AssistantMessage, AssistantMessageEvent } from "../types";
1
+ import type { AssistantMessage, AssistantMessageEvent } from "../types.js";
2
2
  export declare class EventStream<T, R = T> implements AsyncIterable<T> {
3
3
  #private;
4
4
  queue: T[];
@@ -7,7 +7,7 @@
7
7
  * hashline DSL form. Other tools and surfaces fall through to
8
8
  * abort-and-retry handled by the agent loop.
9
9
  */
10
- import type { AssistantMessage, Model, ToolCall } from "../types";
10
+ import type { AssistantMessage, Model, ToolCall } from "../types.js";
11
11
  declare const SIGNAL_ORDER: readonly ["M", "C", "G", "S", "B", "R", "T"];
12
12
  export type HarmonySignalClass = "H" | (typeof SIGNAL_ORDER)[number];
13
13
  export type HarmonySurface = "assistant_text" | "assistant_thinking" | "tool_arg";
@@ -13,6 +13,25 @@ export type CapturedHttpErrorResponse = {
13
13
  bodyText?: string;
14
14
  bodyJson?: unknown;
15
15
  };
16
+ /**
17
+ * Build the JSON persisted for a rejected request. Request fields stay at the
18
+ * top level (so existing dump parsers still read `body`); the provider's error
19
+ * is added under `errorResponse` so a failed request is diagnosable from the
20
+ * dump file rather than the request alone.
21
+ */
22
+ export declare function buildHttp400DumpPayload(dump: RawHttpRequestDump, error: unknown, message: string): RawHttpRequestDump & {
23
+ errorResponse: {
24
+ status: number | undefined;
25
+ message: string;
26
+ };
27
+ };
28
+ /** HTTP statuses whose rejected request we persist for post-hoc diagnosis: the
29
+ * request-content rejections that wedge a session. 400 (bad request) and 413
30
+ * (payload too large — an oversized image / snapcompact frame payload that 413s
31
+ * and empties the turn). Auth (401/403), not-found (404), rate limits and 5xx
32
+ * are excluded: 429/5xx are retried, so persisting them here would write one
33
+ * dump per attempt. */
34
+ export declare function shouldDumpRejectedRequest(error: unknown): boolean;
16
35
  export declare function appendRawHttpRequestDumpFor400(message: string, error: unknown, dump: RawHttpRequestDump | undefined): Promise<string>;
17
36
  export declare function finalizeErrorMessage(error: unknown, rawRequestDump: RawHttpRequestDump | undefined, capturedErrorResponse?: CapturedHttpErrorResponse): Promise<string>;
18
37
  /**
@@ -24,7 +24,7 @@
24
24
  * `../dialect/owned-stream.ts`, minus all in-band tool-call grammar: tool-call
25
25
  * events are forwarded verbatim.
26
26
  */
27
- import { AssistantMessageEventStream } from "./event-stream";
27
+ import { AssistantMessageEventStream } from "./event-stream.js";
28
28
  /**
29
29
  * Wrap a provider stream so leaked reasoning fences are healed into thinking
30
30
  * blocks live, for every provider. Returns a new stream that re-projects the
@@ -15,10 +15,10 @@
15
15
  * chain-state detectors, which regex over `error.message`.
16
16
  */
17
17
  import { type SseEventObserver } from "@oh-my-pi/pi-utils";
18
- import * as AIError from "../error";
19
- import { OpenAIHttpError } from "../error";
18
+ import * as AIError from "../error/index.js";
19
+ import { OpenAIHttpError } from "../error/index.js";
20
20
  export { OpenAIHttpError };
21
- import type { FetchImpl } from "../types";
21
+ import type { FetchImpl } from "../types.js";
22
22
  export interface OpenAIStreamRequestInit {
23
23
  url: string;
24
24
  headers: Record<string, string>;
@@ -26,12 +26,6 @@ export interface OpenAIStreamRequestInit {
26
26
  body: unknown;
27
27
  signal: AbortSignal;
28
28
  fetch?: FetchImpl;
29
- /**
30
- * Total attempts (initial + retries). Defaults to {@link DEFAULT_MAX_ATTEMPTS}.
31
- * Pass `1` when a first-event watchdog is armed so retries cannot silently
32
- * extend the caller's deadline (mirrors the old `maxRetries: 0` hint).
33
- */
34
- maxAttempts?: number;
35
29
  /** Raw wire-frame observer (`onSseEvent` debug pipeline). */
36
30
  onSseEvent?: SseEventObserver;
37
31
  }
@@ -1,3 +1,3 @@
1
- import type { Api, Model, ProviderResponseMetadata, StreamOptions } from "../types";
1
+ import type { Api, Model, ProviderResponseMetadata, StreamOptions } from "../types.js";
2
2
  export declare function normalizeProviderResponse(response: Response, requestId?: string | null, metadata?: Record<string, unknown>): ProviderResponseMetadata;
3
3
  export declare function notifyProviderResponse(options: Pick<StreamOptions, "onResponse"> | undefined, response: Response, model?: Model<Api>, requestId?: string | null, metadata?: Record<string, unknown>): Promise<void>;
@@ -1,5 +1,5 @@
1
1
  import * as tls from "node:tls";
2
- import type { FetchImpl } from "../types";
2
+ import type { FetchImpl } from "../types.js";
3
3
  /**
4
4
  * Checks if a host is local or cloud metadata, which should always bypass the proxy
5
5
  * (e.g. localhost, 127/8, ::1, 169.254.169.254, metadata.google.internal).
@@ -1,4 +1,4 @@
1
- import type { FetchImpl } from "../types";
1
+ import type { FetchImpl } from "../types.js";
2
2
  export type RequestDebugHeaders = Headers | Record<string, string | string[] | number | undefined | null> | undefined;
3
3
  export interface RequestDebugPayload {
4
4
  method: string;
@@ -1,4 +1,4 @@
1
- import { isCopilotTransientModelError } from "../error/flags";
1
+ import { isCopilotTransientModelError } from "../error/flags.js";
2
2
  export { isCopilotTransientModelError };
3
3
  /**
4
4
  * Wrap an initial Copilot request so transient `model_not_supported` 400s are
@@ -1,4 +1,4 @@
1
- import type { JsonObject } from "./types";
1
+ import type { JsonObject } from "./types.js";
2
2
  export declare function areJsonValuesEqual(left: unknown, right: unknown): boolean;
3
3
  export declare function mergeCompatibleEnumSchemas(existing: unknown, incoming: unknown): JsonObject | null;
4
4
  export declare function mergePropertySchemas(existing: unknown, incoming: unknown): unknown;
@@ -1,15 +1,15 @@
1
- export * from "./adapt";
2
- export * from "./compatibility";
3
- export * from "./dereference";
4
- export * from "./draft";
5
- export * from "./equality";
6
- export * from "./fields";
7
- export * from "./json-schema-validator";
8
- export * from "./meta-validator";
9
- export * from "./normalize";
10
- export * from "./spill";
11
- export * from "./strict-tool-validation";
12
- export * from "./types";
13
- export * from "./typescript";
14
- export * from "./wire";
15
- export * from "./zod-decontaminate";
1
+ export * from "./adapt.js";
2
+ export * from "./compatibility.js";
3
+ export * from "./dereference.js";
4
+ export * from "./draft.js";
5
+ export * from "./equality.js";
6
+ export * from "./fields.js";
7
+ export * from "./json-schema-validator.js";
8
+ export * from "./meta-validator.js";
9
+ export * from "./normalize.js";
10
+ export * from "./spill.js";
11
+ export * from "./strict-tool-validation.js";
12
+ export * from "./types.js";
13
+ export * from "./typescript.js";
14
+ export * from "./wire.js";
15
+ export * from "./zod-decontaminate.js";
@@ -1,5 +1,5 @@
1
- import { type DescriptionSpillFormat } from "./spill";
2
- import { type JsonObject } from "./types";
1
+ import { type DescriptionSpillFormat } from "./spill.js";
2
+ import { type JsonObject } from "./types.js";
3
3
  export type ResidualSchemaIncompatibility = "type-array" | "type-null" | "nullable" | "combiners";
4
4
  export interface NormalizeSchemaOptions {
5
5
  unsupportedFields: (key: string) => boolean;
@@ -66,6 +66,11 @@ export declare function normalizeSchemaForMCP(value: unknown): unknown;
66
66
  * and the depth-10 limit.
67
67
  */
68
68
  export declare function normalizeSchemaForMoonshot(value: unknown): unknown;
69
+ /**
70
+ * Rewrites standard JSON Schema forms that Ollama's Go `/api/chat` tool parser
71
+ * cannot unmarshal into its object-shaped `Schema` struct.
72
+ */
73
+ export declare function sanitizeSchemaForOllama(schema: JsonObject): JsonObject;
69
74
  /**
70
75
  * OpenAI Responses rejects `oneOf` in tool schemas even when strict mode is
71
76
  * disabled, and rejects every schema node with `type: "object"` unless it has
@@ -1,4 +1,4 @@
1
- import type { JsonObject } from "./types";
1
+ import type { JsonObject } from "./types.js";
2
2
  export type DescriptionSpillFormat = "spill" | "paren";
3
3
  /**
4
4
  * Demote stripped JSON Schema keywords into a node's `description` so the model
@@ -12,7 +12,7 @@
12
12
  */
13
13
  import type { Type } from "arktype";
14
14
  import { type ZodType } from "zod/v4";
15
- import type { Tool } from "../../types";
15
+ import type { Tool } from "../../types.js";
16
16
  /**
17
17
  * True when `value` is a live Zod schema instance.
18
18
  *
@@ -1,5 +1,5 @@
1
1
  import type { ServerSentEvent } from "@oh-my-pi/pi-utils";
2
- import type { RawSseEvent } from "../types";
2
+ import type { RawSseEvent } from "../types.js";
3
3
  type RawSseObserver = (event: RawSseEvent) => void;
4
4
  export declare function notifyRawSseEvent(observer: RawSseObserver | undefined, event: ServerSentEvent | RawSseEvent): void;
5
5
  export {};
@@ -1,5 +1,5 @@
1
- import type { Api, Model, StreamOptions } from "../types";
2
- import { AssistantMessageEventStream } from "./event-stream";
1
+ import type { Api, Model, StreamOptions } from "../types.js";
2
+ import { AssistantMessageEventStream } from "./event-stream.js";
3
3
  /** Stable lead phrase of the guard's error message; exported for tests. The
4
4
  * message also carries "stream stall" so the session + transport retry
5
5
  * classifiers treat it as a transient (retryable) stop without bespoke rules. */
@@ -1,4 +1,4 @@
1
- import type { AssistantMessage, ToolResultMessage } from "../types";
1
+ import type { AssistantMessage, ToolResultMessage } from "../types.js";
2
2
  /** Runtime settings for cross-turn tool-call repetition detection. */
3
3
  export interface ToolCallLoopGuardOptions {
4
4
  readonly threshold: number;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Utility functions for mapping unified ToolChoice to provider-specific formats.
3
3
  */
4
- import type { ToolChoice } from "../types";
4
+ import type { ToolChoice } from "../types.js";
5
5
  /** OpenAI Completions API tool choice format */
6
6
  export type OpenAICompletionsToolChoice = "auto" | "none" | "required" | {
7
7
  type: "function";
@@ -1,4 +1,4 @@
1
- import type { Tool, ToolCall } from "../types";
1
+ import type { Tool, ToolCall } from "../types.js";
2
2
  /**
3
3
  * Finds a tool by name and validates the tool call arguments against its schema.
4
4
  * @param tools Array of tool definitions
@@ -1,5 +1,5 @@
1
- import type { ResponseInput } from "./providers/openai-responses-wire";
2
- import type { CacheRetention, OpenAIResponsesHistoryPayload, ProviderPayload } from "./types";
1
+ import type { ResponseInput } from "./providers/openai-responses-wire.js";
2
+ import type { CacheRetention, OpenAIResponsesHistoryPayload, ProviderPayload } from "./types.js";
3
3
  export { isRecord } from "@oh-my-pi/pi-utils";
4
4
  export declare function normalizeSystemPrompts(systemPrompt: readonly string[] | string | undefined | null): string[];
5
5
  export declare function normalizeToolCallId(id: string): string;
@@ -14,6 +14,18 @@ export declare function normalizeResponsesToolCallId(id: string, itemPrefix?: Re
14
14
  */
15
15
  export declare function truncateResponseItemId(id: string, prefix: string): string;
16
16
  export declare function sanitizeOpenAIResponsesHistoryItemsForReplay(items: Array<Record<string, unknown>>): ResponseInput;
17
+ /**
18
+ * Sanitize assistant-native Responses history for replay.
19
+ *
20
+ * Returns `undefined` for hidden-empty turns that only contain reasoning and an
21
+ * empty assistant message, allowing callers to rebuild visible transcript
22
+ * history instead of replaying stale native state.
23
+ */
24
+ export declare function sanitizeOpenAIResponsesAssistantHistoryItemsForReplay(items: Array<Record<string, unknown>>): ResponseInput | undefined;
25
+ /**
26
+ * Drop hidden-only fallback assistant replay after a native Responses snapshot is rejected.
27
+ */
28
+ export declare function sanitizeOpenAIResponsesAssistantFallbackItemsForReplay(items: ResponseInput): ResponseInput;
17
29
  export declare function createOpenAIResponsesHistoryPayload(provider: string, items: Array<Record<string, unknown>>, incremental?: boolean): OpenAIResponsesHistoryPayload;
18
30
  export declare function getOpenAIResponsesHistoryPayload(providerPayload: ProviderPayload | undefined, currentProvider: string, fallbackProvider?: string): OpenAIResponsesHistoryPayload | undefined;
19
31
  export declare function getOpenAIResponsesHistoryItems(providerPayload: ProviderPayload | undefined, currentProvider: string, fallbackProvider?: string): Array<Record<string, unknown>> | undefined;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-ai",
4
- "version": "16.3.5",
4
+ "version": "16.3.7",
5
5
  "description": "Unified LLM API with automatic model discovery and provider configuration",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
@@ -38,9 +38,9 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@bufbuild/protobuf": "^2.12.0",
41
- "@oh-my-pi/pi-catalog": "16.3.5",
42
- "@oh-my-pi/pi-utils": "16.3.5",
43
- "@oh-my-pi/pi-wire": "16.3.5",
41
+ "@oh-my-pi/pi-catalog": "16.3.7",
42
+ "@oh-my-pi/pi-utils": "16.3.7",
43
+ "@oh-my-pi/pi-wire": "16.3.7",
44
44
  "arktype": "^2.2.0",
45
45
  "zod": "^4"
46
46
  },
@@ -9,6 +9,9 @@ import { readSseEvents } from "@oh-my-pi/pi-utils";
9
9
  import { type } from "arktype";
10
10
  import type { AuthCredential } from "../auth-storage";
11
11
  import type {
12
+ CredentialBlockRequest,
13
+ CredentialBlockResponse,
14
+ CredentialBlocksDeleteResponse,
12
15
  CredentialDisableRequest,
13
16
  CredentialDisableResponse,
14
17
  CredentialRefreshResponse,
@@ -20,6 +23,8 @@ import type {
20
23
  UsageResponse,
21
24
  } from "./types";
22
25
  import {
26
+ credentialBlockResponseSchema,
27
+ credentialBlocksDeleteResponseSchema,
23
28
  credentialDisableResponseSchema,
24
29
  credentialRefreshResponseSchema,
25
30
  credentialUploadResponseSchema,
@@ -106,7 +111,11 @@ export class AuthBrokerClient {
106
111
  }
107
112
 
108
113
  healthz(signal?: AbortSignal): Promise<HealthzResponse> {
109
- return this.#request("GET", "/v1/healthz", { schema: healthzResponseSchema, auth: false, signal });
114
+ return this.#request<HealthzResponse>("GET", "/v1/healthz", {
115
+ schema: healthzResponseSchema,
116
+ auth: false,
117
+ signal,
118
+ });
110
119
  }
111
120
 
112
121
  async fetchSnapshot(opts: FetchSnapshotOptions = {}): Promise<FetchSnapshotResult> {
@@ -230,19 +239,19 @@ export class AuthBrokerClient {
230
239
  // `metadata`) but leaves provider-specific extension fields permissive so
231
240
  // the broker can ship new shapes ahead of the client. `raw` is accepted
232
241
  // but normally stripped by the broker before send.
233
- return this.#request("GET", "/v1/usage", { schema: usageResponseSchema, signal }) as Promise<UsageResponse>;
242
+ return this.#request<UsageResponse>("GET", "/v1/usage", { schema: usageResponseSchema, signal });
234
243
  }
235
244
 
236
245
  async refreshCredential(id: number, signal?: AbortSignal): Promise<CredentialRefreshResponse> {
237
- return this.#request("POST", `/v1/credential/${id}/refresh`, {
246
+ return this.#request<CredentialRefreshResponse>("POST", `/v1/credential/${id}/refresh`, {
238
247
  schema: credentialRefreshResponseSchema,
239
248
  signal,
240
- }) as Promise<CredentialRefreshResponse>;
249
+ });
241
250
  }
242
251
 
243
252
  async disableCredential(id: number, cause: string, signal?: AbortSignal): Promise<CredentialDisableResponse> {
244
253
  const body: CredentialDisableRequest = { cause };
245
- return this.#request("POST", `/v1/credential/${id}/disable`, {
254
+ return this.#request<CredentialDisableResponse>("POST", `/v1/credential/${id}/disable`, {
246
255
  body,
247
256
  schema: credentialDisableResponseSchema,
248
257
  signal,
@@ -255,18 +264,38 @@ export class AuthBrokerClient {
255
264
  signal?: AbortSignal,
256
265
  ): Promise<CredentialUploadResponse> {
257
266
  const body: CredentialUploadRequest = { provider, credential };
258
- return this.#request("POST", "/v1/credential", {
267
+ return this.#request<CredentialUploadResponse>("POST", "/v1/credential", {
259
268
  body,
260
269
  schema: credentialUploadResponseSchema,
261
270
  signal,
262
- }) as Promise<CredentialUploadResponse>;
271
+ });
272
+ }
273
+
274
+ async upsertCredentialBlock(
275
+ id: number,
276
+ block: CredentialBlockRequest,
277
+ signal?: AbortSignal,
278
+ ): Promise<CredentialBlockResponse> {
279
+ const body: CredentialBlockRequest = block;
280
+ return this.#request<CredentialBlockResponse>("POST", `/v1/credential/${id}/block`, {
281
+ body,
282
+ schema: credentialBlockResponseSchema,
283
+ signal,
284
+ });
285
+ }
286
+
287
+ async deleteCredentialBlocks(id: number, signal?: AbortSignal): Promise<CredentialBlocksDeleteResponse> {
288
+ return this.#request<CredentialBlocksDeleteResponse>("DELETE", `/v1/credential/${id}/blocks`, {
289
+ schema: credentialBlocksDeleteResponseSchema,
290
+ signal,
291
+ });
263
292
  }
264
293
 
265
- async #request(
266
- method: "GET" | "POST",
294
+ async #request<t>(
295
+ method: "GET" | "POST" | "DELETE",
267
296
  path: string,
268
297
  opts: { schema: (input: unknown) => unknown; auth?: boolean; body?: unknown; signal?: AbortSignal },
269
- ): Promise<any> {
298
+ ): Promise<t> {
270
299
  const response = await this.#fetchRaw(method, path, opts);
271
300
  const text = await response.text();
272
301
  const raw = this.#parseJson(text, response.status);
@@ -277,7 +306,7 @@ export class AuthBrokerClient {
277
306
  body: validated.summary,
278
307
  });
279
308
  }
280
- return validated;
309
+ return validated as t;
281
310
  }
282
311
 
283
312
  #parseJson(text: string, status: number): unknown {
@@ -293,7 +322,7 @@ export class AuthBrokerClient {
293
322
  }
294
323
 
295
324
  async #fetchRaw(
296
- method: "GET" | "POST",
325
+ method: "GET" | "POST" | "DELETE",
297
326
  path: string,
298
327
  opts: {
299
328
  auth?: boolean;