@cadraos/sdk 0.1.11-test → 0.1.12
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 +899 -252
- package/dist/chat/index.cjs.map +1 -1
- package/dist/chat/index.d.cts +277 -39
- package/dist/chat/index.d.ts +277 -39
- package/dist/chat/index.js +894 -253
- 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 +14 -19
- package/dist/chat/styles.css +0 -1
package/dist/chat/index.cjs
CHANGED
|
@@ -588,9 +588,11 @@ var DEFAULT_STREAMING_CONFIG = {
|
|
|
588
588
|
activityTimeoutMs: 3e4,
|
|
589
589
|
pollingIntervalMs: 2e3
|
|
590
590
|
};
|
|
591
|
+
var DEFAULT_POLLING_ENABLED = true;
|
|
591
592
|
var ExecutionStreamControllerImpl = class {
|
|
592
593
|
options;
|
|
593
594
|
config;
|
|
595
|
+
pollingEnabled;
|
|
594
596
|
sseClient = null;
|
|
595
597
|
status = "connecting";
|
|
596
598
|
reconnectAttempts = 0;
|
|
@@ -624,6 +626,7 @@ var ExecutionStreamControllerImpl = class {
|
|
|
624
626
|
constructor(options) {
|
|
625
627
|
this.options = options;
|
|
626
628
|
this.config = { ...DEFAULT_STREAMING_CONFIG, ...options.config };
|
|
629
|
+
this.pollingEnabled = options.pollingEnabled ?? DEFAULT_POLLING_ENABLED;
|
|
627
630
|
}
|
|
628
631
|
/**
|
|
629
632
|
* Get the last event ID (for resume support)
|
|
@@ -964,15 +967,61 @@ var ExecutionStreamControllerImpl = class {
|
|
|
964
967
|
if (this.status === "closed") {
|
|
965
968
|
return;
|
|
966
969
|
}
|
|
970
|
+
await this.recoverState();
|
|
971
|
+
if (this.status === "closed") {
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
967
974
|
try {
|
|
968
975
|
await this.connectSSE();
|
|
969
976
|
} catch {
|
|
970
977
|
await this.handleConnectionError(error);
|
|
971
978
|
}
|
|
972
979
|
} else {
|
|
973
|
-
this.
|
|
974
|
-
|
|
975
|
-
|
|
980
|
+
if (this.pollingEnabled) {
|
|
981
|
+
this.status = "fallback_polling";
|
|
982
|
+
this.emit("connectionChange", { connected: false, usingFallback: true });
|
|
983
|
+
this.startPolling();
|
|
984
|
+
} else {
|
|
985
|
+
this.handleError({
|
|
986
|
+
error: "SSE connection failed and polling is disabled",
|
|
987
|
+
errorCode: "connection_failed"
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
/**
|
|
993
|
+
* Recover state by checking execution status.
|
|
994
|
+
*
|
|
995
|
+
* Called during reconnection to catch any events missed while SSE was down.
|
|
996
|
+
* If the execution completed while disconnected, emits completion immediately.
|
|
997
|
+
* Otherwise, emits any new logs that weren't seen via SSE.
|
|
998
|
+
*/
|
|
999
|
+
async recoverState() {
|
|
1000
|
+
try {
|
|
1001
|
+
const execution = await this.options.getExecution(this.options.executionId);
|
|
1002
|
+
if (execution.logs) {
|
|
1003
|
+
for (const log of execution.logs) {
|
|
1004
|
+
if (!this.seenEventIds.has(log.uuid)) {
|
|
1005
|
+
this.seenEventIds.add(log.uuid);
|
|
1006
|
+
this.emit("log", log);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
if (execution.status === "completed") {
|
|
1011
|
+
this.stopPolling();
|
|
1012
|
+
this.handleComplete(execution);
|
|
1013
|
+
return;
|
|
1014
|
+
}
|
|
1015
|
+
if (execution.status === "failed" || execution.status === "cancelled") {
|
|
1016
|
+
this.stopPolling();
|
|
1017
|
+
this.handleError({
|
|
1018
|
+
error: execution.error ?? `Execution ${execution.status}`,
|
|
1019
|
+
errorCode: execution.status
|
|
1020
|
+
});
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
} catch (err) {
|
|
1024
|
+
console.warn("[SDK:StreamController] State recovery failed (non-fatal):", err);
|
|
976
1025
|
}
|
|
977
1026
|
}
|
|
978
1027
|
/**
|
|
@@ -2824,12 +2873,54 @@ function useExecutionStream(options) {
|
|
|
2824
2873
|
}
|
|
2825
2874
|
|
|
2826
2875
|
// src/chat/hooks/useAgentChat.ts
|
|
2876
|
+
var __DEV__ = typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
|
|
2827
2877
|
var SILENT_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
2828
2878
|
"check_delegations"
|
|
2829
2879
|
]);
|
|
2830
2880
|
function generateId() {
|
|
2831
2881
|
return `msg-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
2832
2882
|
}
|
|
2883
|
+
function extractImagesFromResult(result, sourceToolCallId) {
|
|
2884
|
+
if (!result) return [];
|
|
2885
|
+
let data = result;
|
|
2886
|
+
if (typeof result === "string") {
|
|
2887
|
+
try {
|
|
2888
|
+
data = JSON.parse(result);
|
|
2889
|
+
} catch {
|
|
2890
|
+
if (/\.(png|jpg|jpeg|gif|webp|svg|bmp)(\?.*)?$/i.test(result) || result.startsWith("data:image/")) {
|
|
2891
|
+
return [{ url: result, sourceToolCallId }];
|
|
2892
|
+
}
|
|
2893
|
+
return [];
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
if (typeof data !== "object" || data === null) return [];
|
|
2897
|
+
const obj = data;
|
|
2898
|
+
if (Array.isArray(obj.images)) {
|
|
2899
|
+
return obj.images.filter((img) => typeof img.url === "string").map((img) => ({
|
|
2900
|
+
url: img.url,
|
|
2901
|
+
alt: img.alt || img.prompt || void 0,
|
|
2902
|
+
filename: img.filename,
|
|
2903
|
+
sourceToolCallId
|
|
2904
|
+
}));
|
|
2905
|
+
}
|
|
2906
|
+
if (typeof obj.url === "string" && /\.(png|jpg|jpeg|gif|webp|svg|bmp)(\?.*)?$/i.test(obj.url)) {
|
|
2907
|
+
return [{ url: obj.url, alt: obj.alt, sourceToolCallId }];
|
|
2908
|
+
}
|
|
2909
|
+
if (typeof obj.imageUrl === "string") {
|
|
2910
|
+
return [{ url: obj.imageUrl, alt: obj.alt, sourceToolCallId }];
|
|
2911
|
+
}
|
|
2912
|
+
return [];
|
|
2913
|
+
}
|
|
2914
|
+
function deriveImagesFromToolCalls(toolCalls) {
|
|
2915
|
+
if (!toolCalls) return [];
|
|
2916
|
+
const images = [];
|
|
2917
|
+
for (const tc of toolCalls) {
|
|
2918
|
+
if (tc.status === "completed" && tc.result) {
|
|
2919
|
+
images.push(...extractImagesFromResult(tc.result, tc.id));
|
|
2920
|
+
}
|
|
2921
|
+
}
|
|
2922
|
+
return images;
|
|
2923
|
+
}
|
|
2833
2924
|
function historyToMessage(historyMsg) {
|
|
2834
2925
|
return {
|
|
2835
2926
|
id: historyMsg.uuid,
|
|
@@ -2870,7 +2961,9 @@ function useAgentChat(options) {
|
|
|
2870
2961
|
// Deprecated, but still supported
|
|
2871
2962
|
onToolCall,
|
|
2872
2963
|
onToolResult,
|
|
2873
|
-
onClarification
|
|
2964
|
+
onClarification,
|
|
2965
|
+
pollingInterval,
|
|
2966
|
+
pollingEnabled
|
|
2874
2967
|
} = options;
|
|
2875
2968
|
const contextConfig = useChatConfigOptional();
|
|
2876
2969
|
const adapter = propsAdapter ?? contextConfig?.adapter;
|
|
@@ -2902,8 +2995,14 @@ function useAgentChat(options) {
|
|
|
2902
2995
|
const streamingMessageIdRef = react.useRef(null);
|
|
2903
2996
|
const pendingToolCallsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
2904
2997
|
const lastMessageContentRef = react.useRef("");
|
|
2998
|
+
const finalizedRef = react.useRef(false);
|
|
2905
2999
|
const firedToolResultsRef = react.useRef(/* @__PURE__ */ new Set());
|
|
2906
3000
|
const streamControllerRef = react.useRef(null);
|
|
3001
|
+
const pendingDelegationsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
3002
|
+
const onDelegationRef = react.useRef(options.onDelegation);
|
|
3003
|
+
react.useEffect(() => {
|
|
3004
|
+
onDelegationRef.current = options.onDelegation;
|
|
3005
|
+
}, [options.onDelegation]);
|
|
2907
3006
|
const updateStreamingMessage = react.useCallback((content) => {
|
|
2908
3007
|
if (!streamingMessageIdRef.current) return;
|
|
2909
3008
|
setMessages(
|
|
@@ -2932,25 +3031,72 @@ function useAgentChat(options) {
|
|
|
2932
3031
|
});
|
|
2933
3032
|
});
|
|
2934
3033
|
}, []);
|
|
2935
|
-
const
|
|
3034
|
+
const addDelegationEvent = react.useCallback((delegation) => {
|
|
3035
|
+
setMessages((prev) => {
|
|
3036
|
+
const targetId = streamingMessageIdRef.current ?? [...prev].reverse().find((m) => m.role === "assistant")?.id;
|
|
3037
|
+
if (!targetId) return prev;
|
|
3038
|
+
return prev.map((msg) => {
|
|
3039
|
+
if (msg.id !== targetId) return msg;
|
|
3040
|
+
const existing = msg.delegationEvents ?? [];
|
|
3041
|
+
if (delegation.type === "delegation_completed" && delegation.handoffId) {
|
|
3042
|
+
const updatedEvents = existing.map(
|
|
3043
|
+
(de) => de.handoffId === delegation.handoffId ? { ...de, ...delegation, status: delegation.status ?? "completed" } : de
|
|
3044
|
+
);
|
|
3045
|
+
const hasMatch = existing.some((de) => de.handoffId === delegation.handoffId);
|
|
3046
|
+
return {
|
|
3047
|
+
...msg,
|
|
3048
|
+
delegationEvents: hasMatch ? updatedEvents : [...existing, delegation]
|
|
3049
|
+
};
|
|
3050
|
+
}
|
|
3051
|
+
return { ...msg, delegationEvents: [...existing, delegation] };
|
|
3052
|
+
});
|
|
3053
|
+
});
|
|
3054
|
+
}, []);
|
|
3055
|
+
const updateMessageImages = react.useCallback(() => {
|
|
3056
|
+
setMessages((prev) => {
|
|
3057
|
+
const targetId = streamingMessageIdRef.current ?? [...prev].reverse().find((m) => m.role === "assistant")?.id;
|
|
3058
|
+
if (!targetId) return prev;
|
|
3059
|
+
return prev.map((msg) => {
|
|
3060
|
+
if (msg.id !== targetId) return msg;
|
|
3061
|
+
const images = deriveImagesFromToolCalls(msg.toolCalls);
|
|
3062
|
+
return images.length > 0 ? { ...msg, images } : msg;
|
|
3063
|
+
});
|
|
3064
|
+
});
|
|
3065
|
+
}, []);
|
|
3066
|
+
const finalizeStreamingMessage = react.useCallback((finalOutput) => {
|
|
2936
3067
|
if (!streamingMessageIdRef.current) return;
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
3068
|
+
finalizedRef.current = true;
|
|
3069
|
+
const streamMsgId = streamingMessageIdRef.current;
|
|
3070
|
+
setMessages((prev) => {
|
|
3071
|
+
const resolvedContent = finalOutput || streamingContentRef.current || "";
|
|
3072
|
+
const duplicateExists = resolvedContent && prev.some(
|
|
3073
|
+
(msg) => msg.id !== streamMsgId && msg.role === "assistant" && !msg.isStreaming && msg.content === resolvedContent
|
|
3074
|
+
);
|
|
3075
|
+
if (duplicateExists) {
|
|
3076
|
+
return prev.filter((msg) => msg.id !== streamMsgId);
|
|
3077
|
+
}
|
|
3078
|
+
return prev.map((msg) => {
|
|
3079
|
+
if (msg.id !== streamMsgId) return msg;
|
|
2940
3080
|
const updatedToolCalls = msg.toolCalls?.map(
|
|
2941
|
-
(tc) => tc.status === "running" || tc.status === "pending" ? { ...tc, status:
|
|
3081
|
+
(tc) => tc.status === "running" || tc.status === "pending" ? { ...tc, status: "completed" } : tc
|
|
2942
3082
|
);
|
|
2943
|
-
return {
|
|
2944
|
-
|
|
2945
|
-
|
|
3083
|
+
return {
|
|
3084
|
+
...msg,
|
|
3085
|
+
content: resolvedContent || msg.content,
|
|
3086
|
+
isStreaming: false,
|
|
3087
|
+
toolCalls: updatedToolCalls
|
|
3088
|
+
};
|
|
3089
|
+
});
|
|
3090
|
+
});
|
|
2946
3091
|
streamingMessageIdRef.current = null;
|
|
2947
3092
|
streamingContentRef.current = "";
|
|
2948
3093
|
pendingToolCallsRef.current.clear();
|
|
2949
3094
|
firedToolResultsRef.current.clear();
|
|
3095
|
+
pendingDelegationsRef.current.clear();
|
|
2950
3096
|
}, []);
|
|
2951
3097
|
const handleExecutionLog = react.useCallback(
|
|
2952
3098
|
(log) => {
|
|
2953
|
-
console.log("[useAgentChat] handleExecutionLog:", log.type, log.metadata);
|
|
3099
|
+
if (__DEV__) console.log("[useAgentChat] handleExecutionLog:", log.type, log.metadata);
|
|
2954
3100
|
switch (log.type) {
|
|
2955
3101
|
// Primary handlers for ai-saas-api worker log types
|
|
2956
3102
|
case "llm_response": {
|
|
@@ -2970,11 +3116,46 @@ function useAgentChat(options) {
|
|
|
2970
3116
|
}
|
|
2971
3117
|
break;
|
|
2972
3118
|
}
|
|
3119
|
+
case "delegation": {
|
|
3120
|
+
const delegationType = log.metadata?.delegationType;
|
|
3121
|
+
if (delegationType === "started" || delegationType === "delegation_started") {
|
|
3122
|
+
const delegation = {
|
|
3123
|
+
type: "delegation_started",
|
|
3124
|
+
handoffId: log.metadata?.handoffId,
|
|
3125
|
+
toAgent: log.metadata?.targetAgentName || log.metadata?.targetAgentUuid,
|
|
3126
|
+
targetAgentUuid: log.metadata?.targetAgentUuid,
|
|
3127
|
+
taskPreview: log.metadata?.taskPreview,
|
|
3128
|
+
timestamp: new Date(log.timestamp || Date.now()),
|
|
3129
|
+
status: "active"
|
|
3130
|
+
};
|
|
3131
|
+
if (delegation.handoffId) {
|
|
3132
|
+
pendingDelegationsRef.current.set(delegation.handoffId, delegation);
|
|
3133
|
+
}
|
|
3134
|
+
addDelegationEvent(delegation);
|
|
3135
|
+
onDelegationRef.current?.(delegation);
|
|
3136
|
+
} else if (delegationType === "completed" || delegationType === "delegation_completed") {
|
|
3137
|
+
const delegation = {
|
|
3138
|
+
type: "delegation_completed",
|
|
3139
|
+
handoffId: log.metadata?.handoffId,
|
|
3140
|
+
resultPreview: log.metadata?.resultPreview,
|
|
3141
|
+
timestamp: new Date(log.timestamp || Date.now()),
|
|
3142
|
+
status: log.metadata?.status === "failed" ? "failed" : "completed",
|
|
3143
|
+
durationMs: log.durationMs
|
|
3144
|
+
};
|
|
3145
|
+
if (delegation.handoffId) {
|
|
3146
|
+
pendingDelegationsRef.current.delete(delegation.handoffId);
|
|
3147
|
+
}
|
|
3148
|
+
addDelegationEvent(delegation);
|
|
3149
|
+
onDelegationRef.current?.(delegation);
|
|
3150
|
+
}
|
|
3151
|
+
break;
|
|
3152
|
+
}
|
|
2973
3153
|
case "info":
|
|
2974
3154
|
case "system":
|
|
2975
|
-
console.log("[useAgentChat] Status:", log.type, log.title);
|
|
3155
|
+
if (__DEV__) console.log("[useAgentChat] Status:", log.type, log.title);
|
|
2976
3156
|
break;
|
|
2977
3157
|
case "tool_call": {
|
|
3158
|
+
if (finalizedRef.current) break;
|
|
2978
3159
|
const toolName = log.metadata?.toolName;
|
|
2979
3160
|
if (SILENT_TOOL_NAMES.has(toolName)) break;
|
|
2980
3161
|
const toolCallId = log.metadata?.toolCallId || `tool-${Date.now()}`;
|
|
@@ -3029,17 +3210,18 @@ function useAgentChat(options) {
|
|
|
3029
3210
|
firedToolResultsRef.current.add(resultToolCallId);
|
|
3030
3211
|
}
|
|
3031
3212
|
onToolResultRef.current?.(resultToolName, result, durationMs);
|
|
3213
|
+
updateMessageImages();
|
|
3032
3214
|
break;
|
|
3033
3215
|
}
|
|
3034
3216
|
default:
|
|
3035
|
-
console.log("[useAgentChat] Unhandled log type:", log.type, log);
|
|
3217
|
+
if (__DEV__) console.log("[useAgentChat] Unhandled log type:", log.type, log);
|
|
3036
3218
|
}
|
|
3037
3219
|
},
|
|
3038
|
-
[updateStreamingMessage, updateToolCall]
|
|
3220
|
+
[updateStreamingMessage, updateToolCall, updateMessageImages, addDelegationEvent]
|
|
3039
3221
|
);
|
|
3040
3222
|
const handleStreamLog = react.useCallback(
|
|
3041
3223
|
(log) => {
|
|
3042
|
-
console.log("[useAgentChat] handleStreamLog:", log.logType, log.metadata);
|
|
3224
|
+
if (__DEV__) console.log("[useAgentChat] handleStreamLog:", log.logType, log.metadata);
|
|
3043
3225
|
switch (log.logType) {
|
|
3044
3226
|
case "llm_response": {
|
|
3045
3227
|
const llmText = log.metadata?.text || "";
|
|
@@ -3058,9 +3240,42 @@ function useAgentChat(options) {
|
|
|
3058
3240
|
}
|
|
3059
3241
|
break;
|
|
3060
3242
|
}
|
|
3243
|
+
case "delegation_started": {
|
|
3244
|
+
const delegation = {
|
|
3245
|
+
type: "delegation_started",
|
|
3246
|
+
handoffId: log.metadata?.handoffId,
|
|
3247
|
+
toAgent: log.metadata?.targetAgentName || log.metadata?.targetAgentUuid,
|
|
3248
|
+
targetAgentUuid: log.metadata?.targetAgentUuid,
|
|
3249
|
+
taskPreview: log.metadata?.taskPreview,
|
|
3250
|
+
timestamp: new Date(log.timestamp || Date.now()),
|
|
3251
|
+
status: "active"
|
|
3252
|
+
};
|
|
3253
|
+
if (delegation.handoffId) {
|
|
3254
|
+
pendingDelegationsRef.current.set(delegation.handoffId, delegation);
|
|
3255
|
+
}
|
|
3256
|
+
addDelegationEvent(delegation);
|
|
3257
|
+
onDelegationRef.current?.(delegation);
|
|
3258
|
+
break;
|
|
3259
|
+
}
|
|
3260
|
+
case "delegation_completed": {
|
|
3261
|
+
const delegation = {
|
|
3262
|
+
type: "delegation_completed",
|
|
3263
|
+
handoffId: log.metadata?.handoffId,
|
|
3264
|
+
resultPreview: log.metadata?.resultPreview,
|
|
3265
|
+
timestamp: new Date(log.timestamp || Date.now()),
|
|
3266
|
+
status: log.metadata?.status === "failed" ? "failed" : "completed",
|
|
3267
|
+
durationMs: log.durationMs
|
|
3268
|
+
};
|
|
3269
|
+
if (delegation.handoffId) {
|
|
3270
|
+
pendingDelegationsRef.current.delete(delegation.handoffId);
|
|
3271
|
+
}
|
|
3272
|
+
addDelegationEvent(delegation);
|
|
3273
|
+
onDelegationRef.current?.(delegation);
|
|
3274
|
+
break;
|
|
3275
|
+
}
|
|
3061
3276
|
case "info":
|
|
3062
3277
|
case "system":
|
|
3063
|
-
console.log("[useAgentChat] Status:", log.logType, log.message);
|
|
3278
|
+
if (__DEV__) console.log("[useAgentChat] Status:", log.logType, log.message);
|
|
3064
3279
|
break;
|
|
3065
3280
|
case "response_text":
|
|
3066
3281
|
case "text_chunk": {
|
|
@@ -3070,6 +3285,7 @@ function useAgentChat(options) {
|
|
|
3070
3285
|
break;
|
|
3071
3286
|
}
|
|
3072
3287
|
case "tool_call": {
|
|
3288
|
+
if (finalizedRef.current) break;
|
|
3073
3289
|
const toolName = log.metadata?.toolName;
|
|
3074
3290
|
if (SILENT_TOOL_NAMES.has(toolName)) break;
|
|
3075
3291
|
const toolCallId = log.metadata?.toolCallId || `tool-${Date.now()}`;
|
|
@@ -3124,6 +3340,7 @@ function useAgentChat(options) {
|
|
|
3124
3340
|
firedToolResultsRef.current.add(resultToolCallId);
|
|
3125
3341
|
}
|
|
3126
3342
|
onToolResultRef.current?.(resultToolName, result, durationMs);
|
|
3343
|
+
updateMessageImages();
|
|
3127
3344
|
break;
|
|
3128
3345
|
}
|
|
3129
3346
|
case "final_response": {
|
|
@@ -3135,10 +3352,10 @@ function useAgentChat(options) {
|
|
|
3135
3352
|
break;
|
|
3136
3353
|
}
|
|
3137
3354
|
default:
|
|
3138
|
-
console.log("[useAgentChat] Unknown log type:", log.logType, log);
|
|
3355
|
+
if (__DEV__) console.log("[useAgentChat] Unknown log type:", log.logType, log);
|
|
3139
3356
|
}
|
|
3140
3357
|
},
|
|
3141
|
-
[updateStreamingMessage, updateToolCall]
|
|
3358
|
+
[updateStreamingMessage, updateToolCall, updateMessageImages, addDelegationEvent]
|
|
3142
3359
|
);
|
|
3143
3360
|
const handleClarification = react.useCallback(
|
|
3144
3361
|
(data) => {
|
|
@@ -3147,17 +3364,23 @@ function useAgentChat(options) {
|
|
|
3147
3364
|
},
|
|
3148
3365
|
[onClarification]
|
|
3149
3366
|
);
|
|
3150
|
-
const
|
|
3151
|
-
|
|
3367
|
+
const completedRef = react.useRef(false);
|
|
3368
|
+
const handleComplete = react.useCallback((finalOutput) => {
|
|
3369
|
+
if (completedRef.current) {
|
|
3370
|
+
if (__DEV__) console.log("[useAgentChat] handleComplete: skipping duplicate complete");
|
|
3371
|
+
return;
|
|
3372
|
+
}
|
|
3373
|
+
completedRef.current = true;
|
|
3374
|
+
if (__DEV__) console.log("[useAgentChat] handleComplete called");
|
|
3152
3375
|
setIsLoading(false);
|
|
3153
3376
|
setIsStreamControllerConnected(false);
|
|
3154
|
-
finalizeStreamingMessage();
|
|
3377
|
+
finalizeStreamingMessage(finalOutput);
|
|
3155
3378
|
setCurrentExecutionId(null);
|
|
3156
3379
|
streamControllerRef.current = null;
|
|
3157
3380
|
}, [finalizeStreamingMessage]);
|
|
3158
3381
|
const handleError = react.useCallback(
|
|
3159
3382
|
(errorMsg) => {
|
|
3160
|
-
console.log("[useAgentChat] handleError called:", errorMsg);
|
|
3383
|
+
if (__DEV__) console.log("[useAgentChat] handleError called:", errorMsg);
|
|
3161
3384
|
const chatError = {
|
|
3162
3385
|
code: "EXECUTION_ERROR",
|
|
3163
3386
|
message: errorMsg,
|
|
@@ -3166,7 +3389,7 @@ function useAgentChat(options) {
|
|
|
3166
3389
|
setError(chatError);
|
|
3167
3390
|
setIsLoading(false);
|
|
3168
3391
|
setIsStreamControllerConnected(false);
|
|
3169
|
-
finalizeStreamingMessage(
|
|
3392
|
+
finalizeStreamingMessage();
|
|
3170
3393
|
setCurrentExecutionId(null);
|
|
3171
3394
|
streamControllerRef.current = null;
|
|
3172
3395
|
onError?.(chatError);
|
|
@@ -3196,43 +3419,39 @@ function useAgentChat(options) {
|
|
|
3196
3419
|
if (pollingExecutionIdRef.current === executionId) return;
|
|
3197
3420
|
stopPolling();
|
|
3198
3421
|
pollingExecutionIdRef.current = executionId;
|
|
3199
|
-
console.log("[useAgentChat] Starting polling fallback for:", executionId);
|
|
3422
|
+
if (__DEV__) console.log("[useAgentChat] Starting polling fallback for:", executionId);
|
|
3200
3423
|
const poll = async () => {
|
|
3201
3424
|
if (pollingExecutionIdRef.current !== executionId) return;
|
|
3202
3425
|
try {
|
|
3203
3426
|
const execution = await adapter.getExecution(executionId);
|
|
3204
3427
|
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
|
-
}
|
|
3428
|
+
if (__DEV__) console.log("[useAgentChat] Polling: execution completed");
|
|
3210
3429
|
stopPolling();
|
|
3211
|
-
handleComplete();
|
|
3430
|
+
handleComplete(execution.result || void 0);
|
|
3212
3431
|
} else if (execution.status === "failed") {
|
|
3213
|
-
console.log("[useAgentChat] Polling: execution failed");
|
|
3432
|
+
if (__DEV__) console.log("[useAgentChat] Polling: execution failed");
|
|
3214
3433
|
stopPolling();
|
|
3215
3434
|
handleError(execution.error || "Execution failed");
|
|
3216
3435
|
}
|
|
3217
3436
|
} catch (err) {
|
|
3218
|
-
console.warn("[useAgentChat] Polling error (will retry):", err);
|
|
3437
|
+
if (__DEV__) console.warn("[useAgentChat] Polling error (will retry):", err);
|
|
3219
3438
|
}
|
|
3220
3439
|
};
|
|
3221
3440
|
poll();
|
|
3222
|
-
pollingIntervalRef.current = setInterval(poll, 2e3);
|
|
3223
|
-
}, [adapter, stopPolling,
|
|
3441
|
+
pollingIntervalRef.current = setInterval(poll, pollingInterval ?? 2e3);
|
|
3442
|
+
}, [adapter, stopPolling, handleComplete, handleError, pollingInterval]);
|
|
3224
3443
|
react.useEffect(() => {
|
|
3225
|
-
if (!useStreamController && isUsingFallback && currentExecutionId && isLoading) {
|
|
3226
|
-
console.log("[useAgentChat] SSE fallback detected, activating polling");
|
|
3444
|
+
if (!useStreamController && isUsingFallback && currentExecutionId && isLoading && pollingEnabled !== false) {
|
|
3445
|
+
if (__DEV__) console.log("[useAgentChat] SSE fallback detected, activating polling");
|
|
3227
3446
|
startPolling(currentExecutionId);
|
|
3228
3447
|
}
|
|
3229
|
-
}, [useStreamController, isUsingFallback, currentExecutionId, isLoading, startPolling]);
|
|
3448
|
+
}, [useStreamController, isUsingFallback, currentExecutionId, isLoading, startPolling, pollingEnabled]);
|
|
3230
3449
|
const sseTimeoutRef = react.useRef(null);
|
|
3231
3450
|
react.useEffect(() => {
|
|
3232
|
-
if (!useStreamController && currentExecutionId && isLoading && !legacyIsConnected && !isUsingFallback) {
|
|
3451
|
+
if (!useStreamController && currentExecutionId && isLoading && !legacyIsConnected && !isUsingFallback && pollingEnabled !== false) {
|
|
3233
3452
|
sseTimeoutRef.current = setTimeout(() => {
|
|
3234
3453
|
if (!legacyIsConnected && currentExecutionId && isLoading) {
|
|
3235
|
-
console.log("[useAgentChat] SSE connection timeout, activating polling fallback");
|
|
3454
|
+
if (__DEV__) console.log("[useAgentChat] SSE connection timeout, activating polling fallback");
|
|
3236
3455
|
startPolling(currentExecutionId);
|
|
3237
3456
|
}
|
|
3238
3457
|
}, 1e4);
|
|
@@ -3243,7 +3462,7 @@ function useAgentChat(options) {
|
|
|
3243
3462
|
sseTimeoutRef.current = null;
|
|
3244
3463
|
}
|
|
3245
3464
|
};
|
|
3246
|
-
}, [useStreamController, currentExecutionId, isLoading, legacyIsConnected, isUsingFallback, startPolling]);
|
|
3465
|
+
}, [useStreamController, currentExecutionId, isLoading, legacyIsConnected, isUsingFallback, startPolling, pollingEnabled]);
|
|
3247
3466
|
react.useEffect(() => {
|
|
3248
3467
|
if (!currentExecutionId) {
|
|
3249
3468
|
stopPolling();
|
|
@@ -3259,7 +3478,7 @@ function useAgentChat(options) {
|
|
|
3259
3478
|
streamControllerRef.current.cancel();
|
|
3260
3479
|
streamControllerRef.current = null;
|
|
3261
3480
|
}
|
|
3262
|
-
console.log("[useAgentChat] Creating stream controller for:", executionId);
|
|
3481
|
+
if (__DEV__) console.log("[useAgentChat] Creating stream controller for:", executionId);
|
|
3263
3482
|
const controller = adapter.createStream(executionId, sessionId);
|
|
3264
3483
|
streamControllerRef.current = controller;
|
|
3265
3484
|
controller.on("log", (log) => {
|
|
@@ -3310,6 +3529,34 @@ function useAgentChat(options) {
|
|
|
3310
3529
|
}
|
|
3311
3530
|
firedToolResultsRef.current.add(toolCallId);
|
|
3312
3531
|
onToolResultRef.current?.(toolName, data.result, data.durationMs);
|
|
3532
|
+
updateMessageImages();
|
|
3533
|
+
});
|
|
3534
|
+
controller.on("delegationStarted", (data) => {
|
|
3535
|
+
const delegation = {
|
|
3536
|
+
type: "delegation_started",
|
|
3537
|
+
handoffId: data.handoffId,
|
|
3538
|
+
toAgent: data.targetAgentName || data.targetAgentUuid,
|
|
3539
|
+
targetAgentUuid: data.targetAgentUuid,
|
|
3540
|
+
taskPreview: data.taskPreview,
|
|
3541
|
+
timestamp: new Date(data.timestamp),
|
|
3542
|
+
status: "active"
|
|
3543
|
+
};
|
|
3544
|
+
pendingDelegationsRef.current.set(data.handoffId, delegation);
|
|
3545
|
+
addDelegationEvent(delegation);
|
|
3546
|
+
onDelegationRef.current?.(delegation);
|
|
3547
|
+
});
|
|
3548
|
+
controller.on("delegationCompleted", (data) => {
|
|
3549
|
+
const delegation = {
|
|
3550
|
+
type: "delegation_completed",
|
|
3551
|
+
handoffId: data.handoffId,
|
|
3552
|
+
resultPreview: data.resultPreview,
|
|
3553
|
+
timestamp: new Date(data.timestamp),
|
|
3554
|
+
status: data.status === "failed" ? "failed" : "completed",
|
|
3555
|
+
durationMs: data.durationMs
|
|
3556
|
+
};
|
|
3557
|
+
pendingDelegationsRef.current.delete(data.handoffId);
|
|
3558
|
+
addDelegationEvent(delegation);
|
|
3559
|
+
onDelegationRef.current?.(delegation);
|
|
3313
3560
|
});
|
|
3314
3561
|
controller.on("textDelta", (data) => {
|
|
3315
3562
|
streamingContentRef.current += data.delta;
|
|
@@ -3323,11 +3570,8 @@ function useAgentChat(options) {
|
|
|
3323
3570
|
});
|
|
3324
3571
|
});
|
|
3325
3572
|
controller.on("complete", ({ execution }) => {
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
updateStreamingMessage(execution.output);
|
|
3329
|
-
}
|
|
3330
|
-
handleComplete();
|
|
3573
|
+
const output = execution?.output || void 0;
|
|
3574
|
+
handleComplete(output);
|
|
3331
3575
|
});
|
|
3332
3576
|
controller.on("error", (errorEvent) => {
|
|
3333
3577
|
handleError(errorEvent.error);
|
|
@@ -3341,7 +3585,7 @@ function useAgentChat(options) {
|
|
|
3341
3585
|
});
|
|
3342
3586
|
setIsStreamControllerConnected(true);
|
|
3343
3587
|
},
|
|
3344
|
-
[adapter, handleExecutionLog, updateStreamingMessage, updateToolCall, handleClarification, handleComplete, handleError]
|
|
3588
|
+
[adapter, handleExecutionLog, updateStreamingMessage, updateToolCall, updateMessageImages, addDelegationEvent, handleClarification, handleComplete, handleError]
|
|
3345
3589
|
);
|
|
3346
3590
|
const sendMessage = react.useCallback(
|
|
3347
3591
|
async (content, options2) => {
|
|
@@ -3371,8 +3615,10 @@ function useAgentChat(options) {
|
|
|
3371
3615
|
setMessages((prev) => [...prev, assistantMessage]);
|
|
3372
3616
|
streamingMessageIdRef.current = assistantMessageId;
|
|
3373
3617
|
streamingContentRef.current = "";
|
|
3618
|
+
completedRef.current = false;
|
|
3619
|
+
finalizedRef.current = false;
|
|
3374
3620
|
try {
|
|
3375
|
-
console.log("[useAgentChat] Starting execution...", { agentId, sessionId: currentSessionId });
|
|
3621
|
+
if (__DEV__) console.log("[useAgentChat] Starting execution...", { agentId, sessionId: currentSessionId });
|
|
3376
3622
|
const result = await adapter.startExecution({
|
|
3377
3623
|
agentId,
|
|
3378
3624
|
teamId,
|
|
@@ -3380,7 +3626,7 @@ function useAgentChat(options) {
|
|
|
3380
3626
|
content: content.trim(),
|
|
3381
3627
|
attachmentUuids
|
|
3382
3628
|
});
|
|
3383
|
-
console.log("[useAgentChat] Execution started:", result);
|
|
3629
|
+
if (__DEV__) console.log("[useAgentChat] Execution started:", result);
|
|
3384
3630
|
if (!currentSessionId && result.sessionId) {
|
|
3385
3631
|
internallyCreatedSessionRef.current = result.sessionId;
|
|
3386
3632
|
setCurrentSessionId(result.sessionId);
|
|
@@ -3391,7 +3637,7 @@ function useAgentChat(options) {
|
|
|
3391
3637
|
connectStreamController(result.executionId, result.sessionId || currentSessionId || void 0);
|
|
3392
3638
|
setCurrentExecutionId(result.executionId);
|
|
3393
3639
|
} else {
|
|
3394
|
-
console.log("[useAgentChat] Setting executionId:", result.executionId);
|
|
3640
|
+
if (__DEV__) console.log("[useAgentChat] Setting executionId:", result.executionId);
|
|
3395
3641
|
setCurrentExecutionId(result.executionId);
|
|
3396
3642
|
}
|
|
3397
3643
|
} catch (err) {
|
|
@@ -3451,6 +3697,7 @@ function useAgentChat(options) {
|
|
|
3451
3697
|
setMessages([]);
|
|
3452
3698
|
setCurrentSessionId(null);
|
|
3453
3699
|
hasLoadedInitialSession.current = false;
|
|
3700
|
+
lastLoadedSessionRef.current = null;
|
|
3454
3701
|
internallyCreatedSessionRef.current = null;
|
|
3455
3702
|
}, []);
|
|
3456
3703
|
const loadSession = react.useCallback(
|
|
@@ -3546,15 +3793,20 @@ function useAgentChat(options) {
|
|
|
3546
3793
|
},
|
|
3547
3794
|
[adapter, onError]
|
|
3548
3795
|
);
|
|
3796
|
+
const lastLoadedSessionRef = react.useRef(null);
|
|
3549
3797
|
react.useEffect(() => {
|
|
3550
|
-
if (initialSessionId
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
return;
|
|
3554
|
-
}
|
|
3798
|
+
if (!initialSessionId) return;
|
|
3799
|
+
if (internallyCreatedSessionRef.current === initialSessionId) {
|
|
3800
|
+
lastLoadedSessionRef.current = initialSessionId;
|
|
3555
3801
|
hasLoadedInitialSession.current = true;
|
|
3556
|
-
|
|
3802
|
+
return;
|
|
3803
|
+
}
|
|
3804
|
+
if (lastLoadedSessionRef.current === initialSessionId && hasLoadedInitialSession.current) {
|
|
3805
|
+
return;
|
|
3557
3806
|
}
|
|
3807
|
+
lastLoadedSessionRef.current = initialSessionId;
|
|
3808
|
+
hasLoadedInitialSession.current = true;
|
|
3809
|
+
loadSession(initialSessionId);
|
|
3558
3810
|
}, [initialSessionId, loadSession]);
|
|
3559
3811
|
react.useEffect(() => {
|
|
3560
3812
|
return () => {
|
|
@@ -3570,6 +3822,16 @@ function useAgentChat(options) {
|
|
|
3570
3822
|
}
|
|
3571
3823
|
return !!currentExecutionId && legacyIsConnected;
|
|
3572
3824
|
}, [useStreamController, currentExecutionId, isStreamControllerConnected, legacyIsConnected]);
|
|
3825
|
+
const activeDelegation = react.useMemo(() => {
|
|
3826
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
3827
|
+
const msg = messages[i];
|
|
3828
|
+
if (msg.delegationEvents) {
|
|
3829
|
+
const active = msg.delegationEvents.find((de) => de.status === "active");
|
|
3830
|
+
if (active) return active;
|
|
3831
|
+
}
|
|
3832
|
+
}
|
|
3833
|
+
return null;
|
|
3834
|
+
}, [messages]);
|
|
3573
3835
|
return {
|
|
3574
3836
|
messages,
|
|
3575
3837
|
isLoading,
|
|
@@ -3578,6 +3840,7 @@ function useAgentChat(options) {
|
|
|
3578
3840
|
error,
|
|
3579
3841
|
sessionId: currentSessionId,
|
|
3580
3842
|
clarification,
|
|
3843
|
+
activeDelegation,
|
|
3581
3844
|
sendMessage,
|
|
3582
3845
|
respondToClarification,
|
|
3583
3846
|
cancel,
|
|
@@ -4433,18 +4696,30 @@ function ChatContainer({
|
|
|
4433
4696
|
children,
|
|
4434
4697
|
maxHeight = "600px",
|
|
4435
4698
|
className,
|
|
4436
|
-
theme = "system"
|
|
4699
|
+
theme = "system",
|
|
4700
|
+
layout = "fixed"
|
|
4437
4701
|
}) {
|
|
4438
4702
|
const maxHeightValue = typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight;
|
|
4703
|
+
const isFill = layout === "fill";
|
|
4439
4704
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4440
4705
|
"div",
|
|
4441
4706
|
{
|
|
4442
4707
|
className: cn2(
|
|
4443
|
-
"flex flex-col
|
|
4708
|
+
"cadra-chat-container flex flex-col overflow-hidden",
|
|
4709
|
+
// Default colors use CSS custom properties with Tailwind fallbacks.
|
|
4710
|
+
// Consumers can override via CSS: --chat-bg, --chat-border, --chat-border-radius
|
|
4711
|
+
!isFill && "rounded-lg border",
|
|
4712
|
+
isFill && "flex-1 min-h-0",
|
|
4444
4713
|
className
|
|
4445
4714
|
),
|
|
4446
|
-
style: {
|
|
4715
|
+
style: {
|
|
4716
|
+
...!isFill ? { maxHeight: maxHeightValue } : void 0,
|
|
4717
|
+
// CSS custom properties for theming — consumers set these to override
|
|
4718
|
+
backgroundColor: "var(--chat-bg, var(--background, #fff))",
|
|
4719
|
+
borderColor: !isFill ? "var(--chat-border, var(--border, #e5e7eb))" : void 0
|
|
4720
|
+
},
|
|
4447
4721
|
"data-theme": theme,
|
|
4722
|
+
"data-layout": layout,
|
|
4448
4723
|
children
|
|
4449
4724
|
}
|
|
4450
4725
|
);
|
|
@@ -5131,7 +5406,7 @@ var FileDropZone = react.forwardRef(
|
|
|
5131
5406
|
{
|
|
5132
5407
|
ref: dropZoneRef,
|
|
5133
5408
|
"data-dropzone": "wrapper",
|
|
5134
|
-
className: cn4("relative
|
|
5409
|
+
className: cn4("relative flex flex-col flex-1 min-h-0", className),
|
|
5135
5410
|
style: { minHeight: "inherit" },
|
|
5136
5411
|
children: [
|
|
5137
5412
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5416,6 +5691,312 @@ function AskUserPrompt({
|
|
|
5416
5691
|
function cn6(...classes) {
|
|
5417
5692
|
return classes.filter(Boolean).join(" ");
|
|
5418
5693
|
}
|
|
5694
|
+
function formatDuration(ms) {
|
|
5695
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
5696
|
+
return `${(ms / 1e3).toFixed(1)}s`;
|
|
5697
|
+
}
|
|
5698
|
+
function DelegationProgress({
|
|
5699
|
+
event,
|
|
5700
|
+
className
|
|
5701
|
+
}) {
|
|
5702
|
+
const statusIcon = react.useMemo(() => {
|
|
5703
|
+
switch (event.status) {
|
|
5704
|
+
case "active":
|
|
5705
|
+
return /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, { className: "h-4 w-4 text-blue-500" });
|
|
5706
|
+
case "completed":
|
|
5707
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CheckCircleIcon, { className: "h-4 w-4 text-green-500" });
|
|
5708
|
+
case "failed":
|
|
5709
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AlertCircleIcon, { className: "h-4 w-4 text-red-500" });
|
|
5710
|
+
default:
|
|
5711
|
+
return /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, { className: "h-4 w-4 text-gray-400" });
|
|
5712
|
+
}
|
|
5713
|
+
}, [event.status]);
|
|
5714
|
+
const statusColor = react.useMemo(() => {
|
|
5715
|
+
switch (event.status) {
|
|
5716
|
+
case "active":
|
|
5717
|
+
return "border-blue-200 dark:border-blue-800 bg-blue-50/50 dark:bg-blue-950/20";
|
|
5718
|
+
case "completed":
|
|
5719
|
+
return "border-green-200 dark:border-green-800 bg-green-50/50 dark:bg-green-950/20";
|
|
5720
|
+
case "failed":
|
|
5721
|
+
return "border-red-200 dark:border-red-800 bg-red-50/50 dark:bg-red-950/20";
|
|
5722
|
+
default:
|
|
5723
|
+
return "border-gray-200 dark:border-gray-700";
|
|
5724
|
+
}
|
|
5725
|
+
}, [event.status]);
|
|
5726
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5727
|
+
"div",
|
|
5728
|
+
{
|
|
5729
|
+
className: cn6(
|
|
5730
|
+
"rounded-lg border text-sm px-3 py-2",
|
|
5731
|
+
statusColor,
|
|
5732
|
+
className
|
|
5733
|
+
),
|
|
5734
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
5735
|
+
statusIcon,
|
|
5736
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
5737
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
5738
|
+
event.fromAgent && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5739
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-gray-700 dark:text-gray-300 truncate", children: event.fromAgent }),
|
|
5740
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400 dark:text-gray-500 flex-shrink-0", children: "\u2192" })
|
|
5741
|
+
] }),
|
|
5742
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-gray-900 dark:text-gray-100 truncate", children: event.toAgent || event.targetAgentUuid || "Specialist" })
|
|
5743
|
+
] }),
|
|
5744
|
+
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 }),
|
|
5745
|
+
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 })
|
|
5746
|
+
] }),
|
|
5747
|
+
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) })
|
|
5748
|
+
] })
|
|
5749
|
+
}
|
|
5750
|
+
);
|
|
5751
|
+
}
|
|
5752
|
+
function DelegationProgressList({
|
|
5753
|
+
events,
|
|
5754
|
+
className
|
|
5755
|
+
}) {
|
|
5756
|
+
if (!events || events.length === 0) return null;
|
|
5757
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn6("space-y-2", className), children: events.map((event, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5758
|
+
DelegationProgress,
|
|
5759
|
+
{
|
|
5760
|
+
event
|
|
5761
|
+
},
|
|
5762
|
+
event.handoffId || `delegation-${index}`
|
|
5763
|
+
)) });
|
|
5764
|
+
}
|
|
5765
|
+
function ImageLightbox({
|
|
5766
|
+
images,
|
|
5767
|
+
currentIndex,
|
|
5768
|
+
onClose,
|
|
5769
|
+
onPrev,
|
|
5770
|
+
onNext,
|
|
5771
|
+
className
|
|
5772
|
+
}) {
|
|
5773
|
+
const currentImage = images[currentIndex];
|
|
5774
|
+
const hasMultiple = images.length > 1;
|
|
5775
|
+
react.useEffect(() => {
|
|
5776
|
+
function handleKeyDown(e) {
|
|
5777
|
+
switch (e.key) {
|
|
5778
|
+
case "Escape":
|
|
5779
|
+
onClose();
|
|
5780
|
+
break;
|
|
5781
|
+
case "ArrowLeft":
|
|
5782
|
+
if (hasMultiple) onPrev();
|
|
5783
|
+
break;
|
|
5784
|
+
case "ArrowRight":
|
|
5785
|
+
if (hasMultiple) onNext();
|
|
5786
|
+
break;
|
|
5787
|
+
}
|
|
5788
|
+
}
|
|
5789
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
5790
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
5791
|
+
}, [onClose, onPrev, onNext, hasMultiple]);
|
|
5792
|
+
react.useEffect(() => {
|
|
5793
|
+
const originalOverflow = document.body.style.overflow;
|
|
5794
|
+
document.body.style.overflow = "hidden";
|
|
5795
|
+
return () => {
|
|
5796
|
+
document.body.style.overflow = originalOverflow;
|
|
5797
|
+
};
|
|
5798
|
+
}, []);
|
|
5799
|
+
const handleDownload = react.useCallback(() => {
|
|
5800
|
+
if (!currentImage) return;
|
|
5801
|
+
const link = document.createElement("a");
|
|
5802
|
+
link.href = currentImage.url;
|
|
5803
|
+
link.download = currentImage.filename || `image-${currentIndex + 1}`;
|
|
5804
|
+
link.target = "_blank";
|
|
5805
|
+
link.rel = "noopener noreferrer";
|
|
5806
|
+
document.body.appendChild(link);
|
|
5807
|
+
link.click();
|
|
5808
|
+
document.body.removeChild(link);
|
|
5809
|
+
}, [currentImage, currentIndex]);
|
|
5810
|
+
if (!currentImage) return null;
|
|
5811
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5812
|
+
"div",
|
|
5813
|
+
{
|
|
5814
|
+
className: `fixed inset-0 z-50 flex items-center justify-center bg-black/80 ${className || ""}`,
|
|
5815
|
+
onClick: onClose,
|
|
5816
|
+
children: [
|
|
5817
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-0 left-0 right-0 flex items-center justify-between p-4 z-10", children: [
|
|
5818
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-white text-sm", children: hasMultiple && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
5819
|
+
currentIndex + 1,
|
|
5820
|
+
" / ",
|
|
5821
|
+
images.length
|
|
5822
|
+
] }) }),
|
|
5823
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
5824
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5825
|
+
"button",
|
|
5826
|
+
{
|
|
5827
|
+
type: "button",
|
|
5828
|
+
onClick: (e) => {
|
|
5829
|
+
e.stopPropagation();
|
|
5830
|
+
handleDownload();
|
|
5831
|
+
},
|
|
5832
|
+
className: "p-2 rounded-full bg-black/50 hover:bg-black/70 text-white transition-colors",
|
|
5833
|
+
"aria-label": "Download image",
|
|
5834
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon, { className: "h-5 w-5" })
|
|
5835
|
+
}
|
|
5836
|
+
),
|
|
5837
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5838
|
+
"button",
|
|
5839
|
+
{
|
|
5840
|
+
type: "button",
|
|
5841
|
+
onClick: (e) => {
|
|
5842
|
+
e.stopPropagation();
|
|
5843
|
+
onClose();
|
|
5844
|
+
},
|
|
5845
|
+
className: "p-2 rounded-full bg-black/50 hover:bg-black/70 text-white transition-colors",
|
|
5846
|
+
"aria-label": "Close lightbox",
|
|
5847
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(XIcon, { className: "h-5 w-5" })
|
|
5848
|
+
}
|
|
5849
|
+
)
|
|
5850
|
+
] })
|
|
5851
|
+
] }),
|
|
5852
|
+
hasMultiple && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5853
|
+
"button",
|
|
5854
|
+
{
|
|
5855
|
+
type: "button",
|
|
5856
|
+
onClick: (e) => {
|
|
5857
|
+
e.stopPropagation();
|
|
5858
|
+
onPrev();
|
|
5859
|
+
},
|
|
5860
|
+
className: "absolute left-4 top-1/2 -translate-y-1/2 p-2 rounded-full bg-black/50 hover:bg-black/70 text-white transition-colors z-10",
|
|
5861
|
+
"aria-label": "Previous image",
|
|
5862
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, { className: "h-6 w-6" })
|
|
5863
|
+
}
|
|
5864
|
+
),
|
|
5865
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5866
|
+
"img",
|
|
5867
|
+
{
|
|
5868
|
+
src: currentImage.url,
|
|
5869
|
+
alt: currentImage.alt || `Image ${currentIndex + 1}`,
|
|
5870
|
+
className: "max-w-[90vw] max-h-[85vh] object-contain",
|
|
5871
|
+
onClick: (e) => e.stopPropagation()
|
|
5872
|
+
}
|
|
5873
|
+
),
|
|
5874
|
+
hasMultiple && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5875
|
+
"button",
|
|
5876
|
+
{
|
|
5877
|
+
type: "button",
|
|
5878
|
+
onClick: (e) => {
|
|
5879
|
+
e.stopPropagation();
|
|
5880
|
+
onNext();
|
|
5881
|
+
},
|
|
5882
|
+
className: "absolute right-4 top-1/2 -translate-y-1/2 p-2 rounded-full bg-black/50 hover:bg-black/70 text-white transition-colors z-10",
|
|
5883
|
+
"aria-label": "Next image",
|
|
5884
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, { className: "h-6 w-6" })
|
|
5885
|
+
}
|
|
5886
|
+
),
|
|
5887
|
+
currentImage.alt && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-0 right-0 p-4 text-center z-10", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-white text-sm bg-black/50 inline-block px-3 py-1 rounded-full", children: currentImage.alt }) })
|
|
5888
|
+
]
|
|
5889
|
+
}
|
|
5890
|
+
);
|
|
5891
|
+
}
|
|
5892
|
+
function cn7(...classes) {
|
|
5893
|
+
return classes.filter(Boolean).join(" ");
|
|
5894
|
+
}
|
|
5895
|
+
function ImageWithLoading({ src, alt, className, onClick }) {
|
|
5896
|
+
const [isLoaded, setIsLoaded] = react.useState(false);
|
|
5897
|
+
const [hasError, setHasError] = react.useState(false);
|
|
5898
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5899
|
+
"div",
|
|
5900
|
+
{
|
|
5901
|
+
className: cn7(
|
|
5902
|
+
"relative overflow-hidden bg-gray-100 dark:bg-gray-800",
|
|
5903
|
+
className
|
|
5904
|
+
),
|
|
5905
|
+
children: [
|
|
5906
|
+
!isLoaded && !hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 animate-pulse bg-gray-200 dark:bg-gray-700" }),
|
|
5907
|
+
hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center text-gray-400 dark:text-gray-500 text-sm", children: "Failed to load" }),
|
|
5908
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5909
|
+
"img",
|
|
5910
|
+
{
|
|
5911
|
+
src,
|
|
5912
|
+
alt,
|
|
5913
|
+
loading: "lazy",
|
|
5914
|
+
className: cn7(
|
|
5915
|
+
"w-full h-auto max-h-[300px] object-contain transition-opacity duration-200",
|
|
5916
|
+
isLoaded ? "opacity-100" : "opacity-0"
|
|
5917
|
+
),
|
|
5918
|
+
onLoad: () => setIsLoaded(true),
|
|
5919
|
+
onError: () => setHasError(true),
|
|
5920
|
+
onClick,
|
|
5921
|
+
style: onClick ? { cursor: "pointer" } : void 0
|
|
5922
|
+
}
|
|
5923
|
+
)
|
|
5924
|
+
]
|
|
5925
|
+
}
|
|
5926
|
+
);
|
|
5927
|
+
}
|
|
5928
|
+
function ImageGallery({
|
|
5929
|
+
images,
|
|
5930
|
+
onImageClick,
|
|
5931
|
+
className
|
|
5932
|
+
}) {
|
|
5933
|
+
const [lightboxIndex, setLightboxIndex] = react.useState(null);
|
|
5934
|
+
const handleImageClick = react.useCallback(
|
|
5935
|
+
(image, index) => {
|
|
5936
|
+
if (onImageClick) {
|
|
5937
|
+
onImageClick(image);
|
|
5938
|
+
} else {
|
|
5939
|
+
setLightboxIndex(index);
|
|
5940
|
+
}
|
|
5941
|
+
},
|
|
5942
|
+
[onImageClick]
|
|
5943
|
+
);
|
|
5944
|
+
const handleLightboxClose = react.useCallback(() => {
|
|
5945
|
+
setLightboxIndex(null);
|
|
5946
|
+
}, []);
|
|
5947
|
+
const handleLightboxPrev = react.useCallback(() => {
|
|
5948
|
+
setLightboxIndex(
|
|
5949
|
+
(prev) => prev !== null ? (prev - 1 + images.length) % images.length : null
|
|
5950
|
+
);
|
|
5951
|
+
}, [images.length]);
|
|
5952
|
+
const handleLightboxNext = react.useCallback(() => {
|
|
5953
|
+
setLightboxIndex(
|
|
5954
|
+
(prev) => prev !== null ? (prev + 1) % images.length : null
|
|
5955
|
+
);
|
|
5956
|
+
}, [images.length]);
|
|
5957
|
+
if (!images || images.length === 0) return null;
|
|
5958
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5959
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5960
|
+
"div",
|
|
5961
|
+
{
|
|
5962
|
+
className: cn7(
|
|
5963
|
+
"grid gap-2",
|
|
5964
|
+
images.length === 1 ? "grid-cols-1" : images.length === 2 ? "grid-cols-2" : "grid-cols-2 sm:grid-cols-3",
|
|
5965
|
+
className
|
|
5966
|
+
),
|
|
5967
|
+
children: images.map((image, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5968
|
+
"button",
|
|
5969
|
+
{
|
|
5970
|
+
type: "button",
|
|
5971
|
+
onClick: () => handleImageClick(image, index),
|
|
5972
|
+
className: "block rounded-lg overflow-hidden border border-gray-200 dark:border-gray-700 hover:border-blue-400 dark:hover:border-blue-600 transition-colors text-left",
|
|
5973
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5974
|
+
ImageWithLoading,
|
|
5975
|
+
{
|
|
5976
|
+
src: image.url,
|
|
5977
|
+
alt: image.alt || `Image ${index + 1}`
|
|
5978
|
+
}
|
|
5979
|
+
)
|
|
5980
|
+
},
|
|
5981
|
+
`${image.url}-${index}`
|
|
5982
|
+
))
|
|
5983
|
+
}
|
|
5984
|
+
),
|
|
5985
|
+
lightboxIndex !== null && !onImageClick && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5986
|
+
ImageLightbox,
|
|
5987
|
+
{
|
|
5988
|
+
images,
|
|
5989
|
+
currentIndex: lightboxIndex,
|
|
5990
|
+
onClose: handleLightboxClose,
|
|
5991
|
+
onPrev: handleLightboxPrev,
|
|
5992
|
+
onNext: handleLightboxNext
|
|
5993
|
+
}
|
|
5994
|
+
)
|
|
5995
|
+
] });
|
|
5996
|
+
}
|
|
5997
|
+
function cn8(...classes) {
|
|
5998
|
+
return classes.filter(Boolean).join(" ");
|
|
5999
|
+
}
|
|
5419
6000
|
function MarkdownContent({
|
|
5420
6001
|
content,
|
|
5421
6002
|
className,
|
|
@@ -5435,11 +6016,11 @@ function MarkdownContent({
|
|
|
5435
6016
|
h3: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold mt-3 mb-1 first:mt-0", children }),
|
|
5436
6017
|
h4: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-base font-semibold mt-2 mb-1 first:mt-0", children }),
|
|
5437
6018
|
// Paragraphs
|
|
5438
|
-
p: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-
|
|
6019
|
+
p: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-1.5 last:mb-0", children }),
|
|
5439
6020
|
// 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: "
|
|
6021
|
+
ul: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "list-disc list-inside mb-1.5 last:mb-0", children }),
|
|
6022
|
+
ol: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "list-decimal list-inside mb-1.5 last:mb-0", children }),
|
|
6023
|
+
li: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "", children }),
|
|
5443
6024
|
// Links
|
|
5444
6025
|
a: ({ href, children }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5445
6026
|
"a",
|
|
@@ -5474,7 +6055,7 @@ function MarkdownContent({
|
|
|
5474
6055
|
if (isCodeBlock) {
|
|
5475
6056
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative my-2", children: [
|
|
5476
6057
|
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:
|
|
6058
|
+
/* @__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
6059
|
] });
|
|
5479
6060
|
}
|
|
5480
6061
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5521,7 +6102,7 @@ function MarkdownContent({
|
|
|
5521
6102
|
() => customComponents ? { ...defaultComponents, ...customComponents } : defaultComponents,
|
|
5522
6103
|
[defaultComponents, customComponents]
|
|
5523
6104
|
);
|
|
5524
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className:
|
|
6105
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn8("max-w-none text-sm leading-relaxed", className), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5525
6106
|
ReactMarkdown__default.default,
|
|
5526
6107
|
{
|
|
5527
6108
|
remarkPlugins: [remarkGfm__default.default],
|
|
@@ -5531,6 +6112,58 @@ function MarkdownContent({
|
|
|
5531
6112
|
}
|
|
5532
6113
|
) });
|
|
5533
6114
|
}
|
|
6115
|
+
function cn9(...classes) {
|
|
6116
|
+
return classes.filter(Boolean).join(" ");
|
|
6117
|
+
}
|
|
6118
|
+
function ThinkingBlock({
|
|
6119
|
+
block,
|
|
6120
|
+
defaultExpanded = false,
|
|
6121
|
+
className
|
|
6122
|
+
}) {
|
|
6123
|
+
const [isExpanded, setIsExpanded] = react.useState(defaultExpanded);
|
|
6124
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6125
|
+
"div",
|
|
6126
|
+
{
|
|
6127
|
+
className: cn9(
|
|
6128
|
+
"rounded-lg border",
|
|
6129
|
+
"border-purple-200 dark:border-purple-800",
|
|
6130
|
+
"bg-purple-50/50 dark:bg-purple-950/20",
|
|
6131
|
+
className
|
|
6132
|
+
),
|
|
6133
|
+
children: [
|
|
6134
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6135
|
+
"button",
|
|
6136
|
+
{
|
|
6137
|
+
type: "button",
|
|
6138
|
+
onClick: () => setIsExpanded(!isExpanded),
|
|
6139
|
+
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",
|
|
6140
|
+
children: [
|
|
6141
|
+
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" }),
|
|
6142
|
+
/* @__PURE__ */ jsxRuntime.jsx(SparklesIcon, { className: "h-4 w-4 text-purple-500 flex-shrink-0" }),
|
|
6143
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-purple-700 dark:text-purple-300", children: "Thinking" })
|
|
6144
|
+
]
|
|
6145
|
+
}
|
|
6146
|
+
),
|
|
6147
|
+
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 }) })
|
|
6148
|
+
]
|
|
6149
|
+
}
|
|
6150
|
+
);
|
|
6151
|
+
}
|
|
6152
|
+
function ThinkingBlockList({
|
|
6153
|
+
blocks,
|
|
6154
|
+
defaultExpanded = false,
|
|
6155
|
+
className
|
|
6156
|
+
}) {
|
|
6157
|
+
if (!blocks || blocks.length === 0) return null;
|
|
6158
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn9("space-y-2", className), children: blocks.map((block) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6159
|
+
ThinkingBlock,
|
|
6160
|
+
{
|
|
6161
|
+
block,
|
|
6162
|
+
defaultExpanded
|
|
6163
|
+
},
|
|
6164
|
+
block.id
|
|
6165
|
+
)) });
|
|
6166
|
+
}
|
|
5534
6167
|
var INTERNAL_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
5535
6168
|
"update_task_list",
|
|
5536
6169
|
"create_task",
|
|
@@ -5561,7 +6194,7 @@ function isInternalTool(toolName) {
|
|
|
5561
6194
|
}
|
|
5562
6195
|
return false;
|
|
5563
6196
|
}
|
|
5564
|
-
function
|
|
6197
|
+
function cn10(...classes) {
|
|
5565
6198
|
return classes.filter(Boolean).join(" ");
|
|
5566
6199
|
}
|
|
5567
6200
|
function formatToolName(toolName) {
|
|
@@ -5610,7 +6243,7 @@ function formatToolName(toolName) {
|
|
|
5610
6243
|
}
|
|
5611
6244
|
return uniqueWords.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
5612
6245
|
}
|
|
5613
|
-
function
|
|
6246
|
+
function formatDuration2(ms) {
|
|
5614
6247
|
if (ms < 1e3) {
|
|
5615
6248
|
return `${ms}ms`;
|
|
5616
6249
|
}
|
|
@@ -5631,7 +6264,7 @@ function formatJsonPreview(data, maxLength = 100) {
|
|
|
5631
6264
|
return String(data);
|
|
5632
6265
|
}
|
|
5633
6266
|
}
|
|
5634
|
-
function
|
|
6267
|
+
function extractImagesFromResult2(result) {
|
|
5635
6268
|
if (!result) return [];
|
|
5636
6269
|
let data = result;
|
|
5637
6270
|
if (typeof result === "string") {
|
|
@@ -5675,7 +6308,7 @@ function ToolCallEntry({
|
|
|
5675
6308
|
[toolCall.name]
|
|
5676
6309
|
);
|
|
5677
6310
|
const resultImages = react.useMemo(
|
|
5678
|
-
() => toolCall.status === "completed" && toolCall.result ?
|
|
6311
|
+
() => toolCall.status === "completed" && toolCall.result ? extractImagesFromResult2(toolCall.result) : [],
|
|
5679
6312
|
[toolCall.status, toolCall.result]
|
|
5680
6313
|
);
|
|
5681
6314
|
const hasImages = resultImages.length > 0;
|
|
@@ -5711,14 +6344,14 @@ function ToolCallEntry({
|
|
|
5711
6344
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5712
6345
|
"div",
|
|
5713
6346
|
{
|
|
5714
|
-
className:
|
|
6347
|
+
className: cn10(
|
|
5715
6348
|
"inline-flex items-center gap-1.5 text-xs text-gray-500 dark:text-gray-400",
|
|
5716
6349
|
className
|
|
5717
6350
|
),
|
|
5718
6351
|
children: [
|
|
5719
6352
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: statusIcon }),
|
|
5720
6353
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formattedName }),
|
|
5721
|
-
toolCall.durationMs !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400 dark:text-gray-500", children:
|
|
6354
|
+
toolCall.durationMs !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400 dark:text-gray-500", children: formatDuration2(toolCall.durationMs) })
|
|
5722
6355
|
]
|
|
5723
6356
|
}
|
|
5724
6357
|
);
|
|
@@ -5726,7 +6359,7 @@ function ToolCallEntry({
|
|
|
5726
6359
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5727
6360
|
"div",
|
|
5728
6361
|
{
|
|
5729
|
-
className:
|
|
6362
|
+
className: cn10(
|
|
5730
6363
|
"rounded-lg border text-sm",
|
|
5731
6364
|
statusColor,
|
|
5732
6365
|
className
|
|
@@ -5742,12 +6375,12 @@ function ToolCallEntry({
|
|
|
5742
6375
|
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
6376
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: statusIcon }),
|
|
5744
6377
|
/* @__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:
|
|
6378
|
+
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
6379
|
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
6380
|
]
|
|
5748
6381
|
}
|
|
5749
6382
|
),
|
|
5750
|
-
hasImages && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pb-2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className:
|
|
6383
|
+
hasImages && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pb-2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn10(
|
|
5751
6384
|
"grid gap-2",
|
|
5752
6385
|
resultImages.length === 1 ? "grid-cols-1" : "grid-cols-2"
|
|
5753
6386
|
), children: resultImages.map((img, idx) => {
|
|
@@ -5806,22 +6439,28 @@ function ToolCallEntry({
|
|
|
5806
6439
|
}
|
|
5807
6440
|
);
|
|
5808
6441
|
}
|
|
5809
|
-
function
|
|
6442
|
+
function cn11(...classes) {
|
|
5810
6443
|
return classes.filter(Boolean).join(" ");
|
|
5811
6444
|
}
|
|
5812
6445
|
function ChatMessage({
|
|
5813
6446
|
message,
|
|
5814
6447
|
enableMarkdown = true,
|
|
5815
6448
|
showToolCalls = true,
|
|
5816
|
-
toolCallVerbosity,
|
|
6449
|
+
toolCallVerbosity: _toolCallVerbosity,
|
|
5817
6450
|
className,
|
|
5818
6451
|
markdownComponents,
|
|
5819
6452
|
markdownUrlTransform,
|
|
5820
6453
|
markdownContentTransform,
|
|
5821
|
-
onImageClick
|
|
6454
|
+
onImageClick,
|
|
6455
|
+
showThinking = true,
|
|
6456
|
+
showDelegation = true,
|
|
6457
|
+
showImages = true,
|
|
6458
|
+
renderToolCall,
|
|
6459
|
+
variant = "bubble"
|
|
5822
6460
|
}) {
|
|
5823
6461
|
const isUser = message.role === "user";
|
|
5824
6462
|
const isAssistant = message.role === "assistant";
|
|
6463
|
+
const isFlat = variant === "flat";
|
|
5825
6464
|
const formattedTime = react.useMemo(() => {
|
|
5826
6465
|
const date = message.timestamp instanceof Date ? message.timestamp : new Date(message.timestamp);
|
|
5827
6466
|
return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
@@ -5829,113 +6468,124 @@ function ChatMessage({
|
|
|
5829
6468
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5830
6469
|
"div",
|
|
5831
6470
|
{
|
|
5832
|
-
className:
|
|
5833
|
-
"flex gap-3
|
|
5834
|
-
|
|
6471
|
+
className: cn11(
|
|
6472
|
+
"cadra-chat-message flex gap-3",
|
|
6473
|
+
isFlat ? "py-5 px-4" : "p-4",
|
|
6474
|
+
// Bubble: user messages right-aligned. Flat: always left-aligned.
|
|
6475
|
+
!isFlat && isUser ? "flex-row-reverse" : "flex-row",
|
|
6476
|
+
// Flat variant: subtle row background for user messages
|
|
6477
|
+
isFlat && isUser && "chat-message-user-row",
|
|
5835
6478
|
className
|
|
5836
6479
|
),
|
|
6480
|
+
style: isFlat && isUser ? {
|
|
6481
|
+
backgroundColor: "var(--chat-user-row-bg, rgba(128, 128, 128, 0.08))"
|
|
6482
|
+
} : void 0,
|
|
6483
|
+
"data-role": message.role,
|
|
5837
6484
|
children: [
|
|
5838
6485
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5839
6486
|
"div",
|
|
5840
6487
|
{
|
|
5841
|
-
className:
|
|
5842
|
-
|
|
5843
|
-
isUser ? "
|
|
5844
|
-
|
|
6488
|
+
className: "flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center shadow-sm",
|
|
6489
|
+
style: {
|
|
6490
|
+
backgroundColor: isUser ? "var(--chat-user-avatar-bg, #3b82f6)" : "var(--chat-assistant-avatar-bg, #e5e7eb)",
|
|
6491
|
+
color: isUser ? "var(--chat-user-avatar-text, #fff)" : "var(--chat-assistant-avatar-text, #4b5563)"
|
|
6492
|
+
},
|
|
5845
6493
|
children: isUser ? /* @__PURE__ */ jsxRuntime.jsx(UserIcon, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(BotIcon, { className: "h-4 w-4" })
|
|
5846
6494
|
}
|
|
5847
6495
|
),
|
|
5848
6496
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5849
6497
|
"div",
|
|
5850
6498
|
{
|
|
5851
|
-
className:
|
|
5852
|
-
"flex-1 min-w-0
|
|
5853
|
-
|
|
6499
|
+
className: cn11(
|
|
6500
|
+
"flex-1 min-w-0",
|
|
6501
|
+
isFlat ? "pt-0.5" : "space-y-2",
|
|
6502
|
+
!isFlat && isUser ? "text-right" : "text-left"
|
|
5854
6503
|
),
|
|
5855
6504
|
children: [
|
|
5856
6505
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5857
6506
|
"div",
|
|
5858
6507
|
{
|
|
5859
|
-
className:
|
|
5860
|
-
"flex items-center gap-2 text-xs
|
|
5861
|
-
|
|
6508
|
+
className: cn11(
|
|
6509
|
+
"flex items-center gap-2 text-xs",
|
|
6510
|
+
isFlat ? "mb-1.5" : "",
|
|
6511
|
+
!isFlat && isUser ? "justify-end" : "justify-start"
|
|
5862
6512
|
),
|
|
6513
|
+
style: { color: "var(--chat-meta-text, #6b7280)" },
|
|
5863
6514
|
children: [
|
|
5864
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: isUser ? "You" : "Assistant" }),
|
|
6515
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", style: { color: "var(--chat-label-text, inherit)" }, children: isUser ? "You" : "Assistant" }),
|
|
5865
6516
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formattedTime }),
|
|
5866
6517
|
message.isStreaming && /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, { className: "h-3 w-3" })
|
|
5867
6518
|
]
|
|
5868
6519
|
}
|
|
5869
6520
|
),
|
|
5870
|
-
message.thinkingBlocks && message.thinkingBlocks.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
children: [
|
|
5875
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-medium text-purple-600 dark:text-purple-400 mb-1", children: "Thinking..." }),
|
|
5876
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-pre-wrap", children: block.content })
|
|
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
|
-
] });
|
|
5907
|
-
}
|
|
5908
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: filteredToolCalls.map((toolCall) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6521
|
+
showThinking && message.thinkingBlocks && message.thinkingBlocks.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ThinkingBlockList, { blocks: message.thinkingBlocks }),
|
|
6522
|
+
showDelegation && message.delegationEvents && message.delegationEvents.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(DelegationProgressList, { events: message.delegationEvents }),
|
|
6523
|
+
showToolCalls && message.toolCalls && message.toolCalls.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: message.toolCalls.map((toolCall) => {
|
|
6524
|
+
const defaultRender = () => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5909
6525
|
ToolCallEntry,
|
|
5910
6526
|
{
|
|
5911
6527
|
toolCall,
|
|
5912
6528
|
onImageClick
|
|
5913
6529
|
},
|
|
5914
6530
|
toolCall.id
|
|
5915
|
-
)
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
6531
|
+
);
|
|
6532
|
+
if (renderToolCall) {
|
|
6533
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderToolCall(toolCall, defaultRender) }, toolCall.id);
|
|
6534
|
+
}
|
|
6535
|
+
return defaultRender();
|
|
6536
|
+
}) }),
|
|
6537
|
+
showImages && message.images && message.images.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6538
|
+
ImageGallery,
|
|
5919
6539
|
{
|
|
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 })
|
|
6540
|
+
images: message.images,
|
|
6541
|
+
onImageClick: onImageClick ? (img) => onImageClick({ url: img.url, alt: img.alt, filename: img.filename }) : void 0
|
|
5933
6542
|
}
|
|
5934
6543
|
),
|
|
6544
|
+
message.content && (isFlat ? (
|
|
6545
|
+
// Flat variant: no bubble, just text with theme-aware color
|
|
6546
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6547
|
+
"div",
|
|
6548
|
+
{
|
|
6549
|
+
className: cn11("text-sm break-words", !(isAssistant && enableMarkdown) && "whitespace-pre-wrap"),
|
|
6550
|
+
style: { color: "var(--chat-content-text, inherit)" },
|
|
6551
|
+
children: isAssistant && enableMarkdown ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6552
|
+
MarkdownContent,
|
|
6553
|
+
{
|
|
6554
|
+
content: message.content,
|
|
6555
|
+
components: markdownComponents,
|
|
6556
|
+
urlTransform: markdownUrlTransform,
|
|
6557
|
+
contentTransform: markdownContentTransform
|
|
6558
|
+
}
|
|
6559
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap", children: message.content })
|
|
6560
|
+
}
|
|
6561
|
+
)
|
|
6562
|
+
) : (
|
|
6563
|
+
// Bubble variant: colored bubble backgrounds
|
|
6564
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6565
|
+
"div",
|
|
6566
|
+
{
|
|
6567
|
+
className: "rounded-lg p-3",
|
|
6568
|
+
style: {
|
|
6569
|
+
backgroundColor: isUser ? "var(--chat-user-bg, #3b82f6)" : "var(--chat-assistant-bg, #f3f4f6)",
|
|
6570
|
+
color: isUser ? "var(--chat-user-text, #fff)" : "var(--chat-assistant-text, #111827)"
|
|
6571
|
+
},
|
|
6572
|
+
children: isAssistant && enableMarkdown ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6573
|
+
MarkdownContent,
|
|
6574
|
+
{
|
|
6575
|
+
content: message.content,
|
|
6576
|
+
components: markdownComponents,
|
|
6577
|
+
urlTransform: markdownUrlTransform,
|
|
6578
|
+
contentTransform: markdownContentTransform
|
|
6579
|
+
}
|
|
6580
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap", children: message.content })
|
|
6581
|
+
}
|
|
6582
|
+
)
|
|
6583
|
+
)),
|
|
5935
6584
|
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
6585
|
"div",
|
|
5937
6586
|
{
|
|
5938
|
-
className: "flex items-center gap-2
|
|
6587
|
+
className: "flex items-center gap-2 rounded-lg px-3 py-2 text-sm",
|
|
6588
|
+
style: { backgroundColor: "var(--chat-assistant-bg, #f3f4f6)" },
|
|
5939
6589
|
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate max-w-[150px]", children: attachment.filename })
|
|
5940
6590
|
},
|
|
5941
6591
|
attachment.uuid
|
|
@@ -5947,7 +6597,7 @@ function ChatMessage({
|
|
|
5947
6597
|
}
|
|
5948
6598
|
);
|
|
5949
6599
|
}
|
|
5950
|
-
function
|
|
6600
|
+
function cn12(...classes) {
|
|
5951
6601
|
return classes.filter(Boolean).join(" ");
|
|
5952
6602
|
}
|
|
5953
6603
|
function MessageList({
|
|
@@ -5965,6 +6615,12 @@ function MessageList({
|
|
|
5965
6615
|
markdownUrlTransform,
|
|
5966
6616
|
markdownContentTransform,
|
|
5967
6617
|
onImageClick,
|
|
6618
|
+
showThinking = true,
|
|
6619
|
+
showDelegation = true,
|
|
6620
|
+
showImages = true,
|
|
6621
|
+
renderMessage,
|
|
6622
|
+
renderToolCall,
|
|
6623
|
+
messageVariant = "bubble",
|
|
5968
6624
|
sendMessage
|
|
5969
6625
|
}) {
|
|
5970
6626
|
const scrollRef = react.useRef(null);
|
|
@@ -5978,7 +6634,7 @@ function MessageList({
|
|
|
5978
6634
|
"div",
|
|
5979
6635
|
{
|
|
5980
6636
|
ref: scrollRef,
|
|
5981
|
-
className:
|
|
6637
|
+
className: cn12(
|
|
5982
6638
|
"flex-1 overflow-y-auto",
|
|
5983
6639
|
className
|
|
5984
6640
|
),
|
|
@@ -5989,20 +6645,31 @@ function MessageList({
|
|
|
5989
6645
|
] }) }),
|
|
5990
6646
|
messages.length === 0 && !isLoading && !isLoadingHistory && (renderWelcome ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: typeof renderWelcome === "function" ? renderWelcome({ sendMessage: sendMessage || (() => {
|
|
5991
6647
|
}) }) : 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
|
-
|
|
6648
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-gray-100 dark:divide-gray-800", children: messages.map((message) => {
|
|
6649
|
+
const defaultRender = () => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6650
|
+
ChatMessage,
|
|
6651
|
+
{
|
|
6652
|
+
message,
|
|
6653
|
+
enableMarkdown,
|
|
6654
|
+
showToolCalls,
|
|
6655
|
+
toolCallVerbosity,
|
|
6656
|
+
markdownComponents,
|
|
6657
|
+
markdownUrlTransform,
|
|
6658
|
+
markdownContentTransform,
|
|
6659
|
+
onImageClick,
|
|
6660
|
+
showThinking,
|
|
6661
|
+
showDelegation,
|
|
6662
|
+
showImages,
|
|
6663
|
+
renderToolCall,
|
|
6664
|
+
variant: messageVariant
|
|
6665
|
+
},
|
|
6666
|
+
message.id
|
|
6667
|
+
);
|
|
6668
|
+
if (renderMessage) {
|
|
6669
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderMessage(message, defaultRender) }, message.id);
|
|
6670
|
+
}
|
|
6671
|
+
return defaultRender();
|
|
6672
|
+
}) }),
|
|
6006
6673
|
isLoading && !isStreaming && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 p-4", children: [
|
|
6007
6674
|
/* @__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
6675
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-gray-500 dark:text-gray-400", children: "Thinking..." })
|
|
@@ -6058,6 +6725,7 @@ function AgentChat({
|
|
|
6058
6725
|
maxHeight = "600px",
|
|
6059
6726
|
className,
|
|
6060
6727
|
theme = "system",
|
|
6728
|
+
layout = "fixed",
|
|
6061
6729
|
enableAttachments = false,
|
|
6062
6730
|
enableMarkdown = true,
|
|
6063
6731
|
showToolCalls = true,
|
|
@@ -6065,7 +6733,20 @@ function AgentChat({
|
|
|
6065
6733
|
markdownComponents,
|
|
6066
6734
|
markdownUrlTransform,
|
|
6067
6735
|
markdownContentTransform,
|
|
6068
|
-
onImageClick
|
|
6736
|
+
onImageClick,
|
|
6737
|
+
// Extension props
|
|
6738
|
+
hideHeader,
|
|
6739
|
+
renderAboveInput,
|
|
6740
|
+
renderBelowMessages,
|
|
6741
|
+
renderMessage,
|
|
6742
|
+
renderToolCall,
|
|
6743
|
+
messageVariant = "bubble",
|
|
6744
|
+
showThinking = true,
|
|
6745
|
+
showDelegation = true,
|
|
6746
|
+
showImages = true,
|
|
6747
|
+
pollingInterval,
|
|
6748
|
+
pollingEnabled,
|
|
6749
|
+
onDelegation
|
|
6069
6750
|
}) {
|
|
6070
6751
|
const {
|
|
6071
6752
|
messages,
|
|
@@ -6092,7 +6773,10 @@ function AgentChat({
|
|
|
6092
6773
|
onSessionStart,
|
|
6093
6774
|
onToolCall,
|
|
6094
6775
|
onToolResult,
|
|
6095
|
-
onClarification
|
|
6776
|
+
onClarification,
|
|
6777
|
+
onDelegation,
|
|
6778
|
+
pollingInterval,
|
|
6779
|
+
pollingEnabled
|
|
6096
6780
|
});
|
|
6097
6781
|
const effectiveVerbosity = showToolCalls === false ? "hidden" : toolCallVerbosity ?? "compact";
|
|
6098
6782
|
const dropZoneRef = react.useRef(null);
|
|
@@ -6121,51 +6805,31 @@ function AgentChat({
|
|
|
6121
6805
|
},
|
|
6122
6806
|
[enableAttachments, attachments, sendMessage]
|
|
6123
6807
|
);
|
|
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
|
-
),
|
|
6808
|
+
const messageListProps = {
|
|
6809
|
+
messages,
|
|
6810
|
+
welcomeMessage: hideHeader ? void 0 : welcomeMessage,
|
|
6811
|
+
renderWelcome: hideHeader ? void 0 : renderWelcome,
|
|
6812
|
+
isLoading,
|
|
6813
|
+
isStreaming,
|
|
6814
|
+
isLoadingHistory,
|
|
6815
|
+
enableMarkdown,
|
|
6816
|
+
showToolCalls,
|
|
6817
|
+
toolCallVerbosity: effectiveVerbosity,
|
|
6818
|
+
markdownComponents,
|
|
6819
|
+
markdownUrlTransform,
|
|
6820
|
+
markdownContentTransform,
|
|
6821
|
+
onImageClick,
|
|
6822
|
+
showThinking,
|
|
6823
|
+
showDelegation,
|
|
6824
|
+
showImages,
|
|
6825
|
+
renderMessage,
|
|
6826
|
+
renderToolCall,
|
|
6827
|
+
messageVariant,
|
|
6828
|
+
sendMessage: handleSend
|
|
6829
|
+
};
|
|
6830
|
+
const chatContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6831
|
+
/* @__PURE__ */ jsxRuntime.jsx(MessageList, { ...messageListProps }),
|
|
6832
|
+
renderBelowMessages?.(),
|
|
6169
6833
|
clarification && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-gray-200 dark:border-gray-700 p-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6170
6834
|
AskUserPrompt,
|
|
6171
6835
|
{
|
|
@@ -6175,6 +6839,7 @@ function AgentChat({
|
|
|
6175
6839
|
}
|
|
6176
6840
|
) }),
|
|
6177
6841
|
error && /* @__PURE__ */ jsxRuntime.jsx(ErrorBanner, { error, onRetry: retry, onDismiss: clearError }),
|
|
6842
|
+
renderAboveInput?.(),
|
|
6178
6843
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6179
6844
|
ChatInput,
|
|
6180
6845
|
{
|
|
@@ -6191,8 +6856,17 @@ function AgentChat({
|
|
|
6191
6856
|
}
|
|
6192
6857
|
)
|
|
6193
6858
|
] });
|
|
6859
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ChatContainer, { maxHeight, className, theme, layout, children: enableAttachments ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6860
|
+
FileDropZone,
|
|
6861
|
+
{
|
|
6862
|
+
ref: dropZoneRef,
|
|
6863
|
+
...attachments.dropZoneProps,
|
|
6864
|
+
disabled: isLoading || !!clarification || isLoadingHistory,
|
|
6865
|
+
children: chatContent
|
|
6866
|
+
}
|
|
6867
|
+
) : chatContent });
|
|
6194
6868
|
}
|
|
6195
|
-
function
|
|
6869
|
+
function cn13(...classes) {
|
|
6196
6870
|
return classes.filter(Boolean).join(" ");
|
|
6197
6871
|
}
|
|
6198
6872
|
function TodoList({
|
|
@@ -6221,7 +6895,7 @@ function TodoList({
|
|
|
6221
6895
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6222
6896
|
"div",
|
|
6223
6897
|
{
|
|
6224
|
-
className:
|
|
6898
|
+
className: cn13(
|
|
6225
6899
|
"rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden",
|
|
6226
6900
|
className
|
|
6227
6901
|
),
|
|
@@ -6229,7 +6903,7 @@ function TodoList({
|
|
|
6229
6903
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6230
6904
|
"div",
|
|
6231
6905
|
{
|
|
6232
|
-
className:
|
|
6906
|
+
className: cn13(
|
|
6233
6907
|
"flex items-center gap-2 px-3 py-2 bg-gray-50 dark:bg-gray-800/50",
|
|
6234
6908
|
collapsible && "cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800"
|
|
6235
6909
|
),
|
|
@@ -6260,7 +6934,7 @@ function TodoList({
|
|
|
6260
6934
|
!isCollapsed && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "divide-y divide-gray-100 dark:divide-gray-700", children: todos.map((todo, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6261
6935
|
"li",
|
|
6262
6936
|
{
|
|
6263
|
-
className:
|
|
6937
|
+
className: cn13(
|
|
6264
6938
|
"px-3 py-2 flex items-start gap-2 text-sm",
|
|
6265
6939
|
todo.status === "in_progress" && "bg-blue-50/50 dark:bg-blue-950/20",
|
|
6266
6940
|
todo.status === "completed" && "opacity-60"
|
|
@@ -6270,7 +6944,7 @@ function TodoList({
|
|
|
6270
6944
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6271
6945
|
"p",
|
|
6272
6946
|
{
|
|
6273
|
-
className:
|
|
6947
|
+
className: cn13(
|
|
6274
6948
|
"text-gray-700 dark:text-gray-300",
|
|
6275
6949
|
todo.status === "completed" && "line-through"
|
|
6276
6950
|
),
|
|
@@ -6287,39 +6961,6 @@ function TodoList({
|
|
|
6287
6961
|
);
|
|
6288
6962
|
}
|
|
6289
6963
|
|
|
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
6964
|
exports.AgentChat = AgentChat;
|
|
6324
6965
|
exports.AlertCircleIcon = AlertCircleIcon;
|
|
6325
6966
|
exports.AskUserPrompt = AskUserPrompt;
|
|
@@ -6338,6 +6979,8 @@ exports.ClockIcon = ClockIcon;
|
|
|
6338
6979
|
exports.CodeIcon = CodeIcon;
|
|
6339
6980
|
exports.CopyIcon = CopyIcon;
|
|
6340
6981
|
exports.DatabaseIcon = DatabaseIcon;
|
|
6982
|
+
exports.DelegationProgress = DelegationProgress;
|
|
6983
|
+
exports.DelegationProgressList = DelegationProgressList;
|
|
6341
6984
|
exports.DownloadIcon = DownloadIcon;
|
|
6342
6985
|
exports.ExternalLinkIcon = ExternalLinkIcon;
|
|
6343
6986
|
exports.FileDropZone = FileDropZone;
|
|
@@ -6345,7 +6988,9 @@ exports.FileIcon = FileIcon;
|
|
|
6345
6988
|
exports.FileTextIcon = FileTextIcon;
|
|
6346
6989
|
exports.HelpCircleIcon = HelpCircleIcon;
|
|
6347
6990
|
exports.INTERNAL_TOOL_NAMES = INTERNAL_TOOL_NAMES;
|
|
6991
|
+
exports.ImageGallery = ImageGallery;
|
|
6348
6992
|
exports.ImageIcon = ImageIcon;
|
|
6993
|
+
exports.ImageLightbox = ImageLightbox;
|
|
6349
6994
|
exports.ImagesIcon = ImagesIcon;
|
|
6350
6995
|
exports.ListTodoIcon = ListTodoIcon;
|
|
6351
6996
|
exports.LoadingSpinner = LoadingSpinner;
|
|
@@ -6358,6 +7003,8 @@ exports.PaperclipIcon = PaperclipIcon;
|
|
|
6358
7003
|
exports.SendIcon = SendIcon;
|
|
6359
7004
|
exports.SparklesIcon = SparklesIcon;
|
|
6360
7005
|
exports.StopCircleIcon = StopCircleIcon;
|
|
7006
|
+
exports.ThinkingBlock = ThinkingBlock;
|
|
7007
|
+
exports.ThinkingBlockList = ThinkingBlockList;
|
|
6361
7008
|
exports.TodoList = TodoList;
|
|
6362
7009
|
exports.ToolCallEntry = ToolCallEntry;
|
|
6363
7010
|
exports.UserIcon = UserIcon;
|