pi-free 2.0.8 → 2.0.9
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 +544 -540
- package/index.ts +1 -1
- package/lib/built-in-toggle.ts +2 -2
- package/lib/model-detection.ts +1 -1
- package/lib/model-enhancer.ts +20 -20
- package/lib/provider-compat.ts +1 -1
- package/lib/registry.ts +1 -1
- package/lib/util.ts +1 -1
- package/package.json +68 -68
- package/provider-helper.ts +1 -1
- package/providers/cline/cline-auth.ts +1 -1
- package/providers/cline/cline.ts +2 -2
- package/providers/codestral/codestral.ts +1 -1
- package/providers/crofai/crofai.ts +1 -1
- package/providers/deepinfra/deepinfra.ts +1 -1
- package/providers/dynamic-built-in/index.ts +1 -1
- package/providers/kilo/kilo-auth.ts +1 -1
- package/providers/kilo/kilo.ts +2 -2
- package/providers/llm7/llm7.ts +1 -1
- package/providers/nvidia/nvidia.ts +1 -1
- package/providers/ollama/ollama.ts +1 -1
- package/providers/qwen/qwen-auth.ts +1 -1
- package/providers/qwen/qwen-models.ts +101 -101
- package/providers/qwen/qwen.ts +2 -2
- package/providers/sambanova/sambanova.ts +1 -1
- package/providers/zenmux/zenmux.ts +1 -1
package/index.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* - LLM7: AI gateway (free default/fast selectors)
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import type { ExtensionAPI } from "@
|
|
19
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
20
20
|
import { setupBuiltInProviderToggles } from "./lib/built-in-toggle.ts";
|
|
21
21
|
import { createLogger } from "./lib/logger.ts";
|
|
22
22
|
import {
|
package/lib/built-in-toggle.ts
CHANGED
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
* Usage: /toggle-opencode
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import type { Api, Model } from "@
|
|
14
|
+
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
15
15
|
import type {
|
|
16
16
|
ExtensionAPI,
|
|
17
17
|
ProviderModelConfig,
|
|
18
|
-
} from "@
|
|
18
|
+
} from "@earendil-works/pi-coding-agent";
|
|
19
19
|
import { getOpencodeShowPaid, getOpenrouterShowPaid } from "../config.ts";
|
|
20
20
|
import { createLogger } from "./logger.ts";
|
|
21
21
|
import { isFreeModel, registerWithGlobalToggle } from "./registry.ts";
|
package/lib/model-detection.ts
CHANGED
package/lib/model-enhancer.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Model name enhancement helper
|
|
3
|
-
* Adds Coding Index scores to model names for display in /model
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { ProviderModelConfig } from "@
|
|
7
|
-
import { enhanceModelNameWithCodingIndex } from "../provider-failover/benchmark-lookup.ts";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Enhance model names with Coding Index scores
|
|
11
|
-
* Use this before registering providers to show CI in /model list
|
|
12
|
-
*/
|
|
13
|
-
export function enhanceModelsWithCodingIndex(
|
|
14
|
-
models: ProviderModelConfig[],
|
|
15
|
-
): ProviderModelConfig[] {
|
|
16
|
-
return models.map((m) => ({
|
|
17
|
-
...m,
|
|
18
|
-
name: enhanceModelNameWithCodingIndex(m.name, m.id),
|
|
19
|
-
}));
|
|
20
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Model name enhancement helper
|
|
3
|
+
* Adds Coding Index scores to model names for display in /model
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ProviderModelConfig } from "@earendil-works/pi-coding-agent";
|
|
7
|
+
import { enhanceModelNameWithCodingIndex } from "../provider-failover/benchmark-lookup.ts";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Enhance model names with Coding Index scores
|
|
11
|
+
* Use this before registering providers to show CI in /model list
|
|
12
|
+
*/
|
|
13
|
+
export function enhanceModelsWithCodingIndex(
|
|
14
|
+
models: ProviderModelConfig[],
|
|
15
|
+
): ProviderModelConfig[] {
|
|
16
|
+
return models.map((m) => ({
|
|
17
|
+
...m,
|
|
18
|
+
name: enhanceModelNameWithCodingIndex(m.name, m.id),
|
|
19
|
+
}));
|
|
20
|
+
}
|
package/lib/provider-compat.ts
CHANGED
package/lib/registry.ts
CHANGED
package/lib/util.ts
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
getProxyModelCompat,
|
|
4
4
|
isLikelyReasoningModel,
|
|
5
5
|
} from "./provider-compat.ts";
|
|
6
|
-
import type { ProviderModelConfig as PiProviderModelConfig } from "@
|
|
6
|
+
import type { ProviderModelConfig as PiProviderModelConfig } from "@earendil-works/pi-coding-agent";
|
|
7
7
|
import type { ProviderModelConfig } from "./types.ts";
|
|
8
8
|
|
|
9
9
|
const _logger = createLogger("util");
|
package/package.json
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "pi-free",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"description": "AI model providers for Pi with free model filtering. Shows only $0 cost models by default. Supports Kilo (free OAuth), Cline (free), NVIDIA (freemium), ZenMux, CrofAI, Ollama Cloud, and more.",
|
|
6
|
-
"keywords": [
|
|
7
|
-
"pi-package",
|
|
8
|
-
"pi-extension",
|
|
9
|
-
"free-models",
|
|
10
|
-
"paid-models",
|
|
11
|
-
"model-filter",
|
|
12
|
-
"nvidia-nim",
|
|
13
|
-
"kilo",
|
|
14
|
-
"cline",
|
|
15
|
-
"zenmux",
|
|
16
|
-
"crofai",
|
|
17
|
-
"ollama-cloud"
|
|
18
|
-
],
|
|
19
|
-
"license": "MIT",
|
|
20
|
-
"author": "Apostolos Mantzaris",
|
|
21
|
-
"homepage": "https://github.com/apmantza/pi-free#readme",
|
|
22
|
-
"bugs": {
|
|
23
|
-
"url": "https://github.com/apmantza/pi-free/issues"
|
|
24
|
-
},
|
|
25
|
-
"repository": {
|
|
26
|
-
"type": "git",
|
|
27
|
-
"url": "git+https://github.com/apmantza/pi-free.git"
|
|
28
|
-
},
|
|
29
|
-
"engines": {
|
|
30
|
-
"node": ">=20.0.0"
|
|
31
|
-
},
|
|
32
|
-
"files": [
|
|
33
|
-
"index.ts",
|
|
34
|
-
"providers/**/*.ts",
|
|
35
|
-
"lib/**/*.ts",
|
|
36
|
-
"provider-failover/**/*.ts",
|
|
37
|
-
"config.ts",
|
|
38
|
-
"constants.ts",
|
|
39
|
-
"provider-helper.ts",
|
|
40
|
-
"README.md",
|
|
41
|
-
"LICENSE",
|
|
42
|
-
"CHANGELOG.md",
|
|
43
|
-
"banner.svg",
|
|
44
|
-
"scripts/check-extensions.mjs"
|
|
45
|
-
],
|
|
46
|
-
"scripts": {
|
|
47
|
-
"check": "node scripts/check-extensions.mjs",
|
|
48
|
-
"test": "vitest",
|
|
49
|
-
"test:ui": "vitest --ui",
|
|
50
|
-
"test:run": "vitest run"
|
|
51
|
-
},
|
|
52
|
-
"peerDependencies": {
|
|
53
|
-
"@
|
|
54
|
-
"@
|
|
55
|
-
"@
|
|
56
|
-
},
|
|
57
|
-
"devDependencies": {
|
|
58
|
-
"@vitest/ui": "^4.1.5",
|
|
59
|
-
"tsx": "^4.0.0",
|
|
60
|
-
"typescript": "^6.0.2",
|
|
61
|
-
"vitest": "^4.1.5"
|
|
62
|
-
},
|
|
63
|
-
"pi": {
|
|
64
|
-
"extensions": [
|
|
65
|
-
"./index.ts"
|
|
66
|
-
]
|
|
67
|
-
}
|
|
68
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "pi-free",
|
|
3
|
+
"version": "2.0.9",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "AI model providers for Pi with free model filtering. Shows only $0 cost models by default. Supports Kilo (free OAuth), Cline (free), NVIDIA (freemium), ZenMux, CrofAI, Ollama Cloud, and more.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"pi-package",
|
|
8
|
+
"pi-extension",
|
|
9
|
+
"free-models",
|
|
10
|
+
"paid-models",
|
|
11
|
+
"model-filter",
|
|
12
|
+
"nvidia-nim",
|
|
13
|
+
"kilo",
|
|
14
|
+
"cline",
|
|
15
|
+
"zenmux",
|
|
16
|
+
"crofai",
|
|
17
|
+
"ollama-cloud"
|
|
18
|
+
],
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"author": "Apostolos Mantzaris",
|
|
21
|
+
"homepage": "https://github.com/apmantza/pi-free#readme",
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/apmantza/pi-free/issues"
|
|
24
|
+
},
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/apmantza/pi-free.git"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=20.0.0"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"index.ts",
|
|
34
|
+
"providers/**/*.ts",
|
|
35
|
+
"lib/**/*.ts",
|
|
36
|
+
"provider-failover/**/*.ts",
|
|
37
|
+
"config.ts",
|
|
38
|
+
"constants.ts",
|
|
39
|
+
"provider-helper.ts",
|
|
40
|
+
"README.md",
|
|
41
|
+
"LICENSE",
|
|
42
|
+
"CHANGELOG.md",
|
|
43
|
+
"banner.svg",
|
|
44
|
+
"scripts/check-extensions.mjs"
|
|
45
|
+
],
|
|
46
|
+
"scripts": {
|
|
47
|
+
"check": "node scripts/check-extensions.mjs",
|
|
48
|
+
"test": "vitest",
|
|
49
|
+
"test:ui": "vitest --ui",
|
|
50
|
+
"test:run": "vitest run"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"@earendil-works/pi-ai": "*",
|
|
54
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
55
|
+
"@earendil-works/pi-tui": "*"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@vitest/ui": "^4.1.5",
|
|
59
|
+
"tsx": "^4.0.0",
|
|
60
|
+
"typescript": "^6.0.2",
|
|
61
|
+
"vitest": "^4.1.5"
|
|
62
|
+
},
|
|
63
|
+
"pi": {
|
|
64
|
+
"extensions": [
|
|
65
|
+
"./index.ts"
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
}
|
package/provider-helper.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import type {
|
|
11
11
|
ExtensionAPI,
|
|
12
12
|
ProviderModelConfig,
|
|
13
|
-
} from "@
|
|
13
|
+
} from "@earendil-works/pi-coding-agent";
|
|
14
14
|
import { saveConfig } from "./config.ts";
|
|
15
15
|
import { createLogger } from "./lib/logger.ts";
|
|
16
16
|
import { enhanceModelNameWithCodingIndex } from "./provider-failover/benchmark-lookup.ts";
|
|
@@ -14,7 +14,7 @@ import { URL as NodeURL } from "node:url";
|
|
|
14
14
|
import type {
|
|
15
15
|
OAuthCredentials,
|
|
16
16
|
OAuthLoginCallbacks,
|
|
17
|
-
} from "@
|
|
17
|
+
} from "@earendil-works/pi-ai";
|
|
18
18
|
import { BASE_URL_CLINE, CLINE_AUTH_TIMEOUT_MS } from "../../constants.ts";
|
|
19
19
|
import { createLogger } from "../../lib/logger.ts";
|
|
20
20
|
|
package/providers/cline/cline.ts
CHANGED
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
* # Models appear immediately; run /login cline to start chatting
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import type { OAuthCredentials } from "@
|
|
18
|
-
import type { ExtensionAPI } from "@
|
|
17
|
+
import type { OAuthCredentials } from "@earendil-works/pi-ai";
|
|
18
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
19
19
|
import { getClineShowPaid } from "../../config.ts";
|
|
20
20
|
import { BASE_URL_CLINE, PROVIDER_CLINE } from "../../constants.ts";
|
|
21
21
|
import { isFreeModel, registerWithGlobalToggle } from "../../lib/registry.ts";
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* # Models appear in /model selector
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import type { ExtensionAPI } from "@
|
|
18
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
19
19
|
import { getCrofaiApiKey, getCrofaiShowPaid } from "../../config.ts";
|
|
20
20
|
import { BASE_URL_CROFAI, PROVIDER_CROFAI } from "../../constants.ts";
|
|
21
21
|
import { createLogger } from "../../lib/logger.ts";
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
import type {
|
|
29
29
|
ExtensionAPI,
|
|
30
30
|
ProviderModelConfig,
|
|
31
|
-
} from "@
|
|
31
|
+
} from "@earendil-works/pi-coding-agent";
|
|
32
32
|
import { getDeepinfraApiKey } from "../../config.ts";
|
|
33
33
|
import { BASE_URL_DEEPINFRA, PROVIDER_DEEPINFRA } from "../../constants.ts";
|
|
34
34
|
import { createLogger } from "../../lib/logger.ts";
|
package/providers/kilo/kilo.ts
CHANGED
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
* # Free models visible immediately; /login kilo for paid access
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import type { Api, Model, OAuthCredentials } from "@
|
|
15
|
+
import type { Api, Model, OAuthCredentials } from "@earendil-works/pi-ai";
|
|
16
16
|
import type {
|
|
17
17
|
ExtensionAPI,
|
|
18
18
|
ProviderModelConfig,
|
|
19
|
-
} from "@
|
|
19
|
+
} from "@earendil-works/pi-coding-agent";
|
|
20
20
|
import {
|
|
21
21
|
getKiloFreeOnly,
|
|
22
22
|
getKiloShowPaid,
|
package/providers/llm7/llm7.ts
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
import type {
|
|
36
36
|
ExtensionAPI,
|
|
37
37
|
ProviderModelConfig,
|
|
38
|
-
} from "@
|
|
38
|
+
} from "@earendil-works/pi-coding-agent";
|
|
39
39
|
import { getLlm7ApiKey, getLlm7ShowPaid } from "../../config.ts";
|
|
40
40
|
import { BASE_URL_LLM7, PROVIDER_LLM7 } from "../../constants.ts";
|
|
41
41
|
import { createLogger } from "../../lib/logger.ts";
|
|
@@ -16,7 +16,7 @@ import crypto from "node:crypto";
|
|
|
16
16
|
import type {
|
|
17
17
|
OAuthCredentials,
|
|
18
18
|
OAuthLoginCallbacks,
|
|
19
|
-
} from "@
|
|
19
|
+
} from "@earendil-works/pi-ai";
|
|
20
20
|
import { createLogger } from "../../lib/logger.ts";
|
|
21
21
|
import { openBrowser } from "../../lib/open-browser.ts";
|
|
22
22
|
|
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Qwen OAuth model definitions.
|
|
3
|
-
*
|
|
4
|
-
* @deprecated The 1,000 req/day free tier is no longer available. Auth is broken.
|
|
5
|
-
* This provider remains for backward compatibility but should not be used.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { ProviderModelConfig } from "@
|
|
9
|
-
import { createLogger } from "../../lib/logger.ts";
|
|
10
|
-
|
|
11
|
-
const _logger = createLogger("qwen-models");
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* portal.qwen.ai compatibility settings.
|
|
15
|
-
*
|
|
16
|
-
* portal.qwen.ai's OpenAI-compatible API does not support several parameters
|
|
17
|
-
* that the pi framework sends by default.
|
|
18
|
-
*/
|
|
19
|
-
export const PORTAL_COMPAT: NonNullable<ProviderModelConfig["compat"]> = {
|
|
20
|
-
supportsStore: false,
|
|
21
|
-
supportsDeveloperRole: false,
|
|
22
|
-
supportsReasoningEffort: false,
|
|
23
|
-
supportsUsageInStreaming: false,
|
|
24
|
-
supportsStrictMode: false,
|
|
25
|
-
maxTokensField: "max_tokens",
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Fallback model used before OAuth completes or if model discovery fails.
|
|
30
|
-
* The real model ID is resolved dynamically via fetchQwenLiveModels() after auth.
|
|
31
|
-
*/
|
|
32
|
-
export const QWEN_FREE_MODELS: ProviderModelConfig[] = [
|
|
33
|
-
{
|
|
34
|
-
id: "coder-model",
|
|
35
|
-
name: "Qwen Coder — DEPRECATED (free tier discontinued)",
|
|
36
|
-
reasoning: false,
|
|
37
|
-
input: ["text"],
|
|
38
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
39
|
-
contextWindow: 131_072,
|
|
40
|
-
maxTokens: 16_384,
|
|
41
|
-
compat: PORTAL_COMPAT,
|
|
42
|
-
},
|
|
43
|
-
];
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Fetch Qwen models. Returns static model list for backward compatibility.
|
|
47
|
-
* @deprecated Qwen free tier is discontinued.
|
|
48
|
-
*/
|
|
49
|
-
export async function fetchQwenModels(): Promise<ProviderModelConfig[]> {
|
|
50
|
-
_logger.info("Qwen provider is deprecated, returning placeholder models");
|
|
51
|
-
return QWEN_FREE_MODELS;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Fetch live model list from the Qwen API using the OAuth access token.
|
|
56
|
-
* Returns updated models with real IDs from the server, or the original
|
|
57
|
-
* models unchanged if the request fails.
|
|
58
|
-
*/
|
|
59
|
-
export async function fetchQwenLiveModels(
|
|
60
|
-
baseUrl: string,
|
|
61
|
-
accessToken: string,
|
|
62
|
-
templateModels: ProviderModelConfig[],
|
|
63
|
-
): Promise<ProviderModelConfig[]> {
|
|
64
|
-
try {
|
|
65
|
-
const response = await fetch(`${baseUrl}/models`, {
|
|
66
|
-
headers: {
|
|
67
|
-
Authorization: `Bearer ${accessToken}`,
|
|
68
|
-
Accept: "application/json",
|
|
69
|
-
},
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
if (!response.ok) {
|
|
73
|
-
_logger.info("Qwen /v1/models fetch failed, keeping current model IDs", {
|
|
74
|
-
status: response.status,
|
|
75
|
-
});
|
|
76
|
-
return templateModels;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
interface ModelEntry {
|
|
80
|
-
id: string;
|
|
81
|
-
}
|
|
82
|
-
const data = (await response.json()) as { data?: ModelEntry[] };
|
|
83
|
-
const ids: string[] = (data.data ?? [])
|
|
84
|
-
.map((m: ModelEntry) => m.id)
|
|
85
|
-
.filter(Boolean);
|
|
86
|
-
|
|
87
|
-
_logger.info("Qwen live models discovered", { ids });
|
|
88
|
-
|
|
89
|
-
if (ids.length === 0) return templateModels;
|
|
90
|
-
|
|
91
|
-
// Prefer a coder model if available, otherwise use the first model
|
|
92
|
-
const preferred = ids.find((id) => /coder/i.test(id)) ?? ids[0];
|
|
93
|
-
|
|
94
|
-
return templateModels.map((m) => ({ ...m, id: preferred }));
|
|
95
|
-
} catch (err) {
|
|
96
|
-
_logger.info("Qwen live model fetch error, keeping current model IDs", {
|
|
97
|
-
error: String(err),
|
|
98
|
-
});
|
|
99
|
-
return templateModels;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Qwen OAuth model definitions.
|
|
3
|
+
*
|
|
4
|
+
* @deprecated The 1,000 req/day free tier is no longer available. Auth is broken.
|
|
5
|
+
* This provider remains for backward compatibility but should not be used.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ProviderModelConfig } from "@earendil-works/pi-coding-agent";
|
|
9
|
+
import { createLogger } from "../../lib/logger.ts";
|
|
10
|
+
|
|
11
|
+
const _logger = createLogger("qwen-models");
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* portal.qwen.ai compatibility settings.
|
|
15
|
+
*
|
|
16
|
+
* portal.qwen.ai's OpenAI-compatible API does not support several parameters
|
|
17
|
+
* that the pi framework sends by default.
|
|
18
|
+
*/
|
|
19
|
+
export const PORTAL_COMPAT: NonNullable<ProviderModelConfig["compat"]> = {
|
|
20
|
+
supportsStore: false,
|
|
21
|
+
supportsDeveloperRole: false,
|
|
22
|
+
supportsReasoningEffort: false,
|
|
23
|
+
supportsUsageInStreaming: false,
|
|
24
|
+
supportsStrictMode: false,
|
|
25
|
+
maxTokensField: "max_tokens",
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Fallback model used before OAuth completes or if model discovery fails.
|
|
30
|
+
* The real model ID is resolved dynamically via fetchQwenLiveModels() after auth.
|
|
31
|
+
*/
|
|
32
|
+
export const QWEN_FREE_MODELS: ProviderModelConfig[] = [
|
|
33
|
+
{
|
|
34
|
+
id: "coder-model",
|
|
35
|
+
name: "Qwen Coder — DEPRECATED (free tier discontinued)",
|
|
36
|
+
reasoning: false,
|
|
37
|
+
input: ["text"],
|
|
38
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
39
|
+
contextWindow: 131_072,
|
|
40
|
+
maxTokens: 16_384,
|
|
41
|
+
compat: PORTAL_COMPAT,
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Fetch Qwen models. Returns static model list for backward compatibility.
|
|
47
|
+
* @deprecated Qwen free tier is discontinued.
|
|
48
|
+
*/
|
|
49
|
+
export async function fetchQwenModels(): Promise<ProviderModelConfig[]> {
|
|
50
|
+
_logger.info("Qwen provider is deprecated, returning placeholder models");
|
|
51
|
+
return QWEN_FREE_MODELS;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Fetch live model list from the Qwen API using the OAuth access token.
|
|
56
|
+
* Returns updated models with real IDs from the server, or the original
|
|
57
|
+
* models unchanged if the request fails.
|
|
58
|
+
*/
|
|
59
|
+
export async function fetchQwenLiveModels(
|
|
60
|
+
baseUrl: string,
|
|
61
|
+
accessToken: string,
|
|
62
|
+
templateModels: ProviderModelConfig[],
|
|
63
|
+
): Promise<ProviderModelConfig[]> {
|
|
64
|
+
try {
|
|
65
|
+
const response = await fetch(`${baseUrl}/models`, {
|
|
66
|
+
headers: {
|
|
67
|
+
Authorization: `Bearer ${accessToken}`,
|
|
68
|
+
Accept: "application/json",
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
_logger.info("Qwen /v1/models fetch failed, keeping current model IDs", {
|
|
74
|
+
status: response.status,
|
|
75
|
+
});
|
|
76
|
+
return templateModels;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
interface ModelEntry {
|
|
80
|
+
id: string;
|
|
81
|
+
}
|
|
82
|
+
const data = (await response.json()) as { data?: ModelEntry[] };
|
|
83
|
+
const ids: string[] = (data.data ?? [])
|
|
84
|
+
.map((m: ModelEntry) => m.id)
|
|
85
|
+
.filter(Boolean);
|
|
86
|
+
|
|
87
|
+
_logger.info("Qwen live models discovered", { ids });
|
|
88
|
+
|
|
89
|
+
if (ids.length === 0) return templateModels;
|
|
90
|
+
|
|
91
|
+
// Prefer a coder model if available, otherwise use the first model
|
|
92
|
+
const preferred = ids.find((id) => /coder/i.test(id)) ?? ids[0];
|
|
93
|
+
|
|
94
|
+
return templateModels.map((m) => ({ ...m, id: preferred }));
|
|
95
|
+
} catch (err) {
|
|
96
|
+
_logger.info("Qwen live model fetch error, keeping current model IDs", {
|
|
97
|
+
error: String(err),
|
|
98
|
+
});
|
|
99
|
+
return templateModels;
|
|
100
|
+
}
|
|
101
|
+
}
|
package/providers/qwen/qwen.ts
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* 1,000 free API calls/day — run /login qwen to authenticate.~~
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import type { Api, Model, OAuthCredentials } from "@
|
|
14
|
-
import type { ExtensionAPI } from "@
|
|
13
|
+
import type { Api, Model, OAuthCredentials } from "@earendil-works/pi-ai";
|
|
14
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
15
15
|
import { PROVIDER_QWEN, URL_QWEN_TOS } from "../../constants.ts";
|
|
16
16
|
import { createLogger } from "../../lib/logger.ts";
|
|
17
17
|
import { logWarning } from "../../lib/util.ts";
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* # Models appear in /model selector as "sambanova/Meta-Llama-3.3-70B-Instruct"
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
|
-
import type { ExtensionAPI } from "@
|
|
30
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
31
31
|
import { getSambanovaApiKey, getSambanovaShowPaid } from "../../config.ts";
|
|
32
32
|
import { BASE_URL_SAMBANOVA, PROVIDER_SAMBANOVA } from "../../constants.ts";
|
|
33
33
|
import { createLogger } from "../../lib/logger.ts";
|