ucode-agent 1.58.0 → 1.59.0

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 om dixit
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # ucode
2
2
 
3
3
  A coding agent that lives in your terminal. It reads your code, edits it, runs
4
- your commands, and keeps every conversation on disk. It runs on NVIDIA,
5
- Cohere and Nex AGI models, all of them free.
4
+ your commands, and keeps every conversation on disk. It runs on models served
5
+ by NVIDIA — DeepSeek, Kimi, GLM and Nemotron — with a free key.
6
6
 
7
7
  It opens on a quiet screen — the name, the place to type, and the version in the
8
8
  corner:
@@ -66,14 +66,13 @@ space straight back when it finishes.
66
66
  npm i -g ucode-agent
67
67
  ```
68
68
 
69
- Then put a key where it will survive upgrades:
69
+ Then save your NVIDIA key (free at [build.nvidia.com](https://build.nvidia.com)):
70
70
 
71
71
  ```bash
72
- mkdir -p ~/.ucode
73
- echo "UCODE_API_KEY=sk-or-..." > ~/.ucode/.env
72
+ ucode login nvapi-...
74
73
  ```
75
74
 
76
- Keys are free at [openrouter.ai/keys](https://openrouter.ai/keys). A `.env` in
75
+ It is written to `~/.ucode/.env` as `NVIDIA_API_KEY`. A `.env` in
77
76
  the project you are working on wins over that one, and a real environment
78
77
  variable wins over both.
79
78
 
@@ -87,35 +86,16 @@ Needs Node 22 or newer.
87
86
 
88
87
  ## The models
89
88
 
90
- Six, and no picker full of names nobody recognises. NVIDIA, Cohere and Nex AGI
91
- all serve capable models free, and all handle tool calling properly, which is
92
- the thing an agent actually depends on.
93
-
94
- | Model | Context | For |
95
- | --- | --- | --- |
96
- | Nemotron 3 Ultra | 1M | deepest reasoning, slowest to first token |
97
- | Nemotron 3.5 Lightning | 1M | the same enormous window, answers much sooner |
98
- | Nemotron 3 Super | 262k | strong all-rounder, quick to start |
99
- | Nemotron 3 Nano Omni | 256k | small, fast, reasoning tuned |
100
- | **North Mini Code** ★ | 256k | the default — built for code and interface work, quick to answer |
101
- | Nex N2.5 Pro | 262k | new agentic coder, on trial — can stall on big builds |
102
-
103
- `/model` shows them and switches. `ucode -m cohere/north-mini-code:free`
104
- starts on one.
105
-
106
- North Mini Code is the default: it is built for code and interfaces, which is most
107
- of what ucode is asked to do, and it answers far sooner than the big reasoning
108
- models. Switch to Ultra when a problem needs the million-token window more than
109
- the speed.
110
-
111
- **The model you chose is the model you keep.** Free endpoints are shared and
112
- "too many requests" is routine, so ucode waits it out with growing pauses and
113
- comes back to the same model. It does not quietly hand your build to a
114
- different one: a build that starts on one model and finishes on another
115
- finishes to a different standard, and the swap lands exactly when you are least
116
- placed to work out why the output changed. Set `UCODE_FALLBACK=1` if you would
117
- rather it moved down the list — North Mini Code, Nemotron 3.5 Lightning, Super,
118
- Ultra — when a model stays busy.
89
+ Served by NVIDIA (build.nvidia.com), with a free key.
90
+
91
+ | Model | For |
92
+ | --- | --- |
93
+ | **DeepSeek V4.1 Flash** ★ | the default — fast, and reliable with tools |
94
+ | Kimi K3 | strong agentic coder — can be slow when NVIDIA is busy |
95
+ | GLM 5.3 | strong coder — can be slow when NVIDIA is busy |
96
+ | Nemotron 3 Super | NVIDIA all-rounder |
97
+
98
+ `/model` shows them and switches. `ucode -m moonshotai/kimi-k3` starts on one.
119
99
 
120
100
  ## What it does
121
101
 
@@ -474,7 +454,7 @@ The tests need no network and no framework — `node test/run.js` runs them all.
474
454
 
475
455
  ## Licence
476
456
 
477
- ISC. Made with ❤️ by om dixit.
457
+ MIT — see [LICENSE](LICENSE). Made with ❤️ by om dixit.
478
458
 
479
459
  The edit matchers, the summary template, the context-overflow and transient-error
480
460
  patterns and tool-name repair are adapted from
package/package.json CHANGED
@@ -1,64 +1,64 @@
1
- {
2
- "name": "ucode-agent",
3
- "version": "1.58.0",
4
- "description": "ucode - a terminal coding agent that reads, edits and runs your code, on NVIDIA, Cohere and Nex AGI models.",
5
- "type": "module",
6
- "main": "ucode.js",
7
- "bin": {
8
- "ucode": "ucode.js"
9
- },
10
- "files": [
11
- "ucode.js",
12
- "src/",
13
- "skills/",
14
- "templates/",
15
- "THIRD_PARTY_NOTICES.md"
16
- ],
17
- "scripts": {
18
- "start": "node ucode.js",
19
- "test": "node test/run.js",
20
- "prepublishOnly": "node scripts/no-bundled-key.js && node test/run.js",
21
- "hooks": "node scripts/install-hooks.js"
22
- },
23
- "repository": {
24
- "type": "git",
25
- "url": "git+https://github.com/sppideey/ucode-agent.git"
26
- },
27
- "bugs": {
28
- "url": "https://github.com/sppideey/ucode-agent/issues"
29
- },
30
- "homepage": "https://github.com/sppideey/ucode-agent#readme",
31
- "engines": {
32
- "node": ">=22"
33
- },
34
- "keywords": [
35
- "agent",
36
- "cli",
37
- "terminal",
38
- "coding-agent",
39
- "llm",
40
- "nvidia",
41
- "nemotron",
42
- "cohere",
43
- "nex-agi"
44
- ],
45
- "author": "om dixit",
46
- "license": "ISC",
47
- "dependencies": {
48
- "@babel/parser": "^7.29.8",
49
- "chalk": "^6.0.0",
50
- "dotenv": "^17.4.2",
51
- "jsonrepair": "^3.15.0",
52
- "marked": "^15.0.12",
53
- "marked-terminal": "^7.3.0",
54
- "openai": "^7.4.0",
55
- "playwright-core": "^1.63.0"
56
- },
57
- "devDependencies": {
58
- "@types/node": "^26.5.1",
59
- "typescript": "^5.9.3"
60
- },
61
- "publishConfig": {
62
- "access": "public"
63
- }
64
- }
1
+ {
2
+ "name": "ucode-agent",
3
+ "version": "1.59.0",
4
+ "description": "ucode - a terminal coding agent that reads, edits and runs your code, on models served by NVIDIA: DeepSeek, Kimi, GLM and Nemotron.",
5
+ "type": "module",
6
+ "main": "ucode.js",
7
+ "bin": {
8
+ "ucode": "ucode.js"
9
+ },
10
+ "files": [
11
+ "ucode.js",
12
+ "src/",
13
+ "skills/",
14
+ "templates/",
15
+ "THIRD_PARTY_NOTICES.md"
16
+ ],
17
+ "scripts": {
18
+ "start": "node ucode.js",
19
+ "test": "node test/run.js",
20
+ "prepublishOnly": "node scripts/no-bundled-key.js && node test/run.js",
21
+ "hooks": "node scripts/install-hooks.js"
22
+ },
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/sppideey/ucode-agent.git"
26
+ },
27
+ "bugs": {
28
+ "url": "https://github.com/sppideey/ucode-agent/issues"
29
+ },
30
+ "homepage": "https://github.com/sppideey/ucode-agent#readme",
31
+ "engines": {
32
+ "node": ">=22"
33
+ },
34
+ "keywords": [
35
+ "agent",
36
+ "cli",
37
+ "terminal",
38
+ "coding-agent",
39
+ "llm",
40
+ "nvidia",
41
+ "nemotron",
42
+ "cohere",
43
+ "nex-agi"
44
+ ],
45
+ "author": "om dixit",
46
+ "license": "MIT",
47
+ "dependencies": {
48
+ "@babel/parser": "^7.29.8",
49
+ "chalk": "^6.0.0",
50
+ "dotenv": "^17.4.2",
51
+ "jsonrepair": "^3.15.0",
52
+ "marked": "^15.0.12",
53
+ "marked-terminal": "^7.3.0",
54
+ "openai": "^7.4.0",
55
+ "playwright-core": "^1.63.0"
56
+ },
57
+ "devDependencies": {
58
+ "@types/node": "^26.5.1",
59
+ "typescript": "^5.9.3"
60
+ },
61
+ "publishConfig": {
62
+ "access": "public"
63
+ }
64
+ }
@@ -12,7 +12,7 @@ import os from 'node:os';
12
12
  import path from 'node:path';
13
13
  import { theme, dim, blue } from '../ui/theme.js';
14
14
  import { VERSION } from './version.js';
15
- import { DEFAULT_MODEL, ENV_FILE } from './provider.js';
15
+ import { DEFAULT_MODEL, ENV_FILE, BASE_URL, nvidiaKey } from './provider.js';
16
16
  import { newer } from './updater.js';
17
17
 
18
18
  const DEADLINE = 6000;
@@ -24,10 +24,10 @@ function version(cmd) {
24
24
  }
25
25
 
26
26
  async function checkKey() {
27
- const key = process.env.UCODE_API_KEY || process.env.OPENROUTER_API_KEY;
28
- if (!key) return { ok: false, name: 'API key', detail: 'not set', fix: `Add UCODE_API_KEY=... to ${ENV_FILE}` };
27
+ const key = nvidiaKey();
28
+ if (!key) return { ok: false, name: 'API key', detail: 'not set', fix: `Add NVIDIA_API_KEY=nvapi-... to ${ENV_FILE} (free at build.nvidia.com)` };
29
29
  try {
30
- const r = await fetch('https://openrouter.ai/api/v1/chat/completions', {
30
+ const r = await fetch(`${BASE_URL}/chat/completions`, {
31
31
  method: 'POST',
32
32
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
33
33
  body: JSON.stringify({ model: DEFAULT_MODEL, messages: [{ role: 'user', content: 'ok' }], max_tokens: 1 }),
package/src/core/login.js CHANGED
@@ -14,11 +14,11 @@ import { promises as fs } from 'node:fs';
14
14
  import path from 'node:path';
15
15
  import { ENV_FILE } from './provider.js';
16
16
 
17
- const NAME = 'OPENROUTER_API_KEY';
17
+ const NAME = 'NVIDIA_API_KEY';
18
18
 
19
- /** A plausible OpenRouter key, so a typo is caught here and not mid-answer. */
19
+ /** A plausible NVIDIA key, so a typo is caught here and not mid-answer. */
20
20
  export function looksLikeKey(key) {
21
- return typeof key === 'string' && /^sk-[A-Za-z0-9_-]{20,}$/.test(key.trim());
21
+ return typeof key === 'string' && /^nvapi-[A-Za-z0-9_-]{20,}$/.test(key.trim());
22
22
  }
23
23
 
24
24
  /** Put `key` in the machine-wide env file, keeping whatever else is in it. */
@@ -44,10 +44,10 @@ export async function saveKey(key) {
44
44
  const trimmed = String(key ?? '').trim();
45
45
 
46
46
  if (!trimmed) {
47
- return ` Usage: ucode login <key>\n\n Get one free at https://openrouter.ai/keys\n It is saved to ${ENV_FILE} and used by every project on this machine.`;
47
+ return ` Usage: ucode login <key>\n\n Get one free at https://build.nvidia.com\n It is saved to ${ENV_FILE} and used by every project on this machine.`;
48
48
  }
49
49
  if (!looksLikeKey(trimmed)) {
50
- return ` That does not look like an OpenRouter key — they start with "sk-".\n Get one at https://openrouter.ai/keys`;
50
+ return ` That does not look like an NVIDIA key — they start with "nvapi-".\n Get one at https://build.nvidia.com`;
51
51
  }
52
52
 
53
53
  const existing = await fs.readFile(ENV_FILE, 'utf8').catch(() => '');
@@ -32,8 +32,8 @@ const PACKAGE_ROOT = join(HERE, '..', '..');
32
32
  export const UCODE_HOME = join(homedir(), '.ucode');
33
33
  export const ENV_FILE = join(UCODE_HOME, '.env');
34
34
 
35
- export const BASE_URL = 'https://openrouter.ai/api/v1';
36
- export const PROVIDER = 'OpenRouter';
35
+ export const BASE_URL = 'https://integrate.api.nvidia.com/v1';
36
+ export const PROVIDER = 'NVIDIA';
37
37
 
38
38
  // First definition wins — dotenv never overwrites a variable that already
39
39
  // exists — so the order here is the precedence order:
@@ -44,60 +44,36 @@ dotenv.config({ path: ENV_FILE, quiet: true });
44
44
  dotenv.config({ path: join(PACKAGE_ROOT, '.env'), quiet: true });
45
45
 
46
46
  /**
47
- * The whole model list. Not a starting point — the list.
48
- *
49
- * ucode runs on NVIDIA, Cohere and Nex AGI only. All three serve genuinely
50
- * capable models free through OpenRouter, all handle tool calling properly,
51
- * and keeping the set to six means every one of them has
52
- * been used in anger rather than listed on the strength of a benchmark. A
53
- * picker offering sixty models is a picker nobody reads.
47
+ * The whole model list, served by NVIDIA (build.nvidia.com).
54
48
  *
55
49
  * `name` is what the status bar shows. `note` is what the picker shows.
56
50
  */
57
51
  export const MODELS = {
58
- 'nvidia/nemotron-3-ultra-550b-a55b:free': {
59
- name: 'Nemotron 3 Ultra',
60
- context: 1_000_000,
52
+ 'deepseek-ai/deepseek-v4.1-flash': {
53
+ name: 'DeepSeek V4.1 Flash',
54
+ context: 128_000,
61
55
  star: true,
62
- note: 'deepest reasoning, 1M context — slowest to answer',
63
- },
64
- 'nvidia/nemotron-3.5-lightning:free': {
65
- name: 'Nemotron 3.5 Lightning',
66
- context: 1_000_000,
67
- note: 'same huge window, answers much sooner',
56
+ note: 'the default — fast, and reliable with tools',
68
57
  },
69
- 'nvidia/nemotron-3-super-120b-a12b:free': {
70
- name: 'Nemotron 3 Super',
71
- context: 262_144,
72
- note: 'strong all-rounder, quick to first token',
58
+ 'moonshotai/kimi-k3': {
59
+ name: 'Kimi K3',
60
+ context: 128_000,
61
+ note: 'strong agentic coder — can be slow when NVIDIA is busy',
73
62
  },
74
- 'nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free': {
75
- name: 'Nemotron 3 Nano Omni',
76
- context: 256_000,
77
- note: 'small and fast, reasoning tuned',
78
- },
79
- 'cohere/north-mini-code:free': {
80
- name: 'North Mini Code',
81
- context: 256_000,
82
- star: true,
83
- note: 'the default — built for code and interface work, quick to answer',
63
+ 'z-ai/glm-5.3': {
64
+ name: 'GLM 5.3',
65
+ context: 128_000,
66
+ note: 'strong coder — can be slow when NVIDIA is busy',
84
67
  },
85
- // On trial, so not the default and not in FALLBACKS yet. Nex AGI is its only
86
- // upstream, so a stall there has nowhere else to go.
87
- 'nex-agi/nex-n2.5-pro:free': {
88
- name: 'Nex N2.5 Pro',
89
- context: 262_144,
90
- note: 'new agentic coder, on trial — can stall on big builds',
68
+ 'nvidia/nemotron-3-super-120b-a12b': {
69
+ name: 'Nemotron 3 Super',
70
+ context: 128_000,
71
+ note: 'NVIDIA all-rounder',
91
72
  },
92
73
  };
93
74
 
94
- /**
95
- * North Mini Code is the default: it is built for code and interface work,
96
- * which is what ucode is mostly asked to do, and it answers far sooner than
97
- * the big reasoning models. /model moves to Ultra when a problem needs the
98
- * million-token window and the long think more than it needs the speed.
99
- */
100
- export const DEFAULT_MODEL = 'cohere/north-mini-code:free';
75
+ /** The model a session starts on. */
76
+ export const DEFAULT_MODEL = 'deepseek-ai/deepseek-v4.1-flash';
101
77
 
102
78
  /**
103
79
  * Where to go when a model is busy, in order of preference. Each is served by
@@ -106,10 +82,10 @@ export const DEFAULT_MODEL = 'cohere/north-mini-code:free';
106
82
  * the first "too many requests".
107
83
  */
108
84
  export const FALLBACKS = [
109
- 'cohere/north-mini-code:free',
110
- 'nvidia/nemotron-3.5-lightning:free',
111
- 'nvidia/nemotron-3-super-120b-a12b:free',
112
- 'nvidia/nemotron-3-ultra-550b-a55b:free',
85
+ 'deepseek-ai/deepseek-v4.1-flash',
86
+ 'nvidia/nemotron-3-super-120b-a12b',
87
+ 'moonshotai/kimi-k3',
88
+ 'z-ai/glm-5.3',
113
89
  ];
114
90
 
115
91
  /** The next model to try after `id`, skipping any already tried this round. */
@@ -173,7 +149,7 @@ export function setModel(id) {
173
149
  throw new Failure({
174
150
  kind: 'bad_model',
175
151
  attempted: `switching to "${wanted}"`,
176
- failed: 'ucode only runs NVIDIA, Cohere and Nex AGI models, and that is not one of them.',
152
+ failed: 'That model is not in ucode\'s list.',
177
153
  fix: `Run /model to choose from: ${Object.keys(MODELS).join(', ')}`,
178
154
  });
179
155
  }
@@ -238,19 +214,27 @@ export function estimateConversation(messages) {
238
214
  * package is readable by anyone who runs `npm pack ucode-agent`, and no amount
239
215
  * of first-run convenience is worth handing out a live credential.
240
216
  */
217
+ /** The NVIDIA key: NVIDIA_API_KEY, or a UCODE_API_KEY that is one (nvapi-...). */
218
+ export function nvidiaKey() {
219
+ const direct = (process.env.NVIDIA_API_KEY || '').trim();
220
+ if (direct) return direct;
221
+ const shared = (process.env.UCODE_API_KEY || '').trim();
222
+ return shared.startsWith('nvapi-') ? shared : '';
223
+ }
224
+
241
225
  function apiKey() {
242
226
  // UCODE_API_KEY is the documented name. The provider's own variable name is
243
227
  // still read, so a key set up for another tool keeps working here.
244
- const key = (process.env.UCODE_API_KEY || process.env.OPENROUTER_API_KEY || '').trim();
228
+ const key = nvidiaKey();
245
229
  if (!key) {
246
230
  throw new Failure({
247
231
  kind: 'no_api_key',
248
232
  attempted: 'connecting to the model',
249
- failed: 'No API key is set - UCODE_API_KEY is missing from the environment and from every .env file.',
233
+ failed: 'No NVIDIA API key is set - NVIDIA_API_KEY is missing from the environment and from every .env file.',
250
234
  fix:
251
- `Put UCODE_API_KEY=your-key in ${ENV_FILE} — that applies to every ` +
235
+ `Put NVIDIA_API_KEY=nvapi-... in ${ENV_FILE} — that applies to every ` +
252
236
  'project on this machine — or in a .env file beside your code. ' +
253
- 'Free keys: https://openrouter.ai/keys',
237
+ 'Free keys: https://build.nvidia.com',
254
238
  });
255
239
  }
256
240
  return key;
@@ -672,7 +656,6 @@ export async function ask(messages, tools = [], opts = {}) {
672
656
  // nothing, and the provider eventually drops the request as idle. Asking
673
657
  // for it fixes the blank screen and the dropped request together. Models
674
658
  // that do not reason ignore the flag.
675
- include_reasoning: true,
676
659
  };
677
660
 
678
661
  const wired = wireTools(tools);
@@ -20,7 +20,7 @@ import { ToolFailure } from '../core/failure.js';
20
20
  import { ask } from '../core/provider.js';
21
21
  import { getRoot, result } from './shared.js';
22
22
 
23
- const VISION_MODEL = 'nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free';
23
+ const VISION_MODEL = 'nvidia/nemotron-3-nano-omni-30b-a3b-reasoning';
24
24
  const WIDTHS = [
25
25
  { name: 'phone', width: 375, height: 812 },
26
26
  { name: 'desktop', width: 1440, height: 900 },
package/ucode.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  /**
3
3
  * ucode.js — the command.
4
4
  *
@@ -64,8 +64,8 @@ async function usage() {
64
64
  ' doctor check that everything ucode needs is working\n' +
65
65
  ' login <key> save your key for every folder on this machine\n\n' +
66
66
  ` ${sky('Models')}\n${models}\n\n` +
67
- ` Needs UCODE_API_KEY in the environment or in ${ENV_FILE}\n` +
68
- ' Free keys: https://openrouter.ai/keys\n\n'
67
+ ` Needs NVIDIA_API_KEY in the environment or in ${ENV_FILE}\n` +
68
+ ' Free keys: https://build.nvidia.com\n\n'
69
69
  );
70
70
  }
71
71