UNPKG

@botpress/adk-cli

Version:

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

114 lines (111 loc) 4.02 kB
// @bun import { AdkError } from "./chunk-p0hjqn4r.js"; // src/utils/dev-server.ts import { readFileSync, existsSync, accessSync } from "fs"; import { dirname, join, parse, resolve } from "path"; import { homedir } from "os"; var DEFAULT_DEV_SERVER_PORT = 3001; var HEALTH_TIMEOUT_MS = 2000; var REQUEST_TIMEOUT_MS = 5000; var CONSOLE_PORT_FILE = join(homedir(), ".adk", "console.port"); var DEV_SERVER_DOWN_ERROR = "Dev server not running \u2014 start with `adk dev`"; function getDevServerUrl() { if (existsSync(CONSOLE_PORT_FILE)) { try { const port = parseInt(readFileSync(CONSOLE_PORT_FILE, "utf-8").trim(), 10); if (port > 0) return `http://localhost:${port}`; } catch {} } return `http://localhost:${DEFAULT_DEV_SERVER_PORT}`; } function resolveAgentRoot(cwd = process.cwd()) { let currentPath = resolve(cwd); const root = parse(currentPath).root; while (currentPath !== root) { try { accessSync(join(currentPath, "agent.config.ts")); return currentPath; } catch { currentPath = dirname(currentPath); } } return null; } function buildDevServerHeaders(agentRoot) { return agentRoot ? { "X-Agent-Path": agentRoot } : {}; } var cachedHeaders; function getDevServerHeaders() { if (cachedHeaders === undefined) { cachedHeaders = buildDevServerHeaders(resolveAgentRoot()); } return cachedHeaders; } async function fetchJson(pathname, headers = getDevServerHeaders(), timeoutMs = REQUEST_TIMEOUT_MS) { const response = await fetch(`${getDevServerUrl()}${pathname}`, { headers, signal: AbortSignal.timeout(timeoutMs) }); if (!response.ok) { throw new AdkError({ code: "DEV_SERVER_FETCH", message: `Failed to fetch ${pathname} from dev server (${response.status} ${response.statusText})`, expected: true, details: { status: response.status } }); } return await response.json(); } async function assertDevServerRunning(headers = getDevServerHeaders()) { try { const response = await fetch(`${getDevServerUrl()}/api/health`, { headers, signal: AbortSignal.timeout(HEALTH_TIMEOUT_MS) }); if (!response.ok) { throw new AdkError({ code: "DEV_SERVER_DOWN", message: DEV_SERVER_DOWN_ERROR, expected: true }); } } catch { throw new AdkError({ code: "DEV_SERVER_DOWN", message: DEV_SERVER_DOWN_ERROR, expected: true }); } } async function getDevServerConfig(headers = getDevServerHeaders()) { await assertDevServerRunning(headers); return fetchJson("/api/config", headers); } async function getDevServerAgent(headers = getDevServerHeaders()) { await assertDevServerRunning(headers); return fetchJson("/api/agent", headers); } function hasWorkflowInput(inputSchema) { const required = Array.isArray(inputSchema.required) ? inputSchema.required.length > 0 : false; const properties = inputSchema.properties ? Object.keys(inputSchema.properties).length > 0 : false; return required || properties; } function normalizeDevServerWorkflow(workflow) { const inputSchema = workflow.input ?? { type: "object", properties: {} }; return { name: workflow.name, description: workflow.description, hasSchedule: Boolean(workflow.schedule), hasInput: hasWorkflowInput(inputSchema), schedule: workflow.schedule, timeout: workflow.timeout, inputSchema }; } function normalizeDevServerWorkflows(workflows) { return (workflows ?? []).map(normalizeDevServerWorkflow); } async function listDevServerWorkflows(headers = getDevServerHeaders()) { const agent = await getDevServerAgent(headers); return normalizeDevServerWorkflows(agent.workflows); } async function getDevServerWorkflow(name, headers = getDevServerHeaders()) { const workflows = await listDevServerWorkflows(headers); return workflows.find((workflow) => workflow.name === name) ?? null; } export { DEV_SERVER_DOWN_ERROR, getDevServerUrl, resolveAgentRoot, buildDevServerHeaders, getDevServerConfig, listDevServerWorkflows, getDevServerWorkflow };