mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-25 17:45:53 +01:00
feat(runner): make evidence a devtools tab
This commit is contained in:
1 parent
827ade0135
commit
641dbd406c
3 files changed
+21
-7
No files matched your search
@@ -238,6 +238,7 @@ test.describe("Capability issue thread", () => {
|
||||
).toBeVisible();
|
||||
await expect(panel.getByText("Agent tool — always")).toBeVisible();
|
||||
await expect(panel.getByText("Agent tool — granted")).toBeVisible();
|
||||
|
||||
});
|
||||
|
||||
test("tool exposure groups are deduplicated, foldable, and open catalog details", async ({ page }) => {
|
||||
@@ -716,6 +717,16 @@ test.describe("Capability clean-room chat", () => {
|
||||
});
|
||||
await openCleanRoom(page);
|
||||
await page.getByTestId("evidence-toggle").click();
|
||||
const panel = page.getByTestId("evidence-panel");
|
||||
const tabs = panel.getByRole("tab");
|
||||
await expect(tabs.first()).toHaveText(/Evidence/);
|
||||
await expect(tabs.nth(1)).toHaveText(/Timeline/);
|
||||
await expect(tabs.first()).toHaveAttribute("aria-selected", "true");
|
||||
await expect(panel.locator("#evidence-turn-selector")).toBeVisible();
|
||||
await panel.getByRole("tab", { name: /Timeline/ }).click();
|
||||
await expect(panel.locator("#evidence-turn-selector")).toHaveCount(0);
|
||||
await panel.getByRole("tab", { name: /Evidence/ }).click();
|
||||
await expect(panel.locator("#evidence-turn-selector")).toBeVisible();
|
||||
await page.getByRole("tab", { name: /Documents/ }).click();
|
||||
await expect(page.getByRole("heading", { name: "Runner plan" })).toBeVisible();
|
||||
await expect(page.getByText("Inspectable from DevTools.")).toBeVisible();
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useEffect, useMemo, useState } from "react";
|
||||
import type { CapabilityDevtoolsSnapshot } from "../../../src/devtools";
|
||||
import { Icon } from "./Icons";
|
||||
|
||||
type Tab = "timeline" | "state" | "diff" | "documents" | "protocol" | "runtime" | "authority";
|
||||
export type CapabilityDevtoolsTab = "evidence" | "timeline" | "state" | "diff" | "documents" | "protocol" | "runtime" | "authority";
|
||||
type Json = null | boolean | number | string | Json[] | { [key: string]: Json };
|
||||
|
||||
function JsonTree({ value, name = "root" }: { value: Json; name?: string }) {
|
||||
@@ -55,7 +55,8 @@ function download(snapshot: CapabilityDevtoolsSnapshot) {
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
const TABS: ReadonlyArray<{ id: Tab; glyph: string; label: string }> = [
|
||||
const TABS: ReadonlyArray<{ id: CapabilityDevtoolsTab; glyph: string; label: string }> = [
|
||||
{ id: "evidence", glyph: "◎", label: "Evidence" },
|
||||
{ id: "timeline", glyph: "◫", label: "Timeline" },
|
||||
{ id: "state", glyph: "{}", label: "State" },
|
||||
{ id: "diff", glyph: "±", label: "Diff" },
|
||||
@@ -85,8 +86,7 @@ function documentsOf(state: Json): Array<{ id: string; key: string; title: strin
|
||||
});
|
||||
}
|
||||
|
||||
export function DevtoolsInspector({ snapshot, onFork }: { snapshot: CapabilityDevtoolsSnapshot; onFork: (revision: number) => void }) {
|
||||
const [tab, setTab] = useState<Tab>("timeline");
|
||||
export function DevtoolsInspector({ snapshot, onFork, tab, onTabChange }: { snapshot: CapabilityDevtoolsSnapshot; onFork: (revision: number) => void; tab: CapabilityDevtoolsTab; onTabChange: (tab: CapabilityDevtoolsTab) => void }) {
|
||||
const [query, setQuery] = useState("");
|
||||
const latest = snapshot.revisions.at(-1)!;
|
||||
const [revision, setRevision] = useState(latest.revision);
|
||||
@@ -125,7 +125,7 @@ export function DevtoolsInspector({ snapshot, onFork }: { snapshot: CapabilityDe
|
||||
</div>
|
||||
<div className="pit-devtools-tabs" role="tablist" aria-label="Developer tools">
|
||||
{TABS.map(({ id, glyph, label }) => (
|
||||
<button key={id} type="button" role="tab" aria-selected={tab === id} className="pit-tab" onClick={() => setTab(id)}><span className="pit-tab-glyph" aria-hidden="true">{glyph}</span>{label}</button>
|
||||
<button key={id} type="button" role="tab" aria-selected={tab === id} className="pit-tab" onClick={() => onTabChange(id)}><span className="pit-tab-glyph" aria-hidden="true">{glyph}</span>{label}</button>
|
||||
))}
|
||||
</div>
|
||||
{tab === "timeline" ? (
|
||||
|
||||
@@ -9,7 +9,7 @@ import type {
|
||||
CapabilityToolDisposition,
|
||||
} from "../../../src/issue-thread/types";
|
||||
import type { CapabilityDevtoolsSnapshot } from "../../../src/devtools";
|
||||
import { DevtoolsInspector } from "./DevtoolsInspector";
|
||||
import { DevtoolsInspector, type CapabilityDevtoolsTab } from "./DevtoolsInspector";
|
||||
import { Icon } from "./Icons";
|
||||
import { capabilitySemanticToolDescriptor } from "../../../src/semantic-tools/catalog";
|
||||
import {
|
||||
@@ -271,6 +271,7 @@ function Section({
|
||||
}
|
||||
|
||||
export function EvidencePanel(props: EvidencePanelProps) {
|
||||
const [devtoolsTab, setDevtoolsTab] = useState<CapabilityDevtoolsTab>("evidence");
|
||||
const {
|
||||
snapshot,
|
||||
devtools,
|
||||
@@ -331,11 +332,12 @@ export function EvidencePanel(props: EvidencePanelProps) {
|
||||
{devtools === null ? (
|
||||
<p className="pit-muted pit-devtools-loading">Loading company state…</p>
|
||||
) : (
|
||||
<DevtoolsInspector snapshot={devtools} onFork={onForkRevision} />
|
||||
<DevtoolsInspector snapshot={devtools} onFork={onForkRevision} tab={devtoolsTab} onTabChange={setDevtoolsTab} />
|
||||
)}
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{devtoolsTab === "evidence" ? <div className="pit-evidence-browser">
|
||||
<div className="pit-evidence-filter">
|
||||
<label className="pit-card-meta" htmlFor="evidence-turn-selector">Evidence scope</label>
|
||||
<select className="pit-select" id="evidence-turn-selector" value={selectedTurnId} onChange={(event) => onSelectTurn(event.target.value as string | "all")}>
|
||||
@@ -548,6 +550,7 @@ export function EvidencePanel(props: EvidencePanelProps) {
|
||||
</div>
|
||||
))}
|
||||
</Section>
|
||||
</div> : null}
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user