@agents24/client 0.2.0 → 0.2.2

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/README.md CHANGED
@@ -1,24 +1,33 @@
1
1
  # `@agents24/client`
2
2
 
3
- Last Updated: 2026-07-19
3
+ Last Updated: 2026-08-12
4
4
 
5
5
  Framework-neutral end-user runtime client for one deployment-scoped Agents24 Agent. It supports public client sessions, authenticated streaming, durable reconnect, threads, attachments, HITL, and MCP without accepting organization API keys.
6
6
 
7
7
  The root package uses structural capabilities and resolves without DOM or Node declarations. Runtime adapter subpaths provide verified global-capability bindings. The canonical wire validators and SSE parser are exported from `@agents24/client/protocol`.
8
8
 
9
- Persistent refresh grants require DPoP and an explicit storage adapter. `createFencedRefreshCoordinator` accepts an atomic compare-and-swap store for cross-tab refresh rotation; lease takeovers retain the server idempotency operation ID and stale owners cannot write rotated credentials. Access tokens remain memory-only.
9
+ Persistent refresh grants require DPoP plus durable credential and refresh-fence storage. In browsers, `createBrowserSessionPersistence(...)` provides the complete IndexedDB-backed persistence set, including fenced cross-tab refresh coordination. `createFencedRefreshCoordinator` remains available for non-browser adapters with an atomic compare-and-swap store. Access tokens remain memory-only.
10
10
 
11
11
  Allowlisted host headers can be carried through `chat.stream` and durable `runs.attach`; authentication, DPoP, Origin, cache, content-type, and idempotency headers remain client-owned and cannot be overridden.
12
12
 
13
13
  ## Browser quickstart
14
14
 
15
15
  ```ts
16
- import { createAnonymousSessionProvider } from "@agents24/client";
17
- import { createBrowserAgentClient } from "@agents24/client/browser";
16
+ import { createAnonymousSessionProvider, createWebCryptoDpopKeyProvider } from "@agents24/client";
17
+ import { createBrowserAgentClient, createBrowserSessionPersistence } from "@agents24/client/browser";
18
18
 
19
19
  const baseUrl = "https://api.agents24.example";
20
20
  const deploymentId = "public-deployment-id";
21
- const sessionProvider = createAnonymousSessionProvider({ baseUrl, deploymentId });
21
+ const persistence = createBrowserSessionPersistence({ namespace: `${baseUrl}:${deploymentId}` });
22
+ const dpopKeyProvider = createWebCryptoDpopKeyProvider({ storage: persistence.dpopKeyStorage });
23
+ const sessionProvider = createAnonymousSessionProvider({
24
+ baseUrl,
25
+ deploymentId,
26
+ persistent: true,
27
+ dpopKeyProvider,
28
+ storage: persistence.sessionStorage,
29
+ coordinator: persistence.refreshCoordinator,
30
+ });
22
31
  const client = createBrowserAgentClient({ baseUrl, deploymentId, sessionProvider });
23
32
 
24
33
  await client.chat.stream({ input: "Hello" }, (event) => {
@@ -26,13 +35,32 @@ await client.chat.stream({ input: "Hello" }, (event) => {
26
35
  });
27
36
  ```
28
37
 
38
+ The browser adapter stores the rotating refresh grant, non-extractable WebCrypto key, and refresh fence in IndexedDB. It coordinates reloads and concurrent tabs so only the canonical rotated grant is used. Once enrollment or refresh rotation starts, it finishes persisting the replacement credential even if the initiating React request is disposed. Access tokens remain memory-only. Namespace persistence by both API origin and deployment ID so credentials cannot collide across environments.
39
+
29
40
  Use `createManagedSessionProvider` when a trusted backend mints a session after authenticating the user. The backend must derive the subject from its own session and accept only deployment-registered origins/native profiles. Use `createHostedOidcSessionProvider` for hosted Authorization Code + PKCE. Organization keys, raw customer identities, tenant IDs, Agent/version choices, and fixed credential bindings never belong in client runtime requests.
30
41
 
31
- The client also exposes threads, thread-summary events, run attach/cancel, attachments, HITL resume, MCP authorization, refresh, and revoke. Aborting a stream detaches locally; call `client.runs.cancel` for durable cancellation.
42
+ The client also exposes threads, thread-summary events, run attach/cancel, attachments, HITL resume, MCP authorization, refresh, and revoke. Bootstrap V2 exposes the exact resolved Agent's canonical `features.inputs` and model default. `client.attachments.uploadBatch(...)` uploads one turn's selected items atomically and returns all attachment records. `client.attachments.createContentAccess({ attachmentId, disposition })` returns a private inline-render or direct-download URL valid for at most five minutes and never beyond payload expiry. Aborting a stream detaches locally; call `client.runs.cancel` for durable cancellation.
43
+
44
+ Agent questions resume through the existing HITL method:
45
+
46
+ ```ts
47
+ await client.hitl.resume({
48
+ runId,
49
+ interruptId,
50
+ action: "respond",
51
+ answers: [{
52
+ question_id: "framework",
53
+ selected_option_ids: ["react"],
54
+ }],
55
+ idempotencyKey,
56
+ });
57
+ ```
58
+
59
+ For a single-choice question, send exactly one listed option or `custom_text` for Other, not both. Multi-select questions may combine them. Reattach to the same run after a successful or idempotent resolution.
32
60
 
33
61
  ## Same-origin BFF
34
62
 
35
- `@agents24/client/bff` exposes `createBffAgentClient({ basePath })`, an `AgentClient` implementation for a customer-owned same-origin BFF. It covers the complete chat lifecycle, uses same-origin credentials, and accepts only an absolute path such as `/api/agents24`. Pair it with `createAgents24BffHandler` from `@agents24/node/bff`; use `npm create agents24-app@latest` for the complete React/Vite setup.
63
+ `@agents24/client/bff` exposes `createBffAgentClient({ basePath })`, an `AgentClient` implementation for a customer-owned same-origin BFF. It covers the complete chat lifecycle, uses same-origin credentials, reconnects with the last durable cursor, and reuses caller idempotency keys for mutations. It accepts only an absolute path such as `/api/agents24`. Pair it with `createAgents24BffHandler` from `@agents24/node/bff`; use `npm create agents24-app@latest` for the complete React/Vite setup.
36
64
 
37
65
  `compatibility.json` contains the exact generated contract hash, protocol versions, peers, and target operation counts. Do not infer compatibility from semver alone.
38
66
 
@@ -48,4 +76,4 @@ The client also exposes threads, thread-summary events, run attach/cancel, attac
48
76
  | Tauri 2 and Expo iOS/Android | Experimental and unverified; no support claim |
49
77
  | Bare React Native/Metro | Experimental compile-only; packed iOS and Android bundles pass |
50
78
 
51
- Run the maintained non-UI gates with `pnpm check:bun`, `pnpm check:deno`, `pnpm check:service-worker`, `pnpm check:electron`, and `pnpm check:metro`. Every gate installs an `npm pack` artifact rather than a workspace link.
79
+ Run the maintained non-UI gates with `pnpm check:bun`, `pnpm check:deno`, `pnpm check:service-worker`, and `pnpm check:metro`. Every gate installs an `npm pack` artifact rather than a workspace link. Electron runs only when the client package changes and is outside release admission.
@@ -1,5 +1,5 @@
1
1
  {
2
- "contractHash": "90a64d2df2facc3c4510edc7a0762cb86a336578667d3bc6cfeb7ae035133e00",
2
+ "contractHash": "a409af6996d10a8d94e0f6332c9a381c3535a9c8511314b6c42b237d7e057029",
3
3
  "contractVersion": "0.2.0",
4
4
  "corpus": "conformance/v1/corpus.json",
5
5
  "generatedBy": "@agents24/sdk-contract",
@@ -15,11 +15,11 @@
15
15
  "reactDom": ">=19 <20"
16
16
  },
17
17
  "@agents24/client": {
18
- "contract": "90a64d2df2facc3c4510edc7a0762cb86a336578667d3bc6cfeb7ae035133e00",
19
- "runtime": "run-stream.v2"
18
+ "contract": "a409af6996d10a8d94e0f6332c9a381c3535a9c8511314b6c42b237d7e057029",
19
+ "runtime": "run-stream.v3"
20
20
  },
21
21
  "@agents24/node": {
22
- "contract": "90a64d2df2facc3c4510edc7a0762cb86a336578667d3bc6cfeb7ae035133e00",
22
+ "contract": "a409af6996d10a8d94e0f6332c9a381c3535a9c8511314b6c42b237d7e057029",
23
23
  "node": "^22.0.0 || ^24.0.0"
24
24
  },
25
25
  "@agents24/react": {
@@ -27,18 +27,18 @@
27
27
  "react": ">=19 <20"
28
28
  },
29
29
  "@talmudpedia/runtime-sdk": {
30
- "contract": "90a64d2df2facc3c4510edc7a0762cb86a336578667d3bc6cfeb7ae035133e00",
30
+ "contract": "a409af6996d10a8d94e0f6332c9a381c3535a9c8511314b6c42b237d7e057029",
31
31
  "protocolOwner": "@agents24/client"
32
32
  },
33
33
  "agents24": {
34
- "contract": "90a64d2df2facc3c4510edc7a0762cb86a336578667d3bc6cfeb7ae035133e00",
34
+ "contract": "a409af6996d10a8d94e0f6332c9a381c3535a9c8511314b6c42b237d7e057029",
35
35
  "python": ">=3.10"
36
36
  }
37
37
  },
38
38
  "protocols": {
39
39
  "runtime": {
40
40
  "minimum": "2.0.0",
41
- "wire": "run-stream.v2"
41
+ "wire": "run-stream.v3"
42
42
  },
43
43
  "threadSummary": {
44
44
  "minimum": "1.0.0",
@@ -47,8 +47,8 @@
47
47
  },
48
48
  "schemaVersion": "agents24.compatibility.v1",
49
49
  "targetOperationCounts": {
50
- "client": 19,
51
- "node": 60,
52
- "python": 55
50
+ "client": 22,
51
+ "node": 79,
52
+ "python": 70
53
53
  }
54
54
  }
@@ -1,3 +1,85 @@
1
- import type { AgentClient, Agents24ClientOptions } from "../types.js";
1
+ import type { DpopKeyHandleStorage } from "../dpop.js";
2
+ import type { AgentClient, Agents24ClientOptions, ClientSessionStorage, SessionRefreshCoordinator } from "../types.js";
2
3
  export declare const runtimeAdapter: "browser";
4
+ type RequestLike<T> = {
5
+ error?: unknown;
6
+ result: T;
7
+ onsuccess: (() => void) | null;
8
+ onerror: (() => void) | null;
9
+ };
10
+ type OpenRequestLike = RequestLike<DatabaseLike> & {
11
+ onupgradeneeded: (() => void) | null;
12
+ };
13
+ type ObjectStoreLike = {
14
+ delete(key: string): RequestLike<unknown>;
15
+ get(key: string): RequestLike<unknown>;
16
+ put(value: unknown, key: string): RequestLike<unknown>;
17
+ };
18
+ type TransactionLike = {
19
+ error?: unknown;
20
+ objectStore(name: string): ObjectStoreLike;
21
+ oncomplete: (() => void) | null;
22
+ onabort: (() => void) | null;
23
+ onerror: (() => void) | null;
24
+ };
25
+ type DatabaseLike = {
26
+ close(): void;
27
+ createObjectStore(name: string): unknown;
28
+ objectStoreNames: {
29
+ contains(name: string): boolean;
30
+ };
31
+ transaction(name: string, mode: "readonly" | "readwrite"): TransactionLike;
32
+ };
33
+ type IndexedDatabaseLike = {
34
+ open(name: string, version: number): OpenRequestLike;
35
+ };
36
+ export type BrowserSessionPersistenceOptions = {
37
+ databaseName?: string;
38
+ indexedDatabase?: IndexedDatabaseLike;
39
+ namespace: string;
40
+ };
41
+ export type BrowserSessionPersistence = {
42
+ dpopKeyStorage: DpopKeyHandleStorage;
43
+ refreshCoordinator: SessionRefreshCoordinator;
44
+ sessionStorage: ClientSessionStorage;
45
+ };
46
+ export declare function createBrowserSessionPersistence(options: BrowserSessionPersistenceOptions): BrowserSessionPersistence;
3
47
  export declare function createBrowserAgentClient(options: Agents24ClientOptions): AgentClient;
48
+ export type BrowserDeploymentIdentityState = "loading" | "guest" | "authenticated" | "signed_out" | "error";
49
+ export type BrowserDeploymentSessionSnapshot = {
50
+ identity: {
51
+ state: BrowserDeploymentIdentityState;
52
+ displayName?: string;
53
+ secondaryText?: string;
54
+ };
55
+ authModes: readonly string[];
56
+ error?: string;
57
+ };
58
+ type BrowserStorageLike = {
59
+ getItem(key: string): string | null;
60
+ setItem(key: string, value: string): void;
61
+ removeItem(key: string): void;
62
+ };
63
+ export type BrowserDeploymentSessionControllerOptions = {
64
+ deploymentId: string;
65
+ baseUrl?: string;
66
+ fetch?: Agents24ClientOptions["fetch"];
67
+ sessionStorage?: BrowserStorageLike;
68
+ getLocationHref?: () => string;
69
+ navigate?: (url: string) => void;
70
+ replaceLocation?: (url: string) => void;
71
+ persistence?: {
72
+ anonymous: BrowserSessionPersistence;
73
+ oidc: BrowserSessionPersistence;
74
+ };
75
+ };
76
+ export type BrowserDeploymentSessionController = {
77
+ client: AgentClient;
78
+ getSnapshot(): BrowserDeploymentSessionSnapshot;
79
+ subscribe(listener: () => void): () => void;
80
+ initialize(): Promise<void>;
81
+ signIn(): Promise<void>;
82
+ signOut(): Promise<void>;
83
+ };
84
+ export declare function createBrowserDeploymentSessionController(options: BrowserDeploymentSessionControllerOptions): BrowserDeploymentSessionController;
85
+ export {};
@@ -1,13 +1,312 @@
1
- import { createAgents24Client } from '../chunk-QAIOKNUK.js';
2
- import '../chunk-SCZMUBXD.js';
3
- import '../chunk-NGZUJ3YT.js';
1
+ import { createFencedRefreshCoordinator, createWebCryptoDpopKeyProvider, createAnonymousSessionProvider, createHostedOidcSessionProvider, createPkcePair } from '../chunk-ZDLWNALI.js';
2
+ import { createAgents24Client } from '../chunk-DEXGPNLL.js';
3
+ import '../chunk-LG3ZMQ2W.js';
4
+ import '../chunk-FLTCOJZR.js';
4
5
 
5
6
  // src/adapters/browser.ts
6
7
  var runtimeAdapter = "browser";
8
+ var STORE_NAME = "runtime";
9
+ function requestResult(request) {
10
+ return new Promise((resolve, reject) => {
11
+ request.onsuccess = () => resolve(request.result);
12
+ request.onerror = () => reject(request.error instanceof Error ? request.error : new Error("Browser storage request failed."));
13
+ });
14
+ }
15
+ function transactionDone(transaction) {
16
+ return new Promise((resolve, reject) => {
17
+ transaction.oncomplete = () => resolve();
18
+ const fail = () => reject(transaction.error instanceof Error ? transaction.error : new Error("Browser storage transaction failed."));
19
+ transaction.onabort = fail;
20
+ transaction.onerror = fail;
21
+ });
22
+ }
23
+ function resolveIndexedDatabase(injected) {
24
+ const value = injected ?? globalThis.indexedDB;
25
+ if (!value) throw new Error("Persistent browser sessions require IndexedDB.");
26
+ return value;
27
+ }
28
+ async function openDatabase(options) {
29
+ const request = resolveIndexedDatabase(options.indexedDatabase).open(
30
+ options.databaseName || "agents24-client",
31
+ 1
32
+ );
33
+ request.onupgradeneeded = () => {
34
+ if (!request.result.objectStoreNames.contains(STORE_NAME)) request.result.createObjectStore(STORE_NAME);
35
+ };
36
+ return requestResult(request);
37
+ }
38
+ function createRecordStorage(options, suffix) {
39
+ const key = `${options.namespace}:${suffix}`;
40
+ return {
41
+ async load() {
42
+ const database = await openDatabase(options);
43
+ try {
44
+ const transaction = database.transaction(STORE_NAME, "readonly");
45
+ const value = await requestResult(transaction.objectStore(STORE_NAME).get(key));
46
+ return value ?? null;
47
+ } finally {
48
+ database.close();
49
+ }
50
+ },
51
+ async save(value) {
52
+ const database = await openDatabase(options);
53
+ try {
54
+ const transaction = database.transaction(STORE_NAME, "readwrite");
55
+ transaction.objectStore(STORE_NAME).put(value, key);
56
+ await transactionDone(transaction);
57
+ } finally {
58
+ database.close();
59
+ }
60
+ },
61
+ async clear() {
62
+ const database = await openDatabase(options);
63
+ try {
64
+ const transaction = database.transaction(STORE_NAME, "readwrite");
65
+ transaction.objectStore(STORE_NAME).delete(key);
66
+ await transactionDone(transaction);
67
+ } finally {
68
+ database.close();
69
+ }
70
+ }
71
+ };
72
+ }
73
+ function createRefreshFenceStorage(options) {
74
+ const key = `${options.namespace}:refresh-fence`;
75
+ return {
76
+ async load() {
77
+ const database = await openDatabase(options);
78
+ try {
79
+ const transaction = database.transaction(STORE_NAME, "readonly");
80
+ const value = await requestResult(transaction.objectStore(STORE_NAME).get(key));
81
+ return value ?? null;
82
+ } finally {
83
+ database.close();
84
+ }
85
+ },
86
+ async compareAndSwap(expectedFence, next) {
87
+ const database = await openDatabase(options);
88
+ try {
89
+ const transaction = database.transaction(STORE_NAME, "readwrite");
90
+ const store = transaction.objectStore(STORE_NAME);
91
+ const current = await requestResult(store.get(key));
92
+ if ((current?.fence ?? null) !== expectedFence) {
93
+ await transactionDone(transaction);
94
+ return false;
95
+ }
96
+ store.put(next, key);
97
+ await transactionDone(transaction);
98
+ return true;
99
+ } finally {
100
+ database.close();
101
+ }
102
+ }
103
+ };
104
+ }
105
+ function createBrowserSessionPersistence(options) {
106
+ const sessionStorage = createRecordStorage(options, "session");
107
+ const dpopKeyStorage = createRecordStorage(options, "dpop-key");
108
+ const refreshCoordinator = createFencedRefreshCoordinator({
109
+ storage: createRefreshFenceStorage(options)
110
+ });
111
+ return { sessionStorage, dpopKeyStorage, refreshCoordinator };
112
+ }
7
113
  function createBrowserAgentClient(options) {
8
114
  return createAgents24Client(options);
9
115
  }
116
+ var DEFAULT_API_BASE_URL = "https://api.agents24.dev";
117
+ function createBrowserDeploymentSessionController(options) {
118
+ const baseUrl = String(options.baseUrl || DEFAULT_API_BASE_URL).replace(/\/+$/, "");
119
+ const namespace = `${baseUrl}:${options.deploymentId}`;
120
+ const anonymousPersistence = options.persistence?.anonymous ?? createBrowserSessionPersistence({ namespace: `${namespace}:anonymous` });
121
+ const oidcPersistence = options.persistence?.oidc ?? createBrowserSessionPersistence({ namespace: `${namespace}:oidc` });
122
+ const anonymousDpop = createWebCryptoDpopKeyProvider({ storage: anonymousPersistence.dpopKeyStorage });
123
+ const oidcDpop = createWebCryptoDpopKeyProvider({ storage: oidcPersistence.dpopKeyStorage });
124
+ const anonymousProvider = createAnonymousSessionProvider({
125
+ baseUrl,
126
+ deploymentId: options.deploymentId,
127
+ ...options.fetch ? { fetch: options.fetch } : {},
128
+ dpopKeyProvider: anonymousDpop,
129
+ persistent: true,
130
+ coordinator: anonymousPersistence.refreshCoordinator,
131
+ storage: anonymousPersistence.sessionStorage
132
+ });
133
+ const oidcProvider = createHostedOidcSessionProvider({
134
+ baseUrl,
135
+ deploymentId: options.deploymentId,
136
+ ...options.fetch ? { fetch: options.fetch } : {},
137
+ dpopKeyProvider: oidcDpop,
138
+ coordinator: oidcPersistence.refreshCoordinator,
139
+ storage: oidcPersistence.sessionStorage
140
+ });
141
+ let activeProvider;
142
+ const awaitActiveProvider = async () => {
143
+ if (!activeProvider) await initialize();
144
+ if (!activeProvider) throw new Error("The browser deployment session could not be initialized.");
145
+ return activeProvider;
146
+ };
147
+ const delegatingProvider = {
148
+ async getAccess(context) {
149
+ return (await awaitActiveProvider()).getAccess(context);
150
+ },
151
+ async refresh(context) {
152
+ const provider = await awaitActiveProvider();
153
+ if (!provider.refresh) throw new Error("Session refresh is unavailable.");
154
+ return provider.refresh(context);
155
+ },
156
+ async revoke(input) {
157
+ return (await awaitActiveProvider()).revoke?.(input);
158
+ }
159
+ };
160
+ const client = createBrowserAgentClient({
161
+ baseUrl,
162
+ deploymentId: options.deploymentId,
163
+ sessionProvider: delegatingProvider,
164
+ ...options.fetch ? { fetch: options.fetch } : {}
165
+ });
166
+ const listeners = /* @__PURE__ */ new Set();
167
+ let bootstrap;
168
+ let snapshot = {
169
+ identity: { state: "loading" },
170
+ authModes: []
171
+ };
172
+ let initializing;
173
+ const pkceKey = `${namespace}:oidc-return`;
174
+ const browserStorage = () => {
175
+ const value = options.sessionStorage ?? globalThis.sessionStorage;
176
+ if (!value) throw new Error("OIDC sign-in requires browser sessionStorage.");
177
+ return value;
178
+ };
179
+ const locationHref = () => options.getLocationHref?.() ?? globalThis.location?.href ?? "";
180
+ const publish = (next) => {
181
+ snapshot = next;
182
+ listeners.forEach((listener) => listener());
183
+ };
184
+ const modes = () => [...bootstrap?.authentication.modes ?? []];
185
+ const failure = (message) => publish({ identity: { state: "error", secondaryText: message }, authModes: modes(), error: message });
186
+ const cleanCallbackUrl = (href) => {
187
+ const url = new URL(href);
188
+ url.searchParams.delete("code");
189
+ return url.toString();
190
+ };
191
+ const readPkceState = () => {
192
+ const raw = browserStorage().getItem(pkceKey);
193
+ if (!raw) return null;
194
+ try {
195
+ const value = JSON.parse(raw);
196
+ if (!value.verifier || !value.redirectUri || !value.returnUrl || !value.createdAt) return null;
197
+ if (Date.now() - value.createdAt > 10 * 60 * 1e3) return null;
198
+ return value;
199
+ } catch {
200
+ return null;
201
+ }
202
+ };
203
+ const finishCallback = async (code) => {
204
+ const state = readPkceState();
205
+ if (!state) {
206
+ browserStorage().removeItem(pkceKey);
207
+ throw new Error("The OIDC callback is missing valid local PKCE state.");
208
+ }
209
+ const currentOrigin = new URL(locationHref()).origin;
210
+ if (new URL(state.returnUrl).origin !== currentOrigin) throw new Error("The OIDC return location is invalid.");
211
+ await oidcProvider.exchange({ code, codeVerifier: state.verifier });
212
+ browserStorage().removeItem(pkceKey);
213
+ activeProvider = oidcProvider;
214
+ if (options.replaceLocation) options.replaceLocation(state.returnUrl);
215
+ else globalThis.history?.replaceState(null, "", state.returnUrl);
216
+ publish({ identity: { state: "authenticated", displayName: "Signed in" }, authModes: modes() });
217
+ };
218
+ const initialize = async () => {
219
+ if (initializing) return initializing;
220
+ initializing = (async () => {
221
+ publish({ identity: { state: "loading" }, authModes: [] });
222
+ try {
223
+ bootstrap = await client.bootstrap();
224
+ const authModes = modes();
225
+ const href = locationHref();
226
+ const callbackCode = href ? new URL(href).searchParams.get("code") : null;
227
+ if (callbackCode) {
228
+ if (!authModes.includes("external_oidc")) throw new Error("This deployment does not allow OIDC authentication.");
229
+ await finishCallback(callbackCode);
230
+ return;
231
+ }
232
+ if (href && new URL(href).searchParams.has("code")) throw new Error("The OIDC callback code is malformed.");
233
+ if (authModes.includes("external_oidc") && await oidcPersistence.sessionStorage.load()) {
234
+ activeProvider = oidcProvider;
235
+ await oidcProvider.getAccess({ reason: "request" });
236
+ publish({ identity: { state: "authenticated", displayName: "Signed in" }, authModes });
237
+ return;
238
+ }
239
+ if (authModes.includes("anonymous")) {
240
+ activeProvider = anonymousProvider;
241
+ publish({ identity: { state: "guest", displayName: "Guest" }, authModes });
242
+ return;
243
+ }
244
+ if (authModes.includes("external_oidc")) {
245
+ activeProvider = oidcProvider;
246
+ publish({ identity: { state: "signed_out" }, authModes });
247
+ return;
248
+ }
249
+ failure("Backend exchange requires a host integration and cannot run as a direct browser app.");
250
+ } catch (error) {
251
+ const href = locationHref();
252
+ const callbackPending = Boolean(href && new URL(href).searchParams.has("code"));
253
+ if (!callbackPending && modes().includes("anonymous")) {
254
+ activeProvider = anonymousProvider;
255
+ publish({ identity: { state: "guest", displayName: "Guest" }, authModes: modes() });
256
+ } else {
257
+ failure(error instanceof Error ? error.message : "The browser deployment session could not be initialized.");
258
+ }
259
+ }
260
+ })().finally(() => {
261
+ initializing = void 0;
262
+ });
263
+ return initializing;
264
+ };
265
+ return {
266
+ client,
267
+ getSnapshot: () => snapshot,
268
+ subscribe(listener) {
269
+ listeners.add(listener);
270
+ return () => listeners.delete(listener);
271
+ },
272
+ initialize,
273
+ async signIn() {
274
+ if (!bootstrap) await initialize();
275
+ if (!modes().includes("external_oidc")) throw new Error("This deployment does not allow OIDC sign-in.");
276
+ const href = locationHref();
277
+ if (!href) throw new Error("OIDC sign-in requires a browser location.");
278
+ const returnUrl = cleanCallbackUrl(href);
279
+ const redirect = new URL(returnUrl);
280
+ redirect.search = "";
281
+ const redirectUri = redirect.toString();
282
+ const pkce = await createPkcePair();
283
+ browserStorage().setItem(pkceKey, JSON.stringify({ verifier: pkce.verifier, redirectUri, returnUrl, createdAt: Date.now() }));
284
+ publish({ identity: { state: "loading" }, authModes: modes() });
285
+ try {
286
+ const authorization = await oidcProvider.beginAuthorization({ redirectUri, codeChallenge: pkce.challenge });
287
+ if (options.navigate) options.navigate(authorization.authorizationUrl);
288
+ else globalThis.location?.assign(authorization.authorizationUrl);
289
+ } catch (error) {
290
+ browserStorage().removeItem(pkceKey);
291
+ failure(error instanceof Error ? error.message : "OIDC sign-in could not start.");
292
+ throw error;
293
+ }
294
+ },
295
+ async signOut() {
296
+ publish({ identity: { state: "loading" }, authModes: modes() });
297
+ await oidcProvider.revoke?.();
298
+ browserStorage().removeItem(pkceKey);
299
+ if (modes().includes("anonymous")) {
300
+ activeProvider = anonymousProvider;
301
+ publish({ identity: { state: "guest", displayName: "Guest" }, authModes: modes() });
302
+ } else {
303
+ activeProvider = oidcProvider;
304
+ publish({ identity: { state: "signed_out" }, authModes: modes() });
305
+ }
306
+ }
307
+ };
308
+ }
10
309
 
11
- export { createBrowserAgentClient, runtimeAdapter };
310
+ export { createBrowserAgentClient, createBrowserDeploymentSessionController, createBrowserSessionPersistence, runtimeAdapter };
12
311
  //# sourceMappingURL=browser.js.map
13
312
  //# sourceMappingURL=browser.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/adapters/browser.ts"],"names":[],"mappings":";;;;;AAGO,IAAM,cAAA,GAAiB;AAEvB,SAAS,yBAAyB,OAAA,EAA6C;AACpF,EAAA,OAAO,qBAAqB,OAAO,CAAA;AACrC","file":"browser.js","sourcesContent":["import { createAgents24Client } from \"../client.js\";\nimport type { AgentClient, Agents24ClientOptions } from \"../types.js\";\n\nexport const runtimeAdapter = \"browser\" as const;\n\nexport function createBrowserAgentClient(options: Agents24ClientOptions): AgentClient {\n return createAgents24Client(options);\n}\n"]}
1
+ {"version":3,"sources":["../../src/adapters/browser.ts"],"names":[],"mappings":"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","file":"browser.js","sourcesContent":["import { createAgents24Client } from \"../client.js\";\nimport { createPkcePair, createWebCryptoDpopKeyProvider } from \"../dpop.js\";\nimport type { DpopKeyHandle, DpopKeyHandleStorage } from \"../dpop.js\";\nimport {\n createAnonymousSessionProvider,\n createFencedRefreshCoordinator,\n createHostedOidcSessionProvider,\n} from \"../sessions.js\";\nimport type {\n AgentClient,\n Agents24ClientOptions,\n ClientSessionStorage,\n ClientSessionStorageRecord,\n ClientSessionProvider,\n ClientBootstrap,\n SessionRefreshCoordinator,\n SessionRefreshFenceRecord,\n SessionRefreshFenceStorage,\n} from \"../types.js\";\n\nexport const runtimeAdapter = \"browser\" as const;\n\ntype RequestLike<T> = {\n error?: unknown;\n result: T;\n onsuccess: (() => void) | null;\n onerror: (() => void) | null;\n};\n\ntype OpenRequestLike = RequestLike<DatabaseLike> & {\n onupgradeneeded: (() => void) | null;\n};\n\ntype ObjectStoreLike = {\n delete(key: string): RequestLike<unknown>;\n get(key: string): RequestLike<unknown>;\n put(value: unknown, key: string): RequestLike<unknown>;\n};\n\ntype TransactionLike = {\n error?: unknown;\n objectStore(name: string): ObjectStoreLike;\n oncomplete: (() => void) | null;\n onabort: (() => void) | null;\n onerror: (() => void) | null;\n};\n\ntype DatabaseLike = {\n close(): void;\n createObjectStore(name: string): unknown;\n objectStoreNames: { contains(name: string): boolean };\n transaction(name: string, mode: \"readonly\" | \"readwrite\"): TransactionLike;\n};\n\ntype IndexedDatabaseLike = {\n open(name: string, version: number): OpenRequestLike;\n};\n\nexport type BrowserSessionPersistenceOptions = {\n databaseName?: string;\n indexedDatabase?: IndexedDatabaseLike;\n namespace: string;\n};\n\nconst STORE_NAME = \"runtime\";\n\nfunction requestResult<T>(request: RequestLike<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error instanceof Error ? request.error : new Error(\"Browser storage request failed.\"));\n });\n}\n\nfunction transactionDone(transaction: TransactionLike): Promise<void> {\n return new Promise((resolve, reject) => {\n transaction.oncomplete = () => resolve();\n const fail = () => reject(transaction.error instanceof Error ? transaction.error : new Error(\"Browser storage transaction failed.\"));\n transaction.onabort = fail;\n transaction.onerror = fail;\n });\n}\n\nfunction resolveIndexedDatabase(injected?: IndexedDatabaseLike): IndexedDatabaseLike {\n const value = injected ?? (globalThis as unknown as { indexedDB?: IndexedDatabaseLike }).indexedDB;\n if (!value) throw new Error(\"Persistent browser sessions require IndexedDB.\");\n return value;\n}\n\nasync function openDatabase(options: BrowserSessionPersistenceOptions): Promise<DatabaseLike> {\n const request = resolveIndexedDatabase(options.indexedDatabase).open(\n options.databaseName || \"agents24-client\",\n 1,\n );\n request.onupgradeneeded = () => {\n if (!request.result.objectStoreNames.contains(STORE_NAME)) request.result.createObjectStore(STORE_NAME);\n };\n return requestResult(request);\n}\n\nfunction createRecordStorage<T>(options: BrowserSessionPersistenceOptions, suffix: string) {\n const key = `${options.namespace}:${suffix}`;\n return {\n async load(): Promise<T | null> {\n const database = await openDatabase(options);\n try {\n const transaction = database.transaction(STORE_NAME, \"readonly\");\n const value = await requestResult(transaction.objectStore(STORE_NAME).get(key));\n return (value as T | undefined) ?? null;\n } finally {\n database.close();\n }\n },\n async save(value: T): Promise<void> {\n const database = await openDatabase(options);\n try {\n const transaction = database.transaction(STORE_NAME, \"readwrite\");\n transaction.objectStore(STORE_NAME).put(value, key);\n await transactionDone(transaction);\n } finally {\n database.close();\n }\n },\n async clear(): Promise<void> {\n const database = await openDatabase(options);\n try {\n const transaction = database.transaction(STORE_NAME, \"readwrite\");\n transaction.objectStore(STORE_NAME).delete(key);\n await transactionDone(transaction);\n } finally {\n database.close();\n }\n },\n };\n}\n\nfunction createRefreshFenceStorage(\n options: BrowserSessionPersistenceOptions,\n): SessionRefreshFenceStorage {\n const key = `${options.namespace}:refresh-fence`;\n return {\n async load(): Promise<SessionRefreshFenceRecord | null> {\n const database = await openDatabase(options);\n try {\n const transaction = database.transaction(STORE_NAME, \"readonly\");\n const value = await requestResult(transaction.objectStore(STORE_NAME).get(key));\n return (value as SessionRefreshFenceRecord | undefined) ?? null;\n } finally {\n database.close();\n }\n },\n async compareAndSwap(\n expectedFence: number | null,\n next: SessionRefreshFenceRecord,\n ): Promise<boolean> {\n const database = await openDatabase(options);\n try {\n const transaction = database.transaction(STORE_NAME, \"readwrite\");\n const store = transaction.objectStore(STORE_NAME);\n const current = await requestResult(store.get(key)) as SessionRefreshFenceRecord | undefined;\n if ((current?.fence ?? null) !== expectedFence) {\n await transactionDone(transaction);\n return false;\n }\n store.put(next, key);\n await transactionDone(transaction);\n return true;\n } finally {\n database.close();\n }\n },\n };\n}\n\nexport type BrowserSessionPersistence = {\n dpopKeyStorage: DpopKeyHandleStorage;\n refreshCoordinator: SessionRefreshCoordinator;\n sessionStorage: ClientSessionStorage;\n};\n\nexport function createBrowserSessionPersistence(options: BrowserSessionPersistenceOptions): BrowserSessionPersistence {\n const sessionStorage = createRecordStorage<ClientSessionStorageRecord>(options, \"session\");\n const dpopKeyStorage = createRecordStorage<DpopKeyHandle>(options, \"dpop-key\");\n const refreshCoordinator = createFencedRefreshCoordinator({\n storage: createRefreshFenceStorage(options),\n });\n return { sessionStorage, dpopKeyStorage, refreshCoordinator };\n}\n\nexport function createBrowserAgentClient(options: Agents24ClientOptions): AgentClient {\n return createAgents24Client(options);\n}\n\nexport type BrowserDeploymentIdentityState =\n | \"loading\"\n | \"guest\"\n | \"authenticated\"\n | \"signed_out\"\n | \"error\";\n\nexport type BrowserDeploymentSessionSnapshot = {\n identity: {\n state: BrowserDeploymentIdentityState;\n displayName?: string;\n secondaryText?: string;\n };\n authModes: readonly string[];\n error?: string;\n};\n\ntype BrowserStorageLike = {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n};\n\nexport type BrowserDeploymentSessionControllerOptions = {\n deploymentId: string;\n baseUrl?: string;\n fetch?: Agents24ClientOptions[\"fetch\"];\n sessionStorage?: BrowserStorageLike;\n getLocationHref?: () => string;\n navigate?: (url: string) => void;\n replaceLocation?: (url: string) => void;\n persistence?: {\n anonymous: BrowserSessionPersistence;\n oidc: BrowserSessionPersistence;\n };\n};\n\nexport type BrowserDeploymentSessionController = {\n client: AgentClient;\n getSnapshot(): BrowserDeploymentSessionSnapshot;\n subscribe(listener: () => void): () => void;\n initialize(): Promise<void>;\n signIn(): Promise<void>;\n signOut(): Promise<void>;\n};\n\ntype PkceReturnState = {\n verifier: string;\n redirectUri: string;\n returnUrl: string;\n createdAt: number;\n};\n\nconst DEFAULT_API_BASE_URL = \"https://api.agents24.dev\";\n\nexport function createBrowserDeploymentSessionController(\n options: BrowserDeploymentSessionControllerOptions,\n): BrowserDeploymentSessionController {\n const baseUrl = String(options.baseUrl || DEFAULT_API_BASE_URL).replace(/\\/+$/, \"\");\n const namespace = `${baseUrl}:${options.deploymentId}`;\n const anonymousPersistence = options.persistence?.anonymous ?? createBrowserSessionPersistence({ namespace: `${namespace}:anonymous` });\n const oidcPersistence = options.persistence?.oidc ?? createBrowserSessionPersistence({ namespace: `${namespace}:oidc` });\n const anonymousDpop = createWebCryptoDpopKeyProvider({ storage: anonymousPersistence.dpopKeyStorage });\n const oidcDpop = createWebCryptoDpopKeyProvider({ storage: oidcPersistence.dpopKeyStorage });\n const anonymousProvider = createAnonymousSessionProvider({\n baseUrl,\n deploymentId: options.deploymentId,\n ...(options.fetch ? { fetch: options.fetch } : {}),\n dpopKeyProvider: anonymousDpop,\n persistent: true,\n coordinator: anonymousPersistence.refreshCoordinator,\n storage: anonymousPersistence.sessionStorage,\n });\n const oidcProvider = createHostedOidcSessionProvider({\n baseUrl,\n deploymentId: options.deploymentId,\n ...(options.fetch ? { fetch: options.fetch } : {}),\n dpopKeyProvider: oidcDpop,\n coordinator: oidcPersistence.refreshCoordinator,\n storage: oidcPersistence.sessionStorage,\n });\n let activeProvider: ClientSessionProvider | undefined;\n const awaitActiveProvider = async (): Promise<ClientSessionProvider> => {\n if (!activeProvider) await initialize();\n if (!activeProvider) throw new Error(\"The browser deployment session could not be initialized.\");\n return activeProvider;\n };\n const delegatingProvider: ClientSessionProvider = {\n async getAccess(context) {\n return (await awaitActiveProvider()).getAccess(context);\n },\n async refresh(context) {\n const provider = await awaitActiveProvider();\n if (!provider.refresh) throw new Error(\"Session refresh is unavailable.\");\n return provider.refresh(context);\n },\n async revoke(input) {\n return (await awaitActiveProvider()).revoke?.(input);\n },\n };\n const client = createBrowserAgentClient({\n baseUrl,\n deploymentId: options.deploymentId,\n sessionProvider: delegatingProvider,\n ...(options.fetch ? { fetch: options.fetch } : {}),\n });\n const listeners = new Set<() => void>();\n let bootstrap: ClientBootstrap | undefined;\n let snapshot: BrowserDeploymentSessionSnapshot = {\n identity: { state: \"loading\" },\n authModes: [],\n };\n let initializing: Promise<void> | undefined;\n const pkceKey = `${namespace}:oidc-return`;\n\n const browserStorage = (): BrowserStorageLike => {\n const value = options.sessionStorage ?? (globalThis as unknown as { sessionStorage?: BrowserStorageLike }).sessionStorage;\n if (!value) throw new Error(\"OIDC sign-in requires browser sessionStorage.\");\n return value;\n };\n const locationHref = () => options.getLocationHref?.() ?? (globalThis as unknown as { location?: { href?: string } }).location?.href ?? \"\";\n const publish = (next: BrowserDeploymentSessionSnapshot) => {\n snapshot = next;\n listeners.forEach((listener) => listener());\n };\n const modes = () => [...(bootstrap?.authentication.modes ?? [])];\n const failure = (message: string) => publish({ identity: { state: \"error\", secondaryText: message }, authModes: modes(), error: message });\n const cleanCallbackUrl = (href: string): string => {\n const url = new URL(href);\n url.searchParams.delete(\"code\");\n return url.toString();\n };\n const readPkceState = (): PkceReturnState | null => {\n const raw = browserStorage().getItem(pkceKey);\n if (!raw) return null;\n try {\n const value = JSON.parse(raw) as Partial<PkceReturnState>;\n if (!value.verifier || !value.redirectUri || !value.returnUrl || !value.createdAt) return null;\n if (Date.now() - value.createdAt > 10 * 60 * 1000) return null;\n return value as PkceReturnState;\n } catch {\n return null;\n }\n };\n const finishCallback = async (code: string) => {\n const state = readPkceState();\n if (!state) {\n browserStorage().removeItem(pkceKey);\n throw new Error(\"The OIDC callback is missing valid local PKCE state.\");\n }\n const currentOrigin = new URL(locationHref()).origin;\n if (new URL(state.returnUrl).origin !== currentOrigin) throw new Error(\"The OIDC return location is invalid.\");\n await oidcProvider.exchange({ code, codeVerifier: state.verifier });\n browserStorage().removeItem(pkceKey);\n activeProvider = oidcProvider;\n if (options.replaceLocation) options.replaceLocation(state.returnUrl);\n else (globalThis as unknown as { history?: { replaceState(data: unknown, unused: string, url?: string): void } }).history?.replaceState(null, \"\", state.returnUrl);\n publish({ identity: { state: \"authenticated\", displayName: \"Signed in\" }, authModes: modes() });\n };\n\n const initialize = async () => {\n if (initializing) return initializing;\n initializing = (async () => {\n publish({ identity: { state: \"loading\" }, authModes: [] });\n try {\n bootstrap = await client.bootstrap();\n const authModes = modes();\n const href = locationHref();\n const callbackCode = href ? new URL(href).searchParams.get(\"code\") : null;\n if (callbackCode) {\n if (!authModes.includes(\"external_oidc\")) throw new Error(\"This deployment does not allow OIDC authentication.\");\n await finishCallback(callbackCode);\n return;\n }\n if (href && new URL(href).searchParams.has(\"code\")) throw new Error(\"The OIDC callback code is malformed.\");\n if (authModes.includes(\"external_oidc\") && await oidcPersistence.sessionStorage.load()) {\n activeProvider = oidcProvider;\n await oidcProvider.getAccess({ reason: \"request\" });\n publish({ identity: { state: \"authenticated\", displayName: \"Signed in\" }, authModes });\n return;\n }\n if (authModes.includes(\"anonymous\")) {\n activeProvider = anonymousProvider;\n publish({ identity: { state: \"guest\", displayName: \"Guest\" }, authModes });\n return;\n }\n if (authModes.includes(\"external_oidc\")) {\n activeProvider = oidcProvider;\n publish({ identity: { state: \"signed_out\" }, authModes });\n return;\n }\n failure(\"Backend exchange requires a host integration and cannot run as a direct browser app.\");\n } catch (error) {\n const href = locationHref();\n const callbackPending = Boolean(href && new URL(href).searchParams.has(\"code\"));\n if (!callbackPending && modes().includes(\"anonymous\")) {\n activeProvider = anonymousProvider;\n publish({ identity: { state: \"guest\", displayName: \"Guest\" }, authModes: modes() });\n } else {\n failure(error instanceof Error ? error.message : \"The browser deployment session could not be initialized.\");\n }\n }\n })().finally(() => { initializing = undefined; });\n return initializing;\n };\n\n return {\n client,\n getSnapshot: () => snapshot,\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n initialize,\n async signIn() {\n if (!bootstrap) await initialize();\n if (!modes().includes(\"external_oidc\")) throw new Error(\"This deployment does not allow OIDC sign-in.\");\n const href = locationHref();\n if (!href) throw new Error(\"OIDC sign-in requires a browser location.\");\n const returnUrl = cleanCallbackUrl(href);\n const redirect = new URL(returnUrl);\n redirect.search = \"\";\n const redirectUri = redirect.toString();\n const pkce = await createPkcePair();\n browserStorage().setItem(pkceKey, JSON.stringify({ verifier: pkce.verifier, redirectUri, returnUrl, createdAt: Date.now() } satisfies PkceReturnState));\n publish({ identity: { state: \"loading\" }, authModes: modes() });\n try {\n const authorization = await oidcProvider.beginAuthorization({ redirectUri, codeChallenge: pkce.challenge });\n if (options.navigate) options.navigate(authorization.authorizationUrl);\n else (globalThis as unknown as { location?: { assign(url: string): void } }).location?.assign(authorization.authorizationUrl);\n } catch (error) {\n browserStorage().removeItem(pkceKey);\n failure(error instanceof Error ? error.message : \"OIDC sign-in could not start.\");\n throw error;\n }\n },\n async signOut() {\n publish({ identity: { state: \"loading\" }, authModes: modes() });\n await oidcProvider.revoke?.();\n browserStorage().removeItem(pkceKey);\n if (modes().includes(\"anonymous\")) {\n activeProvider = anonymousProvider;\n publish({ identity: { state: \"guest\", displayName: \"Guest\" }, authModes: modes() });\n } else {\n activeProvider = oidcProvider;\n publish({ identity: { state: \"signed_out\" }, authModes: modes() });\n }\n },\n };\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { createAgents24Client } from '../chunk-QAIOKNUK.js';
2
- import '../chunk-SCZMUBXD.js';
3
- import '../chunk-NGZUJ3YT.js';
1
+ import { createAgents24Client } from '../chunk-DEXGPNLL.js';
2
+ import '../chunk-LG3ZMQ2W.js';
3
+ import '../chunk-FLTCOJZR.js';
4
4
 
5
5
  // src/adapters/cloudflare.ts
6
6
  var runtimeAdapter = "cloudflare";
@@ -1,6 +1,6 @@
1
- import { createAgents24Client } from '../chunk-QAIOKNUK.js';
2
- import '../chunk-SCZMUBXD.js';
3
- import '../chunk-NGZUJ3YT.js';
1
+ import { createAgents24Client } from '../chunk-DEXGPNLL.js';
2
+ import '../chunk-LG3ZMQ2W.js';
3
+ import '../chunk-FLTCOJZR.js';
4
4
 
5
5
  // src/adapters/node.ts
6
6
  var runtimeAdapter = "node";
@@ -1,6 +1,6 @@
1
- import { createAgents24Client } from '../chunk-QAIOKNUK.js';
2
- import '../chunk-SCZMUBXD.js';
3
- import '../chunk-NGZUJ3YT.js';
1
+ import { createAgents24Client } from '../chunk-DEXGPNLL.js';
2
+ import '../chunk-LG3ZMQ2W.js';
3
+ import '../chunk-FLTCOJZR.js';
4
4
 
5
5
  // src/adapters/worker.ts
6
6
  var runtimeAdapter = "worker";