@cadraos/sdk 0.1.10 → 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 +1013 -259
- package/dist/chat/index.cjs.map +1 -1
- package/dist/chat/index.d.cts +323 -50
- package/dist/chat/index.d.ts +323 -50
- package/dist/chat/index.js +1006 -260
- package/dist/chat/index.js.map +1 -1
- package/dist/index.cjs +104 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -29
- package/dist/index.d.ts +31 -29
- package/dist/index.js +101 -32
- package/dist/index.js.map +1 -1
- package/package.json +14 -15
package/dist/chat/index.cjs
CHANGED
|
@@ -65,7 +65,7 @@ var BaseResourceAPI = class {
|
|
|
65
65
|
};
|
|
66
66
|
|
|
67
67
|
// src/errors/sdk-errors.ts
|
|
68
|
-
var
|
|
68
|
+
var CadraError = class extends Error {
|
|
69
69
|
/** Error code */
|
|
70
70
|
code;
|
|
71
71
|
/** HTTP status code */
|
|
@@ -76,7 +76,7 @@ var AISaaSError = class extends Error {
|
|
|
76
76
|
requestId;
|
|
77
77
|
constructor(message, code, status, details, requestId) {
|
|
78
78
|
super(message);
|
|
79
|
-
this.name = "
|
|
79
|
+
this.name = "CadraError";
|
|
80
80
|
this.code = code;
|
|
81
81
|
this.status = status;
|
|
82
82
|
this.details = details;
|
|
@@ -86,25 +86,25 @@ var AISaaSError = class extends Error {
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
};
|
|
89
|
-
var AuthenticationError = class extends
|
|
89
|
+
var AuthenticationError = class extends CadraError {
|
|
90
90
|
constructor(message = "Authentication failed", code = "authentication_error", details, requestId) {
|
|
91
91
|
super(message, code, 401, details, requestId);
|
|
92
92
|
this.name = "AuthenticationError";
|
|
93
93
|
}
|
|
94
94
|
};
|
|
95
|
-
var AuthorizationError = class extends
|
|
95
|
+
var AuthorizationError = class extends CadraError {
|
|
96
96
|
constructor(message = "Access denied", code = "authorization_error", details, requestId) {
|
|
97
97
|
super(message, code, 403, details, requestId);
|
|
98
98
|
this.name = "AuthorizationError";
|
|
99
99
|
}
|
|
100
100
|
};
|
|
101
|
-
var NotFoundError = class extends
|
|
101
|
+
var NotFoundError = class extends CadraError {
|
|
102
102
|
constructor(message = "Resource not found", code = "not_found", details, requestId) {
|
|
103
103
|
super(message, code, 404, details, requestId);
|
|
104
104
|
this.name = "NotFoundError";
|
|
105
105
|
}
|
|
106
106
|
};
|
|
107
|
-
var ValidationError = class extends
|
|
107
|
+
var ValidationError = class extends CadraError {
|
|
108
108
|
/** Field-level validation errors */
|
|
109
109
|
errors;
|
|
110
110
|
constructor(message = "Validation failed", errors = [], details, requestId) {
|
|
@@ -113,7 +113,7 @@ var ValidationError = class extends AISaaSError {
|
|
|
113
113
|
this.errors = errors;
|
|
114
114
|
}
|
|
115
115
|
};
|
|
116
|
-
var RateLimitError = class extends
|
|
116
|
+
var RateLimitError = class extends CadraError {
|
|
117
117
|
/** Seconds until rate limit resets */
|
|
118
118
|
retryAfter;
|
|
119
119
|
constructor(message = "Rate limit exceeded", retryAfter, details, requestId) {
|
|
@@ -122,25 +122,25 @@ var RateLimitError = class extends AISaaSError {
|
|
|
122
122
|
this.retryAfter = retryAfter;
|
|
123
123
|
}
|
|
124
124
|
};
|
|
125
|
-
var ServerError = class extends
|
|
125
|
+
var ServerError = class extends CadraError {
|
|
126
126
|
constructor(message = "Server error", status = 500, details, requestId) {
|
|
127
127
|
super(message, "server_error", status, details, requestId);
|
|
128
128
|
this.name = "ServerError";
|
|
129
129
|
}
|
|
130
130
|
};
|
|
131
|
-
var ConflictError = class extends
|
|
131
|
+
var ConflictError = class extends CadraError {
|
|
132
132
|
constructor(message = "Resource conflict", details, requestId) {
|
|
133
133
|
super(message, "conflict", 409, details, requestId);
|
|
134
134
|
this.name = "ConflictError";
|
|
135
135
|
}
|
|
136
136
|
};
|
|
137
|
-
var TimeoutError = class extends
|
|
137
|
+
var TimeoutError = class extends CadraError {
|
|
138
138
|
constructor(message = "Request timed out", details, requestId) {
|
|
139
139
|
super(message, "timeout", 408, details, requestId);
|
|
140
140
|
this.name = "TimeoutError";
|
|
141
141
|
}
|
|
142
142
|
};
|
|
143
|
-
var NetworkError = class extends
|
|
143
|
+
var NetworkError = class extends CadraError {
|
|
144
144
|
constructor(message = "Network error", details) {
|
|
145
145
|
super(message, "network_error", 0, details);
|
|
146
146
|
this.name = "NetworkError";
|
|
@@ -182,7 +182,7 @@ function parseApiError(status, body, requestId) {
|
|
|
182
182
|
if (status >= 500) {
|
|
183
183
|
return new ServerError(message, status, details, requestId);
|
|
184
184
|
}
|
|
185
|
-
return new
|
|
185
|
+
return new CadraError(message, code, status, details, requestId);
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
|
|
@@ -270,15 +270,21 @@ var HttpClient = class {
|
|
|
270
270
|
* Build full URL with query parameters
|
|
271
271
|
*/
|
|
272
272
|
buildUrl(path, query) {
|
|
273
|
-
const
|
|
273
|
+
const base = this.config.baseUrl.replace(/\/+$/, "");
|
|
274
|
+
let url = `${base}${path}`;
|
|
274
275
|
if (query) {
|
|
276
|
+
const params = new URLSearchParams();
|
|
275
277
|
for (const [key, value] of Object.entries(query)) {
|
|
276
278
|
if (value !== void 0) {
|
|
277
|
-
|
|
279
|
+
params.set(key, String(value));
|
|
278
280
|
}
|
|
279
281
|
}
|
|
282
|
+
const qs = params.toString();
|
|
283
|
+
if (qs) {
|
|
284
|
+
url += `?${qs}`;
|
|
285
|
+
}
|
|
280
286
|
}
|
|
281
|
-
return url
|
|
287
|
+
return url;
|
|
282
288
|
}
|
|
283
289
|
/**
|
|
284
290
|
* Make an HTTP request
|
|
@@ -582,9 +588,11 @@ var DEFAULT_STREAMING_CONFIG = {
|
|
|
582
588
|
activityTimeoutMs: 3e4,
|
|
583
589
|
pollingIntervalMs: 2e3
|
|
584
590
|
};
|
|
591
|
+
var DEFAULT_POLLING_ENABLED = true;
|
|
585
592
|
var ExecutionStreamControllerImpl = class {
|
|
586
593
|
options;
|
|
587
594
|
config;
|
|
595
|
+
pollingEnabled;
|
|
588
596
|
sseClient = null;
|
|
589
597
|
status = "connecting";
|
|
590
598
|
reconnectAttempts = 0;
|
|
@@ -618,6 +626,7 @@ var ExecutionStreamControllerImpl = class {
|
|
|
618
626
|
constructor(options) {
|
|
619
627
|
this.options = options;
|
|
620
628
|
this.config = { ...DEFAULT_STREAMING_CONFIG, ...options.config };
|
|
629
|
+
this.pollingEnabled = options.pollingEnabled ?? DEFAULT_POLLING_ENABLED;
|
|
621
630
|
}
|
|
622
631
|
/**
|
|
623
632
|
* Get the last event ID (for resume support)
|
|
@@ -678,7 +687,7 @@ var ExecutionStreamControllerImpl = class {
|
|
|
678
687
|
return Promise.resolve(this.finalExecution);
|
|
679
688
|
}
|
|
680
689
|
if (this.finalError) {
|
|
681
|
-
return Promise.reject(new
|
|
690
|
+
return Promise.reject(new CadraError(
|
|
682
691
|
this.finalError.error,
|
|
683
692
|
this.finalError.errorCode ?? "execution_error",
|
|
684
693
|
500
|
|
@@ -697,7 +706,8 @@ var ExecutionStreamControllerImpl = class {
|
|
|
697
706
|
* Connect to SSE endpoint
|
|
698
707
|
*/
|
|
699
708
|
async connectSSE() {
|
|
700
|
-
const
|
|
709
|
+
const base = this.options.baseUrl.replace(/\/+$/, "");
|
|
710
|
+
const url = `${base}/api/v1/agents/runs/${this.options.executionId}/stream`;
|
|
701
711
|
let authToken = this.options.apiKey;
|
|
702
712
|
if (!authToken && this.options.tokenProvider) {
|
|
703
713
|
authToken = await this.options.tokenProvider();
|
|
@@ -932,7 +942,7 @@ var ExecutionStreamControllerImpl = class {
|
|
|
932
942
|
this.finalError = error;
|
|
933
943
|
this.emit("error", error);
|
|
934
944
|
if (this.waitReject) {
|
|
935
|
-
this.waitReject(new
|
|
945
|
+
this.waitReject(new CadraError(
|
|
936
946
|
error.error,
|
|
937
947
|
error.errorCode ?? "execution_error",
|
|
938
948
|
500
|
|
@@ -957,15 +967,61 @@ var ExecutionStreamControllerImpl = class {
|
|
|
957
967
|
if (this.status === "closed") {
|
|
958
968
|
return;
|
|
959
969
|
}
|
|
970
|
+
await this.recoverState();
|
|
971
|
+
if (this.status === "closed") {
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
960
974
|
try {
|
|
961
975
|
await this.connectSSE();
|
|
962
976
|
} catch {
|
|
963
977
|
await this.handleConnectionError(error);
|
|
964
978
|
}
|
|
965
979
|
} else {
|
|
966
|
-
this.
|
|
967
|
-
|
|
968
|
-
|
|
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);
|
|
969
1025
|
}
|
|
970
1026
|
}
|
|
971
1027
|
/**
|
|
@@ -1050,7 +1106,7 @@ function createExecutionStreamController(options) {
|
|
|
1050
1106
|
// src/resources/agents.ts
|
|
1051
1107
|
var AgentsAPI = class extends BaseResourceAPI {
|
|
1052
1108
|
constructor(http, getStreamConfig) {
|
|
1053
|
-
super(http, "/agents");
|
|
1109
|
+
super(http, "/api/v1/agents");
|
|
1054
1110
|
this.getStreamConfig = getStreamConfig;
|
|
1055
1111
|
}
|
|
1056
1112
|
// ===== LIST Operations =====
|
|
@@ -1326,7 +1382,7 @@ var AgentsAPI = class extends BaseResourceAPI {
|
|
|
1326
1382
|
// src/resources/skills.ts
|
|
1327
1383
|
var SkillsAPI = class extends BaseResourceAPI {
|
|
1328
1384
|
constructor(http) {
|
|
1329
|
-
super(http, "/skills");
|
|
1385
|
+
super(http, "/api/v1/skills");
|
|
1330
1386
|
}
|
|
1331
1387
|
// ===== LIST Operations =====
|
|
1332
1388
|
/**
|
|
@@ -1470,7 +1526,7 @@ var SkillsAPI = class extends BaseResourceAPI {
|
|
|
1470
1526
|
// src/resources/tools.ts
|
|
1471
1527
|
var ToolsAPI = class extends BaseResourceAPI {
|
|
1472
1528
|
constructor(http) {
|
|
1473
|
-
super(http, "/tools");
|
|
1529
|
+
super(http, "/api/v1/tools");
|
|
1474
1530
|
}
|
|
1475
1531
|
// ===== LIST Operations =====
|
|
1476
1532
|
/**
|
|
@@ -1633,7 +1689,7 @@ var ToolsAPI = class extends BaseResourceAPI {
|
|
|
1633
1689
|
// src/resources/artifacts.ts
|
|
1634
1690
|
var ArtifactsAPI = class extends BaseResourceAPI {
|
|
1635
1691
|
constructor(http) {
|
|
1636
|
-
super(http, "/artifacts");
|
|
1692
|
+
super(http, "/api/v1/artifacts");
|
|
1637
1693
|
}
|
|
1638
1694
|
// ===== LIST Operations =====
|
|
1639
1695
|
/**
|
|
@@ -1829,7 +1885,7 @@ var ArtifactsAPI = class extends BaseResourceAPI {
|
|
|
1829
1885
|
// src/resources/sessions.ts
|
|
1830
1886
|
var SessionsAPI = class extends BaseResourceAPI {
|
|
1831
1887
|
constructor(http, getStreamConfig) {
|
|
1832
|
-
super(http, "/sessions");
|
|
1888
|
+
super(http, "/api/v1/sessions");
|
|
1833
1889
|
this.getStreamConfig = getStreamConfig;
|
|
1834
1890
|
}
|
|
1835
1891
|
// ===== LIST Operations =====
|
|
@@ -2060,9 +2116,9 @@ var SessionsAPI = class extends BaseResourceAPI {
|
|
|
2060
2116
|
};
|
|
2061
2117
|
|
|
2062
2118
|
// src/client.ts
|
|
2063
|
-
var DEFAULT_BASE_URL = "https://api.
|
|
2119
|
+
var DEFAULT_BASE_URL = "https://api.cadraos.com";
|
|
2064
2120
|
var DEFAULT_TIMEOUT = 3e4;
|
|
2065
|
-
var
|
|
2121
|
+
var CadraClient = class {
|
|
2066
2122
|
httpClient;
|
|
2067
2123
|
config;
|
|
2068
2124
|
/**
|
|
@@ -2093,19 +2149,19 @@ var AISaaSClient = class {
|
|
|
2093
2149
|
* @example
|
|
2094
2150
|
* ```typescript
|
|
2095
2151
|
* // API key authentication
|
|
2096
|
-
* const client = new
|
|
2152
|
+
* const client = new CadraClient({
|
|
2097
2153
|
* apiKey: 'sk_...',
|
|
2098
2154
|
* orgId: 123,
|
|
2099
2155
|
* });
|
|
2100
2156
|
*
|
|
2101
2157
|
* // OAuth token authentication
|
|
2102
|
-
* const client = new
|
|
2158
|
+
* const client = new CadraClient({
|
|
2103
2159
|
* token: 'eyJ...',
|
|
2104
2160
|
* orgId: 123,
|
|
2105
2161
|
* });
|
|
2106
2162
|
*
|
|
2107
2163
|
* // Token provider (for automatic refresh)
|
|
2108
|
-
* const client = new
|
|
2164
|
+
* const client = new CadraClient({
|
|
2109
2165
|
* tokenProvider: async () => myAuth.getAccessToken(),
|
|
2110
2166
|
* orgId: 123,
|
|
2111
2167
|
* });
|
|
@@ -2113,6 +2169,19 @@ var AISaaSClient = class {
|
|
|
2113
2169
|
*/
|
|
2114
2170
|
constructor(options) {
|
|
2115
2171
|
this.validateOptions(options);
|
|
2172
|
+
if (options.baseUrl) {
|
|
2173
|
+
try {
|
|
2174
|
+
const parsed = new URL(options.baseUrl);
|
|
2175
|
+
if (/\/(api|v\d)/.test(parsed.pathname)) {
|
|
2176
|
+
if (typeof process !== "undefined" && process.env?.NODE_ENV !== "production") {
|
|
2177
|
+
console.warn(
|
|
2178
|
+
`[CadraOS SDK] baseUrl should be the origin only (e.g., "https://api.cadraos.com" or "http://localhost:3000"). The SDK automatically prepends "/api/v1/" to all requests. Received: "${options.baseUrl}"`
|
|
2179
|
+
);
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
} catch {
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2116
2185
|
this.config = {
|
|
2117
2186
|
baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,
|
|
2118
2187
|
orgId: options.orgId,
|
|
@@ -2185,21 +2254,21 @@ function resolveClient(config) {
|
|
|
2185
2254
|
throw new Error("DefaultAdapterConfig requires 'orgId' when 'client' is not provided");
|
|
2186
2255
|
}
|
|
2187
2256
|
if (config.apiKey) {
|
|
2188
|
-
return new
|
|
2257
|
+
return new CadraClient({
|
|
2189
2258
|
apiKey: config.apiKey,
|
|
2190
2259
|
orgId: config.orgId,
|
|
2191
2260
|
baseUrl: config.baseUrl
|
|
2192
2261
|
});
|
|
2193
2262
|
}
|
|
2194
2263
|
if (config.token) {
|
|
2195
|
-
return new
|
|
2264
|
+
return new CadraClient({
|
|
2196
2265
|
token: config.token,
|
|
2197
2266
|
orgId: config.orgId,
|
|
2198
2267
|
baseUrl: config.baseUrl
|
|
2199
2268
|
});
|
|
2200
2269
|
}
|
|
2201
2270
|
if (config.tokenProvider) {
|
|
2202
|
-
return new
|
|
2271
|
+
return new CadraClient({
|
|
2203
2272
|
tokenProvider: config.tokenProvider,
|
|
2204
2273
|
orgId: config.orgId,
|
|
2205
2274
|
baseUrl: config.baseUrl
|
|
@@ -2211,7 +2280,7 @@ function resolveClient(config) {
|
|
|
2211
2280
|
}
|
|
2212
2281
|
function resolveBaseUrl(config) {
|
|
2213
2282
|
if (config.baseUrl) return config.baseUrl;
|
|
2214
|
-
return "https://api.
|
|
2283
|
+
return "https://api.cadraos.com";
|
|
2215
2284
|
}
|
|
2216
2285
|
async function getAuthHeaders(config) {
|
|
2217
2286
|
const headers = {
|
|
@@ -2320,7 +2389,7 @@ function createDefaultAdapter(config) {
|
|
|
2320
2389
|
// Attachment Methods (raw fetch — CadraClient has no AttachmentsAPI yet)
|
|
2321
2390
|
// -------------------------------------------------------------------------
|
|
2322
2391
|
async getUploadUrl(input) {
|
|
2323
|
-
return rawRequest(config, "POST", "/attachments/upload-url", {
|
|
2392
|
+
return rawRequest(config, "POST", "/api/v1/attachments/upload-url", {
|
|
2324
2393
|
sessionId: input.sessionId,
|
|
2325
2394
|
filename: input.filename,
|
|
2326
2395
|
mimeType: input.mimeType,
|
|
@@ -2328,10 +2397,10 @@ function createDefaultAdapter(config) {
|
|
|
2328
2397
|
});
|
|
2329
2398
|
},
|
|
2330
2399
|
async confirmUpload(uuid) {
|
|
2331
|
-
await rawRequest(config, "POST", `/attachments/${uuid}/confirm`);
|
|
2400
|
+
await rawRequest(config, "POST", `/api/v1/attachments/${uuid}/confirm`);
|
|
2332
2401
|
},
|
|
2333
2402
|
async getDownloadUrl(uuid) {
|
|
2334
|
-
const result = await rawRequest(config, "GET", `/attachments/${uuid}/download-url`);
|
|
2403
|
+
const result = await rawRequest(config, "GET", `/api/v1/attachments/${uuid}/download-url`);
|
|
2335
2404
|
return result.url;
|
|
2336
2405
|
},
|
|
2337
2406
|
// -------------------------------------------------------------------------
|
|
@@ -2412,7 +2481,7 @@ function createDefaultAdapter(config) {
|
|
|
2412
2481
|
);
|
|
2413
2482
|
}
|
|
2414
2483
|
}
|
|
2415
|
-
return `${baseUrl}/agents/runs/${executionId}/stream`;
|
|
2484
|
+
return `${baseUrl}/api/v1/agents/runs/${executionId}/stream`;
|
|
2416
2485
|
},
|
|
2417
2486
|
// -------------------------------------------------------------------------
|
|
2418
2487
|
// Secure SSE Streaming (Recommended)
|
|
@@ -2804,12 +2873,54 @@ function useExecutionStream(options) {
|
|
|
2804
2873
|
}
|
|
2805
2874
|
|
|
2806
2875
|
// src/chat/hooks/useAgentChat.ts
|
|
2876
|
+
var __DEV__ = typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
|
|
2807
2877
|
var SILENT_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
2808
2878
|
"check_delegations"
|
|
2809
2879
|
]);
|
|
2810
2880
|
function generateId() {
|
|
2811
2881
|
return `msg-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
2812
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
|
+
}
|
|
2813
2924
|
function historyToMessage(historyMsg) {
|
|
2814
2925
|
return {
|
|
2815
2926
|
id: historyMsg.uuid,
|
|
@@ -2850,7 +2961,9 @@ function useAgentChat(options) {
|
|
|
2850
2961
|
// Deprecated, but still supported
|
|
2851
2962
|
onToolCall,
|
|
2852
2963
|
onToolResult,
|
|
2853
|
-
onClarification
|
|
2964
|
+
onClarification,
|
|
2965
|
+
pollingInterval,
|
|
2966
|
+
pollingEnabled
|
|
2854
2967
|
} = options;
|
|
2855
2968
|
const contextConfig = useChatConfigOptional();
|
|
2856
2969
|
const adapter = propsAdapter ?? contextConfig?.adapter;
|
|
@@ -2882,8 +2995,14 @@ function useAgentChat(options) {
|
|
|
2882
2995
|
const streamingMessageIdRef = react.useRef(null);
|
|
2883
2996
|
const pendingToolCallsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
2884
2997
|
const lastMessageContentRef = react.useRef("");
|
|
2998
|
+
const finalizedRef = react.useRef(false);
|
|
2885
2999
|
const firedToolResultsRef = react.useRef(/* @__PURE__ */ new Set());
|
|
2886
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]);
|
|
2887
3006
|
const updateStreamingMessage = react.useCallback((content) => {
|
|
2888
3007
|
if (!streamingMessageIdRef.current) return;
|
|
2889
3008
|
setMessages(
|
|
@@ -2912,21 +3031,72 @@ function useAgentChat(options) {
|
|
|
2912
3031
|
});
|
|
2913
3032
|
});
|
|
2914
3033
|
}, []);
|
|
2915
|
-
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) => {
|
|
2916
3067
|
if (!streamingMessageIdRef.current) return;
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
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;
|
|
3080
|
+
const updatedToolCalls = msg.toolCalls?.map(
|
|
3081
|
+
(tc) => tc.status === "running" || tc.status === "pending" ? { ...tc, status: "completed" } : tc
|
|
3082
|
+
);
|
|
3083
|
+
return {
|
|
3084
|
+
...msg,
|
|
3085
|
+
content: resolvedContent || msg.content,
|
|
3086
|
+
isStreaming: false,
|
|
3087
|
+
toolCalls: updatedToolCalls
|
|
3088
|
+
};
|
|
3089
|
+
});
|
|
3090
|
+
});
|
|
2922
3091
|
streamingMessageIdRef.current = null;
|
|
2923
3092
|
streamingContentRef.current = "";
|
|
2924
3093
|
pendingToolCallsRef.current.clear();
|
|
2925
3094
|
firedToolResultsRef.current.clear();
|
|
3095
|
+
pendingDelegationsRef.current.clear();
|
|
2926
3096
|
}, []);
|
|
2927
3097
|
const handleExecutionLog = react.useCallback(
|
|
2928
3098
|
(log) => {
|
|
2929
|
-
console.log("[useAgentChat] handleExecutionLog:", log.type, log.metadata);
|
|
3099
|
+
if (__DEV__) console.log("[useAgentChat] handleExecutionLog:", log.type, log.metadata);
|
|
2930
3100
|
switch (log.type) {
|
|
2931
3101
|
// Primary handlers for ai-saas-api worker log types
|
|
2932
3102
|
case "llm_response": {
|
|
@@ -2946,11 +3116,46 @@ function useAgentChat(options) {
|
|
|
2946
3116
|
}
|
|
2947
3117
|
break;
|
|
2948
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
|
+
}
|
|
2949
3153
|
case "info":
|
|
2950
3154
|
case "system":
|
|
2951
|
-
console.log("[useAgentChat] Status:", log.type, log.title);
|
|
3155
|
+
if (__DEV__) console.log("[useAgentChat] Status:", log.type, log.title);
|
|
2952
3156
|
break;
|
|
2953
3157
|
case "tool_call": {
|
|
3158
|
+
if (finalizedRef.current) break;
|
|
2954
3159
|
const toolName = log.metadata?.toolName;
|
|
2955
3160
|
if (SILENT_TOOL_NAMES.has(toolName)) break;
|
|
2956
3161
|
const toolCallId = log.metadata?.toolCallId || `tool-${Date.now()}`;
|
|
@@ -3005,17 +3210,18 @@ function useAgentChat(options) {
|
|
|
3005
3210
|
firedToolResultsRef.current.add(resultToolCallId);
|
|
3006
3211
|
}
|
|
3007
3212
|
onToolResultRef.current?.(resultToolName, result, durationMs);
|
|
3213
|
+
updateMessageImages();
|
|
3008
3214
|
break;
|
|
3009
3215
|
}
|
|
3010
3216
|
default:
|
|
3011
|
-
console.log("[useAgentChat] Unhandled log type:", log.type, log);
|
|
3217
|
+
if (__DEV__) console.log("[useAgentChat] Unhandled log type:", log.type, log);
|
|
3012
3218
|
}
|
|
3013
3219
|
},
|
|
3014
|
-
[updateStreamingMessage, updateToolCall]
|
|
3220
|
+
[updateStreamingMessage, updateToolCall, updateMessageImages, addDelegationEvent]
|
|
3015
3221
|
);
|
|
3016
3222
|
const handleStreamLog = react.useCallback(
|
|
3017
3223
|
(log) => {
|
|
3018
|
-
console.log("[useAgentChat] handleStreamLog:", log.logType, log.metadata);
|
|
3224
|
+
if (__DEV__) console.log("[useAgentChat] handleStreamLog:", log.logType, log.metadata);
|
|
3019
3225
|
switch (log.logType) {
|
|
3020
3226
|
case "llm_response": {
|
|
3021
3227
|
const llmText = log.metadata?.text || "";
|
|
@@ -3034,9 +3240,42 @@ function useAgentChat(options) {
|
|
|
3034
3240
|
}
|
|
3035
3241
|
break;
|
|
3036
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
|
+
}
|
|
3037
3276
|
case "info":
|
|
3038
3277
|
case "system":
|
|
3039
|
-
console.log("[useAgentChat] Status:", log.logType, log.message);
|
|
3278
|
+
if (__DEV__) console.log("[useAgentChat] Status:", log.logType, log.message);
|
|
3040
3279
|
break;
|
|
3041
3280
|
case "response_text":
|
|
3042
3281
|
case "text_chunk": {
|
|
@@ -3046,6 +3285,7 @@ function useAgentChat(options) {
|
|
|
3046
3285
|
break;
|
|
3047
3286
|
}
|
|
3048
3287
|
case "tool_call": {
|
|
3288
|
+
if (finalizedRef.current) break;
|
|
3049
3289
|
const toolName = log.metadata?.toolName;
|
|
3050
3290
|
if (SILENT_TOOL_NAMES.has(toolName)) break;
|
|
3051
3291
|
const toolCallId = log.metadata?.toolCallId || `tool-${Date.now()}`;
|
|
@@ -3100,6 +3340,7 @@ function useAgentChat(options) {
|
|
|
3100
3340
|
firedToolResultsRef.current.add(resultToolCallId);
|
|
3101
3341
|
}
|
|
3102
3342
|
onToolResultRef.current?.(resultToolName, result, durationMs);
|
|
3343
|
+
updateMessageImages();
|
|
3103
3344
|
break;
|
|
3104
3345
|
}
|
|
3105
3346
|
case "final_response": {
|
|
@@ -3111,10 +3352,10 @@ function useAgentChat(options) {
|
|
|
3111
3352
|
break;
|
|
3112
3353
|
}
|
|
3113
3354
|
default:
|
|
3114
|
-
console.log("[useAgentChat] Unknown log type:", log.logType, log);
|
|
3355
|
+
if (__DEV__) console.log("[useAgentChat] Unknown log type:", log.logType, log);
|
|
3115
3356
|
}
|
|
3116
3357
|
},
|
|
3117
|
-
[updateStreamingMessage, updateToolCall]
|
|
3358
|
+
[updateStreamingMessage, updateToolCall, updateMessageImages, addDelegationEvent]
|
|
3118
3359
|
);
|
|
3119
3360
|
const handleClarification = react.useCallback(
|
|
3120
3361
|
(data) => {
|
|
@@ -3123,17 +3364,23 @@ function useAgentChat(options) {
|
|
|
3123
3364
|
},
|
|
3124
3365
|
[onClarification]
|
|
3125
3366
|
);
|
|
3126
|
-
const
|
|
3127
|
-
|
|
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");
|
|
3128
3375
|
setIsLoading(false);
|
|
3129
3376
|
setIsStreamControllerConnected(false);
|
|
3130
|
-
finalizeStreamingMessage();
|
|
3377
|
+
finalizeStreamingMessage(finalOutput);
|
|
3131
3378
|
setCurrentExecutionId(null);
|
|
3132
3379
|
streamControllerRef.current = null;
|
|
3133
3380
|
}, [finalizeStreamingMessage]);
|
|
3134
3381
|
const handleError = react.useCallback(
|
|
3135
3382
|
(errorMsg) => {
|
|
3136
|
-
console.log("[useAgentChat] handleError called:", errorMsg);
|
|
3383
|
+
if (__DEV__) console.log("[useAgentChat] handleError called:", errorMsg);
|
|
3137
3384
|
const chatError = {
|
|
3138
3385
|
code: "EXECUTION_ERROR",
|
|
3139
3386
|
message: errorMsg,
|
|
@@ -3172,43 +3419,39 @@ function useAgentChat(options) {
|
|
|
3172
3419
|
if (pollingExecutionIdRef.current === executionId) return;
|
|
3173
3420
|
stopPolling();
|
|
3174
3421
|
pollingExecutionIdRef.current = executionId;
|
|
3175
|
-
console.log("[useAgentChat] Starting polling fallback for:", executionId);
|
|
3422
|
+
if (__DEV__) console.log("[useAgentChat] Starting polling fallback for:", executionId);
|
|
3176
3423
|
const poll = async () => {
|
|
3177
3424
|
if (pollingExecutionIdRef.current !== executionId) return;
|
|
3178
3425
|
try {
|
|
3179
3426
|
const execution = await adapter.getExecution(executionId);
|
|
3180
3427
|
if (execution.status === "completed") {
|
|
3181
|
-
console.log("[useAgentChat] Polling: execution completed");
|
|
3182
|
-
if (execution.result) {
|
|
3183
|
-
streamingContentRef.current = execution.result;
|
|
3184
|
-
updateStreamingMessage(execution.result);
|
|
3185
|
-
}
|
|
3428
|
+
if (__DEV__) console.log("[useAgentChat] Polling: execution completed");
|
|
3186
3429
|
stopPolling();
|
|
3187
|
-
handleComplete();
|
|
3430
|
+
handleComplete(execution.result || void 0);
|
|
3188
3431
|
} else if (execution.status === "failed") {
|
|
3189
|
-
console.log("[useAgentChat] Polling: execution failed");
|
|
3432
|
+
if (__DEV__) console.log("[useAgentChat] Polling: execution failed");
|
|
3190
3433
|
stopPolling();
|
|
3191
3434
|
handleError(execution.error || "Execution failed");
|
|
3192
3435
|
}
|
|
3193
3436
|
} catch (err) {
|
|
3194
|
-
console.warn("[useAgentChat] Polling error (will retry):", err);
|
|
3437
|
+
if (__DEV__) console.warn("[useAgentChat] Polling error (will retry):", err);
|
|
3195
3438
|
}
|
|
3196
3439
|
};
|
|
3197
3440
|
poll();
|
|
3198
|
-
pollingIntervalRef.current = setInterval(poll, 2e3);
|
|
3199
|
-
}, [adapter, stopPolling,
|
|
3441
|
+
pollingIntervalRef.current = setInterval(poll, pollingInterval ?? 2e3);
|
|
3442
|
+
}, [adapter, stopPolling, handleComplete, handleError, pollingInterval]);
|
|
3200
3443
|
react.useEffect(() => {
|
|
3201
|
-
if (!useStreamController && isUsingFallback && currentExecutionId && isLoading) {
|
|
3202
|
-
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");
|
|
3203
3446
|
startPolling(currentExecutionId);
|
|
3204
3447
|
}
|
|
3205
|
-
}, [useStreamController, isUsingFallback, currentExecutionId, isLoading, startPolling]);
|
|
3448
|
+
}, [useStreamController, isUsingFallback, currentExecutionId, isLoading, startPolling, pollingEnabled]);
|
|
3206
3449
|
const sseTimeoutRef = react.useRef(null);
|
|
3207
3450
|
react.useEffect(() => {
|
|
3208
|
-
if (!useStreamController && currentExecutionId && isLoading && !legacyIsConnected && !isUsingFallback) {
|
|
3451
|
+
if (!useStreamController && currentExecutionId && isLoading && !legacyIsConnected && !isUsingFallback && pollingEnabled !== false) {
|
|
3209
3452
|
sseTimeoutRef.current = setTimeout(() => {
|
|
3210
3453
|
if (!legacyIsConnected && currentExecutionId && isLoading) {
|
|
3211
|
-
console.log("[useAgentChat] SSE connection timeout, activating polling fallback");
|
|
3454
|
+
if (__DEV__) console.log("[useAgentChat] SSE connection timeout, activating polling fallback");
|
|
3212
3455
|
startPolling(currentExecutionId);
|
|
3213
3456
|
}
|
|
3214
3457
|
}, 1e4);
|
|
@@ -3219,7 +3462,7 @@ function useAgentChat(options) {
|
|
|
3219
3462
|
sseTimeoutRef.current = null;
|
|
3220
3463
|
}
|
|
3221
3464
|
};
|
|
3222
|
-
}, [useStreamController, currentExecutionId, isLoading, legacyIsConnected, isUsingFallback, startPolling]);
|
|
3465
|
+
}, [useStreamController, currentExecutionId, isLoading, legacyIsConnected, isUsingFallback, startPolling, pollingEnabled]);
|
|
3223
3466
|
react.useEffect(() => {
|
|
3224
3467
|
if (!currentExecutionId) {
|
|
3225
3468
|
stopPolling();
|
|
@@ -3235,7 +3478,7 @@ function useAgentChat(options) {
|
|
|
3235
3478
|
streamControllerRef.current.cancel();
|
|
3236
3479
|
streamControllerRef.current = null;
|
|
3237
3480
|
}
|
|
3238
|
-
console.log("[useAgentChat] Creating stream controller for:", executionId);
|
|
3481
|
+
if (__DEV__) console.log("[useAgentChat] Creating stream controller for:", executionId);
|
|
3239
3482
|
const controller = adapter.createStream(executionId, sessionId);
|
|
3240
3483
|
streamControllerRef.current = controller;
|
|
3241
3484
|
controller.on("log", (log) => {
|
|
@@ -3286,6 +3529,34 @@ function useAgentChat(options) {
|
|
|
3286
3529
|
}
|
|
3287
3530
|
firedToolResultsRef.current.add(toolCallId);
|
|
3288
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);
|
|
3289
3560
|
});
|
|
3290
3561
|
controller.on("textDelta", (data) => {
|
|
3291
3562
|
streamingContentRef.current += data.delta;
|
|
@@ -3299,11 +3570,8 @@ function useAgentChat(options) {
|
|
|
3299
3570
|
});
|
|
3300
3571
|
});
|
|
3301
3572
|
controller.on("complete", ({ execution }) => {
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
updateStreamingMessage(execution.output);
|
|
3305
|
-
}
|
|
3306
|
-
handleComplete();
|
|
3573
|
+
const output = execution?.output || void 0;
|
|
3574
|
+
handleComplete(output);
|
|
3307
3575
|
});
|
|
3308
3576
|
controller.on("error", (errorEvent) => {
|
|
3309
3577
|
handleError(errorEvent.error);
|
|
@@ -3317,7 +3585,7 @@ function useAgentChat(options) {
|
|
|
3317
3585
|
});
|
|
3318
3586
|
setIsStreamControllerConnected(true);
|
|
3319
3587
|
},
|
|
3320
|
-
[adapter, handleExecutionLog, updateStreamingMessage, updateToolCall, handleClarification, handleComplete, handleError]
|
|
3588
|
+
[adapter, handleExecutionLog, updateStreamingMessage, updateToolCall, updateMessageImages, addDelegationEvent, handleClarification, handleComplete, handleError]
|
|
3321
3589
|
);
|
|
3322
3590
|
const sendMessage = react.useCallback(
|
|
3323
3591
|
async (content, options2) => {
|
|
@@ -3347,8 +3615,10 @@ function useAgentChat(options) {
|
|
|
3347
3615
|
setMessages((prev) => [...prev, assistantMessage]);
|
|
3348
3616
|
streamingMessageIdRef.current = assistantMessageId;
|
|
3349
3617
|
streamingContentRef.current = "";
|
|
3618
|
+
completedRef.current = false;
|
|
3619
|
+
finalizedRef.current = false;
|
|
3350
3620
|
try {
|
|
3351
|
-
console.log("[useAgentChat] Starting execution...", { agentId, sessionId: currentSessionId });
|
|
3621
|
+
if (__DEV__) console.log("[useAgentChat] Starting execution...", { agentId, sessionId: currentSessionId });
|
|
3352
3622
|
const result = await adapter.startExecution({
|
|
3353
3623
|
agentId,
|
|
3354
3624
|
teamId,
|
|
@@ -3356,7 +3626,7 @@ function useAgentChat(options) {
|
|
|
3356
3626
|
content: content.trim(),
|
|
3357
3627
|
attachmentUuids
|
|
3358
3628
|
});
|
|
3359
|
-
console.log("[useAgentChat] Execution started:", result);
|
|
3629
|
+
if (__DEV__) console.log("[useAgentChat] Execution started:", result);
|
|
3360
3630
|
if (!currentSessionId && result.sessionId) {
|
|
3361
3631
|
internallyCreatedSessionRef.current = result.sessionId;
|
|
3362
3632
|
setCurrentSessionId(result.sessionId);
|
|
@@ -3367,7 +3637,7 @@ function useAgentChat(options) {
|
|
|
3367
3637
|
connectStreamController(result.executionId, result.sessionId || currentSessionId || void 0);
|
|
3368
3638
|
setCurrentExecutionId(result.executionId);
|
|
3369
3639
|
} else {
|
|
3370
|
-
console.log("[useAgentChat] Setting executionId:", result.executionId);
|
|
3640
|
+
if (__DEV__) console.log("[useAgentChat] Setting executionId:", result.executionId);
|
|
3371
3641
|
setCurrentExecutionId(result.executionId);
|
|
3372
3642
|
}
|
|
3373
3643
|
} catch (err) {
|
|
@@ -3427,6 +3697,7 @@ function useAgentChat(options) {
|
|
|
3427
3697
|
setMessages([]);
|
|
3428
3698
|
setCurrentSessionId(null);
|
|
3429
3699
|
hasLoadedInitialSession.current = false;
|
|
3700
|
+
lastLoadedSessionRef.current = null;
|
|
3430
3701
|
internallyCreatedSessionRef.current = null;
|
|
3431
3702
|
}, []);
|
|
3432
3703
|
const loadSession = react.useCallback(
|
|
@@ -3522,15 +3793,20 @@ function useAgentChat(options) {
|
|
|
3522
3793
|
},
|
|
3523
3794
|
[adapter, onError]
|
|
3524
3795
|
);
|
|
3796
|
+
const lastLoadedSessionRef = react.useRef(null);
|
|
3525
3797
|
react.useEffect(() => {
|
|
3526
|
-
if (initialSessionId
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
return;
|
|
3530
|
-
}
|
|
3798
|
+
if (!initialSessionId) return;
|
|
3799
|
+
if (internallyCreatedSessionRef.current === initialSessionId) {
|
|
3800
|
+
lastLoadedSessionRef.current = initialSessionId;
|
|
3531
3801
|
hasLoadedInitialSession.current = true;
|
|
3532
|
-
|
|
3802
|
+
return;
|
|
3803
|
+
}
|
|
3804
|
+
if (lastLoadedSessionRef.current === initialSessionId && hasLoadedInitialSession.current) {
|
|
3805
|
+
return;
|
|
3533
3806
|
}
|
|
3807
|
+
lastLoadedSessionRef.current = initialSessionId;
|
|
3808
|
+
hasLoadedInitialSession.current = true;
|
|
3809
|
+
loadSession(initialSessionId);
|
|
3534
3810
|
}, [initialSessionId, loadSession]);
|
|
3535
3811
|
react.useEffect(() => {
|
|
3536
3812
|
return () => {
|
|
@@ -3546,6 +3822,16 @@ function useAgentChat(options) {
|
|
|
3546
3822
|
}
|
|
3547
3823
|
return !!currentExecutionId && legacyIsConnected;
|
|
3548
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]);
|
|
3549
3835
|
return {
|
|
3550
3836
|
messages,
|
|
3551
3837
|
isLoading,
|
|
@@ -3554,6 +3840,7 @@ function useAgentChat(options) {
|
|
|
3554
3840
|
error,
|
|
3555
3841
|
sessionId: currentSessionId,
|
|
3556
3842
|
clarification,
|
|
3843
|
+
activeDelegation,
|
|
3557
3844
|
sendMessage,
|
|
3558
3845
|
respondToClarification,
|
|
3559
3846
|
cancel,
|
|
@@ -4409,18 +4696,30 @@ function ChatContainer({
|
|
|
4409
4696
|
children,
|
|
4410
4697
|
maxHeight = "600px",
|
|
4411
4698
|
className,
|
|
4412
|
-
theme = "system"
|
|
4699
|
+
theme = "system",
|
|
4700
|
+
layout = "fixed"
|
|
4413
4701
|
}) {
|
|
4414
4702
|
const maxHeightValue = typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight;
|
|
4703
|
+
const isFill = layout === "fill";
|
|
4415
4704
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4416
4705
|
"div",
|
|
4417
4706
|
{
|
|
4418
4707
|
className: cn2(
|
|
4419
|
-
"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",
|
|
4420
4713
|
className
|
|
4421
4714
|
),
|
|
4422
|
-
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
|
+
},
|
|
4423
4721
|
"data-theme": theme,
|
|
4722
|
+
"data-layout": layout,
|
|
4424
4723
|
children
|
|
4425
4724
|
}
|
|
4426
4725
|
);
|
|
@@ -5107,7 +5406,7 @@ var FileDropZone = react.forwardRef(
|
|
|
5107
5406
|
{
|
|
5108
5407
|
ref: dropZoneRef,
|
|
5109
5408
|
"data-dropzone": "wrapper",
|
|
5110
|
-
className: cn4("relative
|
|
5409
|
+
className: cn4("relative flex flex-col flex-1 min-h-0", className),
|
|
5111
5410
|
style: { minHeight: "inherit" },
|
|
5112
5411
|
children: [
|
|
5113
5412
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5392,6 +5691,312 @@ function AskUserPrompt({
|
|
|
5392
5691
|
function cn6(...classes) {
|
|
5393
5692
|
return classes.filter(Boolean).join(" ");
|
|
5394
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
|
+
}
|
|
5395
6000
|
function MarkdownContent({
|
|
5396
6001
|
content,
|
|
5397
6002
|
className,
|
|
@@ -5411,11 +6016,11 @@ function MarkdownContent({
|
|
|
5411
6016
|
h3: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold mt-3 mb-1 first:mt-0", children }),
|
|
5412
6017
|
h4: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-base font-semibold mt-2 mb-1 first:mt-0", children }),
|
|
5413
6018
|
// Paragraphs
|
|
5414
|
-
p: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-
|
|
6019
|
+
p: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-1.5 last:mb-0", children }),
|
|
5415
6020
|
// Lists
|
|
5416
|
-
ul: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "list-disc list-inside mb-
|
|
5417
|
-
ol: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "list-decimal list-inside mb-
|
|
5418
|
-
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 }),
|
|
5419
6024
|
// Links
|
|
5420
6025
|
a: ({ href, children }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5421
6026
|
"a",
|
|
@@ -5450,7 +6055,7 @@ function MarkdownContent({
|
|
|
5450
6055
|
if (isCodeBlock) {
|
|
5451
6056
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative my-2", children: [
|
|
5452
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 }),
|
|
5453
|
-
/* @__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 }) })
|
|
5454
6059
|
] });
|
|
5455
6060
|
}
|
|
5456
6061
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5497,7 +6102,7 @@ function MarkdownContent({
|
|
|
5497
6102
|
() => customComponents ? { ...defaultComponents, ...customComponents } : defaultComponents,
|
|
5498
6103
|
[defaultComponents, customComponents]
|
|
5499
6104
|
);
|
|
5500
|
-
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(
|
|
5501
6106
|
ReactMarkdown__default.default,
|
|
5502
6107
|
{
|
|
5503
6108
|
remarkPlugins: [remarkGfm__default.default],
|
|
@@ -5507,7 +6112,89 @@ function MarkdownContent({
|
|
|
5507
6112
|
}
|
|
5508
6113
|
) });
|
|
5509
6114
|
}
|
|
5510
|
-
function
|
|
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
|
+
}
|
|
6167
|
+
var INTERNAL_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
6168
|
+
"update_task_list",
|
|
6169
|
+
"create_task",
|
|
6170
|
+
"mark_task_complete",
|
|
6171
|
+
"handoff_to_agent",
|
|
6172
|
+
"delegate_to_agent",
|
|
6173
|
+
"delegate_task",
|
|
6174
|
+
"get_tool_info",
|
|
6175
|
+
"get_tools",
|
|
6176
|
+
"list_tools",
|
|
6177
|
+
"call_tool",
|
|
6178
|
+
"invoke_tool",
|
|
6179
|
+
"execute_tool",
|
|
6180
|
+
"check_task_status",
|
|
6181
|
+
"assign_task",
|
|
6182
|
+
"update_plan",
|
|
6183
|
+
"check_delegations"
|
|
6184
|
+
]);
|
|
6185
|
+
function isInternalTool(toolName) {
|
|
6186
|
+
if (!toolName) return false;
|
|
6187
|
+
const lower = toolName.toLowerCase();
|
|
6188
|
+
if (INTERNAL_TOOL_NAMES.has(lower)) return true;
|
|
6189
|
+
for (const internal of INTERNAL_TOOL_NAMES) {
|
|
6190
|
+
if (lower.endsWith(internal) && lower.length > internal.length) {
|
|
6191
|
+
const charBefore = lower[lower.length - internal.length - 1];
|
|
6192
|
+
if (charBefore === "_" || charBefore === ".") return true;
|
|
6193
|
+
}
|
|
6194
|
+
}
|
|
6195
|
+
return false;
|
|
6196
|
+
}
|
|
6197
|
+
function cn10(...classes) {
|
|
5511
6198
|
return classes.filter(Boolean).join(" ");
|
|
5512
6199
|
}
|
|
5513
6200
|
function formatToolName(toolName) {
|
|
@@ -5556,7 +6243,7 @@ function formatToolName(toolName) {
|
|
|
5556
6243
|
}
|
|
5557
6244
|
return uniqueWords.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
5558
6245
|
}
|
|
5559
|
-
function
|
|
6246
|
+
function formatDuration2(ms) {
|
|
5560
6247
|
if (ms < 1e3) {
|
|
5561
6248
|
return `${ms}ms`;
|
|
5562
6249
|
}
|
|
@@ -5577,7 +6264,7 @@ function formatJsonPreview(data, maxLength = 100) {
|
|
|
5577
6264
|
return String(data);
|
|
5578
6265
|
}
|
|
5579
6266
|
}
|
|
5580
|
-
function
|
|
6267
|
+
function extractImagesFromResult2(result) {
|
|
5581
6268
|
if (!result) return [];
|
|
5582
6269
|
let data = result;
|
|
5583
6270
|
if (typeof result === "string") {
|
|
@@ -5612,7 +6299,8 @@ function ToolCallEntry({
|
|
|
5612
6299
|
toolCall,
|
|
5613
6300
|
className,
|
|
5614
6301
|
showFullJson = true,
|
|
5615
|
-
onImageClick
|
|
6302
|
+
onImageClick,
|
|
6303
|
+
compact = false
|
|
5616
6304
|
}) {
|
|
5617
6305
|
const [isExpanded, setIsExpanded] = react.useState(false);
|
|
5618
6306
|
const formattedName = react.useMemo(
|
|
@@ -5620,7 +6308,7 @@ function ToolCallEntry({
|
|
|
5620
6308
|
[toolCall.name]
|
|
5621
6309
|
);
|
|
5622
6310
|
const resultImages = react.useMemo(
|
|
5623
|
-
() => toolCall.status === "completed" && toolCall.result ?
|
|
6311
|
+
() => toolCall.status === "completed" && toolCall.result ? extractImagesFromResult2(toolCall.result) : [],
|
|
5624
6312
|
[toolCall.status, toolCall.result]
|
|
5625
6313
|
);
|
|
5626
6314
|
const hasImages = resultImages.length > 0;
|
|
@@ -5652,10 +6340,26 @@ function ToolCallEntry({
|
|
|
5652
6340
|
return "border-gray-200 dark:border-gray-700";
|
|
5653
6341
|
}
|
|
5654
6342
|
}, [toolCall.status]);
|
|
6343
|
+
if (compact && (toolCall.status === "completed" || toolCall.status === "failed")) {
|
|
6344
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6345
|
+
"div",
|
|
6346
|
+
{
|
|
6347
|
+
className: cn10(
|
|
6348
|
+
"inline-flex items-center gap-1.5 text-xs text-gray-500 dark:text-gray-400",
|
|
6349
|
+
className
|
|
6350
|
+
),
|
|
6351
|
+
children: [
|
|
6352
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: statusIcon }),
|
|
6353
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formattedName }),
|
|
6354
|
+
toolCall.durationMs !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400 dark:text-gray-500", children: formatDuration2(toolCall.durationMs) })
|
|
6355
|
+
]
|
|
6356
|
+
}
|
|
6357
|
+
);
|
|
6358
|
+
}
|
|
5655
6359
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5656
6360
|
"div",
|
|
5657
6361
|
{
|
|
5658
|
-
className:
|
|
6362
|
+
className: cn10(
|
|
5659
6363
|
"rounded-lg border text-sm",
|
|
5660
6364
|
statusColor,
|
|
5661
6365
|
className
|
|
@@ -5671,12 +6375,12 @@ function ToolCallEntry({
|
|
|
5671
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" }),
|
|
5672
6376
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: statusIcon }),
|
|
5673
6377
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-gray-900 dark:text-gray-100 truncate", children: formattedName }),
|
|
5674
|
-
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) }),
|
|
5675
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 })
|
|
5676
6380
|
]
|
|
5677
6381
|
}
|
|
5678
6382
|
),
|
|
5679
|
-
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(
|
|
5680
6384
|
"grid gap-2",
|
|
5681
6385
|
resultImages.length === 1 ? "grid-cols-1" : "grid-cols-2"
|
|
5682
6386
|
), children: resultImages.map((img, idx) => {
|
|
@@ -5735,21 +6439,28 @@ function ToolCallEntry({
|
|
|
5735
6439
|
}
|
|
5736
6440
|
);
|
|
5737
6441
|
}
|
|
5738
|
-
function
|
|
6442
|
+
function cn11(...classes) {
|
|
5739
6443
|
return classes.filter(Boolean).join(" ");
|
|
5740
6444
|
}
|
|
5741
6445
|
function ChatMessage({
|
|
5742
6446
|
message,
|
|
5743
6447
|
enableMarkdown = true,
|
|
5744
6448
|
showToolCalls = true,
|
|
6449
|
+
toolCallVerbosity: _toolCallVerbosity,
|
|
5745
6450
|
className,
|
|
5746
6451
|
markdownComponents,
|
|
5747
6452
|
markdownUrlTransform,
|
|
5748
6453
|
markdownContentTransform,
|
|
5749
|
-
onImageClick
|
|
6454
|
+
onImageClick,
|
|
6455
|
+
showThinking = true,
|
|
6456
|
+
showDelegation = true,
|
|
6457
|
+
showImages = true,
|
|
6458
|
+
renderToolCall,
|
|
6459
|
+
variant = "bubble"
|
|
5750
6460
|
}) {
|
|
5751
6461
|
const isUser = message.role === "user";
|
|
5752
6462
|
const isAssistant = message.role === "assistant";
|
|
6463
|
+
const isFlat = variant === "flat";
|
|
5753
6464
|
const formattedTime = react.useMemo(() => {
|
|
5754
6465
|
const date = message.timestamp instanceof Date ? message.timestamp : new Date(message.timestamp);
|
|
5755
6466
|
return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
@@ -5757,85 +6468,124 @@ function ChatMessage({
|
|
|
5757
6468
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5758
6469
|
"div",
|
|
5759
6470
|
{
|
|
5760
|
-
className:
|
|
5761
|
-
"flex gap-3
|
|
5762
|
-
|
|
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",
|
|
5763
6478
|
className
|
|
5764
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,
|
|
5765
6484
|
children: [
|
|
5766
6485
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5767
6486
|
"div",
|
|
5768
6487
|
{
|
|
5769
|
-
className:
|
|
5770
|
-
|
|
5771
|
-
isUser ? "
|
|
5772
|
-
|
|
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
|
+
},
|
|
5773
6493
|
children: isUser ? /* @__PURE__ */ jsxRuntime.jsx(UserIcon, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(BotIcon, { className: "h-4 w-4" })
|
|
5774
6494
|
}
|
|
5775
6495
|
),
|
|
5776
6496
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5777
6497
|
"div",
|
|
5778
6498
|
{
|
|
5779
|
-
className:
|
|
5780
|
-
"flex-1 min-w-0
|
|
5781
|
-
|
|
6499
|
+
className: cn11(
|
|
6500
|
+
"flex-1 min-w-0",
|
|
6501
|
+
isFlat ? "pt-0.5" : "space-y-2",
|
|
6502
|
+
!isFlat && isUser ? "text-right" : "text-left"
|
|
5782
6503
|
),
|
|
5783
6504
|
children: [
|
|
5784
6505
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5785
6506
|
"div",
|
|
5786
6507
|
{
|
|
5787
|
-
className:
|
|
5788
|
-
"flex items-center gap-2 text-xs
|
|
5789
|
-
|
|
6508
|
+
className: cn11(
|
|
6509
|
+
"flex items-center gap-2 text-xs",
|
|
6510
|
+
isFlat ? "mb-1.5" : "",
|
|
6511
|
+
!isFlat && isUser ? "justify-end" : "justify-start"
|
|
5790
6512
|
),
|
|
6513
|
+
style: { color: "var(--chat-meta-text, #6b7280)" },
|
|
5791
6514
|
children: [
|
|
5792
|
-
/* @__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" }),
|
|
5793
6516
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formattedTime }),
|
|
5794
6517
|
message.isStreaming && /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, { className: "h-3 w-3" })
|
|
5795
6518
|
]
|
|
5796
6519
|
}
|
|
5797
6520
|
),
|
|
5798
|
-
message.thinkingBlocks && message.thinkingBlocks.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
)) }),
|
|
5817
|
-
message.content && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5818
|
-
"div",
|
|
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(
|
|
6525
|
+
ToolCallEntry,
|
|
6526
|
+
{
|
|
6527
|
+
toolCall,
|
|
6528
|
+
onImageClick
|
|
6529
|
+
},
|
|
6530
|
+
toolCall.id
|
|
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,
|
|
5819
6539
|
{
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
isUser ? "bg-blue-500 text-white" : "bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-gray-100"
|
|
5823
|
-
),
|
|
5824
|
-
children: isAssistant && enableMarkdown ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5825
|
-
MarkdownContent,
|
|
5826
|
-
{
|
|
5827
|
-
content: message.content,
|
|
5828
|
-
components: markdownComponents,
|
|
5829
|
-
urlTransform: markdownUrlTransform,
|
|
5830
|
-
contentTransform: markdownContentTransform
|
|
5831
|
-
}
|
|
5832
|
-
) : /* @__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
|
|
5833
6542
|
}
|
|
5834
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
|
+
)),
|
|
5835
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(
|
|
5836
6585
|
"div",
|
|
5837
6586
|
{
|
|
5838
|
-
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)" },
|
|
5839
6589
|
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate max-w-[150px]", children: attachment.filename })
|
|
5840
6590
|
},
|
|
5841
6591
|
attachment.uuid
|
|
@@ -5847,7 +6597,7 @@ function ChatMessage({
|
|
|
5847
6597
|
}
|
|
5848
6598
|
);
|
|
5849
6599
|
}
|
|
5850
|
-
function
|
|
6600
|
+
function cn12(...classes) {
|
|
5851
6601
|
return classes.filter(Boolean).join(" ");
|
|
5852
6602
|
}
|
|
5853
6603
|
function MessageList({
|
|
@@ -5859,11 +6609,18 @@ function MessageList({
|
|
|
5859
6609
|
isLoadingHistory = false,
|
|
5860
6610
|
enableMarkdown = true,
|
|
5861
6611
|
showToolCalls = true,
|
|
6612
|
+
toolCallVerbosity,
|
|
5862
6613
|
className,
|
|
5863
6614
|
markdownComponents,
|
|
5864
6615
|
markdownUrlTransform,
|
|
5865
6616
|
markdownContentTransform,
|
|
5866
6617
|
onImageClick,
|
|
6618
|
+
showThinking = true,
|
|
6619
|
+
showDelegation = true,
|
|
6620
|
+
showImages = true,
|
|
6621
|
+
renderMessage,
|
|
6622
|
+
renderToolCall,
|
|
6623
|
+
messageVariant = "bubble",
|
|
5867
6624
|
sendMessage
|
|
5868
6625
|
}) {
|
|
5869
6626
|
const scrollRef = react.useRef(null);
|
|
@@ -5877,7 +6634,7 @@ function MessageList({
|
|
|
5877
6634
|
"div",
|
|
5878
6635
|
{
|
|
5879
6636
|
ref: scrollRef,
|
|
5880
|
-
className:
|
|
6637
|
+
className: cn12(
|
|
5881
6638
|
"flex-1 overflow-y-auto",
|
|
5882
6639
|
className
|
|
5883
6640
|
),
|
|
@@ -5888,19 +6645,31 @@ function MessageList({
|
|
|
5888
6645
|
] }) }),
|
|
5889
6646
|
messages.length === 0 && !isLoading && !isLoadingHistory && (renderWelcome ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: typeof renderWelcome === "function" ? renderWelcome({ sendMessage: sendMessage || (() => {
|
|
5890
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 }) }) })),
|
|
5891
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-gray-100 dark:divide-gray-800", children: messages.map((message) =>
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
|
|
5899
|
-
|
|
5900
|
-
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
|
|
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
|
+
}) }),
|
|
5904
6673
|
isLoading && !isStreaming && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 p-4", children: [
|
|
5905
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" }) }),
|
|
5906
6675
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-gray-500 dark:text-gray-400", children: "Thinking..." })
|
|
@@ -5956,13 +6725,28 @@ function AgentChat({
|
|
|
5956
6725
|
maxHeight = "600px",
|
|
5957
6726
|
className,
|
|
5958
6727
|
theme = "system",
|
|
6728
|
+
layout = "fixed",
|
|
5959
6729
|
enableAttachments = false,
|
|
5960
6730
|
enableMarkdown = true,
|
|
5961
6731
|
showToolCalls = true,
|
|
6732
|
+
toolCallVerbosity,
|
|
5962
6733
|
markdownComponents,
|
|
5963
6734
|
markdownUrlTransform,
|
|
5964
6735
|
markdownContentTransform,
|
|
5965
|
-
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
|
|
5966
6750
|
}) {
|
|
5967
6751
|
const {
|
|
5968
6752
|
messages,
|
|
@@ -5989,8 +6773,12 @@ function AgentChat({
|
|
|
5989
6773
|
onSessionStart,
|
|
5990
6774
|
onToolCall,
|
|
5991
6775
|
onToolResult,
|
|
5992
|
-
onClarification
|
|
6776
|
+
onClarification,
|
|
6777
|
+
onDelegation,
|
|
6778
|
+
pollingInterval,
|
|
6779
|
+
pollingEnabled
|
|
5993
6780
|
});
|
|
6781
|
+
const effectiveVerbosity = showToolCalls === false ? "hidden" : toolCallVerbosity ?? "compact";
|
|
5994
6782
|
const dropZoneRef = react.useRef(null);
|
|
5995
6783
|
const attachments = useFileAttachments({
|
|
5996
6784
|
onUpload: enableAttachments && adapter ? async (_file, meta) => {
|
|
@@ -6017,50 +6805,31 @@ function AgentChat({
|
|
|
6017
6805
|
},
|
|
6018
6806
|
[enableAttachments, attachments, sendMessage]
|
|
6019
6807
|
);
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
}
|
|
6046
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
6047
|
-
MessageList,
|
|
6048
|
-
{
|
|
6049
|
-
messages,
|
|
6050
|
-
welcomeMessage,
|
|
6051
|
-
renderWelcome,
|
|
6052
|
-
isLoading,
|
|
6053
|
-
isStreaming,
|
|
6054
|
-
isLoadingHistory,
|
|
6055
|
-
enableMarkdown,
|
|
6056
|
-
showToolCalls,
|
|
6057
|
-
markdownComponents,
|
|
6058
|
-
markdownUrlTransform,
|
|
6059
|
-
markdownContentTransform,
|
|
6060
|
-
onImageClick,
|
|
6061
|
-
sendMessage: handleSend
|
|
6062
|
-
}
|
|
6063
|
-
),
|
|
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?.(),
|
|
6064
6833
|
clarification && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-gray-200 dark:border-gray-700 p-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6065
6834
|
AskUserPrompt,
|
|
6066
6835
|
{
|
|
@@ -6070,6 +6839,7 @@ function AgentChat({
|
|
|
6070
6839
|
}
|
|
6071
6840
|
) }),
|
|
6072
6841
|
error && /* @__PURE__ */ jsxRuntime.jsx(ErrorBanner, { error, onRetry: retry, onDismiss: clearError }),
|
|
6842
|
+
renderAboveInput?.(),
|
|
6073
6843
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6074
6844
|
ChatInput,
|
|
6075
6845
|
{
|
|
@@ -6086,8 +6856,17 @@ function AgentChat({
|
|
|
6086
6856
|
}
|
|
6087
6857
|
)
|
|
6088
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 });
|
|
6089
6868
|
}
|
|
6090
|
-
function
|
|
6869
|
+
function cn13(...classes) {
|
|
6091
6870
|
return classes.filter(Boolean).join(" ");
|
|
6092
6871
|
}
|
|
6093
6872
|
function TodoList({
|
|
@@ -6116,7 +6895,7 @@ function TodoList({
|
|
|
6116
6895
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6117
6896
|
"div",
|
|
6118
6897
|
{
|
|
6119
|
-
className:
|
|
6898
|
+
className: cn13(
|
|
6120
6899
|
"rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden",
|
|
6121
6900
|
className
|
|
6122
6901
|
),
|
|
@@ -6124,7 +6903,7 @@ function TodoList({
|
|
|
6124
6903
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6125
6904
|
"div",
|
|
6126
6905
|
{
|
|
6127
|
-
className:
|
|
6906
|
+
className: cn13(
|
|
6128
6907
|
"flex items-center gap-2 px-3 py-2 bg-gray-50 dark:bg-gray-800/50",
|
|
6129
6908
|
collapsible && "cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800"
|
|
6130
6909
|
),
|
|
@@ -6155,7 +6934,7 @@ function TodoList({
|
|
|
6155
6934
|
!isCollapsed && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "divide-y divide-gray-100 dark:divide-gray-700", children: todos.map((todo, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6156
6935
|
"li",
|
|
6157
6936
|
{
|
|
6158
|
-
className:
|
|
6937
|
+
className: cn13(
|
|
6159
6938
|
"px-3 py-2 flex items-start gap-2 text-sm",
|
|
6160
6939
|
todo.status === "in_progress" && "bg-blue-50/50 dark:bg-blue-950/20",
|
|
6161
6940
|
todo.status === "completed" && "opacity-60"
|
|
@@ -6165,7 +6944,7 @@ function TodoList({
|
|
|
6165
6944
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6166
6945
|
"p",
|
|
6167
6946
|
{
|
|
6168
|
-
className:
|
|
6947
|
+
className: cn13(
|
|
6169
6948
|
"text-gray-700 dark:text-gray-300",
|
|
6170
6949
|
todo.status === "completed" && "line-through"
|
|
6171
6950
|
),
|
|
@@ -6182,39 +6961,6 @@ function TodoList({
|
|
|
6182
6961
|
);
|
|
6183
6962
|
}
|
|
6184
6963
|
|
|
6185
|
-
// src/chat/index.ts
|
|
6186
|
-
var DEPRECATION_WARNING = `
|
|
6187
|
-
[@cadraos/sdk/chat] DEPRECATION WARNING
|
|
6188
|
-
|
|
6189
|
-
This module is deprecated and will be removed in a future version.
|
|
6190
|
-
Please migrate to @cadraos/react for:
|
|
6191
|
-
- Simpler setup with CadraCopilot
|
|
6192
|
-
- Better security (header-based SSE auth)
|
|
6193
|
-
- Scoped CSS that won't conflict with your app
|
|
6194
|
-
|
|
6195
|
-
Migration steps:
|
|
6196
|
-
1. npm install @cadraos/react
|
|
6197
|
-
2. import '@cadraos/react/styles.css'
|
|
6198
|
-
3. Replace <AgentChat> with <CadraCopilot> or <CadraChat>
|
|
6199
|
-
|
|
6200
|
-
See: https://github.com/cadraos/cadra-sdk/blob/main/packages/react/MIGRATION.md
|
|
6201
|
-
`;
|
|
6202
|
-
var hasWarned = false;
|
|
6203
|
-
function showDeprecationWarning() {
|
|
6204
|
-
if (hasWarned) return;
|
|
6205
|
-
hasWarned = true;
|
|
6206
|
-
if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") {
|
|
6207
|
-
return;
|
|
6208
|
-
}
|
|
6209
|
-
if (typeof window === "undefined") {
|
|
6210
|
-
return;
|
|
6211
|
-
}
|
|
6212
|
-
console.warn(DEPRECATION_WARNING);
|
|
6213
|
-
}
|
|
6214
|
-
if (typeof window !== "undefined") {
|
|
6215
|
-
setTimeout(showDeprecationWarning, 0);
|
|
6216
|
-
}
|
|
6217
|
-
|
|
6218
6964
|
exports.AgentChat = AgentChat;
|
|
6219
6965
|
exports.AlertCircleIcon = AlertCircleIcon;
|
|
6220
6966
|
exports.AskUserPrompt = AskUserPrompt;
|
|
@@ -6233,13 +6979,18 @@ exports.ClockIcon = ClockIcon;
|
|
|
6233
6979
|
exports.CodeIcon = CodeIcon;
|
|
6234
6980
|
exports.CopyIcon = CopyIcon;
|
|
6235
6981
|
exports.DatabaseIcon = DatabaseIcon;
|
|
6982
|
+
exports.DelegationProgress = DelegationProgress;
|
|
6983
|
+
exports.DelegationProgressList = DelegationProgressList;
|
|
6236
6984
|
exports.DownloadIcon = DownloadIcon;
|
|
6237
6985
|
exports.ExternalLinkIcon = ExternalLinkIcon;
|
|
6238
6986
|
exports.FileDropZone = FileDropZone;
|
|
6239
6987
|
exports.FileIcon = FileIcon;
|
|
6240
6988
|
exports.FileTextIcon = FileTextIcon;
|
|
6241
6989
|
exports.HelpCircleIcon = HelpCircleIcon;
|
|
6990
|
+
exports.INTERNAL_TOOL_NAMES = INTERNAL_TOOL_NAMES;
|
|
6991
|
+
exports.ImageGallery = ImageGallery;
|
|
6242
6992
|
exports.ImageIcon = ImageIcon;
|
|
6993
|
+
exports.ImageLightbox = ImageLightbox;
|
|
6243
6994
|
exports.ImagesIcon = ImagesIcon;
|
|
6244
6995
|
exports.ListTodoIcon = ListTodoIcon;
|
|
6245
6996
|
exports.LoadingSpinner = LoadingSpinner;
|
|
@@ -6252,6 +7003,8 @@ exports.PaperclipIcon = PaperclipIcon;
|
|
|
6252
7003
|
exports.SendIcon = SendIcon;
|
|
6253
7004
|
exports.SparklesIcon = SparklesIcon;
|
|
6254
7005
|
exports.StopCircleIcon = StopCircleIcon;
|
|
7006
|
+
exports.ThinkingBlock = ThinkingBlock;
|
|
7007
|
+
exports.ThinkingBlockList = ThinkingBlockList;
|
|
6255
7008
|
exports.TodoList = TodoList;
|
|
6256
7009
|
exports.ToolCallEntry = ToolCallEntry;
|
|
6257
7010
|
exports.UserIcon = UserIcon;
|
|
@@ -6260,6 +7013,7 @@ exports.ZoomInIcon = ZoomInIcon;
|
|
|
6260
7013
|
exports.ZoomOutIcon = ZoomOutIcon;
|
|
6261
7014
|
exports.compressImage = compressImage;
|
|
6262
7015
|
exports.createDefaultAdapter = createDefaultAdapter;
|
|
7016
|
+
exports.isInternalTool = isInternalTool;
|
|
6263
7017
|
exports.useAgentChat = useAgentChat;
|
|
6264
7018
|
exports.useChatConfig = useChatConfig;
|
|
6265
7019
|
exports.useChatConfigOptional = useChatConfigOptional;
|