@mcp-b/react-components 0.20.4 → 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/MessageScroller.js +1 -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/Stepper.js +1 -5
- package/dist/components/TestResults.js +15 -15
- 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 +69 -66
- package/dist/components/ThinkExecutionDetail.js +4 -4
- package/dist/components/ThinkExecutionRun.js +2 -2
- package/dist/components/ThinkExecutionWorkbench.js +5 -4
- package/dist/components/ThinkFullAppViewSwitch.d.ts +1 -1
- package/dist/components/ThinkRoutine.js +2 -10
- package/dist/components/ThinkRoutineBrowser.js +1 -0
- package/dist/components/ThinkRoutineRuns.js +3 -2
- package/dist/components/ThinkThreadPicker.js +4 -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/accordion.css +2 -1
- package/dist/styles/activity-header.css +45 -25
- package/dist/styles/activity.css +26 -4
- package/dist/styles/agent-activity-preview-overlay.css +51 -12
- package/dist/styles/agent-activity-preview.css +34 -33
- package/dist/styles/agent-attention.css +9 -16
- package/dist/styles/agent-chat.css +199 -0
- package/dist/styles/agent-connection.css +10 -10
- 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 +5 -5
- package/dist/styles/attachment-preview.css +1 -1
- package/dist/styles/badge.css +1 -1
- package/dist/styles/base-ui-motion.css +1 -1
- package/dist/styles/base.css +110 -3
- package/dist/styles/browser-control-overlay.css +16 -6
- package/dist/styles/browser-live-view.css +5 -38
- package/dist/styles/browser-replay.css +4 -8
- package/dist/styles/browser-run-panel.css +5 -19
- package/dist/styles/button.css +4 -2
- package/dist/styles/card.css +4 -4
- package/dist/styles/chain-of-thought.css +1 -2
- package/dist/styles/chatgpt-sign-in-screen.css +9 -7
- package/dist/styles/checkbox-group.css +4 -4
- package/dist/styles/code-block.css +9 -9
- package/dist/styles/commit.css +1 -1
- 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 +8 -8
- package/dist/styles/field.css +2 -2
- package/dist/styles/fieldset.css +1 -1
- package/dist/styles/file-tree.css +1 -1
- package/dist/styles/github-motion-mark.css +1 -1
- 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/label.css +1 -1
- package/dist/styles/mcp-server-picker.css +1 -1
- package/dist/styles/media-preview-card.css +5 -3
- package/dist/styles/menu.css +1 -1
- package/dist/styles/message-scroller.css +7 -25
- package/dist/styles/message.css +5 -7
- package/dist/styles/model-selector.css +5 -8
- package/dist/styles/plan.css +1 -1
- package/dist/styles/popover.css +1 -1
- package/dist/styles/preview-card.css +1 -1
- package/dist/styles/pricing-page.css +37 -35
- package/dist/styles/prompt-input.css +19 -41
- package/dist/styles/queue.css +3 -3
- package/dist/styles/recipes.css +92 -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 +2 -2
- package/dist/styles/status-pill.css +39 -0
- package/dist/styles/stepper.css +2 -2
- package/dist/styles/streamdown.css +39 -35
- 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 +2 -2
- package/dist/styles/terminal.css +6 -6
- package/dist/styles/test-results.css +2 -3
- package/dist/styles/textarea.css +1 -1
- package/dist/styles/theme-mode-control.css +3 -4
- package/dist/styles/think-execution-status.css +4 -23
- package/dist/styles/think-execution-workbench.css +3 -4
- package/dist/styles/think-full-app.css +3 -3
- package/dist/styles/think-routine-library.css +22 -24
- package/dist/styles/think-thread-picker.css +20 -47
- 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/web-preview.css +4 -4
- package/dist/styles/workspace-explorer.css +6 -8
- package/package.json +2 -2
|
@@ -1,13 +1,24 @@
|
|
|
1
|
+
import { t as capitalize } from "../format-S6uWyoSb.js";
|
|
1
2
|
import { displayUrl, getToolDisplayName, isBrowserToolPart, isExecuteToolPart, isFetchToolPart, isPartFailed, isPartWorking, isSessionContextToolFailure, isSessionContextToolPart, isSkillToolPart, isWorkspaceToolPart } from "./ThinkChatToolParts.js";
|
|
2
3
|
import { t as summarizeToolInput } from "../summarize-tool-input-CqTcGRYy.js";
|
|
3
4
|
import { getToolName, isReasoningUIPart, isToolUIPart } from "ai";
|
|
4
5
|
//#region src/components/ThinkChatActivitySummary.ts
|
|
6
|
+
function described(action, detail) {
|
|
7
|
+
return detail ? {
|
|
8
|
+
action,
|
|
9
|
+
detail
|
|
10
|
+
} : { action };
|
|
11
|
+
}
|
|
5
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
|
+
}
|
|
6
17
|
function boundedActivityHeader(header) {
|
|
7
|
-
if (header.label.length <= ACTIVITY_HEADER_LABEL_MAX_LENGTH) return header;
|
|
8
18
|
return {
|
|
9
19
|
...header,
|
|
10
|
-
|
|
20
|
+
action: bounded(header.action),
|
|
21
|
+
...header.detail ? { detail: bounded(header.detail) } : {}
|
|
11
22
|
};
|
|
12
23
|
}
|
|
13
24
|
function getToolInput(part) {
|
|
@@ -99,9 +110,7 @@ function genericToolPresentation(part, hasUrl) {
|
|
|
99
110
|
}
|
|
100
111
|
function describeGenericToolPart(part) {
|
|
101
112
|
const labels = genericToolPresentation(part, activityPartUrl(part) !== null);
|
|
102
|
-
|
|
103
|
-
const detail = summarizeToolInput(getToolInput(part));
|
|
104
|
-
return detail ? `${label} · ${detail}` : label;
|
|
113
|
+
return described(isPartFailed(part) ? labels.failed : isPartWorking(part) ? labels.working : labels.done, summarizeToolInput(getToolInput(part)));
|
|
105
114
|
}
|
|
106
115
|
function activityPartUrl(part) {
|
|
107
116
|
if (isFetchToolPart(part)) return firstHttpUrl(part.input?.url ?? part.input?.path);
|
|
@@ -150,7 +159,7 @@ function activityPartWorkspaceDestination(part) {
|
|
|
150
159
|
}
|
|
151
160
|
}
|
|
152
161
|
/**
|
|
153
|
-
* One-line natural-language
|
|
162
|
+
* One-line natural-language action for an activity part ("Ran vp test",
|
|
154
163
|
* "Fetched developers.cloudflare.com/agents/"); `null` for boundaries that
|
|
155
164
|
* aren't steps (step-start). Exported so a custom `renderPart` can reuse the
|
|
156
165
|
* built-in labels for tools it doesn't override.
|
|
@@ -158,12 +167,12 @@ function activityPartWorkspaceDestination(part) {
|
|
|
158
167
|
function describeThinkChatActivityPart(part, toolRenderers) {
|
|
159
168
|
if (isToolUIPart(part)) {
|
|
160
169
|
const custom = toolRenderers?.[getToolName(part)]?.describe?.(part);
|
|
161
|
-
if (custom !== void 0) return custom;
|
|
170
|
+
if (custom !== void 0) return custom ?? null;
|
|
162
171
|
}
|
|
163
172
|
if (isReasoningUIPart(part)) {
|
|
164
173
|
const snippet = summarizeReasoningTitle(part.text);
|
|
165
|
-
const
|
|
166
|
-
return snippet ??
|
|
174
|
+
const action = part.state === "streaming" ? "Thinking…" : "Thought";
|
|
175
|
+
return described(snippet ?? action);
|
|
167
176
|
}
|
|
168
177
|
if (isWorkspaceToolPart(part)) return describeWorkspaceToolPart(part);
|
|
169
178
|
if (isSkillToolPart(part)) return describeSkillToolPart(part);
|
|
@@ -182,88 +191,83 @@ function describeWorkspaceToolPart(part) {
|
|
|
182
191
|
const failed = isPartFailed(part);
|
|
183
192
|
if (part.type === "tool-bash") {
|
|
184
193
|
const command = part.input?.script?.trim() ?? "";
|
|
185
|
-
if (failed) return
|
|
194
|
+
if (failed) return described("Command failed", command);
|
|
186
195
|
const verb = working ? "Running" : "Ran";
|
|
187
|
-
return command ?
|
|
196
|
+
return command ? described(verb, command) : described(`${verb} a command`);
|
|
188
197
|
}
|
|
189
|
-
const
|
|
198
|
+
const { action, detail } = (() => {
|
|
190
199
|
switch (part.type) {
|
|
191
|
-
case "tool-read": return
|
|
192
|
-
case "tool-write": return
|
|
193
|
-
case "tool-edit": return
|
|
194
|
-
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");
|
|
195
204
|
case "tool-list": {
|
|
196
205
|
const path = part.input?.path;
|
|
197
|
-
return
|
|
206
|
+
return described(working ? "Listing" : "Listed", path && path !== "/" ? path : "files");
|
|
198
207
|
}
|
|
199
|
-
case "tool-find": return
|
|
200
|
-
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"}`);
|
|
201
210
|
}
|
|
202
211
|
})();
|
|
203
|
-
return failed ? `${
|
|
212
|
+
return failed ? described(`${action} ${detail ?? ""}`.trim() + " · failed") : described(action, detail);
|
|
204
213
|
}
|
|
205
214
|
function describeSkillToolPart(part) {
|
|
206
215
|
const working = isPartWorking(part);
|
|
207
216
|
const failed = isPartFailed(part);
|
|
208
|
-
const
|
|
217
|
+
const { action, detail } = (() => {
|
|
209
218
|
switch (part.type) {
|
|
210
219
|
case "tool-activate_skill": {
|
|
211
220
|
const name = part.input?.name;
|
|
212
|
-
return
|
|
221
|
+
return described(working ? "Using" : "Used", name ? `the ${name} skill` : "a skill");
|
|
213
222
|
}
|
|
214
|
-
case "tool-read_skill_resource": return
|
|
215
|
-
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");
|
|
216
225
|
}
|
|
217
226
|
})();
|
|
218
|
-
return failed ? `${
|
|
227
|
+
return failed ? described(`${action} ${detail ?? ""}`.trim() + " · failed") : described(action, detail);
|
|
219
228
|
}
|
|
220
229
|
function describeSessionContextToolPart(part) {
|
|
221
230
|
const working = isPartWorking(part);
|
|
222
231
|
const failed = isSessionContextToolFailure(part);
|
|
223
|
-
const
|
|
232
|
+
const { action, detail } = (() => {
|
|
224
233
|
switch (part.type) {
|
|
225
|
-
case "tool-set_context":
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
case "tool-
|
|
230
|
-
case "tool-unload_context": return `${working ? "Unloading" : "Unloaded"} ${part.input?.key ?? "context"}`;
|
|
231
|
-
case "tool-search_context": return `${working ? "Searching" : "Searched"} ${part.input?.label ?? "context"}`;
|
|
232
|
-
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");
|
|
233
239
|
}
|
|
234
240
|
})();
|
|
235
|
-
return failed ? `${
|
|
241
|
+
return failed ? described(`${action} ${detail ?? ""}`.trim() + " · failed") : described(action, detail);
|
|
236
242
|
}
|
|
237
243
|
function describeBrowserToolPart(part) {
|
|
238
244
|
const working = isPartWorking(part);
|
|
239
245
|
const failed = isPartFailed(part);
|
|
240
246
|
if (part.type === "tool-browser_execute") {
|
|
241
247
|
const output = part.state === "output-available" ? part.output : void 0;
|
|
242
|
-
if (failed || output?.status === "error") return "Browser automation failed";
|
|
243
|
-
if (output?.status === "paused") return isHumanWaitPause(output) ? "Browser waiting for human" : "Browser waiting for approval";
|
|
244
|
-
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");
|
|
245
251
|
}
|
|
246
252
|
const page = displayUrl(part.input?.url) || "a page";
|
|
247
|
-
const
|
|
253
|
+
const { action, detail } = (() => {
|
|
248
254
|
switch (part.type) {
|
|
249
|
-
case "tool-browser_extract": return
|
|
250
|
-
case "tool-browser_links": return
|
|
251
|
-
case "tool-browser_scrape": return
|
|
252
|
-
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);
|
|
253
259
|
}
|
|
254
260
|
})();
|
|
255
|
-
return failed ? `${
|
|
261
|
+
return failed ? described(`${action} ${detail ?? ""}`.trim() + " · failed") : described(action, detail);
|
|
256
262
|
}
|
|
257
263
|
function describeExecuteToolPart(part) {
|
|
258
264
|
const output = part.state === "output-available" ? part.output : void 0;
|
|
259
|
-
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");
|
|
260
266
|
const explicitSummary = part.input ? Reflect.get(part.input, "summary") : void 0;
|
|
261
267
|
const summary = typeof explicitSummary === "string" ? summarizeToolInput({ summary: explicitSummary }) : null;
|
|
262
|
-
if (summary) return summary;
|
|
263
|
-
if (isPartFailed(part) || output?.status === "error") return "Code failed";
|
|
264
|
-
|
|
265
|
-
const snippet = summarizeToolInput(part.input);
|
|
266
|
-
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));
|
|
267
271
|
}
|
|
268
272
|
function summarizeReasoningTitle(text) {
|
|
269
273
|
const line = text.split("\n").find((candidate) => candidate.trim())?.trim();
|
|
@@ -278,9 +282,9 @@ function isHumanWaitPause(output) {
|
|
|
278
282
|
function describeFetchToolPart(part) {
|
|
279
283
|
const target = part.input?.url ?? part.input?.path ?? "";
|
|
280
284
|
const output = part.state === "output-available" ? part.output : void 0;
|
|
281
|
-
if (isPartFailed(part) || output?.ok === false) return
|
|
285
|
+
if (isPartFailed(part) || output?.ok === false) return described("Fetch failed", target);
|
|
282
286
|
const verb = isPartWorking(part) ? "Fetching" : "Fetched";
|
|
283
|
-
return target ?
|
|
287
|
+
return target ? described(verb, target) : described(`${verb} a URL`);
|
|
284
288
|
}
|
|
285
289
|
function summarizeActivitySteps(parts) {
|
|
286
290
|
const byTool = /* @__PURE__ */ new Map();
|
|
@@ -339,43 +343,42 @@ function summarizeActivitySteps(parts) {
|
|
|
339
343
|
for (const segment of genericSegments) if (!includedSegments.has(segment)) segments.push(segment);
|
|
340
344
|
if (segments.length === 0) return "Worked";
|
|
341
345
|
const top = segments.slice(0, 3);
|
|
342
|
-
|
|
343
|
-
return joined.charAt(0).toUpperCase() + joined.slice(1);
|
|
346
|
+
return capitalize(top.length === 1 ? top[0] : `${top.slice(0, -1).join(", ")} and ${top.at(-1)}`);
|
|
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
|
] })]
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { t as capitalize } from "../format-S6uWyoSb.js";
|
|
1
2
|
//#region src/components/ThinkExecutionRun.ts
|
|
2
3
|
/** Narrows the direct upstream execution union without wrapping either record. */
|
|
3
4
|
function isThinkSubmissionRun(run) {
|
|
@@ -35,8 +36,7 @@ function getThinkExecutionRunStatusTone(run) {
|
|
|
35
36
|
return "neutral";
|
|
36
37
|
}
|
|
37
38
|
function formatThinkExecutionStatus(status) {
|
|
38
|
-
|
|
39
|
-
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
39
|
+
return capitalize(status.replaceAll(/([a-z])([A-Z])/g, "$1 $2"));
|
|
40
40
|
}
|
|
41
41
|
function formatThinkExecutionTimestamp(value, fallback = "Not recorded") {
|
|
42
42
|
if (value == null) return fallback;
|
|
@@ -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",
|
|
@@ -1,17 +1,9 @@
|
|
|
1
|
+
import { formatThinkExecutionShortTimestamp } from "./ThinkExecutionRun.js";
|
|
1
2
|
//#region src/components/ThinkRoutine.ts
|
|
2
3
|
function getThinkRoutineNextRun(routine) {
|
|
3
4
|
if (!routine.schedule) return null;
|
|
4
5
|
if (!routine.enabled) return "Paused";
|
|
5
|
-
return
|
|
6
|
-
}
|
|
7
|
-
function formatThinkExecutionDate(value, fallback) {
|
|
8
|
-
const date = value instanceof Date ? value : new Date(value);
|
|
9
|
-
return Number.isNaN(date.getTime()) ? fallback : date.toLocaleString(void 0, {
|
|
10
|
-
month: "short",
|
|
11
|
-
day: "numeric",
|
|
12
|
-
hour: "numeric",
|
|
13
|
-
minute: "2-digit"
|
|
14
|
-
});
|
|
6
|
+
return formatThinkExecutionShortTimestamp(routine.schedule.time * 1e3, "Not scheduled");
|
|
15
7
|
}
|
|
16
8
|
//#endregion
|
|
17
9
|
export { getThinkRoutineNextRun };
|
|
@@ -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";
|
|
@@ -187,6 +188,7 @@ function ThinkThreadPicker({ threads, renderThreadLink, onCreate, onDelete, clas
|
|
|
187
188
|
className: "think-thread-picker__scroll",
|
|
188
189
|
children: [/* @__PURE__ */ jsx(ScrollArea.Viewport, {
|
|
189
190
|
className: "think-thread-picker__viewport",
|
|
191
|
+
"data-recipe": "scroll-fade-y",
|
|
190
192
|
"aria-label": "Thread list",
|
|
191
193
|
children: visibleThreads.length ? /* @__PURE__ */ jsx("ul", {
|
|
192
194
|
className: "think-thread-picker__list",
|
|
@@ -246,9 +248,9 @@ function ThinkThreadPicker({ threads, renderThreadLink, onCreate, onDelete, clas
|
|
|
246
248
|
}) : null]
|
|
247
249
|
}, thread.id);
|
|
248
250
|
})
|
|
249
|
-
}) : /* @__PURE__ */ jsx(
|
|
251
|
+
}) : /* @__PURE__ */ jsx(EmptyState, {
|
|
250
252
|
className: "think-thread-picker__empty",
|
|
251
|
-
|
|
253
|
+
description: threads.length ? "No matching threads." : "No threads yet."
|
|
252
254
|
})
|
|
253
255
|
}), /* @__PURE__ */ jsx(ScrollArea.Scrollbar, {
|
|
254
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,
|