@springbrand/message-panel 0.1.3-alpha.0 → 0.1.3-alpha.1
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/package.json
CHANGED
|
@@ -74,6 +74,7 @@ export interface CamelChatMessagesProps {
|
|
|
74
74
|
isServerStreaming?: boolean;
|
|
75
75
|
/** Show the opt-in activity bar for recovering or server-streaming states. */
|
|
76
76
|
showActivityStatus?: boolean;
|
|
77
|
+
activityStatusLabel?: string;
|
|
77
78
|
hasPendingSteer?: boolean;
|
|
78
79
|
startedWithPending?: boolean;
|
|
79
80
|
error?: unknown;
|
|
@@ -403,16 +404,21 @@ function CamelToolRow({
|
|
|
403
404
|
onApprove: (approvalId: string, decision: ToolApprovalDecision) => void;
|
|
404
405
|
getToolApproval?: (part: unknown) => ToolApprovalView | undefined;
|
|
405
406
|
}) {
|
|
406
|
-
const [open, setOpen] = useState(false);
|
|
407
407
|
const approval = getToolApproval?.(part) ?? toolApprovalOf(part);
|
|
408
408
|
const pendingApproval = approval && approval.approved === undefined;
|
|
409
409
|
const presentation = getCamelToolPresentation(part, isActive);
|
|
410
|
+
const autoOpen = presentation.running && (
|
|
411
|
+
presentation.isSubAgent ||
|
|
412
|
+
presentation.kind === "write" ||
|
|
413
|
+
presentation.kind === "edit"
|
|
414
|
+
);
|
|
415
|
+
const [open, setOpen] = useState(autoOpen);
|
|
410
416
|
const hasDetails = children != null || presentation.hasDetails;
|
|
411
417
|
const title = presentation.summary;
|
|
412
418
|
|
|
413
419
|
useEffect(() => {
|
|
414
|
-
if (
|
|
415
|
-
}, [
|
|
420
|
+
if (autoOpen) setOpen(true);
|
|
421
|
+
}, [autoOpen]);
|
|
416
422
|
|
|
417
423
|
return (
|
|
418
424
|
<div data-part-type={normalizedPartType(part)}>
|
|
@@ -1189,6 +1195,11 @@ function AssistantTurn({
|
|
|
1189
1195
|
const thinkingActivity = deriveThinkingActivity(
|
|
1190
1196
|
turn.traceParts.at(-1)?.part ?? turn.finalParts.at(-1)?.part,
|
|
1191
1197
|
);
|
|
1198
|
+
const hasRunningTool = turn.traceParts.some(
|
|
1199
|
+
({ part }) =>
|
|
1200
|
+
toolNameOfPart(part) !== null &&
|
|
1201
|
+
getCamelToolPresentation(part, isActive).running,
|
|
1202
|
+
);
|
|
1192
1203
|
const activeActivity = hasPendingSteer
|
|
1193
1204
|
? pendingSteerActivity
|
|
1194
1205
|
: thinkingActivity;
|
|
@@ -1269,7 +1280,7 @@ function AssistantTurn({
|
|
|
1269
1280
|
{turn.copyText && <ClipboardAction text={turn.copyText} />}
|
|
1270
1281
|
</div>
|
|
1271
1282
|
)}
|
|
1272
|
-
{isActive && turn.finalParts.length === 0 && (
|
|
1283
|
+
{isActive && turn.finalParts.length === 0 && !hasRunningTool && (
|
|
1273
1284
|
<ThinkingIndicator {...activeActivity} />
|
|
1274
1285
|
)}
|
|
1275
1286
|
</div>
|
|
@@ -1285,6 +1296,7 @@ export function CamelChatMessages({
|
|
|
1285
1296
|
isRecovering = false,
|
|
1286
1297
|
isServerStreaming = false,
|
|
1287
1298
|
showActivityStatus = false,
|
|
1299
|
+
activityStatusLabel,
|
|
1288
1300
|
hasPendingSteer = false,
|
|
1289
1301
|
startedWithPending = false,
|
|
1290
1302
|
error,
|
|
@@ -1345,7 +1357,7 @@ export function CamelChatMessages({
|
|
|
1345
1357
|
role="status"
|
|
1346
1358
|
>
|
|
1347
1359
|
<span className="size-1.5 animate-pulse rounded-full bg-blue-500" />
|
|
1348
|
-
{isRecovering ? "Recovering…" : "Running…"}
|
|
1360
|
+
{activityStatusLabel ?? (isRecovering ? "Recovering…" : "Running…")}
|
|
1349
1361
|
</div>
|
|
1350
1362
|
)}
|
|
1351
1363
|
<div
|
package/src/camel/camel-turn.ts
CHANGED
|
@@ -169,11 +169,20 @@ function isTraceWork(
|
|
|
169
169
|
if (isVisibleReasoning(part)) return true;
|
|
170
170
|
const kind = resolvePartKind(part);
|
|
171
171
|
if (kind === "plan") return false;
|
|
172
|
-
|
|
173
|
-
if (toolName !== null && finalToolNames.includes(toolName)) return false;
|
|
172
|
+
if (isFinalOutputTool(part, finalToolNames)) return false;
|
|
174
173
|
return TRACE_PART_KINDS.has(kind ?? "");
|
|
175
174
|
}
|
|
176
175
|
|
|
176
|
+
function isFinalOutputTool(
|
|
177
|
+
part: CamelPart,
|
|
178
|
+
finalToolNames: readonly string[],
|
|
179
|
+
): boolean {
|
|
180
|
+
const toolName = toolNameOfPart(part);
|
|
181
|
+
return toolName !== null &&
|
|
182
|
+
(finalToolNames.includes(toolName) ||
|
|
183
|
+
resolvePartKind(part) === "suggestions");
|
|
184
|
+
}
|
|
185
|
+
|
|
177
186
|
function isTraceBoundary(
|
|
178
187
|
part: CamelPart,
|
|
179
188
|
finalToolNames: readonly string[],
|
|
@@ -226,8 +235,17 @@ export function projectCamelAssistantTurn(
|
|
|
226
235
|
partIndex,
|
|
227
236
|
part,
|
|
228
237
|
}));
|
|
229
|
-
let
|
|
238
|
+
let finalOutputBoundary = parts.length;
|
|
230
239
|
for (let index = parts.length - 1; index >= 0; index -= 1) {
|
|
240
|
+
if (isFinalOutputTool(parts[index].part, finalToolNames)) {
|
|
241
|
+
finalOutputBoundary = index;
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
let lastTraceBoundary = -1;
|
|
246
|
+
// Provider cleanup steps after final output must not pull the answer back
|
|
247
|
+
// into the collapsible work trace.
|
|
248
|
+
for (let index = finalOutputBoundary - 1; index >= 0; index -= 1) {
|
|
231
249
|
if (isTraceBoundary(parts[index].part, finalToolNames)) {
|
|
232
250
|
lastTraceBoundary = index;
|
|
233
251
|
break;
|
package/src/parts/plan.ts
CHANGED
|
@@ -26,8 +26,9 @@ export function planStepsOfPart(part: unknown): PlanStep[] {
|
|
|
26
26
|
const value = recordOf(step);
|
|
27
27
|
const text = typeof value.text === "string" ? value.text.trim() : "";
|
|
28
28
|
if (!text) return [];
|
|
29
|
-
const status =
|
|
30
|
-
|
|
29
|
+
const status = value.status === "completed"
|
|
30
|
+
? "done"
|
|
31
|
+
: value.status === "in_progress" || value.status === "done"
|
|
31
32
|
? value.status
|
|
32
33
|
: "pending";
|
|
33
34
|
return [{ text, status }];
|