@agent-native/toolkit 0.198.5 → 0.198.6

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 (87) hide show
  1. package/dist/app/agentkit/react/components.d.ts +2 -1
  2. package/dist/app/agentkit/react/components.d.ts.map +1 -1
  3. package/dist/app/agentkit/react/components.js +86 -62
  4. package/dist/app/agentkit/react/components.js.map +1 -1
  5. package/dist/app/agentkit/react/styles.css +36 -24
  6. package/dist/app/chat/AgentKitAssistantChat.js +14 -7
  7. package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
  8. package/dist/app/chat/AgentPanel.d.ts +1 -1
  9. package/dist/app/chat/AgentPanel.d.ts.map +1 -1
  10. package/dist/app/chat/AgentPanel.js +11 -38
  11. package/dist/app/chat/AgentPanel.js.map +1 -1
  12. package/dist/app/chat/AgentSidebar.d.ts.map +1 -1
  13. package/dist/app/chat/AgentSidebar.js +3 -11
  14. package/dist/app/chat/AgentSidebar.js.map +1 -1
  15. package/dist/app/chat/chat/tool-call-display.d.ts +2 -1
  16. package/dist/app/chat/chat/tool-call-display.d.ts.map +1 -1
  17. package/dist/app/chat/chat/tool-call-display.js +83 -55
  18. package/dist/app/chat/chat/tool-call-display.js.map +1 -1
  19. package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
  20. package/dist/app/i18n/catalogs/ar-SA.js +1 -0
  21. package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
  22. package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
  23. package/dist/app/i18n/catalogs/de-DE.js +1 -0
  24. package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
  25. package/dist/app/i18n/catalogs/en-US.d.ts +1 -0
  26. package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
  27. package/dist/app/i18n/catalogs/en-US.js +1 -0
  28. package/dist/app/i18n/catalogs/en-US.js.map +1 -1
  29. package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
  30. package/dist/app/i18n/catalogs/es-ES.js +1 -0
  31. package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
  32. package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
  33. package/dist/app/i18n/catalogs/fr-FR.js +1 -0
  34. package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
  35. package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
  36. package/dist/app/i18n/catalogs/hi-IN.js +1 -0
  37. package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
  38. package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
  39. package/dist/app/i18n/catalogs/ja-JP.js +1 -0
  40. package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
  41. package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
  42. package/dist/app/i18n/catalogs/ko-KR.js +1 -0
  43. package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
  44. package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
  45. package/dist/app/i18n/catalogs/pt-BR.js +1 -0
  46. package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
  47. package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
  48. package/dist/app/i18n/catalogs/zh-CN.js +1 -0
  49. package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
  50. package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
  51. package/dist/app/i18n/catalogs/zh-TW.js +1 -0
  52. package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
  53. package/dist/composer/TiptapComposer.d.ts +1 -1
  54. package/dist/composer/TiptapComposer.d.ts.map +1 -1
  55. package/dist/composer/TiptapComposer.js +26 -23
  56. package/dist/composer/TiptapComposer.js.map +1 -1
  57. package/dist/ui/sonner.js +1 -1
  58. package/dist/ui/sonner.js.map +1 -1
  59. package/package.json +3 -3
  60. package/src/app/agentkit/react/components.tsx +156 -128
  61. package/src/app/agentkit/react/lifecycle.spec.tsx +556 -39
  62. package/src/app/agentkit/react/styles.css +36 -24
  63. package/src/app/chat/AgentKitAssistantChat.spec.tsx +22 -0
  64. package/src/app/chat/AgentKitAssistantChat.tsx +19 -9
  65. package/src/app/chat/AgentPanel.overlay.spec.tsx +28 -4
  66. package/src/app/chat/AgentPanel.tsx +51 -168
  67. package/src/app/chat/AgentSidebar.spec.tsx +19 -19
  68. package/src/app/chat/AgentSidebar.tsx +59 -94
  69. package/src/app/chat/chat/tool-call-display.spec.tsx +371 -15
  70. package/src/app/chat/chat/tool-call-display.tsx +154 -80
  71. package/src/app/i18n/catalogs/ar-SA.ts +1 -0
  72. package/src/app/i18n/catalogs/de-DE.ts +1 -0
  73. package/src/app/i18n/catalogs/en-US.ts +1 -0
  74. package/src/app/i18n/catalogs/es-ES.ts +1 -0
  75. package/src/app/i18n/catalogs/fr-FR.ts +1 -0
  76. package/src/app/i18n/catalogs/hi-IN.ts +1 -0
  77. package/src/app/i18n/catalogs/ja-JP.ts +1 -0
  78. package/src/app/i18n/catalogs/ko-KR.ts +1 -0
  79. package/src/app/i18n/catalogs/pt-BR.ts +1 -0
  80. package/src/app/i18n/catalogs/zh-CN.ts +1 -0
  81. package/src/app/i18n/catalogs/zh-TW.ts +1 -0
  82. package/src/app-shell/sidebar-overflow.spec.tsx +2 -1
  83. package/src/composer/PromptComposer.context.spec.tsx +28 -15
  84. package/src/composer/TiptapComposer.spec.ts +14 -2
  85. package/src/composer/TiptapComposer.tsx +77 -86
  86. package/src/ui/sonner.spec.ts +15 -0
  87. package/src/ui/sonner.tsx +1 -1
package/dist/ui/sonner.js CHANGED
@@ -3,7 +3,7 @@ import { useTheme } from "next-themes";
3
3
  import { Toaster as Sonner } from "sonner";
4
4
  import { cn } from "../utils.js";
5
5
  const toastWidthClasses = "group-[.toaster]:!w-[var(--width)] group-[.toaster]:!min-w-[min(20rem,calc(100vw_-_2rem))] group-[.toaster]:!max-w-[var(--width)] group-[.toaster]:!gap-3 group-[.toaster]:!break-normal";
6
- const toastContentClasses = "group-[.toast]:!min-w-[min(16rem,calc(100vw_-_14rem))] group-[.toast]:!flex-1 group-[.toast]:!basis-auto group-[.toast]:break-words";
6
+ const toastContentClasses = "group-[.toast]:!min-w-0 group-[.toast]:!flex-1 group-[.toast]:!basis-auto group-[.toast]:break-words";
7
7
  const toastButtonClasses = "group-[.toast]:!shrink-0 group-[.toast]:!whitespace-nowrap";
8
8
  const Toaster = ({ className, toastOptions, ...props }) => {
9
9
  const { theme = "system" } = useTheme();
@@ -1 +1 @@
1
- {"version":3,"file":"sonner.js","sourceRoot":"","sources":["../../src/ui/sonner.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE3C,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAIjC,MAAM,iBAAiB,GACrB,0LAA0L,CAAC;AAC7L,MAAM,mBAAmB,GACvB,qIAAqI,CAAC;AACxI,MAAM,kBAAkB,GACtB,4DAA4D,CAAC;AAE/D,MAAM,OAAO,GAAG,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,KAAK,EAAgB,EAAE,EAAE;IACtE,MAAM,EAAE,KAAK,GAAG,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC;IACxC,MAAM,UAAU,GAAG,YAAY,EAAE,UAAU,CAAC;IAE5C,OAAO,CACL,KAAC,MAAM,IACL,KAAK,EAAE,KAA8B,EACrC,SAAS,EAAE,EAAE,CACX,uDAAuD,EACvD,SAAS,CACV,EACD,YAAY,EAAE;YACZ,GAAG,YAAY;YACf,UAAU,EAAE;gBACV,GAAG,UAAU;gBACb,KAAK,EAAE,EAAE,CACP,iBAAiB,EACjB,uIAAuI,EACvI,UAAU,EAAE,KAAK,CAClB;gBACD,KAAK,EAAE,EAAE,CAAC,4BAA4B,EAAE,UAAU,EAAE,KAAK,CAAC;gBAC1D,WAAW,EAAE,EAAE,CACb,iEAAiE,EACjE,UAAU,EAAE,WAAW,CACxB;gBACD,OAAO,EAAE,EAAE,CAAC,mBAAmB,EAAE,UAAU,EAAE,OAAO,CAAC;gBACrD,YAAY,EAAE,EAAE,CACd,kBAAkB,EAClB,kEAAkE,EAClE,UAAU,EAAE,YAAY,CACzB;gBACD,YAAY,EAAE,EAAE,CACd,kBAAkB,EAClB,8DAA8D,EAC9D,UAAU,EAAE,YAAY,CACzB;aACF;SACF,KACG,KAAK,GACT,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"sonner.js","sourceRoot":"","sources":["../../src/ui/sonner.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE3C,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAIjC,MAAM,iBAAiB,GACrB,0LAA0L,CAAC;AAC7L,MAAM,mBAAmB,GACvB,sGAAsG,CAAC;AACzG,MAAM,kBAAkB,GACtB,4DAA4D,CAAC;AAE/D,MAAM,OAAO,GAAG,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,KAAK,EAAgB,EAAE,EAAE;IACtE,MAAM,EAAE,KAAK,GAAG,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC;IACxC,MAAM,UAAU,GAAG,YAAY,EAAE,UAAU,CAAC;IAE5C,OAAO,CACL,KAAC,MAAM,IACL,KAAK,EAAE,KAA8B,EACrC,SAAS,EAAE,EAAE,CACX,uDAAuD,EACvD,SAAS,CACV,EACD,YAAY,EAAE;YACZ,GAAG,YAAY;YACf,UAAU,EAAE;gBACV,GAAG,UAAU;gBACb,KAAK,EAAE,EAAE,CACP,iBAAiB,EACjB,uIAAuI,EACvI,UAAU,EAAE,KAAK,CAClB;gBACD,KAAK,EAAE,EAAE,CAAC,4BAA4B,EAAE,UAAU,EAAE,KAAK,CAAC;gBAC1D,WAAW,EAAE,EAAE,CACb,iEAAiE,EACjE,UAAU,EAAE,WAAW,CACxB;gBACD,OAAO,EAAE,EAAE,CAAC,mBAAmB,EAAE,UAAU,EAAE,OAAO,CAAC;gBACrD,YAAY,EAAE,EAAE,CACd,kBAAkB,EAClB,kEAAkE,EAClE,UAAU,EAAE,YAAY,CACzB;gBACD,YAAY,EAAE,EAAE,CACd,kBAAkB,EAClB,8DAA8D,EAC9D,UAAU,EAAE,YAAY,CACzB;aACF;SACF,KACG,KAAK,GACT,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/toolkit",
3
- "version": "0.198.5",
3
+ "version": "0.198.6",
4
4
  "description": "Reusable app-building UI and helpers for Agent-Native apps.",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -665,7 +665,7 @@
665
665
  "y-protocols": "^1.0.7",
666
666
  "yjs": "^13.6.33",
667
667
  "zod": "^4.3.6",
668
- "@agent-native/agentkit": "^0.198.5"
668
+ "@agent-native/agentkit": "^0.198.6"
669
669
  },
670
670
  "devDependencies": {
671
671
  "@excalidraw/excalidraw": "0.18.1",
@@ -686,7 +686,7 @@
686
686
  "typescript-7": "npm:typescript@^7.0.2",
687
687
  "vite": "8.1.0",
688
688
  "vitest": "^4.1.5",
689
- "@agent-native/core": "^0.198.5"
689
+ "@agent-native/core": "^0.198.6"
690
690
  },
691
691
  "peerDependencies": {
692
692
  "@agent-native/core": ">=0.196.0",
@@ -763,7 +763,23 @@ function RepeatedActivityCluster({
763
763
  );
764
764
  }
765
765
 
766
+ function formatToolDiagnostic(value: unknown): string | undefined {
767
+ if (value === undefined) return undefined;
768
+ if (typeof value === "string") return value || undefined;
769
+ try {
770
+ return JSON.stringify(value, null, 2) ?? String(value);
771
+ } catch {
772
+ return String(value);
773
+ }
774
+ }
775
+
766
776
  function toolToActivity(tool: AgentToolCall): AgentActivity {
777
+ const failed = tool.status === "failed";
778
+ const errorMessage = failed
779
+ ? ((tool.error?.message?.trim() ? tool.error.message : undefined) ??
780
+ formatToolDiagnostic(tool.output) ??
781
+ formatToolDiagnostic(tool.error?.details))
782
+ : undefined;
767
783
  return {
768
784
  id: tool.id,
769
785
  kind: inferAgentActivityKind(tool.name),
@@ -774,12 +790,17 @@ function toolToActivity(tool: AgentToolCall): AgentActivity {
774
790
  : tool.status === "running"
775
791
  ? "running"
776
792
  : tool.status,
777
- detail:
778
- typeof tool.output === "string"
793
+ detail: failed
794
+ ? undefined
795
+ : typeof tool.output === "string"
779
796
  ? tool.output
780
797
  : typeof tool.input === "string"
781
798
  ? tool.input
782
799
  : undefined,
800
+ summary:
801
+ failed && errorMessage
802
+ ? [{ type: "text", text: errorMessage }]
803
+ : undefined,
783
804
  };
784
805
  }
785
806
 
@@ -904,11 +925,13 @@ export function AgentActivityGroup({
904
925
  afterSequence,
905
926
  throughSequence,
906
927
  excludeAgentActivities = false,
928
+ isCurrentSegment = true,
907
929
  }: {
908
930
  runId?: RunId;
909
931
  afterSequence?: number;
910
932
  throughSequence?: number;
911
933
  excludeAgentActivities?: boolean;
934
+ isCurrentSegment?: boolean;
912
935
  }) {
913
936
  const { threadId, slots, registry, labels } = useAgentKit();
914
937
  const thread = useAgentThread();
@@ -1011,7 +1034,7 @@ export function AgentActivityGroup({
1011
1034
  const activityItems = items.filter(
1012
1035
  (activity) => !durableToolResultIds.has(activity.id),
1013
1036
  );
1014
- const latestActivity = activityItems.reduce<AgentActivity | undefined>(
1037
+ const latestRunningActivity = items.reduce<AgentActivity | undefined>(
1015
1038
  (current, activity) => {
1016
1039
  if (activity.status !== "running") return current;
1017
1040
  if (!current) return activity;
@@ -1046,38 +1069,37 @@ export function AgentActivityGroup({
1046
1069
  Number.isFinite(startedAt) && Number.isFinite(completedAt)
1047
1070
  ? Math.max(0, completedAt - startedAt)
1048
1071
  : undefined;
1072
+ const hasTerminalRunEvent = runEvents.some(
1073
+ (event) =>
1074
+ event.runId === runId &&
1075
+ (event.type === "run.completed" ||
1076
+ event.type === "run.failed" ||
1077
+ event.type === "run.cancelled"),
1078
+ );
1049
1079
  const activelyWorking =
1050
- throughSequence === undefined &&
1051
- (run === undefined ? running : run.status === "running");
1052
- const currentActivity = activelyWorking ? latestActivity : undefined;
1053
- const visiblyRunning =
1054
- throughSequence === undefined && activelyWorking && running;
1055
- const [elapsedAt, setElapsedAt] = useState<number>();
1056
- useEffect(() => {
1057
- if (!activelyWorking || !Number.isFinite(startedAt)) return;
1058
- const update = () => setElapsedAt(Date.now());
1059
- update();
1060
- const interval = globalThis.setInterval(update, 1_000);
1061
- return () => globalThis.clearInterval(interval);
1062
- }, [activelyWorking, startedAt]);
1063
- const activeDurationMs =
1064
- activelyWorking && elapsedAt !== undefined && Number.isFinite(startedAt)
1065
- ? Math.max(0, elapsedAt - startedAt)
1066
- : undefined;
1080
+ isCurrentSegment &&
1081
+ (run ? run.status === "running" : running && !hasTerminalRunEvent);
1067
1082
  const completedRunSummary =
1068
- throughSequence !== undefined ||
1069
- (items.length > 0 && !running) ||
1070
- runEvents.some(
1071
- (event) =>
1072
- event.runId === runId &&
1073
- (event.type === "run.completed" ||
1074
- event.type === "run.failed" ||
1075
- event.type === "run.cancelled"),
1076
- ) ||
1077
- (afterSequence === undefined &&
1078
- run !== undefined &&
1079
- ["completed", "failed", "cancelled"].includes(run.status));
1080
- if (items.length === 0) return null;
1083
+ !activelyWorking &&
1084
+ (throughSequence !== undefined ||
1085
+ (items.length > 0 && !running) ||
1086
+ hasTerminalRunEvent ||
1087
+ (afterSequence === undefined &&
1088
+ run !== undefined &&
1089
+ ["completed", "failed", "cancelled"].includes(run.status)));
1090
+ if (items.length === 0 && !activelyWorking) return null;
1091
+ const currentActivity = activelyWorking
1092
+ ? (latestRunningActivity ?? {
1093
+ id: `thinking:${runId ?? thread.id}`,
1094
+ kind: "model",
1095
+ label: labels.reasoning,
1096
+ status: "running",
1097
+ })
1098
+ : undefined;
1099
+ const currentActivityLabel =
1100
+ currentActivity?.label === "Contacting model"
1101
+ ? labels.reasoning
1102
+ : currentActivity?.label;
1081
1103
  const displayGroups = new Map<ActivityBucket, AgentActivity[][]>(
1082
1104
  ACTIVITY_BUCKET_ORDER.map((bucket) => [bucket, []]),
1083
1105
  );
@@ -1114,7 +1136,9 @@ export function AgentActivityGroup({
1114
1136
  }
1115
1137
  }
1116
1138
  const hasExpandableActivity = ACTIVITY_BUCKET_ORDER.some(
1117
- (bucket) => displayGroups.get(bucket)!.length > 0,
1139
+ (bucket) =>
1140
+ (!completedRunSummary || bucket !== "thinking") &&
1141
+ displayGroups.get(bucket)!.length > 0,
1118
1142
  );
1119
1143
  const activityBucketLabels = {
1120
1144
  thinking: "Thinking",
@@ -1130,34 +1154,15 @@ export function AgentActivityGroup({
1130
1154
  second: labels.durationSecondShort,
1131
1155
  });
1132
1156
  const summaryLabel = activelyWorking
1133
- ? activeDurationMs !== undefined && activeDurationMs >= 1_000
1134
- ? labels.workingFor.replace(
1135
- "{{duration}}",
1136
- formatDuration(activeDurationMs),
1137
- )
1138
- : labels.working
1157
+ ? ""
1139
1158
  : completedRunSummary
1140
1159
  ? durationMs !== undefined && durationMs >= 1_000
1141
1160
  ? labels.workedFor.replace("{{duration}}", formatDuration(durationMs))
1142
1161
  : labels.worked
1143
1162
  : labels.activities;
1163
+ const visiblyRunning = activelyWorking;
1144
1164
  return (
1145
1165
  <>
1146
- {items
1147
- .filter((activity) => activity.status === "failed")
1148
- .map((activity) => (
1149
- <div key={activity.id} className="agentkit-run-failure" role="alert">
1150
- <IconAlertCircle aria-hidden="true" className="agentkit-icon" />
1151
- <div className="agentkit-run-failure-copy">
1152
- <strong>{activity.label}</strong>
1153
- <span>
1154
- {toolMap.get(activity.id)?.error?.message ??
1155
- activity.detail ??
1156
- labels.error}
1157
- </span>
1158
- </div>
1159
- </div>
1160
- ))}
1161
1166
  {durableToolResults.length ? (
1162
1167
  <div data-agentkit-tool-results="true">
1163
1168
  {durableToolResults.map(({ tool, Renderer }) => (
@@ -1165,10 +1170,11 @@ export function AgentActivityGroup({
1165
1170
  ))}
1166
1171
  </div>
1167
1172
  ) : null}
1168
- {hasExpandableActivity ? (
1173
+ {hasExpandableActivity || activelyWorking ? (
1169
1174
  <AgentWorkDisclosure
1170
1175
  label={summaryLabel}
1171
1176
  running={visiblyRunning}
1177
+ expandable={hasExpandableActivity}
1172
1178
  current={
1173
1179
  currentActivity ? (
1174
1180
  <span
@@ -1182,8 +1188,8 @@ export function AgentActivityGroup({
1182
1188
  threadId={threadId}
1183
1189
  compact
1184
1190
  />
1185
- <span className="agentkit-activities-current-label">
1186
- {currentActivity.label}
1191
+ <span className="agentkit-activities-current-label agent-running-shimmer">
1192
+ {currentActivityLabel}
1187
1193
  </span>
1188
1194
  </span>
1189
1195
  ) : null
@@ -1191,6 +1197,7 @@ export function AgentActivityGroup({
1191
1197
  >
1192
1198
  <div className="agentkit-activities-list">
1193
1199
  {ACTIVITY_BUCKET_ORDER.map((bucket) => {
1200
+ if (completedRunSummary && bucket === "thinking") return null;
1194
1201
  const groups = displayGroups.get(bucket)!;
1195
1202
  if (groups.length === 0) return null;
1196
1203
  return (
@@ -1262,7 +1269,9 @@ export function AgentActivityGroup({
1262
1269
  </AgentWorkDisclosure>
1263
1270
  ) : (
1264
1271
  <div className="agentkit-activities-static">
1265
- <span className="agentkit-activities-label">{summaryLabel}</span>
1272
+ {summaryLabel ? (
1273
+ <span className="agentkit-activities-label">{summaryLabel}</span>
1274
+ ) : null}
1266
1275
  {currentActivity ? (
1267
1276
  <span
1268
1277
  className="agentkit-activities-current"
@@ -1275,8 +1284,8 @@ export function AgentActivityGroup({
1275
1284
  threadId={threadId}
1276
1285
  compact
1277
1286
  />
1278
- <span className="agentkit-activities-current-label">
1279
- {currentActivity.label}
1287
+ <span className="agentkit-activities-current-label agent-running-shimmer">
1288
+ {currentActivityLabel}
1280
1289
  </span>
1281
1290
  </span>
1282
1291
  ) : null}
@@ -1289,11 +1298,13 @@ export function AgentActivityGroup({
1289
1298
  function AgentWorkDisclosure({
1290
1299
  label,
1291
1300
  running,
1301
+ expandable = true,
1292
1302
  current,
1293
1303
  children,
1294
1304
  }: {
1295
1305
  label: string;
1296
1306
  running?: boolean;
1307
+ expandable?: boolean;
1297
1308
  current?: ReactNode;
1298
1309
  children: ReactNode;
1299
1310
  }) {
@@ -1302,23 +1313,30 @@ function AgentWorkDisclosure({
1302
1313
  <details
1303
1314
  className="agentkit-activities"
1304
1315
  data-running={running ? "true" : undefined}
1316
+ data-expandable={expandable ? "true" : "false"}
1305
1317
  open={open}
1306
1318
  >
1307
1319
  <summary
1308
1320
  className="agentkit-activities-summary"
1321
+ aria-disabled={!expandable}
1309
1322
  onClick={(event) => {
1310
1323
  event.preventDefault();
1324
+ if (!expandable) return;
1311
1325
  setOpen((value) => !value);
1312
1326
  }}
1313
1327
  >
1314
- <span className="agentkit-activities-heading">
1315
- <span className="agentkit-activities-label">{label}</span>
1316
- <IconChevronRight
1317
- aria-hidden="true"
1318
- className="agentkit-icon agentkit-summary-chevron"
1319
- />
1328
+ <span className="agentkit-activities-summary-content">
1329
+ {label ? (
1330
+ <span className="agentkit-activities-heading">
1331
+ <span className="agentkit-activities-label">{label}</span>
1332
+ </span>
1333
+ ) : null}
1334
+ {current}
1320
1335
  </span>
1321
- {current}
1336
+ <IconChevronRight
1337
+ aria-hidden="true"
1338
+ className="agentkit-icon agentkit-summary-chevron"
1339
+ />
1322
1340
  </summary>
1323
1341
  {children}
1324
1342
  </details>
@@ -1359,9 +1377,7 @@ const ACTIVITY_BUCKET_ORDER: ActivityBucket[] = [
1359
1377
  ];
1360
1378
 
1361
1379
  function activityBucketForKind(kind: string): ActivityBucket {
1362
- if (kind === "reasoning" || kind === "model" || kind === "status") {
1363
- return "thinking";
1364
- }
1380
+ if (kind === "reasoning") return "thinking";
1365
1381
  if (kind === "search" || kind === "read") return "research";
1366
1382
  if (
1367
1383
  kind === "write" ||
@@ -2451,6 +2467,9 @@ export function AgentMessageActions({
2451
2467
  () => resolveAgentMessageRequestId(message, thread.events),
2452
2468
  [message, thread.events],
2453
2469
  );
2470
+ const hasMessageMenuActions = Boolean(
2471
+ requestId || (forkingCapability.visible && onThreadForked),
2472
+ );
2454
2473
  const runId = useMemo(
2455
2474
  () => resolveAgentMessageRunId(message, thread.events),
2456
2475
  [message, thread.events],
@@ -2569,7 +2588,11 @@ export function AgentMessageActions({
2569
2588
  forkAction.error ??
2570
2589
  regenerateAction.error;
2571
2590
  return (
2572
- <div className="agentkit-message-actions" data-role={message.role}>
2591
+ <div
2592
+ className="agentkit-message-actions"
2593
+ data-role={message.role}
2594
+ data-streaming={message.status === "streaming" ? "true" : undefined}
2595
+ >
2573
2596
  {message.role === "assistant" ? (
2574
2597
  <>
2575
2598
  <div className="agentkit-message-actions-leading">
@@ -2752,63 +2775,67 @@ export function AgentMessageActions({
2752
2775
  threadId={threadId}
2753
2776
  />
2754
2777
  ) : null}
2755
- <Menu
2756
- open={actionsMenuOpen}
2757
- onOpenChange={(open) => {
2758
- setActionsMenuOpen(open);
2759
- if (!open) setRequestIdCopied(false);
2760
- }}
2761
- placement="bottom"
2762
- align="end"
2763
- className="agentkit-message-menu w-48"
2764
- trigger={
2765
- <IconButton
2766
- label={labels.messageActions}
2767
- icon={<IconDotsVertical aria-hidden="true" />}
2768
- size="compact"
2769
- aria-expanded={actionsMenuOpen}
2770
- title={labels.messageActions}
2771
- />
2772
- }
2773
- items={[
2774
- {
2775
- id: "copy-request-id",
2776
- label: requestIdCopied
2777
- ? labels.copied
2778
- : requestId
2779
- ? labels.copyRequestId
2780
- : labels.requestIdUnavailable,
2781
- icon: requestIdCopied ? (
2782
- <IconCircleCheck size={14} aria-hidden="true" />
2783
- ) : (
2784
- <IconId size={14} aria-hidden="true" />
2785
- ),
2786
- disabled: !requestId || requestIdAction.pending,
2787
- },
2788
- ...(forkingCapability.visible && onThreadForked
2789
- ? [
2790
- {
2791
- id: "fork-chat",
2792
- label: (
2793
- <span title={forkingCapability.reason}>
2794
- {labels.fork}
2795
- </span>
2796
- ),
2797
- icon: <IconGitBranch size={14} aria-hidden="true" />,
2798
- disabled:
2799
- !forkingCapability.enabled || forkAction.pending,
2800
- },
2801
- ]
2802
- : []),
2803
- ]}
2804
- onAction={(id) => {
2805
- if (id === "copy-request-id") {
2806
- void requestIdAction.execute().catch(() => undefined);
2807
- } else if (id === "fork-chat") {
2808
- void forkAction.execute().catch(() => undefined);
2778
+ {hasMessageMenuActions ? (
2779
+ <Menu
2780
+ open={actionsMenuOpen}
2781
+ onOpenChange={(open) => {
2782
+ setActionsMenuOpen(open);
2783
+ if (!open) setRequestIdCopied(false);
2784
+ }}
2785
+ placement="bottom"
2786
+ align="end"
2787
+ className="agentkit-message-menu w-48"
2788
+ trigger={
2789
+ <IconButton
2790
+ label={labels.messageActions}
2791
+ icon={<IconDotsVertical aria-hidden="true" />}
2792
+ size="compact"
2793
+ aria-expanded={actionsMenuOpen}
2794
+ title={labels.messageActions}
2795
+ />
2809
2796
  }
2810
- }}
2811
- />
2797
+ items={[
2798
+ ...(requestId
2799
+ ? [
2800
+ {
2801
+ id: "copy-request-id",
2802
+ label: requestIdCopied
2803
+ ? labels.copied
2804
+ : labels.copyRequestId,
2805
+ icon: requestIdCopied ? (
2806
+ <IconCircleCheck size={14} aria-hidden="true" />
2807
+ ) : (
2808
+ <IconId size={14} aria-hidden="true" />
2809
+ ),
2810
+ disabled: requestIdAction.pending,
2811
+ },
2812
+ ]
2813
+ : []),
2814
+ ...(forkingCapability.visible && onThreadForked
2815
+ ? [
2816
+ {
2817
+ id: "fork-chat",
2818
+ label: (
2819
+ <span title={forkingCapability.reason}>
2820
+ {labels.fork}
2821
+ </span>
2822
+ ),
2823
+ icon: <IconGitBranch size={14} aria-hidden="true" />,
2824
+ disabled:
2825
+ !forkingCapability.enabled || forkAction.pending,
2826
+ },
2827
+ ]
2828
+ : []),
2829
+ ]}
2830
+ onAction={(id) => {
2831
+ if (id === "copy-request-id") {
2832
+ void requestIdAction.execute().catch(() => undefined);
2833
+ } else if (id === "fork-chat") {
2834
+ void forkAction.execute().catch(() => undefined);
2835
+ }
2836
+ }}
2837
+ />
2838
+ ) : null}
2812
2839
  </div>
2813
2840
  </>
2814
2841
  ) : (
@@ -4215,6 +4242,7 @@ export function AgentKitChat({
4215
4242
  afterSequence={afterSequence}
4216
4243
  throughSequence={throughSequence}
4217
4244
  excludeAgentActivities
4245
+ isCurrentSegment={throughSequence === undefined}
4218
4246
  />
4219
4247
  </AgentKitSurfaceBoundary>
4220
4248
  );