dooers-agents-client 0.5.0 → 0.8.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/dist/main.cjs CHANGED
@@ -6,7 +6,23 @@ var shallow = require('zustand/shallow');
6
6
  var vanilla = require('zustand/vanilla');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
8
 
9
- // src/hooks/use-analytics.ts
9
+ // src/helpers/api-messages-url-to-ws.ts
10
+ function apiMessagesUrlToWebSocketUrl(url) {
11
+ const t = url.trim();
12
+ if (!t) {
13
+ throw new Error("API Messages URL is empty");
14
+ }
15
+ if (/^wss:\/\//i.test(t) || /^ws:\/\//i.test(t)) {
16
+ return t;
17
+ }
18
+ if (/^https:\/\//i.test(t)) {
19
+ return `wss://${t.slice("https://".length)}`;
20
+ }
21
+ if (/^http:\/\//i.test(t)) {
22
+ return `ws://${t.slice("http://".length)}`;
23
+ }
24
+ throw new Error("API Messages URL must start with http://, https://, ws://, or wss://");
25
+ }
10
26
 
11
27
  // src/types.ts
12
28
  function isSettingsFieldGroup(item) {
@@ -179,6 +195,8 @@ function toSettingsField(w) {
179
195
  label: w.label,
180
196
  required: w.required,
181
197
  readonly: w.readonly,
198
+ user_editable: w.user_editable ?? true,
199
+ visibility: w.visibility ?? "user",
182
200
  value: w.value,
183
201
  placeholder: w.placeholder,
184
202
  options: w.options,
@@ -199,7 +217,8 @@ function toSettingsItem(w) {
199
217
  id: g.id,
200
218
  label: g.label,
201
219
  fields: g.fields.map(toSettingsField),
202
- collapsible: g.collapsible
220
+ collapsible: g.collapsible,
221
+ visibility: g.visibility ?? "user"
203
222
  };
204
223
  }
205
224
  return toSettingsField(w);
@@ -220,12 +239,31 @@ function toWireContentPart(p) {
220
239
  switch (p.type) {
221
240
  case "text":
222
241
  return { type: "text", text: p.text };
223
- case "audio":
224
- return { type: "audio", ref_id: p.refId, duration: p.duration };
225
- case "image":
226
- return { type: "image", ref_id: p.refId };
227
- case "document":
228
- return { type: "document", ref_id: p.refId };
242
+ case "audio": {
243
+ const w = {
244
+ type: "audio",
245
+ ref_id: p.refId
246
+ };
247
+ if (p.duration != null) w.duration = p.duration;
248
+ if (p.url) w.url = p.url;
249
+ return w;
250
+ }
251
+ case "image": {
252
+ const w = {
253
+ type: "image",
254
+ ref_id: p.refId
255
+ };
256
+ if (p.url) w.url = p.url;
257
+ return w;
258
+ }
259
+ case "document": {
260
+ const w = {
261
+ type: "document",
262
+ ref_id: p.refId
263
+ };
264
+ if (p.url) w.url = p.url;
265
+ return w;
266
+ }
229
267
  }
230
268
  }
231
269
 
@@ -233,6 +271,92 @@ function toWireContentPart(p) {
233
271
  var MAX_RECONNECT_ATTEMPTS = 5;
234
272
  var RECONNECT_DELAYS = [1e3, 2e3, 4e3, 8e3, 16e3];
235
273
  var SEND_MESSAGE_TIMEOUT = 3e4;
274
+ var AgentServerClient = class {
275
+ wsUrl;
276
+ constructor(apiMessagesUrl) {
277
+ this.wsUrl = apiMessagesUrlToWebSocketUrl(apiMessagesUrl);
278
+ }
279
+ /**
280
+ * Opens a short-lived WebSocket, requests `settings.public_schema`, and returns the public field
281
+ * list. Closes the socket when done.
282
+ */
283
+ fetchPublicSettingsSchema(options) {
284
+ const timeoutMs = options?.timeoutMs ?? 15e3;
285
+ return new Promise((resolve, reject) => {
286
+ const ws = new WebSocket(this.wsUrl);
287
+ const frameId = crypto.randomUUID();
288
+ let settled = false;
289
+ const finish = (fn) => {
290
+ if (settled) return;
291
+ settled = true;
292
+ clearTimeout(timer);
293
+ try {
294
+ ws.close();
295
+ } catch {
296
+ }
297
+ fn();
298
+ };
299
+ const timer = setTimeout(() => {
300
+ finish(() => reject(new Error("AgentServerClient.fetchPublicSettingsSchema: timeout")));
301
+ }, timeoutMs);
302
+ ws.onopen = () => {
303
+ ws.send(
304
+ JSON.stringify({
305
+ id: frameId,
306
+ type: "settings.public_schema",
307
+ payload: {}
308
+ })
309
+ );
310
+ };
311
+ ws.onmessage = (ev) => {
312
+ let msg;
313
+ try {
314
+ msg = JSON.parse(ev.data);
315
+ } catch {
316
+ return;
317
+ }
318
+ if (msg.type === "ack" && msg.payload?.ack_id === frameId) {
319
+ if (msg.payload?.ok === false) {
320
+ finish(
321
+ () => reject(
322
+ new Error(
323
+ msg.payload?.error?.message ?? "AgentServerClient.fetchPublicSettingsSchema: request rejected"
324
+ )
325
+ )
326
+ );
327
+ }
328
+ return;
329
+ }
330
+ if (msg.type === "settings.public_schema.result" && msg.id === frameId) {
331
+ const raw = msg.payload?.schema;
332
+ const fieldsWire = raw?.fields ?? [];
333
+ const fields = fieldsWire.map((w) => toSettingsItem(w));
334
+ finish(
335
+ () => resolve({
336
+ version: typeof raw?.version === "string" ? raw.version : "1.0",
337
+ fields
338
+ })
339
+ );
340
+ }
341
+ };
342
+ ws.onerror = () => {
343
+ finish(
344
+ () => reject(new Error("AgentServerClient.fetchPublicSettingsSchema: WebSocket error"))
345
+ );
346
+ };
347
+ ws.onclose = (ev) => {
348
+ if (settled) return;
349
+ finish(
350
+ () => reject(
351
+ new Error(
352
+ `AgentServerClient.fetchPublicSettingsSchema: connection closed (${ev.code})${ev.reason ? ` ${ev.reason}` : ""}`
353
+ )
354
+ )
355
+ );
356
+ };
357
+ });
358
+ }
359
+ };
236
360
  var AgentClient = class {
237
361
  ws = null;
238
362
  callbacks;
@@ -278,6 +402,9 @@ var AgentClient = class {
278
402
  }
279
403
  const formData = new FormData();
280
404
  formData.append("file", file);
405
+ if (this.agentId) {
406
+ formData.append("agent_id", this.agentId);
407
+ }
281
408
  const headers = {};
282
409
  if (this.config.authToken) {
283
410
  headers.Authorization = `Bearer ${this.config.authToken}`;
@@ -295,16 +422,17 @@ var AgentClient = class {
295
422
  refId: result.ref_id,
296
423
  mimeType: result.mime_type,
297
424
  filename: result.filename,
298
- sizeBytes: result.size_bytes
425
+ sizeBytes: result.size_bytes ?? result.size ?? 0,
426
+ publicUrl: result.public_url ?? void 0
299
427
  };
300
428
  }
301
429
  connect(url, agentId, config) {
302
- this.url = url;
430
+ this.url = apiMessagesUrlToWebSocketUrl(url);
303
431
  this.agentId = agentId;
304
432
  this.config = config ?? { organizationId: "", workspaceId: "", userId: "" };
305
433
  this.isIntentionallyClosed = false;
306
434
  try {
307
- const parsed = new URL(url);
435
+ const parsed = new URL(this.url);
308
436
  parsed.protocol = parsed.protocol === "wss:" ? "https:" : "http:";
309
437
  parsed.pathname = "";
310
438
  parsed.search = "";
@@ -385,8 +513,12 @@ var AgentClient = class {
385
513
  });
386
514
  }
387
515
  // --- Settings ---
388
- subscribeSettings() {
389
- this.send("settings.subscribe", { agent_id: this.agentId });
516
+ subscribeSettings(options) {
517
+ this.send("settings.subscribe", {
518
+ agent_id: this.agentId,
519
+ audience: options?.audience ?? "user",
520
+ agent_owner_user_id: options?.agentOwnerUserId ?? null
521
+ });
390
522
  }
391
523
  unsubscribeSettings() {
392
524
  this.send("settings.unsubscribe", { agent_id: this.agentId });
@@ -662,6 +794,8 @@ var AgentClient = class {
662
794
  frame.payload.updated_at
663
795
  );
664
796
  break;
797
+ case "settings.public_schema.result":
798
+ break;
665
799
  case "feedback.ack":
666
800
  if (frame.payload.ok) {
667
801
  this.callbacks.onFeedbackAck(
@@ -1439,7 +1573,10 @@ function useSettings() {
1439
1573
  const fields = useShallowStore((s) => s.settings.fields);
1440
1574
  const updatedAt = useStore((s) => s.settings.updatedAt);
1441
1575
  const isLoading = useStore((s) => s.settings.isLoading);
1442
- const subscribe = react.useCallback(() => client.subscribeSettings(), [client]);
1576
+ const subscribe = react.useCallback(
1577
+ (options) => client.subscribeSettings(options),
1578
+ [client]
1579
+ );
1443
1580
  const unsubscribe = react.useCallback(() => client.unsubscribeSettings(), [client]);
1444
1581
  const patchField = react.useCallback(
1445
1582
  (fieldId, value) => client.patchSetting(fieldId, value),
@@ -1566,6 +1703,8 @@ function useUpload() {
1566
1703
  }
1567
1704
 
1568
1705
  exports.AgentProvider = AgentProvider;
1706
+ exports.AgentServerClient = AgentServerClient;
1707
+ exports.apiMessagesUrlToWebSocketUrl = apiMessagesUrlToWebSocketUrl;
1569
1708
  exports.isSettingsFieldGroup = isSettingsFieldGroup;
1570
1709
  exports.toFormElement = toFormElement;
1571
1710
  exports.toFormEventData = toFormEventData;