@barivia/barsom-mcp 0.20.2 → 0.20.3

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 CHANGED
@@ -29,7 +29,7 @@ MCP clients typically run it with **`npx`** (downloads on first use):
29
29
 
30
30
  **Audit logging (0.10.3+):** Each tool invocation emits a structured **`mcp_tool_call`** line on stderr for support correlation — not sent to the Barivia API. Fields: `tool`, `action`, `duration_ms`, `outcome`, **`rid`** (matches API `X-Request-ID`), **`job_id`** / **`dataset_id`** when the action returns or accepts them, scale hints **`grid_x`** / **`grid_y`** on training submits, and **`timeout_hit`** / **`output_truncated`** when proxy fetch/output limits apply. No API keys or file paths. Grep client stderr alongside API/worker logs by `rid`; see `docs/OPERATIONS_MANUAL.md` §5b.
31
31
 
32
- **Also available:** hosted HTTP MCP at **`https://mcp.barivia.se/mcp`** (same API key; no npm) for clients that support remote MCP.
32
+ **Hosted HTTP MCP paused (2026-06):** `https://mcp.barivia.se/mcp` returns **503** (`hosted_mcp_paused`). Use this npm package only.
33
33
 
34
34
  **Cursor / multi-account note:** Cursor's tool dispatcher resolves tools under a `serverIdentifier` (e.g. `user-barivia-bbb-maps`), which can differ from the key you wrote in `mcp.json` (e.g. `barivia-bbb-maps`). If a tool call fails with **"server does not exist"** or similar, list the resolved identifier with your client's tool inspector (`mcp.list-tools` or equivalent) and use that identifier — not the `mcp.json` key.
35
35
 
package/dist/shared.js CHANGED
@@ -26,7 +26,7 @@ export const RETRYABLE_STATUS = new Set([502, 503, 504]);
26
26
  * X-Barsom-Client-Version so the server can annotate tool guidance with the
27
27
  * wrapper version each action requires. Keep in sync with package.json on bump.
28
28
  */
29
- export const CLIENT_VERSION = "0.20.2";
29
+ export const CLIENT_VERSION = "0.20.3";
30
30
  /** User-facing links; keep aligned with barivia.se / api.barivia.se. */
31
31
  export const PUBLIC_SITE_ORIGIN = "https://barivia.se";
32
32
  /** Self-serve account dashboard (manage plan, billing, and API keys). */
@@ -2,7 +2,7 @@ import { z } from "zod";
2
2
  import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
3
3
  import { runMcpToolAudit } from "../audit.js";
4
4
  import { apiCall, getClientSupportsMcpApps, getVizPort, structuredTextResult, } from "../shared.js";
5
- import { lastEpochTeFromCurves } from "../training_monitor_curve.js";
5
+ import { lastEpochTeFromCurves, snapTeCurvesToMapTe } from "../training_monitor_curve.js";
6
6
  export const TRAINING_MONITOR_URI = "ui://barsom/training-monitor";
7
7
  export const TRAINING_MONITOR_REFRESH_MS = 5000;
8
8
  function hasCurveArrays(data) {
@@ -72,13 +72,13 @@ async function enrichWithTrainingLog(job_id, data) {
72
72
  if (status === "completed" || status === "failed" || status === "cancelled") {
73
73
  merged.topographic_error = mapTe;
74
74
  }
75
- return merged;
75
+ return snapTeCurvesToMapTe(merged);
76
76
  }
77
77
  catch {
78
78
  if (epochTe != null) {
79
- return { ...data, epoch_topographic_error: epochTe };
79
+ return snapTeCurvesToMapTe({ ...data, epoch_topographic_error: epochTe });
80
80
  }
81
- return data;
81
+ return data.kernel_complete === true ? snapTeCurvesToMapTe(data) : data;
82
82
  }
83
83
  }
84
84
  export function registerTrainingMonitorTool(server) {
@@ -9,13 +9,38 @@ export function combinedBatchAxis(nOrd, nConv) {
9
9
  return [];
10
10
  return [...batchSampleAxis(nOrd, 0), ...batchSampleAxis(nConv, nOrd)];
11
11
  }
12
+ export function isKernelTrainingComplete(data, status) {
13
+ if (status === "failed" || status === "cancelled")
14
+ return true;
15
+ if (data.kernel_complete === true)
16
+ return true;
17
+ return status === "completed";
18
+ }
19
+ /** Snap the last TE curve point to authoritative full-map TE when kernel training is done. */
20
+ export function snapTeCurvesToMapTe(data) {
21
+ const mapTe = data.map_topographic_error ??
22
+ (data.kernel_complete === true ? data.topographic_error : null);
23
+ if (mapTe == null || !Number.isFinite(Number(mapTe)))
24
+ return data;
25
+ const out = { ...data };
26
+ for (const key of ["ordering_topographic_errors", "convergence_topographic_errors"]) {
27
+ const arr = out[key];
28
+ if (Array.isArray(arr) && arr.length > 0) {
29
+ const copy = arr.slice();
30
+ copy[copy.length - 1] = Number(mapTe);
31
+ out[key] = copy;
32
+ }
33
+ }
34
+ return out;
35
+ }
36
+ export function teCurveLabel(base, kernelComplete) {
37
+ return kernelComplete ? `${base} (→ map TE)` : `${base} (sampled)`;
38
+ }
12
39
  export function formatCurveSourceNote(data) {
13
40
  const src = data.training_curve_source_batches;
14
- if (!src)
15
- return null;
16
41
  const parts = [];
17
- const ordTotal = typeof src.ordering === "number" ? src.ordering : null;
18
- const convTotal = typeof src.convergence === "number" ? src.convergence : null;
42
+ const ordTotal = src && typeof src.ordering === "number" ? src.ordering : null;
43
+ const convTotal = src && typeof src.convergence === "number" ? src.convergence : null;
19
44
  const ordShown = Array.isArray(data.ordering_errors) ? data.ordering_errors.length : 0;
20
45
  const convShown = Array.isArray(data.convergence_errors) ? data.convergence_errors.length : 0;
21
46
  if (ordTotal != null && ordTotal > ordShown) {
@@ -24,9 +49,24 @@ export function formatCurveSourceNote(data) {
24
49
  if (convTotal != null && convTotal > convShown) {
25
50
  parts.push(`${convShown} of ${convTotal.toLocaleString()} convergence batch samples`);
26
51
  }
52
+ const mapTe = data.map_topographic_error;
53
+ const epochTe = data.epoch_topographic_error;
54
+ if (mapTe != null &&
55
+ epochTe != null &&
56
+ Number.isFinite(Number(mapTe)) &&
57
+ Number.isFinite(Number(epochTe)) &&
58
+ Math.abs(Number(epochTe) - Number(mapTe)) > 0.0005) {
59
+ parts.push(`Live TE is a subsampled batch estimate during training; final point snaps to map TE ${Number(mapTe).toFixed(4)} (last sampled ${Number(epochTe).toFixed(4)})`);
60
+ }
61
+ else if (mapTe != null && Number.isFinite(Number(mapTe))) {
62
+ parts.push(`TE curve final point is full-map topographic error (${Number(mapTe).toFixed(4)}).`);
63
+ }
27
64
  if (parts.length === 0)
28
65
  return null;
29
- return `Displaying uniformly subsampled QE+TE curves (≤1000 points/phase, joint indices): ${parts.join("; ")}.`;
66
+ const subsample = ordTotal != null || convTotal != null
67
+ ? "Displaying uniformly subsampled QE+TE curves (≤1000 points/phase, joint indices): "
68
+ : "";
69
+ return `${subsample}${parts.join("; ")}.`.replace(/: ;/, ":");
30
70
  }
31
71
  /** Map TE onto QE batch axis; when batch-aligned (same length), use values directly. */
32
72
  export function alignTeToQeAxis(te, qeLen) {