@oh-my-pi/pi-ai 14.4.0 → 14.4.3
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/package.json +3 -3
- package/src/providers/anthropic.ts +9 -9
- package/src/providers/azure-openai-responses.ts +2 -2
- package/src/providers/openai-codex-responses.ts +2 -2
- package/src/providers/openai-completions.ts +2 -2
- package/src/providers/openai-responses.ts +2 -2
- package/src/types.ts +7 -1
- package/src/utils/validation.ts +20 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-ai",
|
|
4
|
-
"version": "14.4.
|
|
4
|
+
"version": "14.4.3",
|
|
5
5
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
6
6
|
"homepage": "https://github.com/can1357/oh-my-pi",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"@aws-sdk/credential-provider-node": "^3.972.36",
|
|
47
47
|
"@bufbuild/protobuf": "^2.12.0",
|
|
48
48
|
"@google/genai": "^1.50.1",
|
|
49
|
-
"@oh-my-pi/pi-natives": "14.4.
|
|
50
|
-
"@oh-my-pi/pi-utils": "14.4.
|
|
49
|
+
"@oh-my-pi/pi-natives": "14.4.3",
|
|
50
|
+
"@oh-my-pi/pi-utils": "14.4.3",
|
|
51
51
|
"@sinclair/typebox": "^0.34.49",
|
|
52
52
|
"@smithy/node-http-handler": "^4.6.1",
|
|
53
53
|
"ajv": "^8.20.0",
|
|
@@ -84,7 +84,6 @@ export function buildBetaHeader(baseBetas: string[], extraBetas: string[]): stri
|
|
|
84
84
|
const claudeCodeBetaDefaults = [
|
|
85
85
|
"claude-code-20250219",
|
|
86
86
|
"oauth-2025-04-20",
|
|
87
|
-
"interleaved-thinking-2025-05-14",
|
|
88
87
|
"context-management-2025-06-27",
|
|
89
88
|
"prompt-caching-scope-2026-01-05",
|
|
90
89
|
];
|
|
@@ -1160,6 +1159,7 @@ export function buildAnthropicClientOptions(args: AnthropicClientOptionsArgs): A
|
|
|
1160
1159
|
dynamicHeaders,
|
|
1161
1160
|
isOAuth,
|
|
1162
1161
|
} = args;
|
|
1162
|
+
const needsInterleavedBeta = interleavedThinking && !supportsAdaptiveThinkingDisplay(model.id);
|
|
1163
1163
|
const oauthToken = isOAuth ?? isAnthropicOAuthToken(apiKey);
|
|
1164
1164
|
const baseUrl = resolveAnthropicBaseUrl(model, apiKey);
|
|
1165
1165
|
const foundryCustomHeaders = resolveAnthropicCustomHeaders(model);
|
|
@@ -1193,7 +1193,7 @@ export function buildAnthropicClientOptions(args: AnthropicClientOptionsArgs): A
|
|
|
1193
1193
|
}
|
|
1194
1194
|
|
|
1195
1195
|
const betaFeatures = [...extraBetas];
|
|
1196
|
-
if (
|
|
1196
|
+
if (needsInterleavedBeta) {
|
|
1197
1197
|
betaFeatures.push("interleaved-thinking-2025-05-14");
|
|
1198
1198
|
}
|
|
1199
1199
|
|
|
@@ -1498,9 +1498,6 @@ function buildParams(
|
|
|
1498
1498
|
stream: true,
|
|
1499
1499
|
};
|
|
1500
1500
|
|
|
1501
|
-
if (options?.temperature !== undefined) {
|
|
1502
|
-
params.temperature = options.temperature;
|
|
1503
|
-
}
|
|
1504
1501
|
if (options?.topP !== undefined) {
|
|
1505
1502
|
params.top_p = options.topP;
|
|
1506
1503
|
}
|
|
@@ -1510,13 +1507,16 @@ function buildParams(
|
|
|
1510
1507
|
|
|
1511
1508
|
// Opus 4.7+ rejects non-default sampling parameters with 400 error.
|
|
1512
1509
|
if (hasOpus47ApiRestrictions(model.id)) {
|
|
1513
|
-
delete params.
|
|
1514
|
-
delete
|
|
1515
|
-
delete (params as AnthropicSamplingParams).top_k;
|
|
1510
|
+
delete params.top_p;
|
|
1511
|
+
delete params.top_k;
|
|
1516
1512
|
}
|
|
1517
1513
|
|
|
1518
1514
|
if (context.tools) {
|
|
1519
|
-
params.tools = convertTools(
|
|
1515
|
+
params.tools = convertTools(
|
|
1516
|
+
context.tools,
|
|
1517
|
+
isOAuthToken,
|
|
1518
|
+
disableStrictTools || model.provider === "github-copilot",
|
|
1519
|
+
);
|
|
1520
1520
|
}
|
|
1521
1521
|
|
|
1522
1522
|
if (options?.thinkingEnabled && model.reasoning && model.provider !== "github-copilot") {
|
|
@@ -10,11 +10,11 @@ import {
|
|
|
10
10
|
type Api,
|
|
11
11
|
type AssistantMessage,
|
|
12
12
|
type Context,
|
|
13
|
-
isSpecialServiceTier,
|
|
14
13
|
type Model,
|
|
15
14
|
type ServiceTier,
|
|
16
15
|
type StreamFunction,
|
|
17
16
|
type StreamOptions,
|
|
17
|
+
shouldSendServiceTier,
|
|
18
18
|
type Tool,
|
|
19
19
|
type ToolChoice,
|
|
20
20
|
} from "../types";
|
|
@@ -298,7 +298,7 @@ function buildParams(
|
|
|
298
298
|
if (options?.repetitionPenalty !== undefined) {
|
|
299
299
|
params.repetition_penalty = options.repetitionPenalty;
|
|
300
300
|
}
|
|
301
|
-
if (
|
|
301
|
+
if (shouldSendServiceTier(options?.serviceTier, model.provider)) {
|
|
302
302
|
params.service_tier = options.serviceTier;
|
|
303
303
|
}
|
|
304
304
|
|
|
@@ -19,12 +19,12 @@ import {
|
|
|
19
19
|
type Api,
|
|
20
20
|
type AssistantMessage,
|
|
21
21
|
type Context,
|
|
22
|
-
isSpecialServiceTier,
|
|
23
22
|
type Model,
|
|
24
23
|
type ProviderSessionState,
|
|
25
24
|
type ServiceTier,
|
|
26
25
|
type StreamFunction,
|
|
27
26
|
type StreamOptions,
|
|
27
|
+
shouldSendServiceTier,
|
|
28
28
|
type TextContent,
|
|
29
29
|
type ThinkingContent,
|
|
30
30
|
type Tool,
|
|
@@ -493,7 +493,7 @@ async function buildTransformedCodexRequestBody(
|
|
|
493
493
|
if (options?.repetitionPenalty !== undefined) {
|
|
494
494
|
params.repetition_penalty = options.repetitionPenalty;
|
|
495
495
|
}
|
|
496
|
-
if (
|
|
496
|
+
if (shouldSendServiceTier(options?.serviceTier, model.provider)) {
|
|
497
497
|
params.service_tier = options.serviceTier;
|
|
498
498
|
}
|
|
499
499
|
if (context.tools && context.tools.length > 0) {
|
|
@@ -14,7 +14,6 @@ import { getEnvApiKey } from "../stream";
|
|
|
14
14
|
import {
|
|
15
15
|
type AssistantMessage,
|
|
16
16
|
type Context,
|
|
17
|
-
isSpecialServiceTier,
|
|
18
17
|
type Message,
|
|
19
18
|
type MessageAttribution,
|
|
20
19
|
type Model,
|
|
@@ -23,6 +22,7 @@ import {
|
|
|
23
22
|
type StopReason,
|
|
24
23
|
type StreamFunction,
|
|
25
24
|
type StreamOptions,
|
|
25
|
+
shouldSendServiceTier,
|
|
26
26
|
type TextContent,
|
|
27
27
|
type ThinkingContent,
|
|
28
28
|
type Tool,
|
|
@@ -811,7 +811,7 @@ function buildParams(
|
|
|
811
811
|
if (options?.repetitionPenalty !== undefined) {
|
|
812
812
|
params.repetition_penalty = options.repetitionPenalty;
|
|
813
813
|
}
|
|
814
|
-
if (
|
|
814
|
+
if (shouldSendServiceTier(options?.serviceTier, model.provider)) {
|
|
815
815
|
params.service_tier = options.serviceTier;
|
|
816
816
|
}
|
|
817
817
|
|
|
@@ -11,13 +11,13 @@ import {
|
|
|
11
11
|
type AssistantMessage,
|
|
12
12
|
type CacheRetention,
|
|
13
13
|
type Context,
|
|
14
|
-
isSpecialServiceTier,
|
|
15
14
|
type MessageAttribution,
|
|
16
15
|
type Model,
|
|
17
16
|
type ProviderSessionState,
|
|
18
17
|
type ServiceTier,
|
|
19
18
|
type StreamFunction,
|
|
20
19
|
type StreamOptions,
|
|
20
|
+
shouldSendServiceTier,
|
|
21
21
|
type Tool,
|
|
22
22
|
type ToolChoice,
|
|
23
23
|
} from "../types";
|
|
@@ -384,7 +384,7 @@ function buildParams(
|
|
|
384
384
|
if (options?.repetitionPenalty !== undefined) {
|
|
385
385
|
params.repetition_penalty = options.repetitionPenalty;
|
|
386
386
|
}
|
|
387
|
-
if (
|
|
387
|
+
if (shouldSendServiceTier(options?.serviceTier, model.provider)) {
|
|
388
388
|
params.service_tier = options.serviceTier;
|
|
389
389
|
}
|
|
390
390
|
|
package/src/types.ts
CHANGED
|
@@ -152,7 +152,13 @@ export type CacheRetention = "none" | "short" | "long";
|
|
|
152
152
|
/** OpenAI service tier for processing priority. Only applies to OpenAI-compatible APIs. */
|
|
153
153
|
export type ServiceTier = "auto" | "default" | "flex" | "scale" | "priority";
|
|
154
154
|
|
|
155
|
-
export function
|
|
155
|
+
export function shouldSendServiceTier(
|
|
156
|
+
serviceTier?: ServiceTier | null,
|
|
157
|
+
provider?: Provider,
|
|
158
|
+
): serviceTier is "flex" | "scale" | "priority" {
|
|
159
|
+
if (provider !== "openai" && provider !== "openai-codex") {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
156
162
|
return serviceTier === "flex" || serviceTier === "scale" || serviceTier === "priority";
|
|
157
163
|
}
|
|
158
164
|
|
package/src/utils/validation.ts
CHANGED
|
@@ -585,6 +585,26 @@ function normalizeOptionalNullsForSchema(schema: unknown, value: unknown): { val
|
|
|
585
585
|
nextValue[key] = normalized.value;
|
|
586
586
|
}
|
|
587
587
|
|
|
588
|
+
// Strip unknown keys with null/"null" values when the schema forbids extras.
|
|
589
|
+
// LLMs sometimes hallucinate verbs alongside valid ones (e.g. `split: null`,
|
|
590
|
+
// `original: null`). Rejecting the entire tool call wastes a turn; treating
|
|
591
|
+
// these the same as null on known optional fields is a safer fallback. Keys
|
|
592
|
+
// with non-null unknown values are left intact so genuine schema mistakes
|
|
593
|
+
// still surface as validation errors.
|
|
594
|
+
if (schemaObject.additionalProperties === false) {
|
|
595
|
+
const knownKeys = new Set(Object.keys(properties));
|
|
596
|
+
for (const key of Object.keys(nextValue)) {
|
|
597
|
+
if (knownKeys.has(key)) continue;
|
|
598
|
+
const v = nextValue[key];
|
|
599
|
+
if (v !== null && v !== "null") continue;
|
|
600
|
+
if (!changed) {
|
|
601
|
+
nextValue = { ...nextValue };
|
|
602
|
+
changed = true;
|
|
603
|
+
}
|
|
604
|
+
delete nextValue[key];
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
588
608
|
return { value: changed ? nextValue : value, changed };
|
|
589
609
|
}
|
|
590
610
|
|