agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
142 lines (141 loc) • 7.05 kB
TypeScript
/**
* agentCoreBrowser — AWS Bedrock AgentCore **Browser** as a {@link BrowserRunner}.
*
* A managed Chrome in AWS's account that an agent can drive, a person can watch
* live, and — the part this adapter exists for — a person can TAKE OVER
* mid-session and hand back.
*
* ── Two channels, and only one of them is here ───────────────────────────────
* A browser session has two doors, and confusing them wastes a day:
*
* 1. **The automation stream** — a CDP WebSocket. Navigate, find an element,
* fill a form: everything page-shaped happens here, driven by Playwright
* or another CDP client. This adapter hands you
* {@link BrowserSession.automationEndpoint} and stays out of the way. It
* does not depend on Playwright and does not drive the page for you.
* 2. **`InvokeBrowser`** — the data-plane operation this adapter calls. It is
* OS-LEVEL input ABOVE the page: mouse, keyboard, screenshots. Its action
* union, read off the SDK rather than remembered, is exactly
* `mouseClick | mouseMove | mouseDrag | mouseScroll | keyType | keyPress |
* keyShortcut | screenshot`. **There is no navigate action**, and a reader
* expecting one is looking at the wrong door.
*
* ── The takeover ─────────────────────────────────────────────────────────────
* `UpdateBrowserStream` with `automationStreamUpdate.streamStatus` set to
* `DISABLED` stops the automation channel and leaves the live-view user in
* control; `ENABLED` gives it back. That is `handControlTo('person' | 'agent')`
* here, and it composes with this library's check-in: the agent pauses, a
* person finishes the login, the agent resumes on the page they left — and both
* handovers are ordinary events in the trace.
*
* ── How this talks to the SDK (the 9.4.0 law) ────────────────────────────────
* Through `client.send(new SomeCommand(input))`, never a method on the client —
* a bare `@aws-sdk/client-*` Client carries `send` and `destroy` and nothing
* else. Every command name and request shape below was read off a real install
* of `@aws-sdk/client-bedrock-agentcore` **3.1118.0**, including the action
* union above and `ScreenshotResult`'s `{ status, error?, data? }`.
*
* ── One documented contradiction, left as AWS wrote it ───────────────────────
* The devguide says a session defaults to 15 minutes; `StartBrowserSession`'s
* API reference says 3600 seconds. This adapter sends nothing unless you pass
* `sessionTimeoutSeconds`, so the default is whatever the service applies —
* rather than this file picking a side in somebody else's disagreement.
*
* Pattern: Adapter (GoF) + lazy peer-dep load — the SDK is required only when
* `start()` first runs, or never, if you inject `_client` / `_sdk`.
*/
import type { BrowserRunner } from '../../provider-contract/types.js';
/** AWS's managed browser. A custom `CreateBrowser` resource id goes here instead. */
export declare const AWS_SYSTEM_BROWSER = "aws.browser.v1";
export interface AgentCoreBrowserOptions {
/** AWS region. Falls back to the SDK's own resolution when omitted. */
readonly region?: string;
/** Which browser resource. Default {@link AWS_SYSTEM_BROWSER}. */
readonly browserIdentifier?: string;
/**
* Session lifetime in seconds. **Left unset by default on purpose** — AWS's
* own devguide (15 minutes) and API reference (3600 seconds) disagree, so
* sending nothing lets the service apply whichever it actually means.
*/
readonly sessionTimeoutSeconds?: number;
/** Viewport for the session, when you want one that is not the default. */
readonly viewport?: {
readonly width: number;
readonly height: number;
};
/** Stable runner id (default `'agentcore-browser'`). */
readonly id?: string;
/** Test seam — inject a client implementing {@link AgentCoreBrowserClientLike}. */
readonly _client?: AgentCoreBrowserClientLike;
/** @internal Test injection — the AWS SDK module. */
readonly _sdk?: BedrockAgentCoreBrowserSdkModule;
}
/** The operation-semantic surface this adapter calls. */
export interface AgentCoreBrowserClientLike {
startBrowserSession(input: {
readonly browserIdentifier: string;
readonly name?: string;
readonly sessionTimeoutSeconds?: number;
readonly viewPort?: {
readonly width: number;
readonly height: number;
};
}): Promise<{
readonly sessionId?: string;
readonly streams?: {
readonly automationStream?: {
readonly streamEndpoint?: string;
};
readonly liveViewStream?: {
readonly streamEndpoint?: string;
};
};
}>;
invokeBrowser(input: {
readonly browserIdentifier: string;
readonly sessionId: string;
readonly action: Readonly<Record<string, unknown>>;
}): Promise<{
readonly result?: Readonly<Record<string, unknown>>;
}>;
updateBrowserStream(input: {
readonly browserIdentifier: string;
readonly sessionId: string;
readonly streamUpdate: {
readonly automationStreamUpdate: {
readonly streamStatus: 'ENABLED' | 'DISABLED';
};
};
}): Promise<void>;
stopBrowserSession(input: {
readonly browserIdentifier: string;
readonly sessionId: string;
}): Promise<void>;
}
/** The slice of `@aws-sdk/client-bedrock-agentcore` this shim touches. */
export interface BedrockAgentCoreBrowserSdkModule {
readonly BedrockAgentCoreClient?: new (config: {
region?: string;
}) => {
send(cmd: unknown): Promise<unknown>;
};
readonly StartBrowserSessionCommand?: new (input: unknown) => unknown;
readonly InvokeBrowserCommand?: new (input: unknown) => unknown;
readonly UpdateBrowserStreamCommand?: new (input: unknown) => unknown;
readonly StopBrowserSessionCommand?: new (input: unknown) => unknown;
}
/**
* Build a {@link BrowserRunner} backed by AgentCore Browser.
*
* @example A session, a person taking over, and the agent resuming
* const browser = agentCoreBrowser({ region: 'us-east-1' });
* const session = await browser.start({ key: toolSessionKey(ctx, 'run') });
*
* // Page work goes over CDP, not through this adapter:
* // const page = await chromium.connectOverCDP(session.automationEndpoint!)
*
* await session.handControlTo?.('person'); // they finish the login
* await session.handControlTo?.('agent'); // and the agent carries on
* await session.stop();
*/
export declare function agentCoreBrowser(options?: AgentCoreBrowserOptions): BrowserRunner;