mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
ec8f6e5e03
* feat(browser): add copilot security contracts * fix(gateway): expose verified client identity to handlers * feat(browser): add secure per-tab copilot panel Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * refactor(browser): separate copilot gateway hint custody * fix(browser): preserve legacy pairing parse shape * fix(browser): harden copilot lifecycle custody Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * fix(browser): enforce copilot lifecycle boundaries Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * style(browser): format copilot sources Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * fix(browser): preserve copilot consent revocation Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * refactor(browser): split copilot custody owners Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * test(browser): normalize websocket array buffers Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * chore(protocol): regenerate Swift gateway models Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * refactor(browser): model copilot runtime entrypoints Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * fix(browser): honor extension build boundaries Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * test(gateway): assert targeted chat delivery Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * test(gateway): cover targeted delivery calls Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * fix(browser): declare copilot build dependencies Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * fix(ci): clear browser copilot gate failures Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * test(ci): cover copilot lint exclusion Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * fix(browser): gate copilot on relay custody Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * test(browser): bound copilot relay frames Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> --------- Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>
214 lines
8.5 KiB
TypeScript
214 lines
8.5 KiB
TypeScript
// Gateway Protocol schema module defines protocol validation shapes.
|
|
import type { Static } from "typebox";
|
|
import { Type } from "typebox";
|
|
import { closedObject } from "./closed-object.js";
|
|
import { ChatSendSessionKeyString, InputProvenanceSchema, NonEmptyString } from "./primitives.js";
|
|
|
|
/** Cursor-based request for the gateway log tail endpoint. */
|
|
export const LogsTailParamsSchema = closedObject({
|
|
cursor: Type.Optional(Type.Integer({ minimum: 0 })),
|
|
limit: Type.Optional(Type.Integer({ minimum: 1, maximum: 5000 })),
|
|
maxBytes: Type.Optional(Type.Integer({ minimum: 1, maximum: 1_000_000 })),
|
|
});
|
|
|
|
/** Gateway log tail payload returned to dashboard clients. */
|
|
export const LogsTailResultSchema = closedObject({
|
|
file: NonEmptyString,
|
|
cursor: Type.Integer({ minimum: 0 }),
|
|
size: Type.Integer({ minimum: 0 }),
|
|
lines: Type.Array(Type.String()),
|
|
truncated: Type.Optional(Type.Boolean()),
|
|
reset: Type.Optional(Type.Boolean()),
|
|
});
|
|
|
|
/** Session-scoped history request used by WebChat and native WebSocket clients. */
|
|
export const ChatHistoryParamsSchema = closedObject({
|
|
sessionKey: NonEmptyString,
|
|
agentId: Type.Optional(NonEmptyString),
|
|
limit: Type.Optional(Type.Integer({ minimum: 1, maximum: 1000 })),
|
|
offset: Type.Optional(Type.Integer({ minimum: 0 })),
|
|
messageId: Type.Optional(NonEmptyString),
|
|
sessionId: Type.Optional(NonEmptyString),
|
|
maxChars: Type.Optional(Type.Integer({ minimum: 1, maximum: 500_000 })),
|
|
});
|
|
|
|
/** Lightweight chat metadata request; optional agent scope keeps selector state explicit. */
|
|
export const ChatMetadataParamsSchema = closedObject({
|
|
agentId: Type.Optional(NonEmptyString),
|
|
});
|
|
|
|
/** Batched purpose-title request for tool calls rendered in the Control UI. */
|
|
export const ChatToolTitlesParamsSchema = closedObject({
|
|
sessionKey: NonEmptyString,
|
|
agentId: Type.Optional(NonEmptyString),
|
|
items: Type.Array(
|
|
closedObject({
|
|
id: Type.String({ minLength: 1, maxLength: 64 }),
|
|
name: Type.String({ minLength: 1, maxLength: 200 }),
|
|
input: Type.String({ minLength: 1, maxLength: 4_000 }),
|
|
}),
|
|
{ minItems: 1, maxItems: 24 },
|
|
),
|
|
});
|
|
|
|
/**
|
|
* Titles keyed by the caller-provided item id; missing ids mean no title.
|
|
* `disabled: true` tells clients the gateway has tool titles switched off so
|
|
* they stop requesting for the rest of the session.
|
|
*/
|
|
export const ChatToolTitlesResultSchema = closedObject({
|
|
titles: Type.Record(Type.String(), Type.String()),
|
|
disabled: Type.Optional(Type.Boolean()),
|
|
});
|
|
/** Typed result shape for tool-title consumers. */
|
|
export type ChatToolTitlesResult = Static<typeof ChatToolTitlesResultSchema>;
|
|
|
|
/** Fetches one stored chat message without forcing history callers to request huge payloads. */
|
|
export const ChatMessageGetParamsSchema = closedObject({
|
|
sessionKey: NonEmptyString,
|
|
agentId: Type.Optional(NonEmptyString),
|
|
messageId: NonEmptyString,
|
|
maxChars: Type.Optional(Type.Integer({ minimum: 1, maximum: 2_000_000 })),
|
|
});
|
|
|
|
/** Result envelope for single-message lookup, including the stable miss/visibility reason. */
|
|
export const ChatMessageGetResultSchema = closedObject({
|
|
ok: Type.Boolean(),
|
|
message: Type.Optional(Type.Unknown()),
|
|
unavailableReason: Type.Optional(
|
|
Type.Union([Type.Literal("not_found"), Type.Literal("oversized"), Type.Literal("not_visible")]),
|
|
),
|
|
});
|
|
/** Typed result shape for callers that branch on message availability. */
|
|
export type ChatMessageGetResult = Static<typeof ChatMessageGetResultSchema>;
|
|
|
|
/** Attachment envelope shared by chat.send and session creation's initial turn. */
|
|
export const ChatAttachmentsSchema = Type.Array(Type.Unknown());
|
|
|
|
/** Opaque, out-of-band plugin bindings carried separately from model input. */
|
|
export const RunToolBindingsSchema = Type.Record(
|
|
Type.String({ minLength: 1, maxLength: 128 }),
|
|
Type.Unknown(),
|
|
{ maxProperties: 16 },
|
|
);
|
|
export type RunToolBindings = Static<typeof RunToolBindingsSchema>;
|
|
|
|
/** User-to-agent send request; idempotency key lets clients safely retry transport failures. */
|
|
export const ChatSendParamsSchema = closedObject({
|
|
sessionKey: ChatSendSessionKeyString,
|
|
agentId: Type.Optional(NonEmptyString),
|
|
sessionId: Type.Optional(NonEmptyString),
|
|
message: Type.String(),
|
|
thinking: Type.Optional(Type.String()),
|
|
fastMode: Type.Optional(Type.Union([Type.Boolean(), Type.Literal("auto")])),
|
|
// One-turn override for auto fast-mode cutoff seconds.
|
|
fastAutoOnSeconds: Type.Optional(Type.Integer({ minimum: 1 })),
|
|
// One-turn override for active-run queue admission.
|
|
queueMode: Type.Optional(Type.String({ enum: ["steer", "followup", "collect", "interrupt"] })),
|
|
deliver: Type.Optional(Type.Boolean()),
|
|
originatingChannel: Type.Optional(Type.String()),
|
|
originatingTo: Type.Optional(Type.String()),
|
|
originatingAccountId: Type.Optional(Type.String()),
|
|
originatingThreadId: Type.Optional(Type.String()),
|
|
attachments: Type.Optional(ChatAttachmentsSchema),
|
|
toolBindings: Type.Optional(RunToolBindingsSchema),
|
|
timeoutMs: Type.Optional(Type.Integer({ minimum: 0 })),
|
|
systemInputProvenance: Type.Optional(InputProvenanceSchema),
|
|
systemProvenanceReceipt: Type.Optional(Type.String()),
|
|
suppressCommandInterpretation: Type.Optional(Type.Boolean()),
|
|
expectedSessionRoutingContract: Type.Optional(NonEmptyString),
|
|
idempotencyKey: NonEmptyString,
|
|
});
|
|
|
|
/** Cancels the active or named run for a chat session. */
|
|
export const ChatAbortParamsSchema = closedObject({
|
|
sessionKey: NonEmptyString,
|
|
agentId: Type.Optional(NonEmptyString),
|
|
runId: Type.Optional(NonEmptyString),
|
|
preserveSideRuns: Type.Optional(Type.Boolean()),
|
|
});
|
|
|
|
/** Inserts an operator-visible synthetic message into an existing chat transcript. */
|
|
export const ChatInjectParamsSchema = closedObject({
|
|
sessionKey: NonEmptyString,
|
|
agentId: Type.Optional(NonEmptyString),
|
|
message: NonEmptyString,
|
|
label: Type.Optional(Type.String({ maxLength: 100 })),
|
|
});
|
|
|
|
/** Shared event fields preserve stream ordering and route events to the right session. */
|
|
const ChatEventBaseSchema = {
|
|
runId: NonEmptyString,
|
|
sessionKey: NonEmptyString,
|
|
agentId: Type.Optional(NonEmptyString),
|
|
spawnedBy: Type.Optional(NonEmptyString),
|
|
seq: Type.Integer({ minimum: 0 }),
|
|
};
|
|
|
|
/** Stable error categories exposed over the chat stream. */
|
|
const ChatEventErrorKindSchema = Type.Union([
|
|
Type.Literal("refusal"),
|
|
Type.Literal("timeout"),
|
|
Type.Literal("rate_limit"),
|
|
Type.Literal("context_length"),
|
|
Type.Literal("unknown"),
|
|
]);
|
|
|
|
/** Incremental assistant output event; `replace` marks full-content refresh deltas. */
|
|
export const ChatDeltaEventSchema = closedObject({
|
|
...ChatEventBaseSchema,
|
|
state: Type.Literal("delta"),
|
|
message: Type.Optional(Type.Unknown()),
|
|
deltaText: Type.String(),
|
|
replace: Type.Optional(Type.Boolean()),
|
|
usage: Type.Optional(Type.Unknown()),
|
|
});
|
|
|
|
/** Successful terminal event for a completed chat run. */
|
|
export const ChatFinalEventSchema = closedObject({
|
|
...ChatEventBaseSchema,
|
|
state: Type.Literal("final"),
|
|
message: Type.Optional(Type.Unknown()),
|
|
usage: Type.Optional(Type.Unknown()),
|
|
stopReason: Type.Optional(Type.String()),
|
|
yielded: Type.Optional(Type.Literal(true)),
|
|
});
|
|
|
|
/** Terminal event for user-initiated or coordinator-initiated cancellation. */
|
|
export const ChatAbortedEventSchema = closedObject({
|
|
...ChatEventBaseSchema,
|
|
state: Type.Literal("aborted"),
|
|
message: Type.Optional(Type.Unknown()),
|
|
errorMessage: Type.Optional(Type.String()),
|
|
stopReason: Type.Optional(Type.String()),
|
|
});
|
|
|
|
/** Terminal event for failed chat runs with an optional normalized failure kind. */
|
|
export const ChatErrorEventSchema = closedObject({
|
|
...ChatEventBaseSchema,
|
|
state: Type.Literal("error"),
|
|
message: Type.Optional(Type.Unknown()),
|
|
errorMessage: Type.Optional(Type.String()),
|
|
errorKind: Type.Optional(ChatEventErrorKindSchema),
|
|
usage: Type.Optional(Type.Unknown()),
|
|
stopReason: Type.Optional(Type.String()),
|
|
});
|
|
|
|
/** Public chat stream event union consumed by gateway protocol validators. */
|
|
export const ChatEventSchema = Type.Union([
|
|
ChatDeltaEventSchema,
|
|
ChatFinalEventSchema,
|
|
ChatAbortedEventSchema,
|
|
ChatErrorEventSchema,
|
|
]);
|
|
|
|
// Wire types derive directly from local schema consts so public d.ts graphs never
|
|
// pull in the ProtocolSchemas registry.
|
|
export type ChatMetadataParams = Static<typeof ChatMetadataParamsSchema>;
|
|
export type ChatToolTitlesParams = Static<typeof ChatToolTitlesParamsSchema>;
|
|
export type LogsTailParams = Static<typeof LogsTailParamsSchema>;
|
|
export type LogsTailResult = Static<typeof LogsTailResultSchema>;
|
|
export type ChatAbortParams = Static<typeof ChatAbortParamsSchema>;
|
|
export type ChatInjectParams = Static<typeof ChatInjectParamsSchema>;
|
|
export type ChatEvent = Static<typeof ChatEventSchema>;
|