tokenmix 0.4.11 → 0.4.13
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/README.md +12 -0
- package/dist/commands/agent-runner.js +3 -1
- package/dist/commands/welcome.js +28 -0
- package/dist/i18n/messages.js +43 -0
- package/dist/program.js +4 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@ One account, one balance, 160+ models routed automatically across Claude / GPT /
|
|
|
8
8
|
|
|
9
9
|
Behind the zero-config CLI is a gateway built to be the **honest, transparent** LLM backend for BYOK coding agents:
|
|
10
10
|
|
|
11
|
+
- **The model you pick is the model you get.** Your request routes to the real upstream model you named — no silent downgrade to a cheaper one (the grey market's classic "sold Opus, served Haiku"). Model aliases are name normalization only, never a swap.
|
|
11
12
|
- **Transparent, real-time billing.** `tokenmix balance` shows your actual balance, gift credit, and total spent — to micro-USD precision, not opaque "credits". `tokenmix models` lists every model's real price (free models show `$0`, not a dash).
|
|
12
13
|
- **Prompt caching that saves you money — automatically.** Cache hits bill at the discounted rate with nothing to configure: OpenAI / DeepSeek / Gemini / Qwen via their `cached_tokens`, Anthropic via `cache_control` pass-through (cache reads ≈10% of the input price). The savings are yours, and you can see them.
|
|
13
14
|
- **One key, every protocol.** OpenAI Chat Completions, Anthropic Messages, and the Responses API — all on one account, which is why every agent below (terminal and editor alike) runs on a single balance.
|
|
@@ -90,6 +91,17 @@ TOKENMIX_LANG=ja npx tokenmix doctor # 日本語
|
|
|
90
91
|
TOKENMIX_LANG=fr npx tokenmix doctor # Français
|
|
91
92
|
```
|
|
92
93
|
|
|
94
|
+
## Default model
|
|
95
|
+
|
|
96
|
+
Agents default to `claude-sonnet-4.6`. Override it for any launch with the `TOKENMIX_DEFAULT_MODEL` environment variable — handy for a cheaper/faster default or for scripting:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
TOKENMIX_DEFAULT_MODEL=claude-haiku-4.5 npx tokenmix opencode
|
|
100
|
+
TOKENMIX_DEFAULT_MODEL=qwen-flash npx tokenmix aider
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
(`tokenmix claude` and `tokenmix codex` speak the Anthropic / Responses protocols, so they need a Claude-family model; the other agents accept any chat model.)
|
|
104
|
+
|
|
93
105
|
## Configuration Location
|
|
94
106
|
|
|
95
107
|
Your TokenMix credentials are stored locally at:
|
|
@@ -62,7 +62,9 @@ export async function runAgent(agent, args) {
|
|
|
62
62
|
process.exit(1);
|
|
63
63
|
}
|
|
64
64
|
const baseUrl = apiBaseUrl(cfg);
|
|
65
|
-
|
|
65
|
+
// TOKENMIX_DEFAULT_MODEL env overrides the model — handy for CI/scripts that want a
|
|
66
|
+
// cheap model, or as a power-user default. Falls back to stored config, then built-in.
|
|
67
|
+
const defaultModel = process.env.TOKENMIX_DEFAULT_MODEL || cfg.defaultModel || DEFAULT_MODEL;
|
|
66
68
|
// Refuse early with a friendly message if the agent's binary needs a newer Node
|
|
67
69
|
// than we're running on (Codex/Qwen need 22) — avoids a cryptic npm/install error.
|
|
68
70
|
if (agent.minNode && nodeMajor() < agent.minNode) {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { readConfig } from '../config/store.js';
|
|
3
|
+
import { t } from '../i18n/index.js';
|
|
4
|
+
// Shown for a bare `tokenmix` (no command) — friendly, localized onboarding for
|
|
5
|
+
// first-timers instead of commander's raw help. `tokenmix --help` still prints the
|
|
6
|
+
// full command reference. Adapts to whether the user is logged in yet.
|
|
7
|
+
export async function welcomeCommand() {
|
|
8
|
+
const cfg = await readConfig();
|
|
9
|
+
const loggedIn = Boolean(cfg.apiKey);
|
|
10
|
+
const row = (cmd, desc) => ' ' + chalk.cyan(cmd.padEnd(21)) + chalk.dim(desc);
|
|
11
|
+
console.log();
|
|
12
|
+
console.log(' ' + chalk.bold.cyan('TokenMix') + chalk.dim(' — ' + t('welcome.tagline')));
|
|
13
|
+
console.log();
|
|
14
|
+
if (loggedIn) {
|
|
15
|
+
console.log(' ' + chalk.green('✓') + ' ' + t('welcome.loggedIn'));
|
|
16
|
+
console.log(row('tokenmix opencode', t('welcome.s3')));
|
|
17
|
+
console.log(row('tokenmix list', t('welcome.s2')));
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
console.log(' ' + chalk.bold(t('welcome.start')));
|
|
21
|
+
console.log(row('1. tokenmix login', t('welcome.s1')));
|
|
22
|
+
console.log(row('2. tokenmix list', t('welcome.s2')));
|
|
23
|
+
console.log(row('3. tokenmix opencode', t('welcome.s3')));
|
|
24
|
+
}
|
|
25
|
+
console.log();
|
|
26
|
+
console.log(' ' + chalk.dim(t('welcome.more')));
|
|
27
|
+
console.log();
|
|
28
|
+
}
|
package/dist/i18n/messages.js
CHANGED
|
@@ -6,6 +6,14 @@
|
|
|
6
6
|
// `{name}`-style placeholders are filled by t() at call time.
|
|
7
7
|
export const en = {
|
|
8
8
|
'common.notLoggedIn': 'Not logged in. Run `tokenmix login` first.',
|
|
9
|
+
// welcome screen (bare `tokenmix`, no args — onboarding for first-time users)
|
|
10
|
+
'welcome.tagline': 'one account, 160+ models, every open-source coding agent',
|
|
11
|
+
'welcome.start': 'Get started:',
|
|
12
|
+
'welcome.s1': 'log in (opens a browser, ~10s)',
|
|
13
|
+
'welcome.s2': 'see all 11 supported agents',
|
|
14
|
+
'welcome.s3': 'configure & launch one',
|
|
15
|
+
'welcome.loggedIn': "You're logged in — launch an agent:",
|
|
16
|
+
'welcome.more': 'More: `tokenmix --help` for all commands · `tokenmix balance` for your balance',
|
|
9
17
|
// login
|
|
10
18
|
'login.keyMustStart': 'API key should start with sk-tm-',
|
|
11
19
|
'login.verifying': 'Verifying API key against {baseUrl} ...',
|
|
@@ -175,6 +183,13 @@ export const en = {
|
|
|
175
183
|
};
|
|
176
184
|
export const zh = {
|
|
177
185
|
'common.notLoggedIn': '未登录,请先运行 `tokenmix login`。',
|
|
186
|
+
'welcome.tagline': '一个账户、160+ 模型、对接所有开源编程 agent',
|
|
187
|
+
'welcome.start': '快速开始:',
|
|
188
|
+
'welcome.s1': '登录(打开浏览器,约 10 秒)',
|
|
189
|
+
'welcome.s2': '查看支持的 11 个 agent',
|
|
190
|
+
'welcome.s3': '配置并启动一个',
|
|
191
|
+
'welcome.loggedIn': '你已登录 —— 启动一个 agent:',
|
|
192
|
+
'welcome.more': '更多:`tokenmix --help` 查看全部命令 · `tokenmix balance` 查看余额',
|
|
178
193
|
// login
|
|
179
194
|
'login.keyMustStart': 'API 密钥应以 sk-tm- 开头',
|
|
180
195
|
'login.verifying': '正在通过 {baseUrl} 校验 API 密钥 ...',
|
|
@@ -337,6 +352,13 @@ export const zh = {
|
|
|
337
352
|
};
|
|
338
353
|
export const ja = {
|
|
339
354
|
'common.notLoggedIn': 'ログインしていません。まず `tokenmix login` を実行してください。',
|
|
355
|
+
'welcome.tagline': '1 つのアカウントで 160+ モデル、あらゆるオープンソース・コーディング agent に対応',
|
|
356
|
+
'welcome.start': 'はじめに:',
|
|
357
|
+
'welcome.s1': 'ログイン(ブラウザが開きます、約 10 秒)',
|
|
358
|
+
'welcome.s2': 'サポートされている 11 の agent を表示',
|
|
359
|
+
'welcome.s3': '設定して起動',
|
|
360
|
+
'welcome.loggedIn': 'ログイン済みです —— agent を起動:',
|
|
361
|
+
'welcome.more': 'その他:`tokenmix --help` で全コマンド · `tokenmix balance` で残高',
|
|
340
362
|
'login.keyMustStart': 'API キーは sk-tm- で始まる必要があります',
|
|
341
363
|
'login.verifying': '{baseUrl} で API キーを検証しています ...',
|
|
342
364
|
'login.verifyFailed': 'API キーの検証に失敗しました。https://tokenmix.ai/dashboard/keys で確認してください',
|
|
@@ -484,6 +506,13 @@ export const ja = {
|
|
|
484
506
|
};
|
|
485
507
|
export const ko = {
|
|
486
508
|
'common.notLoggedIn': '로그인되어 있지 않습니다. 먼저 `tokenmix login`을 실행하세요.',
|
|
509
|
+
'welcome.tagline': '하나의 계정으로 160+ 모델, 모든 오픈소스 코딩 agent 지원',
|
|
510
|
+
'welcome.start': '시작하기:',
|
|
511
|
+
'welcome.s1': '로그인 (브라우저가 열립니다, 약 10초)',
|
|
512
|
+
'welcome.s2': '지원되는 11개 agent 보기',
|
|
513
|
+
'welcome.s3': '설정하고 실행',
|
|
514
|
+
'welcome.loggedIn': '로그인되었습니다 —— agent를 실행하세요:',
|
|
515
|
+
'welcome.more': '더 보기: `tokenmix --help` 모든 명령 · `tokenmix balance` 잔액',
|
|
487
516
|
'login.keyMustStart': 'API 키는 sk-tm- 로 시작해야 합니다',
|
|
488
517
|
'login.verifying': '{baseUrl} 에서 API 키를 확인하는 중 ...',
|
|
489
518
|
'login.verifyFailed': 'API 키 확인에 실패했습니다. https://tokenmix.ai/dashboard/keys 에서 확인하세요',
|
|
@@ -631,6 +660,13 @@ export const ko = {
|
|
|
631
660
|
};
|
|
632
661
|
export const es = {
|
|
633
662
|
'common.notLoggedIn': 'No has iniciado sesión. Ejecuta `tokenmix login` primero.',
|
|
663
|
+
'welcome.tagline': 'una cuenta, 160+ modelos, todos los agentes de programación de código abierto',
|
|
664
|
+
'welcome.start': 'Empezar:',
|
|
665
|
+
'welcome.s1': 'inicia sesión (abre el navegador, ~10 s)',
|
|
666
|
+
'welcome.s2': 've los 11 agentes compatibles',
|
|
667
|
+
'welcome.s3': 'configura y lanza uno',
|
|
668
|
+
'welcome.loggedIn': 'Has iniciado sesión: lanza un agente:',
|
|
669
|
+
'welcome.more': 'Más: `tokenmix --help` para todos los comandos · `tokenmix balance` para tu saldo',
|
|
634
670
|
'login.keyMustStart': 'La clave de API debe empezar por sk-tm-',
|
|
635
671
|
'login.verifying': 'Verificando la clave de API en {baseUrl} ...',
|
|
636
672
|
'login.verifyFailed': 'Falló la verificación de la clave de API. Compruébala en https://tokenmix.ai/dashboard/keys',
|
|
@@ -778,6 +814,13 @@ export const es = {
|
|
|
778
814
|
};
|
|
779
815
|
export const fr = {
|
|
780
816
|
'common.notLoggedIn': 'Non connecté. Exécutez d’abord `tokenmix login`.',
|
|
817
|
+
'welcome.tagline': 'un seul compte, 160+ modèles, tous les agents de codage open source',
|
|
818
|
+
'welcome.start': 'Démarrer :',
|
|
819
|
+
'welcome.s1': 'connectez-vous (ouvre un navigateur, ~10 s)',
|
|
820
|
+
'welcome.s2': 'voir les 11 agents pris en charge',
|
|
821
|
+
'welcome.s3': 'configurer et lancer un agent',
|
|
822
|
+
'welcome.loggedIn': 'Vous êtes connecté — lancez un agent :',
|
|
823
|
+
'welcome.more': 'Plus : `tokenmix --help` pour toutes les commandes · `tokenmix balance` pour votre solde',
|
|
781
824
|
'login.keyMustStart': 'La clé API doit commencer par sk-tm-',
|
|
782
825
|
'login.verifying': 'Vérification de la clé API sur {baseUrl} ...',
|
|
783
826
|
'login.verifyFailed': 'Échec de la vérification de la clé API. Vérifiez sur https://tokenmix.ai/dashboard/keys',
|
package/dist/program.js
CHANGED
|
@@ -7,6 +7,7 @@ import { topupCommand } from './commands/topup.js';
|
|
|
7
7
|
import { modelsCommand } from './commands/models.js';
|
|
8
8
|
import { listCommand } from './commands/list.js';
|
|
9
9
|
import { doctorCommand } from './commands/doctor.js';
|
|
10
|
+
import { welcomeCommand } from './commands/welcome.js';
|
|
10
11
|
import { registerAgentCommands } from './commands/agent-runner.js';
|
|
11
12
|
import { t } from './i18n/index.js';
|
|
12
13
|
// Read version from package.json so we never have to bump it in two places.
|
|
@@ -22,7 +23,9 @@ export function buildProgram(deps = {}) {
|
|
|
22
23
|
program
|
|
23
24
|
.name('tokenmix')
|
|
24
25
|
.description(t('cmd.program'))
|
|
25
|
-
.version(pkg.version)
|
|
26
|
+
.version(pkg.version)
|
|
27
|
+
// Bare `tokenmix` (no command) shows a friendly onboarding screen, not raw help.
|
|
28
|
+
.action(welcomeCommand);
|
|
26
29
|
program
|
|
27
30
|
.command('login')
|
|
28
31
|
.description(t('cmd.login'))
|