AkurAI Build
Menu

popagent

public

Latest change ec66504a301a4150cf6cd2203554901a84fdc769 - Complete repository brief integration and CI deployment by AkurAI Build

import { describe, expect, test } from "bun:test";
import { AGENT_CONTEXT_KEYS, agentContextValue, createAgentRequestContext } from "./agent-context";
import type { RequestContext } from "@mastra/core/request-context";
import { createWorkspaceTools } from "@mastra/core/workspace";
import { agent } from "./agent";
import { resolveModel } from "./models";
import { agentSettings } from "./agent-settings";
import { agentRuntimeSettings } from "./agent-runtime-settings";
import { agentSkills } from "./agent-skills";

describe("agent", () => {
  test("uses the configured orchestrator model", async () => {
    const runtime = await agentRuntimeSettings.get();
    const model = await agent.getModel();
    expect(model.modelId).toBe(runtime.defaultModel);
  });

  test("exposes native memory and destination-bound secret tools", async () => {
    const names = Object.keys(await agent.listTools());
    expect(names).toEqual(expect.arrayContaining([
      "retainMemory",
      "recallMemory",
      "reflectMemory",
      "editMemory",
      "useBrowserSecret",
      "bifrostNavigator",
      "repoBrief",
    ]));
    expect(names).not.toEqual(expect.arrayContaining([
      "remember",
      "storeSecret",
      "recallSecret",
      "updateSecret",
    ]));
  });

  test("removes memory and credential tools for trusted self-update execution", async () => {
    const requestContext = createAgentRequestContext({
      resourceId: "popagent-user",
      sessionId: "task:self-update",
      turnId: "turn-self-update",
      model: (await agentRuntimeSettings.get()).defaultModel,
      workspaceId: "default",
      executionSource: "self-update",
      taskId: "self-update-task",
      selfUpdateWorkspacePath: `${process.env.POPAGENT_DATA_DIR ?? `${process.cwd()}/data`}/self-update/test`,
    });
    const names = Object.keys(await agent.listTools({ requestContext: requestContext as unknown as RequestContext }));
    expect(names).not.toContain("retainMemory");
    expect(names).not.toContain("editMemory");
    expect(names).not.toContain("useBrowserSecret");
    expect(names).not.toContain("bifrostNavigator");
    expect(names).toContain("recallMemory");
    expect(names).toContain("reflectMemory");
  });

  test("constrains specialist workspace capabilities by role", async () => {
    const delegated = await agent.listAgents();
    expect(Object.keys(delegated)).toEqual(["researcher", "implementer", "reviewer"]);
    const specialists = {
      researcher: delegated.researcher! as unknown as typeof agent,
      implementer: delegated.implementer! as unknown as typeof agent,
      reviewer: delegated.reviewer! as unknown as typeof agent,
    };

    const supervisorWorkspace = await agent.getWorkspace();
    expect(supervisorWorkspace?.lsp).toBeDefined();
    expect(await specialists.implementer.getWorkspace()).toBe(supervisorWorkspace);
    for (const id of ["researcher", "reviewer"] as const) {
      const workspace = await specialists[id].getWorkspace();
      expect(workspace).not.toBe(supervisorWorkspace);
      expect(workspace?.lsp).toBeDefined();
      const tools = Object.keys(await createWorkspaceTools(workspace!));
      expect(tools).toEqual(expect.arrayContaining([
        "mastra_workspace_read_file",
        "mastra_workspace_list_files",
        "mastra_workspace_grep",
        "mastra_workspace_lsp_inspect",
      ]));
      expect(tools).not.toEqual(expect.arrayContaining([
        "mastra_workspace_write_file",
        "mastra_workspace_edit_file",
        "mastra_workspace_delete",
        "mastra_workspace_execute_command",
      ]));
    }

    const implementerWorkspace = await specialists.implementer.getWorkspace();
    const implementerTools = Object.keys(await createWorkspaceTools(implementerWorkspace!));
    expect(implementerTools).toEqual(expect.arrayContaining([
      "mastra_workspace_write_file",
      "mastra_workspace_edit_file",
      "mastra_workspace_lsp_inspect",
      "mastra_workspace_execute_command",
    ]));
    const runtime = await agentRuntimeSettings.get();
    for (const specialist of Object.values(specialists)) {
      expect((await specialist.getDefaultOptions()).maxSteps).toBe(runtime.specialistMaxSteps);
      expect((await specialist.getDefaultOptions()).toolCallConcurrency)
        .toEqual({ limit: runtime.toolConcurrency, strategy: "called" });
    }
  });

  test("withholds researcher when deterministic evidence is implementation-ready", async () => {
    const requestContext = createAgentRequestContext({
      resourceId: "popagent-user",
      sessionId: "brief-session",
      turnId: "brief-turn",
      model: (await agentRuntimeSettings.get()).defaultModel,
      repositoryBriefReady: true,
    });

    const delegated = await agent.listAgents({ requestContext: requestContext as unknown as RequestContext });

    expect(delegated.researcher).toBeUndefined();
    expect(delegated.implementer).toBeDefined();
    expect(delegated.reviewer).toBeDefined();
  });

  test("persists delegated messages with isolated thread identity", async () => {
    const requestContext = createAgentRequestContext({
      resourceId: "popagent-user",
      sessionId: "delegation-persistence",
      turnId: "delegation-persistence-turn",
      model: "cx/gpt-5.3-codex-spark",
    });
    const tools = await (agent as unknown as { listAgentTools: (input: Record<string, unknown>) => Promise<Record<string, { execute?: (input: unknown, context: unknown) => Promise<{ text: string }> }>> }).listAgentTools({
      requestContext: requestContext as RequestContext,
      methodType: "stream",
      threadId: "delegation-persistence",
      resourceId: "popagent-user",
    });
    const researcher = tools["agent-researcher"];
    expect(researcher).toBeDefined();
    const result = await researcher!.execute!({ prompt: "Reply with exactly: delegated" }, {
      abortSignal: AbortSignal.timeout(30_000),
      messages: [],
      toolCallId: "delegation-persistence-tool",
      writer: { write: async () => {} },
    } as never);
    expect(result.text).toContain("delegated");
  });
  test("bounds supervisor tool loops from persisted runtime settings", async () => {
    const runtime = await agentRuntimeSettings.get();
    expect((await agent.getDefaultOptions()).maxSteps).toBe(runtime.supervisorMaxSteps);
    expect((await agent.getDefaultOptions()).toolCallConcurrency)
      .toEqual({ limit: runtime.toolConcurrency, strategy: "called" });
  });

  test("routes role-specific models into specialist runs", async () => {
    const specialists = await agent.listAgents();
    const requestContext = createAgentRequestContext({
      resourceId: "popagent-user",
      sessionId: "session-1",
      turnId: "turn-1",
      model: "cx/gpt-5.6-sol",
    });
    expect(agentContextValue(requestContext, AGENT_CONTEXT_KEYS.model)).toBe("cx/gpt-5.6-sol");
    expect((await agent.getModel({ requestContext: requestContext as RequestContext })).modelId)
      .toBe("cx/gpt-5.6-sol");
    expect((await (specialists.researcher as unknown as typeof agent).getModel({
      requestContext: requestContext as RequestContext,
    })).modelId).toBe("cx/gpt-5.3-codex-spark");
    expect((await (specialists.implementer as unknown as typeof agent).getModel({
      requestContext: requestContext as RequestContext,
    })).modelId).toBe("cx/gpt-5.6-sol");
    expect((await (specialists.reviewer as unknown as typeof agent).getModel({
      requestContext: requestContext as RequestContext,
    })).modelId).toBe("cx/gpt-5.3-codex-spark");
  });

  test("applies persisted specialist capabilities on the next resolution", async () => {
    const implementer = (await agent.listAgents()).implementer! as unknown as typeof agent;
    const original = await agentSettings.get("implementer");
    if (!original) throw new Error("implementer settings missing");
    try {
      await agentSettings.update("implementer", {
        ...original,
        workspaceAccess: "none",
        browserAccess: "none",
        delegationEnabled: false,
        tools: ["getTime"],
      });
      expect(Object.keys(await implementer.listTools())).toContain("getTime");
      expect(Object.keys(await implementer.listTools())).not.toContain("webSearch");
      expect(await implementer.getWorkspace()).toBeUndefined();
      expect((await agent.listAgents()).implementer).toBeUndefined();
    } finally {
      await agentSettings.update("implementer", original);
      await agent.listAgents();
    }
  });

  test("loads specialist instructions entirely from the database", async () => {
    const researcher = (await agent.listAgents()).researcher!;
    const original = await agentSettings.get("researcher");
    if (!original) throw new Error("researcher settings missing");
    const custom = `# Role: Database Researcher\n\nPrefer primary sources ${crypto.randomUUID()}`;
    try {
      await agentSettings.update("researcher", { ...original, instructions: custom });
      expect(await researcher.getInstructions()).toBe(
        `Display identity: ${original.name}.\n\n${custom}`,
      );
    } finally {
      await agentSettings.update("researcher", original);
    }
  });

  test("applies persisted specialist display identity and delegation description at runtime", async () => {
    const researcher = (await agent.listAgents()).researcher!;
    const original = await agentSettings.get("researcher");
    if (!original) throw new Error("researcher settings missing");
    const customName = `Source Analyst ${crypto.randomUUID().slice(0, 8)}`;
    const customDescription = `Delegated source analysis ${crypto.randomUUID().slice(0, 8)}`;
    try {
      await agentSettings.update("researcher", {
        ...original,
        name: customName,
        description: customDescription,
      });
      expect(await researcher.getInstructions()).toContain(`Display identity: ${customName}.`);
      expect(researcher.getDescription()).toBe(customDescription);
    } finally {
      await agentSettings.update("researcher", original);
      await agent.listAgents();
    }
  });

  test("resolves persisted skills for specialist agents", async () => {
    const researcher = (await agent.listAgents()).researcher!;
    expect((await (researcher as unknown as typeof agent).listSkills()).map((item) => item.name))
      .toContain("codebase-investigation");
    const name = `research-sources-${crypto.randomUUID().slice(0, 8)}`;
    const skill = await agentSkills.create("researcher", {
      name,
      description: "Use for source-sensitive research.",
      instructions: "Prefer primary sources and report URLs.",
      references: {},
      enabled: true,
      userInvocable: false,
    });
    try {
      expect((await (researcher as unknown as typeof agent).listSkills()).map((item) => item.name)).toContain(name);
    } finally {
      await agentSkills.delete("researcher", skill.id);
    }
  });

  test("loads supervisor instructions and provenance from the database", async () => {
    const stored = await agentSettings.get("orchistrator");
    expect(stored?.sourceUrls).toEqual(
      expect.arrayContaining([expect.stringContaining("engineering-multi-agent-systems-architect.md")]),
    );
    expect(await agent.getInstructions()).toContain(stored!.instructions);
  });

  test("streams through 9router with the default model", async () => {
    const out = await agent.stream("Reply with exactly the word: pong");
    expect((await out.text).toLowerCase()).toContain("pong");
  }, 60000);
  test("answers with a per-call model override", async () => {
    const out = await agent.stream("Reply with exactly the word: pong", {
      model: resolveModel("cx/gpt-5.3-codex-spark"),
    });
    expect((await out.text).toLowerCase()).toContain("pong");
  }, 60000);
});