@gajae-code/ai 0.11.6 → 0.11.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 +9 -0
- package/dist/types/provider-models/openai-compat.d.ts +2 -2
- package/dist/types/types.d.ts +1 -1
- package/dist/types/utils/oauth/alibaba-token-plan.d.ts +19 -0
- package/dist/types/utils/oauth/types.d.ts +1 -1
- package/package.json +2 -2
- package/src/auth-storage.ts +3 -3
- package/src/model-thinking.ts +11 -3
- package/src/models.json +5362 -1219
- package/src/provider-models/descriptors.ts +5 -6
- package/src/provider-models/openai-compat.ts +12 -12
- package/src/providers/amazon-bedrock.ts +4 -0
- package/src/providers/anthropic.ts +34 -1
- package/src/providers/openai-completions-compat.ts +2 -2
- package/src/stream.ts +1 -1
- package/src/types.ts +1 -1
- package/src/utils/oauth/{alibaba-coding-plan.ts → alibaba-token-plan.ts} +12 -11
- package/src/utils/oauth/index.ts +3 -2
- package/src/utils/oauth/types.ts +1 -1
- package/dist/types/utils/oauth/alibaba-coding-plan.d.ts +0 -18
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.11.7] - 2026-07-22
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Replaced the `alibaba-coding-plan` provider with first-class `alibaba-token-plan` support. The `/login` OAuth list, provider descriptor, model manager, models.dev descriptor, and bundled `models.json` now target the maintained Alibaba Token Plan endpoint (`https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1`, env `ALIBABA_TOKEN_PLAN_API_KEY`) and validate logins against `deepseek-v4-pro`. The retired `alibaba-coding-plan` provider pointed at `coding-intl.dashscope.aliyuncs.com`, which rejected real token-plan keys with 401 and was the only Alibaba entry exposed in `/login`.
|
|
10
|
+
|
|
5
11
|
## [0.11.4] - 2026-07-20
|
|
6
12
|
|
|
7
13
|
### Added
|
|
@@ -32,6 +38,9 @@
|
|
|
32
38
|
### Fixed
|
|
33
39
|
|
|
34
40
|
- Fixed frequent `Request blocked (code=invalid_prompt)` failures on gpt-5.6 (Sol/Terra/Luna) subagent, default-agent, and compaction turns (ref openai/codex#32028, oh-my-pi#5184). Leaked Harmony control-token markers (e.g. `<|channel|>analysis`) were only neutralized on the replayed-history payload path, so markers in assistant reasoning summaries, live-converted message/tool-output text, and user-authored content reached the OpenAI Responses and OpenAI-codex-responses transports verbatim and wedged the session (the poisoned item was re-sent every turn). Both transports now neutralize reserved control tokens across the entire outgoing `input` array at the request boundary via an idempotent zero-width-space insertion that keeps the text human-readable.
|
|
41
|
+
### Fixed
|
|
42
|
+
|
|
43
|
+
- Fixed Fable 5 adaptive thinking being billed but never displayed: model discovery now classifies `claude-fable-*` as `anthropic-adaptive` (was cached as `budget`, sending `enabled`+`budget_tokens` that Fable answers with signature-only thinking), and `supportsAdaptiveThinkingDisplay` opts Fable into `display: "summarized"` on both Anthropic Messages and Bedrock Converse transports (#2791).
|
|
35
44
|
|
|
36
45
|
## [0.10.0] - 2026-07-12
|
|
37
46
|
### Fixed
|
|
@@ -116,11 +116,11 @@ export interface KiloModelManagerConfig {
|
|
|
116
116
|
baseUrl?: string;
|
|
117
117
|
}
|
|
118
118
|
export declare function kiloModelManagerOptions(config?: KiloModelManagerConfig): ModelManagerOptions<"openai-completions">;
|
|
119
|
-
export interface
|
|
119
|
+
export interface AlibabaTokenPlanModelManagerConfig {
|
|
120
120
|
apiKey?: string;
|
|
121
121
|
baseUrl?: string;
|
|
122
122
|
}
|
|
123
|
-
export declare function
|
|
123
|
+
export declare function alibabaTokenPlanModelManagerOptions(config?: AlibabaTokenPlanModelManagerConfig): ModelManagerOptions<"openai-completions">;
|
|
124
124
|
export interface VercelAiGatewayModelManagerConfig {
|
|
125
125
|
apiKey?: string;
|
|
126
126
|
baseUrl?: string;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -51,7 +51,7 @@ export interface ThinkingConfig {
|
|
|
51
51
|
/** Provider-specific transport used to encode the selected effort. */
|
|
52
52
|
mode: ThinkingControlMode;
|
|
53
53
|
}
|
|
54
|
-
export type KnownProvider = "alibaba-
|
|
54
|
+
export type KnownProvider = "alibaba-token-plan" | "amazon-bedrock" | "azure-openai" | "anthropic" | "google" | "google-gemini-cli" | "google-antigravity" | "google-vertex" | "openai" | "openai-codex" | "kimi-code" | "minimax-code" | "minimax-code-cn" | "github-copilot" | "fireworks" | "firepass" | "fugu" | "gitlab-duo" | "cursor" | "deepseek" | "deepinfra" | "xai" | "groq" | "cerebras" | "openrouter" | "kilo" | "vercel-ai-gateway" | "zai" | "glm-zcode" | "mistral" | "minimax" | "opencode-go" | "opencode-zen" | "synthetic" | "cloudflare-ai-gateway" | "huggingface" | "litellm" | "moonshot" | "nvidia" | "nanogpt" | "ollama" | "ollama-cloud" | "qianfan" | "qwen-portal" | "together" | "venice" | "vllm" | "xiaomi" | "xiaomi-token-plan-sgp" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "zenmux" | "lm-studio";
|
|
55
55
|
export type Provider = KnownProvider | string;
|
|
56
56
|
import type { Effort } from "./model-thinking";
|
|
57
57
|
/** Token budgets for each thinking level (token-based providers only) */
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Alibaba Token Plan login flow.
|
|
3
|
+
*
|
|
4
|
+
* Alibaba Token Plan provides OpenAI-compatible models via
|
|
5
|
+
* https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1.
|
|
6
|
+
*
|
|
7
|
+
* This is not OAuth - it's a simple API key flow:
|
|
8
|
+
* 1. Open browser to Alibaba Cloud Model Studio console
|
|
9
|
+
* 2. User copies their API key
|
|
10
|
+
* 3. User pastes the API key into the CLI
|
|
11
|
+
*/
|
|
12
|
+
import type { OAuthController } from "./types";
|
|
13
|
+
/**
|
|
14
|
+
* Login to Alibaba Token Plan.
|
|
15
|
+
*
|
|
16
|
+
* Opens browser to API keys page, prompts user to paste their API key.
|
|
17
|
+
* Returns the API key directly (not OAuthCredentials - this isn't OAuth).
|
|
18
|
+
*/
|
|
19
|
+
export declare function loginAlibabaTokenPlan(options: OAuthController): Promise<string>;
|
|
@@ -7,7 +7,7 @@ export type OAuthCredentials = {
|
|
|
7
7
|
email?: string;
|
|
8
8
|
accountId?: string;
|
|
9
9
|
};
|
|
10
|
-
export type OAuthProvider = "alibaba-
|
|
10
|
+
export type OAuthProvider = "alibaba-token-plan" | "anthropic" | "cerebras" | "cloudflare-ai-gateway" | "cursor" | "deepseek" | "deepinfra" | "fireworks" | "firepass" | "fugu" | "github-copilot" | "google-gemini-cli" | "google-antigravity" | "gitlab-duo" | "huggingface" | "kimi-code" | "kilo" | "kagi" | "litellm" | "lm-studio" | "minimax-code" | "minimax-code-cn" | "moonshot" | "nvidia" | "nanogpt" | "ollama" | "ollama-cloud" | "openai-codex" | "openai-codex-device" | "opencode-go" | "opencode-zen" | "parallel" | "perplexity" | "qianfan" | "qwen-portal" | "synthetic" | "tavily" | "together" | "venice" | "vercel-ai-gateway" | "vllm" | "xai" | "glm-zcode" | "xiaomi" | "xiaomi-token-plan-sgp" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "zenmux" | "zai";
|
|
11
11
|
export type OAuthProviderId = OAuthProvider | (string & {});
|
|
12
12
|
export type OAuthPrompt = {
|
|
13
13
|
message: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gajae-code/ai",
|
|
4
|
-
"version": "0.11.
|
|
4
|
+
"version": "0.11.7",
|
|
5
5
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
6
6
|
"homepage": "https://gajae-code.com",
|
|
7
7
|
"author": "Yeachan-Heo and Gajae Code Contributors",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@anthropic-ai/sdk": "^0.94.0",
|
|
42
42
|
"@bufbuild/protobuf": "^2.12.0",
|
|
43
|
-
"@gajae-code/utils": "0.11.
|
|
43
|
+
"@gajae-code/utils": "0.11.7",
|
|
44
44
|
"openai": "^6.36.0",
|
|
45
45
|
"partial-json": "^0.1.7",
|
|
46
46
|
"zod": "4.4.3"
|
package/src/auth-storage.ts
CHANGED
|
@@ -1587,9 +1587,9 @@ export class AuthStorage {
|
|
|
1587
1587
|
});
|
|
1588
1588
|
break;
|
|
1589
1589
|
}
|
|
1590
|
-
case "alibaba-
|
|
1591
|
-
const {
|
|
1592
|
-
const apiKey = await
|
|
1590
|
+
case "alibaba-token-plan": {
|
|
1591
|
+
const { loginAlibabaTokenPlan } = await import("./utils/oauth/alibaba-token-plan");
|
|
1592
|
+
const apiKey = await loginAlibabaTokenPlan(ctrl);
|
|
1593
1593
|
await saveApiKeyCredential(apiKey);
|
|
1594
1594
|
return;
|
|
1595
1595
|
}
|
package/src/model-thinking.ts
CHANGED
|
@@ -62,7 +62,7 @@ type SemVer = {
|
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
type GeminiKind = "pro" | "flash";
|
|
65
|
-
type AnthropicKind = "opus" | "sonnet";
|
|
65
|
+
type AnthropicKind = "opus" | "sonnet" | "fable";
|
|
66
66
|
type OpenAIVariant =
|
|
67
67
|
| "base"
|
|
68
68
|
| "codex"
|
|
@@ -638,6 +638,11 @@ function inferAnthropicSupportedEfforts<TApi extends Api>(
|
|
|
638
638
|
(model.api === "anthropic-messages" || model.api === "bedrock-converse-stream") &&
|
|
639
639
|
semverGte(parsedModel.version, "4.6")
|
|
640
640
|
) {
|
|
641
|
+
if (parsedModel.kind === "fable") {
|
|
642
|
+
// Fable exposes Anthropic's Messages-only xhigh preset; Bedrock
|
|
643
|
+
// Converse lacks it (same split as Opus 4.7+ below).
|
|
644
|
+
return model.api === "anthropic-messages" ? DEFAULT_REASONING_EFFORTS_WITH_XHIGH : DEFAULT_REASONING_EFFORTS;
|
|
645
|
+
}
|
|
641
646
|
if (parsedModel.kind !== "opus") return DEFAULT_REASONING_EFFORTS;
|
|
642
647
|
return anthropicModelHasRealXHighEffort(model)
|
|
643
648
|
? DEFAULT_REASONING_EFFORTS_WITH_XHIGH_AND_MAX
|
|
@@ -697,7 +702,10 @@ function inferThinkingControlMode<TApi extends Api>(
|
|
|
697
702
|
|
|
698
703
|
case "bedrock-converse-stream":
|
|
699
704
|
if (parsedModel.family === "anthropic") {
|
|
700
|
-
if (
|
|
705
|
+
if (
|
|
706
|
+
semverGte(parsedModel.version, "4.6") &&
|
|
707
|
+
(parsedModel.kind === "opus" || parsedModel.kind === "fable")
|
|
708
|
+
) {
|
|
701
709
|
return "anthropic-adaptive";
|
|
702
710
|
}
|
|
703
711
|
if (semverGte(parsedModel.version, "4.5")) {
|
|
@@ -737,7 +745,7 @@ function parseGeminiModel(modelId: string): GeminiModel | null {
|
|
|
737
745
|
}
|
|
738
746
|
|
|
739
747
|
function parseAnthropicModel(modelId: string): AnthropicModel | null {
|
|
740
|
-
const match = /claude-(opus|sonnet)-(\d{1,2}(?:[.-]\d{1,2}){0,2})\b/.exec(modelId);
|
|
748
|
+
const match = /claude-(opus|sonnet|fable)-(\d{1,2}(?:[.-]\d{1,2}){0,2})\b/.exec(modelId);
|
|
741
749
|
if (!match) {
|
|
742
750
|
return null;
|
|
743
751
|
}
|