Menu
popagent
publicLatest change 6edc7e928c57dab23c0973ed3f7ee70b3ebb72d5 - Initial popagent baseline by AkurAI Build
import { storage } from "./storage";
import {
AGENT_TOOL_NAMES,
MAX_AGENT_INSTRUCTIONS_CHARACTERS,
type AgentSettings,
type AgentSettingsInput,
} from "./api-types";
import { retryableInit } from "./retryable-init";
const AGENT_SETTINGS_COLUMNS = `id, name, description, instructions,
workspace_access AS "workspaceAccess", browser_access AS "browserAccess",
delegation_enabled AS "delegationEnabled",
tools, source_urls AS "sourceUrls",
created_at::text AS "createdAt", updated_at::text AS "updatedAt"`;
const AGENT_TOOL_NAME_SET = new Set<string>(AGENT_TOOL_NAMES);
const initializeAgentRoleStorageOnce = retryableInit(async () => {
await storage.init();
const seed = await Bun.file(new URL("./agent-role-seed.sql", import.meta.url)).text();
await storage.db.none(seed);
});
export function initializeAgentRoleStorage(): Promise<void> {
return initializeAgentRoleStorageOnce();
}
export class AgentSettingsStore {
readonly storage = storage;
init(): Promise<void> {
return initializeAgentRoleStorage();
}
async list(): Promise<AgentSettings[]> {
await this.init();
return this.storage.db.any<AgentSettings>(`
SELECT ${AGENT_SETTINGS_COLUMNS}
FROM popagent_agents ORDER BY name
`);
}
async get(id: string): Promise<AgentSettings | undefined> {
await this.init();
return (await this.storage.db.oneOrNone<AgentSettings>(`
SELECT ${AGENT_SETTINGS_COLUMNS}
FROM popagent_agents WHERE id = $1
`, [id])) ?? undefined;
}
async update(id: string, input: AgentSettingsInput): Promise<AgentSettings | undefined> {
if (input.instructions.length > MAX_AGENT_INSTRUCTIONS_CHARACTERS) {
throw new RangeError(`Agent instructions exceed ${MAX_AGENT_INSTRUCTIONS_CHARACTERS} characters`);
}
if (!input.name.trim() || !input.description.trim() || !input.instructions.trim()) {
throw new RangeError("Agent name, description, and instructions must not be empty");
}
if (
input.tools.some((tool) => !AGENT_TOOL_NAME_SET.has(tool))
|| new Set(input.tools).size !== input.tools.length
) {
throw new RangeError("Agent tools contain an unsupported or duplicate tool");
}
return (await this.storage.db.oneOrNone<AgentSettings>(`
UPDATE popagent_agents
SET name = $2,
description = $3,
instructions = $4,
workspace_access = $5,
browser_access = $6,
delegation_enabled = $7,
tools = $8::jsonb
WHERE id = $1
RETURNING ${AGENT_SETTINGS_COLUMNS}
`, [
id,
input.name.trim(),
input.description.trim(),
input.instructions,
input.workspaceAccess,
input.browserAccess,
input.delegationEnabled,
JSON.stringify(input.tools),
])) ?? undefined;
}
}
export const agentSettings = new AgentSettingsStore();