/**
 * hosting/browserSession — the client half of a session, for a page.
 *
 * A standing agent remembers a conversation per `sessionId`. Something has to
 * decide what that id IS, and in a browser that is one line:
 *
 *   const sessionId = browserSessionId();
 *   await fetch('/invoke', {
 *     method: 'POST',
 *     headers: { 'content-type': 'application/json', 'x-session-id': sessionId },
 *     body: JSON.stringify({ input: 'hello' }),
 *   });
 *
 * The server half is `nodeHost({ sessionHeader })` (default `'x-session-id'`,
 * so the line above needs no server option at all) or
 * `nodeHost({ sessionCookie })`, which does the same job without any client
 * code — see those options for the trade.
 *
 * ── Why this file imports NOTHING ────────────────────────────────────────────
 * It is the one piece of `hosting/` a browser bundle is meant to contain, and
 * the rest of that folder is Node: `httpHost` dynamically imports `node:http`,
 * `sqliteSessions` reaches `node:sqlite` through `createRequire`. So this file
 * has no imports at all and is exported from the MAIN barrel
 * (`import { browserSessionId } from 'agentfootprint'`) rather than from
 * `agentfootprint/hosting`, which no browser bundle should have to pull in. It
 * lives here, beside the server half it pairs with, so the two cannot drift
 * about which header carries what.
 *
 * Pattern: a plain function. There is no state to own beyond the storage key.
 */
/** Options for {@link browserSessionId}. */
export interface BrowserSessionIdOptions {
    /**
     * Where the id is kept. Default `'agentfootprint.sessionId'`.
     *
     * Change it when one origin serves two different agents that must not share a
     * conversation — two keys, two sessions, one browser.
     */
    readonly storageKey?: string;
}
/** The default `localStorage` key. Named, so a page can clear it deliberately. */
export declare const DEFAULT_SESSION_STORAGE_KEY = "agentfootprint.sessionId";
/**
 * The conversation this browser is having with your agent: minted once, kept,
 * and handed back on every later call.
 *
 * Pass it as `x-session-id` (or in the JSON body as `sessionId`) and a
 * `standingAgent` will hydrate the same conversation on every turn — and, since
 * 9.10.0, scope the agent's memory to it too, with no configuration.
 *
 * ── What it is, and the thing it is NOT ──────────────────────────────────────
 * **A session id is not authentication.** It is a handle the browser carries,
 * and anyone who can reach your host can send any string in its place. Nothing
 * here signs it, and nothing on the server side checks it: authenticate the
 * caller by your own means, then check that the authenticated principal is
 * allowed the session they claimed. Storing anything sensitive under a session
 * id alone is storing it under a value the client controls.
 *
 * ── Where it is kept, and what that costs ────────────────────────────────────
 * `localStorage`, under {@link BrowserSessionIdOptions.storageKey}. That means
 * it survives a reload and a closed tab, is scoped to the ORIGIN, and is
 * readable by any script running on that origin — including one you did not
 * write. It is per browser profile, so the same person on a phone and a laptop
 * is two conversations, and a shared machine is one.
 *
 * When `localStorage` cannot be reached — private mode in some browsers throws
 * on access, and there is no `window` at all during SSR — the id is kept in a
 * module-level `Map` instead. Same id for the life of the page, gone on reload.
 * This is a fallback and it is stated rather than hidden: a page that must
 * survive a reload in private mode needs its own storage.
 *
 * ── How it is minted ─────────────────────────────────────────────────────────
 * `crypto.randomUUID()` where it exists (every current browser, in a secure
 * context), then `crypto.getRandomValues`. Both are unguessable. On a runtime
 * that has NEITHER — an insecure-context page in an older browser — it falls
 * back to `Math.random`, which is **not** unguessable, and that is survivable
 * only because of the paragraph above: this id is a handle, never a credential.
 *
 * @example  A chat page that remembers across reloads
 * ```ts
 * import { browserSessionId } from 'agentfootprint';
 *
 * const sessionId = browserSessionId();
 * const reply = await fetch('/invoke', {
 *   method: 'POST',
 *   headers: { 'content-type': 'application/json', 'x-session-id': sessionId },
 *   body: JSON.stringify({ input: message }),
 * }).then((r) => r.json());
 * ```
 *
 * @example  Two agents on one origin, two conversations
 * ```ts
 * const support = browserSessionId({ storageKey: 'support.sessionId' });
 * const billing = browserSessionId({ storageKey: 'billing.sessionId' });
 * ```
 */
export declare function browserSessionId(options?: BrowserSessionIdOptions): string;
