@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.
Files changed (197) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +400 -2
  3. package/bin/fastcode.mjs +59 -0
  4. package/dist/agent/guards.d.ts +35 -0
  5. package/dist/agent/guards.js +74 -0
  6. package/dist/agent/limits.d.ts +24 -0
  7. package/dist/agent/limits.js +71 -0
  8. package/dist/agent/protocol.d.ts +4 -0
  9. package/dist/agent/protocol.js +126 -0
  10. package/dist/agent/tools.d.ts +1 -0
  11. package/dist/agent/tools.js +377 -0
  12. package/dist/app.d.ts +4 -0
  13. package/dist/app.js +476 -0
  14. package/dist/cli.d.ts +1 -0
  15. package/dist/cli.js +518 -0
  16. package/dist/commands/about.d.ts +8 -0
  17. package/dist/commands/about.js +16 -0
  18. package/dist/commands/agent.d.ts +11 -0
  19. package/dist/commands/agent.js +18 -0
  20. package/dist/commands/clear.d.ts +11 -0
  21. package/dist/commands/clear.js +9 -0
  22. package/dist/commands/config.d.ts +7 -0
  23. package/dist/commands/config.js +24 -0
  24. package/dist/commands/cost.d.ts +9 -0
  25. package/dist/commands/cost.js +13 -0
  26. package/dist/commands/cwd.d.ts +7 -0
  27. package/dist/commands/cwd.js +7 -0
  28. package/dist/commands/exit.d.ts +9 -0
  29. package/dist/commands/exit.js +8 -0
  30. package/dist/commands/help.d.ts +6 -0
  31. package/dist/commands/help.js +18 -0
  32. package/dist/commands/index.d.ts +9 -0
  33. package/dist/commands/index.js +58 -0
  34. package/dist/commands/login.d.ts +16 -0
  35. package/dist/commands/login.js +61 -0
  36. package/dist/commands/logout.d.ts +9 -0
  37. package/dist/commands/logout.js +53 -0
  38. package/dist/commands/model.d.ts +11 -0
  39. package/dist/commands/model.js +30 -0
  40. package/dist/commands/plugin.d.ts +11 -0
  41. package/dist/commands/plugin.js +74 -0
  42. package/dist/commands/provider.d.ts +11 -0
  43. package/dist/commands/provider.js +28 -0
  44. package/dist/commands/reset.d.ts +9 -0
  45. package/dist/commands/reset.js +13 -0
  46. package/dist/commands/skills.d.ts +11 -0
  47. package/dist/commands/skills.js +106 -0
  48. package/dist/commands/system.d.ts +11 -0
  49. package/dist/commands/system.js +20 -0
  50. package/dist/commands/theme.d.ts +11 -0
  51. package/dist/commands/theme.js +22 -0
  52. package/dist/commands/tools.d.ts +7 -0
  53. package/dist/commands/tools.js +29 -0
  54. package/dist/commands/whoami.d.ts +9 -0
  55. package/dist/commands/whoami.js +51 -0
  56. package/dist/config/paths.d.ts +4 -0
  57. package/dist/config/paths.js +59 -0
  58. package/dist/config/store.d.ts +69 -0
  59. package/dist/config/store.js +208 -0
  60. package/dist/config/themes.d.ts +73 -0
  61. package/dist/config/themes.js +77 -0
  62. package/dist/config/trust.d.ts +9 -0
  63. package/dist/config/trust.js +67 -0
  64. package/dist/index.d.ts +1 -0
  65. package/dist/index.js +31 -0
  66. package/dist/lib/diagnostics.d.ts +41 -0
  67. package/dist/lib/diagnostics.js +139 -0
  68. package/dist/lib/http.d.ts +13 -0
  69. package/dist/lib/http.js +70 -0
  70. package/dist/lib/markdown.d.ts +1 -0
  71. package/dist/lib/markdown.js +32 -0
  72. package/dist/lib/pkg.d.ts +5 -0
  73. package/dist/lib/pkg.js +27 -0
  74. package/dist/lib/platform.d.ts +7 -0
  75. package/dist/lib/platform.js +57 -0
  76. package/dist/lib/startup.d.ts +6 -0
  77. package/dist/lib/startup.js +25 -0
  78. package/dist/lib/uiMode.d.ts +2 -0
  79. package/dist/lib/uiMode.js +7 -0
  80. package/dist/plugins/manager.d.ts +23 -0
  81. package/dist/plugins/manager.js +101 -0
  82. package/dist/providers/anthropic.d.ts +21 -0
  83. package/dist/providers/anthropic.js +107 -0
  84. package/dist/providers/custom.d.ts +24 -0
  85. package/dist/providers/custom.js +25 -0
  86. package/dist/providers/deepseek.d.ts +24 -0
  87. package/dist/providers/deepseek.js +15 -0
  88. package/dist/providers/google.d.ts +24 -0
  89. package/dist/providers/google.js +19 -0
  90. package/dist/providers/groq.d.ts +24 -0
  91. package/dist/providers/groq.js +20 -0
  92. package/dist/providers/index.d.ts +201 -0
  93. package/dist/providers/index.js +37 -0
  94. package/dist/providers/mistral.d.ts +24 -0
  95. package/dist/providers/mistral.js +19 -0
  96. package/dist/providers/moonshot.d.ts +24 -0
  97. package/dist/providers/moonshot.js +22 -0
  98. package/dist/providers/ollama.d.ts +24 -0
  99. package/dist/providers/ollama.js +22 -0
  100. package/dist/providers/openai.d.ts +24 -0
  101. package/dist/providers/openai.js +25 -0
  102. package/dist/providers/openaiCompatible.d.ts +17 -0
  103. package/dist/providers/openaiCompatible.js +110 -0
  104. package/dist/providers/openrouter.d.ts +24 -0
  105. package/dist/providers/openrouter.js +26 -0
  106. package/dist/providers/qwen.d.ts +24 -0
  107. package/dist/providers/qwen.js +23 -0
  108. package/dist/providers/xai.d.ts +24 -0
  109. package/dist/providers/xai.js +18 -0
  110. package/dist/providers/zhipu.d.ts +24 -0
  111. package/dist/providers/zhipu.js +23 -0
  112. package/dist/session/log.d.ts +29 -0
  113. package/dist/session/log.js +135 -0
  114. package/dist/skills/manager.d.ts +18 -0
  115. package/dist/skills/manager.js +201 -0
  116. package/dist/skills/parser.d.ts +18 -0
  117. package/dist/skills/parser.js +65 -0
  118. package/dist/types.d.ts +146 -0
  119. package/dist/types.js +1 -0
  120. package/dist/ui/Banner.d.ts +5 -0
  121. package/dist/ui/Banner.js +65 -0
  122. package/dist/ui/Message.d.ts +7 -0
  123. package/dist/ui/Message.js +13 -0
  124. package/dist/ui/Prompt.d.ts +10 -0
  125. package/dist/ui/Prompt.js +38 -0
  126. package/dist/ui/Spinner.d.ts +5 -0
  127. package/dist/ui/Spinner.js +33 -0
  128. package/dist/ui/StatusBar.d.ts +10 -0
  129. package/dist/ui/StatusBar.js +19 -0
  130. package/dist/ui/TrustGate.d.ts +5 -0
  131. package/dist/ui/TrustGate.js +26 -0
  132. package/package.json +96 -4
  133. package/src/agent/guards.ts +74 -0
  134. package/src/agent/limits.ts +71 -0
  135. package/src/agent/protocol.ts +126 -0
  136. package/src/agent/tools.ts +377 -0
  137. package/src/app.ts +476 -0
  138. package/src/cli.ts +308 -0
  139. package/src/commands/about.ts +16 -0
  140. package/src/commands/agent.ts +18 -0
  141. package/src/commands/clear.ts +9 -0
  142. package/src/commands/config.ts +24 -0
  143. package/src/commands/cost.ts +13 -0
  144. package/src/commands/cwd.ts +7 -0
  145. package/src/commands/exit.ts +8 -0
  146. package/src/commands/help.ts +18 -0
  147. package/src/commands/index.ts +58 -0
  148. package/src/commands/login.ts +61 -0
  149. package/src/commands/logout.ts +53 -0
  150. package/src/commands/model.ts +30 -0
  151. package/src/commands/plugin.ts +74 -0
  152. package/src/commands/provider.ts +28 -0
  153. package/src/commands/reset.ts +13 -0
  154. package/src/commands/skills.ts +106 -0
  155. package/src/commands/system.ts +20 -0
  156. package/src/commands/theme.ts +22 -0
  157. package/src/commands/tools.ts +29 -0
  158. package/src/commands/whoami.ts +51 -0
  159. package/src/config/paths.ts +59 -0
  160. package/src/config/store.ts +240 -0
  161. package/src/config/themes.ts +77 -0
  162. package/src/config/trust.ts +67 -0
  163. package/src/index.ts +31 -0
  164. package/src/lib/diagnostics.ts +139 -0
  165. package/src/lib/http.ts +70 -0
  166. package/src/lib/markdown.ts +32 -0
  167. package/src/lib/pkg.ts +35 -0
  168. package/src/lib/platform.ts +57 -0
  169. package/src/lib/startup.ts +25 -0
  170. package/src/lib/uiMode.ts +7 -0
  171. package/src/plugins/manager.ts +101 -0
  172. package/src/providers/anthropic.ts +107 -0
  173. package/src/providers/custom.ts +25 -0
  174. package/src/providers/deepseek.ts +15 -0
  175. package/src/providers/google.ts +19 -0
  176. package/src/providers/groq.ts +20 -0
  177. package/src/providers/index.ts +37 -0
  178. package/src/providers/mistral.ts +19 -0
  179. package/src/providers/moonshot.ts +22 -0
  180. package/src/providers/ollama.ts +22 -0
  181. package/src/providers/openai.ts +25 -0
  182. package/src/providers/openaiCompatible.ts +110 -0
  183. package/src/providers/openrouter.ts +26 -0
  184. package/src/providers/qwen.ts +23 -0
  185. package/src/providers/xai.ts +18 -0
  186. package/src/providers/zhipu.ts +23 -0
  187. package/src/session/log.ts +135 -0
  188. package/src/skills/manager.ts +201 -0
  189. package/src/skills/parser.ts +65 -0
  190. package/src/types.ts +143 -0
  191. package/src/ui/Banner.ts +68 -0
  192. package/src/ui/Message.ts +13 -0
  193. package/src/ui/Prompt.ts +38 -0
  194. package/src/ui/Spinner.ts +33 -0
  195. package/src/ui/StatusBar.ts +19 -0
  196. package/src/ui/TrustGate.ts +26 -0
  197. 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;