@hainiva/agent-sdk 0.0.0-stage → 0.3.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 (119) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/LICENSE +21 -0
  3. package/README.md +278 -2
  4. package/SECURITY.md +33 -0
  5. package/dist/cjs/agent.cjs +320 -0
  6. package/dist/cjs/agent.d.cts +239 -0
  7. package/dist/cjs/calls.cjs +277 -0
  8. package/dist/cjs/calls.d.cts +232 -0
  9. package/dist/cjs/contract.cjs +14 -0
  10. package/dist/cjs/contract.d.cts +225 -0
  11. package/dist/cjs/embed.cjs +253 -0
  12. package/dist/cjs/embed.d.cts +187 -0
  13. package/dist/cjs/emitter.cjs +50 -0
  14. package/dist/cjs/emitter.d.cts +22 -0
  15. package/dist/cjs/errors.cjs +28 -0
  16. package/dist/cjs/errors.d.cts +15 -0
  17. package/dist/cjs/events.cjs +97 -0
  18. package/dist/cjs/events.d.cts +97 -0
  19. package/dist/cjs/index.cjs +72 -0
  20. package/dist/cjs/index.d.cts +28 -0
  21. package/dist/cjs/livekit.cjs +56 -0
  22. package/dist/cjs/livekit.d.cts +35 -0
  23. package/dist/cjs/log.cjs +15 -0
  24. package/dist/cjs/log.d.cts +5 -0
  25. package/dist/cjs/react-native.cjs +32 -0
  26. package/dist/cjs/react-native.d.cts +39 -0
  27. package/dist/cjs/reactNativeDesk.cjs +107 -0
  28. package/dist/cjs/reactNativeDesk.d.cts +53 -0
  29. package/dist/cjs/redact.cjs +71 -0
  30. package/dist/cjs/redact.d.cts +21 -0
  31. package/dist/cjs/rest.cjs +286 -0
  32. package/dist/cjs/rest.d.cts +172 -0
  33. package/dist/cjs/session.cjs +159 -0
  34. package/dist/cjs/session.d.cts +101 -0
  35. package/dist/cjs/singleFlight.cjs +49 -0
  36. package/dist/cjs/singleFlight.d.cts +32 -0
  37. package/dist/cjs/url.cjs +39 -0
  38. package/dist/cjs/url.d.cts +13 -0
  39. package/dist/cjs/web.cjs +28 -0
  40. package/dist/cjs/web.d.cts +23 -0
  41. package/dist/cjs/ws.cjs +246 -0
  42. package/dist/cjs/ws.d.cts +134 -0
  43. package/dist/esm/agent.d.ts +240 -0
  44. package/dist/esm/agent.d.ts.map +1 -0
  45. package/dist/esm/agent.js +317 -0
  46. package/dist/esm/agent.js.map +1 -0
  47. package/dist/esm/calls.d.ts +233 -0
  48. package/dist/esm/calls.d.ts.map +1 -0
  49. package/dist/esm/calls.js +271 -0
  50. package/dist/esm/calls.js.map +1 -0
  51. package/dist/esm/contract.d.ts +226 -0
  52. package/dist/esm/contract.d.ts.map +1 -0
  53. package/dist/esm/contract.js +12 -0
  54. package/dist/esm/contract.js.map +1 -0
  55. package/dist/esm/embed.d.ts +188 -0
  56. package/dist/esm/embed.d.ts.map +1 -0
  57. package/dist/esm/embed.js +247 -0
  58. package/dist/esm/embed.js.map +1 -0
  59. package/dist/esm/emitter.d.ts +23 -0
  60. package/dist/esm/emitter.d.ts.map +1 -0
  61. package/dist/esm/emitter.js +47 -0
  62. package/dist/esm/emitter.js.map +1 -0
  63. package/dist/esm/errors.d.ts +16 -0
  64. package/dist/esm/errors.d.ts.map +1 -0
  65. package/dist/esm/errors.js +25 -0
  66. package/dist/esm/errors.js.map +1 -0
  67. package/dist/esm/events.d.ts +98 -0
  68. package/dist/esm/events.d.ts.map +1 -0
  69. package/dist/esm/events.js +90 -0
  70. package/dist/esm/events.js.map +1 -0
  71. package/dist/esm/index.d.ts +29 -0
  72. package/dist/esm/index.d.ts.map +1 -0
  73. package/dist/esm/index.js +29 -0
  74. package/dist/esm/index.js.map +1 -0
  75. package/dist/esm/livekit.d.ts +36 -0
  76. package/dist/esm/livekit.d.ts.map +1 -0
  77. package/dist/esm/livekit.js +54 -0
  78. package/dist/esm/livekit.js.map +1 -0
  79. package/dist/esm/log.d.ts +6 -0
  80. package/dist/esm/log.d.ts.map +1 -0
  81. package/dist/esm/log.js +13 -0
  82. package/dist/esm/log.js.map +1 -0
  83. package/dist/esm/react-native.d.ts +40 -0
  84. package/dist/esm/react-native.d.ts.map +1 -0
  85. package/dist/esm/react-native.js +26 -0
  86. package/dist/esm/react-native.js.map +1 -0
  87. package/dist/esm/reactNativeDesk.d.ts +54 -0
  88. package/dist/esm/reactNativeDesk.d.ts.map +1 -0
  89. package/dist/esm/reactNativeDesk.js +103 -0
  90. package/dist/esm/reactNativeDesk.js.map +1 -0
  91. package/dist/esm/redact.d.ts +22 -0
  92. package/dist/esm/redact.d.ts.map +1 -0
  93. package/dist/esm/redact.js +66 -0
  94. package/dist/esm/redact.js.map +1 -0
  95. package/dist/esm/rest.d.ts +173 -0
  96. package/dist/esm/rest.d.ts.map +1 -0
  97. package/dist/esm/rest.js +281 -0
  98. package/dist/esm/rest.js.map +1 -0
  99. package/dist/esm/session.d.ts +102 -0
  100. package/dist/esm/session.d.ts.map +1 -0
  101. package/dist/esm/session.js +155 -0
  102. package/dist/esm/session.js.map +1 -0
  103. package/dist/esm/singleFlight.d.ts +33 -0
  104. package/dist/esm/singleFlight.d.ts.map +1 -0
  105. package/dist/esm/singleFlight.js +46 -0
  106. package/dist/esm/singleFlight.js.map +1 -0
  107. package/dist/esm/url.d.ts +14 -0
  108. package/dist/esm/url.d.ts.map +1 -0
  109. package/dist/esm/url.js +37 -0
  110. package/dist/esm/url.js.map +1 -0
  111. package/dist/esm/web.d.ts +24 -0
  112. package/dist/esm/web.d.ts.map +1 -0
  113. package/dist/esm/web.js +23 -0
  114. package/dist/esm/web.js.map +1 -0
  115. package/dist/esm/ws.d.ts +135 -0
  116. package/dist/esm/ws.d.ts.map +1 -0
  117. package/dist/esm/ws.js +242 -0
  118. package/dist/esm/ws.js.map +1 -0
  119. package/package.json +117 -4
@@ -0,0 +1,103 @@
1
+ /**
2
+ * `<HainivaDesk/>` — the HAINIVA desk inside your React Native app.
3
+ *
4
+ * import { WebView } from "react-native-webview";
5
+ * import { HainivaDesk } from "@hainiva/agent-sdk/react-native";
6
+ *
7
+ * <HainivaDesk agent={agent} appId={APP_ID} baseUrl="https://app.hainiva.com"
8
+ * onDial={(number, contactId) => placeNativeCall(number, contactId)}
9
+ * onEnded={(reason) => goToSignIn(reason)} />
10
+ *
11
+ * The split is the HAINIVA Agent app's: YOUR app rings and carries call audio
12
+ * natively (@hainiva/react-native-call + this SDK's CallStore); the desk shows
13
+ * the work and hands calls to you (`onDial`, `onDialer`).
14
+ *
15
+ * Security:
16
+ * - `originWhitelist` and `onShouldStartLoadWithRequest` keep the WebView on
17
+ * the HAINIVA desk origin; any other URL is refused there (and offered to
18
+ * `onOpenUrl`, if you pass one);
19
+ * - no window.open passthrough (`setSupportMultipleWindows={false}`,
20
+ * `javaScriptCanOpenWindowsAutomatically={false}`);
21
+ * - the bridge is installed before the desk's scripts and ONLY when the page
22
+ * is on the desk origin; the desk token goes in by injectJavaScript, never
23
+ * in the URL, and is not written to storage.
24
+ */
25
+ import * as React from "react";
26
+ import { DeskHost, deskUrl } from "./embed.js";
27
+ /** Runs before the desk's scripts, on the desk origin only: the partner-rn bridge the desk looks for. */
28
+ export function deskBridgeScript(deskOrigin, appId) {
29
+ return `(function(){if(location.origin!==${JSON.stringify(deskOrigin)})return;`
30
+ + `window.__HAINIVA_EMBED__={host:"partner-rn",appId:${JSON.stringify(appId.toLowerCase())},q:[],deliver:function(s){this.q.push(String(s));}};})();true;`;
31
+ }
32
+ /** A message to the desk, as a script: JSON twice (a string literal of the JSON), nothing interpolated raw. */
33
+ export function deliverScript(m) {
34
+ return `window.__HAINIVA_EMBED__&&window.__HAINIVA_EMBED__.deliver(${JSON.stringify(JSON.stringify(m))});true;`;
35
+ }
36
+ function defaultWebView() {
37
+ const mod = require("react-native-webview");
38
+ const W = mod.WebView ?? mod.default;
39
+ if (!W)
40
+ throw new Error("@hainiva/agent-sdk: install react-native-webview (or pass the WebView prop) to use <HainivaDesk/>");
41
+ return W;
42
+ }
43
+ export function HainivaDesk(props) {
44
+ const url = React.useMemo(() => deskUrl(props.baseUrl, props.appId, props.allowInsecureLocalhost ? { allowInsecureLocalhost: true } : {}), [props.baseUrl, props.appId, props.allowInsecureLocalhost]);
45
+ const origin = url.origin;
46
+ const web = React.useRef(null);
47
+ const latest = React.useRef(props);
48
+ latest.current = props;
49
+ const host = React.useMemo(() => new DeskHost(props.appId, props.agent, (m) => web.current?.injectJavaScript(deliverScript(m)), {
50
+ onDial: (n, c) => latest.current.onDial?.(n, c),
51
+ onDialer: (p) => latest.current.onDialer?.(p),
52
+ onEnded: (r) => latest.current.onEnded?.(r),
53
+ onOpenUrl: (u) => latest.current.onOpenUrl?.(u),
54
+ onMediaError: (n) => latest.current.onMediaError?.(n),
55
+ }),
56
+ // eslint-disable-next-line react-hooks/exhaustive-deps
57
+ [props.appId, props.agent, origin]);
58
+ React.useEffect(() => { if (props.theme && host.isReady)
59
+ host.setTheme(props.theme); }, [props.theme, host]);
60
+ React.useEffect(() => { if (props.locale && host.isReady)
61
+ host.setLocale(props.locale); }, [props.locale, host]);
62
+ // Unmounted: the desk drops its token.
63
+ React.useEffect(() => () => { if (!host.isEnded)
64
+ web.current?.injectJavaScript(deliverScript({ v: 1, type: "hainiva:end" })); }, [host]);
65
+ const W = props.WebView ?? defaultWebView();
66
+ return React.createElement(W, {
67
+ ref: web,
68
+ source: { uri: url.href },
69
+ style: props.style,
70
+ originWhitelist: [origin],
71
+ injectedJavaScriptBeforeContentLoaded: deskBridgeScript(origin, props.appId),
72
+ onMessage: (e) => {
73
+ // Only from the desk origin (a page elsewhere never gets the bridge, and is refused below anyway).
74
+ const from = e.nativeEvent.url;
75
+ if (typeof from === "string" && !from.startsWith(`${origin}/`))
76
+ return;
77
+ const wasReady = host.isReady;
78
+ host.receive(e.nativeEvent.data);
79
+ if (!wasReady && host.isReady) {
80
+ if (latest.current.theme)
81
+ host.setTheme(latest.current.theme);
82
+ if (latest.current.locale)
83
+ host.setLocale(latest.current.locale);
84
+ }
85
+ },
86
+ onShouldStartLoadWithRequest: (r) => {
87
+ if (r.url === "about:blank" || r.url.startsWith(`${origin}/`) || r.url.startsWith("blob:") || r.url.startsWith("data:"))
88
+ return true;
89
+ latest.current.onOpenUrl?.(r.url);
90
+ return false;
91
+ },
92
+ setSupportMultipleWindows: false,
93
+ javaScriptCanOpenWindowsAutomatically: false,
94
+ allowFileAccess: false,
95
+ allowUniversalAccessFromFileURLs: false,
96
+ mixedContentMode: "never",
97
+ domStorageEnabled: true,
98
+ sharedCookiesEnabled: false,
99
+ thirdPartyCookiesEnabled: false,
100
+ mediaPlaybackRequiresUserAction: false,
101
+ });
102
+ }
103
+ //# sourceMappingURL=reactNativeDesk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reactNativeDesk.js","sourceRoot":"","sources":["../../src/reactNativeDesk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Redaction: no token, assertion or secret may leave the SDK in an error message,
3
+ * a log line or an event. Two layers:
4
+ * - patterns that catch credentials by shape (JWTs, Bearer headers, token query
5
+ * parameters, HAINIVA key prefixes), always on;
6
+ * - a Redactor that also knows the exact secrets this client holds right now
7
+ * (the current access and refresh tokens), so even an opaque token is caught.
8
+ */
9
+ /** Redact credential-shaped substrings. */
10
+ export declare function redactString(s: string, known?: Iterable<string>): string;
11
+ /** A deep copy with credentials removed: sensitive keys blanked, strings scrubbed, Errors flattened. */
12
+ export declare function redactValue(v: unknown, known?: Iterable<string>, depth?: number): unknown;
13
+ /** Knows the secrets one client holds right now, on top of the patterns. */
14
+ export declare class Redactor {
15
+ private readonly secrets;
16
+ add(...secrets: (string | null | undefined)[]): void;
17
+ remove(...secrets: (string | null | undefined)[]): void;
18
+ clear(): void;
19
+ string(s: string): string;
20
+ value(v: unknown): unknown;
21
+ }
22
+ //# sourceMappingURL=redact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../src/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgBH,2CAA2C;AAC3C,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,GAAE,QAAQ,CAAC,MAAM,CAAM,GAAG,MAAM,CAK5E;AAED,wGAAwG;AACxG,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,GAAE,QAAQ,CAAC,MAAM,CAAM,EAAE,KAAK,SAAI,GAAG,OAAO,CAcxF;AAED,4EAA4E;AAC5E,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,GAAG,CAAC,GAAG,OAAO,EAAE,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI;IACpD,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI;IACvD,KAAK,IAAI,IAAI;IACb,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;IACzB,KAAK,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO;CAC3B"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Redaction: no token, assertion or secret may leave the SDK in an error message,
3
+ * a log line or an event. Two layers:
4
+ * - patterns that catch credentials by shape (JWTs, Bearer headers, token query
5
+ * parameters, HAINIVA key prefixes), always on;
6
+ * - a Redactor that also knows the exact secrets this client holds right now
7
+ * (the current access and refresh tokens), so even an opaque token is caught.
8
+ */
9
+ const PATTERNS = [
10
+ // JWT / JWS / JWE (assertions, access tokens, LiveKit tokens).
11
+ [/eyJ[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}(?:\.[A-Za-z0-9_-]*){1,3}/g, "[redacted-jwt]"],
12
+ // Authorization header values.
13
+ [/\b(Bearer|Basic|Token)\s+[A-Za-z0-9._~+/=-]{8,}/gi, "$1 [redacted]"],
14
+ // Credentials in a query string.
15
+ [/([?&#](?:access_token|refresh_token|id_token|token|assertion|ticket|api_key|apikey|key|secret|signature|sig|password)=)[^&#\s"']+/gi, "$1[redacted]"],
16
+ // HAINIVA API keys and refresh tokens by prefix.
17
+ [/\b(aicc_(?:live|test)_|hnv_|agr_|apr_)[A-Za-z0-9_-]{6,}/g, "$1[redacted]"],
18
+ ];
19
+ /** Object keys whose values are never shown. */
20
+ const SENSITIVE_KEY = /token|assertion|secret|password|passwd|authori[sz]ation|cookie|refresh|jwt|signature|api[-_]?key|private[-_]?key|credential/i;
21
+ /** Redact credential-shaped substrings. */
22
+ export function redactString(s, known = []) {
23
+ let out = s;
24
+ for (const k of known)
25
+ if (k && k.length >= 8)
26
+ out = out.split(k).join("[redacted]");
27
+ for (const [re, by] of PATTERNS)
28
+ out = out.replace(re, by);
29
+ return out;
30
+ }
31
+ /** A deep copy with credentials removed: sensitive keys blanked, strings scrubbed, Errors flattened. */
32
+ export function redactValue(v, known = [], depth = 0) {
33
+ const list = [...known];
34
+ if (typeof v === "string")
35
+ return redactString(v, list);
36
+ if (v === null || typeof v !== "object")
37
+ return v;
38
+ if (depth > 6)
39
+ return "[truncated]";
40
+ if (v instanceof Error) {
41
+ return { name: v.name, message: redactString(v.message, list), ...(v.stack ? { stack: redactString(v.stack, list) } : {}) };
42
+ }
43
+ if (Array.isArray(v))
44
+ return v.slice(0, 100).map((x) => redactValue(x, list, depth + 1));
45
+ const out = {};
46
+ for (const [k, x] of Object.entries(v)) {
47
+ out[k] = SENSITIVE_KEY.test(k) && x !== null && x !== undefined && x !== "" ? "[redacted]" : redactValue(x, list, depth + 1);
48
+ }
49
+ return out;
50
+ }
51
+ /** Knows the secrets one client holds right now, on top of the patterns. */
52
+ export class Redactor {
53
+ constructor() {
54
+ this.secrets = new Set();
55
+ }
56
+ add(...secrets) { for (const s of secrets)
57
+ if (s)
58
+ this.secrets.add(s); }
59
+ remove(...secrets) { for (const s of secrets)
60
+ if (s)
61
+ this.secrets.delete(s); }
62
+ clear() { this.secrets.clear(); }
63
+ string(s) { return redactString(s, this.secrets); }
64
+ value(v) { return redactValue(v, this.secrets); }
65
+ }
66
+ //# sourceMappingURL=redact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../../src/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,QAAQ,GAAuB;IACnC,+DAA+D;IAC/D,CAAC,mEAAmE,EAAE,gBAAgB,CAAC;IACvF,+BAA+B;IAC/B,CAAC,mDAAmD,EAAE,eAAe,CAAC;IACtE,iCAAiC;IACjC,CAAC,qIAAqI,EAAE,cAAc,CAAC;IACvJ,iDAAiD;IACjD,CAAC,0DAA0D,EAAE,cAAc,CAAC;CAC7E,CAAC;AAEF,gDAAgD;AAChD,MAAM,aAAa,GAAG,8HAA8H,CAAC;AAErJ,2CAA2C;AAC3C,MAAM,UAAU,YAAY,CAAC,CAAS,EAAE,QAA0B,EAAE;IAClE,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC;YAAE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACrF,KAAK,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,QAAQ;QAAE,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3D,OAAO,GAAG,CAAC;AACb,CAAC;AAED,wGAAwG;AACxG,MAAM,UAAU,WAAW,CAAC,CAAU,EAAE,QAA0B,EAAE,EAAE,KAAK,GAAG,CAAC;IAC7E,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IACxB,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACxD,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC;IAClD,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,aAAa,CAAC;IACpC,IAAI,CAAC,YAAY,KAAK,EAAE,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC9H,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IACzF,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAA4B,CAAC,EAAE,CAAC;QAClE,GAAG,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAC/H,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,4EAA4E;AAC5E,MAAM,OAAO,QAAQ;IAArB;QACmB,YAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAM/C,CAAC;IALC,GAAG,CAAC,GAAG,OAAsC,IAAU,KAAK,MAAM,CAAC,IAAI,OAAO;QAAE,IAAI,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7G,MAAM,CAAC,GAAG,OAAsC,IAAU,KAAK,MAAM,CAAC,IAAI,OAAO;QAAE,IAAI,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnH,KAAK,KAAW,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACvC,MAAM,CAAC,CAAS,IAAY,OAAO,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACnE,KAAK,CAAC,CAAU,IAAa,OAAO,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;CACpE"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * The REST client for the Agent API (`/agent/v1/*`).
3
+ *
4
+ * - `baseUrl` is checked with assertSafeUrl (HTTPS only, no credential in it);
5
+ * - the access token goes in the Authorization header only — never in a URL;
6
+ * - a 401 `token_expired` (or `token_invalid`) refreshes ONCE (single flight
7
+ * across every caller: SessionManager) and retries the request once; a
8
+ * refused refresh signs in again with a NEW assertion from `getAssertion`;
9
+ * a 401 `session_revoked` is final (the facade emits `revoked`);
10
+ * - every POST carries an `Idempotency-Key` (the retry after a refresh reuses
11
+ * it, so the server never does the action twice);
12
+ * - each request has a timeout (default 15 s) and honours an AbortSignal;
13
+ * - any non-2xx becomes a HainivaAgentError {status, code, body} from the
14
+ * server's `{error:{code,message}}` envelope, redacted; non-JSON or
15
+ * non-object bodies are handled defensively.
16
+ */
17
+ import type { AgentAcceptDto, AgentCallDto, AgentConversationDto, AgentDispositionDto, AgentMeDto, AgentMediaTokenDto, AgentMessageDto, AgentPage, AgentPresenceStatus, AgentPushSubscriptionDto, AgentPushSubscriptionInput, AgentRingDto, AgentDeskSessionDto, AgentSessionDto, SupervisorAgentDto, SupervisorLiveCallDto, SupervisorSuperviseDto } from "./contract.js";
18
+ import { HainivaAgentError } from "./errors.js";
19
+ import { type Logger } from "./log.js";
20
+ import { Redactor } from "./redact.js";
21
+ import type { AgentSession, SessionTransport } from "./session.js";
22
+ export interface AgentRestOptions {
23
+ /** e.g. https://api.hainiva.com (HTTPS only). */
24
+ baseUrl: string;
25
+ /** Your HAINIVA organisation id: sign-in and refresh name it. */
26
+ tenantId: string;
27
+ fetch?: typeof fetch;
28
+ /** Per request, default 15 000 ms. */
29
+ timeoutMs?: number;
30
+ /** Local development only: http://localhost. */
31
+ allowInsecureLocalhost?: boolean;
32
+ /** Device shown to the organisation's admins in the session list. */
33
+ device?: {
34
+ label?: string;
35
+ platform?: "ios" | "android" | "web" | "other";
36
+ };
37
+ redactor?: Redactor;
38
+ log?: Logger;
39
+ }
40
+ /** Where the client gets its access token, and how it reports a refused one. */
41
+ export interface TokenSource {
42
+ accessToken(): Promise<string>;
43
+ /** The server refused this token: refresh before the next request. */
44
+ invalidate(refused?: string): void;
45
+ }
46
+ export interface RequestOptions {
47
+ body?: unknown;
48
+ query?: Record<string, string | number | undefined>;
49
+ signal?: AbortSignal;
50
+ /** Overrides the client's timeout for this request. */
51
+ timeoutMs?: number;
52
+ }
53
+ /** LiveKit room credentials for a call. */
54
+ export type MediaCredentials = AgentMediaTokenDto;
55
+ export type AgentStatus = AgentPresenceStatus;
56
+ /** Where a call is transferred. */
57
+ export type CallTransferTarget = {
58
+ agentId: string;
59
+ mode?: "warm" | "blind";
60
+ } | {
61
+ queueId: string;
62
+ } | {
63
+ number: string;
64
+ mode?: "warm" | "blind";
65
+ };
66
+ export interface ConversationListQuery {
67
+ scope?: "all" | "mine";
68
+ status?: "open" | "closed" | "all";
69
+ cursor?: string;
70
+ limit?: number;
71
+ }
72
+ /** A random UUID v4: crypto.randomUUID where it exists (browsers, Node), else getRandomValues, else Math.random (Idempotency-Key only, not a secret). */
73
+ export declare function newIdempotencyKey(): string;
74
+ /** Pure: the error a non-2xx answer becomes. Exported for tests. */
75
+ export declare function errorFromResponse(status: number, data: unknown, redactor?: Redactor, retryAfter?: string | null): HainivaAgentError;
76
+ /**
77
+ * The Agent API over fetch. `tokens` is normally the SessionManager; the
78
+ * client's own `sessions` transport is what that SessionManager signs in with.
79
+ */
80
+ export declare class AgentRestClient {
81
+ private readonly o;
82
+ readonly baseUrl: string;
83
+ private readonly fetchFn;
84
+ private readonly timeoutMs;
85
+ private readonly redactor;
86
+ private readonly log;
87
+ private tokens;
88
+ constructor(o: AgentRestOptions, tokens?: TokenSource);
89
+ /** Attach the token source after construction (the SessionManager needs `sessions` first). */
90
+ useTokens(tokens: TokenSource): void;
91
+ /** The wss:// URL of the event stream, derived from baseUrl (never from a server answer). */
92
+ get wsUrl(): string;
93
+ readonly sessions: SessionTransport<AgentSession & AgentSessionDto>;
94
+ /** An authenticated request: refresh-and-retry once on an expired token. */
95
+ request<T>(method: "GET" | "POST" | "PUT" | "DELETE", path: string, opts?: RequestOptions): Promise<T>;
96
+ private raw;
97
+ me(o?: RequestOptions): Promise<AgentMeDto>;
98
+ setStatus(status: AgentStatus, o?: RequestOptions): Promise<{
99
+ status: AgentStatus;
100
+ }>;
101
+ /** Rings for this member now (after a cold start, a missed push or a resync). */
102
+ pendingRings(o?: RequestOptions): Promise<AgentRingDto[]>;
103
+ getCall(callId: string, o?: RequestOptions): Promise<AgentCallDto>;
104
+ acceptCall(callId: string, o?: RequestOptions): Promise<AgentAcceptDto>;
105
+ declineCall(callId: string, o?: RequestOptions): Promise<{
106
+ callId: string;
107
+ declined: true;
108
+ }>;
109
+ endCall(callId: string, o?: RequestOptions): Promise<{
110
+ callId: string;
111
+ ended: true;
112
+ }>;
113
+ holdCall(callId: string, on: boolean, o?: RequestOptions): Promise<{
114
+ callId: string;
115
+ onHold: boolean;
116
+ }>;
117
+ transferCall(callId: string, target: CallTransferTarget, o?: RequestOptions): Promise<{
118
+ callId: string;
119
+ transferred: true;
120
+ }>;
121
+ /**
122
+ * A 15-minute desk token for the embedded HAINIVA desk (S4): give it to the
123
+ * desk over postMessage only (`@hainiva/agent-sdk/embed` does). Never put it
124
+ * in a URL or storage. Ends with this session.
125
+ */
126
+ deskSession(o?: RequestOptions): Promise<AgentDeskSessionDto>;
127
+ /** Re-mint the LiveKit token while still a participant (reconnect, token near expiry). */
128
+ mediaToken(callId: string, o?: RequestOptions): Promise<MediaCredentials>;
129
+ dispositions(channel?: string, o?: RequestOptions): Promise<AgentDispositionDto[]>;
130
+ wrapUp(callId: string, w?: {
131
+ dispositionCode?: string;
132
+ notes?: string;
133
+ }, o?: RequestOptions): Promise<{
134
+ callId: string;
135
+ wrappedUp: true;
136
+ }>;
137
+ listConversations(q?: ConversationListQuery, o?: RequestOptions): Promise<AgentPage<AgentConversationDto>>;
138
+ getConversation(conversationId: string, o?: RequestOptions): Promise<AgentConversationDto>;
139
+ /** Claim it (no agentId), or — a supervisor — assign it to a colleague. */
140
+ assignConversation(conversationId: string, agentId?: string, o?: RequestOptions): Promise<unknown>;
141
+ releaseConversation(conversationId: string, note?: string, o?: RequestOptions): Promise<{
142
+ conversationId: string;
143
+ released: true;
144
+ }>;
145
+ transferConversation(conversationId: string, to: {
146
+ agentId: string;
147
+ } | {
148
+ queueId: string;
149
+ note?: string;
150
+ }, o?: RequestOptions): Promise<unknown>;
151
+ closeConversation(conversationId: string, o?: RequestOptions): Promise<{
152
+ conversationId: string;
153
+ closed: true;
154
+ }>;
155
+ listMessages(conversationId: string, q?: {
156
+ after?: string;
157
+ limit?: number;
158
+ }, o?: RequestOptions): Promise<AgentPage<AgentMessageDto>>;
159
+ sendMessage(conversationId: string, text: string, o?: RequestOptions): Promise<Pick<AgentMessageDto, "id" | "conversationId" | "interactionId" | "createdAt">>;
160
+ typing(conversationId: string, o?: RequestOptions): Promise<{
161
+ ok: true;
162
+ }>;
163
+ liveCalls(o?: RequestOptions): Promise<SupervisorLiveCallDto[]>;
164
+ teamAgents(o?: RequestOptions): Promise<SupervisorAgentDto[]>;
165
+ supervise(callId: string, mode?: "monitor" | "whisper" | "barge", o?: RequestOptions): Promise<SupervisorSuperviseDto>;
166
+ setSuperviseMode(callId: string, mode: "monitor" | "whisper" | "barge", supervisorTrackSid?: string, o?: RequestOptions): Promise<{
167
+ callId: string;
168
+ mode: string;
169
+ }>;
170
+ registerPush(sub: AgentPushSubscriptionInput, o?: RequestOptions): Promise<AgentPushSubscriptionDto>;
171
+ unregisterPush(token: string, o?: RequestOptions): Promise<void>;
172
+ }
173
+ //# sourceMappingURL=rest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest.d.ts","sourceRoot":"","sources":["../../src/rest.ts"],"names":[],"mappings":"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"}