@qoniai/qoni 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -4,18 +4,6 @@ declare function buildStringToSign(method: string, pathname: string, headers: He
4
4
  declare function buildSignature(secretKey: string, stringToSign: string): string;
5
5
  declare function buildAuthorization(accessKey: string, secretKey: string, stringToSign: string): string;
6
6
 
7
- /**
8
- * The interaction `type` discriminator — the single field a consumer
9
- * switches on to pick a card / typed handle.
10
- */
11
- declare const InteractionTypes: {
12
- readonly SiteLogin: "site_login";
13
- readonly Clarification: "clarification";
14
- readonly Confirmation: "confirmation";
15
- readonly TakeControl: "take_control";
16
- readonly Wait: "wait";
17
- };
18
- type InteractionType = (typeof InteractionTypes)[keyof typeof InteractionTypes];
19
7
  /**
20
8
  * Interaction lifecycle status (backend-authoritative):
21
9
  * pending → active → resolved | expired | canceled.
@@ -172,8 +160,15 @@ interface DelegateTokenInteractiveInput extends DelegateTokenBaseInput {
172
160
  mode: "interactive";
173
161
  redirectUri: string;
174
162
  state: string;
163
+ /**
164
+ * @deprecated The authorization page identifies the signed-in user; the
165
+ * delegation service ignores a user sent with an interactive request.
166
+ */
175
167
  user?: UserRef;
176
- /** Alternative to user.id; optional for interactive authorization. */
168
+ /**
169
+ * @deprecated The authorization page identifies the signed-in user; the
170
+ * delegation service ignores a user id sent with an interactive request.
171
+ */
177
172
  userId?: string;
178
173
  }
179
174
  type DelegateTokenInput = DelegateTokenSilentInput | DelegateTokenInteractiveInput;
@@ -197,6 +192,10 @@ interface DelegateTokenResponse {
197
192
  expiresIn: number;
198
193
  grantId: string;
199
194
  auditId: string;
195
+ /**
196
+ * @deprecated The delegation service does not return the granted scopes.
197
+ * Read them from `qoni.genauth.introspectDelegationToken({ token }).data.scope`.
198
+ */
200
199
  grantedScopes?: string[];
201
200
  }
202
201
  type DelegateTokenSilentResponse = DelegateTokenResponse & {
@@ -281,6 +280,29 @@ interface QoniTransport {
281
280
  * button/method only exists when the backend declared the action (structurally
282
281
  * closing off "dead recovery affordances").
283
282
  */
283
+ /**
284
+ * The interaction types a consumer handles. DoAnything asks for the user in
285
+ * five abstract ways — by what the user has to do, never by business — plus
286
+ * the system `wait`:
287
+ *
288
+ * - `site_login`: sign in to a site in the live browser.
289
+ * - `take_control`: operate the browser by hand (captcha, 2FA, …).
290
+ * - `ask_user`: answer a question, shaped by `answerType` / `options`.
291
+ * - `confirmation`: allow or reject an action.
292
+ * - `wait`: the system is waiting (rate limit, external event); no decision.
293
+ *
294
+ * The wire may still say `clarification`; the SDK presents it as `ask_user`.
295
+ */
296
+ declare const InteractionTypes: {
297
+ readonly SiteLogin: "site_login";
298
+ readonly TakeControl: "take_control";
299
+ readonly AskUser: "ask_user";
300
+ readonly Confirmation: "confirmation";
301
+ readonly Wait: "wait";
302
+ /** @deprecated `clarification` is presented as `ask_user`; use `InteractionTypes.AskUser`. */
303
+ readonly Clarification: "ask_user";
304
+ };
305
+ type InteractionType = "site_login" | "take_control" | "ask_user" | "confirmation" | "wait";
284
306
  /** A declared action a consumer can take on an interaction. */
285
307
  interface Action {
286
308
  /** What this action does — maps to a typed method on {@link InteractionHandle}. */
@@ -309,11 +331,26 @@ interface SiteLoginPayload {
309
331
  /** Set when the login is for a Track monitor (monitor.needs_login reuse). */
310
332
  monitorId?: string;
311
333
  }
312
- interface ClarificationPayload {
313
- question: string;
314
- /** Hint for how the answer should be collected (e.g. "text", "choice"). */
315
- inputType?: string;
334
+ /** How an `ask_user` answer is shaped; decides which control the app renders. */
335
+ type AskUserAnswerType = "text" | "number" | "boolean" | "single_choice" | "multiple_choice";
336
+ interface AskUserOption {
337
+ /** What `answer()` submits. */
338
+ value: string;
339
+ /** What the user sees. */
340
+ label: string;
316
341
  }
342
+ interface AskUserPayload {
343
+ /** The question to show the user. */
344
+ question: string;
345
+ /** `text` → string, `number` → number, `boolean` → boolean, `single_choice` → one option value, `multiple_choice` → option values. */
346
+ answerType: AskUserAnswerType;
347
+ /** Candidates for `single_choice` / `multiple_choice`. */
348
+ options?: AskUserOption[];
349
+ }
350
+ /** An `ask_user` answer; its type follows the payload's `answerType`. */
351
+ type AskUserAnswer = string | number | boolean | string[];
352
+ /** @deprecated `clarification` is presented as `ask_user`; use {@link AskUserPayload}. */
353
+ type ClarificationPayload = AskUserPayload;
317
354
  interface ConfirmationPayload {
318
355
  summary: string;
319
356
  }
@@ -332,21 +369,15 @@ interface WaitPayload {
332
369
  /** Maps each interaction `type` to its narrowed payload shape. */
333
370
  interface InteractionPayloadByType {
334
371
  site_login: SiteLoginPayload;
335
- clarification: ClarificationPayload;
336
- confirmation: ConfirmationPayload;
337
372
  take_control: TakeControlPayload;
373
+ ask_user: AskUserPayload;
374
+ confirmation: ConfirmationPayload;
338
375
  wait: WaitPayload;
339
376
  }
340
- /**
341
- * A typed interaction object. Generic over `type` so the `payload` narrows to
342
- * the matching shape; the bare `Interaction` (T = InteractionType) is the union
343
- * a consumer switches on.
344
- */
345
- interface Interaction<T extends InteractionType = InteractionType> {
377
+ /** Fields every interaction carries, whatever its type. */
378
+ interface InteractionBase {
346
379
  /** Stable identity across the interaction's lifecycle. */
347
380
  id: string;
348
- /** The discriminator — the single field a consumer switches on. */
349
- type: T;
350
381
  /** Backend-authoritative lifecycle status. */
351
382
  status: InteractionStatus;
352
383
  createdAt: string;
@@ -360,9 +391,20 @@ interface Interaction<T extends InteractionType = InteractionType> {
360
391
  evidence?: InteractionEvidence | null;
361
392
  /** Declared actions — drives the typed methods + UI buttons. */
362
393
  actions: Action[];
394
+ }
395
+ /**
396
+ * A typed interaction object, distributed over `type`: the bare `Interaction`
397
+ * is a union, so `switch (interaction.type)` narrows `payload` in each branch.
398
+ * `Interaction<"site_login">` picks one member.
399
+ */
400
+ type Interaction<T extends InteractionType = InteractionType> = T extends InteractionType ? InteractionBase & {
401
+ /** The discriminator — the single field a consumer switches on. */
402
+ type: T;
363
403
  /** Type-specific fields. */
364
404
  payload: InteractionPayloadByType[T];
365
- }
405
+ } : never;
406
+ /** The interaction union `onInteraction` hands out; same as the bare {@link Interaction}. */
407
+ type TypedInteraction = Interaction;
366
408
  /**
367
409
  * Posts an interaction action to its declared endpoint. The product namespace
368
410
  * supplies this (token + run addressing already bound); the handle below uses
@@ -392,9 +434,13 @@ interface OpenLoginResult {
392
434
  /** Unmodified response body (escape hatch — shape may evolve with the API). */
393
435
  raw: JsonObject;
394
436
  /**
437
+ * @deprecated {@link InteractionHandle.confirmSignedIn} saves the login
438
+ * itself; call it once the user has signed in, without `confirm()`.
439
+ *
395
440
  * Persist the login into the profile after the user signs in
396
441
  * (`POST /profiles/{profileId}/confirm`). Confirming ends this login
397
- * session and closes its browser, whatever the outcome:
442
+ * session and closes its browser, except when the backend could not save
443
+ * it yet (`release_failed`, below):
398
444
  *
399
445
  * - `active: true` — the login is saved; call
400
446
  * {@link InteractionHandle.confirmSignedIn}.
@@ -407,9 +453,13 @@ interface OpenLoginResult {
407
453
  * already ended on providers that report it this way, or the profile no
408
454
  * longer exists for this user. Handle it like `no_session`: call
409
455
  * `confirmSignedIn()`, and the agent asks again if it is still signed out.
456
+ * - `active: false` with `probeResult: "release_failed"` — the backend kept
457
+ * the session but could not save it yet; call `confirm()` again.
410
458
  * - `active: false` with any other `probeResult` — the user was not signed
411
459
  * in. Start a new session with `openLogin({ siteId, profileId })` and show
412
460
  * its new `liveUrl`; the old one no longer works.
461
+ * - Throws `QoniValidationError` when a newer `openLogin()` replaced this
462
+ * backend session; confirm the newer result instead.
413
463
  *
414
464
  * Requires `QoniScopes.SITE_LOGIN_CONFIRM`.
415
465
  */
@@ -432,6 +482,44 @@ interface ConfirmLoginResult {
432
482
  /** Unmodified response body (escape hatch — shape may evolve with the API). */
433
483
  raw: JsonObject;
434
484
  }
485
+ /** A login session `openLogin()` opened on one interaction. */
486
+ interface LoginSession {
487
+ profileId: string;
488
+ siteId: string;
489
+ /** The backend's login session; reopening may return the same one. */
490
+ sessionId: string;
491
+ /** Latest `openLogin()` call on the interaction that returned it (1, 2, …). */
492
+ call: number;
493
+ /** A newer backend session took over: this one can no longer be saved. */
494
+ replaced?: boolean;
495
+ /** Saved and rechecked: nothing left to do for this session. */
496
+ completed?: boolean;
497
+ /** The save in flight or done; cleared when it fails so a retry saves again. */
498
+ save?: Promise<ConfirmLoginResult>;
499
+ /** `confirmSignedIn()` in flight or done: one save and one recheck per session. */
500
+ done?: Promise<void>;
501
+ }
502
+ /** Per interaction: how many `openLogin()` calls were made, and the session of the latest call that succeeded. */
503
+ interface LoginSessionSlot {
504
+ calls: number;
505
+ /** `openLogin()` calls still waiting for the backend. */
506
+ inflight: number;
507
+ /** The interaction settled (resolved, expired or canceled): nothing will confirm this login any more. */
508
+ ended?: boolean;
509
+ session?: LoginSession;
510
+ }
511
+ /** Login sessions by interaction id, shared by the handles one RunHandle / MonitorHandle hands out. */
512
+ type LoginSessionStore = Map<string, LoginSessionSlot>;
513
+ /** A control session returned by `connectControl()` / `refreshControl()`. */
514
+ interface ControlSession {
515
+ /** Signed URL of the browser the user now controls; show it only to that user. */
516
+ liveUrl: string;
517
+ /** When `liveUrl` stops working; call `refreshControl()` for a new one. */
518
+ expiresAt?: string;
519
+ status?: string;
520
+ /** Unmodified response body (escape hatch — shape may evolve with the API). */
521
+ raw: JsonObject;
522
+ }
435
523
  /**
436
524
  * Typed wrapper over an {@link Interaction} that exposes one method per
437
525
  * action kind. Each method finds the matching declared action and posts to its
@@ -442,16 +530,28 @@ interface ConfirmLoginResult {
442
530
  declare class InteractionHandle<T extends InteractionType = InteractionType> {
443
531
  #private;
444
532
  private readonly post;
533
+ private readonly loginSessions;
445
534
  readonly interaction: Interaction<T>;
446
- constructor(interaction: Interaction<T>, post: InteractionActionPoster);
535
+ /**
536
+ * @param loginSessions Login sessions opened on interactions, by interaction
537
+ * id. A RunHandle / MonitorHandle shares one store across the handles it
538
+ * hands out, so `confirmSignedIn()` finds the login `openLogin()` opened
539
+ * even on the handle of a later event.
540
+ */
541
+ constructor(interaction: Interaction<T>, post: InteractionActionPoster, loginSessions?: LoginSessionStore);
447
542
  get id(): string;
448
543
  get type(): T;
449
544
  get status(): InteractionStatus;
450
545
  get actions(): Action[];
451
546
  /** Whether the backend declared an action of this kind on the interaction. */
452
547
  can(kind: ActionKind): boolean;
453
- /** Answer a clarification ask. */
454
- answer(text: string): Promise<void>;
548
+ /**
549
+ * Answer an `ask_user` question. The value follows `payload.answerType`:
550
+ * `text` → string, `number` → number, `boolean` → boolean, `single_choice` →
551
+ * one option `value`, `multiple_choice` → an array of option values. A value
552
+ * that does not fit throws `QoniValidationError` before anything is sent.
553
+ */
554
+ answer(value: AskUserAnswer): Promise<void>;
455
555
  /** Skip / dismiss the interaction (proceed without acting on it). */
456
556
  skip(): Promise<void>;
457
557
  /** Confirm a pending confirmation (approve the plan / destructive op). */
@@ -462,18 +562,29 @@ declare class InteractionHandle<T extends InteractionType = InteractionType> {
462
562
  * Start an interactive login session for a `site_login` interaction. The
463
563
  * backend needs the site to sign in to: pass `siteId`, or omit it when the
464
564
  * interaction lists exactly one site. Show `liveUrl` to the user; when they
465
- * finish, call `confirm()` on the result to save the login, and act on its
466
- * outcome (see {@link OpenLoginResult.confirm}) before {@link confirmSignedIn}.
565
+ * say they are signed in, call {@link confirmSignedIn}, which saves the login
566
+ * and lets the agent continue.
467
567
  * The delegation must include `QoniScopes.SITE_LOGIN_REQUEST` and
468
568
  * `QoniScopes.SITE_LOGIN_CONFIRM`; the AccessKey policy must allow both.
469
569
  */
470
570
  openLogin(options?: OpenLoginOptions): Promise<OpenLoginResult>;
471
- /** Tell the agent the user has finished signing in. */
571
+ /**
572
+ * The user finished signing in through the live browser `openLogin()`
573
+ * opened. Saves that login (so later tasks reuse it), then tells the agent
574
+ * to recheck the site and continue. If the user is not signed in after all,
575
+ * the agent raises a new `site_login` interaction.
576
+ *
577
+ * Saving needs `QoniScopes.SITE_LOGIN_CONFIRM` on the delegation; without
578
+ * `openLogin()` on this interaction, only the recheck is sent.
579
+ */
472
580
  confirmSignedIn(): Promise<void>;
473
- /** Connect to the live browser for a take_control interaction. */
474
- connectControl(): Promise<void>;
475
- /** Refresh the live control surface / live url. */
476
- refreshControl(): Promise<void>;
581
+ /**
582
+ * Take over the live browser for a take_control interaction. Resolves to the
583
+ * signed control URL to show the user (`liveUrl`) and when it expires.
584
+ */
585
+ connectControl(): Promise<ControlSession>;
586
+ /** Get a fresh control URL when the current one expired. */
587
+ refreshControl(): Promise<ControlSession>;
477
588
  /** Hand control back to the agent. */
478
589
  releaseControl(): Promise<void>;
479
590
  /** Retry a wait interaction now. */
@@ -779,7 +890,10 @@ declare class RunHandle<E extends RunEvent = RunEvent> {
779
890
  * Wrap an {@link Interaction} (from `event.data` of an `interaction` event)
780
891
  * in a typed {@link InteractionHandle} bound to this run. The handle's action
781
892
  * methods (`answer` / `confirmSignedIn` / `releaseControl` / …) post to the
782
- * endpoint the backend declared for that action.
893
+ * endpoint the backend declared for that action. Handles this RunHandle
894
+ * hands out share the login sessions `openLogin()` opens, so
895
+ * `confirmSignedIn()` on the handle of a later event still saves that login.
896
+ * A RunHandle from another `attach()` (or process) does not see them.
783
897
  */
784
898
  interactionHandle(interaction: Interaction): InteractionHandle;
785
899
  /**
@@ -1215,6 +1329,7 @@ interface MonitorWireOps {
1215
1329
  * token or an id.
1216
1330
  */
1217
1331
  declare class MonitorHandle {
1332
+ #private;
1218
1333
  private readonly ops;
1219
1334
  readonly id: string;
1220
1335
  constructor(ops: MonitorWireOps, id: string);
@@ -1247,7 +1362,8 @@ declare class MonitorHandle {
1247
1362
  * Wrap an {@link Interaction} (from `event.data` of an `interaction` event on
1248
1363
  * the monitor stream — e.g. a `site_login` to unlock a `needs_reauth` park)
1249
1364
  * in a typed {@link InteractionHandle}. The handle's action methods post to
1250
- * the endpoint the backend declared for that action.
1365
+ * the endpoint the backend declared for that action. Handles of one
1366
+ * MonitorHandle share the login sessions `openLogin()` opens.
1251
1367
  */
1252
1368
  interactionHandle(interaction: Interaction): InteractionHandle;
1253
1369
  /**
@@ -1479,6 +1595,11 @@ declare const QoniScopes: {
1479
1595
  readonly TRACK_MANAGE: "webagent.track:manage";
1480
1596
  readonly SITE_LOGIN_REQUEST: "webagent.site_login:request";
1481
1597
  readonly SITE_LOGIN_CONFIRM: "webagent.site_login:confirm";
1598
+ readonly USER_PROFILE_READ: "user.profile:read";
1599
+ readonly USER_PROFILE_WRITE: "user.profile:write";
1600
+ readonly USER_PAYMENT_USE: "user.payment:use";
1601
+ readonly AGENT_MAIL_READ: "agent.mail:read";
1602
+ readonly AGENT_MAIL_SEND: "agent.mail:send";
1482
1603
  };
1483
1604
  type QoniScope = (typeof QoniScopes)[keyof typeof QoniScopes];
1484
1605
  /** Product names accepted by `delegateToken({ products })`. */
@@ -1498,4 +1619,4 @@ declare const QoniScopeBundles: {
1498
1619
  readonly TRACK: readonly ["webagent.track:read", "webagent.track:manage"];
1499
1620
  };
1500
1621
 
1501
- export { type Action, type ActionKind, ActionKinds, type Artifact, type BrowserProxyOptions, type BrowserbaseRegion, type CaptureOptions, type ClarificationPayload, type CompleteDelegateAgentInput, type CompleteDelegateTokenInput, type ConfirmLoginOptions, type ConfirmLoginResult, type ConfirmationPayload, type CoreRunEvent, type DeepResearchAttachOptions, type DeepResearchEvent, type DeepResearchRunOptions, type DelegateAgentInput, type DelegateAgentResponse, type DelegateAgentTokenResponse, type DelegateTokenInput, type DelegateTokenInteractiveInput, type DelegateTokenResponse, type DelegateTokenResult, type DelegateTokenSilentInput, type DelegateTokenSilentResponse, type DelegationMode, type DelegationTokenResponse, type DoAnythingAttachOptions, type DoAnythingEvent, type DoAnythingRunOptions, type DoAnythingSnapshot, type GenAuthAccessTokenInput, type GenAuthAdminToken, type GenAuthAdminTokenOverrideInput, type GenAuthDelegationIntrospectionInput, type GenAuthUserCreateBatchInput, type GenAuthUserCreateInput, type GenAuthUserDeleteBatchInput, type GenAuthUserGetBatchInput, type GenAuthUserGetInput, type GenAuthUserListInput, type GenAuthUserUpdateInput, type Interaction, type InteractionEvidence, InteractionHandle, type InteractionPayloadByType, type InteractionSite, type InteractionStatus, InteractionStatuses, type InteractionType, InteractionTypes, type InteractiveDelegationResponse, type JsonObject, type MonitorEvent, type MonitorEventsOptions, MonitorHandle, type MonitorRunsOptions, type OpenLoginOptions, type OpenLoginResult, Qoni, QoniAuthError, QoniDelegationRequiredError, QoniError, type QoniErrorCode, type QoniErrorOptions, type QoniEvent, type QoniEventType, QoniEventTypes, type QoniMeta, type QoniOptions, QoniPermissionDeniedError, type QoniProduct, type QoniProductName, QoniProductScopes, QoniRateLimitError, type QoniResponse, type QoniRuntimeConfig, type QoniSSEEvent, QoniScopeBundles, QoniScopes, QoniTimeoutError, QoniTokenExpiredError, QoniUpstreamError, QoniValidationError, type RawRequestInput, type RunBrowserLiveUrlChangedData, type RunDoneData, type RunEvent, type RunEventsOptions, RunHandle, type RunImage, type RunLimits, type RunMessageData, type RunReconnectInfo, type RunResult, type RunScreenshotData, type RunStatus, type RunWaitOptions, type RuntimeTokenInput, type SessionRef, type SiteLoginPayload, type SnapshotAction, type SnapshotImage, type TakeControlPayload, type TokenInput, type TrackAttachOptions, type TrackCreateOptions, type WaitKind, type WaitPayload, type WebSearchAttachOptions, type WebSearchEvent, type WebSearchRunOptions, buildAuthorization, buildSignature, buildStringToSign };
1622
+ export { type Action, type ActionKind, ActionKinds, type Artifact, type AskUserAnswer, type AskUserAnswerType, type AskUserOption, type AskUserPayload, type BrowserProxyOptions, type BrowserbaseRegion, type CaptureOptions, type ClarificationPayload, type CompleteDelegateAgentInput, type CompleteDelegateTokenInput, type ConfirmLoginOptions, type ConfirmLoginResult, type ConfirmationPayload, type ControlSession, type CoreRunEvent, type DeepResearchAttachOptions, type DeepResearchEvent, type DeepResearchRunOptions, type DelegateAgentInput, type DelegateAgentResponse, type DelegateAgentTokenResponse, type DelegateTokenInput, type DelegateTokenInteractiveInput, type DelegateTokenResponse, type DelegateTokenResult, type DelegateTokenSilentInput, type DelegateTokenSilentResponse, type DelegationMode, type DelegationTokenResponse, type DoAnythingAttachOptions, type DoAnythingEvent, type DoAnythingRunOptions, type DoAnythingSnapshot, type GenAuthAccessTokenInput, type GenAuthAdminToken, type GenAuthAdminTokenOverrideInput, type GenAuthDelegationIntrospectionInput, type GenAuthUserCreateBatchInput, type GenAuthUserCreateInput, type GenAuthUserDeleteBatchInput, type GenAuthUserGetBatchInput, type GenAuthUserGetInput, type GenAuthUserListInput, type GenAuthUserUpdateInput, type Interaction, type InteractionBase, type InteractionEvidence, InteractionHandle, type InteractionPayloadByType, type InteractionSite, type InteractionStatus, InteractionStatuses, type InteractionType, InteractionTypes, type InteractiveDelegationResponse, type JsonObject, type MonitorEvent, type MonitorEventsOptions, MonitorHandle, type MonitorRunsOptions, type OpenLoginOptions, type OpenLoginResult, Qoni, QoniAuthError, QoniDelegationRequiredError, QoniError, type QoniErrorCode, type QoniErrorOptions, type QoniEvent, type QoniEventType, QoniEventTypes, type QoniMeta, type QoniOptions, QoniPermissionDeniedError, type QoniProduct, type QoniProductName, QoniProductScopes, QoniRateLimitError, type QoniResponse, type QoniRuntimeConfig, type QoniSSEEvent, QoniScopeBundles, QoniScopes, QoniTimeoutError, QoniTokenExpiredError, QoniUpstreamError, QoniValidationError, type RawRequestInput, type RunBrowserLiveUrlChangedData, type RunDoneData, type RunEvent, type RunEventsOptions, RunHandle, type RunImage, type RunLimits, type RunMessageData, type RunReconnectInfo, type RunResult, type RunScreenshotData, type RunStatus, type RunWaitOptions, type RuntimeTokenInput, type SessionRef, type SiteLoginPayload, type SnapshotAction, type SnapshotImage, type TakeControlPayload, type TokenInput, type TrackAttachOptions, type TrackCreateOptions, type TypedInteraction, type WaitKind, type WaitPayload, type WebSearchAttachOptions, type WebSearchEvent, type WebSearchRunOptions, buildAuthorization, buildSignature, buildStringToSign };