docs: document gateway live runtime helpers

This commit is contained in:
Peter Steinberger
2026-06-04 17:50:26 -04:00
parent 81d9c2f41f
commit ca72d2706e
12 changed files with 32 additions and 18 deletions

View File

@@ -1,3 +1,5 @@
// Gateway BOOT.md runner.
// Runs per-workspace boot checks in an isolated boot session and restores mappings.
import crypto from "node:crypto";
import fs from "node:fs/promises";
import path from "node:path";
@@ -42,6 +44,7 @@ type SessionMappingSnapshot = {
const log = createSubsystemLogger("gateway/boot");
const BOOT_FILENAME = "BOOT.md";
/** Result of attempting to run a workspace BOOT.md check. */
export type BootRunResult =
| { status: "skipped"; reason: "missing" | "empty" }
| { status: "ran" }

View File

@@ -1,3 +1,5 @@
// Gateway chat attachment parser.
// Normalizes image attachments, offloads large media, and reports unsupported payloads.
import { estimateBase64DecodedBytes } from "@openclaw/media-core/base64";
import { MAX_IMAGE_BYTES } from "@openclaw/media-core/constants";
import { extensionForMime, mimeTypeFromFilePath } from "@openclaw/media-core/mime";
@@ -58,6 +60,7 @@ const TEXT_ONLY_OFFLOAD_LIMIT = 10;
export const DEFAULT_CHAT_ATTACHMENT_MAX_MB = 20;
/** Resolve the maximum decoded attachment size accepted for chat image inputs. */
export function resolveChatAttachmentMaxBytes(cfg: OpenClawConfig): number {
const configured = cfg.agents?.defaults?.mediaMaxMb;
const mb =

View File

@@ -1,3 +1,5 @@
// Gateway CLI session history importer.
// Augments local chat history with bound external Claude CLI transcripts.
import { normalizeProviderId } from "../agents/model-selection.js";
import type { SessionEntry } from "../config/sessions.js";
import {
@@ -12,9 +14,6 @@ import { mergeImportedChatHistoryMessages } from "./cli-session-history.merge.js
const ANTHROPIC_PROVIDER = "anthropic";
// CLI session history import keeps Claude/Anthropic-bound sessions in sync with
// external CLI transcripts while leaving other provider histories untouched
// once local messages already exist.
export {
mergeImportedChatHistoryMessages,
readClaudeCliFallbackSeed,

View File

@@ -1,3 +1,5 @@
// Gateway hook mapping resolver.
// Normalizes hook presets, templates, transforms, and resolved hook actions.
import fs from "node:fs";
import path from "node:path";
import {
@@ -112,6 +114,7 @@ type HookTransformFn = (
ctx: HookMappingContext,
) => HookTransformResult | Promise<HookTransformResult>;
/** Resolve configured hook mappings plus preset mappings into normalized matcher entries. */
export function resolveHookMappings(
hooks?: HooksConfig,
opts?: { configDir?: string },

View File

@@ -1,3 +1,5 @@
// Gateway live agent probe helpers.
// Builds prompts and verification helpers for live image and cron probe tests.
import { execFile } from "node:child_process";
import { randomBytes } from "node:crypto";
import { promisify } from "node:util";
@@ -33,11 +35,13 @@ type LiveCronProbeSpec = {
argsJson: string;
};
/** Return true for live agents that expose Claude-style MCP tool names. */
export function isClaudeLikeLiveAgent(raw: string): boolean {
const normalized = normalizeOptionalLowercaseString(raw);
return normalized === "claude" || normalized === "claude-cli";
}
/** Assert the live image probe answered with the expected cat description. */
export function assertLiveImageProbeReply(text: string): void {
const normalized = normalizeOptionalLowercaseString(text);
if (normalized !== "cat" && !/(^|[^a-z])cat[.!?`'")\]]*$/.test(normalized ?? "")) {
@@ -45,6 +49,7 @@ export function assertLiveImageProbeReply(text: string): void {
}
}
/** Resolve whether a live image probe should run for this agent/override. */
export function shouldRunLiveImageProbe(params: { agent: string; override?: string }): boolean {
const override = params.override?.trim();
if (override) {

View File

@@ -1,3 +1,5 @@
// Gateway live chat projector.
// Converts streaming assistant events into display-safe live chat text.
import { stripInternalRuntimeContext } from "../agents/internal-runtime-context.js";
import {
SILENT_REPLY_TOKEN,
@@ -11,8 +13,6 @@ import {
isSuppressedControlReplyText,
} from "./control-reply-text.js";
// Live chat projection converts streaming assistant runtime events into display
// text while suppressing commentary/control replies and silent-token prefixes.
export const MAX_LIVE_CHAT_BUFFER_CHARS = 500_000;
function capLiveAssistantBuffer(text: string): string {

View File

@@ -1,3 +1,5 @@
// Gateway MCP loopback JSON-RPC handlers.
// Implements initialize, tools/list, tools/call, and notification handling.
import crypto from "node:crypto";
import { runBeforeToolCallHook, type HookContext } from "../agents/agent-tools.before-tool-call.js";
import { formatErrorMessage } from "../infra/errors.js";
@@ -15,9 +17,6 @@ import {
type McpToolSchemaEntry,
} from "./mcp-http.schema.js";
// JSON-RPC handler for the in-process MCP loopback server. It intentionally
// supports the small method set needed by MCP clients: initialize, tools/list,
// tools/call, and notifications that do not need responses.
type McpTextContent = {
type: "text";
text: string;

View File

@@ -1,3 +1,5 @@
// Gateway node catalog builder.
// Merges paired devices, approved node records, and live websocket sessions.
import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce";
import { normalizeSortedUniqueTrimmedStringList } from "@openclaw/normalization-core/string-normalization";
import { hasEffectivePairedDeviceRole, type PairedDevice } from "../infra/device-pairing.js";
@@ -5,9 +7,6 @@ import type { NodePairingPairedNode } from "../infra/node-pairing.js";
import type { NodeListNode } from "../shared/node-list-types.js";
import type { NodeSession } from "./node-registry.js";
// Known node catalog merges three sources: legacy paired devices, approved
// node-pairing records, and live websocket sessions. Live data wins for current
// metadata; pairing records keep approval and last-seen history.
type KnownNodeDevicePairingSource = {
nodeId: string;
displayName?: string;

View File

@@ -1,3 +1,5 @@
// Gateway OpenAI-compatible chat completions endpoint.
// Translates OpenAI chat requests to OpenClaw agent runs and SSE/JSON responses.
import { randomUUID } from "node:crypto";
import type { IncomingMessage, ServerResponse } from "node:http";
import { estimateBase64DecodedBytes } from "@openclaw/media-core/base64";

View File

@@ -1,3 +1,5 @@
// Gateway operator-approvals client helper.
// Connects a backend Gateway client scoped to operator approval events.
import { isLoopbackIpAddress } from "@openclaw/net-policy/ip";
import {
GATEWAY_CLIENT_MODES,
@@ -47,6 +49,7 @@ function shouldOmitApprovalRuntimeDeviceIdentity(params: {
return shouldOmitOperatorApprovalDeviceIdentity(params);
}
/** Create a Gateway client authorized for operator approval event handling. */
export async function createOperatorApprovalsGatewayClient(
params: Pick<
GatewayClientOptions,
@@ -96,6 +99,7 @@ export async function createOperatorApprovalsGatewayClient(
});
}
/** Run a callback with a started operator-approvals Gateway client and close it after. */
export async function withOperatorApprovalsGatewayClient<T>(
params: {
config: OpenClawConfig;

View File

@@ -1,3 +1,5 @@
// Gateway plugin startup bootstrap.
// Runs startup maintenance, loads plugin runtime, and prepares advertised methods.
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
import { initSubagentRegistry } from "../agents/subagent-registry.js";
import { applyPluginAutoEnable } from "../config/plugin-auto-enable.js";

View File

@@ -1,3 +1,5 @@
// Gateway Talk realtime relay.
// Bridges browser Talk audio sessions with realtime voice provider plugins.
import { randomUUID } from "node:crypto";
import { resolveExpiresAtMsFromDurationMs } from "@openclaw/normalization-core/number-coercion";
import type { OpenClawConfig } from "../config/types.js";
@@ -48,13 +50,6 @@ import {
} from "./talk-relay-session-lifecycle.js";
import { forgetUnifiedTalkSession } from "./talk-session-registry.js";
/**
* Gateway-owned relay between browser Talk audio and realtime voice providers.
*
* Each relay is scoped to the owning WebSocket connection; events are broadcast
* back only to that connection so audio, transcript, and tool-call state cannot
* leak across clients that know another relay id.
*/
const RELAY_SESSION_TTL_MS = 30 * 60 * 1000;
const MAX_AUDIO_BASE64_BYTES = 512 * 1024;
const MAX_RELAY_SESSIONS_PER_CONN = 2;