@theoremjs/studio 0.3.4-next.464.g5fc5eed → 0.3.4-next.468.ge2da06f
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/package.json +4 -4
- package/page/assets/{Banner-fUKWqHmI.js → Banner-Z4LFsB9Y.js} +2 -2
- package/page/assets/{ConsoleFrame-B3cd6mje.js → ConsoleFrame-BJo1I5fw.js} +1 -1
- package/page/assets/{ContextMenu-C1HQbsdS.js → ContextMenu-BrT5KgtG.js} +2 -2
- package/page/assets/{ToolResultCharts-CngV4ccU.js → ToolResultCharts-CvdG2e3W.js} +1 -1
- package/page/assets/{TraceInspector-BJS_1iXX.js → TraceInspector-CwsPN13M.js} +1 -1
- package/page/assets/{TraceOverview-6hlA2pmX.js → TraceOverview-Bdz85-Rn.js} +1 -1
- package/page/assets/{_virtual_studio-type-sources-Bu1ywN-k.js → _virtual_studio-type-sources-DdSjKnMh.js} +5 -5
- package/page/assets/{browser-engine-BReGdZx4.js → browser-engine-Biheh6VY.js} +8 -8
- package/page/assets/{browser-transport-Bsz-KNbB.js → browser-transport-Cnyo4CDA.js} +4 -4
- package/page/assets/{crypto-Boxudvjl.js → crypto-C5mfRMPv.js} +1 -1
- package/page/assets/{encode-files-DZ4tVtEQ.js → encode-files-CZXrfYAp.js} +1 -1
- package/page/assets/{export-agent-DDZ8cq19.js → export-agent-CVpG2q1m.js} +1 -1
- package/page/assets/{guardrail-tester-C_T6-YOZ.js → guardrail-tester-CJuC6zTI.js} +1 -1
- package/page/assets/{index-Cw3Spve0.js → index-CYmjuHBy.js} +9 -9
- package/page/assets/{live-messages-dPuowG_o.js → live-messages-CcUq850L.js} +1 -1
- package/page/assets/{reader-BB7aL5yX.js → reader-DkhgU7-Z.js} +4 -4
- package/page/assets/shaped-data-Hq2l-bCM.js +16 -0
- package/page/assets/{stub-DyzmGexy.js → stub-9noS56tk.js} +1 -1
- package/page/assets/{studio-code-pane-xsBtdlWI.js → studio-code-pane-CkjZy0ML.js} +3 -3
- package/page/assets/{studio-console-C3uStRGc.js → studio-console-D7Gp4J9U.js} +1 -1
- package/page/assets/{studio-decision-MvC7eEPm.js → studio-decision-BRgQ4PBH.js} +1 -1
- package/page/assets/{studio-embedding-mvARkljv.js → studio-embedding-Dl4-HUCw.js} +1 -1
- package/page/assets/{studio-host-console-CzHR2V7s.js → studio-host-console-C2kDYgZ0.js} +2 -2
- package/page/assets/{studio-labels-DsQLZ9_e.js → studio-labels-BOSQZulx.js} +1 -1
- package/page/assets/{studio-live-DXV_PScy.js → studio-live-BweMJXiN.js} +1 -1
- package/page/assets/{studio-map-DBLOQt2Q.js → studio-map-ClUV7cPI.js} +1 -1
- package/page/assets/{studio-trace-replay-DHJTvGZO.js → studio-trace-replay-BVJ_xUpV.js} +1 -1
- package/page/assets/{studio-type-checker-BaSH5B4-.js → studio-type-checker-Ch0YO2TO.js} +1 -1
- package/page/assets/{tool-schema-E9NPuDcN.js → tool-schema-DUAd6AXZ.js} +6 -6
- package/page/assets/{trace-record-BjsBbPRl.js → trace-record-Dfx7WS9n.js} +1 -1
- package/page/assets/{tree-2VeaKg0m.js → tree-q4zfZBm3.js} +2 -2
- package/page/assets/{turn-client-Dy9-U9_L.js → turn-client-BHueOGtF.js} +2 -2
- package/page/assets/types-CbxtWiCN.js +1 -0
- package/page/assets/{use-one-call-B3x4YoMP.js → use-one-call-Djq1Oucn.js} +1 -1
- package/page/assets/{workspace-Cno6Ge26.js → workspace-D8wB8WWL.js} +1 -1
- package/page/index.html +15 -15
- package/ui/lib/tree-map-layout.d.ts +75 -0
- package/ui/lib/tree-map-layout.js +289 -0
- package/ui/tree-map.css +2 -0
- package/ui/tree-map.d.ts +10 -6
- package/ui/tree-map.js +55 -286
- package/page/assets/shaped-data-0GUF7Al3.js +0 -16
- package/page/assets/types-CMdljBjd.js +0 -1
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where each node of the tree map stands, closed and grown, and how far each node growing adds has
|
|
3
|
+
* drawn: the part of `tree-map.tsx` that is not drawing, so its motion can be checked without a page.
|
|
4
|
+
*
|
|
5
|
+
* invariant: Grown, every node keeps its place in its column's order and every gap stays a row or
|
|
6
|
+
* more, so no node passes through another on the way; a node growing adds shows only once nothing
|
|
7
|
+
* stands where it is.
|
|
8
|
+
*/
|
|
9
|
+
import { workspaceTree } from "../../mod.js";
|
|
10
|
+
/** A row's height closed, and grown. */
|
|
11
|
+
const ROW = 32;
|
|
12
|
+
const GROWN_ROW = 28;
|
|
13
|
+
/** How far in each level of the tree starts. */
|
|
14
|
+
export const INDENT = 28;
|
|
15
|
+
/** A token's half height. */
|
|
16
|
+
export const HALF = 11;
|
|
17
|
+
export const PAD = 16;
|
|
18
|
+
/** Between the tree's widest row and the feeds. */
|
|
19
|
+
const GAP = 72;
|
|
20
|
+
/** How many of the registry's tools sit under it closed: one of each type first. */
|
|
21
|
+
const SHOWN_TOOLS = 4;
|
|
22
|
+
const TOOL_TYPES = ['function', 'http', 'mcp', 'agent'];
|
|
23
|
+
/** Grown, between one agent's zone and the next. */
|
|
24
|
+
const AGENT_GAP = 16;
|
|
25
|
+
/** Grown, a turn's steps in rows under its runner, so many to a row. */
|
|
26
|
+
const STEPS_ACROSS = 3;
|
|
27
|
+
const STEP_SLOT = 160;
|
|
28
|
+
/** Grown, the registry's tools in columns this tall. */
|
|
29
|
+
const TOOLS_DOWN = 8;
|
|
30
|
+
const TOOL_SLOT = 210;
|
|
31
|
+
/** By how far grown every node has reached its zone; the rest is for drawing in. */
|
|
32
|
+
const MOVE_TO = 0.7;
|
|
33
|
+
/** Over what stretch of growing the added nodes draw, and how long each takes of it. */
|
|
34
|
+
const DRAW_FROM = 0.2;
|
|
35
|
+
const DRAW_TO = 0.95;
|
|
36
|
+
const DRAW_SPAN = 0.1;
|
|
37
|
+
/** How finely growing is walked to find where an added node first stands clear. */
|
|
38
|
+
const SAMPLES = 100;
|
|
39
|
+
/** Space kept clear round a token. */
|
|
40
|
+
const CLEAR = 2;
|
|
41
|
+
export const REGISTRY = 'tool-registry';
|
|
42
|
+
/**
|
|
43
|
+
* What a turn runner does in one turn, in order.
|
|
44
|
+
* why: The kernel contract's turn lifecycle (docs/contracts/kernel.md, "Turn lifecycle"), step for
|
|
45
|
+
* step; a decision and a session have no such list there, so their runners open into nothing.
|
|
46
|
+
*/
|
|
47
|
+
export const TURN_STEPS = [
|
|
48
|
+
{ id: 'resolve', label: 'Resolve' },
|
|
49
|
+
{ id: 'sanitize', label: 'Sanitize' },
|
|
50
|
+
{ id: 'compaction', label: 'Compaction' },
|
|
51
|
+
{ id: 'canary', label: 'Canary bind' },
|
|
52
|
+
{ id: 'pre_turn', label: 'pre_turn' },
|
|
53
|
+
{ id: 'stream', label: 'Provider stream' },
|
|
54
|
+
{ id: 'tools', label: 'Tool loop' },
|
|
55
|
+
{ id: 'before_end', label: 'before_end' },
|
|
56
|
+
{ id: 'validation', label: 'Validation' },
|
|
57
|
+
{ id: 'egress', label: 'Egress' },
|
|
58
|
+
{ id: 'trace', label: 'Trace' },
|
|
59
|
+
{ id: 'post_turn', label: 'post_turn' },
|
|
60
|
+
];
|
|
61
|
+
/** A row's token id: the tree's ids repeat from one agent to the next. */
|
|
62
|
+
export function rowId(row) {
|
|
63
|
+
return `${row.agent}/${row.node.id}`;
|
|
64
|
+
}
|
|
65
|
+
function rowsOf(workspace, only) {
|
|
66
|
+
const rows = [];
|
|
67
|
+
const walk = (node, agent, depth, parent) => {
|
|
68
|
+
const row = {
|
|
69
|
+
node,
|
|
70
|
+
agent,
|
|
71
|
+
x: PAD + depth * INDENT,
|
|
72
|
+
y: PAD + HALF + rows.length * ROW,
|
|
73
|
+
...(parent ? { parent: rowId(parent) } : {}),
|
|
74
|
+
};
|
|
75
|
+
rows.push(row);
|
|
76
|
+
for (const child of node.children)
|
|
77
|
+
walk(child, agent, depth + 1, row);
|
|
78
|
+
};
|
|
79
|
+
workspaceTree(workspace).agents.forEach((root, index) => {
|
|
80
|
+
const key = workspace.agents[index]?.key ?? '';
|
|
81
|
+
if (only === undefined || only.includes(key))
|
|
82
|
+
walk(root, key, 0);
|
|
83
|
+
});
|
|
84
|
+
return rows;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* What runs a profile of this type: `runDecision`, `runSession`, `runEmbedding`, else `runTurn`. A
|
|
88
|
+
* host has none of its own: the tool runner runs its calls.
|
|
89
|
+
*/
|
|
90
|
+
function runnerLabel(type) {
|
|
91
|
+
if (type === 'host')
|
|
92
|
+
return undefined;
|
|
93
|
+
if (type === 'decision')
|
|
94
|
+
return 'Decision runner';
|
|
95
|
+
if (type === 'live')
|
|
96
|
+
return 'Session runner';
|
|
97
|
+
if (type === 'embedding')
|
|
98
|
+
return 'Embedding runner';
|
|
99
|
+
return 'Turn runner';
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Each agent's runner (`runTurn`, or `runDecision` for a decision), beside its name; its providers,
|
|
103
|
+
* beside its models; and the workspace's tool registry, beside its Tools row, with the tool runner
|
|
104
|
+
* under it. A feed sits level with the middle of the rows it joins, or under the feed before it when
|
|
105
|
+
* that is lower. With `detail`, every tool and each turn runner's steps.
|
|
106
|
+
*/
|
|
107
|
+
function feedsOf(workspace, rows, detail) {
|
|
108
|
+
const feeds = [];
|
|
109
|
+
const add = (feed, into = [], depth = 0) => {
|
|
110
|
+
const below = (feeds.at(-1)?.y ?? Number.NEGATIVE_INFINITY) + ROW;
|
|
111
|
+
const middle = into.length ? into.reduce((sum, row) => sum + row.y, 0) / into.length : below;
|
|
112
|
+
feeds.push({ ...feed, y: Math.max(middle, below), into: into.map(rowId), depth });
|
|
113
|
+
};
|
|
114
|
+
for (const agent of workspace.agents) {
|
|
115
|
+
const mine = rows.filter((row) => row.agent === agent.key);
|
|
116
|
+
const name = mine.find((row) => row.node.ref.facet === 'identity');
|
|
117
|
+
if (!name)
|
|
118
|
+
continue;
|
|
119
|
+
const runner = runnerLabel(agent.identity.profileType);
|
|
120
|
+
if (runner) {
|
|
121
|
+
const id = `${agent.key}/runner`;
|
|
122
|
+
add({ id, label: runner, kind: 'runner', agent: agent.key }, [name]);
|
|
123
|
+
const steps = detail && runner === 'Turn runner' ? TURN_STEPS : [];
|
|
124
|
+
for (const step of steps) {
|
|
125
|
+
const of = step.id;
|
|
126
|
+
add({ id: `${id}/${of}`, label: step.label, kind: 'step', agent: agent.key, of, under: id }, [], 1);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const providers = new Map();
|
|
130
|
+
for (const binding of agent.modelBindings) {
|
|
131
|
+
const row = mine.find((each) => each.node.ref.facet === 'modelBinding' && each.node.ref.key === binding.key);
|
|
132
|
+
if (row)
|
|
133
|
+
providers.set(binding.provider, [...(providers.get(binding.provider) ?? []), row]);
|
|
134
|
+
}
|
|
135
|
+
for (const [provider, into] of providers) {
|
|
136
|
+
const id = `${agent.key}/provider:${provider}`;
|
|
137
|
+
add({ id, label: provider, kind: 'provider', agent: agent.key }, into);
|
|
138
|
+
}
|
|
139
|
+
// The workspace's tools are one registry that each agent's tool policy picks from: drawn once,
|
|
140
|
+
// beside the first Tools row, with a line into every other.
|
|
141
|
+
const tools = mine.find((row) => row.node.ref.facet === 'tools');
|
|
142
|
+
const drawn = feeds.find((feed) => feed.id === REGISTRY);
|
|
143
|
+
if (tools && drawn)
|
|
144
|
+
drawn.into.push(rowId(tools));
|
|
145
|
+
else if (tools && workspace.toolSpecs.length > 0) {
|
|
146
|
+
add({ id: REGISTRY, label: 'Tool registry', kind: 'registry', agent: agent.key }, [tools]);
|
|
147
|
+
for (const tool of listedTools(workspace.toolSpecs, detail)) {
|
|
148
|
+
const id = `${REGISTRY}/${tool.key}`;
|
|
149
|
+
const feed = { id, label: tool.toolName, kind: 'tool', agent: agent.key };
|
|
150
|
+
add({ ...feed, of: tool.toolType, under: REGISTRY }, [], 1);
|
|
151
|
+
}
|
|
152
|
+
const runs = { id: 'tool-runner', label: 'Tool runner', kind: 'tool-runner' };
|
|
153
|
+
add({ ...runs, agent: agent.key, under: REGISTRY });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return feeds;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* The registry's tools: the first of each type, then the rest in the registry's order. A few of
|
|
160
|
+
* them, or with `detail` every one.
|
|
161
|
+
*/
|
|
162
|
+
function listedTools(tools, detail) {
|
|
163
|
+
const firsts = TOOL_TYPES.flatMap((type) => {
|
|
164
|
+
const tool = tools.find((each) => each.toolType === type);
|
|
165
|
+
return tool ? [tool] : [];
|
|
166
|
+
});
|
|
167
|
+
const rest = tools.filter((tool) => !firsts.includes(tool));
|
|
168
|
+
const listed = [...firsts, ...rest];
|
|
169
|
+
return detail ? listed : listed.slice(0, SHOWN_TOOLS);
|
|
170
|
+
}
|
|
171
|
+
const clamp = (value) => Math.min(Math.max(value, 0), 1);
|
|
172
|
+
const between = (from, to, at) => from + (to - from) * at;
|
|
173
|
+
/** Every other one from each list, while both last: the turn's steps and the tools draw by turns. */
|
|
174
|
+
function byTurns(first, second) {
|
|
175
|
+
return Array.from({ length: Math.max(first.length, second.length) }, (_, index) => [first[index], second[index]].filter((each) => each !== undefined)).flat();
|
|
176
|
+
}
|
|
177
|
+
/** A step under its runner in rows so many across; a tool under the registry in columns. */
|
|
178
|
+
function slotsOf(feeds) {
|
|
179
|
+
const slots = new Map();
|
|
180
|
+
const counts = new Map();
|
|
181
|
+
for (const feed of feeds) {
|
|
182
|
+
if (feed.under === undefined || feed.depth === 0)
|
|
183
|
+
continue;
|
|
184
|
+
const index = counts.get(feed.under) ?? 0;
|
|
185
|
+
counts.set(feed.under, index + 1);
|
|
186
|
+
const slot = feed.kind === 'tool'
|
|
187
|
+
? { across: Math.floor(index / TOOLS_DOWN) * TOOL_SLOT, down: (index % TOOLS_DOWN) + 1 }
|
|
188
|
+
: {
|
|
189
|
+
across: (index % STEPS_ACROSS) * STEP_SLOT,
|
|
190
|
+
down: Math.floor(index / STEPS_ACROSS) + 1,
|
|
191
|
+
};
|
|
192
|
+
slots.set(feed.id, { holder: feed.under, across: INDENT + slot.across, down: slot.down });
|
|
193
|
+
}
|
|
194
|
+
return slots;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* The column grown: each agent a zone of its own, its rows restacked and its feeds in their order,
|
|
198
|
+
* each level with its rows or under the room the one before it holds for its own.
|
|
199
|
+
*/
|
|
200
|
+
function grownColumn(rows, feeds, slots, feedX) {
|
|
201
|
+
const places = new Map();
|
|
202
|
+
const held = new Map();
|
|
203
|
+
for (const slot of slots.values()) {
|
|
204
|
+
held.set(slot.holder, Math.max(held.get(slot.holder) ?? 0, slot.down));
|
|
205
|
+
}
|
|
206
|
+
let top = PAD + HALF;
|
|
207
|
+
for (const agent of new Set(rows.map((row) => row.agent))) {
|
|
208
|
+
const mine = rows.filter((row) => row.agent === agent);
|
|
209
|
+
mine.forEach((row, index) => {
|
|
210
|
+
places.set(rowId(row), { x: row.x, y: top + index * GROWN_ROW });
|
|
211
|
+
});
|
|
212
|
+
let cursor = top;
|
|
213
|
+
for (const feed of feeds) {
|
|
214
|
+
if (feed.agent !== agent || slots.has(feed.id))
|
|
215
|
+
continue;
|
|
216
|
+
const level = feed.into.flatMap((id) => places.get(id)?.y ?? []);
|
|
217
|
+
const middle = level.length ? level.reduce((sum, y) => sum + y, 0) / level.length : cursor;
|
|
218
|
+
const y = Math.max(middle, cursor);
|
|
219
|
+
places.set(feed.id, { x: feedX, y });
|
|
220
|
+
cursor = y + GROWN_ROW * (1 + (held.get(feed.id) ?? 0));
|
|
221
|
+
}
|
|
222
|
+
top = Math.max(top + mine.length * GROWN_ROW, cursor) + AGENT_GAP;
|
|
223
|
+
}
|
|
224
|
+
return places;
|
|
225
|
+
}
|
|
226
|
+
/** Where a node stands this far grown: a node under a feed keeps its slot under it on the way. */
|
|
227
|
+
export function placeAt(layout, id, grow) {
|
|
228
|
+
const moved = clamp(grow / MOVE_TO);
|
|
229
|
+
const slot = layout.slots.get(id);
|
|
230
|
+
if (slot) {
|
|
231
|
+
const holder = placeAt(layout, slot.holder, grow);
|
|
232
|
+
return { x: holder.x + slot.across, y: holder.y + slot.down * between(ROW, GROWN_ROW, moved) };
|
|
233
|
+
}
|
|
234
|
+
const to = layout.grown.get(id) ?? { x: 0, y: 0 };
|
|
235
|
+
const from = layout.closed.get(id) ?? to;
|
|
236
|
+
return { x: between(from.x, to.x, moved), y: between(from.y, to.y, moved) };
|
|
237
|
+
}
|
|
238
|
+
/** How far a node growing adds has drawn, 0 to 1; undefined for one the map shows closed. */
|
|
239
|
+
export function drawnAt(layout, id, grow) {
|
|
240
|
+
const start = layout.starts.get(id);
|
|
241
|
+
return start === undefined ? undefined : clamp((grow - start) / DRAW_SPAN);
|
|
242
|
+
}
|
|
243
|
+
/** Whether two tokens, at their left sides and middles, touch. */
|
|
244
|
+
function touching(a, aWidth, b, bWidth) {
|
|
245
|
+
return (a.x < b.x + bWidth + CLEAR &&
|
|
246
|
+
b.x < a.x + aWidth + CLEAR &&
|
|
247
|
+
Math.abs(a.y - b.y) < 2 * HALF + CLEAR);
|
|
248
|
+
}
|
|
249
|
+
/** The least growing from which a node stands clear of every other, all the way grown. */
|
|
250
|
+
function clearFrom(layout, id, ids, width) {
|
|
251
|
+
for (let step = SAMPLES; step >= 0; step -= 1) {
|
|
252
|
+
const grow = step / SAMPLES;
|
|
253
|
+
const place = placeAt(layout, id, grow);
|
|
254
|
+
const hit = ids.some((other) => other !== id && touching(place, width(id), placeAt(layout, other, grow), width(other)));
|
|
255
|
+
if (hit)
|
|
256
|
+
return (step + 1) / SAMPLES;
|
|
257
|
+
}
|
|
258
|
+
return 0;
|
|
259
|
+
}
|
|
260
|
+
/** The tree and what feeds it, closed and grown, for tokens this wide. */
|
|
261
|
+
export function treeMapLayout(workspace, agents, width) {
|
|
262
|
+
const rows = rowsOf(workspace, agents);
|
|
263
|
+
const fewFeeds = feedsOf(workspace, rows, false);
|
|
264
|
+
const few = new Set(fewFeeds.map((feed) => feed.id));
|
|
265
|
+
const feeds = feedsOf(workspace, rows, true);
|
|
266
|
+
const feedX = Math.max(0, ...rows.map((row) => row.x + width(rowId(row)))) + GAP;
|
|
267
|
+
const closed = new Map(rows.map((row) => [rowId(row), row]));
|
|
268
|
+
for (const feed of fewFeeds)
|
|
269
|
+
closed.set(feed.id, { x: feedX + feed.depth * INDENT, y: feed.y });
|
|
270
|
+
const slots = slotsOf(feeds);
|
|
271
|
+
const layout = {
|
|
272
|
+
rows,
|
|
273
|
+
feeds,
|
|
274
|
+
few,
|
|
275
|
+
closed,
|
|
276
|
+
grown: grownColumn(rows, feeds, slots, feedX),
|
|
277
|
+
slots,
|
|
278
|
+
starts: new Map(),
|
|
279
|
+
};
|
|
280
|
+
// What growing adds draws in order, the turn's steps and the tools by turns, each once it stands clear.
|
|
281
|
+
const added = feeds.filter((feed) => !few.has(feed.id));
|
|
282
|
+
const order = byTurns(added.filter((feed) => feed.under !== REGISTRY), added.filter((feed) => feed.under === REGISTRY));
|
|
283
|
+
const ids = [...rows.map(rowId), ...feeds.map((feed) => feed.id)];
|
|
284
|
+
order.forEach((feed, index) => {
|
|
285
|
+
const turn = DRAW_FROM + ((DRAW_TO - DRAW_SPAN - DRAW_FROM) * index) / Math.max(order.length - 1, 1);
|
|
286
|
+
layout.starts.set(feed.id, Math.max(turn, clearFrom(layout, feed.id, ids, width)));
|
|
287
|
+
});
|
|
288
|
+
return layout;
|
|
289
|
+
}
|
package/ui/tree-map.css
CHANGED
package/ui/tree-map.d.ts
CHANGED
|
@@ -4,12 +4,16 @@ export interface StudioTreeMapProps {
|
|
|
4
4
|
/** The keys of the agents to draw, in the workspace's order; every agent when unset. */
|
|
5
5
|
agents?: readonly string[] | undefined;
|
|
6
6
|
/**
|
|
7
|
-
* How far the tree has grown, from 0 to 1. As it grows each
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* each
|
|
11
|
-
* runner, and every tool in the registry. Shrinking takes it all back the same way.
|
|
7
|
+
* How far the tree has grown, from 0 to 1. As it grows each agent drifts into a zone of its own,
|
|
8
|
+
* its runner and providers level with its rows, and room opens under each feed for its own. What
|
|
9
|
+
* growing adds draws in as its room opens, its line and then its token: the steps of a turn under
|
|
10
|
+
* each turn runner, and every tool in the registry. Shrinking takes it all back the same way.
|
|
12
11
|
*/
|
|
13
12
|
grow?: number | undefined;
|
|
13
|
+
/** The box the map fits grown: growing, it eases smaller until all of it fits. */
|
|
14
|
+
fit?: {
|
|
15
|
+
width: number;
|
|
16
|
+
height: number;
|
|
17
|
+
} | undefined;
|
|
14
18
|
}
|
|
15
|
-
export declare function StudioTreeMap({ workspace, agents, grow }: StudioTreeMapProps): import("react").JSX.Element;
|
|
19
|
+
export declare function StudioTreeMap({ workspace, agents, grow, fit }: StudioTreeMapProps): import("react").JSX.Element;
|