@oh-my-pi/pi-ai 17.2.2 → 17.2.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/CHANGELOG.md +11 -0
- package/dist/types/registry/aiand.d.ts +7 -0
- package/dist/types/registry/registry.d.ts +4 -0
- package/package.json +4 -4
- package/src/providers/anthropic.ts +7 -12
- package/src/providers/openai-codex-responses.ts +3 -2
- package/src/registry/aiand.ts +22 -0
- package/src/registry/registry.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [17.2.3] - 2026-08-01
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added the ai& (`aiand`) provider registry entry with API-key paste login validated against `https://api.aiand.com/v1/models`.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Fixed Anthropic OAuth (Claude Pro/Max subscription) requests hard-429ing (`Usage credits are required for long context requests`) on every beta-gated 1M model — e.g. `claude-sonnet-4-6`, which the default `task`/`smol`/`scout` subagent roles resolve to — regardless of prompt size, breaking all subagents. The 17.2.1 cowork request profile reintroduced the `context-1m-2025-08-07` beta for any model with a 1M catalog window, but subscription credentials have no long-context credit balance so Anthropic rejects the request outright. The beta is no longer advertised on OAuth requests; subscription accounts transparently get the standard 200k window. ([#7238](https://github.com/can1357/oh-my-pi/issues/7238))
|
|
14
|
+
- Fixed OpenAI Codex Responses ignoring disabled cache retention when deriving `prompt_cache_key`, while preserving transport session identity ([#7219](https://github.com/can1357/oh-my-pi/issues/7219)).
|
|
15
|
+
|
|
5
16
|
## [17.2.2] - 2026-07-31
|
|
6
17
|
|
|
7
18
|
### Added
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { OAuthLoginCallbacks } from "./oauth/types.js";
|
|
2
|
+
export declare const loginAiand: (options: import("./oauth/index.js").OAuthController) => Promise<string>;
|
|
3
|
+
export declare const aiandProvider: {
|
|
4
|
+
readonly id: "aiand";
|
|
5
|
+
readonly name: "ai&";
|
|
6
|
+
readonly login: (cb: OAuthLoginCallbacks) => Promise<string>;
|
|
7
|
+
};
|
|
@@ -7,6 +7,10 @@ import type { ProviderDefinition } from "./types.js";
|
|
|
7
7
|
* list for the loginable providers; non-login model providers are appended.
|
|
8
8
|
*/
|
|
9
9
|
declare const ALL: ({
|
|
10
|
+
readonly id: "aiand";
|
|
11
|
+
readonly name: "ai&";
|
|
12
|
+
readonly login: (cb: import("./oauth/index.js").OAuthLoginCallbacks) => Promise<string>;
|
|
13
|
+
} | {
|
|
10
14
|
readonly id: "aimlapi";
|
|
11
15
|
readonly name: "AIML API";
|
|
12
16
|
} | {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-ai",
|
|
4
|
-
"version": "17.2.
|
|
4
|
+
"version": "17.2.3",
|
|
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.1",
|
|
41
|
-
"@oh-my-pi/pi-catalog": "17.2.
|
|
42
|
-
"@oh-my-pi/pi-utils": "17.2.
|
|
43
|
-
"@oh-my-pi/pi-wire": "17.2.
|
|
41
|
+
"@oh-my-pi/pi-catalog": "17.2.3",
|
|
42
|
+
"@oh-my-pi/pi-utils": "17.2.3",
|
|
43
|
+
"@oh-my-pi/pi-wire": "17.2.3",
|
|
44
44
|
"arktype": "2.2.3",
|
|
45
45
|
"zod": "^4"
|
|
46
46
|
},
|
|
@@ -157,7 +157,6 @@ function mergeAnthropicBetaHeader(callerHeaders: Record<string, string>, beta: s
|
|
|
157
157
|
const midConversationSystemBeta = "mid-conversation-system-2026-04-07";
|
|
158
158
|
const contextManagementBeta = "context-management-2025-06-27";
|
|
159
159
|
const structuredOutputsBeta = "structured-outputs-2025-12-15";
|
|
160
|
-
const context1mBeta = "context-1m-2025-08-07";
|
|
161
160
|
const thinkingTokenCountBeta = "thinking-token-count-2026-05-13";
|
|
162
161
|
const fallbackCreditBeta = "fallback-credit-2026-06-01";
|
|
163
162
|
const coworkUtilityBetaDefaults = [
|
|
@@ -187,15 +186,18 @@ const serverSideFallbackBeta = "server-side-fallback-2026-06-01";
|
|
|
187
186
|
function buildCoworkBetas(
|
|
188
187
|
agentRequest: boolean,
|
|
189
188
|
thinkingRequest: boolean,
|
|
190
|
-
longContext: boolean,
|
|
191
189
|
disableStrictTools = false,
|
|
192
190
|
): readonly string[] {
|
|
191
|
+
// `context-1m-2025-08-07` is intentionally never advertised. OAuth
|
|
192
|
+
// subscription credentials have no long-context credit balance, so Anthropic
|
|
193
|
+
// hard-429s ("Usage credits are required for long context requests") on any
|
|
194
|
+
// beta-gated 1M model regardless of prompt size (#7238). Natively-1M models
|
|
195
|
+
// (e.g. claude-sonnet-5) serve their full window without the beta anyway.
|
|
193
196
|
if (!agentRequest && !disableStrictTools) return coworkUtilityBetaDefaults;
|
|
194
197
|
const betas: string[] = [];
|
|
195
198
|
for (const beta of agentRequest ? coworkAgentBetaDefaults : coworkUtilityBetaDefaults) {
|
|
196
199
|
if (disableStrictTools && beta === structuredOutputsBeta) continue;
|
|
197
200
|
betas.push(beta);
|
|
198
|
-
if (agentRequest && longContext && beta === "claude-code-20250219") betas.push(context1mBeta);
|
|
199
201
|
}
|
|
200
202
|
if (!agentRequest) return betas;
|
|
201
203
|
if (thinkingRequest) betas.push(effortBeta);
|
|
@@ -245,7 +247,7 @@ export function buildAnthropicHeaders(options: AnthropicHeaderOptions): Record<s
|
|
|
245
247
|
// Cowork's beta profile is part of the OAuth fingerprint; API-key requests
|
|
246
248
|
// default to extras only, matching the streaming path.
|
|
247
249
|
const betaHeader = buildBetaHeader(
|
|
248
|
-
options.coworkBetas ?? (oauthToken ? buildCoworkBetas(true, true
|
|
250
|
+
options.coworkBetas ?? (oauthToken ? buildCoworkBetas(true, true) : []),
|
|
249
251
|
extraBetas,
|
|
250
252
|
);
|
|
251
253
|
const acceptHeader = oauthToken ? "application/json" : stream ? "text/event-stream" : "application/json";
|
|
@@ -2949,14 +2951,7 @@ export function buildAnthropicClientOptions(args: AnthropicClientOptionsArgs): A
|
|
|
2949
2951
|
isCloudflareAiGateway: model.provider === "cloudflare-ai-gateway",
|
|
2950
2952
|
allowAnthropicHeaderOverrides: model.compat.allowAnthropicHeaderOverrides,
|
|
2951
2953
|
claudeCodeSessionId,
|
|
2952
|
-
coworkBetas: oauthToken
|
|
2953
|
-
? buildCoworkBetas(
|
|
2954
|
-
hasTools || thinkingEnabled,
|
|
2955
|
-
thinkingEnabled,
|
|
2956
|
-
(model.contextWindow ?? 0) >= 1_000_000,
|
|
2957
|
-
disableStrictTools,
|
|
2958
|
-
)
|
|
2959
|
-
: [],
|
|
2954
|
+
coworkBetas: oauthToken ? buildCoworkBetas(hasTools || thinkingEnabled, thinkingEnabled, disableStrictTools) : [],
|
|
2960
2955
|
});
|
|
2961
2956
|
|
|
2962
2957
|
if (model.provider === "cloudflare-ai-gateway") {
|
|
@@ -111,6 +111,7 @@ import {
|
|
|
111
111
|
finalizePendingResponsesToolCalls,
|
|
112
112
|
finalizeReasoningThinking,
|
|
113
113
|
finalizeToolCallArgumentsDone,
|
|
114
|
+
getOpenAIPromptCacheKey,
|
|
114
115
|
hasExecutableIncompleteResponsesToolCalls,
|
|
115
116
|
isOpenAIResponsesProgressEvent,
|
|
116
117
|
mapOpenAIResponsesStopReason,
|
|
@@ -1373,7 +1374,7 @@ async function buildCodexRequestContext(
|
|
|
1373
1374
|
const accountId = getCodexAccountId(apiKey);
|
|
1374
1375
|
const baseUrl = model.baseUrl || CODEX_BASE_URL;
|
|
1375
1376
|
const url = resolveCodexResponsesUrl(baseUrl);
|
|
1376
|
-
const promptCacheKey =
|
|
1377
|
+
const promptCacheKey = getOpenAIPromptCacheKey(options);
|
|
1377
1378
|
const transportSessionId = normalizeOpenAIPromptCacheKey(options?.sessionId);
|
|
1378
1379
|
const codexClientVersion = CODEX_CLIENT_VERSION;
|
|
1379
1380
|
const transformedBody = await buildTransformedCodexRequestBody(model, context, options, promptCacheKey);
|
|
@@ -1463,7 +1464,7 @@ export async function buildTransformedCodexRequestBody(
|
|
|
1463
1464
|
model: Model<"openai-codex-responses">,
|
|
1464
1465
|
context: Context,
|
|
1465
1466
|
options: OpenAICodexResponsesOptions | undefined,
|
|
1466
|
-
promptCacheKey =
|
|
1467
|
+
promptCacheKey = getOpenAIPromptCacheKey(options),
|
|
1467
1468
|
): Promise<RequestBody> {
|
|
1468
1469
|
const params: RequestBody = {
|
|
1469
1470
|
model: model.requestModelId ?? model.id,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createApiKeyLogin } from "./api-key-login";
|
|
2
|
+
import type { OAuthLoginCallbacks } from "./oauth/types";
|
|
3
|
+
import type { ProviderDefinition } from "./types";
|
|
4
|
+
|
|
5
|
+
export const loginAiand = createApiKeyLogin({
|
|
6
|
+
providerLabel: "ai&",
|
|
7
|
+
authUrl: "https://console.aiand.com/api-keys",
|
|
8
|
+
instructions: "Copy your API key from the ai& console",
|
|
9
|
+
promptMessage: "Paste your ai& API key",
|
|
10
|
+
placeholder: "sk-...",
|
|
11
|
+
validation: {
|
|
12
|
+
kind: "models-endpoint",
|
|
13
|
+
provider: "ai&",
|
|
14
|
+
modelsUrl: "https://api.aiand.com/v1/models",
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const aiandProvider = {
|
|
19
|
+
id: "aiand",
|
|
20
|
+
name: "ai&",
|
|
21
|
+
login: (cb: OAuthLoginCallbacks) => loginAiand(cb),
|
|
22
|
+
} as const satisfies ProviderDefinition;
|
package/src/registry/registry.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { KnownProvider } from "@oh-my-pi/pi-catalog";
|
|
2
|
+
import { aiandProvider } from "./aiand";
|
|
2
3
|
import { aimlApiProvider } from "./aimlapi";
|
|
3
4
|
import { alibabaCodingPlanProvider } from "./alibaba-coding-plan";
|
|
4
5
|
import { alibabaTokenPlanProvider } from "./alibaba-token-plan";
|
|
@@ -101,6 +102,7 @@ const ALL = [
|
|
|
101
102
|
gitLabDuoWorkflowProvider,
|
|
102
103
|
alibabaCodingPlanProvider,
|
|
103
104
|
alibabaTokenPlanProvider,
|
|
105
|
+
aiandProvider,
|
|
104
106
|
aimlApiProvider,
|
|
105
107
|
zhipuCodingPlanProvider,
|
|
106
108
|
umansProvider,
|