diff --git a/maps/feature-map/runs-adapters.md b/maps/feature-map/runs-adapters.md
index 1767da493b0..ef9b83201dc 100644
--- a/maps/feature-map/runs-adapters.md
+++ b/maps/feature-map/runs-adapters.md
@@ -28,6 +28,9 @@ Open an agent’s model/adapter configuration or the instance adapter settings p
### `run-history`
Open an agent run at `/agents/:agentId/runs/:runId` from the agent or task activity.
+The agent header has one Run now action. Administrators can enable
+Capture raw provider traces under the agent configuration’s Debugging section
+for future runs. The header shows Raw tracing on while that setting is enabled.
For latency diagnosis with an operator OTLP endpoint, search the hashed run ID
without restricting the root span name. Compare workspace preparation with its
diff --git a/ui/src/components/AgentActionButtons.test.tsx b/ui/src/components/AgentActionButtons.test.tsx
index 08648570fb9..1177ccb02d1 100644
--- a/ui/src/components/AgentActionButtons.test.tsx
+++ b/ui/src/components/AgentActionButtons.test.tsx
@@ -212,23 +212,20 @@ describe("AgentActionButtons", () => {
expect(container.textContent).not.toContain("Clear error");
});
- it("starts an administrator-selected run with raw provider tracing", async () => {
- render(makeAgent(), { canRunWithProviderTrace: true });
+ it.each([false, true])("keeps the normal run action when persistent tracing is %s", async tracingEnabled => {
+ render(makeAgent({ runtimeConfig: tracingEnabled ? { debug: { providerTrace: "raw" } } : {} }));
await flushReact();
- const traceButton = Array.from(container.querySelectorAll("button")).find(
- (button) => button.textContent?.includes("Run with provider trace"),
- );
- expect(traceButton).toBeTruthy();
+ const buttons = Array.from(container.querySelectorAll("button"));
+ expect(buttons.some(button => button.textContent?.includes("Run with provider trace"))).toBe(false);
+ expect(container.textContent?.includes("Raw tracing on")).toBe(tracingEnabled);
await act(async () => {
- traceButton?.click();
+ buttons.find(button => button.textContent === "Run Heartbeat")!.click();
});
await flushReact();
- expect(mockAgentsApi.invoke).toHaveBeenCalledWith("agent-1", "company-1", {
- debug: { providerTrace: "raw" },
- });
+ expect(mockAgentsApi.invoke).toHaveBeenCalledExactlyOnceWith("agent-1", "company-1");
expect(mockNavigate).toHaveBeenCalledWith("/agents/alpha/runs/run-1");
});
diff --git a/ui/src/components/AgentActionButtons.tsx b/ui/src/components/AgentActionButtons.tsx
index f9498d9a23f..6ee48a346e7 100644
--- a/ui/src/components/AgentActionButtons.tsx
+++ b/ui/src/components/AgentActionButtons.tsx
@@ -167,7 +167,6 @@ export function AgentActionButtons({
workActionsDisabled = false,
workActionsDisabledReason,
navigateToRunOnInvoke = true,
- canRunWithProviderTrace = false,
hasPendingNavigationChanges = false,
onBeforeNavigate,
onActionError,
@@ -188,8 +187,6 @@ export function AgentActionButtons({
workActionsDisabled?: boolean;
workActionsDisabledReason?: string;
navigateToRunOnInvoke?: boolean;
- /** Instance administrators may opt one manual run into short-lived raw provider capture. */
- canRunWithProviderTrace?: boolean;
/** Whether the caller currently has an unsaved draft that navigation would discard. */
hasPendingNavigationChanges?: boolean;
/** Return false to stop an action whose success would navigate away. */
@@ -297,24 +294,6 @@ export function AgentActionButtons({
},
});
- const providerTraceAction = useMutation({
- mutationFn: () =>
- agentsApi.invoke(agent.id, resolvedCompanyId ?? undefined, {
- debug: { providerTrace: "raw" },
- }),
- onSuccess: (run) => {
- onActionError?.(null);
- invalidateAgent();
- if (navigateToRunOnInvoke) {
- if (!confirmLateNavigationChanges(agentActionStartedDirtyRef)) return;
- navigate(`/agents/${canonicalAgentRef}/runs/${run.id}`);
- }
- },
- onError: (err) => {
- reportError(err instanceof Error ? err.message : "Failed to start traced run");
- },
- });
-
const duplicateAgent = useMutation({
mutationFn: async () => {
if (!resolvedCompanyId) {
@@ -370,7 +349,7 @@ export function AgentActionButtons({
});
const isPendingApproval = agent.status === "pending_approval";
- const disabled = actionsDisabled || agentAction.isPending || providerTraceAction.isPending;
+ const disabled = actionsDisabled || agentAction.isPending;
const assignAndRunDisabled = disabled || isPendingApproval || workActionsDisabled || agent.status === "terminated";
const pauseResumeDisabled = disabled || isPendingApproval || (isPaused && workActionsDisabled)
|| Boolean(agent.lifecycleState && ["pausing", "terminating", "cleaning_up", "terminated", "rejected"].includes(agent.lifecycleState));
@@ -412,21 +391,6 @@ export function AgentActionButtons({
label={runLabel}
size={size}
/>}
- {canRunWithProviderTrace && (
-
- )}
{isError ? (
agentAction.mutate("clear_error")}
diff --git a/ui/src/pages/AgentDetail.accounting.test.tsx b/ui/src/pages/AgentDetail.accounting.test.tsx
index 6a443bbc9ed..68becbc2666 100644
--- a/ui/src/pages/AgentDetail.accounting.test.tsx
+++ b/ui/src/pages/AgentDetail.accounting.test.tsx
@@ -5,7 +5,7 @@ import { AgentActionButtons } from "../components/AgentActionButtons";
import type { Agent, HeartbeatRun } from "@paperclipai/shared";
import { describe, expect, it, vi } from "vitest";
import { RunAccountingMetrics } from "./AgentDetail";
-import { hasUnavailableProviderAccounting, supportsRawProviderTrace } from "../lib/utils";
+import { hasUnavailableProviderAccounting } from "../lib/utils";
vi.mock("@/lib/router", () => ({ useNavigate: () => vi.fn() }));
vi.mock("../context/DialogContext", () => ({ useDialogActions: () => ({ openNewIssue: vi.fn() }) }));
@@ -41,7 +41,7 @@ describe("run accounting provenance", () => {
describe("provider trace support", () => {
- const renderActions = (provider: string, isAdmin: boolean) => {
+ const renderActions = (provider: string) => {
const agent: Agent = {
id: "agent-1", companyId: "company-1", name: "Researcher", urlKey: "researcher", role: "researcher",
title: null, icon: null, status: "active", reportsTo: null, capabilities: null,
@@ -52,22 +52,24 @@ describe("provider trace support", () => {
};
return renderToStaticMarkup(
-
+
,
);
};
it("keeps normal Muse actions but removes the unsupported raw traffic promise", () => {
- const markup = renderActions("muse", true);
+ const markup = renderActions("muse");
expect(markup).toContain("Run now");
expect(markup).toContain("Pause");
expect(markup).not.toContain("Run with provider trace");
expect(markup).not.toContain("Capture exact provider traffic");
});
- it("retains other provider tracing only for authorized administrators", () => {
- expect(renderActions("codex", true)).toContain("Run with provider trace");
- expect(renderActions("openai_dot", true)).toContain("Run with provider trace");
- expect(renderActions("codex", false)).not.toContain("Run with provider trace");
+ it.each(["codex", "openai_dot"])("keeps normal %s actions without a separate trace button", provider => {
+ const markup = renderActions(provider);
+ expect(markup).toContain("Run now");
+ expect(markup).toContain("Pause");
+ expect(markup).not.toContain("Run with provider trace");
+ expect(markup).not.toContain("Capture exact provider traffic");
});
});
diff --git a/ui/src/pages/AgentDetail.tsx b/ui/src/pages/AgentDetail.tsx
index 596c11fcb86..a1f7ee43606 100644
--- a/ui/src/pages/AgentDetail.tsx
+++ b/ui/src/pages/AgentDetail.tsx
@@ -1294,7 +1294,6 @@ export function AgentDetail() {
companyId={resolvedCompanyId}
assignLabel="Assign Task"
showStatus={false}
- canRunWithProviderTrace={canUseProviderTrace && supportsRawProviderTrace(currentAgent.adapterType, currentAgent.adapterConfig)}
actionsDisabled={agentAction.isPending}
workActionsDisabled={hasInvalidOrgChain}
workActionsDisabledReason="Repair this agent's reporting chain before assigning tasks or starting runs"