@agent-native/toolkit 0.198.4 → 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.
- package/dist/app/agentkit/react/components.d.ts +6 -3
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +98 -68
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/styles.css +36 -24
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +32 -15
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/AgentPanel.d.ts +1 -1
- package/dist/app/chat/AgentPanel.d.ts.map +1 -1
- package/dist/app/chat/AgentPanel.js +11 -38
- package/dist/app/chat/AgentPanel.js.map +1 -1
- package/dist/app/chat/AgentSidebar.d.ts.map +1 -1
- package/dist/app/chat/AgentSidebar.js +3 -11
- package/dist/app/chat/AgentSidebar.js.map +1 -1
- package/dist/app/chat/chat/tool-call-display.d.ts +2 -1
- package/dist/app/chat/chat/tool-call-display.d.ts.map +1 -1
- package/dist/app/chat/chat/tool-call-display.js +83 -55
- package/dist/app/chat/chat/tool-call-display.js.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +1 -0
- package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.js +1 -0
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +1 -0
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +1 -0
- package/dist/app/i18n/catalogs/en-US.js.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.js +1 -0
- package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.js +1 -0
- package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.js +1 -0
- package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.js +1 -0
- package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.js +1 -0
- package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.js +1 -0
- package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.js +1 -0
- package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.js +1 -0
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/composer/PromptComposer.d.ts +3 -0
- package/dist/composer/PromptComposer.d.ts.map +1 -1
- package/dist/composer/PromptComposer.js +2 -2
- package/dist/composer/PromptComposer.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts +4 -1
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +32 -25
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/ui/sonner.js +1 -1
- package/dist/ui/sonner.js.map +1 -1
- package/package.json +3 -3
- package/src/app/agentkit/react/components.interaction.spec.tsx +93 -0
- package/src/app/agentkit/react/components.spec.tsx +1 -2
- package/src/app/agentkit/react/components.tsx +185 -132
- package/src/app/agentkit/react/composer-context.spec.tsx +7 -0
- package/src/app/agentkit/react/lifecycle.spec.tsx +556 -39
- package/src/app/agentkit/react/styles.css +36 -24
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +60 -1
- package/src/app/chat/AgentKitAssistantChat.tsx +45 -14
- package/src/app/chat/AgentPanel.overlay.spec.tsx +28 -4
- package/src/app/chat/AgentPanel.tsx +51 -168
- package/src/app/chat/AgentSidebar.spec.tsx +19 -19
- package/src/app/chat/AgentSidebar.tsx +59 -94
- package/src/app/chat/chat/tool-call-display.spec.tsx +371 -15
- package/src/app/chat/chat/tool-call-display.tsx +154 -80
- package/src/app/i18n/catalogs/ar-SA.ts +1 -0
- package/src/app/i18n/catalogs/de-DE.ts +1 -0
- package/src/app/i18n/catalogs/en-US.ts +1 -0
- package/src/app/i18n/catalogs/es-ES.ts +1 -0
- package/src/app/i18n/catalogs/fr-FR.ts +1 -0
- package/src/app/i18n/catalogs/hi-IN.ts +1 -0
- package/src/app/i18n/catalogs/ja-JP.ts +1 -0
- package/src/app/i18n/catalogs/ko-KR.ts +1 -0
- package/src/app/i18n/catalogs/pt-BR.ts +1 -0
- package/src/app/i18n/catalogs/zh-CN.ts +1 -0
- package/src/app/i18n/catalogs/zh-TW.ts +1 -0
- package/src/app-shell/sidebar-overflow.spec.tsx +2 -1
- package/src/composer/PromptComposer.context.spec.tsx +28 -15
- package/src/composer/PromptComposer.tsx +7 -0
- package/src/composer/TiptapComposer.spec.ts +40 -6
- package/src/composer/TiptapComposer.tsx +89 -89
- package/src/ui/sonner.spec.ts +15 -0
- package/src/ui/sonner.tsx +1 -1
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
1051
|
-
(run
|
|
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
|
-
|
|
1069
|
-
(
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
(
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
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) =>
|
|
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
|
-
?
|
|
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
|
-
{
|
|
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
|
-
|
|
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
|
-
{
|
|
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-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
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
|
-
|
|
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"
|
|
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
|
|
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
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
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
|
) : (
|
|
@@ -3054,6 +3081,7 @@ export interface AgentKitComposerProps extends Omit<
|
|
|
3054
3081
|
| "extraActionButton"
|
|
3055
3082
|
| "onSubmit"
|
|
3056
3083
|
| "onBeforeSubmit"
|
|
3084
|
+
| "onSubmissionPendingChange"
|
|
3057
3085
|
| "onAttachmentError"
|
|
3058
3086
|
| "interceptBuildRequestsForBuilder"
|
|
3059
3087
|
| "planModeDisabled"
|
|
@@ -3068,6 +3096,8 @@ export interface AgentKitComposerProps extends Omit<
|
|
|
3068
3096
|
composerRef?: { current: TiptapComposerHandle | null };
|
|
3069
3097
|
threadId?: string;
|
|
3070
3098
|
className?: string;
|
|
3099
|
+
/** The host transcript renders its own accessible submission status. */
|
|
3100
|
+
announcePendingSubmission?: boolean;
|
|
3071
3101
|
queueWhileRunning?: boolean;
|
|
3072
3102
|
showModelSelector?: boolean;
|
|
3073
3103
|
/** Controlled execution mode for agent-native act/plan workflows. */
|
|
@@ -3087,6 +3117,7 @@ function hasActiveRuns(thread: AgentThreadState): boolean {
|
|
|
3087
3117
|
export function AgentKitComposer({
|
|
3088
3118
|
threadId: requestedThreadId,
|
|
3089
3119
|
className,
|
|
3120
|
+
announcePendingSubmission = true,
|
|
3090
3121
|
queueWhileRunning = true,
|
|
3091
3122
|
showModelSelector = true,
|
|
3092
3123
|
slashCommands,
|
|
@@ -3135,6 +3166,7 @@ export function AgentKitComposer({
|
|
|
3135
3166
|
extraActionButton,
|
|
3136
3167
|
onSubmit: onSubmitOverride,
|
|
3137
3168
|
onBeforeSubmit,
|
|
3169
|
+
onSubmissionPendingChange,
|
|
3138
3170
|
onAttachmentError,
|
|
3139
3171
|
interceptBuildRequestsForBuilder,
|
|
3140
3172
|
planModeDisabled,
|
|
@@ -3191,6 +3223,15 @@ export function AgentKitComposer({
|
|
|
3191
3223
|
threadId,
|
|
3192
3224
|
);
|
|
3193
3225
|
const submissionBlocked = Boolean(submissionDisabled) || command.pending;
|
|
3226
|
+
const [submissionPending, setSubmissionPending] = useState(false);
|
|
3227
|
+
const handleSubmissionPendingChange = useCallback(
|
|
3228
|
+
(pending: boolean) => {
|
|
3229
|
+
setSubmissionPending(pending);
|
|
3230
|
+
onSubmissionPendingChange?.(pending);
|
|
3231
|
+
},
|
|
3232
|
+
[onSubmissionPendingChange],
|
|
3233
|
+
);
|
|
3234
|
+
const suggestionSubmitBlocked = submissionBlocked || submissionPending;
|
|
3194
3235
|
const localComposerRef = useRef<TiptapComposerHandle>(null);
|
|
3195
3236
|
const composerRef = hostComposerRef ?? localComposerRef;
|
|
3196
3237
|
const selectedSuggestionRef = useRef<
|
|
@@ -3513,7 +3554,7 @@ export function AgentKitComposer({
|
|
|
3513
3554
|
) => {
|
|
3514
3555
|
if (
|
|
3515
3556
|
disabled ||
|
|
3516
|
-
|
|
3557
|
+
suggestionSubmitBlocked ||
|
|
3517
3558
|
!suggestionsCapability.enabled ||
|
|
3518
3559
|
selectedSuggestionRef.current ||
|
|
3519
3560
|
!isCurrentAgentSuggestion(controller.getThread(threadId), suggestion)
|
|
@@ -3536,6 +3577,15 @@ export function AgentKitComposer({
|
|
|
3536
3577
|
const suggestions = selectAgentSuggestions(thread);
|
|
3537
3578
|
return (
|
|
3538
3579
|
<div className={`agentkit-composer-stack ${className ?? ""}`}>
|
|
3580
|
+
{announcePendingSubmission && submissionPending ? (
|
|
3581
|
+
<span
|
|
3582
|
+
className="agentkit-visually-hidden"
|
|
3583
|
+
role="status"
|
|
3584
|
+
aria-live="polite"
|
|
3585
|
+
>
|
|
3586
|
+
{labels.activityBuckets?.thinking ?? "Thinking"}
|
|
3587
|
+
</span>
|
|
3588
|
+
) : null}
|
|
3539
3589
|
{queueCapability.visible ? (
|
|
3540
3590
|
Queue ? (
|
|
3541
3591
|
<Queue
|
|
@@ -3611,14 +3661,14 @@ export function AgentKitComposer({
|
|
|
3611
3661
|
<Suggestions
|
|
3612
3662
|
suggestions={suggestions}
|
|
3613
3663
|
threadId={threadId}
|
|
3614
|
-
pending={
|
|
3664
|
+
pending={suggestionSubmitBlocked}
|
|
3615
3665
|
onSelect={selectSuggestion}
|
|
3616
3666
|
/>
|
|
3617
3667
|
) : (
|
|
3618
3668
|
<AgentSuggestionBar
|
|
3619
3669
|
suggestions={suggestions.map((suggestion) => ({
|
|
3620
3670
|
...suggestion,
|
|
3621
|
-
disabled:
|
|
3671
|
+
disabled: suggestionSubmitBlocked || Boolean(disabled),
|
|
3622
3672
|
}))}
|
|
3623
3673
|
ariaLabel={labels.suggestions}
|
|
3624
3674
|
onSelect={selectSuggestion}
|
|
@@ -3646,7 +3696,6 @@ export function AgentKitComposer({
|
|
|
3646
3696
|
imageModelMenu={imageModelMenu}
|
|
3647
3697
|
autoFocus={autoFocus}
|
|
3648
3698
|
composerRef={composerRef}
|
|
3649
|
-
submitting={command.pending}
|
|
3650
3699
|
willQueue={active && queueWhileRunning && canQueue}
|
|
3651
3700
|
showModelSelector={showModelSelector && canSelectModel}
|
|
3652
3701
|
availableModels={availableModels}
|
|
@@ -3669,8 +3718,11 @@ export function AgentKitComposer({
|
|
|
3669
3718
|
initialTextKey={composerInitialTextKey}
|
|
3670
3719
|
onTextChange={onTextChange}
|
|
3671
3720
|
extraActionButton={extraActionButton}
|
|
3721
|
+
sendButtonDisabled={submissionPending}
|
|
3672
3722
|
onBeforeSubmit={onBeforeSubmit}
|
|
3723
|
+
onSubmissionPendingChange={handleSubmissionPendingChange}
|
|
3673
3724
|
getSubmitFailureDraftScope={getSubmitFailureDraftScope}
|
|
3725
|
+
clearOnSubmitImmediately
|
|
3674
3726
|
onAttachmentError={reportAttachmentError}
|
|
3675
3727
|
interceptBuildRequestsForBuilder={interceptBuildRequestsForBuilder}
|
|
3676
3728
|
planModeDisabled={planModeDisabled}
|
|
@@ -4190,6 +4242,7 @@ export function AgentKitChat({
|
|
|
4190
4242
|
afterSequence={afterSequence}
|
|
4191
4243
|
throughSequence={throughSequence}
|
|
4192
4244
|
excludeAgentActivities
|
|
4245
|
+
isCurrentSegment={throughSequence === undefined}
|
|
4193
4246
|
/>
|
|
4194
4247
|
</AgentKitSurfaceBoundary>
|
|
4195
4248
|
);
|
|
@@ -317,6 +317,7 @@ describe("AgentKit composer context submission", () => {
|
|
|
317
317
|
expect(capture.props).toMatchObject({
|
|
318
318
|
contextItems: source,
|
|
319
319
|
contextMenuItems,
|
|
320
|
+
clearOnSubmitImmediately: true,
|
|
320
321
|
onRemoveContextItem,
|
|
321
322
|
onInspectContextItem,
|
|
322
323
|
onRetryContextItem,
|
|
@@ -332,6 +333,7 @@ describe("AgentKit composer context submission", () => {
|
|
|
332
333
|
];
|
|
333
334
|
let pending: void | Promise<void>;
|
|
334
335
|
await act(async () => {
|
|
336
|
+
capture.props!.onSubmissionPendingChange?.(true);
|
|
335
337
|
pending = capture.props!.onSubmit("Review", [], references, {
|
|
336
338
|
contextItems: source,
|
|
337
339
|
composerModeContext: "Use scheduling tools for this request.",
|
|
@@ -341,6 +343,9 @@ describe("AgentKit composer context submission", () => {
|
|
|
341
343
|
expect(beforeSend).toHaveBeenCalledOnce();
|
|
342
344
|
expect(runtime.startRun).not.toHaveBeenCalled();
|
|
343
345
|
expect(runtime.queueMessage).not.toHaveBeenCalled();
|
|
346
|
+
expect(container.querySelector('[role="status"]')?.textContent).toBe(
|
|
347
|
+
"Thinking",
|
|
348
|
+
);
|
|
344
349
|
expect(Object.isFrozen(saved)).toBe(true);
|
|
345
350
|
expect(Object.isFrozen(saved!.contextItems![0])).toBe(true);
|
|
346
351
|
expect(Object.isFrozen(saved!.references[0].metadata)).toBe(true);
|
|
@@ -349,7 +354,9 @@ describe("AgentKit composer context submission", () => {
|
|
|
349
354
|
await act(async () => {
|
|
350
355
|
release();
|
|
351
356
|
await pending;
|
|
357
|
+
capture.props!.onSubmissionPendingChange?.(false);
|
|
352
358
|
});
|
|
359
|
+
expect(container.querySelector('[role="status"]')).toBeNull();
|
|
353
360
|
const input =
|
|
354
361
|
intent === "queued"
|
|
355
362
|
? runtime.queueMessage.mock.calls[0][0]
|