@botpress/adk-cli
Version:
Command-line interface for the Botpress Agent Development Kit (ADK)
119 lines (114 loc) • 3.6 kB
JavaScript
// @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 };