agent-nuvira 3.3.12 → 3.3.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.
Files changed (152) hide show
  1. package/dist/agents/agents/reasoner.d.ts.map +1 -1
  2. package/dist/agents/agents/reasoner.js +13 -0
  3. package/dist/agents/agents/reasoner.js.map +1 -1
  4. package/dist/agents/orchestrator.d.ts.map +1 -1
  5. package/dist/agents/orchestrator.js +29 -9
  6. package/dist/agents/orchestrator.js.map +1 -1
  7. package/dist/cli/chat.d.ts.map +1 -1
  8. package/dist/cli/chat.js +34 -7
  9. package/dist/cli/chat.js.map +1 -1
  10. package/dist/cli/cli-program.d.ts.map +1 -1
  11. package/dist/cli/cli-program.js +8 -0
  12. package/dist/cli/cli-program.js.map +1 -1
  13. package/dist/cli/config.d.ts.map +1 -1
  14. package/dist/cli/config.js +21 -3
  15. package/dist/cli/config.js.map +1 -1
  16. package/dist/cli/execute.d.ts.map +1 -1
  17. package/dist/cli/execute.js +6 -0
  18. package/dist/cli/execute.js.map +1 -1
  19. package/dist/cli/knowledge.d.ts +23 -0
  20. package/dist/cli/knowledge.d.ts.map +1 -0
  21. package/dist/cli/knowledge.js +132 -0
  22. package/dist/cli/knowledge.js.map +1 -0
  23. package/dist/cli/loop-executor.d.ts.map +1 -1
  24. package/dist/cli/loop-executor.js +45 -6
  25. package/dist/cli/loop-executor.js.map +1 -1
  26. package/dist/cli/omniroute-control.d.ts +88 -0
  27. package/dist/cli/omniroute-control.d.ts.map +1 -0
  28. package/dist/cli/omniroute-control.js +179 -0
  29. package/dist/cli/omniroute-control.js.map +1 -0
  30. package/dist/cli/omniroute.d.ts +21 -0
  31. package/dist/cli/omniroute.d.ts.map +1 -0
  32. package/dist/cli/omniroute.js +67 -0
  33. package/dist/cli/omniroute.js.map +1 -0
  34. package/dist/config/types.d.ts +8 -0
  35. package/dist/config/types.d.ts.map +1 -1
  36. package/dist/context/history.d.ts +21 -0
  37. package/dist/context/history.d.ts.map +1 -1
  38. package/dist/context/history.js +50 -0
  39. package/dist/context/history.js.map +1 -1
  40. package/dist/gateway/hook-contract.d.ts +173 -0
  41. package/dist/gateway/hook-contract.d.ts.map +1 -0
  42. package/dist/gateway/hook-contract.js +352 -0
  43. package/dist/gateway/hook-contract.js.map +1 -0
  44. package/dist/gateway/hooks.d.ts.map +1 -1
  45. package/dist/gateway/hooks.js +14 -0
  46. package/dist/gateway/hooks.js.map +1 -1
  47. package/dist/inference/interface.d.ts +17 -0
  48. package/dist/inference/interface.d.ts.map +1 -1
  49. package/dist/inference/model-id-validation.d.ts +57 -0
  50. package/dist/inference/model-id-validation.d.ts.map +1 -0
  51. package/dist/inference/model-id-validation.js +127 -0
  52. package/dist/inference/model-id-validation.js.map +1 -0
  53. package/dist/inference/openai-compat-adapter.d.ts.map +1 -1
  54. package/dist/inference/openai-compat-adapter.js +12 -1
  55. package/dist/inference/openai-compat-adapter.js.map +1 -1
  56. package/dist/inference/provider-catalog.d.ts +11 -0
  57. package/dist/inference/provider-catalog.d.ts.map +1 -1
  58. package/dist/inference/provider-catalog.js +80 -0
  59. package/dist/inference/provider-catalog.js.map +1 -1
  60. package/dist/inference/route-resolver.d.ts +2 -8
  61. package/dist/inference/route-resolver.d.ts.map +1 -1
  62. package/dist/inference/route-resolver.js +17 -0
  63. package/dist/inference/route-resolver.js.map +1 -1
  64. package/dist/inference/tool-call-utils.d.ts.map +1 -1
  65. package/dist/inference/tool-call-utils.js +10 -8
  66. package/dist/inference/tool-call-utils.js.map +1 -1
  67. package/dist/inference/tools.d.ts +1 -0
  68. package/dist/inference/tools.d.ts.map +1 -1
  69. package/dist/inference/tools.js +20 -3
  70. package/dist/inference/tools.js.map +1 -1
  71. package/dist/learning/auto-router.d.ts +53 -0
  72. package/dist/learning/auto-router.d.ts.map +1 -1
  73. package/dist/learning/auto-router.js +73 -0
  74. package/dist/learning/auto-router.js.map +1 -1
  75. package/dist/learning/error-repair.d.ts +23 -1
  76. package/dist/learning/error-repair.d.ts.map +1 -1
  77. package/dist/learning/error-repair.js +58 -0
  78. package/dist/learning/error-repair.js.map +1 -1
  79. package/dist/learning/knowledge-base.d.ts +124 -0
  80. package/dist/learning/knowledge-base.d.ts.map +1 -0
  81. package/dist/learning/knowledge-base.js +337 -0
  82. package/dist/learning/knowledge-base.js.map +1 -0
  83. package/dist/learning/model-selection.d.ts +2 -1
  84. package/dist/learning/model-selection.d.ts.map +1 -1
  85. package/dist/learning/model-selection.js +35 -2
  86. package/dist/learning/model-selection.js.map +1 -1
  87. package/dist/learning/project-docs.d.ts +83 -0
  88. package/dist/learning/project-docs.d.ts.map +1 -0
  89. package/dist/learning/project-docs.js +132 -0
  90. package/dist/learning/project-docs.js.map +1 -0
  91. package/dist/learning/quota-ledger.d.ts +13 -0
  92. package/dist/learning/quota-ledger.d.ts.map +1 -1
  93. package/dist/learning/quota-ledger.js +28 -0
  94. package/dist/learning/quota-ledger.js.map +1 -1
  95. package/dist/learning/seeded-benchmark.d.ts +14 -0
  96. package/dist/learning/seeded-benchmark.d.ts.map +1 -1
  97. package/dist/learning/seeded-benchmark.js +43 -4
  98. package/dist/learning/seeded-benchmark.js.map +1 -1
  99. package/dist/security/secret-scan.d.ts +156 -0
  100. package/dist/security/secret-scan.d.ts.map +1 -0
  101. package/dist/security/secret-scan.js +525 -0
  102. package/dist/security/secret-scan.js.map +1 -0
  103. package/dist/tools/plan-store.d.ts +24 -2
  104. package/dist/tools/plan-store.d.ts.map +1 -1
  105. package/dist/tools/plan-store.js +42 -2
  106. package/dist/tools/plan-store.js.map +1 -1
  107. package/dist/tools/registry.d.ts.map +1 -1
  108. package/dist/tools/registry.js +149 -1
  109. package/dist/tools/registry.js.map +1 -1
  110. package/dist/tools/remediation-ladder.d.ts +91 -0
  111. package/dist/tools/remediation-ladder.d.ts.map +1 -0
  112. package/dist/tools/remediation-ladder.js +308 -0
  113. package/dist/tools/remediation-ladder.js.map +1 -0
  114. package/dist/tools/run-terminal.d.ts.map +1 -1
  115. package/dist/tools/run-terminal.js +26 -2
  116. package/dist/tools/run-terminal.js.map +1 -1
  117. package/dist/tools/skills-hub.d.ts +7 -0
  118. package/dist/tools/skills-hub.d.ts.map +1 -1
  119. package/dist/tools/skills-hub.js +11 -2
  120. package/dist/tools/skills-hub.js.map +1 -1
  121. package/dist/tools/step-artifact.d.ts +35 -0
  122. package/dist/tools/step-artifact.d.ts.map +1 -0
  123. package/dist/tools/step-artifact.js +154 -0
  124. package/dist/tools/step-artifact.js.map +1 -0
  125. package/dist/tools/tool-loop.d.ts +6 -0
  126. package/dist/tools/tool-loop.d.ts.map +1 -1
  127. package/dist/tools/tool-loop.js +27 -3
  128. package/dist/tools/tool-loop.js.map +1 -1
  129. package/dist/tools/toolsets.js +4 -4
  130. package/dist/tools/toolsets.js.map +1 -1
  131. package/dist/tools/worktree.d.ts +11 -2
  132. package/dist/tools/worktree.d.ts.map +1 -1
  133. package/dist/tools/worktree.js +11 -2
  134. package/dist/tools/worktree.js.map +1 -1
  135. package/dist/web-dashboard/server.d.ts +29 -0
  136. package/dist/web-dashboard/server.d.ts.map +1 -1
  137. package/dist/web-dashboard/server.js +372 -5
  138. package/dist/web-dashboard/server.js.map +1 -1
  139. package/dist/web-dashboard/src/types.d.ts +66 -0
  140. package/dist/web-dashboard/src/types.d.ts.map +1 -1
  141. package/dist/web-dashboard/workspace-guard.d.ts +7 -0
  142. package/dist/web-dashboard/workspace-guard.d.ts.map +1 -1
  143. package/dist/web-dashboard/workspace-guard.js +70 -0
  144. package/dist/web-dashboard/workspace-guard.js.map +1 -1
  145. package/package.json +1 -1
  146. package/src/web-dashboard/public/assets/index-DhiuR4S2.js +210 -0
  147. package/src/web-dashboard/public/assets/index-DhiuR4S2.js.map +1 -0
  148. package/src/web-dashboard/public/assets/index-tK8Y2qHB.css +1 -0
  149. package/src/web-dashboard/public/index.html +2 -2
  150. package/src/web-dashboard/public/assets/index-BrZcYhy6.js +0 -207
  151. package/src/web-dashboard/public/assets/index-BrZcYhy6.js.map +0 -1
  152. package/src/web-dashboard/public/assets/index-DsWczTa6.css +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web-dashboard/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web-dashboard/server.ts"],"names":[],"mappings":"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"}
@@ -25,6 +25,7 @@ import { loadEnv } from '../utils/env.js';
25
25
  import { ConfigManager } from '../config/manager.js';
26
26
  import { runAllChecks } from '../cli/doctor.js';
27
27
  import { getAutoRouter } from '../learning/auto-router.js';
28
+ import { withStrictModel } from '../inference/route-resolver.js';
28
29
  import { readRecallHits } from '../context/session-recall.js';
29
30
  import { getRouterPromotion } from '../learning/router-promotion.js';
30
31
  import { AUTH_CLEAR_THRESHOLD } from '../learning/key-hygiene.js';
@@ -2642,6 +2643,7 @@ function summarizeProvider(type, configManager) {
2642
2643
  : maskKey(key),
2643
2644
  model: c?.model,
2644
2645
  baseUrl: c?.baseUrl,
2646
+ enabled: c?.enabled !== false,
2645
2647
  };
2646
2648
  }
2647
2649
  /**
@@ -2868,6 +2870,26 @@ export function setGatewayShutdownForTest(action) {
2868
2870
  function runDashboardShutdown() {
2869
2871
  dashboardShutdownAction();
2870
2872
  }
2873
+ /**
2874
+ * The OmniRoute lifecycle actions behind /api/admin/omniroute. `null` (default)
2875
+ * → the REAL probe/spawn/stop. Swappable for the same reason as the gateway-stop
2876
+ * action: the real probe hits the network and the real start/stop spawns or
2877
+ * signals a machine-wide process, so a ROUTE test must not do either.
2878
+ */
2879
+ let omniRouteActions = null;
2880
+ /** Test hook: stub the OmniRoute lifecycle actions (null restores the real ones). */
2881
+ export function setOmniRouteActionsForTest(actions) {
2882
+ omniRouteActions = actions;
2883
+ }
2884
+ /** The real actions, lazily imported so dashboard boot does not pull the CLI in. */
2885
+ async function realOmniRouteActions() {
2886
+ const mod = await import('../cli/omniroute-control.js');
2887
+ return {
2888
+ status: () => mod.omnirouteStatus(),
2889
+ start: () => mod.startOmniRoute(),
2890
+ stop: () => mod.stopOmniRoute(),
2891
+ };
2892
+ }
2871
2893
  /**
2872
2894
  * Test hook: swap the pairing manager (e.g. for a fake-bridge manager) so
2873
2895
  * /api/whatsapp integration tests never open a real WhatsApp connection.
@@ -3040,6 +3062,102 @@ function handleRequest(req, res) {
3040
3062
  res.end(JSON.stringify(readHistoryData()));
3041
3063
  return;
3042
3064
  }
3065
+ // POST /api/history/clear — delete stored conversations. Body:
3066
+ // { target: 'session', id } — delete ONE session (the History tab
3067
+ // used to be read-only: only clear-all or an age band existed)
3068
+ // { target: 'older', olderThanMs } — time-based bulk sweep
3069
+ // { target: 'all' } — clear everything
3070
+ // Same gate as the continuity store: this is local memory, so an authenticated
3071
+ // admin/operator may change it. Reads (/api/history) stay open as before.
3072
+ if (pathname === '/api/history/clear' && req.method === 'POST') {
3073
+ const session = adminSessions.validate(bearerToken(req));
3074
+ if (!session) {
3075
+ writeJson(res, 401, { ok: false, error: 'Not authenticated — log in first.' });
3076
+ return;
3077
+ }
3078
+ if (!roleCan(session.role, 'routing.operate')) {
3079
+ writeJson(res, 403, { ok: false, error: `Access denied — role '${session.role}' cannot change conversation history.` });
3080
+ return;
3081
+ }
3082
+ void (async () => {
3083
+ const body = await readJsonBody(req);
3084
+ const target = typeof body?.target === 'string' ? body.target : '';
3085
+ const id = typeof body?.id === 'string' ? body.id : undefined;
3086
+ const olderThanMs = typeof body?.olderThanMs === 'number' && body.olderThanMs > 0 ? body.olderThanMs : 0;
3087
+ const { getChatHistory } = await import('../context/history.js');
3088
+ const history = getChatHistory();
3089
+ let removed = 0;
3090
+ if (target === 'session' && id) {
3091
+ if (await history.deleteSession(id))
3092
+ removed = 1;
3093
+ }
3094
+ else if (target === 'older' && olderThanMs > 0) {
3095
+ removed = history.pruneOlderThan(olderThanMs);
3096
+ }
3097
+ else if (target === 'all') {
3098
+ removed = history.count();
3099
+ history.clear();
3100
+ }
3101
+ else {
3102
+ writeJson(res, 400, { ok: false, error: "Expected { target: 'session', id } | { target: 'older', olderThanMs } | { target: 'all' }." });
3103
+ return;
3104
+ }
3105
+ writeJson(res, 200, { ok: true, removed });
3106
+ })();
3107
+ return;
3108
+ }
3109
+ // ── Hook contract (declarative lifecycle rules) ──────────────────────────
3110
+ // GET /api/hooks — the declared hooks plus the contract vocabulary the page
3111
+ // needs to render an editor (events, action kinds and their descriptions).
3112
+ // Reads are open like /api/history.
3113
+ // PUT /api/hooks — replace the whole set. Gated on routing.operate (admin or
3114
+ // operator), the same capability every other config write uses. The server
3115
+ // VALIDATES before persisting, so a bad declaration is a 400 and the
3116
+ // previously-saved set stays in force.
3117
+ if (pathname === '/api/hooks' && req.method === 'GET') {
3118
+ void (async () => {
3119
+ const m = await import('../gateway/hook-contract.js');
3120
+ writeJson(res, 200, {
3121
+ ok: true,
3122
+ file: m.hookDeclarationsFile(),
3123
+ hooks: m.getHookDeclarations(),
3124
+ events: m.HOOK_EVENTS,
3125
+ eventDescriptions: m.HOOK_EVENT_DESCRIPTIONS,
3126
+ actionKinds: m.HOOK_ACTION_KINDS,
3127
+ actionDescriptions: m.HOOK_ACTION_DESCRIPTIONS,
3128
+ });
3129
+ })();
3130
+ return;
3131
+ }
3132
+ if (pathname === '/api/hooks' && req.method === 'PUT') {
3133
+ void (async () => {
3134
+ const session = adminSessions.validate(bearerToken(req));
3135
+ if (!session) {
3136
+ writeJson(res, 401, { ok: false, error: 'Not authenticated — log in first.' });
3137
+ return;
3138
+ }
3139
+ if (!roleCan(session.role, 'routing.operate')) {
3140
+ writeJson(res, 403, {
3141
+ ok: false,
3142
+ error: `Access denied — role '${session.role}' cannot change hooks (requires admin or operator).`,
3143
+ });
3144
+ return;
3145
+ }
3146
+ const body = await readJsonBody(req);
3147
+ if (!body || !Array.isArray(body.hooks)) {
3148
+ writeJson(res, 400, { ok: false, error: 'Invalid JSON body — expected { hooks: [...] }.' });
3149
+ return;
3150
+ }
3151
+ const m = await import('../gateway/hook-contract.js');
3152
+ const saved = m.setHookDeclarations(body.hooks);
3153
+ if (!saved.ok) {
3154
+ writeJson(res, 400, { ok: false, error: saved.error });
3155
+ return;
3156
+ }
3157
+ writeJson(res, 200, { ok: true, hooks: saved.declarations });
3158
+ })();
3159
+ return;
3160
+ }
3043
3161
  if (pathname === '/api/benchmarks') {
3044
3162
  res.writeHead(200, { 'Content-Type': 'application/json' });
3045
3163
  res.end(JSON.stringify(readBenchmarkData()));
@@ -3212,6 +3330,10 @@ function handleRequest(req, res) {
3212
3330
  icon: entry?.icon,
3213
3331
  envVar: entry?.envVar || null,
3214
3332
  keyless: entry?.keyless === true,
3333
+ // What it is / how to set it up — the dashboard renders these beside
3334
+ // the key fields. Optional: most providers need no explanation.
3335
+ ...(entry?.description ? { description: entry.description } : {}),
3336
+ ...(entry?.setup ? { setup: entry.setup } : {}),
3215
3337
  };
3216
3338
  });
3217
3339
  writeJson(res, 200, { providers });
@@ -3325,6 +3447,67 @@ function handleRequest(req, res) {
3325
3447
  })();
3326
3448
  return;
3327
3449
  }
3450
+ // ── OmniRoute gateway lifecycle (the EXTERNAL AI gateway on port 20128) ──
3451
+ // OmniRoute is a separate long-lived process nuvira does not embed; the Admin
3452
+ // page could configure it as a provider but not start/stop it or say whether
3453
+ // it was up. GET reports reachability (a real HTTP probe — a 401 counts as UP),
3454
+ // POST { action: 'start' | 'stop' } drives it. Reads need a session; start/stop
3455
+ // need gateway.manage (the same gate as `nuvira omniroute start|stop` and
3456
+ // `nuvira gateway stop`).
3457
+ if (pathname === '/api/admin/omniroute' && (req.method === 'GET' || req.method === 'POST')) {
3458
+ void (async () => {
3459
+ const session = adminSessions.validate(bearerToken(req));
3460
+ if (!session) {
3461
+ writeJson(res, 401, { ok: false, error: 'Not authenticated — log in first.' });
3462
+ return;
3463
+ }
3464
+ const actions = omniRouteActions ?? (await realOmniRouteActions());
3465
+ try {
3466
+ if (req.method === 'GET') {
3467
+ const status = await actions.status();
3468
+ writeJson(res, 200, { ok: true, status });
3469
+ return;
3470
+ }
3471
+ if (!roleCan(session.role, 'gateway.manage')) {
3472
+ writeJson(res, 403, {
3473
+ ok: false,
3474
+ error: `Access denied — role '${session.role}' cannot start or stop the OmniRoute gateway (requires admin or operator).`,
3475
+ });
3476
+ return;
3477
+ }
3478
+ const body = await readJsonBody(req);
3479
+ const action = body?.action;
3480
+ if (action === 'start') {
3481
+ const result = await actions.start();
3482
+ writeJson(res, 200, {
3483
+ ok: result.ok,
3484
+ action,
3485
+ started: result.started,
3486
+ detail: result.detail,
3487
+ status: result.status,
3488
+ });
3489
+ return;
3490
+ }
3491
+ if (action === 'stop') {
3492
+ const result = await actions.stop();
3493
+ writeJson(res, 200, {
3494
+ ok: result.stopped,
3495
+ action,
3496
+ stopped: result.stopped,
3497
+ reason: result.reason,
3498
+ pid: result.pid,
3499
+ status: await actions.status(),
3500
+ });
3501
+ return;
3502
+ }
3503
+ writeJson(res, 400, { ok: false, error: 'Invalid action — expected "start" or "stop".' });
3504
+ }
3505
+ catch (err) {
3506
+ writeJson(res, 500, { ok: false, error: err instanceof Error ? err.message : String(err) });
3507
+ }
3508
+ })();
3509
+ return;
3510
+ }
3328
3511
  // ── Agent Hub toggles (I5) — admin-gated writes honored by the I1 runtime
3329
3512
  // gate (tool-loop schema + execution gating), so the dashboard toggle is
3330
3513
  // NEVER cosmetic. Same config the CLI writes (`nuvira tools toolsets`);
@@ -3623,6 +3806,121 @@ function handleRequest(req, res) {
3623
3806
  })();
3624
3807
  return;
3625
3808
  }
3809
+ // ── Knowledge base (tag-scoped retrieval over the operator's own documents) ──
3810
+ // Thin endpoints over learning/knowledge-base.ts: list tags, ingest a file or
3811
+ // folder under a tag, query a tag, and forget a tag. Documents are extracted,
3812
+ // chunked and embedded ONCE on ingest, so a query only embeds the question.
3813
+ // Reads list a tag's metadata; writes (ingest/forget) need routing.operate.
3814
+ if (pathname === '/api/knowledge' && req.method === 'GET') {
3815
+ void (async () => {
3816
+ const session = adminSessions.validate(bearerToken(req));
3817
+ if (!session) {
3818
+ writeJson(res, 401, { ok: false, error: 'Not authenticated — log in first.' });
3819
+ return;
3820
+ }
3821
+ try {
3822
+ const { listKnowledgeTags } = await import('../learning/knowledge-base.js');
3823
+ writeJson(res, 200, { ok: true, tags: listKnowledgeTags() });
3824
+ }
3825
+ catch (err) {
3826
+ writeJson(res, 500, { ok: false, error: err instanceof Error ? err.message : String(err) });
3827
+ }
3828
+ })();
3829
+ return;
3830
+ }
3831
+ if (pathname === '/api/knowledge/ingest' && req.method === 'POST') {
3832
+ void (async () => {
3833
+ const session = adminSessions.validate(bearerToken(req));
3834
+ if (!session) {
3835
+ writeJson(res, 401, { ok: false, error: 'Not authenticated — log in first.' });
3836
+ return;
3837
+ }
3838
+ if (!roleCan(session.role, 'routing.operate')) {
3839
+ writeJson(res, 403, {
3840
+ ok: false,
3841
+ error: `Access denied — role '${session.role}' cannot ingest documents (requires admin or operator).`,
3842
+ });
3843
+ return;
3844
+ }
3845
+ const body = await readJsonBody(req);
3846
+ const tag = typeof body?.tag === 'string' ? body.tag.trim() : '';
3847
+ const paths = Array.isArray(body?.paths) ? body.paths.filter((p) => typeof p === 'string' && p.trim().length > 0) : [];
3848
+ if (!tag) {
3849
+ writeJson(res, 400, { ok: false, error: 'A tag is required.' });
3850
+ return;
3851
+ }
3852
+ if (paths.length === 0) {
3853
+ writeJson(res, 400, { ok: false, error: 'At least one file or folder path is required.' });
3854
+ return;
3855
+ }
3856
+ try {
3857
+ const { ingestKnowledge } = await import('../learning/knowledge-base.js');
3858
+ const result = await ingestKnowledge(tag, paths);
3859
+ writeJson(res, 200, { ok: true, ...result });
3860
+ }
3861
+ catch (err) {
3862
+ writeJson(res, 400, { ok: false, error: err instanceof Error ? err.message : String(err) });
3863
+ }
3864
+ })();
3865
+ return;
3866
+ }
3867
+ if (pathname === '/api/knowledge/query' && req.method === 'POST') {
3868
+ void (async () => {
3869
+ const session = adminSessions.validate(bearerToken(req));
3870
+ if (!session) {
3871
+ writeJson(res, 401, { ok: false, error: 'Not authenticated — log in first.' });
3872
+ return;
3873
+ }
3874
+ const body = await readJsonBody(req);
3875
+ const tag = typeof body?.tag === 'string' ? body.tag.trim() : '';
3876
+ const question = typeof body?.question === 'string' ? body.question.trim() : '';
3877
+ const topK = typeof body?.topK === 'number' ? body.topK : undefined;
3878
+ if (!tag || !question) {
3879
+ writeJson(res, 400, { ok: false, error: 'A tag and a question are required.' });
3880
+ return;
3881
+ }
3882
+ try {
3883
+ const { queryKnowledge } = await import('../learning/knowledge-base.js');
3884
+ const hits = await queryKnowledge(tag, question, { topK });
3885
+ writeJson(res, 200, { ok: true, tag, hits });
3886
+ }
3887
+ catch (err) {
3888
+ writeJson(res, 500, { ok: false, error: err instanceof Error ? err.message : String(err) });
3889
+ }
3890
+ })();
3891
+ return;
3892
+ }
3893
+ if (pathname === '/api/knowledge/forget' && req.method === 'POST') {
3894
+ void (async () => {
3895
+ const session = adminSessions.validate(bearerToken(req));
3896
+ if (!session) {
3897
+ writeJson(res, 401, { ok: false, error: 'Not authenticated — log in first.' });
3898
+ return;
3899
+ }
3900
+ if (!roleCan(session.role, 'routing.operate')) {
3901
+ writeJson(res, 403, {
3902
+ ok: false,
3903
+ error: `Access denied — role '${session.role}' cannot remove knowledge tags (requires admin or operator).`,
3904
+ });
3905
+ return;
3906
+ }
3907
+ const body = await readJsonBody(req);
3908
+ const tag = typeof body?.tag === 'string' ? body.tag.trim() : '';
3909
+ if (!tag) {
3910
+ writeJson(res, 400, { ok: false, error: 'A tag is required.' });
3911
+ return;
3912
+ }
3913
+ try {
3914
+ const { forgetKnowledgeTag } = await import('../learning/knowledge-base.js');
3915
+ const removed = await forgetKnowledgeTag(tag);
3916
+ writeJson(res, 200, { ok: true, removed });
3917
+ }
3918
+ catch (err) {
3919
+ writeJson(res, 500, { ok: false, error: err instanceof Error ? err.message : String(err) });
3920
+ }
3921
+ })();
3922
+ return;
3923
+ }
3626
3924
  // ── PA4 — save skill env vars to ~/.nuvira/.env (dashboard secret capture) ──
3627
3925
  if (pathname === '/api/skills/secrets' && req.method === 'POST') {
3628
3926
  void (async () => {
@@ -4569,6 +4867,26 @@ function handleRequest(req, res) {
4569
4867
  }
4570
4868
  if (typeof body.runner === 'string' && body.runner.trim().length > 0)
4571
4869
  updates.runner = body.runner.trim();
4870
+ // The On/Off switch. `false` removes the provider from the auto-routing
4871
+ // pool WITHOUT deleting its credentials; `true` re-admits it.
4872
+ if (typeof body.enabled === 'boolean')
4873
+ updates.enabled = body.enabled;
4874
+ // A3 — a model id is validated against the provider's LIVE list before
4875
+ // it is written, so a typo cannot become a silent substitution at run
4876
+ // time. An unreachable provider is saved unverified (never blocked); a
4877
+ // reachable one that does not serve the id is refused with suggestions.
4878
+ if (typeof updates.model === 'string' && updates.model) {
4879
+ const { validateModelIdForProvider } = await import('../inference/model-id-validation.js');
4880
+ const verdict = await validateModelIdForProvider(type, updates.model, configManager);
4881
+ if (!verdict.ok) {
4882
+ writeJson(res, 400, {
4883
+ ok: false,
4884
+ error: verdict.message,
4885
+ suggestions: verdict.suggestions ?? [],
4886
+ });
4887
+ return;
4888
+ }
4889
+ }
4572
4890
  // Raw config (vault refs INTACT) — never save a resolved key back to
4573
4891
  // plaintext (the documented resolveVaultRefs footgun).
4574
4892
  const raw = configManager.getAll().providers[type] || {};
@@ -4584,7 +4902,7 @@ function handleRequest(req, res) {
4584
4902
  // explicit undefineds, so the fields vanish from the file.
4585
4903
  if (req.method === 'DELETE') {
4586
4904
  const cleared = configManager.clearProviderApiKey(type);
4587
- configManager.save({ providers: { [type]: { apiKey: undefined, baseUrl: undefined, model: undefined, runner: undefined } } });
4905
+ configManager.save({ providers: { [type]: { apiKey: undefined, baseUrl: undefined, model: undefined, runner: undefined, enabled: undefined } } });
4588
4906
  clearModelListCache();
4589
4907
  // An ENV-sourced key cannot be removed from the file (env re-injects on
4590
4908
  // every load) — surface that so the UI warns instead of hiding the row.
@@ -6277,6 +6595,11 @@ function handleRequest(req, res) {
6277
6595
  // POST /api/continuity/clear — forget stored continuity data. Body:
6278
6596
  // { target: 'sessions' | 'recall' } — clear all of one kind
6279
6597
  // { target: 'session' | 'recall-entry', id } — clear one entry
6598
+ // { target: 'sessions' | 'recall', olderThanMs } — TIME-BASED bulk: clear
6599
+ // only entries older than now − olderThanMs. Per-entry forgetting is fine
6600
+ // for a handful of records but tedious for a store that grows on every
6601
+ // run, so "forget anything older than a week" is one request instead of
6602
+ // N. Absent/<=0 → the existing clear-all behaviour, unchanged.
6280
6603
  if (pathname === '/api/continuity/clear' && req.method === 'POST') {
6281
6604
  const session = adminSessions.validate(bearerToken(req));
6282
6605
  if (!session) {
@@ -6291,8 +6614,23 @@ function handleRequest(req, res) {
6291
6614
  const body = await readJsonBody(req);
6292
6615
  const target = typeof body?.target === 'string' ? body.target : '';
6293
6616
  const id = typeof body?.id === 'string' ? body.id : undefined;
6617
+ const olderThanMs = typeof body?.olderThanMs === 'number' && body.olderThanMs > 0 ? body.olderThanMs : 0;
6618
+ const cutoff = olderThanMs > 0 ? Date.now() - olderThanMs : 0;
6294
6619
  let removed = 0;
6295
- if (target === 'sessions') {
6620
+ if (target === 'sessions' && cutoff > 0) {
6621
+ // Time-based bulk: only snapshots saved before the cutoff.
6622
+ const { listSessionSnapshots, clearSession } = await import('../learning/session-store.js');
6623
+ for (const s of listSessionSnapshots())
6624
+ if (s.savedAt < cutoff && clearSession(s.id))
6625
+ removed += 1;
6626
+ }
6627
+ else if (target === 'recall' && cutoff > 0) {
6628
+ const { listRecallEntries, removeRecallEntry } = await import('../learning/session-recall.js');
6629
+ for (const e of listRecallEntries())
6630
+ if (e.savedAt < cutoff && removeRecallEntry(e.id))
6631
+ removed += 1;
6632
+ }
6633
+ else if (target === 'sessions') {
6296
6634
  const { listSessionSnapshots, clearSession } = await import('../learning/session-store.js');
6297
6635
  for (const s of listSessionSnapshots())
6298
6636
  if (clearSession(s.id))
@@ -6314,7 +6652,7 @@ function handleRequest(req, res) {
6314
6652
  removed = 1;
6315
6653
  }
6316
6654
  else {
6317
- writeJson(res, 400, { ok: false, error: "Expected { target: 'sessions'|'recall'|'session'|'recall-entry', id? }." });
6655
+ writeJson(res, 400, { ok: false, error: "Expected { target: 'sessions'|'recall'|'session'|'recall-entry', id?, olderThanMs? }." });
6318
6656
  return;
6319
6657
  }
6320
6658
  writeJson(res, 200, { ok: true, removed });
@@ -6408,6 +6746,11 @@ function handleRequest(req, res) {
6408
6746
  : newChatSessionId();
6409
6747
  const provider = typeof body?.provider === 'string' ? body.provider : undefined;
6410
6748
  const model = typeof body?.model === 'string' ? body.model : undefined;
6749
+ // Strict-model pin for THIS turn (the dashboard chat's "pin this model
6750
+ // only" switch). Scoped to the turn with AsyncLocalStorage rather than a
6751
+ // process env write, because two sessions can run concurrently and a
6752
+ // global mutation would leak one user's pin into the other's turn.
6753
+ const strict = body?.strict === true;
6411
6754
  // WS5 (#27) — per-turn isolation and resume, from the GUI.
6412
6755
  //
6413
6756
  // Read as a strict TRI-state, because the three cases are genuinely
@@ -6516,7 +6859,7 @@ function handleRequest(req, res) {
6516
6859
  // Mark the failover log BEFORE the turn so a failure can report which
6517
6860
  // models were actually tried (same contract as the gateway).
6518
6861
  const attemptMark = markFailoverAttempts();
6519
- const result = await chatConsole.answer(sessionId, message, {
6862
+ const result = await withStrictModel(strict, () => chatConsole.answer(sessionId, message, {
6520
6863
  provider,
6521
6864
  model,
6522
6865
  projectContext,
@@ -6525,7 +6868,7 @@ function handleRequest(req, res) {
6525
6868
  ...(worktree === undefined ? {} : { worktree }),
6526
6869
  ...(keepWorktree === undefined ? {} : { keepWorktree }),
6527
6870
  ...(resume === undefined ? {} : { resume }),
6528
- });
6871
+ }));
6529
6872
  if (!result.ok) {
6530
6873
  writeJson(res, 400, {
6531
6874
  ok: false,
@@ -6538,6 +6881,29 @@ function handleRequest(req, res) {
6538
6881
  // enforced (see ChatRetryBroker). Without this the console was a dead end
6539
6882
  // — the reader had to wait and re-send the message themselves.
6540
6883
  let content = result.content ?? '';
6884
+ // When a model was pinned WITHOUT strict mode, say plainly what happened
6885
+ // to the pin: a turn that ran on another provider was auto-routed, and a
6886
+ // pinned model that failed may be handed off on the next attempt. Either
6887
+ // way the reader is told how to force the pinned model — enable strict
6888
+ // mode — instead of discovering the switch later.
6889
+ let routingNotice;
6890
+ if (provider) {
6891
+ const requested = `${provider}${model ? `/${model}` : ''}`;
6892
+ const served = result.provider ? `${result.provider}${result.model ? `/${result.model}` : ''}` : '';
6893
+ const substituted = Boolean(served) && result.provider !== provider;
6894
+ if (strict) {
6895
+ if (result.generationFailed === true) {
6896
+ routingNotice =
6897
+ 'Strict model mode is on, so the turn stopped rather than falling back to another model.';
6898
+ }
6899
+ }
6900
+ else if (substituted) {
6901
+ routingNotice = `Auto routing took over: this turn ran on ${served} because your pinned ${requested} was not available. To work with ${requested} only, enable strict model mode.`;
6902
+ }
6903
+ else if (result.generationFailed === true) {
6904
+ routingNotice = `Your pinned ${requested} could not complete this turn, so auto routing may hand the work to another model. To stay on this model only, enable strict model mode.`;
6905
+ }
6906
+ }
6541
6907
  // Did the offer we are about to send get a mechanism behind it? The client
6542
6908
  // uses this to stop offering "↻ Retry" for a turn the server is already
6543
6909
  // retrying on its own — a manual re-send on top of the queued one would
@@ -6569,6 +6935,7 @@ function handleRequest(req, res) {
6569
6935
  followups: result.followups ?? [],
6570
6936
  provider: result.provider ?? null,
6571
6937
  model: result.model ?? null,
6938
+ ...(routingNotice ? { routingNotice } : {}),
6572
6939
  // WS1 — the findings this turn recorded, with the gate's verdicts, so
6573
6940
  // a dashboard client reads the same wire form the CLI, the gateway and
6574
6941
  // the subagent report (the GUI card is a rendering decision; the FACT