agent-nuvira 3.5.2 → 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-registry.d.ts.map +1 -1
- package/dist/tools/run-registry.js +14 -1
- package/dist/tools/run-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 +84 -9
- 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
|
@@ -26,6 +26,7 @@ import { ConfigManager } from '../config/manager.js';
|
|
|
26
26
|
import { parseRuntimeSpec } from '../mcp/runtime.js';
|
|
27
27
|
import { runAllChecks } from '../cli/doctor.js';
|
|
28
28
|
import { getAutoRouter } from '../learning/auto-router.js';
|
|
29
|
+
import { classifyEntries, } from '../learning/cost-classification.js';
|
|
29
30
|
import { acceptanceSummary, collectLabelledTurns, serializeLabelledTurns, parseCorpusText, detectCorpusFormat, mergeImportedLabels, } from '../learning/acceptance-model.js';
|
|
30
31
|
import { readDecisions, recallDecisions, reviseDecision } from '../learning/decision-log.js';
|
|
31
32
|
import { degradedCallsFromTraces } from '../learning/reasoning-trace.js';
|
|
@@ -1513,9 +1514,52 @@ function readCostData() {
|
|
|
1513
1514
|
if (!data?.entries) {
|
|
1514
1515
|
// The empty state deliberately omits `recent` entirely (the dashboard reads
|
|
1515
1516
|
// a missing list as "nothing recorded"), matching the other zero counters.
|
|
1516
|
-
return {
|
|
1517
|
+
return {
|
|
1518
|
+
totalRequests: 0,
|
|
1519
|
+
totalCost: 0,
|
|
1520
|
+
byProvider: {},
|
|
1521
|
+
byModel: {},
|
|
1522
|
+
billedUsd: 0,
|
|
1523
|
+
billedReportedUsd: 0,
|
|
1524
|
+
billedListedUsd: 0,
|
|
1525
|
+
unverifiedListedUsd: 0,
|
|
1526
|
+
notBilledValueUsd: 0,
|
|
1527
|
+
unpricedCalls: 0,
|
|
1528
|
+
unpricedTokens: 0,
|
|
1529
|
+
recomputedCalls: 0,
|
|
1530
|
+
testOriginCalls: 0,
|
|
1531
|
+
// No invoice has been checked yet — stated, not implied.
|
|
1532
|
+
reconciliations: [],
|
|
1533
|
+
};
|
|
1517
1534
|
}
|
|
1518
1535
|
const entries = data.entries;
|
|
1536
|
+
// ── The classified view (ONE judgement for every surface) ────────────────
|
|
1537
|
+
// The Cost page's headline used to be `totalCost` — the sum of a column the
|
|
1538
|
+
// ledger had priced from its own hardcoded table — printed under the words
|
|
1539
|
+
// "Total Spent". It is now split by EVIDENCE: what was billed (provider-reported
|
|
1540
|
+
// exact + list-priced with a declared paid account), the value a free tier
|
|
1541
|
+
// absorbed, the list-priced rows whose tier is undeclared, and the calls with no
|
|
1542
|
+
// price at all. Test-origin rows are excluded here: a row written by a test run
|
|
1543
|
+
// is not the user's usage (the model registry takes the same posture).
|
|
1544
|
+
const classified = classifyEntries(entries, {
|
|
1545
|
+
excludeTestOrigin: true,
|
|
1546
|
+
});
|
|
1547
|
+
const byProviderBilled = {};
|
|
1548
|
+
const byProviderUnverified = {};
|
|
1549
|
+
const byProviderValue = {};
|
|
1550
|
+
const byProviderUnpricedCalls = {};
|
|
1551
|
+
const byModelBilled = {};
|
|
1552
|
+
const byModelValue = {};
|
|
1553
|
+
for (const [provider, t] of Object.entries(classified.byProvider)) {
|
|
1554
|
+
byProviderBilled[provider] = t.billedUsd;
|
|
1555
|
+
byProviderUnverified[provider] = t.unverifiedListedUsd;
|
|
1556
|
+
byProviderValue[provider] = t.notBilledValueUsd;
|
|
1557
|
+
byProviderUnpricedCalls[provider] = t.unpricedCalls;
|
|
1558
|
+
}
|
|
1559
|
+
for (const [model, t] of Object.entries(classified.byModel)) {
|
|
1560
|
+
byModelBilled[model] = t.billedUsd;
|
|
1561
|
+
byModelValue[model] = t.notBilledValueUsd;
|
|
1562
|
+
}
|
|
1519
1563
|
const totalCost = entries.reduce((s, e) => s + (typeof e.costUsd === 'number' ? e.costUsd : 0), 0);
|
|
1520
1564
|
const totalTokens = entries.reduce((s, e) => s + (typeof e.totalTokens === 'number' ? e.totalTokens : 0), 0);
|
|
1521
1565
|
const byProvider = {};
|
|
@@ -1567,9 +1611,53 @@ function readCostData() {
|
|
|
1567
1611
|
measured: e.measured === true,
|
|
1568
1612
|
reported: e.costReported === true,
|
|
1569
1613
|
}));
|
|
1614
|
+
// ── Invoice checks: the only EXTERNAL figures on this page ───────────────
|
|
1615
|
+
// Written by `nuvira stats cost reconcile` when the operator enters the
|
|
1616
|
+
// provider's own charge for a window. Everything else here is an estimate of
|
|
1617
|
+
// money owed; this is the one place the page can be compared against what was
|
|
1618
|
+
// ACTUALLY charged. Read straight from the file (no module import) so the
|
|
1619
|
+
// dashboard keeps resolving its own memory dir, and capped like `recent`.
|
|
1620
|
+
const reconciliationFile = readJSON(join(MEMORY_DIR, 'cost-reconciliations.json'));
|
|
1621
|
+
const reconciliations = (Array.isArray(reconciliationFile?.reconciliations) ? reconciliationFile.reconciliations : [])
|
|
1622
|
+
.filter((r) => r && typeof r.provider === 'string' && typeof r.invoiceUsd === 'number')
|
|
1623
|
+
.slice(0, 20)
|
|
1624
|
+
.map((r) => ({
|
|
1625
|
+
provider: r.provider,
|
|
1626
|
+
invoiceUsd: r.invoiceUsd,
|
|
1627
|
+
billedUsd: r.billedUsd,
|
|
1628
|
+
deltaUsd: r.deltaUsd,
|
|
1629
|
+
verdict: r.verdict,
|
|
1630
|
+
since: r.since,
|
|
1631
|
+
until: r.until,
|
|
1632
|
+
recordedAt: r.recordedAt,
|
|
1633
|
+
...(r.note ? { note: r.note } : {}),
|
|
1634
|
+
...(r.tierEvidence ? { tier: r.tierEvidence.tier } : {}),
|
|
1635
|
+
}));
|
|
1570
1636
|
return {
|
|
1571
1637
|
totalRequests: entries.length,
|
|
1572
1638
|
totalCost: Math.round(totalCost * 100000) / 100000,
|
|
1639
|
+
// The evidence-backed figures. `totalCost` above is kept for compatibility
|
|
1640
|
+
// (it is the ledger total as recorded, including rows priced by the retired
|
|
1641
|
+
// hardcoded table); these are what the page headlines.
|
|
1642
|
+
billedUsd: classified.billedUsd,
|
|
1643
|
+
billedReportedUsd: classified.billedReportedUsd,
|
|
1644
|
+
billedListedUsd: classified.billedListedUsd,
|
|
1645
|
+
billedReportedCalls: classified.billedReportedCalls,
|
|
1646
|
+
billedListedCalls: classified.billedListedCalls,
|
|
1647
|
+
unverifiedListedUsd: classified.unverifiedListedUsd,
|
|
1648
|
+
unverifiedListedCalls: classified.unverifiedListedCalls,
|
|
1649
|
+
notBilledValueUsd: classified.notBilledValueUsd,
|
|
1650
|
+
notBilledValueCalls: classified.notBilledValueCalls,
|
|
1651
|
+
unpricedCalls: classified.unpricedCalls,
|
|
1652
|
+
unpricedTokens: classified.unpricedTokens,
|
|
1653
|
+
recomputedCalls: classified.recomputedCalls,
|
|
1654
|
+
testOriginCalls: classified.testOriginCalls,
|
|
1655
|
+
byProviderBilled,
|
|
1656
|
+
byProviderUnverified,
|
|
1657
|
+
byProviderValue,
|
|
1658
|
+
byProviderUnpricedCalls,
|
|
1659
|
+
byModelBilled,
|
|
1660
|
+
byModelValue,
|
|
1573
1661
|
totalTokens,
|
|
1574
1662
|
byProvider,
|
|
1575
1663
|
byModel,
|
|
@@ -1581,6 +1669,7 @@ function readCostData() {
|
|
|
1581
1669
|
estimatedCost: Math.round(estimatedCost * 100000) / 100000,
|
|
1582
1670
|
reportedCalls,
|
|
1583
1671
|
reportedCost: Math.round(reportedCost * 100000) / 100000,
|
|
1672
|
+
reconciliations,
|
|
1584
1673
|
recent,
|
|
1585
1674
|
};
|
|
1586
1675
|
}
|
|
@@ -7216,7 +7305,27 @@ function handleRequest(req, res) {
|
|
|
7216
7305
|
// `busy` lets a client that reloaded mid-turn know the answer is still being
|
|
7217
7306
|
// produced, so it can keep the bubble alive and poll instead of showing a
|
|
7218
7307
|
// finished-looking thread.
|
|
7219
|
-
|
|
7308
|
+
// `pendingQuestion` rides with the transcript because a reload has to be
|
|
7309
|
+
// able to SEE an open question, not just guess at it from `busy`. The turn
|
|
7310
|
+
// holding for an answer reports `busy: true` exactly like one that is
|
|
7311
|
+
// working, so without this the resumed page showed "⏳ Still working on the
|
|
7312
|
+
// server" for a turn that was waiting on the user (measured 2026-10-14:
|
|
7313
|
+
// trace-1791996357488-wpm352 sat in `ask_user` for 5m02s and was cancelled
|
|
7314
|
+
// with the question never on screen).
|
|
7315
|
+
// `busySince` is when the RUNNING turn started, so a client that gave up on
|
|
7316
|
+
// its own POST (a 5-minute ceiling) or reloaded mid-turn reports how long
|
|
7317
|
+
// the wait really is rather than counting from whenever it attached
|
|
7318
|
+
// (measured 2026-10-14: a 664s turn shown as "1m 25s elapsed").
|
|
7319
|
+
writeJson(res, 200, {
|
|
7320
|
+
ok: true,
|
|
7321
|
+
session: {
|
|
7322
|
+
id,
|
|
7323
|
+
...rec,
|
|
7324
|
+
busy: chatConsole.isBusy(id),
|
|
7325
|
+
...(chatConsole.busySince(id) !== null ? { busySince: chatConsole.busySince(id) } : {}),
|
|
7326
|
+
...(chatConsole.pendingQuestionFor(id) ? { pendingQuestion: chatConsole.pendingQuestionFor(id) } : {}),
|
|
7327
|
+
},
|
|
7328
|
+
});
|
|
7220
7329
|
return;
|
|
7221
7330
|
}
|
|
7222
7331
|
// GET /api/continuity — the stored session snapshots + the semantic recall
|
|
@@ -7949,6 +8058,17 @@ function handleRequest(req, res) {
|
|
|
7949
8058
|
'X-Accel-Buffering': 'no',
|
|
7950
8059
|
});
|
|
7951
8060
|
res.write(`event: init\ndata: ${JSON.stringify({ sessionId })}\n\n`);
|
|
8061
|
+
// A question asked BEFORE this client attached is still waiting for an
|
|
8062
|
+
// answer, and the turn will hold until one arrives. Replaying it here is
|
|
8063
|
+
// what makes a reload (or a second tab) able to ANSWER it: without this the
|
|
8064
|
+
// new page shows a "still working" notice and no choice card at all, while
|
|
8065
|
+
// the turn waits on a reply the page has no way to send — the exact
|
|
8066
|
+
// "the model asked something but nothing appeared on screen" report
|
|
8067
|
+
// (2026-10-14, trace-1791996357488-wpm352, 5m02s in `ask_user`).
|
|
8068
|
+
const pendingQuestion = chatConsole.pendingQuestionFor(sessionId);
|
|
8069
|
+
if (pendingQuestion) {
|
|
8070
|
+
res.write(`event: question\ndata: ${JSON.stringify(pendingQuestion)}\n\n`);
|
|
8071
|
+
}
|
|
7952
8072
|
const heartbeat = setInterval(() => {
|
|
7953
8073
|
try {
|
|
7954
8074
|
res.write(': heartbeat\n\n');
|