@mcp-b/react-components 0.20.5 → 0.21.0
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/dist/{AgentActivity-D2SHSGFX.d.ts → AgentActivity-D3OvrC02.d.ts} +14 -1
- package/dist/{AgentChat-C-ZyXbJz.d.ts → AgentChat-Dvkn8lce.d.ts} +23 -0
- package/dist/AgentChatStartScreen-CvXJBr4y.d.ts +57 -0
- package/dist/{ModelSelector-pecWyOFI.js → ModelSelector-CEd8M9eK.js} +14 -7
- package/dist/{ThinkChatActivity-CdbL0aoA.d.ts → ThinkChatActivity-FY1VWXgh.d.ts} +8 -7
- package/dist/{ThinkChatActivitySummary-D1xOrNrq.d.ts → ThinkChatActivitySummary-kr5fE0wg.d.ts} +14 -5
- package/dist/{ToggleGroup-DNd6cDJZ.d.ts → ToggleGroup-BW1jrhAF.d.ts} +10 -0
- package/dist/components/Activity.d.ts +33 -17
- package/dist/components/Activity.js +39 -27
- package/dist/components/AgentActivity.d.ts +1 -1
- package/dist/components/AgentActivityPreview.d.ts +1 -1
- package/dist/components/AgentActivityPreview.js +2 -2
- package/dist/components/AgentChat.d.ts +1 -1
- package/dist/components/AgentChat.js +142 -129
- package/dist/components/AgentChatStartScreen.d.ts +2 -0
- package/dist/components/AgentChatStartScreen.js +82 -0
- package/dist/components/Approval.js +2 -4
- package/dist/components/BrowserLiveView.js +5 -7
- package/dist/components/BrowserReplay.js +5 -4
- package/dist/components/BrowserRunPanel.js +1 -1
- package/dist/components/ChatGptSignInScreen.js +1 -1
- package/dist/components/Conversation.d.ts +1 -22
- package/dist/components/Conversation.js +2 -29
- package/dist/components/EmptyState.d.ts +46 -0
- package/dist/components/EmptyState.js +50 -0
- package/dist/components/Kbd.d.ts +32 -0
- package/dist/components/Kbd.js +34 -0
- package/dist/components/ModelSelector.d.ts +10 -4
- package/dist/components/ModelSelector.js +2 -2
- package/dist/components/PricingBillingToggle.js +1 -0
- package/dist/components/PromptInput.js +3 -2
- package/dist/components/Reasoning.js +1 -1
- package/dist/components/StatusPill.d.ts +43 -0
- package/dist/components/StatusPill.js +35 -0
- package/dist/components/ThinkChat.d.ts +9 -3
- package/dist/components/ThinkChatActivity.d.ts +2 -2
- package/dist/components/ThinkChatActivity.js +27 -15
- package/dist/components/ThinkChatActivitySummary.d.ts +2 -2
- package/dist/components/ThinkChatActivitySummary.js +67 -64
- package/dist/components/ThinkExecutionDetail.js +4 -4
- package/dist/components/ThinkExecutionWorkbench.js +5 -4
- package/dist/components/ThinkFullAppViewSwitch.d.ts +1 -1
- package/dist/components/ThinkRoutineBrowser.js +1 -0
- package/dist/components/ThinkRoutineRuns.js +3 -2
- package/dist/components/ThinkThreadPicker.js +3 -2
- package/dist/components/ToggleGroup.d.ts +1 -1
- package/dist/components/ToggleGroup.js +54 -7
- package/dist/components/ToolInvocation.js +1 -1
- package/dist/styles/activity-header.css +41 -10
- package/dist/styles/activity.css +26 -4
- package/dist/styles/agent-activity-preview-overlay.css +39 -12
- package/dist/styles/agent-activity-preview.css +31 -30
- package/dist/styles/agent-attention.css +2 -2
- package/dist/styles/agent-chat.css +199 -0
- package/dist/styles/agent-connection.css +8 -8
- package/dist/styles/alert-dialog.css +5 -2
- package/dist/styles/app-top-bar.css +4 -4
- package/dist/styles/approval.css +1 -7
- package/dist/styles/artifact.css +4 -4
- package/dist/styles/base-ui-motion.css +1 -1
- package/dist/styles/base.css +95 -3
- package/dist/styles/browser-control-overlay.css +16 -7
- package/dist/styles/browser-live-view.css +5 -38
- package/dist/styles/browser-replay.css +2 -6
- package/dist/styles/browser-run-panel.css +4 -18
- package/dist/styles/button.css +3 -1
- package/dist/styles/card.css +4 -4
- package/dist/styles/chain-of-thought.css +0 -1
- package/dist/styles/chatgpt-sign-in-screen.css +7 -5
- package/dist/styles/checkbox-group.css +3 -3
- package/dist/styles/code-block.css +4 -4
- package/dist/styles/context-menu.css +1 -1
- package/dist/styles/conversation.css +7 -42
- package/dist/styles/description-list.css +2 -2
- package/dist/styles/dialog.css +17 -2
- package/dist/styles/empty-state.css +48 -0
- package/dist/styles/environment-variables.css +4 -4
- package/dist/styles/field.css +2 -2
- package/dist/styles/index.css +3 -0
- package/dist/styles/inline-citation.css +1 -1
- package/dist/styles/kbd.css +40 -0
- package/dist/styles/media-preview-card.css +5 -3
- package/dist/styles/message-scroller.css +4 -4
- package/dist/styles/message.css +4 -6
- package/dist/styles/model-selector.css +5 -8
- package/dist/styles/popover.css +1 -1
- package/dist/styles/preview-card.css +1 -1
- package/dist/styles/prompt-input.css +18 -40
- package/dist/styles/queue.css +2 -2
- package/dist/styles/recipes.css +68 -9
- package/dist/styles/resizable-side-panel.css +1 -1
- package/dist/styles/responsive-sidebar-shell.css +5 -6
- package/dist/styles/scrollbars.css +32 -3
- package/dist/styles/sources.css +1 -1
- package/dist/styles/status-pill.css +39 -0
- package/dist/styles/stepper.css +2 -2
- package/dist/styles/streamdown.css +13 -12
- package/dist/styles/subagent-run.css +3 -3
- package/dist/styles/switch.css +1 -3
- package/dist/styles/tabs.css +1 -1
- package/dist/styles/task.css +1 -1
- package/dist/styles/terminal.css +2 -2
- package/dist/styles/test-results.css +1 -2
- package/dist/styles/textarea.css +1 -1
- package/dist/styles/theme-mode-control.css +1 -1
- package/dist/styles/think-execution-status.css +4 -23
- package/dist/styles/think-execution-workbench.css +2 -3
- package/dist/styles/think-full-app.css +2 -2
- package/dist/styles/think-routine-library.css +14 -16
- package/dist/styles/think-thread-picker.css +8 -25
- package/dist/styles/toast.css +2 -2
- package/dist/styles/toggle-group.css +76 -3
- package/dist/styles/tooltip.css +1 -2
- package/dist/styles/utilities.css +73 -0
- package/dist/styles/workspace-explorer.css +4 -6
- package/package.json +2 -2
|
@@ -3,12 +3,22 @@ import { displayUrl, getToolDisplayName, isBrowserToolPart, isExecuteToolPart, i
|
|
|
3
3
|
import { t as summarizeToolInput } from "../summarize-tool-input-CqTcGRYy.js";
|
|
4
4
|
import { getToolName, isReasoningUIPart, isToolUIPart } from "ai";
|
|
5
5
|
//#region src/components/ThinkChatActivitySummary.ts
|
|
6
|
+
function described(action, detail) {
|
|
7
|
+
return detail ? {
|
|
8
|
+
action,
|
|
9
|
+
detail
|
|
10
|
+
} : { action };
|
|
11
|
+
}
|
|
6
12
|
const ACTIVITY_HEADER_LABEL_MAX_LENGTH = 240;
|
|
13
|
+
function bounded(text) {
|
|
14
|
+
if (text.length <= ACTIVITY_HEADER_LABEL_MAX_LENGTH) return text;
|
|
15
|
+
return `${text.slice(0, ACTIVITY_HEADER_LABEL_MAX_LENGTH - 1).trimEnd()}…`;
|
|
16
|
+
}
|
|
7
17
|
function boundedActivityHeader(header) {
|
|
8
|
-
if (header.label.length <= ACTIVITY_HEADER_LABEL_MAX_LENGTH) return header;
|
|
9
18
|
return {
|
|
10
19
|
...header,
|
|
11
|
-
|
|
20
|
+
action: bounded(header.action),
|
|
21
|
+
...header.detail ? { detail: bounded(header.detail) } : {}
|
|
12
22
|
};
|
|
13
23
|
}
|
|
14
24
|
function getToolInput(part) {
|
|
@@ -100,9 +110,7 @@ function genericToolPresentation(part, hasUrl) {
|
|
|
100
110
|
}
|
|
101
111
|
function describeGenericToolPart(part) {
|
|
102
112
|
const labels = genericToolPresentation(part, activityPartUrl(part) !== null);
|
|
103
|
-
|
|
104
|
-
const detail = summarizeToolInput(getToolInput(part));
|
|
105
|
-
return detail ? `${label} · ${detail}` : label;
|
|
113
|
+
return described(isPartFailed(part) ? labels.failed : isPartWorking(part) ? labels.working : labels.done, summarizeToolInput(getToolInput(part)));
|
|
106
114
|
}
|
|
107
115
|
function activityPartUrl(part) {
|
|
108
116
|
if (isFetchToolPart(part)) return firstHttpUrl(part.input?.url ?? part.input?.path);
|
|
@@ -151,7 +159,7 @@ function activityPartWorkspaceDestination(part) {
|
|
|
151
159
|
}
|
|
152
160
|
}
|
|
153
161
|
/**
|
|
154
|
-
* One-line natural-language
|
|
162
|
+
* One-line natural-language action for an activity part ("Ran vp test",
|
|
155
163
|
* "Fetched developers.cloudflare.com/agents/"); `null` for boundaries that
|
|
156
164
|
* aren't steps (step-start). Exported so a custom `renderPart` can reuse the
|
|
157
165
|
* built-in labels for tools it doesn't override.
|
|
@@ -159,12 +167,12 @@ function activityPartWorkspaceDestination(part) {
|
|
|
159
167
|
function describeThinkChatActivityPart(part, toolRenderers) {
|
|
160
168
|
if (isToolUIPart(part)) {
|
|
161
169
|
const custom = toolRenderers?.[getToolName(part)]?.describe?.(part);
|
|
162
|
-
if (custom !== void 0) return custom;
|
|
170
|
+
if (custom !== void 0) return custom ?? null;
|
|
163
171
|
}
|
|
164
172
|
if (isReasoningUIPart(part)) {
|
|
165
173
|
const snippet = summarizeReasoningTitle(part.text);
|
|
166
|
-
const
|
|
167
|
-
return snippet ??
|
|
174
|
+
const action = part.state === "streaming" ? "Thinking…" : "Thought";
|
|
175
|
+
return described(snippet ?? action);
|
|
168
176
|
}
|
|
169
177
|
if (isWorkspaceToolPart(part)) return describeWorkspaceToolPart(part);
|
|
170
178
|
if (isSkillToolPart(part)) return describeSkillToolPart(part);
|
|
@@ -183,88 +191,83 @@ function describeWorkspaceToolPart(part) {
|
|
|
183
191
|
const failed = isPartFailed(part);
|
|
184
192
|
if (part.type === "tool-bash") {
|
|
185
193
|
const command = part.input?.script?.trim() ?? "";
|
|
186
|
-
if (failed) return
|
|
194
|
+
if (failed) return described("Command failed", command);
|
|
187
195
|
const verb = working ? "Running" : "Ran";
|
|
188
|
-
return command ?
|
|
196
|
+
return command ? described(verb, command) : described(`${verb} a command`);
|
|
189
197
|
}
|
|
190
|
-
const
|
|
198
|
+
const { action, detail } = (() => {
|
|
191
199
|
switch (part.type) {
|
|
192
|
-
case "tool-read": return
|
|
193
|
-
case "tool-write": return
|
|
194
|
-
case "tool-edit": return
|
|
195
|
-
case "tool-delete": return
|
|
200
|
+
case "tool-read": return described(working ? "Reading" : "Read", basename(part.input?.path) ?? "a file");
|
|
201
|
+
case "tool-write": return described(working ? "Writing" : "Wrote", basename(part.input?.path) ?? "a file");
|
|
202
|
+
case "tool-edit": return described(working ? "Editing" : "Edited", basename(part.input?.path) ?? "a file");
|
|
203
|
+
case "tool-delete": return described(working ? "Deleting" : "Deleted", part.input?.path || "a file");
|
|
196
204
|
case "tool-list": {
|
|
197
205
|
const path = part.input?.path;
|
|
198
|
-
return
|
|
206
|
+
return described(working ? "Listing" : "Listed", path && path !== "/" ? path : "files");
|
|
199
207
|
}
|
|
200
|
-
case "tool-find": return
|
|
201
|
-
case "tool-grep": return
|
|
208
|
+
case "tool-find": return described(working ? "Searching" : "Searched", `for ${part.input?.pattern || "files"}`);
|
|
209
|
+
case "tool-grep": return described(working ? "Searching" : "Searched", `for ${part.input?.query || "text"}`);
|
|
202
210
|
}
|
|
203
211
|
})();
|
|
204
|
-
return failed ? `${
|
|
212
|
+
return failed ? described(`${action} ${detail ?? ""}`.trim() + " · failed") : described(action, detail);
|
|
205
213
|
}
|
|
206
214
|
function describeSkillToolPart(part) {
|
|
207
215
|
const working = isPartWorking(part);
|
|
208
216
|
const failed = isPartFailed(part);
|
|
209
|
-
const
|
|
217
|
+
const { action, detail } = (() => {
|
|
210
218
|
switch (part.type) {
|
|
211
219
|
case "tool-activate_skill": {
|
|
212
220
|
const name = part.input?.name;
|
|
213
|
-
return
|
|
221
|
+
return described(working ? "Using" : "Used", name ? `the ${name} skill` : "a skill");
|
|
214
222
|
}
|
|
215
|
-
case "tool-read_skill_resource": return
|
|
216
|
-
case "tool-run_skill_script": return
|
|
223
|
+
case "tool-read_skill_resource": return described(working ? "Reading" : "Read", part.input?.path ?? "a skill resource");
|
|
224
|
+
case "tool-run_skill_script": return described(working ? "Running" : "Ran", part.input?.path ?? "a skill script");
|
|
217
225
|
}
|
|
218
226
|
})();
|
|
219
|
-
return failed ? `${
|
|
227
|
+
return failed ? described(`${action} ${detail ?? ""}`.trim() + " · failed") : described(action, detail);
|
|
220
228
|
}
|
|
221
229
|
function describeSessionContextToolPart(part) {
|
|
222
230
|
const working = isPartWorking(part);
|
|
223
231
|
const failed = isSessionContextToolFailure(part);
|
|
224
|
-
const
|
|
232
|
+
const { action, detail } = (() => {
|
|
225
233
|
switch (part.type) {
|
|
226
|
-
case "tool-set_context":
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
case "tool-
|
|
231
|
-
case "tool-unload_context": return `${working ? "Unloading" : "Unloaded"} ${part.input?.key ?? "context"}`;
|
|
232
|
-
case "tool-search_context": return `${working ? "Searching" : "Searched"} ${part.input?.label ?? "context"}`;
|
|
233
|
-
case "tool-session_search": return `${working ? "Searching" : "Searched"} conversations`;
|
|
234
|
+
case "tool-set_context": return described(working ? "Updating" : "Updated", part.input?.label || "context");
|
|
235
|
+
case "tool-load_context": return described(working ? "Loading" : "Loaded", part.input?.key ?? "context");
|
|
236
|
+
case "tool-unload_context": return described(working ? "Unloading" : "Unloaded", part.input?.key ?? "context");
|
|
237
|
+
case "tool-search_context": return described(working ? "Searching" : "Searched", part.input?.label ?? "context");
|
|
238
|
+
case "tool-session_search": return described(working ? "Searching" : "Searched", "conversations");
|
|
234
239
|
}
|
|
235
240
|
})();
|
|
236
|
-
return failed ? `${
|
|
241
|
+
return failed ? described(`${action} ${detail ?? ""}`.trim() + " · failed") : described(action, detail);
|
|
237
242
|
}
|
|
238
243
|
function describeBrowserToolPart(part) {
|
|
239
244
|
const working = isPartWorking(part);
|
|
240
245
|
const failed = isPartFailed(part);
|
|
241
246
|
if (part.type === "tool-browser_execute") {
|
|
242
247
|
const output = part.state === "output-available" ? part.output : void 0;
|
|
243
|
-
if (failed || output?.status === "error") return "Browser automation failed";
|
|
244
|
-
if (output?.status === "paused") return isHumanWaitPause(output) ? "Browser waiting for human" : "Browser waiting for approval";
|
|
245
|
-
return working ? "Using the browser" : "Used the browser";
|
|
248
|
+
if (failed || output?.status === "error") return described("Browser automation failed");
|
|
249
|
+
if (output?.status === "paused") return described(isHumanWaitPause(output) ? "Browser waiting for human" : "Browser waiting for approval");
|
|
250
|
+
return described(working ? "Using the browser" : "Used the browser");
|
|
246
251
|
}
|
|
247
252
|
const page = displayUrl(part.input?.url) || "a page";
|
|
248
|
-
const
|
|
253
|
+
const { action, detail } = (() => {
|
|
249
254
|
switch (part.type) {
|
|
250
|
-
case "tool-browser_extract": return
|
|
251
|
-
case "tool-browser_links": return
|
|
252
|
-
case "tool-browser_scrape": return
|
|
253
|
-
default: return
|
|
255
|
+
case "tool-browser_extract": return described(working ? "Extracting data" : "Extracted data", `from ${page}`);
|
|
256
|
+
case "tool-browser_links": return described(working ? "Listing links" : "Listed links", `on ${page}`);
|
|
257
|
+
case "tool-browser_scrape": return described(working ? "Scraping" : "Scraped", page);
|
|
258
|
+
default: return described(working ? "Browsing" : "Browsed", page);
|
|
254
259
|
}
|
|
255
260
|
})();
|
|
256
|
-
return failed ? `${
|
|
261
|
+
return failed ? described(`${action} ${detail ?? ""}`.trim() + " · failed") : described(action, detail);
|
|
257
262
|
}
|
|
258
263
|
function describeExecuteToolPart(part) {
|
|
259
264
|
const output = part.state === "output-available" ? part.output : void 0;
|
|
260
|
-
if (output?.status === "paused") return isHumanWaitPause(output) ? "Code waiting for human" : "Code waiting for approval";
|
|
265
|
+
if (output?.status === "paused") return described(isHumanWaitPause(output) ? "Code waiting for human" : "Code waiting for approval");
|
|
261
266
|
const explicitSummary = part.input ? Reflect.get(part.input, "summary") : void 0;
|
|
262
267
|
const summary = typeof explicitSummary === "string" ? summarizeToolInput({ summary: explicitSummary }) : null;
|
|
263
|
-
if (summary) return summary;
|
|
264
|
-
if (isPartFailed(part) || output?.status === "error") return "Code failed";
|
|
265
|
-
|
|
266
|
-
const snippet = summarizeToolInput(part.input);
|
|
267
|
-
return snippet ? `${label} · ${snippet}` : label;
|
|
268
|
+
if (summary) return described(summary);
|
|
269
|
+
if (isPartFailed(part) || output?.status === "error") return described("Code failed");
|
|
270
|
+
return described(isPartWorking(part) ? "Running code" : "Ran code", summarizeToolInput(part.input));
|
|
268
271
|
}
|
|
269
272
|
function summarizeReasoningTitle(text) {
|
|
270
273
|
const line = text.split("\n").find((candidate) => candidate.trim())?.trim();
|
|
@@ -279,9 +282,9 @@ function isHumanWaitPause(output) {
|
|
|
279
282
|
function describeFetchToolPart(part) {
|
|
280
283
|
const target = part.input?.url ?? part.input?.path ?? "";
|
|
281
284
|
const output = part.state === "output-available" ? part.output : void 0;
|
|
282
|
-
if (isPartFailed(part) || output?.ok === false) return
|
|
285
|
+
if (isPartFailed(part) || output?.ok === false) return described("Fetch failed", target);
|
|
283
286
|
const verb = isPartWorking(part) ? "Fetching" : "Fetched";
|
|
284
|
-
return target ?
|
|
287
|
+
return target ? described(verb, target) : described(`${verb} a URL`);
|
|
285
288
|
}
|
|
286
289
|
function summarizeActivitySteps(parts) {
|
|
287
290
|
const byTool = /* @__PURE__ */ new Map();
|
|
@@ -344,38 +347,38 @@ function summarizeActivitySteps(parts) {
|
|
|
344
347
|
}
|
|
345
348
|
/** Derive the serializable collapsed header from persisted AI SDK message parts. */
|
|
346
349
|
function deriveThinkChatActivityHeader(parts, options = {}) {
|
|
347
|
-
const
|
|
348
|
-
const
|
|
349
|
-
return
|
|
350
|
-
|
|
350
|
+
const steps = parts.flatMap((part) => {
|
|
351
|
+
const description = describeThinkChatActivityPart(part, options.toolDescribers);
|
|
352
|
+
return description ? [{
|
|
353
|
+
description,
|
|
351
354
|
part
|
|
352
355
|
}] : [];
|
|
353
356
|
});
|
|
354
|
-
if (
|
|
357
|
+
if (steps.length === 0) return null;
|
|
355
358
|
if (options.isStreaming ?? parts.some(isPartWorking)) {
|
|
356
|
-
const latest =
|
|
359
|
+
const latest = steps.at(-1);
|
|
357
360
|
const workspaceDestination = activityPartWorkspaceDestination(latest.part);
|
|
358
361
|
return boundedActivityHeader({
|
|
359
|
-
|
|
362
|
+
...latest.description,
|
|
360
363
|
iconKind: activityPartIconKind(latest.part),
|
|
361
364
|
...activityPartUrl(latest.part) ? { url: activityPartUrl(latest.part) } : {},
|
|
362
365
|
...workspaceDestination ? { workspaceDestination } : {}
|
|
363
366
|
});
|
|
364
367
|
}
|
|
365
368
|
if (parts.some((part) => isToolUIPart(part) && isPartFailed(part))) return boundedActivityHeader({
|
|
366
|
-
|
|
369
|
+
action: summarizeActivitySteps(parts),
|
|
367
370
|
iconKind: "approval"
|
|
368
371
|
});
|
|
369
372
|
const workspaceRepresentative = parts.find((part) => activityPartIconKind(part) === "edit" && activityPartWorkspaceDestination(part)) ?? parts.find((part) => activityPartWorkspaceDestination(part));
|
|
370
373
|
const workspaceDestination = workspaceRepresentative ? activityPartWorkspaceDestination(workspaceRepresentative) : null;
|
|
371
374
|
const representative = parts.find((part) => activityPartIconKind(part) === "edit") ?? parts.find((part) => activityPartUrl(part)) ?? parts.find((part) => describeThinkChatActivityPart(part));
|
|
372
375
|
if (!representative) return boundedActivityHeader({
|
|
373
|
-
|
|
376
|
+
action: summarizeActivitySteps(parts),
|
|
374
377
|
iconKind: "tool"
|
|
375
378
|
});
|
|
376
379
|
const url = activityPartUrl(representative);
|
|
377
380
|
return boundedActivityHeader({
|
|
378
|
-
|
|
381
|
+
action: summarizeActivitySteps(parts),
|
|
379
382
|
iconKind: activityPartIconKind(representative),
|
|
380
383
|
...url ? { url } : {},
|
|
381
384
|
...workspaceDestination ? { workspaceDestination } : {}
|
|
@@ -387,14 +390,14 @@ function deriveThinkChatActivityHeader(parts, options = {}) {
|
|
|
387
390
|
*/
|
|
388
391
|
function deriveThinkChatToolLifecycleHeader(snapshot) {
|
|
389
392
|
if (snapshot.state === "approval-required") return boundedActivityHeader({
|
|
390
|
-
|
|
393
|
+
action: "Approval needed",
|
|
391
394
|
iconKind: "approval"
|
|
392
395
|
});
|
|
393
396
|
const part = lifecycleSnapshotToToolPart(snapshot);
|
|
394
397
|
const url = activityPartUrl(part);
|
|
395
398
|
const workspaceDestination = activityPartWorkspaceDestination(part);
|
|
396
399
|
return boundedActivityHeader({
|
|
397
|
-
|
|
400
|
+
...describeThinkChatActivityPart(part) ?? described("Used a tool"),
|
|
398
401
|
iconKind: activityPartIconKind(part),
|
|
399
402
|
...url ? { url } : {},
|
|
400
403
|
...workspaceDestination ? { workspaceDestination } : {}
|
|
@@ -38,7 +38,7 @@ function ThinkExecutionDetail({ className, emptyState = "Select a run to view it
|
|
|
38
38
|
defaultOpen: true,
|
|
39
39
|
children: [/* @__PURE__ */ jsx(ActivityTrigger, {
|
|
40
40
|
icon: /* @__PURE__ */ jsx(TerminalIcon, {}),
|
|
41
|
-
|
|
41
|
+
action: "Activity"
|
|
42
42
|
}), /* @__PURE__ */ jsxs(ActivityContent, { children: [
|
|
43
43
|
/* @__PURE__ */ jsx(ActivityItem, {
|
|
44
44
|
icon: /* @__PURE__ */ jsx(ArrowDownIcon, {}),
|
|
@@ -54,7 +54,7 @@ function ThinkExecutionDetail({ className, emptyState = "Select a run to view it
|
|
|
54
54
|
}) : null,
|
|
55
55
|
error ? /* @__PURE__ */ jsx(ActivityItemGroup, {
|
|
56
56
|
icon: /* @__PURE__ */ jsx(XIcon, {}),
|
|
57
|
-
|
|
57
|
+
action: "Failure",
|
|
58
58
|
children: /* @__PURE__ */ jsx(ActivityPanel, {
|
|
59
59
|
label: "Error",
|
|
60
60
|
text: error,
|
|
@@ -64,12 +64,12 @@ function ThinkExecutionDetail({ className, emptyState = "Select a run to view it
|
|
|
64
64
|
}) : null,
|
|
65
65
|
run.metadata ? /* @__PURE__ */ jsx(ActivityItemGroup, {
|
|
66
66
|
icon: /* @__PURE__ */ jsx(InfoIcon, {}),
|
|
67
|
-
|
|
67
|
+
action: "Metadata",
|
|
68
68
|
children: /* @__PURE__ */ jsx(ActivityOutput, { children: formatJson(run.metadata) })
|
|
69
69
|
}) : null,
|
|
70
70
|
/* @__PURE__ */ jsx(ActivityItemGroup, {
|
|
71
71
|
icon: /* @__PURE__ */ jsx(FileIcon, {}),
|
|
72
|
-
|
|
72
|
+
action: "Raw record",
|
|
73
73
|
children: /* @__PURE__ */ jsx(ActivityOutput, { children: formatJson(run) })
|
|
74
74
|
})
|
|
75
75
|
] })]
|
|
@@ -3,6 +3,7 @@ import { U as RefreshIcon, y as EllipsisIcon } from "../icons-DyOM0EJs.js";
|
|
|
3
3
|
import { t as NavigationLink } from "../navigation-link-Cob7KBlM.js";
|
|
4
4
|
import { Button, buttonVariants } from "./Button.js";
|
|
5
5
|
import { Tooltip } from "./Tooltip.js";
|
|
6
|
+
import { EmptyState } from "./EmptyState.js";
|
|
6
7
|
import { Menu } from "./Menu.js";
|
|
7
8
|
import { AppTopBar } from "./AppTopBar.js";
|
|
8
9
|
import { formatThinkExecutionRunProgress, getThinkExecutionRunAccessibleName, getThinkExecutionRunId, getThinkExecutionRunStatus, getThinkExecutionRunStatusTone, getThinkExecutionRunSubtitle, getThinkExecutionRunTitle, isSameThinkExecutionRun, isThinkSubmissionRun } from "./ThinkExecutionRun.js";
|
|
@@ -188,13 +189,13 @@ function ThinkExecutionWorkbench({ backButton, className, pageSize = executionPa
|
|
|
188
189
|
id: runsId,
|
|
189
190
|
children: "Runs"
|
|
190
191
|
})
|
|
191
|
-
}), runsQuery.isPending && runs.length === 0 ? /* @__PURE__ */ jsx(
|
|
192
|
+
}), runsQuery.isPending && runs.length === 0 ? /* @__PURE__ */ jsx(EmptyState, {
|
|
192
193
|
className: "think-execution-workbench__empty",
|
|
193
194
|
role: "status",
|
|
194
|
-
|
|
195
|
-
}) : runs.length === 0 ? /* @__PURE__ */ jsx(
|
|
195
|
+
description: "Loading runs..."
|
|
196
|
+
}) : runs.length === 0 ? /* @__PURE__ */ jsx(EmptyState, {
|
|
196
197
|
className: "think-execution-workbench__empty",
|
|
197
|
-
|
|
198
|
+
description: "No runs yet."
|
|
198
199
|
}) : /* @__PURE__ */ jsx("ul", {
|
|
199
200
|
className: "think-execution-workbench__list",
|
|
200
201
|
role: "list",
|
|
@@ -36,6 +36,7 @@ function ThinkRoutineBrowser({ className, routines, selectedRoutineId, showOwner
|
|
|
36
36
|
/* @__PURE__ */ jsxs("div", {
|
|
37
37
|
className: "think-routine-library__browser-toolbar",
|
|
38
38
|
children: [/* @__PURE__ */ jsx(ToggleGroup.Root, {
|
|
39
|
+
segmented: true,
|
|
39
40
|
className: "think-routine-library__filters",
|
|
40
41
|
size: "sm",
|
|
41
42
|
"aria-label": "Filter schedules",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { t as cx } from "../class-names-BiMDVpUo.js";
|
|
2
2
|
import { t as NavigationLink } from "../navigation-link-Cob7KBlM.js";
|
|
3
3
|
import { buttonVariants } from "./Button.js";
|
|
4
|
+
import { EmptyState } from "./EmptyState.js";
|
|
4
5
|
import { Badge } from "./Badge.js";
|
|
5
6
|
import { formatThinkExecutionShortTimestamp, getThinkExecutionRunId, getThinkExecutionRunStatus, isThinkSubmissionRun } from "./ThinkExecutionRun.js";
|
|
6
7
|
import { ThinkExecutionStatus } from "./ThinkExecutionStatus.js";
|
|
@@ -65,9 +66,9 @@ function ThinkRoutineRuns({ className, runs, title = "Recent runs", emptyState =
|
|
|
65
66
|
})
|
|
66
67
|
}, `${kind}:${getThinkExecutionRunId(run)}`);
|
|
67
68
|
})
|
|
68
|
-
}) : /* @__PURE__ */ jsx(
|
|
69
|
+
}) : /* @__PURE__ */ jsx(EmptyState, {
|
|
69
70
|
className: "think-routine-library__empty-runs",
|
|
70
|
-
|
|
71
|
+
description: emptyState
|
|
71
72
|
})]
|
|
72
73
|
});
|
|
73
74
|
}
|
|
@@ -2,6 +2,7 @@ import { t as cx } from "../class-names-BiMDVpUo.js";
|
|
|
2
2
|
import { K as SpinnerIcon, Q as WarningIcon, V as PlusIcon, _ as DotIcon, t as ArchiveIcon } from "../icons-DyOM0EJs.js";
|
|
3
3
|
import { t as NavigationLink } from "../navigation-link-Cob7KBlM.js";
|
|
4
4
|
import { Button, buttonVariants } from "./Button.js";
|
|
5
|
+
import { EmptyState } from "./EmptyState.js";
|
|
5
6
|
import { SearchField } from "./SearchField.js";
|
|
6
7
|
import { AlertDialog } from "./AlertDialog.js";
|
|
7
8
|
import { ScrollArea } from "./ScrollArea.js";
|
|
@@ -247,9 +248,9 @@ function ThinkThreadPicker({ threads, renderThreadLink, onCreate, onDelete, clas
|
|
|
247
248
|
}) : null]
|
|
248
249
|
}, thread.id);
|
|
249
250
|
})
|
|
250
|
-
}) : /* @__PURE__ */ jsx(
|
|
251
|
+
}) : /* @__PURE__ */ jsx(EmptyState, {
|
|
251
252
|
className: "think-thread-picker__empty",
|
|
252
|
-
|
|
253
|
+
description: threads.length ? "No matching threads." : "No threads yet."
|
|
253
254
|
})
|
|
254
255
|
}), /* @__PURE__ */ jsx(ScrollArea.Scrollbar, {
|
|
255
256
|
orientation: "vertical",
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as ToggleGroupItemProps, r as ToggleGroupProps, t as ToggleGroup } from "../ToggleGroup-
|
|
1
|
+
import { n as ToggleGroupItemProps, r as ToggleGroupProps, t as ToggleGroup } from "../ToggleGroup-BW1jrhAF.js";
|
|
2
2
|
export { ToggleGroup, ToggleGroupItemProps, ToggleGroupProps };
|
|
@@ -1,10 +1,52 @@
|
|
|
1
1
|
import { n as mergeBaseClassName, t as cx } from "../class-names-BiMDVpUo.js";
|
|
2
|
+
import { n as mergeRefs } from "../merge-refs-DF_7w2x_.js";
|
|
2
3
|
import { toggleVariants } from "./Toggle.js";
|
|
3
4
|
import * as React from "react";
|
|
4
|
-
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
6
|
import { ToggleGroup as ToggleGroup$1 } from "@base-ui/react/toggle-group";
|
|
6
7
|
import { Toggle } from "@base-ui/react/toggle";
|
|
7
8
|
//#region src/components/ToggleGroup.tsx
|
|
9
|
+
/**
|
|
10
|
+
* Tracks the pressed item's box so the segmented thumb can slide to it instead
|
|
11
|
+
* of appearing under it.
|
|
12
|
+
*
|
|
13
|
+
* The measurement is here because CSS cannot do it. Anchor positioning places
|
|
14
|
+
* the thumb correctly but teleports: `inset: anchor(...)` keeps the same
|
|
15
|
+
* computed value when the anchor changes, and transitions run on computed
|
|
16
|
+
* values. Counting siblings with `:has()` slides, but only while every segment
|
|
17
|
+
* is the same width, which stops being true the moment one label is longer.
|
|
18
|
+
*
|
|
19
|
+
* `offsetLeft` is physical, so the thumb is placed with `left` rather than
|
|
20
|
+
* `inset-inline-start` — a logical property fed a physical number lands on the
|
|
21
|
+
* wrong side in RTL.
|
|
22
|
+
*/
|
|
23
|
+
function useSegmentedThumb(enabled) {
|
|
24
|
+
const ref = React.useRef(null);
|
|
25
|
+
React.useLayoutEffect(() => {
|
|
26
|
+
const root = ref.current;
|
|
27
|
+
if (!enabled || !root) return;
|
|
28
|
+
const measure = () => {
|
|
29
|
+
const pressed = root.querySelector("[data-pressed]");
|
|
30
|
+
if (!pressed) return;
|
|
31
|
+
root.style.setProperty("--toggle-group-thumb-start", `${pressed.offsetLeft}px`);
|
|
32
|
+
root.style.setProperty("--toggle-group-thumb-size", `${pressed.offsetWidth}px`);
|
|
33
|
+
};
|
|
34
|
+
measure();
|
|
35
|
+
const attributes = new MutationObserver(measure);
|
|
36
|
+
attributes.observe(root, {
|
|
37
|
+
attributes: true,
|
|
38
|
+
attributeFilter: ["data-pressed"],
|
|
39
|
+
subtree: true
|
|
40
|
+
});
|
|
41
|
+
const resize = new ResizeObserver(measure);
|
|
42
|
+
resize.observe(root);
|
|
43
|
+
return () => {
|
|
44
|
+
attributes.disconnect();
|
|
45
|
+
resize.disconnect();
|
|
46
|
+
};
|
|
47
|
+
}, [enabled]);
|
|
48
|
+
return ref;
|
|
49
|
+
}
|
|
8
50
|
const ToggleGroupContext = React.createContext({
|
|
9
51
|
variant: "default",
|
|
10
52
|
size: "md",
|
|
@@ -35,7 +77,9 @@ const ToggleGroupContext = React.createContext({
|
|
|
35
77
|
*
|
|
36
78
|
* @see {@link https://base-ui.com/react/components/toggle-group | Base UI Toggle Group}
|
|
37
79
|
*/
|
|
38
|
-
function ToggleGroupRoot({ size = "md", spacing = 0, variant = "default", className, children, style, ref, ...props }) {
|
|
80
|
+
function ToggleGroupRoot({ size = "md", spacing = 0, segmented = false, variant = "default", className, children, style, ref, ...props }) {
|
|
81
|
+
const slidesThumb = segmented && !props.multiple;
|
|
82
|
+
const thumbRef = useSegmentedThumb(slidesThumb);
|
|
39
83
|
const gap = `${spacing * .25}rem`;
|
|
40
84
|
const groupStyle = typeof style === "function" ? (state) => ({
|
|
41
85
|
...style(state),
|
|
@@ -44,7 +88,7 @@ function ToggleGroupRoot({ size = "md", spacing = 0, variant = "default", classN
|
|
|
44
88
|
...style,
|
|
45
89
|
gap
|
|
46
90
|
};
|
|
47
|
-
const classes = mergeBaseClassName(cx("toggle-group", size !== "md" && `toggle-group--${size}
|
|
91
|
+
const classes = mergeBaseClassName(cx("toggle-group", size !== "md" && `toggle-group--${size}`, slidesThumb && "toggle-group--segmented"), className);
|
|
48
92
|
const contextValue = React.useMemo(() => ({
|
|
49
93
|
variant,
|
|
50
94
|
size,
|
|
@@ -54,8 +98,8 @@ function ToggleGroupRoot({ size = "md", spacing = 0, variant = "default", classN
|
|
|
54
98
|
spacing,
|
|
55
99
|
variant
|
|
56
100
|
]);
|
|
57
|
-
return /* @__PURE__ */
|
|
58
|
-
ref,
|
|
101
|
+
return /* @__PURE__ */ jsxs(ToggleGroup$1, {
|
|
102
|
+
ref: mergeRefs(ref, thumbRef),
|
|
59
103
|
"data-size": size,
|
|
60
104
|
"data-slot": "toggle-group",
|
|
61
105
|
"data-spacing": spacing,
|
|
@@ -63,10 +107,13 @@ function ToggleGroupRoot({ size = "md", spacing = 0, variant = "default", classN
|
|
|
63
107
|
className: classes,
|
|
64
108
|
style: groupStyle,
|
|
65
109
|
...props,
|
|
66
|
-
children: /* @__PURE__ */ jsx(
|
|
110
|
+
children: [slidesThumb ? /* @__PURE__ */ jsx("span", {
|
|
111
|
+
"aria-hidden": "true",
|
|
112
|
+
className: "toggle-group__thumb"
|
|
113
|
+
}) : null, /* @__PURE__ */ jsx(ToggleGroupContext.Provider, {
|
|
67
114
|
value: contextValue,
|
|
68
115
|
children
|
|
69
|
-
})
|
|
116
|
+
})]
|
|
70
117
|
});
|
|
71
118
|
}
|
|
72
119
|
/**
|
|
@@ -55,7 +55,7 @@ function ToolInvocation({ part, defaultOpen }) {
|
|
|
55
55
|
return /* @__PURE__ */ jsxs(Activity, {
|
|
56
56
|
isStreaming: isToolPartWorking(part),
|
|
57
57
|
defaultOpen,
|
|
58
|
-
children: [/* @__PURE__ */ jsx(ActivityTrigger, {
|
|
58
|
+
children: [/* @__PURE__ */ jsx(ActivityTrigger, { action: describeToolPart(part) }), /* @__PURE__ */ jsxs(ActivityContent, { children: [/* @__PURE__ */ jsx(ActivityPanel, {
|
|
59
59
|
label: part.title ?? getToolName(part),
|
|
60
60
|
text: formatToolValue(getToolInput(part)),
|
|
61
61
|
status: inputStatus,
|
|
@@ -11,13 +11,44 @@
|
|
|
11
11
|
text-align: start;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
/*
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
/*
|
|
15
|
+
* The action holds its content width and the detail absorbs whatever is left,
|
|
16
|
+
* so the two shrink in the right order: a long path loses its tail while
|
|
17
|
+
* "Reading" stays legible. Basis 0 on the detail is what makes it the flexible
|
|
18
|
+
* one; the trailing affordance stays adjacent until the width is exhausted.
|
|
19
|
+
*
|
|
20
|
+
* With no detail present the action is the only flexible item, so a settled
|
|
21
|
+
* summary sentence still truncates rather than inflating its owner.
|
|
22
|
+
*/
|
|
23
|
+
.activity__header-action {
|
|
24
|
+
flex: 0 1 auto;
|
|
18
25
|
min-width: 0;
|
|
19
26
|
max-width: max-content;
|
|
27
|
+
overflow: hidden;
|
|
20
28
|
color: var(--sigvelo-color-text);
|
|
29
|
+
text-overflow: ellipsis;
|
|
30
|
+
white-space: nowrap;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/*
|
|
34
|
+
* The target of the action — a path, a command, a query. Muted, because in a
|
|
35
|
+
* column of activity lines the verb is what the reader scans for.
|
|
36
|
+
*
|
|
37
|
+
* Faded rather than ellipsed: this is data, and a trailing "…" reads as part of
|
|
38
|
+
* the value it is truncating.
|
|
39
|
+
*
|
|
40
|
+
* The fade is unconditional because it does not need a condition. Growing to
|
|
41
|
+
* fill the free space means the box is wider than short text, so the gradient
|
|
42
|
+
* lands on empty space and only bites once the text actually reaches the edge.
|
|
43
|
+
*/
|
|
44
|
+
.activity__header-detail {
|
|
45
|
+
flex: 1 1 0;
|
|
46
|
+
min-width: 0;
|
|
47
|
+
overflow: hidden;
|
|
48
|
+
color: var(--sigvelo-color-text-muted);
|
|
49
|
+
font-weight: var(--sigvelo-font-weight-normal);
|
|
50
|
+
white-space: nowrap;
|
|
51
|
+
mask-image: linear-gradient(to right, #000 calc(100% - 1rem), transparent 100%);
|
|
21
52
|
}
|
|
22
53
|
|
|
23
54
|
.activity__item-icon {
|
|
@@ -26,8 +57,8 @@
|
|
|
26
57
|
color: var(--sigvelo-color-text-muted);
|
|
27
58
|
}
|
|
28
59
|
|
|
29
|
-
.activity[data-streaming] .activity__header-
|
|
30
|
-
.activity__header[data-streaming] .activity__header-
|
|
60
|
+
.activity[data-streaming] .activity__header-action,
|
|
61
|
+
.activity__header[data-streaming] .activity__header-action {
|
|
31
62
|
--sigvelo-shimmer-base: color-mix(in oklab, var(--sigvelo-color-text-muted), transparent 20%);
|
|
32
63
|
background: linear-gradient(
|
|
33
64
|
90deg,
|
|
@@ -43,8 +74,8 @@
|
|
|
43
74
|
}
|
|
44
75
|
|
|
45
76
|
@media (prefers-reduced-motion: reduce) {
|
|
46
|
-
.activity[data-streaming] .activity__header-
|
|
47
|
-
.activity__header[data-streaming] .activity__header-
|
|
77
|
+
.activity[data-streaming] .activity__header-action,
|
|
78
|
+
.activity__header[data-streaming] .activity__header-action {
|
|
48
79
|
animation: none;
|
|
49
80
|
background: none;
|
|
50
81
|
color: inherit;
|
|
@@ -52,8 +83,8 @@
|
|
|
52
83
|
}
|
|
53
84
|
|
|
54
85
|
@media (forced-colors: active) {
|
|
55
|
-
.activity[data-streaming] .activity__header-
|
|
56
|
-
.activity__header[data-streaming] .activity__header-
|
|
86
|
+
.activity[data-streaming] .activity__header-action,
|
|
87
|
+
.activity__header[data-streaming] .activity__header-action {
|
|
57
88
|
animation: none;
|
|
58
89
|
background: none;
|
|
59
90
|
color: inherit;
|
package/dist/styles/activity.css
CHANGED
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
gap: var(--sigvelo-spacing-1-5);
|
|
92
92
|
font-size: var(--sigvelo-text-compact);
|
|
93
93
|
color: var(--sigvelo-color-text);
|
|
94
|
-
line-height: var(--sigvelo-leading-
|
|
94
|
+
line-height: var(--sigvelo-leading-relaxed);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
/* Second collapse level: the trigger reads as a plain item row; the panel is
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
font-size: var(--sigvelo-text-compact);
|
|
119
119
|
font-weight: inherit;
|
|
120
120
|
color: var(--sigvelo-color-text);
|
|
121
|
-
line-height: var(--sigvelo-leading-
|
|
121
|
+
line-height: var(--sigvelo-leading-relaxed);
|
|
122
122
|
text-align: start;
|
|
123
123
|
cursor: pointer;
|
|
124
124
|
transition: background-color var(--sigvelo-motion-duration-interaction)
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
.activity__group-text {
|
|
165
165
|
margin: 0;
|
|
166
166
|
font-size: var(--sigvelo-text-compact);
|
|
167
|
-
line-height: var(--sigvelo-leading-
|
|
167
|
+
line-height: var(--sigvelo-leading-relaxed);
|
|
168
168
|
color: var(--sigvelo-color-text-muted);
|
|
169
169
|
white-space: pre-wrap;
|
|
170
170
|
overflow-wrap: anywhere;
|
|
@@ -200,7 +200,7 @@
|
|
|
200
200
|
margin: 0;
|
|
201
201
|
font-family: var(--sigvelo-font-mono);
|
|
202
202
|
font-size: var(--sigvelo-text-xs);
|
|
203
|
-
line-height: var(--sigvelo-leading-
|
|
203
|
+
line-height: var(--sigvelo-leading-relaxed);
|
|
204
204
|
color: var(--sigvelo-color-text);
|
|
205
205
|
white-space: pre-wrap;
|
|
206
206
|
overflow-wrap: anywhere;
|
|
@@ -323,6 +323,28 @@
|
|
|
323
323
|
overflow-wrap: anywhere;
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
+
/*
|
|
327
|
+
* The target of a row's action. Muted and shrink-first, so a column of rows
|
|
328
|
+
* reads down its verbs — "Read / Edited / Ran" — with the paths and commands
|
|
329
|
+
* present but out of the way.
|
|
330
|
+
*/
|
|
331
|
+
.activity__item-detail {
|
|
332
|
+
flex: 1 1 0;
|
|
333
|
+
min-inline-size: 0;
|
|
334
|
+
overflow: hidden;
|
|
335
|
+
color: var(--sigvelo-color-text-muted);
|
|
336
|
+
white-space: nowrap;
|
|
337
|
+
mask-image: linear-gradient(to right, #000 calc(100% - 1rem), transparent 100%);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/* The action keeps its content width once a detail is beside it to shrink. */
|
|
341
|
+
.activity__item:has(.activity__item-detail) .activity__item-text,
|
|
342
|
+
.activity__group-trigger:has(.activity__item-detail) .activity__item-text {
|
|
343
|
+
flex: 0 1 auto;
|
|
344
|
+
overflow-wrap: normal;
|
|
345
|
+
white-space: nowrap;
|
|
346
|
+
}
|
|
347
|
+
|
|
326
348
|
@media (hover: none) {
|
|
327
349
|
.activity__group-icon {
|
|
328
350
|
opacity: 1;
|