@mcp-b/react-components 0.14.1 → 0.14.2

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.
Files changed (32) hide show
  1. package/dist/{AgentChat-Cgb1xuT7.d.ts → AgentChat-DQkqt82e.d.ts} +4 -2
  2. package/dist/{ModelSelector-DVgVBdvw.js → ModelSelector-CPCpFAUt.js} +15 -6
  3. package/dist/{ThinkChat-7DQ2CogF.js → ThinkChat-BPcehdbP.js} +3 -1
  4. package/dist/{ThinkChatActivity-m9orbdeI.d.ts → ThinkChatActivity-BmwuIigx.d.ts} +2 -2
  5. package/dist/{ThinkChatToolParts-Cv4o7j6F.d.ts → ThinkChatToolParts-CDEjqS6A.d.ts} +50 -1
  6. package/dist/components/AgentChat.d.ts +1 -1
  7. package/dist/components/AgentChat.js +8 -6
  8. package/dist/components/ChatGptSignInScreen.js +1 -1
  9. package/dist/components/ModelSelector.d.ts +15 -3
  10. package/dist/components/ModelSelector.js +1 -1
  11. package/dist/components/NaniteScene.d.ts +10 -1
  12. package/dist/components/NaniteScene.js +36 -1
  13. package/dist/components/SubagentRun.d.ts +87 -0
  14. package/dist/components/SubagentRun.js +101 -0
  15. package/dist/components/SubagentRunDetails.d.ts +44 -0
  16. package/dist/components/SubagentRunDetails.js +48 -0
  17. package/dist/components/ThinkChat.d.ts +8 -4
  18. package/dist/components/ThinkChat.js +1 -1
  19. package/dist/components/ThinkChatActivity.d.ts +2 -2
  20. package/dist/components/ThinkChatActivity.js +30 -3
  21. package/dist/components/ThinkChatToolPanels.d.ts +10 -2
  22. package/dist/components/ThinkChatToolPanels.js +47 -2
  23. package/dist/components/ThinkChatToolParts.d.ts +2 -2
  24. package/dist/components/ThinkChatToolParts.js +17 -1
  25. package/dist/components/ThinkFullApp.js +1 -1
  26. package/dist/styles/agent-chat.css +8 -0
  27. package/dist/styles/index.css +1 -0
  28. package/dist/styles/nanite-scene.css +16 -0
  29. package/dist/styles/subagent-run.css +188 -0
  30. package/dist/styles/think-full-app.css +2 -0
  31. package/dist/utils/codex-model-catalog.d.ts +4 -4
  32. package/package.json +2 -2
@@ -44,8 +44,7 @@ interface AgentChatProps<MessageT extends UIMessage = UIMessage> {
44
44
  * @example Think session compaction setup
45
45
  * ```ts
46
46
  * import { Think, defaultContextOverflowClassifier } from "@cloudflare/think";
47
- * import { Session } from "agents/experimental/memory/session";
48
- * import { createCompactFunction } from "agents/experimental/memory/utils";
47
+ * import { Session, createCompactFunction } from "agents/sessions";
49
48
  * import { generateText } from "ai";
50
49
  *
51
50
  * export class MyAgent extends Think<Env> {
@@ -78,6 +77,8 @@ interface AgentChatProps<MessageT extends UIMessage = UIMessage> {
78
77
  status?: ChatStatus;
79
78
  /** Called with the composed message when the user submits. Omit for a read-only transcript. */
80
79
  onSubmit?: (message: PromptInputMessage) => void | Promise<void>;
80
+ /** Show the prompt composer. Defaults to whether `onSubmit` is provided. */
81
+ showComposer?: boolean;
81
82
  /** Called when the user hits stop while `status` is streaming/submitted. */
82
83
  onStop?: () => void;
83
84
  placeholder?: string;
@@ -174,6 +175,7 @@ declare function AgentChat<MessageT extends UIMessage = UIMessage>({
174
175
  messages,
175
176
  status,
176
177
  onSubmit,
178
+ showComposer,
177
179
  onStop,
178
180
  placeholder,
179
181
  disabled,
@@ -134,7 +134,11 @@ function readCloudflareModelId(entry) {
134
134
  const modelId = readCatalogString(entry);
135
135
  return modelId && isCloudflareRunnableModelId(modelId) ? modelId : null;
136
136
  }
137
- for (const field of ["name", "id"]) {
137
+ for (const field of [
138
+ "model_id",
139
+ "name",
140
+ "id"
141
+ ]) {
138
142
  const modelId = readCatalogField(entry, field);
139
143
  if (modelId && isCloudflareRunnableModelId(modelId)) return modelId;
140
144
  }
@@ -175,12 +179,17 @@ function normalizeCloudflareModelSelectorModels(models) {
175
179
  return options;
176
180
  }
177
181
  async function listCloudflareModelSelectorOptions(client, params) {
182
+ const { account_id, task, per_page = 100 } = params;
178
183
  const models = [];
179
- for await (const model of client.ai.models.list(params)) models.push(model);
180
- if (params.format !== "openrouter") for await (const model of client.ai.models.list({
181
- ...params,
182
- format: "openrouter"
183
- })) models.push(model);
184
+ for (let page = 1;; page += 1) {
185
+ const response = await client.get(`/accounts/${account_id}/ai/catalog/models`, { query: {
186
+ page,
187
+ per_page
188
+ } });
189
+ const pageModels = response.result.filter((model) => !model.private && (!task || model.task === task));
190
+ models.push(...pageModels);
191
+ if (response.result.length < per_page) break;
192
+ }
184
193
  return normalizeCloudflareModelSelectorModels(models);
185
194
  }
186
195
  function groupCloudflareModelOptions(options) {
@@ -119,7 +119,9 @@ const ThinkChatApprovalsContext = React.createContext(null);
119
119
  * The full conversation surface — message list plus composer — with the
120
120
  * activity renderer as the default `renderPart`: runs of reasoning/tool parts
121
121
  * fold into one collapsed Activity block with derived labels and per-tool
122
- * panels. Extend for app-specific tools with `toolRenderers` (label/panel
122
+ * panels. Session-generated context/load/search tools are recognized from
123
+ * their upstream runtime schemas and keep their recorded inputs and outputs
124
+ * inspectable. Extend for app-specific tools with `toolRenderers` (label/panel
123
125
  * inside the log) or `excludeTools` + your own `renderPart` (standalone
124
126
  * card) — see README "App-specific tools" and the Custom Tool Panel story.
125
127
  */
@@ -1,5 +1,5 @@
1
- import { a as AgentChatRenderPartContext, r as AgentChatProps } from "./AgentChat-Cgb1xuT7.js";
2
- import { s as ThinkChatPart } from "./ThinkChatToolParts-Cv4o7j6F.js";
1
+ import { a as AgentChatRenderPartContext, r as AgentChatProps } from "./AgentChat-DQkqt82e.js";
2
+ import { l as ThinkChatPart } from "./ThinkChatToolParts-CDEjqS6A.js";
3
3
  import * as React from "react";
4
4
  import { DynamicToolUIPart, ToolUIPart, UIMessage } from "ai";
5
5
 
@@ -39,6 +39,55 @@ type SkillUITools = {
39
39
  };
40
40
  type SkillToolPart = ToolUIPart<SkillUITools>;
41
41
  declare function isSkillToolPart(part: ThinkChatPart): part is SkillToolPart;
42
+ type SetContextInput = {
43
+ label: string;
44
+ content: string;
45
+ action?: "replace" | "append";
46
+ metadata?: {
47
+ title?: string;
48
+ description?: string;
49
+ };
50
+ };
51
+ type SessionContextUITools = {
52
+ set_context: {
53
+ input: SetContextInput;
54
+ output: string;
55
+ };
56
+ load_context: {
57
+ input: {
58
+ label: string;
59
+ key: string;
60
+ };
61
+ output: string;
62
+ };
63
+ unload_context: {
64
+ input: {
65
+ label: string;
66
+ key: string;
67
+ };
68
+ output: string;
69
+ };
70
+ search_context: {
71
+ input: {
72
+ label: string;
73
+ query: string;
74
+ };
75
+ output: string;
76
+ };
77
+ session_search: {
78
+ input: {
79
+ query: string;
80
+ };
81
+ output: string;
82
+ };
83
+ };
84
+ type SessionContextToolPart = ToolUIPart<SessionContextUITools>;
85
+ type SessionContextToolName = keyof SessionContextUITools;
86
+ declare function isSessionContextToolPart(part: ThinkChatPart): part is SessionContextToolPart;
87
+ /** Session tools report provider failures as successful string outputs so the
88
+ model can recover. Treat that upstream `Error:` envelope as failed UI while
89
+ preserving the recorded tool state and output verbatim. */
90
+ declare function isSessionContextToolFailure(part: SessionContextToolPart): boolean;
42
91
  type FetchToolInput = {
43
92
  url: string;
44
93
  path?: never;
@@ -88,4 +137,4 @@ declare function isPartWorking(part: ThinkChatPart): boolean;
88
137
  declare function isPartFailed(part: ThinkChatPart): boolean;
89
138
  declare function displayUrl(url: string | undefined): string;
90
139
  //#endregion
91
- export { isThinkChatActivityPart as _, ThinkBashToolOutput as a, ThinkWorkspaceToolName as c, isBrowserToolPart as d, isExecuteToolPart as f, isSkillToolPart as g, isPartWorking as h, SkillToolPart as i, WorkspaceToolPart as l, isPartFailed as m, ExecuteToolPart as n, ThinkBashToolPart as o, isFetchToolPart as p, FetchToolPart as r, ThinkChatPart as s, BrowserToolPart as t, displayUrl as u, isWorkspaceToolPart as v };
140
+ export { isWorkspaceToolPart as S, isPartWorking as _, SessionContextToolPart as a, isSkillToolPart as b, ThinkBashToolPart as c, WorkspaceToolPart as d, displayUrl as f, isPartFailed as g, isFetchToolPart as h, SessionContextToolName as i, ThinkChatPart as l, isExecuteToolPart as m, ExecuteToolPart as n, SkillToolPart as o, isBrowserToolPart as p, FetchToolPart as r, ThinkBashToolOutput as s, BrowserToolPart as t, ThinkWorkspaceToolName as u, isSessionContextToolFailure as v, isThinkChatActivityPart as x, isSessionContextToolPart as y };
@@ -1,2 +1,2 @@
1
- import { a as AgentChatRenderPartContext, i as AgentChatRenderMessageContext, n as AgentChatPart, r as AgentChatProps, t as AgentChat } from "../AgentChat-Cgb1xuT7.js";
1
+ import { a as AgentChatRenderPartContext, i as AgentChatRenderMessageContext, n as AgentChatPart, r as AgentChatProps, t as AgentChat } from "../AgentChat-DQkqt82e.js";
2
2
  export { AgentChat, AgentChatPart, AgentChatProps, AgentChatRenderMessageContext, AgentChatRenderPartContext };
@@ -107,11 +107,12 @@ function isStepStartPart(part) {
107
107
  /**
108
108
  * Session compaction overlay marker from Agents Sessions.
109
109
  *
110
- * Agents exports `isCompactionMessage` from
111
- * `agents/experimental/memory/utils`; it checks the canonical `compaction_`
110
+ * Agents exports `isCompactionMessage` from `agents/sessions`; it checks the canonical `compaction_`
112
111
  * id prefix used when `Session.getHistory()` materializes a summary overlay.
113
112
  * `UIMessage` is structurally compatible with the fields the helper reads, so
114
- * keep this wrapper instead of duplicating the prefix test locally.
113
+ * keep this wrapper instead of duplicating the prefix test locally. The
114
+ * runtime import above stays on the deprecated compatibility path until this
115
+ * package raises its Agents dependency floor to the graduating release.
115
116
  */
116
117
  function isCompactionMessage$1(message) {
117
118
  return isCompactionMessage(message);
@@ -310,7 +311,7 @@ function renderDefaultPart(part) {
310
311
  * transport. Product code that talks to a Cloudflare Think agent should render
311
312
  * `ThinkChat`; use this directly only for plain AI SDK or read-only messages.
312
313
  */
313
- function AgentChat({ className, messages, status = "ready", onSubmit, onStop, placeholder = "Ask anything...", disabled, emptyState, composerHeader, composerTools, voiceInput, beforeVoiceStart, composerAddMenuItems, notice, onRegenerate, onEditAndResend, onApprovalResponse, thinkStub, onExecutionSettled, pendingApprovals: durableApprovals = EMPTY_PENDING_APPROVALS, contextWindow, renderPart, renderMessageAfter, ref }) {
314
+ function AgentChat({ className, messages, status = "ready", onSubmit, showComposer = onSubmit !== void 0, onStop, placeholder = "Ask anything...", disabled, emptyState, composerHeader, composerTools, voiceInput, beforeVoiceStart, composerAddMenuItems, notice, onRegenerate, onEditAndResend, onApprovalResponse, thinkStub, onExecutionSettled, pendingApprovals: durableApprovals = EMPTY_PENDING_APPROVALS, contextWindow, renderPart, renderMessageAfter, ref }) {
314
315
  const [copyAnnouncement, setCopyAnnouncement] = React.useState("");
315
316
  const copyAnnouncementTimer = React.useRef(null);
316
317
  const announceCopyStatus = React.useCallback((message) => {
@@ -414,6 +415,7 @@ function AgentChat({ className, messages, status = "ready", onSubmit, onStop, pl
414
415
  return /* @__PURE__ */ jsxs("div", {
415
416
  ref,
416
417
  className: cx("agent-chat", className),
418
+ "data-composer-hidden": showComposer ? void 0 : "",
417
419
  children: [
418
420
  /* @__PURE__ */ jsx("span", {
419
421
  className: "message__copy-status",
@@ -512,7 +514,7 @@ function AgentChat({ className, messages, status = "ready", onSubmit, onStop, pl
512
514
  })]
513
515
  })
514
516
  }),
515
- /* @__PURE__ */ jsxs("div", {
517
+ showComposer ? /* @__PURE__ */ jsxs("div", {
516
518
  ref: composerRef,
517
519
  className: "agent-chat__composer",
518
520
  children: [/* @__PURE__ */ jsx("div", {
@@ -572,7 +574,7 @@ function AgentChat({ className, messages, status = "ready", onSubmit, onStop, pl
572
574
  })] })
573
575
  ] })
574
576
  })]
575
- })
577
+ }) : null
576
578
  ]
577
579
  });
578
580
  }
@@ -1,7 +1,7 @@
1
1
  import { t as cx } from "../class-names-9UtZwb0J.js";
2
2
  import { N as SpinnerIcon } from "../icons-Ba9THQKz.js";
3
3
  import { Button } from "./Button.js";
4
- import { u as ModelSelectorLogo } from "../ModelSelector-DVgVBdvw.js";
4
+ import { u as ModelSelectorLogo } from "../ModelSelector-CPCpFAUt.js";
5
5
  import "react";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  //#region src/components/ChatGptSignInScreen.tsx
@@ -5,7 +5,19 @@ import Cloudflare from "cloudflare";
5
5
  import { AiModelsSearchObject } from "@cloudflare/workers-types";
6
6
 
7
7
  //#region src/components/ModelSelector.d.ts
8
- type CloudflareModelSelectorModels = readonly Cloudflare.AI.ModelListResponse[] | readonly AiModelsSearchObject[] | readonly string[];
8
+ type CloudflareModelSelectorModels = readonly Cloudflare.AI.ModelListResponse[] | readonly CloudflareModelCatalogEntry[] | readonly AiModelsSearchObject[] | readonly string[];
9
+ interface CloudflareModelCatalogEntry {
10
+ readonly model_id: string;
11
+ readonly name?: string;
12
+ readonly description?: string;
13
+ readonly task?: string;
14
+ readonly private?: boolean;
15
+ }
16
+ interface CloudflareModelCatalogListParams {
17
+ readonly account_id: string;
18
+ readonly task?: string;
19
+ readonly per_page?: number;
20
+ }
9
21
  interface CloudflareModelSelectorOption {
10
22
  readonly id: string;
11
23
  readonly provider: string;
@@ -36,7 +48,7 @@ declare function readCloudflareModelId(entry: unknown): string | null;
36
48
  declare function getCloudflareModelProvider(modelId: string): string;
37
49
  declare function formatCloudflareModelProvider(provider: string): string;
38
50
  declare function normalizeCloudflareModelSelectorModels(models: CloudflareModelSelectorModels): CloudflareModelSelectorOption[];
39
- declare function listCloudflareModelSelectorOptions(client: Cloudflare, params: Cloudflare.AI.ModelListParams): Promise<CloudflareModelSelectorOption[]>;
51
+ declare function listCloudflareModelSelectorOptions(client: Cloudflare, params: CloudflareModelCatalogListParams): Promise<CloudflareModelSelectorOption[]>;
40
52
  interface ModelSelectorProps extends React.HTMLAttributes<HTMLDivElement> {
41
53
  /** Controlled dialog open state. */
42
54
  open?: boolean;
@@ -244,4 +256,4 @@ declare function ModelSelectorShortcut({
244
256
  ref?: React.Ref<HTMLSpanElement>;
245
257
  }): React.JSX.Element;
246
258
  //#endregion
247
- export { CloudflareModelSelector, CloudflareModelSelectorModels, CloudflareModelSelectorOption, CloudflareModelSelectorProps, ModelSelector, ModelSelectorContent, ModelSelectorContentProps, ModelSelectorDialog, ModelSelectorDialogProps, ModelSelectorEmpty, ModelSelectorEmptyProps, ModelSelectorGroup, ModelSelectorGroupProps, ModelSelectorInput, ModelSelectorInputProps, ModelSelectorItem, ModelSelectorItemProps, ModelSelectorList, ModelSelectorListProps, ModelSelectorLogo, ModelSelectorLogoGroup, ModelSelectorLogoGroupProps, ModelSelectorLogoProps, ModelSelectorName, ModelSelectorNameProps, ModelSelectorProps, ModelSelectorSeparator, ModelSelectorSeparatorProps, ModelSelectorShortcut, ModelSelectorShortcutProps, ModelSelectorTrigger, ModelSelectorTriggerProps, formatCloudflareModelProvider, getCloudflareModelProvider, isCloudflareRunnableModelId, listCloudflareModelSelectorOptions, normalizeCloudflareModelSelectorModels, readCloudflareModelId };
259
+ export { CloudflareModelCatalogEntry, CloudflareModelCatalogListParams, CloudflareModelSelector, CloudflareModelSelectorModels, CloudflareModelSelectorOption, CloudflareModelSelectorProps, ModelSelector, ModelSelectorContent, ModelSelectorContentProps, ModelSelectorDialog, ModelSelectorDialogProps, ModelSelectorEmpty, ModelSelectorEmptyProps, ModelSelectorGroup, ModelSelectorGroupProps, ModelSelectorInput, ModelSelectorInputProps, ModelSelectorItem, ModelSelectorItemProps, ModelSelectorList, ModelSelectorListProps, ModelSelectorLogo, ModelSelectorLogoGroup, ModelSelectorLogoGroupProps, ModelSelectorLogoProps, ModelSelectorName, ModelSelectorNameProps, ModelSelectorProps, ModelSelectorSeparator, ModelSelectorSeparatorProps, ModelSelectorShortcut, ModelSelectorShortcutProps, ModelSelectorTrigger, ModelSelectorTriggerProps, formatCloudflareModelProvider, getCloudflareModelProvider, isCloudflareRunnableModelId, listCloudflareModelSelectorOptions, normalizeCloudflareModelSelectorModels, readCloudflareModelId };
@@ -1,2 +1,2 @@
1
- import { _ as getCloudflareModelProvider, a as ModelSelectorEmpty, b as normalizeCloudflareModelSelectorModels, c as ModelSelectorItem, d as ModelSelectorLogoGroup, f as ModelSelectorName, g as formatCloudflareModelProvider, h as ModelSelectorTrigger, i as ModelSelectorDialog, l as ModelSelectorList, m as ModelSelectorShortcut, n as ModelSelector, o as ModelSelectorGroup, p as ModelSelectorSeparator, r as ModelSelectorContent, s as ModelSelectorInput, t as CloudflareModelSelector, u as ModelSelectorLogo, v as isCloudflareRunnableModelId, x as readCloudflareModelId, y as listCloudflareModelSelectorOptions } from "../ModelSelector-DVgVBdvw.js";
1
+ import { _ as getCloudflareModelProvider, a as ModelSelectorEmpty, b as normalizeCloudflareModelSelectorModels, c as ModelSelectorItem, d as ModelSelectorLogoGroup, f as ModelSelectorName, g as formatCloudflareModelProvider, h as ModelSelectorTrigger, i as ModelSelectorDialog, l as ModelSelectorList, m as ModelSelectorShortcut, n as ModelSelector, o as ModelSelectorGroup, p as ModelSelectorSeparator, r as ModelSelectorContent, s as ModelSelectorInput, t as CloudflareModelSelector, u as ModelSelectorLogo, v as isCloudflareRunnableModelId, x as readCloudflareModelId, y as listCloudflareModelSelectorOptions } from "../ModelSelector-CPCpFAUt.js";
2
2
  export { CloudflareModelSelector, ModelSelector, ModelSelectorContent, ModelSelectorDialog, ModelSelectorEmpty, ModelSelectorGroup, ModelSelectorInput, ModelSelectorItem, ModelSelectorList, ModelSelectorLogo, ModelSelectorLogoGroup, ModelSelectorName, ModelSelectorSeparator, ModelSelectorShortcut, ModelSelectorTrigger, formatCloudflareModelProvider, getCloudflareModelProvider, isCloudflareRunnableModelId, listCloudflareModelSelectorOptions, normalizeCloudflareModelSelectorModels, readCloudflareModelId };
@@ -6,6 +6,15 @@ type NaniteSceneProps = {
6
6
  readonly className?: string; /** Accessible title when the illustration communicates state. */
7
7
  readonly title?: string;
8
8
  };
9
+ type NaniteMarkProps = {
10
+ /** Selects one of the established Nanite body colors. */readonly index?: number; /** Additional class names for layout only. */
11
+ readonly className?: string;
12
+ };
13
+ /** Compact decorative Nanite identity mark for dense agent and task UI. */
14
+ declare function NaniteMark({
15
+ index,
16
+ className
17
+ }: NaniteMarkProps): import("react").JSX.Element;
9
18
  /**
10
19
  * Decorative Nanites illustration used in setup, status, and empty states.
11
20
  * Pass a title when the illustration communicates state; otherwise it remains
@@ -30,4 +39,4 @@ declare function NaniteScene({
30
39
  title
31
40
  }: NaniteSceneProps): import("react").JSX.Element;
32
41
  //#endregion
33
- export { NaniteScene, NaniteSceneProps, NaniteSceneVariant };
42
+ export { NaniteMark, NaniteMarkProps, NaniteScene, NaniteSceneProps, NaniteSceneVariant };
@@ -22,6 +22,41 @@ const TRIO_XS = [
22
22
  100,
23
23
  160
24
24
  ];
25
+ /** Compact decorative Nanite identity mark for dense agent and task UI. */
26
+ function NaniteMark({ index = 0, className }) {
27
+ return /* @__PURE__ */ jsx("span", {
28
+ className: ["nanite-mark", className].filter(Boolean).join(" "),
29
+ "aria-hidden": "true",
30
+ children: /* @__PURE__ */ jsxs("svg", {
31
+ viewBox: "-18 -34 36 54",
32
+ focusable: "false",
33
+ fill: "none",
34
+ children: [/* @__PURE__ */ jsx(NaniteBody, { index }), /* @__PURE__ */ jsxs("g", {
35
+ className: "nanite-mark__hat",
36
+ children: [
37
+ /* @__PURE__ */ jsx("path", {
38
+ d: "M -9 -22 Q -9 -31 0 -31 Q 9 -31 9 -22 Z",
39
+ fill: HAT_SHELL
40
+ }),
41
+ /* @__PURE__ */ jsx("rect", {
42
+ x: "-12",
43
+ y: "-23",
44
+ width: "24",
45
+ height: "3.5",
46
+ rx: "1.5",
47
+ fill: HAT_BRIM
48
+ }),
49
+ /* @__PURE__ */ jsx("circle", {
50
+ cx: "0",
51
+ cy: "-28",
52
+ r: "2",
53
+ fill: HAT_BULB
54
+ })
55
+ ]
56
+ })]
57
+ })
58
+ });
59
+ }
25
60
  /**
26
61
  * Decorative Nanites illustration used in setup, status, and empty states.
27
62
  * Pass a title when the illustration communicates state; otherwise it remains
@@ -402,4 +437,4 @@ function Nanite({ index, cx, cy, scale }) {
402
437
  });
403
438
  }
404
439
  //#endregion
405
- export { NaniteScene };
440
+ export { NaniteMark, NaniteScene };
@@ -0,0 +1,87 @@
1
+ import { Collapsible } from "./Collapsible.js";
2
+ import { BadgeProps } from "./Badge.js";
3
+ import { SubagentRunActions, SubagentRunActionsProps, SubagentRunMilestone, SubagentRunMilestoneProps, SubagentRunMilestones, SubagentRunMilestonesProps, SubagentRunProgress, SubagentRunProgressProps } from "./SubagentRunDetails.js";
4
+ import * as React from "react";
5
+
6
+ //#region src/components/SubagentRun.d.ts
7
+ interface SubagentRunProps extends Omit<React.ComponentProps<typeof Collapsible.Root>, "className" | "unstyled"> {
8
+ className?: string;
9
+ }
10
+ /** Transport-neutral disclosure for one delegated agent run. */
11
+ declare function SubagentRun({
12
+ className,
13
+ ref,
14
+ ...props
15
+ }: SubagentRunProps): React.JSX.Element;
16
+ interface SubagentRunTriggerProps extends Omit<React.ComponentProps<typeof Collapsible.Trigger>, "className" | "unstyled"> {
17
+ className?: string;
18
+ }
19
+ interface SubagentRunSelectorProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
20
+ naniteIndex?: number;
21
+ selected?: boolean;
22
+ }
23
+ /** Compact selector for a run whose transcript is rendered in a separate detail surface. */
24
+ declare function SubagentRunSelector({
25
+ className,
26
+ children,
27
+ naniteIndex,
28
+ selected,
29
+ ref,
30
+ type,
31
+ ...props
32
+ }: SubagentRunSelectorProps & {
33
+ ref?: React.Ref<HTMLButtonElement>;
34
+ }): React.JSX.Element;
35
+ /** Compact run selector. Use the content for a short preview, not a full child transcript. */
36
+ declare function SubagentRunTrigger({
37
+ className,
38
+ children,
39
+ ref,
40
+ ...props
41
+ }: SubagentRunTriggerProps): React.JSX.Element;
42
+ interface SubagentRunHeadingProps extends React.HTMLAttributes<HTMLSpanElement> {}
43
+ declare function SubagentRunHeading({
44
+ className,
45
+ ref,
46
+ ...props
47
+ }: SubagentRunHeadingProps & {
48
+ ref?: React.Ref<HTMLSpanElement>;
49
+ }): React.JSX.Element;
50
+ interface SubagentRunTitleProps extends React.HTMLAttributes<HTMLSpanElement> {}
51
+ declare function SubagentRunTitle({
52
+ className,
53
+ ref,
54
+ ...props
55
+ }: SubagentRunTitleProps & {
56
+ ref?: React.Ref<HTMLSpanElement>;
57
+ }): React.JSX.Element;
58
+ interface SubagentRunDescriptionProps extends React.HTMLAttributes<HTMLSpanElement> {}
59
+ declare function SubagentRunDescription({
60
+ className,
61
+ ref,
62
+ ...props
63
+ }: SubagentRunDescriptionProps & {
64
+ ref?: React.Ref<HTMLSpanElement>;
65
+ }): React.JSX.Element;
66
+ type SubagentRunStatusTone = "active" | "complete" | "error" | "stopped" | "warning";
67
+ interface SubagentRunStatusProps extends Omit<BadgeProps, "color"> {
68
+ tone?: SubagentRunStatusTone;
69
+ }
70
+ /** Visible status label. A transport adapter owns any debounced live announcement. */
71
+ declare function SubagentRunStatus({
72
+ className,
73
+ tone,
74
+ size,
75
+ ...props
76
+ }: SubagentRunStatusProps): React.JSX.Element;
77
+ interface SubagentRunContentProps extends Omit<React.ComponentProps<typeof Collapsible.Panel>, "className" | "unstyled"> {
78
+ className?: string;
79
+ }
80
+ declare function SubagentRunContent({
81
+ className,
82
+ children,
83
+ ref,
84
+ ...props
85
+ }: SubagentRunContentProps): React.JSX.Element;
86
+ //#endregion
87
+ export { SubagentRun, SubagentRunActions, type SubagentRunActionsProps, SubagentRunContent, SubagentRunContentProps, SubagentRunDescription, SubagentRunDescriptionProps, SubagentRunHeading, SubagentRunHeadingProps, SubagentRunMilestone, type SubagentRunMilestoneProps, SubagentRunMilestones, type SubagentRunMilestonesProps, SubagentRunProgress, type SubagentRunProgressProps, SubagentRunProps, SubagentRunSelector, SubagentRunSelectorProps, SubagentRunStatus, SubagentRunStatusProps, SubagentRunStatusTone, SubagentRunTitle, SubagentRunTitleProps, SubagentRunTrigger, SubagentRunTriggerProps };
@@ -0,0 +1,101 @@
1
+ import { Collapsible } from "./Collapsible.js";
2
+ import { t as cx } from "../class-names-9UtZwb0J.js";
3
+ import { Badge } from "./Badge.js";
4
+ import { NaniteMark } from "./NaniteScene.js";
5
+ import { SubagentRunActions, SubagentRunMilestone, SubagentRunMilestones, SubagentRunProgress } from "./SubagentRunDetails.js";
6
+ import "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ //#region src/components/SubagentRun.tsx
9
+ /** Transport-neutral disclosure for one delegated agent run. */
10
+ function SubagentRun({ className, ref, ...props }) {
11
+ return /* @__PURE__ */ jsx(Collapsible.Root, {
12
+ ref,
13
+ "data-slot": "subagent-run",
14
+ className: cx("subagent-run", className),
15
+ ...props,
16
+ unstyled: true
17
+ });
18
+ }
19
+ /** Compact selector for a run whose transcript is rendered in a separate detail surface. */
20
+ function SubagentRunSelector({ className, children, naniteIndex = 0, selected = false, ref, type = "button", ...props }) {
21
+ return /* @__PURE__ */ jsxs("button", {
22
+ ref,
23
+ type,
24
+ "data-slot": "subagent-run-selector",
25
+ className: cx("subagent-run__trigger", className),
26
+ "aria-pressed": selected,
27
+ ...props,
28
+ children: [/* @__PURE__ */ jsx(NaniteMark, { index: naniteIndex }), /* @__PURE__ */ jsx("span", {
29
+ className: "subagent-run__trigger-content",
30
+ children
31
+ })]
32
+ });
33
+ }
34
+ /** Compact run selector. Use the content for a short preview, not a full child transcript. */
35
+ function SubagentRunTrigger({ className, children, ref, ...props }) {
36
+ return /* @__PURE__ */ jsxs(Collapsible.Trigger, {
37
+ ref,
38
+ "data-slot": "subagent-run-trigger",
39
+ className: cx("subagent-run__trigger", className),
40
+ ...props,
41
+ unstyled: true,
42
+ children: [/* @__PURE__ */ jsx(NaniteMark, {}), /* @__PURE__ */ jsx("span", {
43
+ className: "subagent-run__trigger-content",
44
+ children
45
+ })]
46
+ });
47
+ }
48
+ function SubagentRunHeading({ className, ref, ...props }) {
49
+ return /* @__PURE__ */ jsx("span", {
50
+ ref,
51
+ className: cx("subagent-run__heading", className),
52
+ ...props
53
+ });
54
+ }
55
+ function SubagentRunTitle({ className, ref, ...props }) {
56
+ return /* @__PURE__ */ jsx("span", {
57
+ ref,
58
+ className: cx("subagent-run__title", className),
59
+ ...props
60
+ });
61
+ }
62
+ function SubagentRunDescription({ className, ref, ...props }) {
63
+ return /* @__PURE__ */ jsx("span", {
64
+ ref,
65
+ className: cx("subagent-run__description", className),
66
+ ...props
67
+ });
68
+ }
69
+ const STATUS_COLOR = {
70
+ active: "primary",
71
+ complete: "success",
72
+ error: "destructive",
73
+ stopped: "neutral",
74
+ warning: "warning"
75
+ };
76
+ /** Visible status label. A transport adapter owns any debounced live announcement. */
77
+ function SubagentRunStatus({ className, tone = "active", size = "sm", ...props }) {
78
+ return /* @__PURE__ */ jsx(Badge, {
79
+ "data-slot": "subagent-run-status",
80
+ "data-tone": tone,
81
+ className: cx("subagent-run__status", className),
82
+ color: STATUS_COLOR[tone],
83
+ size,
84
+ ...props
85
+ });
86
+ }
87
+ function SubagentRunContent({ className, children, ref, ...props }) {
88
+ return /* @__PURE__ */ jsx(Collapsible.Panel, {
89
+ ref,
90
+ "data-slot": "subagent-run-content",
91
+ className: cx("subagent-run__content", className),
92
+ ...props,
93
+ unstyled: true,
94
+ children: /* @__PURE__ */ jsx("div", {
95
+ className: "subagent-run__content-inner",
96
+ children
97
+ })
98
+ });
99
+ }
100
+ //#endregion
101
+ export { SubagentRun, SubagentRunActions, SubagentRunContent, SubagentRunDescription, SubagentRunHeading, SubagentRunMilestone, SubagentRunMilestones, SubagentRunProgress, SubagentRunSelector, SubagentRunStatus, SubagentRunTitle, SubagentRunTrigger };
@@ -0,0 +1,44 @@
1
+ import * as React from "react";
2
+
3
+ //#region src/components/SubagentRunDetails.d.ts
4
+ interface SubagentRunProgressProps extends React.HTMLAttributes<HTMLDivElement> {
5
+ /** Human-readable current action or phase. */
6
+ label: string;
7
+ /** Completion fraction from 0 to 1. Omit for indeterminate progress. */
8
+ value?: number;
9
+ }
10
+ declare function SubagentRunProgress({
11
+ className,
12
+ label,
13
+ value,
14
+ ref,
15
+ ...props
16
+ }: SubagentRunProgressProps & {
17
+ ref?: React.Ref<HTMLDivElement>;
18
+ }): React.JSX.Element;
19
+ interface SubagentRunActionsProps extends React.HTMLAttributes<HTMLDivElement> {}
20
+ declare function SubagentRunActions({
21
+ className,
22
+ ref,
23
+ ...props
24
+ }: SubagentRunActionsProps & {
25
+ ref?: React.Ref<HTMLDivElement>;
26
+ }): React.JSX.Element;
27
+ interface SubagentRunMilestonesProps extends React.OlHTMLAttributes<HTMLOListElement> {}
28
+ declare function SubagentRunMilestones({
29
+ className,
30
+ ref,
31
+ ...props
32
+ }: SubagentRunMilestonesProps & {
33
+ ref?: React.Ref<HTMLOListElement>;
34
+ }): React.JSX.Element;
35
+ interface SubagentRunMilestoneProps extends React.LiHTMLAttributes<HTMLLIElement> {}
36
+ declare function SubagentRunMilestone({
37
+ className,
38
+ ref,
39
+ ...props
40
+ }: SubagentRunMilestoneProps & {
41
+ ref?: React.Ref<HTMLLIElement>;
42
+ }): React.JSX.Element;
43
+ //#endregion
44
+ export { SubagentRunActions, SubagentRunActionsProps, SubagentRunMilestone, SubagentRunMilestoneProps, SubagentRunMilestones, SubagentRunMilestonesProps, SubagentRunProgress, SubagentRunProgressProps };
@@ -0,0 +1,48 @@
1
+ import { t as cx } from "../class-names-9UtZwb0J.js";
2
+ import { Progress } from "./Progress.js";
3
+ import * as React from "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/components/SubagentRunDetails.tsx
6
+ function SubagentRunProgress({ className, label, value, ref, ...props }) {
7
+ const labelId = React.useId();
8
+ const percent = value === void 0 ? null : Math.round(Math.min(1, Math.max(0, value)) * 100);
9
+ return /* @__PURE__ */ jsxs("div", {
10
+ ref,
11
+ className: cx("subagent-run__progress", className),
12
+ ...props,
13
+ children: [/* @__PURE__ */ jsxs("span", {
14
+ id: labelId,
15
+ className: "subagent-run__progress-label",
16
+ children: [/* @__PURE__ */ jsx("span", { children: label }), percent === null ? null : /* @__PURE__ */ jsxs("span", { children: [percent, "%"] })]
17
+ }), /* @__PURE__ */ jsx(Progress.Root, {
18
+ value: percent,
19
+ "aria-labelledby": labelId,
20
+ children: /* @__PURE__ */ jsx(Progress.Track, { children: /* @__PURE__ */ jsx(Progress.Indicator, {}) })
21
+ })]
22
+ });
23
+ }
24
+ function SubagentRunActions({ className, ref, ...props }) {
25
+ return /* @__PURE__ */ jsx("div", {
26
+ ref,
27
+ className: cx("subagent-run__actions", className),
28
+ ...props
29
+ });
30
+ }
31
+ function SubagentRunMilestones({ className, ref, ...props }) {
32
+ return /* @__PURE__ */ jsx("ol", {
33
+ ref,
34
+ "data-slot": "subagent-run-milestones",
35
+ className: cx("subagent-run__milestones", className),
36
+ role: "list",
37
+ ...props
38
+ });
39
+ }
40
+ function SubagentRunMilestone({ className, ref, ...props }) {
41
+ return /* @__PURE__ */ jsx("li", {
42
+ ref,
43
+ className: cx("subagent-run__milestone", className),
44
+ ...props
45
+ });
46
+ }
47
+ //#endregion
48
+ export { SubagentRunActions, SubagentRunMilestone, SubagentRunMilestones, SubagentRunProgress };
@@ -1,8 +1,8 @@
1
- import { a as AgentChatRenderPartContext, r as AgentChatProps } from "../AgentChat-Cgb1xuT7.js";
1
+ import { a as AgentChatRenderPartContext, r as AgentChatProps } from "../AgentChat-DQkqt82e.js";
2
2
  import { n as BrowserLiveViewProps, t as BrowserLiveView } from "../BrowserLiveView-BV5qgFgI.js";
3
3
  import { n as BrowserReplayProps, t as BrowserReplay } from "../BrowserReplay-xWvRjRAC.js";
4
- import { _ as isThinkChatActivityPart } from "../ThinkChatToolParts-Cv4o7j6F.js";
5
- import { a as ThinkChatToolRenderers, c as renderThinkChatActivityPart, i as ThinkChatToolRenderer, n as ThinkChatActivityProps, o as createThinkChatActivityRenderer, r as ThinkChatActivityRendererOptions, s as describeThinkChatActivityPart, t as ThinkChatActivity } from "../ThinkChatActivity-m9orbdeI.js";
4
+ import { x as isThinkChatActivityPart } from "../ThinkChatToolParts-CDEjqS6A.js";
5
+ import { a as ThinkChatToolRenderers, c as renderThinkChatActivityPart, i as ThinkChatToolRenderer, n as ThinkChatActivityProps, o as createThinkChatActivityRenderer, r as ThinkChatActivityRendererOptions, s as describeThinkChatActivityPart, t as ThinkChatActivity } from "../ThinkChatActivity-BmwuIigx.js";
6
6
  import { n as ThinkChatValue } from "../ThinkChatContext-C3Eb1Xpi.js";
7
7
  import { FileInfo, UseWorkspaceOptions, WorkspaceExplorer, WorkspaceExplorerProps, WorkspaceFileState, WorkspaceInfo, WorkspaceSource, WorkspaceState, inferWorkspaceLanguage, useWorkspace } from "./WorkspaceExplorer.js";
8
8
  import * as React from "react";
@@ -29,6 +29,8 @@ interface ThinkChatMessagesProps<MessageT extends UIMessage = UIMessage> extends
29
29
  className?: string;
30
30
  /** Disable the composer (e.g. while the agent is unreachable). */
31
31
  disabled?: boolean;
32
+ /** Hide the composer while retaining the normal Think transcript rendering. */
33
+ showComposer?: AgentChatProps<MessageT>["showComposer"];
32
34
  /** Shown in place of the list while there are no messages. */
33
35
  emptyState?: React.ReactNode;
34
36
  /** Extra controls rendered inside the composer, next to the send button. */
@@ -104,7 +106,9 @@ declare function ThinkChatRoot<State = unknown, MessageT extends UIMessage = UIM
104
106
  * The full conversation surface — message list plus composer — with the
105
107
  * activity renderer as the default `renderPart`: runs of reasoning/tool parts
106
108
  * fold into one collapsed Activity block with derived labels and per-tool
107
- * panels. Extend for app-specific tools with `toolRenderers` (label/panel
109
+ * panels. Session-generated context/load/search tools are recognized from
110
+ * their upstream runtime schemas and keep their recorded inputs and outputs
111
+ * inspectable. Extend for app-specific tools with `toolRenderers` (label/panel
108
112
  * inside the log) or `excludeTools` + your own `renderPart` (standalone
109
113
  * card) — see README "App-specific tools" and the Custom Tool Panel story.
110
114
  */
@@ -2,6 +2,6 @@ import { BrowserLiveView } from "./BrowserLiveView.js";
2
2
  import { BrowserReplay } from "./BrowserReplay.js";
3
3
  import { isThinkChatActivityPart } from "./ThinkChatToolParts.js";
4
4
  import { ThinkChatActivity, createThinkChatActivityRenderer, describeThinkChatActivityPart, renderThinkChatActivityPart } from "./ThinkChatActivity.js";
5
- import { a as useThinkChat, i as ThinkChatRoot, n as ThinkChatMessages, o as useThinkPendingApprovals, r as ThinkChatProvider, t as ThinkChat } from "../ThinkChat-7DQ2CogF.js";
5
+ import { a as useThinkChat, i as ThinkChatRoot, n as ThinkChatMessages, o as useThinkPendingApprovals, r as ThinkChatProvider, t as ThinkChat } from "../ThinkChat-BPcehdbP.js";
6
6
  import { WorkspaceExplorer, inferWorkspaceLanguage, useWorkspace } from "./WorkspaceExplorer.js";
7
7
  export { BrowserLiveView, BrowserReplay, ThinkChat, ThinkChatActivity, ThinkChatMessages, ThinkChatProvider, ThinkChatRoot, WorkspaceExplorer, createThinkChatActivityRenderer, describeThinkChatActivityPart, inferWorkspaceLanguage, isThinkChatActivityPart, renderThinkChatActivityPart, useThinkChat, useThinkPendingApprovals, useWorkspace };
@@ -1,3 +1,3 @@
1
- import { _ as isThinkChatActivityPart } from "../ThinkChatToolParts-Cv4o7j6F.js";
2
- import { a as ThinkChatToolRenderers, c as renderThinkChatActivityPart, i as ThinkChatToolRenderer, n as ThinkChatActivityProps, o as createThinkChatActivityRenderer, r as ThinkChatActivityRendererOptions, s as describeThinkChatActivityPart, t as ThinkChatActivity } from "../ThinkChatActivity-m9orbdeI.js";
1
+ import { x as isThinkChatActivityPart } from "../ThinkChatToolParts-CDEjqS6A.js";
2
+ import { a as ThinkChatToolRenderers, c as renderThinkChatActivityPart, i as ThinkChatToolRenderer, n as ThinkChatActivityProps, o as createThinkChatActivityRenderer, r as ThinkChatActivityRendererOptions, s as describeThinkChatActivityPart, t as ThinkChatActivity } from "../ThinkChatActivity-BmwuIigx.js";
3
3
  export { ThinkChatActivity, ThinkChatActivityProps, ThinkChatActivityRendererOptions, ThinkChatToolRenderer, ThinkChatToolRenderers, createThinkChatActivityRenderer, describeThinkChatActivityPart, isThinkChatActivityPart, renderThinkChatActivityPart };
@@ -2,8 +2,8 @@ import { D as PencilIcon, I as TerminalIcon, L as WarningIcon, R as WrenchIcon,
2
2
  import { Activity, ActivityContent, ActivityItem, ActivityItemGroup, ActivityText, ActivityTrigger } from "./Activity.js";
3
3
  import { t as summarizeToolInput } from "../summarize-tool-input-BUJsENSn.js";
4
4
  import { useOptionalThinkChatContext } from "./ThinkChatContext.js";
5
- import { displayUrl, isBrowserToolPart, isExecuteToolPart, isFetchToolPart, isPartFailed, isPartWorking, isSkillToolPart, isThinkChatActivityPart, isWorkspaceToolPart } from "./ThinkChatToolParts.js";
6
- import { ThinkChatBrowserPanel, ThinkChatExecutePanel, ThinkChatFetchPanel, ThinkChatSkillPanel, ThinkChatWorkspacePanel } from "./ThinkChatToolPanels.js";
5
+ import { displayUrl, isBrowserToolPart, isExecuteToolPart, isFetchToolPart, isPartFailed, isPartWorking, isSessionContextToolFailure, isSessionContextToolPart, isSkillToolPart, isThinkChatActivityPart, isWorkspaceToolPart } from "./ThinkChatToolParts.js";
6
+ import { ThinkChatBrowserPanel, ThinkChatExecutePanel, ThinkChatFetchPanel, ThinkChatSessionContextPanel, ThinkChatSkillPanel, ThinkChatWorkspacePanel } from "./ThinkChatToolPanels.js";
7
7
  import * as React from "react";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
  import { getToolInput, getToolOutput } from "@cloudflare/think/react";
@@ -130,6 +130,7 @@ function activityPartIconKind(part) {
130
130
  case "tool-bash": return "command";
131
131
  }
132
132
  if (isSkillToolPart(part)) return "tool";
133
+ if (isSessionContextToolPart(part)) return part.type === "tool-search_context" || part.type === "tool-session_search" ? "search" : "tool";
133
134
  if (isFetchToolPart(part)) return "web";
134
135
  if (isBrowserToolPart(part)) return part.type === "tool-browser_execute" ? "browser" : "web";
135
136
  if (isExecuteToolPart(part)) return "command";
@@ -163,6 +164,7 @@ function describeThinkChatActivityPart(part, toolRenderers) {
163
164
  }
164
165
  if (isWorkspaceToolPart(part)) return describeWorkspaceToolPart(part);
165
166
  if (isSkillToolPart(part)) return describeSkillToolPart(part);
167
+ if (isSessionContextToolPart(part)) return describeSessionContextToolPart(part);
166
168
  if (isFetchToolPart(part)) return describeFetchToolPart(part);
167
169
  if (isBrowserToolPart(part)) return describeBrowserToolPart(part);
168
170
  if (isExecuteToolPart(part)) return describeExecuteToolPart(part);
@@ -212,6 +214,23 @@ function describeSkillToolPart(part) {
212
214
  })();
213
215
  return failed ? `${label} · failed` : label;
214
216
  }
217
+ function describeSessionContextToolPart(part) {
218
+ const working = isPartWorking(part);
219
+ const failed = isSessionContextToolFailure(part);
220
+ const label = (() => {
221
+ switch (part.type) {
222
+ case "tool-set_context": {
223
+ const target = part.input?.label ? ` ${part.input.label}` : " context";
224
+ return `${working ? "Updating" : "Updated"}${target}`;
225
+ }
226
+ case "tool-load_context": return `${working ? "Loading" : "Loaded"} ${part.input?.key ?? "context"}`;
227
+ case "tool-unload_context": return `${working ? "Unloading" : "Unloaded"} ${part.input?.key ?? "context"}`;
228
+ case "tool-search_context": return `${working ? "Searching" : "Searched"} ${part.input?.label ?? "context"}`;
229
+ case "tool-session_search": return `${working ? "Searching" : "Searched"} conversations`;
230
+ }
231
+ })();
232
+ return failed ? `${label} · failed` : label;
233
+ }
215
234
  function describeBrowserToolPart(part) {
216
235
  const working = isPartWorking(part);
217
236
  const failed = isPartFailed(part);
@@ -253,6 +272,7 @@ function summarizeActivitySteps(parts) {
253
272
  const skillNames = /* @__PURE__ */ new Set();
254
273
  let thoughts = 0;
255
274
  let skillParts = 0;
275
+ const sessionSegments = /* @__PURE__ */ new Set();
256
276
  let fetches = 0;
257
277
  let browses = 0;
258
278
  let codeRuns = 0;
@@ -263,7 +283,8 @@ function summarizeActivitySteps(parts) {
263
283
  } else if (isSkillToolPart(part)) {
264
284
  skillParts++;
265
285
  if (typeof part.input?.name === "string") skillNames.add(part.input.name);
266
- } else if (isFetchToolPart(part)) fetches++;
286
+ } else if (isSessionContextToolPart(part)) sessionSegments.add(part.type === "tool-search_context" || part.type === "tool-session_search" ? "searched context" : "updated context");
287
+ else if (isFetchToolPart(part)) fetches++;
267
288
  else if (isBrowserToolPart(part)) browses++;
268
289
  else if (isExecuteToolPart(part)) codeRuns++;
269
290
  else if (isToolUIPart(part)) genericSegments.add(genericToolLabels(getToolName(part), activityPartUrl(part) !== null).summary);
@@ -276,6 +297,7 @@ function summarizeActivitySteps(parts) {
276
297
  const segments = [];
277
298
  if (thoughts > 0) segments.push("thought");
278
299
  if (skillParts > 0) segments.push(skillNames.size === 1 ? `used the ${[...skillNames][0]} skill` : skillNames.size > 1 ? `used ${skillNames.size} skills` : "used a skill");
300
+ for (const segment of ["updated context", "searched context"]) if (sessionSegments.has(segment)) segments.push(segment);
279
301
  if (reads > 0) segments.push(`read ${files(reads)}`);
280
302
  if (edits > 0) segments.push(`edited ${files(edits)}`);
281
303
  if (deletes > 0) segments.push(`deleted ${files(deletes)}`);
@@ -362,6 +384,11 @@ function ThinkChatActivityStep({ text, part, toolRenderers }) {
362
384
  icon,
363
385
  children: /* @__PURE__ */ jsx(ThinkChatSkillPanel, { part })
364
386
  });
387
+ if (isSessionContextToolPart(part)) return /* @__PURE__ */ jsx(ActivityItemGroup, {
388
+ label: text,
389
+ icon,
390
+ children: /* @__PURE__ */ jsx(ThinkChatSessionContextPanel, { part })
391
+ });
365
392
  if (isFetchToolPart(part)) return /* @__PURE__ */ jsx(ActivityItemGroup, {
366
393
  label: text,
367
394
  icon,
@@ -1,4 +1,4 @@
1
- import { i as SkillToolPart, l as WorkspaceToolPart, n as ExecuteToolPart, r as FetchToolPart, t as BrowserToolPart } from "../ThinkChatToolParts-Cv4o7j6F.js";
1
+ import { a as SessionContextToolPart, d as WorkspaceToolPart, n as ExecuteToolPart, o as SkillToolPart, r as FetchToolPart, t as BrowserToolPart } from "../ThinkChatToolParts-CDEjqS6A.js";
2
2
  import * as React from "react";
3
3
 
4
4
  //#region src/components/ThinkChatToolPanels.d.ts
@@ -18,6 +18,14 @@ declare function ThinkChatSkillPanel({
18
18
  }: {
19
19
  part: SkillToolPart;
20
20
  }): React.JSX.Element;
21
+ /** Session panels expose the durable context/search operation recorded in the
22
+ UIMessage. The session itself remains server-owned; this is transcript
23
+ rendering, not a client-side mirror of context state. */
24
+ declare function ThinkChatSessionContextPanel({
25
+ part
26
+ }: {
27
+ part: SessionContextToolPart;
28
+ }): React.JSX.Element;
21
29
  declare function ThinkChatFetchPanel({
22
30
  part
23
31
  }: {
@@ -36,4 +44,4 @@ declare function ThinkChatBrowserPanel({
36
44
  part: BrowserToolPart;
37
45
  }): React.JSX.Element;
38
46
  //#endregion
39
- export { ThinkChatBrowserPanel, ThinkChatExecutePanel, ThinkChatFetchPanel, ThinkChatSkillPanel, ThinkChatWorkspacePanel };
47
+ export { ThinkChatBrowserPanel, ThinkChatExecutePanel, ThinkChatFetchPanel, ThinkChatSessionContextPanel, ThinkChatSkillPanel, ThinkChatWorkspacePanel };
@@ -2,7 +2,7 @@ import { ActivityOutput, ActivityPanel } from "./Activity.js";
2
2
  import { Tabs } from "./Tabs.js";
3
3
  import { t as CodeBlock } from "../CodeBlock-BUFXG8HW.js";
4
4
  import { BrowserLiveView } from "./BrowserLiveView.js";
5
- import { displayUrl } from "./ThinkChatToolParts.js";
5
+ import { displayUrl, isSessionContextToolFailure } from "./ThinkChatToolParts.js";
6
6
  import * as React from "react";
7
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
8
  import { getToolName } from "ai";
@@ -152,6 +152,51 @@ function ThinkChatSkillPanel({ part }) {
152
152
  }
153
153
  }
154
154
  }
155
+ /** Session panels expose the durable context/search operation recorded in the
156
+ UIMessage. The session itself remains server-owned; this is transcript
157
+ rendering, not a client-side mirror of context state. */
158
+ function ThinkChatSessionContextPanel({ part }) {
159
+ if (part.state === "output-error") return /* @__PURE__ */ jsx(ActivityPanel, {
160
+ label: getToolName(part),
161
+ text: part.errorText,
162
+ status: "error",
163
+ error: true
164
+ });
165
+ if (part.state === "output-denied") return renderDeniedPanel(getToolName(part), part.approval.reason);
166
+ const output = part.state === "output-available" ? part.output : void 0;
167
+ const outputIsError = isSessionContextToolFailure(part);
168
+ switch (part.type) {
169
+ case "tool-set_context": {
170
+ const input = part.input;
171
+ const title = input?.metadata?.title;
172
+ return /* @__PURE__ */ jsx(ActivityPanel, {
173
+ label: title ? `${input?.label ?? "context"} / ${title}` : input?.label ?? "context",
174
+ text: input?.content,
175
+ status: output,
176
+ error: outputIsError
177
+ });
178
+ }
179
+ case "tool-load_context":
180
+ case "tool-unload_context": return /* @__PURE__ */ jsx(ActivityPanel, {
181
+ label: `${part.input?.label ?? "context"} / ${part.input?.key ?? "entry"}`,
182
+ text: output,
183
+ status: outputIsError ? "error" : void 0,
184
+ error: outputIsError
185
+ });
186
+ case "tool-search_context": return /* @__PURE__ */ jsx(ActivityPanel, {
187
+ label: part.input?.query ?? "Context search",
188
+ text: output,
189
+ status: outputIsError ? "error" : part.input?.label,
190
+ error: outputIsError
191
+ });
192
+ case "tool-session_search": return /* @__PURE__ */ jsx(ActivityPanel, {
193
+ label: part.input?.query ?? "Conversation search",
194
+ text: output,
195
+ status: outputIsError ? "error" : void 0,
196
+ error: outputIsError
197
+ });
198
+ }
199
+ }
155
200
  function ThinkChatFetchPanel({ part }) {
156
201
  const label = part.input?.url ?? part.input?.path ?? "fetch";
157
202
  if (part.state === "output-error") return /* @__PURE__ */ jsx(ActivityPanel, {
@@ -364,4 +409,4 @@ function getBashStatusText(output, errorText, deniedReason) {
364
409
  return "success";
365
410
  }
366
411
  //#endregion
367
- export { ThinkChatBrowserPanel, ThinkChatExecutePanel, ThinkChatFetchPanel, ThinkChatSkillPanel, ThinkChatWorkspacePanel };
412
+ export { ThinkChatBrowserPanel, ThinkChatExecutePanel, ThinkChatFetchPanel, ThinkChatSessionContextPanel, ThinkChatSkillPanel, ThinkChatWorkspacePanel };
@@ -1,2 +1,2 @@
1
- import { _ as isThinkChatActivityPart, a as ThinkBashToolOutput, c as ThinkWorkspaceToolName, d as isBrowserToolPart, f as isExecuteToolPart, g as isSkillToolPart, h as isPartWorking, i as SkillToolPart, l as WorkspaceToolPart, m as isPartFailed, n as ExecuteToolPart, o as ThinkBashToolPart, p as isFetchToolPart, r as FetchToolPart, s as ThinkChatPart, t as BrowserToolPart, u as displayUrl, v as isWorkspaceToolPart } from "../ThinkChatToolParts-Cv4o7j6F.js";
2
- export { BrowserToolPart, ExecuteToolPart, FetchToolPart, SkillToolPart, ThinkBashToolOutput, ThinkBashToolPart, ThinkChatPart, ThinkWorkspaceToolName, WorkspaceToolPart, displayUrl, isBrowserToolPart, isExecuteToolPart, isFetchToolPart, isPartFailed, isPartWorking, isSkillToolPart, isThinkChatActivityPart, isWorkspaceToolPart };
1
+ import { S as isWorkspaceToolPart, _ as isPartWorking, a as SessionContextToolPart, b as isSkillToolPart, c as ThinkBashToolPart, d as WorkspaceToolPart, f as displayUrl, g as isPartFailed, h as isFetchToolPart, i as SessionContextToolName, l as ThinkChatPart, m as isExecuteToolPart, n as ExecuteToolPart, o as SkillToolPart, p as isBrowserToolPart, r as FetchToolPart, s as ThinkBashToolOutput, t as BrowserToolPart, u as ThinkWorkspaceToolName, v as isSessionContextToolFailure, x as isThinkChatActivityPart, y as isSessionContextToolPart } from "../ThinkChatToolParts-CDEjqS6A.js";
2
+ export { BrowserToolPart, ExecuteToolPart, FetchToolPart, SessionContextToolName, SessionContextToolPart, SkillToolPart, ThinkBashToolOutput, ThinkBashToolPart, ThinkChatPart, ThinkWorkspaceToolName, WorkspaceToolPart, displayUrl, isBrowserToolPart, isExecuteToolPart, isFetchToolPart, isPartFailed, isPartWorking, isSessionContextToolFailure, isSessionContextToolPart, isSkillToolPart, isThinkChatActivityPart, isWorkspaceToolPart };
@@ -22,6 +22,22 @@ const SKILL_TOOL_NAMES = /* @__PURE__ */ new Set([
22
22
  function isSkillToolPart(part) {
23
23
  return isStaticToolUIPart(part) && SKILL_TOOL_NAMES.has(getStaticToolName(part));
24
24
  }
25
+ const SESSION_CONTEXT_TOOL_NAMES = /* @__PURE__ */ new Set([
26
+ "set_context",
27
+ "load_context",
28
+ "unload_context",
29
+ "search_context",
30
+ "session_search"
31
+ ]);
32
+ function isSessionContextToolPart(part) {
33
+ return isStaticToolUIPart(part) && SESSION_CONTEXT_TOOL_NAMES.has(getStaticToolName(part));
34
+ }
35
+ /** Session tools report provider failures as successful string outputs so the
36
+ model can recover. Treat that upstream `Error:` envelope as failed UI while
37
+ preserving the recorded tool state and output verbatim. */
38
+ function isSessionContextToolFailure(part) {
39
+ return isPartFailed(part) || part.state === "output-available" && part.output.startsWith("Error:");
40
+ }
25
41
  function isFetchToolPart(part) {
26
42
  return isStaticToolUIPart(part) && getStaticToolName(part).startsWith("fetch_");
27
43
  }
@@ -63,4 +79,4 @@ function displayUrl(url) {
63
79
  return url ? url.replace(/^https?:\/\//, "") : "";
64
80
  }
65
81
  //#endregion
66
- export { displayUrl, isBrowserToolPart, isExecuteToolPart, isFetchToolPart, isPartFailed, isPartWorking, isSkillToolPart, isThinkChatActivityPart, isWorkspaceToolPart };
82
+ export { displayUrl, isBrowserToolPart, isExecuteToolPart, isFetchToolPart, isPartFailed, isPartWorking, isSessionContextToolFailure, isSessionContextToolPart, isSkillToolPart, isThinkChatActivityPart, isWorkspaceToolPart };
@@ -4,7 +4,7 @@ import { Separator } from "./Separator.js";
4
4
  import { Button } from "./Button.js";
5
5
  import { Tooltip } from "./Tooltip.js";
6
6
  import { ToggleGroup } from "./ToggleGroup.js";
7
- import { o as useThinkPendingApprovals, s as resolveThinkApprovalProps, t as ThinkChat } from "../ThinkChat-7DQ2CogF.js";
7
+ import { o as useThinkPendingApprovals, s as resolveThinkApprovalProps, t as ThinkChat } from "../ThinkChat-BPcehdbP.js";
8
8
  import { WorkspaceExplorer, useWorkspace } from "./WorkspaceExplorer.js";
9
9
  import { ThinkExecutionWorkbench } from "./ThinkExecutionWorkbench.js";
10
10
  import { ThinkThreadShell } from "./ThinkThreadShell.js";
@@ -28,6 +28,10 @@
28
28
  padding-inline: 1rem;
29
29
  }
30
30
 
31
+ .agent-chat[data-composer-hidden] .agent-chat__transcript-content {
32
+ padding-block-end: var(--sigvelo-spacing-4);
33
+ }
34
+
31
35
  .agent-chat__empty-row {
32
36
  display: flex;
33
37
  flex: 1;
@@ -44,6 +48,10 @@
44
48
  );
45
49
  }
46
50
 
51
+ .agent-chat[data-composer-hidden] .agent-chat__scroll-button {
52
+ --message-scroller-button-inset-block-end: var(--sigvelo-spacing-2);
53
+ }
54
+
47
55
  /* Floating over the transcript: solid behind the controls, fading out
48
56
  through the top padding so content slides under instead of hitting a bar. */
49
57
  .agent-chat__composer {
@@ -83,6 +83,7 @@
83
83
  @import "./queue.css" layer(components);
84
84
  @import "./reasoning.css" layer(components);
85
85
  @import "./sources.css" layer(components);
86
+ @import "./subagent-run.css" layer(components);
86
87
  @import "./task.css" layer(components);
87
88
  @import "./terminal.css" layer(components);
88
89
  @import "./test-results.css" layer(components);
@@ -5,6 +5,22 @@
5
5
  line-height: 0;
6
6
  }
7
7
 
8
+ .nanite-mark {
9
+ display: inline-flex;
10
+ flex: 0 0 auto;
11
+ inline-size: 1.25rem;
12
+ block-size: 1.5rem;
13
+ align-items: center;
14
+ justify-content: center;
15
+ line-height: 0;
16
+ }
17
+
18
+ .nanite-mark svg {
19
+ display: block;
20
+ inline-size: 100%;
21
+ block-size: 100%;
22
+ }
23
+
8
24
  .nanite-scene--trio {
9
25
  inline-size: 200px;
10
26
  block-size: 68px;
@@ -0,0 +1,188 @@
1
+ .subagent-run {
2
+ display: inline-flex;
3
+ flex-direction: column;
4
+ max-inline-size: 100%;
5
+ color: var(--sigvelo-color-text);
6
+ font-family: inherit;
7
+ }
8
+
9
+ .subagent-run__trigger {
10
+ display: flex;
11
+ align-items: safe center;
12
+ gap: var(--sigvelo-spacing-1-5);
13
+ min-block-size: var(--sigvelo-control-height-md);
14
+ max-inline-size: 18rem;
15
+ padding-block: var(--sigvelo-spacing-1);
16
+ padding-inline: var(--sigvelo-spacing-2-5);
17
+ border: var(--sigvelo-border-style) var(--sigvelo-border-width)
18
+ var(--sigvelo-color-neutral-border-subtle);
19
+ border-radius: var(--sigvelo-radius-full);
20
+ background-color: var(--sigvelo-color-surface);
21
+ color: var(--sigvelo-color-text);
22
+ font: inherit;
23
+ text-align: start;
24
+ cursor: pointer;
25
+ transition:
26
+ background-color var(--sigvelo-duration-fast) var(--sigvelo-ease-standard),
27
+ border-color var(--sigvelo-duration-fast) var(--sigvelo-ease-standard);
28
+ }
29
+
30
+ .subagent-run__trigger:hover:not([data-disabled]) {
31
+ background-color: var(--sigvelo-color-neutral-bg-subtle);
32
+ border-color: var(--sigvelo-color-neutral-border-muted);
33
+ }
34
+
35
+ .subagent-run__trigger:focus-visible {
36
+ outline: none;
37
+ box-shadow: var(--sigvelo-recipe-focus-shadow);
38
+ }
39
+
40
+ .subagent-run__trigger[data-panel-open],
41
+ .subagent-run__trigger[aria-pressed="true"] {
42
+ border-color: var(--sigvelo-color-neutral-border-muted);
43
+ background-color: var(--sigvelo-color-neutral-bg-subtle);
44
+ }
45
+
46
+ .subagent-run__trigger[aria-pressed="true"] {
47
+ box-shadow: inset 0 0 0 var(--sigvelo-border-width) var(--sigvelo-color-neutral-border-subtle);
48
+ }
49
+
50
+ .subagent-run__trigger-content {
51
+ display: flex;
52
+ align-items: safe center;
53
+ flex: 1 1 0;
54
+ gap: var(--sigvelo-spacing-1-5);
55
+ min-inline-size: 0;
56
+ }
57
+
58
+ .subagent-run__trigger[data-slot="subagent-run-trigger"] .subagent-run__trigger-content {
59
+ align-items: stretch;
60
+ flex-direction: column;
61
+ gap: 0;
62
+ }
63
+
64
+ .subagent-run__heading {
65
+ display: flex;
66
+ align-items: safe center;
67
+ flex-wrap: nowrap;
68
+ gap: var(--sigvelo-spacing-1-5);
69
+ min-inline-size: 0;
70
+ }
71
+
72
+ .subagent-run__title {
73
+ min-inline-size: 0;
74
+ overflow: hidden;
75
+ color: var(--sigvelo-color-text);
76
+ font-size: var(--sigvelo-text-sm);
77
+ font-weight: var(--sigvelo-font-weight-semibold);
78
+ text-overflow: ellipsis;
79
+ white-space: nowrap;
80
+ }
81
+
82
+ .subagent-run__description {
83
+ display: block;
84
+ overflow: hidden;
85
+ color: var(--sigvelo-color-text-muted);
86
+ font-size: var(--sigvelo-text-compact);
87
+ line-height: 1.5;
88
+ text-overflow: ellipsis;
89
+ white-space: nowrap;
90
+ }
91
+
92
+ .subagent-run__description:empty {
93
+ display: none;
94
+ }
95
+
96
+ .subagent-run__status {
97
+ max-inline-size: 100%;
98
+ }
99
+
100
+ .subagent-run__content-inner {
101
+ display: flex;
102
+ flex-direction: column;
103
+ gap: var(--sigvelo-spacing-3);
104
+ padding-block: var(--sigvelo-spacing-3);
105
+ min-inline-size: min(30rem, calc(100vw - var(--sigvelo-spacing-8)));
106
+ margin-block-start: var(--sigvelo-spacing-2);
107
+ padding-inline: var(--sigvelo-spacing-3);
108
+ border: var(--sigvelo-border-style) var(--sigvelo-border-width)
109
+ var(--sigvelo-color-neutral-border-subtle);
110
+ border-radius: var(--sigvelo-radius-lg);
111
+ background-color: var(--sigvelo-color-surface);
112
+ }
113
+
114
+ .subagent-run__progress {
115
+ display: grid;
116
+ gap: var(--sigvelo-spacing-1-5);
117
+ }
118
+
119
+ .subagent-run__progress-label {
120
+ display: flex;
121
+ justify-content: space-between;
122
+ gap: var(--sigvelo-spacing-3);
123
+ color: var(--sigvelo-color-text-muted);
124
+ font-size: var(--sigvelo-text-xs);
125
+ line-height: 1.5;
126
+ }
127
+
128
+ .subagent-run__progress-label > :first-child {
129
+ min-inline-size: 0;
130
+ overflow-wrap: anywhere;
131
+ }
132
+
133
+ .subagent-run__progress-label > :last-child {
134
+ flex: 0 0 auto;
135
+ font-variant-numeric: tabular-nums;
136
+ }
137
+
138
+ .subagent-run__milestones {
139
+ display: grid;
140
+ gap: var(--sigvelo-spacing-1-5);
141
+ margin: 0;
142
+ padding: 0;
143
+ list-style: none;
144
+ }
145
+
146
+ .subagent-run__milestone {
147
+ display: flex;
148
+ align-items: baseline;
149
+ gap: var(--sigvelo-spacing-2);
150
+ color: var(--sigvelo-color-text-muted);
151
+ font-size: var(--sigvelo-text-compact);
152
+ line-height: 1.5;
153
+ }
154
+
155
+ .subagent-run__milestone::before {
156
+ content: "";
157
+ flex: 0 0 auto;
158
+ inline-size: var(--sigvelo-spacing-1-5);
159
+ block-size: var(--sigvelo-spacing-1-5);
160
+ border: var(--sigvelo-border-style) var(--sigvelo-border-width)
161
+ var(--sigvelo-color-neutral-border-muted);
162
+ border-radius: var(--sigvelo-radius-full);
163
+ background-color: var(--sigvelo-color-neutral-bg-subtle);
164
+ }
165
+
166
+ .subagent-run__actions {
167
+ display: flex;
168
+ flex-wrap: wrap;
169
+ gap: var(--sigvelo-spacing-2);
170
+ justify-content: flex-end;
171
+ }
172
+
173
+ @media (forced-colors: active) {
174
+ .subagent-run__trigger,
175
+ .subagent-run__content-inner {
176
+ border-color: CanvasText;
177
+ }
178
+
179
+ .subagent-run__trigger:focus-visible {
180
+ outline: 2px solid Highlight;
181
+ outline-offset: 2px;
182
+ box-shadow: none;
183
+ }
184
+
185
+ .subagent-run__milestone::before {
186
+ border-color: CanvasText;
187
+ }
188
+ }
@@ -46,6 +46,7 @@
46
46
  min-inline-size: 0;
47
47
  min-block-size: 0;
48
48
  display: grid;
49
+ grid-template-columns: minmax(0, 1fr);
49
50
  grid-template-rows: minmax(0, 1fr);
50
51
  overflow: hidden;
51
52
  background: var(--sigvelo-color-surface);
@@ -57,6 +58,7 @@
57
58
  min-inline-size: 0;
58
59
  min-block-size: 0;
59
60
  display: grid;
61
+ grid-template-columns: minmax(0, 1fr);
60
62
  grid-template-rows: minmax(0, 1fr);
61
63
  overflow: hidden;
62
64
  }
@@ -78,7 +78,7 @@ declare const CHECKED_IN_CODEX_MODELS: readonly [{
78
78
  readonly upgradeInfo: null;
79
79
  readonly availabilityNux: null;
80
80
  readonly hidden: boolean;
81
- readonly inputModalities: ("text" | "image")[];
81
+ readonly inputModalities: ("image" | "text")[];
82
82
  readonly supportsPersonality: boolean;
83
83
  readonly additionalSpeedTiers: never[];
84
84
  readonly serviceTiers: never[];
@@ -98,7 +98,7 @@ declare const CHECKED_IN_CODEX_MODELS: readonly [{
98
98
  readonly upgradeInfo: null;
99
99
  readonly availabilityNux: null;
100
100
  readonly hidden: boolean;
101
- readonly inputModalities: ("text" | "image")[];
101
+ readonly inputModalities: ("image" | "text")[];
102
102
  readonly supportsPersonality: boolean;
103
103
  readonly additionalSpeedTiers: never[];
104
104
  readonly serviceTiers: never[];
@@ -115,7 +115,7 @@ declare const CHECKED_IN_CODEX_MODELS: readonly [{
115
115
  readonly upgradeInfo: null;
116
116
  readonly availabilityNux: null;
117
117
  readonly hidden: boolean;
118
- readonly inputModalities: ("text" | "image")[];
118
+ readonly inputModalities: ("image" | "text")[];
119
119
  readonly supportsPersonality: boolean;
120
120
  readonly additionalSpeedTiers: never[];
121
121
  readonly serviceTiers: never[];
@@ -132,7 +132,7 @@ declare const CHECKED_IN_CODEX_MODELS: readonly [{
132
132
  readonly upgradeInfo: null;
133
133
  readonly availabilityNux: null;
134
134
  readonly hidden: boolean;
135
- readonly inputModalities: ("text" | "image")[];
135
+ readonly inputModalities: ("image" | "text")[];
136
136
  readonly supportsPersonality: boolean;
137
137
  readonly additionalSpeedTiers: never[];
138
138
  readonly serviceTiers: never[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-b/react-components",
3
- "version": "0.14.1",
3
+ "version": "0.14.2",
4
4
  "description": "MCP-B React components built on Base UI and shared design tokens, including Cloudflare Think chat primitives.",
5
5
  "homepage": "https://design-system.sigvelo.com",
6
6
  "bugs": {
@@ -53,7 +53,7 @@
53
53
  "lucide-react": "^1.23.0",
54
54
  "shiki": "^3.23.0",
55
55
  "streamdown": "^2.5.0",
56
- "@mcp-b/design-tokens": "0.14.1"
56
+ "@mcp-b/design-tokens": "0.14.2"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@ai-sdk/react": "^3.0.222",