novaprime 1.3.5 → 1.4.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.
Files changed (3) hide show
  1. package/package.json +1 -1
  2. package/src/agent.js +10 -1
  3. package/src/ui.js +20 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "novaprime",
3
- "version": "1.3.5",
3
+ "version": "1.4.0",
4
4
  "description": "NovaPrime — an AI coding assistant in your terminal, powered by GLM.",
5
5
  "bin": {
6
6
  "novaprime": "bin/novaprime.js"
package/src/agent.js CHANGED
@@ -2,7 +2,7 @@
2
2
  const os = require('os');
3
3
  const ora = require('ora');
4
4
  const tools = require('./tools');
5
- const { c, aiLabel, error, warn } = require('./ui');
5
+ const { c, aiLabel, routeReport, error, warn } = require('./ui');
6
6
  const { Renderer } = require('./render');
7
7
 
8
8
  const SYSTEM_PROMPT =
@@ -50,6 +50,15 @@ async function streamMessage(server, key, messages) {
50
50
  return { error: msg };
51
51
  }
52
52
 
53
+ // live model-switch report: show what the free Flash brain decided (only on a fresh prompt)
54
+ try {
55
+ const hdr = res.headers.get('x-novaprime-route');
56
+ if (hdr) {
57
+ const report = JSON.parse(decodeURIComponent(hdr));
58
+ if (report && report.fresh) { stopSpin(); routeReport(report); ensureSpin(c.muted('thinking')); }
59
+ }
60
+ } catch (_) {}
61
+
53
62
  const blocks = [];
54
63
  let stopReason = null, labelShown = false, buffer = '', usedModel = null;
55
64
  const renderer = new Renderer();
package/src/ui.js CHANGED
@@ -100,6 +100,25 @@ function inputBoxClose() { process.stdout.write('\n'); }
100
100
 
101
101
  function aiLabel(model) { process.stdout.write('\n' + c.violet('● ') + c.violet.bold('Nova Prime') + (model ? c.dim(' · ' + model) : '') + '\n'); }
102
102
 
103
+ // Live "model switch" report — shows what the free Flash brain decided for this request.
104
+ function routeReport(r) {
105
+ if (!r) return;
106
+ const sep = c.dim(' → ');
107
+ const tag = c.violet('⚡ ') + c.muted('Flash analyzed');
108
+ let mid, model;
109
+ if (r.decision === 'build') {
110
+ mid = c.amber('new / heavy build');
111
+ model = c.white.bold('switched to ' + (r.chosenLabel || r.chosenModel));
112
+ } else if (r.escalated) {
113
+ mid = c.amber(r.reason || 'escalated');
114
+ model = c.white.bold('using ' + (r.chosenLabel || r.chosenModel));
115
+ } else {
116
+ mid = c.green('quick task');
117
+ model = c.body(r.chosenLabel || r.chosenModel) + (r.free ? c.dim(' · free') : '');
118
+ }
119
+ console.log('\n' + tag + sep + mid + sep + model);
120
+ }
121
+
103
122
  function info(msg) { console.log(c.muted(msg)); }
104
123
  function hint(msg) { console.log(c.dim(msg)); }
105
124
  function warn(msg) { console.log(c.amber(' ! ') + c.amber(msg)); }
@@ -107,4 +126,4 @@ function error(msg) { console.log(c.red(' ✕ ') + c.red(msg)); }
107
126
  function ok(msg) { console.log(c.green(' ✓ ') + c.body(msg)); }
108
127
  function tool(name, detail) { console.log(c.dim(' · ' + name + (detail ? ' ' + detail : ''))); }
109
128
 
110
- module.exports = { chalk, boxen, c, banner, maskKey, aiLabel, inputTop, inputBottom, inputPrompt, inputBoxOpen, inputBoxClose, info, hint, warn, error, ok, tool };
129
+ module.exports = { chalk, boxen, c, banner, maskKey, aiLabel, routeReport, inputTop, inputBottom, inputPrompt, inputBoxOpen, inputBoxClose, info, hint, warn, error, ok, tool };