@barivia/barsom-mcp 0.23.11 → 0.23.12
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 +1 -1
- package/dist/figure_sections.js +63 -0
- package/dist/shared.js +6 -1
- package/dist/tools/explore_map.js +7 -5
- package/dist/tools/training_monitor.js +7 -12
- package/dist/views/src/views/results-explorer/index.html +10 -10
- package/dist/views/src/views/training-monitor/index.html +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -194,7 +194,7 @@ The right viewer depends on **(MCP App support)** **and** **(can the human reach
|
|
|
194
194
|
### Migration notes
|
|
195
195
|
|
|
196
196
|
- **Results explorer figure dropdown (0.23.2):** `results_explorer` puts a grouped `<select>` above the plot (no scrolling the sidebar to switch figures), matching barmesh explorer UX. Sidebar keeps Metrics + Highlights only.
|
|
197
|
-
- **UI delivery + train auto-open (0.22.4+):** `train()` returns `training_monitor` App structured content so supporting hosts open the monitor in the same turn. App tools emit structured `ui_delivery` (`delivery`, `urls`, `hint_for_agent`) and always put the standalone viz URL first. Env: `BARIVIA_UI_DELIVERY
|
|
197
|
+
- **UI delivery + train auto-open (0.22.4+ / 0.23.11+):** `train()` returns `training_monitor` App structured content so supporting hosts open the monitor in the same turn. App tools emit structured `ui_delivery` (`delivery`, `urls`, `hint_for_agent`) and always put the standalone viz URL first. Env: `BARIVIA_UI_DELIVERY` (`auto` \| `apps` \| `localhost` \| `inline` \| `text_only`), `BARIVIA_UI_PREFER_LOCALHOST=1` (opt-in localhost under `auto`), `BARIVIA_VIZ_PORT`. Cyclic cos/sin component PNGs are omitted from default `summary.files` / `figures=all` (encoding for training; panels still appear in `combined` / recolor); opt in with train param `viz_upload_cyclic_components=true`.
|
|
198
198
|
- **Account surface (0.22.0, breaking):** `account(request_compute|compute_status|release_compute)` removed — AWS cloud burst leases are gone. Use `account(status|history|add_funds)`. Capacity is shared LOCAL/GKE pools.
|
|
199
199
|
- **Structured results + train hints (0.21.x, non-breaking):**
|
|
200
200
|
- **`results(action=get)`** returns **`structuredContent`** (job id/type, label, summary metrics, file list) alongside the text summary — same pattern as `training_monitor` / `results_explorer`. Agent hosts can read fields without parsing prose.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical figure taxonomy for barsom results_explorer dropdown sections.
|
|
3
|
+
* Labels match the prior GROUP_LABELS (Summary → Diagnostics → Components → Other).
|
|
4
|
+
*/
|
|
5
|
+
export const FIGURE_SECTION_ORDER = [
|
|
6
|
+
"summary",
|
|
7
|
+
"diagnostic",
|
|
8
|
+
"component",
|
|
9
|
+
"artifact",
|
|
10
|
+
];
|
|
11
|
+
export const FIGURE_SECTION_LABELS = {
|
|
12
|
+
summary: "Summary",
|
|
13
|
+
diagnostic: "Diagnostics",
|
|
14
|
+
component: "Components",
|
|
15
|
+
artifact: "Other",
|
|
16
|
+
};
|
|
17
|
+
/** Map a figure base key into one of four explorer sections. */
|
|
18
|
+
export function figureSection(key) {
|
|
19
|
+
if (key === "combined" || key === "coverage_overview")
|
|
20
|
+
return "summary";
|
|
21
|
+
if (key.startsWith("component_"))
|
|
22
|
+
return "component";
|
|
23
|
+
if (key === "umatrix" ||
|
|
24
|
+
key === "hit_histogram" ||
|
|
25
|
+
key === "learning_curve" ||
|
|
26
|
+
key === "correlation" ||
|
|
27
|
+
key === "divergence_kl" ||
|
|
28
|
+
key === "divergence_w1" ||
|
|
29
|
+
key.startsWith("cluster")) {
|
|
30
|
+
return "diagnostic";
|
|
31
|
+
}
|
|
32
|
+
if (key.startsWith("component"))
|
|
33
|
+
return "component";
|
|
34
|
+
return "artifact";
|
|
35
|
+
}
|
|
36
|
+
export const FIGURE_SORT_RANK = {
|
|
37
|
+
combined: 0,
|
|
38
|
+
coverage_overview: 1,
|
|
39
|
+
umatrix: 10,
|
|
40
|
+
hit_histogram: 11,
|
|
41
|
+
learning_curve: 12,
|
|
42
|
+
correlation: 13,
|
|
43
|
+
divergence_kl: 14,
|
|
44
|
+
divergence_w1: 15,
|
|
45
|
+
};
|
|
46
|
+
export function sortRank(key) {
|
|
47
|
+
if (key in FIGURE_SORT_RANK)
|
|
48
|
+
return FIGURE_SORT_RANK[key];
|
|
49
|
+
if (key.startsWith("component_")) {
|
|
50
|
+
const n = Number(key.replace(/^component_/, "").split("_")[0]);
|
|
51
|
+
return 20 + (Number.isFinite(n) ? n : 0);
|
|
52
|
+
}
|
|
53
|
+
if (key.startsWith("cluster"))
|
|
54
|
+
return 16;
|
|
55
|
+
return 50;
|
|
56
|
+
}
|
|
57
|
+
/** Sort by section order, then canonical rank, then label. */
|
|
58
|
+
export function sortFiguresBySection(figures) {
|
|
59
|
+
return [...figures].sort((a, b) => FIGURE_SECTION_ORDER.indexOf(a.kind ?? figureSection(a.key)) -
|
|
60
|
+
FIGURE_SECTION_ORDER.indexOf(b.kind ?? figureSection(b.key)) ||
|
|
61
|
+
sortRank(a.key) - sortRank(b.key) ||
|
|
62
|
+
a.label.localeCompare(b.label));
|
|
63
|
+
}
|
package/dist/shared.js
CHANGED
|
@@ -66,7 +66,7 @@ function newRequestId() {
|
|
|
66
66
|
* X-Barsom-Client-Version so the server can annotate tool guidance with the
|
|
67
67
|
* wrapper version each action requires. Keep in sync with package.json on bump.
|
|
68
68
|
*/
|
|
69
|
-
export const CLIENT_VERSION = "0.23.
|
|
69
|
+
export const CLIENT_VERSION = "0.23.12";
|
|
70
70
|
/** User-facing links; keep aligned with barivia.se / api.barivia.se. */
|
|
71
71
|
export const PUBLIC_SITE_ORIGIN = "https://barivia.se";
|
|
72
72
|
/** Self-serve account dashboard (manage plan, billing, and API keys). */
|
|
@@ -1096,6 +1096,11 @@ export async function fetchTrainingGuidanceFromApi() {
|
|
|
1096
1096
|
catch (e) {
|
|
1097
1097
|
if (e?.httpStatus === 401 || e?.httpStatus === 403)
|
|
1098
1098
|
throw e;
|
|
1099
|
+
// Prefer last successful payload over a hard failure (TTL may have expired).
|
|
1100
|
+
if (_trainingGuidanceCache?.text) {
|
|
1101
|
+
return (_trainingGuidanceCache.text +
|
|
1102
|
+
"\n\n(Note: API unreachable — showing last cached guidance; may be stale.)");
|
|
1103
|
+
}
|
|
1099
1104
|
return "Could not fetch parameter guidance. Check API key and connectivity.";
|
|
1100
1105
|
}
|
|
1101
1106
|
}
|
|
@@ -4,7 +4,9 @@ import { registerAuditedTool, runMcpToolAudit } from "../audit.js";
|
|
|
4
4
|
import { apiCall, apiRawCall, BARSOM_VIZ_VIEWS, buildStandaloneVizPageUrl, buildVizRelatedUrls, getVizPort, getCaptionForImage, getResultsImagesToFetch, mimeForFilename, structuredTextResult, tryAttachImage, } from "../shared.js";
|
|
5
5
|
import { buildVizStandaloneUrl } from "../viz_links.js";
|
|
6
6
|
import { appendUiDeliveryContent, beginInlineFallback, buildStandaloneVizUrl, resolveUiDelivery, } from "../ui-delivery.js";
|
|
7
|
+
import { figureSection, sortFiguresBySection } from "../figure_sections.js";
|
|
7
8
|
export const RESULTS_EXPLORER_URI = "ui://barsom/results-explorer";
|
|
9
|
+
export { FIGURE_SECTION_LABELS, FIGURE_SECTION_ORDER, figureSection } from "../figure_sections.js";
|
|
8
10
|
function labelForFigure(filename) {
|
|
9
11
|
const base = filename.replace(/\.(png|pdf|svg)$/i, "");
|
|
10
12
|
if (base === "combined")
|
|
@@ -34,7 +36,7 @@ function buildAvailableFigures(jobId, summary) {
|
|
|
34
36
|
// `_fetch_figure` server-tool bridge (the default figure also arrives as a
|
|
35
37
|
// base64 image via the tool result). The standalone browser page builds its
|
|
36
38
|
// own relative-URL payload separately (see views/results-explorer/app.ts).
|
|
37
|
-
return figureFiles.map((filename) => {
|
|
39
|
+
return sortFiguresBySection(figureFiles.map((filename) => {
|
|
38
40
|
const base = filename.replace(/\.(png|pdf|svg)$/i, "");
|
|
39
41
|
const featureName = base.startsWith("component_")
|
|
40
42
|
? base.replace(/^component_\d+_/, "").replace(/_/g, " ")
|
|
@@ -44,11 +46,11 @@ function buildAvailableFigures(jobId, summary) {
|
|
|
44
46
|
key: base,
|
|
45
47
|
label: labelForFigure(filename),
|
|
46
48
|
filename,
|
|
47
|
-
kind: base
|
|
49
|
+
kind: figureSection(base),
|
|
48
50
|
featureName,
|
|
49
51
|
caption: getCaptionForImage(filename) || (!isRaster ? "This figure is available for download, but it is not inline-displayable in this first iteration." : undefined),
|
|
50
52
|
};
|
|
51
|
-
});
|
|
53
|
+
}));
|
|
52
54
|
}
|
|
53
55
|
function buildMetrics(summary) {
|
|
54
56
|
const jobType = String(summary.job_type ?? "train_som");
|
|
@@ -179,7 +181,7 @@ async function handleResultsExplorer(job_id) {
|
|
|
179
181
|
}
|
|
180
182
|
return {
|
|
181
183
|
...structuredTextResult({ ...payload, ui_delivery: uiDelivery }, undefined, content),
|
|
182
|
-
_meta: { ui: { resourceUri: RESULTS_EXPLORER_URI } },
|
|
184
|
+
_meta: { ui: { resourceUri: RESULTS_EXPLORER_URI, visibility: ["app"] } },
|
|
183
185
|
};
|
|
184
186
|
}
|
|
185
187
|
export function registerExploreMapTool(server) {
|
|
@@ -189,7 +191,7 @@ export function registerExploreMapTool(server) {
|
|
|
189
191
|
inputSchema: {
|
|
190
192
|
job_id: z.string().describe("Job ID of a completed map training job"),
|
|
191
193
|
},
|
|
192
|
-
_meta: { ui: { resourceUri: RESULTS_EXPLORER_URI } },
|
|
194
|
+
_meta: { ui: { resourceUri: RESULTS_EXPLORER_URI, visibility: ["app"] } },
|
|
193
195
|
};
|
|
194
196
|
registerAppTool(server, "results_explorer", toolConfig, async (args) => runMcpToolAudit("results_explorer", "default", args, () => handleResultsExplorer(String(args.job_id))));
|
|
195
197
|
// NOTE: this MUST stay a registered tool — the Results Explorer MCP App view
|
|
@@ -100,10 +100,11 @@ async function enrichWithTrainingLog(job_id, data) {
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
export async function buildTrainingMonitorResult(job_id, opts) {
|
|
103
|
-
const {
|
|
103
|
+
const { preamble } = opts ?? {};
|
|
104
104
|
let data = (await apiCall("GET", `/v1/jobs/${job_id}`));
|
|
105
105
|
const jobStatus = String(data.status ?? "");
|
|
106
|
-
|
|
106
|
+
// Enrich terminal jobs for curve arrays (App refresh uses job_id only — no public flag).
|
|
107
|
+
if (needsTrainingLogEnrichment(data) || ["completed", "failed", "cancelled"].includes(jobStatus)) {
|
|
107
108
|
data = await enrichWithTrainingLog(job_id, data);
|
|
108
109
|
}
|
|
109
110
|
const port = getVizPort();
|
|
@@ -178,21 +179,15 @@ export function registerTrainingMonitorTool(server) {
|
|
|
178
179
|
description: "Optional view of training progress for a job_id. Prefer the standalone localhost URL in the tool result (always surfaced when the viz server is up) — some hosts list MCP Apps without mounting panels. When a host mounts the App, the panel auto-refreshes every 5s: QE/TE curves (≤1000 batch samples per phase) plus a hit-distribution heatmap. Set BARIVIA_VIZ_PORT for a stable port; re-run for a fresh link after proxy restart. Headless: jobs(action=status) has the same scalars — not required to finish training or read results.",
|
|
179
180
|
inputSchema: {
|
|
180
181
|
job_id: z.string().describe("Training job ID to monitor"),
|
|
181
|
-
fetch_training_log: z
|
|
182
|
-
.boolean()
|
|
183
|
-
.optional()
|
|
184
|
-
.describe("[INTERNAL — App/refresh path] Merge completed-job training-log arrays when live progress is empty. Agents should omit this."),
|
|
185
182
|
},
|
|
186
|
-
_meta: { ui: { resourceUri: TRAINING_MONITOR_URI } },
|
|
183
|
+
_meta: { ui: { resourceUri: TRAINING_MONITOR_URI, visibility: ["model", "app"] } },
|
|
187
184
|
}, async (args) => runMcpToolAudit("training_monitor", "default", args, async () => {
|
|
188
185
|
beginInlineFallback();
|
|
189
|
-
const { job_id
|
|
190
|
-
const { structuredContent, content, text } = await buildTrainingMonitorResult(job_id
|
|
191
|
-
fetch_training_log,
|
|
192
|
-
});
|
|
186
|
+
const { job_id } = args;
|
|
187
|
+
const { structuredContent, content, text } = await buildTrainingMonitorResult(job_id);
|
|
193
188
|
return {
|
|
194
189
|
...structuredTextResult(structuredContent, text, content),
|
|
195
|
-
_meta: { ui: { resourceUri: TRAINING_MONITOR_URI } },
|
|
190
|
+
_meta: { ui: { resourceUri: TRAINING_MONITOR_URI, visibility: ["model", "app"] } },
|
|
196
191
|
};
|
|
197
192
|
}));
|
|
198
193
|
}
|