@oh-my-pi/pi-ai 16.3.0 → 16.3.2
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 +6 -0
- package/dist/types/providers/openai-responses.d.ts +2 -3
- package/dist/types/providers/openai-shared.d.ts +2 -2
- package/package.json +4 -4
- package/src/providers/azure-openai-responses.ts +1 -1
- package/src/providers/openai-responses.ts +12 -40
- package/src/providers/openai-shared.ts +8 -30
- package/src/providers/openai-responses-reasoning-suppression.md +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -64,8 +64,8 @@ interface OpenAIResponsesProviderSessionState extends ProviderSessionState, Open
|
|
|
64
64
|
}
|
|
65
65
|
interface OpenAIResponsesChainState {
|
|
66
66
|
/**
|
|
67
|
-
* Wire params of the last successful turn
|
|
68
|
-
*
|
|
67
|
+
* Wire params of the last successful turn; never carries
|
|
68
|
+
* `previous_response_id`.
|
|
69
69
|
*/
|
|
70
70
|
lastParams?: OpenAIResponsesSamplingParams;
|
|
71
71
|
lastResponseId?: string;
|
|
@@ -108,7 +108,6 @@ type OpenAIResponsesSamplingParams = ResponseCreateParamsStreaming & {
|
|
|
108
108
|
export declare const streamOpenAIResponses: StreamFunction<"openai-responses">;
|
|
109
109
|
export declare function buildParams(model: Model<"openai-responses">, context: Context, options: OpenAIResponsesOptions | undefined, providerSessionState: OpenAIResponsesProviderSessionState | undefined, strictToolsScope?: OpenAIStrictToolsScope, disableStrictToolsOverride?: boolean): {
|
|
110
110
|
params: OpenAIResponsesSamplingParams;
|
|
111
|
-
trailingScaffoldingItems: number;
|
|
112
111
|
strictToolsApplied: boolean;
|
|
113
112
|
};
|
|
114
113
|
/**
|
|
@@ -465,12 +465,12 @@ export interface ApplyResponsesCompatPolicyOptions {
|
|
|
465
465
|
reasoningSummary?: "auto" | "detailed" | "concise" | null;
|
|
466
466
|
mapEffort?: (effort: string) => string;
|
|
467
467
|
}
|
|
468
|
-
export declare function applyResponsesCompatPolicy<P extends ResponseCreateParamsStreaming>(params: P,
|
|
468
|
+
export declare function applyResponsesCompatPolicy<P extends ResponseCreateParamsStreaming>(params: P, policy: OpenAICompatPolicy, options: ApplyResponsesCompatPolicyOptions | undefined): void;
|
|
469
469
|
/**
|
|
470
470
|
* Apply reasoning-related Responses parameters. Default behavior comes from
|
|
471
471
|
* catalog compat; include/omit arguments are explicit adapter-wrapper overrides.
|
|
472
472
|
*/
|
|
473
|
-
export declare function applyResponsesReasoningParams<P extends ResponseCreateParamsStreaming>(params: P, model: Model<"openai-responses" | "azure-openai-responses" | "openai-codex-responses">, options: ReasoningOptions | undefined,
|
|
473
|
+
export declare function applyResponsesReasoningParams<P extends ResponseCreateParamsStreaming>(params: P, model: Model<"openai-responses" | "azure-openai-responses" | "openai-codex-responses">, options: ReasoningOptions | undefined, mapEffort?: (effort: string) => string, includeEncryptedReasoning?: boolean, omitReasoningEffort?: boolean): void;
|
|
474
474
|
/** Populate `output.usage` from a Responses-API `response.usage` payload. Does not invoke `calculateCost`. */
|
|
475
475
|
export declare function populateResponsesUsageFromResponse(output: AssistantMessage, usage: {
|
|
476
476
|
input_tokens?: number | null;
|
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.
|
|
4
|
+
"version": "16.3.2",
|
|
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.
|
|
42
|
-
"@oh-my-pi/pi-utils": "16.3.
|
|
43
|
-
"@oh-my-pi/pi-wire": "16.3.
|
|
41
|
+
"@oh-my-pi/pi-catalog": "16.3.2",
|
|
42
|
+
"@oh-my-pi/pi-utils": "16.3.2",
|
|
43
|
+
"@oh-my-pi/pi-wire": "16.3.2",
|
|
44
44
|
"arktype": "^2.2.0",
|
|
45
45
|
"zod": "^4"
|
|
46
46
|
},
|
|
@@ -166,8 +166,8 @@ interface OpenAIResponsesProviderSessionState
|
|
|
166
166
|
|
|
167
167
|
interface OpenAIResponsesChainState {
|
|
168
168
|
/**
|
|
169
|
-
* Wire params of the last successful turn
|
|
170
|
-
*
|
|
169
|
+
* Wire params of the last successful turn; never carries
|
|
170
|
+
* `previous_response_id`.
|
|
171
171
|
*/
|
|
172
172
|
lastParams?: OpenAIResponsesSamplingParams;
|
|
173
173
|
lastResponseId?: string;
|
|
@@ -256,30 +256,19 @@ interface OpenAIResponsesChainedParams {
|
|
|
256
256
|
* (same options, strict history prefix), chain via `previous_response_id` +
|
|
257
257
|
* delta-only `input`; otherwise break the chain and replay the full transcript.
|
|
258
258
|
*
|
|
259
|
-
* The prefix check runs on the wire form of the conversation arguments
|
|
260
|
-
*
|
|
261
|
-
* the delta, so a decoration that trails every request can never masquerade as
|
|
262
|
-
* a history mutation.
|
|
259
|
+
* The prefix check runs on the wire form of the conversation arguments, so
|
|
260
|
+
* history mutations or option changes force a full replay.
|
|
263
261
|
*/
|
|
264
262
|
function buildOpenAIResponsesChainedParams(
|
|
265
263
|
params: OpenAIResponsesSamplingParams,
|
|
266
|
-
trailingScaffoldingItems: number,
|
|
267
264
|
chain: OpenAIResponsesChainState,
|
|
268
265
|
): OpenAIResponsesChainedParams {
|
|
269
|
-
const historyParams =
|
|
270
|
-
trailingScaffoldingItems > 0 && Array.isArray(params.input)
|
|
271
|
-
? { ...params, input: params.input.slice(0, params.input.length - trailingScaffoldingItems) }
|
|
272
|
-
: params;
|
|
273
266
|
const deltaInput = chain.canAppend
|
|
274
|
-
? buildResponsesDeltaInput(chain.lastParams, chain.lastResponseItems,
|
|
267
|
+
? buildResponsesDeltaInput(chain.lastParams, chain.lastResponseItems, params)
|
|
275
268
|
: null;
|
|
276
269
|
if (deltaInput && deltaInput.length > 0 && chain.lastResponseId) {
|
|
277
|
-
const scaffolding =
|
|
278
|
-
historyParams !== params && Array.isArray(params.input)
|
|
279
|
-
? params.input.slice(params.input.length - trailingScaffoldingItems)
|
|
280
|
-
: [];
|
|
281
270
|
return {
|
|
282
|
-
params: { ...params, previous_response_id: chain.lastResponseId, input:
|
|
271
|
+
params: { ...params, previous_response_id: chain.lastResponseId, input: deltaInput },
|
|
283
272
|
previousResponseId: chain.lastResponseId,
|
|
284
273
|
};
|
|
285
274
|
}
|
|
@@ -416,9 +405,7 @@ const streamOpenAIResponsesOnce = (
|
|
|
416
405
|
const strictToolsScope = getOpenAIStrictToolsScope(model, baseUrl);
|
|
417
406
|
const builtParams = buildParams(model, context, options, providerSessionState, strictToolsScope);
|
|
418
407
|
const params = builtParams.params;
|
|
419
|
-
const { trailingScaffoldingItems } = builtParams;
|
|
420
408
|
let activeParams = params;
|
|
421
|
-
let activeTrailingScaffoldingItems = trailingScaffoldingItems;
|
|
422
409
|
const resolvedBaseUrl = (baseUrl ?? "https://api.openai.com/v1").replace(/\/+$/, "");
|
|
423
410
|
const requestReasoningEffortFallbacks = new Map<string, OpenAIReasoningEffortFallback>();
|
|
424
411
|
const attemptedReasoningEffortFallbacks = new Set<string>();
|
|
@@ -448,9 +435,7 @@ const streamOpenAIResponsesOnce = (
|
|
|
448
435
|
}
|
|
449
436
|
applyReasoningEffortFallbackForRequest(params);
|
|
450
437
|
let chained: OpenAIResponsesChainedParams =
|
|
451
|
-
chainState && !chainState.disabled
|
|
452
|
-
? buildOpenAIResponsesChainedParams(params, trailingScaffoldingItems, chainState)
|
|
453
|
-
: { params };
|
|
438
|
+
chainState && !chainState.disabled ? buildOpenAIResponsesChainedParams(params, chainState) : { params };
|
|
454
439
|
sentPreviousResponseId = chained.previousResponseId;
|
|
455
440
|
const idleTimeoutMs =
|
|
456
441
|
options?.streamIdleTimeoutMs ?? getOpenAIStreamIdleTimeoutMs(model.compat.streamIdleTimeoutMs);
|
|
@@ -589,11 +574,7 @@ const streamOpenAIResponsesOnce = (
|
|
|
589
574
|
if (chainState && !chainState.disabled) fallbackParams.store = true;
|
|
590
575
|
let fallbackChained: OpenAIResponsesChainedParams =
|
|
591
576
|
chainState && !chainState.disabled
|
|
592
|
-
? buildOpenAIResponsesChainedParams(
|
|
593
|
-
fallbackParams,
|
|
594
|
-
fallbackBuilt.trailingScaffoldingItems,
|
|
595
|
-
chainState,
|
|
596
|
-
)
|
|
577
|
+
? buildOpenAIResponsesChainedParams(fallbackParams, chainState)
|
|
597
578
|
: { params: fallbackParams };
|
|
598
579
|
sentPreviousResponseId = fallbackChained.previousResponseId;
|
|
599
580
|
fallbackChained = {
|
|
@@ -603,7 +584,6 @@ const streamOpenAIResponsesOnce = (
|
|
|
603
584
|
chained = fallbackChained;
|
|
604
585
|
rawRequestDump.body = chained.params;
|
|
605
586
|
activeParams = fallbackParams;
|
|
606
|
-
activeTrailingScaffoldingItems = fallbackBuilt.trailingScaffoldingItems;
|
|
607
587
|
activeStrictToolsApplied = fallbackBuilt.strictToolsApplied;
|
|
608
588
|
continue;
|
|
609
589
|
}
|
|
@@ -646,7 +626,6 @@ const streamOpenAIResponsesOnce = (
|
|
|
646
626
|
chained = { params: retryParams };
|
|
647
627
|
rawRequestDump.body = retryParams;
|
|
648
628
|
activeParams = currentParams;
|
|
649
|
-
activeTrailingScaffoldingItems = currentBuilt.trailingScaffoldingItems;
|
|
650
629
|
activeStrictToolsApplied = currentBuilt.strictToolsApplied;
|
|
651
630
|
}
|
|
652
631
|
}
|
|
@@ -710,14 +689,7 @@ const streamOpenAIResponsesOnce = (
|
|
|
710
689
|
output.providerPayload = createOpenAIResponsesHistoryPayload(model.provider, nativeOutputItems);
|
|
711
690
|
if (providerSessionState) providerSessionState.nativeHistoryReplayWarmed = true;
|
|
712
691
|
if (chainState) {
|
|
713
|
-
chainState.lastParams = structuredCloneJSON(
|
|
714
|
-
activeTrailingScaffoldingItems > 0 && Array.isArray(activeParams.input)
|
|
715
|
-
? {
|
|
716
|
-
...activeParams,
|
|
717
|
-
input: activeParams.input.slice(0, activeParams.input.length - activeTrailingScaffoldingItems),
|
|
718
|
-
}
|
|
719
|
-
: activeParams,
|
|
720
|
-
);
|
|
692
|
+
chainState.lastParams = structuredCloneJSON(activeParams);
|
|
721
693
|
if (output.responseId) {
|
|
722
694
|
chainState.lastResponseId = output.responseId;
|
|
723
695
|
chainState.lastResponseItems = sanitizeOpenAIResponsesHistoryItemsForReplay(
|
|
@@ -790,7 +762,7 @@ export function buildParams(
|
|
|
790
762
|
providerSessionState: OpenAIResponsesProviderSessionState | undefined,
|
|
791
763
|
strictToolsScope?: OpenAIStrictToolsScope,
|
|
792
764
|
disableStrictToolsOverride = false,
|
|
793
|
-
): { params: OpenAIResponsesSamplingParams;
|
|
765
|
+
): { params: OpenAIResponsesSamplingParams; strictToolsApplied: boolean } {
|
|
794
766
|
const policy = resolveOpenAICompatPolicy(model, {
|
|
795
767
|
endpoint: "responses",
|
|
796
768
|
reasoning: options?.reasoning,
|
|
@@ -914,7 +886,7 @@ export function buildParams(
|
|
|
914
886
|
filterReasoningHistory: options?.filterReasoningHistory,
|
|
915
887
|
omitReasoningEffort: options?.omitReasoningEffort,
|
|
916
888
|
});
|
|
917
|
-
|
|
889
|
+
applyResponsesCompatPolicy(params, reasoningPolicy, {
|
|
918
890
|
reasoningSummary: options?.reasoningSummary,
|
|
919
891
|
mapEffort: effort =>
|
|
920
892
|
model.compat.reasoningEffortMap?.[effort as NonNullable<OpenAIResponsesOptions["reasoning"]>] ??
|
|
@@ -926,7 +898,7 @@ export function buildParams(
|
|
|
926
898
|
|
|
927
899
|
applyOpenAIExtraBody(params, options?.extraBody);
|
|
928
900
|
|
|
929
|
-
return { params,
|
|
901
|
+
return { params, strictToolsApplied };
|
|
930
902
|
}
|
|
931
903
|
|
|
932
904
|
/**
|
|
@@ -76,7 +76,6 @@ import {
|
|
|
76
76
|
} from "./github-copilot-headers";
|
|
77
77
|
import type { ChatCompletionCreateParamsStreaming } from "./openai-chat-wire";
|
|
78
78
|
import type { InputItem } from "./openai-codex/request-transformer";
|
|
79
|
-
import responsesReasoningSuppressionPrompt from "./openai-responses-reasoning-suppression.md" with { type: "text" };
|
|
80
79
|
import type {
|
|
81
80
|
ResponseContentPartAddedEvent,
|
|
82
81
|
ResponseCreateParamsStreaming,
|
|
@@ -2404,8 +2403,6 @@ export function applyCommonResponsesSamplingParams<P extends CommonResponsesPara
|
|
|
2404
2403
|
applyOpenAIServiceTier(params, options?.serviceTier, model.provider);
|
|
2405
2404
|
}
|
|
2406
2405
|
|
|
2407
|
-
const RESPONSES_REASONING_SUPPRESSION_PROMPT = responsesReasoningSuppressionPrompt.trim();
|
|
2408
|
-
|
|
2409
2406
|
type ReasoningOptions = {
|
|
2410
2407
|
reasoning?: string;
|
|
2411
2408
|
reasoningSummary?: "auto" | "detailed" | "concise" | null;
|
|
@@ -2420,12 +2417,11 @@ export interface ApplyResponsesCompatPolicyOptions {
|
|
|
2420
2417
|
|
|
2421
2418
|
export function applyResponsesCompatPolicy<P extends ResponseCreateParamsStreaming>(
|
|
2422
2419
|
params: P,
|
|
2423
|
-
messages: ResponseInput,
|
|
2424
2420
|
policy: OpenAICompatPolicy,
|
|
2425
2421
|
options: ApplyResponsesCompatPolicyOptions | undefined,
|
|
2426
|
-
):
|
|
2422
|
+
): void {
|
|
2427
2423
|
const reasoning = policy.reasoning;
|
|
2428
|
-
if (!reasoning.modelSupported) return
|
|
2424
|
+
if (!reasoning.modelSupported) return;
|
|
2429
2425
|
if (reasoning.includeEncryptedReasoning) {
|
|
2430
2426
|
const include = params.include ?? [];
|
|
2431
2427
|
if (!include.includes("reasoning.encrypted_content")) include.push("reasoning.encrypted_content");
|
|
@@ -2435,7 +2431,7 @@ export function applyResponsesCompatPolicy<P extends ResponseCreateParamsStreami
|
|
|
2435
2431
|
if (reasoning.disabled) {
|
|
2436
2432
|
if (reasoning.disableMode === "openrouter-enabled-false") {
|
|
2437
2433
|
params.reasoning = { enabled: false } as P["reasoning"];
|
|
2438
|
-
return
|
|
2434
|
+
return;
|
|
2439
2435
|
}
|
|
2440
2436
|
if (
|
|
2441
2437
|
reasoning.disableMode === "lowest-effort" &&
|
|
@@ -2445,16 +2441,9 @@ export function applyResponsesCompatPolicy<P extends ResponseCreateParamsStreami
|
|
|
2445
2441
|
type ReasoningParam = NonNullable<ResponseCreateParamsStreaming["reasoning"]>;
|
|
2446
2442
|
params.reasoning = { effort: reasoning.wireEffort as ReasoningParam["effort"] } as P["reasoning"] &
|
|
2447
2443
|
ReasoningParam;
|
|
2448
|
-
return
|
|
2449
|
-
}
|
|
2450
|
-
if (policy.compat.requiresReasoningSuppressionPrompt && reasoning.requestedEffort === undefined) {
|
|
2451
|
-
messages.push({
|
|
2452
|
-
role: "developer",
|
|
2453
|
-
content: [{ type: "input_text", text: RESPONSES_REASONING_SUPPRESSION_PROMPT }],
|
|
2454
|
-
});
|
|
2455
|
-
return 1;
|
|
2444
|
+
return;
|
|
2456
2445
|
}
|
|
2457
|
-
return
|
|
2446
|
+
return;
|
|
2458
2447
|
}
|
|
2459
2448
|
|
|
2460
2449
|
if (reasoning.requestedEffort !== undefined || options?.reasoningSummary !== undefined) {
|
|
@@ -2463,7 +2452,7 @@ export function applyResponsesCompatPolicy<P extends ResponseCreateParamsStreami
|
|
|
2463
2452
|
type ReasoningParam = NonNullable<ResponseCreateParamsStreaming["reasoning"]>;
|
|
2464
2453
|
params.reasoning = { summary: options.reasoningSummary || "auto" } as P["reasoning"] & ReasoningParam;
|
|
2465
2454
|
}
|
|
2466
|
-
return
|
|
2455
|
+
return;
|
|
2467
2456
|
}
|
|
2468
2457
|
|
|
2469
2458
|
const requested = reasoning.requestedEffort ?? "medium";
|
|
@@ -2476,17 +2465,8 @@ export function applyResponsesCompatPolicy<P extends ResponseCreateParamsStreami
|
|
|
2476
2465
|
reasoningParams.summary = options?.reasoningSummary || "auto";
|
|
2477
2466
|
}
|
|
2478
2467
|
params.reasoning = reasoningParams as P["reasoning"];
|
|
2479
|
-
return
|
|
2480
|
-
}
|
|
2481
|
-
|
|
2482
|
-
if (policy.compat.requiresReasoningSuppressionPrompt) {
|
|
2483
|
-
messages.push({
|
|
2484
|
-
role: "developer",
|
|
2485
|
-
content: [{ type: "input_text", text: RESPONSES_REASONING_SUPPRESSION_PROMPT }],
|
|
2486
|
-
});
|
|
2487
|
-
return 1;
|
|
2468
|
+
return;
|
|
2488
2469
|
}
|
|
2489
|
-
return 0;
|
|
2490
2470
|
}
|
|
2491
2471
|
|
|
2492
2472
|
/**
|
|
@@ -2497,14 +2477,12 @@ export function applyResponsesReasoningParams<P extends ResponseCreateParamsStre
|
|
|
2497
2477
|
params: P,
|
|
2498
2478
|
model: Model<"openai-responses" | "azure-openai-responses" | "openai-codex-responses">,
|
|
2499
2479
|
options: ReasoningOptions | undefined,
|
|
2500
|
-
messages: ResponseInput,
|
|
2501
2480
|
mapEffort?: (effort: string) => string,
|
|
2502
2481
|
includeEncryptedReasoning?: boolean,
|
|
2503
2482
|
omitReasoningEffort?: boolean,
|
|
2504
|
-
):
|
|
2483
|
+
): void {
|
|
2505
2484
|
return applyResponsesCompatPolicy(
|
|
2506
2485
|
params,
|
|
2507
|
-
messages,
|
|
2508
2486
|
resolveOpenAICompatPolicy(model, {
|
|
2509
2487
|
endpoint: "responses",
|
|
2510
2488
|
reasoning: options?.reasoning,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Keep internal reasoning brief. Continue following the task and use tools normally.
|