@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.
- package/CHANGELOG.md +18 -0
- package/dist/types/api-registry.d.ts +1 -1
- package/dist/types/auth-broker/client.d.ts +2 -2
- package/dist/types/auth-broker/discover.d.ts +1 -1
- package/dist/types/auth-broker/index.d.ts +7 -7
- package/dist/types/auth-broker/refresher.d.ts +1 -1
- package/dist/types/auth-broker/remote-store.d.ts +6 -6
- package/dist/types/auth-broker/server.d.ts +1 -1
- package/dist/types/auth-broker/snapshot-cache.d.ts +1 -1
- package/dist/types/auth-broker/types.d.ts +2 -2
- package/dist/types/auth-gateway/index.d.ts +3 -3
- package/dist/types/auth-gateway/server.d.ts +3 -3
- package/dist/types/auth-gateway/types.d.ts +1 -1
- package/dist/types/auth-retry.d.ts +2 -2
- package/dist/types/auth-storage.d.ts +6 -6
- package/dist/types/dialect/anthropic.d.ts +1 -1
- package/dist/types/dialect/catalog.d.ts +1 -1
- package/dist/types/dialect/coercion.d.ts +1 -1
- package/dist/types/dialect/deepseek.d.ts +1 -1
- package/dist/types/dialect/demotion.d.ts +16 -14
- package/dist/types/dialect/examples.d.ts +1 -1
- package/dist/types/dialect/factory.d.ts +1 -1
- package/dist/types/dialect/gemini.d.ts +1 -1
- package/dist/types/dialect/gemma.d.ts +1 -1
- package/dist/types/dialect/glm.d.ts +1 -1
- package/dist/types/dialect/harmony.d.ts +1 -1
- package/dist/types/dialect/hermes.d.ts +1 -1
- package/dist/types/dialect/history.d.ts +2 -2
- package/dist/types/dialect/index.d.ts +11 -11
- package/dist/types/dialect/inventory.d.ts +1 -1
- package/dist/types/dialect/kimi.d.ts +1 -1
- package/dist/types/dialect/minimax.d.ts +1 -1
- package/dist/types/dialect/owned-stream.d.ts +2 -2
- package/dist/types/dialect/qwen3.d.ts +1 -1
- package/dist/types/dialect/rendering.d.ts +2 -2
- package/dist/types/dialect/thinking.d.ts +1 -1
- package/dist/types/dialect/types.d.ts +1 -1
- package/dist/types/dialect/xml.d.ts +1 -1
- package/dist/types/error/classes.d.ts +1 -1
- package/dist/types/error/finalize.d.ts +3 -3
- package/dist/types/error/flags.d.ts +1 -1
- package/dist/types/error/format.d.ts +1 -1
- package/dist/types/error/index.d.ts +13 -13
- package/dist/types/error/provider.d.ts +1 -1
- package/dist/types/error/rate-limit.d.ts +1 -1
- package/dist/types/index.d.ts +47 -47
- package/dist/types/provider-details.d.ts +1 -1
- package/dist/types/providers/amazon-bedrock.d.ts +1 -1
- package/dist/types/providers/anthropic-client.d.ts +3 -3
- package/dist/types/providers/anthropic-messages-server-schema.d.ts +1 -1
- package/dist/types/providers/anthropic-messages-server.d.ts +2 -2
- package/dist/types/providers/anthropic-wire.d.ts +1 -1
- package/dist/types/providers/anthropic.d.ts +3 -3
- package/dist/types/providers/aws-credentials.d.ts +2 -2
- package/dist/types/providers/azure-openai-responses.d.ts +2 -2
- package/dist/types/providers/cursor.d.ts +18 -3
- package/dist/types/providers/devin.d.ts +1 -1
- package/dist/types/providers/error-message.d.ts +1 -1
- package/dist/types/providers/github-copilot-headers.d.ts +1 -1
- package/dist/types/providers/gitlab-duo-workflow.d.ts +2 -2
- package/dist/types/providers/gitlab-duo.d.ts +2 -2
- package/dist/types/providers/google-auth.d.ts +1 -1
- package/dist/types/providers/google-gemini-cli.d.ts +6 -4
- package/dist/types/providers/google-interactions.d.ts +3 -3
- package/dist/types/providers/google-shared.d.ts +7 -5
- package/dist/types/providers/google-vertex.d.ts +2 -2
- package/dist/types/providers/google.d.ts +2 -2
- package/dist/types/providers/kimi.d.ts +3 -3
- package/dist/types/providers/mock.d.ts +2 -2
- package/dist/types/providers/ollama.d.ts +1 -1
- package/dist/types/providers/openai-anthropic-shim.d.ts +2 -2
- package/dist/types/providers/openai-chat-server-schema.d.ts +1 -1
- package/dist/types/providers/openai-chat-server.d.ts +2 -2
- package/dist/types/providers/openai-codex/request-transformer.d.ts +1 -1
- package/dist/types/providers/openai-codex/response-handler.d.ts +1 -1
- package/dist/types/providers/openai-codex-responses.d.ts +3 -3
- package/dist/types/providers/openai-completions.d.ts +3 -3
- package/dist/types/providers/openai-reasoning-fallback.d.ts +1 -1
- package/dist/types/providers/openai-responses-server-schema.d.ts +1 -1
- package/dist/types/providers/openai-responses-server.d.ts +2 -2
- package/dist/types/providers/openai-responses.d.ts +5 -5
- package/dist/types/providers/openai-shared.d.ts +10 -9
- package/dist/types/providers/pi-native-client.d.ts +1 -1
- package/dist/types/providers/pi-native-server.d.ts +2 -2
- package/dist/types/providers/register-builtins.d.ts +3 -3
- package/dist/types/providers/synthetic.d.ts +3 -3
- package/dist/types/providers/transform-messages.d.ts +1 -1
- package/dist/types/providers/vision-guard.d.ts +1 -1
- package/dist/types/registry/alibaba-coding-plan.d.ts +1 -1
- package/dist/types/registry/anthropic.d.ts +1 -1
- package/dist/types/registry/api-key-login.d.ts +1 -1
- package/dist/types/registry/api-key-validation.d.ts +1 -1
- package/dist/types/registry/baseten.d.ts +2 -2
- package/dist/types/registry/cerebras.d.ts +2 -2
- package/dist/types/registry/cloudflare-ai-gateway.d.ts +1 -1
- package/dist/types/registry/coreweave.d.ts +2 -2
- package/dist/types/registry/cursor.d.ts +1 -1
- package/dist/types/registry/deepseek.d.ts +1 -1
- package/dist/types/registry/devin.d.ts +1 -1
- package/dist/types/registry/firepass.d.ts +2 -2
- package/dist/types/registry/fireworks.d.ts +2 -2
- package/dist/types/registry/github-copilot.d.ts +1 -1
- package/dist/types/registry/gitlab-duo-workflow.d.ts +1 -1
- package/dist/types/registry/gitlab-duo.d.ts +1 -1
- package/dist/types/registry/google-antigravity.d.ts +1 -1
- package/dist/types/registry/google-gemini-cli.d.ts +1 -1
- package/dist/types/registry/huggingface.d.ts +2 -2
- package/dist/types/registry/index.d.ts +4 -4
- package/dist/types/registry/kagi.d.ts +1 -1
- package/dist/types/registry/kilo.d.ts +1 -1
- package/dist/types/registry/kimi-code.d.ts +1 -1
- package/dist/types/registry/litellm.d.ts +1 -1
- package/dist/types/registry/llama-cpp.d.ts +1 -1
- package/dist/types/registry/lm-studio.d.ts +1 -1
- package/dist/types/registry/minimax-code-cn.d.ts +1 -1
- package/dist/types/registry/minimax-code.d.ts +1 -1
- package/dist/types/registry/moonshot.d.ts +2 -2
- package/dist/types/registry/nanogpt.d.ts +2 -2
- package/dist/types/registry/nvidia.d.ts +1 -1
- package/dist/types/registry/oauth/anthropic.d.ts +3 -3
- package/dist/types/registry/oauth/callback-server.d.ts +1 -1
- package/dist/types/registry/oauth/cursor.d.ts +1 -1
- package/dist/types/registry/oauth/devin.d.ts +1 -1
- package/dist/types/registry/oauth/github-copilot.d.ts +2 -2
- package/dist/types/registry/oauth/gitlab-duo-workflow.d.ts +2 -2
- package/dist/types/registry/oauth/gitlab-duo.d.ts +1 -1
- package/dist/types/registry/oauth/google-antigravity.d.ts +1 -1
- package/dist/types/registry/oauth/google-gemini-cli.d.ts +1 -1
- package/dist/types/registry/oauth/google-oauth-shared.d.ts +2 -2
- package/dist/types/registry/oauth/index.d.ts +2 -2
- package/dist/types/registry/oauth/kimi.d.ts +1 -1
- package/dist/types/registry/oauth/minimax-code.d.ts +2 -2
- package/dist/types/registry/oauth/openai-codex.d.ts +1 -1
- package/dist/types/registry/oauth/opencode.d.ts +1 -1
- package/dist/types/registry/oauth/perplexity.d.ts +1 -1
- package/dist/types/registry/oauth/types.d.ts +2 -2
- package/dist/types/registry/oauth/wafer.d.ts +1 -1
- package/dist/types/registry/oauth/xai-oauth.d.ts +3 -3
- package/dist/types/registry/oauth/xiaomi.d.ts +1 -1
- package/dist/types/registry/ollama-cloud.d.ts +1 -1
- package/dist/types/registry/ollama.d.ts +1 -1
- package/dist/types/registry/openai-codex-device.d.ts +1 -1
- package/dist/types/registry/openai-codex.d.ts +1 -1
- package/dist/types/registry/opencode-go.d.ts +1 -1
- package/dist/types/registry/opencode-zen.d.ts +1 -1
- package/dist/types/registry/openrouter.d.ts +2 -2
- package/dist/types/registry/parallel.d.ts +1 -1
- package/dist/types/registry/perplexity.d.ts +2 -2
- package/dist/types/registry/qianfan.d.ts +2 -2
- package/dist/types/registry/qwen-portal.d.ts +1 -1
- package/dist/types/registry/registry.d.ts +69 -69
- package/dist/types/registry/sakana.d.ts +2 -2
- package/dist/types/registry/synthetic.d.ts +2 -2
- package/dist/types/registry/tavily.d.ts +1 -1
- package/dist/types/registry/together.d.ts +1 -1
- package/dist/types/registry/types.d.ts +1 -1
- package/dist/types/registry/umans.d.ts +2 -2
- package/dist/types/registry/venice.d.ts +2 -2
- package/dist/types/registry/vercel-ai-gateway.d.ts +1 -1
- package/dist/types/registry/vllm.d.ts +1 -1
- package/dist/types/registry/wafer-serverless.d.ts +1 -1
- package/dist/types/registry/xai-oauth.d.ts +1 -1
- package/dist/types/registry/xiaomi-token-plan-ams.d.ts +1 -1
- package/dist/types/registry/xiaomi-token-plan-cn.d.ts +1 -1
- package/dist/types/registry/xiaomi-token-plan-sgp.d.ts +1 -1
- package/dist/types/registry/xiaomi.d.ts +1 -1
- package/dist/types/registry/zai.d.ts +2 -2
- package/dist/types/registry/zenmux.d.ts +2 -2
- package/dist/types/registry/zhipu-coding-plan.d.ts +2 -2
- package/dist/types/stream.d.ts +6 -6
- package/dist/types/types.d.ts +24 -21
- package/dist/types/usage/claude.d.ts +1 -1
- package/dist/types/usage/gemini.d.ts +1 -1
- package/dist/types/usage/github-copilot.d.ts +1 -1
- package/dist/types/usage/google-antigravity.d.ts +1 -1
- package/dist/types/usage/kimi.d.ts +1 -1
- package/dist/types/usage/minimax-code.d.ts +1 -1
- package/dist/types/usage/ollama.d.ts +1 -1
- package/dist/types/usage/openai-codex-reset.d.ts +1 -1
- package/dist/types/usage/openai-codex.d.ts +1 -1
- package/dist/types/usage/opencode-go.d.ts +1 -1
- package/dist/types/usage/zai.d.ts +1 -1
- package/dist/types/usage.d.ts +1 -1
- package/dist/types/utils/block-symbols.d.ts +15 -0
- package/dist/types/utils/empty-completion-retry.d.ts +2 -2
- package/dist/types/utils/event-stream.d.ts +1 -1
- package/dist/types/utils/harmony-leak.d.ts +1 -1
- package/dist/types/utils/http-inspector.d.ts +19 -0
- package/dist/types/utils/leaked-thinking-stream.d.ts +1 -1
- package/dist/types/utils/openai-http.d.ts +3 -9
- package/dist/types/utils/provider-response.d.ts +1 -1
- package/dist/types/utils/proxy.d.ts +1 -1
- package/dist/types/utils/request-debug.d.ts +1 -1
- package/dist/types/utils/retry.d.ts +1 -1
- package/dist/types/utils/schema/equality.d.ts +1 -1
- package/dist/types/utils/schema/index.d.ts +15 -15
- package/dist/types/utils/schema/normalize.d.ts +2 -2
- package/dist/types/utils/schema/spill.d.ts +1 -1
- package/dist/types/utils/schema/wire.d.ts +1 -1
- package/dist/types/utils/sse-debug.d.ts +1 -1
- package/dist/types/utils/thinking-loop.d.ts +2 -2
- package/dist/types/utils/tool-call-loop-guard.d.ts +1 -1
- package/dist/types/utils/tool-choice.d.ts +1 -1
- package/dist/types/utils/validation.d.ts +1 -1
- package/dist/types/utils.d.ts +14 -2
- package/package.json +4 -4
- package/src/dialect/demotion.ts +18 -19
- package/src/error/rate-limit.ts +1 -1
- package/src/providers/azure-openai-responses.ts +3 -2
- package/src/providers/cursor.ts +36 -0
- package/src/providers/google-gemini-cli.ts +12 -3
- package/src/providers/google-shared.ts +3 -1
- package/src/providers/mock.ts +10 -3
- package/src/providers/openai-codex-responses.ts +47 -39
- package/src/providers/openai-completions.ts +48 -9
- package/src/providers/openai-responses.ts +37 -23
- package/src/providers/openai-shared.ts +145 -26
- package/src/providers/transform-messages.ts +63 -9
- package/src/registry/oauth/wafer.ts +1 -1
- package/src/stream.ts +6 -0
- package/src/types.ts +27 -3
- package/src/utils/block-symbols.ts +18 -0
- package/src/utils/http-inspector.ts +32 -4
- package/src/utils/openai-http.ts +6 -9
- package/src/utils/retry-after.ts +12 -1
- package/src/utils.ts +78 -0
package/src/utils/openai-http.ts
CHANGED
|
@@ -24,8 +24,11 @@ import type { FetchImpl } from "../types";
|
|
|
24
24
|
import type { CapturedHttpErrorResponse } from "./http-inspector";
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* Total attempts
|
|
28
|
-
*
|
|
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:
|
|
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.
|
package/src/utils/retry-after.ts
CHANGED
|
@@ -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(
|
|
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>,
|