Skip to content

Shared package API ​

Runtime, page-continuity, testing, and diagnostic APIs shared by the four adapters. Import these from their owning package; no adapter re-implementation is involved.

This page covers public APIs in @plingjs/core, @plingjs/agent, @plingjs/dom, and @plingjs/ui.

API overview · Shared package API

PackagePeer dependenciesVersion
@plingjs/core—0.1.0-alpha.2

The current package version is 0.1.0-alpha.2; stability is preview. This is a pre-1.0 alpha, so a minor release may still change the API.

Minimal example ​

ts
import { createExecutor, createPolicy } from "@plingjs/core";
import { createReplayLlm } from "@plingjs/agent";

Page declarations ​

Declare actions, records, regions, state, feedback, task entrances, and sensitive values.

APIKindReference
sensitiveFunctionReference

sensitive ​

Marks a value for outbound masking, tokenization, or a hint while keeping the field name visible.

Imports

@plingjs/core

Signature

ts
// Shared package
sensitive<T>(value: T, options?: SensitivityMode | SensitiveOptions): SensitiveValue<T>

Parameters and options

ParameterTypeRequiredDefaultDescription
valueTYes—Value that enters page context and the model transcript.
options"masked" | "hidden" | SensitiveOptionsNo"masked"Controls whether the model sees a placeholder or no value. The real value remains in the browser.

Example 1 · Mask a phone number

ts
const phone = sensitive(customer.phone, "masked");

Canonical reference

Open the corresponding reference

Shared option types ​

The option shapes referenced by declarations. Adapter aliases are listed where the name differs.

APIKindReference
RecordValueTypeReference
KindTypeReference
ParamDeclarationTypeReference
ExpectationTypeReference
HandoffStepTypeReference
FlowStepTypeReference
RegionRoleTypeReference
PlingUiOptionsTypeReference

RecordValue ​

A row value or a full record declaration with explicit id, label, and fields.

Imports

@plingjs/core

Signature

ts
// Shared package
type RecordValue =
  | object
  | {
      data: object;
      id?: string | number;
      label?: string;
      fields?: Record<string, unknown>;
    }

Parameters and options

ParameterTypeRequiredDefaultDescription
plain object.id | keystring | numberNo—Default primary key when the row itself is passed as a plain object.
envelope.dataobjectConditional—Row data wrapped in the explicit record envelope.
envelope.idstring | numberNo—Overrides the primary key when the field is not named id or key.
envelope.labelstringNo—Human- and model-readable row label.
envelope.fieldsRecord<string, unknown>No—Allowlist of fields visible to the model. Without it, all row fields except the primary key are exposed.

Example 1 · Explicit field allowlist

ts
const value = {
  data: order,
  id: order.code,
  label: `订单 ${order.code}`,
  fields: { customer: order.customer, total: order.total },
};

Canonical reference

Open the corresponding reference

Kind ​

The action risk level used by approval policy.

Imports

@plingjs/core

Signature

ts
// Shared package
type Kind = "read" | "write" | "danger"

Parameters and options

ParameterTypeRequiredDefaultDescription
read"read"No—No business state change. Visibility, navigation, and inspection belong here.
write"write"No—Changes business state but is not destructive or irreversible.
danger"danger"No—Destructive, irreversible, or high-impact. Approval defaults to stricter handling.

Example 1 · Choose a risk level

ts
pling.tool(deleteButton, { desc: "删除此订单", kind: "danger" });

Canonical reference

Open the corresponding reference

ParamDeclaration ​

Array shorthand or JSON Schema used to validate action arguments.

Imports

@plingjs/core

Signature

ts
// Shared package
type ParamDeclaration = readonly ToolParam[] | JsonSchema

Parameters and options

ParameterTypeRequiredDefaultDescription
[].namestringYes—Argument key received by run and visible to the model.
[].labelstringYes—Required explanation of the argument. It is the model's only semantic hint.
[].type"string" | "number" | "boolean"No"string"Argument type. Includes coercion from obvious string forms and rejects invalid values.
[].optionalbooleanNofalseMarks the argument optional. Arguments are required by default.
[].valuesreadonly (string | number)[]No—Closed static value set. Use it when the model must choose from known values.
[].options() => readonly ParamOption[]No—Dynamic value set, re-read for each snapshot and execution.
[].min | [].maxnumber | (() => number)No—Numeric bounds for number arguments, including dynamic bounds.
[].minLength | [].maxLengthnumberNo—String length bounds.
[].patternRegExp | stringNo—Regular-expression constraint for a string argument.
[].format"date"No—Semantic format validation. A date must be a real calendar date.
JSON Schema.type"object"Conditional"object"The direct JSON Schema form must describe an object.
JSON Schema.propertiesRecord<string, unknown>No—Property schemas for the direct JSON Schema form.
JSON Schema.requiredstring[]No—Required property names for the direct JSON Schema form.

Example 1 · Compact parameter declaration

ts
const params = [
  { name: "orderId", label: "订单号", pattern: /^SO-\d{4}$/ },
  { name: "note", label: "新备注", maxLength: 200 },
  { name: "notify", label: "是否通知客户", type: "boolean", optional: true },
];

Canonical reference

Open the corresponding reference

Expectation ​

A success condition checked after an action finishes.

Imports

@plingjs/core

Signature

ts
// Shared package
interface Expectation {
  desc?: string;
  check(): boolean | Promise<boolean>;
  timeout?: number;
}

Parameters and options

ParameterTypeRequiredDefaultDescription
descstringNo—Human-readable statement of the expected outcome. It is included in success and failure receipts.
check() => boolean | Promise<boolean>Yes—Predicate evaluated after execution. Exceptions remain developer errors and are not swallowed.
timeoutnumberNo2000Maximum wait in milliseconds before reporting EXPECTATION_FAILED.

Example 1 · Verify a new row exists

ts
const expect = {
  desc: "新待办出现在列表中",
  check: () => todos.some((todo) => todo.text === "准备发布"),
  timeout: 3000,
};

Canonical reference

Open the corresponding reference

HandoffStep ​

One instruction shown to a person during human handoff.

Imports

@plingjs/core

Signature

ts
// Shared package
interface HandoffStep {
  text: string;
  highlight?: string;
}

Parameters and options

ParameterTypeRequiredDefaultDescription
textstringYes—Instruction shown to the person who takes over.
highlightstringNo—Optional guide-target id or action id to highlight while the step is active.

Example 1 · Guide a human step

ts
const steps = [
  { text: "填写短信验证码", highlight: "captcha" },
  { text: "点击提交", highlight: "submit" },
];

Canonical reference

Open the corresponding reference

FlowStep ​

One step in a compound action. Flow steps are not a second execution channel.

Imports

@plingjs/core

Signature

ts
// Shared package
interface FlowStep {
  action: string;
  args?: Record<string, unknown> | ((params: Record<string, unknown>) => Record<string, unknown>);
  expect?: Expectation;
  desc?: string;
  optional?: boolean;
  idempotent?: boolean;
}

Parameters and options

ParameterTypeRequiredDefaultDescription
actionstringYes—Registered action id to execute. It may contain placeholders.
argsRecord<string, unknown> | ((params) => Record<string, unknown>)No—Step arguments. Strings may reference flow parameters; a function receives the complete parameter object.
expectExpectationNo—Overrides the step action's own success criterion.
descstringNo—Human-readable step description used in progress and receipts.
optionalbooleanNofalseA failed optional step is skipped instead of aborting the flow.
idempotentbooleanNofalseAllows safe retry after an execution or expectation failure. Pre-execution failures are always retryable.

Example 1 · Reference a parameter in a step

ts
const steps = [
  { action: "edit@order:{{orderId}}", desc: "打开订单" },
  { action: "dialog_note", args: { text: "{{note}}" }, desc: "填写备注" },
  { action: "dialog_save", desc: "保存" },
];

Canonical reference

Open the corresponding reference

RegionRole ​

The structural role of a region.

Imports

@plingjs/core

Signature

ts
// Shared package
type RegionRole =
  | "page"
  | "header"
  | "nav"
  | "main"
  | "aside"
  | "section"
  | "form"
  | "dialog"
  | "toolbar"
  | "list"
  | "footer"

Parameters and options

ParameterTypeRequiredDefaultDescription
role"page" | "header" | "nav" | "main" | "aside" | "section" | "form" | "dialog" | "toolbar" | "list" | "footer"Yes—Adds structural context for disambiguating actions with similar names. It does not grant or restrict permissions.

Example 1 · Disambiguate two confirm buttons

ts
pling.scope(dialog, { id: "edit_dialog", role: "dialog", label: "编辑订单" });
pling.scope(toolbar, { id: "bulk_toolbar", role: "toolbar", label: "批量操作" });

Canonical reference

Open the corresponding reference

PlingUiOptions ​

Locale, theme, message overrides, and class names for the shared assistant UI.

Imports

@plingjs/ui

Signature

ts
// Shared package
interface PlingUiOptions {
  locale?: PlingLocale;
  theme?: PlingTheme;
  messages?: PlingCatalogOverrides;
  classNames?: PlingClassNames;
}

Parameters and options

ParameterTypeRequiredDefaultDescription
locale"en-US" | "zh-CN" | "auto" | stringNoen-USLanguage used by the built-in assistant UI. "auto" follows the browser language.
theme"light" | "dark" | "auto" | PlingThemeOverridesNolightTheme for the built-in surfaces. An object can override tokens or choose a mode.
theme.mode"light" | "dark" | "auto"NolightExplicit mode when the theme is an object. "auto" follows the operating-system preference.
theme.tokensPartial<PlingThemeTokens>No—Overrides individual design tokens such as colours, radii, shadows, and font families. Keys not supplied keep the selected light or dark defaults.
messagesPlingCatalogOverridesNo—Adds or replaces message catalog entries for one or more locales.
messages.<locale>Partial<Record<PlingMessageKey, string>>No—Message overrides for one BCP 47 locale. Missing keys fall back to the built-in catalog.
classNamesPlingClassNamesNo—Extra class names applied to the built-in chat, dock, launcher, and panel.
classNames.dockstringNo—Extra class for the dock shell.
classNames.panelstringNo—Extra class for the panel shell.
classNames.launcherstringNo—Extra class for the launcher button.
classNames.chatstringNo—Extra class for the chat surface.

Example 1 · Chinese UI with a token override

ts
const ui = {
  locale: "zh-CN",
  theme: { mode: "light", tokens: { colorPrimary: "#0b6bcb" } },
  classNames: { dock: "product-assistant" },
};

Canonical reference

Open the corresponding reference

Agent runtime ​

Model configuration, sessions, approval and handoff, hooks, tracing, and shared runtime helpers.

APIKindReference
AgentRuntimeOptionsTypeReference
AgentConfigOverridesTypeReference
HookRegistryClassReference
SessionEventTypeReference
AgentTraceOptionsTypeReference
waitForFunctionReference
describeFlowFunctionReference

AgentRuntimeOptions ​

The runtime contract behind AgentSetup: config, registry, model, events, hooks, gates, trace, and continuity.

Imports

@plingjs/agent

Signature

ts
// Shared package
interface AgentRuntimeOptions {
  config: AgentConfig;
  registry?: Registry;
  llm?: Llm;
  responseLocale?: string | (() => string);
  telemetry?: Telemetry;
  trace?: boolean | AgentTraceOptions;
  settle?: () => Promise<void>;
  hooks?: HookRegistry;
  onEvent?: SessionEventListener;
  onApproval?: (pending: PendingApproval | null) => void;
  onHandoff?: (pending: PendingHandoff | null) => void;
  gate?: () => boolean;
  policy?: ConfirmGate;
  approvalTimeoutMs?: number;
  handoffTimeoutMs?: number;
  handoff?: HandoffGate;
  id?: string;
  onLeaseLost?: () => void;
  continuity?: ContinuitySetting;
}

Parameters and options

ParameterTypeRequiredDefaultDescription
configAgentConfigYes—Fully resolved model and runtime configuration.
registryRegistryNo—Page capability registry. Omit it for a chat-only runtime.
llmLlmNo—Injects the model call function. Use it for a test model, a server proxy, or a non-OpenAI-compatible transport.
responseLocalestring | (() => string)No—Locale used when composing the response-language instruction. A function is re-read before each model request.
telemetryTelemetryNo—Collects token, duration, cost, and retry metrics for the current runtime.
traceboolean | AgentTraceOptionsNofalseKeeps a bounded in-memory trace of model requests for the read-only inspector. Disabled by default.
settle() => Promise<void>No—Replaces the page-settle wait used between actions. Most useful in deterministic tests and non-browser hosts.
hooksHookRegistryNo—Tool lifecycle hooks shared by every surface created from this application runtime.
onEvent(event: SessionEvent) => voidNo—Receives the same session event stream that powers the chat and activity views.
onApproval(pending: PendingApproval | null) => voidNo—Called when an approval request appears or clears. Use it to connect a custom approval UI.
onHandoff(pending: PendingHandoff | null) => voidNo—Called when a human-handoff request appears or clears.
policyConfirmGateNo—Replaces the default approval gate. When provided, the built-in gate and chat approval buttons are not used.
approvalTimeoutMsnumberNo60000Time to wait for a human approval before treating it as denied.
handoffTimeoutMsnumberNo300000Default time to wait for a human handoff. A tool-level handoff.timeout overrides it.
handoffHandoffGateNo—Replaces the built-in handoff queue with a custom channel.
idstringNo—Stable session id for multi-session hosts.
onLeaseLost() => voidNo—Called when another tab or host takes over the shared session lease.
continuityContinuitySettingNo—Enables bounded conversation continuity across full-page navigation. "tab" uses sessionStorage. Omit to disable it.
gate() => booleanNotrueReturns false to disable the built-in confirmation channel for this application. Defaults to enabled.

Example 1 · Create a page-operating runtime

ts
const runtime = createAgentRuntime({
  config: resolveAgentConfig({ config: { model: "gpt-4.1-mini" } }),
  registry: pling.registry,
  hooks,
  trace: true,
});

Canonical reference

Open the corresponding reference

AgentConfigOverrides ​

A partial model configuration. Unspecified fields continue to come from environment variables and defaults.

Imports

@plingjs/agent

Signature

ts
// Shared package
type AgentConfigOverrides =
  Partial<Omit<AgentConfig, "limits" | "retry">> & {
    limits?: Partial<AgentLimits>;
    retry?: Partial<AgentRetryConfig>;
  };

Parameters and options

ParameterTypeRequiredDefaultDescription
baseUrlstringNo""OpenAI-compatible API root. A relative path such as /llm/v1 routes through the application server and does not require a browser-side key.
modelstringNo""Model name sent to the provider.
apiKeystringNo""Browser-visible provider key. Leave empty when using a relative proxy URL.
temperaturenumberNo0.3Sampling temperature for model responses.
maxTokensnumberNo1024Maximum output tokens for one model response. This is not the conversation context budget.
systemPromptstringNo""Application-specific instructions appended after the framework rules. It does not replace the framework rules.
streambooleanNotrueUses streaming when the provider supports it.
defaultApproval"danger" | "kind"No"danger"Declaration-time approval policy for tools that omit confirm.
minActionIntervalMsnumberNo0Minimum delay between actions in the same model turn. Useful when UI transitions need to remain visible.
retry.maxRetriesnumberNo3Additional model-request retries after the first attempt. Valid range is 0–5.
retry.baseDelayMsnumberNo500Initial exponential-backoff delay.
retry.maxDelayMsnumberNo4000Maximum delay for one retry.
limits.maxTurnsnumberNo10Maximum model/tool round trips within one send.
limits.contextTokensnumberNo8192Estimated conversation context budget.
limits.reserveForOutputnumberNo1024Tokens reserved for the model response inside the context budget.
limits.compactRationumberNo0.8History is compacted when estimated usage reaches this ratio of the usable budget. Valid range is (0, 1].
limits.keepRecentnumberNo6Recent history entries kept verbatim during compaction.

Example 1 · Override only the necessary fields

ts
const config = {
  model: "gpt-4.1-mini",
  maxTokens: 1600,
  limits: { maxTurns: 14, keepRecent: 8 },
  retry: { maxRetries: 2 },
};

Canonical reference

Open the corresponding reference

HookRegistry ​

PreToolUse and PostToolUse hooks for application policy, redaction, and audit without adding a second executor.

Imports

@plingjs/agent

Signature

ts
// Shared package
class HookRegistry {
  addPreToolUse(handler: PreToolUseHandler): () => void;
  addPostToolUse(handler: PostToolUseHandler): () => void;
  firePreToolUse(payload: PreToolUsePayload): Promise<{ blocked: boolean; reason?: string }>;
  firePostToolUse(payload: PostToolUsePayload): Promise<ExecResult>;
}

Parameters and options

ParameterTypeRequiredDefaultDescription
addPreToolUse(handler)PreToolUseHandlerNo—Adds a hook before execution. Returns an unsubscribe function. Returning { blocked: true, reason } stops the tool.
addPostToolUse(handler)PostToolUseHandlerNo—Adds a hook after execution. It may return a replacement ExecResult for later hooks and the caller.
payload.idstringNo—Original page action id.
payload.toolstringNo—Model-facing legal tool name.
payload.argsRecord<string, unknown>No—Validated call arguments.
payload.turnnumberNo—Current model/tool turn.
payload.resultExecResultNo—Post-hook only: current execution result before this hook runs.

Example 1 · Block and rewrite tool results

ts
const hooks = new HookRegistry();
hooks.addPreToolUse(({ id }) => id === "delete_all" ? { blocked: true, reason: "批量删除已禁用" } : undefined);
hooks.addPostToolUse(({ result }) => redactResult(result));

Canonical reference

Open the corresponding reference

SessionEvent ​

The single event stream consumed by chat, activity, audit, and evaluation views.

Imports

@plingjs/agent

Signature

ts
// Shared package
type SessionEvent =
  | { type: "user"; text: string }
  | { type: "assistant"; text: string }
  | { type: "assistant_delta"; text: string }
  | { type: "tool_call"; id: string; tool: string; args: Record<string, unknown> }
  | { type: "tool_result"; id: string; tool: string; result: ExecResult }
  | { type: "blocked"; id: string; tool: string; reason: string }
  | { type: "handoff"; id: string; tool: string; status: "requested" | "completed" | "cancelled" | "timeout"; reason: string }
  | { type: "notice"; text: string }
  | { type: "final"; text: string }
  | { type: "cancelled" }
  | { type: "error"; code: string; message: string; messageKey?: string; params?: MessageParams };

Parameters and options

ParameterTypeRequiredDefaultDescription
type: "user"{ text: string }No—Echo of the user's input.
type: "assistant"{ text: string }No—Non-final assistant narration.
type: "assistant_delta"{ text: string }No—Streaming increment, not accumulated text.
type: "tool_call"{ id; tool; args }No—A tool is about to execute.
type: "tool_result"{ id; tool; result: ExecResult }No—The structured result of a tool call.
type: "blocked"{ id; tool; reason }No—A hook blocked the tool before execution.
type: "handoff"{ id; tool; status; reason }No—Human handoff requested or resolved.
type: "notice"{ text: string }No—Loop-level guidance such as a turn limit or empty response.
type: "final"{ text: string }No—Final assistant answer for this send.
type: "cancelled"{}No—The user cancelled the run.
type: "error"{ code; message; messageKey?; params? }No—A loop or model error. code remains the authoritative identifier.

Example 1 · Audit the event stream

ts
for await (const event of runtime.session.events) {
  if (event.type === "tool_result") audit(event);
}

Canonical reference

Open the corresponding reference

AgentTraceOptions ​

Bounds the number of model calls retained by the read-only inspector.

Imports

@plingjs/agent

Signature

ts
// Shared package
interface AgentTraceOptions { maxCalls?: number }

Parameters and options

ParameterTypeRequiredDefaultDescription
maxCallsnumberNo20Maximum model calls retained in the in-memory inspector. Omit it to use the default; lower values bound memory in long sessions.

Example 1 · Keep the last eight calls

ts
const trace = { maxCalls: 8 };

Canonical reference

Open the corresponding reference

waitFor ​

Waits for an asynchronous UI condition inside a run or expectation.

Imports

@plingjs/core

Signature

ts
// Shared package
waitFor(check: () => boolean | Promise<boolean>, options?: WaitForOptions): Promise<boolean>

Parameters and options

ParameterTypeRequiredDefaultDescription
check() => boolean | Promise<boolean>Yes—Predicate to evaluate. It is checked immediately and then at the configured interval.
options.timeoutnumberNo2000Maximum wait. Zero checks once without waiting. Timeout returns false rather than throwing.
options.intervalnumberNo30Delay between checks.
options.now() => numberNo—Clock injection for deterministic tests.
options.sleep(ms: number) => Promise<void>No—Sleep injection for deterministic tests.
options.signalAbortSignalNo—Cancels the wait and returns false as soon as it is aborted.

Example 1 · Wait inside a custom runner

ts
await waitFor(() => document.querySelector(".saved"), { timeout: 1500 });

Canonical reference

Open the corresponding reference

describeFlow ​

Produces a model-readable description of a compound action without executing it.

Imports

@plingjs/core

Signature

ts
// Shared package
describeFlow(report: FlowReport): string

Parameters and options

ParameterTypeRequiredDefaultDescription
reportFlowReportYes—Result returned by a flow execution. The formatter reports completed, failed, skipped, handoff, and expectation states.

Example 1 · Render a flow receipt

ts
const text = describeFlow(result.resume?.report ?? report);

Canonical reference

Open the corresponding reference

Page identity and continuity ​

Read page identity, share a runtime across frames, and inspect declared coverage.

APIKindReference
PlingPageInterfaceReference
createPlingPageFunctionReference
sharePlingPageWithFrameFunctionReference
plingPageFromParentFunctionReference
waitForPlingPageFromParentFunctionReference
inspectCoverageMethodReference

PlingPage ​

A page-level runtime shared by multiple framework islands or same-origin frames.

Imports

@plingjs/dom

Signature

ts
// Shared package
interface PlingPage {
  readonly registry: Registry;
  readonly scopes: ScopeController;
  readonly feedback: FeedbackCollector;
  destroy(): void;
}

Parameters and options

ParameterTypeRequiredDefaultDescription
registryRegistryNo—Shared action, record, state, and feedback registry.
scopesScopeControllerNo—Shared region visibility and occlusion controller.
feedbackFeedbackCollectorNo—Page-level feedback collector that observes the document once.
destroy()voidNo—Stops page observers and clears automatic scopes. Adapters should destroy their declarations first.

Example 1 · Share one page runtime

ts
const page = createPlingPage();
const vuePling = createPling({ shared: page });
const reactPling = createPling({ shared: page });

Canonical reference

Open the corresponding reference

createPlingPage ​

Creates the shared registry, scopes, and page identity that adapters can join with shared.

Imports

@plingjs/dom

Signature

ts
// Shared package
createPlingPage(options?: PlingPageOptions): PlingPage

Parameters and options

ParameterTypeRequiredDefaultDescription
options.registryRegistryNo—Existing registry to share. A new registry is created when omitted.
options.scopesScopeControllerOptionsNo—Visibility and hit-testing overrides for the shared page.

Example 1 · Create a mixed-framework page runtime

ts
const page = createPlingPage();

// Pass the same page to Vue, React, or Vanilla islands:
const pling = createPling({ shared: page, namespace: "orders" });

Canonical reference

Open the corresponding reference

sharePlingPageWithFrame ​

Shares a page runtime with a same-origin iframe and returns a cleanup function.

Imports

@plingjs/dom

Signature

ts
// Shared package
sharePlingPageWithFrame(frame: HTMLIFrameElement, page: PlingPage): () => void

Parameters and options

ParameterTypeRequiredDefaultDescription
frameHTMLIFrameElementYes—Same-origin iframe that should receive the shared page runtime.
pagePlingPageYes—Runtime created by createPlingPage.

Example 1 · Share a runtime with a same-origin frame

ts
const page = createPlingPage();
const stop = sharePlingPageWithFrame(iframe, page);

// On teardown:
stop();
page.destroy();

Canonical reference

Open the corresponding reference

plingPageFromParent ​

Reads a shared page runtime from the parent window when the current document is an embedded frame.

Imports

@plingjs/dom

Signature

ts
// Shared package
plingPageFromParent(win?: Window): PlingPage | undefined

Parameters and options

ParameterTypeRequiredDefaultDescription
winWindowNowindowWindow whose parent should be checked. Defaults to the current window.

Example 1 · Read a shared page synchronously

ts
const page = plingPageFromParent();
if (page) createPling({ shared: page });

Canonical reference

Open the corresponding reference

waitForPlingPageFromParent ​

Waits for a parent frame to publish its page runtime.

Imports

@plingjs/dom

Signature

ts
// Shared package
waitForPlingPageFromParent(options?: WaitForFramePageOptions): Promise<PlingPage>

Parameters and options

ParameterTypeRequiredDefaultDescription
options.windowWindowNowindowChild window to listen on. Defaults to the current window.
options.timeoutMsnumberNo5000Maximum wait. Zero waits indefinitely. Rejects when another positive timeout expires.

Example 1 · Wait for the parent runtime

ts
const page = await waitForPlingPageFromParent({ timeoutMs: 8000 });
createPling({ shared: page });

Canonical reference

Open the corresponding reference

inspectCoverage ​

Scans the mounted page for interactive controls that have no declaration. It reports; it never registers an action.

Imports

@plingjs/dom

Signature

ts
// Shared package
inspectCoverage(root: Element | null): CoverageReport

Parameters and options

ParameterTypeRequiredDefaultDescription
rootElement | nullNo—Application root to scan. Vue uses its mount root; React and DOM callers may pass any root.
return.totalnumberNo—Recognized actionable controls in the root.
return.declarednumberNo—Controls with a direct declaration.
return.derivednumberNo—Controls produced by optional L1 derivation.
return.groupednumberNo—Controls covered by a declaration on an ancestor. Review these manually.
return.missingnumberNo—Actionable controls with no declaration in their ancestry.
return.coveragePercentnumber | nullNo—Covered controls divided by total; null when there are no controls.
return.targetsCoverageTarget[]No—Grouped and missing controls with labels and nearby action ids.

Example 1 · Inspect a DOM root

ts
const report = inspectCoverage(document.querySelector("#app"));

Canonical reference

Open the corresponding reference

Testing and execution helpers ​

Deterministic model replay, evaluation, page-context rendering, and the core executor used by tests, external agents, and advanced hosts.

APIKindReference
createReplayLlmFunctionReference
EvalCaseTypeReference
runEvaluationFunctionReference
createAgentLoopFunctionReference
defaultSettleFunctionReference
renderPageContextFunctionReference
createExecutorFunctionReference
createPolicyFunctionReference

createReplayLlm ​

Creates a deterministic model from scripted turns. It exercises the real loop, tool dispatch, approvals, and failure path without a network call.

Imports

@plingjs/agent

Signature

ts
// Shared package
createReplayLlm(turns: readonly ReplayTurn[]): ReplayLlm

Parameters and options

ParameterTypeRequiredDefaultDescription
turns[].contentstringNo—Assistant text returned for that turn.
turns[].callsreadonly ReplayCall[]No—Tool calls requested in that turn.
turns[].calls[].toolstringYes—Original page action id. The replay adapter converts it to the model-facing tool name.
turns[].calls[].argsRecord<string, unknown>No—Arguments serialized into the tool call.
turns[].calls[].idstringNo—Explicit tool-call id. A deterministic id is generated when omitted.

Type shape

ts
interface ReplayCall {
  tool: string;
  args?: Record<string, unknown>;
  id?: string;
}

interface ReplayTurn {
  content?: string;
  calls?: readonly ReplayCall[];
}

interface ReplayLlm extends Llm {
  readonly received: readonly (readonly LlmMessage[])[];
  readonly toolsSeen: readonly (readonly LlmToolSchema[])[];
  readonly turn: number;
  reset(): void;
}

Example 1 · Replay a two-step task

ts
const llm = createReplayLlm([
  { content: "先添加待办。", calls: [{ tool: "add_task", args: { text: "准备发布" } }] },
  { content: "已经添加。" },
]);

Canonical reference

Open the corresponding reference

EvalCase ​

One evaluation case: input, expected and forbidden actions, an optional tool-error budget, and a business-state check.

Imports

@plingjs/agent

Signature

ts
// Shared package
interface EvalCase {
  name?: string;
  input: string;
  expectIncludes?: readonly string[];
  expectTools?: readonly string[];
  expectNotTools?: readonly string[];
  maxToolErrors?: number;
  verify?: () => boolean | Promise<boolean>;
}

Parameters and options

ParameterTypeRequiredDefaultDescription
namestringNo—Display name. Defaults to the input text.
inputstringYes—User message sent to the evaluated agent run.
expectIncludesreadonly string[]No—Strings that must appear in the final answer.
expectToolsreadonly string[]No—Action ids that must be called.
expectNotToolsreadonly string[]No—Action ids that must not be called.
maxToolErrorsnumberNo—Maximum number of tool errors allowed for the case.
verify() => boolean | Promise<boolean>No—Business-state assertion executed after the run.

Example 1 · Assert a completed task

ts
const testCase = {
  name: "完成第一条待办",
  input: "把第一条待办标记为完成",
  expectTools: ["toggle_task"],
  expectNotTools: ["delete_task"],
  verify: () => todos[0].done === true,
};

Canonical reference

Open the corresponding reference

runEvaluation ​

Runs a set of EvalCase entries through one host callback, resets state between cases, and returns a pass/fail report.

Imports

@plingjs/agent

Signature

ts
// Shared package
runEvaluation(options: EvaluateOptions): Promise<EvalReport>

Parameters and options

ParameterTypeRequiredDefaultDescription
run(input: string) => Promise<string>Yes—Executes one case and returns the final assistant answer.
hooksHookRegistryYes—Hooks whose pre/post events are observed for this evaluation.
casesreadonly EvalCase[]Yes—Cases to run in order.
reset() => void | Promise<void>No—Resets application state between cases.
measure() => EvalMetricsNo—Returns tokens, duration, cost, or other numeric metrics per case.
events() => readonly SessionEvent[]No—Returns the event stream for the most recent run.

Type shape

ts
interface EvaluateOptions {
  run: (input: string) => Promise<string>;
  hooks: HookRegistry;
  cases: readonly EvalCase[];
  reset?: () => void | Promise<void>;
  measure?: () => EvalMetrics;
  events?: () => readonly SessionEvent[];
}

Example 1 · Run a small deterministic suite

ts
const report = await runEvaluation({
  run: (input) => session.send(input),
  hooks,
  cases: [completeFirstTodo],
  reset: () => store.reset(),
});
console.log(formatReport(report));

Canonical reference

Open the corresponding reference

createAgentLoop ​

Creates the lower-level conversation loop for tests and custom hosts. Most applications should use AgentSetup or createAgentRuntime instead.

Imports

@plingjs/agent

Signature

ts
// Shared package
createAgentLoop(options: LoopOptions): AgentLoop

Parameters and options

ParameterTypeRequiredDefaultDescription
llmLlmYes—Model call implementation.
registryRegistryNo—Page capability registry. Omit it for a chat-only loop.
policyConfirmGateNo—Approval gate. Omit it for fail-closed behavior when a tool needs approval.
handoffHandoffGateNo—Human-handoff gate. Omit it to fail handoff tools rather than simulate them.
systemPromptstringNo—Additional system instructions. Framework rules remain in force.
responseLocalestring | (() => string)No—Response-language hint; a function is re-read each turn.
contextContextOptionsNo—Bounds for actions, records, state, scopes, feedback, and page identity in model context.
historyHistoryOptionsNo—Context budget, compaction threshold, recent retention, and tool-result cap.
historyStateHistorySnapshotNo—Restores a summary and message list from a checkpoint. System context is rebuilt for the current page.
hooksHookRegistryNo—Tool lifecycle hooks.
telemetryTelemetryNo—Token, duration, cost, and retry metrics.
traceAgentTraceRecorderNo—Bounded request trace for diagnostics.
maxTurnsnumberNo10Maximum model/tool round trips in one run.
loopThresholdnumberNo—Repeated identical tool calls before LOOP_DETECTED.
errorBudgetnumberNo—Cumulative tool failures before the loop asks the model to answer directly.
maxNudgesnumberNo—Consecutive empty model replies allowed before stopping.
settle() => Promise<void>No—Waits for DOM, animation, and navigation to settle before snapshots.
minActionIntervalMsnumberNo0Minimum delay between actions in one model turn.
sleep(ms: number) => Promise<void>No—Sleep injection for deterministic tests.
shouldStop() => booleanNo—Cooperative cancellation checked at safe points.
observe(id: string, args: Record<string, unknown>) => void | Promise<void>No—Post-action observation hook supplied to the executor.
evidencebooleanNotrueCaptures before/after snapshots and attaches changed evidence.
onEvent(event: SessionEvent) => voidNo—Session event callback.
now() => numberNo—Clock injection for deterministic tests.

Example 1 · Create a page-operating loop

ts
const loop = createAgentLoop({
  llm,
  registry: pling.registry,
  policy: createPolicy(confirm),
  maxTurns: 12,
  evidence: true,
});

Canonical reference

Open the corresponding reference

defaultSettle ​

Waits for DOM updates, one browser frame, and a short idle window before the next page snapshot is read.

Imports

@plingjs/agent

Signature

ts
// Shared package
defaultSettle(): Promise<void>

Parameters

None.

Example 1 · Use the browser settle strategy

ts
const settle = defaultSettle;

Canonical reference

Open the corresponding reference

renderPageContext ​

Renders the bounded page context sent to the model: regions, actions, records, state, feedback, and page identity.

Imports

@plingjs/agent

Signature

ts
// Shared package
renderPageContext(snapshot: Snapshot, options?: ContextOptions): string

Parameters and options

ParameterTypeRequiredDefaultDescription
snapshotSnapshotYes—Bounded page snapshot produced by the registry.
options.maxActionsnumberNo40Maximum actions listed, default 40.
options.maxRecordsnumberNo20Maximum record rows listed, default 20.
options.includeStatebooleanNotrueWhether read-only state views are included.
options.maxIdsInHintnumberNo30Maximum action ids repeated in hints, default 30.
options.maxUnavailablenumberNo6Maximum unavailable actions listed, default 6.
options.maxStateCharsnumberNo1200Character budget for state, default 1200.
options.maxRecordCharsnumberNo1500Character budget for records, default 1500.
options.maxScopesnumberNo24Maximum page regions listed, default 24.
options.maxFeedbacknumberNo8Maximum feedback entries listed, default 8.
options.maxFeedbackCharsnumberNo800Character budget for feedback, default 800.
options.maxPageCharsnumberNo500Character budget for page identity, default 500.

Example 1 · Render a smaller context

ts
const text = renderPageContext(registry.snapshot(), {
  maxActions: 20,
  maxRecords: 8,
  maxStateChars: 600,
});

Canonical reference

Open the corresponding reference

createExecutor ​

Creates the shared executor used by the in-page agent and external Surface hosts. It is the only path that applies policy, availability, execution, and success checks.

Imports

@plingjs/core

Signature

ts
// Shared package
createExecutor(options: ExecutorOptions): Executor

Parameters and options

ParameterTypeRequiredDefaultDescription
registryRegistryYes—Registry that resolves actions and computes snapshots.
policyConfirmGateYes—Approval gate applied before an action executes.
handoffHandoffGateNo—Human-handoff gate for tools declared with handoff.
observe(id: string, args: Record<string, unknown>) => void | Promise<void>No—Observation window after execution, for routes, async rendering, or animation.
evidencebooleanNotrueCaptures changed evidence and includes it in successful results.
settle() => Promise<void>No—Wait used before the after-snapshot.
betweenSteps() => Promise<void>No—Optional pause between steps in a flow.
return.execute(id: string, argsJson?: string) => Promise<ExecResult>No—Executes one action and never throws action errors to the caller.

Type shape

ts
interface ExecutorOptions {
  registry: Registry;
  policy: ConfirmGate;
  handoff?: HandoffGate;
  observe?: (id: string, args: Record<string, unknown>) => void | Promise<void>;
  evidence?: boolean;
  settle?: () => Promise<void>;
  betweenSteps?: () => Promise<void>;
}

Example 1 · Execute through the shared pipeline

ts
const executor = createExecutor({
  registry: pling.registry,
  policy: createPolicy(confirm),
});

const result = await executor.execute("add", JSON.stringify({ text: "准备发布" }));

Canonical reference

Open the corresponding reference

createPolicy ​

Creates a confirmation policy. With no confirmation channel it fails closed and denies actions that require approval.

Imports

@plingjs/core

Signature

ts
// Shared package
createPolicy(confirm?: Confirm | null): Policy

Parameters and options

ParameterTypeRequiredDefaultDescription
confirmConfirm | nullNonullApproval callback. Null means no confirmation channel; actions requiring approval fail closed.
request.idstringNo—Action id being approved.
request.kindKindNo—Action risk level.
request.approvalApprovalNo—Resolved approval policy for this action.
request.descriptionstringNo—Model-facing description shown to the approver.
request.argsRecord<string, unknown>No—Validated call arguments.
request.flow.stepsreadonly string[]No—Step ids for a one-approval composite flow.

Example 1 · Connect a confirmation dialog

ts
const policy = createPolicy(async (request) => {
  return window.confirm(request.description) ? true : false;
});

Canonical reference

Open the corresponding reference

Diagnostics and errors ​

Stable error codes and localized rendering helpers. Codes remain authoritative across locales.

APIKindReference
describePlingErrorFunctionReference
describePlingDiagnosticFunctionReference
resolveAgentConfigFunctionReference

describePlingError ​

Renders a Pling error through the shared message catalog while preserving the machine-readable code.

Imports

@plingjs/ui

Signature

ts
// Shared package
describePlingError(error: PlingErrorText, t: PlingTranslator): string

Parameters and options

ParameterTypeRequiredDefaultDescription
error.codestringYes—Stable machine-readable error code. The code is preserved in the rendered summary.
error.messagestringNo—Developer detail added after the localized label when it adds information.
error.messageKeystringNo—Fully localized catalog key, used before the generic code mapping.
error.paramsMessageParamsNo—Interpolation values for the catalog message.
tPlingTranslatorYes—Translator that receives a message key and interpolation values.

Example 1 · Render a localized error

ts
const text = describePlingError(
  { code: "EXPECTATION_FAILED", message: "未等到新行出现" },
  pling.ui.t,
);

Canonical reference

Open the corresponding reference

describePlingDiagnostic ​

Renders a structured configuration diagnostic, including missing model fields and invalid limits.

Imports

@plingjs/ui

Signature

ts
// Shared package
describePlingDiagnostic(diagnostic: PlingDiagnosticText, t: PlingTranslator): string

Parameters and options

ParameterTypeRequiredDefaultDescription
diagnostic.readybooleanYes—When true, the function returns an empty string.
diagnostic.codestringNo—Stable diagnostic code such as MODEL_BASE_URL_MISSING or LIMITS_INVALID.
diagnostic.paramsMessageParamsNo—Non-sensitive interpolation values such as the environment variable name.
diagnostic.hintstringNo—Developer-facing fallback used only when no structured code exists.
tPlingTranslatorYes—Translator used for the diagnostic catalog.

Example 1 · Render configuration guidance

ts
const hint = describePlingDiagnostic(
  { ready: false, code: "MODEL_NAME_MISSING", params: { env: "VITE_AGENT_MODEL" } },
  pling.ui.t,
);

Canonical reference

Open the corresponding reference

resolveAgentConfig ​

Merges defaults, environment variables, and explicit overrides into the final model configuration.

Imports

@plingjs/agent

Signature

ts
// Shared package
resolveAgentConfig(options?: { env?; config? }): AgentConfig

Parameters and options

ParameterTypeRequiredDefaultDescription
options.envRecord<string, unknown>No—Environment-like object. Browser adapters normally pass import.meta.env; Node callers can pass process.env.
options.configAgentConfigOverridesNo—Explicit overrides applied after defaults and environment values.

Example 1 · Resolve configuration outside an adapter

ts
const config = resolveAgentConfig({
  env: import.meta.env,
  config: { model: "gpt-4.1-mini", limits: { maxTurns: 12 } },
});

Canonical reference

Open the corresponding reference

Version and compatibility ​

PackageVersionPeer dependencies
@plingjs/vue0.1.0-alpha.2vue ^3
@plingjs/react0.1.0-alpha.2react >=18
@plingjs/vue20.1.0-alpha.2vue ^2.7.0
@plingjs/vanilla0.1.0-alpha.2—
ItemValue
Introduced0.1.0-alpha.2
StabilityPre-1.0 alpha; a minor release may change the API

Machine-readable copy ​