dewee-webchat 0.2.0 → 0.4.1-beta.1

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.
@@ -0,0 +1,307 @@
1
+ import { A as AgentInfo } from './protocol-CLbGE9Ns.js';
2
+
3
+ interface VisitorClaims {
4
+ /** Visitor id (random, 22 chars; derived from the principal for a signed-in user). */
5
+ v: string;
6
+ /** Expiry, epoch ms. */
7
+ exp: number;
8
+ /**
9
+ * Signed-in users only: the Dewee identity session token. In the signed token it is encrypted
10
+ * (AES-256-GCM), so the browser only ever holds an opaque value; these claims carry it decrypted.
11
+ */
12
+ ids?: string;
13
+ /** Signed-in users only: the agent the identity session is bound to. */
14
+ ida?: string;
15
+ /**
16
+ * Signed-in users only: a keyed digest of the host's subject (see {@link subjectDigest}). Sealed
17
+ * together with `ids`, so the browser never sees the subject or its digest.
18
+ */
19
+ sub?: string;
20
+ /**
21
+ * CCP transport only: the CCP edge session token (`dws1.…`). In the signed token it is encrypted
22
+ * (AES-256-GCM, its own key label), so the browser never holds the raw value.
23
+ */
24
+ es?: string;
25
+ /** CCP transport only: expiry of `es` as CCP reported it, epoch ms on this server's clock. */
26
+ ese?: number;
27
+ }
28
+ /** Signs a visitor bearer token. */
29
+ declare function signVisitorToken(secret: string, claims: VisitorClaims): Promise<string>;
30
+ /** Verifies a visitor bearer token. A reuse hint (or any token with a purpose label) is refused. */
31
+ declare function verifyVisitorToken(secret: string, token: string): Promise<VisitorClaims | null>;
32
+ /**
33
+ * Rate-limit buckets: `session` (new visitor sessions, per IP), `chat` (messages, per visitor and IP),
34
+ * and with signed-in users `preauth` (calls to the host's `authenticate`, per IP), `verified`
35
+ * (signed-in `/session` calls, per user) and `link` (link starts, per user).
36
+ */
37
+ type RateLimitBucket = "session" | "chat" | "preauth" | "verified" | "link";
38
+ /** Returns true when the key may proceed. Implementations may be async (KV, DO, Redis…). */
39
+ type RateLimiter = (key: string, bucket: RateLimitBucket) => boolean | Promise<boolean>;
40
+ /**
41
+ * `[max, windowMs]` per bucket. `preauth` defaults to 120 per minute; `verified` and `link` fall back to
42
+ * the `session` limit when not set.
43
+ */
44
+ interface MemoryRateLimits {
45
+ chat: [number, number];
46
+ session: [number, number];
47
+ preauth?: [number, number];
48
+ verified?: [number, number];
49
+ link?: [number, number];
50
+ }
51
+ /**
52
+ * Fixed-window in-memory limiter. Good enough for a single Node process; on serverless
53
+ * runtimes each isolate keeps its own counters, so pass a shared limiter for hard limits.
54
+ */
55
+ declare function memoryRateLimiter(limits: MemoryRateLimits): RateLimiter;
56
+
57
+ /** Validated CCP endpoint options (see {@link parseCcpOptions}). */
58
+ interface CcpOptions {
59
+ /**
60
+ * The full ingress base the CCP "Website chat" page prints as `DEWEE_CCP_CHAT_URL`, e.g.
61
+ * `https://app.dewee.sh/api/public/webchat/v1/wci_…`. Must be https, except plain http to a
62
+ * loopback host (`localhost`, `127.0.0.1`, `[::1]`) for local development.
63
+ */
64
+ chatUrl: string;
65
+ /** `DEWEE_WEBCHAT_INTEGRATION_ID` (`wci_…`); must equal the id at the end of `chatUrl`. */
66
+ integrationId: string;
67
+ /** `DEWEE_WEBCHAT_INTEGRATION_SECRET` (`dwc_…`). Server-only; never sent to a browser or another origin. */
68
+ integrationSecret: string;
69
+ /** Custom fetch (tests, instrumented hosts). Defaults to the global `fetch`. */
70
+ fetch?: typeof fetch;
71
+ }
72
+ /**
73
+ * A refusal or failure of the ingress. `code` is the contract's public code (`integration_unauthorized`,
74
+ * `rate_limited`, an identity code…), or a local one: `ccp_unreachable` (network), `ccp_redirect`
75
+ * (a redirect was refused), `ccp_bad_response` (not the contract's shape). `message` is CCP's text and
76
+ * is for logs only; it is never sent to a browser.
77
+ */
78
+ declare class CcpError extends Error {
79
+ status: number;
80
+ code: string;
81
+ retryAfterSeconds?: number | undefined;
82
+ remediation?: {
83
+ action: string;
84
+ audience: string;
85
+ } | undefined;
86
+ constructor(status: number, code: string, message: string, retryAfterSeconds?: number | undefined, remediation?: {
87
+ action: string;
88
+ audience: string;
89
+ } | undefined);
90
+ }
91
+
92
+ /**
93
+ * A signed-in user of the host app, as `identity.authenticate` reports it. Scopes are not part of
94
+ * the session exchange: report scope changes with `lifecycle({ event: "scopes_changed" })` from
95
+ * `@dewee/identity`.
96
+ */
97
+ interface AuthenticatedUser {
98
+ /** Your stable, opaque user id. Never an email address (an id containing "@" is refused). */
99
+ subject: string;
100
+ }
101
+ /** A private JWK whose public half is published in the application's `jwks_url`. */
102
+ interface IdentityPrivateJwk {
103
+ kty: string;
104
+ kid: string;
105
+ d: string;
106
+ alg?: string;
107
+ [key: string]: unknown;
108
+ }
109
+ /** Partner assertion signer, the shape `@dewee/identity` takes. */
110
+ type IdentitySigner = {
111
+ applicationId: string;
112
+ issuer: string;
113
+ secret: string;
114
+ } | {
115
+ applicationId: string;
116
+ issuer: string;
117
+ privateKeyJwk: IdentityPrivateJwk;
118
+ algorithm?: "RS256" | "ES256" | "EdDSA";
119
+ };
120
+ /**
121
+ * The two `@dewee/identity` calls the handler uses. Pass `deweeIdentitySdk` from
122
+ * `dewee-webchat/server/identity`; it is a separate entry so that only hosts that sign users in
123
+ * need the SDK installed and bundled.
124
+ */
125
+ interface DeweeIdentitySdk {
126
+ exchangeSession(opts: {
127
+ gatewayUrl: string;
128
+ allowInsecureHttp?: boolean;
129
+ signer: IdentitySigner;
130
+ subject: string;
131
+ agent: string;
132
+ ttlSeconds?: number;
133
+ }): Promise<{
134
+ sessionToken: string;
135
+ principalId: string;
136
+ expiresAt: Date;
137
+ }>;
138
+ startLink(opts: {
139
+ gatewayUrl: string;
140
+ allowInsecureHttp?: boolean;
141
+ sessionToken: string;
142
+ idempotencyKey?: string;
143
+ }): Promise<{
144
+ proofCode: string;
145
+ expiresAt: Date;
146
+ deepLinks: Array<{
147
+ channelType: string;
148
+ channelInstanceId: string;
149
+ name: string;
150
+ displayName?: string;
151
+ }>;
152
+ }>;
153
+ /**
154
+ * Signs a partner assertion. Used by `transport: "ccp"`, where the website signs and CCP exchanges.
155
+ * `deweeIdentitySdk` provides it.
156
+ */
157
+ createAssertion?(opts: {
158
+ purpose: "session";
159
+ subject: string;
160
+ applicationId: string;
161
+ issuer: string;
162
+ secret?: string;
163
+ privateKeyJwk?: IdentityPrivateJwk;
164
+ algorithm?: "RS256" | "ES256" | "EdDSA";
165
+ }): Promise<string>;
166
+ }
167
+ /**
168
+ * Verified signed-in users through a Dewee identity session exchange. The host passes one
169
+ * server-side callback; the handler exchanges the user for a short-lived Dewee identity session bound
170
+ * to one agent, and the gateway derives the user from it.
171
+ */
172
+ interface DeweeIdentityOptions {
173
+ /** `deweeIdentitySdk` from `dewee-webchat/server/identity`. */
174
+ sdk: DeweeIdentitySdk;
175
+ /**
176
+ * Reads your own login (cookie, header…). Return null for a visitor who is not signed in. Throwing
177
+ * means the login could not be read: the visitor gets `503 SOURCE_UNAVAILABLE`, never an anonymous
178
+ * session. Keep it cheap or cached: it runs on every `/session` (every page load) and, with
179
+ * `rebindEachRequest`, on every `/chat`, `/history` and `/link`, behind a generous per-IP cap only.
180
+ */
181
+ authenticate(req: Request): Promise<AuthenticatedUser | null>;
182
+ /** Dewee application id (`dewee identity setup` prints it). */
183
+ appId: string;
184
+ /** The issuer configured on the application, exactly. */
185
+ issuer: string;
186
+ /** Optional check: must equal `dewee:<appId>`, the audience Dewee issued the application. */
187
+ audience?: string;
188
+ /** Assertion secret of an `hmac` application. Exactly one of this or `privateKeyJwk`. */
189
+ assertionSecret?: string;
190
+ /** Private signing key of a `jwks` application (RS256, ES256 or EdDSA, with `kid`). */
191
+ privateKeyJwk?: IdentityPrivateJwk;
192
+ /** Algorithm of `privateKeyJwk`; defaults to its `alg`. */
193
+ algorithm?: "RS256" | "ES256" | "EdDSA";
194
+ /**
195
+ * The agent identity sessions are bound to. Default: `defaultAgent`, else the first of `agents`
196
+ * (with `transport: "ccp"`: the integration's default agent).
197
+ */
198
+ agent?: string;
199
+ /**
200
+ * Refuse visitors who are not signed in (no anonymous fallback). Default false: a visitor for whom
201
+ * `authenticate` returns null chats anonymously exactly as without this option.
202
+ */
203
+ required?: boolean;
204
+ /**
205
+ * Check the signed-in user again on every `/chat`, `/history` and `/link`: `authenticate(req)` must
206
+ * return the same subject the session was issued for, else the request is `401 IDENTITY_REQUIRED`
207
+ * (the widget then asks `/session` again); if it throws, `503 SOURCE_UNAVAILABLE`. Recommended when
208
+ * your login is a cookie: a widget token replayed under another user's cookie is then useless.
209
+ * Default false.
210
+ */
211
+ rebindEachRequest?: boolean;
212
+ /** Identity session lifetime, 60 to 43200 seconds. Default: the gateway default (3600). */
213
+ sessionTtlSeconds?: number;
214
+ /** Allow plain http to a gateway that is not loopback (private networks only). */
215
+ allowInsecureHttp?: boolean;
216
+ }
217
+ /** How this backend reaches Dewee. */
218
+ type DeweeTransport = "ccp" | "legacy-gateway";
219
+ interface DeweeHandlerOptions {
220
+ /**
221
+ * `"ccp"`: the CCP-managed public webchat ingress, configured with `ccp` (recommended).
222
+ * `"legacy-gateway"`: a direct Gateway WebSocket with `gatewayUrl` + `token` (deprecated).
223
+ * Default: `"ccp"` when `ccp` is set, else `"legacy-gateway"`. Setting both `ccp` and the gateway
224
+ * options is a startup error, so a credential is never sent to an origin it was not meant for.
225
+ */
226
+ transport?: DeweeTransport;
227
+ /**
228
+ * The CCP integration (`DEWEE_CCP_CHAT_URL`, `DEWEE_WEBCHAT_INTEGRATION_ID`,
229
+ * `DEWEE_WEBCHAT_INTEGRATION_SECRET` from the CCP "Website chat" page). The integration decides the
230
+ * agents, sign-in mode and whether reasoning and tool activity are shown, so `agents`,
231
+ * `defaultAgent`, `tenantId` and `allowClientCredentials` do not apply to it.
232
+ */
233
+ ccp?: CcpOptions;
234
+ /** Legacy gateway transport: Gateway runtime origin. Required unless every request brings its own credentials. */
235
+ gatewayUrl?: string;
236
+ /** Legacy gateway transport: Gateway token or operator API key (server-side only). */
237
+ token?: string;
238
+ /** Legacy gateway transport. */
239
+ tenantId?: string;
240
+ /** HMAC secret for visitor tokens (>= 32 random chars). */
241
+ secret?: string;
242
+ /** Legacy gateway transport: agents visitors may talk to. The first is the default. `"*"` = every active agent. */
243
+ agents?: Array<string | AgentInfo> | "*";
244
+ defaultAgent?: string;
245
+ /** Let the widget switch between allowed agents. Default: true when more than one agent. */
246
+ allowAgentSwitch?: boolean;
247
+ /** Cross-origin sites allowed to call this backend. Same-origin is always allowed. */
248
+ allowedOrigins?: string[] | "*";
249
+ /**
250
+ * Legacy gateway transport: let visitors bring their own gateway URL + token (sent per request, never stored).
251
+ * Meant for playgrounds. `allowedHosts` restricts which gateways may be targeted.
252
+ */
253
+ allowClientCredentials?: boolean | {
254
+ allowedHosts?: string[];
255
+ };
256
+ /** Cloudflare Turnstile. When set, issuing a visitor session requires a valid challenge. */
257
+ turnstile?: {
258
+ siteKey: string;
259
+ secretKey: string;
260
+ };
261
+ /**
262
+ * Custom limiter, or false to disable. Default (in memory): 20 messages/min per visitor and IP,
263
+ * 10 new sessions/10 min per IP and, with `identity`, 120 `authenticate` calls/min per IP,
264
+ * 30 signed-in sessions/10 min per user and 5 link starts/10 min per user. Defense in depth: the
265
+ * Dewee gateway owns the shared message limit and refuses with `RATE_LIMITED` (forwarded typed).
266
+ */
267
+ rateLimit?: RateLimiter | false;
268
+ maxMessageLength?: number;
269
+ /** Prefix for the per-visitor gateway user id. */
270
+ userIdPrefix?: string;
271
+ sessionTtlMs?: number;
272
+ /** Max duration of one agent run. */
273
+ timeoutMs?: number;
274
+ /** Observe traffic (logging/analytics). Errors thrown here are ignored. */
275
+ onChat?: (info: {
276
+ visitorId: string;
277
+ agent: string;
278
+ message: string;
279
+ reply?: string;
280
+ error?: string;
281
+ }) => void;
282
+ /**
283
+ * Verified signed-in users through Dewee (needs the `@dewee/identity` package). Absent: every
284
+ * visitor is anonymous, exactly as before. Cannot be combined with `allowClientCredentials`.
285
+ */
286
+ identity?: DeweeIdentityOptions;
287
+ }
288
+ /** The backend: one function for every route, plus the logout hook of signed-in users. */
289
+ interface DeweeHandler {
290
+ (request: Request): Promise<Response>;
291
+ /**
292
+ * Call from your logout: ends the Dewee identity sessions this backend holds for `subject` (every
293
+ * bound agent) and forgets them, so the next `/session` exchanges again. With `transport: "ccp"` they
294
+ * are revoked at CCP (`identity/revoke`). Pass the logout request so CCP sees the visitor's origin
295
+ * and IP (without it, the origin of the request the session was issued for is used). `token` is the
296
+ * widget's reuse hint (`reuseHint()`) or visitor token, sent along by your logout page: its identity
297
+ * session is revoked too when it belongs to `subject`, so a host that keeps no memory between
298
+ * requests still ends the exact session. Best effort: never throws. Other sessions held only by
299
+ * other instances end at their expiry (`sessionTtlSeconds`). Without `identity` it does nothing.
300
+ */
301
+ revoke(subject: string, request?: Request, token?: string): Promise<void>;
302
+ }
303
+ declare function createDeweeHandler(options: DeweeHandlerOptions): DeweeHandler;
304
+ /** Reads options from environment variables (process.env, Workers env, import.meta.env…). */
305
+ declare function optionsFromEnv(env: Record<string, string | undefined>, overrides?: Partial<DeweeHandlerOptions>): DeweeHandlerOptions;
306
+
307
+ export { type AuthenticatedUser as A, CcpError as C, type DeweeIdentitySdk as D, type IdentityPrivateJwk as I, type MemoryRateLimits as M, type RateLimitBucket as R, type VisitorClaims as V, type CcpOptions as a, type DeweeHandler as b, type DeweeHandlerOptions as c, type DeweeIdentityOptions as d, type DeweeTransport as e, type IdentitySigner as f, type RateLimiter as g, createDeweeHandler as h, memoryRateLimiter as m, optionsFromEnv as o, signVisitorToken as s, verifyVisitorToken as v };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { b as ActionSensitivity, P as PublicConfig, S as SessionResponse, H as HistoryMessage, c as ChatRequestBody, C as ChatStreamEvent } from './protocol-B72Ry-fY.js';
2
- export { a as ActionManifestEntry, A as AgentInfo, T as ToolCallView } from './protocol-B72Ry-fY.js';
1
+ import { d as ActionSensitivity, P as PublicConfig, S as SessionResponse, L as LinkResponse, H as HistoryMessage, e as ChatRequestBody, C as ChatStreamEvent, R as Remediation } from './protocol-CLbGE9Ns.js';
2
+ export { a as ActionManifestEntry, b as AdmissionErrorCode, A as AgentInfo, I as IdentityErrorCode, f as LinkTarget, T as ToolCallView } from './protocol-CLbGE9Ns.js';
3
3
 
4
4
  type ActionResultStatus = "ok" | "denied" | "error";
5
5
  interface ActionResult {
@@ -39,6 +39,106 @@ type ActionConfirmHook = (action: PageActionInfo & {
39
39
  }, args: Record<string, unknown>) => boolean | Promise<boolean>;
40
40
  type ActionCallStatus = "pending" | "awaiting-confirmation" | "running" | "done" | "denied" | "error";
41
41
 
42
+ /** The only launch data allowed to reach the browser. Never an identity session. */
43
+ interface JobAccessLaunch {
44
+ bootstrap_url: string;
45
+ launch_token: string;
46
+ expires_at: string;
47
+ }
48
+
49
+ /** Extra request headers: a static map, or a function evaluated before every request. */
50
+ type RequestHeadersOption = Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);
51
+ /**
52
+ * Headers the widget owns; `headers` cannot override them (compared case-insensitively). The
53
+ * session bearer token, signed-in or anonymous, travels in `authorization`.
54
+ */
55
+ declare const RESERVED_HEADERS: readonly string[];
56
+ interface ApiClientOptions {
57
+ /** Backend base URL, e.g. "/api/dewee" or "https://example.com/api/dewee". */
58
+ endpoint: string;
59
+ /** Bring-your-own gateway credentials (only if the backend allows it). */
60
+ gatewayUrl?: string;
61
+ gatewayToken?: string;
62
+ /** Called when the backend requires a Turnstile challenge; must resolve to a token. */
63
+ turnstile?: (siteKey: string) => Promise<string>;
64
+ /** Extra headers merged into every request (reserved headers excluded). */
65
+ headers?: RequestHeadersOption;
66
+ /** Replaces `globalThis.fetch` for every request. */
67
+ fetch?: typeof fetch;
68
+ }
69
+ declare class ApiError extends Error {
70
+ status: number;
71
+ code?: string | undefined;
72
+ remediation?: Remediation | undefined;
73
+ retryAfterMs?: number | undefined;
74
+ /** `retryAfterMs`: how long to wait before sending again (`RATE_LIMITED`). */
75
+ constructor(message: string, status: number, code?: string | undefined, remediation?: Remediation | undefined, retryAfterMs?: number | undefined);
76
+ }
77
+ declare class ApiClient {
78
+ private o;
79
+ private session;
80
+ private config;
81
+ private sessionPromise;
82
+ constructor(o: ApiClientOptions);
83
+ private url;
84
+ private get storageKey();
85
+ private get reuseKey();
86
+ /**
87
+ * The tab's reuse hint for signed-in sessions, or null (none sent by this backend). A logout page can
88
+ * send it to the backend's logout route, whose `handler.revoke(subject, request, hint)` then ends
89
+ * exactly that session.
90
+ */
91
+ reuseHint(): string | null;
92
+ private request;
93
+ private headers;
94
+ private parse;
95
+ getConfig(force?: boolean): Promise<PublicConfig>;
96
+ /** When each signed-in session should be refreshed, on this browser's clock. */
97
+ private refreshAt;
98
+ /**
99
+ * Session reuse. A signed-in session follows its schedule (see `scheduleRefresh`). An anonymous
100
+ * token is refreshed once less than 10% of its lifetime (at most 24 h, at least 30 s) remains; a
101
+ * stored token from before `obtainedAt` existed uses the 24 h margin. When the backend reports the
102
+ * lifetime (`expiresIn`), it is counted from receipt, so a skewed browser clock does not matter.
103
+ */
104
+ private fresh;
105
+ /**
106
+ * A signed-in session is refreshed `min(60s, lifetime/2)` before it ends, with the lifetime the
107
+ * backend reports (`expiresIn`) counted from receipt, so a short lifetime is not refreshed on every
108
+ * request and a skewed browser clock does not matter.
109
+ */
110
+ private scheduleRefresh;
111
+ /** The stored anonymous visitor session, if any. Signed-in sessions are never stored. */
112
+ private stored;
113
+ /** Returns a valid visitor session, creating or refreshing it when needed. */
114
+ ensureSession(): Promise<SessionResponse>;
115
+ private loadSession;
116
+ private createSession;
117
+ /** Drops the session; the next request creates a new one. A stored anonymous visitor is kept for a signed-in session. */
118
+ forgetSession(): void;
119
+ /**
120
+ * Asks the backend for a new session now (after a sign-in or sign-out on the host page). The
121
+ * stored anonymous visitor id is kept, so an anonymous visitor's history survives.
122
+ */
123
+ renewSession(): Promise<SessionResponse>;
124
+ /** Requests a single-use launch ticket. Does not refresh or swap the signed-in session after refusal. */
125
+ jobAccess(signal: AbortSignal): Promise<JobAccessLaunch>;
126
+ /** Starts a web-first link of a chat account for the signed-in user (identity backends only). */
127
+ link(): Promise<LinkResponse>;
128
+ history(agent: string, conversationId: string): Promise<HistoryMessage[]>;
129
+ /**
130
+ * Sends a request with the current session. A signed-in session the backend refuses (expired,
131
+ * revoked, or another user signed in) is dropped and renewed once, as chat() does. An anonymous
132
+ * visitor's 401 is final, and its stored visitor is kept.
133
+ */
134
+ private signedInRequest;
135
+ /** Sends a message and calls `onEvent` for every streamed event. Resolves when the run ends. */
136
+ chat(input: ChatRequestBody & {
137
+ agent: string;
138
+ conversationId: string;
139
+ }, onEvent: (e: ChatStreamEvent) => void, signal?: AbortSignal): Promise<void>;
140
+ }
141
+
42
142
  interface DeweeChatConfig {
43
143
  /** Backend base URL (the server handler). Default: "/api/dewee". */
44
144
  endpoint: string;
@@ -88,6 +188,13 @@ interface DeweeChatConfig {
88
188
  maxActionRounds?: number;
89
189
  /** Per-handler timeout. Default 30000 ms. */
90
190
  actionTimeoutMs?: number;
191
+ /**
192
+ * Extra headers for every request to `endpoint` (e.g. a CSRF token). A function is called before
193
+ * each request. Cannot override content-type, authorization or the gateway credential headers.
194
+ */
195
+ headers?: RequestHeadersOption;
196
+ /** Replaces `globalThis.fetch` for every widget request (e.g. to add credentials or tracing). */
197
+ fetch?: typeof fetch;
91
198
  }
92
199
  /** A page action call as shown in the transcript. */
93
200
  interface ActionCallView {
@@ -122,6 +229,7 @@ declare class DeweeChatElement extends ElementBase {
122
229
  private conversationId;
123
230
  private messages;
124
231
  private running;
232
+ private jobAccessLaunch;
125
233
  private activated;
126
234
  private strings;
127
235
  private mql;
@@ -129,6 +237,8 @@ declare class DeweeChatElement extends ElementBase {
129
237
  private propActionNames;
130
238
  private hooks;
131
239
  private acks;
240
+ /** Pause after a RATE_LIMITED refusal; send stays disabled until it ends. */
241
+ private cooldown;
132
242
  private els;
133
243
  constructor();
134
244
  /** Current effective configuration (attributes merged with `configure()` overrides). */
@@ -139,6 +249,12 @@ declare class DeweeChatElement extends ElementBase {
139
249
  registerActions(actions: PageAction | PageAction[]): void;
140
250
  /** Removes a page action. Returns false when it was not registered. */
141
251
  unregisterAction(name: string): boolean;
252
+ /** Extra request headers (property only; same as `configure({ headers })`). */
253
+ get headers(): RequestHeadersOption | undefined;
254
+ set headers(v: RequestHeadersOption | undefined);
255
+ /** Custom fetch for widget requests (property only; same as `configure({ fetch })`). */
256
+ get fetch(): typeof fetch | undefined;
257
+ set fetch(v: typeof fetch | undefined);
142
258
  /** Names of the currently registered page actions. */
143
259
  get actionNames(): string[];
144
260
  private setPropActions;
@@ -161,6 +277,25 @@ declare class DeweeChatElement extends ElementBase {
161
277
  private showNotice;
162
278
  /** Stops the running reply. */
163
279
  stop(): void;
280
+ /**
281
+ * Call after the visitor signs in or out on the host page: the next message uses a session for
282
+ * the current user, and the conversation is reloaded for them.
283
+ */
284
+ renewSession(): Promise<void>;
285
+ /**
286
+ * The tab's signed-in reuse hint, or null. Not a credential: send it to your logout route for
287
+ * `handler.revoke(subject, request, hint)`, which then ends exactly that session.
288
+ */
289
+ reuseHint(): string | null;
290
+ /**
291
+ * Web-first linking for a signed-in user: shows a proof code and the chat apps to send it to
292
+ * ("Continue on Telegram"). The user never types an account id. Resolves null on failure (the
293
+ * error is shown in the chat and emitted as `dewee:error`).
294
+ */
295
+ startLink(): Promise<LinkResponse | null>;
296
+ /** Opens the hosted permission review; the verified session stays on the backend. */
297
+ openJobAccess(): Promise<void>;
298
+ private renderLink;
164
299
  /** Starts a fresh conversation with the current agent. */
165
300
  newConversation(): void;
166
301
  connectedCallback(): void;
@@ -175,6 +310,10 @@ declare class DeweeChatElement extends ElementBase {
175
310
  private renderShell;
176
311
  private autosize;
177
312
  private updateSendButton;
313
+ /** Disables sending for `ms` and announces it; the visible countdown is not read out every second. */
314
+ private startCooldown;
315
+ private renderCooldown;
316
+ private endCooldown;
178
317
  private setRunning;
179
318
  private renderSubtitle;
180
319
  /** Loads backend config and the persisted conversation once. */
@@ -196,47 +335,16 @@ declare class DeweeChatElement extends ElementBase {
196
335
  private nearBottom;
197
336
  private scrollToBottom;
198
337
  private showError;
338
+ /**
339
+ * An admission refusal: the visitor's message never reached the agent, so it goes back to an empty
340
+ * composer to edit or resend. `POLICY_DENIED` is shown next to that message instead of as an empty
341
+ * reply. Returns true when the error was shown here.
342
+ */
343
+ private refuseInline;
199
344
  /** Renders a Turnstile challenge in light DOM (slotted) and resolves with its token. */
200
345
  private challenge;
201
346
  }
202
347
 
203
- interface ApiClientOptions {
204
- /** Backend base URL, e.g. "/api/dewee" or "https://example.com/api/dewee". */
205
- endpoint: string;
206
- /** Bring-your-own gateway credentials (only if the backend allows it). */
207
- gatewayUrl?: string;
208
- gatewayToken?: string;
209
- /** Called when the backend requires a Turnstile challenge; must resolve to a token. */
210
- turnstile?: (siteKey: string) => Promise<string>;
211
- }
212
- declare class ApiError extends Error {
213
- status: number;
214
- code?: string | undefined;
215
- constructor(message: string, status: number, code?: string | undefined);
216
- }
217
- declare class ApiClient {
218
- private o;
219
- private session;
220
- private config;
221
- private sessionPromise;
222
- constructor(o: ApiClientOptions);
223
- private url;
224
- private get storageKey();
225
- private headers;
226
- private parse;
227
- getConfig(force?: boolean): Promise<PublicConfig>;
228
- /** Returns a valid visitor session, creating or refreshing it when needed. */
229
- ensureSession(): Promise<SessionResponse>;
230
- private createSession;
231
- forgetSession(): void;
232
- history(agent: string, conversationId: string): Promise<HistoryMessage[]>;
233
- /** Sends a message and calls `onEvent` for every streamed event. Resolves when the run ends. */
234
- chat(input: ChatRequestBody & {
235
- agent: string;
236
- conversationId: string;
237
- }, onEvent: (e: ChatStreamEvent) => void, signal?: AbortSignal): Promise<void>;
238
- }
239
-
240
348
  type Doc = Document;
241
349
  declare function renderMarkdown(doc: Doc, src: string): DocumentFragment;
242
350
 
@@ -250,4 +358,4 @@ declare global {
250
358
  }
251
359
  }
252
360
 
253
- export { type ActionCallStatus, type ActionCallView, type ActionConfirmHook, type ActionEventDetail, type ActionResult, type ActionResultStatus, ActionSensitivity, ApiClient, type ApiClientOptions, ApiError, ChatRequestBody, ChatStreamEvent, type DeweeChatConfig, DeweeChatElement, HistoryMessage, type JsonSchema, type PageAction, type PageActionContext, type PageActionInfo, PublicConfig, SessionResponse, defineDeweeChat, mount, renderMarkdown };
361
+ export { type ActionCallStatus, type ActionCallView, type ActionConfirmHook, type ActionEventDetail, type ActionResult, type ActionResultStatus, ActionSensitivity, ApiClient, type ApiClientOptions, ApiError, ChatRequestBody, ChatStreamEvent, type DeweeChatConfig, DeweeChatElement, HistoryMessage, type JsonSchema, LinkResponse, type PageAction, type PageActionContext, type PageActionInfo, PublicConfig, RESERVED_HEADERS, Remediation, type RequestHeadersOption, SessionResponse, defineDeweeChat, mount, renderMarkdown };
package/dist/index.js CHANGED
@@ -2,15 +2,17 @@ import {
2
2
  ApiClient,
3
3
  ApiError,
4
4
  DeweeChatElement,
5
+ RESERVED_HEADERS,
5
6
  defineDeweeChat,
6
7
  mount,
7
8
  renderMarkdown
8
- } from "./chunk-YV6PXYJZ.js";
9
- import "./chunk-JX6AH37X.js";
9
+ } from "./chunk-7WT3JK64.js";
10
+ import "./chunk-USXVB3AC.js";
10
11
  export {
11
12
  ApiClient,
12
13
  ApiError,
13
14
  DeweeChatElement,
15
+ RESERVED_HEADERS,
14
16
  defineDeweeChat,
15
17
  mount,
16
18
  renderMarkdown