@cjhyy/code-shell 0.1.6 → 0.1.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/dist/anthropic-UBSB5AQH.js +1 -0
- package/dist/arena/index.js +1 -104
- package/dist/arena-OW55ZCHT.js +3 -0
- package/dist/bwrap-PVZMLHZR.js +2 -0
- package/dist/chunk-2NS3JMNK.js +1 -0
- package/dist/chunk-3QP5BQ3L.js +1 -0
- package/dist/chunk-B7K2OWKC.js +2 -0
- package/dist/chunk-EWWK56K6.js +2 -0
- package/dist/chunk-FU7AHZNN.js +1 -0
- package/dist/chunk-HIJ2XXGX.js +1 -0
- package/dist/chunk-KCXSARAA.js +1 -0
- package/dist/chunk-NFH3UQ3E.js +2 -0
- package/dist/chunk-NMBYBGC7.js +250 -0
- package/dist/chunk-NVAZJ5XS.js +2 -0
- package/dist/chunk-O5HFCH2U.js +1 -0
- package/dist/chunk-P6JSTIFM.js +1 -0
- package/dist/chunk-PGANL6F2.js +3 -0
- package/dist/chunk-Q4O2HGWS.js +251 -0
- package/dist/chunk-QTWU7UNA.js +5 -0
- package/dist/chunk-RP26WO4R.js +1 -0
- package/dist/chunk-SNFAPSLA.js +1 -0
- package/dist/chunk-T222K6IV.js +18 -0
- package/dist/chunk-TKJA6W36.js +3 -0
- package/dist/chunk-UDPUTFQT.js +2 -0
- package/dist/chunk-W47Z7MGS.js +33 -0
- package/dist/chunk-WI6FSWGU.js +1 -0
- package/dist/chunk-WOP6MJKW.js +1 -0
- package/dist/chunk-XDOWC7EG.js +4 -0
- package/dist/chunk-Y2NS6HPO.js +641 -0
- package/dist/cli/main.js +303 -22060
- package/dist/client-base-6ZZJJYDY.js +1 -0
- package/dist/compaction-ECVQVOCT.js +1 -0
- package/dist/devtools-SGDUOOM4.js +1 -0
- package/dist/engine/engine.d.ts +8 -0
- package/dist/export-md-U72T7NW7.js +22 -0
- package/dist/file-history-7FQFEQOL.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -347
- package/dist/llm/token-counter.d.ts +17 -0
- package/dist/manager-C3TDN6MS.js +1 -0
- package/dist/mcp-manager-OP4XYV53.js +1 -0
- package/dist/memory-BNI4WEWL.js +1 -0
- package/dist/model-cache-HEDXI7UJ.js +1 -0
- package/dist/model-fetcher-BJ64META.js +1 -0
- package/dist/off-7SDVMMXW.js +1 -0
- package/dist/openai-KEWQ54TM.js +1 -0
- package/dist/openrouter-models-AM6M52D6.js +1 -0
- package/dist/openrouter-sync-5JNBL3Z6.js +1 -0
- package/dist/product/index.js +1 -21
- package/dist/run/index.js +1 -48
- package/dist/seatbelt-WBYROQT6.js +37 -0
- package/dist/session/session-manager.d.ts +2 -0
- package/dist/session-manager-AGWS5SMJ.js +1 -0
- package/dist/settings/schema.d.ts +72 -6
- package/dist/tool-summary-5UE62VU4.js +2 -0
- package/dist/tool-system/builtin/bash.d.ts +7 -1
- package/dist/tool-system/context.d.ts +7 -0
- package/dist/tool-system/sandbox/bwrap.d.ts +13 -0
- package/dist/tool-system/sandbox/index.d.ts +71 -0
- package/dist/tool-system/sandbox/off.d.ts +2 -0
- package/dist/tool-system/sandbox/seatbelt.d.ts +18 -0
- package/dist/types.d.ts +4 -0
- package/dist/ui/components/SessionPicker.d.ts +2 -0
- package/dist/ui/components/SpinnerWithVerb.d.ts +2 -2
- package/dist/ui/components/StatusLine.d.ts +2 -2
- package/dist/updater-OCNU2K2Z.js +1 -0
- package/package.json +7 -10
- package/dist/anthropic-IBTI4WL2.cjs +0 -10
- package/dist/anthropic-PRZZKHEZ.js +0 -10
- package/dist/arena/index.cjs +0 -104
- package/dist/arena-2LTLIXOL.js +0 -261
- package/dist/arena-ADB7DRFI.cjs +0 -261
- package/dist/chunk-2YW4FPFG.cjs +0 -101
- package/dist/chunk-3OA5G4TM.js +0 -47
- package/dist/chunk-3QO25N6E.js +0 -4711
- package/dist/chunk-3SBSUOWZ.js +0 -447
- package/dist/chunk-52LGZKT3.cjs +0 -47
- package/dist/chunk-55XGPMAP.cjs +0 -146
- package/dist/chunk-6QVAYW7C.cjs +0 -438
- package/dist/chunk-6S4BJ65N.js +0 -113
- package/dist/chunk-76HYEPDM.js +0 -307
- package/dist/chunk-7BI3V74Y.cjs +0 -447
- package/dist/chunk-7EG3V4JY.cjs +0 -113
- package/dist/chunk-7JVTYEEC.js +0 -340
- package/dist/chunk-7QIM3BKD.js +0 -44
- package/dist/chunk-7Y6S3OCX.js +0 -438
- package/dist/chunk-ABRRONJ7.js +0 -107
- package/dist/chunk-BSW22MPA.js +0 -146
- package/dist/chunk-BXCY2FSE.js +0 -203
- package/dist/chunk-BZ5TNE7L.js +0 -5128
- package/dist/chunk-DDB6QOKJ.cjs +0 -1252
- package/dist/chunk-HEKQCI7B.cjs +0 -224
- package/dist/chunk-IK4EWJBP.cjs +0 -203
- package/dist/chunk-ILHE7XLT.cjs +0 -107
- package/dist/chunk-JMR33QVF.cjs +0 -169
- package/dist/chunk-KAQHULYN.js +0 -54
- package/dist/chunk-KE4EQOWA.js +0 -294
- package/dist/chunk-KOVYSDHZ.cjs +0 -340
- package/dist/chunk-KS3RYAYL.cjs +0 -45
- package/dist/chunk-MD32R22I.js +0 -50
- package/dist/chunk-MV7YI4WO.cjs +0 -293
- package/dist/chunk-MY5XHADU.cjs +0 -216
- package/dist/chunk-NUNC3VFB.cjs +0 -307
- package/dist/chunk-PKGRTCCY.js +0 -9092
- package/dist/chunk-QARL3IDQ.js +0 -1252
- package/dist/chunk-S754JHLR.cjs +0 -54
- package/dist/chunk-SFXHZSRF.js +0 -101
- package/dist/chunk-SIHHIQLO.js +0 -224
- package/dist/chunk-T6VYG46N.js +0 -105
- package/dist/chunk-TNLGBJYS.cjs +0 -44
- package/dist/chunk-TUY2T5KP.cjs +0 -105
- package/dist/chunk-UXOCVJJ6.cjs +0 -9092
- package/dist/chunk-VIAGTYYW.js +0 -169
- package/dist/chunk-WASS5YWB.js +0 -215
- package/dist/chunk-WZJV6DJC.cjs +0 -5128
- package/dist/chunk-YIQBXAYU.cjs +0 -264
- package/dist/chunk-YKIAELDZ.cjs +0 -4711
- package/dist/chunk-ZBPSQCPU.js +0 -264
- package/dist/cli/main.cjs +0 -22156
- package/dist/client-base-HTF236ZD.cjs +0 -9
- package/dist/client-base-QKRKCOWB.js +0 -9
- package/dist/compaction-6VU2T643.js +0 -33
- package/dist/compaction-OKUNTCA7.cjs +0 -33
- package/dist/devtools-T2NIZBJK.cjs +0 -6
- package/dist/devtools-YXWHOVKR.js +0 -6
- package/dist/export-md-RXDW6F5W.cjs +0 -135
- package/dist/export-md-XXKZANW5.js +0 -135
- package/dist/file-history-KYPE3ECT.cjs +0 -7
- package/dist/file-history-LF4F7X26.js +0 -7
- package/dist/index.cjs +0 -347
- package/dist/manager-D65VFAPX.js +0 -7
- package/dist/manager-TTF5VHJC.cjs +0 -7
- package/dist/mcp-manager-QMKWPBZ4.js +0 -8
- package/dist/mcp-manager-Z3OKI74O.cjs +0 -8
- package/dist/memory-5LWZ6FI2.cjs +0 -9
- package/dist/memory-VIJLBAMQ.js +0 -9
- package/dist/model-cache-5KIYL5SL.js +0 -13
- package/dist/model-cache-OED3IM4R.cjs +0 -13
- package/dist/model-fetcher-HKGICACL.js +0 -8
- package/dist/model-fetcher-UR6WJOQP.cjs +0 -8
- package/dist/openai-JR2WEKOF.js +0 -10
- package/dist/openai-YBTOET4O.cjs +0 -10
- package/dist/openrouter-models-H56GHBHN.js +0 -15
- package/dist/openrouter-models-TWUFWZ5T.cjs +0 -15
- package/dist/openrouter-sync-5VMGN6C2.cjs +0 -11
- package/dist/openrouter-sync-ALEMF5IU.js +0 -11
- package/dist/product/index.cjs +0 -21
- package/dist/run/index.cjs +0 -48
- package/dist/session-manager-Q22BBMD3.js +0 -8
- package/dist/session-manager-XODQVL3C.cjs +0 -8
- package/dist/tool-summary-63DPIS7G.cjs +0 -31
- package/dist/tool-summary-NP5CDBKG.js +0 -31
- package/dist/updater-I7QBW4DP.cjs +0 -17
- package/dist/updater-NVME5S3Z.js +0 -17
package/dist/chunk-VIAGTYYW.js
DELETED
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
init_esm_shims
|
|
3
|
-
} from "./chunk-MD32R22I.js";
|
|
4
|
-
|
|
5
|
-
// src/session/memory.ts
|
|
6
|
-
init_esm_shims();
|
|
7
|
-
import { mkdirSync, existsSync, readFileSync, writeFileSync, readdirSync, unlinkSync } from "fs";
|
|
8
|
-
import { join } from "path";
|
|
9
|
-
import { homedir } from "os";
|
|
10
|
-
function resolveMemoryBaseDir(override) {
|
|
11
|
-
if (override) return override;
|
|
12
|
-
const fromEnv = process.env.CODE_SHELL_HOME;
|
|
13
|
-
if (fromEnv && fromEnv.length > 0) return fromEnv;
|
|
14
|
-
return join(homedir(), ".code-shell");
|
|
15
|
-
}
|
|
16
|
-
var MemoryManager = class {
|
|
17
|
-
baseDir;
|
|
18
|
-
memoryDir;
|
|
19
|
-
indexPath;
|
|
20
|
-
// Per-instance cache of {fileName -> {name, description}} so the
|
|
21
|
-
// index can be rewritten without re-reading every memory file
|
|
22
|
-
// every time a single entry is saved/deleted (the previous code
|
|
23
|
-
// path called loadAll() on every save, giving O(N²) total I/O).
|
|
24
|
-
// null = "not initialized yet, fall back to disk on next access."
|
|
25
|
-
indexCache = null;
|
|
26
|
-
constructor(options) {
|
|
27
|
-
const opts = typeof options === "string" ? { projectDir: options } : options ?? {};
|
|
28
|
-
this.baseDir = resolveMemoryBaseDir(opts.baseDir);
|
|
29
|
-
if (opts.projectDir) {
|
|
30
|
-
const projectHash = opts.projectDir.replace(/[/\\:]/g, "-").replace(/^-/, "");
|
|
31
|
-
this.memoryDir = join(this.baseDir, "projects", projectHash, "memory");
|
|
32
|
-
} else {
|
|
33
|
-
this.memoryDir = join(this.baseDir, "memory");
|
|
34
|
-
}
|
|
35
|
-
this.indexPath = join(this.memoryDir, "MEMORY.md");
|
|
36
|
-
mkdirSync(this.memoryDir, { recursive: true });
|
|
37
|
-
}
|
|
38
|
-
getMemoryDir() {
|
|
39
|
-
return this.memoryDir;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Save a memory entry. Creates the file and updates the index.
|
|
43
|
-
*/
|
|
44
|
-
save(entry) {
|
|
45
|
-
const fileName = this.slugify(entry.name) + ".md";
|
|
46
|
-
const filePath = join(this.memoryDir, fileName);
|
|
47
|
-
const content = `---
|
|
48
|
-
name: ${entry.name}
|
|
49
|
-
description: ${entry.description}
|
|
50
|
-
type: ${entry.type}
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
${entry.content}
|
|
54
|
-
`;
|
|
55
|
-
writeFileSync(filePath, content, "utf-8");
|
|
56
|
-
const cache = this.ensureIndexCache();
|
|
57
|
-
cache.set(fileName, { name: entry.name, description: entry.description });
|
|
58
|
-
this.writeIndex(cache);
|
|
59
|
-
return fileName;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Load all memory entries.
|
|
63
|
-
*/
|
|
64
|
-
loadAll() {
|
|
65
|
-
if (!existsSync(this.memoryDir)) return [];
|
|
66
|
-
const files = readdirSync(this.memoryDir).filter(
|
|
67
|
-
(f) => f.endsWith(".md") && f !== "MEMORY.md"
|
|
68
|
-
);
|
|
69
|
-
const entries = [];
|
|
70
|
-
for (const file of files) {
|
|
71
|
-
const entry = this.loadFile(file);
|
|
72
|
-
if (entry) entries.push(entry);
|
|
73
|
-
}
|
|
74
|
-
return entries;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Load a single memory file.
|
|
78
|
-
*/
|
|
79
|
-
loadFile(fileName) {
|
|
80
|
-
const filePath = join(this.memoryDir, fileName);
|
|
81
|
-
if (!existsSync(filePath)) return null;
|
|
82
|
-
try {
|
|
83
|
-
const raw = readFileSync(filePath, "utf-8");
|
|
84
|
-
const frontmatterMatch = raw.match(/^---\n([\s\S]*?)\n---\n\n?([\s\S]*)$/);
|
|
85
|
-
if (!frontmatterMatch) return null;
|
|
86
|
-
const frontmatter = frontmatterMatch[1];
|
|
87
|
-
const content = frontmatterMatch[2].trim();
|
|
88
|
-
const name = frontmatter.match(/name:\s*(.+)/)?.[1]?.trim() ?? fileName;
|
|
89
|
-
const description = frontmatter.match(/description:\s*(.+)/)?.[1]?.trim() ?? "";
|
|
90
|
-
const type = frontmatter.match(/type:\s*(.+)/)?.[1]?.trim() ?? "project";
|
|
91
|
-
return { name, description, type, content, fileName };
|
|
92
|
-
} catch {
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Delete a memory by name or filename.
|
|
98
|
-
*/
|
|
99
|
-
delete(nameOrFile) {
|
|
100
|
-
const entries = this.loadAll();
|
|
101
|
-
const entry = entries.find(
|
|
102
|
-
(e) => e.name === nameOrFile || e.fileName === nameOrFile
|
|
103
|
-
);
|
|
104
|
-
if (!entry) return false;
|
|
105
|
-
try {
|
|
106
|
-
unlinkSync(join(this.memoryDir, entry.fileName));
|
|
107
|
-
const cache = this.ensureIndexCache();
|
|
108
|
-
cache.delete(entry.fileName);
|
|
109
|
-
this.writeIndex(cache);
|
|
110
|
-
return true;
|
|
111
|
-
} catch {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Get the MEMORY.md index content for injection into prompts.
|
|
117
|
-
*/
|
|
118
|
-
getIndex() {
|
|
119
|
-
if (!existsSync(this.indexPath)) return "";
|
|
120
|
-
return readFileSync(this.indexPath, "utf-8");
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Build a prompt-friendly summary of all memories.
|
|
124
|
-
*/
|
|
125
|
-
buildMemoryContext() {
|
|
126
|
-
const entries = this.loadAll();
|
|
127
|
-
if (entries.length === 0) return "";
|
|
128
|
-
const lines = entries.map(
|
|
129
|
-
(e) => `- [${e.type}] ${e.name}: ${e.description}`
|
|
130
|
-
);
|
|
131
|
-
return `# Persistent Memory
|
|
132
|
-
|
|
133
|
-
The following memories from previous sessions may be relevant:
|
|
134
|
-
|
|
135
|
-
` + lines.join("\n") + `
|
|
136
|
-
|
|
137
|
-
To read a specific memory, check ${this.memoryDir}/`;
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Lazy-build the in-memory index from disk on first use, then
|
|
141
|
-
* keep it in sync incrementally via save/delete. Avoids the
|
|
142
|
-
* O(N²) re-read of every memory file on every save.
|
|
143
|
-
*/
|
|
144
|
-
ensureIndexCache() {
|
|
145
|
-
if (this.indexCache !== null) return this.indexCache;
|
|
146
|
-
const cache = /* @__PURE__ */ new Map();
|
|
147
|
-
for (const entry of this.loadAll()) {
|
|
148
|
-
cache.set(entry.fileName, { name: entry.name, description: entry.description });
|
|
149
|
-
}
|
|
150
|
-
this.indexCache = cache;
|
|
151
|
-
return cache;
|
|
152
|
-
}
|
|
153
|
-
writeIndex(cache) {
|
|
154
|
-
const lines = [];
|
|
155
|
-
for (const [fileName, meta] of cache) {
|
|
156
|
-
lines.push(`- [${meta.name}](${fileName}) \u2014 ${meta.description}`);
|
|
157
|
-
}
|
|
158
|
-
const content = lines.length > 0 ? lines.join("\n") + "\n" : "(no memories stored)\n";
|
|
159
|
-
writeFileSync(this.indexPath, content, "utf-8");
|
|
160
|
-
}
|
|
161
|
-
slugify(text) {
|
|
162
|
-
return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
export {
|
|
167
|
-
resolveMemoryBaseDir,
|
|
168
|
-
MemoryManager
|
|
169
|
-
};
|
package/dist/chunk-WASS5YWB.js
DELETED
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isStale,
|
|
3
|
-
readCache,
|
|
4
|
-
writeCache
|
|
5
|
-
} from "./chunk-3OA5G4TM.js";
|
|
6
|
-
import {
|
|
7
|
-
init_esm_shims
|
|
8
|
-
} from "./chunk-MD32R22I.js";
|
|
9
|
-
|
|
10
|
-
// src/llm/model-fetcher.ts
|
|
11
|
-
init_esm_shims();
|
|
12
|
-
import { readFileSync, existsSync } from "fs";
|
|
13
|
-
import { fileURLToPath } from "url";
|
|
14
|
-
import { dirname, join } from "path";
|
|
15
|
-
|
|
16
|
-
// src/llm/provider-kinds.ts
|
|
17
|
-
init_esm_shims();
|
|
18
|
-
var NON_CHAT_PATTERNS = /(?:^|[-_/])(?:embed(?:ding)?|whisper|tts|audio|image|dall-?e|moderation|rerank|guard|vision-only)(?:$|[-_/])/i;
|
|
19
|
-
var isChatLike = (id) => !NON_CHAT_PATTERNS.test(id);
|
|
20
|
-
var bearer = (k) => k ? { Authorization: `Bearer ${k}` } : {};
|
|
21
|
-
var PROVIDER_KINDS = {
|
|
22
|
-
openai: {
|
|
23
|
-
label: "OpenAI",
|
|
24
|
-
defaultBaseUrl: "https://api.openai.com/v1",
|
|
25
|
-
modelsPath: "/models",
|
|
26
|
-
protocol: "openai-compat",
|
|
27
|
-
authHeader: bearer,
|
|
28
|
-
chatFilter: isChatLike
|
|
29
|
-
},
|
|
30
|
-
anthropic: {
|
|
31
|
-
label: "Anthropic",
|
|
32
|
-
defaultBaseUrl: "https://api.anthropic.com/v1",
|
|
33
|
-
modelsPath: "/models",
|
|
34
|
-
protocol: "anthropic-style",
|
|
35
|
-
authHeader: (k) => k ? { "x-api-key": k, "anthropic-version": "2023-06-01" } : { "anthropic-version": "2023-06-01" },
|
|
36
|
-
chatFilter: isChatLike
|
|
37
|
-
},
|
|
38
|
-
deepseek: {
|
|
39
|
-
label: "DeepSeek",
|
|
40
|
-
defaultBaseUrl: "https://api.deepseek.com/v1",
|
|
41
|
-
modelsPath: "/models",
|
|
42
|
-
protocol: "openai-compat",
|
|
43
|
-
authHeader: bearer,
|
|
44
|
-
chatFilter: isChatLike
|
|
45
|
-
},
|
|
46
|
-
xai: {
|
|
47
|
-
label: "xAI (Grok)",
|
|
48
|
-
defaultBaseUrl: "https://api.x.ai/v1",
|
|
49
|
-
modelsPath: "/models",
|
|
50
|
-
protocol: "openai-compat",
|
|
51
|
-
authHeader: bearer,
|
|
52
|
-
chatFilter: isChatLike
|
|
53
|
-
},
|
|
54
|
-
mistral: {
|
|
55
|
-
label: "Mistral",
|
|
56
|
-
defaultBaseUrl: "https://api.mistral.ai/v1",
|
|
57
|
-
modelsPath: "/models",
|
|
58
|
-
protocol: "openai-compat",
|
|
59
|
-
authHeader: bearer,
|
|
60
|
-
chatFilter: isChatLike
|
|
61
|
-
},
|
|
62
|
-
groq: {
|
|
63
|
-
label: "Groq",
|
|
64
|
-
defaultBaseUrl: "https://api.groq.com/openai/v1",
|
|
65
|
-
modelsPath: "/models",
|
|
66
|
-
protocol: "openai-compat",
|
|
67
|
-
authHeader: bearer,
|
|
68
|
-
chatFilter: isChatLike
|
|
69
|
-
},
|
|
70
|
-
google: {
|
|
71
|
-
label: "Google Gemini",
|
|
72
|
-
defaultBaseUrl: "https://generativelanguage.googleapis.com/v1beta",
|
|
73
|
-
modelsPath: "/models",
|
|
74
|
-
protocol: "gemini",
|
|
75
|
-
authHeader: () => ({}),
|
|
76
|
-
authQuery: (k) => k ? { key: k } : {},
|
|
77
|
-
chatFilter: (id) => isChatLike(id) && /gemini/i.test(id)
|
|
78
|
-
},
|
|
79
|
-
openrouter: {
|
|
80
|
-
label: "OpenRouter",
|
|
81
|
-
defaultBaseUrl: "https://openrouter.ai/api/v1",
|
|
82
|
-
modelsPath: "/models",
|
|
83
|
-
protocol: "openai-compat",
|
|
84
|
-
authHeader: bearer,
|
|
85
|
-
chatFilter: isChatLike
|
|
86
|
-
},
|
|
87
|
-
ollama: {
|
|
88
|
-
label: "Ollama (local)",
|
|
89
|
-
defaultBaseUrl: "http://localhost:11434",
|
|
90
|
-
modelsPath: "/api/tags",
|
|
91
|
-
protocol: "ollama",
|
|
92
|
-
authHeader: () => ({}),
|
|
93
|
-
chatFilter: isChatLike
|
|
94
|
-
},
|
|
95
|
-
custom: {
|
|
96
|
-
label: "Custom",
|
|
97
|
-
defaultBaseUrl: "",
|
|
98
|
-
modelsPath: "/models",
|
|
99
|
-
protocol: "openai-compat",
|
|
100
|
-
authHeader: bearer,
|
|
101
|
-
chatFilter: isChatLike
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
function getKindMeta(kind) {
|
|
105
|
-
return PROVIDER_KINDS[kind] ?? PROVIDER_KINDS.custom;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// src/llm/model-fetcher.ts
|
|
109
|
-
var HERE = dirname(fileURLToPath(import.meta.url));
|
|
110
|
-
var OPENROUTER_SNAPSHOT = join(HERE, "..", "data", "openrouter-models.json");
|
|
111
|
-
async function fetchModelList(provider, opts) {
|
|
112
|
-
const meta = getKindMeta(provider.kind);
|
|
113
|
-
if (!opts.refresh) {
|
|
114
|
-
const cached = readCache(opts.cacheDir, provider.key);
|
|
115
|
-
if (cached && !isStale(cached)) return { ...cached, fromCache: true };
|
|
116
|
-
}
|
|
117
|
-
if (provider.kind === "openrouter") {
|
|
118
|
-
return loadOpenRouterSnapshot(provider.key, opts.cacheDir);
|
|
119
|
-
}
|
|
120
|
-
try {
|
|
121
|
-
const path = provider.modelsPath ?? meta.modelsPath;
|
|
122
|
-
const url = new URL(joinUrl(provider.baseUrl, path));
|
|
123
|
-
const headers = meta.authHeader(provider.apiKey ?? "");
|
|
124
|
-
if (meta.authQuery) {
|
|
125
|
-
const q = meta.authQuery(provider.apiKey ?? "");
|
|
126
|
-
for (const [k, v] of Object.entries(q)) url.searchParams.set(k, v);
|
|
127
|
-
}
|
|
128
|
-
const res = await fetch(url.toString(), {
|
|
129
|
-
headers: { Accept: "application/json", ...headers },
|
|
130
|
-
signal: AbortSignal.timeout(opts.timeoutMs ?? 2e4)
|
|
131
|
-
});
|
|
132
|
-
if (!res.ok) {
|
|
133
|
-
return errorResult(provider.key, opts.cacheDir, `HTTP ${res.status}`);
|
|
134
|
-
}
|
|
135
|
-
const payload = await res.json();
|
|
136
|
-
const raw = normalize(payload, meta.protocol);
|
|
137
|
-
const filtered = raw.filter((m) => meta.chatFilter(m.id));
|
|
138
|
-
const file = writeCache(opts.cacheDir, provider.key, filtered);
|
|
139
|
-
return file;
|
|
140
|
-
} catch (err) {
|
|
141
|
-
const msg = err.message || String(err);
|
|
142
|
-
return errorResult(provider.key, opts.cacheDir, msg);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
function normalize(payload, protocol) {
|
|
146
|
-
switch (protocol) {
|
|
147
|
-
case "ollama": {
|
|
148
|
-
const p = payload;
|
|
149
|
-
return (p.models ?? []).map((m) => ({ id: m.name, contextLength: 0, maxOutputTokens: 0 }));
|
|
150
|
-
}
|
|
151
|
-
case "anthropic-style": {
|
|
152
|
-
const p = payload;
|
|
153
|
-
return (p.data ?? []).map((m) => ({
|
|
154
|
-
id: m.id,
|
|
155
|
-
contextLength: m.context_window ?? 2e5,
|
|
156
|
-
maxOutputTokens: m.max_output_tokens ?? 0
|
|
157
|
-
}));
|
|
158
|
-
}
|
|
159
|
-
case "gemini": {
|
|
160
|
-
const p = payload;
|
|
161
|
-
return (p.models ?? []).map((m) => ({
|
|
162
|
-
id: m.name.replace(/^models\//, ""),
|
|
163
|
-
contextLength: m.inputTokenLimit ?? 0,
|
|
164
|
-
maxOutputTokens: m.outputTokenLimit ?? 0
|
|
165
|
-
}));
|
|
166
|
-
}
|
|
167
|
-
case "openai-compat": {
|
|
168
|
-
const p = payload;
|
|
169
|
-
return (p.data ?? []).map((m) => ({
|
|
170
|
-
id: m.id,
|
|
171
|
-
contextLength: m.context_window ?? m.context_length ?? 0,
|
|
172
|
-
maxOutputTokens: m.max_completion_tokens ?? 0
|
|
173
|
-
}));
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
const _exhaustive = protocol;
|
|
177
|
-
return _exhaustive;
|
|
178
|
-
}
|
|
179
|
-
function loadOpenRouterSnapshot(providerKey, cacheDir) {
|
|
180
|
-
if (!existsSync(OPENROUTER_SNAPSHOT)) {
|
|
181
|
-
return errorResult(providerKey, cacheDir, "openrouter snapshot missing");
|
|
182
|
-
}
|
|
183
|
-
try {
|
|
184
|
-
const snapshot = JSON.parse(
|
|
185
|
-
readFileSync(OPENROUTER_SNAPSHOT, "utf-8")
|
|
186
|
-
);
|
|
187
|
-
const models = (snapshot.models ?? []).map((m) => ({
|
|
188
|
-
id: m.id,
|
|
189
|
-
contextLength: m.contextLength ?? 0,
|
|
190
|
-
maxOutputTokens: m.maxOutputTokens ?? 0
|
|
191
|
-
}));
|
|
192
|
-
return writeCache(cacheDir, providerKey, models);
|
|
193
|
-
} catch (err) {
|
|
194
|
-
return errorResult(providerKey, cacheDir, err.message);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
function errorResult(providerKey, cacheDir, error) {
|
|
198
|
-
const stale = readCache(cacheDir, providerKey);
|
|
199
|
-
if (stale) return { ...stale, error, fromCache: true };
|
|
200
|
-
return {
|
|
201
|
-
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
202
|
-
providerKey,
|
|
203
|
-
models: [],
|
|
204
|
-
error
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
function joinUrl(base, path) {
|
|
208
|
-
if (!base) return path;
|
|
209
|
-
return `${base.replace(/\/$/, "")}${path.startsWith("/") ? "" : "/"}${path}`;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
export {
|
|
213
|
-
PROVIDER_KINDS,
|
|
214
|
-
fetchModelList
|
|
215
|
-
};
|