Ctrl K
ComunidadGuías…

e2e/issue-task-history.spec.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { test, expect } from "@playwright/test";
import pg from "pg";
import { createTestApi } from "./helpers";

test("issue loads compact runs until Runs requests full own or subtree history", async ({ page }) => {
  const api = await createTestApi();
  const db = new pg.Client(process.env.DATABASE_URL);
  await db.connect();
  let runtimeId = "";
  let agentId = "";
  try {
    const workspace = (await api.getWorkspaces())[0]!;
    const userId = (await db.query('SELECT id FROM "user" WHERE email=$1', [api.getEmail()])).rows[0].id;
    const issue = await api.createIssue("On-demand run history");
    const child = await api.createIssue("Child run history", { parent_issue_id: issue.id });

    // Seed finished runs without dispatching any work to a real runtime.
    runtimeId = (await db.query(`
      INSERT INTO agent_runtime (workspace_id,name,runtime_mode,provider,status,device_info,metadata,owner_id)
      VALUES ($1,'History test runtime','cloud','test','offline','Test','{}',$2) RETURNING id
    `, [workspace.id, userId])).rows[0].id;
    agentId = (await db.query(`
      INSERT INTO agent (workspace_id,name,description,instructions,runtime_mode,runtime_config,runtime_id,visibility,permission_mode,max_concurrent_tasks,owner_id)
      VALUES ($1,'History test agent','','','cloud','{}',$2,'private','private',1,$3) RETURNING id
    `, [workspace.id, runtimeId, userId])).rows[0].id;
    for (const issueId of [issue.id, child.id]) {
      await db.query(`
        INSERT INTO agent_task_queue (agent_id,runtime_id,issue_id,status,result,handoff_note,started_at,completed_at)
        VALUES ($1,$2,$3,'completed',$4,'Full handoff details',now()-interval '1 minute',now())
      `, [agentId, runtimeId, issueId, JSON.stringify({
        comment: "Inline run summary",
        output: `Full provider output for ${issueId}`,
        session_id: "history-test-session",
      })]);
    }

    await page.setViewportSize({ width: 1440, height: 900 });
    await page.addInitScript((token) => {
      localStorage.setItem("multica_token", token!);
      localStorage.setItem("multica:chat:isOpen", "false");
    }, api.getToken());
    const isIssueTasks = (url: URL) => url.pathname.endsWith(`/issues/${issue.id}/task-runs`);
    const requests: URL[] = [];
    page.on("request", (request) => {
      const url = new URL(request.url());
      if (isIssueTasks(url)) requests.push(url);
    });
    const compactResponse = page.waitForResponse((response) => {
      const url = new URL(response.url());
      return isIssueTasks(url) && url.searchParams.get("view") === "timeline";
    });
    await page.goto(`/${workspace.slug}/issues/${issue.id}`);
    const compact = await (await compactResponse).json();
    expect(compact).toHaveLength(1);
    expect(compact[0].result).toEqual({ comment: "Inline run summary" });
    expect(compact[0].handoff_note).toBeFalsy();
    const openRuns = page.getByRole("button", { name: /^Open timeline/ });
    await expect(openRuns).toBeVisible();
    expect(requests.length).toBeGreaterThan(0);
    expect(requests.every((url) => url.searchParams.get("view") === "timeline")).toBe(true);

    const ownHistory = page.waitForResponse((response) => {
      const url = new URL(response.url());
      return isIssueTasks(url) && !url.searchParams.has("view") && !url.searchParams.has("scope");
    });
    await openRuns.click();
    const own = await (await ownHistory).json();
    expect(own).toHaveLength(1);
    expect(own[0].result.output).toBe(`Full provider output for ${issue.id}`);
    expect(own[0].handoff_note).toBe("Full handoff details");

    const subtreeHistory = page.waitForResponse((response) => {
      const url = new URL(response.url());
      return isIssueTasks(url) && !url.searchParams.has("view") && url.searchParams.get("scope") === "subtree";
    });
    const includeChildren = page.getByRole("dialog").getByRole("checkbox", { name: "Include sub-issues" });
    await includeChildren.check();
    const subtree = await (await subtreeHistory).json();
    expect(subtree).toHaveLength(2);
    expect(subtree.map((task: { result: { output: string } }) => task.result.output).sort()).toEqual(
      [issue.id, child.id].map((id) => `Full provider output for ${id}`).sort(),
    );
    expect(subtree.every((task: { handoff_note: string }) => task.handoff_note === "Full handoff details")).toBe(true);
    await expect(includeChildren).toBeChecked();
  } finally {
    await api.cleanup();
    if (agentId) await db.query("DELETE FROM agent_task_queue WHERE agent_id=$1", [agentId]);
    if (agentId) await db.query("DELETE FROM agent WHERE id=$1", [agentId]);
    if (runtimeId) await db.query("DELETE FROM agent_runtime WHERE id=$1", [runtimeId]);
    await db.end();
  }
});