Files
PaperClipAI/docs/specs/agent-config-ui.md
T
Devin FoleyandPaperclip 83abfa46f6 feat(ui): enable Grok in Cloud agent setup (#13791)
## Thinking Path

> - Paperclip manages AI agents and their execution settings.
> - The new-agent flow selects an adapter before configuring credentials
and a model.
> - Cloud uses one adapter policy for the picker and direct setup links.
> - That policy excludes Grok despite its existing adapter and xAI
connection support.
> - This change adds Grok to the Cloud policy.
> - Cloud users can configure Grok with the existing subscription or
API-key flow.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

Agent creation on Cloud.

**Current behavior**

The Cloud picker offers Claude, Codex, and OpenCode. Direct Grok setup
links also fail the shared adapter check.

**Proposed behavior**

Offer Grok alongside the existing choices. Use the existing xAI
connection and managed sandbox setup.

**Reason and benefit**

Users can select an already-supported adapter through the Cloud creation
flow.

**Breaking changes**

None. Loaded and enabled checks still apply. Other excluded adapters
remain excluded.

## What Changed

- Add `grok_local` to the shared Cloud creation policy.
- Display four adapter choices in a 2×2 grid on desktop and mobile, and
reuse the theme-aware provider mark on the connection step so Grok is
visible in dark mode.
- Verify picker navigation and both Grok authentication methods through
sandbox setup, model testing, and agent creation.
- Verify that probe and hire payloads carry the xAI connection binding
without the entered API key.
- Update the agent configuration specification.

## Verification

- `cd ui && pnpm exec vitest run src/components/NewAgentDialog.test.tsx
src/pages/NewAgent.test.tsx
src/components/new-agent/AgentProviderConnection.test.tsx` — 69 tests
passed.
- Chromium checks against the production components and built stylesheet
— four cards occupy two rows and two columns at 1280px and 390px; the
connection step loads and displays the white Grok logo in dark mode and
the black logo in light mode.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- `pnpm --filter @paperclipai/ui build` — passed.
- `pnpm check:token-gates` — passed.
- `git diff origin/master...HEAD | gitleaks stdin --redact --no-banner`
— no leaks found; manual diff review found no private identifiers or
user data.
- `pnpm -r typecheck` and `pnpm build` — blocked at the existing runner
package because `cargo` is not installed locally.
- `pnpm test:run` — started locally, then stopped after the equivalent
CI suites passed.
- Initial [PR
CI](https://github.com/paperclipai/paperclip/actions/runs/35681351752)
passed, including full typecheck/build, general and serialized tests,
Rust checks, and all eight browser-test shards. One unchanged Cursor
test timed out on the first attempt; its five-test file passed locally
and the failed CI shard passed on retry.
- The [latest CI
run](https://github.com/paperclipai/paperclip/actions/runs/35683642812)
passed build, typecheck, all general and serialized tests, Rust checks,
and all eight browser-test shards. One unchanged
local-service-supervisor test failed its HTTP readiness check on the
first attempt; its six-test file passed locally, and the failed server
shard passed on retry.
- Live xAI login and model execution were not run; the setup tests mock
provider calls.

## Risks

Small UI policy change. The existing Grok adapter, authentication, and
secret storage paths remain in use. No schema or control-plane change is
required. Cloud must deploy a tenant-app release containing this change.
Revert the policy entry to hide Grok from new-agent setup again.

## Model Used

- OpenAI GPT-6 (Codex), with repository inspection, code editing, and
shell-based verification.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-22 09:17:59 -07:00

308 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Agent Configuration & Activity UI
## Current implementation (2026-09-07)
The shipped new-agent flow starts from **Agents → New Agent**. A small dialog collects a name and an enabled adapter, then opens a setup page with numbered navigation. Claude, Codex, and Grok have a subscription/API-key connection step. Configuration provides a searchable, free-text model selector and an environment selector; additional settings remain on the full agent page. **Finish setup** submits the existing governed hire request. Confirmation links to configuration and opens a new task with the created agent assigned; agents awaiting approval cannot be assigned work yet.
On Cloud, the new-agent picker and direct setup links allow Claude, Codex, OpenCode, and Grok. Four available adapters use a two-column grid on desktop and mobile. Grok uses the existing `grok_local` adapter with an xAI subscription or API-key connection and the managed sandbox environment. The picker and connection step share provider marks that adapt to light and dark mode. An adapter must also be loaded and enabled to be available.
Paperclip Runner offers native Codex (app server), Claude via ACPX, and OpenCode. The selected provider is passed through the existing runner configuration builder. Codex's default is the adapter catalog default. OpenCode and Pi require a provider/model ID; OpenRouter uses `openrouter/<provider>/<model>` and `OPENROUTER_API_KEY`. Entered keys are tested through the probe-only `testCredentials` field without storage. Finishing setup saves each key as an isolated user secret so a failed test cannot overwrite another agent’s credential, and an existing organization secret can also be bound. Agent configuration and revisions contain references, never the entered key.
**Run test** uses the chosen environment and current configuration. For Claude/Codex readiness checks that do not make a model request, setup also invokes the adapter's existing CLI hello probe with the same environment and credentials. Runtime failures, provider failures, warnings, and in-progress tests use the same compact result card in setup and full configuration. Warnings remain distinguishable from blocking failures.
The new-agent dialog also retains an external-agent invitation link, with an optional message, one-time onboarding prompt, and clipboard fallback. External agents still require organization-admin approval.
The full configuration page retains the contextual navigation and existing instruction-file editor, skills, tools, permissions, API keys, and revision behavior. **Secrets & variables** groups environment bindings with API secret-access grants. Its page-level Save/Discard actions include editor-local environment drafts. Activity, runs, costs, and budgets link to the company audit views scoped to the agent.
The sections below are the original design reference; the implementation summary above supersedes their creation-dialog layout.
## Context
Agents are the employees of a Paperclip company. Each agent has an adapter type (`claude_local`, `codex_local`, `process`, `http`) that determines how it runs, a position in the org chart (who it reports to), a heartbeat policy (how/when it wakes up), and a budget. The UI at `/agents` needs to support creating and configuring agents, viewing their org hierarchy, and inspecting what they've been doing -- their run history, live logs, and accumulated costs.
This spec covers three surfaces:
1. **Agent Creation Dialog** -- the "New Agent" flow
2. **Agent Detail Page** -- configuration, activity, and logs
3. **Agents List Page** -- improvements to the existing list
---
## 1. Agent Creation Dialog
Follows the existing `NewIssueDialog` / `NewProjectDialog` pattern: a `Dialog` component with expand/minimize toggle, company badge breadcrumb, and Cmd+Enter submit.
### Fields
**Identity (always visible):**
| Field | Control | Required | Default | Notes |
|-------|---------|----------|---------|-------|
| Name | Text input (large, auto-focused) | Yes | -- | e.g. "Alice", "Build Bot" |
| Title | Text input (subtitle style) | No | -- | e.g. "VP of Engineering" |
| Role | Chip popover (select) | No | `general` | Values from `AGENT_ROLES`: ceo, cto, cmo, cfo, engineer, designer, pm, qa, devops, researcher, general |
| Reports To | Chip popover (agent select) | No | -- | Dropdown of existing agents in the company. If this is the first agent, auto-set role to `ceo` and gray out Reports To. Otherwise required unless role is `ceo`. |
| Capabilities | Text input | No | -- | Free-text description of what this agent can do |
**Adapter (collapsible section, default open):**
| Field | Control | Default | Notes |
|-------|---------|---------|-------|
| Adapter Type | Chip popover (select) | `claude_local` | `claude_local`, `codex_local`, `process`, `http` |
| Test environment | Button | -- | Runs adapter-specific diagnostics and returns pass/warn/fail checks for current unsaved config |
| CWD | Text input | -- | Working directory for local adapters |
| Prompt Template | Textarea | -- | Supports `{{ agent.id }}`, `{{ agent.name }}` etc. |
| Model | Text input | -- | Optional model override |
**Adapter-specific fields (shown/hidden based on adapter type):**
*claude_local:*
| Field | Control | Default |
|-------|---------|---------|
| Max Turns Per Run | Number input | 80 |
| Skip Permissions | Toggle | true |
*codex_local:*
| Field | Control | Default |
|-------|---------|---------|
| Search | Toggle | false |
| Bypass Sandbox | Toggle | true |
*process:*
| Field | Control | Default |
|-------|---------|---------|
| Command | Text input | -- |
| Args | Text input (comma-separated) | -- |
*http:*
| Field | Control | Default |
|-------|---------|---------|
| URL | Text input | -- |
| Method | Select | POST |
| Headers | Key-value pairs | -- |
**Runtime (collapsible section, default collapsed):**
| Field | Control | Default |
|-------|---------|---------|
| Context Mode | Chip popover | `thin` |
| Monthly Budget (cents) | Number input | 0 |
| Timeout (sec) | Number input | 900 |
| Grace Period (sec) | Number input | 15 |
| Extra Args | Text input | -- |
| Env Vars | Key-value pair editor | -- |
**Heartbeat Policy (collapsible section, default collapsed):**
| Field | Control | Default |
|-------|---------|---------|
| Enabled | Toggle | true |
| Interval (sec) | Number input | 300 |
| Wake on Assignment | Toggle | true |
| Wake on On-Demand | Toggle | true |
| Wake on Automation | Toggle | true |
| Cooldown (sec) | Number input | 10 |
### Behavior
- On submit, calls `agentsApi.create(companyId, data)` where `data` packs identity fields at the top level and adapter-specific fields into `adapterConfig` and heartbeat/runtime into `runtimeConfig`.
- After creation, navigate to the new agent's detail page.
- If the company has zero agents, pre-fill role as `ceo` and disable Reports To.
- The adapter config section updates its visible fields when adapter type changes, preserving any shared field values (cwd, promptTemplate, etc.).
---
## 2. Agent Detail Page
Restructure the existing tabbed layout. Keep the header (name, role, title, status badge, action buttons) and add richer tabs.
### Header
```
[StatusBadge] Agent Name [Invoke] [Pause/Resume] [...]
Role / Title
```
The `[...]` overflow menu contains: Terminate, Reset Session, Create API Key.
### Tabs
#### Overview Tab
Two-column layout: left column is a summary card, right column is the org position.
**Summary card:**
- Adapter type + model (if set)
- Heartbeat interval (e.g. "every 5 min") or "Disabled"
- Last heartbeat time (relative, e.g. "3 min ago")
- Session status: "Active (session abc123...)" or "No session"
- Current month spend / budget with progress bar
**Org position card:**
- Reports to: clickable agent name (links to their detail page)
- Direct reports: list of agents who report to this agent (clickable)
#### Configuration Tab
Editable form with the same sections as the creation dialog (Adapter, Runtime, Heartbeat Policy) but pre-populated with current values. Uses inline editing -- click a value to edit, press Enter or blur to save via `agentsApi.update()`.
Sections:
- **Identity**: name, title, role, reports to, capabilities
- **Adapter Config**: all adapter-specific fields for the current adapter type
- **Heartbeat Policy**: enable/disable, interval, wake-on triggers, cooldown
- **Runtime**: context mode, budget, timeout, grace, env vars, extra args
Each section is a collapsible card. Save happens per-field (PATCH on blur/enter), not a single form submit. Validation errors show inline.
#### Runs Tab
This is the primary activity/history view. Shows a paginated list of heartbeat runs, most recent first.
**Run list item:**
```
[StatusIcon] #run-id-short source: timer 2 min ago 1.2k tokens $0.03
"Reviewed 3 PRs and filed 2 issues"
```
Fields per row:
- Status icon (green check = succeeded, red X = failed, yellow spinner = running, gray clock = queued, orange timeout = timed_out, slash = cancelled)
- Run ID (short, first 8 chars)
- Invocation source chip (timer, assignment, on_demand, automation)
- Relative timestamp
- Token usage summary (total input + output)
- Cost
- Result summary (first line of result or error)
**Clicking a run** opens a run detail inline (accordion expand) or a slide-over panel showing:
- Full status timeline (queued -> running -> outcome) with timestamps
- Session before/after
- Token breakdown: input, output, cached input
- Cost breakdown
- Error message and error code (if failed)
- Exit code and signal (if applicable)
**Log viewer** within the run detail:
- Streams `heartbeat_run_events` for the run, ordered by `seq`
- Each event rendered as a log line with timestamp, level (color-coded), and message
- Events of type `stdout`/`stderr` shown in monospace
- System events shown with distinct styling
- For running runs, auto-scrolls and appends live via WebSocket events (`heartbeat.run.event`, `heartbeat.run.log`)
- "View full log" link fetches from `heartbeatsApi.log(runId)` and shows in a scrollable monospace container
- Truncation: show last 200 events by default, "Load more" button to fetch earlier events
#### Issues Tab
Keep as-is: list of issues assigned to this agent with status, clickable to navigate to issue detail.
#### Costs Tab
Expand the existing costs tab:
- **Cumulative totals** from `agent_runtime_state`: total input tokens, total output tokens, total cached tokens, total cost
- **Monthly budget** progress bar (current month spend vs budget)
- **Per-run cost table**: date, run ID, tokens in/out/cached, cost -- sortable by date or cost
- **Chart** (stretch): simple bar chart of daily spend over last 30 days
### Properties Panel (Right Sidebar)
The existing `AgentProperties` panel continues to show the quick-glance info. Add:
- Session ID (truncated, with copy button)
- Last error (if any, in red)
- Link to "View Configuration" (scrolls to / switches to Configuration tab)
---
## 3. Agents List Page
### Current state
Shows a flat list of agents with status badge, name, role, title, and budget bar.
### Improvements
**Add "New Agent" button** in the header (Plus icon + "New Agent"), opens the creation dialog.
**Add view toggle**: List view (current) and Org Chart view.
**Org Chart view:**
- Tree layout showing reporting hierarchy
- Each node shows: agent name, role, status badge
- CEO at the top, direct reports below, etc.
- Uses the `agentsApi.org(companyId)` endpoint which already returns `OrgNode[]`
- Clicking a node navigates to agent detail
**List view improvements:**
- Add adapter type as a small chip/tag on each row
- Add "last active" relative timestamp
- Add running indicator (animated dot) if agent currently has a running heartbeat
**Filtering:**
- Tab filters: All, Active, Paused, Error (similar to Issues page pattern)
---
## 4. Component Inventory
New components needed:
| Component | Purpose |
|-----------|---------|
| `NewAgentDialog` | Agent creation form dialog |
| `AgentConfigForm` | Shared form sections for create + edit (adapter, heartbeat, runtime) |
| `AdapterConfigFields` | Conditional fields based on adapter type |
| `HeartbeatPolicyFields` | Heartbeat configuration fields |
| `EnvVarEditor` | Key-value pair editor for environment variables |
| `RunListItem` | Single run row in the runs list |
| `RunDetail` | Expanded run detail with log viewer |
| `LogViewer` | Streaming log viewer with auto-scroll |
| `OrgChart` | Tree visualization of agent hierarchy |
| `AgentSelect` | Reusable agent picker (for Reports To, etc.) |
Reused existing components:
- `StatusBadge`, `EntityRow`, `EmptyState`, `PropertyRow`
- shadcn: `Dialog`, `Tabs`, `Button`, `Popover`, `Command`, `Separator`, `Toggle`
---
## 5. API Surface
All endpoints already exist. No new server work needed for V1.
| Action | Endpoint | Used by |
|--------|----------|---------|
| List agents | `GET /companies/:id/agents` | List page |
| Get org tree | `GET /companies/:id/org` | Org chart view |
| Create agent | `POST /companies/:id/agents` | Creation dialog |
| Update agent | `PATCH /agents/:id` | Configuration tab |
| Pause/Resume/Terminate | `POST /agents/:id/{action}` | Header actions |
| Reset session | `POST /agents/:id/runtime-state/reset-session` | Overflow menu |
| Create API key | `POST /agents/:id/keys` | Overflow menu |
| Get runtime state | `GET /agents/:id/runtime-state` | Overview tab, properties panel |
| Invoke/Wakeup | `POST /agents/:id/heartbeat/invoke` | Header invoke button |
| List runs | `GET /companies/:id/heartbeat-runs?agentId=X` | Runs tab |
| Cancel run | `POST /heartbeat-runs/:id/cancel` | Run detail |
| Run events | `GET /heartbeat-runs/:id/events` | Log viewer |
| Run log | `GET /heartbeat-runs/:id/log` | Full log view |
---
## 6. Implementation Order
1. **New Agent Dialog** -- unblocks agent creation from the UI
2. **Agents List improvements** -- add New Agent button, tab filters, adapter chip, running indicator
3. **Agent Detail: Configuration tab** -- editable adapter/heartbeat/runtime config
4. **Agent Detail: Runs tab** -- run history list with status, tokens, cost
5. **Agent Detail: Run Detail + Log Viewer** -- expandable run detail with streaming logs
6. **Agent Detail: Overview tab** -- summary card, org position
7. **Agent Detail: Costs tab** -- expanded cost breakdown
8. **Org Chart view** -- tree visualization on list page
9. **Properties panel updates** -- session ID, last error
Steps 1-5 are the core. Steps 6-9 are polish.
Native ACPX connection tests reject unsupported local platforms before a host CLI
login can incorrectly mark the runner connected. The existing verified Claude
ACPX runtime requires Linux x64; remote environments are evaluated independently
of the control-plane host platform.