dooers-agents-client 0.9.3 → 0.12.0
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/README.md +4 -4
- package/dist/main.cjs +74 -11
- package/dist/main.cjs.map +1 -1
- package/dist/main.d.cts +14 -2
- package/dist/main.d.ts +14 -2
- package/dist/main.js +74 -11
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ React agents client SDK for agents server SDK.
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install dooers-agents
|
|
8
|
+
npm install dooers-agents
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
Peer dependency: `react >= 18`
|
|
@@ -15,7 +15,7 @@ Peer dependency: `react >= 18`
|
|
|
15
15
|
Wrap your component tree in `AgentProvider`, then use hooks anywhere inside.
|
|
16
16
|
|
|
17
17
|
```tsx
|
|
18
|
-
import { AgentProvider, useConnection, useThreadDetails, useMessage } from "dooers-agents
|
|
18
|
+
import { AgentProvider, useConnection, useThreadDetails, useMessage } from "dooers-agents"
|
|
19
19
|
|
|
20
20
|
function App() {
|
|
21
21
|
return (
|
|
@@ -230,9 +230,9 @@ import type {
|
|
|
230
230
|
AnalyticsEvent,
|
|
231
231
|
FeedbackType, // "like" | "dislike"
|
|
232
232
|
FeedbackTarget, // "event" | "run" | "thread"
|
|
233
|
-
} from "dooers-agents
|
|
233
|
+
} from "dooers-agents"
|
|
234
234
|
|
|
235
|
-
import { isSettingsFieldGroup } from "dooers-agents
|
|
235
|
+
import { isSettingsFieldGroup } from "dooers-agents" // type guard
|
|
236
236
|
```
|
|
237
237
|
|
|
238
238
|
## Architecture
|
package/dist/main.cjs
CHANGED
|
@@ -25,7 +25,7 @@ function apiMessagesUrlToWebSocketUrl(url) {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
// src/version.ts
|
|
28
|
-
var PACKAGE_VERSION = "0.
|
|
28
|
+
var PACKAGE_VERSION = "0.10.0";
|
|
29
29
|
|
|
30
30
|
// src/types.ts
|
|
31
31
|
function isSettingsFieldGroup(item) {
|
|
@@ -286,6 +286,7 @@ function toWireContentPart(p) {
|
|
|
286
286
|
var MAX_RECONNECT_ATTEMPTS = 5;
|
|
287
287
|
var RECONNECT_DELAYS = [1e3, 2e3, 4e3, 8e3, 16e3];
|
|
288
288
|
var SEND_MESSAGE_TIMEOUT = 3e4;
|
|
289
|
+
var PING_INTERVAL_MS = 3e4;
|
|
289
290
|
function blobPartFilename(blob, override) {
|
|
290
291
|
const o = (override ?? "").trim();
|
|
291
292
|
if (o) return o;
|
|
@@ -438,6 +439,9 @@ var AgentClient = class {
|
|
|
438
439
|
isLoadingMore = false;
|
|
439
440
|
// Event pagination cursors per thread
|
|
440
441
|
eventPaginationCursors = /* @__PURE__ */ new Map();
|
|
442
|
+
/** Active settings subscription — restored after reconnect. */
|
|
443
|
+
settingsSubscription = null;
|
|
444
|
+
pingTimer = null;
|
|
441
445
|
constructor(callbacks) {
|
|
442
446
|
this.callbacks = callbacks;
|
|
443
447
|
}
|
|
@@ -458,6 +462,16 @@ var AgentClient = class {
|
|
|
458
462
|
setUploadRunId(runId) {
|
|
459
463
|
this.uploadRunId = (runId ?? "").trim();
|
|
460
464
|
}
|
|
465
|
+
/**
|
|
466
|
+
* Merge connection metadata without tearing down the WebSocket.
|
|
467
|
+
* Use for handshake token refresh and identity/role updates on an open session.
|
|
468
|
+
*/
|
|
469
|
+
updateConnectionConfig(config) {
|
|
470
|
+
this.config = { ...this.config, ...config };
|
|
471
|
+
}
|
|
472
|
+
isConnected() {
|
|
473
|
+
return this.ws?.readyState === WebSocket.OPEN;
|
|
474
|
+
}
|
|
461
475
|
async upload(file, options) {
|
|
462
476
|
if (!this.uploadUrl) {
|
|
463
477
|
throw new Error("uploadUrl not configured");
|
|
@@ -541,6 +555,7 @@ var AgentClient = class {
|
|
|
541
555
|
}
|
|
542
556
|
disconnect() {
|
|
543
557
|
this.isIntentionallyClosed = true;
|
|
558
|
+
this.stopHeartbeat();
|
|
544
559
|
if (this.reconnectTimer) {
|
|
545
560
|
clearTimeout(this.reconnectTimer);
|
|
546
561
|
this.reconnectTimer = null;
|
|
@@ -606,13 +621,17 @@ var AgentClient = class {
|
|
|
606
621
|
}
|
|
607
622
|
// --- Settings ---
|
|
608
623
|
subscribeSettings(options) {
|
|
624
|
+
const audience = options?.audience ?? "user";
|
|
625
|
+
const agentOwnerUserId = options?.agentOwnerUserId ?? null;
|
|
626
|
+
this.settingsSubscription = { audience, agentOwnerUserId };
|
|
609
627
|
this.send("settings.subscribe", {
|
|
610
628
|
agent_id: this.agentId,
|
|
611
|
-
audience
|
|
612
|
-
agent_owner_user_id:
|
|
629
|
+
audience,
|
|
630
|
+
agent_owner_user_id: agentOwnerUserId
|
|
613
631
|
});
|
|
614
632
|
}
|
|
615
633
|
unsubscribeSettings() {
|
|
634
|
+
this.settingsSubscription = null;
|
|
616
635
|
this.send("settings.unsubscribe", { agent_id: this.agentId });
|
|
617
636
|
}
|
|
618
637
|
patchSetting(fieldId, value) {
|
|
@@ -755,6 +774,7 @@ var AgentClient = class {
|
|
|
755
774
|
});
|
|
756
775
|
}
|
|
757
776
|
createConnection() {
|
|
777
|
+
this.stopHeartbeat();
|
|
758
778
|
if (this.ws) {
|
|
759
779
|
this.abortPendingMessages("Connection lost; reconnecting");
|
|
760
780
|
this.ws.onopen = null;
|
|
@@ -822,6 +842,8 @@ var AgentClient = class {
|
|
|
822
842
|
after_event_id: afterEventId
|
|
823
843
|
});
|
|
824
844
|
}
|
|
845
|
+
this.resubscribeSettings();
|
|
846
|
+
this.startHeartbeat();
|
|
825
847
|
} else {
|
|
826
848
|
this.callbacks.setConnectionStatus("error", frame.payload.error?.message);
|
|
827
849
|
}
|
|
@@ -963,7 +985,28 @@ var AgentClient = class {
|
|
|
963
985
|
break;
|
|
964
986
|
}
|
|
965
987
|
}
|
|
988
|
+
resubscribeSettings() {
|
|
989
|
+
if (!this.settingsSubscription) return;
|
|
990
|
+
this.send("settings.subscribe", {
|
|
991
|
+
agent_id: this.agentId,
|
|
992
|
+
audience: this.settingsSubscription.audience,
|
|
993
|
+
agent_owner_user_id: this.settingsSubscription.agentOwnerUserId
|
|
994
|
+
});
|
|
995
|
+
}
|
|
996
|
+
startHeartbeat() {
|
|
997
|
+
this.stopHeartbeat();
|
|
998
|
+
this.pingTimer = setInterval(() => {
|
|
999
|
+
this.send("ping", {});
|
|
1000
|
+
}, PING_INTERVAL_MS);
|
|
1001
|
+
}
|
|
1002
|
+
stopHeartbeat() {
|
|
1003
|
+
if (this.pingTimer) {
|
|
1004
|
+
clearInterval(this.pingTimer);
|
|
1005
|
+
this.pingTimer = null;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
966
1008
|
scheduleReconnect() {
|
|
1009
|
+
this.stopHeartbeat();
|
|
967
1010
|
if (this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
|
968
1011
|
this.abortPendingMessages("Connection lost after maximum retries");
|
|
969
1012
|
this.callbacks.setReconnectFailed();
|
|
@@ -1462,9 +1505,17 @@ function AgentProvider({
|
|
|
1462
1505
|
clientRef.current?.setUploadAgentId(agentId);
|
|
1463
1506
|
}, [agentId]);
|
|
1464
1507
|
const identityIdsKey = identityIds?.join(",") ?? "";
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1508
|
+
const channelMetaKey = channelMeta ? JSON.stringify(channelMeta) : "";
|
|
1509
|
+
const connectionConfig = react.useMemo(() => {
|
|
1510
|
+
let parsedChannelMeta;
|
|
1511
|
+
if (channelMetaKey) {
|
|
1512
|
+
try {
|
|
1513
|
+
parsedChannelMeta = JSON.parse(channelMetaKey);
|
|
1514
|
+
} catch {
|
|
1515
|
+
parsedChannelMeta = channelMeta;
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
return {
|
|
1468
1519
|
organizationId,
|
|
1469
1520
|
workspaceId,
|
|
1470
1521
|
userId,
|
|
@@ -1478,12 +1529,9 @@ function AgentProvider({
|
|
|
1478
1529
|
workspaceRole,
|
|
1479
1530
|
authToken,
|
|
1480
1531
|
channel,
|
|
1481
|
-
channelMeta
|
|
1482
|
-
}
|
|
1483
|
-
return () => clientRef.current?.disconnect();
|
|
1532
|
+
channelMeta: parsedChannelMeta
|
|
1533
|
+
};
|
|
1484
1534
|
}, [
|
|
1485
|
-
url,
|
|
1486
|
-
agentId,
|
|
1487
1535
|
organizationId,
|
|
1488
1536
|
workspaceId,
|
|
1489
1537
|
userId,
|
|
@@ -1497,8 +1545,23 @@ function AgentProvider({
|
|
|
1497
1545
|
workspaceRole,
|
|
1498
1546
|
authToken,
|
|
1499
1547
|
channel,
|
|
1548
|
+
channelMetaKey,
|
|
1500
1549
|
channelMeta
|
|
1501
1550
|
]);
|
|
1551
|
+
const connectionConfigRef = react.useRef(connectionConfig);
|
|
1552
|
+
connectionConfigRef.current = connectionConfig;
|
|
1553
|
+
react.useEffect(() => {
|
|
1554
|
+
if (!url || !agentId) {
|
|
1555
|
+
clientRef.current?.disconnect();
|
|
1556
|
+
return;
|
|
1557
|
+
}
|
|
1558
|
+
clientRef.current?.connect(url, agentId, connectionConfigRef.current);
|
|
1559
|
+
return () => clientRef.current?.disconnect();
|
|
1560
|
+
}, [url, agentId]);
|
|
1561
|
+
react.useEffect(() => {
|
|
1562
|
+
if (!url || !agentId) return;
|
|
1563
|
+
clientRef.current?.updateConnectionConfig(connectionConfig);
|
|
1564
|
+
}, [url, agentId, connectionConfig]);
|
|
1502
1565
|
const contextValue = react.useMemo(
|
|
1503
1566
|
() => ({ store: storeRef.current, client: clientRef.current }),
|
|
1504
1567
|
[]
|