agent-nuvira 3.5.5 → 3.5.6
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 +66 -0
- package/dist/cli/chat.d.ts.map +1 -1
- package/dist/cli/chat.js +72 -19
- package/dist/cli/chat.js.map +1 -1
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +17 -3
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/execute.d.ts.map +1 -1
- package/dist/cli/execute.js +63 -22
- package/dist/cli/execute.js.map +1 -1
- package/dist/cli/failover-runner.js +4 -4
- package/dist/cli/failover-runner.js.map +1 -1
- package/dist/cli/gateway.js +13 -13
- package/dist/cli/gateway.js.map +1 -1
- package/dist/cli/loop-executor.d.ts +22 -0
- package/dist/cli/loop-executor.d.ts.map +1 -1
- package/dist/cli/loop-executor.js +56 -12
- package/dist/cli/loop-executor.js.map +1 -1
- package/dist/cli/stats.d.ts +62 -4
- package/dist/cli/stats.d.ts.map +1 -1
- package/dist/cli/stats.js +282 -5
- package/dist/cli/stats.js.map +1 -1
- package/dist/cli/ui/index.d.ts +2 -2
- package/dist/cli/ui/index.d.ts.map +1 -1
- package/dist/cli/ui/index.js +1 -1
- package/dist/cli/ui/index.js.map +1 -1
- package/dist/cli/ui/presenter.d.ts +43 -0
- package/dist/cli/ui/presenter.d.ts.map +1 -1
- package/dist/cli/ui/presenter.js +88 -1
- package/dist/cli/ui/presenter.js.map +1 -1
- package/dist/config/manager.d.ts +29 -1
- package/dist/config/manager.d.ts.map +1 -1
- package/dist/config/manager.js +178 -143
- package/dist/config/manager.js.map +1 -1
- package/dist/config/paths.d.ts +48 -1
- package/dist/config/paths.d.ts.map +1 -1
- package/dist/config/paths.js +59 -9
- package/dist/config/paths.js.map +1 -1
- package/dist/config/service-catalog.js +1 -1
- package/dist/config/service-catalog.js.map +1 -1
- package/dist/config/service-probe.js +1 -1
- package/dist/config/service-probe.js.map +1 -1
- package/dist/config/types.d.ts +22 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/gateway/adapters.js +8 -8
- package/dist/gateway/adapters.js.map +1 -1
- package/dist/gateway/registry.js +1 -1
- package/dist/gateway/registry.js.map +1 -1
- package/dist/learning/auto-router.d.ts +30 -4
- package/dist/learning/auto-router.d.ts.map +1 -1
- package/dist/learning/auto-router.js +54 -38
- package/dist/learning/auto-router.js.map +1 -1
- package/dist/learning/cost-classification.d.ts +188 -0
- package/dist/learning/cost-classification.d.ts.map +1 -0
- package/dist/learning/cost-classification.js +294 -0
- package/dist/learning/cost-classification.js.map +1 -0
- package/dist/learning/cost-ledger-maintenance.d.ts +122 -0
- package/dist/learning/cost-ledger-maintenance.d.ts.map +1 -0
- package/dist/learning/cost-ledger-maintenance.js +289 -0
- package/dist/learning/cost-ledger-maintenance.js.map +1 -0
- package/dist/learning/cost-reconcile.d.ts +160 -0
- package/dist/learning/cost-reconcile.d.ts.map +1 -0
- package/dist/learning/cost-reconcile.js +238 -0
- package/dist/learning/cost-reconcile.js.map +1 -0
- package/dist/learning/cost-tracker.d.ts +134 -13
- package/dist/learning/cost-tracker.d.ts.map +1 -1
- package/dist/learning/cost-tracker.js +190 -68
- package/dist/learning/cost-tracker.js.map +1 -1
- package/dist/learning/model-pricing.d.ts +240 -0
- package/dist/learning/model-pricing.d.ts.map +1 -0
- package/dist/learning/model-pricing.js +309 -0
- package/dist/learning/model-pricing.js.map +1 -0
- package/dist/learning/model-selection.d.ts +15 -0
- package/dist/learning/model-selection.d.ts.map +1 -1
- package/dist/learning/model-selection.js +22 -2
- package/dist/learning/model-selection.js.map +1 -1
- package/dist/learning/model-warmup.d.ts.map +1 -1
- package/dist/learning/model-warmup.js +4 -1
- package/dist/learning/model-warmup.js.map +1 -1
- package/dist/learning/session-store.d.ts +1 -5
- package/dist/learning/session-store.d.ts.map +1 -1
- package/dist/learning/session-store.js +10 -1
- package/dist/learning/session-store.js.map +1 -1
- package/dist/learning/step-checkpoint.d.ts +32 -3
- package/dist/learning/step-checkpoint.d.ts.map +1 -1
- package/dist/learning/step-checkpoint.js +33 -4
- package/dist/learning/step-checkpoint.js.map +1 -1
- package/dist/mcp/settings.d.ts +15 -3
- package/dist/mcp/settings.d.ts.map +1 -1
- package/dist/mcp/settings.js +30 -15
- package/dist/mcp/settings.js.map +1 -1
- package/dist/parity/drivers.d.ts.map +1 -1
- package/dist/parity/drivers.js +31 -5
- package/dist/parity/drivers.js.map +1 -1
- package/dist/tools/child-agent-runtime.d.ts.map +1 -1
- package/dist/tools/child-agent-runtime.js +13 -7
- package/dist/tools/child-agent-runtime.js.map +1 -1
- package/dist/tools/followup-utils.d.ts +36 -0
- package/dist/tools/followup-utils.d.ts.map +1 -1
- package/dist/tools/followup-utils.js +66 -0
- package/dist/tools/followup-utils.js.map +1 -1
- package/dist/tools/modality/browser.js +2 -2
- package/dist/tools/modality/browser.js.map +1 -1
- package/dist/tools/modality/image-gen.d.ts +1 -1
- package/dist/tools/modality/image-gen.js +1 -1
- package/dist/tools/modality/image-providers.js +1 -1
- package/dist/tools/modality/image-providers.js.map +1 -1
- package/dist/tools/modality/vision.d.ts +1 -1
- package/dist/tools/modality/vision.js +1 -1
- package/dist/tools/modality/voice.js +2 -2
- package/dist/tools/modality/voice.js.map +1 -1
- package/dist/tools/neutts-synth.d.ts +3 -3
- package/dist/tools/neutts-synth.js +3 -3
- package/dist/tools/neutts-synth.js.map +1 -1
- package/dist/tools/process-liveness.d.ts +50 -0
- package/dist/tools/process-liveness.d.ts.map +1 -1
- package/dist/tools/process-liveness.js +82 -9
- package/dist/tools/process-liveness.js.map +1 -1
- package/dist/tools/registry.d.ts +1 -1
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +27 -4
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/run-terminal.d.ts.map +1 -1
- package/dist/tools/run-terminal.js +18 -1
- package/dist/tools/run-terminal.js.map +1 -1
- package/dist/tools/tool-loop.d.ts.map +1 -1
- package/dist/tools/tool-loop.js +5 -3
- package/dist/tools/tool-loop.js.map +1 -1
- package/dist/tools/web-research.d.ts +1 -1
- package/dist/tools/web-research.js +3 -3
- package/dist/tools/web-research.js.map +1 -1
- package/dist/web-dashboard/chat-console.d.ts +56 -0
- package/dist/web-dashboard/chat-console.d.ts.map +1 -1
- package/dist/web-dashboard/chat-console.js +57 -1
- package/dist/web-dashboard/chat-console.js.map +1 -1
- package/dist/web-dashboard/server.d.ts.map +1 -1
- package/dist/web-dashboard/server.js +122 -2
- package/dist/web-dashboard/server.js.map +1 -1
- package/dist/web-dashboard/src/types.d.ts +63 -0
- package/dist/web-dashboard/src/types.d.ts.map +1 -1
- package/dist/web-dashboard/task-runner.d.ts +17 -1
- package/dist/web-dashboard/task-runner.d.ts.map +1 -1
- package/dist/web-dashboard/task-runner.js +40 -4
- package/dist/web-dashboard/task-runner.js.map +1 -1
- package/package.json +1 -1
- package/src/web-dashboard/public/assets/index-DeSsNU94.css +1 -0
- package/src/web-dashboard/public/assets/index-Do_O67Kv.js +236 -0
- package/src/web-dashboard/public/assets/index-Do_O67Kv.js.map +1 -0
- package/src/web-dashboard/public/index.html +2 -2
- package/src/web-dashboard/public/assets/index-DycGBWwy.js +0 -236
- package/src/web-dashboard/public/assets/index-DycGBWwy.js.map +0 -1
- package/src/web-dashboard/public/assets/index-aO3aG7ex.css +0 -1
package/README.md
CHANGED
|
@@ -460,6 +460,10 @@ OpenRouter gives you access to 200+ models from OpenAI, Anthropic, Google, Meta,
|
|
|
460
460
|
export OPENROUTER_API_KEY="sk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
461
461
|
```
|
|
462
462
|
|
|
463
|
+
> **Not every provider needs a key from you.** A local runner (Ollama) and an optional local gateway
|
|
464
|
+
> (**OmniRoute**, which holds the *upstream* keys itself) are configured without an API key on this
|
|
465
|
+
> side — see [Provider Details → OmniRoute](#-omniroute-ai-gateway--no-key-needed).
|
|
466
|
+
|
|
463
467
|
## MCP (Model Context Protocol) Configuration
|
|
464
468
|
|
|
465
469
|
MCP servers extend your agent's capabilities by connecting to external tools and data sources — databases, APIs, file systems, search engines, code repositories, and more. Agent-Nuvira supports the MCP standard for discovering and invoking tools from connected servers.
|
|
@@ -1906,6 +1910,68 @@ agent-nuvira chat --provider openrouter --model openai/gpt-4o
|
|
|
1906
1910
|
agent-nuvira chat --provider openrouter --model anthropic/claude-3-haiku
|
|
1907
1911
|
```
|
|
1908
1912
|
|
|
1913
|
+
### 🔀 OmniRoute (AI gateway — no key needed)
|
|
1914
|
+
|
|
1915
|
+
[OmniRoute](https://github.com/diegosouzapw/OmniRoute) is a local, MIT-licensed gateway that
|
|
1916
|
+
multiplexes many upstream providers behind **one** OpenAI-compatible endpoint. It is an
|
|
1917
|
+
**aggregation gateway, not a second router**: agent-nuvira still picks the provider × model for each
|
|
1918
|
+
step, and OmniRoute only decides which upstream serves a request that has *already been addressed to
|
|
1919
|
+
it*. Unlike the providers above it needs **no key from you** — the gateway holds the upstream keys.
|
|
1920
|
+
|
|
1921
|
+
```bash
|
|
1922
|
+
# 1. Install and start the gateway (its dashboard + /v1 API land on http://127.0.0.1:20128)
|
|
1923
|
+
npm install -g omniroute
|
|
1924
|
+
omniroute
|
|
1925
|
+
|
|
1926
|
+
# 2. Give it upstream keys, so its combos have something to route to (repeat per provider)
|
|
1927
|
+
omniroute providers add deepseek --credential-stdin
|
|
1928
|
+
|
|
1929
|
+
# 3. Start / stop / inspect it from here — no need to hunt for the background process
|
|
1930
|
+
agent-nuvira omniroute status
|
|
1931
|
+
agent-nuvira omniroute start
|
|
1932
|
+
agent-nuvira omniroute stop
|
|
1933
|
+
|
|
1934
|
+
# 4. Let the router consider it (Dashboard → Admin → Provider Configuration → 🔀 row has the same switch)
|
|
1935
|
+
agent-nuvira config set providers.omniroute.enabled true
|
|
1936
|
+
```
|
|
1937
|
+
|
|
1938
|
+
**Use it** — pin the gateway's own combos, or leave the switch On and let auto routing pick it:
|
|
1939
|
+
|
|
1940
|
+
```bash
|
|
1941
|
+
agent-nuvira execute "fix the failing test" --provider omniroute --model auto
|
|
1942
|
+
agent-nuvira execute "..." --provider omniroute --model auto/coding # or auto/fast, auto/cheap, auto/offline
|
|
1943
|
+
NUVIRA_STRICT_MODEL=1 agent-nuvira execute "..." --provider omniroute --model auto
|
|
1944
|
+
```
|
|
1945
|
+
|
|
1946
|
+
With a concrete `--provider`, `-m auto` means **OmniRoute's own combo**, not agent-nuvira's
|
|
1947
|
+
auto-route; `-m auto` on its own (or `-p auto`) is still agent-nuvira's routing.
|
|
1948
|
+
|
|
1949
|
+
**Verify your own install** — each line is a real check, and each has an honest failure mode:
|
|
1950
|
+
|
|
1951
|
+
| Check | What it tells you |
|
|
1952
|
+
|---|---|
|
|
1953
|
+
| `agent-nuvira omniroute status` | Reachable, or "auth-gated (HTTP 401)" — a `401` still counts as **up**. "Not reachable" = nothing is listening. |
|
|
1954
|
+
| `agent-nuvira config get providers.omniroute.enabled` | `true` when the automatic pool may pick it. |
|
|
1955
|
+
| `omniroute providers list` | One row per upstream connection (deepseek, groq, gemini, …). |
|
|
1956
|
+
|
|
1957
|
+
The gateway's own state lives in `~/.omniroute/`: `storage.sqlite` (connections, usage),
|
|
1958
|
+
`logs/application/app.log` (startup + per-request combo traces), `server/crash.log` (restart lines
|
|
1959
|
+
such as `Server crashed 2 times in <30s>`) and `supervisor/.pid`.
|
|
1960
|
+
|
|
1961
|
+
**Two limits worth knowing**
|
|
1962
|
+
|
|
1963
|
+
- **Attribution.** It is an aggregation gateway, so a quality number measured on `omniroute/auto`
|
|
1964
|
+
describes the gateway *plus its own internal failover across the upstreams it holds*, not one model.
|
|
1965
|
+
(Measured on the seeded-bug suite in `NUVIRA_STRICT_MODEL=1`: both `omniroute/auto` and
|
|
1966
|
+
`omniroute/auto/smart` landed at 94% composite, found 6/7, fixed 7/7, false-success 0/7, and the
|
|
1967
|
+
repeat reproduced the same single miss.)
|
|
1968
|
+
- **Accounting.** nuvira cannot see what the upstream charged, because the gateway — not nuvira —
|
|
1969
|
+
holds the credentials. Spend through OmniRoute is recorded as **passthrough**: zero attributable
|
|
1970
|
+
dollars, explicitly claimed as neither spend nor saving (`agent-nuvira stats cost`).
|
|
1971
|
+
|
|
1972
|
+
> Need the routing rules, the failure modes and the deeper recipes? See the
|
|
1973
|
+
> [User Manual → OmniRoute](docs/USER_MANUAL.md#omniroute--one-endpoint-in-front-of-many-providers).
|
|
1974
|
+
|
|
1909
1975
|
---
|
|
1910
1976
|
|
|
1911
1977
|
## Multi-Agent Orchestration (`agent-nuvira execute`)
|
package/dist/cli/chat.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/cli/chat.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,WAAW,EAAc,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/cli/chat.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/chat.js
CHANGED
|
@@ -16,7 +16,7 @@ import { decisionsRecordingEnabled, recallDecisionBlock } from '../learning/deci
|
|
|
16
16
|
import { getMemoryManager } from '../memory/manager.js';
|
|
17
17
|
import { logger } from '../utils/logger.js';
|
|
18
18
|
import { printOrchestrationResult } from './execute.js';
|
|
19
|
-
import { AnswerStream, attachShellCards, gitDiffCard, presentAnswer, shouldUseRichUi, toolCallCard, } from './ui/index.js';
|
|
19
|
+
import { AnswerStream, attachShellCards, gitDiffCard, presentAnswer, shouldUseRichUi, THINKING_NOTE, toolCallCard, } from './ui/index.js';
|
|
20
20
|
// WS5 (#27) — isolation (a git worktree around the turn) and resume (replaying
|
|
21
21
|
// recorded steps instead of re-paying for them). See the module headers for why
|
|
22
22
|
// the worktree is created HERE, around the whole turn, and why a replay is
|
|
@@ -74,7 +74,7 @@ import { getTool, TOOL_CONTRACT_JSON } from '../tools/registry.js';
|
|
|
74
74
|
// WS1 — the finding tool's bus event, and the wire shape every surface reports.
|
|
75
75
|
import { FINDING_EVENT } from '../tools/finding-tool.js';
|
|
76
76
|
import { debugLogNotice, sessionDebugLog } from '../observability/debug-log.js';
|
|
77
|
-
import { buildFollowupContinuationPrompt, isSuggestedFollowup, withContinuationFollowups, } from '../tools/followup-utils.js';
|
|
77
|
+
import { buildFollowupContinuationPrompt, followupsFromAnswerList, isSuggestedFollowup, withContinuationFollowups, } from '../tools/followup-utils.js';
|
|
78
78
|
// S2/S3 — the shared tool-call reliability helpers (salvage failed_generation,
|
|
79
79
|
// compact fallback schemas). One copy for every tool-calling surface, not
|
|
80
80
|
// chat-private (execute/plan/… inherit the fix).
|
|
@@ -1314,10 +1314,21 @@ export class ChatCommand extends BaseCommand {
|
|
|
1314
1314
|
* cleared there.
|
|
1315
1315
|
*/
|
|
1316
1316
|
liveAnswer(header, opts = {}) {
|
|
1317
|
-
if (!shouldUseRichUi(opts))
|
|
1318
|
-
return { overrides: {}, stop: () => { }, stream: null };
|
|
1317
|
+
if (!shouldUseRichUi(opts)) {
|
|
1318
|
+
return { overrides: {}, stop: () => { }, start: () => { }, stream: null };
|
|
1319
|
+
}
|
|
1319
1320
|
const stream = new AnswerStream({ header, headerColor: 'assistant' }, opts);
|
|
1320
1321
|
let begun = false;
|
|
1322
|
+
/** Show a note, mounting the frame if this is the first sign of life. */
|
|
1323
|
+
const show = (note) => {
|
|
1324
|
+
if (!begun) {
|
|
1325
|
+
begun = true;
|
|
1326
|
+
stream.begin(note === undefined ? {} : { note });
|
|
1327
|
+
return;
|
|
1328
|
+
}
|
|
1329
|
+
if (note !== undefined)
|
|
1330
|
+
stream.setNote(note);
|
|
1331
|
+
};
|
|
1321
1332
|
// Shell commands are emitted on the process-wide bus (utils/shell.ts owns
|
|
1322
1333
|
// them), so the turn subscribes for its own duration and detaches on stop().
|
|
1323
1334
|
const detachShell = attachShellCards((card) => stream.card(card));
|
|
@@ -1325,25 +1336,30 @@ export class ChatCommand extends BaseCommand {
|
|
|
1325
1336
|
stream,
|
|
1326
1337
|
overrides: {
|
|
1327
1338
|
onToken: (token) => {
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1339
|
+
show(undefined);
|
|
1340
|
+
// The text is the signal now — a stale `thinking…` beside streaming
|
|
1341
|
+
// prose reads as a hang that is not happening.
|
|
1342
|
+
stream.setNote(undefined);
|
|
1332
1343
|
stream.append(token);
|
|
1333
1344
|
},
|
|
1334
1345
|
onToolCall: (phase, info) => {
|
|
1335
1346
|
if (phase === 'started') {
|
|
1336
1347
|
// The step's preamble is not the answer: clear it so the preview
|
|
1337
|
-
// shows the step that is actually producing the reply
|
|
1348
|
+
// shows the step that is actually producing the reply — and name the
|
|
1349
|
+
// call that is running, so the EXECUTION half is visible too.
|
|
1338
1350
|
if (begun)
|
|
1339
1351
|
stream.reset();
|
|
1352
|
+
show(`⚙ ${info.tool} …`);
|
|
1340
1353
|
return;
|
|
1341
1354
|
}
|
|
1355
|
+
if (begun)
|
|
1356
|
+
stream.setNote(undefined);
|
|
1342
1357
|
// Completed call → an archived card (this is what the turn DID).
|
|
1343
1358
|
stream.card(toolCallCard({ tool: info.tool, ok: info.ok, error: info.error, result: info.result, durationMs: info.durationMs, args: info.args }));
|
|
1344
1359
|
},
|
|
1345
1360
|
onGitDiff: (payload) => stream.card(gitDiffCard(payload)),
|
|
1346
1361
|
},
|
|
1362
|
+
start: (note) => show(note ?? THINKING_NOTE),
|
|
1347
1363
|
stop: () => {
|
|
1348
1364
|
detachShell();
|
|
1349
1365
|
stream.finish({ archive: false });
|
|
@@ -1480,6 +1496,9 @@ export class ChatCommand extends BaseCommand {
|
|
|
1480
1496
|
// elsewhere). `stop()` unmounts the preview once the turn returns; the
|
|
1481
1497
|
// final frame is printed by the answer path below.
|
|
1482
1498
|
const live = this.liveAnswer(`nuvira · ${provider.name}${model ? ` / ${model}` : ''}`);
|
|
1499
|
+
// Mount before the turn: the first token can be seconds away on a local or
|
|
1500
|
+
// cold provider, and a silent console is indistinguishable from a hang.
|
|
1501
|
+
live.start();
|
|
1483
1502
|
const answer = await this.runChatAnswer(prompt, [], { type, provider, model }, options || {}, cacheEnabled, { auto: autoMode }, parsed,
|
|
1484
1503
|
// WS5 (#27) — isolation and resume ride on the CLI's own flags. Passed
|
|
1485
1504
|
// per turn: in the REPL each message is its own turn (see the manual).
|
|
@@ -1534,6 +1553,7 @@ export class ChatCommand extends BaseCommand {
|
|
|
1534
1553
|
if (!picked)
|
|
1535
1554
|
break;
|
|
1536
1555
|
const liveNext = this.liveAnswer(`nuvira · ${provider.name}${model ? ` / ${model}` : ''}`);
|
|
1556
|
+
liveNext.start();
|
|
1537
1557
|
const next = await this.runChatAnswer(picked, history, { type, provider, model }, options || {}, cacheEnabled, { auto: autoMode }, parseRequestSync(picked),
|
|
1538
1558
|
// P5 — a picked followup continues the previous execution.
|
|
1539
1559
|
{ continuation: true, ...this.ws5Overrides(options), ...liveNext.overrides }).finally(() => liveNext.stop());
|
|
@@ -1632,6 +1652,7 @@ export class ChatCommand extends BaseCommand {
|
|
|
1632
1652
|
const session = { type, provider, model: effectiveModel };
|
|
1633
1653
|
// P7 — live preview for this turn (see `liveAnswer`).
|
|
1634
1654
|
const live = this.liveAnswer(`nuvira · ${provider.name}${effectiveModel ? ` / ${effectiveModel}` : ''}`);
|
|
1655
|
+
live.start();
|
|
1635
1656
|
const answer = await withLogCorrelation({ sessionId: chatSessionId }, () => recordMetricTime('llm.answer.ms', () => this.runChatAnswer(message, history, session, options || {}, cacheEnabled, { auto: autoMode }, parsed,
|
|
1636
1657
|
// P5 — a picked followup (or a typed one that matches the last
|
|
1637
1658
|
// suggestions) is a continuation, not a fresh independent request.
|
|
@@ -1811,8 +1832,10 @@ export class ChatCommand extends BaseCommand {
|
|
|
1811
1832
|
// is the one fact needed to tell a replay from a real turn.
|
|
1812
1833
|
debugLog?.event('cache.hit', { chars: cached.response.length, scope: turnScope });
|
|
1813
1834
|
const cacheNotice = debugLogNotice(ctxOverrides?.debugSurface ?? 'cli-chat', debugLog?.write() ?? null);
|
|
1835
|
+
// Diagnostic (where a bug report's evidence lives), not part of the
|
|
1836
|
+
// answer: `--debug` only. A normal turn prints the answer and nothing else.
|
|
1814
1837
|
if (cacheNotice)
|
|
1815
|
-
logger.
|
|
1838
|
+
logger.debug(cacheNotice);
|
|
1816
1839
|
return {
|
|
1817
1840
|
content: cached.response,
|
|
1818
1841
|
...(cached.toolCalls ? { toolCalls: cached.toolCalls } : {}),
|
|
@@ -1847,6 +1870,19 @@ export class ChatCommand extends BaseCommand {
|
|
|
1847
1870
|
* in, and what it changed.
|
|
1848
1871
|
*/
|
|
1849
1872
|
const report = ctxOverrides?.onProgress ?? ((line) => void logger.info(line));
|
|
1873
|
+
/**
|
|
1874
|
+
* Where a DIAGNOSTIC notice goes (checkpoint/resume counts — printed on EVERY
|
|
1875
|
+
* `execute` run, since checkpointing is default-on).
|
|
1876
|
+
*
|
|
1877
|
+
* A surface with its own progress channel still gets them — the dashboard
|
|
1878
|
+
* renders the resume notice, and the gateway logs it — but this process's
|
|
1879
|
+
* console only shows them under `--debug` (`-d`, the switch that raises the
|
|
1880
|
+
* logger to the debug channel). Measured: a plain `nuvira execute` question
|
|
1881
|
+
* printed a checkpoint line and a resume-probe line with its why-not detail
|
|
1882
|
+
* before the answer, on EVERY turn. A refusal or an error still goes through
|
|
1883
|
+
* `report` above; those are the user's business.
|
|
1884
|
+
*/
|
|
1885
|
+
const reportDiagnostic = ctxOverrides?.onProgress ?? ((line) => void logger.debug(line));
|
|
1850
1886
|
// Same directory the cache key above is scoped to (see `turnScope`) — one
|
|
1851
1887
|
// resolution per turn, so the cached answer and the work cannot disagree
|
|
1852
1888
|
// about which project the turn belongs to.
|
|
@@ -1903,7 +1939,7 @@ export class ChatCommand extends BaseCommand {
|
|
|
1903
1939
|
// this line used to state the outcome here, which meant every resumed turn
|
|
1904
1940
|
// announced "nothing to replay" before it had tried anything.
|
|
1905
1941
|
if (resume)
|
|
1906
|
-
|
|
1942
|
+
reportDiagnostic(resume.ledger.openNotice());
|
|
1907
1943
|
/**
|
|
1908
1944
|
* Attach this turn's isolation and resume outcomes to whatever it returns.
|
|
1909
1945
|
*
|
|
@@ -1918,6 +1954,9 @@ export class ChatCommand extends BaseCommand {
|
|
|
1918
1954
|
if (worktree) {
|
|
1919
1955
|
const outcome = endIsolation(worktree, { keep: isolationRequest.keep });
|
|
1920
1956
|
extra.worktree = outcome;
|
|
1957
|
+
// The isolation notice is USER-facing even though the checkpoint one
|
|
1958
|
+
// beside it is not: it carries the worktree's path, and for a kept
|
|
1959
|
+
// worktree that path is where the turn's changes are.
|
|
1921
1960
|
report(outcome.notice);
|
|
1922
1961
|
}
|
|
1923
1962
|
if (resume) {
|
|
@@ -1925,7 +1964,7 @@ export class ChatCommand extends BaseCommand {
|
|
|
1925
1964
|
extra.resume = outcome;
|
|
1926
1965
|
// The wording lives in `ResumeOutcome.notice` — one sentence, every
|
|
1927
1966
|
// surface, including the reason when nothing replayed.
|
|
1928
|
-
|
|
1967
|
+
reportDiagnostic(outcome.notice);
|
|
1929
1968
|
}
|
|
1930
1969
|
return { ...result, ...extra };
|
|
1931
1970
|
};
|
|
@@ -3083,8 +3122,10 @@ export class ChatCommand extends BaseCommand {
|
|
|
3083
3122
|
...(served === requested ? {} : { requested }),
|
|
3084
3123
|
});
|
|
3085
3124
|
const notice = debugLogNotice(ctxOverrides?.debugSurface ?? 'cli-chat', debugLog.write());
|
|
3125
|
+
// `--debug` only — see `reportDiagnostic`: the log path is evidence for a bug
|
|
3126
|
+
// report, not part of the answer.
|
|
3086
3127
|
if (notice)
|
|
3087
|
-
logger.
|
|
3128
|
+
logger.debug(notice);
|
|
3088
3129
|
}
|
|
3089
3130
|
// WS3 (#25) — close the turn span and ship it. The status is the turn's own
|
|
3090
3131
|
// outcome, so a failed turn is a RED span in the collector rather than an
|
|
@@ -3101,7 +3142,7 @@ export class ChatCommand extends BaseCommand {
|
|
|
3101
3142
|
});
|
|
3102
3143
|
const otelLine = otelNoticeOnce(ctxOverrides?.debugSurface ?? 'cli-chat');
|
|
3103
3144
|
if (otelLine)
|
|
3104
|
-
logger.
|
|
3145
|
+
logger.debug(otelLine);
|
|
3105
3146
|
await flushSpans();
|
|
3106
3147
|
}
|
|
3107
3148
|
// A4 — an unfinished turn (cancelled, or an outcome that did not conclude)
|
|
@@ -3123,7 +3164,15 @@ export class ChatCommand extends BaseCommand {
|
|
|
3123
3164
|
undeliveredChange: result.undeliveredChange,
|
|
3124
3165
|
unbackedHealthClaim: result.unbackedHealthClaim,
|
|
3125
3166
|
});
|
|
3126
|
-
|
|
3167
|
+
// E3b — what the model SUGGESTED, structurally when it called the tool and
|
|
3168
|
+
// recovered from its own prose list when it did not (see
|
|
3169
|
+
// `followupsFromAnswerList`). Applied HERE, at the one boundary every
|
|
3170
|
+
// surface's followups come from, so the CLI menu, the dashboard chips and
|
|
3171
|
+
// the gateway's "Try next" list agree instead of each recovering its own.
|
|
3172
|
+
const engineFollowups = result.followups && result.followups.length > 0
|
|
3173
|
+
? result.followups
|
|
3174
|
+
: followupsFromAnswerList(result.content);
|
|
3175
|
+
const chatFollowups = withContinuationFollowups(engineFollowups, {
|
|
3127
3176
|
unfinished: !traceOutcomeSucceeded(chatOutcomeForFollowups),
|
|
3128
3177
|
hadTools: (result.successfulToolCalls ?? result.toolCalls ?? []).length > 0,
|
|
3129
3178
|
});
|
|
@@ -3760,7 +3809,11 @@ export class ChatCommand extends BaseCommand {
|
|
|
3760
3809
|
// Logging must never break a turn.
|
|
3761
3810
|
}
|
|
3762
3811
|
try {
|
|
3763
|
-
return await generateWithTransientRetry(() => tryGenerate(session.provider, session.type, session.model), abort, (attempt, err) =>
|
|
3812
|
+
return await generateWithTransientRetry(() => tryGenerate(session.provider, session.type, session.model), abort, (attempt, err) =>
|
|
3813
|
+
// `--debug` only: a retry the user did not have to act on is diagnosis,
|
|
3814
|
+
// not news — and the provider's own error body (a 503 JSON dump) is
|
|
3815
|
+
// quoted as ONE capped line so it can never spray the console.
|
|
3816
|
+
logger.debug(` ⏳ ${session.provider.name} transient failure (attempt ${attempt}) — retrying shortly: ${err instanceof Error ? err.message.split('\n')[0].slice(0, 160) : String(err)}`),
|
|
3764
3817
|
// Empty-response patience from the plan: granted for a proven pair
|
|
3765
3818
|
// (registry track record or real work this turn), LONGER when every
|
|
3766
3819
|
// alternative would de-escalate a capability band. A pair with neither
|
|
@@ -3813,7 +3866,7 @@ export class ChatCommand extends BaseCommand {
|
|
|
3813
3866
|
// (the E2E repair-failover contract): one warn per walk, one
|
|
3814
3867
|
// success log per landed candidate — and now the failure KIND in the
|
|
3815
3868
|
// line, so the console says what went wrong instead of only that it did.
|
|
3816
|
-
logger.
|
|
3869
|
+
logger.debug(` ⚠️ ${session.provider.name} failed (${describeFailureKind(primaryKind)}) — trying the next auto candidate...`);
|
|
3817
3870
|
/**
|
|
3818
3871
|
* ── PAIR-SCOPED WALK: follow what is ROUTABLE, not one model per
|
|
3819
3872
|
* provider ────────────────────────────────────────────────────────
|
|
@@ -3924,7 +3977,7 @@ export class ChatCommand extends BaseCommand {
|
|
|
3924
3977
|
// erase the resolved id that tryGenerate just recorded.
|
|
3925
3978
|
if (next.model && next.model !== 'default')
|
|
3926
3979
|
session.model = next.model;
|
|
3927
|
-
logger.
|
|
3980
|
+
logger.debug(`✅ Auto failover: answered from ${next.provider.name} (${next.model}) after ${firstType} failed`);
|
|
3928
3981
|
return resp;
|
|
3929
3982
|
}
|
|
3930
3983
|
catch (nextErr) {
|
|
@@ -3964,7 +4017,7 @@ export class ChatCommand extends BaseCommand {
|
|
|
3964
4017
|
}
|
|
3965
4018
|
if (providerOut)
|
|
3966
4019
|
failedProviders.add(next.type);
|
|
3967
|
-
logger.
|
|
4020
|
+
logger.debug(` ⚠️ ${next.type}/${next.model ?? 'default'} failed (${describeFailureKind(nextKind)}) — ` +
|
|
3968
4021
|
(providerOut
|
|
3969
4022
|
? 'that provider is out; trying the next auto candidate...'
|
|
3970
4023
|
: `trying ${next.type}'s next model, then the next provider...`));
|