@adonis-agora/agent
Version:
Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.
119 lines • 5.77 kB
TypeScript
/**
* The host side of a sandbox drawn in a `react-native-webview`, as plain functions: what the
* WebView may load, what it may say, how the host talks back, the theme it gets. No React Native
* import here — the renderer (`sandbox.tsx`) wires these to the WebView, the tests call them as is.
*/
import type { StandardSchemaV1 } from '@standard-schema/spec';
import { type UiAction } from '../../genui/actions.js';
import { type SandboxPolicy } from '../../genui/sandbox.js';
import type { JsonSchema } from '../../genui/schema.js';
import type { SandboxRefusal } from '../../react/core/genui/sandbox.js';
/** Whether a URL is the inline sandbox document itself — everything else is a navigation away. */
export declare function isInlineDocumentUrl(url: unknown): boolean;
/**
* `onShouldStartLoadWithRequest`: the inline document loads, nothing else does — no link, no
* `location = …`, no `window.open`, no `tel:` / `mailto:` / app scheme. (Used with an
* `originWhitelist` that lets every URL through to it: `react-native-webview` hands a URL the
* whitelist refuses to `Linking.openURL` — the system browser or another app — instead of dropping it.)
*/
export declare function shouldStartSandboxLoad(request: {
url?: unknown;
}): boolean;
/** Room for the envelope (`type`, `token`, keys) around a payload in one bridge message. */
export declare const NATIVE_SANDBOX_ENVELOPE_CHARS = 1024;
export type FrameMessage =
/** A message with this frame's token, parsed. */
{
kind: 'message';
data: Record<string, unknown> & {
type: string;
};
}
/** An `agent.send` with this frame's token, too long to even parse (`bytes`: at least). */
| {
kind: 'too-large';
bytes: number;
}
/** Anything else — not a string, too long, not JSON, not an object, no or another token. */
| {
kind: 'drop';
};
/**
* Read one `onMessage` string from the WebView. Its length is capped BEFORE it is parsed (the cap
* is the payload limit plus the envelope: a payload within the limit always fits, as its JSON has at
* most as many UTF-16 units as UTF-8 bytes); only a JSON object carrying `token` and a frame message
* type gets through. A send too long to parse is recognised by its envelope's exact prefix — which
* the bridge writes first — so it is refused as `too-large` rather than dropped unseen.
*/
export declare function parseFrameMessage(raw: unknown, token: string, maxPayloadBytes: number): FrameMessage;
/**
* The script `injectJavaScript` runs to hand the frame one host message: a `message` event whose
* `source` is the frame's own window — its `parent` (a top-level document is its own parent), the
* only source the bridge and the JSX runtime listen to. The message is JSON (as a JS literal; the
* line separators JSON leaves raw are escaped), never code.
*/
export declare function hostMessageScript(message: Record<string, unknown>): string;
/** The frame's height: what it measured, within 24 px and the policy's `maxHeight`. */
export declare function clampSandboxHeight(value: number, policy: SandboxPolicy): number;
/**
* The app's design tokens for the frame — what a web host reads off its page's `:root`. `vars` are
* CSS custom properties (`{ '--primary': '#2563eb' }` or `{ primary: '#2563eb' }`); `dark` sets the
* frame's `dark` class and `data-theme`; `colorScheme` (`'dark'`, `'light dark'`) is mirrored as
* `color-scheme` when given.
*/
export interface NativeSandboxTheme {
vars: Record<string, string>;
dark?: boolean;
colorScheme?: string;
/** Light/dark attributes for the frame's root (`data-theme`, `data-bs-theme`…), as a web host mirrors its own. */
attributes?: Record<string, string>;
}
/** The theme as the frame takes it: `:root{…}`, light/dark, root attributes, Tailwind's `@theme`. */
export interface NativeThemeCss {
css: string;
dark: boolean;
attributes: Record<string, string>;
tailwind: string;
}
/** `vars` keyed `--name` (a bare `name` gets its dashes), invalid names and non-strings dropped. */
export declare function normalizeThemeVars(vars: Record<string, unknown>): Record<string, string>;
export declare function nativeThemeCss(theme: NativeSandboxTheme): NativeThemeCss;
/**
* A url the config names, made absolute against `baseUrl` (React Native has no page origin to
* resolve it against). Only `http:` / `https:` come out; anything else, or a relative url without
* an absolute `baseUrl`, is `undefined`.
*/
export declare function resolveSandboxUrl(url: string, baseUrl: string | undefined): string | undefined;
/** The count and time of the accepted sends of one frame. */
export interface SendState {
count: number;
last: number;
}
export interface SendCheck {
payload: unknown;
state: SendState;
policy: SandboxPolicy;
/** The view is still being written: what it sends is not the user's yet. */
incomplete: boolean;
schema?: StandardSchemaV1 | JsonSchema;
confirm?: (action: UiAction) => boolean | Promise<boolean>;
hasHandler: boolean;
componentId?: string;
title?: string;
now?: number;
}
/**
* Everything the web host checks an `agent.send` for, in its order: a preview's send declined, the
* count, the interval, JSON, the size, `schema`, `confirm`, a handler. The interval clock starts at
* a send that passed the size check; the count grows only for a delivered action.
*/
export declare function checkSandboxSend(check: SendCheck): Promise<{
ok: true;
action: UiAction;
} | {
ok: false;
refusal: SandboxRefusal;
}>;
/** A per-frame token. Not a secret from the frame's own code — it tells this frame's messages apart. */
export declare function sandboxToken(): string;
//# sourceMappingURL=sandbox-host.d.ts.map