dooers-agents-client 0.9.2 → 0.11.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 +117 -20
- package/dist/main.cjs.map +1 -1
- package/dist/main.d.cts +33 -2
- package/dist/main.d.ts +33 -2
- package/dist/main.js +117 -21
- 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
|
@@ -24,6 +24,9 @@ function apiMessagesUrlToWebSocketUrl(url) {
|
|
|
24
24
|
throw new Error("API Messages URL must start with http://, https://, ws://, or wss://");
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
// src/version.ts
|
|
28
|
+
var PACKAGE_VERSION = "0.10.0";
|
|
29
|
+
|
|
27
30
|
// src/types.ts
|
|
28
31
|
function isSettingsFieldGroup(item) {
|
|
29
32
|
return "fields" in item && Array.isArray(item.fields);
|
|
@@ -34,6 +37,8 @@ function toUser(w) {
|
|
|
34
37
|
userId: w.user_id,
|
|
35
38
|
userName: w.user_name,
|
|
36
39
|
userEmail: w.user_email,
|
|
40
|
+
userMobileNumber: w.user_mobile_number,
|
|
41
|
+
userWhatsappNumber: w.user_whatsapp_number,
|
|
37
42
|
identityIds: w.identity_ids,
|
|
38
43
|
systemRole: w.system_role,
|
|
39
44
|
organizationRole: w.organization_role,
|
|
@@ -65,7 +70,8 @@ function toDisplayContentPart(w) {
|
|
|
65
70
|
url: w.url,
|
|
66
71
|
mimeType: w.mime_type,
|
|
67
72
|
duration: w.duration,
|
|
68
|
-
filename: w.filename
|
|
73
|
+
filename: w.filename,
|
|
74
|
+
...w.ref_id ? { refId: w.ref_id } : {}
|
|
69
75
|
};
|
|
70
76
|
case "image":
|
|
71
77
|
return {
|
|
@@ -75,7 +81,8 @@ function toDisplayContentPart(w) {
|
|
|
75
81
|
width: w.width,
|
|
76
82
|
height: w.height,
|
|
77
83
|
alt: w.alt,
|
|
78
|
-
filename: w.filename
|
|
84
|
+
filename: w.filename,
|
|
85
|
+
...w.ref_id ? { refId: w.ref_id } : {}
|
|
79
86
|
};
|
|
80
87
|
case "document":
|
|
81
88
|
return {
|
|
@@ -83,7 +90,8 @@ function toDisplayContentPart(w) {
|
|
|
83
90
|
url: w.url,
|
|
84
91
|
filename: w.filename,
|
|
85
92
|
mimeType: w.mime_type,
|
|
86
|
-
sizeBytes: w.size_bytes
|
|
93
|
+
sizeBytes: w.size_bytes,
|
|
94
|
+
...w.ref_id ? { refId: w.ref_id } : {}
|
|
87
95
|
};
|
|
88
96
|
}
|
|
89
97
|
}
|
|
@@ -278,6 +286,7 @@ function toWireContentPart(p) {
|
|
|
278
286
|
var MAX_RECONNECT_ATTEMPTS = 5;
|
|
279
287
|
var RECONNECT_DELAYS = [1e3, 2e3, 4e3, 8e3, 16e3];
|
|
280
288
|
var SEND_MESSAGE_TIMEOUT = 3e4;
|
|
289
|
+
var PING_INTERVAL_MS = 3e4;
|
|
281
290
|
function blobPartFilename(blob, override) {
|
|
282
291
|
const o = (override ?? "").trim();
|
|
283
292
|
if (o) return o;
|
|
@@ -410,7 +419,8 @@ var AgentClient = class {
|
|
|
410
419
|
config = {
|
|
411
420
|
organizationId: "",
|
|
412
421
|
workspaceId: "",
|
|
413
|
-
userId: ""
|
|
422
|
+
userId: "",
|
|
423
|
+
channel: "dooers-platform"
|
|
414
424
|
};
|
|
415
425
|
connectFrameId = "";
|
|
416
426
|
isIntentionallyClosed = false;
|
|
@@ -429,6 +439,9 @@ var AgentClient = class {
|
|
|
429
439
|
isLoadingMore = false;
|
|
430
440
|
// Event pagination cursors per thread
|
|
431
441
|
eventPaginationCursors = /* @__PURE__ */ new Map();
|
|
442
|
+
/** Active settings subscription — restored after reconnect. */
|
|
443
|
+
settingsSubscription = null;
|
|
444
|
+
pingTimer = null;
|
|
432
445
|
constructor(callbacks) {
|
|
433
446
|
this.callbacks = callbacks;
|
|
434
447
|
}
|
|
@@ -449,6 +462,16 @@ var AgentClient = class {
|
|
|
449
462
|
setUploadRunId(runId) {
|
|
450
463
|
this.uploadRunId = (runId ?? "").trim();
|
|
451
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
|
+
}
|
|
452
475
|
async upload(file, options) {
|
|
453
476
|
if (!this.uploadUrl) {
|
|
454
477
|
throw new Error("uploadUrl not configured");
|
|
@@ -532,6 +555,7 @@ var AgentClient = class {
|
|
|
532
555
|
}
|
|
533
556
|
disconnect() {
|
|
534
557
|
this.isIntentionallyClosed = true;
|
|
558
|
+
this.stopHeartbeat();
|
|
535
559
|
if (this.reconnectTimer) {
|
|
536
560
|
clearTimeout(this.reconnectTimer);
|
|
537
561
|
this.reconnectTimer = null;
|
|
@@ -597,13 +621,17 @@ var AgentClient = class {
|
|
|
597
621
|
}
|
|
598
622
|
// --- Settings ---
|
|
599
623
|
subscribeSettings(options) {
|
|
624
|
+
const audience = options?.audience ?? "user";
|
|
625
|
+
const agentOwnerUserId = options?.agentOwnerUserId ?? null;
|
|
626
|
+
this.settingsSubscription = { audience, agentOwnerUserId };
|
|
600
627
|
this.send("settings.subscribe", {
|
|
601
628
|
agent_id: this.agentId,
|
|
602
|
-
audience
|
|
603
|
-
agent_owner_user_id:
|
|
629
|
+
audience,
|
|
630
|
+
agent_owner_user_id: agentOwnerUserId
|
|
604
631
|
});
|
|
605
632
|
}
|
|
606
633
|
unsubscribeSettings() {
|
|
634
|
+
this.settingsSubscription = null;
|
|
607
635
|
this.send("settings.unsubscribe", { agent_id: this.agentId });
|
|
608
636
|
}
|
|
609
637
|
patchSetting(fieldId, value) {
|
|
@@ -697,9 +725,7 @@ var AgentClient = class {
|
|
|
697
725
|
content
|
|
698
726
|
}
|
|
699
727
|
};
|
|
700
|
-
|
|
701
|
-
payload.metadata = params.metadata;
|
|
702
|
-
}
|
|
728
|
+
payload.metadata = this.withChannelMetadata(params.metadata);
|
|
703
729
|
this.sendRaw({
|
|
704
730
|
id: clientEventId,
|
|
705
731
|
type: "event.create",
|
|
@@ -727,7 +753,8 @@ var AgentClient = class {
|
|
|
727
753
|
values: params.values
|
|
728
754
|
}
|
|
729
755
|
}
|
|
730
|
-
}
|
|
756
|
+
},
|
|
757
|
+
metadata: this.withChannelMetadata(params.metadata)
|
|
731
758
|
});
|
|
732
759
|
return promise;
|
|
733
760
|
}
|
|
@@ -747,6 +774,7 @@ var AgentClient = class {
|
|
|
747
774
|
});
|
|
748
775
|
}
|
|
749
776
|
createConnection() {
|
|
777
|
+
this.stopHeartbeat();
|
|
750
778
|
if (this.ws) {
|
|
751
779
|
this.abortPendingMessages("Connection lost; reconnecting");
|
|
752
780
|
this.ws.onopen = null;
|
|
@@ -787,13 +815,15 @@ var AgentClient = class {
|
|
|
787
815
|
user_id: this.config.userId ?? "",
|
|
788
816
|
user_name: this.config.userName ?? null,
|
|
789
817
|
user_email: this.config.userEmail ?? null,
|
|
818
|
+
user_mobile_number: this.config.userMobileNumber ?? null,
|
|
819
|
+
user_whatsapp_number: this.config.userWhatsappNumber ?? null,
|
|
790
820
|
identity_ids: this.config.identityIds ?? [],
|
|
791
821
|
system_role: this.config.systemRole ?? "user",
|
|
792
822
|
organization_role: this.config.organizationRole ?? "member",
|
|
793
823
|
workspace_role: this.config.workspaceRole ?? "member"
|
|
794
824
|
},
|
|
795
825
|
auth_token: this.config.authToken,
|
|
796
|
-
client: { name: "dooers-agents-client", version:
|
|
826
|
+
client: { name: "dooers-agents-client", version: PACKAGE_VERSION }
|
|
797
827
|
}
|
|
798
828
|
});
|
|
799
829
|
}
|
|
@@ -812,6 +842,8 @@ var AgentClient = class {
|
|
|
812
842
|
after_event_id: afterEventId
|
|
813
843
|
});
|
|
814
844
|
}
|
|
845
|
+
this.resubscribeSettings();
|
|
846
|
+
this.startHeartbeat();
|
|
815
847
|
} else {
|
|
816
848
|
this.callbacks.setConnectionStatus("error", frame.payload.error?.message);
|
|
817
849
|
}
|
|
@@ -953,7 +985,28 @@ var AgentClient = class {
|
|
|
953
985
|
break;
|
|
954
986
|
}
|
|
955
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
|
+
}
|
|
956
1008
|
scheduleReconnect() {
|
|
1009
|
+
this.stopHeartbeat();
|
|
957
1010
|
if (this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
|
958
1011
|
this.abortPendingMessages("Connection lost after maximum retries");
|
|
959
1012
|
this.callbacks.setReconnectFailed();
|
|
@@ -971,6 +1024,17 @@ var AgentClient = class {
|
|
|
971
1024
|
send(type, payload) {
|
|
972
1025
|
this.sendRaw({ id: crypto.randomUUID(), type, payload });
|
|
973
1026
|
}
|
|
1027
|
+
withChannelMetadata(metadata) {
|
|
1028
|
+
const channel = (this.config.channel || "dooers-platform").trim() || "dooers-platform";
|
|
1029
|
+
const base = metadata ? { ...metadata } : {};
|
|
1030
|
+
if (!("channel" in base)) {
|
|
1031
|
+
base.channel = channel;
|
|
1032
|
+
}
|
|
1033
|
+
if (this.config.channelMeta && !("channel_meta" in base)) {
|
|
1034
|
+
base.channel_meta = this.config.channelMeta;
|
|
1035
|
+
}
|
|
1036
|
+
return Object.keys(base).length > 0 ? base : void 0;
|
|
1037
|
+
}
|
|
974
1038
|
sendRaw(frame) {
|
|
975
1039
|
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return;
|
|
976
1040
|
this.ws.send(JSON.stringify(frame));
|
|
@@ -1412,11 +1476,15 @@ function AgentProvider({
|
|
|
1412
1476
|
userId,
|
|
1413
1477
|
userName,
|
|
1414
1478
|
userEmail,
|
|
1479
|
+
userMobileNumber,
|
|
1480
|
+
userWhatsappNumber,
|
|
1415
1481
|
identityIds,
|
|
1416
1482
|
systemRole,
|
|
1417
1483
|
organizationRole,
|
|
1418
1484
|
workspaceRole,
|
|
1419
1485
|
authToken,
|
|
1486
|
+
channel,
|
|
1487
|
+
channelMeta,
|
|
1420
1488
|
uploadUrl,
|
|
1421
1489
|
onError,
|
|
1422
1490
|
children
|
|
@@ -1437,35 +1505,63 @@ function AgentProvider({
|
|
|
1437
1505
|
clientRef.current?.setUploadAgentId(agentId);
|
|
1438
1506
|
}, [agentId]);
|
|
1439
1507
|
const identityIdsKey = identityIds?.join(",") ?? "";
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
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 {
|
|
1443
1519
|
organizationId,
|
|
1444
1520
|
workspaceId,
|
|
1445
1521
|
userId,
|
|
1446
1522
|
userName,
|
|
1447
1523
|
userEmail,
|
|
1524
|
+
userMobileNumber,
|
|
1525
|
+
userWhatsappNumber,
|
|
1448
1526
|
identityIds: identityIdsKey ? identityIdsKey.split(",") : void 0,
|
|
1449
1527
|
systemRole,
|
|
1450
1528
|
organizationRole,
|
|
1451
1529
|
workspaceRole,
|
|
1452
|
-
authToken
|
|
1453
|
-
|
|
1454
|
-
|
|
1530
|
+
authToken,
|
|
1531
|
+
channel,
|
|
1532
|
+
channelMeta: parsedChannelMeta
|
|
1533
|
+
};
|
|
1455
1534
|
}, [
|
|
1456
|
-
url,
|
|
1457
|
-
agentId,
|
|
1458
1535
|
organizationId,
|
|
1459
1536
|
workspaceId,
|
|
1460
1537
|
userId,
|
|
1461
1538
|
userName,
|
|
1462
1539
|
userEmail,
|
|
1540
|
+
userMobileNumber,
|
|
1541
|
+
userWhatsappNumber,
|
|
1463
1542
|
identityIdsKey,
|
|
1464
1543
|
systemRole,
|
|
1465
1544
|
organizationRole,
|
|
1466
1545
|
workspaceRole,
|
|
1467
|
-
authToken
|
|
1546
|
+
authToken,
|
|
1547
|
+
channel,
|
|
1548
|
+
channelMetaKey,
|
|
1549
|
+
channelMeta
|
|
1468
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]);
|
|
1469
1565
|
const contextValue = react.useMemo(
|
|
1470
1566
|
() => ({ store: storeRef.current, client: clientRef.current }),
|
|
1471
1567
|
[]
|
|
@@ -1919,6 +2015,7 @@ function useUpload() {
|
|
|
1919
2015
|
|
|
1920
2016
|
exports.AgentProvider = AgentProvider;
|
|
1921
2017
|
exports.AgentServerClient = AgentServerClient;
|
|
2018
|
+
exports.PACKAGE_VERSION = PACKAGE_VERSION;
|
|
1922
2019
|
exports.apiMessagesUrlToWebSocketUrl = apiMessagesUrlToWebSocketUrl;
|
|
1923
2020
|
exports.isSettingsFieldGroup = isSettingsFieldGroup;
|
|
1924
2021
|
exports.toFormElement = toFormElement;
|