dooers-agents-client 0.14.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.cjs +190 -3
- package/dist/main.cjs.map +1 -1
- package/dist/main.d.cts +54 -2
- package/dist/main.d.ts +54 -2
- package/dist/main.js +186 -4
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -211,6 +211,20 @@ function toThreadEvent(w) {
|
|
|
211
211
|
clientEventId: w.client_event_id
|
|
212
212
|
};
|
|
213
213
|
}
|
|
214
|
+
function toThreadArtifact(w) {
|
|
215
|
+
return {
|
|
216
|
+
eventId: w.event_id,
|
|
217
|
+
direction: w.direction,
|
|
218
|
+
kind: w.kind,
|
|
219
|
+
filename: w.filename,
|
|
220
|
+
mimeType: w.mime_type,
|
|
221
|
+
url: w.url,
|
|
222
|
+
refId: w.ref_id,
|
|
223
|
+
createdAt: w.created_at,
|
|
224
|
+
userId: w.user_id,
|
|
225
|
+
userName: w.user_name
|
|
226
|
+
};
|
|
227
|
+
}
|
|
214
228
|
function toRun(w) {
|
|
215
229
|
return {
|
|
216
230
|
id: w.id,
|
|
@@ -308,12 +322,13 @@ function toWireContentPart(p) {
|
|
|
308
322
|
}
|
|
309
323
|
|
|
310
324
|
// src/version.ts
|
|
311
|
-
var PACKAGE_VERSION = "0.
|
|
325
|
+
var PACKAGE_VERSION = "0.15.1";
|
|
312
326
|
|
|
313
327
|
// src/client.ts
|
|
314
328
|
var MAX_RECONNECT_ATTEMPTS = 5;
|
|
315
329
|
var RECONNECT_DELAYS = [1e3, 2e3, 4e3, 8e3, 16e3];
|
|
316
330
|
var SEND_MESSAGE_TIMEOUT = 3e4;
|
|
331
|
+
var ARTIFACTS_LIST_TIMEOUT = 5e3;
|
|
317
332
|
var PING_INTERVAL_MS = 3e4;
|
|
318
333
|
function blobPartFilename(blob, override) {
|
|
319
334
|
const o = (override ?? "").trim();
|
|
@@ -467,6 +482,7 @@ var AgentClient = class {
|
|
|
467
482
|
pendingOptimistic = /* @__PURE__ */ new Map();
|
|
468
483
|
// Pending message promises — keyed by outbound frame id (same as client_event_id for sends).
|
|
469
484
|
pendingMessages = /* @__PURE__ */ new Map();
|
|
485
|
+
pendingArtifactsRequests = /* @__PURE__ */ new Map();
|
|
470
486
|
// Track last event ID per thread for gap recovery on reconnect
|
|
471
487
|
lastEventIds = /* @__PURE__ */ new Map();
|
|
472
488
|
// Pagination
|
|
@@ -604,6 +620,13 @@ var AgentClient = class {
|
|
|
604
620
|
}
|
|
605
621
|
this.pendingMessages.clear();
|
|
606
622
|
}
|
|
623
|
+
abortPendingArtifacts(reason) {
|
|
624
|
+
for (const [frameId, pending] of this.pendingArtifactsRequests) {
|
|
625
|
+
clearTimeout(pending.timer);
|
|
626
|
+
this.pendingArtifactsRequests.delete(frameId);
|
|
627
|
+
pending.reject(new Error(reason));
|
|
628
|
+
}
|
|
629
|
+
}
|
|
607
630
|
disconnect() {
|
|
608
631
|
this.isIntentionallyClosed = true;
|
|
609
632
|
this.stopHeartbeat();
|
|
@@ -612,6 +635,7 @@ var AgentClient = class {
|
|
|
612
635
|
this.reconnectTimer = null;
|
|
613
636
|
}
|
|
614
637
|
this.abortPendingMessages("Disconnected");
|
|
638
|
+
this.abortPendingArtifacts("Disconnected");
|
|
615
639
|
if (this.ws) {
|
|
616
640
|
this.ws.onopen = null;
|
|
617
641
|
this.ws.onmessage = null;
|
|
@@ -670,6 +694,40 @@ var AgentClient = class {
|
|
|
670
694
|
limit
|
|
671
695
|
});
|
|
672
696
|
}
|
|
697
|
+
requestThreadArtifactsList(threadId, options) {
|
|
698
|
+
if (!this.isConnected()) {
|
|
699
|
+
return Promise.reject(new Error("Not connected"));
|
|
700
|
+
}
|
|
701
|
+
const frameId = crypto.randomUUID();
|
|
702
|
+
return new Promise((resolve, reject) => {
|
|
703
|
+
const timer = setTimeout(() => {
|
|
704
|
+
this.pendingArtifactsRequests.delete(frameId);
|
|
705
|
+
reject(new Error("thread.artifacts.list timed out"));
|
|
706
|
+
}, ARTIFACTS_LIST_TIMEOUT);
|
|
707
|
+
this.pendingArtifactsRequests.set(frameId, {
|
|
708
|
+
threadId,
|
|
709
|
+
resolve: (value) => {
|
|
710
|
+
clearTimeout(timer);
|
|
711
|
+
resolve(value);
|
|
712
|
+
},
|
|
713
|
+
reject: (err) => {
|
|
714
|
+
clearTimeout(timer);
|
|
715
|
+
reject(err);
|
|
716
|
+
},
|
|
717
|
+
timer
|
|
718
|
+
});
|
|
719
|
+
this.sendRaw({
|
|
720
|
+
id: frameId,
|
|
721
|
+
type: "thread.artifacts.list",
|
|
722
|
+
payload: {
|
|
723
|
+
thread_id: threadId,
|
|
724
|
+
cursor: options?.cursor ?? null,
|
|
725
|
+
limit: options?.limit,
|
|
726
|
+
direction: options?.direction ?? "all"
|
|
727
|
+
}
|
|
728
|
+
});
|
|
729
|
+
});
|
|
730
|
+
}
|
|
673
731
|
// --- Settings ---
|
|
674
732
|
subscribeSettings(options) {
|
|
675
733
|
const audience = options?.audience ?? "user";
|
|
@@ -883,6 +941,8 @@ var AgentClient = class {
|
|
|
883
941
|
case "ack": {
|
|
884
942
|
if (frame.payload.ack_id === this.connectFrameId) {
|
|
885
943
|
if (frame.payload.ok) {
|
|
944
|
+
const sv = frame.payload.server?.version?.trim();
|
|
945
|
+
this.callbacks.setServerVersion(sv || null);
|
|
886
946
|
this.callbacks.setConnectionStatus("connected");
|
|
887
947
|
this.callbacks.resetReconnect();
|
|
888
948
|
this.requestThreadList();
|
|
@@ -915,6 +975,13 @@ var AgentClient = class {
|
|
|
915
975
|
pending.reject(new Error(msg));
|
|
916
976
|
this.callbacks.setSendError(msg);
|
|
917
977
|
}
|
|
978
|
+
const artifactsPending = this.pendingArtifactsRequests.get(ackId);
|
|
979
|
+
if (artifactsPending) {
|
|
980
|
+
clearTimeout(artifactsPending.timer);
|
|
981
|
+
this.pendingArtifactsRequests.delete(ackId);
|
|
982
|
+
const msg = err.message || "Request rejected";
|
|
983
|
+
artifactsPending.reject(new Error(msg));
|
|
984
|
+
}
|
|
918
985
|
}
|
|
919
986
|
this.onError?.({
|
|
920
987
|
code: err.code,
|
|
@@ -999,6 +1066,21 @@ var AgentClient = class {
|
|
|
999
1066
|
);
|
|
1000
1067
|
break;
|
|
1001
1068
|
}
|
|
1069
|
+
case "thread.artifacts.list.result": {
|
|
1070
|
+
const threadId = frame.payload.thread_id;
|
|
1071
|
+
for (const [frameId, pending] of this.pendingArtifactsRequests) {
|
|
1072
|
+
if (pending.threadId !== threadId) continue;
|
|
1073
|
+
clearTimeout(pending.timer);
|
|
1074
|
+
this.pendingArtifactsRequests.delete(frameId);
|
|
1075
|
+
pending.resolve({
|
|
1076
|
+
artifacts: this.resolveArtifactUrls(frame.payload.artifacts.map(toThreadArtifact)),
|
|
1077
|
+
cursor: frame.payload.cursor,
|
|
1078
|
+
hasMore: frame.payload.has_more
|
|
1079
|
+
});
|
|
1080
|
+
break;
|
|
1081
|
+
}
|
|
1082
|
+
break;
|
|
1083
|
+
}
|
|
1002
1084
|
case "thread.upsert":
|
|
1003
1085
|
this.callbacks.onThreadUpsert(toThread(frame.payload.thread));
|
|
1004
1086
|
break;
|
|
@@ -1060,6 +1142,7 @@ var AgentClient = class {
|
|
|
1060
1142
|
this.stopHeartbeat();
|
|
1061
1143
|
if (this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
|
1062
1144
|
this.abortPendingMessages("Connection lost after maximum retries");
|
|
1145
|
+
this.abortPendingArtifacts("Connection lost after maximum retries");
|
|
1063
1146
|
this.callbacks.setReconnectFailed();
|
|
1064
1147
|
this.callbacks.setConnectionStatus("error", "Connection lost after maximum retries");
|
|
1065
1148
|
return;
|
|
@@ -1104,7 +1187,38 @@ var AgentClient = class {
|
|
|
1104
1187
|
};
|
|
1105
1188
|
});
|
|
1106
1189
|
}
|
|
1190
|
+
resolveArtifactUrls(artifacts) {
|
|
1191
|
+
if (!this.httpBaseUrl) return artifacts;
|
|
1192
|
+
const base = this.httpBaseUrl;
|
|
1193
|
+
return artifacts.map((artifact) => {
|
|
1194
|
+
if (!artifact.url?.startsWith("/")) return artifact;
|
|
1195
|
+
return { ...artifact, url: `${base}${artifact.url}` };
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1107
1198
|
};
|
|
1199
|
+
|
|
1200
|
+
// src/helpers/server-version.ts
|
|
1201
|
+
var THREAD_ARTIFACTS_MIN_SERVER_VERSION = "0.17.1";
|
|
1202
|
+
function parseSemverParts(version) {
|
|
1203
|
+
const core = version.trim().split("-")[0]?.split("+")[0] ?? "";
|
|
1204
|
+
const [maj, min, pat] = core.split(".");
|
|
1205
|
+
return [Number(maj) || 0, Number(min) || 0, Number(pat) || 0];
|
|
1206
|
+
}
|
|
1207
|
+
function compareSemver(a, b) {
|
|
1208
|
+
const [aMaj, aMin, aPat] = parseSemverParts(a);
|
|
1209
|
+
const [bMaj, bMin, bPat] = parseSemverParts(b);
|
|
1210
|
+
if (aMaj !== bMaj) return aMaj < bMaj ? -1 : 1;
|
|
1211
|
+
if (aMin !== bMin) return aMin < bMin ? -1 : 1;
|
|
1212
|
+
if (aPat !== bPat) return aPat < bPat ? -1 : 1;
|
|
1213
|
+
return 0;
|
|
1214
|
+
}
|
|
1215
|
+
function isServerAtLeast(version, minimum) {
|
|
1216
|
+
if (!version?.trim()) return false;
|
|
1217
|
+
return compareSemver(version, minimum) >= 0;
|
|
1218
|
+
}
|
|
1219
|
+
function supportsThreadArtifactsList(serverVersion) {
|
|
1220
|
+
return isServerAtLeast(serverVersion, THREAD_ARTIFACTS_MIN_SERVER_VERSION);
|
|
1221
|
+
}
|
|
1108
1222
|
function mergeDisplayContentParts(prev, next) {
|
|
1109
1223
|
if (!next?.length) return prev;
|
|
1110
1224
|
if (!prev?.length) return next;
|
|
@@ -1164,6 +1278,7 @@ function createAgentStore() {
|
|
|
1164
1278
|
connection: {
|
|
1165
1279
|
status: "idle",
|
|
1166
1280
|
error: null,
|
|
1281
|
+
serverVersion: null,
|
|
1167
1282
|
sendError: null,
|
|
1168
1283
|
reconnectAttempts: 0,
|
|
1169
1284
|
reconnectFailed: false
|
|
@@ -1197,9 +1312,13 @@ function createAgentStore() {
|
|
|
1197
1312
|
...s.connection,
|
|
1198
1313
|
status,
|
|
1199
1314
|
error: error ?? null,
|
|
1200
|
-
...status === "connected" ? { sendError: null } : {}
|
|
1315
|
+
...status === "connected" ? { sendError: null } : {},
|
|
1316
|
+
...status === "connecting" ? { serverVersion: null } : {}
|
|
1201
1317
|
}
|
|
1202
1318
|
})),
|
|
1319
|
+
setServerVersion: (version) => set((s) => ({
|
|
1320
|
+
connection: { ...s.connection, serverVersion: version }
|
|
1321
|
+
})),
|
|
1203
1322
|
setSendError: (message) => set((s) => ({
|
|
1204
1323
|
connection: { ...s.connection, sendError: message }
|
|
1205
1324
|
})),
|
|
@@ -1756,13 +1875,22 @@ function useConnection() {
|
|
|
1756
1875
|
const { client } = useAgentContext();
|
|
1757
1876
|
const status = useStore((s) => s.connection.status);
|
|
1758
1877
|
const error = useStore((s) => s.connection.error);
|
|
1878
|
+
const serverVersion = useStore((s) => s.connection.serverVersion);
|
|
1759
1879
|
const sendError = useStore((s) => s.connection.sendError);
|
|
1760
1880
|
const reconnectFailed = useStore((s) => s.connection.reconnectFailed);
|
|
1761
1881
|
const reconnect = react.useCallback(() => client.retry(), [client]);
|
|
1762
1882
|
const dismissSendError = react.useCallback(() => {
|
|
1763
1883
|
client.clearSendError();
|
|
1764
1884
|
}, [client]);
|
|
1765
|
-
return {
|
|
1885
|
+
return {
|
|
1886
|
+
status,
|
|
1887
|
+
error,
|
|
1888
|
+
serverVersion,
|
|
1889
|
+
sendError,
|
|
1890
|
+
dismissSendError,
|
|
1891
|
+
reconnectFailed,
|
|
1892
|
+
reconnect
|
|
1893
|
+
};
|
|
1766
1894
|
}
|
|
1767
1895
|
function useFeedback(targetId, targetType = "event") {
|
|
1768
1896
|
const { client } = useAgentContext();
|
|
@@ -2025,6 +2153,60 @@ function useThreadEvents(threadId) {
|
|
|
2025
2153
|
);
|
|
2026
2154
|
return { hasOlderEvents, loadOlderEvents };
|
|
2027
2155
|
}
|
|
2156
|
+
function useThreadArtifacts(threadId, options) {
|
|
2157
|
+
const { client } = useAgentContext();
|
|
2158
|
+
const direction = options?.direction ?? "all";
|
|
2159
|
+
const enabled = options?.enabled !== false;
|
|
2160
|
+
const limit = options?.limit;
|
|
2161
|
+
const [artifacts, setArtifacts] = react.useState([]);
|
|
2162
|
+
const [cursor, setCursor] = react.useState(null);
|
|
2163
|
+
const [hasMore, setHasMore] = react.useState(false);
|
|
2164
|
+
const [isLoading, setIsLoading] = react.useState(false);
|
|
2165
|
+
const [error, setError] = react.useState(null);
|
|
2166
|
+
const cursorRef = react.useRef(null);
|
|
2167
|
+
const load = react.useCallback(
|
|
2168
|
+
async (append) => {
|
|
2169
|
+
if (!threadId) return;
|
|
2170
|
+
setIsLoading(true);
|
|
2171
|
+
setError(null);
|
|
2172
|
+
try {
|
|
2173
|
+
const result = await client.requestThreadArtifactsList(threadId, {
|
|
2174
|
+
cursor: append ? cursorRef.current : null,
|
|
2175
|
+
limit,
|
|
2176
|
+
direction
|
|
2177
|
+
});
|
|
2178
|
+
cursorRef.current = result.cursor;
|
|
2179
|
+
setCursor(result.cursor);
|
|
2180
|
+
setHasMore(result.hasMore);
|
|
2181
|
+
setArtifacts((prev) => append ? [...prev, ...result.artifacts] : result.artifacts);
|
|
2182
|
+
} catch (err) {
|
|
2183
|
+
setError(err instanceof Error ? err.message : "Failed to load artifacts");
|
|
2184
|
+
} finally {
|
|
2185
|
+
setIsLoading(false);
|
|
2186
|
+
}
|
|
2187
|
+
},
|
|
2188
|
+
[threadId, client, limit, direction]
|
|
2189
|
+
);
|
|
2190
|
+
react.useEffect(() => {
|
|
2191
|
+
if (!threadId || !enabled) {
|
|
2192
|
+
setArtifacts([]);
|
|
2193
|
+
setCursor(null);
|
|
2194
|
+
cursorRef.current = null;
|
|
2195
|
+
setHasMore(false);
|
|
2196
|
+
setError(null);
|
|
2197
|
+
return;
|
|
2198
|
+
}
|
|
2199
|
+
void load(false);
|
|
2200
|
+
}, [threadId, enabled, direction, load]);
|
|
2201
|
+
const loadMore = react.useCallback(() => {
|
|
2202
|
+
if (!hasMore || isLoading) return;
|
|
2203
|
+
void load(true);
|
|
2204
|
+
}, [hasMore, isLoading, load]);
|
|
2205
|
+
const refresh = react.useCallback(() => {
|
|
2206
|
+
void load(false);
|
|
2207
|
+
}, [load]);
|
|
2208
|
+
return { artifacts, cursor, hasMore, isLoading, error, loadMore, refresh };
|
|
2209
|
+
}
|
|
2028
2210
|
function useThreadsList() {
|
|
2029
2211
|
const threadOrder = useStore((s) => s.threadOrder);
|
|
2030
2212
|
const threadMap = useStore((s) => s.threads);
|
|
@@ -2071,8 +2253,12 @@ function useUpload() {
|
|
|
2071
2253
|
exports.AgentProvider = AgentProvider;
|
|
2072
2254
|
exports.AgentServerClient = AgentServerClient;
|
|
2073
2255
|
exports.PACKAGE_VERSION = PACKAGE_VERSION;
|
|
2256
|
+
exports.THREAD_ARTIFACTS_MIN_SERVER_VERSION = THREAD_ARTIFACTS_MIN_SERVER_VERSION;
|
|
2074
2257
|
exports.apiMessagesUrlToWebSocketUrl = apiMessagesUrlToWebSocketUrl;
|
|
2258
|
+
exports.compareSemver = compareSemver;
|
|
2259
|
+
exports.isServerAtLeast = isServerAtLeast;
|
|
2075
2260
|
exports.isSettingsFieldGroup = isSettingsFieldGroup;
|
|
2261
|
+
exports.supportsThreadArtifactsList = supportsThreadArtifactsList;
|
|
2076
2262
|
exports.toChartEventData = toChartEventData;
|
|
2077
2263
|
exports.toFormElement = toFormElement;
|
|
2078
2264
|
exports.toFormEventData = toFormEventData;
|
|
@@ -2087,6 +2273,7 @@ exports.useFormFileUpload = useFormFileUpload;
|
|
|
2087
2273
|
exports.useMessage = useMessage;
|
|
2088
2274
|
exports.useSettings = useSettings;
|
|
2089
2275
|
exports.useSettingsFileUpload = useSettingsFileUpload;
|
|
2276
|
+
exports.useThreadArtifacts = useThreadArtifacts;
|
|
2090
2277
|
exports.useThreadDetails = useThreadDetails;
|
|
2091
2278
|
exports.useThreadEvents = useThreadEvents;
|
|
2092
2279
|
exports.useThreadsActions = useThreadsActions;
|