@everfur/sdk 0.1.1 → 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 (187) hide show
  1. package/CHANGELOG.md +634 -0
  2. package/README.md +58 -23
  3. package/consent/package.json +8 -0
  4. package/dist/Chat-DPUD6dnc.d.cts +128 -0
  5. package/dist/Chat-DwAC2vhB.d.ts +128 -0
  6. package/dist/DepthViews-DNEM96Se.d.ts +16 -0
  7. package/dist/DepthViews-DP0R-DhB.d.cts +19 -0
  8. package/dist/DepthViews-D_3hl4xk.d.ts +19 -0
  9. package/dist/DepthViews-DbFhR4Du.d.cts +16 -0
  10. package/dist/ErrorPolicyPort-CNf4uQZP.d.cts +22 -0
  11. package/dist/ErrorPolicyPort-CwbfmxzJ.d.ts +22 -0
  12. package/dist/{EverfurResult-D92-uL82.d.cts → EverfurResult-DN9pL2Ab.d.cts} +11 -10
  13. package/dist/{EverfurResult-D92-uL82.d.ts → EverfurResult-DN9pL2Ab.d.ts} +11 -10
  14. package/dist/{PhotoController-BItt5M7u.d.cts → PhotoController-3l7MT9jA.d.cts} +1 -1
  15. package/dist/{PhotoController-D8zMTdcW.d.ts → PhotoController-vzY5bfY_.d.ts} +1 -1
  16. package/dist/animations/index.cjs +1 -1997
  17. package/dist/animations/index.d.cts +35 -35
  18. package/dist/animations/index.d.ts +35 -35
  19. package/dist/animations/index.js +1 -1972
  20. package/dist/attachments-5NeobOCd.d.ts +256 -0
  21. package/dist/attachments-Bw3iMQgu.d.ts +146 -0
  22. package/dist/attachments-CQgFrEQ7.d.cts +146 -0
  23. package/dist/attachments-D8T5re7e.d.cts +256 -0
  24. package/dist/casesRepository-ClLv6qMl.d.ts +188 -0
  25. package/dist/casesRepository-DHwtGRYY.d.cts +188 -0
  26. package/dist/chat/index.cjs +1 -1170
  27. package/dist/chat/index.d.cts +31 -53
  28. package/dist/chat/index.d.ts +31 -53
  29. package/dist/chat/index.js +1 -1167
  30. package/dist/client/index.cjs +9 -2315
  31. package/dist/client/index.d.cts +77 -15
  32. package/dist/client/index.d.ts +77 -15
  33. package/dist/client/index.js +9 -2215
  34. package/dist/{config-CiJ0PVBB.d.ts → config-CzTZGlfF.d.cts} +63 -25
  35. package/dist/{config-BSjBdxrZ.d.cts → config-DW60uRb9.d.ts} +63 -25
  36. package/dist/consent/index.cjs +1 -0
  37. package/dist/consent/index.d.cts +33 -0
  38. package/dist/consent/index.d.ts +33 -0
  39. package/dist/consent/index.js +1 -0
  40. package/dist/context-DXhqHlPU.d.ts +159 -0
  41. package/dist/context-XvTzq1tE.d.cts +159 -0
  42. package/dist/copy-Mjoo91aS.d.ts +198 -0
  43. package/dist/copy-bKDNigLb.d.cts +198 -0
  44. package/dist/core/index.cjs +13 -3178
  45. package/dist/core/index.d.cts +58 -12
  46. package/dist/core/index.d.ts +58 -12
  47. package/dist/core/index.js +13 -3166
  48. package/dist/depth-CErXCU8J.d.cts +502 -0
  49. package/dist/depth-DjDcJ6kH.d.ts +502 -0
  50. package/dist/entitlementRepository-DKdXFgTo.d.cts +698 -0
  51. package/dist/entitlementRepository-DSbzuyAW.d.ts +698 -0
  52. package/dist/{identity-DK9zORrG.d.ts → identity-BMx2SUOM.d.ts} +19 -6
  53. package/dist/{identity-Brl-lDd6.d.cts → identity-DI4eVx9S.d.cts} +19 -6
  54. package/dist/{ids-CJ1S6adf.d.cts → ids-B2GAAifq.d.cts} +1 -1
  55. package/dist/{ids-CJ1S6adf.d.ts → ids-B2GAAifq.d.ts} +1 -1
  56. package/dist/index.cjs +12 -4494
  57. package/dist/index.d.cts +29 -121
  58. package/dist/index.d.ts +29 -121
  59. package/dist/index.js +12 -4470
  60. package/dist/models-B-Uh2LTf.d.ts +214 -0
  61. package/dist/models-D2EUxPZY.d.cts +214 -0
  62. package/dist/notifications/index.cjs +2 -0
  63. package/dist/notifications/index.d.cts +17 -0
  64. package/dist/notifications/index.d.ts +17 -0
  65. package/dist/notifications/index.js +2 -0
  66. package/dist/pets-CtQdRpWo.d.ts +92 -0
  67. package/dist/pets-aB8q0JyX.d.cts +92 -0
  68. package/dist/photo/index.cjs +1 -2189
  69. package/dist/photo/index.d.cts +6 -6
  70. package/dist/photo/index.d.ts +6 -6
  71. package/dist/photo/index.js +1 -2186
  72. package/dist/ports-BN6RHF9W.d.cts +48 -0
  73. package/dist/ports-BN6RHF9W.d.ts +48 -0
  74. package/dist/ports-DEBzEhbp.d.cts +386 -0
  75. package/dist/ports-DMolTRzU.d.ts +386 -0
  76. package/dist/profile-CSs1wlXT.d.cts +93 -0
  77. package/dist/profile-CSs1wlXT.d.ts +93 -0
  78. package/dist/records/depth/index.cjs +2 -0
  79. package/dist/records/depth/index.d.cts +13 -0
  80. package/dist/records/depth/index.d.ts +13 -0
  81. package/dist/records/depth/index.js +2 -0
  82. package/dist/records/index.cjs +3 -2839
  83. package/dist/records/index.d.cts +137 -203
  84. package/dist/records/index.d.ts +137 -203
  85. package/dist/records/index.js +3 -2833
  86. package/dist/requestFunnel-CjW7uDuA.d.ts +87 -0
  87. package/dist/requestFunnel-L-BQfi0z.d.cts +87 -0
  88. package/dist/{resolve-Dq_4_agU.d.ts → resolve-D4Ywz5OS.d.cts} +10 -4
  89. package/dist/{resolve-Dq_4_agU.d.cts → resolve-D4Ywz5OS.d.ts} +10 -4
  90. package/dist/{runtime-Bvr8yqXm.d.cts → runtime-B8s-_hv8.d.cts} +121 -59
  91. package/dist/{runtime-BIYzf9cK.d.ts → runtime-BR9ysG0J.d.ts} +121 -59
  92. package/dist/server/events/index.cjs +2 -0
  93. package/dist/server/events/index.d.cts +550 -0
  94. package/dist/server/events/index.d.ts +550 -0
  95. package/dist/server/events/index.js +2 -0
  96. package/dist/server/index.cjs +2 -533
  97. package/dist/server/index.d.cts +73 -18
  98. package/dist/server/index.d.ts +73 -18
  99. package/dist/server/index.js +2 -530
  100. package/dist/species-BXAIMh7I.d.cts +9 -0
  101. package/dist/species-BXAIMh7I.d.ts +9 -0
  102. package/dist/televet/index.cjs +1 -0
  103. package/dist/televet/index.d.cts +60 -0
  104. package/dist/televet/index.d.ts +60 -0
  105. package/dist/televet/index.js +1 -0
  106. package/dist/testing/index.cjs +5 -823
  107. package/dist/testing/index.d.cts +17 -3
  108. package/dist/testing/index.d.ts +17 -3
  109. package/dist/testing/index.js +5 -820
  110. package/dist/testing/rn/index.cjs +1 -449
  111. package/dist/testing/rn/index.d.cts +17 -29
  112. package/dist/testing/rn/index.d.ts +17 -29
  113. package/dist/testing/rn/index.js +1 -444
  114. package/dist/testing/web/index.cjs +1 -0
  115. package/dist/testing/web/index.d.cts +131 -0
  116. package/dist/testing/web/index.d.ts +131 -0
  117. package/dist/testing/web/index.js +1 -0
  118. package/dist/timelineRows-CaohZzXS.d.cts +19 -0
  119. package/dist/timelineRows-DZed6dAM.d.ts +19 -0
  120. package/dist/typeStyle-0TydiZ1w.d.cts +19 -0
  121. package/dist/typeStyle-CWMsoe6b.d.ts +19 -0
  122. package/dist/uploadTransport-D0M0T4hN.d.ts +38 -0
  123. package/dist/uploadTransport-DKJHs3Yj.d.cts +38 -0
  124. package/dist/useRecordsDepth-BHBzJ76R.d.cts +237 -0
  125. package/dist/useRecordsDepth-BU-OhzH6.d.ts +237 -0
  126. package/dist/useVetVisit-Bc84hWUU.d.cts +187 -0
  127. package/dist/useVetVisit-CjmMa896.d.ts +187 -0
  128. package/dist/video/index.cjs +1 -1941
  129. package/dist/video/index.d.cts +4 -4
  130. package/dist/video/index.d.ts +4 -4
  131. package/dist/video/index.js +1 -1938
  132. package/dist/view-C3qPIXGX.d.cts +310 -0
  133. package/dist/view-DtSPYpKa.d.ts +310 -0
  134. package/dist/visitIntent-D7_yVp1I.d.cts +8 -0
  135. package/dist/visitIntent-D7_yVp1I.d.ts +8 -0
  136. package/dist/web/consent/index.cjs +1 -0
  137. package/dist/web/consent/index.d.cts +34 -0
  138. package/dist/web/consent/index.d.ts +34 -0
  139. package/dist/web/consent/index.js +1 -0
  140. package/dist/web/index.cjs +14 -0
  141. package/dist/web/index.d.cts +217 -0
  142. package/dist/web/index.d.ts +217 -0
  143. package/dist/web/index.js +14 -0
  144. package/dist/web/notifications/index.cjs +2 -0
  145. package/dist/web/notifications/index.d.cts +213 -0
  146. package/dist/web/notifications/index.d.ts +213 -0
  147. package/dist/web/notifications/index.js +2 -0
  148. package/dist/web/records/depth/index.cjs +2 -0
  149. package/dist/web/records/depth/index.d.cts +12 -0
  150. package/dist/web/records/depth/index.d.ts +12 -0
  151. package/dist/web/records/depth/index.js +2 -0
  152. package/dist/web/records/index.cjs +4 -0
  153. package/dist/web/records/index.d.cts +194 -0
  154. package/dist/web/records/index.d.ts +194 -0
  155. package/dist/web/records/index.js +4 -0
  156. package/dist/web/televet/index.cjs +1 -0
  157. package/dist/web/televet/index.d.cts +50 -0
  158. package/dist/web/televet/index.d.ts +50 -0
  159. package/dist/web/televet/index.js +1 -0
  160. package/notifications/package.json +8 -0
  161. package/package.json +197 -9
  162. package/records/depth/package.json +8 -0
  163. package/server/events/device-blocked.cjs +15 -0
  164. package/server/events/package.json +9 -0
  165. package/televet/package.json +8 -0
  166. package/testing/web/native-blocked.cjs +12 -0
  167. package/testing/web/package.json +8 -0
  168. package/web/consent/native-blocked.cjs +12 -0
  169. package/web/consent/package.json +8 -0
  170. package/web/native-blocked.cjs +12 -0
  171. package/web/notifications/native-blocked.cjs +12 -0
  172. package/web/notifications/package.json +8 -0
  173. package/web/package.json +8 -0
  174. package/web/records/depth/native-blocked.cjs +12 -0
  175. package/web/records/depth/package.json +8 -0
  176. package/web/records/native-blocked.cjs +12 -0
  177. package/web/records/package.json +8 -0
  178. package/web/televet/native-blocked.cjs +12 -0
  179. package/web/televet/package.json +8 -0
  180. package/dist/ChatController-CKdBvPj2.d.ts +0 -146
  181. package/dist/ChatController-CpUMvvZf.d.cts +0 -146
  182. package/dist/FilePort-BabWrv7I.d.cts +0 -22
  183. package/dist/FilePort-BabWrv7I.d.ts +0 -22
  184. package/dist/petsRepository-BEGb97M9.d.cts +0 -326
  185. package/dist/petsRepository-Bu18r2kK.d.ts +0 -326
  186. package/dist/requestFunnel-DuUH-kAe.d.cts +0 -28
  187. package/dist/requestFunnel-dio5OmR9.d.ts +0 -28
@@ -1,146 +0,0 @@
1
- import { R as RequestFunnel } from './requestFunnel-dio5OmR9.js';
2
- import { A as AuthContext } from './identity-DK9zORrG.js';
3
- import { a as EverfurErrorCode, f as EverfurError, E as EverfurResult } from './EverfurResult-D92-uL82.js';
4
- import { b as ResponseId, a as ConversationId, P as PetRef } from './ids-CJ1S6adf.js';
5
- import { F as Frame } from './config-CiJ0PVBB.js';
6
- import { T as TelemetryPort } from './TelemetryPort-BDNr00hu.js';
7
-
8
- /**
9
- * Recovery policy. A host may narrow retry ceilings (e.g. a metered plan) but can never widen the SDK's
10
- * settle-don't-throw contract. `attempt` is 0-based (the first try is attempt 0).
11
- */
12
- interface ErrorPolicyPort {
13
- /** Whether to retry `code` on this attempt. Default: `isAutoRetryable(code) && attempt < maxAttempts(code)`. */
14
- shouldRetry(code: EverfurErrorCode, attempt: number): boolean;
15
- /** Total attempts (the initial try plus retries) before the terminal error surfaces. Default 4. */
16
- maxAttempts(code: EverfurErrorCode): number;
17
- /** Observation hook for a handled, product-expected failure. Never rendered, never thrown. */
18
- onExpectedFailure?(error: EverfurError): void;
19
- }
20
- /**
21
- * The shipped default policy (applied when EverfurConfig omits `errorPolicy`). Pure and total.
22
- * `authExpired` is deliberately NOT auto-retried here: it is a token refresh + single replay handled by the
23
- * controller / authedSend, not a backoff retry (SPEC-00 §3.2 / §4.3).
24
- */
25
- declare const defaultErrorPolicy: ErrorPolicyPort;
26
-
27
- /** Injectable timers so the watchdog + deadlines are testable with a fake clock (no direct setTimeout). */
28
- interface Timers {
29
- setTimeout(handler: () => void, ms: number): unknown;
30
- clearTimeout(handle: unknown): void;
31
- now(): number;
32
- }
33
-
34
- type ChatStatus = 'idle' | 'streaming' | 'complete' | 'error';
35
- /** Opaque citation record (DoneFrame.citations shape). Rendered by the UI layer, never trusted for logic. */
36
- type Citation = Readonly<Record<string, unknown>>;
37
- interface ChatMessage {
38
- /** Stable list key: a client id for a user turn, the responseId for a finalized assistant turn. */
39
- readonly id: string;
40
- readonly role: 'user' | 'assistant';
41
- readonly text: string;
42
- readonly citations?: readonly Citation[];
43
- readonly responseId?: ResponseId;
44
- /** Optimistic user bubble; removed if the turn fails BEFORE the first delta. */
45
- readonly pending?: boolean;
46
- }
47
- interface ChatSnapshot {
48
- readonly status: ChatStatus;
49
- /** [] => Empty state; length > 0 => Populated. */
50
- readonly messages: readonly ChatMessage[];
51
- /** nulled on a 404 before recreate. */
52
- readonly conversationId: ConversationId | null;
53
- /** present iff status === 'error'; NEVER thrown. */
54
- readonly error: EverfurError | null;
55
- readonly isStreaming: boolean;
56
- /** true during the initial conversation prime => Loading. */
57
- readonly isBootstrapping: boolean;
58
- /**
59
- * Flattened, de-duplicated suggested-prompt strings from the prompts bootstrap (backend-owned copy; empty
60
- * until the bootstrap resolves, empty when the backend returns none). The UI renders these as the tappable
61
- * "Follow up questions" list; each string is a ready-to-send message.
62
- */
63
- readonly suggestedPrompts: readonly string[];
64
- }
65
- interface SendOptions {
66
- readonly conversationId?: ConversationId;
67
- readonly petRef?: PetRef;
68
- readonly signal?: AbortSignal;
69
- readonly idempotencyKey?: string;
70
- }
71
- interface ChatHandlers {
72
- onFrame(frame: Frame): void;
73
- onDone(responseId: ResponseId | null): void;
74
- onError(error: EverfurError): void;
75
- }
76
- /** A suggested-prompt category returned by the prompts bootstrap endpoint. */
77
- interface SuggestedPromptCategory {
78
- readonly category: string;
79
- readonly prompts: readonly string[];
80
- }
81
- interface ChatControllerDeps {
82
- /** Device auth context (bearer-XOR-pk precedence + lazy token). Carries the TransportPort. */
83
- readonly auth: AuthContext;
84
- readonly telemetry?: TelemetryPort;
85
- readonly errorPolicy?: ErrorPolicyPort;
86
- readonly timers?: Timers;
87
- /** Injected RNG for deterministic backoff in tests. */
88
- readonly rng?: () => number;
89
- /** Injected id factory (client message ids) for deterministic tests. */
90
- readonly newId?: () => string;
91
- /** Injected idempotency-key factory for the TURN identity (see `buildSendRequest`). */
92
- readonly makeIdempotencyKey?: () => string;
93
- /** The ONE request funnel. Built from `auth` when absent; injected in tests for a deterministic clock. */
94
- readonly funnel?: RequestFunnel;
95
- readonly budget?: {
96
- readonly idleMs?: number;
97
- readonly overallMs?: number;
98
- };
99
- readonly initialConversationId?: ConversationId | null;
100
- }
101
- interface ChatController {
102
- /** useSyncExternalStore subscribe. Returns an unsubscribe. */
103
- subscribe(listener: () => void): () => void;
104
- /** A stable frozen snapshot; identity changes only on real change. */
105
- getSnapshot(): ChatSnapshot;
106
- /** Stream a reply. The iterable ALWAYS completes cleanly; a failure is a terminal Frame, never a throw. */
107
- send(text: string, opts?: SendOptions): AsyncIterable<Frame>;
108
- /** Imperative escape hatch; returns a teardown, also torn down on dispose(). */
109
- send(text: string, opts: SendOptions, handlers: ChatHandlers): () => void;
110
- /** Re-send the last turn without a duplicate user bubble, reusing its idempotency key. */
111
- retryLast(): AsyncIterable<Frame>;
112
- /** Abort in-flight; not an error. Returns to pre-send (idle) and drops a never-answered optimistic bubble. */
113
- stop(): void;
114
- /** Idempotent. Aborts in-flight, bumps the epoch, drops listeners + handler subscriptions. */
115
- dispose(): void;
116
- /** Re-scope on user/pet switch: aborts in-flight and bumps the epoch so a late write drops. */
117
- rescope(): void;
118
- /** Bootstrap helper (§8): create a conversation. Unary, authed, settles. */
119
- createConversation(opts?: {
120
- readonly petRef?: PetRef;
121
- }): Promise<EverfurResult<ConversationId>>;
122
- /** Bootstrap helper (§8): fetch the session's suggested prompts, optionally personalized to a pet. Settles; never throws. */
123
- getPrompts(opts?: {
124
- readonly petRef?: PetRef;
125
- }): Promise<EverfurResult<readonly SuggestedPromptCategory[]>>;
126
- /** Adopt (or clear) the active conversation id, e.g. after bootstrap primes one. */
127
- adoptConversation(id: ConversationId | null): void;
128
- /**
129
- * Adopt the suggested-prompt categories fetched by the bootstrap (§8): flattened + de-duplicated onto the
130
- * snapshot's `suggestedPrompts` so the prebuilt UI can render the tappable follow-up list. Idempotent; a
131
- * no-op when the flattened set is empty and none are shown.
132
- */
133
- adoptPrompts(categories: readonly SuggestedPromptCategory[]): void;
134
- }
135
- declare function createChatController(deps: ChatControllerDeps): ChatController;
136
- /**
137
- * The server's own limits on a chat message, mirrored here so a violation is caught before any UI is
138
- * rendered for it. `SendWidgetMessageRequest.message` on EFBackend main declares
139
- * `min_length=1, max_length=4000`; the server remains authoritative and still enforces both.
140
- *
141
- * These are NOT in the generated contract projection, so they are pinned here with their source rather
142
- * than derived. If the server relaxes either bound, this is the one place to update.
143
- */
144
- declare const MESSAGE_MAX_CHARS = 4000;
145
-
146
- export { type ChatController as C, type ErrorPolicyPort as E, MESSAGE_MAX_CHARS as M, type SuggestedPromptCategory as S, type Timers as T, type ChatControllerDeps as a, type ChatHandlers as b, type ChatMessage as c, type ChatSnapshot as d, type ChatStatus as e, type Citation as f, type SendOptions as g, createChatController as h, defaultErrorPolicy as i };
@@ -1,146 +0,0 @@
1
- import { R as RequestFunnel } from './requestFunnel-DuUH-kAe.cjs';
2
- import { A as AuthContext } from './identity-Brl-lDd6.cjs';
3
- import { a as EverfurErrorCode, f as EverfurError, E as EverfurResult } from './EverfurResult-D92-uL82.cjs';
4
- import { b as ResponseId, a as ConversationId, P as PetRef } from './ids-CJ1S6adf.cjs';
5
- import { F as Frame } from './config-BSjBdxrZ.cjs';
6
- import { T as TelemetryPort } from './TelemetryPort-BDNr00hu.cjs';
7
-
8
- /**
9
- * Recovery policy. A host may narrow retry ceilings (e.g. a metered plan) but can never widen the SDK's
10
- * settle-don't-throw contract. `attempt` is 0-based (the first try is attempt 0).
11
- */
12
- interface ErrorPolicyPort {
13
- /** Whether to retry `code` on this attempt. Default: `isAutoRetryable(code) && attempt < maxAttempts(code)`. */
14
- shouldRetry(code: EverfurErrorCode, attempt: number): boolean;
15
- /** Total attempts (the initial try plus retries) before the terminal error surfaces. Default 4. */
16
- maxAttempts(code: EverfurErrorCode): number;
17
- /** Observation hook for a handled, product-expected failure. Never rendered, never thrown. */
18
- onExpectedFailure?(error: EverfurError): void;
19
- }
20
- /**
21
- * The shipped default policy (applied when EverfurConfig omits `errorPolicy`). Pure and total.
22
- * `authExpired` is deliberately NOT auto-retried here: it is a token refresh + single replay handled by the
23
- * controller / authedSend, not a backoff retry (SPEC-00 §3.2 / §4.3).
24
- */
25
- declare const defaultErrorPolicy: ErrorPolicyPort;
26
-
27
- /** Injectable timers so the watchdog + deadlines are testable with a fake clock (no direct setTimeout). */
28
- interface Timers {
29
- setTimeout(handler: () => void, ms: number): unknown;
30
- clearTimeout(handle: unknown): void;
31
- now(): number;
32
- }
33
-
34
- type ChatStatus = 'idle' | 'streaming' | 'complete' | 'error';
35
- /** Opaque citation record (DoneFrame.citations shape). Rendered by the UI layer, never trusted for logic. */
36
- type Citation = Readonly<Record<string, unknown>>;
37
- interface ChatMessage {
38
- /** Stable list key: a client id for a user turn, the responseId for a finalized assistant turn. */
39
- readonly id: string;
40
- readonly role: 'user' | 'assistant';
41
- readonly text: string;
42
- readonly citations?: readonly Citation[];
43
- readonly responseId?: ResponseId;
44
- /** Optimistic user bubble; removed if the turn fails BEFORE the first delta. */
45
- readonly pending?: boolean;
46
- }
47
- interface ChatSnapshot {
48
- readonly status: ChatStatus;
49
- /** [] => Empty state; length > 0 => Populated. */
50
- readonly messages: readonly ChatMessage[];
51
- /** nulled on a 404 before recreate. */
52
- readonly conversationId: ConversationId | null;
53
- /** present iff status === 'error'; NEVER thrown. */
54
- readonly error: EverfurError | null;
55
- readonly isStreaming: boolean;
56
- /** true during the initial conversation prime => Loading. */
57
- readonly isBootstrapping: boolean;
58
- /**
59
- * Flattened, de-duplicated suggested-prompt strings from the prompts bootstrap (backend-owned copy; empty
60
- * until the bootstrap resolves, empty when the backend returns none). The UI renders these as the tappable
61
- * "Follow up questions" list; each string is a ready-to-send message.
62
- */
63
- readonly suggestedPrompts: readonly string[];
64
- }
65
- interface SendOptions {
66
- readonly conversationId?: ConversationId;
67
- readonly petRef?: PetRef;
68
- readonly signal?: AbortSignal;
69
- readonly idempotencyKey?: string;
70
- }
71
- interface ChatHandlers {
72
- onFrame(frame: Frame): void;
73
- onDone(responseId: ResponseId | null): void;
74
- onError(error: EverfurError): void;
75
- }
76
- /** A suggested-prompt category returned by the prompts bootstrap endpoint. */
77
- interface SuggestedPromptCategory {
78
- readonly category: string;
79
- readonly prompts: readonly string[];
80
- }
81
- interface ChatControllerDeps {
82
- /** Device auth context (bearer-XOR-pk precedence + lazy token). Carries the TransportPort. */
83
- readonly auth: AuthContext;
84
- readonly telemetry?: TelemetryPort;
85
- readonly errorPolicy?: ErrorPolicyPort;
86
- readonly timers?: Timers;
87
- /** Injected RNG for deterministic backoff in tests. */
88
- readonly rng?: () => number;
89
- /** Injected id factory (client message ids) for deterministic tests. */
90
- readonly newId?: () => string;
91
- /** Injected idempotency-key factory for the TURN identity (see `buildSendRequest`). */
92
- readonly makeIdempotencyKey?: () => string;
93
- /** The ONE request funnel. Built from `auth` when absent; injected in tests for a deterministic clock. */
94
- readonly funnel?: RequestFunnel;
95
- readonly budget?: {
96
- readonly idleMs?: number;
97
- readonly overallMs?: number;
98
- };
99
- readonly initialConversationId?: ConversationId | null;
100
- }
101
- interface ChatController {
102
- /** useSyncExternalStore subscribe. Returns an unsubscribe. */
103
- subscribe(listener: () => void): () => void;
104
- /** A stable frozen snapshot; identity changes only on real change. */
105
- getSnapshot(): ChatSnapshot;
106
- /** Stream a reply. The iterable ALWAYS completes cleanly; a failure is a terminal Frame, never a throw. */
107
- send(text: string, opts?: SendOptions): AsyncIterable<Frame>;
108
- /** Imperative escape hatch; returns a teardown, also torn down on dispose(). */
109
- send(text: string, opts: SendOptions, handlers: ChatHandlers): () => void;
110
- /** Re-send the last turn without a duplicate user bubble, reusing its idempotency key. */
111
- retryLast(): AsyncIterable<Frame>;
112
- /** Abort in-flight; not an error. Returns to pre-send (idle) and drops a never-answered optimistic bubble. */
113
- stop(): void;
114
- /** Idempotent. Aborts in-flight, bumps the epoch, drops listeners + handler subscriptions. */
115
- dispose(): void;
116
- /** Re-scope on user/pet switch: aborts in-flight and bumps the epoch so a late write drops. */
117
- rescope(): void;
118
- /** Bootstrap helper (§8): create a conversation. Unary, authed, settles. */
119
- createConversation(opts?: {
120
- readonly petRef?: PetRef;
121
- }): Promise<EverfurResult<ConversationId>>;
122
- /** Bootstrap helper (§8): fetch the session's suggested prompts, optionally personalized to a pet. Settles; never throws. */
123
- getPrompts(opts?: {
124
- readonly petRef?: PetRef;
125
- }): Promise<EverfurResult<readonly SuggestedPromptCategory[]>>;
126
- /** Adopt (or clear) the active conversation id, e.g. after bootstrap primes one. */
127
- adoptConversation(id: ConversationId | null): void;
128
- /**
129
- * Adopt the suggested-prompt categories fetched by the bootstrap (§8): flattened + de-duplicated onto the
130
- * snapshot's `suggestedPrompts` so the prebuilt UI can render the tappable follow-up list. Idempotent; a
131
- * no-op when the flattened set is empty and none are shown.
132
- */
133
- adoptPrompts(categories: readonly SuggestedPromptCategory[]): void;
134
- }
135
- declare function createChatController(deps: ChatControllerDeps): ChatController;
136
- /**
137
- * The server's own limits on a chat message, mirrored here so a violation is caught before any UI is
138
- * rendered for it. `SendWidgetMessageRequest.message` on EFBackend main declares
139
- * `min_length=1, max_length=4000`; the server remains authoritative and still enforces both.
140
- *
141
- * These are NOT in the generated contract projection, so they are pinned here with their source rather
142
- * than derived. If the server relaxes either bound, this is the one place to update.
143
- */
144
- declare const MESSAGE_MAX_CHARS = 4000;
145
-
146
- export { type ChatController as C, type ErrorPolicyPort as E, MESSAGE_MAX_CHARS as M, type SuggestedPromptCategory as S, type Timers as T, type ChatControllerDeps as a, type ChatHandlers as b, type ChatMessage as c, type ChatSnapshot as d, type ChatStatus as e, type Citation as f, type SendOptions as g, createChatController as h, defaultErrorPolicy as i };
@@ -1,22 +0,0 @@
1
- /** Opaque handle to a local file to upload. Server-owned upload target is defined by records/video specs. */
2
- interface FileHandle {
3
- /** Local file URI. */
4
- readonly uri: string;
5
- readonly mimeType: string;
6
- readonly sizeBytes?: number;
7
- /** Original file name, when the host has one. */
8
- readonly name?: string;
9
- }
10
- /**
11
- * Presigned PUT upload. `idempotencyKey` is reused on every retry (a re-uploaded identical file dedupes
12
- * server-side). `signal` cancels an in-flight upload. Settles at the controller; this port itself may reject,
13
- * which the controller normalizes to a typed EverfurError.
14
- */
15
- interface FilePort {
16
- presignedPut(file: FileHandle, opts: {
17
- readonly idempotencyKey: string;
18
- readonly signal?: AbortSignal;
19
- }): Promise<void>;
20
- }
21
-
22
- export type { FileHandle as F, FilePort as a };
@@ -1,22 +0,0 @@
1
- /** Opaque handle to a local file to upload. Server-owned upload target is defined by records/video specs. */
2
- interface FileHandle {
3
- /** Local file URI. */
4
- readonly uri: string;
5
- readonly mimeType: string;
6
- readonly sizeBytes?: number;
7
- /** Original file name, when the host has one. */
8
- readonly name?: string;
9
- }
10
- /**
11
- * Presigned PUT upload. `idempotencyKey` is reused on every retry (a re-uploaded identical file dedupes
12
- * server-side). `signal` cancels an in-flight upload. Settles at the controller; this port itself may reject,
13
- * which the controller normalizes to a typed EverfurError.
14
- */
15
- interface FilePort {
16
- presignedPut(file: FileHandle, opts: {
17
- readonly idempotencyKey: string;
18
- readonly signal?: AbortSignal;
19
- }): Promise<void>;
20
- }
21
-
22
- export type { FileHandle as F, FilePort as a };
@@ -1,326 +0,0 @@
1
- import { f as EverfurError, E as EverfurResult } from './EverfurResult-D92-uL82.cjs';
2
- import { R as RequestFunnel } from './requestFunnel-DuUH-kAe.cjs';
3
- import { A as AuthContext } from './identity-Brl-lDd6.cjs';
4
- import { E as EntitlementDecision } from './resolve-Dq_4_agU.cjs';
5
- import { P as PetRef } from './ids-CJ1S6adf.cjs';
6
-
7
- /** Recursively freeze a plain object/array tree in place and return it (typed as the input). */
8
- declare function deepFreeze<T>(value: T): T;
9
- /** Foreground text tokens; the semantic text ramp over surfaces. */
10
- interface EverfurTextColorTokens {
11
- readonly primary: string;
12
- readonly secondary: string;
13
- readonly muted: string;
14
- readonly placeholder: string;
15
- /** Text drawn on the brand fill (a compiled default; resolve recomputes onPrimary/onAccent via WCAG). */
16
- readonly onBrand: string;
17
- readonly metaCool: string;
18
- }
19
- /** The Everfur color system: brand + surfaces + text ramp + semantic palette + component washes. */
20
- interface EverfurColorTokens {
21
- readonly brand: string;
22
- readonly brandSoft: string;
23
- readonly brandSofter: string;
24
- readonly brandBorder: string;
25
- readonly borderHairlineGreen: string;
26
- readonly surface: string;
27
- readonly surfaceCream: string;
28
- readonly surfaceSubtle: string;
29
- readonly background: string;
30
- readonly borderRingCream: string;
31
- readonly text: EverfurTextColorTokens;
32
- /** The primary CTA fill (server-overridable via primary_color). Foreground is `onPrimary`. */
33
- readonly primary: string;
34
- /** WCAG-legible foreground for `primary` (computed by resolveTheme, never passed through). */
35
- readonly onPrimary: string;
36
- /** The user/CTA accent fill (server-overridable via accent_color). Foreground is `onAccent`. */
37
- readonly accent: string;
38
- /** WCAG-legible foreground for `accent` (computed by resolveTheme). */
39
- readonly onAccent: string;
40
- /** The 0.5px bubble edge (a lightened brand / success green for the default). */
41
- readonly accentEdge: string;
42
- readonly success: string;
43
- readonly danger: string;
44
- readonly errorRed: string;
45
- readonly warningStrong: string;
46
- readonly cautionAccent: string;
47
- readonly riskConcern: string;
48
- readonly badgeBgPositive: string;
49
- readonly badgeBgCaution: string;
50
- readonly badgeBgCritical: string;
51
- readonly badgeBgNeutral: string;
52
- /** user bubble = accent fill; assistant bubble = bare surface (the mobile/Flutter asymmetry). */
53
- readonly bubbleUser: string;
54
- readonly bubbleAssistant: string;
55
- readonly skeleton: string;
56
- readonly scanButtonPink: string;
57
- readonly checkupCardLowRiskBg: string;
58
- readonly checkupCardConcernBg: string;
59
- }
60
- /** Spacing scale (dp). */
61
- interface EverfurSpaceTokens {
62
- readonly xs: number;
63
- readonly sm: number;
64
- readonly md: number;
65
- readonly lg: number;
66
- readonly xl: number;
67
- readonly xxl: number;
68
- }
69
- /** Corner-radius scale (dp); `pill` is an effectively-infinite radius. */
70
- interface EverfurRadiusTokens {
71
- readonly tile: number;
72
- readonly xs: number;
73
- readonly sm: number;
74
- readonly md: number;
75
- readonly lg: number;
76
- readonly xl: number;
77
- readonly pill: number;
78
- }
79
- interface EverfurTypeSizeTokens {
80
- readonly nano: number;
81
- readonly small: number;
82
- readonly micro: number;
83
- readonly tiny: number;
84
- readonly caption: number;
85
- readonly bodyTight: number;
86
- readonly body: number;
87
- readonly subtitle: number;
88
- readonly heading: number;
89
- readonly verdict: number;
90
- }
91
- /** Line-height multipliers (applied to a size to derive an absolute lineHeight). */
92
- interface EverfurLineHeightTokens {
93
- readonly tight: number;
94
- readonly snug: number;
95
- readonly normal: number;
96
- readonly relaxed: number;
97
- }
98
- /**
99
- * RN-assignable font-weight literals. Typed as the exact string literals we ship (not bare `string`) so a
100
- * consumer can spread a weight token straight into a `Text` style: React Native's `TextStyle['fontWeight']`
101
- * accepts these, but rejects `string`. Kept framework-free (no react-native import) to hold the client layer's
102
- * no-framework boundary - these three literals are a subset of RN's fontWeight union.
103
- */
104
- type EverfurFontWeight = '400' | '500' | '700';
105
- /** RN fontWeight tokens. */
106
- interface EverfurWeightTokens {
107
- readonly regular: EverfurFontWeight;
108
- readonly medium: EverfurFontWeight;
109
- readonly bold: EverfurFontWeight;
110
- }
111
- interface EverfurLetterSpacingTokens {
112
- readonly eyebrow: number;
113
- readonly monoWide: number;
114
- readonly headerBrand: number;
115
- readonly tight: number;
116
- }
117
- /** Typography tokens. `family`/`mono` default to the platform font; server font_family/font_url may override. */
118
- interface EverfurTypeTokens {
119
- readonly family: string;
120
- readonly mono: string;
121
- /** Optional remote font (server font_url); null unless a server override supplies an https URL. */
122
- readonly fontUrl: string | null;
123
- readonly size: EverfurTypeSizeTokens;
124
- readonly lineHeight: EverfurLineHeightTokens;
125
- readonly weight: EverfurWeightTokens;
126
- readonly letterSpacing: EverfurLetterSpacingTokens;
127
- }
128
- interface EverfurSpringToken {
129
- readonly damping: number;
130
- readonly stiffness: number;
131
- }
132
- interface EverfurMotionDurationTokens {
133
- readonly instant: number;
134
- readonly fast: number;
135
- readonly normal: number;
136
- readonly slow: number;
137
- }
138
- /** Motion tokens. Under reduced-motion, resolveTheme collapses durations to 0 and stiffens the spring. */
139
- interface EverfurMotionTokens {
140
- readonly duration: EverfurMotionDurationTokens;
141
- readonly spring: {
142
- readonly gentle: EverfurSpringToken;
143
- };
144
- readonly easing: {
145
- readonly standard: string;
146
- };
147
- /** true when the resolved theme has collapsed motion (AccessibilityInfo reduced-motion). */
148
- readonly reducedMotion: boolean;
149
- }
150
- /** Non-visual identity + partner copy carried on the theme (server display_name/logo_url/placeholder overlay). */
151
- interface EverfurThemeMeta {
152
- readonly displayName: string;
153
- readonly logoUrl: string | null;
154
- /** Server-overridable composer placeholder (chat_placeholder/placeholder); null keeps Everfur's neutral default. */
155
- readonly placeholder: string | null;
156
- /** White-label switch (hide_powered_by): drop the "powered by everfur" attribution. Default false (shown). */
157
- readonly hidePoweredBy: boolean;
158
- }
159
- /**
160
- * The frozen, never-null theme the rn layer renders. Read a token as `theme.color.brand`,
161
- * `theme.space.md`, `theme.type.size.body`, `theme.radius.lg`, `theme.motion.duration.fast`.
162
- */
163
- interface EverfurTheme {
164
- readonly brightness: 'light' | 'dark';
165
- readonly meta: EverfurThemeMeta;
166
- readonly color: EverfurColorTokens;
167
- readonly space: EverfurSpaceTokens;
168
- readonly radius: EverfurRadiusTokens;
169
- readonly type: EverfurTypeTokens;
170
- readonly motion: EverfurMotionTokens;
171
- }
172
- /** The compiled LIGHT default (deeply frozen). */
173
- declare const EVERFUR_LIGHT: EverfurTheme;
174
- /** The compiled DARK default (deeply frozen). */
175
- declare const EVERFUR_DARK: EverfurTheme;
176
-
177
- interface ClientBranding {
178
- readonly displayName: string | null;
179
- /** normalized (https-hardened downstream) logo URL */
180
- readonly logoUrl: string | null;
181
- /** normalized color string (#RRGGBB or rgba(...)) or null */
182
- readonly primaryColor: string | null;
183
- readonly accentColor: string | null;
184
- readonly brightness: 'light' | 'dark' | null;
185
- readonly fontFamily: string | null;
186
- readonly fontUrl: string | null;
187
- /** composer placeholder override (chat_placeholder/placeholder); null keeps the base. */
188
- readonly placeholder: string | null;
189
- /** white-label switch (hide_powered_by): hide the powered-by attribution. null = unset (keep the base). */
190
- readonly hidePoweredBy: boolean | null;
191
- }
192
- /** true when every field is null (no config) - treated by callers as "absent". */
193
- declare function isEmptyBranding(b: ClientBranding): boolean;
194
- /**
195
- * Parse an untrusted branding blob (from the entitlements render_hints, or the client `theme` prop) into a
196
- * normalized `ClientBranding`. Accepts BOTH snake_case and camelCase keys. Returns null when the input is not
197
- * an object OR when the result is empty (all fields null) - callers read null as "no config" (fail-closed to
198
- * the compiled default). Never throws.
199
- */
200
- declare function parseClientBranding(json: unknown): ClientBranding | null;
201
- /**
202
- * Parse a permissive color into a normalized string (`#RRGGBB` when opaque, else `rgba(r,g,b,a)`), or null.
203
- * Accepts `#RGB`, `#RRGGBB`, `#AARRGGBB`, `0xAARRGGBB` (string), a 32-bit ARGB `int`, and `rgb()/rgba()`.
204
- * An empty string, whitespace, or an unrecognized value yields null.
205
- */
206
- declare function parseColor(value: unknown): string | null;
207
- /**
208
- * Return the more legible of near-black / white for `background` (WCAG 2.x contrast). Ported from Flutter
209
- * `_readableOn`. Falls back to white for an unparseable background (never throws).
210
- */
211
- declare function readableOn(background: string): string;
212
- /**
213
- * Return the URL only if it is an https URL with no embedded whitespace, else null (security invariant:
214
- * https-only; rejects http:, javascript:, data:, etc.). Uses a protocol-locked regex rather than the URL
215
- * constructor so it is portable + total on React Native (whose URL global is incomplete) and never throws.
216
- */
217
- declare function hardenHttpsUrl(url: string | null): string | null;
218
- /**
219
- * Overlay `b` onto `base`, field by field: a non-null branding field WINS; a null field KEEPS the base. A
220
- * valid brightness re-selects the matching compiled palette (light/dark); an invalid/absent brightness leaves
221
- * the base palette untouched. Returns a NEW deeply-frozen theme; `base` and `b` are never mutated.
222
- *
223
- * NOTE: foreground legibility (onPrimary/onAccent) and URL hardening are applied by `resolveTheme`, the total
224
- * entry point. Call this directly only when you will finalize the result yourself.
225
- */
226
- declare function withServerBranding(base: EverfurTheme, b: ClientBranding | null): EverfurTheme;
227
- /**
228
- * Inputs to the total theme resolve. All optional; `resolveTheme(undefined)` yields the compiled Everfur
229
- * default. Merge order (server wins): compiled default <- clientOverride (first-paint/offline fallback) <-
230
- * branding (server render_hints).
231
- */
232
- interface ResolveThemeInput {
233
- /** Server-driven branding from the live entitlements render_hints (authoritative overlay). */
234
- readonly branding?: ClientBranding | null;
235
- /** The clamped client `theme` prop - a first-paint/offline fallback merged UNDER the server. */
236
- readonly clientOverride?: ClientBranding | null;
237
- /** The device color scheme (useColorScheme); selects the base palette when branding sets no brightness. */
238
- readonly colorScheme?: 'light' | 'dark' | null;
239
- /** AccessibilityInfo reduced-motion: collapses the motion tokens. */
240
- readonly reducedMotion?: boolean;
241
- }
242
- /**
243
- * Resolve the final, legible, deeply-frozen theme. Never throws, never returns null/transparent. Applies the
244
- * client fallback UNDER the server overlay, recomputes onPrimary/onAccent via WCAG, hardens logo/font URLs to
245
- * https-only, guarantees a non-empty displayName, and collapses motion under reduced-motion.
246
- */
247
- declare function resolveTheme(input?: ResolveThemeInput): EverfurTheme;
248
-
249
- /** The conditional-GET endpoint (SPEC-00 §5.3). Relative; the transport prefixes the resolved base URL. */
250
- declare const ENTITLEMENTS_PATH = "/widget/v1/entitlements";
251
- /**
252
- * The settled outcome of one entitlement fetch. `updated` carries a fresh verdict + the cadence to re-poll on;
253
- * `notModified` means the cached verdict still holds; `failed` carries a normalized error and means keep-last.
254
- */
255
- type EntitlementResolution = {
256
- readonly kind: 'updated';
257
- readonly revision: number;
258
- readonly region: string;
259
- readonly ttlSeconds: number;
260
- readonly decisions: readonly EntitlementDecision[];
261
- /**
262
- * Server-driven branding parsed from the SAME 200 body's render_hints (orthogonal to capabilities).
263
- * null when absent or unparseable (fail-closed -> the compiled Everfur default theme). OPTIONAL so a
264
- * hand-built resolution (tests / injected resolve) need not supply it.
265
- */
266
- readonly branding?: ClientBranding | null;
267
- } | {
268
- readonly kind: 'notModified';
269
- } | {
270
- readonly kind: 'failed';
271
- readonly error: EverfurError;
272
- };
273
- interface FetchEntitlementsArgs {
274
- /** The revision we last stored; echoed as If-None-Match so an unchanged verdict returns 304. */
275
- readonly cachedRevision?: number | null;
276
- /** Optional region hint; forwarded as ?region. */
277
- readonly region?: string;
278
- }
279
- /**
280
- * Fetch the server-resolved entitlement verdict once. Never throws: a 304, a domain error, a network reject,
281
- * and a malformed body all SETTLE to an EntitlementResolution. Fail-closed on every non-`updated` path.
282
- */
283
- declare function fetchEntitlements(auth: AuthContext, args?: FetchEntitlementsArgs, funnel?: RequestFunnel): Promise<EntitlementResolution>;
284
-
285
- /**
286
- * Server-declared bounds on `WidgetPetInput`, mirrored so a violation is refused before the wire rather
287
- * than returning a 422 after the caller has already driven a registration flow. Every field is optional
288
- * server-side: `POST` with an empty body registers a bare pet, which is all consent needs.
289
- */
290
- declare const PET_NAME_MAX = 100;
291
- declare const PET_SPECIES_MAX = 50;
292
- declare const PET_BREED_MAX = 100;
293
- declare const PET_AGE_YEARS_MAX = 50;
294
- declare const PET_WEIGHT_KG_MAX = 500;
295
- /** The optional profile fields. Omit all of them to register the pet without describing it. */
296
- interface PetProfileInput {
297
- readonly name?: string;
298
- readonly species?: string;
299
- readonly breed?: string;
300
- readonly ageYears?: number;
301
- readonly weightKg?: number;
302
- }
303
- /** The registered profile, as the server echoes it back. */
304
- interface RegisteredPet {
305
- readonly petRef: string;
306
- readonly name: string | null;
307
- readonly species: string | null;
308
- readonly breed: string | null;
309
- readonly ageYears: number | null;
310
- readonly weightKg: number | null;
311
- }
312
- interface PetsRepository {
313
- /**
314
- * `POST /widget/v1/pets/{pet_ref}` - create or update the widget pet profile. Idempotent by construction:
315
- * the route is an upsert, so calling it for an already-registered pet updates rather than duplicates.
316
- *
317
- * Settles: `ok(RegisteredPet)` on 201, `err(EverfurError)` otherwise. Never throws.
318
- */
319
- registerPet(petRef: PetRef, profile?: PetProfileInput, opts?: {
320
- signal?: AbortSignal;
321
- }): Promise<EverfurResult<RegisteredPet>>;
322
- }
323
- /** Build the repository over a device AuthContext (personalized bearer XOR anonymous pk). */
324
- declare function createPetsRepository(auth: AuthContext): PetsRepository;
325
-
326
- export { deepFreeze as A, fetchEntitlements as B, type ClientBranding as C, hardenHttpsUrl as D, ENTITLEMENTS_PATH as E, type FetchEntitlementsArgs as F, isEmptyBranding as G, parseClientBranding as H, parseColor as I, readableOn as J, resolveTheme as K, withServerBranding as L, PET_AGE_YEARS_MAX as P, type RegisteredPet as R, EVERFUR_DARK as a, EVERFUR_LIGHT as b, type EntitlementResolution as c, type EverfurColorTokens as d, type EverfurFontWeight as e, type EverfurLetterSpacingTokens as f, type EverfurLineHeightTokens as g, type EverfurMotionDurationTokens as h, type EverfurMotionTokens as i, type EverfurRadiusTokens as j, type EverfurSpaceTokens as k, type EverfurSpringToken as l, type EverfurTextColorTokens as m, type EverfurTheme as n, type EverfurThemeMeta as o, type EverfurTypeSizeTokens as p, type EverfurTypeTokens as q, type EverfurWeightTokens as r, PET_BREED_MAX as s, PET_NAME_MAX as t, PET_SPECIES_MAX as u, PET_WEIGHT_KG_MAX as v, type PetProfileInput as w, type PetsRepository as x, type ResolveThemeInput as y, createPetsRepository as z };