@noodleseed/assistant 1.28.0 → 1.29.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 (41) hide show
  1. package/dist/{app-view-element-mXHvcAXc.d.ts → app-view-element-kR8eqhyD.d.cts} +1 -1
  2. package/dist/{app-view-element-BjRkwNN1.d.cts → app-view-element-nY1svwHT.d.ts} +1 -1
  3. package/dist/app-view.d.cts +3 -3
  4. package/dist/app-view.d.ts +3 -3
  5. package/dist/{chunk-WJV4MJUR.js → chunk-3VZ3M5BE.js} +92 -9
  6. package/dist/{chunk-WJV4MJUR.js.map → chunk-3VZ3M5BE.js.map} +1 -1
  7. package/dist/{chunk-QH7PL3GU.js → chunk-DOWFW3KA.js} +259 -54
  8. package/dist/chunk-DOWFW3KA.js.map +1 -0
  9. package/dist/{client-CPFw8tfo.d.ts → client-contract-Bw9dtrhw.d.cts} +26 -35
  10. package/dist/{client-_xivfs4q.d.cts → client-contract-DjU9qsoP.d.ts} +26 -35
  11. package/dist/client.cjs +91 -8
  12. package/dist/client.cjs.map +1 -1
  13. package/dist/client.d.cts +12 -2
  14. package/dist/client.d.ts +12 -2
  15. package/dist/client.js +1 -1
  16. package/dist/embed.global.js +46 -46
  17. package/dist/index.cjs +348 -60
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +3 -3
  20. package/dist/index.d.ts +3 -3
  21. package/dist/index.js +2 -2
  22. package/dist/react/client.cjs +91 -8
  23. package/dist/react/client.cjs.map +1 -1
  24. package/dist/react/client.d.cts +2 -2
  25. package/dist/react/client.d.ts +2 -2
  26. package/dist/react/client.js +1 -1
  27. package/dist/react.cjs +348 -60
  28. package/dist/react.cjs.map +1 -1
  29. package/dist/react.d.cts +3 -3
  30. package/dist/react.d.ts +3 -3
  31. package/dist/react.js +2 -2
  32. package/dist/server-CMqlAnxs.d.cts +270 -0
  33. package/dist/server-CMqlAnxs.d.ts +270 -0
  34. package/dist/server.cjs.map +1 -1
  35. package/dist/server.d.cts +1 -121
  36. package/dist/server.d.ts +1 -121
  37. package/dist/server.js.map +1 -1
  38. package/package.json +1 -1
  39. package/dist/appearance-BpVu3lpk.d.cts +0 -146
  40. package/dist/appearance-BpVu3lpk.d.ts +0 -146
  41. package/dist/chunk-QH7PL3GU.js.map +0 -1
package/dist/react.d.cts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { ReactElement, RefAttributes } from 'react';
2
- import { a as AssistantThemeMode } from './appearance-BpVu3lpk.cjs';
3
- import { A as AssistantClient, a as AssistantViewAvailableDetail, b as AssistantPageContext, c as AssistantContext, f as AssistantAppearance, g as AssistantModelContextUpdate, h as AssistantClientEvent, e as AssistantErrorDetail, i as AssistantAppearanceWarning } from './client-_xivfs4q.cjs';
2
+ import { A as AssistantThemeMode } from './server-CMqlAnxs.cjs';
3
+ import { A as AssistantClient, a as AssistantViewAvailableDetail, b as AssistantPageContext, c as AssistantContext, Q as AssistantAppearance, y as AssistantModelContextUpdate, h as AssistantClientEvent, e as AssistantErrorDetail, R as AssistantAppearanceWarning } from './client-contract-Bw9dtrhw.cjs';
4
4
  import { NoodleAssistantElement } from './index.cjs';
5
- import { a as AssistantAppViewErrorDetail } from './app-view-element-BjRkwNN1.cjs';
5
+ import { a as AssistantAppViewErrorDetail } from './app-view-element-kR8eqhyD.cjs';
6
6
  import 'ai';
7
7
 
8
8
  interface NoodleAppViewProps {
package/dist/react.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { ReactElement, RefAttributes } from 'react';
2
- import { a as AssistantThemeMode } from './appearance-BpVu3lpk.js';
3
- import { A as AssistantClient, a as AssistantViewAvailableDetail, b as AssistantPageContext, c as AssistantContext, f as AssistantAppearance, g as AssistantModelContextUpdate, h as AssistantClientEvent, e as AssistantErrorDetail, i as AssistantAppearanceWarning } from './client-CPFw8tfo.js';
2
+ import { A as AssistantThemeMode } from './server-CMqlAnxs.js';
3
+ import { A as AssistantClient, a as AssistantViewAvailableDetail, b as AssistantPageContext, c as AssistantContext, Q as AssistantAppearance, y as AssistantModelContextUpdate, h as AssistantClientEvent, e as AssistantErrorDetail, R as AssistantAppearanceWarning } from './client-contract-DjU9qsoP.js';
4
4
  import { NoodleAssistantElement } from './index.js';
5
- import { a as AssistantAppViewErrorDetail } from './app-view-element-mXHvcAXc.js';
5
+ import { a as AssistantAppViewErrorDetail } from './app-view-element-nY1svwHT.js';
6
6
  import 'ai';
7
7
 
8
8
  interface NoodleAppViewProps {
package/dist/react.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  registerNoodleAssistant
3
- } from "./chunk-QH7PL3GU.js";
3
+ } from "./chunk-DOWFW3KA.js";
4
4
  import {
5
5
  APP_VIEW_TAG_NAME,
6
6
  registerNoodleAppView
7
7
  } from "./chunk-5NBHHNI3.js";
8
8
  import "./chunk-XKTUXFGX.js";
9
- import "./chunk-WJV4MJUR.js";
9
+ import "./chunk-3VZ3M5BE.js";
10
10
  import "./chunk-P223CYPO.js";
11
11
  import "./chunk-3YYTUJPJ.js";
12
12
  import "./chunk-5FUTL2UF.js";
@@ -0,0 +1,270 @@
1
+ type AssistantThemeMode = 'auto' | 'light' | 'dark' | 'invert';
2
+ type AssistantLayoutMode = 'floating' | 'inline' | 'drawer';
3
+ type AssistantPosition = 'bottom-left' | 'bottom-center' | 'bottom-right';
4
+ type AssistantPresentationTone = 'neutral' | 'success' | 'warning' | 'danger';
5
+ interface AssistantPresentationConfiguration {
6
+ readonly panel?: {
7
+ readonly surface?: 'solid' | 'glass';
8
+ readonly elevation?: 'soft' | 'dramatic';
9
+ readonly border?: 'subtle' | 'strong';
10
+ readonly radius?: number;
11
+ };
12
+ readonly launcher?: {
13
+ readonly style?: 'pill' | 'bubble';
14
+ readonly icon?: 'brand-mark' | 'chat' | 'none';
15
+ readonly size?: 'md' | 'lg';
16
+ readonly status?: 'none' | 'session';
17
+ readonly effect?: 'none' | 'pulse';
18
+ };
19
+ readonly header?: {
20
+ readonly mark?: 'none' | 'brand-mark' | 'status';
21
+ readonly badge?: {
22
+ readonly text: string;
23
+ readonly tone?: AssistantPresentationTone;
24
+ readonly indicator?: boolean;
25
+ };
26
+ };
27
+ readonly composer?: {
28
+ readonly leadingIcon?: 'none' | 'brand-mark';
29
+ readonly sendIcon?: 'arrow-up' | 'paper-plane';
30
+ readonly shape?: 'rounded' | 'pill';
31
+ };
32
+ readonly messages?: {
33
+ readonly userStyle?: 'bubble' | 'accent';
34
+ readonly assistantStyle?: 'plain' | 'bubble';
35
+ };
36
+ }
37
+ interface AssistantConfiguration {
38
+ readonly branding?: {
39
+ readonly name?: string;
40
+ readonly accent?: string;
41
+ readonly surface?: string;
42
+ readonly surfaceDark?: string;
43
+ readonly logo?: AssistantBrandAsset;
44
+ readonly mark?: AssistantBrandAsset;
45
+ readonly avatar?: AssistantBrandAsset;
46
+ readonly theme?: {
47
+ readonly light?: BrandThemeOverrides;
48
+ readonly dark?: BrandThemeOverrides;
49
+ };
50
+ readonly radius?: 'none' | 'sm' | 'md' | 'lg';
51
+ readonly density?: 'compact' | 'comfortable';
52
+ readonly typography?: 'system' | 'serif' | 'mono';
53
+ readonly colorScheme?: Exclude<AssistantThemeMode, 'invert'>;
54
+ };
55
+ readonly assistant?: AssistantUiConfiguration;
56
+ }
57
+ interface AssistantBrandAsset {
58
+ readonly uri: string;
59
+ readonly darkUri?: string;
60
+ readonly alt: string;
61
+ }
62
+ interface BrandThemeOverrides {
63
+ readonly surface?: string;
64
+ readonly surfaceRaised?: string;
65
+ readonly surfaceMuted?: string;
66
+ readonly text?: string;
67
+ readonly textMuted?: string;
68
+ readonly accent?: string;
69
+ readonly accentText?: string;
70
+ readonly link?: string;
71
+ readonly border?: string;
72
+ readonly borderStrong?: string;
73
+ readonly focus?: string;
74
+ readonly success?: string;
75
+ readonly warning?: string;
76
+ readonly danger?: string;
77
+ readonly code?: string;
78
+ }
79
+ interface AssistantUiConfiguration {
80
+ readonly theme?: AssistantThemeMode;
81
+ readonly layout?: {
82
+ readonly mode?: AssistantLayoutMode;
83
+ readonly position?: AssistantPosition;
84
+ readonly panelWidth?: number;
85
+ readonly panelMinHeight?: number;
86
+ readonly panelMaxHeight?: number;
87
+ readonly edgeOffset?: number;
88
+ readonly zIndex?: number;
89
+ readonly density?: 'compact' | 'comfortable';
90
+ readonly mobileFullscreen?: boolean;
91
+ };
92
+ readonly behavior?: {
93
+ readonly startOpen?: boolean;
94
+ readonly closeOnEscape?: boolean;
95
+ readonly closeOnOutsideClick?: boolean;
96
+ readonly showLauncher?: boolean;
97
+ readonly showHeader?: boolean;
98
+ readonly showAvatars?: boolean;
99
+ readonly showTimestamps?: boolean;
100
+ readonly showPoweredBy?: boolean;
101
+ readonly showConfirmationDetails?: boolean;
102
+ };
103
+ readonly labels?: Partial<AssistantLabels>;
104
+ readonly presentation?: AssistantPresentationConfiguration;
105
+ readonly suggestedPrompts?: readonly string[];
106
+ readonly privacyUrl?: string;
107
+ readonly termsUrl?: string;
108
+ readonly locale?: string;
109
+ readonly direction?: 'ltr' | 'rtl' | 'auto';
110
+ /** Opt in to projecting this session's governed tools to the browser's agent (ADR 0220). */
111
+ readonly webmcp?: {
112
+ readonly enabled?: boolean;
113
+ };
114
+ }
115
+ interface AssistantLabels {
116
+ readonly welcomeHeading: string;
117
+ readonly welcomeMessage: string;
118
+ readonly launcherPlaceholder: string;
119
+ readonly composerPlaceholder: string;
120
+ readonly thinking: string;
121
+ readonly send: string;
122
+ readonly stop: string;
123
+ readonly close: string;
124
+ readonly open: string;
125
+ readonly confirm: string;
126
+ readonly decline: string;
127
+ readonly cancel: string;
128
+ readonly confirmationHeading: string;
129
+ readonly additionalDetails: string;
130
+ readonly redacted: string;
131
+ readonly completed: string;
132
+ readonly stopped: string;
133
+ readonly copy: string;
134
+ readonly newMessages: string;
135
+ readonly reconnect: string;
136
+ readonly newConversation: string;
137
+ readonly retry: string;
138
+ readonly unavailable: string;
139
+ readonly sessionExpired: string;
140
+ readonly sessionIdle: string;
141
+ readonly sessionLoading: string;
142
+ readonly sessionReady: string;
143
+ readonly sessionError: string;
144
+ readonly signInHeading: string;
145
+ readonly signInBody: string;
146
+ readonly signInAction: string;
147
+ readonly signUpAction: string;
148
+ }
149
+
150
+ interface AssistantSessionExchangeBase {
151
+ readonly serviceUrl: string;
152
+ readonly clientId: string;
153
+ readonly clientSecret: string;
154
+ /** Browser origin to bind into the short-lived assistant session. */
155
+ readonly origin: string;
156
+ /** The signed-in person your backend vouches for — on both arms: an elevation IS this vouching. */
157
+ readonly user: {
158
+ readonly id: string;
159
+ readonly email?: string;
160
+ readonly name?: string;
161
+ readonly tenant?: string;
162
+ readonly roles?: readonly string[];
163
+ readonly scopes?: readonly string[];
164
+ };
165
+ /** Backend-verified user preferences; these outrank untrusted browser presentation hints. */
166
+ readonly preferences?: {
167
+ readonly locale?: string;
168
+ readonly timeZone?: string;
169
+ };
170
+ /**
171
+ * Verified session claims from your authenticated backend. Only claims the server declares in
172
+ * `embeddedAssistant({ sessionClaims })` reach tools (`\${user.claims.<key>}`) and, when marked
173
+ * `exposeToModel`, the assistant's identity context. Flat scalars only.
174
+ */
175
+ readonly claims?: Readonly<Record<string, string | number | boolean | null>>;
176
+ }
177
+ /**
178
+ * Fresh mint XOR mid-conversation sign-in, exclusive rather than merged for the same reason the
179
+ * client's `sessionEndpoint`/`embedId` pair is: the two are different operations, and the wrong
180
+ * combination should fail to typecheck instead of silently picking a meaning.
181
+ *
182
+ * `context` applies only when a session is being created; an elevation keeps the existing
183
+ * conversation, so it is excluded rather than silently ignored. `routing` is allowed on both arms —
184
+ * elevation is the first authenticated moment, so it is the only chance a routed connector's
185
+ * session ever gets its backend-verified customer routes.
186
+ */
187
+ type CreateAssistantSessionInput = (AssistantSessionExchangeBase & {
188
+ readonly signInTicket?: undefined;
189
+ readonly context?: Readonly<Record<string, string | number | boolean | null>>;
190
+ /** Backend-verified connector routes keyed by authored `customerEndpoint` name. */
191
+ readonly routing?: {
192
+ readonly endpoints: Readonly<Record<string, string>>;
193
+ };
194
+ /** Resume applies only when spending a sign-in ticket; a fresh mint has nothing pending. */
195
+ readonly resume?: undefined;
196
+ }) | (AssistantSessionExchangeBase & {
197
+ /**
198
+ * Single-use sign-in ticket from the widget's `assistant-sign-in-requested` event
199
+ * (ADR 0201, 5.6b). Spending it binds this signed-in user to the visitor's existing
200
+ * anonymous conversation instead of minting a new one. Unrelated to the server-held
201
+ * interaction continuation, which never reaches browser code.
202
+ */
203
+ readonly signInTicket: string;
204
+ readonly context?: undefined;
205
+ /** Backend-verified connector routes keyed by authored `customerEndpoint` name. */
206
+ readonly routing?: {
207
+ readonly endpoints: Readonly<Record<string, string>>;
208
+ };
209
+ /**
210
+ * Whether the service resumes the intercepted tool call as the elevated session's first
211
+ * turn (issue #1177). ON by default — omit it and the visitor's pending question answers
212
+ * itself after sign-in; pass `false` if your application provides its own affordance.
213
+ */
214
+ readonly resume?: boolean;
215
+ });
216
+ interface AssistantSession {
217
+ readonly token: string;
218
+ readonly expiresAt: string;
219
+ readonly endpoints: {
220
+ readonly turns: string;
221
+ readonly toolConfirmations: string;
222
+ readonly interactions?: string;
223
+ readonly apps?: string;
224
+ /** Additive hosted sandbox document for widget frames; absent on older services. */
225
+ readonly sandbox?: string;
226
+ /** Additive bounded visible-transcript endpoint; absent on older services. */
227
+ readonly transcript?: string;
228
+ /** Additive model-generated prompt suggestions; absent on older services. */
229
+ readonly suggestions?: string;
230
+ };
231
+ /**
232
+ * Present only on an elevation that armed the one-shot resume of the intercepted tool. Forward
233
+ * the response body unchanged and the widget answers with one automatic turn.
234
+ */
235
+ readonly resume?: {
236
+ readonly tool: string;
237
+ };
238
+ readonly configuration?: AssistantConfiguration;
239
+ }
240
+ /** The service's refusal codes for a sign-in ticket the exchange would not honour. */
241
+ declare const ASSISTANT_ELEVATION_REFUSAL_CODES: readonly ["elevation_ticket_invalid", "elevation_ticket_expired", "elevation_tenant_mismatch", "elevation_session_unavailable", "elevation_already_signed_in"];
242
+ type AssistantElevationRefusalCode = (typeof ASSISTANT_ELEVATION_REFUSAL_CODES)[number];
243
+ /**
244
+ * Structurally mirrors the browser client's `AssistantErrorDetail` (declared locally: the backend
245
+ * entry must not pull the browser transport module into its graph). `code` is a closed union owned
246
+ * by this package; `serviceCode` passes the service's machine code through additively.
247
+ */
248
+ interface AssistantSessionExchangeErrorDetail {
249
+ readonly code: 'session_exchange_failed';
250
+ readonly status: number;
251
+ /** 5xx infrastructure failures may be retried; a refused exchange must not be — tickets are single-use. */
252
+ readonly retryable: boolean;
253
+ /** The service's machine code when the body carried one, e.g. `elevation_ticket_expired`. */
254
+ readonly serviceCode?: string;
255
+ }
256
+ declare class AssistantSessionExchangeError extends Error {
257
+ readonly detail: AssistantSessionExchangeErrorDetail;
258
+ constructor(detail: AssistantSessionExchangeErrorDetail, message: string);
259
+ /**
260
+ * The narrowed sign-in refusal, when this failure is one. `elevation_ticket_expired` means the
261
+ * visitor took too long — re-prompt; `elevation_tenant_mismatch` means a client reached for a
262
+ * conversation it does not own — alert someone, never retry.
263
+ */
264
+ get elevationRefusal(): AssistantElevationRefusalCode | undefined;
265
+ }
266
+ declare function createAssistantSession(input: CreateAssistantSessionInput, dependencies?: {
267
+ readonly fetch?: typeof fetch;
268
+ }): Promise<AssistantSession>;
269
+
270
+ export { type AssistantThemeMode as A, type CreateAssistantSessionInput as C, type AssistantConfiguration as a, type AssistantSession as b, ASSISTANT_ELEVATION_REFUSAL_CODES as c, type AssistantElevationRefusalCode as d, AssistantSessionExchangeError as e, type AssistantSessionExchangeErrorDetail as f, createAssistantSession as g };
@@ -0,0 +1,270 @@
1
+ type AssistantThemeMode = 'auto' | 'light' | 'dark' | 'invert';
2
+ type AssistantLayoutMode = 'floating' | 'inline' | 'drawer';
3
+ type AssistantPosition = 'bottom-left' | 'bottom-center' | 'bottom-right';
4
+ type AssistantPresentationTone = 'neutral' | 'success' | 'warning' | 'danger';
5
+ interface AssistantPresentationConfiguration {
6
+ readonly panel?: {
7
+ readonly surface?: 'solid' | 'glass';
8
+ readonly elevation?: 'soft' | 'dramatic';
9
+ readonly border?: 'subtle' | 'strong';
10
+ readonly radius?: number;
11
+ };
12
+ readonly launcher?: {
13
+ readonly style?: 'pill' | 'bubble';
14
+ readonly icon?: 'brand-mark' | 'chat' | 'none';
15
+ readonly size?: 'md' | 'lg';
16
+ readonly status?: 'none' | 'session';
17
+ readonly effect?: 'none' | 'pulse';
18
+ };
19
+ readonly header?: {
20
+ readonly mark?: 'none' | 'brand-mark' | 'status';
21
+ readonly badge?: {
22
+ readonly text: string;
23
+ readonly tone?: AssistantPresentationTone;
24
+ readonly indicator?: boolean;
25
+ };
26
+ };
27
+ readonly composer?: {
28
+ readonly leadingIcon?: 'none' | 'brand-mark';
29
+ readonly sendIcon?: 'arrow-up' | 'paper-plane';
30
+ readonly shape?: 'rounded' | 'pill';
31
+ };
32
+ readonly messages?: {
33
+ readonly userStyle?: 'bubble' | 'accent';
34
+ readonly assistantStyle?: 'plain' | 'bubble';
35
+ };
36
+ }
37
+ interface AssistantConfiguration {
38
+ readonly branding?: {
39
+ readonly name?: string;
40
+ readonly accent?: string;
41
+ readonly surface?: string;
42
+ readonly surfaceDark?: string;
43
+ readonly logo?: AssistantBrandAsset;
44
+ readonly mark?: AssistantBrandAsset;
45
+ readonly avatar?: AssistantBrandAsset;
46
+ readonly theme?: {
47
+ readonly light?: BrandThemeOverrides;
48
+ readonly dark?: BrandThemeOverrides;
49
+ };
50
+ readonly radius?: 'none' | 'sm' | 'md' | 'lg';
51
+ readonly density?: 'compact' | 'comfortable';
52
+ readonly typography?: 'system' | 'serif' | 'mono';
53
+ readonly colorScheme?: Exclude<AssistantThemeMode, 'invert'>;
54
+ };
55
+ readonly assistant?: AssistantUiConfiguration;
56
+ }
57
+ interface AssistantBrandAsset {
58
+ readonly uri: string;
59
+ readonly darkUri?: string;
60
+ readonly alt: string;
61
+ }
62
+ interface BrandThemeOverrides {
63
+ readonly surface?: string;
64
+ readonly surfaceRaised?: string;
65
+ readonly surfaceMuted?: string;
66
+ readonly text?: string;
67
+ readonly textMuted?: string;
68
+ readonly accent?: string;
69
+ readonly accentText?: string;
70
+ readonly link?: string;
71
+ readonly border?: string;
72
+ readonly borderStrong?: string;
73
+ readonly focus?: string;
74
+ readonly success?: string;
75
+ readonly warning?: string;
76
+ readonly danger?: string;
77
+ readonly code?: string;
78
+ }
79
+ interface AssistantUiConfiguration {
80
+ readonly theme?: AssistantThemeMode;
81
+ readonly layout?: {
82
+ readonly mode?: AssistantLayoutMode;
83
+ readonly position?: AssistantPosition;
84
+ readonly panelWidth?: number;
85
+ readonly panelMinHeight?: number;
86
+ readonly panelMaxHeight?: number;
87
+ readonly edgeOffset?: number;
88
+ readonly zIndex?: number;
89
+ readonly density?: 'compact' | 'comfortable';
90
+ readonly mobileFullscreen?: boolean;
91
+ };
92
+ readonly behavior?: {
93
+ readonly startOpen?: boolean;
94
+ readonly closeOnEscape?: boolean;
95
+ readonly closeOnOutsideClick?: boolean;
96
+ readonly showLauncher?: boolean;
97
+ readonly showHeader?: boolean;
98
+ readonly showAvatars?: boolean;
99
+ readonly showTimestamps?: boolean;
100
+ readonly showPoweredBy?: boolean;
101
+ readonly showConfirmationDetails?: boolean;
102
+ };
103
+ readonly labels?: Partial<AssistantLabels>;
104
+ readonly presentation?: AssistantPresentationConfiguration;
105
+ readonly suggestedPrompts?: readonly string[];
106
+ readonly privacyUrl?: string;
107
+ readonly termsUrl?: string;
108
+ readonly locale?: string;
109
+ readonly direction?: 'ltr' | 'rtl' | 'auto';
110
+ /** Opt in to projecting this session's governed tools to the browser's agent (ADR 0220). */
111
+ readonly webmcp?: {
112
+ readonly enabled?: boolean;
113
+ };
114
+ }
115
+ interface AssistantLabels {
116
+ readonly welcomeHeading: string;
117
+ readonly welcomeMessage: string;
118
+ readonly launcherPlaceholder: string;
119
+ readonly composerPlaceholder: string;
120
+ readonly thinking: string;
121
+ readonly send: string;
122
+ readonly stop: string;
123
+ readonly close: string;
124
+ readonly open: string;
125
+ readonly confirm: string;
126
+ readonly decline: string;
127
+ readonly cancel: string;
128
+ readonly confirmationHeading: string;
129
+ readonly additionalDetails: string;
130
+ readonly redacted: string;
131
+ readonly completed: string;
132
+ readonly stopped: string;
133
+ readonly copy: string;
134
+ readonly newMessages: string;
135
+ readonly reconnect: string;
136
+ readonly newConversation: string;
137
+ readonly retry: string;
138
+ readonly unavailable: string;
139
+ readonly sessionExpired: string;
140
+ readonly sessionIdle: string;
141
+ readonly sessionLoading: string;
142
+ readonly sessionReady: string;
143
+ readonly sessionError: string;
144
+ readonly signInHeading: string;
145
+ readonly signInBody: string;
146
+ readonly signInAction: string;
147
+ readonly signUpAction: string;
148
+ }
149
+
150
+ interface AssistantSessionExchangeBase {
151
+ readonly serviceUrl: string;
152
+ readonly clientId: string;
153
+ readonly clientSecret: string;
154
+ /** Browser origin to bind into the short-lived assistant session. */
155
+ readonly origin: string;
156
+ /** The signed-in person your backend vouches for — on both arms: an elevation IS this vouching. */
157
+ readonly user: {
158
+ readonly id: string;
159
+ readonly email?: string;
160
+ readonly name?: string;
161
+ readonly tenant?: string;
162
+ readonly roles?: readonly string[];
163
+ readonly scopes?: readonly string[];
164
+ };
165
+ /** Backend-verified user preferences; these outrank untrusted browser presentation hints. */
166
+ readonly preferences?: {
167
+ readonly locale?: string;
168
+ readonly timeZone?: string;
169
+ };
170
+ /**
171
+ * Verified session claims from your authenticated backend. Only claims the server declares in
172
+ * `embeddedAssistant({ sessionClaims })` reach tools (`\${user.claims.<key>}`) and, when marked
173
+ * `exposeToModel`, the assistant's identity context. Flat scalars only.
174
+ */
175
+ readonly claims?: Readonly<Record<string, string | number | boolean | null>>;
176
+ }
177
+ /**
178
+ * Fresh mint XOR mid-conversation sign-in, exclusive rather than merged for the same reason the
179
+ * client's `sessionEndpoint`/`embedId` pair is: the two are different operations, and the wrong
180
+ * combination should fail to typecheck instead of silently picking a meaning.
181
+ *
182
+ * `context` applies only when a session is being created; an elevation keeps the existing
183
+ * conversation, so it is excluded rather than silently ignored. `routing` is allowed on both arms —
184
+ * elevation is the first authenticated moment, so it is the only chance a routed connector's
185
+ * session ever gets its backend-verified customer routes.
186
+ */
187
+ type CreateAssistantSessionInput = (AssistantSessionExchangeBase & {
188
+ readonly signInTicket?: undefined;
189
+ readonly context?: Readonly<Record<string, string | number | boolean | null>>;
190
+ /** Backend-verified connector routes keyed by authored `customerEndpoint` name. */
191
+ readonly routing?: {
192
+ readonly endpoints: Readonly<Record<string, string>>;
193
+ };
194
+ /** Resume applies only when spending a sign-in ticket; a fresh mint has nothing pending. */
195
+ readonly resume?: undefined;
196
+ }) | (AssistantSessionExchangeBase & {
197
+ /**
198
+ * Single-use sign-in ticket from the widget's `assistant-sign-in-requested` event
199
+ * (ADR 0201, 5.6b). Spending it binds this signed-in user to the visitor's existing
200
+ * anonymous conversation instead of minting a new one. Unrelated to the server-held
201
+ * interaction continuation, which never reaches browser code.
202
+ */
203
+ readonly signInTicket: string;
204
+ readonly context?: undefined;
205
+ /** Backend-verified connector routes keyed by authored `customerEndpoint` name. */
206
+ readonly routing?: {
207
+ readonly endpoints: Readonly<Record<string, string>>;
208
+ };
209
+ /**
210
+ * Whether the service resumes the intercepted tool call as the elevated session's first
211
+ * turn (issue #1177). ON by default — omit it and the visitor's pending question answers
212
+ * itself after sign-in; pass `false` if your application provides its own affordance.
213
+ */
214
+ readonly resume?: boolean;
215
+ });
216
+ interface AssistantSession {
217
+ readonly token: string;
218
+ readonly expiresAt: string;
219
+ readonly endpoints: {
220
+ readonly turns: string;
221
+ readonly toolConfirmations: string;
222
+ readonly interactions?: string;
223
+ readonly apps?: string;
224
+ /** Additive hosted sandbox document for widget frames; absent on older services. */
225
+ readonly sandbox?: string;
226
+ /** Additive bounded visible-transcript endpoint; absent on older services. */
227
+ readonly transcript?: string;
228
+ /** Additive model-generated prompt suggestions; absent on older services. */
229
+ readonly suggestions?: string;
230
+ };
231
+ /**
232
+ * Present only on an elevation that armed the one-shot resume of the intercepted tool. Forward
233
+ * the response body unchanged and the widget answers with one automatic turn.
234
+ */
235
+ readonly resume?: {
236
+ readonly tool: string;
237
+ };
238
+ readonly configuration?: AssistantConfiguration;
239
+ }
240
+ /** The service's refusal codes for a sign-in ticket the exchange would not honour. */
241
+ declare const ASSISTANT_ELEVATION_REFUSAL_CODES: readonly ["elevation_ticket_invalid", "elevation_ticket_expired", "elevation_tenant_mismatch", "elevation_session_unavailable", "elevation_already_signed_in"];
242
+ type AssistantElevationRefusalCode = (typeof ASSISTANT_ELEVATION_REFUSAL_CODES)[number];
243
+ /**
244
+ * Structurally mirrors the browser client's `AssistantErrorDetail` (declared locally: the backend
245
+ * entry must not pull the browser transport module into its graph). `code` is a closed union owned
246
+ * by this package; `serviceCode` passes the service's machine code through additively.
247
+ */
248
+ interface AssistantSessionExchangeErrorDetail {
249
+ readonly code: 'session_exchange_failed';
250
+ readonly status: number;
251
+ /** 5xx infrastructure failures may be retried; a refused exchange must not be — tickets are single-use. */
252
+ readonly retryable: boolean;
253
+ /** The service's machine code when the body carried one, e.g. `elevation_ticket_expired`. */
254
+ readonly serviceCode?: string;
255
+ }
256
+ declare class AssistantSessionExchangeError extends Error {
257
+ readonly detail: AssistantSessionExchangeErrorDetail;
258
+ constructor(detail: AssistantSessionExchangeErrorDetail, message: string);
259
+ /**
260
+ * The narrowed sign-in refusal, when this failure is one. `elevation_ticket_expired` means the
261
+ * visitor took too long — re-prompt; `elevation_tenant_mismatch` means a client reached for a
262
+ * conversation it does not own — alert someone, never retry.
263
+ */
264
+ get elevationRefusal(): AssistantElevationRefusalCode | undefined;
265
+ }
266
+ declare function createAssistantSession(input: CreateAssistantSessionInput, dependencies?: {
267
+ readonly fetch?: typeof fetch;
268
+ }): Promise<AssistantSession>;
269
+
270
+ export { type AssistantThemeMode as A, type CreateAssistantSessionInput as C, type AssistantConfiguration as a, type AssistantSession as b, ASSISTANT_ELEVATION_REFUSAL_CODES as c, type AssistantElevationRefusalCode as d, AssistantSessionExchangeError as e, type AssistantSessionExchangeErrorDetail as f, createAssistantSession as g };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server.ts"],"sourcesContent":["import type { AssistantConfiguration } from './appearance.js';\n\ninterface AssistantSessionExchangeBase {\n readonly serviceUrl: string;\n readonly clientId: string;\n readonly clientSecret: string;\n /** Browser origin to bind into the short-lived assistant session. */\n readonly origin: string;\n /** The signed-in person your backend vouches for — on both arms: an elevation IS this vouching. */\n readonly user: {\n readonly id: string;\n readonly email?: string;\n readonly name?: string;\n readonly tenant?: string;\n readonly roles?: readonly string[];\n readonly scopes?: readonly string[];\n };\n /** Backend-verified user preferences; these outrank untrusted browser presentation hints. */\n readonly preferences?: {\n readonly locale?: string;\n readonly timeZone?: string;\n };\n /**\n * Verified session claims from your authenticated backend. Only claims the server declares in\n * `embeddedAssistant({ sessionClaims })` reach tools (`\\${user.claims.<key>}`) and, when marked\n * `exposeToModel`, the assistant's identity context. Flat scalars only.\n */\n readonly claims?: Readonly<Record<string, string | number | boolean | null>>;\n}\n\n/**\n * Fresh mint XOR mid-conversation sign-in, exclusive rather than merged for the same reason the\n * client's `sessionEndpoint`/`embedId` pair is: the two are different operations, and the wrong\n * combination should fail to typecheck instead of silently picking a meaning.\n *\n * `context` applies only when a session is being created; an elevation keeps the existing\n * conversation, so it is excluded rather than silently ignored. `routing` is allowed on both arms —\n * elevation is the first authenticated moment, so it is the only chance a routed connector's\n * session ever gets its backend-verified customer routes.\n */\nexport type CreateAssistantSessionInput =\n | (AssistantSessionExchangeBase & {\n readonly signInTicket?: undefined;\n readonly context?: Readonly<Record<string, string | number | boolean | null>>;\n /** Backend-verified connector routes keyed by authored `customerEndpoint` name. */\n readonly routing?: {\n readonly endpoints: Readonly<Record<string, string>>;\n };\n /** Resume applies only when spending a sign-in ticket; a fresh mint has nothing pending. */\n readonly resume?: undefined;\n })\n | (AssistantSessionExchangeBase & {\n /**\n * Single-use sign-in ticket from the widget's `assistant-sign-in-requested` event\n * (ADR 0201, 5.6b). Spending it binds this signed-in user to the visitor's existing\n * anonymous conversation instead of minting a new one. Unrelated to the server-held\n * interaction continuation, which never reaches browser code.\n */\n readonly signInTicket: string;\n readonly context?: undefined;\n /** Backend-verified connector routes keyed by authored `customerEndpoint` name. */\n readonly routing?: {\n readonly endpoints: Readonly<Record<string, string>>;\n };\n /**\n * Whether the service resumes the intercepted tool call as the elevated session's first\n * turn (issue #1177). ON by default — omit it and the visitor's pending question answers\n * itself after sign-in; pass `false` if your application provides its own affordance.\n */\n readonly resume?: boolean;\n });\n\nexport interface AssistantSession {\n readonly token: string;\n readonly expiresAt: string;\n readonly endpoints: {\n readonly turns: string;\n readonly toolConfirmations: string;\n readonly interactions?: string;\n readonly apps?: string;\n /** Additive hosted sandbox document for widget frames; absent on older services. */\n readonly sandbox?: string;\n /** Additive bounded visible-transcript endpoint; absent on older services. */\n readonly transcript?: string;\n };\n /**\n * Present only on an elevation that armed the one-shot resume of the intercepted tool. Forward\n * the response body unchanged and the widget answers with one automatic turn.\n */\n readonly resume?: { readonly tool: string };\n readonly configuration?: AssistantConfiguration;\n}\n\n/** The service's refusal codes for a sign-in ticket the exchange would not honour. */\nexport const ASSISTANT_ELEVATION_REFUSAL_CODES = [\n 'elevation_ticket_invalid',\n 'elevation_ticket_expired',\n 'elevation_tenant_mismatch',\n 'elevation_session_unavailable',\n 'elevation_already_signed_in',\n] as const;\nexport type AssistantElevationRefusalCode = (typeof ASSISTANT_ELEVATION_REFUSAL_CODES)[number];\n\n/**\n * Structurally mirrors the browser client's `AssistantErrorDetail` (declared locally: the backend\n * entry must not pull the browser transport module into its graph). `code` is a closed union owned\n * by this package; `serviceCode` passes the service's machine code through additively.\n */\nexport interface AssistantSessionExchangeErrorDetail {\n readonly code: 'session_exchange_failed';\n readonly status: number;\n /** 5xx infrastructure failures may be retried; a refused exchange must not be — tickets are single-use. */\n readonly retryable: boolean;\n /** The service's machine code when the body carried one, e.g. `elevation_ticket_expired`. */\n readonly serviceCode?: string;\n}\n\nexport class AssistantSessionExchangeError extends Error {\n readonly detail: AssistantSessionExchangeErrorDetail;\n\n constructor(detail: AssistantSessionExchangeErrorDetail, message: string) {\n super(message);\n this.name = 'AssistantSessionExchangeError';\n this.detail = detail;\n }\n\n /**\n * The narrowed sign-in refusal, when this failure is one. `elevation_ticket_expired` means the\n * visitor took too long — re-prompt; `elevation_tenant_mismatch` means a client reached for a\n * conversation it does not own — alert someone, never retry.\n */\n get elevationRefusal(): AssistantElevationRefusalCode | undefined {\n const code = this.detail.serviceCode;\n return code !== undefined &&\n (ASSISTANT_ELEVATION_REFUSAL_CODES as readonly string[]).includes(code)\n ? (code as AssistantElevationRefusalCode)\n : undefined;\n }\n}\n\n/** Never throws while reading the body — a proxy can answer with HTML instead of JSON. */\nasync function exchangeError(response: Response): Promise<AssistantSessionExchangeError> {\n const body = (await response.json().catch(() => undefined)) as\n | { readonly error?: unknown; readonly code?: unknown }\n | undefined;\n const serviceCode = typeof body?.code === 'string' ? body.code : undefined;\n return new AssistantSessionExchangeError(\n {\n code: 'session_exchange_failed',\n status: response.status,\n // `elevation_unavailable` is a 503 an operator has to fix; retrying cannot help.\n retryable: response.status >= 500 && serviceCode !== 'elevation_unavailable',\n ...(serviceCode === undefined ? {} : { serviceCode }),\n },\n `Assistant session exchange failed (${response.status})`,\n );\n}\n\nexport async function createAssistantSession(\n input: CreateAssistantSessionInput,\n dependencies: { readonly fetch?: typeof fetch } = {},\n): Promise<AssistantSession> {\n if (input.signInTicket !== undefined && (input as { context?: unknown }).context !== undefined) {\n // Mirrors resolveSessionSource: silently dropping what the service ignores would pick a\n // meaning the developer did not intend.\n throw new Error('context does not apply when spending a sign-in ticket');\n }\n const request = dependencies.fetch ?? fetch;\n const serviceUrl = input.serviceUrl.replace(/\\/$/, '');\n const credentials = Buffer.from(`${input.clientId}:${input.clientSecret}`, 'utf8').toString(\n 'base64',\n );\n const response = await request(`${serviceUrl}/v1/assistant/sessions`, {\n method: 'POST',\n headers: {\n Authorization: `Basic ${credentials}`,\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n origin: input.origin,\n user: input.user,\n ...(input.signInTicket === undefined ? {} : { signInTicket: input.signInTicket }),\n ...(input.signInTicket !== undefined && input.resume !== undefined\n ? { resume: input.resume }\n : {}),\n ...(input.claims ? { claims: input.claims } : {}),\n ...(input.context ? { context: input.context } : {}),\n ...(input.preferences ? { preferences: input.preferences } : {}),\n ...(input.routing ? { routing: input.routing } : {}),\n }),\n });\n // A fresh mint answers 201, an elevation 200; both are the same wire shape (ADR 0151).\n if (!response.ok) throw await exchangeError(response);\n return (await response.json()) as AssistantSession;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8FO,IAAM,oCAAoC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAiBO,IAAM,gCAAN,cAA4C,MAAM;AAAA,EAC9C;AAAA,EAET,YAAY,QAA6C,SAAiB;AACxE,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,mBAA8D;AAChE,UAAM,OAAO,KAAK,OAAO;AACzB,WAAO,SAAS,UACb,kCAAwD,SAAS,IAAI,IACnE,OACD;AAAA,EACN;AACF;AAGA,eAAe,cAAc,UAA4D;AACvF,QAAM,OAAQ,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,MAAS;AAGzD,QAAM,cAAc,OAAO,MAAM,SAAS,WAAW,KAAK,OAAO;AACjE,SAAO,IAAI;AAAA,IACT;AAAA,MACE,MAAM;AAAA,MACN,QAAQ,SAAS;AAAA;AAAA,MAEjB,WAAW,SAAS,UAAU,OAAO,gBAAgB;AAAA,MACrD,GAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,YAAY;AAAA,IACrD;AAAA,IACA,sCAAsC,SAAS,MAAM;AAAA,EACvD;AACF;AAEA,eAAsB,uBACpB,OACA,eAAkD,CAAC,GACxB;AAC3B,MAAI,MAAM,iBAAiB,UAAc,MAAgC,YAAY,QAAW;AAG9F,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AACA,QAAM,UAAU,aAAa,SAAS;AACtC,QAAM,aAAa,MAAM,WAAW,QAAQ,OAAO,EAAE;AACrD,QAAM,cAAc,OAAO,KAAK,GAAG,MAAM,QAAQ,IAAI,MAAM,YAAY,IAAI,MAAM,EAAE;AAAA,IACjF;AAAA,EACF;AACA,QAAM,WAAW,MAAM,QAAQ,GAAG,UAAU,0BAA0B;AAAA,IACpE,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,eAAe,SAAS,WAAW;AAAA,MACnC,QAAQ;AAAA,MACR,gBAAgB;AAAA,IAClB;AAAA,IACA,MAAM,KAAK,UAAU;AAAA,MACnB,QAAQ,MAAM;AAAA,MACd,MAAM,MAAM;AAAA,MACZ,GAAI,MAAM,iBAAiB,SAAY,CAAC,IAAI,EAAE,cAAc,MAAM,aAAa;AAAA,MAC/E,GAAI,MAAM,iBAAiB,UAAa,MAAM,WAAW,SACrD,EAAE,QAAQ,MAAM,OAAO,IACvB,CAAC;AAAA,MACL,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,MAC/C,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,MAClD,GAAI,MAAM,cAAc,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,MAC9D,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,IACpD,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,SAAS,GAAI,OAAM,MAAM,cAAc,QAAQ;AACpD,SAAQ,MAAM,SAAS,KAAK;AAC9B;","names":[]}
1
+ {"version":3,"sources":["../src/server.ts"],"sourcesContent":["import type { AssistantConfiguration } from './appearance.js';\n\ninterface AssistantSessionExchangeBase {\n readonly serviceUrl: string;\n readonly clientId: string;\n readonly clientSecret: string;\n /** Browser origin to bind into the short-lived assistant session. */\n readonly origin: string;\n /** The signed-in person your backend vouches for — on both arms: an elevation IS this vouching. */\n readonly user: {\n readonly id: string;\n readonly email?: string;\n readonly name?: string;\n readonly tenant?: string;\n readonly roles?: readonly string[];\n readonly scopes?: readonly string[];\n };\n /** Backend-verified user preferences; these outrank untrusted browser presentation hints. */\n readonly preferences?: {\n readonly locale?: string;\n readonly timeZone?: string;\n };\n /**\n * Verified session claims from your authenticated backend. Only claims the server declares in\n * `embeddedAssistant({ sessionClaims })` reach tools (`\\${user.claims.<key>}`) and, when marked\n * `exposeToModel`, the assistant's identity context. Flat scalars only.\n */\n readonly claims?: Readonly<Record<string, string | number | boolean | null>>;\n}\n\n/**\n * Fresh mint XOR mid-conversation sign-in, exclusive rather than merged for the same reason the\n * client's `sessionEndpoint`/`embedId` pair is: the two are different operations, and the wrong\n * combination should fail to typecheck instead of silently picking a meaning.\n *\n * `context` applies only when a session is being created; an elevation keeps the existing\n * conversation, so it is excluded rather than silently ignored. `routing` is allowed on both arms —\n * elevation is the first authenticated moment, so it is the only chance a routed connector's\n * session ever gets its backend-verified customer routes.\n */\nexport type CreateAssistantSessionInput =\n | (AssistantSessionExchangeBase & {\n readonly signInTicket?: undefined;\n readonly context?: Readonly<Record<string, string | number | boolean | null>>;\n /** Backend-verified connector routes keyed by authored `customerEndpoint` name. */\n readonly routing?: {\n readonly endpoints: Readonly<Record<string, string>>;\n };\n /** Resume applies only when spending a sign-in ticket; a fresh mint has nothing pending. */\n readonly resume?: undefined;\n })\n | (AssistantSessionExchangeBase & {\n /**\n * Single-use sign-in ticket from the widget's `assistant-sign-in-requested` event\n * (ADR 0201, 5.6b). Spending it binds this signed-in user to the visitor's existing\n * anonymous conversation instead of minting a new one. Unrelated to the server-held\n * interaction continuation, which never reaches browser code.\n */\n readonly signInTicket: string;\n readonly context?: undefined;\n /** Backend-verified connector routes keyed by authored `customerEndpoint` name. */\n readonly routing?: {\n readonly endpoints: Readonly<Record<string, string>>;\n };\n /**\n * Whether the service resumes the intercepted tool call as the elevated session's first\n * turn (issue #1177). ON by default — omit it and the visitor's pending question answers\n * itself after sign-in; pass `false` if your application provides its own affordance.\n */\n readonly resume?: boolean;\n });\n\nexport interface AssistantSession {\n readonly token: string;\n readonly expiresAt: string;\n readonly endpoints: {\n readonly turns: string;\n readonly toolConfirmations: string;\n readonly interactions?: string;\n readonly apps?: string;\n /** Additive hosted sandbox document for widget frames; absent on older services. */\n readonly sandbox?: string;\n /** Additive bounded visible-transcript endpoint; absent on older services. */\n readonly transcript?: string;\n /** Additive model-generated prompt suggestions; absent on older services. */\n readonly suggestions?: string;\n };\n /**\n * Present only on an elevation that armed the one-shot resume of the intercepted tool. Forward\n * the response body unchanged and the widget answers with one automatic turn.\n */\n readonly resume?: { readonly tool: string };\n readonly configuration?: AssistantConfiguration;\n}\n\n/** The service's refusal codes for a sign-in ticket the exchange would not honour. */\nexport const ASSISTANT_ELEVATION_REFUSAL_CODES = [\n 'elevation_ticket_invalid',\n 'elevation_ticket_expired',\n 'elevation_tenant_mismatch',\n 'elevation_session_unavailable',\n 'elevation_already_signed_in',\n] as const;\nexport type AssistantElevationRefusalCode = (typeof ASSISTANT_ELEVATION_REFUSAL_CODES)[number];\n\n/**\n * Structurally mirrors the browser client's `AssistantErrorDetail` (declared locally: the backend\n * entry must not pull the browser transport module into its graph). `code` is a closed union owned\n * by this package; `serviceCode` passes the service's machine code through additively.\n */\nexport interface AssistantSessionExchangeErrorDetail {\n readonly code: 'session_exchange_failed';\n readonly status: number;\n /** 5xx infrastructure failures may be retried; a refused exchange must not be — tickets are single-use. */\n readonly retryable: boolean;\n /** The service's machine code when the body carried one, e.g. `elevation_ticket_expired`. */\n readonly serviceCode?: string;\n}\n\nexport class AssistantSessionExchangeError extends Error {\n readonly detail: AssistantSessionExchangeErrorDetail;\n\n constructor(detail: AssistantSessionExchangeErrorDetail, message: string) {\n super(message);\n this.name = 'AssistantSessionExchangeError';\n this.detail = detail;\n }\n\n /**\n * The narrowed sign-in refusal, when this failure is one. `elevation_ticket_expired` means the\n * visitor took too long — re-prompt; `elevation_tenant_mismatch` means a client reached for a\n * conversation it does not own — alert someone, never retry.\n */\n get elevationRefusal(): AssistantElevationRefusalCode | undefined {\n const code = this.detail.serviceCode;\n return code !== undefined &&\n (ASSISTANT_ELEVATION_REFUSAL_CODES as readonly string[]).includes(code)\n ? (code as AssistantElevationRefusalCode)\n : undefined;\n }\n}\n\n/** Never throws while reading the body — a proxy can answer with HTML instead of JSON. */\nasync function exchangeError(response: Response): Promise<AssistantSessionExchangeError> {\n const body = (await response.json().catch(() => undefined)) as\n | { readonly error?: unknown; readonly code?: unknown }\n | undefined;\n const serviceCode = typeof body?.code === 'string' ? body.code : undefined;\n return new AssistantSessionExchangeError(\n {\n code: 'session_exchange_failed',\n status: response.status,\n // `elevation_unavailable` is a 503 an operator has to fix; retrying cannot help.\n retryable: response.status >= 500 && serviceCode !== 'elevation_unavailable',\n ...(serviceCode === undefined ? {} : { serviceCode }),\n },\n `Assistant session exchange failed (${response.status})`,\n );\n}\n\nexport async function createAssistantSession(\n input: CreateAssistantSessionInput,\n dependencies: { readonly fetch?: typeof fetch } = {},\n): Promise<AssistantSession> {\n if (input.signInTicket !== undefined && (input as { context?: unknown }).context !== undefined) {\n // Mirrors resolveSessionSource: silently dropping what the service ignores would pick a\n // meaning the developer did not intend.\n throw new Error('context does not apply when spending a sign-in ticket');\n }\n const request = dependencies.fetch ?? fetch;\n const serviceUrl = input.serviceUrl.replace(/\\/$/, '');\n const credentials = Buffer.from(`${input.clientId}:${input.clientSecret}`, 'utf8').toString(\n 'base64',\n );\n const response = await request(`${serviceUrl}/v1/assistant/sessions`, {\n method: 'POST',\n headers: {\n Authorization: `Basic ${credentials}`,\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n origin: input.origin,\n user: input.user,\n ...(input.signInTicket === undefined ? {} : { signInTicket: input.signInTicket }),\n ...(input.signInTicket !== undefined && input.resume !== undefined\n ? { resume: input.resume }\n : {}),\n ...(input.claims ? { claims: input.claims } : {}),\n ...(input.context ? { context: input.context } : {}),\n ...(input.preferences ? { preferences: input.preferences } : {}),\n ...(input.routing ? { routing: input.routing } : {}),\n }),\n });\n // A fresh mint answers 201, an elevation 200; both are the same wire shape (ADR 0151).\n if (!response.ok) throw await exchangeError(response);\n return (await response.json()) as AssistantSession;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgGO,IAAM,oCAAoC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAiBO,IAAM,gCAAN,cAA4C,MAAM;AAAA,EAC9C;AAAA,EAET,YAAY,QAA6C,SAAiB;AACxE,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,mBAA8D;AAChE,UAAM,OAAO,KAAK,OAAO;AACzB,WAAO,SAAS,UACb,kCAAwD,SAAS,IAAI,IACnE,OACD;AAAA,EACN;AACF;AAGA,eAAe,cAAc,UAA4D;AACvF,QAAM,OAAQ,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,MAAS;AAGzD,QAAM,cAAc,OAAO,MAAM,SAAS,WAAW,KAAK,OAAO;AACjE,SAAO,IAAI;AAAA,IACT;AAAA,MACE,MAAM;AAAA,MACN,QAAQ,SAAS;AAAA;AAAA,MAEjB,WAAW,SAAS,UAAU,OAAO,gBAAgB;AAAA,MACrD,GAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,YAAY;AAAA,IACrD;AAAA,IACA,sCAAsC,SAAS,MAAM;AAAA,EACvD;AACF;AAEA,eAAsB,uBACpB,OACA,eAAkD,CAAC,GACxB;AAC3B,MAAI,MAAM,iBAAiB,UAAc,MAAgC,YAAY,QAAW;AAG9F,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AACA,QAAM,UAAU,aAAa,SAAS;AACtC,QAAM,aAAa,MAAM,WAAW,QAAQ,OAAO,EAAE;AACrD,QAAM,cAAc,OAAO,KAAK,GAAG,MAAM,QAAQ,IAAI,MAAM,YAAY,IAAI,MAAM,EAAE;AAAA,IACjF;AAAA,EACF;AACA,QAAM,WAAW,MAAM,QAAQ,GAAG,UAAU,0BAA0B;AAAA,IACpE,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,eAAe,SAAS,WAAW;AAAA,MACnC,QAAQ;AAAA,MACR,gBAAgB;AAAA,IAClB;AAAA,IACA,MAAM,KAAK,UAAU;AAAA,MACnB,QAAQ,MAAM;AAAA,MACd,MAAM,MAAM;AAAA,MACZ,GAAI,MAAM,iBAAiB,SAAY,CAAC,IAAI,EAAE,cAAc,MAAM,aAAa;AAAA,MAC/E,GAAI,MAAM,iBAAiB,UAAa,MAAM,WAAW,SACrD,EAAE,QAAQ,MAAM,OAAO,IACvB,CAAC;AAAA,MACL,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,MAC/C,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,MAClD,GAAI,MAAM,cAAc,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,MAC9D,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,IACpD,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,SAAS,GAAI,OAAM,MAAM,cAAc,QAAQ;AACpD,SAAQ,MAAM,SAAS,KAAK;AAC9B;","names":[]}