From bdfc445453a43d61c98b319299dd99f163570955 Mon Sep 17 00:00:00 2001 From: Donovan Tjemmes Date: Tue, 14 Jul 2026 15:26:05 -0500 Subject: [PATCH] feat(workflows): publish the model brand mark on the workflows entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The graph's node cards already resolve and render a model's brand mark, but the only entry that published modelBrandFor/ModelBrandStack was dashboard. A host labelling a node outside the canvas — a side panel, a run row — had to import them from there, dragging the model-picker and widget surface in behind them: 3.2 KB of gzipped JS for a glyph, measured on the platform SPA. They cost this entry nothing — node-ui.tsx already pulls the module — so the same glyph now comes from the entry the host is already importing the graph from. --- package.json | 4 ++-- src/workflows/entry.test.ts | 25 +++++++++++++++++++++++++ src/workflows/index.ts | 11 +++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 src/workflows/entry.test.ts diff --git a/package.json b/package.json index feda5bb..331bc4f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@tangle-network/sandbox-ui", - "version": "0.81.0", - "description": "Unified UI component library for Tangle Sandbox — primitives, chat, dashboard, terminal, editor, and workspace components", + "version": "0.82.0", + "description": "Unified UI component library for Tangle Sandbox \u2014 primitives, chat, dashboard, terminal, editor, and workspace components", "repository": { "type": "git", "url": "https://github.com/tangle-network/sandbox-ui" diff --git a/src/workflows/entry.test.ts b/src/workflows/entry.test.ts new file mode 100644 index 0000000..90d6a62 --- /dev/null +++ b/src/workflows/entry.test.ts @@ -0,0 +1,25 @@ +import { describe, expect, it } from "vitest" +import * as workflows from "./index" + +/** + * The workflows entry is the one a host renders a graph from, and the node cards it + * renders resolve a model's brand mark themselves (node-ui.tsx). A host labelling a + * node OUTSIDE the canvas — a side panel, a run row — needs the same two symbols, and + * the only other entry that publishes them is `dashboard`, which carries the whole + * model-picker/widget surface behind it: reaching for them there costs a consumer + * kilobytes of gzipped JS for a glyph. Keeping them on this entry is therefore a + * contract, not a convenience, and this asserts it stays one. + */ +describe("@tangle-network/sandbox-ui/workflows entry", () => { + it("publishes the model brand mark the graph's own node cards use", () => { + expect(typeof workflows.modelBrandFor).toBe("function") + expect(typeof workflows.ModelBrandStack).toBe("function") + }) + + it("resolves a brand from a bare model id, as a node card does", () => { + expect(workflows.modelBrandFor("anthropic/claude-sonnet-4-5")?.lab.key).toBe( + "anthropic", + ) + expect(workflows.modelBrandFor("some-internal/model-x")).toBeNull() + }) +}) diff --git a/src/workflows/index.ts b/src/workflows/index.ts index 9d6a804..29f83ac 100644 --- a/src/workflows/index.ts +++ b/src/workflows/index.ts @@ -27,3 +27,14 @@ export { // WorkflowGraph component is reached only through the lazy wrapper's import(). export type { WorkflowGraphProps } from "./WorkflowGraph"; export { WorkflowGraph as WorkflowGraphLazy } from "./WorkflowGraphLazy"; + +// The brand mark of the model a node ran on. The graph's own node cards resolve and +// render these (node-ui.tsx), so a host labelling a node OUTSIDE the canvas — a side +// panel, a run row — reaches for the same two symbols. Exported here so it can have +// them without importing the dashboard entry, which drags the whole model-picker / +// widget surface in behind them. +export { + type ModelBrandIdentity, + ModelBrandStack, + modelBrandFor, +} from "../lib/model-brand";