donobu
Version:
Create browser automations with an LLM agent and replay them as Playwright scripts.
183 lines • 8.31 kB
TypeScript
import { z } from 'zod/v4';
import { type GptClient } from '../../clients/GptClient';
import { DonobuFlow } from '../../managers/DonobuFlow';
import type { DonobuStack } from '../../managers/DonobuStack';
import type { FlowMetadata } from '../../models/FlowMetadata';
import type { DonobuExtendedPage } from '../page/DonobuExtendedPage';
import type { PageAiCache } from './cache/cache';
/**
* Page AI orchestration entry point.
*
* - {@link PageAiRunner} sets up the `DonobuFlow` and keeps the persistence
* layer in sync. It knows nothing about caches.
* - {@link PageAi} glues together the runner with a pluggable cache so that
* consumers (e.g., Playwright fixtures) keep their simple `page.ai.act(...)`
* API while gaining better separation of concerns.
*
* The documentation in this file attempts to guide new contributors through
* the lifecycle of a single `page.ai.act(...)` call: resolve cache -> run flow ->
* persist metadata -> update cache.
*/
type PageAiBaseOptions = {
/**
* Tool names the flow is allowed to invoke. Leave undefined to grant the
* default Donobu tool-set; otherwise the supplied names are merged with the
* minimal bookkeeping tools to form the final allow-list.
*/
allowedTools?: string[];
/**
* Upper bound for how many tool calls the autonomous run may perform before
* aborting. Defaults to `DonobuFlowsManager.DEFAULT_MAX_TOOL_CALLS`.
*/
maxToolCalls?: number;
/**
* Explicit environment variable names (in addition to the heuristically
* derived ones) that the flow may read via `envDataManager.getByNames`.
*/
envVars?: string[];
/**
* Explicitly supply environment variable values that amend (or override)
* the environment observed by this `page.ai` call. Keys are merged with
* any names derived from {@link PageAiBaseOptions.envVars} and from
* `{{$.env.*}}` interpolations in the instruction.
*
* - A `string` value sets or overrides the variable for this invocation.
* - An `undefined` value *removes* the variable, even if it would
* otherwise be resolved from persistence.
*
* Only the **names** (keys) influence the cache key, not the values
* themselves, so changing a value will replay a cached run with the new
* value rather than busting the cache.
*/
envVals?: Record<string, string | undefined>;
/**
* Overrides the GPT client used for this invocation; falls back to the
* client supplied when constructing {@link PageAi}.
*/
gptClient?: GptClient;
/**
* Enables cache lookup/storage for deterministic replays. Defaults to `true`.
* When `false`, runs skip cache reads/writes and options that only influence
* caching ({@link PageAiBaseOptions.volatileElementIds} and
* {@link PageAiBaseOptions.noSelectorFailover}) are ignored.
*/
cache?: boolean;
/**
* Treats ID-only selectors as unstable when persisting cached tool calls,
* causing them to be dropped unless the cache would otherwise lose every
* selector candidate. Ignored when `cache` is `false`.
*/
volatileElementIds?: boolean;
/**
* Keeps only the most specific selector when preparing cached tool calls,
* effectively disabling selector fail-over during replays. Ignored when
* `cache` is `false`.
*/
noSelectorFailover?: boolean;
};
export type PageAiSchemaOptions<Schema extends z.ZodObject> = PageAiBaseOptions & {
schema: Schema;
};
export type PageAiNoSchemaOptions = PageAiBaseOptions & {
schema?: undefined;
};
export type PageAiOptions<Schema extends z.ZodObject | undefined = undefined> = Schema extends z.ZodObject ? PageAiSchemaOptions<Schema> : PageAiNoSchemaOptions;
type AiResult<Schema extends z.ZodObject | undefined> = Schema extends z.ZodObject ? z.infer<Schema> : void;
type PageAiRunConfiguration<Schema extends z.ZodObject | undefined> = {
page: DonobuExtendedPage;
instruction: string;
schema: Schema;
jsonSchema: Record<string, unknown> | null;
allowedTools: string[];
maxToolCalls: number;
envVarNames: string[];
envVals?: Record<string, string | undefined>;
runMode: FlowMetadata['runMode'];
gptClient: GptClient | undefined;
};
type PageAiRunResult<Schema extends z.ZodObject | undefined> = {
donobuFlow: DonobuFlow;
parsedResult: AiResult<Schema>;
};
/**
* Prepares and executes a Donobu autonomous flow.
*
* Responsibilities:
* - Gather environment data based on allowed env vars.
* - Seed `DonobuFlow` with deterministic metadata (run mode, allowed tools, etc.).
* - Run the flow, updating persisted metadata regardless of outcome.
*
* The runner does **not** perform cache lookups or updates. That is deferred to
* the higher-level {@link PageAi} facade so that the runner can stay focused on
* “how do we execute a flow safely?” rather than “should we execute a flow at
* all?”.
*/
export declare class PageAiRunner {
private readonly donobu;
private readonly gptClient;
constructor(donobu: DonobuStack, gptClient: GptClient);
/**
* Executes a flow using the provided configuration.
*
* @param config Runtime information prepared by the higher-level facade.
* @returns Parsed result (if a schema was provided) along with the executed flow.
* @throws PageAiException when the underlying flow fails.
*/
run<Schema extends z.ZodObject | undefined>(config: PageAiRunConfiguration<Schema>): Promise<PageAiRunResult<Schema>>;
/**
* Builds a `ToolManager` constrained to the tools the flow is allowed to use.
* We always allow the objective bookkeeping tools even if the caller supplied
* a narrower list.
*/
private buildToolManager;
}
/**
* High-level API used by Playwright tests. It resolves caching policy,
* delegates execution to {@link PageAiRunner}, and records successful runs back
* into the configured cache.
*/
export declare class PageAi {
private readonly cache;
private readonly runner;
private readonly donobu;
/**
* @param donobu Donobu stack providing flow managers and shared services.
* @param gptClient GPT client used for autonomous reasoning.
* @param cache Pluggable cache implementation the facade should consult.
*/
constructor(donobu: DonobuStack, gptClient: GptClient, cache: PageAiCache);
/**
* Builds a `PageAi` instance configured to use the file-backed cache stored
* alongside the current test file. This mirrors the behaviour relied upon by
* the Playwright fixture.
*/
static withFileCache(donobu: DonobuStack, gptClient: GptClient, cacheFilepath: string): PageAi;
static withInMemoryCache(donobu: DonobuStack, gptClient: GptClient): PageAi;
/**
* Public entry point invoked by `page.ai.act`. Handles cache lookup, delegates to
* the runner, and stores the result back into the cache when appropriate.
*/
ai<Schema extends z.ZodObject>(page: DonobuExtendedPage, instruction: string, options: PageAiSchemaOptions<Schema>): Promise<z.infer<Schema>>;
ai(page: DonobuExtendedPage, instruction: string, options?: PageAiNoSchemaOptions): Promise<void>;
ai<Schema extends z.ZodObject | undefined = undefined>(page: DonobuExtendedPage, instruction: string, options?: PageAiOptions<Schema>): Promise<AiResult<Schema>>;
/**
* Invalidates cache entries matching the provided invocation parameters.
*
* Returns `true` when a matching record existed and was removed.
*/
invalidate<Schema extends z.ZodObject | undefined>(page: DonobuExtendedPage, instruction: string, options?: PageAiOptions<Schema>): Promise<boolean>;
private synthesizeResultFromMetadata;
/**
* Normalises user-provided options into a single structure that can be reused
* across cache operations and flow execution.
*/
private buildDescriptor;
/**
* Computes the cache key that uniquely identifies a `page.ai.act(...)` invocation.
* Keep this logic in sync with any external cache generators (e.g. the code
* generator) so that hits and invalidations behave the same everywhere.
*/
private buildCacheKey;
}
export {};
//# sourceMappingURL=PageAi.d.ts.map