UNPKG

@botpress/adk-cli

Version:

Command-line interface for the Botpress Agent Development Kit (ADK)

119 lines (114 loc) 3.6 kB
// @bun import { createCliLogger } from "./chunk-gzwt1qdr.js"; import { AdkError } from "./chunk-p0hjqn4r.js"; import { ne } from "./chunk-6w0knnta.js"; // src/utils/port-scanner.ts var {serve } = globalThis.Bun; async function findAvailablePort(startPort, maxAttempts = 20) { for (let i = 0;i < maxAttempts; i++) { const port = startPort + i; try { const server = serve({ port, hostname: "0.0.0.0", fetch() { return new Response(null, { status: 404 }); } }); server.stop(true); return port; } catch { continue; } } throw new AdkError({ code: "NO_AVAILABLE_PORT", message: `No available port found in range ${startPort}\u2013${startPort + maxAttempts - 1}. ` + `Free up a port or increase the scan range.`, expected: true }); } // src/server/socket/ndjson.ts var logger = createCliLogger({ tag: "ndjson" }); var MAX_BUFFER_BYTES = 64 * 1024; function encode(message) { return JSON.stringify(message) + ` `; } function createLineParser() { let buffer = ""; return { feed(data) { buffer += data; if (buffer.length > MAX_BUFFER_BYTES) { logger.warn(`Dropping ${buffer.length}-byte buffer exceeding ${MAX_BUFFER_BYTES}-byte cap`); buffer = ""; return []; } const lines = buffer.split(` `); buffer = lines.pop(); const messages = []; for (const line of lines) { if (line.length === 0) continue; try { messages.push(JSON.parse(line)); } catch {} } return messages; } }; } // src/server/socket/protocol.ts var PROTOCOL_VERSION = 1; var agentStatusSchema = ne.union([ne.literal("starting"), ne.literal("ready"), ne.literal("error")]); var processMetadataSchema = ne.object({ adkPid: ne.number().int().positive().optional(), botPid: ne.number().int().positive().optional(), startedAt: ne.number().int().positive().optional(), updatedAt: ne.number().int().positive().optional() }).optional(); var registerMessageSchema = ne.object({ v: ne.literal(PROTOCOL_VERSION), type: ne.literal("register"), name: ne.string().min(1), agentPath: ne.string().min(1), backendPort: ne.number().int().positive(), botPort: ne.number().int().positive(), runtimeVersion: ne.string().optional(), cliVersion: ne.string().optional(), process: processMetadataSchema }); var deregisterMessageSchema = ne.object({ v: ne.literal(PROTOCOL_VERSION), type: ne.literal("deregister"), agentPath: ne.string().min(1) }); var heartbeatMessageSchema = ne.object({ v: ne.literal(PROTOCOL_VERSION), type: ne.literal("heartbeat"), agentPath: ne.string().min(1), status: agentStatusSchema, process: processMetadataSchema }); var agentToServerMessageSchema = ne.union([registerMessageSchema, deregisterMessageSchema, heartbeatMessageSchema]); function createRegisterMessage(fields) { return { v: PROTOCOL_VERSION, type: "register", ...fields }; } function createDeregisterMessage(agentPath) { return { v: PROTOCOL_VERSION, type: "deregister", agentPath }; } function createHeartbeatMessage(agentPath, status, processInfo) { return { v: PROTOCOL_VERSION, type: "heartbeat", agentPath, status, process: processInfo }; } function parseAgentToServerMessage(value) { const result = agentToServerMessageSchema.safeParse(value); return result.success ? result.data : null; } export { findAvailablePort, encode, createLineParser, PROTOCOL_VERSION, createRegisterMessage, createDeregisterMessage, createHeartbeatMessage, parseAgentToServerMessage };