AkurAI Build
Menu

popagent

public

Latest 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());