Normalize adapter display labels (#8913)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Adapter names are part of the board-facing agent setup and management experience. > - The product now treats adapters as harnesses, while execution environments are modeled separately. > - Several built-in adapter labels still carried legacy local wording from the older harness-by-environment model. > - That wording makes the UI noisier and implies a distinction users no longer need to reason about. > - This pull request normalizes adapter display labels while keeping persisted adapter type identifiers unchanged. > - The benefit is clearer adapter selection and management copy without a database migration. ## Linked Issues or Issue Description No public GitHub issue was found for this exact cleanup. Related public PRs: - Supersedes #8910, an earlier branch for the same cleanup that did not include the later docs/gateway/Cursor alignment. - Refs #8819, which is related display-registry work for external multi-segment adapter labels, but not a duplicate of this built-in label cleanup. Feature request details: - Subsystem affected: Cross-cutting (`ui/`, `packages/adapters`, and docs). - Problem or motivation: user-facing adapter names include legacy local qualifiers even though adapters map to harnesses and environments are first-class elsewhere. - Proposed solution: remove the legacy local wording from built-in display labels, keep machine-readable adapter type ids unchanged, and keep gateway disambiguation where it is useful. - Alternatives considered: changing persisted adapter type ids was ruled out because it would create migration and compatibility risk; one-off UI replacements were ruled out because the display registry is already the correct central label boundary. - Roadmap alignment: this is small adapter UX polish, not a new roadmap-level core feature. ## What Changed - Updated the adapter display registry so known adapter labels are final and no built-in local adapter renders a legacy local suffix. - Preserved clean derived labels for unknown plugin local types while keeping gateway disambiguation for unknown gateway types. - Updated `AdapterManager` to prefer registry labels when the server reports raw adapter type ids for built-ins. - Removed legacy local wording from built-in adapter metadata labels in UI and adapter packages. - Aligned Cursor adapter metadata with the central display registry label. - Updated adapter docs and Storybook fixtures to match the new display names. - Added focused registry coverage for built-in labels and unknown plugin suffix behavior. ## Verification - `pnpm check:tokens` - `git diff --check origin/master...fix/adapter-display-labels` - Patch-addition scan for added secrets, private paths, and internal links: no matches. - GitHub duplicate search for open adapter-label/local-suffix issues and PRs; #8910 was identified as the older superseded public PR. - `pnpm exec vitest run ui/src/adapters/adapter-display-registry.test.ts` - `pnpm --filter @paperclipai/ui typecheck` - Stale-label scan found no remaining user-facing display-label suffixes; remaining local wording is operational/test terminology such as adapter ids, docs about running locally, and test descriptions. ## Risks Low risk. The change is display-label and documentation focused, and adapter type ids remain unchanged. The main risk is ambiguous gateway naming, mitigated by keeping explicit gateway labels where variants need disambiguation. ## Model Used OpenAI GPT-5 via Codex, tool-enabled coding agent in a local repository workspace. Context window size is not exposed by this environment. ## 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>
This commit is contained in:
parent
936687ca55
commit
bf982c8c83
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
title: Claude Local
|
||||
title: Claude Code
|
||||
summary: Claude Code local adapter setup and configuration
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
title: Codex Local
|
||||
title: Codex
|
||||
summary: OpenAI Codex local adapter setup and configuration
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ my-adapter/ # external plugin
|
|||
|
||||
```ts
|
||||
export const type = "my_agent"; // snake_case, globally unique
|
||||
export const label = "My Agent (local)";
|
||||
export const label = "My Agent";
|
||||
export const models = [
|
||||
{ id: "model-a", label: "Model A" },
|
||||
];
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ The plugin loader calls `createServerAdapter()` from your package root. This fun
|
|||
|
||||
```ts
|
||||
export const type = "my_adapter"; // snake_case, globally unique
|
||||
export const label = "My Agent (local)";
|
||||
export const label = "My Agent";
|
||||
|
||||
export const models = [
|
||||
{ id: "model-a", label: "Model A" },
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
title: Gemini Local
|
||||
title: Gemini CLI
|
||||
summary: Gemini CLI local adapter setup and configuration
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@ When a heartbeat fires, Paperclip:
|
|||
|
||||
| Adapter | Type Key | Description |
|
||||
|---------|----------|-------------|
|
||||
| [Claude Local](/adapters/claude-local) | `claude_local` | Runs Claude Code CLI locally |
|
||||
| [Codex Local](/adapters/codex-local) | `codex_local` | Runs OpenAI Codex CLI locally |
|
||||
| [Gemini Local](/adapters/gemini-local) | `gemini_local` | Runs Gemini CLI locally (experimental — adapter package exists, not yet in stable type enum) |
|
||||
| OpenCode Local | `opencode_local` | Runs OpenCode CLI locally (multi-provider `provider/model`) |
|
||||
| [Claude Code](/adapters/claude-local) | `claude_local` | Runs Claude Code CLI locally |
|
||||
| [Codex](/adapters/codex-local) | `codex_local` | Runs OpenAI Codex CLI locally |
|
||||
| [Gemini CLI](/adapters/gemini-local) | `gemini_local` | Runs Gemini CLI locally (experimental — adapter package exists, not yet in stable type enum) |
|
||||
| OpenCode | `opencode_local` | Runs OpenCode CLI locally (multi-provider `provider/model`) |
|
||||
| Cursor | `cursor` | Runs Cursor in background mode |
|
||||
| Pi Local | `pi_local` | Runs an embedded Pi agent locally |
|
||||
| Hermes Local | `hermes_local` | Runs the local Hermes CLI through `@paperclipai/hermes-paperclip-adapter` |
|
||||
| Pi | `pi_local` | Runs an embedded Pi agent locally |
|
||||
| Hermes | `hermes_local` | Runs the local Hermes CLI through `@paperclipai/hermes-paperclip-adapter` |
|
||||
| Hermes Gateway | `hermes_gateway` | Calls an already-running Hermes API server through `@paperclipai/hermes-paperclip-adapter/gateway` |
|
||||
| OpenClaw Gateway | `openclaw_gateway` | Connects to an OpenClaw gateway endpoint |
|
||||
| [Process](/adapters/process) | `process` | Executes arbitrary shell commands |
|
||||
|
|
@ -49,7 +49,7 @@ These adapters ship as standalone npm packages and are installed via the plugin
|
|||
|
||||
| Adapter | Package | Type Key | Description |
|
||||
|---------|---------|----------|-------------|
|
||||
| Droid Local | `@henkey/droid-paperclip-adapter` | `droid_local` | Runs Factory Droid locally |
|
||||
| Droid | `@henkey/droid-paperclip-adapter` | `droid_local` | Runs Factory Droid locally |
|
||||
|
||||
## External Adapters
|
||||
|
||||
|
|
|
|||
|
|
@ -50,5 +50,5 @@ These are set automatically by the server when invoking agents:
|
|||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `ANTHROPIC_API_KEY` | Anthropic API key (for Claude Local adapter) |
|
||||
| `OPENAI_API_KEY` | OpenAI API key (for Codex Local adapter) |
|
||||
| `ANTHROPIC_API_KEY` | Anthropic API key (for Claude Code adapter) |
|
||||
| `OPENAI_API_KEY` | OpenAI API key (for Codex adapter) |
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ Go to the Goals section and create your top-level company goal.
|
|||
|
||||
## Step 3: Create the CEO Agent
|
||||
|
||||
The CEO is the first agent you create. Choose an adapter type (Claude Local is a good default) and configure:
|
||||
The CEO is the first agent you create. Choose an adapter type (Claude Code is a good default) and configure:
|
||||
|
||||
- **Name** — e.g. "CEO"
|
||||
- **Role** — `ceo`
|
||||
- **Adapter** — how the agent runs (Claude Local, Codex Local, etc.)
|
||||
- **Adapter** — how the agent runs (Claude Code, Codex, etc.)
|
||||
- **Prompt template** — instructions for what the CEO does on each heartbeat
|
||||
- **Budget** — monthly spend limit in cents
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Paperclip is a monorepo with four main layers.
|
|||
│ Schema, migrations, embedded mode │
|
||||
├─────────────────────────────────────┤
|
||||
│ Adapters │
|
||||
│ Claude Local, Codex Local, │
|
||||
│ Claude Code, Codex, │
|
||||
│ Process, HTTP │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { AdapterModel } from "@paperclipai/adapter-utils";
|
||||
|
||||
export const type = "acpx_local";
|
||||
export const label = "ACPX (local)";
|
||||
export const label = "ACPX";
|
||||
|
||||
export const DEFAULT_ACPX_LOCAL_AGENT = "claude";
|
||||
export const DEFAULT_ACPX_LOCAL_MODE = "persistent";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { AdapterModelProfileDefinition } from "@paperclipai/adapter-utils";
|
||||
|
||||
export const type = "claude_local";
|
||||
export const label = "Claude Code (local)";
|
||||
export const label = "Claude Code";
|
||||
|
||||
export const SANDBOX_INSTALL_COMMAND = "npm install -g @anthropic-ai/claude-code";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { AdapterModelProfileDefinition } from "@paperclipai/adapter-utils";
|
||||
|
||||
export const type = "codex_local";
|
||||
export const label = "Codex (local)";
|
||||
export const label = "Codex";
|
||||
|
||||
export const SANDBOX_INSTALL_COMMAND = "npm install -g @openai/codex";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { AdapterModelProfileDefinition } from "@paperclipai/adapter-utils";
|
||||
|
||||
export const type = "cursor";
|
||||
export const label = "Cursor CLI (local)";
|
||||
export const label = "Cursor";
|
||||
|
||||
// Cursor CLI is not distributed as an npm package — the official install
|
||||
// path is the upstream installer script at cursor.com/install. Other adapters
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
} from "@paperclipai/adapter-utils";
|
||||
|
||||
export const type = "gemini_local";
|
||||
export const label = "Gemini CLI (local)";
|
||||
export const label = "Gemini CLI";
|
||||
|
||||
export const SANDBOX_INSTALL_COMMAND = buildSandboxNpmInstallCommand("@google/gemini-cli");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
export const type = "grok_local";
|
||||
export const label = "Grok Build (local)";
|
||||
export const label = "Grok Build";
|
||||
|
||||
export const DEFAULT_GROK_LOCAL_MODEL = "grok-build";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { AdapterModelProfileDefinition } from "@paperclipai/adapter-utils";
|
||||
|
||||
export const type = "opencode_local";
|
||||
export const label = "OpenCode (local)";
|
||||
export const label = "OpenCode";
|
||||
|
||||
// Use OpenCode's official installer instead of `npm install -g opencode-ai`.
|
||||
// The npm package reifies four large Linux x64 prebuilt-binary subpackages
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { AdapterModelProfileDefinition } from "@paperclipai/adapter-utils";
|
||||
|
||||
export const type = "pi_local";
|
||||
export const label = "Pi (local)";
|
||||
export const label = "Pi";
|
||||
|
||||
export const SANDBOX_INSTALL_COMMAND = "npm install -g @earendil-works/pi-coding-agent@0.74.0";
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { SchemaConfigFields } from "../schema-config-fields";
|
|||
|
||||
export const acpxLocalUIAdapter: UIAdapterModule = {
|
||||
type: "acpx_local",
|
||||
label: "ACPX (local)",
|
||||
label: "ACPX",
|
||||
parseStdoutLine: parseAcpxStdoutLine,
|
||||
ConfigFields: SchemaConfigFields,
|
||||
buildAdapterConfig: buildAcpxLocalConfig,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { getAdapterDisplay, getAdapterLabel, getAdapterLabels } from "./adapter-display-registry";
|
||||
|
||||
describe("adapter display registry", () => {
|
||||
it("uses user-facing labels without the legacy local qualifier for built-in adapters", () => {
|
||||
expect(getAdapterLabel("codex_local")).toBe("Codex");
|
||||
expect(getAdapterLabel("claude_local")).toBe("Claude Code");
|
||||
expect(getAdapterLabel("acpx_local")).toBe("ACPX");
|
||||
expect(getAdapterLabel("cursor")).toBe("Cursor");
|
||||
expect(getAdapterLabel("gemini_local")).toBe("Gemini CLI");
|
||||
expect(getAdapterLabel("grok_local")).toBe("Grok Build");
|
||||
expect(getAdapterLabel("hermes_local")).toBe("Hermes");
|
||||
expect(getAdapterLabel("hermes_gateway")).toBe("Hermes Gateway");
|
||||
expect(getAdapterLabel("opencode_local")).toBe("OpenCode");
|
||||
expect(getAdapterLabel("pi_local")).toBe("Pi");
|
||||
|
||||
expect(getAdapterLabels()).toMatchObject({
|
||||
codex_local: "Codex",
|
||||
claude_local: "Claude Code",
|
||||
acpx_local: "ACPX",
|
||||
cursor: "Cursor",
|
||||
gemini_local: "Gemini CLI",
|
||||
grok_local: "Grok Build",
|
||||
hermes_local: "Hermes",
|
||||
hermes_gateway: "Hermes Gateway",
|
||||
opencode_local: "OpenCode",
|
||||
pi_local: "Pi",
|
||||
});
|
||||
});
|
||||
|
||||
it("drops local suffixes for unknown plugin adapter labels", () => {
|
||||
expect(getAdapterLabel("droid_local")).toBe("Droid");
|
||||
expect(getAdapterDisplay("droid_local")).toMatchObject({
|
||||
label: "Droid",
|
||||
description: "External adapter",
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps a gateway suffix for unknown plugin adapter labels", () => {
|
||||
expect(getAdapterLabel("droid_gateway")).toBe("Droid (gateway)");
|
||||
expect(getAdapterDisplay("droid_gateway")).toMatchObject({
|
||||
label: "Droid (gateway)",
|
||||
description: "External gateway adapter",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -21,13 +21,19 @@ import { OpenCodeLogoIcon } from "@/components/OpenCodeLogoIcon";
|
|||
// Type suffix parsing
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const TYPE_SUFFIXES: Record<string, string> = {
|
||||
_local: "local",
|
||||
// Suffixes stripped from type ids when deriving a human-readable label for
|
||||
// unknown (plugin) adapter types. "_local" is a legacy qualifier from before
|
||||
// first-class Environments and is never displayed; "_gateway" is re-appended
|
||||
// as " (gateway)" to disambiguate gateway variants. Known adapters in
|
||||
// `adapterDisplayMap` have final labels and never get a derived suffix.
|
||||
const STRIPPED_TYPE_SUFFIXES = ["_local", "_gateway"] as const;
|
||||
|
||||
const DISPLAY_SUFFIXES: Record<string, string> = {
|
||||
_gateway: "gateway",
|
||||
};
|
||||
|
||||
function getTypeSuffix(type: string): string | null {
|
||||
for (const [suffix, mode] of Object.entries(TYPE_SUFFIXES)) {
|
||||
for (const [suffix, mode] of Object.entries(DISPLAY_SUFFIXES)) {
|
||||
if (type.endsWith(suffix)) return mode;
|
||||
}
|
||||
return null;
|
||||
|
|
@ -55,57 +61,57 @@ export interface AdapterDisplayInfo {
|
|||
const adapterDisplayMap: Record<string, AdapterDisplayInfo> = {
|
||||
acpx_local: {
|
||||
label: "ACPX",
|
||||
description: "Experimental local ACPX multi-agent adapter",
|
||||
description: "Experimental ACPX multi-agent harness",
|
||||
icon: Bot,
|
||||
experimental: true,
|
||||
hideFromVisualSelection: true,
|
||||
},
|
||||
claude_local: {
|
||||
label: "Claude Code",
|
||||
description: "Local Claude agent",
|
||||
description: "Claude Code CLI harness",
|
||||
icon: Sparkles,
|
||||
recommended: true,
|
||||
},
|
||||
codex_local: {
|
||||
label: "Codex",
|
||||
description: "Local Codex agent",
|
||||
description: "Codex CLI harness",
|
||||
icon: Code,
|
||||
recommended: true,
|
||||
},
|
||||
gemini_local: {
|
||||
label: "Gemini CLI",
|
||||
description: "Local Gemini agent",
|
||||
description: "Gemini CLI harness",
|
||||
icon: Gem,
|
||||
},
|
||||
grok_local: {
|
||||
label: "Grok Build",
|
||||
description: "Local Grok Build agent",
|
||||
description: "Grok Build harness",
|
||||
icon: Bot,
|
||||
},
|
||||
hermes_gateway: {
|
||||
label: "Hermes",
|
||||
label: "Hermes Gateway",
|
||||
description: "Remote Hermes API server",
|
||||
icon: Bot,
|
||||
hideFromVisualSelection: true,
|
||||
},
|
||||
hermes_local: {
|
||||
label: "Hermes",
|
||||
description: "Local Hermes agent",
|
||||
description: "Hermes harness",
|
||||
icon: Bot,
|
||||
},
|
||||
opencode_local: {
|
||||
label: "OpenCode",
|
||||
description: "Local multi-provider agent",
|
||||
description: "OpenCode multi-provider harness",
|
||||
icon: OpenCodeLogoIcon,
|
||||
},
|
||||
pi_local: {
|
||||
label: "Pi",
|
||||
description: "Local Pi agent",
|
||||
description: "Pi harness",
|
||||
icon: Terminal,
|
||||
},
|
||||
cursor: {
|
||||
label: "Cursor",
|
||||
description: "Local Cursor agent",
|
||||
description: "Cursor CLI harness",
|
||||
icon: MousePointer2,
|
||||
},
|
||||
cursor_cloud: {
|
||||
|
|
@ -142,7 +148,7 @@ const adapterDisplayMap: Record<string, AdapterDisplayInfo> = {
|
|||
function humanizeType(type: string): string {
|
||||
// Strip known type suffixes so "droid_local" → "Droid", not "Droid Local"
|
||||
let base = type;
|
||||
for (const suffix of Object.keys(TYPE_SUFFIXES)) {
|
||||
for (const suffix of STRIPPED_TYPE_SUFFIXES) {
|
||||
if (base.endsWith(suffix)) {
|
||||
base = base.slice(0, -suffix.length);
|
||||
break;
|
||||
|
|
@ -152,16 +158,20 @@ function humanizeType(type: string): string {
|
|||
}
|
||||
|
||||
export function getAdapterLabel(type: string): string {
|
||||
const base = adapterDisplayMap[type]?.label ?? humanizeType(type);
|
||||
return withSuffix(base, getTypeSuffix(type));
|
||||
// Known labels are final — only unknown (plugin) types get a derived
|
||||
// suffix, so labels like "OpenClaw Gateway" don't become
|
||||
// "OpenClaw Gateway (gateway)".
|
||||
const known = adapterDisplayMap[type];
|
||||
if (known) return known.label;
|
||||
return withSuffix(humanizeType(type), getTypeSuffix(type));
|
||||
}
|
||||
|
||||
export function getAdapterLabels(): Record<string, string> {
|
||||
const suffixed: Record<string, string> = {};
|
||||
const labels: Record<string, string> = {};
|
||||
for (const [type, info] of Object.entries(adapterDisplayMap)) {
|
||||
suffixed[type] = withSuffix(info.label, getTypeSuffix(type));
|
||||
labels[type] = info.label;
|
||||
}
|
||||
return suffixed;
|
||||
return labels;
|
||||
}
|
||||
|
||||
export function getAdapterDisplay(type: string): AdapterDisplayInfo {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { buildClaudeLocalConfig } from "@paperclipai/adapter-claude-local/ui";
|
|||
|
||||
export const claudeLocalUIAdapter: UIAdapterModule = {
|
||||
type: "claude_local",
|
||||
label: "Claude Code (local)",
|
||||
label: "Claude Code",
|
||||
parseStdoutLine: parseClaudeStdoutLine,
|
||||
ConfigFields: ClaudeLocalConfigFields,
|
||||
buildAdapterConfig: buildClaudeLocalConfig,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { buildCodexLocalConfig } from "@paperclipai/adapter-codex-local/ui";
|
|||
|
||||
export const codexLocalUIAdapter: UIAdapterModule = {
|
||||
type: "codex_local",
|
||||
label: "Codex (local)",
|
||||
label: "Codex",
|
||||
parseStdoutLine: parseCodexStdoutLine,
|
||||
ConfigFields: CodexLocalConfigFields,
|
||||
buildAdapterConfig: buildCodexLocalConfig,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { buildCursorLocalConfig } from "@paperclipai/adapter-cursor-local/ui";
|
|||
|
||||
export const cursorLocalUIAdapter: UIAdapterModule = {
|
||||
type: "cursor",
|
||||
label: "Cursor CLI (local)",
|
||||
label: "Cursor",
|
||||
parseStdoutLine: parseCursorStdoutLine,
|
||||
ConfigFields: CursorLocalConfigFields,
|
||||
buildAdapterConfig: buildCursorLocalConfig,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { buildGeminiLocalConfig } from "@paperclipai/adapter-gemini-local/ui";
|
|||
|
||||
export const geminiLocalUIAdapter: UIAdapterModule = {
|
||||
type: "gemini_local",
|
||||
label: "Gemini CLI (local)",
|
||||
label: "Gemini CLI",
|
||||
parseStdoutLine: parseGeminiStdoutLine,
|
||||
ConfigFields: GeminiLocalConfigFields,
|
||||
buildAdapterConfig: buildGeminiLocalConfig,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { GrokLocalConfigFields } from "./config-fields";
|
|||
|
||||
export const grokLocalUIAdapter: UIAdapterModule = {
|
||||
type: "grok_local",
|
||||
label: "Grok Build (local)",
|
||||
label: "Grok Build",
|
||||
parseStdoutLine: parseGrokStdoutLine,
|
||||
createStdoutParser: createGrokStdoutParser,
|
||||
ConfigFields: GrokLocalConfigFields,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { buildOpenCodeLocalConfig } from "@paperclipai/adapter-opencode-local/ui
|
|||
|
||||
export const openCodeLocalUIAdapter: UIAdapterModule = {
|
||||
type: "opencode_local",
|
||||
label: "OpenCode (local)",
|
||||
label: "OpenCode",
|
||||
parseStdoutLine: parseOpenCodeStdoutLine,
|
||||
ConfigFields: OpenCodeLocalConfigFields,
|
||||
buildAdapterConfig: buildOpenCodeLocalConfig,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { buildPiLocalConfig } from "@paperclipai/adapter-pi-local/ui";
|
|||
|
||||
export const piLocalUIAdapter: UIAdapterModule = {
|
||||
type: "pi_local",
|
||||
label: "Pi (local)",
|
||||
label: "Pi",
|
||||
parseStdoutLine: parsePiStdoutLine,
|
||||
ConfigFields: PiLocalConfigFields,
|
||||
buildAdapterConfig: buildPiLocalConfig,
|
||||
|
|
|
|||
|
|
@ -72,7 +72,10 @@ function AdapterRow({
|
|||
<div className="min-w-0 flex-1">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<span className={cn("font-medium", adapter.disabled && "text-muted-foreground line-through")}>
|
||||
{adapter.label || getAdapterLabel(adapter.type)}
|
||||
{/* The server reports label = raw type id, so prefer the display
|
||||
registry's human label; keep a real self-reported label if an
|
||||
external adapter ever provides one. */}
|
||||
{adapter.label && adapter.label !== adapter.type ? adapter.label : getAdapterLabel(adapter.type)}
|
||||
</span>
|
||||
<Badge variant="outline">{adapter.source === "external" ? "External" : "Built-in"}</Badge>
|
||||
{adapter.source === "external" && (
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ function installStorybookApiFixtures() {
|
|||
return Response.json([
|
||||
{
|
||||
type: "claude_local",
|
||||
label: "Claude Local",
|
||||
label: "Claude Code",
|
||||
source: "builtin",
|
||||
modelsCount: 2,
|
||||
loaded: true,
|
||||
|
|
@ -119,7 +119,7 @@ function installStorybookApiFixtures() {
|
|||
},
|
||||
{
|
||||
type: "codex_local",
|
||||
label: "Codex Local",
|
||||
label: "Codex",
|
||||
source: "builtin",
|
||||
modelsCount: 3,
|
||||
loaded: true,
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ const storybookSecrets: CompanySecret[] = [
|
|||
const adapterFixtures: AdapterInfo[] = [
|
||||
{
|
||||
type: "codex_local",
|
||||
label: "Codex Local",
|
||||
label: "Codex",
|
||||
source: "builtin",
|
||||
modelsCount: 3,
|
||||
loaded: true,
|
||||
|
|
@ -313,7 +313,7 @@ const adapterFixtures: AdapterInfo[] = [
|
|||
},
|
||||
{
|
||||
type: "claude_local",
|
||||
label: "Claude Local",
|
||||
label: "Claude Code",
|
||||
source: "builtin",
|
||||
modelsCount: 2,
|
||||
loaded: true,
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@ function hydrateDialogQueries(queryClient: ReturnType<typeof useQueryClient>) {
|
|||
queryClient.setQueryData(queryKeys.adapters.all, [
|
||||
{
|
||||
type: "codex_local",
|
||||
label: "Codex local",
|
||||
label: "Codex",
|
||||
source: "builtin",
|
||||
modelsCount: 5,
|
||||
loaded: true,
|
||||
|
|
@ -388,7 +388,7 @@ function hydrateDialogQueries(queryClient: ReturnType<typeof useQueryClient>) {
|
|||
},
|
||||
{
|
||||
type: "claude_local",
|
||||
label: "Claude local",
|
||||
label: "Claude Code",
|
||||
source: "builtin",
|
||||
modelsCount: 4,
|
||||
loaded: true,
|
||||
|
|
@ -721,7 +721,7 @@ function useCheapLaneAdapterOverrides(variant: CheapLaneVariant) {
|
|||
queryClient.setQueryData(queryKeys.adapters.all, [
|
||||
{
|
||||
type: "codex_local",
|
||||
label: "Codex local",
|
||||
label: "Codex",
|
||||
source: "builtin",
|
||||
modelsCount: 5,
|
||||
loaded: true,
|
||||
|
|
@ -736,7 +736,7 @@ function useCheapLaneAdapterOverrides(variant: CheapLaneVariant) {
|
|||
},
|
||||
{
|
||||
type: "opencode_local",
|
||||
label: "OpenCode local",
|
||||
label: "OpenCode",
|
||||
source: "builtin",
|
||||
modelsCount: 2,
|
||||
loaded: true,
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ const adapterSchema: JsonSchemaNode = {
|
|||
title: "Adapter name",
|
||||
description: "Human-readable name shown in the adapter manager.",
|
||||
minLength: 3,
|
||||
default: "Codex local",
|
||||
default: "Codex",
|
||||
},
|
||||
mode: {
|
||||
type: "string",
|
||||
|
|
@ -175,7 +175,7 @@ const adapterSchema: JsonSchemaNode = {
|
|||
|
||||
const validAdapterValues = {
|
||||
...getDefaultValues(adapterSchema),
|
||||
adapterName: "Codex local",
|
||||
adapterName: "Codex",
|
||||
mode: "implementation",
|
||||
apiKey: "secret:openai-api-key",
|
||||
concurrency: 2,
|
||||
|
|
|
|||
Loading…
Reference in New Issue