/** * Protocol types and limits defined in CONTRACTS.md Revision 1 */ export const PROTOCOL_VERSION = 1; // Size limits in bytes export const KIB = 1024; export const MIB = 1024 * 1024; /** * Protocol maximum for one query in milliseconds. The backend sets * CONFLUENCE_WEB_MAX_DEADLINE_SECONDS on the container; the supervisor forwards * it. Invalid or absent values fall back to 900 s (15 minutes). */ function maxDeadlineMs(): number { const raw = typeof process !== 'undefined' ? process.env.CONFLUENCE_WEB_MAX_DEADLINE_SECONDS : undefined; const seconds = raw === undefined || raw === '' ? NaN : Number(raw); return Number.isInteger(seconds) && seconds >= 60 && seconds <= 3600 ? seconds * 1000 : 900_000; } export const LIMITS = { USER_PROMPT_MAX_BYTES: 16 * MIB, FINAL_MARKDOWN_MAX_BYTES: 128 * MIB, TOOL_REQUEST_PAYLOAD_MAX_BYTES: 16 * MIB, TOOL_RESULT_PAYLOAD_MAX_BYTES: 128 * MIB, MODEL_REQUEST_PAYLOAD_MAX_BYTES: 128 * MIB, MODEL_RESULT_PAYLOAD_MAX_BYTES: 128 * MIB, ENVELOPE_ALLOWANCE_BYTES: 64 * KIB, START_FRAME_MAX_BYTES: 6 * (16 * MIB) + 64 * KIB, COLLECTION_START_FRAME_MAX_BYTES: 6 * (128 * MIB) + 64 * KIB, ORDINARY_FRAME_MAX_BYTES: 128 * MIB + 64 * KIB, ARTIFACT_CHUNK_MAX_DECODED_BYTES: 64 * KIB, ARTIFACT_MAX_FILES: 20, ARTIFACT_MAX_FILE_BYTES: 10 * MIB, ARTIFACT_MAX_TOTAL_BYTES: 50 * MIB, MAX_DEADLINE_MS: maxDeadlineMs(), MAX_REMOTE_CONCURRENCY: 4, MAX_WARNINGS: 100, MAX_ERROR_MESSAGE_BYTES: 1024, MAX_PATH_BYTES: 1024 } as const; export interface ErrorShape { code: string; message: string; } export interface Warning { code: string; message: string; tool_call_id?: string; name?: string; } export interface Page { page_id: string; title: string; space: string; url: string; } export interface Pagination { offset: number; limit: number; has_more: boolean; } export interface ModelDescriptor { id: string; context_window_tokens: number; max_output_tokens: number; } // Model Protocol export type TextContentBlock = { type: "text"; text: string; }; export type ToolCallContentBlock = { type: "tool_call"; id: string; name: string; arguments: Record; }; export type ContentBlock = TextContentBlock | ToolCallContentBlock; export interface UserMessageContract { role: "user"; content: Array<{ type: "text"; text: string }>; } export interface AssistantMessageContract { role: "assistant"; content: ContentBlock[]; provider_state?: string; } export interface ToolMessageContract { role: "tool"; tool_call_id: string; name: string; content: string; is_error: boolean; } export type MessageContract = | UserMessageContract | AssistantMessageContract | ToolMessageContract; export interface ToolDeclaration { name: string; description: string; input_schema: Record; } export interface ModelRequest { messages: MessageContract[]; tools: ToolDeclaration[]; } export interface ModelResponse { content: ContentBlock[]; stop_reason: "stop" | "tool_calls" | "length"; usage: { input_tokens: number; output_tokens: number; }; provider_state?: string; } // Bridge Protocol Frames export interface BridgeBaseMessage { v: number; type: string; id: string; reply_to?: string; payload: any; } export interface StartMessage extends BridgeBaseMessage { type: "start"; payload: { prompt: string; system_instruction: string; remaining_ms: number; model: ModelDescriptor; }; } export interface ToolRequestMessage extends BridgeBaseMessage { type: "tool_request"; payload: { tool: string; parameters: Record; }; } export interface ToolResponseMessage extends BridgeBaseMessage { type: "tool_response"; reply_to: string; payload: { result: any; error: ErrorShape | null; }; } export interface ModelRequestMessage extends BridgeBaseMessage { type: "model_request"; payload: ModelRequest; } export interface ModelResponseMessage extends BridgeBaseMessage { type: "model_response"; reply_to: string; payload: { result: ModelResponse | null; error: ErrorShape | null; }; } export interface CollectionStartMessage extends BridgeBaseMessage { type: "collection_start"; payload: { markdown: string; warnings: Warning[]; }; } export interface CollectionReadyMessage extends BridgeBaseMessage { type: "collection_ready"; reply_to: string; payload: Record; } export interface ArtifactBeginMessage extends BridgeBaseMessage { type: "artifact_begin"; payload: { transfer_id: string; name: string; size_bytes: number; }; } export interface ArtifactAckMessage extends BridgeBaseMessage { type: "artifact_ack"; reply_to: string; payload: { transfer_id: string; decision: "accept" | "skip" | "stored"; warning: Warning | null; }; } export interface ArtifactChunkMessage extends BridgeBaseMessage { type: "artifact_chunk"; payload: { transfer_id: string; index: number; data_base64: string; }; } export interface ArtifactEndMessage extends BridgeBaseMessage { type: "artifact_end"; payload: { transfer_id: string; size_bytes: number; chunks: number; }; } export interface CompleteMessage extends BridgeBaseMessage { type: "complete"; payload: { accepted_transfer_count: number; }; } export interface ErrorMessage extends BridgeBaseMessage { type: "error"; payload: ErrorShape; } export type BridgeInboundMessage = | StartMessage | ToolResponseMessage | ModelResponseMessage | CollectionReadyMessage | ArtifactAckMessage; export type BridgeOutboundMessage = | ToolRequestMessage | ModelRequestMessage | CollectionStartMessage | ArtifactBeginMessage | ArtifactChunkMessage | ArtifactEndMessage | CompleteMessage | ErrorMessage;