@cadraos/sdk 0.1.11-test → 0.1.13
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/chat/index.cjs +1209 -288
- package/dist/chat/index.cjs.map +1 -1
- package/dist/chat/index.d.cts +303 -39
- package/dist/chat/index.d.ts +303 -39
- package/dist/chat/index.js +1204 -289
- package/dist/chat/index.js.map +1 -1
- package/dist/index.cjs +52 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +52 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -6
- package/dist/chat/styles.css +0 -1
package/dist/chat/index.cjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var react = require('react');
|
|
4
4
|
var fetchEventSource = require('@microsoft/fetch-event-source');
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
var reactDom = require('react-dom');
|
|
6
7
|
var ReactMarkdown = require('react-markdown');
|
|
7
8
|
var remarkGfm = require('remark-gfm');
|
|
8
9
|
|
|
@@ -588,9 +589,11 @@ var DEFAULT_STREAMING_CONFIG = {
|
|
|
588
589
|
activityTimeoutMs: 3e4,
|
|
589
590
|
pollingIntervalMs: 2e3
|
|
590
591
|
};
|
|
592
|
+
var DEFAULT_POLLING_ENABLED = true;
|
|
591
593
|
var ExecutionStreamControllerImpl = class {
|
|
592
594
|
options;
|
|
593
595
|
config;
|
|
596
|
+
pollingEnabled;
|
|
594
597
|
sseClient = null;
|
|
595
598
|
status = "connecting";
|
|
596
599
|
reconnectAttempts = 0;
|
|
@@ -624,6 +627,7 @@ var ExecutionStreamControllerImpl = class {
|
|
|
624
627
|
constructor(options) {
|
|
625
628
|
this.options = options;
|
|
626
629
|
this.config = { ...DEFAULT_STREAMING_CONFIG, ...options.config };
|
|
630
|
+
this.pollingEnabled = options.pollingEnabled ?? DEFAULT_POLLING_ENABLED;
|
|
627
631
|
}
|
|
628
632
|
/**
|
|
629
633
|
* Get the last event ID (for resume support)
|
|
@@ -964,15 +968,61 @@ var ExecutionStreamControllerImpl = class {
|
|
|
964
968
|
if (this.status === "closed") {
|
|
965
969
|
return;
|
|
966
970
|
}
|
|
971
|
+
await this.recoverState();
|
|
972
|
+
if (this.status === "closed") {
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
967
975
|
try {
|
|
968
976
|
await this.connectSSE();
|
|
969
977
|
} catch {
|
|
970
978
|
await this.handleConnectionError(error);
|
|
971
979
|
}
|
|
972
980
|
} else {
|
|
973
|
-
this.
|
|
974
|
-
|
|
975
|
-
|
|
981
|
+
if (this.pollingEnabled) {
|
|
982
|
+
this.status = "fallback_polling";
|
|
983
|
+
this.emit("connectionChange", { connected: false, usingFallback: true });
|
|
984
|
+
this.startPolling();
|
|
985
|
+
} else {
|
|
986
|
+
this.handleError({
|
|
987
|
+
error: "SSE connection failed and polling is disabled",
|
|
988
|
+
errorCode: "connection_failed"
|
|
989
|
+
});
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
/**
|
|
994
|
+
* Recover state by checking execution status.
|
|
995
|
+
*
|
|
996
|
+
* Called during reconnection to catch any events missed while SSE was down.
|
|
997
|
+
* If the execution completed while disconnected, emits completion immediately.
|
|
998
|
+
* Otherwise, emits any new logs that weren't seen via SSE.
|
|
999
|
+
*/
|
|
1000
|
+
async recoverState() {
|
|
1001
|
+
try {
|
|
1002
|
+
const execution = await this.options.getExecution(this.options.executionId);
|
|
1003
|
+
if (execution.logs) {
|
|
1004
|
+
for (const log of execution.logs) {
|
|
1005
|
+
if (!this.seenEventIds.has(log.uuid)) {
|
|
1006
|
+
this.seenEventIds.add(log.uuid);
|
|
1007
|
+
this.emit("log", log);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
if (execution.status === "completed") {
|
|
1012
|
+
this.stopPolling();
|
|
1013
|
+
this.handleComplete(execution);
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1016
|
+
if (execution.status === "failed" || execution.status === "cancelled") {
|
|
1017
|
+
this.stopPolling();
|
|
1018
|
+
this.handleError({
|
|
1019
|
+
error: execution.error ?? `Execution ${execution.status}`,
|
|
1020
|
+
errorCode: execution.status
|
|
1021
|
+
});
|
|
1022
|
+
return;
|
|
1023
|
+
}
|
|
1024
|
+
} catch (err) {
|
|
1025
|
+
console.warn("[SDK:StreamController] State recovery failed (non-fatal):", err);
|
|
976
1026
|
}
|
|
977
1027
|
}
|
|
978
1028
|
/**
|
|
@@ -2824,12 +2874,54 @@ function useExecutionStream(options) {
|
|
|
2824
2874
|
}
|
|
2825
2875
|
|
|
2826
2876
|
// src/chat/hooks/useAgentChat.ts
|
|
2877
|
+
var __DEV__ = typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
|
|
2827
2878
|
var SILENT_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
2828
2879
|
"check_delegations"
|
|
2829
2880
|
]);
|
|
2830
2881
|
function generateId() {
|
|
2831
2882
|
return `msg-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
2832
2883
|
}
|
|
2884
|
+
function extractImagesFromResult(result, sourceToolCallId) {
|
|
2885
|
+
if (!result) return [];
|
|
2886
|
+
let data = result;
|
|
2887
|
+
if (typeof result === "string") {
|
|
2888
|
+
try {
|
|
2889
|
+
data = JSON.parse(result);
|
|
2890
|
+
} catch {
|
|
2891
|
+
if (/\.(png|jpg|jpeg|gif|webp|svg|bmp)(\?.*)?$/i.test(result) || result.startsWith("data:image/")) {
|
|
2892
|
+
return [{ url: result, sourceToolCallId }];
|
|
2893
|
+
}
|
|
2894
|
+
return [];
|
|
2895
|
+
}
|
|
2896
|
+
}
|
|
2897
|
+
if (typeof data !== "object" || data === null) return [];
|
|
2898
|
+
const obj = data;
|
|
2899
|
+
if (Array.isArray(obj.images)) {
|
|
2900
|
+
return obj.images.filter((img) => typeof img.url === "string").map((img) => ({
|
|
2901
|
+
url: img.url,
|
|
2902
|
+
alt: img.alt || img.prompt || void 0,
|
|
2903
|
+
filename: img.filename,
|
|
2904
|
+
sourceToolCallId
|
|
2905
|
+
}));
|
|
2906
|
+
}
|
|
2907
|
+
if (typeof obj.url === "string" && /\.(png|jpg|jpeg|gif|webp|svg|bmp)(\?.*)?$/i.test(obj.url)) {
|
|
2908
|
+
return [{ url: obj.url, alt: obj.alt, sourceToolCallId }];
|
|
2909
|
+
}
|
|
2910
|
+
if (typeof obj.imageUrl === "string") {
|
|
2911
|
+
return [{ url: obj.imageUrl, alt: obj.alt, sourceToolCallId }];
|
|
2912
|
+
}
|
|
2913
|
+
return [];
|
|
2914
|
+
}
|
|
2915
|
+
function deriveImagesFromToolCalls(toolCalls) {
|
|
2916
|
+
if (!toolCalls) return [];
|
|
2917
|
+
const images = [];
|
|
2918
|
+
for (const tc of toolCalls) {
|
|
2919
|
+
if (tc.status === "completed" && tc.result) {
|
|
2920
|
+
images.push(...extractImagesFromResult(tc.result, tc.id));
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
return images;
|
|
2924
|
+
}
|
|
2833
2925
|
function historyToMessage(historyMsg) {
|
|
2834
2926
|
return {
|
|
2835
2927
|
id: historyMsg.uuid,
|
|
@@ -2870,7 +2962,9 @@ function useAgentChat(options) {
|
|
|
2870
2962
|
// Deprecated, but still supported
|
|
2871
2963
|
onToolCall,
|
|
2872
2964
|
onToolResult,
|
|
2873
|
-
onClarification
|
|
2965
|
+
onClarification,
|
|
2966
|
+
pollingInterval,
|
|
2967
|
+
pollingEnabled
|
|
2874
2968
|
} = options;
|
|
2875
2969
|
const contextConfig = useChatConfigOptional();
|
|
2876
2970
|
const adapter = propsAdapter ?? contextConfig?.adapter;
|
|
@@ -2902,8 +2996,14 @@ function useAgentChat(options) {
|
|
|
2902
2996
|
const streamingMessageIdRef = react.useRef(null);
|
|
2903
2997
|
const pendingToolCallsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
2904
2998
|
const lastMessageContentRef = react.useRef("");
|
|
2999
|
+
const finalizedRef = react.useRef(false);
|
|
2905
3000
|
const firedToolResultsRef = react.useRef(/* @__PURE__ */ new Set());
|
|
2906
3001
|
const streamControllerRef = react.useRef(null);
|
|
3002
|
+
const pendingDelegationsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
3003
|
+
const onDelegationRef = react.useRef(options.onDelegation);
|
|
3004
|
+
react.useEffect(() => {
|
|
3005
|
+
onDelegationRef.current = options.onDelegation;
|
|
3006
|
+
}, [options.onDelegation]);
|
|
2907
3007
|
const updateStreamingMessage = react.useCallback((content) => {
|
|
2908
3008
|
if (!streamingMessageIdRef.current) return;
|
|
2909
3009
|
setMessages(
|
|
@@ -2932,25 +3032,72 @@ function useAgentChat(options) {
|
|
|
2932
3032
|
});
|
|
2933
3033
|
});
|
|
2934
3034
|
}, []);
|
|
2935
|
-
const
|
|
3035
|
+
const addDelegationEvent = react.useCallback((delegation) => {
|
|
3036
|
+
setMessages((prev) => {
|
|
3037
|
+
const targetId = streamingMessageIdRef.current ?? [...prev].reverse().find((m) => m.role === "assistant")?.id;
|
|
3038
|
+
if (!targetId) return prev;
|
|
3039
|
+
return prev.map((msg) => {
|
|
3040
|
+
if (msg.id !== targetId) return msg;
|
|
3041
|
+
const existing = msg.delegationEvents ?? [];
|
|
3042
|
+
if (delegation.type === "delegation_completed" && delegation.handoffId) {
|
|
3043
|
+
const updatedEvents = existing.map(
|
|
3044
|
+
(de) => de.handoffId === delegation.handoffId ? { ...de, ...delegation, status: delegation.status ?? "completed" } : de
|
|
3045
|
+
);
|
|
3046
|
+
const hasMatch = existing.some((de) => de.handoffId === delegation.handoffId);
|
|
3047
|
+
return {
|
|
3048
|
+
...msg,
|
|
3049
|
+
delegationEvents: hasMatch ? updatedEvents : [...existing, delegation]
|
|
3050
|
+
};
|
|
3051
|
+
}
|
|
3052
|
+
return { ...msg, delegationEvents: [...existing, delegation] };
|
|
3053
|
+
});
|
|
3054
|
+
});
|
|
3055
|
+
}, []);
|
|
3056
|
+
const updateMessageImages = react.useCallback(() => {
|
|
3057
|
+
setMessages((prev) => {
|
|
3058
|
+
const targetId = streamingMessageIdRef.current ?? [...prev].reverse().find((m) => m.role === "assistant")?.id;
|
|
3059
|
+
if (!targetId) return prev;
|
|
3060
|
+
return prev.map((msg) => {
|
|
3061
|
+
if (msg.id !== targetId) return msg;
|
|
3062
|
+
const images = deriveImagesFromToolCalls(msg.toolCalls);
|
|
3063
|
+
return images.length > 0 ? { ...msg, images } : msg;
|
|
3064
|
+
});
|
|
3065
|
+
});
|
|
3066
|
+
}, []);
|
|
3067
|
+
const finalizeStreamingMessage = react.useCallback((finalOutput) => {
|
|
2936
3068
|
if (!streamingMessageIdRef.current) return;
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
3069
|
+
finalizedRef.current = true;
|
|
3070
|
+
const streamMsgId = streamingMessageIdRef.current;
|
|
3071
|
+
setMessages((prev) => {
|
|
3072
|
+
const resolvedContent = finalOutput || streamingContentRef.current || "";
|
|
3073
|
+
const duplicateExists = resolvedContent && prev.some(
|
|
3074
|
+
(msg) => msg.id !== streamMsgId && msg.role === "assistant" && !msg.isStreaming && msg.content === resolvedContent
|
|
3075
|
+
);
|
|
3076
|
+
if (duplicateExists) {
|
|
3077
|
+
return prev.filter((msg) => msg.id !== streamMsgId);
|
|
3078
|
+
}
|
|
3079
|
+
return prev.map((msg) => {
|
|
3080
|
+
if (msg.id !== streamMsgId) return msg;
|
|
2940
3081
|
const updatedToolCalls = msg.toolCalls?.map(
|
|
2941
|
-
(tc) => tc.status === "running" || tc.status === "pending" ? { ...tc, status:
|
|
3082
|
+
(tc) => tc.status === "running" || tc.status === "pending" ? { ...tc, status: "completed" } : tc
|
|
2942
3083
|
);
|
|
2943
|
-
return {
|
|
2944
|
-
|
|
2945
|
-
|
|
3084
|
+
return {
|
|
3085
|
+
...msg,
|
|
3086
|
+
content: resolvedContent || msg.content,
|
|
3087
|
+
isStreaming: false,
|
|
3088
|
+
toolCalls: updatedToolCalls
|
|
3089
|
+
};
|
|
3090
|
+
});
|
|
3091
|
+
});
|
|
2946
3092
|
streamingMessageIdRef.current = null;
|
|
2947
3093
|
streamingContentRef.current = "";
|
|
2948
3094
|
pendingToolCallsRef.current.clear();
|
|
2949
3095
|
firedToolResultsRef.current.clear();
|
|
3096
|
+
pendingDelegationsRef.current.clear();
|
|
2950
3097
|
}, []);
|
|
2951
3098
|
const handleExecutionLog = react.useCallback(
|
|
2952
3099
|
(log) => {
|
|
2953
|
-
console.log("[useAgentChat] handleExecutionLog:", log.type, log.metadata);
|
|
3100
|
+
if (__DEV__) console.log("[useAgentChat] handleExecutionLog:", log.type, log.metadata);
|
|
2954
3101
|
switch (log.type) {
|
|
2955
3102
|
// Primary handlers for ai-saas-api worker log types
|
|
2956
3103
|
case "llm_response": {
|
|
@@ -2970,11 +3117,46 @@ function useAgentChat(options) {
|
|
|
2970
3117
|
}
|
|
2971
3118
|
break;
|
|
2972
3119
|
}
|
|
3120
|
+
case "delegation": {
|
|
3121
|
+
const delegationType = log.metadata?.delegationType;
|
|
3122
|
+
if (delegationType === "started" || delegationType === "delegation_started") {
|
|
3123
|
+
const delegation = {
|
|
3124
|
+
type: "delegation_started",
|
|
3125
|
+
handoffId: log.metadata?.handoffId,
|
|
3126
|
+
toAgent: log.metadata?.targetAgentName || log.metadata?.targetAgentUuid,
|
|
3127
|
+
targetAgentUuid: log.metadata?.targetAgentUuid,
|
|
3128
|
+
taskPreview: log.metadata?.taskPreview,
|
|
3129
|
+
timestamp: new Date(log.timestamp || Date.now()),
|
|
3130
|
+
status: "active"
|
|
3131
|
+
};
|
|
3132
|
+
if (delegation.handoffId) {
|
|
3133
|
+
pendingDelegationsRef.current.set(delegation.handoffId, delegation);
|
|
3134
|
+
}
|
|
3135
|
+
addDelegationEvent(delegation);
|
|
3136
|
+
onDelegationRef.current?.(delegation);
|
|
3137
|
+
} else if (delegationType === "completed" || delegationType === "delegation_completed") {
|
|
3138
|
+
const delegation = {
|
|
3139
|
+
type: "delegation_completed",
|
|
3140
|
+
handoffId: log.metadata?.handoffId,
|
|
3141
|
+
resultPreview: log.metadata?.resultPreview,
|
|
3142
|
+
timestamp: new Date(log.timestamp || Date.now()),
|
|
3143
|
+
status: log.metadata?.status === "failed" ? "failed" : "completed",
|
|
3144
|
+
durationMs: log.durationMs
|
|
3145
|
+
};
|
|
3146
|
+
if (delegation.handoffId) {
|
|
3147
|
+
pendingDelegationsRef.current.delete(delegation.handoffId);
|
|
3148
|
+
}
|
|
3149
|
+
addDelegationEvent(delegation);
|
|
3150
|
+
onDelegationRef.current?.(delegation);
|
|
3151
|
+
}
|
|
3152
|
+
break;
|
|
3153
|
+
}
|
|
2973
3154
|
case "info":
|
|
2974
3155
|
case "system":
|
|
2975
|
-
console.log("[useAgentChat] Status:", log.type, log.title);
|
|
3156
|
+
if (__DEV__) console.log("[useAgentChat] Status:", log.type, log.title);
|
|
2976
3157
|
break;
|
|
2977
3158
|
case "tool_call": {
|
|
3159
|
+
if (finalizedRef.current) break;
|
|
2978
3160
|
const toolName = log.metadata?.toolName;
|
|
2979
3161
|
if (SILENT_TOOL_NAMES.has(toolName)) break;
|
|
2980
3162
|
const toolCallId = log.metadata?.toolCallId || `tool-${Date.now()}`;
|
|
@@ -3029,17 +3211,18 @@ function useAgentChat(options) {
|
|
|
3029
3211
|
firedToolResultsRef.current.add(resultToolCallId);
|
|
3030
3212
|
}
|
|
3031
3213
|
onToolResultRef.current?.(resultToolName, result, durationMs);
|
|
3214
|
+
updateMessageImages();
|
|
3032
3215
|
break;
|
|
3033
3216
|
}
|
|
3034
3217
|
default:
|
|
3035
|
-
console.log("[useAgentChat] Unhandled log type:", log.type, log);
|
|
3218
|
+
if (__DEV__) console.log("[useAgentChat] Unhandled log type:", log.type, log);
|
|
3036
3219
|
}
|
|
3037
3220
|
},
|
|
3038
|
-
[updateStreamingMessage, updateToolCall]
|
|
3221
|
+
[updateStreamingMessage, updateToolCall, updateMessageImages, addDelegationEvent]
|
|
3039
3222
|
);
|
|
3040
3223
|
const handleStreamLog = react.useCallback(
|
|
3041
3224
|
(log) => {
|
|
3042
|
-
console.log("[useAgentChat] handleStreamLog:", log.logType, log.metadata);
|
|
3225
|
+
if (__DEV__) console.log("[useAgentChat] handleStreamLog:", log.logType, log.metadata);
|
|
3043
3226
|
switch (log.logType) {
|
|
3044
3227
|
case "llm_response": {
|
|
3045
3228
|
const llmText = log.metadata?.text || "";
|
|
@@ -3058,9 +3241,42 @@ function useAgentChat(options) {
|
|
|
3058
3241
|
}
|
|
3059
3242
|
break;
|
|
3060
3243
|
}
|
|
3244
|
+
case "delegation_started": {
|
|
3245
|
+
const delegation = {
|
|
3246
|
+
type: "delegation_started",
|
|
3247
|
+
handoffId: log.metadata?.handoffId,
|
|
3248
|
+
toAgent: log.metadata?.targetAgentName || log.metadata?.targetAgentUuid,
|
|
3249
|
+
targetAgentUuid: log.metadata?.targetAgentUuid,
|
|
3250
|
+
taskPreview: log.metadata?.taskPreview,
|
|
3251
|
+
timestamp: new Date(log.timestamp || Date.now()),
|
|
3252
|
+
status: "active"
|
|
3253
|
+
};
|
|
3254
|
+
if (delegation.handoffId) {
|
|
3255
|
+
pendingDelegationsRef.current.set(delegation.handoffId, delegation);
|
|
3256
|
+
}
|
|
3257
|
+
addDelegationEvent(delegation);
|
|
3258
|
+
onDelegationRef.current?.(delegation);
|
|
3259
|
+
break;
|
|
3260
|
+
}
|
|
3261
|
+
case "delegation_completed": {
|
|
3262
|
+
const delegation = {
|
|
3263
|
+
type: "delegation_completed",
|
|
3264
|
+
handoffId: log.metadata?.handoffId,
|
|
3265
|
+
resultPreview: log.metadata?.resultPreview,
|
|
3266
|
+
timestamp: new Date(log.timestamp || Date.now()),
|
|
3267
|
+
status: log.metadata?.status === "failed" ? "failed" : "completed",
|
|
3268
|
+
durationMs: log.durationMs
|
|
3269
|
+
};
|
|
3270
|
+
if (delegation.handoffId) {
|
|
3271
|
+
pendingDelegationsRef.current.delete(delegation.handoffId);
|
|
3272
|
+
}
|
|
3273
|
+
addDelegationEvent(delegation);
|
|
3274
|
+
onDelegationRef.current?.(delegation);
|
|
3275
|
+
break;
|
|
3276
|
+
}
|
|
3061
3277
|
case "info":
|
|
3062
3278
|
case "system":
|
|
3063
|
-
console.log("[useAgentChat] Status:", log.logType, log.message);
|
|
3279
|
+
if (__DEV__) console.log("[useAgentChat] Status:", log.logType, log.message);
|
|
3064
3280
|
break;
|
|
3065
3281
|
case "response_text":
|
|
3066
3282
|
case "text_chunk": {
|
|
@@ -3070,6 +3286,7 @@ function useAgentChat(options) {
|
|
|
3070
3286
|
break;
|
|
3071
3287
|
}
|
|
3072
3288
|
case "tool_call": {
|
|
3289
|
+
if (finalizedRef.current) break;
|
|
3073
3290
|
const toolName = log.metadata?.toolName;
|
|
3074
3291
|
if (SILENT_TOOL_NAMES.has(toolName)) break;
|
|
3075
3292
|
const toolCallId = log.metadata?.toolCallId || `tool-${Date.now()}`;
|
|
@@ -3124,6 +3341,7 @@ function useAgentChat(options) {
|
|
|
3124
3341
|
firedToolResultsRef.current.add(resultToolCallId);
|
|
3125
3342
|
}
|
|
3126
3343
|
onToolResultRef.current?.(resultToolName, result, durationMs);
|
|
3344
|
+
updateMessageImages();
|
|
3127
3345
|
break;
|
|
3128
3346
|
}
|
|
3129
3347
|
case "final_response": {
|
|
@@ -3135,10 +3353,10 @@ function useAgentChat(options) {
|
|
|
3135
3353
|
break;
|
|
3136
3354
|
}
|
|
3137
3355
|
default:
|
|
3138
|
-
console.log("[useAgentChat] Unknown log type:", log.logType, log);
|
|
3356
|
+
if (__DEV__) console.log("[useAgentChat] Unknown log type:", log.logType, log);
|
|
3139
3357
|
}
|
|
3140
3358
|
},
|
|
3141
|
-
[updateStreamingMessage, updateToolCall]
|
|
3359
|
+
[updateStreamingMessage, updateToolCall, updateMessageImages, addDelegationEvent]
|
|
3142
3360
|
);
|
|
3143
3361
|
const handleClarification = react.useCallback(
|
|
3144
3362
|
(data) => {
|
|
@@ -3147,17 +3365,23 @@ function useAgentChat(options) {
|
|
|
3147
3365
|
},
|
|
3148
3366
|
[onClarification]
|
|
3149
3367
|
);
|
|
3150
|
-
const
|
|
3151
|
-
|
|
3368
|
+
const completedRef = react.useRef(false);
|
|
3369
|
+
const handleComplete = react.useCallback((finalOutput) => {
|
|
3370
|
+
if (completedRef.current) {
|
|
3371
|
+
if (__DEV__) console.log("[useAgentChat] handleComplete: skipping duplicate complete");
|
|
3372
|
+
return;
|
|
3373
|
+
}
|
|
3374
|
+
completedRef.current = true;
|
|
3375
|
+
if (__DEV__) console.log("[useAgentChat] handleComplete called");
|
|
3152
3376
|
setIsLoading(false);
|
|
3153
3377
|
setIsStreamControllerConnected(false);
|
|
3154
|
-
finalizeStreamingMessage();
|
|
3378
|
+
finalizeStreamingMessage(finalOutput);
|
|
3155
3379
|
setCurrentExecutionId(null);
|
|
3156
3380
|
streamControllerRef.current = null;
|
|
3157
3381
|
}, [finalizeStreamingMessage]);
|
|
3158
3382
|
const handleError = react.useCallback(
|
|
3159
3383
|
(errorMsg) => {
|
|
3160
|
-
console.log("[useAgentChat] handleError called:", errorMsg);
|
|
3384
|
+
if (__DEV__) console.log("[useAgentChat] handleError called:", errorMsg);
|
|
3161
3385
|
const chatError = {
|
|
3162
3386
|
code: "EXECUTION_ERROR",
|
|
3163
3387
|
message: errorMsg,
|
|
@@ -3166,7 +3390,7 @@ function useAgentChat(options) {
|
|
|
3166
3390
|
setError(chatError);
|
|
3167
3391
|
setIsLoading(false);
|
|
3168
3392
|
setIsStreamControllerConnected(false);
|
|
3169
|
-
finalizeStreamingMessage(
|
|
3393
|
+
finalizeStreamingMessage();
|
|
3170
3394
|
setCurrentExecutionId(null);
|
|
3171
3395
|
streamControllerRef.current = null;
|
|
3172
3396
|
onError?.(chatError);
|
|
@@ -3196,43 +3420,39 @@ function useAgentChat(options) {
|
|
|
3196
3420
|
if (pollingExecutionIdRef.current === executionId) return;
|
|
3197
3421
|
stopPolling();
|
|
3198
3422
|
pollingExecutionIdRef.current = executionId;
|
|
3199
|
-
console.log("[useAgentChat] Starting polling fallback for:", executionId);
|
|
3423
|
+
if (__DEV__) console.log("[useAgentChat] Starting polling fallback for:", executionId);
|
|
3200
3424
|
const poll = async () => {
|
|
3201
3425
|
if (pollingExecutionIdRef.current !== executionId) return;
|
|
3202
3426
|
try {
|
|
3203
3427
|
const execution = await adapter.getExecution(executionId);
|
|
3204
3428
|
if (execution.status === "completed") {
|
|
3205
|
-
console.log("[useAgentChat] Polling: execution completed");
|
|
3206
|
-
if (execution.result) {
|
|
3207
|
-
streamingContentRef.current = execution.result;
|
|
3208
|
-
updateStreamingMessage(execution.result);
|
|
3209
|
-
}
|
|
3429
|
+
if (__DEV__) console.log("[useAgentChat] Polling: execution completed");
|
|
3210
3430
|
stopPolling();
|
|
3211
|
-
handleComplete();
|
|
3431
|
+
handleComplete(execution.result || void 0);
|
|
3212
3432
|
} else if (execution.status === "failed") {
|
|
3213
|
-
console.log("[useAgentChat] Polling: execution failed");
|
|
3433
|
+
if (__DEV__) console.log("[useAgentChat] Polling: execution failed");
|
|
3214
3434
|
stopPolling();
|
|
3215
3435
|
handleError(execution.error || "Execution failed");
|
|
3216
3436
|
}
|
|
3217
3437
|
} catch (err) {
|
|
3218
|
-
console.warn("[useAgentChat] Polling error (will retry):", err);
|
|
3438
|
+
if (__DEV__) console.warn("[useAgentChat] Polling error (will retry):", err);
|
|
3219
3439
|
}
|
|
3220
3440
|
};
|
|
3221
3441
|
poll();
|
|
3222
|
-
pollingIntervalRef.current = setInterval(poll, 2e3);
|
|
3223
|
-
}, [adapter, stopPolling,
|
|
3442
|
+
pollingIntervalRef.current = setInterval(poll, pollingInterval ?? 2e3);
|
|
3443
|
+
}, [adapter, stopPolling, handleComplete, handleError, pollingInterval]);
|
|
3224
3444
|
react.useEffect(() => {
|
|
3225
|
-
if (!useStreamController && isUsingFallback && currentExecutionId && isLoading) {
|
|
3226
|
-
console.log("[useAgentChat] SSE fallback detected, activating polling");
|
|
3445
|
+
if (!useStreamController && isUsingFallback && currentExecutionId && isLoading && pollingEnabled !== false) {
|
|
3446
|
+
if (__DEV__) console.log("[useAgentChat] SSE fallback detected, activating polling");
|
|
3227
3447
|
startPolling(currentExecutionId);
|
|
3228
3448
|
}
|
|
3229
|
-
}, [useStreamController, isUsingFallback, currentExecutionId, isLoading, startPolling]);
|
|
3449
|
+
}, [useStreamController, isUsingFallback, currentExecutionId, isLoading, startPolling, pollingEnabled]);
|
|
3230
3450
|
const sseTimeoutRef = react.useRef(null);
|
|
3231
3451
|
react.useEffect(() => {
|
|
3232
|
-
if (!useStreamController && currentExecutionId && isLoading && !legacyIsConnected && !isUsingFallback) {
|
|
3452
|
+
if (!useStreamController && currentExecutionId && isLoading && !legacyIsConnected && !isUsingFallback && pollingEnabled !== false) {
|
|
3233
3453
|
sseTimeoutRef.current = setTimeout(() => {
|
|
3234
3454
|
if (!legacyIsConnected && currentExecutionId && isLoading) {
|
|
3235
|
-
console.log("[useAgentChat] SSE connection timeout, activating polling fallback");
|
|
3455
|
+
if (__DEV__) console.log("[useAgentChat] SSE connection timeout, activating polling fallback");
|
|
3236
3456
|
startPolling(currentExecutionId);
|
|
3237
3457
|
}
|
|
3238
3458
|
}, 1e4);
|
|
@@ -3243,7 +3463,7 @@ function useAgentChat(options) {
|
|
|
3243
3463
|
sseTimeoutRef.current = null;
|
|
3244
3464
|
}
|
|
3245
3465
|
};
|
|
3246
|
-
}, [useStreamController, currentExecutionId, isLoading, legacyIsConnected, isUsingFallback, startPolling]);
|
|
3466
|
+
}, [useStreamController, currentExecutionId, isLoading, legacyIsConnected, isUsingFallback, startPolling, pollingEnabled]);
|
|
3247
3467
|
react.useEffect(() => {
|
|
3248
3468
|
if (!currentExecutionId) {
|
|
3249
3469
|
stopPolling();
|
|
@@ -3259,7 +3479,7 @@ function useAgentChat(options) {
|
|
|
3259
3479
|
streamControllerRef.current.cancel();
|
|
3260
3480
|
streamControllerRef.current = null;
|
|
3261
3481
|
}
|
|
3262
|
-
console.log("[useAgentChat] Creating stream controller for:", executionId);
|
|
3482
|
+
if (__DEV__) console.log("[useAgentChat] Creating stream controller for:", executionId);
|
|
3263
3483
|
const controller = adapter.createStream(executionId, sessionId);
|
|
3264
3484
|
streamControllerRef.current = controller;
|
|
3265
3485
|
controller.on("log", (log) => {
|
|
@@ -3310,6 +3530,34 @@ function useAgentChat(options) {
|
|
|
3310
3530
|
}
|
|
3311
3531
|
firedToolResultsRef.current.add(toolCallId);
|
|
3312
3532
|
onToolResultRef.current?.(toolName, data.result, data.durationMs);
|
|
3533
|
+
updateMessageImages();
|
|
3534
|
+
});
|
|
3535
|
+
controller.on("delegationStarted", (data) => {
|
|
3536
|
+
const delegation = {
|
|
3537
|
+
type: "delegation_started",
|
|
3538
|
+
handoffId: data.handoffId,
|
|
3539
|
+
toAgent: data.targetAgentName || data.targetAgentUuid,
|
|
3540
|
+
targetAgentUuid: data.targetAgentUuid,
|
|
3541
|
+
taskPreview: data.taskPreview,
|
|
3542
|
+
timestamp: new Date(data.timestamp),
|
|
3543
|
+
status: "active"
|
|
3544
|
+
};
|
|
3545
|
+
pendingDelegationsRef.current.set(data.handoffId, delegation);
|
|
3546
|
+
addDelegationEvent(delegation);
|
|
3547
|
+
onDelegationRef.current?.(delegation);
|
|
3548
|
+
});
|
|
3549
|
+
controller.on("delegationCompleted", (data) => {
|
|
3550
|
+
const delegation = {
|
|
3551
|
+
type: "delegation_completed",
|
|
3552
|
+
handoffId: data.handoffId,
|
|
3553
|
+
resultPreview: data.resultPreview,
|
|
3554
|
+
timestamp: new Date(data.timestamp),
|
|
3555
|
+
status: data.status === "failed" ? "failed" : "completed",
|
|
3556
|
+
durationMs: data.durationMs
|
|
3557
|
+
};
|
|
3558
|
+
pendingDelegationsRef.current.delete(data.handoffId);
|
|
3559
|
+
addDelegationEvent(delegation);
|
|
3560
|
+
onDelegationRef.current?.(delegation);
|
|
3313
3561
|
});
|
|
3314
3562
|
controller.on("textDelta", (data) => {
|
|
3315
3563
|
streamingContentRef.current += data.delta;
|
|
@@ -3323,11 +3571,8 @@ function useAgentChat(options) {
|
|
|
3323
3571
|
});
|
|
3324
3572
|
});
|
|
3325
3573
|
controller.on("complete", ({ execution }) => {
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
updateStreamingMessage(execution.output);
|
|
3329
|
-
}
|
|
3330
|
-
handleComplete();
|
|
3574
|
+
const output = execution?.output || void 0;
|
|
3575
|
+
handleComplete(output);
|
|
3331
3576
|
});
|
|
3332
3577
|
controller.on("error", (errorEvent) => {
|
|
3333
3578
|
handleError(errorEvent.error);
|
|
@@ -3341,7 +3586,7 @@ function useAgentChat(options) {
|
|
|
3341
3586
|
});
|
|
3342
3587
|
setIsStreamControllerConnected(true);
|
|
3343
3588
|
},
|
|
3344
|
-
[adapter, handleExecutionLog, updateStreamingMessage, updateToolCall, handleClarification, handleComplete, handleError]
|
|
3589
|
+
[adapter, handleExecutionLog, updateStreamingMessage, updateToolCall, updateMessageImages, addDelegationEvent, handleClarification, handleComplete, handleError]
|
|
3345
3590
|
);
|
|
3346
3591
|
const sendMessage = react.useCallback(
|
|
3347
3592
|
async (content, options2) => {
|
|
@@ -3371,8 +3616,10 @@ function useAgentChat(options) {
|
|
|
3371
3616
|
setMessages((prev) => [...prev, assistantMessage]);
|
|
3372
3617
|
streamingMessageIdRef.current = assistantMessageId;
|
|
3373
3618
|
streamingContentRef.current = "";
|
|
3619
|
+
completedRef.current = false;
|
|
3620
|
+
finalizedRef.current = false;
|
|
3374
3621
|
try {
|
|
3375
|
-
console.log("[useAgentChat] Starting execution...", { agentId, sessionId: currentSessionId });
|
|
3622
|
+
if (__DEV__) console.log("[useAgentChat] Starting execution...", { agentId, sessionId: currentSessionId });
|
|
3376
3623
|
const result = await adapter.startExecution({
|
|
3377
3624
|
agentId,
|
|
3378
3625
|
teamId,
|
|
@@ -3380,7 +3627,7 @@ function useAgentChat(options) {
|
|
|
3380
3627
|
content: content.trim(),
|
|
3381
3628
|
attachmentUuids
|
|
3382
3629
|
});
|
|
3383
|
-
console.log("[useAgentChat] Execution started:", result);
|
|
3630
|
+
if (__DEV__) console.log("[useAgentChat] Execution started:", result);
|
|
3384
3631
|
if (!currentSessionId && result.sessionId) {
|
|
3385
3632
|
internallyCreatedSessionRef.current = result.sessionId;
|
|
3386
3633
|
setCurrentSessionId(result.sessionId);
|
|
@@ -3391,7 +3638,7 @@ function useAgentChat(options) {
|
|
|
3391
3638
|
connectStreamController(result.executionId, result.sessionId || currentSessionId || void 0);
|
|
3392
3639
|
setCurrentExecutionId(result.executionId);
|
|
3393
3640
|
} else {
|
|
3394
|
-
console.log("[useAgentChat] Setting executionId:", result.executionId);
|
|
3641
|
+
if (__DEV__) console.log("[useAgentChat] Setting executionId:", result.executionId);
|
|
3395
3642
|
setCurrentExecutionId(result.executionId);
|
|
3396
3643
|
}
|
|
3397
3644
|
} catch (err) {
|
|
@@ -3451,6 +3698,7 @@ function useAgentChat(options) {
|
|
|
3451
3698
|
setMessages([]);
|
|
3452
3699
|
setCurrentSessionId(null);
|
|
3453
3700
|
hasLoadedInitialSession.current = false;
|
|
3701
|
+
lastLoadedSessionRef.current = null;
|
|
3454
3702
|
internallyCreatedSessionRef.current = null;
|
|
3455
3703
|
}, []);
|
|
3456
3704
|
const loadSession = react.useCallback(
|
|
@@ -3546,15 +3794,20 @@ function useAgentChat(options) {
|
|
|
3546
3794
|
},
|
|
3547
3795
|
[adapter, onError]
|
|
3548
3796
|
);
|
|
3797
|
+
const lastLoadedSessionRef = react.useRef(null);
|
|
3549
3798
|
react.useEffect(() => {
|
|
3550
|
-
if (initialSessionId
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
return;
|
|
3554
|
-
}
|
|
3799
|
+
if (!initialSessionId) return;
|
|
3800
|
+
if (internallyCreatedSessionRef.current === initialSessionId) {
|
|
3801
|
+
lastLoadedSessionRef.current = initialSessionId;
|
|
3555
3802
|
hasLoadedInitialSession.current = true;
|
|
3556
|
-
|
|
3803
|
+
return;
|
|
3804
|
+
}
|
|
3805
|
+
if (lastLoadedSessionRef.current === initialSessionId && hasLoadedInitialSession.current) {
|
|
3806
|
+
return;
|
|
3557
3807
|
}
|
|
3808
|
+
lastLoadedSessionRef.current = initialSessionId;
|
|
3809
|
+
hasLoadedInitialSession.current = true;
|
|
3810
|
+
loadSession(initialSessionId);
|
|
3558
3811
|
}, [initialSessionId, loadSession]);
|
|
3559
3812
|
react.useEffect(() => {
|
|
3560
3813
|
return () => {
|
|
@@ -3570,6 +3823,16 @@ function useAgentChat(options) {
|
|
|
3570
3823
|
}
|
|
3571
3824
|
return !!currentExecutionId && legacyIsConnected;
|
|
3572
3825
|
}, [useStreamController, currentExecutionId, isStreamControllerConnected, legacyIsConnected]);
|
|
3826
|
+
const activeDelegation = react.useMemo(() => {
|
|
3827
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
3828
|
+
const msg = messages[i];
|
|
3829
|
+
if (msg.delegationEvents) {
|
|
3830
|
+
const active = msg.delegationEvents.find((de) => de.status === "active");
|
|
3831
|
+
if (active) return active;
|
|
3832
|
+
}
|
|
3833
|
+
}
|
|
3834
|
+
return null;
|
|
3835
|
+
}, [messages]);
|
|
3573
3836
|
return {
|
|
3574
3837
|
messages,
|
|
3575
3838
|
isLoading,
|
|
@@ -3578,6 +3841,7 @@ function useAgentChat(options) {
|
|
|
3578
3841
|
error,
|
|
3579
3842
|
sessionId: currentSessionId,
|
|
3580
3843
|
clarification,
|
|
3844
|
+
activeDelegation,
|
|
3581
3845
|
sendMessage,
|
|
3582
3846
|
respondToClarification,
|
|
3583
3847
|
cancel,
|
|
@@ -3769,6 +4033,24 @@ function useFileAttachments(options) {
|
|
|
3769
4033
|
console.log("[useFileAttachments] prepareForSubmit result:", aiUuids);
|
|
3770
4034
|
return aiUuids;
|
|
3771
4035
|
}, [onSubmitUpload, onError]);
|
|
4036
|
+
const addExternalFile = react.useCallback(
|
|
4037
|
+
(opts) => {
|
|
4038
|
+
const category = opts.category || (opts.mimeType.startsWith("image/") ? "image" : "document");
|
|
4039
|
+
const placeholderFile = new File([], opts.filename, { type: opts.mimeType });
|
|
4040
|
+
const newAttachment = {
|
|
4041
|
+
uuid: opts.uuid,
|
|
4042
|
+
file: placeholderFile,
|
|
4043
|
+
status: "ready",
|
|
4044
|
+
progress: 100,
|
|
4045
|
+
category,
|
|
4046
|
+
previewUrl: opts.previewUrl,
|
|
4047
|
+
hasThumbnail: category === "image",
|
|
4048
|
+
actualSize: opts.size
|
|
4049
|
+
};
|
|
4050
|
+
setFiles((prev) => [...prev, newAttachment]);
|
|
4051
|
+
},
|
|
4052
|
+
[]
|
|
4053
|
+
);
|
|
3772
4054
|
const clear = react.useCallback(() => {
|
|
3773
4055
|
for (const file of filesRef.current) {
|
|
3774
4056
|
if (file.previewUrl) {
|
|
@@ -3794,6 +4076,7 @@ function useFileAttachments(options) {
|
|
|
3794
4076
|
files,
|
|
3795
4077
|
dropZoneProps,
|
|
3796
4078
|
removeFile,
|
|
4079
|
+
addExternalFile,
|
|
3797
4080
|
getReadyUuids,
|
|
3798
4081
|
getReadyUrls,
|
|
3799
4082
|
prepareForSubmit,
|
|
@@ -4433,18 +4716,30 @@ function ChatContainer({
|
|
|
4433
4716
|
children,
|
|
4434
4717
|
maxHeight = "600px",
|
|
4435
4718
|
className,
|
|
4436
|
-
theme = "system"
|
|
4719
|
+
theme = "system",
|
|
4720
|
+
layout = "fixed"
|
|
4437
4721
|
}) {
|
|
4438
4722
|
const maxHeightValue = typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight;
|
|
4723
|
+
const isFill = layout === "fill";
|
|
4439
4724
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4440
4725
|
"div",
|
|
4441
4726
|
{
|
|
4442
4727
|
className: cn2(
|
|
4443
|
-
"flex flex-col
|
|
4728
|
+
"cadra-chat-container flex flex-col overflow-hidden",
|
|
4729
|
+
// Default colors use CSS custom properties with Tailwind fallbacks.
|
|
4730
|
+
// Consumers can override via CSS: --chat-bg, --chat-border, --chat-border-radius
|
|
4731
|
+
!isFill && "rounded-lg border",
|
|
4732
|
+
isFill && "flex-1 min-h-0",
|
|
4444
4733
|
className
|
|
4445
4734
|
),
|
|
4446
|
-
style: {
|
|
4735
|
+
style: {
|
|
4736
|
+
...!isFill ? { maxHeight: maxHeightValue } : void 0,
|
|
4737
|
+
// CSS custom properties for theming — consumers set these to override
|
|
4738
|
+
backgroundColor: "var(--chat-bg, var(--background, #fff))",
|
|
4739
|
+
borderColor: !isFill ? "var(--chat-border, var(--border, #e5e7eb))" : void 0
|
|
4740
|
+
},
|
|
4447
4741
|
"data-theme": theme,
|
|
4742
|
+
"data-layout": layout,
|
|
4448
4743
|
children
|
|
4449
4744
|
}
|
|
4450
4745
|
);
|
|
@@ -5131,7 +5426,7 @@ var FileDropZone = react.forwardRef(
|
|
|
5131
5426
|
{
|
|
5132
5427
|
ref: dropZoneRef,
|
|
5133
5428
|
"data-dropzone": "wrapper",
|
|
5134
|
-
className: cn4("relative
|
|
5429
|
+
className: cn4("relative flex flex-col flex-1 min-h-0", className),
|
|
5135
5430
|
style: { minHeight: "inherit" },
|
|
5136
5431
|
children: [
|
|
5137
5432
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5416,6 +5711,380 @@ function AskUserPrompt({
|
|
|
5416
5711
|
function cn6(...classes) {
|
|
5417
5712
|
return classes.filter(Boolean).join(" ");
|
|
5418
5713
|
}
|
|
5714
|
+
function formatDuration(ms) {
|
|
5715
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
5716
|
+
return `${(ms / 1e3).toFixed(1)}s`;
|
|
5717
|
+
}
|
|
5718
|
+
function DelegationProgress({
|
|
5719
|
+
event,
|
|
5720
|
+
className
|
|
5721
|
+
}) {
|
|
5722
|
+
const statusIcon = react.useMemo(() => {
|
|
5723
|
+
switch (event.status) {
|
|
5724
|
+
case "active":
|
|
5725
|
+
return /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, { className: "h-4 w-4 text-blue-500" });
|
|
5726
|
+
case "completed":
|
|
5727
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CheckCircleIcon, { className: "h-4 w-4 text-green-500" });
|
|
5728
|
+
case "failed":
|
|
5729
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AlertCircleIcon, { className: "h-4 w-4 text-red-500" });
|
|
5730
|
+
default:
|
|
5731
|
+
return /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, { className: "h-4 w-4 text-gray-400" });
|
|
5732
|
+
}
|
|
5733
|
+
}, [event.status]);
|
|
5734
|
+
const statusColor = react.useMemo(() => {
|
|
5735
|
+
switch (event.status) {
|
|
5736
|
+
case "active":
|
|
5737
|
+
return "border-blue-200 dark:border-blue-800 bg-blue-50/50 dark:bg-blue-950/20";
|
|
5738
|
+
case "completed":
|
|
5739
|
+
return "border-green-200 dark:border-green-800 bg-green-50/50 dark:bg-green-950/20";
|
|
5740
|
+
case "failed":
|
|
5741
|
+
return "border-red-200 dark:border-red-800 bg-red-50/50 dark:bg-red-950/20";
|
|
5742
|
+
default:
|
|
5743
|
+
return "border-gray-200 dark:border-gray-700";
|
|
5744
|
+
}
|
|
5745
|
+
}, [event.status]);
|
|
5746
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5747
|
+
"div",
|
|
5748
|
+
{
|
|
5749
|
+
className: cn6(
|
|
5750
|
+
"rounded-lg border text-sm px-3 py-2",
|
|
5751
|
+
statusColor,
|
|
5752
|
+
className
|
|
5753
|
+
),
|
|
5754
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
5755
|
+
statusIcon,
|
|
5756
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
5757
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
5758
|
+
event.fromAgent && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5759
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-gray-700 dark:text-gray-300 truncate", children: event.fromAgent }),
|
|
5760
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400 dark:text-gray-500 flex-shrink-0", children: "\u2192" })
|
|
5761
|
+
] }),
|
|
5762
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-gray-900 dark:text-gray-100 truncate", children: event.toAgent || event.targetAgentUuid || "Specialist" })
|
|
5763
|
+
] }),
|
|
5764
|
+
event.taskPreview && event.status === "active" && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 truncate mt-0.5", children: event.taskPreview }),
|
|
5765
|
+
event.resultPreview && event.status === "completed" && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-green-600 dark:text-green-400 truncate mt-0.5", children: event.resultPreview })
|
|
5766
|
+
] }),
|
|
5767
|
+
event.durationMs !== void 0 && event.status !== "active" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400 flex-shrink-0", children: formatDuration(event.durationMs) })
|
|
5768
|
+
] })
|
|
5769
|
+
}
|
|
5770
|
+
);
|
|
5771
|
+
}
|
|
5772
|
+
function DelegationProgressList({
|
|
5773
|
+
events,
|
|
5774
|
+
className
|
|
5775
|
+
}) {
|
|
5776
|
+
if (!events || events.length === 0) return null;
|
|
5777
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn6("space-y-2", className), children: events.map((event, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5778
|
+
DelegationProgress,
|
|
5779
|
+
{
|
|
5780
|
+
event
|
|
5781
|
+
},
|
|
5782
|
+
event.handoffId || `delegation-${index}`
|
|
5783
|
+
)) });
|
|
5784
|
+
}
|
|
5785
|
+
function ImageLightbox({
|
|
5786
|
+
images,
|
|
5787
|
+
currentIndex,
|
|
5788
|
+
onClose,
|
|
5789
|
+
onPrev,
|
|
5790
|
+
onNext,
|
|
5791
|
+
className
|
|
5792
|
+
}) {
|
|
5793
|
+
const currentImage = images[currentIndex];
|
|
5794
|
+
const hasMultiple = images.length > 1;
|
|
5795
|
+
const [container, setContainer] = react.useState(null);
|
|
5796
|
+
react.useEffect(() => {
|
|
5797
|
+
const el = document.createElement("div");
|
|
5798
|
+
el.id = "cadra-lightbox-root";
|
|
5799
|
+
el.style.position = "fixed";
|
|
5800
|
+
el.style.inset = "0";
|
|
5801
|
+
el.style.zIndex = "999999";
|
|
5802
|
+
el.style.pointerEvents = "auto";
|
|
5803
|
+
document.body.appendChild(el);
|
|
5804
|
+
setContainer(el);
|
|
5805
|
+
return () => {
|
|
5806
|
+
document.body.removeChild(el);
|
|
5807
|
+
};
|
|
5808
|
+
}, []);
|
|
5809
|
+
const onCloseRef = react.useRef(onClose);
|
|
5810
|
+
const onPrevRef = react.useRef(onPrev);
|
|
5811
|
+
const onNextRef = react.useRef(onNext);
|
|
5812
|
+
onCloseRef.current = onClose;
|
|
5813
|
+
onPrevRef.current = onPrev;
|
|
5814
|
+
onNextRef.current = onNext;
|
|
5815
|
+
react.useEffect(() => {
|
|
5816
|
+
function handleKeyDown(e) {
|
|
5817
|
+
switch (e.key) {
|
|
5818
|
+
case "Escape":
|
|
5819
|
+
e.preventDefault();
|
|
5820
|
+
e.stopPropagation();
|
|
5821
|
+
onCloseRef.current();
|
|
5822
|
+
break;
|
|
5823
|
+
case "ArrowLeft":
|
|
5824
|
+
if (hasMultiple) onPrevRef.current();
|
|
5825
|
+
break;
|
|
5826
|
+
case "ArrowRight":
|
|
5827
|
+
if (hasMultiple) onNextRef.current();
|
|
5828
|
+
break;
|
|
5829
|
+
}
|
|
5830
|
+
}
|
|
5831
|
+
document.addEventListener("keydown", handleKeyDown, true);
|
|
5832
|
+
return () => document.removeEventListener("keydown", handleKeyDown, true);
|
|
5833
|
+
}, [hasMultiple]);
|
|
5834
|
+
react.useEffect(() => {
|
|
5835
|
+
const originalOverflow = document.body.style.overflow;
|
|
5836
|
+
document.body.style.overflow = "hidden";
|
|
5837
|
+
return () => {
|
|
5838
|
+
document.body.style.overflow = originalOverflow;
|
|
5839
|
+
};
|
|
5840
|
+
}, []);
|
|
5841
|
+
react.useEffect(() => {
|
|
5842
|
+
if (!container) return;
|
|
5843
|
+
function handleClick(e) {
|
|
5844
|
+
const target = e.target;
|
|
5845
|
+
if (target.dataset.lightboxBackdrop === "true") {
|
|
5846
|
+
e.preventDefault();
|
|
5847
|
+
e.stopPropagation();
|
|
5848
|
+
onCloseRef.current();
|
|
5849
|
+
}
|
|
5850
|
+
}
|
|
5851
|
+
container.addEventListener("click", handleClick, true);
|
|
5852
|
+
return () => container.removeEventListener("click", handleClick, true);
|
|
5853
|
+
}, [container]);
|
|
5854
|
+
const handleDownload = react.useCallback(async () => {
|
|
5855
|
+
if (!currentImage) return;
|
|
5856
|
+
const filename = currentImage.filename || `image-${currentIndex + 1}`;
|
|
5857
|
+
try {
|
|
5858
|
+
const response = await fetch(currentImage.url);
|
|
5859
|
+
const blob = await response.blob();
|
|
5860
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
5861
|
+
const link = document.createElement("a");
|
|
5862
|
+
link.href = blobUrl;
|
|
5863
|
+
link.download = filename;
|
|
5864
|
+
document.body.appendChild(link);
|
|
5865
|
+
link.click();
|
|
5866
|
+
document.body.removeChild(link);
|
|
5867
|
+
URL.revokeObjectURL(blobUrl);
|
|
5868
|
+
} catch {
|
|
5869
|
+
window.open(currentImage.url, "_blank");
|
|
5870
|
+
}
|
|
5871
|
+
}, [currentImage, currentIndex]);
|
|
5872
|
+
const handleClose = react.useCallback(() => {
|
|
5873
|
+
onCloseRef.current();
|
|
5874
|
+
}, []);
|
|
5875
|
+
if (!currentImage || !container) return null;
|
|
5876
|
+
return reactDom.createPortal(
|
|
5877
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5878
|
+
"div",
|
|
5879
|
+
{
|
|
5880
|
+
"data-lightbox-backdrop": "true",
|
|
5881
|
+
className: `absolute inset-0 flex items-center justify-center bg-black/90 ${className || ""}`,
|
|
5882
|
+
style: { cursor: "zoom-out" },
|
|
5883
|
+
children: [
|
|
5884
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5885
|
+
"div",
|
|
5886
|
+
{
|
|
5887
|
+
className: "absolute top-0 left-0 right-0 flex items-center justify-between p-4",
|
|
5888
|
+
style: { zIndex: 10 },
|
|
5889
|
+
children: [
|
|
5890
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-white text-sm", children: hasMultiple && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
5891
|
+
currentIndex + 1,
|
|
5892
|
+
" / ",
|
|
5893
|
+
images.length
|
|
5894
|
+
] }) }),
|
|
5895
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
5896
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5897
|
+
"button",
|
|
5898
|
+
{
|
|
5899
|
+
type: "button",
|
|
5900
|
+
onClick: (e) => {
|
|
5901
|
+
e.stopPropagation();
|
|
5902
|
+
handleDownload();
|
|
5903
|
+
},
|
|
5904
|
+
className: "p-2 rounded-full bg-white/10 hover:bg-white/20 text-white transition-colors",
|
|
5905
|
+
style: { cursor: "pointer", pointerEvents: "auto" },
|
|
5906
|
+
"aria-label": "Download image",
|
|
5907
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon, { className: "h-5 w-5" })
|
|
5908
|
+
}
|
|
5909
|
+
),
|
|
5910
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5911
|
+
"button",
|
|
5912
|
+
{
|
|
5913
|
+
type: "button",
|
|
5914
|
+
onClick: (e) => {
|
|
5915
|
+
e.stopPropagation();
|
|
5916
|
+
handleClose();
|
|
5917
|
+
},
|
|
5918
|
+
className: "p-2 rounded-full bg-white/10 hover:bg-white/20 text-white transition-colors",
|
|
5919
|
+
style: { cursor: "pointer", pointerEvents: "auto" },
|
|
5920
|
+
"aria-label": "Close lightbox",
|
|
5921
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(XIcon, { className: "h-5 w-5" })
|
|
5922
|
+
}
|
|
5923
|
+
)
|
|
5924
|
+
] })
|
|
5925
|
+
]
|
|
5926
|
+
}
|
|
5927
|
+
),
|
|
5928
|
+
hasMultiple && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5929
|
+
"button",
|
|
5930
|
+
{
|
|
5931
|
+
type: "button",
|
|
5932
|
+
onClick: (e) => {
|
|
5933
|
+
e.stopPropagation();
|
|
5934
|
+
onPrev();
|
|
5935
|
+
},
|
|
5936
|
+
className: "absolute left-4 top-1/2 -translate-y-1/2 p-2 rounded-full bg-white/10 hover:bg-white/20 text-white transition-colors",
|
|
5937
|
+
style: { zIndex: 10, cursor: "pointer", pointerEvents: "auto" },
|
|
5938
|
+
"aria-label": "Previous image",
|
|
5939
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, { className: "h-6 w-6" })
|
|
5940
|
+
}
|
|
5941
|
+
),
|
|
5942
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5943
|
+
"img",
|
|
5944
|
+
{
|
|
5945
|
+
src: currentImage.url,
|
|
5946
|
+
alt: currentImage.alt || `Image ${currentIndex + 1}`,
|
|
5947
|
+
className: "max-w-[90vw] max-h-[85vh] object-contain select-none",
|
|
5948
|
+
style: { cursor: "default", pointerEvents: "auto" },
|
|
5949
|
+
draggable: false
|
|
5950
|
+
}
|
|
5951
|
+
),
|
|
5952
|
+
hasMultiple && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5953
|
+
"button",
|
|
5954
|
+
{
|
|
5955
|
+
type: "button",
|
|
5956
|
+
onClick: (e) => {
|
|
5957
|
+
e.stopPropagation();
|
|
5958
|
+
onNext();
|
|
5959
|
+
},
|
|
5960
|
+
className: "absolute right-4 top-1/2 -translate-y-1/2 p-2 rounded-full bg-white/10 hover:bg-white/20 text-white transition-colors",
|
|
5961
|
+
style: { zIndex: 10, cursor: "pointer", pointerEvents: "auto" },
|
|
5962
|
+
"aria-label": "Next image",
|
|
5963
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, { className: "h-6 w-6" })
|
|
5964
|
+
}
|
|
5965
|
+
),
|
|
5966
|
+
currentImage.alt && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5967
|
+
"div",
|
|
5968
|
+
{
|
|
5969
|
+
className: "absolute bottom-0 left-0 right-0 p-4 text-center",
|
|
5970
|
+
style: { zIndex: 10, pointerEvents: "none" },
|
|
5971
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-white text-sm bg-black/50 inline-block px-3 py-1 rounded-full", children: currentImage.alt })
|
|
5972
|
+
}
|
|
5973
|
+
)
|
|
5974
|
+
]
|
|
5975
|
+
}
|
|
5976
|
+
),
|
|
5977
|
+
container
|
|
5978
|
+
);
|
|
5979
|
+
}
|
|
5980
|
+
function cn7(...classes) {
|
|
5981
|
+
return classes.filter(Boolean).join(" ");
|
|
5982
|
+
}
|
|
5983
|
+
function ImageWithLoading({ src, alt, className, onClick }) {
|
|
5984
|
+
const [isLoaded, setIsLoaded] = react.useState(false);
|
|
5985
|
+
const [hasError, setHasError] = react.useState(false);
|
|
5986
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5987
|
+
"div",
|
|
5988
|
+
{
|
|
5989
|
+
className: cn7(
|
|
5990
|
+
"relative overflow-hidden rounded-lg",
|
|
5991
|
+
className
|
|
5992
|
+
),
|
|
5993
|
+
children: [
|
|
5994
|
+
!isLoaded && !hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 animate-pulse bg-gray-200 dark:bg-gray-700 rounded-lg" }),
|
|
5995
|
+
hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center text-gray-400 dark:text-gray-500 text-sm rounded-lg bg-gray-100 dark:bg-gray-800", children: "Failed to load" }),
|
|
5996
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5997
|
+
"img",
|
|
5998
|
+
{
|
|
5999
|
+
src,
|
|
6000
|
+
alt,
|
|
6001
|
+
loading: "lazy",
|
|
6002
|
+
className: cn7(
|
|
6003
|
+
"w-full h-auto max-h-[280px] object-cover rounded-lg shadow-sm transition-opacity duration-200",
|
|
6004
|
+
isLoaded ? "opacity-100" : "opacity-0"
|
|
6005
|
+
),
|
|
6006
|
+
onLoad: () => setIsLoaded(true),
|
|
6007
|
+
onError: () => setHasError(true),
|
|
6008
|
+
onClick,
|
|
6009
|
+
style: onClick ? { cursor: "pointer" } : void 0
|
|
6010
|
+
}
|
|
6011
|
+
)
|
|
6012
|
+
]
|
|
6013
|
+
}
|
|
6014
|
+
);
|
|
6015
|
+
}
|
|
6016
|
+
function ImageGallery({
|
|
6017
|
+
images,
|
|
6018
|
+
onImageClick,
|
|
6019
|
+
className
|
|
6020
|
+
}) {
|
|
6021
|
+
const [lightboxIndex, setLightboxIndex] = react.useState(null);
|
|
6022
|
+
const handleImageClick = react.useCallback(
|
|
6023
|
+
(image, index) => {
|
|
6024
|
+
if (onImageClick) {
|
|
6025
|
+
onImageClick(image);
|
|
6026
|
+
} else {
|
|
6027
|
+
setLightboxIndex(index);
|
|
6028
|
+
}
|
|
6029
|
+
},
|
|
6030
|
+
[onImageClick]
|
|
6031
|
+
);
|
|
6032
|
+
const handleLightboxClose = react.useCallback(() => {
|
|
6033
|
+
setLightboxIndex(null);
|
|
6034
|
+
}, []);
|
|
6035
|
+
const handleLightboxPrev = react.useCallback(() => {
|
|
6036
|
+
setLightboxIndex(
|
|
6037
|
+
(prev) => prev !== null ? (prev - 1 + images.length) % images.length : null
|
|
6038
|
+
);
|
|
6039
|
+
}, [images.length]);
|
|
6040
|
+
const handleLightboxNext = react.useCallback(() => {
|
|
6041
|
+
setLightboxIndex(
|
|
6042
|
+
(prev) => prev !== null ? (prev + 1) % images.length : null
|
|
6043
|
+
);
|
|
6044
|
+
}, [images.length]);
|
|
6045
|
+
if (!images || images.length === 0) return null;
|
|
6046
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6047
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6048
|
+
"div",
|
|
6049
|
+
{
|
|
6050
|
+
className: cn7(
|
|
6051
|
+
"grid gap-2",
|
|
6052
|
+
images.length === 1 ? "grid-cols-1" : images.length === 2 ? "grid-cols-2" : "grid-cols-2 sm:grid-cols-3",
|
|
6053
|
+
className
|
|
6054
|
+
),
|
|
6055
|
+
children: images.map((image, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6056
|
+
"button",
|
|
6057
|
+
{
|
|
6058
|
+
type: "button",
|
|
6059
|
+
onClick: () => handleImageClick(image, index),
|
|
6060
|
+
className: "block rounded-lg overflow-hidden transition-transform hover:scale-[1.02] text-left",
|
|
6061
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6062
|
+
ImageWithLoading,
|
|
6063
|
+
{
|
|
6064
|
+
src: image.url,
|
|
6065
|
+
alt: image.alt || `Image ${index + 1}`
|
|
6066
|
+
}
|
|
6067
|
+
)
|
|
6068
|
+
},
|
|
6069
|
+
`${image.url}-${index}`
|
|
6070
|
+
))
|
|
6071
|
+
}
|
|
6072
|
+
),
|
|
6073
|
+
lightboxIndex !== null && !onImageClick && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6074
|
+
ImageLightbox,
|
|
6075
|
+
{
|
|
6076
|
+
images,
|
|
6077
|
+
currentIndex: lightboxIndex,
|
|
6078
|
+
onClose: handleLightboxClose,
|
|
6079
|
+
onPrev: handleLightboxPrev,
|
|
6080
|
+
onNext: handleLightboxNext
|
|
6081
|
+
}
|
|
6082
|
+
)
|
|
6083
|
+
] });
|
|
6084
|
+
}
|
|
6085
|
+
function cn8(...classes) {
|
|
6086
|
+
return classes.filter(Boolean).join(" ");
|
|
6087
|
+
}
|
|
5419
6088
|
function MarkdownContent({
|
|
5420
6089
|
content,
|
|
5421
6090
|
className,
|
|
@@ -5435,11 +6104,11 @@ function MarkdownContent({
|
|
|
5435
6104
|
h3: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold mt-3 mb-1 first:mt-0", children }),
|
|
5436
6105
|
h4: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-base font-semibold mt-2 mb-1 first:mt-0", children }),
|
|
5437
6106
|
// Paragraphs
|
|
5438
|
-
p: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-
|
|
6107
|
+
p: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-1.5 last:mb-0", children }),
|
|
5439
6108
|
// Lists
|
|
5440
|
-
ul: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "list-disc list-inside mb-
|
|
5441
|
-
ol: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "list-decimal list-inside mb-
|
|
5442
|
-
li: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "
|
|
6109
|
+
ul: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "list-disc list-inside mb-1.5 last:mb-0", children }),
|
|
6110
|
+
ol: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "list-decimal list-inside mb-1.5 last:mb-0", children }),
|
|
6111
|
+
li: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "", children }),
|
|
5443
6112
|
// Links
|
|
5444
6113
|
a: ({ href, children }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5445
6114
|
"a",
|
|
@@ -5474,7 +6143,7 @@ function MarkdownContent({
|
|
|
5474
6143
|
if (isCodeBlock) {
|
|
5475
6144
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative my-2", children: [
|
|
5476
6145
|
language && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-0 right-0 px-2 py-1 text-xs font-mono text-gray-500 dark:text-gray-400 bg-gray-100 dark:bg-gray-800 rounded-bl rounded-tr border-b border-l border-gray-200 dark:border-gray-700", children: language }),
|
|
5477
|
-
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "bg-gray-100 dark:bg-gray-800 rounded-lg p-4 overflow-x-auto text-sm", children: /* @__PURE__ */ jsxRuntime.jsx("code", { className:
|
|
6146
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "bg-gray-100 dark:bg-gray-800 rounded-lg p-4 overflow-x-auto text-sm", children: /* @__PURE__ */ jsxRuntime.jsx("code", { className: cn8("font-mono", codeClassName), ...props, children }) })
|
|
5478
6147
|
] });
|
|
5479
6148
|
}
|
|
5480
6149
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5521,7 +6190,7 @@ function MarkdownContent({
|
|
|
5521
6190
|
() => customComponents ? { ...defaultComponents, ...customComponents } : defaultComponents,
|
|
5522
6191
|
[defaultComponents, customComponents]
|
|
5523
6192
|
);
|
|
5524
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className:
|
|
6193
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn8("max-w-none text-sm leading-relaxed", className), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5525
6194
|
ReactMarkdown__default.default,
|
|
5526
6195
|
{
|
|
5527
6196
|
remarkPlugins: [remarkGfm__default.default],
|
|
@@ -5531,6 +6200,58 @@ function MarkdownContent({
|
|
|
5531
6200
|
}
|
|
5532
6201
|
) });
|
|
5533
6202
|
}
|
|
6203
|
+
function cn9(...classes) {
|
|
6204
|
+
return classes.filter(Boolean).join(" ");
|
|
6205
|
+
}
|
|
6206
|
+
function ThinkingBlock({
|
|
6207
|
+
block,
|
|
6208
|
+
defaultExpanded = false,
|
|
6209
|
+
className
|
|
6210
|
+
}) {
|
|
6211
|
+
const [isExpanded, setIsExpanded] = react.useState(defaultExpanded);
|
|
6212
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6213
|
+
"div",
|
|
6214
|
+
{
|
|
6215
|
+
className: cn9(
|
|
6216
|
+
"rounded-lg border",
|
|
6217
|
+
"border-purple-200 dark:border-purple-800",
|
|
6218
|
+
"bg-purple-50/50 dark:bg-purple-950/20",
|
|
6219
|
+
className
|
|
6220
|
+
),
|
|
6221
|
+
children: [
|
|
6222
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6223
|
+
"button",
|
|
6224
|
+
{
|
|
6225
|
+
type: "button",
|
|
6226
|
+
onClick: () => setIsExpanded(!isExpanded),
|
|
6227
|
+
className: "w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-purple-100/50 dark:hover:bg-purple-900/30 transition-colors rounded-lg",
|
|
6228
|
+
children: [
|
|
6229
|
+
isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon, { className: "h-4 w-4 text-purple-400 flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, { className: "h-4 w-4 text-purple-400 flex-shrink-0" }),
|
|
6230
|
+
/* @__PURE__ */ jsxRuntime.jsx(SparklesIcon, { className: "h-4 w-4 text-purple-500 flex-shrink-0" }),
|
|
6231
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-purple-700 dark:text-purple-300", children: "Thinking" })
|
|
6232
|
+
]
|
|
6233
|
+
}
|
|
6234
|
+
),
|
|
6235
|
+
isExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pb-3 border-t border-purple-200 dark:border-purple-800", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 text-sm text-purple-800 dark:text-purple-200 whitespace-pre-wrap font-mono leading-relaxed", children: block.content }) })
|
|
6236
|
+
]
|
|
6237
|
+
}
|
|
6238
|
+
);
|
|
6239
|
+
}
|
|
6240
|
+
function ThinkingBlockList({
|
|
6241
|
+
blocks,
|
|
6242
|
+
defaultExpanded = false,
|
|
6243
|
+
className
|
|
6244
|
+
}) {
|
|
6245
|
+
if (!blocks || blocks.length === 0) return null;
|
|
6246
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn9("space-y-2", className), children: blocks.map((block) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6247
|
+
ThinkingBlock,
|
|
6248
|
+
{
|
|
6249
|
+
block,
|
|
6250
|
+
defaultExpanded
|
|
6251
|
+
},
|
|
6252
|
+
block.id
|
|
6253
|
+
)) });
|
|
6254
|
+
}
|
|
5534
6255
|
var INTERNAL_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
5535
6256
|
"update_task_list",
|
|
5536
6257
|
"create_task",
|
|
@@ -5547,7 +6268,8 @@ var INTERNAL_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
5547
6268
|
"check_task_status",
|
|
5548
6269
|
"assign_task",
|
|
5549
6270
|
"update_plan",
|
|
5550
|
-
"check_delegations"
|
|
6271
|
+
"check_delegations",
|
|
6272
|
+
"activate_skill"
|
|
5551
6273
|
]);
|
|
5552
6274
|
function isInternalTool(toolName) {
|
|
5553
6275
|
if (!toolName) return false;
|
|
@@ -5561,11 +6283,20 @@ function isInternalTool(toolName) {
|
|
|
5561
6283
|
}
|
|
5562
6284
|
return false;
|
|
5563
6285
|
}
|
|
5564
|
-
function
|
|
6286
|
+
function cn10(...classes) {
|
|
5565
6287
|
return classes.filter(Boolean).join(" ");
|
|
5566
6288
|
}
|
|
5567
6289
|
function formatToolName(toolName) {
|
|
5568
6290
|
if (!toolName) return toolName;
|
|
6291
|
+
if (toolName.includes(".")) {
|
|
6292
|
+
const segments = toolName.split(".");
|
|
6293
|
+
const uniqueSegments = segments.filter(
|
|
6294
|
+
(seg, idx) => idx === 0 || seg.toLowerCase().trim() !== segments[idx - 1]?.toLowerCase().trim()
|
|
6295
|
+
);
|
|
6296
|
+
const bestSegment = uniqueSegments[uniqueSegments.length - 1]?.trim() || toolName;
|
|
6297
|
+
if (bestSegment.includes(" ")) return bestSegment;
|
|
6298
|
+
return formatToolName(bestSegment);
|
|
6299
|
+
}
|
|
5569
6300
|
const prefixesToRemove = [
|
|
5570
6301
|
"skills_api_",
|
|
5571
6302
|
"tools_api_",
|
|
@@ -5610,7 +6341,7 @@ function formatToolName(toolName) {
|
|
|
5610
6341
|
}
|
|
5611
6342
|
return uniqueWords.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
5612
6343
|
}
|
|
5613
|
-
function
|
|
6344
|
+
function formatDuration2(ms) {
|
|
5614
6345
|
if (ms < 1e3) {
|
|
5615
6346
|
return `${ms}ms`;
|
|
5616
6347
|
}
|
|
@@ -5631,7 +6362,7 @@ function formatJsonPreview(data, maxLength = 100) {
|
|
|
5631
6362
|
return String(data);
|
|
5632
6363
|
}
|
|
5633
6364
|
}
|
|
5634
|
-
function
|
|
6365
|
+
function extractImagesFromResult2(result) {
|
|
5635
6366
|
if (!result) return [];
|
|
5636
6367
|
let data = result;
|
|
5637
6368
|
if (typeof result === "string") {
|
|
@@ -5670,14 +6401,23 @@ function ToolCallEntry({
|
|
|
5670
6401
|
compact = false
|
|
5671
6402
|
}) {
|
|
5672
6403
|
const [isExpanded, setIsExpanded] = react.useState(false);
|
|
6404
|
+
const [lightboxIndex, setLightboxIndex] = react.useState(null);
|
|
5673
6405
|
const formattedName = react.useMemo(
|
|
5674
6406
|
() => formatToolName(toolCall.name),
|
|
5675
6407
|
[toolCall.name]
|
|
5676
6408
|
);
|
|
5677
6409
|
const resultImages = react.useMemo(
|
|
5678
|
-
() => toolCall.status === "completed" && toolCall.result ?
|
|
6410
|
+
() => toolCall.status === "completed" && toolCall.result ? extractImagesFromResult2(toolCall.result) : [],
|
|
5679
6411
|
[toolCall.status, toolCall.result]
|
|
5680
6412
|
);
|
|
6413
|
+
const lightboxImages = react.useMemo(
|
|
6414
|
+
() => resultImages.map((img) => ({
|
|
6415
|
+
url: img.url,
|
|
6416
|
+
alt: img.alt || img.prompt,
|
|
6417
|
+
filename: img.alt || img.prompt
|
|
6418
|
+
})),
|
|
6419
|
+
[resultImages]
|
|
6420
|
+
);
|
|
5681
6421
|
const hasImages = resultImages.length > 0;
|
|
5682
6422
|
const statusIcon = react.useMemo(() => {
|
|
5683
6423
|
switch (toolCall.status) {
|
|
@@ -5711,14 +6451,14 @@ function ToolCallEntry({
|
|
|
5711
6451
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5712
6452
|
"div",
|
|
5713
6453
|
{
|
|
5714
|
-
className:
|
|
6454
|
+
className: cn10(
|
|
5715
6455
|
"inline-flex items-center gap-1.5 text-xs text-gray-500 dark:text-gray-400",
|
|
5716
6456
|
className
|
|
5717
6457
|
),
|
|
5718
6458
|
children: [
|
|
5719
6459
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: statusIcon }),
|
|
5720
6460
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formattedName }),
|
|
5721
|
-
toolCall.durationMs !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400 dark:text-gray-500", children:
|
|
6461
|
+
toolCall.durationMs !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400 dark:text-gray-500", children: formatDuration2(toolCall.durationMs) })
|
|
5722
6462
|
]
|
|
5723
6463
|
}
|
|
5724
6464
|
);
|
|
@@ -5726,7 +6466,7 @@ function ToolCallEntry({
|
|
|
5726
6466
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5727
6467
|
"div",
|
|
5728
6468
|
{
|
|
5729
|
-
className:
|
|
6469
|
+
className: cn10(
|
|
5730
6470
|
"rounded-lg border text-sm",
|
|
5731
6471
|
statusColor,
|
|
5732
6472
|
className
|
|
@@ -5742,52 +6482,61 @@ function ToolCallEntry({
|
|
|
5742
6482
|
isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon, { className: "h-4 w-4 text-gray-400 flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, { className: "h-4 w-4 text-gray-400 flex-shrink-0" }),
|
|
5743
6483
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: statusIcon }),
|
|
5744
6484
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-gray-900 dark:text-gray-100 truncate", children: formattedName }),
|
|
5745
|
-
toolCall.status === "completed" && toolCall.durationMs !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto text-xs text-gray-500 dark:text-gray-400 flex-shrink-0", children:
|
|
6485
|
+
toolCall.status === "completed" && toolCall.durationMs !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto text-xs text-gray-500 dark:text-gray-400 flex-shrink-0", children: formatDuration2(toolCall.durationMs) }),
|
|
5746
6486
|
toolCall.status === "failed" && toolCall.error && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto text-xs text-red-600 dark:text-red-400 truncate max-w-[150px]", children: toolCall.error })
|
|
5747
6487
|
]
|
|
5748
6488
|
}
|
|
5749
6489
|
),
|
|
5750
|
-
hasImages && /* @__PURE__ */ jsxRuntime.
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
/* @__PURE__ */ jsxRuntime.
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
6490
|
+
hasImages && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 pb-3", children: [
|
|
6491
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn10(
|
|
6492
|
+
"grid gap-3",
|
|
6493
|
+
resultImages.length === 1 ? "grid-cols-1 max-w-sm" : resultImages.length === 2 ? "grid-cols-2" : "grid-cols-2 sm:grid-cols-3"
|
|
6494
|
+
), children: resultImages.map((img, idx) => {
|
|
6495
|
+
const altText = img.alt || img.prompt || `Generated image ${idx + 1}`;
|
|
6496
|
+
const imageElement = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group relative", children: [
|
|
6497
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6498
|
+
"img",
|
|
6499
|
+
{
|
|
6500
|
+
src: img.thumbnailUrl || img.url,
|
|
6501
|
+
alt: altText,
|
|
6502
|
+
className: "w-full h-auto max-h-[280px] object-cover rounded-lg shadow-sm",
|
|
6503
|
+
loading: "lazy"
|
|
6504
|
+
}
|
|
6505
|
+
),
|
|
6506
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 rounded-lg bg-black/0 group-hover:bg-black/10 dark:group-hover:bg-white/5 transition-colors" })
|
|
6507
|
+
] });
|
|
5768
6508
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5769
6509
|
"button",
|
|
5770
6510
|
{
|
|
5771
6511
|
type: "button",
|
|
5772
|
-
onClick: () =>
|
|
5773
|
-
|
|
6512
|
+
onClick: () => {
|
|
6513
|
+
if (onImageClick) {
|
|
6514
|
+
onImageClick({ url: img.url, alt: altText, filename: altText });
|
|
6515
|
+
} else {
|
|
6516
|
+
setLightboxIndex(idx);
|
|
6517
|
+
}
|
|
6518
|
+
},
|
|
6519
|
+
className: "block rounded-lg overflow-hidden cursor-pointer text-left transition-transform hover:scale-[1.02]",
|
|
5774
6520
|
children: imageElement
|
|
5775
6521
|
},
|
|
5776
6522
|
idx
|
|
5777
6523
|
);
|
|
5778
|
-
}
|
|
5779
|
-
|
|
5780
|
-
|
|
6524
|
+
}) }),
|
|
6525
|
+
lightboxIndex !== null && !onImageClick && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6526
|
+
ImageLightbox,
|
|
5781
6527
|
{
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
6528
|
+
images: lightboxImages,
|
|
6529
|
+
currentIndex: lightboxIndex,
|
|
6530
|
+
onClose: () => setLightboxIndex(null),
|
|
6531
|
+
onPrev: () => setLightboxIndex(
|
|
6532
|
+
(prev) => prev !== null ? (prev - 1 + lightboxImages.length) % lightboxImages.length : null
|
|
6533
|
+
),
|
|
6534
|
+
onNext: () => setLightboxIndex(
|
|
6535
|
+
(prev) => prev !== null ? (prev + 1) % lightboxImages.length : null
|
|
6536
|
+
)
|
|
6537
|
+
}
|
|
6538
|
+
)
|
|
6539
|
+
] }),
|
|
5791
6540
|
isExpanded && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-gray-200 dark:border-gray-700 px-3 py-2 space-y-2", children: [
|
|
5792
6541
|
toolCall.args && Object.keys(toolCall.args).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
5793
6542
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-medium text-gray-500 dark:text-gray-400 mb-1", children: "Input" }),
|
|
@@ -5806,22 +6555,185 @@ function ToolCallEntry({
|
|
|
5806
6555
|
}
|
|
5807
6556
|
);
|
|
5808
6557
|
}
|
|
5809
|
-
function
|
|
6558
|
+
function cn11(...classes) {
|
|
5810
6559
|
return classes.filter(Boolean).join(" ");
|
|
5811
6560
|
}
|
|
6561
|
+
function normalizeToolNameForGrouping(name) {
|
|
6562
|
+
const lastSegment = name.includes(".") ? name.split(".").pop() : name;
|
|
6563
|
+
return lastSegment.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
6564
|
+
}
|
|
6565
|
+
function groupToolCalls(toolCalls) {
|
|
6566
|
+
const byNormalizedName = /* @__PURE__ */ new Map();
|
|
6567
|
+
const nameOrder = [];
|
|
6568
|
+
for (const tc of toolCalls) {
|
|
6569
|
+
const key = normalizeToolNameForGrouping(tc.name);
|
|
6570
|
+
if (!byNormalizedName.has(key)) {
|
|
6571
|
+
byNormalizedName.set(key, []);
|
|
6572
|
+
nameOrder.push(key);
|
|
6573
|
+
}
|
|
6574
|
+
byNormalizedName.get(key).push(tc);
|
|
6575
|
+
}
|
|
6576
|
+
const groups = [];
|
|
6577
|
+
for (const key of nameOrder) {
|
|
6578
|
+
const calls = byNormalizedName.get(key);
|
|
6579
|
+
if (calls.length === 1) {
|
|
6580
|
+
groups.push({ type: "single", toolCall: calls[0] });
|
|
6581
|
+
} else {
|
|
6582
|
+
groups.push({ type: "group", name: calls[0].name, toolCalls: calls });
|
|
6583
|
+
}
|
|
6584
|
+
}
|
|
6585
|
+
return groups;
|
|
6586
|
+
}
|
|
6587
|
+
function ToolCallList({ toolCalls, toolCallVerbosity, onImageClick, renderToolCall }) {
|
|
6588
|
+
const visibleToolCalls = react.useMemo(() => {
|
|
6589
|
+
if (toolCallVerbosity !== "compact") return toolCalls;
|
|
6590
|
+
return toolCalls.filter((tc) => !isInternalTool(tc.name));
|
|
6591
|
+
}, [toolCalls, toolCallVerbosity]);
|
|
6592
|
+
const grouped = react.useMemo(() => groupToolCalls(visibleToolCalls), [visibleToolCalls]);
|
|
6593
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: grouped.map((group) => {
|
|
6594
|
+
if (group.type === "single") {
|
|
6595
|
+
const toolCall = group.toolCall;
|
|
6596
|
+
const defaultRender = () => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6597
|
+
ToolCallEntry,
|
|
6598
|
+
{
|
|
6599
|
+
toolCall,
|
|
6600
|
+
onImageClick
|
|
6601
|
+
},
|
|
6602
|
+
toolCall.id
|
|
6603
|
+
);
|
|
6604
|
+
if (renderToolCall) {
|
|
6605
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderToolCall(toolCall, defaultRender) }, toolCall.id);
|
|
6606
|
+
}
|
|
6607
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: defaultRender() }, toolCall.id);
|
|
6608
|
+
}
|
|
6609
|
+
const completed = group.toolCalls.filter((tc) => tc.status === "completed" || tc.status === "failed");
|
|
6610
|
+
const running = group.toolCalls.filter((tc) => tc.status !== "completed" && tc.status !== "failed");
|
|
6611
|
+
const allImages = completed.flatMap(
|
|
6612
|
+
(tc) => tc.result ? extractImagesFromResult2(tc.result) : []
|
|
6613
|
+
);
|
|
6614
|
+
const hasImages = allImages.length > 0;
|
|
6615
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
6616
|
+
running.length > 0 && running[0] && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6617
|
+
ToolCallEntry,
|
|
6618
|
+
{
|
|
6619
|
+
toolCall: {
|
|
6620
|
+
...running[0],
|
|
6621
|
+
name: running.length > 1 ? `${running[0].name} (${running.length})` : running[0].name
|
|
6622
|
+
},
|
|
6623
|
+
onImageClick
|
|
6624
|
+
},
|
|
6625
|
+
running[0].id
|
|
6626
|
+
),
|
|
6627
|
+
completed.length > 0 && hasImages && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6628
|
+
GroupedImageGallery,
|
|
6629
|
+
{
|
|
6630
|
+
images: allImages,
|
|
6631
|
+
completedCount: completed.length,
|
|
6632
|
+
onImageClick
|
|
6633
|
+
}
|
|
6634
|
+
),
|
|
6635
|
+
completed.length > 0 && !hasImages && completed.map((tc) => {
|
|
6636
|
+
const defaultRender = () => /* @__PURE__ */ jsxRuntime.jsx(ToolCallEntry, { toolCall: tc, onImageClick }, tc.id);
|
|
6637
|
+
if (renderToolCall) {
|
|
6638
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderToolCall(tc, defaultRender) }, tc.id);
|
|
6639
|
+
}
|
|
6640
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: defaultRender() }, tc.id);
|
|
6641
|
+
})
|
|
6642
|
+
] }, `group-${group.name}-${group.toolCalls[0]?.id}`);
|
|
6643
|
+
}) });
|
|
6644
|
+
}
|
|
6645
|
+
function GroupedImageGallery({
|
|
6646
|
+
images,
|
|
6647
|
+
completedCount,
|
|
6648
|
+
onImageClick
|
|
6649
|
+
}) {
|
|
6650
|
+
const [lightboxIndex, setLightboxIndex] = react.useState(null);
|
|
6651
|
+
const lightboxImages = react.useMemo(
|
|
6652
|
+
() => images.map((img) => ({
|
|
6653
|
+
url: img.url,
|
|
6654
|
+
alt: img.alt || img.prompt,
|
|
6655
|
+
filename: img.alt || img.prompt
|
|
6656
|
+
})),
|
|
6657
|
+
[images]
|
|
6658
|
+
);
|
|
6659
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
6660
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400 px-1", children: [
|
|
6661
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-4 w-4 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "h-4 w-4 text-green-500", children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "20 6 9 17 4 12" }) }) }),
|
|
6662
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
6663
|
+
completedCount,
|
|
6664
|
+
" image",
|
|
6665
|
+
completedCount !== 1 ? "s" : "",
|
|
6666
|
+
" generated"
|
|
6667
|
+
] })
|
|
6668
|
+
] }),
|
|
6669
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn11(
|
|
6670
|
+
"grid gap-3",
|
|
6671
|
+
images.length === 1 ? "grid-cols-1 max-w-sm" : images.length === 2 ? "grid-cols-2" : "grid-cols-2 sm:grid-cols-3"
|
|
6672
|
+
), children: images.map((img, idx) => {
|
|
6673
|
+
const altText = img.alt || img.prompt || `Generated image ${idx + 1}`;
|
|
6674
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6675
|
+
"button",
|
|
6676
|
+
{
|
|
6677
|
+
type: "button",
|
|
6678
|
+
onClick: () => {
|
|
6679
|
+
if (onImageClick) {
|
|
6680
|
+
onImageClick({ url: img.url, alt: altText, filename: altText });
|
|
6681
|
+
} else {
|
|
6682
|
+
setLightboxIndex(idx);
|
|
6683
|
+
}
|
|
6684
|
+
},
|
|
6685
|
+
className: "block rounded-lg overflow-hidden cursor-pointer text-left transition-transform hover:scale-[1.02] group",
|
|
6686
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
6687
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6688
|
+
"img",
|
|
6689
|
+
{
|
|
6690
|
+
src: img.thumbnailUrl || img.url,
|
|
6691
|
+
alt: altText,
|
|
6692
|
+
className: "w-full h-auto max-h-[280px] object-cover rounded-lg shadow-sm",
|
|
6693
|
+
loading: "lazy"
|
|
6694
|
+
}
|
|
6695
|
+
),
|
|
6696
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 rounded-lg bg-black/0 group-hover:bg-black/10 dark:group-hover:bg-white/5 transition-colors" })
|
|
6697
|
+
] })
|
|
6698
|
+
},
|
|
6699
|
+
`${img.url}-${idx}`
|
|
6700
|
+
);
|
|
6701
|
+
}) }),
|
|
6702
|
+
lightboxIndex !== null && !onImageClick && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6703
|
+
ImageLightbox,
|
|
6704
|
+
{
|
|
6705
|
+
images: lightboxImages,
|
|
6706
|
+
currentIndex: lightboxIndex,
|
|
6707
|
+
onClose: () => setLightboxIndex(null),
|
|
6708
|
+
onPrev: () => setLightboxIndex(
|
|
6709
|
+
(prev) => prev !== null ? (prev - 1 + lightboxImages.length) % lightboxImages.length : null
|
|
6710
|
+
),
|
|
6711
|
+
onNext: () => setLightboxIndex(
|
|
6712
|
+
(prev) => prev !== null ? (prev + 1) % lightboxImages.length : null
|
|
6713
|
+
)
|
|
6714
|
+
}
|
|
6715
|
+
)
|
|
6716
|
+
] });
|
|
6717
|
+
}
|
|
5812
6718
|
function ChatMessage({
|
|
5813
6719
|
message,
|
|
5814
6720
|
enableMarkdown = true,
|
|
5815
6721
|
showToolCalls = true,
|
|
5816
|
-
toolCallVerbosity,
|
|
6722
|
+
toolCallVerbosity = "compact",
|
|
5817
6723
|
className,
|
|
5818
6724
|
markdownComponents,
|
|
5819
6725
|
markdownUrlTransform,
|
|
5820
6726
|
markdownContentTransform,
|
|
5821
|
-
onImageClick
|
|
6727
|
+
onImageClick,
|
|
6728
|
+
showThinking = true,
|
|
6729
|
+
showDelegation = true,
|
|
6730
|
+
showImages = true,
|
|
6731
|
+
renderToolCall,
|
|
6732
|
+
variant = "bubble"
|
|
5822
6733
|
}) {
|
|
5823
6734
|
const isUser = message.role === "user";
|
|
5824
6735
|
const isAssistant = message.role === "assistant";
|
|
6736
|
+
const isFlat = variant === "flat";
|
|
5825
6737
|
const formattedTime = react.useMemo(() => {
|
|
5826
6738
|
const date = message.timestamp instanceof Date ? message.timestamp : new Date(message.timestamp);
|
|
5827
6739
|
return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
@@ -5829,113 +6741,119 @@ function ChatMessage({
|
|
|
5829
6741
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5830
6742
|
"div",
|
|
5831
6743
|
{
|
|
5832
|
-
className:
|
|
5833
|
-
"flex gap-3
|
|
5834
|
-
|
|
6744
|
+
className: cn11(
|
|
6745
|
+
"cadra-chat-message flex gap-3",
|
|
6746
|
+
isFlat ? "py-5 px-4" : "p-4",
|
|
6747
|
+
// Bubble: user messages right-aligned. Flat: always left-aligned.
|
|
6748
|
+
!isFlat && isUser ? "flex-row-reverse" : "flex-row",
|
|
6749
|
+
// Flat variant: subtle row background for user messages
|
|
6750
|
+
isFlat && isUser && "chat-message-user-row",
|
|
5835
6751
|
className
|
|
5836
6752
|
),
|
|
6753
|
+
style: isFlat && isUser ? {
|
|
6754
|
+
backgroundColor: "var(--chat-user-row-bg, rgba(128, 128, 128, 0.08))"
|
|
6755
|
+
} : void 0,
|
|
6756
|
+
"data-role": message.role,
|
|
5837
6757
|
children: [
|
|
5838
6758
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5839
6759
|
"div",
|
|
5840
6760
|
{
|
|
5841
|
-
className:
|
|
5842
|
-
|
|
5843
|
-
isUser ? "
|
|
5844
|
-
|
|
6761
|
+
className: "flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center shadow-sm",
|
|
6762
|
+
style: {
|
|
6763
|
+
backgroundColor: isUser ? "var(--chat-user-avatar-bg, #3b82f6)" : "var(--chat-assistant-avatar-bg, #e5e7eb)",
|
|
6764
|
+
color: isUser ? "var(--chat-user-avatar-text, #fff)" : "var(--chat-assistant-avatar-text, #4b5563)"
|
|
6765
|
+
},
|
|
5845
6766
|
children: isUser ? /* @__PURE__ */ jsxRuntime.jsx(UserIcon, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(BotIcon, { className: "h-4 w-4" })
|
|
5846
6767
|
}
|
|
5847
6768
|
),
|
|
5848
6769
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5849
6770
|
"div",
|
|
5850
6771
|
{
|
|
5851
|
-
className:
|
|
5852
|
-
"flex-1 min-w-0
|
|
5853
|
-
|
|
6772
|
+
className: cn11(
|
|
6773
|
+
"flex-1 min-w-0",
|
|
6774
|
+
isFlat ? "pt-0.5" : "space-y-2",
|
|
6775
|
+
!isFlat && isUser ? "text-right" : "text-left"
|
|
5854
6776
|
),
|
|
5855
6777
|
children: [
|
|
5856
6778
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5857
6779
|
"div",
|
|
5858
6780
|
{
|
|
5859
|
-
className:
|
|
5860
|
-
"flex items-center gap-2 text-xs
|
|
5861
|
-
|
|
6781
|
+
className: cn11(
|
|
6782
|
+
"flex items-center gap-2 text-xs",
|
|
6783
|
+
isFlat ? "mb-1.5" : "",
|
|
6784
|
+
!isFlat && isUser ? "justify-end" : "justify-start"
|
|
5862
6785
|
),
|
|
6786
|
+
style: { color: "var(--chat-meta-text, #6b7280)" },
|
|
5863
6787
|
children: [
|
|
5864
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: isUser ? "You" : "Assistant" }),
|
|
6788
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", style: { color: "var(--chat-label-text, inherit)" }, children: isUser ? "You" : "Assistant" }),
|
|
5865
6789
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formattedTime }),
|
|
5866
6790
|
message.isStreaming && /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, { className: "h-3 w-3" })
|
|
5867
6791
|
]
|
|
5868
6792
|
}
|
|
5869
6793
|
),
|
|
5870
|
-
message.thinkingBlocks && message.thinkingBlocks.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5871
|
-
|
|
6794
|
+
showThinking && message.thinkingBlocks && message.thinkingBlocks.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ThinkingBlockList, { blocks: message.thinkingBlocks }),
|
|
6795
|
+
showDelegation && message.delegationEvents && message.delegationEvents.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(DelegationProgressList, { events: message.delegationEvents }),
|
|
6796
|
+
showToolCalls && toolCallVerbosity !== "hidden" && message.toolCalls && message.toolCalls.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6797
|
+
ToolCallList,
|
|
5872
6798
|
{
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
]
|
|
5878
|
-
},
|
|
5879
|
-
block.id
|
|
5880
|
-
)) }),
|
|
5881
|
-
showToolCalls && toolCallVerbosity !== "hidden" && message.toolCalls && message.toolCalls.length > 0 && (() => {
|
|
5882
|
-
const verbosity = toolCallVerbosity ?? "verbose";
|
|
5883
|
-
const filteredToolCalls = verbosity === "compact" ? message.toolCalls.filter((tc) => !isInternalTool(tc.name)) : message.toolCalls;
|
|
5884
|
-
if (filteredToolCalls.length === 0) return null;
|
|
5885
|
-
if (verbosity === "compact") {
|
|
5886
|
-
const runningTools = filteredToolCalls.filter((tc) => tc.status === "pending" || tc.status === "running");
|
|
5887
|
-
const doneTools = filteredToolCalls.filter((tc) => tc.status === "completed" || tc.status === "failed");
|
|
5888
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
5889
|
-
doneTools.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-x-3 gap-y-1", children: doneTools.map((toolCall) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5890
|
-
ToolCallEntry,
|
|
5891
|
-
{
|
|
5892
|
-
toolCall,
|
|
5893
|
-
onImageClick,
|
|
5894
|
-
compact: true
|
|
5895
|
-
},
|
|
5896
|
-
toolCall.id
|
|
5897
|
-
)) }),
|
|
5898
|
-
runningTools.map((toolCall) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5899
|
-
ToolCallEntry,
|
|
5900
|
-
{
|
|
5901
|
-
toolCall,
|
|
5902
|
-
onImageClick
|
|
5903
|
-
},
|
|
5904
|
-
toolCall.id
|
|
5905
|
-
))
|
|
5906
|
-
] });
|
|
6799
|
+
toolCalls: message.toolCalls,
|
|
6800
|
+
toolCallVerbosity,
|
|
6801
|
+
onImageClick,
|
|
6802
|
+
renderToolCall
|
|
5907
6803
|
}
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
toolCall,
|
|
5912
|
-
onImageClick
|
|
5913
|
-
},
|
|
5914
|
-
toolCall.id
|
|
5915
|
-
)) });
|
|
5916
|
-
})(),
|
|
5917
|
-
message.content && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5918
|
-
"div",
|
|
6804
|
+
),
|
|
6805
|
+
showImages && !showToolCalls && message.images && message.images.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6806
|
+
ImageGallery,
|
|
5919
6807
|
{
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
isUser ? "bg-blue-500 text-white" : "bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-gray-100"
|
|
5923
|
-
),
|
|
5924
|
-
children: isAssistant && enableMarkdown ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5925
|
-
MarkdownContent,
|
|
5926
|
-
{
|
|
5927
|
-
content: message.content,
|
|
5928
|
-
components: markdownComponents,
|
|
5929
|
-
urlTransform: markdownUrlTransform,
|
|
5930
|
-
contentTransform: markdownContentTransform
|
|
5931
|
-
}
|
|
5932
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap", children: message.content })
|
|
6808
|
+
images: message.images,
|
|
6809
|
+
onImageClick: onImageClick ? (img) => onImageClick({ url: img.url, alt: img.alt, filename: img.filename }) : void 0
|
|
5933
6810
|
}
|
|
5934
6811
|
),
|
|
6812
|
+
message.content && (isFlat ? (
|
|
6813
|
+
// Flat variant: no bubble, just text with theme-aware color
|
|
6814
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6815
|
+
"div",
|
|
6816
|
+
{
|
|
6817
|
+
className: cn11("text-sm break-words", !(isAssistant && enableMarkdown) && "whitespace-pre-wrap"),
|
|
6818
|
+
style: { color: "var(--chat-content-text, inherit)" },
|
|
6819
|
+
children: isAssistant && enableMarkdown ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6820
|
+
MarkdownContent,
|
|
6821
|
+
{
|
|
6822
|
+
content: message.content,
|
|
6823
|
+
components: markdownComponents,
|
|
6824
|
+
urlTransform: markdownUrlTransform,
|
|
6825
|
+
contentTransform: markdownContentTransform
|
|
6826
|
+
}
|
|
6827
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap", children: message.content })
|
|
6828
|
+
}
|
|
6829
|
+
)
|
|
6830
|
+
) : (
|
|
6831
|
+
// Bubble variant: colored bubble backgrounds
|
|
6832
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6833
|
+
"div",
|
|
6834
|
+
{
|
|
6835
|
+
className: "rounded-lg p-3",
|
|
6836
|
+
style: {
|
|
6837
|
+
backgroundColor: isUser ? "var(--chat-user-bg, #3b82f6)" : "var(--chat-assistant-bg, #f3f4f6)",
|
|
6838
|
+
color: isUser ? "var(--chat-user-text, #fff)" : "var(--chat-assistant-text, #111827)"
|
|
6839
|
+
},
|
|
6840
|
+
children: isAssistant && enableMarkdown ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6841
|
+
MarkdownContent,
|
|
6842
|
+
{
|
|
6843
|
+
content: message.content,
|
|
6844
|
+
components: markdownComponents,
|
|
6845
|
+
urlTransform: markdownUrlTransform,
|
|
6846
|
+
contentTransform: markdownContentTransform
|
|
6847
|
+
}
|
|
6848
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap", children: message.content })
|
|
6849
|
+
}
|
|
6850
|
+
)
|
|
6851
|
+
)),
|
|
5935
6852
|
message.attachments && message.attachments.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: message.attachments.map((attachment) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5936
6853
|
"div",
|
|
5937
6854
|
{
|
|
5938
|
-
className: "flex items-center gap-2
|
|
6855
|
+
className: "flex items-center gap-2 rounded-lg px-3 py-2 text-sm",
|
|
6856
|
+
style: { backgroundColor: "var(--chat-assistant-bg, #f3f4f6)" },
|
|
5939
6857
|
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate max-w-[150px]", children: attachment.filename })
|
|
5940
6858
|
},
|
|
5941
6859
|
attachment.uuid
|
|
@@ -5947,7 +6865,7 @@ function ChatMessage({
|
|
|
5947
6865
|
}
|
|
5948
6866
|
);
|
|
5949
6867
|
}
|
|
5950
|
-
function
|
|
6868
|
+
function cn12(...classes) {
|
|
5951
6869
|
return classes.filter(Boolean).join(" ");
|
|
5952
6870
|
}
|
|
5953
6871
|
function MessageList({
|
|
@@ -5965,6 +6883,12 @@ function MessageList({
|
|
|
5965
6883
|
markdownUrlTransform,
|
|
5966
6884
|
markdownContentTransform,
|
|
5967
6885
|
onImageClick,
|
|
6886
|
+
showThinking = true,
|
|
6887
|
+
showDelegation = true,
|
|
6888
|
+
showImages = true,
|
|
6889
|
+
renderMessage,
|
|
6890
|
+
renderToolCall,
|
|
6891
|
+
messageVariant = "bubble",
|
|
5968
6892
|
sendMessage
|
|
5969
6893
|
}) {
|
|
5970
6894
|
const scrollRef = react.useRef(null);
|
|
@@ -5978,7 +6902,7 @@ function MessageList({
|
|
|
5978
6902
|
"div",
|
|
5979
6903
|
{
|
|
5980
6904
|
ref: scrollRef,
|
|
5981
|
-
className:
|
|
6905
|
+
className: cn12(
|
|
5982
6906
|
"flex-1 overflow-y-auto",
|
|
5983
6907
|
className
|
|
5984
6908
|
),
|
|
@@ -5989,20 +6913,31 @@ function MessageList({
|
|
|
5989
6913
|
] }) }),
|
|
5990
6914
|
messages.length === 0 && !isLoading && !isLoadingHistory && (renderWelcome ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: typeof renderWelcome === "function" ? renderWelcome({ sendMessage: sendMessage || (() => {
|
|
5991
6915
|
}) }) : renderWelcome }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center h-full p-8", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center text-gray-500 dark:text-gray-400", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg", children: welcomeMessage }) }) })),
|
|
5992
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-gray-100 dark:divide-gray-800", children: messages.map((message) =>
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6916
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-gray-100 dark:divide-gray-800", children: messages.map((message) => {
|
|
6917
|
+
const defaultRender = () => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6918
|
+
ChatMessage,
|
|
6919
|
+
{
|
|
6920
|
+
message,
|
|
6921
|
+
enableMarkdown,
|
|
6922
|
+
showToolCalls,
|
|
6923
|
+
toolCallVerbosity,
|
|
6924
|
+
markdownComponents,
|
|
6925
|
+
markdownUrlTransform,
|
|
6926
|
+
markdownContentTransform,
|
|
6927
|
+
onImageClick,
|
|
6928
|
+
showThinking,
|
|
6929
|
+
showDelegation,
|
|
6930
|
+
showImages,
|
|
6931
|
+
renderToolCall,
|
|
6932
|
+
variant: messageVariant
|
|
6933
|
+
},
|
|
6934
|
+
message.id
|
|
6935
|
+
);
|
|
6936
|
+
if (renderMessage) {
|
|
6937
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderMessage(message, defaultRender) }, message.id);
|
|
6938
|
+
}
|
|
6939
|
+
return defaultRender();
|
|
6940
|
+
}) }),
|
|
6006
6941
|
isLoading && !isStreaming && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 p-4", children: [
|
|
6007
6942
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 w-8 h-8 rounded-full bg-gray-200 dark:bg-gray-700 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, { className: "h-4 w-4 text-gray-600 dark:text-gray-300" }) }),
|
|
6008
6943
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-gray-500 dark:text-gray-400", children: "Thinking..." })
|
|
@@ -6058,6 +6993,7 @@ function AgentChat({
|
|
|
6058
6993
|
maxHeight = "600px",
|
|
6059
6994
|
className,
|
|
6060
6995
|
theme = "system",
|
|
6996
|
+
layout = "fixed",
|
|
6061
6997
|
enableAttachments = false,
|
|
6062
6998
|
enableMarkdown = true,
|
|
6063
6999
|
showToolCalls = true,
|
|
@@ -6065,7 +7001,21 @@ function AgentChat({
|
|
|
6065
7001
|
markdownComponents,
|
|
6066
7002
|
markdownUrlTransform,
|
|
6067
7003
|
markdownContentTransform,
|
|
6068
|
-
onImageClick
|
|
7004
|
+
onImageClick,
|
|
7005
|
+
// Extension props
|
|
7006
|
+
hideHeader,
|
|
7007
|
+
renderAboveInput,
|
|
7008
|
+
renderBelowMessages,
|
|
7009
|
+
renderMessage,
|
|
7010
|
+
renderToolCall,
|
|
7011
|
+
messageVariant = "bubble",
|
|
7012
|
+
showThinking = true,
|
|
7013
|
+
showDelegation = true,
|
|
7014
|
+
showImages = true,
|
|
7015
|
+
pollingInterval,
|
|
7016
|
+
pollingEnabled,
|
|
7017
|
+
onDelegation,
|
|
7018
|
+
onAttachmentsReady
|
|
6069
7019
|
}) {
|
|
6070
7020
|
const {
|
|
6071
7021
|
messages,
|
|
@@ -6092,7 +7042,10 @@ function AgentChat({
|
|
|
6092
7042
|
onSessionStart,
|
|
6093
7043
|
onToolCall,
|
|
6094
7044
|
onToolResult,
|
|
6095
|
-
onClarification
|
|
7045
|
+
onClarification,
|
|
7046
|
+
onDelegation,
|
|
7047
|
+
pollingInterval,
|
|
7048
|
+
pollingEnabled
|
|
6096
7049
|
});
|
|
6097
7050
|
const effectiveVerbosity = showToolCalls === false ? "hidden" : toolCallVerbosity ?? "compact";
|
|
6098
7051
|
const dropZoneRef = react.useRef(null);
|
|
@@ -6109,6 +7062,11 @@ function AgentChat({
|
|
|
6109
7062
|
console.error("[AgentChat] Attachment error:", msg);
|
|
6110
7063
|
}
|
|
6111
7064
|
});
|
|
7065
|
+
react.useEffect(() => {
|
|
7066
|
+
if (enableAttachments && onAttachmentsReady) {
|
|
7067
|
+
onAttachmentsReady({ addExternalFile: attachments.addExternalFile });
|
|
7068
|
+
}
|
|
7069
|
+
}, [enableAttachments, onAttachmentsReady, attachments.addExternalFile]);
|
|
6112
7070
|
const handleSend = react.useCallback(
|
|
6113
7071
|
async (content) => {
|
|
6114
7072
|
if (enableAttachments && attachments.hasReadyFiles) {
|
|
@@ -6121,51 +7079,31 @@ function AgentChat({
|
|
|
6121
7079
|
},
|
|
6122
7080
|
[enableAttachments, attachments, sendMessage]
|
|
6123
7081
|
);
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
)
|
|
6150
|
-
}
|
|
6151
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
6152
|
-
MessageList,
|
|
6153
|
-
{
|
|
6154
|
-
messages,
|
|
6155
|
-
welcomeMessage,
|
|
6156
|
-
renderWelcome,
|
|
6157
|
-
isLoading,
|
|
6158
|
-
isStreaming,
|
|
6159
|
-
isLoadingHistory,
|
|
6160
|
-
enableMarkdown,
|
|
6161
|
-
showToolCalls,
|
|
6162
|
-
markdownComponents,
|
|
6163
|
-
markdownUrlTransform,
|
|
6164
|
-
markdownContentTransform,
|
|
6165
|
-
onImageClick,
|
|
6166
|
-
sendMessage: handleSend
|
|
6167
|
-
}
|
|
6168
|
-
),
|
|
7082
|
+
const messageListProps = {
|
|
7083
|
+
messages,
|
|
7084
|
+
welcomeMessage: hideHeader ? void 0 : welcomeMessage,
|
|
7085
|
+
renderWelcome: hideHeader ? void 0 : renderWelcome,
|
|
7086
|
+
isLoading,
|
|
7087
|
+
isStreaming,
|
|
7088
|
+
isLoadingHistory,
|
|
7089
|
+
enableMarkdown,
|
|
7090
|
+
showToolCalls,
|
|
7091
|
+
toolCallVerbosity: effectiveVerbosity,
|
|
7092
|
+
markdownComponents,
|
|
7093
|
+
markdownUrlTransform,
|
|
7094
|
+
markdownContentTransform,
|
|
7095
|
+
onImageClick,
|
|
7096
|
+
showThinking,
|
|
7097
|
+
showDelegation,
|
|
7098
|
+
showImages,
|
|
7099
|
+
renderMessage,
|
|
7100
|
+
renderToolCall,
|
|
7101
|
+
messageVariant,
|
|
7102
|
+
sendMessage: handleSend
|
|
7103
|
+
};
|
|
7104
|
+
const chatContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7105
|
+
/* @__PURE__ */ jsxRuntime.jsx(MessageList, { ...messageListProps }),
|
|
7106
|
+
renderBelowMessages?.(),
|
|
6169
7107
|
clarification && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-gray-200 dark:border-gray-700 p-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6170
7108
|
AskUserPrompt,
|
|
6171
7109
|
{
|
|
@@ -6175,6 +7113,7 @@ function AgentChat({
|
|
|
6175
7113
|
}
|
|
6176
7114
|
) }),
|
|
6177
7115
|
error && /* @__PURE__ */ jsxRuntime.jsx(ErrorBanner, { error, onRetry: retry, onDismiss: clearError }),
|
|
7116
|
+
renderAboveInput?.(),
|
|
6178
7117
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6179
7118
|
ChatInput,
|
|
6180
7119
|
{
|
|
@@ -6191,8 +7130,17 @@ function AgentChat({
|
|
|
6191
7130
|
}
|
|
6192
7131
|
)
|
|
6193
7132
|
] });
|
|
7133
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ChatContainer, { maxHeight, className, theme, layout, children: enableAttachments ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
7134
|
+
FileDropZone,
|
|
7135
|
+
{
|
|
7136
|
+
ref: dropZoneRef,
|
|
7137
|
+
...attachments.dropZoneProps,
|
|
7138
|
+
disabled: isLoading || !!clarification || isLoadingHistory,
|
|
7139
|
+
children: chatContent
|
|
7140
|
+
}
|
|
7141
|
+
) : chatContent });
|
|
6194
7142
|
}
|
|
6195
|
-
function
|
|
7143
|
+
function cn13(...classes) {
|
|
6196
7144
|
return classes.filter(Boolean).join(" ");
|
|
6197
7145
|
}
|
|
6198
7146
|
function TodoList({
|
|
@@ -6221,7 +7169,7 @@ function TodoList({
|
|
|
6221
7169
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6222
7170
|
"div",
|
|
6223
7171
|
{
|
|
6224
|
-
className:
|
|
7172
|
+
className: cn13(
|
|
6225
7173
|
"rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden",
|
|
6226
7174
|
className
|
|
6227
7175
|
),
|
|
@@ -6229,7 +7177,7 @@ function TodoList({
|
|
|
6229
7177
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6230
7178
|
"div",
|
|
6231
7179
|
{
|
|
6232
|
-
className:
|
|
7180
|
+
className: cn13(
|
|
6233
7181
|
"flex items-center gap-2 px-3 py-2 bg-gray-50 dark:bg-gray-800/50",
|
|
6234
7182
|
collapsible && "cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800"
|
|
6235
7183
|
),
|
|
@@ -6260,7 +7208,7 @@ function TodoList({
|
|
|
6260
7208
|
!isCollapsed && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "divide-y divide-gray-100 dark:divide-gray-700", children: todos.map((todo, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6261
7209
|
"li",
|
|
6262
7210
|
{
|
|
6263
|
-
className:
|
|
7211
|
+
className: cn13(
|
|
6264
7212
|
"px-3 py-2 flex items-start gap-2 text-sm",
|
|
6265
7213
|
todo.status === "in_progress" && "bg-blue-50/50 dark:bg-blue-950/20",
|
|
6266
7214
|
todo.status === "completed" && "opacity-60"
|
|
@@ -6270,7 +7218,7 @@ function TodoList({
|
|
|
6270
7218
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6271
7219
|
"p",
|
|
6272
7220
|
{
|
|
6273
|
-
className:
|
|
7221
|
+
className: cn13(
|
|
6274
7222
|
"text-gray-700 dark:text-gray-300",
|
|
6275
7223
|
todo.status === "completed" && "line-through"
|
|
6276
7224
|
),
|
|
@@ -6287,39 +7235,6 @@ function TodoList({
|
|
|
6287
7235
|
);
|
|
6288
7236
|
}
|
|
6289
7237
|
|
|
6290
|
-
// src/chat/index.ts
|
|
6291
|
-
var DEPRECATION_WARNING = `
|
|
6292
|
-
[@cadraos/sdk/chat] DEPRECATION WARNING
|
|
6293
|
-
|
|
6294
|
-
This module is deprecated and will be removed in a future version.
|
|
6295
|
-
Please migrate to @cadraos/react for:
|
|
6296
|
-
- Simpler setup with CadraCopilot
|
|
6297
|
-
- Better security (header-based SSE auth)
|
|
6298
|
-
- Scoped CSS that won't conflict with your app
|
|
6299
|
-
|
|
6300
|
-
Migration steps:
|
|
6301
|
-
1. npm install @cadraos/react
|
|
6302
|
-
2. import '@cadraos/react/styles.css'
|
|
6303
|
-
3. Replace <AgentChat> with <CadraCopilot> or <CadraChat>
|
|
6304
|
-
|
|
6305
|
-
See: https://github.com/cadraos/cadra-sdk/blob/main/packages/react/MIGRATION.md
|
|
6306
|
-
`;
|
|
6307
|
-
var hasWarned = false;
|
|
6308
|
-
function showDeprecationWarning() {
|
|
6309
|
-
if (hasWarned) return;
|
|
6310
|
-
hasWarned = true;
|
|
6311
|
-
if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") {
|
|
6312
|
-
return;
|
|
6313
|
-
}
|
|
6314
|
-
if (typeof window === "undefined") {
|
|
6315
|
-
return;
|
|
6316
|
-
}
|
|
6317
|
-
console.warn(DEPRECATION_WARNING);
|
|
6318
|
-
}
|
|
6319
|
-
if (typeof window !== "undefined") {
|
|
6320
|
-
setTimeout(showDeprecationWarning, 0);
|
|
6321
|
-
}
|
|
6322
|
-
|
|
6323
7238
|
exports.AgentChat = AgentChat;
|
|
6324
7239
|
exports.AlertCircleIcon = AlertCircleIcon;
|
|
6325
7240
|
exports.AskUserPrompt = AskUserPrompt;
|
|
@@ -6338,6 +7253,8 @@ exports.ClockIcon = ClockIcon;
|
|
|
6338
7253
|
exports.CodeIcon = CodeIcon;
|
|
6339
7254
|
exports.CopyIcon = CopyIcon;
|
|
6340
7255
|
exports.DatabaseIcon = DatabaseIcon;
|
|
7256
|
+
exports.DelegationProgress = DelegationProgress;
|
|
7257
|
+
exports.DelegationProgressList = DelegationProgressList;
|
|
6341
7258
|
exports.DownloadIcon = DownloadIcon;
|
|
6342
7259
|
exports.ExternalLinkIcon = ExternalLinkIcon;
|
|
6343
7260
|
exports.FileDropZone = FileDropZone;
|
|
@@ -6345,7 +7262,9 @@ exports.FileIcon = FileIcon;
|
|
|
6345
7262
|
exports.FileTextIcon = FileTextIcon;
|
|
6346
7263
|
exports.HelpCircleIcon = HelpCircleIcon;
|
|
6347
7264
|
exports.INTERNAL_TOOL_NAMES = INTERNAL_TOOL_NAMES;
|
|
7265
|
+
exports.ImageGallery = ImageGallery;
|
|
6348
7266
|
exports.ImageIcon = ImageIcon;
|
|
7267
|
+
exports.ImageLightbox = ImageLightbox;
|
|
6349
7268
|
exports.ImagesIcon = ImagesIcon;
|
|
6350
7269
|
exports.ListTodoIcon = ListTodoIcon;
|
|
6351
7270
|
exports.LoadingSpinner = LoadingSpinner;
|
|
@@ -6358,6 +7277,8 @@ exports.PaperclipIcon = PaperclipIcon;
|
|
|
6358
7277
|
exports.SendIcon = SendIcon;
|
|
6359
7278
|
exports.SparklesIcon = SparklesIcon;
|
|
6360
7279
|
exports.StopCircleIcon = StopCircleIcon;
|
|
7280
|
+
exports.ThinkingBlock = ThinkingBlock;
|
|
7281
|
+
exports.ThinkingBlockList = ThinkingBlockList;
|
|
6361
7282
|
exports.TodoList = TodoList;
|
|
6362
7283
|
exports.ToolCallEntry = ToolCallEntry;
|
|
6363
7284
|
exports.UserIcon = UserIcon;
|