mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
docs: document qa runtime facade contracts
This commit is contained in:
@@ -97,53 +97,69 @@ function loadFacadeModule(): FacadeModule {
|
||||
});
|
||||
}
|
||||
|
||||
/** Build a QA bus target string from conversation and optional thread parts. */
|
||||
export const buildQaTarget: FacadeModule["buildQaTarget"] = ((...args) =>
|
||||
loadFacadeModule().buildQaTarget(...args)) as FacadeModule["buildQaTarget"];
|
||||
|
||||
/** Format a QA bus target string for display and CLI output. */
|
||||
export const formatQaTarget: FacadeModule["buildQaTarget"] = ((...args) =>
|
||||
loadFacadeModule().buildQaTarget(...args)) as FacadeModule["buildQaTarget"];
|
||||
|
||||
/** Create a QA bus thread through the bundled QA channel facade. */
|
||||
export const createQaBusThread: FacadeModule["createQaBusThread"] = ((...args) =>
|
||||
loadFacadeModule().createQaBusThread(...args)) as FacadeModule["createQaBusThread"];
|
||||
|
||||
/** Delete a QA bus message through the bundled QA channel facade. */
|
||||
export const deleteQaBusMessage: FacadeModule["deleteQaBusMessage"] = ((...args) =>
|
||||
loadFacadeModule().deleteQaBusMessage(...args)) as FacadeModule["deleteQaBusMessage"];
|
||||
|
||||
/** Edit a QA bus message through the bundled QA channel facade. */
|
||||
export const editQaBusMessage: FacadeModule["editQaBusMessage"] = ((...args) =>
|
||||
loadFacadeModule().editQaBusMessage(...args)) as FacadeModule["editQaBusMessage"];
|
||||
|
||||
/** Read the current QA bus state snapshot. */
|
||||
export const getQaBusState: FacadeModule["getQaBusState"] = ((...args) =>
|
||||
loadFacadeModule().getQaBusState(...args)) as FacadeModule["getQaBusState"];
|
||||
|
||||
/** Inject an inbound QA bus message for channel and gateway tests. */
|
||||
export const injectQaBusInboundMessage: FacadeModule["injectQaBusInboundMessage"] = ((...args) =>
|
||||
loadFacadeModule().injectQaBusInboundMessage(
|
||||
...args,
|
||||
)) as FacadeModule["injectQaBusInboundMessage"];
|
||||
|
||||
/** Normalize a user-provided QA target string when possible. */
|
||||
export const normalizeQaTarget: FacadeModule["normalizeQaTarget"] = ((...args) =>
|
||||
loadFacadeModule().normalizeQaTarget(...args)) as FacadeModule["normalizeQaTarget"];
|
||||
|
||||
/** Parse a QA target string into chat type, conversation id, and optional thread id. */
|
||||
export const parseQaTarget: FacadeModule["parseQaTarget"] = ((...args) =>
|
||||
loadFacadeModule().parseQaTarget(...args)) as FacadeModule["parseQaTarget"];
|
||||
|
||||
/** Poll the QA bus for new messages from a cursor. */
|
||||
export const pollQaBus: FacadeModule["pollQaBus"] = ((...args) =>
|
||||
loadFacadeModule().pollQaBus(...args)) as FacadeModule["pollQaBus"];
|
||||
|
||||
/** Lazy QA channel plugin object used by plugin loader tests. */
|
||||
export const qaChannelPlugin: FacadeModule["qaChannelPlugin"] = createLazyFacadeObjectValue(
|
||||
() => loadFacadeModule().qaChannelPlugin,
|
||||
);
|
||||
|
||||
/** Add a reaction to a QA bus message. */
|
||||
export const reactToQaBusMessage: FacadeModule["reactToQaBusMessage"] = ((...args) =>
|
||||
loadFacadeModule().reactToQaBusMessage(...args)) as FacadeModule["reactToQaBusMessage"];
|
||||
|
||||
/** Read one QA bus message by id. */
|
||||
export const readQaBusMessage: FacadeModule["readQaBusMessage"] = ((...args) =>
|
||||
loadFacadeModule().readQaBusMessage(...args)) as FacadeModule["readQaBusMessage"];
|
||||
|
||||
/** Search QA bus messages using the bundled channel facade. */
|
||||
export const searchQaBusMessages: FacadeModule["searchQaBusMessages"] = ((...args) =>
|
||||
loadFacadeModule().searchQaBusMessages(...args)) as FacadeModule["searchQaBusMessages"];
|
||||
|
||||
/** Send an outbound QA bus message with optional attachments and tool calls. */
|
||||
export const sendQaBusMessage: FacadeModule["sendQaBusMessage"] = ((...args) =>
|
||||
loadFacadeModule().sendQaBusMessage(...args)) as FacadeModule["sendQaBusMessage"];
|
||||
|
||||
/** Install a test runtime implementation into the bundled QA channel facade. */
|
||||
export const setQaChannelRuntime: FacadeModule["setQaChannelRuntime"] = ((...args) =>
|
||||
loadFacadeModule().setQaChannelRuntime(...args)) as FacadeModule["setQaChannelRuntime"];
|
||||
|
||||
@@ -30,6 +30,7 @@ function isMissingQaRuntimeError(error: unknown) {
|
||||
);
|
||||
}
|
||||
|
||||
/** Load the bundled QA lab runtime surface, throwing when the private bundle is absent. */
|
||||
export function loadQaRuntimeModule(): QaRuntimeSurface {
|
||||
const env = resolvePrivateQaBundledPluginsEnv();
|
||||
return loadBundledPluginPublicSurfaceModuleSync<QaRuntimeSurface>({
|
||||
@@ -39,6 +40,7 @@ export function loadQaRuntimeModule(): QaRuntimeSurface {
|
||||
});
|
||||
}
|
||||
|
||||
/** Check whether the bundled QA lab runtime surface is present without hiding other load errors. */
|
||||
export function isQaRuntimeAvailable(): boolean {
|
||||
try {
|
||||
loadQaRuntimeModule();
|
||||
@@ -51,6 +53,7 @@ export function isQaRuntimeAvailable(): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
/** Normalized options passed from live-transport QA CLIs into lane runners. */
|
||||
export type LiveTransportQaCommandOptions = {
|
||||
repoRoot?: string;
|
||||
outputDir?: string;
|
||||
@@ -85,16 +88,19 @@ type LiveTransportQaCommanderOptions = {
|
||||
credentialRole?: string;
|
||||
};
|
||||
|
||||
/** Commander registration hook for one live-transport QA subcommand. */
|
||||
export type LiveTransportQaCliRegistration = {
|
||||
commandName: string;
|
||||
register(qa: Command): void;
|
||||
};
|
||||
|
||||
/** Help text customizations for live credential source and role flags. */
|
||||
export type LiveTransportQaCredentialCliOptions = {
|
||||
sourceDescription?: string;
|
||||
roleDescription?: string;
|
||||
};
|
||||
|
||||
/** Declarative command metadata and runner used to install a live-transport QA CLI. */
|
||||
export type LiveTransportQaCliRegistrationOptions = {
|
||||
commandName: string;
|
||||
credentialOptions?: LiveTransportQaCredentialCliOptions;
|
||||
@@ -111,6 +117,7 @@ export type LiveTransportQaCliRegistrationOptions = {
|
||||
run: (opts: LiveTransportQaCommandOptions) => Promise<void>;
|
||||
};
|
||||
|
||||
/** Memoize a lazy CLI runtime import so repeated command paths share one loaded module. */
|
||||
export function createLazyCliRuntimeLoader<T>(load: () => Promise<T>) {
|
||||
let promise: Promise<T> | null = null;
|
||||
return async () => {
|
||||
@@ -195,6 +202,7 @@ function registerLiveTransportQaCli(
|
||||
});
|
||||
}
|
||||
|
||||
/** Build a Commander registration object for one live-transport QA command. */
|
||||
export function createLiveTransportQaCliRegistration(
|
||||
params: LiveTransportQaCliRegistrationOptions,
|
||||
): LiveTransportQaCliRegistration {
|
||||
@@ -209,12 +217,14 @@ export function createLiveTransportQaCliRegistration(
|
||||
};
|
||||
}
|
||||
|
||||
/** One top-level check row in a rendered QA markdown report. */
|
||||
export type QaReportCheck = {
|
||||
name: string;
|
||||
status: "pass" | "fail" | "skip";
|
||||
details?: string;
|
||||
};
|
||||
|
||||
/** One scenario section in a rendered QA markdown report. */
|
||||
export type QaReportScenario = {
|
||||
name: string;
|
||||
status: "pass" | "fail" | "skip";
|
||||
@@ -231,12 +241,14 @@ export {
|
||||
type LiveTransportStandardScenarioId,
|
||||
} from "./qa-live-transport-scenarios.js";
|
||||
|
||||
/** Docker command runner abstraction used by QA Docker helpers and tests. */
|
||||
export type QaDockerRunCommand = (
|
||||
command: string,
|
||||
args: string[],
|
||||
cwd: string,
|
||||
) => Promise<{ stdout: string; stderr: string }>;
|
||||
|
||||
/** Minimal fetch-like health probe used by QA Docker runtime helpers. */
|
||||
export type QaDockerFetchLike = (input: string) => Promise<{ ok: boolean }>;
|
||||
|
||||
const DEFAULT_QA_DOCKER_COMMAND_TIMEOUT_MS = 120_000;
|
||||
@@ -250,6 +262,7 @@ function pushQaReportDetailsBlock(lines: string[], label: string, details: strin
|
||||
lines.push("", "```text", details, "```");
|
||||
}
|
||||
|
||||
/** Render checks, scenarios, timeline, and notes into the standard QA markdown report format. */
|
||||
export function renderQaMarkdownReport(params: {
|
||||
title: string;
|
||||
startedAt: Date;
|
||||
@@ -329,10 +342,12 @@ export function renderQaMarkdownReport(params: {
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
/** Append a formatted live-lane issue while preserving the caller-owned issue list. */
|
||||
export function appendQaLiveLaneIssue(issues: string[], label: string, error: unknown) {
|
||||
issues.push(`${label}: ${formatErrorMessage(error)}`);
|
||||
}
|
||||
|
||||
/** Format a live-lane failure message that includes artifact labels and paths. */
|
||||
export function buildQaLiveLaneArtifactsError(params: {
|
||||
heading: string;
|
||||
artifacts: Record<string, string>;
|
||||
@@ -346,6 +361,7 @@ export function buildQaLiveLaneArtifactsError(params: {
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
/** Print live-transport QA artifact paths with a lane label for CI log parsers. */
|
||||
export function printLiveTransportQaArtifacts(
|
||||
laneLabel: string,
|
||||
artifacts: Record<string, string>,
|
||||
@@ -397,6 +413,7 @@ async function findFreeQaDockerPort() {
|
||||
});
|
||||
}
|
||||
|
||||
/** Return the preferred Docker host port unless it is unpinned and already occupied. */
|
||||
export async function resolveQaDockerHostPort(preferredPort: number, pinned: boolean) {
|
||||
if (pinned || (await isQaDockerPortFree(preferredPort))) {
|
||||
return preferredPort;
|
||||
@@ -471,6 +488,7 @@ async function isQaDockerHealthy(url: string, fetchImpl: QaDockerFetchLike) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Create Docker command, health-check, and compose helpers for QA harnesses. */
|
||||
export function createQaDockerRuntime(params: {
|
||||
auditContext: string;
|
||||
commandTimeoutMs?: number | null;
|
||||
@@ -639,6 +657,7 @@ export function createQaDockerRuntime(params: {
|
||||
|
||||
type ProcessWriteCallback = (err?: Error | null) => void;
|
||||
|
||||
/** Tee stdout and stderr into a private artifact file until the returned stop hook runs. */
|
||||
export async function startLiveTransportQaOutputTee(params: {
|
||||
fileName: string;
|
||||
outputDir: string;
|
||||
|
||||
Reference in New Issue
Block a user