mimo2codex 0.1.15 → 0.1.16
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/AGENTS.md +24 -5
- package/README.md +46 -5
- package/README.zh.md +46 -5
- package/dist/admin/router.js +117 -2
- package/dist/admin/router.js.map +1 -1
- package/dist/cli.js +67 -147
- package/dist/cli.js.map +1 -1
- package/dist/config.js +16 -10
- package/dist/config.js.map +1 -1
- package/dist/db/logs.js +80 -0
- package/dist/db/logs.js.map +1 -1
- package/dist/providers/generic.js +96 -0
- package/dist/providers/generic.js.map +1 -0
- package/dist/providers/genericLoader.js +229 -0
- package/dist/providers/genericLoader.js.map +1 -0
- package/dist/providers/registry.js +48 -10
- package/dist/providers/registry.js.map +1 -1
- package/dist/server.js +201 -1
- package/dist/server.js.map +1 -1
- package/dist/setup/snippets.js +187 -0
- package/dist/setup/snippets.js.map +1 -0
- package/dist/translate/reqToChat.js +1 -1
- package/dist/translate/reqToChat.js.map +1 -1
- package/dist/upstream/openaiCompatClient.js +32 -11
- package/dist/upstream/openaiCompatClient.js.map +1 -1
- package/dist/web/assets/index-D19ffnSJ.css +1 -0
- package/dist/web/assets/index-DPLJprJ4.js +67 -0
- package/dist/web/index.html +2 -2
- package/doc/generic-providers.md +399 -0
- package/doc/generic-providers.zh.md +399 -0
- package/mimoskill/SKILL.md +69 -8
- package/mimoskill/references/ocr_workflow.md +216 -0
- package/mimoskill/scripts/generate_image.py +163 -0
- package/mimoskill/scripts/ocr.py +396 -0
- package/package.json +5 -4
- package/dist/web/assets/index-BoykBCnY.js +0 -67
- package/dist/web/assets/index-DAJbSznk.css +0 -1
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,20 @@ import { buildConfig, parseArgv } from "./config.js";
|
|
|
4
4
|
import { startServer } from "./server.js";
|
|
5
5
|
import { setVerbose, log, redactKey } from "./util/log.js";
|
|
6
6
|
import { closeDb, openDb } from "./db/index.js";
|
|
7
|
-
import {
|
|
7
|
+
import { initRegistry } from "./providers/registry.js";
|
|
8
|
+
import { loadGenericProviders, GenericLoaderError } from "./providers/genericLoader.js";
|
|
9
|
+
import { resolveDataDir } from "./db/dataDir.js";
|
|
10
|
+
import { existsSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { homedir } from "node:os";
|
|
13
|
+
// Discover the data-dir path WITHOUT creating it. Used for print-config /
|
|
14
|
+
// print-cc-switch subcommands so a one-shot snippet print doesn't have
|
|
15
|
+
// filesystem side effects.
|
|
16
|
+
function nonCreatingDataDirCandidate(cliOverride, env) {
|
|
17
|
+
const dir = cliOverride ?? env.MIMO2CODEX_DATA_DIR ?? join(homedir(), ".mimo2codex");
|
|
18
|
+
return existsSync(dir) ? dir : "";
|
|
19
|
+
}
|
|
20
|
+
import { ccSwitchSnippet, configSnippet, configSnippetEnvKey, resolveSnippetTarget, } from "./setup/snippets.js";
|
|
8
21
|
const VERSION = createRequire(import.meta.url)("../package.json").version;
|
|
9
22
|
const HELP = `mimo2codex v${VERSION} — local proxy: Codex Responses API → Chat Completions (MiMo / DeepSeek)
|
|
10
23
|
|
|
@@ -36,6 +49,23 @@ PROVIDER KEYS
|
|
|
36
49
|
registered automatically when their key is present (per-request routing
|
|
37
50
|
lands in a follow-up release).
|
|
38
51
|
|
|
52
|
+
GENERIC OPENAI-COMPAT PROVIDERS
|
|
53
|
+
Declare any OpenAI Chat-Completions-compatible upstream (Qwen, GLM, Kimi,
|
|
54
|
+
vLLM, Ollama, etc.) in providers.json — by default at:
|
|
55
|
+
~/.mimo2codex/providers.json
|
|
56
|
+
Or set MIMO2CODEX_PROVIDERS_FILE to point elsewhere.
|
|
57
|
+
|
|
58
|
+
For a one-shot single instance, set GENERIC_BASE_URL + GENERIC_API_KEY +
|
|
59
|
+
GENERIC_DEFAULT_MODEL; mimo2codex synthesizes a provider with id "generic".
|
|
60
|
+
|
|
61
|
+
Each provider entry supports wireApi: "chat" (default — translate to
|
|
62
|
+
Chat Completions) or "responses" (pipe Codex's Responses payload through
|
|
63
|
+
to the upstream's /v1/responses unchanged — use when the upstream natively
|
|
64
|
+
speaks the Responses API).
|
|
65
|
+
|
|
66
|
+
To make a generic provider the default, pass --model <id-or-shortcut>
|
|
67
|
+
(e.g. \`--model qwen\`). With no flag, mimo2codex defaults to mimo.
|
|
68
|
+
|
|
39
69
|
DEFAULTS BAKED IN (no flag needed)
|
|
40
70
|
✓ MiMo thinking mode ON — model generates reasoning_content; use
|
|
41
71
|
--no-reasoning to hide it from the Codex terminal (still preserved
|
|
@@ -62,152 +92,15 @@ EXAMPLES
|
|
|
62
92
|
mimo2codex print-config > codex-mimo.toml
|
|
63
93
|
mimo2codex print-config --env-key # legacy env-var variant
|
|
64
94
|
mimo2codex print-cc-switch
|
|
65
|
-
`;
|
|
66
|
-
function deepseekMaxOutput() {
|
|
67
|
-
// DeepSeek V4 family: 1M input / 384K max output across all current models.
|
|
68
|
-
return 393_216;
|
|
69
|
-
}
|
|
70
|
-
// Pick the provider's default model + look up its context window. Alternative
|
|
71
|
-
// model ids (including the long-context [1m] variants) are surfaced via the
|
|
72
|
-
// `alternativesComment` block embedded in the printed toml — users edit two
|
|
73
|
-
// lines (model + model_context_window) to switch.
|
|
74
|
-
function resolveSnippetTarget(parsed) {
|
|
75
|
-
const providerId = parsed.model
|
|
76
|
-
? (byShortcut(parsed.model)?.id ?? "mimo")
|
|
77
|
-
: "mimo";
|
|
78
|
-
const provider = PROVIDERS[providerId];
|
|
79
|
-
const modelMeta = provider.builtinModels.find((m) => m.id === provider.defaultModel);
|
|
80
|
-
return {
|
|
81
|
-
providerId,
|
|
82
|
-
providerKey: providerId === "mimo" ? "mimo" : "mimo2codex",
|
|
83
|
-
providerLabel: provider.displayName,
|
|
84
|
-
modelId: provider.defaultModel,
|
|
85
|
-
contextWindow: modelMeta?.contextWindow,
|
|
86
|
-
maxOutputTokens: providerId === "deepseek" ? deepseekMaxOutput() : undefined,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
function modelTuningLines(t) {
|
|
90
|
-
const lines = [];
|
|
91
|
-
if (t.contextWindow)
|
|
92
|
-
lines.push(`model_context_window = ${t.contextWindow}`);
|
|
93
|
-
if (t.maxOutputTokens)
|
|
94
|
-
lines.push(`model_max_output_tokens = ${t.maxOutputTokens}`);
|
|
95
|
-
return lines.length ? "\n" + lines.join("\n") : "";
|
|
96
|
-
}
|
|
97
|
-
// Comment block listing every builtin model for the chosen provider, with the
|
|
98
|
-
// matching context_window and (for DS) max_output_tokens. Lets the user pick
|
|
99
|
-
// a different variant just by editing two lines in their config.toml — no
|
|
100
|
-
// extra CLI flag needed.
|
|
101
|
-
function alternativesComment(t) {
|
|
102
|
-
const provider = PROVIDERS[t.providerId];
|
|
103
|
-
const lines = [];
|
|
104
|
-
lines.push(`# Switch model — replace the two lines above (model = ... and`, `# model_context_window = ...) with one of the entries below. The 1M variants`, `# require (1) your account to actually offer them upstream, and (2) Codex`, `# client to honor model_context_window (older versions cap at ~256K).`, `# Available ${provider.displayName} models:`);
|
|
105
|
-
for (const m of provider.builtinModels) {
|
|
106
|
-
if (m.deprecatedAfter)
|
|
107
|
-
continue; // hide legacy aliases from the suggestion list
|
|
108
|
-
const ctx = m.contextWindow
|
|
109
|
-
? ` model_context_window = ${m.contextWindow}`
|
|
110
|
-
: "";
|
|
111
|
-
const maxOut = t.providerId === "deepseek" && m.contextWindow
|
|
112
|
-
? ` model_max_output_tokens = ${deepseekMaxOutput()}`
|
|
113
|
-
: "";
|
|
114
|
-
const marker = m.id === t.modelId ? " (current)" : "";
|
|
115
|
-
lines.push(`# model = "${m.id}"${ctx}${maxOut}${marker}`);
|
|
116
|
-
}
|
|
117
|
-
return lines.join("\n");
|
|
118
|
-
}
|
|
119
|
-
// Default snippet — uses ~/.codex/auth.json + requires_openai_auth = true.
|
|
120
|
-
// This avoids the common "Missing environment variable: MIMO2CODEX_KEY" error
|
|
121
|
-
// on the Codex desktop app, which doesn't inherit shell env vars set via
|
|
122
|
-
// `export` or `setx`. Works for both CLI and desktop with no env setup.
|
|
123
|
-
function configSnippet(cfg, target) {
|
|
124
|
-
return `# Step 1 — write ~/.codex/auth.json (Windows: %USERPROFILE%\\.codex\\auth.json)
|
|
125
|
-
# Any non-empty value works; mimo2codex does not validate inbound credentials.
|
|
126
|
-
{
|
|
127
|
-
"OPENAI_API_KEY": "mimo2codex-local"
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
# Step 2 — append to ~/.codex/config.toml (Windows: %USERPROFILE%\\.codex\\config.toml)
|
|
131
|
-
model = "${target.modelId}"
|
|
132
|
-
model_provider = "${target.providerKey}"${modelTuningLines(target)}
|
|
133
|
-
|
|
134
|
-
${alternativesComment(target)}
|
|
135
|
-
|
|
136
|
-
[model_providers.${target.providerKey}]
|
|
137
|
-
name = "${target.providerLabel}"
|
|
138
|
-
base_url = "http://${cfg.host}:${cfg.port}/v1"
|
|
139
|
-
wire_api = "responses"
|
|
140
|
-
requires_openai_auth = true
|
|
141
|
-
request_max_retries = 1
|
|
142
|
-
|
|
143
|
-
# Step 3 — completely quit and restart Codex (the desktop app must be relaunched
|
|
144
|
-
# for the new auth.json to be picked up). Then run \`codex\` and pick this provider.
|
|
145
|
-
|
|
146
|
-
# ⚠️ If you also use Codex with your real OpenAI account, this auth.json overwrites
|
|
147
|
-
# your OpenAI login. Use cc-switch (\`mimo2codex print-cc-switch\`) instead to switch
|
|
148
|
-
# between providers cleanly, or use \`mimo2codex print-config --env-key\` for the
|
|
149
|
-
# env-var-based variant (works for Codex CLI but not the desktop app).
|
|
150
|
-
`;
|
|
151
|
-
}
|
|
152
|
-
// Legacy env_key variant — keeps ~/.codex/auth.json untouched (preserving any
|
|
153
|
-
// existing OpenAI login). Requires MIMO2CODEX_KEY to be set in the environment
|
|
154
|
-
// of the process running \`codex\`. Codex DESKTOP APP does not inherit shell env
|
|
155
|
-
// vars on macOS/Windows, so this variant only works reliably for the CLI.
|
|
156
|
-
function configSnippetEnvKey(cfg, target) {
|
|
157
|
-
return `# ~/.codex/config.toml — env-var variant (Codex CLI only; desktop app won't see shell env vars)
|
|
158
|
-
model = "${target.modelId}"
|
|
159
|
-
model_provider = "${target.providerKey}"${modelTuningLines(target)}
|
|
160
|
-
|
|
161
|
-
${alternativesComment(target)}
|
|
162
|
-
|
|
163
|
-
[model_providers.${target.providerKey}]
|
|
164
|
-
name = "${target.providerLabel}"
|
|
165
|
-
base_url = "http://${cfg.host}:${cfg.port}/v1"
|
|
166
|
-
wire_api = "responses"
|
|
167
|
-
env_key = "MIMO2CODEX_KEY"
|
|
168
|
-
request_max_retries = 1
|
|
169
|
-
|
|
170
|
-
# Then in your shell (the same shell you launch \`codex\` from):
|
|
171
|
-
# export MIMO2CODEX_KEY=anything # macOS/Linux/Git Bash
|
|
172
|
-
# $env:MIMO2CODEX_KEY="anything" # Windows PowerShell
|
|
173
|
-
# set MIMO2CODEX_KEY=anything # Windows CMD (current session only)
|
|
174
|
-
#
|
|
175
|
-
# For Codex DESKTOP APP, this variant does NOT work — desktop apps launched from
|
|
176
|
-
# Finder/Start Menu don't inherit shell env vars. Use the default print-config
|
|
177
|
-
# (auth.json variant) or \`mimo2codex print-cc-switch\` instead.
|
|
178
|
-
`;
|
|
179
|
-
}
|
|
180
|
-
// cc-switch (https://github.com/farion1231/cc-switch) is a desktop app that
|
|
181
|
-
// manages multiple Codex providers via a "+" → "Custom" panel. It writes
|
|
182
|
-
// ~/.codex/auth.json + ~/.codex/config.toml when you switch providers.
|
|
183
|
-
// This subcommand prints both snippets in a copy-pasteable form so users can
|
|
184
|
-
// add mimo2codex as a custom Codex provider in cc-switch.
|
|
185
|
-
function ccSwitchSnippet(cfg, target) {
|
|
186
|
-
const authJson = JSON.stringify({ OPENAI_API_KEY: "mimo2codex-local" }, null, 2);
|
|
187
|
-
const configToml = `model_provider = "${target.providerKey}"
|
|
188
|
-
model = "${target.modelId}"${modelTuningLines(target)}
|
|
189
|
-
|
|
190
|
-
${alternativesComment(target)}
|
|
191
|
-
|
|
192
|
-
[model_providers.${target.providerKey}]
|
|
193
|
-
name = "${target.providerLabel}"
|
|
194
|
-
base_url = "http://${cfg.host}:${cfg.port}/v1"
|
|
195
|
-
wire_api = "responses"
|
|
196
|
-
requires_openai_auth = true
|
|
197
|
-
request_max_retries = 1
|
|
198
|
-
`;
|
|
199
|
-
return `# cc-switch — Add Provider → Codex tab → Custom
|
|
200
95
|
|
|
201
|
-
#
|
|
202
|
-
|
|
96
|
+
# Generic OpenAI-compat upstream — single instance via env vars
|
|
97
|
+
GENERIC_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1 \\
|
|
98
|
+
GENERIC_API_KEY=sk-... GENERIC_DEFAULT_MODEL=qwen3-max \\
|
|
99
|
+
mimo2codex --model generic
|
|
203
100
|
|
|
204
|
-
#
|
|
205
|
-
|
|
206
|
-
# Note: OPENAI_API_KEY can be any non-empty string — mimo2codex does not
|
|
207
|
-
# validate inbound credentials. Your real upstream key (MIMO_API_KEY /
|
|
208
|
-
# DS_API_KEY) stays in the env of the machine running mimo2codex.
|
|
101
|
+
# Multi-instance — declare in ~/.mimo2codex/providers.json, then:
|
|
102
|
+
QWEN_API_KEY=sk-... mimo2codex --model qwen
|
|
209
103
|
`;
|
|
210
|
-
}
|
|
211
104
|
function checkMimoHostMismatch(cfg) {
|
|
212
105
|
// Catch the most common foot-gun: tp-* key sent at the pay-as-you-go host
|
|
213
106
|
// (or sk-* key sent at the token-plan host) — usually because MIMO_BASE_URL
|
|
@@ -288,11 +181,38 @@ function main() {
|
|
|
288
181
|
console.log(VERSION);
|
|
289
182
|
return;
|
|
290
183
|
}
|
|
184
|
+
// Register generic providers from providers.json (or GENERIC_* env vars)
|
|
185
|
+
// BEFORE we look at print-config / print-cc-switch subcommands, so those
|
|
186
|
+
// can resolve `--model qwen` against a user-declared generic. We do NOT
|
|
187
|
+
// call resolveDataDir() here (which would auto-create ~/.mimo2codex/) — we
|
|
188
|
+
// only inspect the default path if it already exists, so a one-shot
|
|
189
|
+
// `mimo2codex print-config` doesn't have filesystem side effects.
|
|
190
|
+
const isSubcommand = parsed.positional[0] === "print-config" || parsed.positional[0] === "print-cc-switch";
|
|
191
|
+
const adminEnabledForLoader = parsed.noAdmin
|
|
192
|
+
? false
|
|
193
|
+
: process.env.MIMO2CODEX_NO_ADMIN
|
|
194
|
+
? false
|
|
195
|
+
: true;
|
|
196
|
+
const dataDirForLoader = !isSubcommand && adminEnabledForLoader
|
|
197
|
+
? resolveDataDir(parsed.dataDir, process.env)
|
|
198
|
+
: nonCreatingDataDirCandidate(parsed.dataDir, process.env);
|
|
199
|
+
try {
|
|
200
|
+
const generics = loadGenericProviders(process.env, dataDirForLoader);
|
|
201
|
+
initRegistry(generics);
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
if (err instanceof GenericLoaderError) {
|
|
205
|
+
// eslint-disable-next-line no-console
|
|
206
|
+
console.error(`error: ${err.message}`);
|
|
207
|
+
process.exit(2);
|
|
208
|
+
}
|
|
209
|
+
throw err;
|
|
210
|
+
}
|
|
291
211
|
if (parsed.positional[0] === "print-config") {
|
|
292
212
|
const host = parsed.host ?? "127.0.0.1";
|
|
293
213
|
const port = parsed.port ?? 8788;
|
|
294
214
|
const useEnvKey = parsed.envKey === true;
|
|
295
|
-
const target = resolveSnippetTarget(parsed);
|
|
215
|
+
const target = resolveSnippetTarget(parsed.model);
|
|
296
216
|
// eslint-disable-next-line no-console
|
|
297
217
|
console.log(useEnvKey
|
|
298
218
|
? configSnippetEnvKey({ host, port }, target)
|
|
@@ -302,7 +222,7 @@ function main() {
|
|
|
302
222
|
if (parsed.positional[0] === "print-cc-switch") {
|
|
303
223
|
const host = parsed.host ?? "127.0.0.1";
|
|
304
224
|
const port = parsed.port ?? 8788;
|
|
305
|
-
const target = resolveSnippetTarget(parsed);
|
|
225
|
+
const target = resolveSnippetTarget(parsed.model);
|
|
306
226
|
// eslint-disable-next-line no-console
|
|
307
227
|
console.log(ccSwitchSnippet({ host, port }, target));
|
|
308
228
|
return;
|
|
@@ -328,7 +248,7 @@ function main() {
|
|
|
328
248
|
process.exit(2);
|
|
329
249
|
}
|
|
330
250
|
}
|
|
331
|
-
printStartupBanner(cfg, resolveSnippetTarget(parsed));
|
|
251
|
+
printStartupBanner(cfg, resolveSnippetTarget(parsed.model));
|
|
332
252
|
const server = startServer(cfg);
|
|
333
253
|
server.on("listening", () => {
|
|
334
254
|
log.debug("server listening");
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { byShortcut, isProviderId, PROVIDER_LIST, PROVIDERS } from "./providers/registry.js";
|
|
2
2
|
import { resolveDataDir } from "./db/dataDir.js";
|
|
3
|
+
// Documentation URLs surfaced in "missing API key" errors. Built-ins are
|
|
4
|
+
// hardcoded here so error messages stay user-friendly; generic providers
|
|
5
|
+
// supply their own via Provider.docsUrl.
|
|
6
|
+
const BUILTIN_DOCS_URL = {
|
|
7
|
+
mimo: "https://platform.xiaomimimo.com/#/console/api-keys",
|
|
8
|
+
deepseek: "https://platform.deepseek.com/api_keys",
|
|
9
|
+
};
|
|
3
10
|
const DEFAULTS = {
|
|
4
11
|
host: "127.0.0.1",
|
|
5
12
|
port: 8788,
|
|
@@ -121,13 +128,11 @@ export function buildConfig(parsed, env, version) {
|
|
|
121
128
|
}
|
|
122
129
|
defaultProviderId = env.MIMO2CODEX_DEFAULT_PROVIDER;
|
|
123
130
|
}
|
|
124
|
-
// Resolve runtime for every provider
|
|
125
|
-
//
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
deepseek: null,
|
|
130
|
-
};
|
|
131
|
+
// Resolve runtime for every registered provider (built-ins + any generic
|
|
132
|
+
// providers loaded via initRegistry). Runtime is null when no key is
|
|
133
|
+
// available; the registry stays populated so per-request model-based
|
|
134
|
+
// routing can still recognize the provider's catalog.
|
|
135
|
+
const providers = Object.fromEntries(PROVIDER_LIST.map((p) => [p.id, null]));
|
|
131
136
|
for (const p of PROVIDER_LIST) {
|
|
132
137
|
providers[p.id] = resolveProviderRuntime(p, p.id === defaultProviderId, parsed, env);
|
|
133
138
|
}
|
|
@@ -135,9 +140,10 @@ export function buildConfig(parsed, env, version) {
|
|
|
135
140
|
if (!defaultRuntime) {
|
|
136
141
|
const def = PROVIDERS[defaultProviderId];
|
|
137
142
|
const envHint = def.envKeys.join(" or ");
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
143
|
+
const docsUrl = def.docsUrl ?? BUILTIN_DOCS_URL[def.id];
|
|
144
|
+
const docs = docsUrl
|
|
145
|
+
? `Get one at ${docsUrl}`
|
|
146
|
+
: `Configure baseUrl + envKey in your providers.json entry for "${def.id}".`;
|
|
141
147
|
throw new Error(`missing API key for ${def.displayName} — set ${envHint} env var or pass --api-key. ${docs}`);
|
|
142
148
|
}
|
|
143
149
|
const portFromEnv = env.MIMO2CODEX_PORT ? Number(env.MIMO2CODEX_PORT) : undefined;
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAE7F,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/db/logs.js
CHANGED
|
@@ -105,4 +105,84 @@ export function deleteLogsBefore(ts) {
|
|
|
105
105
|
const info = getDb().prepare("DELETE FROM chat_logs WHERE ts < ?").run(ts);
|
|
106
106
|
return info.changes;
|
|
107
107
|
}
|
|
108
|
+
function pad2(n) {
|
|
109
|
+
return String(n).padStart(2, "0");
|
|
110
|
+
}
|
|
111
|
+
function isoDate(d) {
|
|
112
|
+
return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`;
|
|
113
|
+
}
|
|
114
|
+
function isoHour(d) {
|
|
115
|
+
return `${isoDate(d)} ${pad2(d.getHours())}`;
|
|
116
|
+
}
|
|
117
|
+
export function aggregateTokensTimeseries(range, bucket = "day") {
|
|
118
|
+
const span = RANGE_MS[range] ?? RANGE_MS["7d"];
|
|
119
|
+
const since = Date.now() - span;
|
|
120
|
+
// Build the dense bucket list spanning [since..now] inclusive, in local
|
|
121
|
+
// time. Emitted ascending so the chart x-axis reads left-to-right from
|
|
122
|
+
// oldest to newest.
|
|
123
|
+
const buckets = [];
|
|
124
|
+
if (bucket === "hour") {
|
|
125
|
+
const start = new Date(since);
|
|
126
|
+
start.setMinutes(0, 0, 0);
|
|
127
|
+
const end = new Date();
|
|
128
|
+
end.setMinutes(0, 0, 0);
|
|
129
|
+
for (let d = new Date(start); d <= end; d.setHours(d.getHours() + 1)) {
|
|
130
|
+
buckets.push(isoHour(d));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
const start = new Date(since);
|
|
135
|
+
start.setHours(0, 0, 0, 0);
|
|
136
|
+
const end = new Date();
|
|
137
|
+
end.setHours(0, 0, 0, 0);
|
|
138
|
+
for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
|
|
139
|
+
buckets.push(isoDate(d));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const bucketIndex = new Map(buckets.map((b, i) => [b, i]));
|
|
143
|
+
// The SQL-side bucket key must match the JS string format above so the
|
|
144
|
+
// bucketIndex lookup hits. strftime + unixepoch + localtime gives us the
|
|
145
|
+
// local-tz date/hour string SQLite-side.
|
|
146
|
+
const fmt = bucket === "hour" ? "%Y-%m-%d %H" : "%Y-%m-%d";
|
|
147
|
+
const rows = getDb()
|
|
148
|
+
.prepare(`SELECT strftime('${fmt}', ts/1000, 'unixepoch', 'localtime') AS day,
|
|
149
|
+
provider_id,
|
|
150
|
+
upstream_model,
|
|
151
|
+
COALESCE(SUM(prompt_tokens), 0) AS prompt_tokens,
|
|
152
|
+
COALESCE(SUM(completion_tokens), 0) AS completion_tokens,
|
|
153
|
+
COALESCE(SUM(total_tokens), 0) AS total_tokens
|
|
154
|
+
FROM chat_logs
|
|
155
|
+
WHERE ts >= @since
|
|
156
|
+
GROUP BY day, provider_id, upstream_model
|
|
157
|
+
ORDER BY day ASC`)
|
|
158
|
+
.all({ since });
|
|
159
|
+
// Pivot the long-format rows into per-model series with dense bucket arrays.
|
|
160
|
+
const seriesMap = new Map();
|
|
161
|
+
for (const r of rows) {
|
|
162
|
+
const key = `${r.provider_id}:::${r.upstream_model}`;
|
|
163
|
+
let s = seriesMap.get(key);
|
|
164
|
+
if (!s) {
|
|
165
|
+
s = {
|
|
166
|
+
provider_id: r.provider_id,
|
|
167
|
+
upstream_model: r.upstream_model,
|
|
168
|
+
tokens: new Array(buckets.length).fill(0),
|
|
169
|
+
prompt_tokens: new Array(buckets.length).fill(0),
|
|
170
|
+
completion_tokens: new Array(buckets.length).fill(0),
|
|
171
|
+
total: 0,
|
|
172
|
+
};
|
|
173
|
+
seriesMap.set(key, s);
|
|
174
|
+
}
|
|
175
|
+
const idx = bucketIndex.get(r.day);
|
|
176
|
+
if (idx === undefined)
|
|
177
|
+
continue;
|
|
178
|
+
s.tokens[idx] = r.total_tokens;
|
|
179
|
+
s.prompt_tokens[idx] = r.prompt_tokens;
|
|
180
|
+
s.completion_tokens[idx] = r.completion_tokens;
|
|
181
|
+
s.total += r.total_tokens;
|
|
182
|
+
}
|
|
183
|
+
// Sort by total descending so the chart picks the most-used models when
|
|
184
|
+
// truncating the legend.
|
|
185
|
+
const series = Array.from(seriesMap.values()).sort((a, b) => b.total - a.total);
|
|
186
|
+
return { range, bucket, since, buckets, series };
|
|
187
|
+
}
|
|
108
188
|
//# sourceMappingURL=logs.js.map
|
package/dist/db/logs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/db/logs.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/db/logs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { reqToChat } from "../translate/reqToChat.js";
|
|
2
|
+
const RESERVED_IDS = new Set(["mimo", "deepseek"]);
|
|
3
|
+
export class GenericProviderSpecError extends Error {
|
|
4
|
+
constructor(message) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "GenericProviderSpecError";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export function validateSpec(spec) {
|
|
10
|
+
if (!spec.id || typeof spec.id !== "string") {
|
|
11
|
+
throw new GenericProviderSpecError("generic provider spec missing id");
|
|
12
|
+
}
|
|
13
|
+
if (RESERVED_IDS.has(spec.id)) {
|
|
14
|
+
throw new GenericProviderSpecError(`generic provider id "${spec.id}" conflicts with a built-in provider — pick a different id`);
|
|
15
|
+
}
|
|
16
|
+
if (!/^[a-z0-9][a-z0-9_-]*$/i.test(spec.id)) {
|
|
17
|
+
throw new GenericProviderSpecError(`generic provider id "${spec.id}" must be alphanumeric + dash/underscore (no spaces, no slashes)`);
|
|
18
|
+
}
|
|
19
|
+
if (!spec.baseUrl) {
|
|
20
|
+
throw new GenericProviderSpecError(`generic provider "${spec.id}" missing baseUrl`);
|
|
21
|
+
}
|
|
22
|
+
if (!spec.envKey) {
|
|
23
|
+
throw new GenericProviderSpecError(`generic provider "${spec.id}" missing envKey`);
|
|
24
|
+
}
|
|
25
|
+
if (!spec.defaultModel) {
|
|
26
|
+
throw new GenericProviderSpecError(`generic provider "${spec.id}" missing defaultModel`);
|
|
27
|
+
}
|
|
28
|
+
if (spec.wireApi && spec.wireApi !== "chat" && spec.wireApi !== "responses") {
|
|
29
|
+
throw new GenericProviderSpecError(`generic provider "${spec.id}" has invalid wireApi "${spec.wireApi}" — must be "chat" or "responses"`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function createGenericProvider(spec) {
|
|
33
|
+
validateSpec(spec);
|
|
34
|
+
const declaredModels = spec.models ?? [];
|
|
35
|
+
const hasDeclaredModels = declaredModels.length > 0;
|
|
36
|
+
const wireApi = spec.wireApi ?? "chat";
|
|
37
|
+
const features = spec.features ?? {};
|
|
38
|
+
return {
|
|
39
|
+
id: spec.id,
|
|
40
|
+
shortcut: spec.shortcut ?? spec.id,
|
|
41
|
+
displayName: spec.displayName ?? spec.id,
|
|
42
|
+
defaultBaseUrl: spec.baseUrl,
|
|
43
|
+
baseUrlEnv: `${spec.envKey.replace(/_API_KEY$/i, "")}_BASE_URL`,
|
|
44
|
+
envKeys: [spec.envKey],
|
|
45
|
+
defaultModel: spec.defaultModel,
|
|
46
|
+
builtinModels: declaredModels,
|
|
47
|
+
wireApi,
|
|
48
|
+
docsUrl: spec.docsUrl,
|
|
49
|
+
detectFlags(_apiKey, _baseUrl) {
|
|
50
|
+
return {};
|
|
51
|
+
},
|
|
52
|
+
resolveModel(clientModel) {
|
|
53
|
+
if (!hasDeclaredModels) {
|
|
54
|
+
// Untyped passthrough — accept any model id and let the upstream
|
|
55
|
+
// validate. This is the design choice that matches Codex's habit of
|
|
56
|
+
// "whatever model = "..." is in config.toml gets sent verbatim".
|
|
57
|
+
return { id: clientModel };
|
|
58
|
+
}
|
|
59
|
+
for (const m of declaredModels) {
|
|
60
|
+
if (m.id === clientModel)
|
|
61
|
+
return m;
|
|
62
|
+
if (m.aliases?.includes(clientModel))
|
|
63
|
+
return m;
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
},
|
|
67
|
+
preprocessResponses(req, _ctx) {
|
|
68
|
+
const chat = reqToChat(req, {
|
|
69
|
+
forceParallelToolCalls: !!features.forceParallelToolCalls,
|
|
70
|
+
enableWebSearch: !!features.webSearch,
|
|
71
|
+
});
|
|
72
|
+
// Generic OpenAI-compat upstreams don't understand MiMo's `thinking`
|
|
73
|
+
// family. Strip pre-emptively (reqToChat doesn't emit them, but a
|
|
74
|
+
// future caller might).
|
|
75
|
+
delete chat.thinking;
|
|
76
|
+
delete chat.enable_thinking;
|
|
77
|
+
return chat;
|
|
78
|
+
},
|
|
79
|
+
preprocessChat(req, _ctx) {
|
|
80
|
+
const out = { ...req };
|
|
81
|
+
delete out.thinking;
|
|
82
|
+
delete out.enable_thinking;
|
|
83
|
+
return out;
|
|
84
|
+
},
|
|
85
|
+
preprocessResponsesPassthrough(req, _ctx) {
|
|
86
|
+
// Identity passthrough — the routing layer will substitute `model`
|
|
87
|
+
// separately. Hook exists so users can later override for upstream
|
|
88
|
+
// quirks without changing the server's branching logic.
|
|
89
|
+
return req;
|
|
90
|
+
},
|
|
91
|
+
enhanceError(_ctx) {
|
|
92
|
+
return null;
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=generic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic.js","sourceRoot":"","sources":["../../src/providers/generic.ts"],"names":[],"mappings":"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"}
|