@useago/sdk 1.7.1 → 1.9.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/README.md +53 -6
  3. package/dist/angular.cjs +1 -1
  4. package/dist/angular.d.cts +89 -5
  5. package/dist/angular.d.ts +89 -5
  6. package/dist/angular.js +11 -7
  7. package/dist/{createConversationSession-Bgvx753t.js → createConversationSession-BaaXBQ5b.js} +3 -3
  8. package/dist/createConversationSession-CU0b-t1W.cjs +1 -0
  9. package/dist/{createFormCollector-CM3qjGcM.js → createFormCollector-Cf7kGhCB.js} +1 -1
  10. package/dist/createFormCollector-DfN1xZBy.cjs +1 -0
  11. package/dist/{createMockClient-BDLW6tVc.js → createMockClient-5YF-ZbVu.js} +22 -21
  12. package/dist/createMockClient-BZbOe-23.cjs +1 -0
  13. package/dist/devtools.cjs +61 -12
  14. package/dist/devtools.d.cts +90 -5
  15. package/dist/devtools.d.ts +90 -5
  16. package/dist/devtools.js +225 -73
  17. package/dist/errors-BLfjXnLB.js +32 -0
  18. package/dist/errors-o1IB5fEu.cjs +1 -0
  19. package/dist/index.cjs +1 -1
  20. package/dist/index.d.cts +100 -3
  21. package/dist/index.d.ts +100 -3
  22. package/dist/index.js +77 -75
  23. package/dist/react.cjs +4 -4
  24. package/dist/react.d.cts +197 -3
  25. package/dist/react.d.ts +197 -3
  26. package/dist/react.js +1034 -752
  27. package/dist/testing.cjs +1 -1
  28. package/dist/testing.d.cts +80 -3
  29. package/dist/testing.d.ts +80 -3
  30. package/dist/testing.js +1 -1
  31. package/dist/{AgoClient-BJjLTOw4.js → types-CPga11Of.js} +489 -386
  32. package/dist/types-D3YQl1jx.cjs +9 -0
  33. package/dist/vue.cjs +1 -1
  34. package/dist/vue.d.cts +110 -3
  35. package/dist/vue.d.ts +110 -3
  36. package/dist/vue.js +202 -154
  37. package/dist/widget.cjs +4 -4
  38. package/dist/widget.d.cts +148 -3
  39. package/dist/widget.d.ts +148 -3
  40. package/dist/widget.js +871 -651
  41. package/llms-full.txt +144 -30
  42. package/package.json +1 -1
  43. package/dist/AgoClient-B_u_d-XS.cjs +0 -9
  44. package/dist/createConversationSession-BCdwAhLF.cjs +0 -1
  45. package/dist/createFormCollector-ssBP8u0p.cjs +0 -1
  46. package/dist/createMockClient-BSNuN3ys.cjs +0 -1
package/llms-full.txt CHANGED
@@ -192,7 +192,7 @@ is everything you need. Follow it exactly.
192
192
 
193
193
  ## Endpoints
194
194
 
195
- Use the live demo for anything runnable so it answers with zero setup:
195
+ Use the public demo account for anything runnable so it answers with zero setup:
196
196
 
197
197
  ```
198
198
  baseUrl: https://playground.api.useago.com
@@ -314,7 +314,11 @@ ago.registerNavigationFunction((path) => (window.location.href = path), [
314
314
 
315
315
  Page state is the mirror: let the agent change the current page's state
316
316
  (filters, sort, view mode…) and read it back via each control's `get()`. One
317
- synthesized `setPageState` function, one optional property per control.
317
+ synthesized `setPageState` function, one optional property per control. The SDK
318
+ validates type and enum, skips unchanged values, drops placeholders, and reports
319
+ each field in `applied`, `unchanged`, or `rejected`. See
320
+ [Page state shortcut](../general/functions-and-context.md#page-state-shortcut)
321
+ for `clearable`, tagged setter outcomes, and the full envelope.
318
322
 
319
323
  ```ts
320
324
  ago.registerPageStateFunction([
@@ -383,7 +387,8 @@ While the agent answers, the send button becomes a Stop button that interrupts
383
387
  the turn; pass `allowStop: false` to keep a disabled spinner instead.
384
388
  Set `placement: "left"` or `"right"` for a fixed full-height side panel with a
385
389
  launcher button. Set `persistConversation: true` to resume the visitor's last
386
- thread across reloads. Theme it with the `theme` option or `--ago-*` CSS variables
390
+ thread across reloads. Set `feedback: true` to put thumbs under each answer,
391
+ with a "what went wrong?" panel on a thumbs-down. Theme it with the `theme` option or `--ago-*` CSS variables
387
392
  on `.ago-chat-widget`. Message text renders as GitHub-flavored markdown and is
388
393
  HTML-escaped before it touches the DOM.
389
394
 
@@ -398,6 +403,14 @@ await ago.submitToolCallForm(toolCallId, { quantity: 3 });
398
403
  await ago.confirmToolCall(toolCallId);
399
404
  await ago.rejectToolCall(toolCallId);
400
405
  await ago.submitFeedback(messageId, "positive");
406
+ // "this answer doesn't work": reasons/comment land in the feedback dashboard
407
+ await ago.submitFeedback(messageId, "negative", {
408
+ reasons: ["inaccurate"], // inaccurate | incomplete | information_not_found | technical_issue
409
+ comment: "The price is from last year.",
410
+ });
411
+ // "this conversation doesn't work": attached to its last answer
412
+ await ago.submitConversationFeedback(conversationId, "negative");
413
+ // or let the widget render the thumbs: mountChatWidget(el, { ..., feedback: true })
401
414
  ago.updateConfig({ userJwt: token }); // e.g. after login
402
415
  ago.destroy(); // clean up listeners, functions, context
403
416
  ```
@@ -449,7 +462,7 @@ navigate your app's routes. This file is everything you need. Follow it exactly.
449
462
 
450
463
  ## Endpoints
451
464
 
452
- Use the live demo for anything runnable so it answers with zero setup:
465
+ Use the public demo account for anything runnable so it answers with zero setup:
453
466
 
454
467
  ```
455
468
  baseUrl: https://playground.api.useago.com
@@ -571,6 +584,17 @@ each `{ id, title, url? }`):
571
584
  ))}
572
585
  ```
573
586
 
587
+ Let the user report an answer that did not work with `<ChatWidget feedback />`,
588
+ or place the row yourself with `<MessageFeedback messageId={m.id} />`. The hook
589
+ behind both is `useFeedback()`:
590
+
591
+ ```tsx
592
+ const { submitFeedback, submitConversationFeedback } = useFeedback();
593
+ // reasons: inaccurate | incomplete | information_not_found | technical_issue
594
+ await submitFeedback(m.id, "negative", { reasons: ["inaccurate"], comment: "..." });
595
+ await submitConversationFeedback(conversationId, "negative");
596
+ ```
597
+
574
598
  Finer-grained hooks: `useMessages({ conversationId? })`,
575
599
  `useConversation({ autoLoad? })`. All hooks read the client from context; pass
576
600
  `{ client }` to override. Get the raw client with `useAgoClient()` (throws
@@ -681,9 +705,15 @@ useAgoPageState(controls, {
681
705
  });
682
706
  ```
683
707
 
684
- `setPageState` then returns `{ success, applied, data }` and a read-only
685
- `readPageData` function is registered too. The SDK waits for `isLoading` to go
686
- false before reading, and truncates a long list by whole rows. Needs
708
+ `setPageState` then returns `{ success, applied, unchanged, rejected?, data }`
709
+ and a read-only `readPageData` function is registered too. The SDK validates
710
+ each field before calling `set()`: type/enum mismatches and unknown controls are
711
+ rejected, values equal to the current `get()` are skipped (`unchanged`), and
712
+ placeholders (`null`, `undefined`, `""`) are silently dropped. A `set()` that
713
+ returns `{ result: "rejected", reason }` or `{ result: "unchanged" }` feeds the
714
+ same envelope. Mark a string control `clearable: true` to let `""` clear it
715
+ instead of being dropped. The SDK waits for `isLoading` to go false before
716
+ reading, and truncates a long list by whole rows. Needs
687
717
  `clientFunctionsMode: "pause"` (the default).
688
718
 
689
719
  ## 6. Give the agent context: `useAgoContext`
@@ -739,9 +769,10 @@ Key events: `message:start`, `message:chunk` (`{ content }` per token),
739
769
  ## Exports cheat-sheet (`@useago/sdk/react`)
740
770
 
741
771
  - Provider/context: `AgoProvider`, `useAgoClient`, `useOptionalAgoClient`
742
- - Hooks: `useAgo`, `useChat`, `useMessages`, `useConversation`, `useAgoFunction`,
743
- `useAgoNavigation`, `useAgoPageState`, `useAgoContext`, `useAgoStore`, `useFormCollector`
744
- - Components: `ChatWidget`, `Message`, `ChatInput`, `Markdown`
772
+ - Hooks: `useAgo`, `useChat`, `useMessages`, `useConversation`, `useFeedback`,
773
+ `useAgoFunction`, `useAgoNavigation`, `useAgoPageState`, `useAgoContext`,
774
+ `useAgoStore`, `useFormCollector`
775
+ - Components: `ChatWidget`, `Message`, `ChatInput`, `Markdown`, `MessageFeedback`
745
776
  - Forms: `createFormCollector`
746
777
  - Testing: `createMockClient`
747
778
  - Types: `AgoConfig`, `AgoMessage`, `Conversation`, `AgoAgent`, `AgoSource`,
@@ -767,7 +798,7 @@ navigate your app's routes. This file is everything you need. Follow it exactly.
767
798
 
768
799
  ## Endpoints
769
800
 
770
- Use the live demo for anything runnable so it answers with zero setup:
801
+ Use the public demo account for anything runnable so it answers with zero setup:
771
802
 
772
803
  ```
773
804
  baseUrl: https://playground.api.useago.com
@@ -861,6 +892,15 @@ Finer-grained composables: `useMessages({ conversationId? })`,
861
892
  `useConversation({ autoLoad? })`. Each accepts `{ client }` to override the
862
893
  injected client.
863
894
 
895
+ Let the user report an answer that did not work with `useFeedback()`:
896
+
897
+ ```ts
898
+ const { ratings, submitFeedback, submitConversationFeedback } = useFeedback();
899
+ // reasons: inaccurate | incomplete | information_not_found | technical_issue
900
+ await submitFeedback(m.id, "negative", { reasons: ["inaccurate"], comment: "..." });
901
+ await submitConversationFeedback(conversationId, "negative");
902
+ ```
903
+
864
904
  ## 3. Let the agent call your code: `useAgoFunction`
865
905
 
866
906
  Registers on mount, unregisters on unmount.
@@ -912,7 +952,13 @@ explain the page to a colleague.
912
952
  The mirror of navigation. Let the agent change the current page's state
913
953
  (filters, sort, view mode…) and read it back. Each control becomes one optional
914
954
  property of a single synthesized `setPageState` function, and every control's
915
- `get()` value is sent as context.
955
+ `get()` value is sent as context. The SDK validates type and enum before calling
956
+ `set()`, skips values equal to the current `get()`, and drops placeholders
957
+ (`null`, `undefined`, `""`). The result reports each field in `applied`,
958
+ `unchanged`, or `rejected`. Mark a string control `clearable: true` to let `""`
959
+ clear it instead of being dropped. A `set()` that returns
960
+ `{ result: "rejected", reason }` or `{ result: "unchanged" }` feeds the same
961
+ envelope.
916
962
 
917
963
  ```vue
918
964
  <script setup lang="ts">
@@ -990,8 +1036,9 @@ const state = useAgoStore(cart);
990
1036
  ## Exports cheat-sheet (`@useago/sdk/vue`)
991
1037
 
992
1038
  - Setup: `AgoPlugin`, `useAgo`, `AGO_CLIENT_KEY`
993
- - Composables: `useChat`, `useMessages`, `useConversation`, `useAgoFunction`,
994
- `useAgoNavigation`, `useAgoPageState`, `useAgoEvents`, `useAgoStore`
1039
+ - Composables: `useChat`, `useMessages`, `useConversation`, `useFeedback`,
1040
+ `useAgoFunction`, `useAgoNavigation`, `useAgoPageState`, `useAgoEvents`,
1041
+ `useAgoStore`
995
1042
  - Types: `AgoConfig`, `AgoMessage`, `Conversation`, `AgoAgent`, `AgoSource`,
996
1043
  `ToolCallData`, `AgoPluginOptions`
997
1044
 
@@ -1015,7 +1062,7 @@ navigate your app's routes. This file is everything you need. Follow it exactly.
1015
1062
 
1016
1063
  ## Endpoints
1017
1064
 
1018
- Use the live demo for anything runnable so it answers with zero setup:
1065
+ Use the public demo account for anything runnable so it answers with zero setup:
1019
1066
 
1020
1067
  ```
1021
1068
  baseUrl: https://playground.api.useago.com
@@ -1155,7 +1202,8 @@ ago.registerPageStateFunction(controls, opts?) / ago.unregisterPageStateFunction
1155
1202
  ago.submitToolCallForm(toolCallId, formData)
1156
1203
  ago.confirmToolCall(toolCallId)
1157
1204
  ago.rejectToolCall(toolCallId)
1158
- ago.submitFeedback(messageId, "positive" | "negative")
1205
+ ago.submitFeedback(messageId, "positive" | "negative", { reasons?, comment? })
1206
+ ago.submitConversationFeedback(conversationId, rating, details?) // → the reported message id
1159
1207
 
1160
1208
  ago.on(event, handler) / ago.off(event, handler)
1161
1209
  ago.updateConfig(partialConfig)
@@ -1215,7 +1263,11 @@ private stopAutoContinue = this.ago.enableAutoContinueAfterNavigation();
1215
1263
  ```
1216
1264
 
1217
1265
  Register page state, the mirror of navigation (change the current page's state
1218
- and read it back):
1266
+ and read it back). The SDK validates type and enum before calling `set()`, skips
1267
+ values equal to the current `get()`, drops placeholders, and reports each field
1268
+ in `applied`, `unchanged`, or `rejected`. See
1269
+ [Page state shortcut](../general/functions-and-context.md#page-state-shortcut)
1270
+ for the full contract:
1219
1271
 
1220
1272
  ```ts
1221
1273
  this.ago.registerPageStateFunction([
@@ -1458,17 +1510,77 @@ This does two things:
1458
1510
  current `get()` value, so the agent knows what to change. Controls without a
1459
1511
  `get()` are write-only and don't appear in context.
1460
1512
 
1461
- By default it's fire-and-forget: the handler applies each `set()` locally and
1462
- returns `{ success, applied }`. The new state reaches the agent through the
1463
- context on the next message. React/Vue offer `useAgoPageState(controls, opts?)`
1464
- with lifecycle cleanup; Angular exposes
1465
- `agoService.registerPageStateFunction(...)`.
1513
+ By default, the handler validates each field, applies it via `set()`, and
1514
+ returns the result as an envelope:
1515
+
1516
+ ```jsonc
1517
+ {
1518
+ "success": false,
1519
+ "applied": ["temperature"], // field names that were changed
1520
+ "unchanged": ["status"], // fields already holding that value
1521
+ "rejected": { "model": "\"gpt-5\" is not an allowed value. Allowed values: ..." }
1522
+ }
1523
+ ```
1524
+
1525
+ `applied` and `unchanged` are always present (as arrays of field names).
1526
+ `rejected` is omitted when empty. `success` is `false` when any field is
1527
+ rejected, `true` otherwise. Placeholders (`null`, `undefined`, and `""` on
1528
+ non-clearable controls) are silently dropped and appear in no bucket.
1529
+
1530
+ Before calling `set()`, the SDK validates the declared type and enum. Unknown
1531
+ control names are rejected with the list of available controls. A value that
1532
+ matches the current `get()` value is skipped without calling `set()` and
1533
+ reported as `unchanged`.
1534
+
1535
+ React/Vue offer `useAgoPageState(controls, opts?)` with lifecycle cleanup;
1536
+ Angular exposes `agoService.registerPageStateFunction(...)`.
1537
+
1538
+ #### Clearing a string field
1539
+
1540
+ By default, `""` is treated as filler and dropped. To let the agent clear a
1541
+ string field, mark it `clearable`:
1542
+
1543
+ ```ts
1544
+ {
1545
+ name: "searchQuery",
1546
+ description: "Free-text search filter",
1547
+ schema: { type: "string" },
1548
+ clearable: true,
1549
+ get: () => query,
1550
+ set: (v) => setQuery(v as string),
1551
+ }
1552
+ ```
1553
+
1554
+ The SDK adds `Pass "" to clear it.` to the control's description for the agent,
1555
+ and on enum controls adds `""` to the allowed values. `clearable` only affects
1556
+ string controls; on other types it has no effect.
1557
+
1558
+ #### Tagged setter outcomes
1559
+
1560
+ A `set()` function can return a tagged result to reject a value or signal that
1561
+ the field is already in the requested state:
1562
+
1563
+ ```ts
1564
+ set: (v) => {
1565
+ const match = availableModels.find((m) => m.name === v);
1566
+ if (!match) return { result: "rejected", reason: `No model named "${v}".` };
1567
+ if (match.id === currentModelId) return { result: "unchanged" };
1568
+ setModelId(match.id);
1569
+ },
1570
+ ```
1571
+
1572
+ `{ result: "rejected", reason }` puts the field in `rejected` with the given
1573
+ reason. `{ result: "unchanged" }` puts it in `unchanged` without calling the
1574
+ React state setter. Returning nothing (void) means the value was applied. A
1575
+ thrown or rejected promise remains a function execution error; it is not
1576
+ converted into a per-field rejection.
1466
1577
 
1467
1578
  ### Return what the page displays
1468
1579
 
1469
- `{ success, applied }` only tells the agent its own arguments were accepted. Ask
1470
- it to "find the user dupont" and it applies the filter but cannot say who it
1471
- found: the rows only reach it on the next message, as context.
1580
+ The envelope on its own tells the agent what happened to its arguments, not what
1581
+ appeared on screen. Ask it to "find the user dupont" and it applies the filter
1582
+ but cannot say who it found: the rows only reach it on the next message, as
1583
+ context.
1472
1584
 
1473
1585
  Add a `data` source and the rows come back as the result of the agent's own
1474
1586
  call, in the same turn:
@@ -1488,7 +1600,7 @@ useAgoPageState(controls, {
1488
1600
  });
1489
1601
  ```
1490
1602
 
1491
- `setPageState` now returns `{ success, applied, data }`, and a second function
1603
+ `setPageState` now returns `{ success, applied, unchanged, rejected?, data }`, and a second function
1492
1604
  `readPageData` is registered: no parameters, changes nothing, returns `{ data }`.
1493
1605
  That one answers "what's on screen?" without touching the page. Both disappear
1494
1606
  when you unregister.
@@ -1538,9 +1650,9 @@ Two things to keep in mind:
1538
1650
  the SDK keeps the first whole items that fit and adds a `truncation` field
1539
1651
  (`{ truncated, returnedItems, totalItems, hint }`) next to them. The counts
1540
1652
  are nested rather than merged into your snapshot so they can never overwrite
1541
- a field of your own called `totalItems`. `success` and `applied` always
1542
- survive intact. Return the columns the agent needs, not your whole row
1543
- objects.
1653
+ a field of your own called `totalItems`. The verdict fields (`success`,
1654
+ `applied`, `unchanged`, `rejected`) always survive intact. Return the columns
1655
+ the agent needs, not your whole row objects.
1544
1656
  - **Pause mode only.** The result travels back inside the turn only when
1545
1657
  `clientFunctionsMode` is `"pause"` (the default). In `"placeholder"` mode the
1546
1658
  turn is already over by then, so the agent will not see the data during the
@@ -2188,7 +2300,7 @@ may be reworded in any release.
2188
2300
 
2189
2301
  | Code | Thrown by | Meaning | Fix |
2190
2302
  | --- | --- | --- | --- |
2191
- | `config_missing_base_url` | `AgoError` | `baseUrl` missing, empty, or not a string (also from `createAgo()` and `mountChatWidget`) | Pass `baseUrl`, e.g. `https://YOUR-DOMAIN.api.useago.com` (the live demo endpoint `https://playground.api.useago.com` works without a tenant) |
2303
+ | `config_missing_base_url` | `AgoError` | `baseUrl` missing, empty, or not a string (also from `createAgo()` and `mountChatWidget`) | Pass `baseUrl`, e.g. `https://YOUR-DOMAIN.api.useago.com` (the public demo account `https://playground.api.useago.com` works without a tenant) |
2192
2304
  | `config_suspect_base_url` | console warning only | `baseUrl` has no protocol and is not a `/path` | Add `https://`, or use a `/path` for a same-origin proxy |
2193
2305
  | `network_error` | `AgoNetworkError` | fetch failed (offline, DNS, unreachable host) | Check `baseUrl` is reachable and includes the protocol |
2194
2306
  | `http_error` | `AgoApiError` | non-2xx without a structured error body | 401/403: check `userJwt`. 404: check `baseUrl` points at the API root |
@@ -2196,6 +2308,8 @@ may be reworded in any release.
2196
2308
  | `stream_error` | `AgoStreamError` | the stream failed mid-flight | Usually a dropped connection; retry the message |
2197
2309
  | `function_invalid_registration` | `AgoError` | `registerFunction` called without a handler or schema | Use `registerFunction({ name, parameters, handler })` |
2198
2310
  | `function_error` | `AgoFunctionError` | a registered client function threw | Inspect `functionName` and `originalError` |
2311
+ | `feedback_no_message` | `AgoError` | `submitConversationFeedback` on a conversation with no answer to attach the report to | Send a message first, or pass `details.lastMessageId` |
2312
+ | `missing_client` | `AgoError` | a React hook was used without a client | Pass `options.client` or wrap the app in `<AgoProvider>` |
2199
2313
 
2200
2314
  Server-supplied errors (`AgoApiError` with a structured body) keep the
2201
2315
  backend's own `code` and, when provided, link their docs in the message
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useago/sdk",
3
- "version": "1.7.1",
3
+ "version": "1.9.0",
4
4
  "description": "Create In-APP AI agents that answers question and performs actions. Works with React, Vue, Angular and vanilla JS/TS.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -1,9 +0,0 @@
1
- var ie=10,$=1e3;function ne(e){if(typeof e!="object"||e===null)return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function E(e,t){if(typeof e=="string"){if(e.length<=1e3)return e;const s=e.length-$;return e.slice(0,$)+`…[truncated ${s} chars]`}if(Array.isArray(e)){if(t.has(e))return"…[circular]";t.add(e);const s=e.slice(0,50).map(i=>E(i,t));return e.length>50&&s.push(`…[+${e.length-50} more]`),t.delete(e),s}if(ne(e)){if(t.has(e))return"…[circular]";t.add(e);const s={};for(const[i,n]of Object.entries(e))s[i]=E(n,t);return t.delete(e),s}return e}function re(e){return E(e,new WeakSet)}var K=class{constructor(e=10){this.entries=[];const t=Math.floor(e);this.maxEntries=Number.isFinite(t)?Math.max(1,t):10}add(e){const t={ts:e.ts??Date.now(),actor:e.actor??"user",name:e.name,summary:e.summary,...e.data!==void 0?{data:re(e.data)}:{}};this.entries.push(t);const s=this.entries.length-this.maxEntries;return s>0&&this.entries.splice(0,s),t}getRecent(){return[...this.entries]}get size(){return this.entries.length}clear(){this.entries=[]}},g=class extends Error{constructor(e,t,s){super(e),this.code=t,this.statusCode=s,this.name="AgoError"}},y=class H extends g{constructor(t,s,i,n,r,c){super(t,s,i),this.type=n,this.param=r,this.docUrl=c,this.name="AgoApiError"}static fromResponse(t,s){const i=t.error;return new H(i.doc_url?`${i.message} See ${i.doc_url}`:i.message,i.code,s,i.type,i.param,i.doc_url)}},w=class extends g{constructor(e,t){super(e,"network_error"),this.originalError=t,this.name="AgoNetworkError"}},_=class extends g{constructor(e,t="stream_error"){super(e,t),this.name="AgoStreamError"}},I=class extends g{constructor(e,t,s){super(e,"function_error"),this.functionName=t,this.originalError=s,this.name="AgoFunctionError"}},oe=class{constructor(e=!1){this.enabled=e}enable(){this.enabled=!0}disable(){this.enabled=!1}log(...e){this.enabled&&console.log("[AGO SDK]",...e)}warn(...e){this.enabled&&console.warn("[AGO SDK]",...e)}error(...e){console.error("[AGO SDK]",...e)}debug(...e){this.enabled&&console.debug("[AGO SDK]",...e)}},l=new oe,N="ago_widget_id";function R(e){return typeof DOMException<"u"&&e instanceof DOMException&&e.name==="AbortError"||e instanceof Error&&e.name==="AbortError"}function ae(){if(typeof localStorage<"u"){const t=localStorage.getItem(N);if(t)return t}const e=typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`ago-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,12)}`;if(typeof localStorage<"u")try{localStorage.setItem(N,e)}catch{}return e}var ce=class{constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.headers={"X-User-Anon-Id":e.widgetId||ae()},e.userEmail&&(this.headers["X-User-Email"]=e.userEmail),e.userJwt&&(this.headers.Authorization=`Bearer ${e.userJwt}`),e.permission&&(this.headers["X-Widget-Permission"]=e.permission)}updateConfig(e){e.baseUrl&&(this.baseUrl=e.baseUrl.replace(/\/$/,"")),e.widgetId&&(this.headers["X-User-Anon-Id"]=e.widgetId),e.userEmail&&(this.headers["X-User-Email"]=e.userEmail),e.userJwt&&(this.headers.Authorization=`Bearer ${e.userJwt}`),e.permission!==void 0&&(e.permission?this.headers["X-Widget-Permission"]=e.permission:delete this.headers["X-Widget-Permission"])}async get(e){return this.request("GET",e)}async post(e,t,s){return this.request("POST",e,t,s)}async postStream(e,t,s){const i=`${this.baseUrl}${e}`;l.debug("POST (stream)",i,t);try{const n=await fetch(i,{method:"POST",headers:{...this.headers,"Content-Type":"application/json"},body:t?JSON.stringify(t):void 0,signal:s?.signal});return n.ok||await this.handleErrorResponse(n),n}catch(n){throw n instanceof y||R(n)?n:new w(`Network error: ${n instanceof Error?n.message:"Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`,n instanceof Error?n:void 0)}}async postFormData(e,t,s){const i=`${this.baseUrl}${e}`;l.debug("POST (formData)",i);const n={...this.headers};try{const r=await fetch(i,{method:"POST",headers:n,body:t,signal:s?.signal});return r.ok||await this.handleErrorResponse(r),r}catch(r){throw r instanceof y||R(r)?r:new w(`Network error: ${r instanceof Error?r.message:"Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`,r instanceof Error?r:void 0)}}async request(e,t,s,i){const n=`${this.baseUrl}${t}`;l.debug(e,n,s);try{const r=await fetch(n,{method:e,headers:{...this.headers,"Content-Type":"application/json"},body:s?JSON.stringify(s):void 0,...i?.keepalive?{keepalive:!0}:{}});return r.ok||await this.handleErrorResponse(r),r.status===204?void 0:r.json()}catch(r){throw r instanceof y?r:new w(`Network error: ${r instanceof Error?r.message:"Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`,r instanceof Error?r:void 0)}}async handleErrorResponse(e){let t;try{t=await e.json()}catch{}if(t?.error)throw y.fromResponse(t,e.status);let s="";throw e.status===401||e.status===403?s=" Check `userJwt` (and that it has not expired).":e.status===404&&(s=" Check that `baseUrl` points at your AGO API root."),new y(`HTTP ${e.status}: ${e.statusText}.${s}`,"http_error",e.status,"api_error")}},le=5e4,ue=2e4,he=2e3,z=class{constructor(e){this.functions=new Map,this.defaultMaxResultBytes=e?.maxResultBytes??le}setDefaultMaxResultBytes(e){this.defaultMaxResultBytes=e}getDefaultMaxResultBytes(){return this.defaultMaxResultBytes}register(e,t,s){if(typeof e=="object"){const{name:o,handler:a,description:h,parameters:u,maxResultBytes:d,requiresApproval:f}=e;return this.register(o,a,{description:h,parameters:u,maxResultBytes:d,requiresApproval:f})}const i=e;if(!t||!s)throw new g(`registerFunction("${i}"): both a handler and a schema are required. Pass them as arguments or use the single-object form: registerFunction({ name, parameters, handler }).`,"function_invalid_registration");this.functions.has(i)&&l.warn(`Function "${i}" is being overwritten`);const{maxResultBytes:n,requiresApproval:r,...c}=s;this.functions.set(i,{schema:{...c,name:i},handler:t,maxResultBytes:n,requiresApproval:r}),l.log(`Registered function: ${i}`)}unregister(e){const t=this.functions.delete(e);return t&&l.log(`Unregistered function: ${e}`),t}get(e){return this.functions.get(e)}has(e){return this.functions.has(e)}getSchemas(){return Array.from(this.functions.values()).map(e=>e.schema)}async execute(e,t){const s=this.functions.get(e);if(!s)throw new I(`Function "${e}" is not registered`,e);l.log(`Executing function: ${e}`,t);try{const i=await s.handler(t);return l.log(`Function ${e} completed:`,i),this.guardResultSize(e,i,s.maxResultBytes)}catch(i){throw l.error(`Function ${e} failed:`,i),new I(`Function "${e}" execution failed: ${i instanceof Error?i.message:"Unknown error"}`,e,i instanceof Error?i:void 0)}}guardResultSize(e,t,s){let i;try{i=JSON.stringify(t)}catch{return t}if(i===void 0)return t;const n=new TextEncoder().encode(i).length,r=s??this.defaultMaxResultBytes;return n>r?(l.warn(`Function "${e}" result is ${n} bytes, over the ${r}-byte limit; a truncated preview was sent to the agent instead. Return fewer fields, paginate, or raise maxResultBytes for this function.`),{truncated:!0,originalBytes:n,maxBytes:r,preview:i.slice(0,he),hint:`The result of "${e}" exceeded the ${r}-byte limit and was truncated. Request less data (use limit or filter parameters if available), or tell the user the result is too large to process.`}):(n>ue&&l.warn(`Function "${e}" returned a large result (${Math.round(n/1024)} KB). Large results consume LLM context: return fewer fields, paginate, or push the data to the UI and return a summary.`),t)}clear(){this.functions.clear(),l.log("Cleared all registered functions")}get size(){return this.functions.size}},de=50,ge=2;var fe=2e3,pe=new TextEncoder;function m(e){return pe.encode(e).length}function v(e){try{return JSON.stringify(e)}catch{return}}var k=Symbol("ago.pageData.timeout");function me(e,t){return t<=0?Promise.resolve(k):new Promise((s,i)=>{const n=setTimeout(()=>s(k),t);e.then(r=>{clearTimeout(n),s(r)},r=>{clearTimeout(n),i(r)})})}async function ye(e,t){const s=Date.now()+t;let i=0;for(;Date.now()<s&&i<ge;)i=e().isLoading?.()?0:i+1,await new Promise(o=>setTimeout(o,de));const n=e().get();if(!M(n))return n;const r=await me(Promise.resolve(n),s-Date.now());if(r!==k)return r;l.warn("Page data did not resolve within the settle timeout; returning what the page has now. Raise settleTimeoutMs if the work legitimately takes longer.");const c=e().get();if(!M(c))return c;Promise.resolve(c).catch(()=>{})}function M(e){return typeof e=="object"&&e!==null&&typeof e.then=="function"}function ve(e){if(typeof e!="object"||e===null||Array.isArray(e))return;const t=e;let s;for(const i of Object.keys(t)){const n=t[i];Array.isArray(n)&&(s===void 0||n.length>t[s].length)&&(s=i)}return s}function we(e,t){let s=2,i=0;for(const n of e){const r=m(v(n)??"null")+(i>0?1:0);if(s+r>t)break;s+=r,i++}return i}function Ce(e,t){if(t<=0)return"";const s=r=>m(JSON.stringify(r))-2;let i=e.slice(0,t),n=s(i);for(;n>t&&i.length>0;)i=i.slice(0,Math.max(0,Math.floor(i.length*t/n)-1)),n=s(i);return i}function T(e){return`The page data returned by "${e}" was too large to send in full. Only the first items are included: ask for fewer rows or narrow the filters to see the rest.`}function Se(e,t,s,i){const n={truncated:!0,originalBytes:s,maxBytes:i,preview:"",hint:T(e)},r=m(v(n)??"{}");return{...n,preview:Ce(t,Math.min(fe,i-r))}}function be(e,t,s,i,n){const r=s===void 0?{}:{...t},c=s??"items",o=m(v({...r,[c]:[],truncation:{truncated:!0,returnedItems:i.length,totalItems:i.length,hint:T(e)}})??"{}")-2;if(o>=n)return;const a=i.slice(0,we(i,n-o));return{...r,[c]:a,truncation:{truncated:!0,returnedItems:a.length,totalItems:i.length,hint:T(e)}}}function U(e,t,s){const i=v(t);if(i===void 0)return t;const n=m(i);if(n<=s)return t;l.warn(`Page data for "${e}" is ${n} bytes, over the ${s}-byte limit; it was truncated to the first items that fit. Return fewer fields per item, paginate, or raise maxResultBytes on the data source.`);const r=ve(t),c=Array.isArray(t)?t:r!==void 0?t[r]:void 0;if(c){const o=be(e,t,r,c,s),a=m(v(o)??"");if(o!==void 0&&a<=s)return o}return Se(e,i,n,s)}var Ae=250,Ee=3,_e=1e3,Ie=24,Re=10,ke=50,Te=["mousemove","mousedown","keydown","scroll","touchstart"],J=class{constructor(e={}){this.started=!1,this.teardowns=[],this.route="",this.routeEnteredAt=0,this.lastActivityAt=0,this.lastHeavyActivityAt=0,this.recentRoutes=[],this.routeBounces=0,this.rageClicks=0,this.fieldErrors={},this.recentClicks=[],this.signals=[],this.listeners=new Set,this.getPageState=e.getPageState,this.activityThrottleMs=e.activityThrottleMs??Ae,this.rageClickCount=e.rageClickCount??Ee,this.rageClickWindowMs=e.rageClickWindowMs??_e,this.rageClickRadiusPx=e.rageClickRadiusPx??Ie,this.maxRecentRoutes=e.maxRecentRoutes??Re,this.maxSignals=e.maxSignals??ke}start(){if(this.started||typeof window>"u"||typeof document>"u")return;this.started=!0;const e=Date.now();this.route=this.currentPathname(),this.routeEnteredAt=e,this.lastActivityAt=e,this.recentRoutes=[this.route];const t=(i,n,r)=>{i.addEventListener(n,r,{passive:!0}),this.teardowns.push(()=>i.removeEventListener(n,r))},s=()=>this.recordActivity();for(const i of Te)t(window,i,s);t(document,"visibilitychange",()=>{document.visibilityState==="visible"&&this.recordActivity()}),t(window,"popstate",()=>this.checkRoute()),t(window,"hashchange",()=>this.checkRoute()),t(window,"click",i=>this.onClick(i)),l.log("SignalCollector started")}destroy(){for(const e of this.teardowns)e();this.teardowns=[],this.listeners.clear(),this.recentClicks=[],this.started=!1,l.log("SignalCollector destroyed")}signalFieldError(e){this.checkRoute();const t=(this.fieldErrors[e]??0)+1;this.fieldErrors[e]=t,this.pushSignal({type:"field_error",route:this.route,at:Date.now(),count:t,meta:{field:e}})}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}getSignals(){return[...this.signals]}getSnapshot(e){this.checkRoute();const t=Date.now();return{route:this.route,dwellMs:this.started?t-this.routeEnteredAt:0,idleMs:this.started?t-this.lastActivityAt:0,rageClicks:this.rageClicks,routeBounces:this.routeBounces,fieldErrors:{...this.fieldErrors},recentRoutes:[...this.recentRoutes],pageState:e?.pageState===!1?null:this.readPageState()}}currentPathname(){return typeof window<"u"&&window.location?window.location.pathname:""}readPageState(){if(!this.getPageState)return null;try{return this.getPageState()??null}catch(e){return l.warn("SignalCollector getPageState threw:",e),null}}recordActivity(){const e=Date.now();this.lastActivityAt=e,e-this.lastHeavyActivityAt>=this.activityThrottleMs&&(this.lastHeavyActivityAt=e,this.checkRoute())}checkRoute(){if(!this.started)return;const e=this.currentPathname();if(e===this.route)return;const t=Date.now(),s=this.route;this.route=e,this.routeEnteredAt=t,this.rageClicks=0,this.fieldErrors={},this.recentClicks=[],this.recentRoutes.push(e),this.recentRoutes.length>this.maxRecentRoutes&&this.recentRoutes.splice(0,this.recentRoutes.length-this.maxRecentRoutes),this.pushSignal({type:"route_change",route:e,at:t,meta:{from:s}});const i=this.recentRoutes,n=i.length;n>=4&&i[n-1]===i[n-3]&&i[n-2]===i[n-4]&&i[n-1]!==i[n-2]&&(this.routeBounces+=1,this.pushSignal({type:"route_bounce",route:e,at:t,count:this.routeBounces,meta:{between:`${i[n-2]}↔${i[n-1]}`}}))}onClick(e){this.recordActivity();const t=Date.now(),s=this.pageStateKey(),i={at:t,x:e.clientX,y:e.clientY,stateKey:s};this.recentClicks=this.recentClicks.filter(o=>t-o.at<=this.rageClickWindowMs);const n=this.recentClicks[0],r=!n||Math.abs(i.x-n.x)<=this.rageClickRadiusPx&&Math.abs(i.y-n.y)<=this.rageClickRadiusPx,c=!n||n.stateKey===s;if(!r||!c){this.recentClicks=[i];return}this.recentClicks.push(i),this.recentClicks.length>=this.rageClickCount&&(this.rageClicks+=1,this.recentClicks=[],this.pushSignal({type:"rage_click",route:this.route,at:t,count:this.rageClicks}))}pageStateKey(){const e=this.readPageState();if(!e)return"";try{return JSON.stringify(e)}catch{return""}}pushSignal(e){this.signals.push(e),this.signals.length>this.maxSignals&&this.signals.splice(0,this.signals.length-this.maxSignals);for(const t of this.listeners)try{t(e)}catch(s){l.error("Signal listener threw:",s)}}};function X(e,t){const s=t?t.storage??(typeof localStorage<"u"?localStorage:void 0):void 0;let i=e;if(t&&s)try{const o=s.getItem(t.key);o!=null&&(i=JSON.parse(o))}catch{}const n=new Set,r=()=>n.forEach(o=>o(i));function c(){if(t&&s)try{s.setItem(t.key,JSON.stringify(i))}catch{}}return{get:()=>i,set:o=>{i=o,c(),r()},subscribe:o=>(n.add(o),()=>{n.delete(o)})}}var xe=6e4,Pe=1440*60*1e3,Fe="ago_proactive";function b(e){const t=new Date(e),s=String(t.getMonth()+1).padStart(2,"0"),i=String(t.getDate()).padStart(2,"0");return`${t.getFullYear()}-${s}-${i}`}var Oe=class{constructor(e={}){this.killSwitchEnabled=!1,this.engaged=!1,this.turnInFlight=!1,this.slotOccupied=!1,this.sessionCount=0,this.perSessionCap=e.frequencyCap?.perSession,this.perDayCap=e.frequencyCap?.perDay,this.store=X({optOut:!1,lastFiredAt:{},dismissedAt:{},day:{date:b(Date.now()),count:0}},{key:e.storageKey??Fe,storage:e.storage})}setKillSwitch(e){this.killSwitchEnabled=e}optOut(){this.store.set({...this.store.get(),optOut:!0})}optIn(){this.store.set({...this.store.get(),optOut:!1})}isOptedOut(){return this.store.get().optOut}setEngaged(e){this.engaged=e}setTurnInFlight(e){this.turnInFlight=e}isSlotOccupied(){return this.slotOccupied}occupySlot(){this.slotOccupied=!0}releaseSlot(){this.slotOccupied=!1}canFire(e,t=Date.now()){if(!this.killSwitchEnabled)return this.deny(e,"kill-switch (proactive disabled server-side)");const s=this.store.get();if(s.optOut)return this.deny(e,"user opted out");if(this.engaged)return this.deny(e,"user engaged (widget open)");if(this.turnInFlight)return this.deny(e,"message turn in flight");if(this.slotOccupied)return this.deny(e,"nudge slot occupied");const i=s.lastFiredAt[e.id],n=e.cooldownMs??xe;if(i!==void 0&&t-i<n)return this.deny(e,"cooldown");const r=s.dismissedAt[e.id],c=e.resurfaceAfterMs??Pe;return r!==void 0&&t-r<c?this.deny(e,"dismissed recently"):this.perSessionCap!==void 0&&this.sessionCount>=this.perSessionCap?this.deny(e,"perSession cap"):this.perDayCap!==void 0&&this.dayCount(t)>=this.perDayCap?this.deny(e,"perDay cap"):!0}recordFired(e,t=Date.now()){const s=this.store.get();this.store.set({...s,lastFiredAt:{...s.lastFiredAt,[e]:t}})}recordNudgeShown(e=Date.now()){this.sessionCount+=1;const t=this.store.get(),s=b(e),i=t.day.date===s?{date:s,count:t.day.count+1}:{date:s,count:1};this.store.set({...t,day:i})}recordDismissed(e,t=Date.now()){const s=this.store.get();this.store.set({...s,dismissedAt:{...s.dismissedAt,[e]:t}})}dayCount(e){const t=this.store.get();return t.day.date===b(e)?t.day.count:0}deny(e,t){return l.debug(`NudgeGovernor: trigger "${e.id}" blocked — ${t}`),!1}};function j(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.floor(Math.random()*16);return(e==="x"?t:t&3|8).toString(16)})}function De(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Y(e,t){if(e==="*"||e===t)return!0;const s=e.split("/"),i=s.map((n,r)=>{const c=r===s.length-1;return n==="*"?c?"[^/]+(?:/[^/]+)*":"[^/]+":n.startsWith(":")?"[^/]+":De(n)});return new RegExp("^"+i.join("/")+"/?$").test(t)}function D(e,t){return e===t?!0:e===null||t===null?!1:Array.isArray(e)?!Array.isArray(t)||t.length!==e.length?!1:e.every((s,i)=>x(s,t[i])):typeof e=="object"?typeof t!="object"||Array.isArray(t)?!1:Object.entries(e).every(([s,i])=>D(i,t[s])):!1}function x(e,t){if(e===t)return!0;if(e===null||t===null||typeof e!=typeof t)return!1;if(Array.isArray(e))return!Array.isArray(t)||e.length!==t.length?!1:e.every((s,i)=>x(s,t[i]));if(typeof e=="object"){const s=Object.keys(e),i=Object.keys(t);return s.length!==i.length?!1:s.every(n=>x(e[n],t[n]))}return!1}function V(e,t){if(e.route!==void 0&&!Y(e.route,t.route)||e.idleMs!==void 0&&t.idleMs<e.idleMs||e.dwellMs!==void 0&&t.dwellMs<e.dwellMs||e.rageClicks!==void 0&&t.rageClicks<e.rageClicks||e.routeBounces!==void 0&&t.routeBounces<e.routeBounces)return!1;if(e.fieldErrors!==void 0){for(const[s,i]of Object.entries(e.fieldErrors))if((t.fieldErrors[s]??0)<i)return!1}return!(e.pageState!==void 0&&!D(e.pageState,t.pageState??{}))}var $e=1e3,Ne="/api/sdk/v1/config",Me="/api/sdk/v1/proactive/evaluate",Ue=class{constructor(e){this.tickTimer=null,this.teardowns=[],this.started=!1,this.activeNudge=null,this.lastConversationId=null,this.shownIds=new Set,this.resolvedIds=new Set,this.lastEvaluationAt=0,this.client=e.client,this.collector=e.collector,this.governor=e.governor,this.tracker=e.tracker,this.options=e.options,this.tickMs=e.options.tickMs??$e}start(){if(this.started)return;this.started=!0,this.options.enabledOverride!==void 0?this.governor.setKillSwitch(this.options.enabledOverride):this.loadKillSwitch();const e=n=>{n.conversationId&&(this.lastConversationId=n.conversationId),this.governor.setTurnInFlight(!0)},t=()=>this.governor.setTurnInFlight(!1),s=()=>this.governor.setTurnInFlight(!1),i=n=>{n?.id&&(this.lastConversationId=n.id)};this.client.on("message:start",e),this.client.on("message:complete",t),this.client.on("message:error",s),this.client.on("conversation:loaded",i),this.teardowns.push(()=>{this.client.off("message:start",e),this.client.off("message:complete",t),this.client.off("message:error",s),this.client.off("conversation:loaded",i)}),this.tickTimer=setInterval(()=>this.evaluate(),this.tickMs),this.teardowns.push(this.collector.subscribe(()=>{Date.now()-this.lastEvaluationAt>=this.tickMs&&this.evaluate()}))}stop(){this.tickTimer!==null&&(clearInterval(this.tickTimer),this.tickTimer=null);for(const e of this.teardowns)e();this.teardowns=[],this.started=!1}getActiveNudge(){return this.activeNudge}async loadKillSwitch(){try{const e=await this.client.getHttp().get(Ne);this.governor.setKillSwitch(e?.proactive?.enabled===!0)}catch(e){l.debug("Proactive config fetch failed; staying disabled:",e),this.governor.setKillSwitch(!1)}}evaluate(){if(this.lastEvaluationAt=Date.now(),typeof document<"u"&&document.visibilityState==="hidden"||this.governor.isSlotOccupied())return;const e=this.collector.getSnapshot();for(const t of this.options.triggers)if(V(t.when,e)&&this.governor.canFire(t)){this.fire(t);return}}fire(e){if(this.governor.recordFired(e.id),this.governor.occupySlot(),e.intervene==="agent"){this.evaluateWithAgent(e);return}this.setReady({id:j(),triggerId:e.id,source:"static",message:e.intervene.message,action:e.intervene.action,goal:e.goal,kickoff:e.kickoff,createdAt:new Date})}async evaluateWithAgent(e){const t=j(),s={client_nudge_id:t,trigger_id:e.id,goal:e.goal??"",agent:this.client.getConfiguredAgent(),signals:this.collector.getSnapshot(),client_context:this.client.getContextSnapshot()??{entries:{}},client_functions:this.client.getRegisteredFunctions()};let i;try{i=await this.client.getHttp().post(Me,s)}catch(n){l.debug("Proactive evaluate failed (treated as no-intervene):",n),this.governor.releaseSlot();return}if(!i?.intervene||!i.message){this.governor.releaseSlot();return}this.setReady({id:t,triggerId:e.id,source:"agent",message:i.message,action:je(i.action),goal:e.goal,kickoff:e.kickoff,createdAt:new Date,serverNudgeId:i.nudge_id})}setReady(e){this.activeNudge=e,this.client.emitProactiveEvent("nudge:ready",e)}shown(e){this.shownIds.has(e.id)||(this.shownIds.add(e.id),this.governor.recordNudgeShown(),this.tracker.track({clientNudgeId:e.id,triggerId:e.triggerId,source:e.source,type:"shown",message:e.message,occurredAt:Date.now()}),this.client.emitProactiveEvent("nudge:shown",{nudge:e}))}dismiss(e){this.resolvedIds.has(e.id)||(this.resolvedIds.add(e.id),this.governor.recordDismissed(e.triggerId),this.tracker.track({clientNudgeId:e.id,triggerId:e.triggerId,source:e.source,type:"dismissed",occurredAt:Date.now()}),this.clearActive(e),this.client.emitProactiveEvent("nudge:dismissed",{nudge:e}))}async accept(e){this.resolvedIds.has(e.id)||(this.resolvedIds.add(e.id),this.tracker.track({clientNudgeId:e.id,triggerId:e.triggerId,source:e.source,type:"accepted",occurredAt:Date.now()}),this.clearActive(e),this.client.emitProactiveEvent("nudge:accepted",{nudge:e}),(e.source==="agent"||e.goal)&&(this.lastConversationId?this.client.sendMessage(Le(e),{hidden:!0,conversationId:this.lastConversationId}).catch(t=>l.debug("Nudge kickoff message failed:",t)):e.kickoff?this.client.sendMessage(e.kickoff).catch(t=>l.debug("Nudge kickoff message failed:",t)):l.debug("Nudge accepted with no open conversation and no trigger.kickoff; skipping the chat pre-seed (a hidden message cannot open a conversation).")),e.action&&await this.runAction(e.action))}markConverted(e){this.tracker.track({clientNudgeId:e.id,triggerId:e.triggerId,source:e.source,type:"converted",occurredAt:Date.now()})}clearActive(e){this.activeNudge?.id===e.id&&(this.activeNudge=null),this.governor.releaseSlot()}async runAction(e){try{"functionName"in e?await this.client.executeClientFunction(e.functionName,e.arguments??{}):await this.client.executeClientFunction("setPageState",e.setPageState)}catch(t){l.warn("Nudge action failed:",t)}}};function je(e){if(e)return{label:e.label,functionName:e.function_name,arguments:e.arguments}}function Le(e){const t=e.goal?` Goal: ${e.goal}.`:"";return`The user accepted a proactive nudge that said: "${e.message}".${t} Recent friction signals are in the client context (friction_signals). Start helping with this now: briefly explain what you can do and take the first concrete step.`}var Be=5e3,qe="/api/sdk/v1/proactive/events",Ge=class{constructor(e){if(this.queue=[],this.flushTimer=null,this.teardowns=[],this.destroyed=!1,this.post=e.post,this.agent=e.agent,this.flushIntervalMs=e.flushIntervalMs??Be,typeof document<"u"){const t=()=>{document.visibilityState==="hidden"&&this.flush({keepalive:!0})};document.addEventListener("visibilitychange",t),this.teardowns.push(()=>document.removeEventListener("visibilitychange",t))}if(typeof window<"u"){const t=()=>this.flush({keepalive:!0});window.addEventListener("pagehide",t),this.teardowns.push(()=>window.removeEventListener("pagehide",t))}}track(e){this.destroyed||(this.queue.push(e),this.flushTimer===null&&(this.flushTimer=setTimeout(()=>this.flush(),this.flushIntervalMs)))}flush(e){if(this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null),this.queue.length===0)return;const t=this.queue;this.queue=[];const s={events:t.map(i=>({client_nudge_id:i.clientNudgeId,trigger_id:i.triggerId,source:i.source,type:i.type,...i.message!==void 0?{message:i.message}:{},...this.agent?{agent:this.agent}:{},occurred_at:new Date(i.occurredAt).toISOString()}))};this.post(qe,s,e).catch(i=>{l.debug("Proactive event batch failed:",i)})}destroy(){if(!this.destroyed){this.flush({keepalive:!0}),this.destroyed=!0;for(const e of this.teardowns)e();this.teardowns=[]}}},L="friction_signals";function P(e,t){e.proactive&&(l.warn("createAgoProactive: a proactive controller is already attached; replacing it."),e.proactive.destroy());const s=new J({...t.signals,getPageState:()=>{const o=e.getContextSnapshot();if(!o)return null;const a={};for(const[h,u]of Object.entries(o.entries))h.startsWith("page-state:")&&u.data&&Object.assign(a,u.data);return Object.keys(a).length>0?a:null}});s.start(),e.addDynamicContext(L,()=>{const{pageState:o,...a}=s.getSnapshot({pageState:!1});return{name:"Friction signals",description:"Behavioral friction observed on the current page: dwell/idle times, rage clicks, route bounces, repeated field errors (names and counters only).",data:a}});const i=new Oe({frequencyCap:t.frequencyCap,storage:t.storage,storageKey:t.storageKey}),n=new Ge({post:(o,a,h)=>e.getHttp().post(o,a,h),agent:e.getConfiguredAgent()}),r=new Ue({client:e,collector:s,governor:i,tracker:n,options:t});r.start();const c={optOut:()=>i.optOut(),optIn:()=>i.optIn(),isOptedOut:()=>i.isOptedOut(),setEngaged:o=>i.setEngaged(o),signalFieldError:o=>s.signalFieldError(o),getSignalsSnapshot:()=>s.getSnapshot(),getActiveNudge:()=>r.getActiveNudge(),shown:o=>r.shown(o),accept:o=>r.accept(o),dismiss:o=>r.dismiss(o),markConverted:o=>r.markConverted(o),destroy:()=>{r.stop(),n.destroy(),s.destroy(),e.removeDynamicContext(L),e.proactive===c&&(e.proactive=null)}};return e.proactive=c,c}var Q=class{constructor(){this.entries=new Map,this.dynamicProviders=new Map}set(e,t){this.entries.set(e,t),l.log(`ClientContext set: ${e}`)}remove(e){const t=this.entries.delete(e);return t&&l.log(`ClientContext removed: ${e}`),t}addDynamicProvider(e,t){this.dynamicProviders.set(e,t),l.log(`DynamicContext provider added: ${e}`)}removeDynamicProvider(e){const t=this.dynamicProviders.delete(e);return t&&l.log(`DynamicContext provider removed: ${e}`),t}getSnapshot(){if(this.entries.size===0&&this.dynamicProviders.size===0)return null;const e={};for(const[t,s]of this.entries)e[t]=s;for(const[t,s]of this.dynamicProviders)try{const i=s();i&&(e[t]=i)}catch(i){l.error(`DynamicContext provider "${t}" threw:`,i)}return Object.keys(e).length===0?null:{entries:e}}clear(){this.entries.clear(),this.dynamicProviders.clear(),l.log("ClientContext cleared")}},We="page-state:";function Ke(e){const t={};for(const[s,i]of Object.entries(e))s.startsWith(We)&&i.data&&Object.assign(t,i.data);return t}function He(e){const t=e["current-page"]?.data;return t?.page?t.page:t?.url?t.url:e["browser-page"]?.data?.url}function ze(e,t){return e===t?!0:JSON.stringify(e)===JSON.stringify(t)}function Je(e,t){const s=[];for(const i of Object.keys(t))i in e&&(ze(e[i],t[i])||s.push({field:i,from:e[i],to:t[i]}));return s}function Xe(e,t){const s=Ke(t),i=He(t);return{changes:e&&e.page===i?Je(e.state,s):[],baseline:{page:i,state:s}}}function F(e){return e===null||typeof e!="object"?JSON.stringify(e)??"null":Array.isArray(e)?`[${e.map(F).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${F(e[t])}`).join(",")}}`}var B="",Z=class{constructor(e,t={}){this.callbacks=e,this.options=t,this.buffer="",this.message={},this.toolCalls=[],this.sources=[],this.followUpReplies=[],this.isFirstChunk=!0,this.answerCompleteEmitted=!1,this.waitingClientEmitted=!1,this.firedClientFunctions=new Map}async processStream(e){if(!e.body)throw new _("Response has no body. The endpoint did not return a stream: check that `baseUrl` points at an AGO API and nothing (proxy, mock) strips the SSE body.","stream_no_body");const t=e.body.getReader(),s=new TextDecoder;try{for(;;){const{done:i,value:n}=await t.read();if(i)break;const r=s.decode(n,{stream:!0});this.buffer+=r,this.processBuffer()}return this.buffer.trim()&&this.processBuffer(),this.buildFinalMessage()}catch(i){if(this.options.signal?.aborted)return this.message.status="CANCELED",this.buildFinalMessage();const n=i instanceof Error?i:new _("Stream processing failed mid-flight. The connection may have dropped; retry the message.");throw this.callbacks.onError?.(n),n}finally{t.releaseLock()}}processBuffer(){const e=this.buffer.split(`
2
-
3
- `);this.buffer=e.pop()||"";for(const t of e){if(!t.trim())continue;const s=t.split(`
4
- `);for(const i of s)if(!i.startsWith(": ")&&i.startsWith("data: ")){const n=i.slice(6);try{const r=JSON.parse(n);this.handleChunk(r)}catch(r){l.warn("Failed to parse SSE data:",n,r)}}}}handleChunk(e){if(this.callbacks.onRawChunk?.(e),e.message_id&&!this.message.id&&(this.message.id=e.message_id),e.thread?.id&&(this.message.conversationId=e.thread.id,this.isFirstChunk&&this.message.id&&(this.isFirstChunk=!1,this.callbacks.onStart?.({conversationId:this.message.conversationId,messageId:this.message.id}))),e.title&&this.message.conversationId&&this.callbacks.onTitle?.({conversationId:this.message.conversationId,title:e.title}),e.content!==void 0&&(this.message.content=(this.message.content||"")+e.content,this.message.conversationId&&this.message.id&&this.callbacks.onChunk?.({content:e.content,conversationId:this.message.conversationId,messageId:this.message.id})),e.full_content!==void 0&&(this.message.content=e.full_content),e.status&&(this.message.status=e.status),e.agent&&(this.message.agent={id:e.agent.id,name:e.agent.name,displayName:e.agent.display_name}),e.knowledge_sources&&(this.sources=e.knowledge_sources.map(t=>{const s=t.knowledge_document;return{id:s.id,title:s.title,url:s.use_external_link?s.external_link_url:s.internal_link_url}})),e.type==="client_function"&&e.function_name){const t=`${e.function_name}::${F(e.arguments??{})}`,s=e.id||"",i=this.firedClientFunctions.get(t);let n=!1;i?s&&!i.has(s)&&(i.has(B)?(i.delete(B),i.add(s)):(i.add(s),n=!0)):(this.firedClientFunctions.set(t,new Set([s])),n=!0),n&&this.callbacks.onClientFunction?.({invocationId:s,functionName:e.function_name,arguments:e.arguments||{},conversationId:this.message.conversationId||""})}if(e.tool_call_data&&e.type&&e.type!=="client_function"){const t=this.parseToolCall(e);this.callbacks.onToolCall?.(t);const s=this.toolCalls.findIndex(i=>i.id===t.id);s>=0?this.toolCalls[s]=t:this.toolCalls.push(t)}e.follow_up_replies&&(this.followUpReplies=e.follow_up_replies),this.message.status==="DONE"&&!this.answerCompleteEmitted&&this.message.id&&(this.answerCompleteEmitted=!0,this.callbacks.onAnswerComplete?.(this.buildMessage())),this.message.status==="WAITING_CLIENT"&&!this.waitingClientEmitted&&this.message.id&&(this.waitingClientEmitted=!0,this.callbacks.onWaitingClient?.({conversationId:this.message.conversationId||"",messageId:this.message.id,waitingToolCallIds:e.waiting_tool_call_ids??[]}))}parseToolCall(e){return{id:e.id||"",type:e.type||"status_message",status:e.status||"unknown",toolName:e.tool_name||"",toolDisplayName:e.tool_display_name,message:e.message,formSchema:e.form_schema,data:e.data,functionName:e.function_name,arguments:e.arguments}}buildMessage(){return{id:this.message.id||"",conversationId:this.message.conversationId||"",content:this.message.content||"",role:"assistant",status:this.message.status||"DONE",agent:this.message.agent,sources:this.sources.length>0?this.sources:void 0,toolCalls:this.toolCalls.length>0?this.toolCalls:void 0,followUpReplies:this.followUpReplies.length>0?this.followUpReplies:void 0,createdAt:new Date}}buildFinalMessage(){const e=this.buildMessage();return e.status!=="WAITING_CLIENT"&&this.callbacks.onComplete?.(e),e}};function Ye(e){const t=e.message.toLowerCase();return t.includes("load failed")||t.includes("failed to fetch")||t.includes("network")||t.includes("abort")}var Ve=new Set(["image/jpeg","image/png","image/gif","image/webp","image/bmp","image/tiff"]);function ee(e){if(!e)return;const t=typeof window<"u"&&window.location?window.location.href:"https://ago.local/";try{const s=new URL(e,t);if(s.protocol==="http:"||s.protocol==="https:"||s.protocol==="blob:")return e}catch{}}function Qe(e){return e.isSafeImage===!0&&typeof e.contentType=="string"&&e.contentType.startsWith("image/")&&ee(e.url)!==void 0}function Ze(e){if(e==null||e<0)return"";if(e<1024)return`${e} B`;const t=e/1024;return t<1024?`${t.toFixed(1)} KB`:`${(t/1024).toFixed(1)} MB`}function et(e){return{id:String(e.id??""),name:typeof e.name=="string"&&e.name?e.name:"file",contentType:typeof e.content_type=="string"?e.content_type:void 0,fileSize:typeof e.file_size=="number"?e.file_size:void 0,url:typeof e.file_url=="string"?e.file_url:void 0,isSafeImage:e.is_safe_image===!0}}function tt(e){return e.map((t,s)=>({id:`local-${s}-${t.name}`,name:t.name,contentType:t.type||void 0,fileSize:t.size,url:typeof URL<"u"&&URL.createObjectURL?URL.createObjectURL(t):void 0,isSafeImage:Ve.has(t.type)}))}var te=class{constructor(){this.handlers=new Map}on(e,t){this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t)}off(e,t){const s=this.handlers.get(e);s&&s.delete(t)}emit(e,t){const s=this.handlers.get(e);s&&s.forEach(i=>{try{i(t)}catch(n){console.error(`Error in event handler for ${String(e)}:`,n)}})}once(e,t){const s=(i=>{this.off(e,s),t(i)});this.on(e,s)}waitFor(e,t){return new Promise((s,i)=>{let n;const r=(c=>{n&&clearTimeout(n),s(c)});this.once(e,r),t?.timeout&&(n=setTimeout(()=>{this.off(e,r),i(new Error(`waitFor("${String(e)}") timed out after ${t.timeout}ms`))},t.timeout))})}removeAllListeners(e){e?this.handlers.delete(e):this.handlers.clear()}},q='`baseUrl` is required, e.g. new AgoClient({ baseUrl: "https://YOUR-DOMAIN.api.useago.com" }). Try the live demo endpoint https://playground.api.useago.com. See docs/general/configuration.md#error-codes (config_missing_base_url).',st=/^[a-z][a-z0-9+.-]*:\/\//i,G=!1;function O(e,t="AgoClient"){if(typeof e!="object"||e===null)throw new g(`${t}: ${q}`,"config_missing_base_url");const s=e.baseUrl;if(typeof s!="string"||s.trim()==="")throw new g(`${t}: ${q}`,"config_missing_base_url");!s.startsWith("/")&&!st.test(s)&&(G||(G=!0,console.warn(`[AGO] ${t}: \`baseUrl\` has no protocol and is not a relative path (config_suspect_base_url). Requests will fail: Node throws a URL parse error, browsers fetch it as a relative path. Use "https://..." (or a "/path" for a same-origin proxy).`)))}function it(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function A(e){return e.split("/").filter(t=>t.startsWith(":")).map(t=>t.slice(1))}function nt(e,t){const s=[];return{path:e.split("/").map(i=>{if(!i.startsWith(":"))return i;const n=i.slice(1),r=t[n];return r==null||r===""?(s.push(n),i):encodeURIComponent(String(r))}).join("/"),missing:s}}function rt(e,t){const s=t.find(n=>n.path===e);if(s)return s;const i=t.find(n=>{if(!n.path.includes(":"))return!1;const r="^"+n.path.split("/").map(c=>c.startsWith(":")?"[^/]+":it(c)).join("/")+"/?$";return new RegExp(r).test(e)});return i||t.filter(n=>n.path!=="/"&&e.startsWith(n.path)).sort((n,r)=>r.path.length-n.path.length)[0]}var ot="activity:recent",at="state:delta";function W(e){return e==="setPageState"?"readPageData":`read${e.charAt(0).toUpperCase()}${e.slice(1)}Data`}var ct=class se{constructor(t){this.lastSentPageState=null,this.warnedEmptyConversations=new Set,this.warnedPageDataPlaceholder=!1,this.pageDataCompanions=new Set,this.pendingResumes=new Map,this.pendingApprovals=new Map,this.resumeGate=null,this.activeTurn=null,this.pausedTurn=null,this.stoppedTurnIds=new Set,this.proactive=null,O(t,"AgoClient"),this.config=t,this.activityLedger=new K(t.maxActivityEntries),this.httpClient=new ce(t),this.functionRegistry=new z({maxResultBytes:t.maxFunctionResultBytes}),this.contextRegistry=new Q,this.eventEmitter=new te,this.registerActivityContext(),t.debug&&l.enable(),t.proactive&&P(this,t.proactive),l.log("AgoClient initialized")}async sendMessage(t,s){const i=this.functionRegistry.getSchemas(),n=this.buildSendContext(),r=this.config.agent||this.config.defaultAgentId,c=this.resolveClientFunctionsMode(s),o={content:t,conversation_id:s?.conversationId,agent_id:s?.agentId||r};i.length>0&&(o.client_functions=i,c==="pause"&&(o.client_functions_mode=c)),n&&(o.client_context=n),s?.hidden&&(o.hidden=!0);const a=this.beginTurn();let h;if(s?.files&&s.files.length>0){const u=new FormData;u.append("content",t),s.conversationId&&u.append("conversation_id",s.conversationId),(s.agentId||r)&&u.append("agent_id",s.agentId||r||""),i.length>0&&(u.append("client_functions",JSON.stringify(i)),c==="pause"&&u.append("client_functions_mode",c)),n&&u.append("client_context",JSON.stringify(n)),s.hidden&&u.append("hidden","true");for(const d of s.files)u.append("files",d);h=await this.sendRequest(a,()=>this.httpClient.postFormData("/api/sdk/v1/messages",u,{signal:a.controller.signal}))}else h=await this.sendRequest(a,()=>this.httpClient.postStream("/api/sdk/v1/messages",o,{signal:a.controller.signal}));return h?this.processSSEResponse(h,a):this.buildStoppedMessage(a)}async sendRequest(t,s){try{return await s()}catch(i){if(this.endTurn(t),R(i))return null;throw i}}async processSSEResponse(t,s){let i=!1;const n=new Z({onRawChunk:r=>{s&&(r.message_id&&!s.messageId&&(s.messageId=r.message_id),r.thread?.id&&(s.conversationId=r.thread.id)),this.eventEmitter.emit("stream:message",r)},onStart:r=>{this.eventEmitter.emit("message:start",r)},onChunk:r=>{this.eventEmitter.emit("message:chunk",r)},onToolCall:r=>{this.eventEmitter.emit("toolCall:received",r),r.type==="form"&&this.eventEmitter.emit("toolCall:form",r)},onClientFunction:async r=>{if(i=!0,this.eventEmitter.emit("function:invoke",r),this.recordAgentAction(r),r.invocationId&&this.requiresApproval(r)){this.pendingApprovals.set(r.invocationId,r),this.eventEmitter.emit("function:awaiting-approval",r);return}await this.handleClientFunctionInvocation(r)},onTitle:r=>{this.eventEmitter.emit("conversation:title",r)},onAnswerComplete:r=>{this.eventEmitter.emit("message:answer-complete",r)},onWaitingClient:r=>{this.pausedTurn={messageId:r.messageId,conversationId:r.conversationId},this.eventEmitter.emit("message:waiting-client",r),this.markResumeSignal(r.messageId,r.conversationId,"waitingConfirmed")},onComplete:r=>{s?.stopRequested&&!r.id||this.eventEmitter.emit("message:complete",r)},onError:r=>{this.eventEmitter.emit("message:error",{error:r.message,code:r instanceof g?r.code:void 0})}},{signal:s?.controller.signal});try{const r=await n.processStream(t);return s?.stopRequested&&(this.postStopForTurn(s,s.messageId??r.id),this.eventEmitter.emit("message:stopped",{conversationId:s.conversationId??r.conversationId??"",messageId:s.messageId??r.id??""})),r.status!=="WAITING_CLIENT"&&this.maybeFlagEmptyReply(r,i),r}finally{s&&this.endTurn(s)}}async stop(){const t=this.activeTurn;if(t){t.stopRequested=!0;const n=t.messageId;return t.controller.abort(),n?this.postStopForTurn(t,n):null}const s=this.pausedTurn;if(!s)return null;this.pausedTurn=null,this.pendingResumes.delete(s.messageId),this.stoppedTurnIds.add(s.messageId);let i=null;try{i=await this.stopMessage(s.messageId)}catch(n){l.warn("Failed to stop the paused turn:",n)}return this.eventEmitter.emit("message:stopped",{conversationId:s.conversationId,messageId:s.messageId}),i}async stopMessage(t){const s=await this.httpClient.post(`/api/sdk/v1/messages/${t}/stop`);return{status:s.status,messageStatus:s.message_status}}isGenerating(){return this.activeTurn!==null||this.pausedTurn!==null}beginTurn(){this.pausedTurn=null;const t={controller:new AbortController,messageId:null,conversationId:null,stopRequested:!1,stopPosted:!1};return this.activeTurn=t,t}endTurn(t){this.activeTurn===t&&(this.activeTurn=null)}async postStopForTurn(t,s){if(!s||t.stopPosted)return null;t.stopPosted=!0;try{return await this.stopMessage(s)}catch(i){return l.warn("Failed to stop the turn server-side:",i),null}}buildStoppedMessage(t){const s={id:t.messageId??"",conversationId:t.conversationId??"",content:"",role:"assistant",status:"CANCELED",createdAt:new Date};return s.id&&this.eventEmitter.emit("message:complete",s),this.eventEmitter.emit("message:stopped",{conversationId:s.conversationId,messageId:s.id}),s}resolveClientFunctionsMode(t){return t?.clientFunctionsMode??this.config.clientFunctionsMode??"pause"}registerResumeGate(t){return this.resumeGate=t,()=>{this.resumeGate===t&&(this.resumeGate=null)}}async continueMessage(t){const s=this.functionRegistry.getSchemas(),i=this.buildSendContext(),n={};s.length>0&&(n.client_functions=s),i&&(n.client_context=i);const r=this.beginTurn();r.messageId=t;const c=await this.sendRequest(r,()=>this.httpClient.postStream(`/api/sdk/v1/messages/${t}/continue`,n,{signal:r.controller.signal}));return c?this.processSSEResponse(c,r):this.buildStoppedMessage(r)}markResumeSignal(t,s,i){if(!t)return;const n=this.pendingResumes.get(t)??{conversationId:s,waitingConfirmed:!1,resultsReady:!1,started:!1};n[i]=!0,s&&(n.conversationId=s),this.pendingResumes.set(t,n),!(!n.waitingConfirmed||!n.resultsReady||n.started)&&(n.started=!0,this.runAutoResume(t,n.conversationId))}async runAutoResume(t,s){try{this.resumeGate&&await this.resumeGate({conversationId:s,messageId:t})}catch(i){l.warn("Resume gate threw; resuming anyway:",i)}if(this.pendingResumes.delete(t),!this.stoppedTurnIds.delete(t))try{await this.continueMessage(t)}catch(i){l.warn("Auto-resume of paused turn failed:",i)}}maybeFlagEmptyReply(t,s){t.status==="DONE"&&(t.content??"").trim()===""&&!s&&!(t.toolCalls&&t.toolCalls.length>0)&&!(t.followUpReplies&&t.followUpReplies.length>0)&&setTimeout(()=>{if(this.eventEmitter.emit("message:empty",{conversationId:t.conversationId??"",messageId:t.id??""}),this.config.warnOnEmptyReply===!1)return;const i=t.conversationId||"(no conversation)";if(this.warnedEmptyConversations.has(i))return;this.warnedEmptyConversations.add(i);const n=this.config.agent||this.config.defaultAgentId;t.id?console.warn("[AGO] Reply completed with empty content. Possible causes: "+(n?`the agent "${n}" may not exist for this tenant, `:"an unknown `agent` slug, ")+"or the agent replied with no text. Listen for the `message:empty` event to handle this in your app; silence this warning with `warnOnEmptyReply: false`."):console.warn("[AGO] The stream completed without any message data. Possible causes: "+(n?`the agent "${n}" may not exist for this tenant, or `:"")+"`baseUrl` does not point at an AGO endpoint that returns server-sent events. Listen for the `message:empty` event to handle this in your app; silence this warning with `warnOnEmptyReply: false`.")},0)}async handleClientFunctionInvocation(t){let s,i;try{s=await this.functionRegistry.execute(t.functionName,t.arguments)}catch(n){i=n instanceof Error?n.message:"Unknown error",l.error("Client function execution failed:",n)}if(t.invocationId)try{const n=await this.submitToolCallForm(t.invocationId,{result:s,error:i,_type:"client_function_result"});n?.resume?.ready&&this.markResumeSignal(n.resume.message_id,t.conversationId,"resultsReady")}catch(n){l.error("Failed to submit function result:",n)}this.eventEmitter.emit("function:result",{invocationId:t.invocationId,result:s,error:i})}requiresApproval(t){const s=this.config.approvalPolicy;if(s)try{if(s(t))return!0}catch(i){l.warn("approvalPolicy threw; not gating this call:",i)}return this.functionRegistry.get(t.functionName)?.requiresApproval===!0}async approveFunction(t){const s=this.pendingApprovals.get(t);s&&(this.pendingApprovals.delete(t),await this.handleClientFunctionInvocation(s))}async rejectFunction(t){const s=this.pendingApprovals.get(t);if(!s)return;this.pendingApprovals.delete(t);const i={approved:!1,reason:"user_rejected"};try{const n=await this.submitToolCallForm(t,{result:i,_type:"client_function_result"});n?.resume?.ready&&this.markResumeSignal(n.resume.message_id,s.conversationId,"resultsReady")}catch(n){l.error("Failed to submit function rejection:",n)}this.eventEmitter.emit("function:result",{invocationId:t,result:i})}async getConversations(t){const s=new URLSearchParams;t?.page!==void 0&&s.set("page",String(t.page)),t?.pageSize!==void 0&&s.set("page_size",String(t.pageSize));const i=s.toString(),n=await this.httpClient.get(`/api/sdk/v1/conversations${i?`?${i}`:""}`),r=(Array.isArray(n.data)?n.data:[]).map(c=>({id:String(c.id),title:c.title??"",lastMessageDate:new Date(c.last_message_at??c.created_at??0)}));return{data:r,hasMore:n.has_more??!1,total:n.total??r.length}}async getConversation(t){const s=await this.httpClient.get(`/api/sdk/v1/conversations/${t}`),i={id:s.id,title:s.title,lastMessageDate:new Date(s.last_message_at??s.created_at??0),messages:s.messages.map(n=>({id:n.id,conversationId:s.id,content:n.content,role:n.role,status:n.status,createdAt:new Date(n.created_at),hidden:n.hidden,toolCalls:se.mapPersistedToolCalls(n.tool_call_data),attachments:n.attachments&&n.attachments.length>0?n.attachments.map(et):void 0,followUpReplies:n.follow_up_replies&&n.follow_up_replies.length>0?n.follow_up_replies:void 0}))};return this.eventEmitter.emit("conversation:loaded",i),i}static mapPersistedToolCalls(t){if(!(!t||t.length===0))return t.map(s=>({id:String(s.id??""),type:s.type??"status_message",status:String(s.status??"unknown"),toolName:s.tool_name??"",toolDisplayName:s.tool_display_name,message:s.message,formSchema:s.form_schema,data:s.data,functionName:s.function_name,arguments:s.arguments}))}async getMessages(t){return(await this.getConversation(t)).messages||[]}async resumePendingClientFunctions(t){const s=[...t.messages??[]].reverse().find(o=>o.role==="assistant"&&o.status==="WAITING_CLIENT");if(!s)return null;const i=(s.toolCalls??[]).filter(o=>o.type==="client_function"&&o.status==="waiting_input"&&o.functionName),n=new Set(this.functionRegistry.getSchemas().map(o=>o.name)),r=i.filter(o=>!n.has(o.functionName));if(r.length>0)return l.warn("Cannot resume paused turn: function(s) not registered on this page:",r.map(o=>o.functionName)),null;let c=i.length===0;for(const o of i){const a={invocationId:o.id,functionName:o.functionName,arguments:o.arguments??{},conversationId:t.id};if(this.requiresApproval(a)){this.pendingApprovals.set(o.id,a),this.markResumeSignal(s.id,t.id,"waitingConfirmed"),this.eventEmitter.emit("function:awaiting-approval",a),c=!1;continue}this.eventEmitter.emit("function:invoke",a);let h,u;try{h=await this.functionRegistry.execute(o.functionName,o.arguments??{})}catch(d){u=d instanceof Error?d.message:"Unknown error",l.error("Client function execution failed:",d)}this.eventEmitter.emit("function:result",{invocationId:o.id,result:h,error:u}),c=(await this.submitToolCallForm(o.id,{result:h,error:u,_type:"client_function_result"}))?.resume?.ready??c}return c?this.continueMessage(s.id):null}async submitToolCallForm(t,s){return this.httpClient.post(`/api/sdk/v1/tool-calls/${t}/submit`,{formData:s})}async confirmToolCall(t){await this.httpClient.post(`/api/tool-calls/${t}/confirm/`)}async rejectToolCall(t){await this.httpClient.post(`/api/tool-calls/${t}/reject/`)}async getFormCollector(t){const s=await this.httpClient.get(`/api/sdk/v1/forms/${encodeURIComponent(t)}`);return{name:s.name,description:s.description,schema:s.schema,submit:s.submit??void 0}}async submitFormCollector(t,s){return this.httpClient.post("/api/sdk/v1/forms/submit",{name:t,values:s})}async submitFeedback(t,s){await this.httpClient.post(`/api/sdk/v1/messages/${t}/feedback`,{rating:s})}registerFunction(t,s,i){typeof t=="object"?this.functionRegistry.register(t):this.functionRegistry.register(t,s,i)}register(t){if(Array.isArray(t))for(const s of t)this.functionRegistry.register(s);else this.functionRegistry.register(t)}unregisterFunction(t){return this.functionRegistry.unregister(t)}getRegisteredFunctions(){return this.functionRegistry.getSchemas()}async executeClientFunction(t,s){return this.functionRegistry.execute(t,s)}registerNavigationFunction(t,s){const i=s.map(o=>o.name),n=s.map(o=>{const a=A(o.path),h=a.length>0?` (requires ${a.map(u=>`"${u}"`).join(", ")})`:"";return`- "${o.name}"${h}: ${o.description}`}).join(`
5
- `),r=new Map;for(const o of s)for(const a of A(o.path))r.set(a,[...r.get(a)??[],o.name]);const c={page:{type:"string",description:"The page to navigate to",enum:i}};for(const[o,a]of r){if(o==="page"){l.error('registerNavigationFunction: a ":page" placeholder collides with the "page" argument and is ignored. Rename the placeholder.');continue}c[o]={type:"string",description:`Value for ":${o}" in the page path. Required when page is ${a.map(h=>`"${h}"`).join(" or ")}.`}}this.registerFunction("navigateToPage",async o=>{const a=o.page,h=s.find(p=>p.name===a);if(!h)return{success:!1,error:`Unknown page: ${a}`};let u={};if(typeof o.params=="string")try{u=JSON.parse(o.params)}catch{}else o.params&&typeof o.params=="object"&&(u=o.params);const d={};for(const p of A(h.path))d[p]=o[p]??u[p];const{path:f,missing:C}=nt(h.path,d);if(C.length>0){const p=C.map(S=>`"${S}": "..."`).join(", ");return{success:!1,error:`Page "${a}" needs ${C.map(S=>`"${S}"`).join(", ")}. Retry with { "page": "${a}", ${p} }.`}}return t(f),{success:!0,navigatedTo:f}},{description:`Navigate the user to a page in the application. Available pages:
6
- ${n}`,parameters:{type:"object",properties:c,required:["page"]}}),this.addDynamicContext("current-page",()=>{if(typeof window>"u"||!window.location)return null;const o=window.location.href,a=typeof document<"u"?document.title:void 0,h=rt(window.location.pathname,s),u={url:o};return h&&(u.page=h.name),a&&(u.title=a),{name:"Current page",description:"The page the user is currently viewing.",data:u}})}unregisterNavigationFunction(){this.unregisterFunction("navigateToPage"),this.removeDynamicContext("current-page")}registerPageStateFunction(t,s){const i=s?.functionName??"setPageState",n=new Map(t.map(a=>[a.name,a])),r=s?.data,c=t.map(a=>`- "${a.name}": ${a.description}`).join(`
7
- `);this.registerFunction(i,async a=>{const h={};for(const[u,d]of Object.entries(a)){if(d===void 0)continue;const f=n.get(u);f&&(await f.set(d),h[u]=d)}return r?{success:!0,applied:h,data:U(i,await this.readPageData(i,r,s),this.pageDataBudget(r)-this.envelopeBytes({success:!0,applied:h}))}:{success:!0,applied:h}},{description:`Change the state of the current page. Set ONLY the controls the user explicitly asked for; leave the others unset. Available controls:
8
- ${c}`+(r?`
9
- Returns the resulting page data once it has loaded: ${r.description}`:""),parameters:{type:"object",properties:Object.fromEntries(t.map(a=>[a.name,{...a.schema,description:a.description}])),required:[]},requiresApproval:s?.requiresApproval,maxResultBytes:r?.maxResultBytes});const o=W(i);r?(this.warnIfPlaceholderMode(i),this.registerFunction(o,async()=>({data:U(i,await this.readPageData(i,r,s),this.pageDataBudget(r)-this.envelopeBytes({}))}),{description:`Read what the current page is displaying, without changing anything: ${r.description}`,parameters:{type:"object",properties:{}},maxResultBytes:r.maxResultBytes}),this.pageDataCompanions.add(o)):this.pageDataCompanions.delete(o)&&this.unregisterFunction(o),this.addDynamicContext(`page-state:${i}`,()=>{const a=t.filter(u=>typeof u.get=="function");if(a.length===0)return null;const h={};for(const u of a)h[u.name]=u.get();return{name:"Page state",description:"Current, editable state of the page the user is viewing.",data:h}})}unregisterPageStateFunction(t){const s=t??"setPageState";this.unregisterFunction(s);const i=W(s);this.pageDataCompanions.delete(i)&&this.unregisterFunction(i),this.removeDynamicContext(`page-state:${s}`)}pageDataBudget(t){return t.maxResultBytes??this.functionRegistry.getDefaultMaxResultBytes()}envelopeBytes(t){return m(JSON.stringify({...t,data:null}))-4}readPageData(t,s,i){return ye(()=>s,i?.settleTimeoutMs??1e4).catch(n=>(l.warn(`Reading page data for "${t}" failed:`,n),{error:"page_data_unavailable",message:n instanceof Error?n.message:String(n)}))}warnIfPlaceholderMode(t){this.warnedPageDataPlaceholder||this.config.clientFunctionsMode==="placeholder"&&(this.warnedPageDataPlaceholder=!0,l.warn(`"${t}" declares a data source, but clientFunctionsMode is "placeholder": the agent will not see that data during the turn it calls the function. Switch to "pause" (the default) for the data to come back as the result of its own call.`))}setContext(t,s){this.contextRegistry.set(t,s),this.notifyContextChanged()}removeContext(t){const s=this.contextRegistry.remove(t);return s&&this.notifyContextChanged(),s}addDynamicContext(t,s){this.contextRegistry.addDynamicProvider(t,s),this.notifyContextChanged()}removeDynamicContext(t){const s=this.contextRegistry.removeDynamicProvider(t);return s&&this.notifyContextChanged(),s}notifyContextChanged(){this.eventEmitter.emit("context:changed",this.contextRegistry.getSnapshot())}emitFormEvent(t,s){this.eventEmitter.emit(t,s)}emitProactiveEvent(t,s){this.eventEmitter.emit(t,s)}getHttp(){return this.httpClient}getConfiguredAgent(){return this.config.agent||this.config.defaultAgentId}enableAutoPageContext(){this.addDynamicContext("browser-page",()=>{const t=typeof window<"u"?window.location.href:void 0,s=typeof document<"u"?document.title:void 0;return!t&&!s?null:{name:"Browser page",description:"Current page the user is viewing",data:{url:t,title:s}}})}getContextSnapshot(){return this.contextRegistry.getSnapshot()}buildSendContext(){const t=this.contextRegistry.getSnapshot(),s=t?.entries??{},{changes:i,baseline:n}=Xe(this.lastSentPageState,s);return this.lastSentPageState=n,i.length===0?t:{entries:{...s,[at]:{name:"State changes",description:"Fields in the page state that changed since your last message, as field: <old> -> <new>.",data:{changes:i}}}}}recordActivity(t){this.addActivity(t)}getRecentActivity(){return this.activityLedger.getRecent()}clearActivity(){this.activityLedger.clear()}addActivity(t){const s=this.activityLedger.add(t);this.eventEmitter.emit("activity:recorded",s)}recordAgentAction(t){const s=t.functionName,i=t.arguments;let n,r;if(s==="navigateToPage"){const c=i?.page;n="agent.navigate",r=c?`Agent navigated to "${String(c)}"`:"Agent navigated"}else s==="setPageState"?(n="agent.page_state",r="Agent changed the page state"):(n=`agent.${s}`,r=`Agent ran "${s}"`);this.addActivity({actor:"agent",name:n,summary:r,...i&&Object.keys(i).length>0?{data:{arguments:i}}:{}})}registerActivityContext(){this.contextRegistry.addDynamicProvider(ot,()=>{const t=this.activityLedger.getRecent();return t.length===0?null:{name:"Recent activity",description:"Recent actions by the user and the agent in the app, oldest first. Use this to understand what just happened before this message.",data:{events:t}}})}on(t,s){this.eventEmitter.on(t,s)}off(t,s){this.eventEmitter.off(t,s)}once(t,s){this.eventEmitter.once(t,s)}waitFor(t,s){return this.eventEmitter.waitFor(t,s)}updateConfig(t){const s={};for(const[n,r]of Object.entries(t))r!==void 0&&(s[n]=r);const i={...this.config,...s};O(i,"AgoClient.updateConfig"),this.config=i,this.httpClient.updateConfig(s),s.debug!==void 0&&(s.debug?l.enable():l.disable()),s.maxFunctionResultBytes!==void 0&&this.functionRegistry.setDefaultMaxResultBytes(s.maxFunctionResultBytes)}destroy(){this.proactive?.destroy(),this.proactive=null,this.activeTurn?.controller.abort(),this.activeTurn=null,this.pausedTurn=null,this.stoppedTurnIds.clear(),this.eventEmitter.removeAllListeners(),this.functionRegistry.clear(),this.contextRegistry.clear(),this.pendingResumes.clear(),this.pendingApprovals.clear(),this.resumeGate=null,l.log("AgoClient destroyed")}reviveAfterDestroy(){this.registerActivityContext(),this.config.proactive&&!this.proactive&&P(this,this.config.proactive)}};Object.defineProperty(exports,"ActivityLedger",{enumerable:!0,get:function(){return K}});Object.defineProperty(exports,"AgoApiError",{enumerable:!0,get:function(){return y}});Object.defineProperty(exports,"AgoClient",{enumerable:!0,get:function(){return ct}});Object.defineProperty(exports,"AgoError",{enumerable:!0,get:function(){return g}});Object.defineProperty(exports,"AgoFunctionError",{enumerable:!0,get:function(){return I}});Object.defineProperty(exports,"AgoNetworkError",{enumerable:!0,get:function(){return w}});Object.defineProperty(exports,"AgoStreamError",{enumerable:!0,get:function(){return _}});Object.defineProperty(exports,"ClientContextRegistry",{enumerable:!0,get:function(){return Q}});Object.defineProperty(exports,"DEFAULT_MAX_ACTIVITY_ENTRIES",{enumerable:!0,get:function(){return ie}});Object.defineProperty(exports,"EventEmitter",{enumerable:!0,get:function(){return te}});Object.defineProperty(exports,"FunctionRegistry",{enumerable:!0,get:function(){return z}});Object.defineProperty(exports,"SSEHandler",{enumerable:!0,get:function(){return Z}});Object.defineProperty(exports,"SignalCollector",{enumerable:!0,get:function(){return J}});Object.defineProperty(exports,"attachmentsFromFiles",{enumerable:!0,get:function(){return tt}});Object.defineProperty(exports,"canInlineImage",{enumerable:!0,get:function(){return Qe}});Object.defineProperty(exports,"createAgoProactive",{enumerable:!0,get:function(){return P}});Object.defineProperty(exports,"createStore",{enumerable:!0,get:function(){return X}});Object.defineProperty(exports,"formatFileSize",{enumerable:!0,get:function(){return Ze}});Object.defineProperty(exports,"isStreamNetworkError",{enumerable:!0,get:function(){return Ye}});Object.defineProperty(exports,"logger",{enumerable:!0,get:function(){return l}});Object.defineProperty(exports,"matchesRoutePattern",{enumerable:!0,get:function(){return Y}});Object.defineProperty(exports,"matchesWhen",{enumerable:!0,get:function(){return V}});Object.defineProperty(exports,"partialDeepMatch",{enumerable:!0,get:function(){return D}});Object.defineProperty(exports,"safeAttachmentUrl",{enumerable:!0,get:function(){return ee}});Object.defineProperty(exports,"validateConfig",{enumerable:!0,get:function(){return O}});
@@ -1 +0,0 @@
1
- const d=require("./AgoClient-B_u_d-XS.cjs");var f="ago_widget_id",g="ago_last_thread",y=7200*1e3;function v(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const r=Math.floor(Math.random()*16);return(e==="x"?r:r&3|8).toString(16)})}function _(e={}){const r=e.key??f,i=e.threadKey??g,u=e.ttlMs??y,l=e.storage??(typeof localStorage<"u"?localStorage:void 0);let n=e.widgetId??"";if(!n&&l)try{n=l.getItem(r)??""}catch{}if(n||(n=v()),l)try{l.setItem(r,n)}catch{}const o=d.createStore({value:null,lastMessageAt:null},{key:i,storage:l}),s=o.get();s.value!==null&&c(s.lastMessageAt)&&o.set({value:null,lastMessageAt:null});function c(t){return t===null?!0:Number.isFinite(u)?Date.now()-t>u:!1}return{widgetId:n,key:r,getLastActiveThread(){const{value:t,lastMessageAt:a}=o.get();return t===null||c(a)?null:t},setActiveThread(t,a){const x=a==null?null:a instanceof Date?a.getTime():a;o.set({value:t,lastMessageAt:x})},clear(){o.set({value:null,lastMessageAt:null})}}}Object.defineProperty(exports,"createConversationSession",{enumerable:!0,get:function(){return _}});
@@ -1 +0,0 @@
1
- const C=require("./AgoClient-B_u_d-XS.cjs");var W=/^[a-zA-Z0-9_-]{1,40}$/,A=n=>n==null||n==="";function S(n,e){if("anyOf"in n)return n.anyOf.some(c=>S(c,e));if("allOf"in n)return n.allOf.every(c=>S(c,e));const l=e[n.property];if(A(l))return!1;if(Array.isArray(n.value))return n.value.some(c=>String(l)===String(c));if(!n.op)return String(l)===String(n.value);const i=Number(l),a=Number(n.value);if(Number.isNaN(i)||Number.isNaN(a))return!1;switch(n.op){case">=":return i>=a;case"<=":return i<=a;case">":return i>a;case"<":return i<a;default:return C.logger.warn(`Unknown requiredWhen op "${n.op}"; treating as not required.`),!1}}function h(n,e){const l=n.properties??{},i=new Set;for(const c of n.required??[]){const d=l[c]?.requiredWhen;(!d||S(d,e))&&i.add(c)}for(const[c,d]of Object.entries(l))d.requiredWhen&&S(d.requiredWhen,e)&&i.add(c);const a=[...i].filter(c=>A(e[c]));return{missing:a,complete:a.length===0}}function B(n){const e={};for(const[l,i]of Object.entries(n.properties??{}))e[l]={type:i.type,...i.description!=null&&{description:i.description},...i.enum&&{enum:i.enum},...i.default!==void 0&&{default:i.default}};return{type:"object",properties:e,required:[]}}function V(n){const{name:e,description:l,schema:i}=n;if(!W.test(e))throw new Error(`Invalid form collector name "${e}": must match ${W} (it becomes the update_/submit_ function names).`);const a=typeof n.submit=="string"?n.submit?{via:"client",url:n.submit}:!1:n.submit??!1;n.autoSubmit===!0&&!a&&C.logger.warn(`FormCollector "${e}": autoSubmit is ignored because no submit target is configured.`);const c=(n.autoSubmit??!0)&&!!a,d=i.properties??{},$=t=>{const r={};for(const[o,s]of Object.entries(t)){const u=d[o];if(u)if(s==null)r[o]=s;else if(u.type==="number"||u.type==="integer"){const f=typeof s=="number"?s:Number(s);r[o]=Number.isNaN(f)?s:f}else u.type==="boolean"?r[o]=typeof s=="boolean"?s:s==="true"?!0:s==="false"?!1:!!s:r[o]=s}return r},N=n.initialValues??{},m=C.createStore({values:N,submitted:!1}),w=t=>{const r=m.get(),o={...r,values:{...r.values,...t}};return m.set(o),o};let b=null;const k=(t,r)=>{b?.emitFormEvent("form:error",{name:e,values:t,error:r})};let p=null;const I=async()=>{const{values:t}=m.get(),{complete:r,missing:o}=h(i,t);if(!r)return{ok:!1,missing:o};if(!a)return{ok:!1,error:"No submit target configured for this form collector."};const s=t;try{let u;if(a.via==="client")if("handler"in a)u=await a.handler(s);else{const f=await fetch(a.url,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(s)});if(!f.ok){const j=`Submit failed: HTTP ${f.status}`;return k(s,j),{ok:!1,error:j}}u=await f.json().catch(()=>{})}else{if(!b)return{ok:!1,error:"Backend submit requires install(client) (or useFormCollector) first."};u=await b.submitFormCollector(e,s)}return m.set({...m.get(),submitted:!0,submitResult:u}),b?.emitFormEvent("form:submitted",{name:e,values:s,result:u}),{ok:!0,result:u}}catch(u){const f=u instanceof Error?u.message:"Submit failed";return C.logger.error(`FormCollector "${e}" submit failed:`,u),k(s,f),{ok:!1,error:f}}},F=()=>p||(p=(async()=>{try{return await I()}finally{p=null}})(),p),q=async()=>{if(!c||!a)return null;const{values:t,submitted:r}=m.get();return r||!h(i,t).complete?null:F()},O={name:`update_${e}`,description:`Fill or update fields of the "${e}" form. ${l} Pass any subset of fields; call it repeatedly to fill the form as the user provides information. Returns the current values and which required fields are still missing.`,parameters:B(i),handler:async t=>{const r=w($(t)),{missing:o}=h(i,r.values),s=await q();return s?s.ok?{ok:!0,values:r.values,missing:o,submitted:!0}:{ok:!0,values:r.values,missing:o,submitted:!1,submitError:s.error}:{ok:!0,values:r.values,missing:o}}},y=[O];a&&!c&&y.push({name:`submit_${e}`,description:`Submit the completed "${e}" form. Only call this once every required field is collected and the user has confirmed. If fields are missing it returns them instead of submitting.`,parameters:{type:"object",properties:{}},handler:()=>F()});const D="client__",_=a?`submit_${e}`:null,R=t=>{const r=t.functionName??t.toolName;if(r)return r.startsWith(D)?r.slice(8):r},x=t=>{let r={...N},o=!1;for(const s of t){const u=R(s);u===O.name?s.arguments&&(r={...r,...$(s.arguments)}):_&&u===_&&s.status?.toLowerCase()==="done"&&(o=!0)}m.set({values:r,submitted:o})},g=`form:${e}`,v=`${g}:definition`,P=()=>({name:`Form definition: ${e}`,description:`${l} Some fields are conditionally required; the requiredWhen field in the schema tells you when each becomes required. The form schema is the following: ${JSON.stringify(i)}.`,stable:!0}),T=()=>{const{values:t,submitted:r}=m.get(),{missing:o,complete:s}=h(i,t),u=a?c?" The form is submitted automatically as soon as every required field is filled, so there is no submit function to call.":` When nothing is missing and the user confirms, call submit_${e}.`:"",f=r?`The "${e}" form has been submitted.`:`You are currently collecting information from the user to fill the "${e}" form.`;return{name:`Form: ${e}`,description:`${f} The form's schema and field requirements are in the "${v}" client context. Call update_${e} with any fields the user provides; ask only for what is still missing.${u}`,data:{values:t,missing:o,complete:s,submitted:r}}},E=t=>{x((t.messages??[]).flatMap(r=>r.toolCalls??[]))};return{name:e,store:m,functions:y,contextKey:g,contextProvider:T,definitionContextKey:v,definitionContextProvider:P,install:t=>{b=t;for(const o of y)t.register(o);t.addDynamicContext(v,P),t.addDynamicContext(g,T);const r=m.subscribe(()=>t.notifyContextChanged());return t.on("conversation:loaded",E),()=>{r();for(const o of y)t.unregisterFunction(o.name);t.removeDynamicContext(g),t.removeDynamicContext(v),t.off("conversation:loaded",E),b===t&&(b=null)}},hydrate:x,submit:F,getValues:()=>m.get().values,setValues:t=>{w($(t)),q()},reset:()=>{m.set({values:N,submitted:!1})},getStatus:()=>h(i,m.get().values)}}async function L(n,e){const l=await n.getFormCollector(e.name);return V({name:l.name,description:e.description??l.description,schema:e.schema??l.schema,submit:e.submit??l.submit,initialValues:e.initialValues,autoSubmit:e.autoSubmit??l.autoSubmit})}Object.defineProperty(exports,"createFormCollector",{enumerable:!0,get:function(){return V}});Object.defineProperty(exports,"deriveFormStatus",{enumerable:!0,get:function(){return h}});Object.defineProperty(exports,"loadFormCollector",{enumerable:!0,get:function(){return L}});
@@ -1 +0,0 @@
1
- function y(u={}){const{overrides:g={}}=u,a={id:"mock-msg-1",conversationId:"mock-conv-1",content:"Mock response",role:"assistant",status:"DONE",createdAt:new Date},l={id:"mock-conv-1",title:"Mock Conversation",lastMessageDate:new Date},n=new Map,r=[],m={sendMessage:async()=>a,continueMessage:async()=>a,stop:async()=>null,stopMessage:async()=>({status:"not_running"}),isGenerating:()=>!1,resumePendingClientFunctions:async()=>null,registerResumeGate:()=>()=>{},getConversations:async()=>[l],getConversation:async()=>l,getMessages:async()=>[a],submitToolCallForm:async()=>({status:"completed"}),confirmToolCall:async()=>{},rejectToolCall:async()=>{},submitFeedback:async()=>{},registerFunction:()=>{},unregisterFunction:()=>!0,getRegisteredFunctions:()=>[],executeClientFunction:async()=>{},getContextSnapshot:()=>null,notifyContextChanged:()=>{},setContext:()=>{},removeContext:()=>!0,addDynamicContext:()=>{},removeDynamicContext:()=>!0,registerNavigationFunction:()=>{},unregisterNavigationFunction:()=>{},getConfiguredAgent:()=>{},getHttp:()=>({get:async()=>({}),post:async()=>({})}),emitProactiveEvent:(e,t)=>{const o=n.get(e);o&&[...o].forEach(s=>s(t))},on:(e,t)=>{n.has(e)||n.set(e,new Set),n.get(e).add(t)},off:(e,t)=>{n.get(e)?.delete(t)},once:(e,t)=>{const o=(...s)=>{n.get(e)?.delete(o),t(...s)};n.has(e)||n.set(e,new Set),n.get(e).add(o)},waitFor:(e,t)=>new Promise((o,s)=>{let c;const d=f=>{c&&clearTimeout(c),n.get(e)?.delete(d),o(f)};n.has(e)||n.set(e,new Set),n.get(e).add(d),t?.timeout&&(c=setTimeout(()=>{n.get(e)?.delete(d),s(new Error(`waitFor("${e}") timed out after ${t.timeout}ms`))},t.timeout))}),updateConfig:()=>{},destroy:()=>{n.clear()},...g},i={};for(const[e,t]of Object.entries(m))i[e]=(...o)=>(r.push({method:e,args:o}),t(...o));return i.proactive=null,i.__calls=r,i.__callsFor=e=>r.filter(t=>t.method===e),i.__emitEvent=(e,t)=>{const o=n.get(e);o&&[...o].forEach(s=>s(t))},i}Object.defineProperty(exports,"createMockClient",{enumerable:!0,get:function(){return y}});