Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog

## 0.81.0

### Workflows

- **An agent node says WHO runs it.** A node whose profile is a minted catalog id (`ap_` + 16 random characters) was titled by humanising that id — "Ap nro qux n7d c7 ll30", which names nothing and cannot be resolved without the host's catalog. It is now the generic **"AI Agent"**, carrying the brand mark of the model it runs, resolved from the model slug alone. A model with no published mark keeps its kind glyph rather than getting an invented logo. A human-authored slug is untouched — the minted-id shape is pinned to its exact length, so `ap_code_review` stays "Ap code review".
- **The mark names the model the run ACTUALLY used.** The subtitle already yields to `state.model` once a run is live (a router can fall back to another lab); the mark now agrees with it, so a fallback run can't show one lab's logo beside another lab's name.
- **The graph reframes itself when density changes.** Node ids and count are unchanged across a compact/expanded flip, so React Flow won't auto-fit and the graph was left mis-zoomed. It now refits — and *glides* to the new framing rather than jumping, because the reader is watching it happen. Motion is opt-out: a reader who asked for `prefers-reduced-motion`, or an environment that cannot report the preference, gets the framing without the movement.

### Dashboard

- **New API:** `modelBrandFor(model: string)` and `ModelBrandStack` (exported from `./dashboard`) — the mark for a model, resolved from the id alone, so any surface holding a model string shows the same glyph the picker does instead of deriving one of its own. Returns `null` for a model with no published mark.

### Internal

- The brand table, its resolution, and the marks move to a leaf module. Rendering a mark previously meant importing from the model picker, and a bundler cannot split a source module — so the `./workflows` entry pulled in the entire picker (`@radix-ui/react-dropdown-menu`, the `ModelPicker` component and its rows). A consumer rendering a workflow graph downloaded a dropdown it never shows. The picker re-exports the leaf, so nothing about the public API changes.

## 0.80.0

### Chat
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tangle-network/sandbox-ui",
"version": "0.80.0",
"version": "0.81.0",
"description": "Unified UI component library for Tangle Sandbox — primitives, chat, dashboard, terminal, editor, and workspace components",
"repository": {
"type": "git",
Expand Down
11 changes: 4 additions & 7 deletions src/dashboard/dashboard-layout.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,11 @@ describe("DashboardLayout — rail collapse control", () => {

// The collapse toggle persists rail state to localStorage; reset it so each
// test starts from the provider's default (expanded), independent of order.
// localStorage is unavailable in some jsdom setups (opaque origin) where the
// provider's writes are already no-ops, so guard the clear.
// Unguarded on purpose: `setupFiles` runs before every test file, and the setup
// installs an in-memory Storage wherever the host does not supply a usable one —
// including where reading `localStorage` throws (see test-support/memory-storage).
beforeEach(() => {
try {
localStorage.clear()
} catch {
/* localStorage unavailable — nothing was persisted to reset */
}
localStorage.clear()
})

it("renders a discoverable collapse toggle on the labeled rail", () => {
Expand Down
8 changes: 8 additions & 0 deletions src/dashboard/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ export {
type ModelPickerProps,
type ModelPickerVariant,
type ModelInfo,
// The model's brand mark, so any surface that knows a model id — a workflow
// node, a run header — shows the same glyph the picker does instead of
// re-deriving one. A caller holds a model STRING, so `modelBrandFor` is the
// whole surface; the brand table, its keys, and the ModelInfo-shaped resolver
// behind it stay internal.
ModelBrandStack,
modelBrandFor,
type ModelBrandIdentity,
} from "./model-picker";
export {
BillingDashboard,
Expand Down
Loading
Loading