@botpress/adk-cli
Version:
Command-line interface for the Botpress Agent Development Kit (ADK)
242 lines (238 loc) • 7.67 kB
JavaScript
// @bun
import {
AdkError,
ConfigWriter,
auth
} from "./chunk-p0hjqn4r.js";
import {
Uk
} from "./chunk-3xrpxgq4.js";
// src/commands/adk-link-utils.ts
function validateBotName(value) {
const trimmed = value.trim();
if (!trimmed) {
return "Bot name cannot be empty";
}
if (trimmed.length < 3) {
return "Bot name must be at least 3 characters";
}
if (trimmed.length > 50) {
return "Bot name must be less than 50 characters";
}
return null;
}
function getAutoCreateBotName(projectName) {
if (!projectName) {
return null;
}
const validationError = validateBotName(projectName);
return validationError ? null : projectName.trim();
}
function findProjectNameExactMatch(bots, projectName) {
if (!projectName) {
return null;
}
const matches = bots.filter((bot) => bot.name.toLowerCase() === projectName.toLowerCase());
return matches.length === 1 ? matches[0] : null;
}
function shouldClearDevIdAfterRelink(previous, next) {
if (!previous?.devId) {
return false;
}
return previous.botId !== next.botId || previous.workspaceId !== next.workspaceId || previous.apiUrl !== next.apiUrl;
}
function resolveLinkApiUrl(options) {
return options.explicitApiUrl || options.projectApiUrl || options.credentialsApiUrl;
}
function getCreateNewBotAction(options) {
const { fromInit, projectName } = options;
const autoCreateBotName = fromInit ? getAutoCreateBotName(projectName) : null;
if (autoCreateBotName) {
return {
type: "auto-create",
botName: autoCreateBotName
};
}
if (fromInit && projectName) {
return {
type: "prompt",
message: `\u26A0\uFE0F Project name "${projectName.trim()}" does not meet bot name requirements. Enter a bot name manually.`
};
}
return {
type: "prompt"
};
}
// src/utils/bot-linking.ts
async function getClient(options = {}) {
const resolvedCredentials = options.credentials ?? await auth.getActiveCredentials();
return new Uk({
token: resolvedCredentials.token,
apiUrl: options.apiUrl || resolvedCredentials.apiUrl,
workspaceId: options.workspaceId || resolvedCredentials.workspaceId,
botId: options.botId || resolvedCredentials.botId,
headers: {
"x-multiple-integrations": "true"
}
});
}
async function getBot(botId, workspaceId, apiUrl, credentials) {
const client = await getClient({ workspaceId, apiUrl, credentials });
let bot;
let resolvedWorkspaceId;
try {
({ bot } = await client.getBot({ id: botId }));
({ workspaceId: resolvedWorkspaceId } = await client.introspect({ botId }));
} catch (error) {
throw new AdkError({
code: "BOT_FETCH_FAILED",
message: `Failed to get bot: ${error instanceof Error ? error.message : String(error)}`,
expected: true,
cause: error
});
}
if (workspaceId && resolvedWorkspaceId !== workspaceId) {
throw new AdkError({
code: "WORKSPACE_MISMATCH",
message: `Bot ${botId} does not belong to workspace ${workspaceId}, it belongs to ${resolvedWorkspaceId}`,
expected: true
});
}
return { ...bot, workspaceId: resolvedWorkspaceId };
}
async function listWorkspaces(apiUrl, credentials) {
const resolvedCredentials = credentials ?? await auth.getActiveCredentials();
const client = new Uk({
token: resolvedCredentials.token,
apiUrl: apiUrl || resolvedCredentials.apiUrl,
headers: {
"x-multiple-integrations": "true"
}
});
try {
return await client.list.workspaces({}).collect();
} catch (error) {
throw new AdkError({
code: "WORKSPACE_LIST_FAILED",
message: `Failed to list workspaces: ${error instanceof Error ? error.message : String(error)}`,
expected: true,
cause: error
});
}
}
async function validateWorkspace(workspaceId, apiUrl, credentials) {
const client = await getClient({ workspaceId, apiUrl, credentials });
try {
return await client.getWorkspace({ id: workspaceId });
} catch (error) {
throw new AdkError({
code: "WORKSPACE_ACCESS_FAILED",
message: `Failed to access workspace: ${error instanceof Error ? error.message : String(error)}`,
expected: true,
cause: error
});
}
}
async function listBots(workspaceId, apiUrl, credentials) {
const client = await getClient({ workspaceId, apiUrl, credentials });
try {
return await client.list.bots({ dev: false }).collect();
} catch (error) {
throw new AdkError({
code: "BOT_LIST_FAILED",
message: `Failed to list bots: ${error instanceof Error ? error.message : String(error)}`,
expected: true,
cause: error
});
}
}
async function createBot(options) {
const client = await getClient({
workspaceId: options.workspaceId,
apiUrl: options.apiUrl,
credentials: options.credentials
});
try {
const { bot } = await client.createBot({
name: options.name.trim(),
...options.dev !== undefined ? { dev: options.dev } : {},
...options.url !== undefined ? { url: options.url } : {},
tags: {
runtime: "adk"
}
});
return bot;
} catch (error) {
throw new AdkError({
code: "BOT_CREATE_FAILED",
message: `Failed to create bot: ${error instanceof Error ? error.message : String(error)}`,
expected: true,
cause: error
});
}
}
async function deleteBot(options) {
const client = await getClient({
workspaceId: options.workspaceId,
apiUrl: options.apiUrl,
credentials: options.credentials
});
try {
await client.deleteBot({ id: options.botId });
} catch (error) {
throw new AdkError({
code: "BOT_DELETE_FAILED",
message: `Failed to delete bot ${options.botId}: ${error instanceof Error ? error.message : String(error)}`,
expected: true,
cause: error
});
}
}
async function writeAgentLink(options) {
const previousAgentInfo = options.project.agentInfo ? { ...options.project.agentInfo } : undefined;
const resolvedCredentials = options.credentials ?? await auth.getActiveCredentials();
const finalApiUrl = resolveLinkApiUrl({
explicitApiUrl: options.apiUrl,
projectApiUrl: previousAgentInfo?.apiUrl,
credentialsApiUrl: resolvedCredentials.apiUrl
});
const clearStaleDevId = !options.local && !options.devBotId && shouldClearDevIdAfterRelink(previousAgentInfo, {
botId: options.botId,
workspaceId: options.workspaceId,
apiUrl: finalApiUrl
});
if (options.local) {
await options.project.createAgentLocalInfo({
botId: options.botId,
workspaceId: options.workspaceId,
apiUrl: finalApiUrl,
...options.devBotId ? { devId: options.devBotId } : {}
});
} else {
const agentInfo = {
botId: options.botId,
workspaceId: options.workspaceId,
apiUrl: finalApiUrl
};
await options.project.createAgentInfo(agentInfo);
const localUpdates = {
botId: undefined,
workspaceId: undefined,
apiUrl: undefined
};
if (options.devBotId) {
localUpdates.devId = options.devBotId;
} else if (clearStaleDevId) {
localUpdates.devId = undefined;
}
await options.project.updateAgentLocalInfo(localUpdates);
}
if ((options.syncConfigName ?? true) && options.botName && options.project.config?.name !== options.botName) {
try {
const configWriter = new ConfigWriter(options.project.path);
await configWriter.updateName(options.botName);
} catch {}
}
return { apiUrl: finalApiUrl };
}
export { validateBotName, findProjectNameExactMatch, getCreateNewBotAction, getClient, getBot, listWorkspaces, validateWorkspace, listBots, createBot, deleteBot, writeAgentLink };