Menu
popagent
publicLatest change 7cecf6a89b6f39dae8c5678f5b369014199aeb3c - Add self-hosted Mastra observability by AkurAI Build
import { Agent } from "@mastra/core/agent";
import type { RequestContext } from "@mastra/core/request-context";
import { Mastra } from "@mastra/core/mastra";
import {
createFinalResponseGuard,
specialistExecutionOptions,
toolCallConcurrency,
} from "./agent-autonomy";
import { AGENT_CONTEXT_KEYS, agentContextValue } from "./agent-context";
import { agentRuntimeSettings } from "./agent-runtime-settings";
import { agentSettings } from "./agent-settings";
import { agentSkills } from "./agent-skills";
import type { AgentRuntimeSettings, AgentSettings } from "./api-types";
import { resolveModel } from "./models";
import { logger, observability, setAppLogger } from "./observability";
import { memory, storage } from "./storage";
import { getTime } from "./tools/get-time";
import { remember } from "./tools/remember";
import { recallSecret, storeSecret, updateSecret } from "./tools/secrets";
import { webSearch } from "./tools/web-search";
import { agentWorkspaceRuntime } from "./workspace";
async function requiredAgentProfile(id: string): Promise<AgentSettings> {
const settings = await agentSettings.get(id);
if (!settings) throw new Error(`Agent settings not found: ${id}`);
return settings;
}
function renderedInstructions(settings: AgentSettings): string {
const instructions = settings.instructions.trim();
if (!instructions) throw new Error(`Agent instructions are empty: ${settings.id}`);
return `Display identity: ${settings.name.trim()}.\n\n${instructions}`;
}
async function configuredRuntime(
requestContext: RequestContext | undefined,
): Promise<AgentRuntimeSettings> {
return agentContextValue(requestContext, AGENT_CONTEXT_KEYS.runtimeSettings)
?? agentRuntimeSettings.get();
}
const modelForContext = async (
{ requestContext }: { requestContext: RequestContext },
) => {
const selected = agentContextValue(requestContext, AGENT_CONTEXT_KEYS.model);
const settings = selected ? undefined : await configuredRuntime(requestContext);
return resolveModel(selected ?? settings!.defaultModel);
};
const sharedSubagentOptions = {
model: modelForContext,
defaultOptions: specialistExecutionOptions,
};
const toolRegistry = {
getTime,
remember,
storeSecret,
recallSecret,
updateSecret,
webSearch,
};
async function configuredTools(id: string) {
const profile = await requiredAgentProfile(id);
return Object.fromEntries(
profile.tools.map((tool) => [tool, toolRegistry[tool]]),
) as Partial<typeof toolRegistry>;
}
const workspaceFor = (id: string) =>
async ({ requestContext }: { requestContext: RequestContext }) => {
const profile = await requiredAgentProfile(id);
if (profile.workspaceAccess === "none") return undefined;
const selectedWorkspace = agentContextValue(requestContext, AGENT_CONTEXT_KEYS.workspaceId);
return agentWorkspaceRuntime.resolve(
selectedWorkspace,
profile.workspaceAccess === "read-only",
);
};
let [supervisorProfile, researcherProfile, implementerProfile, reviewerProfile] = await Promise.all([
requiredAgentProfile("popagent"),
requiredAgentProfile("researcher"),
requiredAgentProfile("implementer"),
requiredAgentProfile("reviewer"),
]);
let researcherAgent: Agent;
researcherAgent = new Agent({
id: "researcher",
name: researcherProfile.name,
description: researcherProfile.description,
instructions: async () => {
researcherProfile = await requiredAgentProfile("researcher");
researcherAgent.name = researcherProfile.name;
return renderedInstructions(researcherProfile);
},
tools: () => configuredTools("researcher"),
skills: () => agentSkills.resolve("researcher"),
workspace: workspaceFor("researcher"),
...sharedSubagentOptions,
});
researcherAgent.getDescription = () => researcherProfile.description;
let implementerAgent: Agent;
implementerAgent = new Agent({
id: "implementer",
name: implementerProfile.name,
description: implementerProfile.description,
instructions: async () => {
implementerProfile = await requiredAgentProfile("implementer");
implementerAgent.name = implementerProfile.name;
return renderedInstructions(implementerProfile);
},
tools: () => configuredTools("implementer"),
skills: () => agentSkills.resolve("implementer"),
workspace: workspaceFor("implementer"),
...sharedSubagentOptions,
});
implementerAgent.getDescription = () => implementerProfile.description;
let reviewerAgent: Agent;
reviewerAgent = new Agent({
id: "reviewer",
name: reviewerProfile.name,
description: reviewerProfile.description,
instructions: async () => {
reviewerProfile = await requiredAgentProfile("reviewer");
reviewerAgent.name = reviewerProfile.name;
return renderedInstructions(reviewerProfile);
},
tools: () => configuredTools("reviewer"),
skills: () => agentSkills.resolve("reviewer"),
workspace: workspaceFor("reviewer"),
...sharedSubagentOptions,
});
reviewerAgent.getDescription = () => reviewerProfile.description;
const specialistAgents = {
researcher: researcherAgent,
implementer: implementerAgent,
reviewer: reviewerAgent,
};
async function refreshSpecialistProfiles() {
[researcherProfile, implementerProfile, reviewerProfile] = await Promise.all([
requiredAgentProfile("researcher"),
requiredAgentProfile("implementer"),
requiredAgentProfile("reviewer"),
]);
researcherAgent.name = researcherProfile.name;
implementerAgent.name = implementerProfile.name;
reviewerAgent.name = reviewerProfile.name;
return Object.fromEntries(
Object.entries(specialistAgents).filter(([id]) => {
if (id === "researcher") return researcherProfile.delegationEnabled;
if (id === "implementer") return implementerProfile.delegationEnabled;
return reviewerProfile.delegationEnabled;
}),
) as typeof specialistAgents;
}
let supervisorAgent: Agent;
supervisorAgent = new Agent({
id: "popagent",
name: supervisorProfile.name,
description: supervisorProfile.description,
instructions: async () => {
supervisorProfile = await requiredAgentProfile("popagent");
supervisorAgent.name = supervisorProfile.name;
return renderedInstructions(supervisorProfile);
},
model: modelForContext,
defaultOptions: async ({ requestContext }) => {
const settings = await configuredRuntime(requestContext);
return {
maxSteps: settings.supervisorMaxSteps,
toolCallConcurrency: toolCallConcurrency(settings),
onIterationComplete: createFinalResponseGuard(settings),
};
},
tools: () => configuredTools("popagent"),
memory,
workspace: workspaceFor("popagent"),
skills: () => agentSkills.resolve("popagent"),
agents: refreshSpecialistProfiles,
});
supervisorAgent.getDescription = () => supervisorProfile.description;
export const agent = supervisorAgent;
export const mastra = new Mastra({
agents: { popagent: agent },
storage,
logger,
observability,
environment: process.env.POPAGENT_ENVIRONMENT ?? process.env.NODE_ENV,
});
setAppLogger(mastra.getLogger());