mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
docs: document auth profile failure policy contract (#89613)
* docs: document markdown marker renderer * docs: document rendered markdown chunking * docs: document markdown text chunking * docs: document shared text chunking * docs: document plugin text chunking exports * docs: document avatar policy constants * docs: document node match candidates * docs: document scoped expiring id cache * docs: document runtime import normalization * docs: document string sample summaries * docs: document session usage timeseries types * docs: document session usage response types * docs: document manifest frontmatter shapes * docs: document channel route input metadata * docs: document pair loop guard settings * docs: document migration config patch helpers * docs: document api provider registry * docs: document tool call repair payloads * docs: document plugin tool payload helpers * docs: document lazy promise loader * docs: document store writer queue state * docs: document thread binding lifecycle * docs: document concurrency helper contract * docs: document gateway client info contract * docs: document delivery context contracts * docs: document secret ref defaults contract * docs: document command gating contract * docs: document avatar policy contract * docs: document node match policy * docs: document message channel normalization * docs: document boolean parsing contract * docs: document zod parse helpers * docs: document direct dm guard policy * docs: document fixed window limiter contract * docs: document node presence event contract * docs: document secret normalization contract * docs: document progress draft line removal * docs: document usage formatting contracts * docs: document agent run status contract * docs: document runtime import helpers * docs: document provider utility ownership * docs: document invalid config helpers * docs: document json compat parser * docs: document channel config metadata ownership * docs: document channel logging helpers * docs: document sender identity validation ownership * docs: document string sampling helper * docs: document global singleton helpers * docs: document transcript tool helpers * docs: document exec safe-bin normalization * docs: document reaction level resolver * docs: document account snapshot redaction boundary * docs: document messaging target helpers * docs: document thread binding messages * docs: document conversation binding context * docs: document conversation resolution helper * docs: document owner display secret retention * docs: document provider request config types * docs: document skills config types * docs: document memory config types * docs: document imessage config types * docs: document crestodian config types * docs: document tools config policies * docs: document shared config base types * docs: document channel config contracts * docs: document openclaw config state types * docs: document model config contracts * docs: document shared agent config types * docs: document agent defaults config types * docs: document secret input contracts * docs: document auth config contracts * docs: document gateway config contracts * docs: document tool call stream repair contracts * docs: document memory host facades * docs: document llm core contracts * docs: document markdown core contracts * docs: document gateway connect error contracts * docs: document gateway protocol primitives * docs: document gateway frame schemas * docs: document gateway device schemas * docs: document gateway environment schemas * docs: document gateway push schemas * docs: document gateway plugin schemas * docs: document gateway artifact schemas * docs: document gateway command schemas * docs: document gateway task schemas * docs: document gateway exec approval schemas * docs: document gateway secret schemas * docs: document gateway config schemas * docs: document gateway snapshot schemas * docs: document gateway chat schemas * docs: document gateway wizard schemas * docs: document gateway node schemas * docs: document gateway plugin approval schemas * docs: document gateway talk schemas * docs: document gateway agent schemas * docs: document gateway session schemas * docs: document gateway cron schemas * docs: document gateway agent model skill schemas * docs: document gateway skill proposal tool schemas * docs: document gateway protocol registry * docs: document gateway channel status schemas * docs: document gateway schema regression tests * docs: document gateway schema barrel * docs: document gateway validator tests * docs: document gateway primitive push tests * docs: document gateway contract tests * docs: document native protocol guard * docs: document channel schema tests * docs: document gateway protocol smoke tests * docs: document gateway protocol entrypoint * docs: document gateway protocol type exports * docs: document gateway error codes * docs: document protocol schema registry * docs: document talk audio codec * docs: document talk activation names * docs: document talk consult questions * docs: document talk consult tool * docs: document talk run control contracts * docs: document talk run control adapter * docs: document talkback consult queue * docs: document talk consult transcript guard * docs: document talk fast context runtime * docs: document forced talk consult coordinator * docs: document talk output activity tracker * docs: document talk event metrics * docs: document talk diagnostics * docs: document talk observability hook * docs: document talk provider resolver * docs: document talk provider registry * docs: document talk runtime primitives * docs: document talk consult controller logs * docs: document channel identity helpers * docs: document channel account allowlist helpers * docs: document channel metadata draft controls * docs: document channel ingress policy * docs: document channel sender access gates * docs: document channel catalog message contracts * docs: document channel account plugin helpers * docs: document configured binding helpers * docs: document channel acp approval config helpers * docs: document channel bundled config write helpers * docs: document channel plugin utility contracts * docs: document channel config access helpers * docs: document channel message action helpers * docs: document channel outbound runtime helpers * docs: document channel pairing promotion helpers * docs: document channel registry helpers * docs: document channel setup wizard helpers * docs: document channel lifecycle status helpers * docs: document channel target thread helpers * docs: document channel session binding helpers * docs: document channel package module probes * docs: document channel setup wizard contracts * docs: document channel plugin API barrels * docs: document channel contract test helpers * docs: document channel core helpers * docs: document small core facades * docs: document provider runtime helpers * docs: document persistence and realtime helpers * docs: document mcp and state helpers * docs: document tool planner contracts * docs: document music generation runtime * docs: document crestodian command flow * docs: document utility helpers * docs: document node host helpers * docs: document transcript contracts * docs: document trajectory export contracts * docs: document image generation contracts * docs: document routing helper contracts * docs: document session helper contracts * docs: document video generation contracts * docs: document model catalog contracts * docs: document proxy capture contracts * docs: document status rendering contracts * docs: document test helper contracts * docs: document wizard setup contracts * docs: document process contracts * docs: document memory host sdk contracts * docs: document tts contracts * docs: document secrets runtime contracts * docs: document shared helper contracts * docs: document hook runtime contracts * docs: document security audit contracts * docs: document flow contracts * docs: document media understanding contracts * docs: document tui contracts * docs: document logging contracts * docs: document llm contracts * docs: document cron contracts * docs: document daemon contracts * docs: document task contracts * docs: document acp contracts * docs: document test utility contracts * docs: document skill contracts * docs: document config contracts * docs: document outbound infra contracts * docs: document command analysis contracts * docs: document provider usage infra contracts * docs: document file safety infra contracts * docs: document exec approval infra contracts * docs: document gateway runtime infra contracts * docs: document infra utility contracts * docs: document infra queue storage contracts * docs: document heartbeat infra contracts * docs: document remaining infra contracts * docs: document gateway auth contracts * docs: document gateway display helpers * docs: document gateway http helpers * docs: document gateway node helpers * docs: document gateway mcp helpers * docs: document gateway support helpers * docs: document gateway server runtime helpers * docs: document gateway runtime bootstrap helpers * docs: document gateway session events * docs: document gateway utility helpers * docs: document gateway talk helpers * docs: document gateway helper contracts * docs: document gateway server method helpers * docs: document gateway server auth helpers * docs: document gateway server tests * docs: document gateway test helpers * docs: document gateway node tests * docs: document gateway channel tests * docs: document gateway session tests * docs: document gateway server startup tests * docs: document gateway tool test helpers * docs: document gateway server test helpers * docs: document gateway server method tests * docs: document remaining gateway tests * docs: document plugin sdk public subpaths * docs: document plugin sdk runtime helpers * docs: document plugin sdk memory provider helpers * docs: document plugin sdk runtime facades * docs: document plugin sdk command approval helpers * docs: document plugin sdk runtime types * docs: document plugin sdk browser account helpers * docs: document plugin sdk media memory helpers * docs: document plugin sdk core tests * docs: document plugin sdk contract helpers * docs: document plugin sdk test helpers * docs: document remaining plugin sdk tests * docs: document cli utility helpers * docs: document cli runtime helpers * docs: document cli command registration helpers * docs: document node cli helpers * docs: document cli program registration * docs: document message cli registration * docs: document daemon cli helpers * docs: document cli route parsers
This commit is contained in:
committed by
GitHub
parent
8de37e1ce4
commit
0b8aabe864
@@ -2,7 +2,14 @@ import { Compile } from "typebox/compile";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { ChannelsStatusResultSchema, WebLoginWaitParamsSchema } from "./schema/channels.js";
|
||||
|
||||
/**
|
||||
* Channel schema regressions for browser login and status diagnostics.
|
||||
* These payloads are consumed by dashboard/operator UI, so QR payload bounds
|
||||
* and event-loop diagnostic shape are part of the public gateway contract.
|
||||
*/
|
||||
|
||||
describe("WebLoginWaitParamsSchema", () => {
|
||||
/** Compiled validator reused across QR bounds cases. */
|
||||
const validate = Compile(WebLoginWaitParamsSchema);
|
||||
|
||||
it("bounds caller-provided QR data URLs", () => {
|
||||
@@ -26,6 +33,7 @@ describe("WebLoginWaitParamsSchema", () => {
|
||||
});
|
||||
|
||||
describe("ChannelsStatusResultSchema", () => {
|
||||
/** Compiled status validator for channel docking diagnostics. */
|
||||
const validate = Compile(ChannelsStatusResultSchema);
|
||||
|
||||
it("accepts gateway event-loop diagnostics emitted by channels.status", () => {
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* Shared gateway client identity contract.
|
||||
*
|
||||
* These values cross the WebSocket handshake boundary, so additions must stay
|
||||
* aligned with protocol schemas and server policy checks.
|
||||
*/
|
||||
function normalizeOptionalLowercaseString(raw?: string | null): string | undefined {
|
||||
if (typeof raw !== "string") {
|
||||
return undefined;
|
||||
@@ -6,6 +12,7 @@ function normalizeOptionalLowercaseString(raw?: string | null): string | undefin
|
||||
return normalized || undefined;
|
||||
}
|
||||
|
||||
/** Canonical client ids accepted in gateway hello/connect payloads. */
|
||||
export const GATEWAY_CLIENT_IDS = {
|
||||
WEBCHAT_UI: "webchat-ui",
|
||||
CONTROL_UI: "openclaw-control-ui",
|
||||
@@ -30,6 +37,7 @@ export const GATEWAY_CLIENT_NAMES = GATEWAY_CLIENT_IDS;
|
||||
/** Compatibility alias for internal callers that still use "name" terminology. */
|
||||
export type GatewayClientName = GatewayClientId;
|
||||
|
||||
/** Coarse modes let policy group clients without matching every product id. */
|
||||
export const GATEWAY_CLIENT_MODES = {
|
||||
WEBCHAT: "webchat",
|
||||
CLI: "cli",
|
||||
@@ -45,16 +53,25 @@ export type GatewayClientMode = (typeof GATEWAY_CLIENT_MODES)[keyof typeof GATEW
|
||||
|
||||
/** Client metadata sent during gateway connection setup. */
|
||||
export type GatewayClientInfo = {
|
||||
/** Stable product/client identifier from `GATEWAY_CLIENT_IDS`. */
|
||||
id: GatewayClientId;
|
||||
/** Human-readable label for diagnostics; not used for policy decisions. */
|
||||
displayName?: string;
|
||||
/** Client app or package version reported by the connecting process. */
|
||||
version: string;
|
||||
/** Runtime platform string, such as `darwin`, `ios`, `android`, or `web`. */
|
||||
platform: string;
|
||||
/** Optional device family used by native clients for display and routing hints. */
|
||||
deviceFamily?: string;
|
||||
/** Native hardware/model identifier when available. */
|
||||
modelIdentifier?: string;
|
||||
/** Coarse category from `GATEWAY_CLIENT_MODES` for policy and diagnostics. */
|
||||
mode: GatewayClientMode;
|
||||
/** Per-installation or per-process id used to distinguish same-product clients. */
|
||||
instanceId?: string;
|
||||
};
|
||||
|
||||
/** Capability flags a client may advertise during the gateway handshake. */
|
||||
export const GATEWAY_CLIENT_CAPS = {
|
||||
TOOL_EVENTS: "tool-events",
|
||||
} as const;
|
||||
@@ -67,6 +84,8 @@ const GATEWAY_CLIENT_MODE_SET = new Set<GatewayClientMode>(Object.values(GATEWAY
|
||||
|
||||
/** Normalizes untrusted client ids and rejects unknown values. */
|
||||
export function normalizeGatewayClientId(raw?: string | null): GatewayClientId | undefined {
|
||||
// Handshake input is intentionally case-insensitive, but policy decisions use
|
||||
// the canonical lowercase ids from the closed registry above.
|
||||
const normalized = normalizeOptionalLowercaseString(raw);
|
||||
if (!normalized) {
|
||||
return undefined;
|
||||
|
||||
@@ -16,6 +16,14 @@ import {
|
||||
resolveAuthConnectErrorDetailCode,
|
||||
} from "./connect-error-details.js";
|
||||
|
||||
/**
|
||||
* Connect error detail regressions for Gateway/WebSocket clients.
|
||||
*
|
||||
* These tests pin structured auth/pairing details, human-readable fallback
|
||||
* formatting, and request-id sanitization because these strings surface in
|
||||
* control UI reconnect flows and device pairing diagnostics.
|
||||
*/
|
||||
|
||||
describe("readConnectErrorDetailCode", () => {
|
||||
it("reads structured detail codes", () => {
|
||||
expect(readConnectErrorDetailCode({ code: "AUTH_TOKEN_MISMATCH" })).toBe("AUTH_TOKEN_MISMATCH");
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* Shared gateway connect-error detail helpers.
|
||||
*
|
||||
* These details cross client/server boundaries, so readers normalize untrusted
|
||||
* payloads before using them in reconnect decisions or user-facing messages.
|
||||
*/
|
||||
function normalizeOptionalString(value: unknown): string | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
@@ -18,6 +24,7 @@ function normalizeArrayBackedTrimmedStringList(value: unknown): string[] | undef
|
||||
return values.length > 0 ? values : undefined;
|
||||
}
|
||||
|
||||
/** Structured connect-error codes carried in gateway error `details.code`. */
|
||||
export const ConnectErrorDetailCodes = {
|
||||
AUTH_REQUIRED: "AUTH_REQUIRED",
|
||||
AUTH_UNAUTHORIZED: "AUTH_UNAUTHORIZED",
|
||||
@@ -53,6 +60,7 @@ export const ConnectErrorDetailCodes = {
|
||||
export type ConnectErrorDetailCode =
|
||||
(typeof ConnectErrorDetailCodes)[keyof typeof ConnectErrorDetailCodes];
|
||||
|
||||
/** Pairing-specific reasons clients can display and use for reconnect policy. */
|
||||
export const ConnectPairingRequiredReasons = {
|
||||
NOT_PAIRED: "not-paired",
|
||||
ROLE_UPGRADE: "role-upgrade",
|
||||
@@ -63,6 +71,7 @@ export const ConnectPairingRequiredReasons = {
|
||||
export type ConnectPairingRequiredReason =
|
||||
(typeof ConnectPairingRequiredReasons)[keyof typeof ConnectPairingRequiredReasons];
|
||||
|
||||
/** Suggested client-side recovery action for structured connect errors. */
|
||||
export type ConnectRecoveryNextStep =
|
||||
| "retry_with_device_token"
|
||||
| "update_auth_configuration"
|
||||
@@ -70,11 +79,13 @@ export type ConnectRecoveryNextStep =
|
||||
| "wait_then_retry"
|
||||
| "review_auth_configuration";
|
||||
|
||||
/** Optional retry guidance extracted from gateway connect-error details. */
|
||||
export type ConnectErrorRecoveryAdvice = {
|
||||
canRetryWithDeviceToken?: boolean;
|
||||
recommendedNextStep?: ConnectRecoveryNextStep;
|
||||
};
|
||||
|
||||
/** Full structured details for pairing-required connect failures. */
|
||||
export type PairingConnectErrorDetails = {
|
||||
code: typeof ConnectErrorDetailCodes.PAIRING_REQUIRED;
|
||||
reason?: ConnectPairingRequiredReason;
|
||||
@@ -90,6 +101,7 @@ export type PairingConnectErrorDetails = {
|
||||
approvedScopes?: string[];
|
||||
};
|
||||
|
||||
/** Compact pairing-required subset used by reconnect/status surfaces. */
|
||||
export type ConnectPairingRequiredDetails = Pick<
|
||||
PairingConnectErrorDetails,
|
||||
"reason" | "requestId"
|
||||
@@ -152,6 +164,7 @@ const CONNECT_PAIRING_REQUIRED_MESSAGE_BY_REASON: Readonly<
|
||||
"metadata-upgrade": "device metadata change pending approval",
|
||||
};
|
||||
|
||||
/** Maps internal auth failure reasons to public connect-error detail codes. */
|
||||
export function resolveAuthConnectErrorDetailCode(
|
||||
reason: string | undefined,
|
||||
): ConnectErrorDetailCode {
|
||||
@@ -191,6 +204,7 @@ export function resolveAuthConnectErrorDetailCode(
|
||||
}
|
||||
}
|
||||
|
||||
/** Maps device-auth verifier reasons to public connect-error detail codes. */
|
||||
export function resolveDeviceAuthConnectErrorDetailCode(
|
||||
reason: string | undefined,
|
||||
): ConnectErrorDetailCode {
|
||||
@@ -212,6 +226,7 @@ export function resolveDeviceAuthConnectErrorDetailCode(
|
||||
}
|
||||
}
|
||||
|
||||
/** Reads a non-empty detail code from an untrusted error details payload. */
|
||||
export function readConnectErrorDetailCode(details: unknown): string | null {
|
||||
if (!details || typeof details !== "object" || Array.isArray(details)) {
|
||||
return null;
|
||||
@@ -220,6 +235,7 @@ export function readConnectErrorDetailCode(details: unknown): string | null {
|
||||
return typeof code === "string" && code.trim().length > 0 ? code : null;
|
||||
}
|
||||
|
||||
/** Extracts normalized retry advice from untrusted connect-error details. */
|
||||
export function readConnectErrorRecoveryAdvice(details: unknown): ConnectErrorRecoveryAdvice {
|
||||
if (!details || typeof details !== "object" || Array.isArray(details)) {
|
||||
return {};
|
||||
@@ -249,6 +265,7 @@ function normalizePairingConnectReason(value: unknown): ConnectPairingRequiredRe
|
||||
: undefined;
|
||||
}
|
||||
|
||||
/** Normalizes pairing request ids before echoing them in close reasons or UI text. */
|
||||
export function normalizePairingConnectRequestId(value: unknown): string | undefined {
|
||||
const normalized = normalizeOptionalString(value);
|
||||
return normalized && PAIRING_CONNECT_REQUEST_ID_PATTERN.test(normalized) ? normalized : undefined;
|
||||
@@ -287,6 +304,7 @@ function createPairingConnectErrorDetails(params: {
|
||||
};
|
||||
}
|
||||
|
||||
/** Human-readable requirement summary for a pairing-required reason. */
|
||||
export function describePairingConnectRequirement(
|
||||
reason: ConnectPairingRequiredReason | undefined,
|
||||
): string {
|
||||
@@ -295,6 +313,7 @@ export function describePairingConnectRequirement(
|
||||
: "device approval is required";
|
||||
}
|
||||
|
||||
/** Builds the gateway close/error message for a pairing-required connect failure. */
|
||||
export function buildPairingConnectErrorMessage(
|
||||
reason: ConnectPairingRequiredReason | undefined,
|
||||
): string {
|
||||
@@ -311,6 +330,7 @@ function buildPairingConnectRemediationHint(
|
||||
: "Approve the pending device request before retrying.";
|
||||
}
|
||||
|
||||
/** Short user-facing recovery title for pairing-required connect failures. */
|
||||
export function buildPairingConnectRecoveryTitle(
|
||||
reason: ConnectPairingRequiredReason | undefined,
|
||||
): string {
|
||||
@@ -319,6 +339,7 @@ export function buildPairingConnectRecoveryTitle(
|
||||
: "Gateway pairing approval required.";
|
||||
}
|
||||
|
||||
/** Builds sanitized structured details for a pairing-required connect failure. */
|
||||
export function buildPairingConnectErrorDetails(params: {
|
||||
reason: ConnectPairingRequiredReason | undefined;
|
||||
requestId?: string;
|
||||
@@ -356,6 +377,7 @@ export function buildPairingConnectErrorDetails(params: {
|
||||
});
|
||||
}
|
||||
|
||||
/** Builds a sanitized close reason string for WebSocket pairing rejections. */
|
||||
export function buildPairingConnectCloseReason(params: {
|
||||
reason: ConnectPairingRequiredReason | undefined;
|
||||
requestId?: string;
|
||||
@@ -365,6 +387,7 @@ export function buildPairingConnectCloseReason(params: {
|
||||
return requestId ? `${message} (requestId: ${requestId})` : message;
|
||||
}
|
||||
|
||||
/** Reads and backfills pairing-required details from an untrusted details object. */
|
||||
export function readPairingConnectErrorDetails(
|
||||
details: unknown,
|
||||
): PairingConnectErrorDetails | null {
|
||||
@@ -417,6 +440,7 @@ export function readPairingConnectErrorDetails(
|
||||
});
|
||||
}
|
||||
|
||||
/** Reads the compact pairing-required subset from untrusted connect details. */
|
||||
export function readConnectPairingRequiredDetails(
|
||||
details: unknown,
|
||||
): ConnectPairingRequiredDetails | null {
|
||||
@@ -430,6 +454,7 @@ export function readConnectPairingRequiredDetails(
|
||||
};
|
||||
}
|
||||
|
||||
/** Parses legacy/string-only pairing-required messages into structured details. */
|
||||
export function readConnectPairingRequiredMessage(
|
||||
message: string | null | undefined,
|
||||
): ConnectPairingRequiredDetails | null {
|
||||
@@ -462,6 +487,7 @@ export function readConnectPairingRequiredMessage(
|
||||
};
|
||||
}
|
||||
|
||||
/** Formats pairing-required details into the canonical user-facing message. */
|
||||
export function formatConnectPairingRequiredMessage(details: unknown): string {
|
||||
const pairing = readPairingConnectErrorDetails(details);
|
||||
const base =
|
||||
@@ -471,6 +497,7 @@ export function formatConnectPairingRequiredMessage(details: unknown): string {
|
||||
return pairing?.requestId ? `${base} (requestId: ${pairing.requestId})` : base;
|
||||
}
|
||||
|
||||
/** Formats connect errors using structured details before falling back to raw messages. */
|
||||
export function formatConnectErrorMessage(params: { message?: string; details?: unknown }): string {
|
||||
if (readConnectErrorDetailCode(params.details) === ConnectErrorDetailCodes.PAIRING_REQUIRED) {
|
||||
return formatConnectPairingRequiredMessage(params.details);
|
||||
|
||||
@@ -9,6 +9,14 @@ import {
|
||||
validateCronUpdateParams,
|
||||
} from "./index.js";
|
||||
|
||||
/**
|
||||
* Cron validator regressions for public scheduler RPC payloads.
|
||||
*
|
||||
* The cases cover both canonical `id` selectors and legacy `jobId` aliases,
|
||||
* delivery routing, update clears, and run-log path traversal guards.
|
||||
*/
|
||||
|
||||
/** Smallest valid cron job create payload shared by add/update variations. */
|
||||
const minimalAddParams = {
|
||||
name: "daily-summary",
|
||||
schedule: { kind: "every", everyMs: 60_000 },
|
||||
|
||||
@@ -5,6 +5,12 @@ import {
|
||||
validateExecApprovalsSetParams,
|
||||
} from "./index.js";
|
||||
|
||||
/**
|
||||
* Exec approval validator regressions for gateway and node-scoped policy
|
||||
* writes. The fixtures pin runtime-owned allowlist metadata and command-span
|
||||
* bounds because those contracts are consumed by approval UI and replay logic.
|
||||
*/
|
||||
|
||||
describe("exec approvals protocol validators", () => {
|
||||
it("accepts runtime-owned allowlist metadata on gateway and node set payloads", () => {
|
||||
const file = {
|
||||
|
||||
@@ -36,6 +36,15 @@ import {
|
||||
type ValidationError,
|
||||
} from "./index.js";
|
||||
|
||||
/**
|
||||
* Broad protocol validator smoke tests.
|
||||
*
|
||||
* This file exercises exported lazy validators, readable validation errors, and
|
||||
* representative cross-surface payloads so schema registry changes fail before
|
||||
* they reach CLI, Gateway, channel, or dashboard consumers.
|
||||
*/
|
||||
|
||||
/** Builds a validation error fixture while keeping only the field under test noisy. */
|
||||
const makeError = (overrides: Partial<ValidationError>): ValidationError => ({
|
||||
keyword: "type",
|
||||
instancePath: "",
|
||||
@@ -45,6 +54,7 @@ const makeError = (overrides: Partial<ValidationError>): ValidationError => ({
|
||||
...overrides,
|
||||
});
|
||||
|
||||
/** Runtime shape shared by all exported lazy protocol validator functions. */
|
||||
type ProtocolValidator = (value: unknown) => boolean;
|
||||
|
||||
describe("lazy protocol validators", () => {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Public gateway protocol entrypoint. Keep this barrel aligned with schema.ts
|
||||
// so clients can import wire types, JSON schemas, and validators from one place.
|
||||
import { Compile, type Validator as TypeBoxValidator } from "typebox/compile";
|
||||
import {
|
||||
type AgentEvent,
|
||||
@@ -464,11 +466,16 @@ export type ValidationError = {
|
||||
message?: string;
|
||||
};
|
||||
|
||||
/** Runtime validator shape shared by gateway clients and server handlers. */
|
||||
export type ProtocolValidator<T = unknown> = ((data: unknown) => data is T) & {
|
||||
/** Last validation errors, matching Ajv-style caller expectations. */
|
||||
errors: ValidationError[] | null;
|
||||
/** Original schema used by the validator, exposed for diagnostics/tests. */
|
||||
schema: unknown;
|
||||
};
|
||||
|
||||
// Defer TypeBox compilation until the first validation call. Importing this
|
||||
// module is common in CLIs/tests, so eager compilation would add startup cost.
|
||||
function lazyCompile<T = unknown>(schema: unknown): ProtocolValidator<T> {
|
||||
let compiled: TypeBoxValidator | undefined;
|
||||
let errors: ValidationError[] | null = null;
|
||||
@@ -491,6 +498,7 @@ function lazyCompile<T = unknown>(schema: unknown): ProtocolValidator<T> {
|
||||
enumerable: true,
|
||||
get: () => errors,
|
||||
set: (nextErrors: ValidationError[] | null | undefined) => {
|
||||
// Preserve Ajv-compatible mutability for callers/tests that clear errors.
|
||||
errors = nextErrors ?? null;
|
||||
},
|
||||
},
|
||||
@@ -504,6 +512,8 @@ function lazyCompile<T = unknown>(schema: unknown): ProtocolValidator<T> {
|
||||
return validate;
|
||||
}
|
||||
|
||||
// Public per-method validators. Names intentionally mirror the exported schema
|
||||
// constants so call sites can pair validation with the wire contract directly.
|
||||
export const validateCommandsListParams = lazyCompile<CommandsListParams>(CommandsListParamsSchema);
|
||||
export const validateConnectParams = lazyCompile<ConnectParams>(ConnectParamsSchema);
|
||||
export const validateRequestFrame = lazyCompile<RequestFrame>(RequestFrameSchema);
|
||||
@@ -873,6 +883,7 @@ function firstStringParam(value: unknown): string | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Convert validator errors into compact operator-facing failure text. */
|
||||
export function formatValidationErrors(errors: ValidationError[] | null | undefined) {
|
||||
if (!errors?.length) {
|
||||
return "unknown validation error";
|
||||
@@ -907,6 +918,8 @@ export function formatValidationErrors(errors: ValidationError[] | null | undefi
|
||||
|
||||
const failingKeyword =
|
||||
typeof err?.params?.failingKeyword === "string" ? err.params.failingKeyword : "";
|
||||
// TypeBox reports conditional required-property misses through if/then
|
||||
// keywords, which otherwise hide the actionable missing-property context.
|
||||
const message =
|
||||
keyword === "then" || (keyword === "if" && failingKeyword === "then")
|
||||
? "must have required conditional properties"
|
||||
@@ -925,6 +938,8 @@ export function formatValidationErrors(errors: ValidationError[] | null | undefi
|
||||
return unique.join("; ");
|
||||
}
|
||||
|
||||
// Schema exports stay explicit to make additions/removals reviewable as public
|
||||
// protocol surface changes.
|
||||
export {
|
||||
ConnectParamsSchema,
|
||||
HelloOkSchema,
|
||||
@@ -1132,6 +1147,7 @@ export {
|
||||
errorShape,
|
||||
};
|
||||
|
||||
// Type exports mirror the schema exports for downstream TypeScript consumers.
|
||||
export type {
|
||||
GatewayFrame,
|
||||
ConnectParams,
|
||||
|
||||
@@ -3,6 +3,15 @@ import path from "node:path";
|
||||
import { describe, it } from "vitest";
|
||||
import { MIN_CLIENT_PROTOCOL_VERSION, PROTOCOL_VERSION } from "./version.js";
|
||||
|
||||
/**
|
||||
* Cross-language guard for Gateway protocol version constants.
|
||||
*
|
||||
* Native Swift/Kotlin clients and dev smoke scripts cannot derive these values
|
||||
* from TypeScript at runtime, so this test keeps checked-in generated constants
|
||||
* and connect payloads aligned with the package source of truth.
|
||||
*/
|
||||
|
||||
/** Min/max protocol pair expected in every native client surface. */
|
||||
type ProtocolLevels = {
|
||||
min: number;
|
||||
max: number;
|
||||
@@ -13,10 +22,12 @@ const expectedLevels: ProtocolLevels = {
|
||||
max: PROTOCOL_VERSION,
|
||||
};
|
||||
|
||||
/** Reads a repo-relative source file used by a native protocol guard. */
|
||||
async function readRepoFile(relativePath: string): Promise<string> {
|
||||
return fs.readFile(path.join(process.cwd(), relativePath), "utf8");
|
||||
}
|
||||
|
||||
/** Extracts one integer constant and reports the owning file on drift. */
|
||||
function extractInteger(
|
||||
content: string,
|
||||
pattern: RegExp,
|
||||
@@ -32,6 +43,7 @@ function extractInteger(
|
||||
return Number.parseInt(match[1], 10);
|
||||
}
|
||||
|
||||
/** Compares native min/max values to the TypeScript version constants. */
|
||||
function assertLevelsMatch(relativePath: string, actual: ProtocolLevels): void {
|
||||
if (actual.min === expectedLevels.min && actual.max === expectedLevels.max) {
|
||||
return;
|
||||
@@ -41,6 +53,7 @@ function assertLevelsMatch(relativePath: string, actual: ProtocolLevels): void {
|
||||
);
|
||||
}
|
||||
|
||||
/** Asserts a compatibility pattern exists in generated/native source text. */
|
||||
function assertPattern(
|
||||
content: string,
|
||||
relativePath: string,
|
||||
|
||||
@@ -6,6 +6,11 @@ import {
|
||||
} from "../../../src/test-utils/secret-ref-test-vectors.js";
|
||||
import { SecretInputSchema, SecretRefSchema } from "./schema/primitives.js";
|
||||
|
||||
/**
|
||||
* SecretRef schema regressions shared with core secret-ref test vectors.
|
||||
* Exec-backed ids have stricter character rules than env/file refs, so these
|
||||
* checks keep provider config payloads aligned with runtime secret resolution.
|
||||
*/
|
||||
describe("gateway protocol SecretRef schema", () => {
|
||||
const validateSecretRef = Compile(SecretRefSchema);
|
||||
const validateSecretInput = Compile(SecretInputSchema);
|
||||
|
||||
@@ -2,6 +2,11 @@ import { Compile } from "typebox/compile";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { PushTestResultSchema } from "./schema/push.js";
|
||||
|
||||
/**
|
||||
* Push protocol schema regression for APNS test results.
|
||||
* The transport field tells operators whether delivery used direct APNS or the
|
||||
* relay path, so it is part of the public result contract.
|
||||
*/
|
||||
describe("gateway protocol push schema", () => {
|
||||
const validatePushTestResult = Compile(PushTestResultSchema);
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* Public schema barrel for the gateway protocol package.
|
||||
*
|
||||
* Runtime validators import canonical TypeBox schemas from their owning modules;
|
||||
* this barrel gives package consumers one stable path for schema-level imports.
|
||||
*/
|
||||
export * from "./schema/primitives.js";
|
||||
export * from "./schema/agent.js";
|
||||
export * from "./schema/agents-models-skills.js";
|
||||
|
||||
@@ -2,6 +2,11 @@ import { Value } from "typebox/value";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { AgentParamsSchema } from "./agent.js";
|
||||
|
||||
/**
|
||||
* Regression coverage for agent-run schema payloads that carry internal
|
||||
* completion events. These events are produced by child automation and consumed
|
||||
* by parent agent runs, so the fixture mirrors the cross-runtime boundary.
|
||||
*/
|
||||
type AgentInternalEvent = {
|
||||
type: "task_completion";
|
||||
source: string;
|
||||
@@ -17,6 +22,7 @@ type AgentInternalEvent = {
|
||||
replyInstruction?: string;
|
||||
};
|
||||
|
||||
/** Builds the smallest valid agent request that embeds one internal event. */
|
||||
function makeAgentParamsWithInternalEvent(event: AgentInternalEvent) {
|
||||
return {
|
||||
message: "A music generation task finished. Process the completion update now.",
|
||||
@@ -26,6 +32,7 @@ function makeAgentParamsWithInternalEvent(event: AgentInternalEvent) {
|
||||
};
|
||||
}
|
||||
|
||||
/** Representative generated-media completion event from a child task. */
|
||||
const musicCompletionEvent: AgentInternalEvent = {
|
||||
type: "task_completion",
|
||||
source: "music_generation",
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import { Type } from "typebox";
|
||||
import { InputProvenanceSchema, NonEmptyString, SessionLabelString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Agent and channel-action gateway schemas.
|
||||
*
|
||||
* These payloads sit on the boundary between external channel adapters, gateway
|
||||
* RPC callers, and the agent runtime. Keep public request fields documented
|
||||
* because older CLI/channel clients may continue sending them across releases.
|
||||
*/
|
||||
const AGENT_INTERNAL_EVENT_TYPE_TASK_COMPLETION = "task_completion";
|
||||
const AGENT_INTERNAL_EVENT_SOURCES = [
|
||||
"subagent",
|
||||
@@ -11,6 +18,7 @@ const AGENT_INTERNAL_EVENT_SOURCES = [
|
||||
] as const;
|
||||
const AGENT_INTERNAL_EVENT_STATUSES = ["ok", "timeout", "error", "unknown"] as const;
|
||||
|
||||
/** Generated media/file attachment metadata carried by internal agent events. */
|
||||
export const AgentGeneratedAttachmentSchema = Type.Object(
|
||||
{
|
||||
type: Type.Optional(Type.String({ enum: ["image", "audio", "video", "file"] })),
|
||||
@@ -24,6 +32,7 @@ export const AgentGeneratedAttachmentSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Internal completion event surfaced when child automation reports back to a parent run. */
|
||||
export const AgentInternalEventSchema = Type.Object(
|
||||
{
|
||||
type: Type.Literal(AGENT_INTERNAL_EVENT_TYPE_TASK_COMPLETION),
|
||||
@@ -43,6 +52,7 @@ export const AgentInternalEventSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Stream event emitted by the agent runtime over the gateway protocol. */
|
||||
export const AgentEventSchema = Type.Object(
|
||||
{
|
||||
runId: NonEmptyString,
|
||||
@@ -56,6 +66,7 @@ export const AgentEventSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Channel context injected into message actions so tools can reply in-place. */
|
||||
export const MessageActionToolContextSchema = Type.Object(
|
||||
{
|
||||
currentChannelId: Type.Optional(Type.String()),
|
||||
@@ -84,6 +95,7 @@ export const MessageActionToolContextSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Request to execute a channel message action through a configured adapter. */
|
||||
export const MessageActionParamsSchema = Type.Object(
|
||||
{
|
||||
channel: NonEmptyString,
|
||||
@@ -106,6 +118,7 @@ export const MessageActionParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Outbound send request shared by channel adapters. */
|
||||
export const SendParamsSchema = Type.Object(
|
||||
{
|
||||
to: NonEmptyString,
|
||||
@@ -135,6 +148,7 @@ export const SendParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Poll creation request for adapters that support native polls. */
|
||||
export const PollParamsSchema = Type.Object(
|
||||
{
|
||||
to: NonEmptyString,
|
||||
@@ -157,6 +171,7 @@ export const PollParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Main agent-run request accepted by the gateway. */
|
||||
export const AgentParamsSchema = Type.Object(
|
||||
{
|
||||
message: NonEmptyString,
|
||||
@@ -212,6 +227,7 @@ export const AgentParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Identity lookup request for the current or selected agent/session. */
|
||||
export const AgentIdentityParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
@@ -220,6 +236,7 @@ export const AgentIdentityParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Public display identity returned for an agent. */
|
||||
export const AgentIdentityResultSchema = Type.Object(
|
||||
{
|
||||
agentId: NonEmptyString,
|
||||
@@ -233,6 +250,7 @@ export const AgentIdentityResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Waits for a submitted agent run to complete or time out. */
|
||||
export const AgentWaitParamsSchema = Type.Object(
|
||||
{
|
||||
runId: NonEmptyString,
|
||||
@@ -241,6 +259,7 @@ export const AgentWaitParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Wake request from external schedulers or devices into an agent session. */
|
||||
export const WakeParamsSchema = Type.Object(
|
||||
{
|
||||
mode: Type.Union([Type.Literal("now"), Type.Literal("next-heartbeat")]),
|
||||
|
||||
@@ -6,6 +6,13 @@ import {
|
||||
ToolsEffectiveResultSchema,
|
||||
} from "./agents-models-skills.js";
|
||||
|
||||
/**
|
||||
* Schema regression tests for agent metadata, skill proposals, and effective
|
||||
* tool catalogs. These payloads are UI-facing but also consumed by runtime
|
||||
* guards, so the fixtures exercise strictness at the public gateway boundary.
|
||||
*/
|
||||
|
||||
/** Minimal effective-tools result used by strict notice tests. */
|
||||
function toolsEffectiveResult() {
|
||||
return {
|
||||
agentId: "main",
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
import { Type } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Agent, model, skill, and tool catalog schemas.
|
||||
*
|
||||
* These contracts back dashboard selectors, agent management, model catalogs,
|
||||
* skill upload/install flows, skill workshop proposals, and effective tool
|
||||
* discovery. Keep public request/result schemas documented because they are
|
||||
* shared by gateway RPC, CLI, and UI clients.
|
||||
*/
|
||||
|
||||
/** Model option shown in selectors and model catalog results. */
|
||||
export const ModelChoiceSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -13,6 +23,7 @@ export const ModelChoiceSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Condensed agent record returned by list APIs. */
|
||||
export const AgentSummarySchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -73,8 +84,10 @@ export const AgentSummarySchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Empty request payload for listing configured agents. */
|
||||
export const AgentsListParamsSchema = Type.Object({}, { additionalProperties: false });
|
||||
|
||||
/** Agent list result including the default agent and session scoping mode. */
|
||||
export const AgentsListResultSchema = Type.Object(
|
||||
{
|
||||
defaultId: NonEmptyString,
|
||||
@@ -85,6 +98,7 @@ export const AgentsListResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Creates a configured agent with workspace, identity, and optional model. */
|
||||
export const AgentsCreateParamsSchema = Type.Object(
|
||||
{
|
||||
name: NonEmptyString,
|
||||
@@ -96,6 +110,7 @@ export const AgentsCreateParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Result returned after creating an agent. */
|
||||
export const AgentsCreateResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Literal(true),
|
||||
@@ -107,6 +122,7 @@ export const AgentsCreateResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Updates mutable agent identity, workspace, and model fields. */
|
||||
export const AgentsUpdateParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: NonEmptyString,
|
||||
@@ -119,6 +135,7 @@ export const AgentsUpdateParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Result returned after updating an agent. */
|
||||
export const AgentsUpdateResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Literal(true),
|
||||
@@ -127,6 +144,7 @@ export const AgentsUpdateResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Deletes an agent and optionally its workspace/config files. */
|
||||
export const AgentsDeleteParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: NonEmptyString,
|
||||
@@ -135,6 +153,7 @@ export const AgentsDeleteParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Result returned after deleting an agent and unbinding sessions. */
|
||||
export const AgentsDeleteResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Literal(true),
|
||||
@@ -144,6 +163,7 @@ export const AgentsDeleteResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** File metadata and optional content for agent-local editable files. */
|
||||
export const AgentsFileEntrySchema = Type.Object(
|
||||
{
|
||||
name: NonEmptyString,
|
||||
@@ -156,6 +176,7 @@ export const AgentsFileEntrySchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Lists editable files for one agent. */
|
||||
export const AgentsFilesListParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: NonEmptyString,
|
||||
@@ -163,6 +184,7 @@ export const AgentsFilesListParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Editable file list for an agent workspace. */
|
||||
export const AgentsFilesListResultSchema = Type.Object(
|
||||
{
|
||||
agentId: NonEmptyString,
|
||||
@@ -172,6 +194,7 @@ export const AgentsFilesListResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Reads one editable agent file by name. */
|
||||
export const AgentsFilesGetParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: NonEmptyString,
|
||||
@@ -180,6 +203,7 @@ export const AgentsFilesGetParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Result for reading one editable agent file. */
|
||||
export const AgentsFilesGetResultSchema = Type.Object(
|
||||
{
|
||||
agentId: NonEmptyString,
|
||||
@@ -189,6 +213,7 @@ export const AgentsFilesGetResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Writes one editable agent file. */
|
||||
export const AgentsFilesSetParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: NonEmptyString,
|
||||
@@ -198,6 +223,7 @@ export const AgentsFilesSetParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Result returned after writing an editable agent file. */
|
||||
export const AgentsFilesSetResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Literal(true),
|
||||
@@ -208,6 +234,7 @@ export const AgentsFilesSetResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Model catalog request with optional visibility scope. */
|
||||
export const ModelsListParamsSchema = Type.Object(
|
||||
{
|
||||
view: Type.Optional(
|
||||
@@ -217,6 +244,7 @@ export const ModelsListParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Model catalog result. */
|
||||
export const ModelsListResultSchema = Type.Object(
|
||||
{
|
||||
models: Type.Array(ModelChoiceSchema),
|
||||
@@ -224,6 +252,7 @@ export const ModelsListResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Reads installed skill status, optionally for a selected agent. */
|
||||
export const SkillsStatusParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
@@ -231,8 +260,10 @@ export const SkillsStatusParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Empty request payload for listing available skill bins. */
|
||||
export const SkillsBinsParamsSchema = Type.Object({}, { additionalProperties: false });
|
||||
|
||||
/** Skill bin names available to the gateway. */
|
||||
export const SkillsBinsResultSchema = Type.Object(
|
||||
{
|
||||
bins: Type.Array(NonEmptyString),
|
||||
@@ -254,6 +285,7 @@ const SkillUploadDataBase64String = Type.String({
|
||||
maxLength: 5_592_408,
|
||||
});
|
||||
|
||||
/** Starts a chunked skill archive upload. */
|
||||
export const SkillsUploadBeginParamsSchema = Type.Object(
|
||||
{
|
||||
kind: Type.Literal("skill-archive"),
|
||||
@@ -266,6 +298,7 @@ export const SkillsUploadBeginParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Uploads one base64-encoded chunk for a skill archive. */
|
||||
export const SkillsUploadChunkParamsSchema = Type.Object(
|
||||
{
|
||||
uploadId: NonEmptyString,
|
||||
@@ -275,6 +308,7 @@ export const SkillsUploadChunkParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Commits a completed skill archive upload. */
|
||||
export const SkillsUploadCommitParamsSchema = Type.Object(
|
||||
{
|
||||
uploadId: NonEmptyString,
|
||||
@@ -283,6 +317,7 @@ export const SkillsUploadCommitParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Installs a skill from legacy install id, ClawHub, or uploaded archive. */
|
||||
export const SkillsInstallParamsSchema = Type.Union([
|
||||
Type.Object(
|
||||
{
|
||||
@@ -322,6 +357,7 @@ export const SkillsInstallParamsSchema = Type.Union([
|
||||
),
|
||||
]);
|
||||
|
||||
/** Updates installed skill settings or refreshes ClawHub-installed skills. */
|
||||
export const SkillsUpdateParamsSchema = Type.Union([
|
||||
Type.Object(
|
||||
{
|
||||
@@ -342,6 +378,7 @@ export const SkillsUpdateParamsSchema = Type.Union([
|
||||
),
|
||||
]);
|
||||
|
||||
/** Searches the skill registry. */
|
||||
export const SkillsSearchParamsSchema = Type.Object(
|
||||
{
|
||||
query: Type.Optional(NonEmptyString),
|
||||
@@ -350,6 +387,7 @@ export const SkillsSearchParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Ranked skill registry search results. */
|
||||
export const SkillsSearchResultSchema = Type.Object(
|
||||
{
|
||||
results: Type.Array(
|
||||
@@ -369,6 +407,7 @@ export const SkillsSearchResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Reads registry detail for one skill slug. */
|
||||
export const SkillsDetailParamsSchema = Type.Object(
|
||||
{
|
||||
slug: NonEmptyString,
|
||||
@@ -376,6 +415,7 @@ export const SkillsDetailParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Reads current security verdicts for configured skills. */
|
||||
export const SkillsSecurityVerdictsParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
@@ -383,6 +423,7 @@ export const SkillsSecurityVerdictsParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Skill registry detail, latest version, metadata, and owner info. */
|
||||
export const SkillsDetailResultSchema = Type.Object(
|
||||
{
|
||||
skill: Type.Union([
|
||||
@@ -441,6 +482,7 @@ export const SkillsDetailResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Security verdict report for installed/requested skills. */
|
||||
export const SkillsSecurityVerdictsResultSchema = Type.Object(
|
||||
{
|
||||
schema: Type.Literal("openclaw.skills.security-verdicts.v1"),
|
||||
@@ -481,6 +523,7 @@ export const SkillsSecurityVerdictsResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Reads the rendered skill card for one installed skill. */
|
||||
export const SkillsSkillCardParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
@@ -489,6 +532,7 @@ export const SkillsSkillCardParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Rendered skill card content and file metadata. */
|
||||
export const SkillsSkillCardResultSchema = Type.Object(
|
||||
{
|
||||
schema: Type.Literal("openclaw.skills.skill-card.v1"),
|
||||
@@ -507,19 +551,23 @@ const SkillProposalStatusSchema = Type.Union([
|
||||
Type.Literal("quarantined"),
|
||||
Type.Literal("stale"),
|
||||
]);
|
||||
/** Skill proposal operation type: new skill or update to an existing skill. */
|
||||
const SkillProposalKindSchema = Type.Union([Type.Literal("create"), Type.Literal("update")]);
|
||||
/** Scan state for proposed skill content before it can be applied. */
|
||||
const SkillProposalScanStateSchema = Type.Union([
|
||||
Type.Literal("pending"),
|
||||
Type.Literal("clean"),
|
||||
Type.Literal("failed"),
|
||||
Type.Literal("quarantined"),
|
||||
]);
|
||||
/** Source that created the skill proposal record. */
|
||||
const SkillProposalSourceSchema = Type.Union([
|
||||
Type.Literal("skill-workshop"),
|
||||
Type.Literal("cli"),
|
||||
Type.Literal("gateway"),
|
||||
]);
|
||||
const SkillProposalContentString = Type.String({ minLength: 1, maxLength: 1_048_576 });
|
||||
/** Support file payload accepted from proposal create/revise requests. */
|
||||
const SkillProposalSupportFileInputSchema = Type.Object(
|
||||
{
|
||||
path: NonEmptyString,
|
||||
@@ -527,6 +575,7 @@ const SkillProposalSupportFileInputSchema = Type.Object(
|
||||
},
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
/** Stored support file metadata, including target conflict hashes for updates. */
|
||||
const SkillProposalSupportFileSchema = Type.Object(
|
||||
{
|
||||
path: NonEmptyString,
|
||||
@@ -538,6 +587,7 @@ const SkillProposalSupportFileSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** One static-scan finding against proposed skill content. */
|
||||
const SkillProposalFindingSchema = Type.Object(
|
||||
{
|
||||
ruleId: NonEmptyString,
|
||||
@@ -550,6 +600,7 @@ const SkillProposalFindingSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Aggregated scan report attached to a proposal record. */
|
||||
const SkillProposalScanSchema = Type.Object(
|
||||
{
|
||||
state: SkillProposalScanStateSchema,
|
||||
@@ -562,6 +613,7 @@ const SkillProposalScanSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Skill file target that a proposal creates or updates. */
|
||||
const SkillProposalTargetSchema = Type.Object(
|
||||
{
|
||||
skillName: NonEmptyString,
|
||||
@@ -574,6 +626,7 @@ const SkillProposalTargetSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Optional runtime origin tying a proposal back to an agent turn. */
|
||||
const SkillProposalOriginSchema = Type.Object(
|
||||
{
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
@@ -584,6 +637,7 @@ const SkillProposalOriginSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Full persisted skill proposal record. */
|
||||
const SkillProposalRecordSchema = Type.Object(
|
||||
{
|
||||
schema: Type.Literal("openclaw.skill-workshop.proposal.v1"),
|
||||
@@ -613,6 +667,7 @@ const SkillProposalRecordSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Condensed proposal manifest entry for list views. */
|
||||
const SkillProposalManifestEntrySchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -629,6 +684,7 @@ const SkillProposalManifestEntrySchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Lists skill-workshop proposals for the selected agent scope. */
|
||||
export const SkillsProposalsListParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
@@ -636,6 +692,7 @@ export const SkillsProposalsListParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Proposal manifest response for dashboard/workshop list views. */
|
||||
export const SkillsProposalsListResultSchema = Type.Object(
|
||||
{
|
||||
schema: Type.Literal("openclaw.skill-workshop.proposals-manifest.v1"),
|
||||
@@ -645,6 +702,7 @@ export const SkillsProposalsListResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Reads a proposal record plus editable draft/support content. */
|
||||
export const SkillsProposalInspectParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
@@ -653,6 +711,7 @@ export const SkillsProposalInspectParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Full proposal inspection result used before apply/revise decisions. */
|
||||
export const SkillsProposalInspectResultSchema = Type.Object(
|
||||
{
|
||||
record: SkillProposalRecordSchema,
|
||||
@@ -662,6 +721,7 @@ export const SkillsProposalInspectResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Creates a proposal for a new skill. */
|
||||
export const SkillsProposalCreateParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
@@ -675,6 +735,7 @@ export const SkillsProposalCreateParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Creates a proposal to update an existing skill. */
|
||||
export const SkillsProposalUpdateParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
@@ -688,6 +749,7 @@ export const SkillsProposalUpdateParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Replaces draft content/support files for an existing proposal. */
|
||||
export const SkillsProposalReviseParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
@@ -701,6 +763,7 @@ export const SkillsProposalReviseParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Shared approve/reject/quarantine action payload for one proposal. */
|
||||
export const SkillsProposalActionParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
@@ -710,6 +773,7 @@ export const SkillsProposalActionParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Result returned after applying a skill proposal to disk. */
|
||||
export const SkillsProposalApplyResultSchema = Type.Object(
|
||||
{
|
||||
record: SkillProposalRecordSchema,
|
||||
@@ -718,8 +782,10 @@ export const SkillsProposalApplyResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Proposal record result returned after non-apply proposal actions. */
|
||||
export const SkillsProposalRecordResultSchema = SkillProposalRecordSchema;
|
||||
|
||||
/** Reads the configured tool catalog for an agent. */
|
||||
export const ToolsCatalogParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
@@ -728,6 +794,7 @@ export const ToolsCatalogParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Reads the effective tool set for one session. */
|
||||
export const ToolsEffectiveParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
@@ -736,6 +803,7 @@ export const ToolsEffectiveParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Invokes one tool through the gateway tool dispatcher. */
|
||||
export const ToolsInvokeParamsSchema = Type.Object(
|
||||
{
|
||||
name: NonEmptyString,
|
||||
@@ -748,6 +816,7 @@ export const ToolsInvokeParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Tool profile shown in catalog views. */
|
||||
export const ToolCatalogProfileSchema = Type.Object(
|
||||
{
|
||||
id: Type.Union([
|
||||
@@ -761,6 +830,7 @@ export const ToolCatalogProfileSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Tool catalog entry before session-specific filtering is applied. */
|
||||
export const ToolCatalogEntrySchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -785,6 +855,7 @@ export const ToolCatalogEntrySchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Group of related catalog tools from core or a plugin. */
|
||||
export const ToolCatalogGroupSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -796,6 +867,7 @@ export const ToolCatalogGroupSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Tool catalog result for agent configuration UI. */
|
||||
export const ToolsCatalogResultSchema = Type.Object(
|
||||
{
|
||||
agentId: NonEmptyString,
|
||||
@@ -805,6 +877,7 @@ export const ToolsCatalogResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Effective tool entry after session/profile/channel/plugin filtering. */
|
||||
export const ToolsEffectiveEntrySchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -827,6 +900,7 @@ export const ToolsEffectiveEntrySchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Effective tool group shown to runtime/session callers. */
|
||||
export const ToolsEffectiveGroupSchema = Type.Object(
|
||||
{
|
||||
id: Type.Union([
|
||||
@@ -847,6 +921,7 @@ export const ToolsEffectiveGroupSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Notice explaining runtime filtering such as quarantined tool schemas. */
|
||||
export const ToolsEffectiveNoticeSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -856,6 +931,7 @@ export const ToolsEffectiveNoticeSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Effective tool set for a session, including profile and filtering notices. */
|
||||
export const ToolsEffectiveResultSchema = Type.Object(
|
||||
{
|
||||
agentId: NonEmptyString,
|
||||
@@ -866,6 +942,7 @@ export const ToolsEffectiveResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Normalized error shape for tool invocation failures. */
|
||||
export const ToolsInvokeErrorSchema = Type.Object(
|
||||
{
|
||||
code: NonEmptyString,
|
||||
@@ -875,6 +952,7 @@ export const ToolsInvokeErrorSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Tool invocation result, including approval handoff when required. */
|
||||
export const ToolsInvokeResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Boolean(),
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { Type } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Artifact lookup and download protocol schemas.
|
||||
*
|
||||
* Artifacts are files or payloads produced by sessions, runs, tasks, or agents;
|
||||
* these schemas keep lookup filters explicit and download results transport-safe.
|
||||
*/
|
||||
const ArtifactQueryParamsProperties = {
|
||||
sessionKey: Type.Optional(NonEmptyString),
|
||||
runId: Type.Optional(NonEmptyString),
|
||||
@@ -8,10 +14,12 @@ const ArtifactQueryParamsProperties = {
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
};
|
||||
|
||||
/** Shared artifact filter payload used by list-style requests. */
|
||||
export const ArtifactQueryParamsSchema = Type.Object(ArtifactQueryParamsProperties, {
|
||||
additionalProperties: false,
|
||||
});
|
||||
|
||||
/** Artifact lookup payload with a required artifact id plus optional scope filters. */
|
||||
export const ArtifactGetParamsSchema = Type.Object(
|
||||
{
|
||||
...ArtifactQueryParamsProperties,
|
||||
@@ -20,6 +28,7 @@ export const ArtifactGetParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Public artifact metadata returned before or alongside download data. */
|
||||
export const ArtifactSummarySchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -42,8 +51,10 @@ export const ArtifactSummarySchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** List request payload for artifacts visible in the selected scope. */
|
||||
export const ArtifactsListParamsSchema = ArtifactQueryParamsSchema;
|
||||
|
||||
/** List response containing artifact summaries only. */
|
||||
export const ArtifactsListResultSchema = Type.Object(
|
||||
{
|
||||
artifacts: Type.Array(ArtifactSummarySchema),
|
||||
@@ -51,8 +62,10 @@ export const ArtifactsListResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Get request payload for one artifact summary. */
|
||||
export const ArtifactsGetParamsSchema = ArtifactGetParamsSchema;
|
||||
|
||||
/** Get response containing one artifact summary. */
|
||||
export const ArtifactsGetResultSchema = Type.Object(
|
||||
{
|
||||
artifact: ArtifactSummarySchema,
|
||||
@@ -60,8 +73,10 @@ export const ArtifactsGetResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Download request payload for one artifact. */
|
||||
export const ArtifactsDownloadParamsSchema = ArtifactGetParamsSchema;
|
||||
|
||||
/** Download response, either inline base64 bytes, URL, or metadata for unsupported modes. */
|
||||
export const ArtifactsDownloadResultSchema = Type.Object(
|
||||
{
|
||||
artifact: ArtifactSummarySchema,
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
import { Type } from "typebox";
|
||||
import { NonEmptyString, SecretInputSchema } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Channel and Talk protocol schemas.
|
||||
*
|
||||
* Talk schemas are consumed by browser realtime clients, gateway relay sessions,
|
||||
* and channel adapters, so the mode/transport/brain unions below are shared
|
||||
* API vocabulary rather than provider-local implementation details.
|
||||
*/
|
||||
|
||||
/** Toggles Talk mode for the gateway, with an optional rollout phase marker. */
|
||||
export const TalkModeParamsSchema = Type.Object(
|
||||
{
|
||||
enabled: Type.Boolean(),
|
||||
@@ -9,6 +18,7 @@ export const TalkModeParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Reads Talk configuration; secrets are included only for trusted callers. */
|
||||
export const TalkConfigParamsSchema = Type.Object(
|
||||
{
|
||||
includeSecrets: Type.Optional(Type.Boolean()),
|
||||
@@ -16,6 +26,7 @@ export const TalkConfigParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** One-shot text-to-speech request with provider-specific voice tuning knobs. */
|
||||
export const TalkSpeakParamsSchema = Type.Object(
|
||||
{
|
||||
text: NonEmptyString,
|
||||
@@ -36,12 +47,14 @@ export const TalkSpeakParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Supported Talk session shapes exposed to clients and providers. */
|
||||
const TalkModeSchema = Type.Union([
|
||||
Type.Literal("realtime"),
|
||||
Type.Literal("stt-tts"),
|
||||
Type.Literal("transcription"),
|
||||
]);
|
||||
|
||||
/** Transport families; browser clients branch on this value to choose setup flow. */
|
||||
const TalkTransportSchema = Type.Union([
|
||||
Type.Literal("webrtc"),
|
||||
Type.Literal("provider-websocket"),
|
||||
@@ -49,12 +62,14 @@ const TalkTransportSchema = Type.Union([
|
||||
Type.Literal("managed-room"),
|
||||
]);
|
||||
|
||||
/** How a Talk session delegates reasoning/tool use to the agent runtime. */
|
||||
const TalkBrainSchema = Type.Union([
|
||||
Type.Literal("agent-consult"),
|
||||
Type.Literal("direct-tools"),
|
||||
Type.Literal("none"),
|
||||
]);
|
||||
|
||||
/** Agent control actions accepted from Talk clients and managed rooms. */
|
||||
const TalkAgentControlModeSchema = Type.Union([
|
||||
Type.Literal("status"),
|
||||
Type.Literal("steer"),
|
||||
@@ -62,6 +77,7 @@ const TalkAgentControlModeSchema = Type.Union([
|
||||
Type.Literal("followup"),
|
||||
]);
|
||||
|
||||
/** Stable event names emitted by Talk sessions across providers/transports. */
|
||||
const TalkEventTypeSchema = Type.Union([
|
||||
Type.Literal("session.started"),
|
||||
Type.Literal("session.ready"),
|
||||
@@ -93,6 +109,7 @@ const TalkEventTypeSchema = Type.Union([
|
||||
Type.Literal("health.changed"),
|
||||
]);
|
||||
|
||||
/** Event types that must carry a turn id for client-side stream correlation. */
|
||||
const TURN_SCOPED_TALK_EVENT_TYPES = [
|
||||
"turn.started",
|
||||
"turn.ended",
|
||||
@@ -112,6 +129,7 @@ const TURN_SCOPED_TALK_EVENT_TYPES = [
|
||||
"tool.error",
|
||||
];
|
||||
|
||||
/** Capture lifecycle events must include capture id to avoid cross-turn ambiguity. */
|
||||
const CAPTURE_SCOPED_TALK_EVENT_TYPES = [
|
||||
"capture.started",
|
||||
"capture.stopped",
|
||||
@@ -119,11 +137,13 @@ const CAPTURE_SCOPED_TALK_EVENT_TYPES = [
|
||||
"capture.once",
|
||||
];
|
||||
|
||||
/** Builds JSON Schema conditional requirements while avoiding reserved word syntax. */
|
||||
function requireJsonSchemaProperties(properties: string[]): Record<string, { required: string[] }> {
|
||||
const conditionalRequirementKey = ["th", "en"].join("");
|
||||
return Object.fromEntries([[conditionalRequirementKey, { required: properties }]]);
|
||||
}
|
||||
|
||||
/** Canonical Talk event envelope emitted to browser, relay, and channel consumers. */
|
||||
export const TalkEventSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -164,6 +184,7 @@ export const TalkEventSchema = Type.Object(
|
||||
},
|
||||
);
|
||||
|
||||
/** Creates a browser-facing Talk client session. */
|
||||
export const TalkClientCreateParamsSchema = Type.Object(
|
||||
{
|
||||
sessionKey: Type.Optional(Type.String()),
|
||||
@@ -181,6 +202,7 @@ export const TalkClientCreateParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Tool-call request from a browser/client session back into the agent runtime. */
|
||||
export const TalkClientToolCallParamsSchema = Type.Object(
|
||||
{
|
||||
sessionKey: NonEmptyString,
|
||||
@@ -192,6 +214,7 @@ export const TalkClientToolCallParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Agent run identity returned after accepting a Talk client tool call. */
|
||||
export const TalkClientToolCallResultSchema = Type.Object(
|
||||
{
|
||||
runId: NonEmptyString,
|
||||
@@ -200,6 +223,7 @@ export const TalkClientToolCallResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Text steering request for a Talk session bound to an agent turn. */
|
||||
export const TalkClientSteerParamsSchema = Type.Object(
|
||||
{
|
||||
sessionKey: NonEmptyString,
|
||||
@@ -209,6 +233,7 @@ export const TalkClientSteerParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Result of applying agent control to an embedded or reply-backed Talk run. */
|
||||
export const TalkAgentControlResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Boolean(),
|
||||
@@ -239,6 +264,7 @@ export const TalkAgentControlResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Joins an existing managed-room Talk session. */
|
||||
export const TalkSessionJoinParamsSchema = Type.Object(
|
||||
{
|
||||
sessionId: NonEmptyString,
|
||||
@@ -247,6 +273,7 @@ export const TalkSessionJoinParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Creates a gateway-managed Talk session for realtime, transcription, or relay use. */
|
||||
export const TalkSessionCreateParamsSchema = Type.Object(
|
||||
{
|
||||
sessionKey: Type.Optional(Type.String()),
|
||||
@@ -266,6 +293,7 @@ export const TalkSessionCreateParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Appends base64 audio to an active Talk session. */
|
||||
export const TalkSessionAppendAudioParamsSchema = Type.Object(
|
||||
{
|
||||
sessionId: NonEmptyString,
|
||||
@@ -275,6 +303,7 @@ export const TalkSessionAppendAudioParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Starts or advances a Talk turn within a session. */
|
||||
export const TalkSessionTurnParamsSchema = Type.Object(
|
||||
{
|
||||
sessionId: NonEmptyString,
|
||||
@@ -283,6 +312,7 @@ export const TalkSessionTurnParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Cancels the active or named Talk turn. */
|
||||
export const TalkSessionCancelTurnParamsSchema = Type.Object(
|
||||
{
|
||||
sessionId: NonEmptyString,
|
||||
@@ -292,6 +322,7 @@ export const TalkSessionCancelTurnParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Cancels currently streaming Talk output without necessarily ending the turn. */
|
||||
export const TalkSessionCancelOutputParamsSchema = Type.Object(
|
||||
{
|
||||
sessionId: NonEmptyString,
|
||||
@@ -301,6 +332,7 @@ export const TalkSessionCancelOutputParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Submits a tool result back to a Talk provider session. */
|
||||
export const TalkSessionSubmitToolResultParamsSchema = Type.Object(
|
||||
{
|
||||
sessionId: NonEmptyString,
|
||||
@@ -319,6 +351,7 @@ export const TalkSessionSubmitToolResultParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Steers a managed Talk session by session id rather than transcript key. */
|
||||
export const TalkSessionSteerParamsSchema = Type.Object(
|
||||
{
|
||||
sessionId: NonEmptyString,
|
||||
@@ -329,6 +362,7 @@ export const TalkSessionSteerParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Closes a gateway-managed Talk session. */
|
||||
export const TalkSessionCloseParamsSchema = Type.Object(
|
||||
{
|
||||
sessionId: NonEmptyString,
|
||||
@@ -336,6 +370,7 @@ export const TalkSessionCloseParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Mutable room state returned when a client joins a managed Talk room. */
|
||||
const TalkSessionManagedRoomStateSchema = Type.Object(
|
||||
{
|
||||
activeClientId: Type.Optional(Type.String()),
|
||||
@@ -345,6 +380,7 @@ const TalkSessionManagedRoomStateSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Managed-room session record shared with browser clients. */
|
||||
const TalkSessionManagedRoomRecordSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -367,8 +403,10 @@ const TalkSessionManagedRoomRecordSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Empty request payload for reading configured Talk provider capabilities. */
|
||||
export const TalkCatalogParamsSchema = Type.Object({}, { additionalProperties: false });
|
||||
|
||||
/** One provider entry in the Talk capability catalog. */
|
||||
const TalkCatalogProviderSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -413,6 +451,7 @@ const TalkCatalogProviderSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Active provider plus all candidates for a Talk capability family. */
|
||||
const TalkCatalogProviderGroupSchema = Type.Object(
|
||||
{
|
||||
activeProvider: Type.Optional(Type.String()),
|
||||
@@ -421,6 +460,7 @@ const TalkCatalogProviderGroupSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Provider, mode, transport, and audio-format catalog returned to clients. */
|
||||
export const TalkCatalogResultSchema = Type.Object(
|
||||
{
|
||||
modes: Type.Array(TalkModeSchema),
|
||||
@@ -433,6 +473,7 @@ export const TalkCatalogResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Audio format contract for realtime browser sessions. */
|
||||
const BrowserRealtimeAudioContractSchema = Type.Object(
|
||||
{
|
||||
inputEncoding: Type.Union([Type.Literal("pcm16"), Type.Literal("g711_ulaw")]),
|
||||
@@ -443,6 +484,7 @@ const BrowserRealtimeAudioContractSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Session creation result with transport-specific ids and credentials. */
|
||||
export const TalkSessionCreateResultSchema = Type.Object(
|
||||
{
|
||||
sessionId: NonEmptyString,
|
||||
@@ -464,6 +506,7 @@ export const TalkSessionCreateResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Result for a Talk turn request, optionally including emitted events. */
|
||||
export const TalkSessionTurnResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Boolean(),
|
||||
@@ -473,8 +516,10 @@ export const TalkSessionTurnResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Managed-room record returned to clients after joining an existing Talk session. */
|
||||
export const TalkSessionJoinResultSchema = TalkSessionManagedRoomRecordSchema;
|
||||
|
||||
/** Generic success result for Talk session lifecycle calls. */
|
||||
export const TalkSessionOkResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Boolean(),
|
||||
@@ -482,6 +527,7 @@ export const TalkSessionOkResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Browser WebRTC setup payload using provider SDP exchange. */
|
||||
const BrowserRealtimeWebRtcSdpSessionSchema = Type.Object(
|
||||
{
|
||||
provider: NonEmptyString,
|
||||
@@ -496,6 +542,7 @@ const BrowserRealtimeWebRtcSdpSessionSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Browser websocket setup payload with JSON/PCM audio contract. */
|
||||
const BrowserRealtimeJsonPcmWebSocketSessionSchema = Type.Object(
|
||||
{
|
||||
provider: NonEmptyString,
|
||||
@@ -512,6 +559,7 @@ const BrowserRealtimeJsonPcmWebSocketSessionSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Browser setup payload for gateway-relayed realtime audio. */
|
||||
const BrowserRealtimeGatewayRelaySessionSchema = Type.Object(
|
||||
{
|
||||
provider: NonEmptyString,
|
||||
@@ -525,6 +573,7 @@ const BrowserRealtimeGatewayRelaySessionSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Browser setup payload for managed-room Talk sessions. */
|
||||
const BrowserRealtimeManagedRoomSessionSchema = Type.Object(
|
||||
{
|
||||
provider: NonEmptyString,
|
||||
@@ -538,6 +587,7 @@ const BrowserRealtimeManagedRoomSessionSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Union of all browser Talk session setup payloads. */
|
||||
export const TalkClientCreateResultSchema = Type.Union([
|
||||
BrowserRealtimeWebRtcSdpSessionSchema,
|
||||
BrowserRealtimeJsonPcmWebSocketSessionSchema,
|
||||
@@ -545,14 +595,17 @@ export const TalkClientCreateResultSchema = Type.Union([
|
||||
BrowserRealtimeManagedRoomSessionSchema,
|
||||
]);
|
||||
|
||||
/** Secret-bearing provider fields; extra provider options remain provider-owned. */
|
||||
const talkProviderFieldSchemas = {
|
||||
apiKey: Type.Optional(SecretInputSchema),
|
||||
};
|
||||
|
||||
/** Per-provider Talk config bag. */
|
||||
const TalkProviderConfigSchema = Type.Object(talkProviderFieldSchemas, {
|
||||
additionalProperties: true,
|
||||
});
|
||||
|
||||
/** Realtime Talk defaults and provider selection stored in config. */
|
||||
const TalkRealtimeConfigSchema = Type.Object(
|
||||
{
|
||||
provider: Type.Optional(Type.String()),
|
||||
@@ -569,6 +622,7 @@ const TalkRealtimeConfigSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Resolved active Talk provider plus its normalized provider config. */
|
||||
const ResolvedTalkConfigSchema = Type.Object(
|
||||
{
|
||||
provider: Type.String(),
|
||||
@@ -577,6 +631,7 @@ const ResolvedTalkConfigSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Talk config subtree returned through gateway config APIs. */
|
||||
const TalkConfigSchema = Type.Object(
|
||||
{
|
||||
provider: Type.Optional(Type.String()),
|
||||
@@ -592,6 +647,7 @@ const TalkConfigSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Full Talk config read result, including related session/UI context. */
|
||||
export const TalkConfigResultSchema = Type.Object(
|
||||
{
|
||||
config: Type.Object(
|
||||
@@ -620,6 +676,7 @@ export const TalkConfigResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Text-to-speech result with encoded audio and provider output metadata. */
|
||||
export const TalkSpeakResultSchema = Type.Object(
|
||||
{
|
||||
audioBase64: NonEmptyString,
|
||||
@@ -632,6 +689,7 @@ export const TalkSpeakResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Channel status request, optionally probing one channel before returning. */
|
||||
export const ChannelsStatusParamsSchema = Type.Object(
|
||||
{
|
||||
probe: Type.Optional(Type.Boolean()),
|
||||
@@ -641,8 +699,12 @@ export const ChannelsStatusParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
// Channel docking: channels.status is intentionally schema-light so new
|
||||
// channels can ship without protocol updates.
|
||||
/**
|
||||
* Per-account status snapshot for channel docking.
|
||||
*
|
||||
* This is intentionally schema-light so new channel-specific metadata can ship
|
||||
* without a gateway protocol update; known fields stay documented for UI use.
|
||||
*/
|
||||
export const ChannelAccountSnapshotSchema = Type.Object(
|
||||
{
|
||||
accountId: NonEmptyString,
|
||||
@@ -683,6 +745,7 @@ export const ChannelAccountSnapshotSchema = Type.Object(
|
||||
{ additionalProperties: true },
|
||||
);
|
||||
|
||||
/** UI label and icon metadata for one channel. */
|
||||
export const ChannelUiMetaSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -693,6 +756,7 @@ export const ChannelUiMetaSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Event-loop health snapshot included with channel status responses. */
|
||||
export const ChannelEventLoopHealthSchema = Type.Object(
|
||||
{
|
||||
degraded: Type.Boolean(),
|
||||
@@ -712,6 +776,7 @@ export const ChannelEventLoopHealthSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Full channel status result for dashboard and operator diagnostics. */
|
||||
export const ChannelsStatusResultSchema = Type.Object(
|
||||
{
|
||||
ts: Type.Integer({ minimum: 0 }),
|
||||
@@ -730,6 +795,7 @@ export const ChannelsStatusResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Logs out one channel account. */
|
||||
export const ChannelsLogoutParamsSchema = Type.Object(
|
||||
{
|
||||
channel: NonEmptyString,
|
||||
@@ -738,6 +804,7 @@ export const ChannelsLogoutParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Stops one channel account runtime. */
|
||||
export const ChannelsStopParamsSchema = Type.Object(
|
||||
{
|
||||
channel: NonEmptyString,
|
||||
@@ -746,6 +813,7 @@ export const ChannelsStopParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Starts one channel account runtime. */
|
||||
export const ChannelsStartParamsSchema = Type.Object(
|
||||
{
|
||||
channel: NonEmptyString,
|
||||
@@ -754,6 +822,7 @@ export const ChannelsStartParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Starts browser/web login for a channel account. */
|
||||
export const WebLoginStartParamsSchema = Type.Object(
|
||||
{
|
||||
force: Type.Optional(Type.Boolean()),
|
||||
@@ -769,6 +838,7 @@ const QrDataUrlSchema = Type.String({
|
||||
pattern: "^data:image/png;base64,",
|
||||
});
|
||||
|
||||
/** Waits for web login completion or the next QR code. */
|
||||
export const WebLoginWaitParamsSchema = Type.Object(
|
||||
{
|
||||
timeoutMs: Type.Optional(Type.Integer({ minimum: 0 })),
|
||||
|
||||
@@ -1,31 +1,50 @@
|
||||
import { Type } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Command catalog protocol schemas.
|
||||
*
|
||||
* Command entries describe native, skill, and plugin commands that clients can
|
||||
* render or route; limits keep command catalogs bounded for UI and transport.
|
||||
*/
|
||||
/** Maximum command display/name length accepted in catalog entries. */
|
||||
export const COMMAND_NAME_MAX_LENGTH = 200;
|
||||
/** Maximum command description length accepted in catalog entries. */
|
||||
export const COMMAND_DESCRIPTION_MAX_LENGTH = 2_000;
|
||||
/** Maximum text aliases advertised for one command. */
|
||||
export const COMMAND_ALIAS_MAX_ITEMS = 20;
|
||||
/** Maximum declared arguments advertised for one command. */
|
||||
export const COMMAND_ARGS_MAX_ITEMS = 20;
|
||||
/** Maximum argument name length accepted in catalog entries. */
|
||||
export const COMMAND_ARG_NAME_MAX_LENGTH = 200;
|
||||
/** Maximum argument description length accepted in catalog entries. */
|
||||
export const COMMAND_ARG_DESCRIPTION_MAX_LENGTH = 500;
|
||||
/** Maximum static choices advertised for one argument. */
|
||||
export const COMMAND_ARG_CHOICES_MAX_ITEMS = 50;
|
||||
/** Maximum machine-readable choice value length. */
|
||||
export const COMMAND_CHOICE_VALUE_MAX_LENGTH = 200;
|
||||
/** Maximum user-facing choice label length. */
|
||||
export const COMMAND_CHOICE_LABEL_MAX_LENGTH = 200;
|
||||
/** Maximum commands returned by one catalog response. */
|
||||
export const COMMAND_LIST_MAX_ITEMS = 500;
|
||||
|
||||
const BoundedNonEmptyString = (maxLength: number) => Type.String({ minLength: 1, maxLength });
|
||||
|
||||
/** Source system that contributed a command. */
|
||||
export const CommandSourceSchema = Type.Union([
|
||||
Type.Literal("native"),
|
||||
Type.Literal("skill"),
|
||||
Type.Literal("plugin"),
|
||||
]);
|
||||
|
||||
/** Surfaces where a command may be invoked. */
|
||||
export const CommandScopeSchema = Type.Union([
|
||||
Type.Literal("text"),
|
||||
Type.Literal("native"),
|
||||
Type.Literal("both"),
|
||||
]);
|
||||
|
||||
/** Coarse UI grouping for command catalog display. */
|
||||
export const CommandCategorySchema = Type.Union([
|
||||
Type.Literal("session"),
|
||||
Type.Literal("options"),
|
||||
@@ -36,6 +55,7 @@ export const CommandCategorySchema = Type.Union([
|
||||
Type.Literal("docks"),
|
||||
]);
|
||||
|
||||
/** Static argument choice shown to clients. */
|
||||
export const CommandArgChoiceSchema = Type.Object(
|
||||
{
|
||||
value: Type.String({ maxLength: COMMAND_CHOICE_VALUE_MAX_LENGTH }),
|
||||
@@ -44,6 +64,7 @@ export const CommandArgChoiceSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** One typed argument advertised for a command. */
|
||||
export const CommandArgSchema = Type.Object(
|
||||
{
|
||||
name: BoundedNonEmptyString(COMMAND_ARG_NAME_MAX_LENGTH),
|
||||
@@ -58,6 +79,7 @@ export const CommandArgSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** One command catalog entry visible to clients. */
|
||||
export const CommandEntrySchema = Type.Object(
|
||||
{
|
||||
name: BoundedNonEmptyString(COMMAND_NAME_MAX_LENGTH),
|
||||
@@ -77,6 +99,7 @@ export const CommandEntrySchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Command catalog request filters. */
|
||||
export const CommandsListParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
@@ -87,6 +110,7 @@ export const CommandsListParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Bounded command catalog response. */
|
||||
export const CommandsListResultSchema = Type.Object(
|
||||
{
|
||||
commands: Type.Array(CommandEntrySchema, { maxItems: COMMAND_LIST_MAX_ITEMS }),
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { Type } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Gateway config and update protocol schemas.
|
||||
*
|
||||
* These payloads carry raw config text plus optional delivery context so the
|
||||
* gateway can report edits/restarts back to the originating channel.
|
||||
*/
|
||||
const ConfigSchemaLookupPathString = Type.String({
|
||||
minLength: 1,
|
||||
maxLength: 1024,
|
||||
@@ -17,8 +23,10 @@ const ConfigDeliveryContextSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Empty request payload for reading the current raw config. */
|
||||
export const ConfigGetParamsSchema = Type.Object({}, { additionalProperties: false });
|
||||
|
||||
/** Full raw config replacement request with optional base hash guard. */
|
||||
export const ConfigSetParamsSchema = Type.Object(
|
||||
{
|
||||
raw: NonEmptyString,
|
||||
@@ -27,6 +35,7 @@ export const ConfigSetParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Shared config apply/patch payload with optional restart notification context. */
|
||||
const ConfigApplyLikeParamsSchema = Type.Object(
|
||||
{
|
||||
raw: NonEmptyString,
|
||||
@@ -39,11 +48,15 @@ const ConfigApplyLikeParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Raw config apply request that may schedule a restart. */
|
||||
export const ConfigApplyParamsSchema = ConfigApplyLikeParamsSchema;
|
||||
/** Raw config patch request that may schedule a restart. */
|
||||
export const ConfigPatchParamsSchema = ConfigApplyLikeParamsSchema;
|
||||
|
||||
/** Empty request payload for fetching the generated config schema. */
|
||||
export const ConfigSchemaParamsSchema = Type.Object({}, { additionalProperties: false });
|
||||
|
||||
/** Schema lookup request for one config path. */
|
||||
export const ConfigSchemaLookupParamsSchema = Type.Object(
|
||||
{
|
||||
path: ConfigSchemaLookupPathString,
|
||||
@@ -51,8 +64,10 @@ export const ConfigSchemaLookupParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Empty request payload for checking update/restart status. */
|
||||
export const UpdateStatusParamsSchema = Type.Object({}, { additionalProperties: false });
|
||||
|
||||
/** Request payload for running an update/restart flow with optional channel delivery context. */
|
||||
export const UpdateRunParamsSchema = Type.Object(
|
||||
{
|
||||
sessionKey: Type.Optional(Type.String()),
|
||||
@@ -65,6 +80,7 @@ export const UpdateRunParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** UI metadata attached to config schema paths. */
|
||||
export const ConfigUiHintSchema = Type.Object(
|
||||
{
|
||||
label: Type.Optional(Type.String()),
|
||||
@@ -80,6 +96,7 @@ export const ConfigUiHintSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Full generated config schema response. */
|
||||
export const ConfigSchemaResponseSchema = Type.Object(
|
||||
{
|
||||
schema: Type.Unknown(),
|
||||
@@ -90,6 +107,7 @@ export const ConfigSchemaResponseSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Child entry returned when looking up a config schema path. */
|
||||
export const ConfigSchemaLookupChildSchema = Type.Object(
|
||||
{
|
||||
key: NonEmptyString,
|
||||
@@ -106,6 +124,7 @@ export const ConfigSchemaLookupChildSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Schema lookup response for one config path and its immediate children. */
|
||||
export const ConfigSchemaLookupResultSchema = Type.Object(
|
||||
{
|
||||
path: NonEmptyString,
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
import { Type, type TSchema } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Cron scheduler protocol schemas.
|
||||
*
|
||||
* These contracts describe scheduled agent turns, system events, delivery
|
||||
* routing, run history, and mutable job state shared by gateway RPC clients.
|
||||
*/
|
||||
|
||||
/** Builds create/patch payload variants while preserving per-call field optionality. */
|
||||
function cronAgentTurnPayloadSchema(params: { message: TSchema; toolsAllow: TSchema }) {
|
||||
return Type.Object(
|
||||
{
|
||||
@@ -18,13 +26,16 @@ function cronAgentTurnPayloadSchema(params: { message: TSchema; toolsAllow: TSch
|
||||
);
|
||||
}
|
||||
|
||||
/** Session target accepted by cron jobs. */
|
||||
const CronSessionTargetSchema = Type.Union([
|
||||
Type.Literal("main"),
|
||||
Type.Literal("isolated"),
|
||||
Type.Literal("current"),
|
||||
Type.String({ pattern: "^session:.+" }),
|
||||
]);
|
||||
/** Whether a cron job waits for heartbeat processing or wakes immediately. */
|
||||
const CronWakeModeSchema = Type.Union([Type.Literal("next-heartbeat"), Type.Literal("now")]);
|
||||
/** Run status factory reused for the active field and deprecated alias metadata. */
|
||||
function cronRunStatusSchema(options: Record<string, unknown> = {}) {
|
||||
return Type.Union([Type.Literal("ok"), Type.Literal("error"), Type.Literal("skipped")], options);
|
||||
}
|
||||
@@ -159,6 +170,7 @@ const CronRunLogJobIdSchema = Type.String({
|
||||
pattern: "^[^/\\\\]+$",
|
||||
});
|
||||
|
||||
/** Schedule expression for one-time, interval, or cron-expression jobs. */
|
||||
export const CronScheduleSchema = Type.Union([
|
||||
Type.Object(
|
||||
{
|
||||
@@ -186,6 +198,7 @@ export const CronScheduleSchema = Type.Union([
|
||||
),
|
||||
]);
|
||||
|
||||
/** Full cron payload for new jobs. */
|
||||
export const CronPayloadSchema = Type.Union([
|
||||
Type.Object(
|
||||
{
|
||||
@@ -200,6 +213,7 @@ export const CronPayloadSchema = Type.Union([
|
||||
}),
|
||||
]);
|
||||
|
||||
/** Partial cron payload for job updates. */
|
||||
export const CronPayloadPatchSchema = Type.Union([
|
||||
Type.Object(
|
||||
{
|
||||
@@ -214,6 +228,7 @@ export const CronPayloadPatchSchema = Type.Union([
|
||||
}),
|
||||
]);
|
||||
|
||||
/** Failure alert policy for repeated cron run failures. */
|
||||
export const CronFailureAlertSchema = Type.Object(
|
||||
{
|
||||
after: Type.Optional(Type.Integer({ minimum: 1 })),
|
||||
@@ -227,6 +242,7 @@ export const CronFailureAlertSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Delivery destination used when failure alerts need a separate target. */
|
||||
export const CronFailureDestinationSchema = Type.Object(
|
||||
{
|
||||
channel: Type.Optional(CronAnnounceChannelSchema),
|
||||
@@ -301,12 +317,14 @@ const CronDeliveryWebhookSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Delivery policy for cron run output. */
|
||||
export const CronDeliverySchema = Type.Union([
|
||||
CronDeliveryNoopSchema,
|
||||
CronDeliveryAnnounceSchema,
|
||||
CronDeliveryWebhookSchema,
|
||||
]);
|
||||
|
||||
/** Patch shape for cron delivery policy updates. */
|
||||
export const CronDeliveryPatchSchema = Type.Object(
|
||||
{
|
||||
mode: Type.Optional(
|
||||
@@ -330,6 +348,7 @@ const CronFailureNotificationDeliverySchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Scheduler-maintained state for the latest run/delivery outcome. */
|
||||
export const CronJobStateSchema = Type.Object(
|
||||
{
|
||||
nextRunAtMs: Type.Optional(Type.Integer({ minimum: 0 })),
|
||||
@@ -378,6 +397,7 @@ const CronJobStatePatchSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Persisted cron job definition returned by scheduler list/get APIs. */
|
||||
export const CronJobSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -400,6 +420,7 @@ export const CronJobSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Query params for listing cron jobs with filters and pagination. */
|
||||
export const CronListParamsSchema = Type.Object(
|
||||
{
|
||||
includeDisabled: Type.Optional(Type.Boolean()),
|
||||
@@ -416,10 +437,13 @@ export const CronListParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Empty request payload for scheduler status. */
|
||||
export const CronStatusParamsSchema = Type.Object({}, { additionalProperties: false });
|
||||
|
||||
/** Looks up a job by stable id or legacy jobId alias. */
|
||||
export const CronGetParamsSchema = cronIdOrJobIdParams({});
|
||||
|
||||
/** Creates a scheduled job with schedule, target, payload, and delivery policy. */
|
||||
export const CronAddParamsSchema = Type.Object(
|
||||
{
|
||||
name: NonEmptyString,
|
||||
@@ -434,6 +458,7 @@ export const CronAddParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Mutable cron job fields accepted by update APIs. */
|
||||
export const CronJobPatchSchema = Type.Object(
|
||||
{
|
||||
name: Type.Optional(NonEmptyString),
|
||||
@@ -449,16 +474,20 @@ export const CronJobPatchSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Updates a cron job by id or legacy jobId alias. */
|
||||
export const CronUpdateParamsSchema = cronIdOrJobIdParams({
|
||||
patch: CronJobPatchSchema,
|
||||
});
|
||||
|
||||
/** Removes a cron job by id or legacy jobId alias. */
|
||||
export const CronRemoveParamsSchema = cronIdOrJobIdParams({});
|
||||
|
||||
/** Runs a cron job immediately or only if due. */
|
||||
export const CronRunParamsSchema = cronIdOrJobIdParams({
|
||||
mode: Type.Optional(Type.Union([Type.Literal("due"), Type.Literal("force")])),
|
||||
});
|
||||
|
||||
/** Query params for cron run history. */
|
||||
export const CronRunsParamsSchema = Type.Object(
|
||||
{
|
||||
scope: Type.Optional(Type.Union([Type.Literal("job"), Type.Literal("all")])),
|
||||
@@ -479,6 +508,7 @@ export const CronRunsParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** One persisted cron run history entry. */
|
||||
export const CronRunLogEntrySchema = Type.Object(
|
||||
{
|
||||
ts: Type.Integer({ minimum: 0 }),
|
||||
|
||||
@@ -1,23 +1,34 @@
|
||||
import { Type } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Device pairing and token-management protocol schemas.
|
||||
*
|
||||
* These payloads cross the gateway approval boundary, so request ids and device
|
||||
* ids stay explicit and feature handlers own the authorization checks.
|
||||
*/
|
||||
/** Lists pending and approved device pairing records. */
|
||||
export const DevicePairListParamsSchema = Type.Object({}, { additionalProperties: false });
|
||||
|
||||
/** Approves a pending pairing request by request id. */
|
||||
export const DevicePairApproveParamsSchema = Type.Object(
|
||||
{ requestId: NonEmptyString },
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Rejects a pending pairing request by request id. */
|
||||
export const DevicePairRejectParamsSchema = Type.Object(
|
||||
{ requestId: NonEmptyString },
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Removes an approved or remembered device by device id. */
|
||||
export const DevicePairRemoveParamsSchema = Type.Object(
|
||||
{ deviceId: NonEmptyString },
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Rotates or issues a device token for a specific role/scope grant. */
|
||||
export const DeviceTokenRotateParamsSchema = Type.Object(
|
||||
{
|
||||
deviceId: NonEmptyString,
|
||||
@@ -27,6 +38,7 @@ export const DeviceTokenRotateParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Revokes one role-bound device token grant. */
|
||||
export const DeviceTokenRevokeParamsSchema = Type.Object(
|
||||
{
|
||||
deviceId: NonEmptyString,
|
||||
@@ -35,6 +47,7 @@ export const DeviceTokenRevokeParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Event emitted when a client opens or refreshes a pairing request. */
|
||||
export const DevicePairRequestedEventSchema = Type.Object(
|
||||
{
|
||||
requestId: NonEmptyString,
|
||||
@@ -56,6 +69,7 @@ export const DevicePairRequestedEventSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Event emitted after a pairing request is approved, rejected, or otherwise resolved. */
|
||||
export const DevicePairResolvedEventSchema = Type.Object(
|
||||
{
|
||||
requestId: NonEmptyString,
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import { Type } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Environment inventory protocol schemas.
|
||||
*
|
||||
* Environments are runtime targets such as local hosts, VMs, or remote workers;
|
||||
* this schema layer only describes their gateway-visible status summary.
|
||||
*/
|
||||
/** Runtime availability state for an environment target. */
|
||||
export const EnvironmentStatusSchema = Type.String({
|
||||
enum: ["available", "unavailable", "starting", "stopping", "error"],
|
||||
});
|
||||
@@ -18,10 +25,13 @@ function createEnvironmentSummarySchema() {
|
||||
);
|
||||
}
|
||||
|
||||
/** Public environment summary shown in listings and status responses. */
|
||||
export const EnvironmentSummarySchema = createEnvironmentSummarySchema();
|
||||
|
||||
/** Empty request payload for listing known environments. */
|
||||
export const EnvironmentsListParamsSchema = Type.Object({}, { additionalProperties: false });
|
||||
|
||||
/** List response containing all gateway-visible environment summaries. */
|
||||
export const EnvironmentsListResultSchema = Type.Object(
|
||||
{
|
||||
environments: Type.Array(EnvironmentSummarySchema),
|
||||
@@ -29,9 +39,11 @@ export const EnvironmentsListResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Status lookup request for one environment id. */
|
||||
export const EnvironmentsStatusParamsSchema = Type.Object(
|
||||
{ environmentId: NonEmptyString },
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Status lookup result for one environment id. */
|
||||
export const EnvironmentsStatusResultSchema = createEnvironmentSummarySchema();
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
import type { ErrorShape } from "./types.js";
|
||||
|
||||
/** Gateway JSON-RPC style error codes shared by clients and server handlers. */
|
||||
export const ErrorCodes = {
|
||||
/** Client has not completed account/device linking for this gateway. */
|
||||
NOT_LINKED: "NOT_LINKED",
|
||||
/** Device exists but still needs an explicit pairing approval. */
|
||||
NOT_PAIRED: "NOT_PAIRED",
|
||||
/** Agent turn exceeded the gateway wait window. */
|
||||
AGENT_TIMEOUT: "AGENT_TIMEOUT",
|
||||
/** Request payload failed protocol validation or method preconditions. */
|
||||
INVALID_REQUEST: "INVALID_REQUEST",
|
||||
/** Approval resolution referenced a missing or expired approval request. */
|
||||
APPROVAL_NOT_FOUND: "APPROVAL_NOT_FOUND",
|
||||
/** Gateway service or required backend is temporarily unavailable. */
|
||||
UNAVAILABLE: "UNAVAILABLE",
|
||||
} as const;
|
||||
|
||||
/** Closed set of canonical gateway error code strings. */
|
||||
export type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
|
||||
|
||||
/** Builds the canonical gateway error payload while preserving optional retry metadata. */
|
||||
export function errorShape(
|
||||
code: ErrorCode,
|
||||
message: string,
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import { Type } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Exec approval protocol schemas.
|
||||
*
|
||||
* These payloads cross the security-review boundary for command execution, so
|
||||
* persisted policy, request snapshots, and resolve decisions stay explicit.
|
||||
*/
|
||||
/** One persisted allowlist entry for a command pattern or resolved executable. */
|
||||
export const ExecApprovalsAllowlistEntrySchema = Type.Object(
|
||||
{
|
||||
id: Type.Optional(NonEmptyString),
|
||||
@@ -22,10 +29,12 @@ const ExecApprovalsPolicyFields = {
|
||||
autoAllowSkills: Type.Optional(Type.Boolean()),
|
||||
};
|
||||
|
||||
/** Default exec approval policy shared by all agents unless overridden. */
|
||||
export const ExecApprovalsDefaultsSchema = Type.Object(ExecApprovalsPolicyFields, {
|
||||
additionalProperties: false,
|
||||
});
|
||||
|
||||
/** Agent-specific exec approval policy and allowlist. */
|
||||
export const ExecApprovalsAgentSchema = Type.Object(
|
||||
{
|
||||
...ExecApprovalsPolicyFields,
|
||||
@@ -34,6 +43,7 @@ export const ExecApprovalsAgentSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Versioned exec approvals config file edited through gateway APIs. */
|
||||
export const ExecApprovalsFileSchema = Type.Object(
|
||||
{
|
||||
version: Type.Literal(1),
|
||||
@@ -52,6 +62,7 @@ export const ExecApprovalsFileSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Read snapshot with path/hash metadata for optimistic writes. */
|
||||
export const ExecApprovalsSnapshotSchema = Type.Object(
|
||||
{
|
||||
path: NonEmptyString,
|
||||
@@ -62,8 +73,10 @@ export const ExecApprovalsSnapshotSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Empty request payload for reading local exec approval policy. */
|
||||
export const ExecApprovalsGetParamsSchema = Type.Object({}, { additionalProperties: false });
|
||||
|
||||
/** Local exec approval policy write request with optional base hash guard. */
|
||||
export const ExecApprovalsSetParamsSchema = Type.Object(
|
||||
{
|
||||
file: ExecApprovalsFileSchema,
|
||||
@@ -72,6 +85,7 @@ export const ExecApprovalsSetParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Node-scoped request payload for reading exec approval policy. */
|
||||
export const ExecApprovalsNodeGetParamsSchema = Type.Object(
|
||||
{
|
||||
nodeId: NonEmptyString,
|
||||
@@ -79,6 +93,7 @@ export const ExecApprovalsNodeGetParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Node-scoped exec approval policy write request with optional base hash guard. */
|
||||
export const ExecApprovalsNodeSetParamsSchema = Type.Object(
|
||||
{
|
||||
nodeId: NonEmptyString,
|
||||
@@ -88,6 +103,7 @@ export const ExecApprovalsNodeSetParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Lookup request for one pending exec approval by id. */
|
||||
export const ExecApprovalGetParamsSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -95,6 +111,7 @@ export const ExecApprovalGetParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Pending command execution approval request shown to reviewers. */
|
||||
export const ExecApprovalRequestParamsSchema = Type.Object(
|
||||
{
|
||||
id: Type.Optional(NonEmptyString),
|
||||
@@ -166,6 +183,7 @@ export const ExecApprovalRequestParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Reviewer decision payload for one pending exec approval. */
|
||||
export const ExecApprovalResolveParamsSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
|
||||
@@ -2,6 +2,13 @@ import { Type } from "typebox";
|
||||
import { GatewayClientIdSchema, GatewayClientModeSchema, NonEmptyString } from "./primitives.js";
|
||||
import { SnapshotSchema, StateVersionSchema } from "./snapshot.js";
|
||||
|
||||
/**
|
||||
* Top-level gateway frame schemas.
|
||||
*
|
||||
* These are the WebSocket envelope contracts; method/event payload schemas live
|
||||
* in feature-specific modules and are referenced by runtime validators.
|
||||
*/
|
||||
/** Periodic server heartbeat event payload. */
|
||||
export const TickEventSchema = Type.Object(
|
||||
{
|
||||
ts: Type.Integer({ minimum: 0 }),
|
||||
@@ -9,6 +16,7 @@ export const TickEventSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Server shutdown notice event payload. */
|
||||
export const ShutdownEventSchema = Type.Object(
|
||||
{
|
||||
reason: NonEmptyString,
|
||||
@@ -17,6 +25,7 @@ export const ShutdownEventSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Initial client hello/connect payload sent before the gateway accepts frames. */
|
||||
export const ConnectParamsSchema = Type.Object(
|
||||
{
|
||||
minProtocol: Type.Integer({ minimum: 1 }),
|
||||
@@ -70,6 +79,7 @@ export const ConnectParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Successful gateway hello response with negotiated protocol and initial state. */
|
||||
export const HelloOkSchema = Type.Object(
|
||||
{
|
||||
type: Type.Literal("hello-ok"),
|
||||
@@ -124,6 +134,7 @@ export const HelloOkSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Standard structured error shape used in response frames and connect failures. */
|
||||
export const ErrorShapeSchema = Type.Object(
|
||||
{
|
||||
code: NonEmptyString,
|
||||
@@ -135,6 +146,7 @@ export const ErrorShapeSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Client request frame envelope; `method` selects the payload validator. */
|
||||
export const RequestFrameSchema = Type.Object(
|
||||
{
|
||||
type: Type.Literal("req"),
|
||||
@@ -145,6 +157,7 @@ export const RequestFrameSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Server response frame envelope paired with a prior request id. */
|
||||
export const ResponseFrameSchema = Type.Object(
|
||||
{
|
||||
type: Type.Literal("res"),
|
||||
@@ -156,6 +169,7 @@ export const ResponseFrameSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Server event frame envelope; `event` selects the payload validator. */
|
||||
export const EventFrameSchema = Type.Object(
|
||||
{
|
||||
type: Type.Literal("event"),
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { Static } from "typebox";
|
||||
import { Type } from "typebox";
|
||||
import { ChatSendSessionKeyString, InputProvenanceSchema, NonEmptyString } from "./primitives.js";
|
||||
|
||||
/** Cursor-based request for the gateway log tail endpoint. */
|
||||
export const LogsTailParamsSchema = Type.Object(
|
||||
{
|
||||
cursor: Type.Optional(Type.Integer({ minimum: 0 })),
|
||||
@@ -11,6 +12,7 @@ export const LogsTailParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Gateway log tail payload returned to dashboard clients. */
|
||||
export const LogsTailResultSchema = Type.Object(
|
||||
{
|
||||
file: NonEmptyString,
|
||||
@@ -23,7 +25,7 @@ export const LogsTailResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
// WebChat/WebSocket-native chat methods
|
||||
/** Session-scoped history request used by WebChat and native WebSocket clients. */
|
||||
export const ChatHistoryParamsSchema = Type.Object(
|
||||
{
|
||||
sessionKey: NonEmptyString,
|
||||
@@ -34,6 +36,7 @@ export const ChatHistoryParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Lightweight chat metadata request; optional agent scope keeps selector state explicit. */
|
||||
export const ChatMetadataParamsSchema = Type.Object(
|
||||
{
|
||||
agentId: Type.Optional(NonEmptyString),
|
||||
@@ -41,6 +44,7 @@ export const ChatMetadataParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Fetches one stored chat message without forcing history callers to request huge payloads. */
|
||||
export const ChatMessageGetParamsSchema = Type.Object(
|
||||
{
|
||||
sessionKey: NonEmptyString,
|
||||
@@ -51,6 +55,7 @@ export const ChatMessageGetParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Result envelope for single-message lookup, including the stable miss/visibility reason. */
|
||||
export const ChatMessageGetResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Boolean(),
|
||||
@@ -65,8 +70,10 @@ export const ChatMessageGetResultSchema = Type.Object(
|
||||
},
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
/** Typed result shape for callers that branch on message availability. */
|
||||
export type ChatMessageGetResult = Static<typeof ChatMessageGetResultSchema>;
|
||||
|
||||
/** User-to-agent send request; idempotency key lets clients safely retry transport failures. */
|
||||
export const ChatSendParamsSchema = Type.Object(
|
||||
{
|
||||
sessionKey: ChatSendSessionKeyString,
|
||||
@@ -89,6 +96,7 @@ export const ChatSendParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Cancels the active or named run for a chat session. */
|
||||
export const ChatAbortParamsSchema = Type.Object(
|
||||
{
|
||||
sessionKey: NonEmptyString,
|
||||
@@ -98,6 +106,7 @@ export const ChatAbortParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Inserts an operator-visible synthetic message into an existing chat transcript. */
|
||||
export const ChatInjectParamsSchema = Type.Object(
|
||||
{
|
||||
sessionKey: NonEmptyString,
|
||||
@@ -108,6 +117,7 @@ export const ChatInjectParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Shared event fields preserve stream ordering and route events to the right session. */
|
||||
const ChatEventBaseSchema = {
|
||||
runId: NonEmptyString,
|
||||
sessionKey: NonEmptyString,
|
||||
@@ -116,6 +126,7 @@ const ChatEventBaseSchema = {
|
||||
seq: Type.Integer({ minimum: 0 }),
|
||||
};
|
||||
|
||||
/** Stable error categories exposed over the chat stream. */
|
||||
const ChatEventErrorKindSchema = Type.Union([
|
||||
Type.Literal("refusal"),
|
||||
Type.Literal("timeout"),
|
||||
@@ -124,6 +135,7 @@ const ChatEventErrorKindSchema = Type.Union([
|
||||
Type.Literal("unknown"),
|
||||
]);
|
||||
|
||||
/** Incremental assistant output event; `replace` marks full-content refresh deltas. */
|
||||
export const ChatDeltaEventSchema = Type.Object(
|
||||
{
|
||||
...ChatEventBaseSchema,
|
||||
@@ -136,6 +148,7 @@ export const ChatDeltaEventSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Successful terminal event for a completed chat run. */
|
||||
export const ChatFinalEventSchema = Type.Object(
|
||||
{
|
||||
...ChatEventBaseSchema,
|
||||
@@ -147,6 +160,7 @@ export const ChatFinalEventSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Terminal event for user-initiated or coordinator-initiated cancellation. */
|
||||
export const ChatAbortedEventSchema = Type.Object(
|
||||
{
|
||||
...ChatEventBaseSchema,
|
||||
@@ -157,6 +171,7 @@ export const ChatAbortedEventSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Terminal event for failed chat runs with an optional normalized failure kind. */
|
||||
export const ChatErrorEventSchema = Type.Object(
|
||||
{
|
||||
...ChatEventBaseSchema,
|
||||
@@ -170,6 +185,7 @@ export const ChatErrorEventSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Public chat stream event union consumed by gateway protocol validators. */
|
||||
export const ChatEventSchema = Type.Union([
|
||||
ChatDeltaEventSchema,
|
||||
ChatFinalEventSchema,
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import { Type } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/** Pending node work classes that the gateway may queue for paired devices. */
|
||||
const NodePendingWorkTypeSchema = Type.String({
|
||||
enum: ["status.request", "location.request"],
|
||||
});
|
||||
|
||||
/** Queue priority accepted when operators enqueue node work. */
|
||||
const NodePendingWorkPrioritySchema = Type.String({
|
||||
enum: ["normal", "high"],
|
||||
});
|
||||
|
||||
/** Reasons a node can report itself alive without implying an operator action. */
|
||||
export const NodePresenceAliveReasonSchema = Type.String({
|
||||
enum: [
|
||||
"background",
|
||||
@@ -20,6 +23,7 @@ export const NodePresenceAliveReasonSchema = Type.String({
|
||||
],
|
||||
});
|
||||
|
||||
/** Presence heartbeat payload sent by remote nodes to refresh gateway state. */
|
||||
export const NodePresenceAlivePayloadSchema = Type.Object(
|
||||
{
|
||||
trigger: NodePresenceAliveReasonSchema,
|
||||
@@ -34,6 +38,7 @@ export const NodePresenceAlivePayloadSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Normalized result for node-originated events after gateway dispatch. */
|
||||
export const NodeEventResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Boolean(),
|
||||
@@ -44,6 +49,7 @@ export const NodeEventResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Pairing request metadata advertised by a node before trust is granted. */
|
||||
export const NodePairRequestParamsSchema = Type.Object(
|
||||
{
|
||||
nodeId: NonEmptyString,
|
||||
@@ -63,35 +69,43 @@ export const NodePairRequestParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Lists pending node-pairing requests. */
|
||||
export const NodePairListParamsSchema = Type.Object({}, { additionalProperties: false });
|
||||
|
||||
/** Approves a pending node-pairing request by request id. */
|
||||
export const NodePairApproveParamsSchema = Type.Object(
|
||||
{ requestId: NonEmptyString },
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Rejects a pending node-pairing request by request id. */
|
||||
export const NodePairRejectParamsSchema = Type.Object(
|
||||
{ requestId: NonEmptyString },
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Removes an already paired node from the gateway trust set. */
|
||||
export const NodePairRemoveParamsSchema = Type.Object(
|
||||
{ nodeId: NonEmptyString },
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Verifies node ownership with a short-lived pairing token. */
|
||||
export const NodePairVerifyParamsSchema = Type.Object(
|
||||
{ nodeId: NonEmptyString, token: NonEmptyString },
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Renames a paired node while preserving its stable node id. */
|
||||
export const NodeRenameParamsSchema = Type.Object(
|
||||
{ nodeId: NonEmptyString, displayName: NonEmptyString },
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Lists paired nodes known to the gateway. */
|
||||
export const NodeListParamsSchema = Type.Object({}, { additionalProperties: false });
|
||||
|
||||
/** Acknowledges queued node work that the node has consumed. */
|
||||
export const NodePendingAckParamsSchema = Type.Object(
|
||||
{
|
||||
ids: Type.Array(NonEmptyString, { minItems: 1 }),
|
||||
@@ -99,11 +113,13 @@ export const NodePendingAckParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Requests detailed metadata for one paired node. */
|
||||
export const NodeDescribeParamsSchema = Type.Object(
|
||||
{ nodeId: NonEmptyString },
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Invokes a command on a paired node; idempotency allows safe retries. */
|
||||
export const NodeInvokeParamsSchema = Type.Object(
|
||||
{
|
||||
nodeId: NonEmptyString,
|
||||
@@ -115,6 +131,7 @@ export const NodeInvokeParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Result callback payload for a node command invocation. */
|
||||
export const NodeInvokeResultParamsSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -135,6 +152,7 @@ export const NodeInvokeResultParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Generic node event envelope accepted by the gateway. */
|
||||
export const NodeEventParamsSchema = Type.Object(
|
||||
{
|
||||
event: NonEmptyString,
|
||||
@@ -144,6 +162,7 @@ export const NodeEventParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Request for a bounded batch of queued work assigned to the calling node. */
|
||||
export const NodePendingDrainParamsSchema = Type.Object(
|
||||
{
|
||||
maxItems: Type.Optional(Type.Integer({ minimum: 1, maximum: 10 })),
|
||||
@@ -151,6 +170,7 @@ export const NodePendingDrainParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** One queued node-work item returned by pending-work drain calls. */
|
||||
export const NodePendingDrainItemSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -163,6 +183,7 @@ export const NodePendingDrainItemSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Drain response with a revision marker for node queue state. */
|
||||
export const NodePendingDrainResultSchema = Type.Object(
|
||||
{
|
||||
nodeId: NonEmptyString,
|
||||
@@ -173,6 +194,7 @@ export const NodePendingDrainResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Enqueues gateway-initiated work for a paired node. */
|
||||
export const NodePendingEnqueueParamsSchema = Type.Object(
|
||||
{
|
||||
nodeId: NonEmptyString,
|
||||
@@ -184,6 +206,7 @@ export const NodePendingEnqueueParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Enqueue result echoes queue revision and whether wake delivery was attempted. */
|
||||
export const NodePendingEnqueueResultSchema = Type.Object(
|
||||
{
|
||||
nodeId: NonEmptyString,
|
||||
@@ -194,6 +217,7 @@ export const NodePendingEnqueueResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Event payload used by the gateway to ask a node to run a command. */
|
||||
export const NodeInvokeRequestEventSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
import { Type } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Plugin approval schemas.
|
||||
*
|
||||
* These payloads cross from plugin/tool execution into reviewer-facing UI, so
|
||||
* title, description, decision set, and timeout limits are part of the public
|
||||
* gateway contract.
|
||||
*/
|
||||
const MAX_PLUGIN_APPROVAL_TIMEOUT_MS = 600_000;
|
||||
const PLUGIN_APPROVAL_TITLE_MAX_LENGTH = 80;
|
||||
const PLUGIN_APPROVAL_DESCRIPTION_MAX_LENGTH = 256;
|
||||
|
||||
/** Approval request raised by a plugin before a sensitive tool action proceeds. */
|
||||
export const PluginApprovalRequestParamsSchema = Type.Object(
|
||||
{
|
||||
pluginId: Type.Optional(NonEmptyString),
|
||||
@@ -31,6 +39,7 @@ export const PluginApprovalRequestParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Reviewer decision payload resolving one pending plugin approval request. */
|
||||
export const PluginApprovalResolveParamsSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
import { Type } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Plugin control-surface protocol schemas.
|
||||
*
|
||||
* These payloads let the gateway expose plugin-provided UI actions without
|
||||
* baking plugin-specific payload shapes into the core protocol.
|
||||
*/
|
||||
/** Arbitrary plugin-owned JSON payload carried opaquely through the gateway. */
|
||||
export const PluginJsonValueSchema = Type.Unknown();
|
||||
|
||||
/** Descriptor for one plugin-provided control UI action or surface. */
|
||||
export const PluginControlUiDescriptorSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -23,8 +31,10 @@ export const PluginControlUiDescriptorSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Empty request payload for listing plugin UI descriptors. */
|
||||
export const PluginsUiDescriptorsParamsSchema = Type.Object({}, { additionalProperties: false });
|
||||
|
||||
/** Response payload containing all plugin UI descriptors visible to the client. */
|
||||
export const PluginsUiDescriptorsResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Literal(true),
|
||||
@@ -33,6 +43,7 @@ export const PluginsUiDescriptorsResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Request payload for invoking one plugin-owned session action. */
|
||||
export const PluginsSessionActionParamsSchema = Type.Object(
|
||||
{
|
||||
pluginId: NonEmptyString,
|
||||
@@ -43,6 +54,7 @@ export const PluginsSessionActionParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Successful plugin action result, optionally continuing the agent turn. */
|
||||
export const PluginsSessionActionSuccessResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Literal(true),
|
||||
@@ -53,6 +65,7 @@ export const PluginsSessionActionSuccessResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Failed plugin action result with plugin-owned detail payload. */
|
||||
export const PluginsSessionActionFailureResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Literal(false),
|
||||
@@ -63,6 +76,7 @@ export const PluginsSessionActionFailureResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Discriminated plugin action result returned to gateway clients. */
|
||||
export const PluginsSessionActionResultSchema = Type.Union([
|
||||
PluginsSessionActionSuccessResultSchema,
|
||||
PluginsSessionActionFailureResultSchema,
|
||||
|
||||
@@ -8,20 +8,31 @@ import {
|
||||
SINGLE_VALUE_FILE_REF_ID,
|
||||
} from "../secret-ref-contract.js";
|
||||
|
||||
/**
|
||||
* Shared schema primitives reused by gateway protocol request/result schemas.
|
||||
*
|
||||
* Keep these schemas small and transport-oriented; feature-specific validation
|
||||
* belongs in the owning schema module or runtime handler.
|
||||
*/
|
||||
const ENV_SECRET_REF_ID_RE = /^[A-Z][A-Z0-9_]{0,127}$/;
|
||||
const INPUT_PROVENANCE_KIND_VALUES = ["external_user", "inter_session", "internal_system"] as const;
|
||||
const SESSION_LABEL_MAX_LENGTH = 512;
|
||||
|
||||
/** Non-empty string primitive for protocol fields that reject blank values. */
|
||||
export const NonEmptyString = Type.String({ minLength: 1 });
|
||||
/** Maximum stable session key length accepted by chat-send protocol requests. */
|
||||
export const CHAT_SEND_SESSION_KEY_MAX_LENGTH = 512;
|
||||
/** Chat-send session key string primitive with bounded length. */
|
||||
export const ChatSendSessionKeyString = Type.String({
|
||||
minLength: 1,
|
||||
maxLength: CHAT_SEND_SESSION_KEY_MAX_LENGTH,
|
||||
});
|
||||
/** Human-readable session label primitive with bounded display length. */
|
||||
export const SessionLabelString = Type.String({
|
||||
minLength: 1,
|
||||
maxLength: SESSION_LABEL_MAX_LENGTH,
|
||||
});
|
||||
/** Provenance marker for content copied from another user/session/system source. */
|
||||
export const InputProvenanceSchema = Type.Object(
|
||||
{
|
||||
kind: Type.String({ enum: [...INPUT_PROVENANCE_KIND_VALUES] }),
|
||||
@@ -33,10 +44,13 @@ export const InputProvenanceSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Closed gateway client id schema aligned with `GATEWAY_CLIENT_IDS`. */
|
||||
export const GatewayClientIdSchema = Type.Enum(GATEWAY_CLIENT_IDS);
|
||||
|
||||
/** Closed gateway client mode schema aligned with `GATEWAY_CLIENT_MODES`. */
|
||||
export const GatewayClientModeSchema = Type.Enum(GATEWAY_CLIENT_MODES);
|
||||
|
||||
/** Supported secret reference backing stores for protocol SecretRef payloads. */
|
||||
export const SecretRefSourceSchema = Type.Union([
|
||||
Type.Literal("env"),
|
||||
Type.Literal("file"),
|
||||
@@ -87,10 +101,12 @@ const ExecSecretRefSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Structured secret reference accepted by config and channel protocol payloads. */
|
||||
export const SecretRefSchema = Type.Union([
|
||||
EnvSecretRefSchema,
|
||||
FileSecretRefSchema,
|
||||
ExecSecretRefSchema,
|
||||
]);
|
||||
|
||||
/** Secret input value: either an inline string or a structured SecretRef. */
|
||||
export const SecretInputSchema = Type.Union([Type.String(), SecretRefSchema]);
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/**
|
||||
* Central registry for every gateway protocol schema.
|
||||
*
|
||||
* The keys in this object are the public schema names used by validators,
|
||||
* generated static types, and protocol tooling. Add new entries here only after
|
||||
* the owning schema module exports the canonical TypeBox schema.
|
||||
*/
|
||||
import type { TSchema } from "typebox";
|
||||
import {
|
||||
AgentEventSchema,
|
||||
@@ -292,7 +299,9 @@ import {
|
||||
WizardStepSchema,
|
||||
} from "./wizard.js";
|
||||
|
||||
/** Public schema registry keyed by stable protocol schema name. */
|
||||
export const ProtocolSchemas = {
|
||||
// Handshake, transport frames, state snapshots, and shared error envelopes.
|
||||
ConnectParams: ConnectParamsSchema,
|
||||
HelloOk: HelloOkSchema,
|
||||
RequestFrame: RequestFrameSchema,
|
||||
@@ -303,6 +312,8 @@ export const ProtocolSchemas = {
|
||||
StateVersion: StateVersionSchema,
|
||||
Snapshot: SnapshotSchema,
|
||||
ErrorShape: ErrorShapeSchema,
|
||||
|
||||
// Environment and agent-facing control RPC payloads.
|
||||
EnvironmentStatus: EnvironmentStatusSchema,
|
||||
EnvironmentSummary: EnvironmentSummarySchema,
|
||||
EnvironmentsListParams: EnvironmentsListParamsSchema,
|
||||
@@ -318,6 +329,8 @@ export const ProtocolSchemas = {
|
||||
AgentIdentityResult: AgentIdentityResultSchema,
|
||||
AgentWaitParams: AgentWaitParamsSchema,
|
||||
WakeParams: WakeParamsSchema,
|
||||
|
||||
// Node pairing, invocation, presence, and pending-queue payloads.
|
||||
NodePairRequestParams: NodePairRequestParamsSchema,
|
||||
NodePairListParams: NodePairListParamsSchema,
|
||||
NodePairApproveParams: NodePairApproveParamsSchema,
|
||||
@@ -339,12 +352,16 @@ export const ProtocolSchemas = {
|
||||
NodePendingEnqueueParams: NodePendingEnqueueParamsSchema,
|
||||
NodePendingEnqueueResult: NodePendingEnqueueResultSchema,
|
||||
NodeInvokeRequestEvent: NodeInvokeRequestEventSchema,
|
||||
|
||||
// Push and secret-resolution payloads used by mobile/control integrations.
|
||||
PushTestParams: PushTestParamsSchema,
|
||||
PushTestResult: PushTestResultSchema,
|
||||
SecretsReloadParams: SecretsReloadParamsSchema,
|
||||
SecretsResolveParams: SecretsResolveParamsSchema,
|
||||
SecretsResolveAssignment: SecretsResolveAssignmentSchema,
|
||||
SecretsResolveResult: SecretsResolveResultSchema,
|
||||
|
||||
// Session lifecycle, message routing, compaction, and usage accounting.
|
||||
SessionsListParams: SessionsListParamsSchema,
|
||||
SessionsCleanupParams: SessionsCleanupParamsSchema,
|
||||
SessionsPreviewParams: SessionsPreviewParamsSchema,
|
||||
@@ -372,6 +389,8 @@ export const ProtocolSchemas = {
|
||||
SessionsDeleteParams: SessionsDeleteParamsSchema,
|
||||
SessionsCompactParams: SessionsCompactParamsSchema,
|
||||
SessionsUsageParams: SessionsUsageParamsSchema,
|
||||
|
||||
// Task ledger and config/wizard setup payloads.
|
||||
TaskSummary: TaskSummarySchema,
|
||||
TasksListParams: TasksListParamsSchema,
|
||||
TasksListResult: TasksListResultSchema,
|
||||
@@ -395,6 +414,8 @@ export const ProtocolSchemas = {
|
||||
WizardNextResult: WizardNextResultSchema,
|
||||
WizardStartResult: WizardStartResultSchema,
|
||||
WizardStatusResult: WizardStatusResultSchema,
|
||||
|
||||
// Realtime Talk client/session events and channel control payloads.
|
||||
TalkModeParams: TalkModeParamsSchema,
|
||||
TalkEvent: TalkEventSchema,
|
||||
TalkCatalogParams: TalkCatalogParamsSchema,
|
||||
@@ -429,6 +450,8 @@ export const ProtocolSchemas = {
|
||||
ChannelsLogoutParams: ChannelsLogoutParamsSchema,
|
||||
WebLoginStartParams: WebLoginStartParamsSchema,
|
||||
WebLoginWaitParams: WebLoginWaitParamsSchema,
|
||||
|
||||
// Agent files, artifacts, model catalogs, commands, tools, and skill workshop.
|
||||
AgentSummary: AgentSummarySchema,
|
||||
AgentsCreateParams: AgentsCreateParamsSchema,
|
||||
AgentsCreateResult: AgentsCreateResultSchema,
|
||||
@@ -497,6 +520,8 @@ export const ProtocolSchemas = {
|
||||
SkillsUploadCommitParams: SkillsUploadCommitParamsSchema,
|
||||
SkillsInstallParams: SkillsInstallParamsSchema,
|
||||
SkillsUpdateParams: SkillsUpdateParamsSchema,
|
||||
|
||||
// Scheduler, logs, approval, plugin control, device, chat, and lifecycle events.
|
||||
CronJob: CronJobSchema,
|
||||
CronListParams: CronListParamsSchema,
|
||||
CronStatusParams: CronStatusParamsSchema,
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
import { Type } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Push-notification protocol schemas.
|
||||
*
|
||||
* APNS test schemas exercise native push routing; Web Push schemas describe the
|
||||
* browser subscription lifecycle exposed by the gateway.
|
||||
*/
|
||||
const ApnsEnvironmentSchema = Type.String({ enum: ["sandbox", "production"] });
|
||||
|
||||
/** Request payload for sending a test APNS notification to one node. */
|
||||
export const PushTestParamsSchema = Type.Object(
|
||||
{
|
||||
nodeId: NonEmptyString,
|
||||
@@ -13,6 +20,7 @@ export const PushTestParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Result payload from an APNS push test, including provider status and transport. */
|
||||
export const PushTestResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Boolean(),
|
||||
@@ -37,8 +45,10 @@ const WebPushKeysSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Empty request payload for fetching the Web Push VAPID public key. */
|
||||
export const WebPushVapidPublicKeyParamsSchema = Type.Object({}, { additionalProperties: false });
|
||||
|
||||
/** Browser Web Push subscription payload registered with the gateway. */
|
||||
export const WebPushSubscribeParamsSchema = Type.Object(
|
||||
{
|
||||
endpoint: Type.String({ minLength: 1, maxLength: 2048, pattern: "^https://" }),
|
||||
@@ -47,6 +57,7 @@ export const WebPushSubscribeParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Browser Web Push endpoint removal payload. */
|
||||
export const WebPushUnsubscribeParamsSchema = Type.Object(
|
||||
{
|
||||
endpoint: Type.String({ minLength: 1, maxLength: 2048, pattern: "^https://" }),
|
||||
@@ -54,6 +65,7 @@ export const WebPushUnsubscribeParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Request payload for sending a test Web Push notification to current subscriptions. */
|
||||
export const WebPushTestParamsSchema = Type.Object(
|
||||
{
|
||||
title: Type.Optional(Type.String()),
|
||||
@@ -62,14 +74,18 @@ export const WebPushTestParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Empty request type for fetching the Web Push VAPID public key. */
|
||||
export type WebPushVapidPublicKeyParams = Record<string, never>;
|
||||
/** Browser PushSubscription subset persisted by the gateway. */
|
||||
export type WebPushSubscribeParams = {
|
||||
endpoint: string;
|
||||
keys: { p256dh: string; auth: string };
|
||||
};
|
||||
/** Browser PushSubscription endpoint removal request. */
|
||||
export type WebPushUnsubscribeParams = {
|
||||
endpoint: string;
|
||||
};
|
||||
/** Optional title/body overrides for a Web Push test notification. */
|
||||
export type WebPushTestParams = {
|
||||
title?: string;
|
||||
body?: string;
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
import { Type, type Static } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Secret-provider protocol schemas.
|
||||
*
|
||||
* These payloads request secret materialization from the gateway while keeping
|
||||
* caller scope, allowed paths, and provider overrides explicit.
|
||||
*/
|
||||
/** Empty request payload for reloading configured secret providers. */
|
||||
export const SecretsReloadParamsSchema = Type.Object({}, { additionalProperties: false });
|
||||
|
||||
/** Request payload for resolving the secrets needed by one command invocation. */
|
||||
export const SecretsResolveParamsSchema = Type.Object(
|
||||
{
|
||||
commandName: NonEmptyString,
|
||||
@@ -23,8 +31,10 @@ export const SecretsResolveParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Static type for secret resolution requests. */
|
||||
export type SecretsResolveParams = Static<typeof SecretsResolveParamsSchema>;
|
||||
|
||||
/** One resolved secret assignment path plus its provider-owned value. */
|
||||
export const SecretsResolveAssignmentSchema = Type.Object(
|
||||
{
|
||||
path: Type.Optional(NonEmptyString),
|
||||
@@ -34,6 +44,7 @@ export const SecretsResolveAssignmentSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Secret resolution response with assignments and safe diagnostics. */
|
||||
export const SecretsResolveResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Optional(Type.Boolean()),
|
||||
@@ -44,4 +55,5 @@ export const SecretsResolveResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Static type for secret resolution responses. */
|
||||
export type SecretsResolveResult = Static<typeof SecretsResolveResultSchema>;
|
||||
|
||||
@@ -2,6 +2,15 @@ import { Type } from "typebox";
|
||||
import { PluginJsonValueSchema } from "./plugins.js";
|
||||
import { NonEmptyString, SessionLabelString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Session protocol schemas.
|
||||
*
|
||||
* These requests and results cover transcript discovery, lifecycle control,
|
||||
* compaction checkpoints, per-session plugin state, and usage reporting. The
|
||||
* schemas are shared by dashboard, CLI, ACP, and gateway RPC callers.
|
||||
*/
|
||||
|
||||
/** Reason a compaction checkpoint was created. */
|
||||
export const SessionCompactionCheckpointReasonSchema = Type.Union([
|
||||
Type.Literal("manual"),
|
||||
Type.Literal("auto-threshold"),
|
||||
@@ -9,6 +18,7 @@ export const SessionCompactionCheckpointReasonSchema = Type.Union([
|
||||
Type.Literal("timeout-retry"),
|
||||
]);
|
||||
|
||||
/** Start/end event emitted while a session compaction operation runs. */
|
||||
export const SessionOperationEventSchema = Type.Object(
|
||||
{
|
||||
operationId: NonEmptyString,
|
||||
@@ -23,6 +33,7 @@ export const SessionOperationEventSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Reference to the transcript location before or after compaction. */
|
||||
export const SessionCompactionTranscriptReferenceSchema = Type.Object(
|
||||
{
|
||||
sessionId: NonEmptyString,
|
||||
@@ -33,6 +44,7 @@ export const SessionCompactionTranscriptReferenceSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Stored compaction checkpoint metadata for branching or restoring a session. */
|
||||
export const SessionCompactionCheckpointSchema = Type.Object(
|
||||
{
|
||||
checkpointId: NonEmptyString,
|
||||
@@ -50,6 +62,7 @@ export const SessionCompactionCheckpointSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Lists sessions with optional scope, activity, label, and preview filters. */
|
||||
export const SessionsListParamsSchema = Type.Object(
|
||||
{
|
||||
/**
|
||||
@@ -84,6 +97,7 @@ export const SessionsListParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Repairs or removes invalid session records from the selected agent scope. */
|
||||
export const SessionsCleanupParamsSchema = Type.Object(
|
||||
{
|
||||
agent: Type.Optional(NonEmptyString),
|
||||
@@ -96,6 +110,7 @@ export const SessionsCleanupParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Reads short previews for selected session keys. */
|
||||
export const SessionsPreviewParamsSchema = Type.Object(
|
||||
{
|
||||
keys: Type.Array(NonEmptyString, { minItems: 1 }),
|
||||
@@ -105,6 +120,7 @@ export const SessionsPreviewParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Describes one session and optional derived title/last-message previews. */
|
||||
export const SessionsDescribeParamsSchema = Type.Object(
|
||||
{
|
||||
key: NonEmptyString,
|
||||
@@ -114,6 +130,7 @@ export const SessionsDescribeParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Resolves a session by key, raw session id, label, or parent/agent scope. */
|
||||
export const SessionsResolveParamsSchema = Type.Object(
|
||||
{
|
||||
key: Type.Optional(NonEmptyString),
|
||||
@@ -127,6 +144,7 @@ export const SessionsResolveParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Creates or adopts a session with optional model, label, and parent linkage. */
|
||||
export const SessionsCreateParamsSchema = Type.Object(
|
||||
{
|
||||
key: Type.Optional(NonEmptyString),
|
||||
@@ -141,6 +159,7 @@ export const SessionsCreateParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Sends one message into an existing session. */
|
||||
export const SessionsSendParamsSchema = Type.Object(
|
||||
{
|
||||
key: NonEmptyString,
|
||||
@@ -154,6 +173,7 @@ export const SessionsSendParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Subscribes a client to live message updates for one session. */
|
||||
export const SessionsMessagesSubscribeParamsSchema = Type.Object(
|
||||
{
|
||||
key: NonEmptyString,
|
||||
@@ -162,6 +182,7 @@ export const SessionsMessagesSubscribeParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Removes a live message subscription for one session. */
|
||||
export const SessionsMessagesUnsubscribeParamsSchema = Type.Object(
|
||||
{
|
||||
key: NonEmptyString,
|
||||
@@ -170,6 +191,7 @@ export const SessionsMessagesUnsubscribeParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Aborts the active or named run for a session. */
|
||||
export const SessionsAbortParamsSchema = Type.Object(
|
||||
{
|
||||
key: Type.Optional(NonEmptyString),
|
||||
@@ -179,6 +201,7 @@ export const SessionsAbortParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Mutable per-session preferences and routing metadata. */
|
||||
export const SessionsPatchParamsSchema = Type.Object(
|
||||
{
|
||||
key: NonEmptyString,
|
||||
@@ -227,6 +250,7 @@ export const SessionsPatchParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Updates or clears one plugin namespace value on a session record. */
|
||||
export const SessionsPluginPatchParamsSchema = Type.Object(
|
||||
{
|
||||
key: NonEmptyString,
|
||||
@@ -238,6 +262,7 @@ export const SessionsPluginPatchParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Result returned after patching session plugin state. */
|
||||
export const SessionsPluginPatchResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Literal(true),
|
||||
@@ -247,6 +272,7 @@ export const SessionsPluginPatchResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Resets a session to a new or reset transcript state. */
|
||||
export const SessionsResetParamsSchema = Type.Object(
|
||||
{
|
||||
key: NonEmptyString,
|
||||
@@ -256,6 +282,7 @@ export const SessionsResetParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Deletes a session record and optionally its transcript. */
|
||||
export const SessionsDeleteParamsSchema = Type.Object(
|
||||
{
|
||||
key: NonEmptyString,
|
||||
@@ -267,6 +294,7 @@ export const SessionsDeleteParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Requests manual compaction for a session transcript. */
|
||||
export const SessionsCompactParamsSchema = Type.Object(
|
||||
{
|
||||
key: NonEmptyString,
|
||||
@@ -276,6 +304,7 @@ export const SessionsCompactParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Lists compaction checkpoints for one session. */
|
||||
export const SessionsCompactionListParamsSchema = Type.Object(
|
||||
{
|
||||
key: NonEmptyString,
|
||||
@@ -284,6 +313,7 @@ export const SessionsCompactionListParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Reads one compaction checkpoint by id. */
|
||||
export const SessionsCompactionGetParamsSchema = Type.Object(
|
||||
{
|
||||
key: NonEmptyString,
|
||||
@@ -293,6 +323,7 @@ export const SessionsCompactionGetParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Creates a new branch from a compaction checkpoint. */
|
||||
export const SessionsCompactionBranchParamsSchema = Type.Object(
|
||||
{
|
||||
key: NonEmptyString,
|
||||
@@ -302,6 +333,7 @@ export const SessionsCompactionBranchParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Restores an existing session to a compaction checkpoint. */
|
||||
export const SessionsCompactionRestoreParamsSchema = Type.Object(
|
||||
{
|
||||
key: NonEmptyString,
|
||||
@@ -311,6 +343,7 @@ export const SessionsCompactionRestoreParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** List response for session compaction checkpoints. */
|
||||
export const SessionsCompactionListResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Literal(true),
|
||||
@@ -320,6 +353,7 @@ export const SessionsCompactionListResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Get response for a single compaction checkpoint. */
|
||||
export const SessionsCompactionGetResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Literal(true),
|
||||
@@ -329,6 +363,7 @@ export const SessionsCompactionGetResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Branch response with the newly created session key and entry metadata. */
|
||||
export const SessionsCompactionBranchResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Literal(true),
|
||||
@@ -347,6 +382,7 @@ export const SessionsCompactionBranchResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Restore response with updated session entry metadata. */
|
||||
export const SessionsCompactionRestoreResultSchema = Type.Object(
|
||||
{
|
||||
ok: Type.Literal(true),
|
||||
@@ -364,6 +400,7 @@ export const SessionsCompactionRestoreResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Usage report query across one session, one agent, or all agent sessions. */
|
||||
export const SessionsUsageParamsSchema = Type.Object(
|
||||
{
|
||||
/** Specific session key to analyze; if omitted returns sessions for the effective agent. */
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import { Type } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Gateway state snapshot schemas.
|
||||
*
|
||||
* Snapshots are sent during hello and later event streams; they summarize node
|
||||
* presence, health, session defaults, and version counters for clients.
|
||||
*/
|
||||
/** One gateway-visible presence record for a node/client/runtime. */
|
||||
export const PresenceEntrySchema = Type.Object(
|
||||
{
|
||||
host: Type.Optional(NonEmptyString),
|
||||
@@ -23,8 +30,10 @@ export const PresenceEntrySchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Health snapshot is intentionally opaque because providers contribute nested shapes. */
|
||||
export const HealthSnapshotSchema = Type.Any();
|
||||
|
||||
/** Default session routing keys included in initial gateway snapshots. */
|
||||
export const SessionDefaultsSchema = Type.Object(
|
||||
{
|
||||
defaultAgentId: NonEmptyString,
|
||||
@@ -35,6 +44,7 @@ export const SessionDefaultsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Monotonic version counters for snapshot subtrees. */
|
||||
export const StateVersionSchema = Type.Object(
|
||||
{
|
||||
presence: Type.Integer({ minimum: 0 }),
|
||||
@@ -43,6 +53,7 @@ export const StateVersionSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Initial and incremental gateway state snapshot payload. */
|
||||
export const SnapshotSchema = Type.Object(
|
||||
{
|
||||
presence: Type.Array(PresenceEntrySchema),
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import { Type } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/**
|
||||
* Task ledger protocol schemas.
|
||||
*
|
||||
* Tasks represent long-running SDK/agent operations exposed through the gateway;
|
||||
* these schemas keep list/get/cancel payloads bounded and status values closed.
|
||||
*/
|
||||
/** Closed task lifecycle statuses visible in the gateway task ledger. */
|
||||
export const TaskLedgerStatusSchema = Type.Union([
|
||||
Type.Literal("queued"),
|
||||
Type.Literal("running"),
|
||||
@@ -12,6 +19,7 @@ export const TaskLedgerStatusSchema = Type.Union([
|
||||
|
||||
const TimestampSchema = Type.Union([Type.String(), Type.Integer({ minimum: 0 })]);
|
||||
|
||||
/** Public task summary returned by task list/get/cancel responses. */
|
||||
export const TaskSummarySchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -39,6 +47,7 @@ export const TaskSummarySchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Task list filters with bounded pagination. */
|
||||
export const TasksListParamsSchema = Type.Object(
|
||||
{
|
||||
status: Type.Optional(Type.Union([TaskLedgerStatusSchema, Type.Array(TaskLedgerStatusSchema)])),
|
||||
@@ -50,6 +59,7 @@ export const TasksListParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Task list page response. */
|
||||
export const TasksListResultSchema = Type.Object(
|
||||
{
|
||||
tasks: Type.Array(TaskSummarySchema),
|
||||
@@ -58,6 +68,7 @@ export const TasksListResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Lookup request for one task id. */
|
||||
export const TasksGetParamsSchema = Type.Object(
|
||||
{
|
||||
taskId: NonEmptyString,
|
||||
@@ -65,6 +76,7 @@ export const TasksGetParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Lookup result for one task summary. */
|
||||
export const TasksGetResultSchema = Type.Object(
|
||||
{
|
||||
task: TaskSummarySchema,
|
||||
@@ -72,6 +84,7 @@ export const TasksGetResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Cancel request for one task id with optional operator reason. */
|
||||
export const TasksCancelParamsSchema = Type.Object(
|
||||
{
|
||||
taskId: NonEmptyString,
|
||||
@@ -80,6 +93,7 @@ export const TasksCancelParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Cancel result, including the task snapshot when it was found. */
|
||||
export const TasksCancelResultSchema = Type.Object(
|
||||
{
|
||||
found: Type.Boolean(),
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
/**
|
||||
* Static TypeScript types derived from the canonical gateway protocol schemas.
|
||||
*
|
||||
* Keep aliases wired through `ProtocolSchemas` so validators, runtime schemas,
|
||||
* and exported compile-time types cannot drift apart.
|
||||
*/
|
||||
import type { Static } from "typebox";
|
||||
import { ProtocolSchemas } from "./protocol-schemas.js";
|
||||
|
||||
/** Stable schema names registered in the protocol schema registry. */
|
||||
type ProtocolSchemaName = keyof typeof ProtocolSchemas;
|
||||
/** Inferred TypeScript type for a named TypeBox protocol schema. */
|
||||
type SchemaType<TName extends ProtocolSchemaName> = Static<(typeof ProtocolSchemas)[TName]>;
|
||||
|
||||
/** Connection handshake, envelope, snapshot, and shared error wire types. */
|
||||
export type ConnectParams = SchemaType<"ConnectParams">;
|
||||
export type HelloOk = SchemaType<"HelloOk">;
|
||||
export type RequestFrame = SchemaType<"RequestFrame">;
|
||||
@@ -14,12 +23,16 @@ export type Snapshot = SchemaType<"Snapshot">;
|
||||
export type PresenceEntry = SchemaType<"PresenceEntry">;
|
||||
export type ErrorShape = SchemaType<"ErrorShape">;
|
||||
export type StateVersion = SchemaType<"StateVersion">;
|
||||
|
||||
/** Environment status RPC payloads used by CLI and Control UI surfaces. */
|
||||
export type EnvironmentStatus = SchemaType<"EnvironmentStatus">;
|
||||
export type EnvironmentSummary = SchemaType<"EnvironmentSummary">;
|
||||
export type EnvironmentsListParams = SchemaType<"EnvironmentsListParams">;
|
||||
export type EnvironmentsListResult = SchemaType<"EnvironmentsListResult">;
|
||||
export type EnvironmentsStatusParams = SchemaType<"EnvironmentsStatusParams">;
|
||||
export type EnvironmentsStatusResult = SchemaType<"EnvironmentsStatusResult">;
|
||||
|
||||
/** Agent activity, identity, send, poll, wait, and wake protocol payloads. */
|
||||
export type AgentEvent = SchemaType<"AgentEvent">;
|
||||
export type AgentIdentityParams = SchemaType<"AgentIdentityParams">;
|
||||
export type AgentIdentityResult = SchemaType<"AgentIdentityResult">;
|
||||
@@ -27,6 +40,8 @@ export type MessageActionParams = SchemaType<"MessageActionParams">;
|
||||
export type PollParams = SchemaType<"PollParams">;
|
||||
export type AgentWaitParams = SchemaType<"AgentWaitParams">;
|
||||
export type WakeParams = SchemaType<"WakeParams">;
|
||||
|
||||
/** Node pairing, presence, invoke, and pending-queue protocol payloads. */
|
||||
export type NodePairRequestParams = SchemaType<"NodePairRequestParams">;
|
||||
export type NodePairListParams = SchemaType<"NodePairListParams">;
|
||||
export type NodePairApproveParams = SchemaType<"NodePairApproveParams">;
|
||||
@@ -47,8 +62,12 @@ export type NodePendingDrainParams = SchemaType<"NodePendingDrainParams">;
|
||||
export type NodePendingDrainResult = SchemaType<"NodePendingDrainResult">;
|
||||
export type NodePendingEnqueueParams = SchemaType<"NodePendingEnqueueParams">;
|
||||
export type NodePendingEnqueueResult = SchemaType<"NodePendingEnqueueResult">;
|
||||
|
||||
/** Push notification test result contracts exposed through gateway RPC. */
|
||||
export type PushTestParams = SchemaType<"PushTestParams">;
|
||||
export type PushTestResult = SchemaType<"PushTestResult">;
|
||||
|
||||
/** Session lifecycle, message routing, compaction, patch, and usage payloads. */
|
||||
export type SessionsListParams = SchemaType<"SessionsListParams">;
|
||||
export type SessionsCleanupParams = SchemaType<"SessionsCleanupParams">;
|
||||
export type SessionsPreviewParams = SchemaType<"SessionsPreviewParams">;
|
||||
@@ -76,6 +95,8 @@ export type SessionsResetParams = SchemaType<"SessionsResetParams">;
|
||||
export type SessionsDeleteParams = SchemaType<"SessionsDeleteParams">;
|
||||
export type SessionsCompactParams = SchemaType<"SessionsCompactParams">;
|
||||
export type SessionsUsageParams = SchemaType<"SessionsUsageParams">;
|
||||
|
||||
/** Task ledger query and cancellation payloads. */
|
||||
export type TaskSummary = SchemaType<"TaskSummary">;
|
||||
export type TasksListParams = SchemaType<"TasksListParams">;
|
||||
export type TasksListResult = SchemaType<"TasksListResult">;
|
||||
@@ -83,6 +104,8 @@ export type TasksGetParams = SchemaType<"TasksGetParams">;
|
||||
export type TasksGetResult = SchemaType<"TasksGetResult">;
|
||||
export type TasksCancelParams = SchemaType<"TasksCancelParams">;
|
||||
export type TasksCancelResult = SchemaType<"TasksCancelResult">;
|
||||
|
||||
/** Config read/write/schema payloads plus update status and run controls. */
|
||||
export type ConfigGetParams = SchemaType<"ConfigGetParams">;
|
||||
export type ConfigSetParams = SchemaType<"ConfigSetParams">;
|
||||
export type ConfigApplyParams = SchemaType<"ConfigApplyParams">;
|
||||
@@ -92,6 +115,8 @@ export type ConfigSchemaLookupParams = SchemaType<"ConfigSchemaLookupParams">;
|
||||
export type ConfigSchemaResponse = SchemaType<"ConfigSchemaResponse">;
|
||||
export type ConfigSchemaLookupResult = SchemaType<"ConfigSchemaLookupResult">;
|
||||
export type UpdateStatusParams = SchemaType<"UpdateStatusParams">;
|
||||
|
||||
/** Wizard setup flow payloads exchanged by CLI, UI, and gateway. */
|
||||
export type WizardStartParams = SchemaType<"WizardStartParams">;
|
||||
export type WizardNextParams = SchemaType<"WizardNextParams">;
|
||||
export type WizardCancelParams = SchemaType<"WizardCancelParams">;
|
||||
@@ -100,6 +125,8 @@ export type WizardStep = SchemaType<"WizardStep">;
|
||||
export type WizardNextResult = SchemaType<"WizardNextResult">;
|
||||
export type WizardStartResult = SchemaType<"WizardStartResult">;
|
||||
export type WizardStatusResult = SchemaType<"WizardStatusResult">;
|
||||
|
||||
/** Realtime Talk client/session/event payloads. */
|
||||
export type TalkEvent = SchemaType<"TalkEvent">;
|
||||
export type TalkModeParams = SchemaType<"TalkModeParams">;
|
||||
export type TalkCatalogParams = SchemaType<"TalkCatalogParams">;
|
||||
@@ -127,6 +154,8 @@ export type TalkSessionCloseParams = SchemaType<"TalkSessionCloseParams">;
|
||||
export type TalkSessionOkResult = SchemaType<"TalkSessionOkResult">;
|
||||
export type TalkSpeakParams = SchemaType<"TalkSpeakParams">;
|
||||
export type TalkSpeakResult = SchemaType<"TalkSpeakResult">;
|
||||
|
||||
/** Channel control and web-login payloads. */
|
||||
export type ChannelsStatusParams = SchemaType<"ChannelsStatusParams">;
|
||||
export type ChannelsStatusResult = SchemaType<"ChannelsStatusResult">;
|
||||
export type ChannelsStartParams = SchemaType<"ChannelsStartParams">;
|
||||
@@ -134,6 +163,8 @@ export type ChannelsStopParams = SchemaType<"ChannelsStopParams">;
|
||||
export type ChannelsLogoutParams = SchemaType<"ChannelsLogoutParams">;
|
||||
export type WebLoginStartParams = SchemaType<"WebLoginStartParams">;
|
||||
export type WebLoginWaitParams = SchemaType<"WebLoginWaitParams">;
|
||||
|
||||
/** Agent config-file CRUD and artifact download/list payloads. */
|
||||
export type AgentSummary = SchemaType<"AgentSummary">;
|
||||
export type AgentsFileEntry = SchemaType<"AgentsFileEntry">;
|
||||
export type AgentsCreateParams = SchemaType<"AgentsCreateParams">;
|
||||
@@ -155,6 +186,8 @@ export type ArtifactsGetParams = SchemaType<"ArtifactsGetParams">;
|
||||
export type ArtifactsGetResult = SchemaType<"ArtifactsGetResult">;
|
||||
export type ArtifactsDownloadParams = SchemaType<"ArtifactsDownloadParams">;
|
||||
export type ArtifactsDownloadResult = SchemaType<"ArtifactsDownloadResult">;
|
||||
|
||||
/** Model, command, plugin UI action, tool catalog, and skill workshop payloads. */
|
||||
export type AgentsListParams = SchemaType<"AgentsListParams">;
|
||||
export type AgentsListResult = SchemaType<"AgentsListResult">;
|
||||
export type ModelChoice = SchemaType<"ModelChoice">;
|
||||
@@ -207,6 +240,8 @@ export type SkillsUploadChunkParams = SchemaType<"SkillsUploadChunkParams">;
|
||||
export type SkillsUploadCommitParams = SchemaType<"SkillsUploadCommitParams">;
|
||||
export type SkillsInstallParams = SchemaType<"SkillsInstallParams">;
|
||||
export type SkillsUpdateParams = SchemaType<"SkillsUpdateParams">;
|
||||
|
||||
/** Cron scheduler and run-log payloads. */
|
||||
export type CronJob = SchemaType<"CronJob">;
|
||||
export type CronListParams = SchemaType<"CronListParams">;
|
||||
export type CronStatusParams = SchemaType<"CronStatusParams">;
|
||||
@@ -217,6 +252,8 @@ export type CronRemoveParams = SchemaType<"CronRemoveParams">;
|
||||
export type CronRunParams = SchemaType<"CronRunParams">;
|
||||
export type CronRunsParams = SchemaType<"CronRunsParams">;
|
||||
export type CronRunLogEntry = SchemaType<"CronRunLogEntry">;
|
||||
|
||||
/** Logs and approval payloads for chat, exec commands, plugins, and devices. */
|
||||
export type LogsTailParams = SchemaType<"LogsTailParams">;
|
||||
export type LogsTailResult = SchemaType<"LogsTailResult">;
|
||||
export type ExecApprovalsGetParams = SchemaType<"ExecApprovalsGetParams">;
|
||||
@@ -238,6 +275,8 @@ export type DeviceTokenRevokeParams = SchemaType<"DeviceTokenRevokeParams">;
|
||||
export type ChatAbortParams = SchemaType<"ChatAbortParams">;
|
||||
export type ChatInjectParams = SchemaType<"ChatInjectParams">;
|
||||
export type ChatEvent = SchemaType<"ChatEvent">;
|
||||
|
||||
/** Gateway update and process lifecycle event payloads. */
|
||||
export type UpdateRunParams = SchemaType<"UpdateRunParams">;
|
||||
export type TickEvent = SchemaType<"TickEvent">;
|
||||
export type ShutdownEvent = SchemaType<"ShutdownEvent">;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Type } from "typebox";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
/** Runtime state reported for gateway-driven setup wizard sessions. */
|
||||
const WizardRunStatusSchema = Type.Union([
|
||||
Type.Literal("running"),
|
||||
Type.Literal("done"),
|
||||
@@ -8,6 +9,7 @@ const WizardRunStatusSchema = Type.Union([
|
||||
Type.Literal("error"),
|
||||
]);
|
||||
|
||||
/** Starts a setup wizard, optionally scoped to a local or remote workspace. */
|
||||
export const WizardStartParamsSchema = Type.Object(
|
||||
{
|
||||
mode: Type.Optional(Type.Union([Type.Literal("local"), Type.Literal("remote")])),
|
||||
@@ -16,6 +18,7 @@ export const WizardStartParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Client answer payload for the current wizard step. */
|
||||
export const WizardAnswerSchema = Type.Object(
|
||||
{
|
||||
stepId: NonEmptyString,
|
||||
@@ -24,6 +27,7 @@ export const WizardAnswerSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Advances a wizard session, with an answer when the previous step requested input. */
|
||||
export const WizardNextParamsSchema = Type.Object(
|
||||
{
|
||||
sessionId: NonEmptyString,
|
||||
@@ -32,6 +36,7 @@ export const WizardNextParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Shared session-id-only params for cancel and status requests. */
|
||||
const WizardSessionIdParamsSchema = Type.Object(
|
||||
{
|
||||
sessionId: NonEmptyString,
|
||||
@@ -39,10 +44,13 @@ const WizardSessionIdParamsSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Cancels an active wizard session. */
|
||||
export const WizardCancelParamsSchema = WizardSessionIdParamsSchema;
|
||||
|
||||
/** Reads status for an active or recently completed wizard session. */
|
||||
export const WizardStatusParamsSchema = WizardSessionIdParamsSchema;
|
||||
|
||||
/** Selectable value shown in a choice-based wizard step. */
|
||||
export const WizardStepOptionSchema = Type.Object(
|
||||
{
|
||||
value: Type.Unknown(),
|
||||
@@ -52,6 +60,7 @@ export const WizardStepOptionSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** UI contract for one wizard step rendered by gateway clients. */
|
||||
export const WizardStepSchema = Type.Object(
|
||||
{
|
||||
id: NonEmptyString,
|
||||
@@ -76,6 +85,7 @@ export const WizardStepSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Common response fields for start and next calls. */
|
||||
const WizardResultFields = {
|
||||
done: Type.Boolean(),
|
||||
step: Type.Optional(WizardStepSchema),
|
||||
@@ -83,10 +93,12 @@ const WizardResultFields = {
|
||||
error: Type.Optional(Type.String()),
|
||||
};
|
||||
|
||||
/** Result after advancing a wizard session. */
|
||||
export const WizardNextResultSchema = Type.Object(WizardResultFields, {
|
||||
additionalProperties: false,
|
||||
});
|
||||
|
||||
/** Result returned when a wizard session is created. */
|
||||
export const WizardStartResultSchema = Type.Object(
|
||||
{
|
||||
sessionId: NonEmptyString,
|
||||
@@ -95,6 +107,7 @@ export const WizardStartResultSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
/** Minimal status poll result used when the client does not need the next step. */
|
||||
export const WizardStatusResultSchema = Type.Object(
|
||||
{
|
||||
status: WizardRunStatusSchema,
|
||||
|
||||
@@ -3,6 +3,13 @@ import { describe, expect, it } from "vitest";
|
||||
import { buildTalkConfigResponse } from "../../../src/config/talk.js";
|
||||
import { validateTalkConfigResult } from "./index.js";
|
||||
|
||||
/**
|
||||
* Talk config contract tests shared between config normalization and gateway
|
||||
* protocol validation. Fixtures capture provider selection and timeout behavior
|
||||
* so config changes cannot silently diverge from the public RPC response shape.
|
||||
*/
|
||||
|
||||
/** Expected resolved provider/config selection for one fixture case. */
|
||||
type ExpectedSelection = {
|
||||
provider: string;
|
||||
normalizedPayload: boolean;
|
||||
@@ -10,6 +17,7 @@ type ExpectedSelection = {
|
||||
apiKey?: string;
|
||||
};
|
||||
|
||||
/** Fixture row that validates normalized Talk provider selection. */
|
||||
type SelectionContractCase = {
|
||||
id: string;
|
||||
defaultProvider: string;
|
||||
@@ -18,6 +26,7 @@ type SelectionContractCase = {
|
||||
talk: Record<string, unknown>;
|
||||
};
|
||||
|
||||
/** Fixture row that validates Talk silence-timeout normalization. */
|
||||
type TimeoutContractCase = {
|
||||
id: string;
|
||||
fallback: number;
|
||||
@@ -25,11 +34,13 @@ type TimeoutContractCase = {
|
||||
talk: Record<string, unknown>;
|
||||
};
|
||||
|
||||
/** JSON fixture file shape used by this contract test. */
|
||||
type TalkConfigContractFixture = {
|
||||
selectionCases: SelectionContractCase[];
|
||||
timeoutCases: TimeoutContractCase[];
|
||||
};
|
||||
|
||||
/** External fixture keeps the matrix readable and reusable across config edits. */
|
||||
const fixturePath = new URL("../../../test/fixtures/talk-config-contract.json", import.meta.url);
|
||||
const fixtures = JSON.parse(fs.readFileSync(fixturePath, "utf-8")) as TalkConfigContractFixture;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** Public LLM core contracts shared by providers, plugin SDK wrappers, and tests. */
|
||||
export * from "./types.js";
|
||||
export * from "./utils/diagnostics.js";
|
||||
export * from "./utils/event-stream.js";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export type { AssistantMessageDiagnostic, DiagnosticErrorInfo } from "./utils/diagnostics.js";
|
||||
import type { AssistantMessageDiagnostic } from "./utils/diagnostics.js";
|
||||
|
||||
/** Provider API families with first-class request/stream adapters in OpenClaw. */
|
||||
export type KnownApi =
|
||||
| "openai-completions"
|
||||
| "mistral-conversations"
|
||||
@@ -12,20 +13,29 @@ export type KnownApi =
|
||||
| "google-generative-ai"
|
||||
| "google-vertex";
|
||||
|
||||
/** Provider API id; custom providers can use ids outside the built-in set. */
|
||||
export type Api = KnownApi | (string & {});
|
||||
|
||||
/** Image-generation API families with first-class adapters in OpenClaw. */
|
||||
export type KnownImagesApi = "openrouter-images";
|
||||
|
||||
/** Image API id; custom image providers can use ids outside the built-in set. */
|
||||
export type ImagesApi = KnownImagesApi | (string & {});
|
||||
|
||||
/** Provider id used for routing, diagnostics, and config lookups. */
|
||||
export type Provider = string;
|
||||
|
||||
/** Image provider ids with first-class adapters in OpenClaw. */
|
||||
export type KnownImagesProvider = "openrouter";
|
||||
|
||||
/** Image provider id used for routing, diagnostics, and config lookups. */
|
||||
export type ImagesProvider = string;
|
||||
|
||||
/** Normalized reasoning-effort levels shared across provider-specific knobs. */
|
||||
export type ThinkingLevel = "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
|
||||
/** Model thinking setting including explicit disabled state. */
|
||||
export type ModelThinkingLevel = "off" | ThinkingLevel;
|
||||
/** Provider-specific values for normalized thinking levels. */
|
||||
export type ThinkingLevelMap = Partial<Record<ModelThinkingLevel, string | null>>;
|
||||
|
||||
/** Token budgets for each thinking level (token-based providers only) */
|
||||
@@ -37,18 +47,22 @@ export interface ThinkingBudgets {
|
||||
max?: number;
|
||||
}
|
||||
|
||||
// Base options all providers share
|
||||
/** Prompt-cache retention preference shared by providers that expose cache controls. */
|
||||
export type CacheRetention = "none" | "short" | "long";
|
||||
|
||||
/** Streaming transport preference for providers that support multiple transports. */
|
||||
export type Transport = "sse" | "websocket" | "websocket-cached" | "auto";
|
||||
|
||||
/** Helper for hooks that may be synchronous or asynchronous. */
|
||||
export type MaybePromise<T> = T | Promise<T>;
|
||||
|
||||
/** Minimal HTTP response metadata surfaced through provider hooks. */
|
||||
export interface ProviderResponse {
|
||||
status: number;
|
||||
headers: Record<string, string>;
|
||||
}
|
||||
|
||||
/** Request options shared by text streaming providers. */
|
||||
export interface StreamOptions {
|
||||
temperature?: number;
|
||||
maxTokens?: number;
|
||||
@@ -125,6 +139,7 @@ export interface StreamOptions {
|
||||
|
||||
export type ProviderStreamOptions = StreamOptions & Record<string, unknown>;
|
||||
|
||||
/** Request options shared by image-generation providers. */
|
||||
export interface ImagesOptions {
|
||||
signal?: AbortSignal;
|
||||
apiKey?: string;
|
||||
@@ -167,7 +182,7 @@ export interface ImagesOptions {
|
||||
|
||||
export type ProviderImagesOptions = ImagesOptions & Record<string, unknown>;
|
||||
|
||||
// Unified options with reasoning passed to streamSimple() and completeSimple()
|
||||
/** Unified text options used by simple completion helpers. */
|
||||
export interface SimpleStreamOptions extends StreamOptions {
|
||||
reasoning?: ThinkingLevel;
|
||||
/** Custom token budgets for thinking levels (token-based providers only) */
|
||||
@@ -206,12 +221,14 @@ export interface TextSignatureV1 {
|
||||
phase?: "commentary" | "final_answer";
|
||||
}
|
||||
|
||||
/** Plain assistant/user text content block. */
|
||||
export interface TextContent {
|
||||
type: "text";
|
||||
text: string;
|
||||
textSignature?: string; // e.g., for OpenAI responses, message metadata (legacy id string or TextSignatureV1 JSON)
|
||||
}
|
||||
|
||||
/** Provider reasoning/thinking content block, including opaque replay signatures. */
|
||||
export interface ThinkingContent {
|
||||
type: "thinking";
|
||||
thinking: string;
|
||||
@@ -222,12 +239,14 @@ export interface ThinkingContent {
|
||||
redacted?: boolean;
|
||||
}
|
||||
|
||||
/** Base64 image content block with MIME type metadata. */
|
||||
export interface ImageContent {
|
||||
type: "image";
|
||||
data: string; // base64 encoded image data
|
||||
mimeType: string; // e.g., "image/jpeg", "image/png"
|
||||
}
|
||||
|
||||
/** Normalized assistant tool call emitted by providers or repaired from text. */
|
||||
export interface ToolCall {
|
||||
type: "toolCall";
|
||||
id: string;
|
||||
@@ -237,6 +256,7 @@ export interface ToolCall {
|
||||
executionMode?: "sequential" | "parallel";
|
||||
}
|
||||
|
||||
/** Normalized token and cost accounting for a provider response. */
|
||||
export interface Usage {
|
||||
input: number;
|
||||
output: number;
|
||||
@@ -252,14 +272,17 @@ export interface Usage {
|
||||
};
|
||||
}
|
||||
|
||||
/** Normalized assistant stop reasons across text providers. */
|
||||
export type StopReason = "stop" | "length" | "toolUse" | "error" | "aborted";
|
||||
|
||||
/** User turn in a text-model conversation. */
|
||||
export interface UserMessage {
|
||||
role: "user";
|
||||
content: string | (TextContent | ImageContent)[];
|
||||
timestamp: number; // Unix timestamp in milliseconds
|
||||
}
|
||||
|
||||
/** Assistant turn, including provider identity and final stop state. */
|
||||
export interface AssistantMessage {
|
||||
role: "assistant";
|
||||
content: (TextContent | ThinkingContent | ToolCall)[];
|
||||
@@ -275,6 +298,7 @@ export interface AssistantMessage {
|
||||
timestamp: number; // Unix timestamp in milliseconds
|
||||
}
|
||||
|
||||
/** Tool result turn that answers a prior assistant tool call. */
|
||||
export interface ToolResultMessage<TDetails = unknown> {
|
||||
role: "toolResult";
|
||||
toolCallId: string;
|
||||
@@ -285,17 +309,23 @@ export interface ToolResultMessage<TDetails = unknown> {
|
||||
timestamp: number; // Unix timestamp in milliseconds
|
||||
}
|
||||
|
||||
/** Any text-model conversation message supported by LLM core. */
|
||||
export type Message = UserMessage | AssistantMessage | ToolResultMessage;
|
||||
|
||||
/** Image request input content accepted by image providers. */
|
||||
export type ImagesInputContent = TextContent | ImageContent;
|
||||
/** Image response output content returned by image providers. */
|
||||
export type ImagesOutputContent = TextContent | ImageContent;
|
||||
|
||||
/** Image-generation request context. */
|
||||
export interface ImagesContext {
|
||||
input: ImagesInputContent[];
|
||||
}
|
||||
|
||||
/** Normalized image-generation stop reasons. */
|
||||
export type ImagesStopReason = "stop" | "error" | "aborted";
|
||||
|
||||
/** Final image-generation response shape. */
|
||||
export interface AssistantImages {
|
||||
api: ImagesApi;
|
||||
provider: ImagesProvider;
|
||||
@@ -310,12 +340,14 @@ export interface AssistantImages {
|
||||
|
||||
import type { TSchema } from "typebox";
|
||||
|
||||
/** Provider tool declaration with a TypeBox/JSON-schema parameter object. */
|
||||
export interface Tool<TParameters extends TSchema = TSchema> {
|
||||
name: string;
|
||||
description: string;
|
||||
parameters: TParameters;
|
||||
}
|
||||
|
||||
/** Text-model request context shared by provider adapters. */
|
||||
export interface Context {
|
||||
systemPrompt?: string;
|
||||
messages: Message[];
|
||||
@@ -349,11 +381,15 @@ export type AssistantMessageEvent =
|
||||
| { type: "error"; reason: Extract<StopReason, "aborted" | "error">; error: AssistantMessage };
|
||||
|
||||
export interface AssistantMessageEventStreamContract extends AsyncIterable<AssistantMessageEvent> {
|
||||
/** Queue one stream event for consumers. */
|
||||
push(event: AssistantMessageEvent): void;
|
||||
/** Complete the stream and optionally resolve the final message. */
|
||||
end(result?: AssistantMessage): void;
|
||||
/** Final assistant message produced by the stream. */
|
||||
result(): Promise<AssistantMessage>;
|
||||
}
|
||||
|
||||
/** Read-only stream contract accepted by consumers that do not need to push events. */
|
||||
export interface AssistantMessageEventStreamLike extends AsyncIterable<AssistantMessageEvent> {
|
||||
result(): Promise<AssistantMessage>;
|
||||
}
|
||||
|
||||
@@ -27,8 +27,11 @@ export interface ApiProvider<
|
||||
TApi extends Api = Api,
|
||||
TOptions extends StreamOptions = StreamOptions,
|
||||
> {
|
||||
/** Model API id this provider handles. */
|
||||
api: TApi;
|
||||
/** Full streaming adapter for callers that already own structured options. */
|
||||
stream: StreamFunction<TApi, TOptions>;
|
||||
/** Simple streaming adapter used by agent and plugin runtime defaults. */
|
||||
streamSimple: StreamFunction<TApi, SimpleStreamOptions>;
|
||||
}
|
||||
|
||||
@@ -72,6 +75,7 @@ function wrapStreamSimple<TApi extends Api>(
|
||||
/** Registers or replaces the provider implementation for an API id. */
|
||||
export function registerApiProvider<TApi extends Api, TOptions extends StreamOptions>(
|
||||
provider: ApiProvider<TApi, TOptions>,
|
||||
/** Optional source id used to unregister all providers owned by one plugin/runtime. */
|
||||
sourceId?: string,
|
||||
): void {
|
||||
apiProviderRegistry.set(provider.api, {
|
||||
|
||||
@@ -18,6 +18,8 @@ function scanParenAwareBreakpoints(text: string): { lastNewline: number; lastWhi
|
||||
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
const char = text[i];
|
||||
// Parenthesized spans often contain rewritten links or file references;
|
||||
// avoid splitting them unless the window has no safer outside break.
|
||||
if (char === "(") {
|
||||
depth += 1;
|
||||
continue;
|
||||
@@ -39,7 +41,11 @@ function scanParenAwareBreakpoints(text: string): { lastNewline: number; lastWhi
|
||||
return { lastNewline, lastWhitespace };
|
||||
}
|
||||
|
||||
/** Splits plain text at readable boundaries while avoiding breaks inside parentheses. */
|
||||
/**
|
||||
* Splits plain text into size-bounded chunks at readable boundaries.
|
||||
*
|
||||
* Returns the original text as one chunk when the limit is non-positive.
|
||||
*/
|
||||
export function chunkText(text: string, limit: number): string[] {
|
||||
const early = resolveChunkEarlyReturn(text, limit);
|
||||
if (early) {
|
||||
@@ -56,6 +62,8 @@ export function chunkText(text: string, limit: number): string[] {
|
||||
const windowEnd = Math.min(text.length, cursor + limit);
|
||||
const window = text.slice(cursor, windowEnd);
|
||||
const { lastNewline, lastWhitespace } = scanParenAwareBreakpoints(window);
|
||||
// Prefer block boundaries, then spaces, then a hard size cut when no
|
||||
// readable breakpoint exists inside this window.
|
||||
const breakOffset = lastNewline > 0 ? lastNewline : lastWhitespace;
|
||||
const end = breakOffset > 0 ? cursor + breakOffset : windowEnd;
|
||||
chunks.push(text.slice(cursor, end));
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { scanFenceSpans, type FenceScanState, type FenceSpan } from "./fences.js";
|
||||
|
||||
/** Incremental inline-code scanner state carried across chunk boundaries. */
|
||||
export type InlineCodeState = {
|
||||
/** Whether the current scan is inside an unterminated inline code span. */
|
||||
open: boolean;
|
||||
/** Backtick run length required to close the current inline code span. */
|
||||
ticks: number;
|
||||
};
|
||||
|
||||
@@ -16,8 +19,11 @@ type InlineCodeSpansResult = {
|
||||
};
|
||||
|
||||
type CodeSpanIndex = {
|
||||
/** Inline-code state to carry into the next streamed chunk. */
|
||||
inlineState: InlineCodeState;
|
||||
/** Fenced-code state to carry into the next streamed chunk. */
|
||||
fenceState: FenceScanState;
|
||||
/** True when an offset is inside fenced code or inline code. */
|
||||
isInside: (index: number) => boolean;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** Public Markdown parsing, rendering, chunking, and table-conversion utilities. */
|
||||
export * from "./code-spans.js";
|
||||
export * from "./fences.js";
|
||||
export * from "./frontmatter.js";
|
||||
|
||||
@@ -8,15 +8,21 @@ import {
|
||||
|
||||
/** A rendered chunk paired with the Markdown IR slice that produced it. */
|
||||
export type RenderedMarkdownChunk<TRendered> = {
|
||||
/** Rendered payload for this chunk after caller-specific escaping/link rewriting. */
|
||||
rendered: TRendered;
|
||||
/** Source IR slice used to produce the rendered payload. */
|
||||
source: MarkdownIR;
|
||||
};
|
||||
|
||||
/** Inputs for chunking Markdown IR against the final rendered payload size. */
|
||||
export type RenderMarkdownIRChunksWithinLimitOptions<TRendered> = {
|
||||
/** Parsed Markdown IR to split. */
|
||||
ir: MarkdownIR;
|
||||
/** Maximum measured size for each rendered chunk. */
|
||||
limit: number;
|
||||
/** Returns the size unit enforced by the target transport. */
|
||||
measureRendered: (rendered: TRendered) => number;
|
||||
/** Renders a candidate IR slice for measuring and final output. */
|
||||
renderChunk: (ir: MarkdownIR) => TRendered;
|
||||
};
|
||||
|
||||
@@ -139,6 +145,8 @@ function findMarkdownIRPreservedSplitIndex(text: string, start: number, limit: n
|
||||
|
||||
for (let index = start; index < maxEnd; index += 1) {
|
||||
const char = text[index];
|
||||
// Parenthesized text often carries rewritten file/link references; prefer
|
||||
// keeping it intact unless no outside break exists in the current window.
|
||||
if (char === "(") {
|
||||
sawNonWhitespace = true;
|
||||
parenDepth += 1;
|
||||
@@ -157,6 +165,7 @@ function findMarkdownIRPreservedSplitIndex(text: string, start: number, limit: n
|
||||
continue;
|
||||
}
|
||||
if (char === "\n") {
|
||||
// Newlines preserve markdown block structure better than other spaces.
|
||||
lastAnyNewlineBreak = index + 1;
|
||||
if (parenDepth === 0) {
|
||||
lastOutsideParenNewlineBreak = index + 1;
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import type { MarkdownIR, MarkdownLinkSpan, MarkdownStyle, MarkdownStyleSpan } from "./ir.js";
|
||||
|
||||
/** Marker pair used to wrap a styled Markdown span in the target renderer. */
|
||||
export type RenderStyleMarker = {
|
||||
open: string | ((span: MarkdownStyleSpan) => string);
|
||||
close: string;
|
||||
};
|
||||
|
||||
/** Optional marker map; omitted styles are emitted as plain escaped text. */
|
||||
export type RenderStyleMap = Partial<Record<MarkdownStyle, RenderStyleMarker>>;
|
||||
|
||||
/** Link wrapper boundaries after a renderer has accepted or rewritten a link span. */
|
||||
export type RenderLink = {
|
||||
start: number;
|
||||
end: number;
|
||||
@@ -14,6 +17,7 @@ export type RenderLink = {
|
||||
close: string;
|
||||
};
|
||||
|
||||
/** Renderer hooks for converting Markdown IR into a marker-based target format. */
|
||||
export type RenderOptions = {
|
||||
styleMarkers: RenderStyleMap;
|
||||
escapeText: (text: string) => string;
|
||||
@@ -46,6 +50,7 @@ function sortStyleSpans(spans: MarkdownStyleSpan[]): MarkdownStyleSpan[] {
|
||||
});
|
||||
}
|
||||
|
||||
/** Renders Markdown IR by nesting configured style markers and optional link markers. */
|
||||
export function renderMarkdownWithMarkers(ir: MarkdownIR, options: RenderOptions): string {
|
||||
const text = ir.text ?? "";
|
||||
if (!text) {
|
||||
@@ -104,7 +109,7 @@ export function renderMarkdownWithMarkers(ir: MarkdownIR, options: RenderOptions
|
||||
}
|
||||
|
||||
const points = [...boundaries].toSorted((a, b) => a - b);
|
||||
// Unified stack for both styles and links, tracking close string and end position
|
||||
// Links and styles share one stack so equal-end spans close in exact reverse open order.
|
||||
const stack: { close: string; end: number }[] = [];
|
||||
type OpeningItem =
|
||||
| { end: number; open: string; close: string; kind: "link"; index: number }
|
||||
@@ -121,7 +126,7 @@ export function renderMarkdownWithMarkers(ir: MarkdownIR, options: RenderOptions
|
||||
for (let i = 0; i < points.length; i += 1) {
|
||||
const pos = points[i];
|
||||
|
||||
// Close ALL elements (styles and links) in LIFO order at this position
|
||||
// Close all elements at this boundary before opening replacements at the same offset.
|
||||
while (stack.length && stack[stack.length - 1]?.end === pos) {
|
||||
const item = stack.pop();
|
||||
if (item) {
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
/** Table rendering modes used when markdown tables need plaintext-safe output. */
|
||||
export type MarkdownTableMode = "off" | "bullets" | "code" | "block";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** Estimates decoded bytes without allocating a cleaned copy of the base64 payload. */
|
||||
export function estimateBase64DecodedBytes(base64: string): number {
|
||||
// Avoid `trim()`/`replace()` here: they allocate a second (potentially huge) string.
|
||||
// We only need a conservative decoded-size estimate to enforce budgets before Buffer.from(..., "base64").
|
||||
@@ -47,8 +48,8 @@ function isBase64DataChar(code: number): boolean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize and validate a base64 string.
|
||||
* Returns canonical base64 (no whitespace) or undefined when invalid.
|
||||
* Normalizes and validates a base64 string, returning canonical no-whitespace
|
||||
* base64 only when the input has valid alphabet, padding, and length.
|
||||
*/
|
||||
export function canonicalizeBase64(base64: string): string | undefined {
|
||||
let cleaned = "";
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
/** Default outbound image payload cap shared by media loaders and adapters. */
|
||||
export const MAX_IMAGE_BYTES = 6 * 1024 * 1024; // 6MB
|
||||
/** Default outbound audio payload cap shared by media loaders and adapters. */
|
||||
export const MAX_AUDIO_BYTES = 16 * 1024 * 1024; // 16MB
|
||||
/** Default outbound video payload cap shared by media loaders and adapters. */
|
||||
export const MAX_VIDEO_BYTES = 16 * 1024 * 1024; // 16MB
|
||||
/** Default outbound document payload cap shared by media loaders and adapters. */
|
||||
export const MAX_DOCUMENT_BYTES = 100 * 1024 * 1024; // 100MB
|
||||
|
||||
/** Media families that share size-policy and MIME-classification behavior. */
|
||||
export type MediaKind = "image" | "audio" | "video" | "document";
|
||||
|
||||
/** Maps a MIME type to the media family used for size limits and routing. */
|
||||
export function mediaKindFromMime(mime?: string | null): MediaKind | undefined {
|
||||
if (!mime) {
|
||||
return undefined;
|
||||
@@ -30,6 +36,7 @@ export function mediaKindFromMime(mime?: string | null): MediaKind | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Returns the default byte cap for a classified media family. */
|
||||
export function maxBytesForKind(kind: MediaKind): number {
|
||||
switch (kind) {
|
||||
case "image":
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** Parses a Content-Length header as a safe integer or rejects malformed values. */
|
||||
export function parseMediaContentLength(raw: string | null): number | null {
|
||||
if (raw === null) {
|
||||
return null;
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import path from "node:path";
|
||||
|
||||
/** Returns the final filename segment for either POSIX or Windows-style paths. */
|
||||
export function basenameFromAnyPath(value: string): string {
|
||||
return path.win32.basename(path.posix.basename(value));
|
||||
}
|
||||
|
||||
/** Returns the extension from the final filename segment of any path flavor. */
|
||||
export function extnameFromAnyPath(value: string): string {
|
||||
return path.extname(basenameFromAnyPath(value));
|
||||
}
|
||||
|
||||
/** Returns the extensionless filename from the final segment of any path flavor. */
|
||||
export function nameFromAnyPath(value: string): string {
|
||||
const base = basenameFromAnyPath(value);
|
||||
const ext = path.extname(base);
|
||||
|
||||
@@ -9,6 +9,8 @@ function normalizePosixAbsolutePath(value: string): string | undefined {
|
||||
if (!trimmed || trimmed.includes("\0")) {
|
||||
return undefined;
|
||||
}
|
||||
// Compare all roots as POSIX-style absolute paths so channel configs can use
|
||||
// stable patterns even when a source reports Windows separators.
|
||||
const normalized = path.posix.normalize(trimmed.replaceAll("\\", "/"));
|
||||
const isAbsolute = normalized.startsWith("/") || WINDOWS_DRIVE_ABS_RE.test(normalized);
|
||||
if (!isAbsolute || normalized === "/") {
|
||||
@@ -44,6 +46,7 @@ function matchesRootPattern(params: { candidatePath: string; rootPattern: string
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Validates an absolute inbound root pattern with whole-segment wildcards only. */
|
||||
export function isValidInboundPathRootPattern(value: string): boolean {
|
||||
const normalized = normalizePosixAbsolutePath(value);
|
||||
if (!normalized) {
|
||||
@@ -56,6 +59,7 @@ export function isValidInboundPathRootPattern(value: string): boolean {
|
||||
return segments.every((segment) => segment === WILDCARD_SEGMENT || !segment.includes("*"));
|
||||
}
|
||||
|
||||
/** Normalizes configured inbound attachment roots, dropping invalid or duplicate patterns. */
|
||||
export function normalizeInboundPathRoots(roots?: readonly string[]): string[] {
|
||||
const normalized: string[] = [];
|
||||
const seen = new Set<string>();
|
||||
@@ -76,6 +80,7 @@ export function normalizeInboundPathRoots(roots?: readonly string[]): string[] {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
/** Merges inbound attachment root lists while preserving first-seen priority. */
|
||||
export function mergeInboundPathRoots(
|
||||
...rootsLists: Array<readonly string[] | undefined>
|
||||
): string[] {
|
||||
@@ -94,6 +99,7 @@ export function mergeInboundPathRoots(
|
||||
return merged;
|
||||
}
|
||||
|
||||
/** Checks whether a candidate inbound media path is covered by configured or fallback roots. */
|
||||
export function isInboundPathAllowed(params: {
|
||||
filePath: string;
|
||||
roots: readonly string[];
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { canonicalizeBase64 } from "./base64.js";
|
||||
|
||||
/** Prefix used to distinguish inline data URLs from remote/local image references. */
|
||||
export const INLINE_IMAGE_DATA_URL_PREFIX = "data:";
|
||||
|
||||
const IMAGE_SIGNATURES: Array<{
|
||||
@@ -47,6 +48,7 @@ function startsWithDataUrl(value: string): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
/** Sniffs supported inline image formats from decoded bytes. */
|
||||
export function sniffInlineImageMime(buffer: Buffer): string | undefined {
|
||||
return IMAGE_SIGNATURES.find((signature) => signature.matches(buffer))?.mime;
|
||||
}
|
||||
@@ -79,6 +81,7 @@ function metadataAllowsImageBase64(metadata: string[]): boolean {
|
||||
return isImageMimeType && options.some((part) => part.toLowerCase() === "base64");
|
||||
}
|
||||
|
||||
/** Canonicalizes trusted inline image data URLs and rejects malformed or non-image payloads. */
|
||||
export function sanitizeInlineImageDataUrl(imageUrl: string): string | undefined {
|
||||
const parsed = parseInlineImageDataUrl(imageUrl);
|
||||
if (!parsed) {
|
||||
@@ -99,5 +102,6 @@ export function sanitizeInlineImageDataUrl(imageUrl: string): string | undefined
|
||||
if (!sniffedMimeType) {
|
||||
return undefined;
|
||||
}
|
||||
// Trust the byte signature over caller-supplied metadata before reinlining.
|
||||
return `data:${sniffedMimeType};base64,${canonicalPayload}`;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
/** Cached async loader used by runtime boundaries that should import on first use. */
|
||||
export type LazyPromiseLoader<T> = {
|
||||
load(): Promise<T>;
|
||||
clear(): void;
|
||||
};
|
||||
|
||||
/** Controls whether a failed first import stays cached or is retried later. */
|
||||
export type LazyPromiseLoaderOptions = {
|
||||
cacheRejections?: boolean;
|
||||
};
|
||||
|
||||
/** Creates a single-flight promise cache around a lazy import or other async loader. */
|
||||
export function createLazyImportLoader<T>(
|
||||
load: () => Promise<T>,
|
||||
options: LazyPromiseLoaderOptions = {},
|
||||
@@ -16,6 +19,7 @@ export function createLazyImportLoader<T>(
|
||||
const createPromise = (): Promise<T> => {
|
||||
const loaded = Promise.resolve().then(load);
|
||||
if (options.cacheRejections !== true) {
|
||||
// Failed optional-runtime imports should retry after install/config changes.
|
||||
void loaded.catch(() => {
|
||||
if (promise === loaded) {
|
||||
promise = undefined;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const HTTP_URL_RE = /^https?:\/\//i;
|
||||
const MXC_URL_RE = /^mxc:\/\//i;
|
||||
|
||||
/** Returns true for remote media URLs that should stay URL-backed instead of local-file-backed. */
|
||||
export function isPassThroughRemoteMediaSource(value: string | null | undefined): boolean {
|
||||
const normalized = value?.trim() ?? "";
|
||||
return Boolean(normalized) && (HTTP_URL_RE.test(normalized) || MXC_URL_RE.test(normalized));
|
||||
|
||||
@@ -2,7 +2,7 @@ import path from "node:path";
|
||||
import { type MediaKind, mediaKindFromMime } from "./constants.js";
|
||||
import { createLazyImportLoader } from "./lazy-import.js";
|
||||
|
||||
/** @internal */
|
||||
/** Maximum byte prefix passed to dependency MIME sniffers for bounded memory/CPU work. */
|
||||
export const FILE_TYPE_SNIFF_MAX_BYTES = 1024 * 1024;
|
||||
|
||||
// Map common mimes to preferred file extensions.
|
||||
@@ -97,6 +97,7 @@ const AUDIO_FILE_EXTENSIONS = new Set([
|
||||
|
||||
const fileTypeModuleLoader = createLazyImportLoader(() => import("file-type"));
|
||||
|
||||
/** Normalizes MIME strings by dropping parameters, lowercasing, and folding APNG to PNG. */
|
||||
export function normalizeMimeType(mime?: string | null): string | undefined {
|
||||
if (!mime) {
|
||||
return undefined;
|
||||
@@ -108,7 +109,7 @@ export function normalizeMimeType(mime?: string | null): string | undefined {
|
||||
return cleaned || undefined;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
/** Returns the bounded buffer prefix used for dependency MIME sniffing. */
|
||||
export function sliceMimeSniffBuffer(buffer: Buffer): Buffer {
|
||||
if (buffer.byteLength <= FILE_TYPE_SNIFF_MAX_BYTES) {
|
||||
return buffer;
|
||||
@@ -144,6 +145,7 @@ function sniffKnownAudioMagic(buffer: Buffer): string | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Extracts a lowercase extension from a local path or HTTP URL pathname. */
|
||||
export function getFileExtension(filePath?: string | null): string | undefined {
|
||||
if (!filePath) {
|
||||
return undefined;
|
||||
@@ -160,6 +162,7 @@ export function getFileExtension(filePath?: string | null): string | undefined {
|
||||
return ext || undefined;
|
||||
}
|
||||
|
||||
/** Maps a file path or URL extension to the preferred MIME type when known. */
|
||||
export function mimeTypeFromFilePath(filePath?: string | null): string | undefined {
|
||||
const ext = getFileExtension(filePath);
|
||||
if (!ext) {
|
||||
@@ -168,6 +171,7 @@ export function mimeTypeFromFilePath(filePath?: string | null): string | undefin
|
||||
return MIME_BY_EXT[ext];
|
||||
}
|
||||
|
||||
/** Returns true when a filename extension is a supported audio container. */
|
||||
export function isAudioFileName(fileName?: string | null): boolean {
|
||||
const ext = getFileExtension(fileName);
|
||||
if (!ext) {
|
||||
@@ -176,6 +180,7 @@ export function isAudioFileName(fileName?: string | null): boolean {
|
||||
return AUDIO_FILE_EXTENSIONS.has(ext);
|
||||
}
|
||||
|
||||
/** Detects the best MIME type from bytes, file path, and header metadata. */
|
||||
export function detectMime(opts: {
|
||||
buffer?: Buffer;
|
||||
headerMime?: string | null;
|
||||
@@ -232,6 +237,7 @@ async function detectMimeImpl(opts: {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Returns the preferred file extension for a normalized or raw MIME string. */
|
||||
export function extensionForMime(mime?: string | null): string | undefined {
|
||||
const normalized = normalizeMimeType(mime);
|
||||
if (!normalized) {
|
||||
@@ -240,6 +246,7 @@ export function extensionForMime(mime?: string | null): string | undefined {
|
||||
return EXT_BY_MIME[normalized];
|
||||
}
|
||||
|
||||
/** Returns true when content type or filename identifies GIF media. */
|
||||
export function isGifMedia(opts: {
|
||||
contentType?: string | null;
|
||||
fileName?: string | null;
|
||||
@@ -251,6 +258,7 @@ export function isGifMedia(opts: {
|
||||
return ext === ".gif";
|
||||
}
|
||||
|
||||
/** Maps image format labels from encoders/probes to MIME types. */
|
||||
export function imageMimeFromFormat(format?: string | null): string | undefined {
|
||||
if (!format) {
|
||||
return undefined;
|
||||
@@ -274,6 +282,7 @@ export function imageMimeFromFormat(format?: string | null): string | undefined
|
||||
}
|
||||
}
|
||||
|
||||
/** Normalizes a MIME string before classifying it into a media family. */
|
||||
export function kindFromMime(mime?: string | null): MediaKind | undefined {
|
||||
return mediaKindFromMime(normalizeMimeType(mime));
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
/** Details passed to byte-stream overflow error factories. */
|
||||
export type ByteStreamLimitOverflow = {
|
||||
size: number;
|
||||
maxBytes: number;
|
||||
};
|
||||
|
||||
/** Options for reading an async byte stream under a hard byte cap. */
|
||||
export type ReadByteStreamWithLimitOptions = {
|
||||
maxBytes: number;
|
||||
onOverflow?: (params: ByteStreamLimitOverflow) => Error;
|
||||
@@ -29,6 +31,8 @@ function destroyReadableOnOverflow(stream: unknown, err: Error): void {
|
||||
destroy?: (error?: Error) => unknown;
|
||||
cancel?: (reason?: unknown) => unknown;
|
||||
};
|
||||
// Stop upstream producers immediately after overflow; otherwise large media
|
||||
// streams can continue buffering after the caller has already failed.
|
||||
if (typeof readable.destroy === "function") {
|
||||
try {
|
||||
readable.destroy(err);
|
||||
@@ -42,6 +46,7 @@ function destroyReadableOnOverflow(stream: unknown, err: Error): void {
|
||||
}
|
||||
}
|
||||
|
||||
/** Reads and concatenates an async byte stream, throwing once the byte cap is exceeded. */
|
||||
export async function readByteStreamWithLimit(
|
||||
stream: AsyncIterable<unknown>,
|
||||
opts: ReadByteStreamWithLimitOptions,
|
||||
|
||||
@@ -23,6 +23,8 @@ async function readChunkWithIdleTimeout(
|
||||
onIdleTimeout?.({ chunkTimeoutMs: resolvedChunkTimeoutMs }) ??
|
||||
new Error(`Media download stalled: no data received for ${resolvedChunkTimeoutMs}ms`);
|
||||
clear();
|
||||
// Cancel the body with the same error so fetch-backed streams release
|
||||
// sockets/buffers instead of idling after the caller times out.
|
||||
void reader.cancel(error).catch(() => undefined);
|
||||
reject(error);
|
||||
}, resolvedChunkTimeoutMs);
|
||||
@@ -123,6 +125,7 @@ async function readResponsePrefix(
|
||||
};
|
||||
}
|
||||
|
||||
/** Reads a response body under a byte cap, cancelling the stream on overflow or idle timeout. */
|
||||
export async function readResponseWithLimit(
|
||||
res: Response,
|
||||
maxBytes: number,
|
||||
@@ -146,6 +149,7 @@ export async function readResponseWithLimit(
|
||||
return prefix.buffer;
|
||||
}
|
||||
|
||||
/** Reads a small collapsed text prefix from a response body for diagnostics/errors. */
|
||||
export async function readResponseTextSnippet(
|
||||
res: Response,
|
||||
opts?: {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Agent-facing runtime facade for memory host packages.
|
||||
// Keep exports here limited to config/state helpers that memory plugins may reuse.
|
||||
export {
|
||||
DEFAULT_AGENT_COMPACTION_RESERVE_TOKENS_FLOOR,
|
||||
asToolParamsRecord,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Config-facing runtime facade for memory host packages.
|
||||
// This keeps memory plugins off broader core config modules and their private helpers.
|
||||
export {
|
||||
getRuntimeConfig,
|
||||
hasConfiguredSecretInput,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Memory-facing runtime facade for plugin registration, embeddings, and prompt artifacts.
|
||||
// Re-export only stable host seams; plugin implementations should not import core internals.
|
||||
export {
|
||||
buildActiveMemoryPromptSection,
|
||||
emptyPluginConfigSchema,
|
||||
|
||||
@@ -632,6 +632,7 @@ const STOP_WORDS_ZH = new Set([
|
||||
"告诉",
|
||||
]);
|
||||
|
||||
/** Returns true for low-value conversational tokens that should not drive FTS matching. */
|
||||
export function isQueryStopWordToken(token: string): boolean {
|
||||
return (
|
||||
STOP_WORDS_EN.has(token) ||
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
// Public query helper facade for memory search token expansion.
|
||||
export { extractKeywords, isQueryStopWordToken } from "./host/query-expansion.js";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** Public repair utilities for model-emitted plain-text tool calls. */
|
||||
export {
|
||||
parseStandalonePlainTextToolCallBlocks,
|
||||
stripPlainTextToolCallBlocks,
|
||||
|
||||
@@ -10,16 +10,25 @@ import {
|
||||
skipWhitespace,
|
||||
} from "./grammar.js";
|
||||
|
||||
/** Parsed standalone plain-text tool call block with source offsets for repair. */
|
||||
export type PlainTextToolCallBlock = {
|
||||
/** Parsed JSON arguments object. */
|
||||
arguments: Record<string, unknown>;
|
||||
/** Exclusive end offset of the parsed block. */
|
||||
end: number;
|
||||
/** Tool name parsed from bracket, Harmony, or XML-ish syntax. */
|
||||
name: string;
|
||||
/** Original text slice that produced this block. */
|
||||
raw: string;
|
||||
/** Inclusive start offset of the parsed block. */
|
||||
start: number;
|
||||
};
|
||||
|
||||
/** Parser limits and allowlist options for plain-text tool-call repair. */
|
||||
export type PlainTextToolCallParseOptions = {
|
||||
/** Optional allowlist of tool names that may be repaired. */
|
||||
allowedToolNames?: Iterable<string>;
|
||||
/** Maximum JSON payload size accepted for one repaired call. */
|
||||
maxPayloadBytes?: number;
|
||||
};
|
||||
|
||||
@@ -389,6 +398,7 @@ export function parseStandalonePlainTextToolCallBlocks(
|
||||
return blocks.length > 0 ? blocks : null;
|
||||
}
|
||||
|
||||
/** Removes full-line standalone plain-text tool-call blocks from user-visible text. */
|
||||
export function stripPlainTextToolCallBlocks(text: string): string {
|
||||
if (
|
||||
!text ||
|
||||
|
||||
@@ -11,26 +11,36 @@ import {
|
||||
} from "./grammar.js";
|
||||
|
||||
export type PlainTextToolCallNameMatcher = {
|
||||
/** True only when the candidate is a complete tool name this request may repair. */
|
||||
hasExactName(name: string): boolean;
|
||||
/** True while streamed bytes still match at least one repairable tool name prefix. */
|
||||
hasNamePrefix(prefix: string): boolean;
|
||||
};
|
||||
|
||||
/** Result of repairing the final message carried by a provider stream `done` event. */
|
||||
export type PlainTextToolCallMessageNormalization =
|
||||
| { kind: "promoted" | "scrubbed"; message: Record<string, unknown> }
|
||||
| undefined;
|
||||
|
||||
/** Stream-level hooks used to promote leaked text tool calls into provider events. */
|
||||
export type PlainTextToolCallStreamNormalizerOptions = {
|
||||
/** Expands a promoted final message into provider-native tool-call stream events. */
|
||||
createPromotedToolCallEvents(message: Record<string, unknown>): Iterable<unknown>;
|
||||
/** Tool-name matcher scoped to the exact request being normalized. */
|
||||
matcher: PlainTextToolCallNameMatcher;
|
||||
/** Repairs or scrubs the final done-message snapshot after text buffering completes. */
|
||||
normalizeDoneMessage(params: {
|
||||
message: unknown;
|
||||
reason: unknown;
|
||||
}): PlainTextToolCallMessageNormalization;
|
||||
/** Stop after the first normalized done event when the wrapped provider has completed. */
|
||||
stopAfterDone?: boolean;
|
||||
};
|
||||
|
||||
const TEXT_TOOL_CALL_BUFFER_MAX_CHARS = 256_000;
|
||||
|
||||
// Keep a bounded prefix plus enough tail to notice closing markers after the cap;
|
||||
// otherwise a huge leaked payload could either grow unbounded or lose the visible suffix.
|
||||
const TEXT_TOOL_CALL_SUPPRESSED_SCAN_MAX_CHARS = TEXT_TOOL_CALL_BUFFER_MAX_CHARS + 64_000;
|
||||
const TEXT_TOOL_CALL_SUPPRESSED_TAIL_CHARS =
|
||||
TEXT_TOOL_CALL_SUPPRESSED_SCAN_MAX_CHARS - TEXT_TOOL_CALL_BUFFER_MAX_CHARS;
|
||||
@@ -941,6 +951,7 @@ function scrubReclassifiedMixedTextFromError(
|
||||
};
|
||||
}
|
||||
|
||||
/** Scrubs final messages whose streamed plain-text tool-call prefix exceeded the buffer cap. */
|
||||
export function scrubOverCapPlainTextToolCallMessage(params: {
|
||||
candidateText: string | undefined;
|
||||
matcher: PlainTextToolCallNameMatcher;
|
||||
@@ -1039,6 +1050,7 @@ function isBufferedTextEvent(bufferedEvent: unknown): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
/** Buffers provider stream text long enough to promote or hide leaked plain-text tool calls. */
|
||||
export async function* normalizePlainTextToolCallStreamEvents(
|
||||
source: AsyncIterable<unknown>,
|
||||
options: PlainTextToolCallStreamNormalizerOptions,
|
||||
@@ -1121,6 +1133,8 @@ export async function* normalizePlainTextToolCallStreamEvents(
|
||||
continue;
|
||||
}
|
||||
if (suppressingOverCapTextToolCall) {
|
||||
// Once the tentative tool call exceeds the cap, suppress text deltas until a closing
|
||||
// marker proves whether the buffered prefix was a hidden call or mixed visible text.
|
||||
if (hasSuppressedTextContentIndex && record.contentIndex !== suppressedTextContentIndex) {
|
||||
if (isAllowedTextToolCallLikeEvent(record, options.matcher)) {
|
||||
continue;
|
||||
@@ -1171,6 +1185,8 @@ export async function* normalizePlainTextToolCallStreamEvents(
|
||||
? stripSerializedToolCallPrefixes(bufferedText.trimStart(), options.matcher)
|
||||
: null;
|
||||
if (visibleText?.trim()) {
|
||||
// A tool-call prefix followed by visible text must be reclassified: emit only the
|
||||
// suffix now, then scrub the final done/error snapshots to match that stream history.
|
||||
yield* flushScrubbedBufferedNonTextEvents(true);
|
||||
reclassifiedMixedTextContentIndex = record.contentIndex;
|
||||
hasReclassifiedMixedTextContentIndex = true;
|
||||
|
||||
@@ -17,6 +17,7 @@ import { classifyAcpToolApproval, type AcpApprovalClass } from "./approval-class
|
||||
|
||||
type PermissionOption = RequestPermissionRequest["options"][number];
|
||||
|
||||
// ACP permission resolution keeps readonly tool classes noninteractive and prompts for risky tools.
|
||||
type PermissionResolverDeps = {
|
||||
prompt?: (toolName: string | undefined, toolTitle?: string) => Promise<boolean>;
|
||||
log?: (line: string) => void;
|
||||
@@ -153,6 +154,7 @@ type AcpClientSpawnEnvOptions = {
|
||||
stripKeys?: Iterable<string>;
|
||||
};
|
||||
|
||||
/** Builds the sanitized environment used when spawning an ACP client process. */
|
||||
export function resolveAcpClientSpawnEnv(
|
||||
baseEnv: NodeJS.ProcessEnv = process.env,
|
||||
options: AcpClientSpawnEnvOptions = {},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { AcpRuntimeErrorCode } from "../runtime/errors.js";
|
||||
import { normalizeText } from "./runtime-options.js";
|
||||
|
||||
/** Captured backend attempt state used to decide whether failover is safe. */
|
||||
export type BackendAttempt = {
|
||||
backend: string;
|
||||
error: string;
|
||||
|
||||
@@ -15,6 +15,7 @@ import { normalizeText } from "./runtime-options.js";
|
||||
const ACP_BACKGROUND_TASK_TEXT_MAX_LENGTH = 160;
|
||||
const ACP_BACKGROUND_TASK_PROGRESS_MAX_LENGTH = 240;
|
||||
|
||||
/** Context needed to mirror a child ACP turn into the requester task registry. */
|
||||
export type BackgroundTaskContext = {
|
||||
requesterSessionKey: string;
|
||||
requesterOrigin?: DeliveryContext;
|
||||
|
||||
@@ -14,6 +14,7 @@ import type {
|
||||
} from "./manager.types.js";
|
||||
import { normalizeActorKey, requireReadySessionMeta } from "./manager.utils.js";
|
||||
|
||||
/** Cancels either the active ACP turn or the idle runtime handle for a session. */
|
||||
export async function runManagerCancelSession(params: {
|
||||
cfg: OpenClawConfig;
|
||||
sessionKey: string;
|
||||
|
||||
@@ -59,6 +59,7 @@ import {
|
||||
} from "./runtime-options.js";
|
||||
import { SessionActorQueue } from "./session-actor-queue.js";
|
||||
|
||||
/** Coordinates ACP session metadata, runtime handles, per-session queues, and turn execution. */
|
||||
export class AcpSessionManager {
|
||||
private readonly actorQueue = new SessionActorQueue();
|
||||
private readonly runtimeHandles = new ManagerRuntimeHandleCache();
|
||||
|
||||
@@ -17,6 +17,7 @@ import { withAcpRuntimeErrorBoundary } from "../runtime/errors.js";
|
||||
import type { SessionAcpMeta, SessionEntry } from "./manager.types.js";
|
||||
import { hasLegacyAcpIdentityProjection } from "./manager.utils.js";
|
||||
|
||||
/** Reconciles runtime-reported session identifiers into persisted ACP session metadata. */
|
||||
export async function reconcileManagerRuntimeSessionIdentifiers(params: {
|
||||
cfg: OpenClawConfig;
|
||||
sessionKey: string;
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
validateRuntimeOptionPatch,
|
||||
} from "./runtime-options.js";
|
||||
|
||||
/** Initializes an ACP runtime session and persists its metadata before caching the handle. */
|
||||
export async function runManagerInitializeSession(params: {
|
||||
input: AcpInitializeSessionInput;
|
||||
sessionKey: string;
|
||||
|
||||
@@ -16,6 +16,7 @@ import { RuntimeCache, type CachedRuntimeState } from "./runtime-cache.js";
|
||||
import { normalizeText } from "./runtime-options.js";
|
||||
import type { SessionActorQueue } from "./session-actor-queue.js";
|
||||
|
||||
/** Process-local cache of live ACP runtime handles keyed by canonical session actor. */
|
||||
export class ManagerRuntimeHandleCache {
|
||||
private readonly runtimeCache = new RuntimeCache();
|
||||
private evictedRuntimeCount = 0;
|
||||
@@ -96,6 +97,7 @@ export class ManagerRuntimeHandleCache {
|
||||
}
|
||||
|
||||
for (const candidate of candidates) {
|
||||
// Evict under the same actor queue so turns cannot race with runtime close.
|
||||
await params.actorQueue.run(candidate.actorKey, async () => {
|
||||
if (params.activeTurnBySession.has(candidate.actorKey)) {
|
||||
return;
|
||||
|
||||
@@ -11,6 +11,7 @@ import type {
|
||||
WriteManagerSessionMeta,
|
||||
} from "./manager.types.js";
|
||||
|
||||
/** Detects acpx exits that are safe to retry with a fresh runtime handle. */
|
||||
export function isRecoverableManagerAcpxExitError(message: string): boolean {
|
||||
return /^acpx exited with (code \d+|signal [a-z0-9]+)/i.test(message.trim());
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import type {
|
||||
WithManagerSessionActor,
|
||||
} from "./manager.types.js";
|
||||
|
||||
/** Resolves pending ACP session identities opportunistically during manager startup. */
|
||||
export async function runManagerStartupIdentityReconcile(params: {
|
||||
cfg: OpenClawConfig;
|
||||
deps: Pick<AcpSessionManagerDeps, "listAcpSessions">;
|
||||
|
||||
@@ -16,6 +16,7 @@ import type {
|
||||
import { requireReadySessionMeta } from "./manager.utils.js";
|
||||
import { resolveRuntimeOptionsFromMeta } from "./runtime-options.js";
|
||||
|
||||
/** Reads a fresh ACP session status and reconciles runtime identifiers from the status response. */
|
||||
export async function runManagerGetSessionStatus(params: {
|
||||
cfg: OpenClawConfig;
|
||||
sessionKey: string;
|
||||
|
||||
@@ -37,6 +37,7 @@ vi.mock("../runtime/registry.js", () => ({
|
||||
|
||||
export const hoisted = hoistedMocks;
|
||||
|
||||
// Shared ACP manager test harness with hoisted runtime/session-meta mocks.
|
||||
const managerModule = await import("./manager.js");
|
||||
export const AcpSessionManager = managerModule.AcpSessionManager;
|
||||
export const resetAcpSessionManagerForTests = () =>
|
||||
|
||||
@@ -15,6 +15,7 @@ export type {
|
||||
|
||||
let ACP_SESSION_MANAGER_SINGLETON: AcpSessionManager | null = null;
|
||||
|
||||
/** Returns the process-wide ACP session manager singleton. */
|
||||
export function getAcpSessionManager(): AcpSessionManager {
|
||||
if (!ACP_SESSION_MANAGER_SINGLETON) {
|
||||
ACP_SESSION_MANAGER_SINGLETON = new AcpSessionManager();
|
||||
|
||||
@@ -12,6 +12,7 @@ export type AcpTurnEventGate = {
|
||||
open: boolean;
|
||||
};
|
||||
|
||||
/** Summary of whether a turn stream emitted user-visible output or terminal events. */
|
||||
export type AcpTurnStreamOutcome = {
|
||||
sawOutput: boolean;
|
||||
sawTerminalEvent: boolean;
|
||||
@@ -113,6 +114,7 @@ export async function consumeAcpTurnStream(params: {
|
||||
) => Promise<void> | void;
|
||||
}): Promise<AcpTurnStreamOutcome> {
|
||||
if (params.runtime.startTurn) {
|
||||
// startTurn exposes result and event streams separately; coordinate both before reporting done.
|
||||
const turn = params.runtime.startTurn(params.turn);
|
||||
const eventsPromise = consumeAcpTurnEvents({
|
||||
events: turn.events,
|
||||
|
||||
@@ -10,6 +10,7 @@ import { resolveRuntimeOptionsFromMeta } from "./runtime-options.js";
|
||||
const ACP_TURN_TIMEOUT_CLEANUP_GRACE_MS = 2_000;
|
||||
const ACP_TURN_TIMEOUT_REASON = "turn-timeout";
|
||||
|
||||
/** Resolves the effective ACP turn timeout from session runtime options or agent defaults. */
|
||||
export function resolveTurnTimeoutMs(params: {
|
||||
cfg: OpenClawConfig;
|
||||
meta: SessionAcpMeta;
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
upsertAcpSessionMeta,
|
||||
} from "../runtime/session-meta.js";
|
||||
|
||||
/** Result of resolving persisted ACP metadata for a session key. */
|
||||
export type AcpSessionResolution =
|
||||
| {
|
||||
kind: "none";
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
} from "../../routing/session-key.js";
|
||||
import type { AcpSessionResolution } from "./manager.types.js";
|
||||
|
||||
/** Resolves the agent id encoded in an ACP session key. */
|
||||
export function resolveAcpAgentFromSessionKey(sessionKey: string, fallback = "main"): string {
|
||||
const parsed = parseAgentSessionKey(sessionKey);
|
||||
return normalizeAgentId(parsed?.agentId ?? fallback);
|
||||
|
||||
@@ -4,6 +4,7 @@ import type {
|
||||
AcpRuntimeSessionMode,
|
||||
} from "@openclaw/acp-core/runtime/types";
|
||||
|
||||
/** Cached runtime handle plus the configuration signature that made it reusable. */
|
||||
export type CachedRuntimeState = {
|
||||
runtime: AcpRuntime;
|
||||
handle: AcpRuntimeHandle;
|
||||
|
||||
@@ -19,6 +19,7 @@ const MAX_BACKEND_OPTION_VALUE_LENGTH = 512;
|
||||
const MAX_BACKEND_EXTRAS = 32;
|
||||
|
||||
const SAFE_OPTION_KEY_RE = /^[a-z0-9][a-z0-9._:-]*$/i;
|
||||
// User-facing config aliases accepted by ACP clients and normalized to session runtime options.
|
||||
const RUNTIME_CONFIG_OPTION_ALIASES = {
|
||||
model: ["model"],
|
||||
thinking: ["thinking", "effort", "reasoning_effort", "thought_level"],
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
|
||||
|
||||
/** Per-session async queue that serializes ACP runtime operations and exposes queue depth. */
|
||||
export class SessionActorQueue {
|
||||
private readonly queue = new KeyedAsyncQueue();
|
||||
private readonly pendingBySession = new Map<string, number>();
|
||||
@@ -26,6 +27,7 @@ export class SessionActorQueue {
|
||||
this.pendingBySession.set(actorKey, (this.pendingBySession.get(actorKey) ?? 0) + 1);
|
||||
},
|
||||
onSettle: () => {
|
||||
// Keep queue-depth accounting symmetric with enqueue even when operations reject.
|
||||
const pending = (this.pendingBySession.get(actorKey) ?? 1) - 1;
|
||||
if (pending <= 0) {
|
||||
this.pendingBySession.delete(actorKey);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** Normalizes ACP conversation identifiers from loose metadata values. */
|
||||
export function normalizeConversationText(value: unknown): string {
|
||||
if (typeof value === "string") {
|
||||
return value.trim();
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
} from "./persistent-bindings.types.js";
|
||||
import { readAcpSessionEntry } from "./runtime/session-meta.js";
|
||||
|
||||
// Binding lifecycle keeps configured channel conversations attached to matching ACP sessions.
|
||||
function sessionMatchesConfiguredBinding(params: {
|
||||
cfg: OpenClawConfig;
|
||||
spec: ConfiguredAcpBindingSpec;
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
type ResolvedConfiguredAcpBinding,
|
||||
} from "./persistent-bindings.types.js";
|
||||
|
||||
/** Resolves a configured ACP binding for a concrete channel conversation. */
|
||||
export function resolveConfiguredAcpBindingRecord(params: {
|
||||
cfg: OpenClawConfig;
|
||||
channel: string;
|
||||
|
||||
@@ -17,6 +17,7 @@ export type AcpRuntimeAdapterContractParams = {
|
||||
}) => void | Promise<void>;
|
||||
};
|
||||
|
||||
/** Runs the shared behavioral contract for ACP runtime adapters. */
|
||||
export async function runAcpRuntimeAdapterContract(
|
||||
params: AcpRuntimeAdapterContractParams,
|
||||
): Promise<void> {
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import { isAcpEnabledByPolicy } from "../policy.js";
|
||||
import { getAcpRuntimeBackend } from "./registry.js";
|
||||
|
||||
/** Returns whether ACP runtime spawning is allowed and the selected backend is healthy enough. */
|
||||
export function isAcpRuntimeSpawnAvailable(params: {
|
||||
config?: OpenClawConfig;
|
||||
sandboxed?: boolean;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { configureAcpErrorRedactor } from "@openclaw/acp-core";
|
||||
import { redactSensitiveText } from "../../logging/redact.js";
|
||||
|
||||
// Ensure ACP-core runtime errors use OpenClaw's secret redaction before re-export.
|
||||
configureAcpErrorRedactor(redactSensitiveText);
|
||||
|
||||
export * from "@openclaw/acp-core/runtime/errors";
|
||||
|
||||
@@ -36,6 +36,7 @@ export type AcpSessionStoreEntry = {
|
||||
storeReadFailed?: boolean;
|
||||
};
|
||||
|
||||
// ACP metadata lives in SQLite but is keyed through the legacy JSON session store.
|
||||
type AcpSessionsTable = OpenClawStateKyselyDatabase["acp_sessions"];
|
||||
type AcpSessionMetaDatabase = Pick<OpenClawStateKyselyDatabase, "acp_sessions">;
|
||||
type AcpSessionRow = Selectable<AcpSessionsTable>;
|
||||
@@ -154,6 +155,7 @@ function selectAcpSessionRow(db: DatabaseSync, sessionKey: string): AcpSessionRo
|
||||
}
|
||||
|
||||
function acpSessionRowMatchesEntry(row: AcpSessionRow, entry: SessionEntry | undefined): boolean {
|
||||
// Rows tied to a specific sessionId are stale after the JSON session entry rotates.
|
||||
return row.session_id == null || row.session_id === entry?.sessionId;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { DEFAULT_SECRET_FILE_MAX_BYTES, readSecretFileSync } from "../infra/secr
|
||||
|
||||
const MAX_SECRET_FILE_BYTES = DEFAULT_SECRET_FILE_MAX_BYTES;
|
||||
|
||||
/** Reads an ACP secret file with the shared secret-file size and symlink policy. */
|
||||
export function readSecretFromFile(filePath: string, label: string): string {
|
||||
return readSecretFileSync(filePath, label, {
|
||||
maxBytes: MAX_SECRET_FILE_BYTES,
|
||||
|
||||
@@ -10,6 +10,7 @@ type AcpSessionMeta = {
|
||||
prefixCwd?: boolean;
|
||||
};
|
||||
|
||||
/** Parses ACP request metadata into OpenClaw session routing hints. */
|
||||
export function parseSessionMeta(meta: unknown): AcpSessionMeta {
|
||||
if (!meta || typeof meta !== "object") {
|
||||
return {};
|
||||
|
||||
@@ -12,6 +12,7 @@ import type { GatewayClient } from "../gateway/client.js";
|
||||
import { AcpGatewayAgent } from "./translator.js";
|
||||
import { createAcpConnection, createAcpGateway } from "./translator.test-helpers.js";
|
||||
|
||||
/** Builds a minimal ACP new-session request for translator tests. */
|
||||
export function createNewSessionRequest(cwd = "/tmp"): NewSessionRequest {
|
||||
return {
|
||||
cwd,
|
||||
|
||||
@@ -12,6 +12,7 @@ import { normalizeOptionalString } from "@openclaw/normalization-core/string-coe
|
||||
import { BASE_THINKING_LEVELS } from "../auto-reply/thinking.shared.js";
|
||||
import type { GatewaySessionRow } from "../gateway/session-utils.js";
|
||||
|
||||
/** ACP config option ids exposed to compatible ACP clients. */
|
||||
export const ACP_THOUGHT_LEVEL_CONFIG_ID = "thought_level";
|
||||
export const ACP_FAST_MODE_CONFIG_ID = "fast_mode";
|
||||
export const ACP_VERBOSE_LEVEL_CONFIG_ID = "verbose_level";
|
||||
@@ -28,6 +29,7 @@ export type ClientCapabilityState = {
|
||||
terminal: boolean;
|
||||
};
|
||||
|
||||
/** Gateway session fields needed to build ACP session presentation state. */
|
||||
export type GatewaySessionPresentationRow = Pick<
|
||||
GatewaySessionRow,
|
||||
| "key"
|
||||
|
||||
@@ -12,6 +12,7 @@ type PendingPromptHarness = {
|
||||
runId: string;
|
||||
};
|
||||
|
||||
// Shared prompt harness used by translator cancellation and lifecycle tests.
|
||||
const DEFAULT_SESSION_ID = "session-1";
|
||||
export const DEFAULT_SESSION_KEY = "agent:main:main";
|
||||
const DEFAULT_PROMPT_TEXT = "hello";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user