@datename/fastcode-termux 0.0.0-stage → 0.1.6
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/LICENSE +21 -0
- package/README.md +400 -2
- package/bin/fastcode.mjs +59 -0
- package/dist/agent/guards.d.ts +35 -0
- package/dist/agent/guards.js +74 -0
- package/dist/agent/limits.d.ts +24 -0
- package/dist/agent/limits.js +71 -0
- package/dist/agent/protocol.d.ts +4 -0
- package/dist/agent/protocol.js +126 -0
- package/dist/agent/tools.d.ts +1 -0
- package/dist/agent/tools.js +377 -0
- package/dist/app.d.ts +4 -0
- package/dist/app.js +476 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +518 -0
- package/dist/commands/about.d.ts +8 -0
- package/dist/commands/about.js +16 -0
- package/dist/commands/agent.d.ts +11 -0
- package/dist/commands/agent.js +18 -0
- package/dist/commands/clear.d.ts +11 -0
- package/dist/commands/clear.js +9 -0
- package/dist/commands/config.d.ts +7 -0
- package/dist/commands/config.js +24 -0
- package/dist/commands/cost.d.ts +9 -0
- package/dist/commands/cost.js +13 -0
- package/dist/commands/cwd.d.ts +7 -0
- package/dist/commands/cwd.js +7 -0
- package/dist/commands/exit.d.ts +9 -0
- package/dist/commands/exit.js +8 -0
- package/dist/commands/help.d.ts +6 -0
- package/dist/commands/help.js +18 -0
- package/dist/commands/index.d.ts +9 -0
- package/dist/commands/index.js +58 -0
- package/dist/commands/login.d.ts +16 -0
- package/dist/commands/login.js +61 -0
- package/dist/commands/logout.d.ts +9 -0
- package/dist/commands/logout.js +53 -0
- package/dist/commands/model.d.ts +11 -0
- package/dist/commands/model.js +30 -0
- package/dist/commands/plugin.d.ts +11 -0
- package/dist/commands/plugin.js +74 -0
- package/dist/commands/provider.d.ts +11 -0
- package/dist/commands/provider.js +28 -0
- package/dist/commands/reset.d.ts +9 -0
- package/dist/commands/reset.js +13 -0
- package/dist/commands/skills.d.ts +11 -0
- package/dist/commands/skills.js +106 -0
- package/dist/commands/system.d.ts +11 -0
- package/dist/commands/system.js +20 -0
- package/dist/commands/theme.d.ts +11 -0
- package/dist/commands/theme.js +22 -0
- package/dist/commands/tools.d.ts +7 -0
- package/dist/commands/tools.js +29 -0
- package/dist/commands/whoami.d.ts +9 -0
- package/dist/commands/whoami.js +51 -0
- package/dist/config/paths.d.ts +4 -0
- package/dist/config/paths.js +59 -0
- package/dist/config/store.d.ts +69 -0
- package/dist/config/store.js +208 -0
- package/dist/config/themes.d.ts +73 -0
- package/dist/config/themes.js +77 -0
- package/dist/config/trust.d.ts +9 -0
- package/dist/config/trust.js +67 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +31 -0
- package/dist/lib/diagnostics.d.ts +41 -0
- package/dist/lib/diagnostics.js +139 -0
- package/dist/lib/http.d.ts +13 -0
- package/dist/lib/http.js +70 -0
- package/dist/lib/markdown.d.ts +1 -0
- package/dist/lib/markdown.js +32 -0
- package/dist/lib/pkg.d.ts +5 -0
- package/dist/lib/pkg.js +27 -0
- package/dist/lib/platform.d.ts +7 -0
- package/dist/lib/platform.js +57 -0
- package/dist/lib/startup.d.ts +6 -0
- package/dist/lib/startup.js +25 -0
- package/dist/lib/uiMode.d.ts +2 -0
- package/dist/lib/uiMode.js +7 -0
- package/dist/plugins/manager.d.ts +23 -0
- package/dist/plugins/manager.js +101 -0
- package/dist/providers/anthropic.d.ts +21 -0
- package/dist/providers/anthropic.js +107 -0
- package/dist/providers/custom.d.ts +24 -0
- package/dist/providers/custom.js +25 -0
- package/dist/providers/deepseek.d.ts +24 -0
- package/dist/providers/deepseek.js +15 -0
- package/dist/providers/google.d.ts +24 -0
- package/dist/providers/google.js +19 -0
- package/dist/providers/groq.d.ts +24 -0
- package/dist/providers/groq.js +20 -0
- package/dist/providers/index.d.ts +201 -0
- package/dist/providers/index.js +37 -0
- package/dist/providers/mistral.d.ts +24 -0
- package/dist/providers/mistral.js +19 -0
- package/dist/providers/moonshot.d.ts +24 -0
- package/dist/providers/moonshot.js +22 -0
- package/dist/providers/ollama.d.ts +24 -0
- package/dist/providers/ollama.js +22 -0
- package/dist/providers/openai.d.ts +24 -0
- package/dist/providers/openai.js +25 -0
- package/dist/providers/openaiCompatible.d.ts +17 -0
- package/dist/providers/openaiCompatible.js +110 -0
- package/dist/providers/openrouter.d.ts +24 -0
- package/dist/providers/openrouter.js +26 -0
- package/dist/providers/qwen.d.ts +24 -0
- package/dist/providers/qwen.js +23 -0
- package/dist/providers/xai.d.ts +24 -0
- package/dist/providers/xai.js +18 -0
- package/dist/providers/zhipu.d.ts +24 -0
- package/dist/providers/zhipu.js +23 -0
- package/dist/session/log.d.ts +29 -0
- package/dist/session/log.js +135 -0
- package/dist/skills/manager.d.ts +18 -0
- package/dist/skills/manager.js +201 -0
- package/dist/skills/parser.d.ts +18 -0
- package/dist/skills/parser.js +65 -0
- package/dist/types.d.ts +146 -0
- package/dist/types.js +1 -0
- package/dist/ui/Banner.d.ts +5 -0
- package/dist/ui/Banner.js +65 -0
- package/dist/ui/Message.d.ts +7 -0
- package/dist/ui/Message.js +13 -0
- package/dist/ui/Prompt.d.ts +10 -0
- package/dist/ui/Prompt.js +38 -0
- package/dist/ui/Spinner.d.ts +5 -0
- package/dist/ui/Spinner.js +33 -0
- package/dist/ui/StatusBar.d.ts +10 -0
- package/dist/ui/StatusBar.js +19 -0
- package/dist/ui/TrustGate.d.ts +5 -0
- package/dist/ui/TrustGate.js +26 -0
- package/package.json +96 -4
- package/src/agent/guards.ts +74 -0
- package/src/agent/limits.ts +71 -0
- package/src/agent/protocol.ts +126 -0
- package/src/agent/tools.ts +377 -0
- package/src/app.ts +476 -0
- package/src/cli.ts +308 -0
- package/src/commands/about.ts +16 -0
- package/src/commands/agent.ts +18 -0
- package/src/commands/clear.ts +9 -0
- package/src/commands/config.ts +24 -0
- package/src/commands/cost.ts +13 -0
- package/src/commands/cwd.ts +7 -0
- package/src/commands/exit.ts +8 -0
- package/src/commands/help.ts +18 -0
- package/src/commands/index.ts +58 -0
- package/src/commands/login.ts +61 -0
- package/src/commands/logout.ts +53 -0
- package/src/commands/model.ts +30 -0
- package/src/commands/plugin.ts +74 -0
- package/src/commands/provider.ts +28 -0
- package/src/commands/reset.ts +13 -0
- package/src/commands/skills.ts +106 -0
- package/src/commands/system.ts +20 -0
- package/src/commands/theme.ts +22 -0
- package/src/commands/tools.ts +29 -0
- package/src/commands/whoami.ts +51 -0
- package/src/config/paths.ts +59 -0
- package/src/config/store.ts +240 -0
- package/src/config/themes.ts +77 -0
- package/src/config/trust.ts +67 -0
- package/src/index.ts +31 -0
- package/src/lib/diagnostics.ts +139 -0
- package/src/lib/http.ts +70 -0
- package/src/lib/markdown.ts +32 -0
- package/src/lib/pkg.ts +35 -0
- package/src/lib/platform.ts +57 -0
- package/src/lib/startup.ts +25 -0
- package/src/lib/uiMode.ts +7 -0
- package/src/plugins/manager.ts +101 -0
- package/src/providers/anthropic.ts +107 -0
- package/src/providers/custom.ts +25 -0
- package/src/providers/deepseek.ts +15 -0
- package/src/providers/google.ts +19 -0
- package/src/providers/groq.ts +20 -0
- package/src/providers/index.ts +37 -0
- package/src/providers/mistral.ts +19 -0
- package/src/providers/moonshot.ts +22 -0
- package/src/providers/ollama.ts +22 -0
- package/src/providers/openai.ts +25 -0
- package/src/providers/openaiCompatible.ts +110 -0
- package/src/providers/openrouter.ts +26 -0
- package/src/providers/qwen.ts +23 -0
- package/src/providers/xai.ts +18 -0
- package/src/providers/zhipu.ts +23 -0
- package/src/session/log.ts +135 -0
- package/src/skills/manager.ts +201 -0
- package/src/skills/parser.ts +65 -0
- package/src/types.ts +143 -0
- package/src/ui/Banner.ts +68 -0
- package/src/ui/Message.ts +13 -0
- package/src/ui/Prompt.ts +38 -0
- package/src/ui/Spinner.ts +33 -0
- package/src/ui/StatusBar.ts +19 -0
- package/src/ui/TrustGate.ts +26 -0
- package/tsconfig.json +22 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { anthropicProvider } from "./anthropic.js";
|
|
2
|
+
import { openaiProvider } from "./openai.js";
|
|
3
|
+
import { googleProvider } from "./google.js";
|
|
4
|
+
import { openrouterProvider } from "./openrouter.js";
|
|
5
|
+
import { groqProvider } from "./groq.js";
|
|
6
|
+
import { deepseekProvider } from "./deepseek.js";
|
|
7
|
+
import { mistralProvider } from "./mistral.js";
|
|
8
|
+
import { ollamaProvider } from "./ollama.js";
|
|
9
|
+
import { xaiProvider } from "./xai.js";
|
|
10
|
+
import { moonshotProvider } from "./moonshot.js";
|
|
11
|
+
import { zhipuProvider } from "./zhipu.js";
|
|
12
|
+
import { qwenProvider } from "./qwen.js";
|
|
13
|
+
import { customProvider } from "./custom.js";
|
|
14
|
+
export const PROVIDERS = [
|
|
15
|
+
anthropicProvider,
|
|
16
|
+
openaiProvider,
|
|
17
|
+
googleProvider,
|
|
18
|
+
deepseekProvider,
|
|
19
|
+
openrouterProvider,
|
|
20
|
+
groqProvider,
|
|
21
|
+
mistralProvider,
|
|
22
|
+
xaiProvider,
|
|
23
|
+
moonshotProvider,
|
|
24
|
+
zhipuProvider,
|
|
25
|
+
qwenProvider,
|
|
26
|
+
ollamaProvider,
|
|
27
|
+
customProvider,
|
|
28
|
+
];
|
|
29
|
+
export function getProvider(id) {
|
|
30
|
+
return PROVIDERS.find((p) => p.id === id);
|
|
31
|
+
}
|
|
32
|
+
export function getProviderOrThrow(id) {
|
|
33
|
+
const p = getProvider(id);
|
|
34
|
+
if (!p)
|
|
35
|
+
throw new Error("Unknown provider: " + id);
|
|
36
|
+
return p;
|
|
37
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const mistralProvider: {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
authEnv: string[];
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
defaultModel: string;
|
|
7
|
+
listModels: (apiKey: any) => Promise<any>;
|
|
8
|
+
stream: (req: any, apiKey: any) => AsyncGenerator<{
|
|
9
|
+
delta: string;
|
|
10
|
+
done: boolean;
|
|
11
|
+
reasoning?: undefined;
|
|
12
|
+
usage?: undefined;
|
|
13
|
+
} | {
|
|
14
|
+
delta: string;
|
|
15
|
+
done: boolean;
|
|
16
|
+
reasoning: string;
|
|
17
|
+
usage?: undefined;
|
|
18
|
+
} | {
|
|
19
|
+
delta: string;
|
|
20
|
+
done: boolean;
|
|
21
|
+
usage: any;
|
|
22
|
+
reasoning?: undefined;
|
|
23
|
+
}, void, unknown>;
|
|
24
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { listModelsHttp, streamChatCompletion } from "./openaiCompatible.js";
|
|
2
|
+
const BASE = "https://api.mistral.ai/v1";
|
|
3
|
+
const STATIC = [
|
|
4
|
+
{ id: "mistral-large-latest", label: "Mistral Large" },
|
|
5
|
+
{ id: "mistral-medium-latest", label: "Mistral Medium" },
|
|
6
|
+
{ id: "mistral-small-latest", label: "Mistral Small" },
|
|
7
|
+
{ id: "codestral-latest", label: "Codestral" },
|
|
8
|
+
{ id: "devstral-medium-latest", label: "Devstral" },
|
|
9
|
+
{ id: "magistral-medium-latest", label: "Magistral" },
|
|
10
|
+
];
|
|
11
|
+
export const mistralProvider = {
|
|
12
|
+
id: "mistral",
|
|
13
|
+
label: "Mistral",
|
|
14
|
+
authEnv: ["MISTRAL_API_KEY"],
|
|
15
|
+
baseUrl: BASE,
|
|
16
|
+
defaultModel: "mistral-small-latest",
|
|
17
|
+
listModels: (apiKey) => listModelsHttp({ baseUrl: BASE, apiKey, staticModels: STATIC }),
|
|
18
|
+
stream: (req, apiKey) => streamChatCompletion(req, { baseUrl: BASE, apiKey, staticModels: STATIC }),
|
|
19
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const moonshotProvider: {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
authEnv: string[];
|
|
5
|
+
readonly baseUrl: string;
|
|
6
|
+
defaultModel: string;
|
|
7
|
+
listModels: (apiKey: any) => Promise<any>;
|
|
8
|
+
stream: (req: any, apiKey: any) => AsyncGenerator<{
|
|
9
|
+
delta: string;
|
|
10
|
+
done: boolean;
|
|
11
|
+
reasoning?: undefined;
|
|
12
|
+
usage?: undefined;
|
|
13
|
+
} | {
|
|
14
|
+
delta: string;
|
|
15
|
+
done: boolean;
|
|
16
|
+
reasoning: string;
|
|
17
|
+
usage?: undefined;
|
|
18
|
+
} | {
|
|
19
|
+
delta: string;
|
|
20
|
+
done: boolean;
|
|
21
|
+
usage: any;
|
|
22
|
+
reasoning?: undefined;
|
|
23
|
+
}, void, unknown>;
|
|
24
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { listModelsHttp, streamChatCompletion } from "./openaiCompatible.js";
|
|
2
|
+
function baseUrl() {
|
|
3
|
+
return (process.env["MOONSHOT_BASE_URL"] ?? "").trim() || "https://api.moonshot.cn/v1";
|
|
4
|
+
}
|
|
5
|
+
const STATIC = [
|
|
6
|
+
{ id: "kimi-k3", label: "Kimi K3" },
|
|
7
|
+
{ id: "kimi-k2.7-code", label: "Kimi K2.7 Code" },
|
|
8
|
+
{ id: "kimi-k2.6", label: "Kimi K2.6" },
|
|
9
|
+
{ id: "kimi-k2-thinking", label: "Kimi K2 Thinking" },
|
|
10
|
+
{ id: "kimi-k2-0905", label: "Kimi K2 0905" },
|
|
11
|
+
];
|
|
12
|
+
export const moonshotProvider = {
|
|
13
|
+
id: "moonshot",
|
|
14
|
+
label: "Moonshot (Kimi)",
|
|
15
|
+
authEnv: ["MOONSHOT_API_KEY"],
|
|
16
|
+
get baseUrl() {
|
|
17
|
+
return baseUrl();
|
|
18
|
+
},
|
|
19
|
+
defaultModel: "kimi-k3",
|
|
20
|
+
listModels: (apiKey) => listModelsHttp({ baseUrl: baseUrl(), apiKey, staticModels: STATIC }),
|
|
21
|
+
stream: (req, apiKey) => streamChatCompletion(req, { baseUrl: baseUrl(), apiKey, staticModels: STATIC }),
|
|
22
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const ollamaProvider: {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
authEnv: any[];
|
|
5
|
+
readonly baseUrl: string;
|
|
6
|
+
defaultModel: string;
|
|
7
|
+
listModels: () => Promise<any>;
|
|
8
|
+
stream: (req: any) => AsyncGenerator<{
|
|
9
|
+
delta: string;
|
|
10
|
+
done: boolean;
|
|
11
|
+
reasoning?: undefined;
|
|
12
|
+
usage?: undefined;
|
|
13
|
+
} | {
|
|
14
|
+
delta: string;
|
|
15
|
+
done: boolean;
|
|
16
|
+
reasoning: string;
|
|
17
|
+
usage?: undefined;
|
|
18
|
+
} | {
|
|
19
|
+
delta: string;
|
|
20
|
+
done: boolean;
|
|
21
|
+
usage: any;
|
|
22
|
+
reasoning?: undefined;
|
|
23
|
+
}, void, unknown>;
|
|
24
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { listModelsHttp, streamChatCompletion } from "./openaiCompatible.js";
|
|
2
|
+
function baseUrl() {
|
|
3
|
+
const host = (process.env["OLLAMA_HOST"] ?? "").trim() || "http://localhost:11434";
|
|
4
|
+
return host.endsWith("/v1") ? host : host + "/v1";
|
|
5
|
+
}
|
|
6
|
+
const STATIC = [
|
|
7
|
+
{ id: "qwen3-coder", label: "qwen3-coder (local)" },
|
|
8
|
+
{ id: "llama3.2", label: "llama3.2 (local)" },
|
|
9
|
+
{ id: "gpt-oss", label: "gpt-oss (local)" },
|
|
10
|
+
{ id: "deepseek-r1", label: "deepseek-r1 (local)" },
|
|
11
|
+
];
|
|
12
|
+
export const ollamaProvider = {
|
|
13
|
+
id: "ollama",
|
|
14
|
+
label: "Ollama (local)",
|
|
15
|
+
authEnv: [],
|
|
16
|
+
get baseUrl() {
|
|
17
|
+
return baseUrl();
|
|
18
|
+
},
|
|
19
|
+
defaultModel: "qwen3-coder",
|
|
20
|
+
listModels: () => listModelsHttp({ baseUrl: baseUrl(), apiKey: undefined, staticModels: STATIC }),
|
|
21
|
+
stream: (req) => streamChatCompletion(req, { baseUrl: baseUrl(), apiKey: undefined, staticModels: STATIC }),
|
|
22
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const openaiProvider: {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
authEnv: string[];
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
defaultModel: string;
|
|
7
|
+
listModels: (apiKey: any) => Promise<any>;
|
|
8
|
+
stream: (req: any, apiKey: any) => AsyncGenerator<{
|
|
9
|
+
delta: string;
|
|
10
|
+
done: boolean;
|
|
11
|
+
reasoning?: undefined;
|
|
12
|
+
usage?: undefined;
|
|
13
|
+
} | {
|
|
14
|
+
delta: string;
|
|
15
|
+
done: boolean;
|
|
16
|
+
reasoning: string;
|
|
17
|
+
usage?: undefined;
|
|
18
|
+
} | {
|
|
19
|
+
delta: string;
|
|
20
|
+
done: boolean;
|
|
21
|
+
usage: any;
|
|
22
|
+
reasoning?: undefined;
|
|
23
|
+
}, void, unknown>;
|
|
24
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { listModelsHttp, streamChatCompletion } from "./openaiCompatible.js";
|
|
2
|
+
const BASE = "https://api.openai.com/v1";
|
|
3
|
+
const STATIC = [
|
|
4
|
+
{ id: "gpt-6.1-sol", label: "GPT-6.1 Sol" },
|
|
5
|
+
{ id: "gpt-6.1-sol-pro", label: "GPT-6.1 Sol Pro" },
|
|
6
|
+
{ id: "gpt-6-luna", label: "GPT-6 Luna" },
|
|
7
|
+
{ id: "gpt-6-luna-pro", label: "GPT-6 Luna Pro" },
|
|
8
|
+
{ id: "gpt-6-sol", label: "GPT-6 Sol" },
|
|
9
|
+
{ id: "gpt-5.6-terra", label: "GPT-5.6 Terra" },
|
|
10
|
+
{ id: "gpt-5.6-luna", label: "GPT-5.6 Luna" },
|
|
11
|
+
{ id: "gpt-4.1", label: "GPT-4.1", pricing: { inputUsdPerM: 2, outputUsdPerM: 8 } },
|
|
12
|
+
{ id: "gpt-4o", label: "GPT-4o", pricing: { inputUsdPerM: 2.5, outputUsdPerM: 10 } },
|
|
13
|
+
{ id: "gpt-4o-mini", label: "GPT-4o mini", pricing: { inputUsdPerM: 0.15, outputUsdPerM: 0.6 } },
|
|
14
|
+
{ id: "o4-mini", label: "o4-mini" },
|
|
15
|
+
{ id: "o3", label: "o3" },
|
|
16
|
+
];
|
|
17
|
+
export const openaiProvider = {
|
|
18
|
+
id: "openai",
|
|
19
|
+
label: "OpenAI",
|
|
20
|
+
authEnv: ["OPENAI_API_KEY"],
|
|
21
|
+
baseUrl: BASE,
|
|
22
|
+
defaultModel: "gpt-6-luna",
|
|
23
|
+
listModels: (apiKey) => listModelsHttp({ baseUrl: BASE, apiKey, staticModels: STATIC }),
|
|
24
|
+
stream: (req, apiKey) => streamChatCompletion(req, { baseUrl: BASE, apiKey, staticModels: STATIC }),
|
|
25
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare function streamChatCompletion(req: any, opts: any): AsyncGenerator<{
|
|
2
|
+
delta: string;
|
|
3
|
+
done: boolean;
|
|
4
|
+
reasoning?: undefined;
|
|
5
|
+
usage?: undefined;
|
|
6
|
+
} | {
|
|
7
|
+
delta: string;
|
|
8
|
+
done: boolean;
|
|
9
|
+
reasoning: string;
|
|
10
|
+
usage?: undefined;
|
|
11
|
+
} | {
|
|
12
|
+
delta: string;
|
|
13
|
+
done: boolean;
|
|
14
|
+
usage: any;
|
|
15
|
+
reasoning?: undefined;
|
|
16
|
+
}, void, unknown>;
|
|
17
|
+
export declare function listModelsHttp(opts: any): Promise<any>;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { fetchJson, streamSSE } from "../lib/http.js";
|
|
2
|
+
/** Build a chat-completions body in the classic or the newer (compat) dialect. */
|
|
3
|
+
function buildBody(req, compat) {
|
|
4
|
+
const messages = [];
|
|
5
|
+
if (req.system)
|
|
6
|
+
messages.push({ role: "system", content: req.system });
|
|
7
|
+
for (const m of req.messages)
|
|
8
|
+
messages.push({ role: m.role, content: m.content });
|
|
9
|
+
const body = { model: req.model, messages, stream: true };
|
|
10
|
+
if (req.maxOutputTokens !== undefined) {
|
|
11
|
+
if (compat)
|
|
12
|
+
body.max_completion_tokens = req.maxOutputTokens;
|
|
13
|
+
else
|
|
14
|
+
body.max_tokens = req.maxOutputTokens;
|
|
15
|
+
}
|
|
16
|
+
if (req.temperature !== undefined && !compat)
|
|
17
|
+
body.temperature = req.temperature;
|
|
18
|
+
return body;
|
|
19
|
+
}
|
|
20
|
+
export async function* streamChatCompletion(req, opts) {
|
|
21
|
+
const send = async (compat) => {
|
|
22
|
+
const headers = {
|
|
23
|
+
"content-type": "application/json",
|
|
24
|
+
accept: "text/event-stream",
|
|
25
|
+
...(opts.extraHeaders ?? {}),
|
|
26
|
+
};
|
|
27
|
+
if (opts.apiKey)
|
|
28
|
+
headers["authorization"] = (opts.authHeader ?? "Bearer") + " " + opts.apiKey;
|
|
29
|
+
return await fetch(trim(opts.baseUrl) + "/chat/completions", {
|
|
30
|
+
method: "POST",
|
|
31
|
+
headers,
|
|
32
|
+
body: JSON.stringify(buildBody(req, compat)),
|
|
33
|
+
signal: req.signal,
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
let res = await send(false);
|
|
37
|
+
if (!res.ok) {
|
|
38
|
+
const detail = await res.text().catch(() => "");
|
|
39
|
+
// Newer OpenAI-style models reject max_tokens and temperature. Retry once
|
|
40
|
+
// in the compatibility dialect before surfacing the real error.
|
|
41
|
+
if (res.status === 400 && /max_tokens|max_completion_tokens|temperature|unsupported|unrecognized|unknown parameter/i.test(detail)) {
|
|
42
|
+
res = await send(true);
|
|
43
|
+
}
|
|
44
|
+
if (!res.ok) {
|
|
45
|
+
const body = await res.text().catch(() => "");
|
|
46
|
+
throw new Error(res.status + " " + res.statusText + ": " + body.slice(0, 500));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
let usage;
|
|
50
|
+
for await (const ev of streamSSE(res)) {
|
|
51
|
+
if (ev.data === "[DONE]")
|
|
52
|
+
break;
|
|
53
|
+
let payload;
|
|
54
|
+
try {
|
|
55
|
+
payload = JSON.parse(ev.data);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const obj = payload;
|
|
61
|
+
const choice = obj.choices?.[0];
|
|
62
|
+
const raw = choice?.delta?.content ?? choice?.text;
|
|
63
|
+
const reasoning = choice?.delta?.reasoning_content ?? choice?.delta?.reasoning;
|
|
64
|
+
if (obj.usage) {
|
|
65
|
+
usage = {
|
|
66
|
+
inputTokens: obj.usage.prompt_tokens,
|
|
67
|
+
outputTokens: obj.usage.completion_tokens,
|
|
68
|
+
totalTokens: obj.usage.total_tokens,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const text = typeof raw === "string"
|
|
72
|
+
? raw
|
|
73
|
+
: Array.isArray(raw)
|
|
74
|
+
? raw.map((part) => (part?.text ?? "")).join("")
|
|
75
|
+
: "";
|
|
76
|
+
if (text)
|
|
77
|
+
yield { delta: text, done: false };
|
|
78
|
+
else if (typeof reasoning === "string" && reasoning)
|
|
79
|
+
yield { delta: "", done: false, reasoning };
|
|
80
|
+
}
|
|
81
|
+
yield { delta: "", done: true, usage };
|
|
82
|
+
}
|
|
83
|
+
export async function listModelsHttp(opts) {
|
|
84
|
+
const staticModels = opts.staticModels ?? [];
|
|
85
|
+
if (!opts.apiKey && staticModels.length)
|
|
86
|
+
return staticModels;
|
|
87
|
+
try {
|
|
88
|
+
const headers = {};
|
|
89
|
+
if (opts.apiKey)
|
|
90
|
+
headers["authorization"] = (opts.authHeader ?? "Bearer") + " " + opts.apiKey;
|
|
91
|
+
const json = await fetchJson(trim(opts.baseUrl) + "/models", { headers });
|
|
92
|
+
const ids = (json.data ?? [])
|
|
93
|
+
.map((m) => m.id)
|
|
94
|
+
.filter((id) => typeof id === "string" && id.length > 0);
|
|
95
|
+
if (ids.length === 0)
|
|
96
|
+
return staticModels;
|
|
97
|
+
// The provider's live list is authoritative: show exactly what it
|
|
98
|
+
// returns (enriched with our labels/pricing where the id is known).
|
|
99
|
+
// Static models the provider no longer returns are dropped so delisted
|
|
100
|
+
// models don't linger in the picker.
|
|
101
|
+
const known = new Map(staticModels.map((m) => [m.id, m]));
|
|
102
|
+
return ids.map((id) => known.get(id) ?? { id });
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return staticModels;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function trim(url) {
|
|
109
|
+
return url.replace(/[/]+$/, "");
|
|
110
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const openrouterProvider: {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
authEnv: string[];
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
defaultModel: string;
|
|
7
|
+
listModels: (apiKey: any) => Promise<any>;
|
|
8
|
+
stream: (req: any, apiKey: any) => AsyncGenerator<{
|
|
9
|
+
delta: string;
|
|
10
|
+
done: boolean;
|
|
11
|
+
reasoning?: undefined;
|
|
12
|
+
usage?: undefined;
|
|
13
|
+
} | {
|
|
14
|
+
delta: string;
|
|
15
|
+
done: boolean;
|
|
16
|
+
reasoning: string;
|
|
17
|
+
usage?: undefined;
|
|
18
|
+
} | {
|
|
19
|
+
delta: string;
|
|
20
|
+
done: boolean;
|
|
21
|
+
usage: any;
|
|
22
|
+
reasoning?: undefined;
|
|
23
|
+
}, void, unknown>;
|
|
24
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { listModelsHttp, streamChatCompletion } from "./openaiCompatible.js";
|
|
2
|
+
const BASE = "https://openrouter.ai/api/v1";
|
|
3
|
+
const STATIC = [
|
|
4
|
+
{ id: "anthropic/claude-sonnet-5.5", label: "Claude Sonnet 5.5" },
|
|
5
|
+
{ id: "openai/gpt-6-luna", label: "GPT-6 Luna" },
|
|
6
|
+
{ id: "google/gemini-3.8-flash", label: "Gemini 3.8 Flash" },
|
|
7
|
+
{ id: "deepseek/deepseek-v4-pro", label: "DeepSeek V4 Pro" },
|
|
8
|
+
{ id: "x-ai/grok-4.7", label: "Grok 4.7" },
|
|
9
|
+
{ id: "moonshotai/kimi-k3", label: "Kimi K3" },
|
|
10
|
+
{ id: "z-ai/glm-5.3", label: "GLM 5.3" },
|
|
11
|
+
{ id: "qwen/qwen3.8-max", label: "Qwen3.8 Max" },
|
|
12
|
+
{ id: "meta-llama/llama-4-maverick", label: "Llama 4 Maverick" },
|
|
13
|
+
];
|
|
14
|
+
const EXTRA_HEADERS = {
|
|
15
|
+
"http-referer": "https://github.com/dateName/fastcode-termux",
|
|
16
|
+
"x-title": "FastCode",
|
|
17
|
+
};
|
|
18
|
+
export const openrouterProvider = {
|
|
19
|
+
id: "openrouter",
|
|
20
|
+
label: "OpenRouter (400+ models)",
|
|
21
|
+
authEnv: ["OPENROUTER_API_KEY"],
|
|
22
|
+
baseUrl: BASE,
|
|
23
|
+
defaultModel: "anthropic/claude-sonnet-5.5",
|
|
24
|
+
listModels: (apiKey) => listModelsHttp({ baseUrl: BASE, apiKey, staticModels: STATIC, extraHeaders: EXTRA_HEADERS }),
|
|
25
|
+
stream: (req, apiKey) => streamChatCompletion(req, { baseUrl: BASE, apiKey, staticModels: STATIC, extraHeaders: EXTRA_HEADERS }),
|
|
26
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const qwenProvider: {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
authEnv: string[];
|
|
5
|
+
readonly baseUrl: string;
|
|
6
|
+
defaultModel: string;
|
|
7
|
+
listModels: (apiKey: any) => Promise<any>;
|
|
8
|
+
stream: (req: any, apiKey: any) => AsyncGenerator<{
|
|
9
|
+
delta: string;
|
|
10
|
+
done: boolean;
|
|
11
|
+
reasoning?: undefined;
|
|
12
|
+
usage?: undefined;
|
|
13
|
+
} | {
|
|
14
|
+
delta: string;
|
|
15
|
+
done: boolean;
|
|
16
|
+
reasoning: string;
|
|
17
|
+
usage?: undefined;
|
|
18
|
+
} | {
|
|
19
|
+
delta: string;
|
|
20
|
+
done: boolean;
|
|
21
|
+
usage: any;
|
|
22
|
+
reasoning?: undefined;
|
|
23
|
+
}, void, unknown>;
|
|
24
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { listModelsHttp, streamChatCompletion } from "./openaiCompatible.js";
|
|
2
|
+
function baseUrl() {
|
|
3
|
+
return (process.env["DASHSCOPE_BASE_URL"] ?? "").trim() || "https://dashscope.aliyuncs.com/compatible-mode/v1";
|
|
4
|
+
}
|
|
5
|
+
const STATIC = [
|
|
6
|
+
{ id: "qwen3.8-max", label: "Qwen3.8 Max" },
|
|
7
|
+
{ id: "qwen3.8-flash", label: "Qwen3.8 Flash" },
|
|
8
|
+
{ id: "qwen3.7-max", label: "Qwen3.7 Max" },
|
|
9
|
+
{ id: "qwen3.7-plus", label: "Qwen3.7 Plus" },
|
|
10
|
+
{ id: "qwen3-coder-next", label: "Qwen3 Coder Next" },
|
|
11
|
+
{ id: "qwen3.6-27b", label: "Qwen3.6 27B" },
|
|
12
|
+
];
|
|
13
|
+
export const qwenProvider = {
|
|
14
|
+
id: "qwen",
|
|
15
|
+
label: "Qwen (DashScope)",
|
|
16
|
+
authEnv: ["DASHSCOPE_API_KEY", "QWEN_API_KEY"],
|
|
17
|
+
get baseUrl() {
|
|
18
|
+
return baseUrl();
|
|
19
|
+
},
|
|
20
|
+
defaultModel: "qwen3.8-max",
|
|
21
|
+
listModels: (apiKey) => listModelsHttp({ baseUrl: baseUrl(), apiKey, staticModels: STATIC }),
|
|
22
|
+
stream: (req, apiKey) => streamChatCompletion(req, { baseUrl: baseUrl(), apiKey, staticModels: STATIC }),
|
|
23
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const xaiProvider: {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
authEnv: string[];
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
defaultModel: string;
|
|
7
|
+
listModels: (apiKey: any) => Promise<any>;
|
|
8
|
+
stream: (req: any, apiKey: any) => AsyncGenerator<{
|
|
9
|
+
delta: string;
|
|
10
|
+
done: boolean;
|
|
11
|
+
reasoning?: undefined;
|
|
12
|
+
usage?: undefined;
|
|
13
|
+
} | {
|
|
14
|
+
delta: string;
|
|
15
|
+
done: boolean;
|
|
16
|
+
reasoning: string;
|
|
17
|
+
usage?: undefined;
|
|
18
|
+
} | {
|
|
19
|
+
delta: string;
|
|
20
|
+
done: boolean;
|
|
21
|
+
usage: any;
|
|
22
|
+
reasoning?: undefined;
|
|
23
|
+
}, void, unknown>;
|
|
24
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { listModelsHttp, streamChatCompletion } from "./openaiCompatible.js";
|
|
2
|
+
const BASE = "https://api.x.ai/v1";
|
|
3
|
+
const STATIC = [
|
|
4
|
+
{ id: "grok-4.7", label: "Grok 4.7" },
|
|
5
|
+
{ id: "grok-4.6", label: "Grok 4.6" },
|
|
6
|
+
{ id: "grok-4.5", label: "Grok 4.5" },
|
|
7
|
+
{ id: "grok-4.3", label: "Grok 4.3" },
|
|
8
|
+
{ id: "grok-4.20", label: "Grok 4.20" },
|
|
9
|
+
];
|
|
10
|
+
export const xaiProvider = {
|
|
11
|
+
id: "xai",
|
|
12
|
+
label: "xAI (Grok)",
|
|
13
|
+
authEnv: ["XAI_API_KEY", "GROK_API_KEY"],
|
|
14
|
+
baseUrl: BASE,
|
|
15
|
+
defaultModel: "grok-4.7",
|
|
16
|
+
listModels: (apiKey) => listModelsHttp({ baseUrl: BASE, apiKey, staticModels: STATIC }),
|
|
17
|
+
stream: (req, apiKey) => streamChatCompletion(req, { baseUrl: BASE, apiKey, staticModels: STATIC }),
|
|
18
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const zhipuProvider: {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
authEnv: string[];
|
|
5
|
+
readonly baseUrl: string;
|
|
6
|
+
defaultModel: string;
|
|
7
|
+
listModels: (apiKey: any) => Promise<any>;
|
|
8
|
+
stream: (req: any, apiKey: any) => AsyncGenerator<{
|
|
9
|
+
delta: string;
|
|
10
|
+
done: boolean;
|
|
11
|
+
reasoning?: undefined;
|
|
12
|
+
usage?: undefined;
|
|
13
|
+
} | {
|
|
14
|
+
delta: string;
|
|
15
|
+
done: boolean;
|
|
16
|
+
reasoning: string;
|
|
17
|
+
usage?: undefined;
|
|
18
|
+
} | {
|
|
19
|
+
delta: string;
|
|
20
|
+
done: boolean;
|
|
21
|
+
usage: any;
|
|
22
|
+
reasoning?: undefined;
|
|
23
|
+
}, void, unknown>;
|
|
24
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { listModelsHttp, streamChatCompletion } from "./openaiCompatible.js";
|
|
2
|
+
function baseUrl() {
|
|
3
|
+
return (process.env["ZHIPU_BASE_URL"] ?? "").trim() || "https://open.bigmodel.cn/api/paas/v4";
|
|
4
|
+
}
|
|
5
|
+
const STATIC = [
|
|
6
|
+
{ id: "glm-5.3", label: "GLM 5.3" },
|
|
7
|
+
{ id: "glm-5.2", label: "GLM 5.2" },
|
|
8
|
+
{ id: "glm-5.1", label: "GLM 5.1" },
|
|
9
|
+
{ id: "glm-5", label: "GLM 5" },
|
|
10
|
+
{ id: "glm-4.7", label: "GLM 4.7" },
|
|
11
|
+
{ id: "glm-4.6", label: "GLM 4.6" },
|
|
12
|
+
];
|
|
13
|
+
export const zhipuProvider = {
|
|
14
|
+
id: "zhipu",
|
|
15
|
+
label: "Zhipu (GLM)",
|
|
16
|
+
authEnv: ["ZHIPUAI_API_KEY", "GLM_API_KEY", "ZHIPU_API_KEY"],
|
|
17
|
+
get baseUrl() {
|
|
18
|
+
return baseUrl();
|
|
19
|
+
},
|
|
20
|
+
defaultModel: "glm-5.3",
|
|
21
|
+
listModels: (apiKey) => listModelsHttp({ baseUrl: baseUrl(), apiKey, staticModels: STATIC }),
|
|
22
|
+
stream: (req, apiKey) => streamChatCompletion(req, { baseUrl: baseUrl(), apiKey, staticModels: STATIC }),
|
|
23
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare function sessionCacheLimitBytes(): number;
|
|
2
|
+
export declare function loggingEnabled(): boolean;
|
|
3
|
+
export declare function createSessionLog(meta?: {}): {
|
|
4
|
+
id: any;
|
|
5
|
+
file: any;
|
|
6
|
+
append: (entry: any) => void;
|
|
7
|
+
close(): void;
|
|
8
|
+
};
|
|
9
|
+
export declare function openSessionLog(file: any): {
|
|
10
|
+
id: any;
|
|
11
|
+
file: any;
|
|
12
|
+
append: (entry: any) => void;
|
|
13
|
+
close(): void;
|
|
14
|
+
};
|
|
15
|
+
export declare function listSessions(): {
|
|
16
|
+
id: string;
|
|
17
|
+
file: string;
|
|
18
|
+
bytes: number;
|
|
19
|
+
modified: string;
|
|
20
|
+
messages: number;
|
|
21
|
+
}[];
|
|
22
|
+
export declare function resolveSessionFile(idOrFile: any): any;
|
|
23
|
+
export declare function readSession(idOrFile: any): any[];
|
|
24
|
+
export declare function loadSessionMessages(idOrFile: any): {
|
|
25
|
+
role: any;
|
|
26
|
+
content: any;
|
|
27
|
+
}[];
|
|
28
|
+
export declare function latestSessionFile(): string;
|
|
29
|
+
export declare function pruneSessions(limit?: number): number;
|