Fix import adapter configuration forms
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
fed94d18f3
commit
0b76b1aced
2 changed files with 88 additions and 88 deletions
|
|
@ -60,6 +60,10 @@ type AgentConfigFormProps = {
|
||||||
onSaveActionChange?: (save: (() => void) | null) => void;
|
onSaveActionChange?: (save: (() => void) | null) => void;
|
||||||
onCancelActionChange?: (cancel: (() => void) | null) => void;
|
onCancelActionChange?: (cancel: (() => void) | null) => void;
|
||||||
hideInlineSave?: boolean;
|
hideInlineSave?: boolean;
|
||||||
|
showAdapterTypeField?: boolean;
|
||||||
|
showAdapterTestEnvironmentButton?: boolean;
|
||||||
|
showCreateRunPolicySection?: boolean;
|
||||||
|
hideInstructionsFile?: boolean;
|
||||||
/** "cards" renders each section as heading + bordered card (for settings pages). Default: "inline" (border-b dividers). */
|
/** "cards" renders each section as heading + bordered card (for settings pages). Default: "inline" (border-b dividers). */
|
||||||
sectionLayout?: "inline" | "cards";
|
sectionLayout?: "inline" | "cards";
|
||||||
} & (
|
} & (
|
||||||
|
|
@ -163,6 +167,10 @@ export function AgentConfigForm(props: AgentConfigFormProps) {
|
||||||
const { mode, adapterModels: externalModels } = props;
|
const { mode, adapterModels: externalModels } = props;
|
||||||
const isCreate = mode === "create";
|
const isCreate = mode === "create";
|
||||||
const cards = props.sectionLayout === "cards";
|
const cards = props.sectionLayout === "cards";
|
||||||
|
const showAdapterTypeField = props.showAdapterTypeField ?? true;
|
||||||
|
const showAdapterTestEnvironmentButton = props.showAdapterTestEnvironmentButton ?? true;
|
||||||
|
const showCreateRunPolicySection = props.showCreateRunPolicySection ?? true;
|
||||||
|
const hideInstructionsFile = props.hideInstructionsFile ?? false;
|
||||||
const { selectedCompanyId } = useCompany();
|
const { selectedCompanyId } = useCompany();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
|
@ -285,6 +293,7 @@ export function AgentConfigForm(props: AgentConfigFormProps) {
|
||||||
adapterType === "codex_local" ||
|
adapterType === "codex_local" ||
|
||||||
adapterType === "gemini_local" ||
|
adapterType === "gemini_local" ||
|
||||||
adapterType === "opencode_local" ||
|
adapterType === "opencode_local" ||
|
||||||
|
adapterType === "pi_local" ||
|
||||||
adapterType === "cursor";
|
adapterType === "cursor";
|
||||||
const uiAdapter = useMemo(() => getUIAdapter(adapterType), [adapterType]);
|
const uiAdapter = useMemo(() => getUIAdapter(adapterType), [adapterType]);
|
||||||
|
|
||||||
|
|
@ -312,6 +321,7 @@ export function AgentConfigForm(props: AgentConfigFormProps) {
|
||||||
eff: eff as <T>(group: "adapterConfig", field: string, original: T) => T,
|
eff: eff as <T>(group: "adapterConfig", field: string, original: T) => T,
|
||||||
mark: mark as (group: "adapterConfig", field: string, value: unknown) => void,
|
mark: mark as (group: "adapterConfig", field: string, value: unknown) => void,
|
||||||
models,
|
models,
|
||||||
|
hideInstructionsFile,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Section toggle state — advanced always starts collapsed
|
// Section toggle state — advanced always starts collapsed
|
||||||
|
|
@ -478,69 +488,73 @@ export function AgentConfigForm(props: AgentConfigFormProps) {
|
||||||
? <h3 className="text-sm font-medium">Adapter</h3>
|
? <h3 className="text-sm font-medium">Adapter</h3>
|
||||||
: <span className="text-xs font-medium text-muted-foreground">Adapter</span>
|
: <span className="text-xs font-medium text-muted-foreground">Adapter</span>
|
||||||
}
|
}
|
||||||
<Button
|
{showAdapterTestEnvironmentButton && (
|
||||||
type="button"
|
<Button
|
||||||
variant="outline"
|
type="button"
|
||||||
size="sm"
|
variant="outline"
|
||||||
className="h-7 px-2.5 text-xs"
|
size="sm"
|
||||||
onClick={() => testEnvironment.mutate()}
|
className="h-7 px-2.5 text-xs"
|
||||||
disabled={testEnvironment.isPending || !selectedCompanyId}
|
onClick={() => testEnvironment.mutate()}
|
||||||
>
|
disabled={testEnvironment.isPending || !selectedCompanyId}
|
||||||
{testEnvironment.isPending ? "Testing..." : "Test environment"}
|
>
|
||||||
</Button>
|
{testEnvironment.isPending ? "Testing..." : "Test environment"}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className={cn(cards ? "border border-border rounded-lg p-4 space-y-3" : "px-4 pb-3 space-y-3")}>
|
<div className={cn(cards ? "border border-border rounded-lg p-4 space-y-3" : "px-4 pb-3 space-y-3")}>
|
||||||
<Field label="Adapter type" hint={help.adapterType}>
|
{showAdapterTypeField && (
|
||||||
<AdapterTypeDropdown
|
<Field label="Adapter type" hint={help.adapterType}>
|
||||||
value={adapterType}
|
<AdapterTypeDropdown
|
||||||
onChange={(t) => {
|
value={adapterType}
|
||||||
if (isCreate) {
|
onChange={(t) => {
|
||||||
// Reset all adapter-specific fields to defaults when switching adapter type
|
if (isCreate) {
|
||||||
const { adapterType: _at, ...defaults } = defaultCreateValues;
|
// Reset all adapter-specific fields to defaults when switching adapter type
|
||||||
const nextValues: CreateConfigValues = { ...defaults, adapterType: t };
|
const { adapterType: _at, ...defaults } = defaultCreateValues;
|
||||||
if (t === "codex_local") {
|
const nextValues: CreateConfigValues = { ...defaults, adapterType: t };
|
||||||
nextValues.model = DEFAULT_CODEX_LOCAL_MODEL;
|
if (t === "codex_local") {
|
||||||
nextValues.dangerouslyBypassSandbox =
|
nextValues.model = DEFAULT_CODEX_LOCAL_MODEL;
|
||||||
DEFAULT_CODEX_LOCAL_BYPASS_APPROVALS_AND_SANDBOX;
|
nextValues.dangerouslyBypassSandbox =
|
||||||
} else if (t === "gemini_local") {
|
DEFAULT_CODEX_LOCAL_BYPASS_APPROVALS_AND_SANDBOX;
|
||||||
nextValues.model = DEFAULT_GEMINI_LOCAL_MODEL;
|
} else if (t === "gemini_local") {
|
||||||
} else if (t === "cursor") {
|
nextValues.model = DEFAULT_GEMINI_LOCAL_MODEL;
|
||||||
nextValues.model = DEFAULT_CURSOR_LOCAL_MODEL;
|
} else if (t === "cursor") {
|
||||||
} else if (t === "opencode_local") {
|
nextValues.model = DEFAULT_CURSOR_LOCAL_MODEL;
|
||||||
nextValues.model = "";
|
} else if (t === "opencode_local") {
|
||||||
|
nextValues.model = "";
|
||||||
|
}
|
||||||
|
set!(nextValues);
|
||||||
|
} else {
|
||||||
|
// Clear all adapter config and explicitly blank out model + effort/mode keys
|
||||||
|
// so the old adapter's values don't bleed through via eff()
|
||||||
|
setOverlay((prev) => ({
|
||||||
|
...prev,
|
||||||
|
adapterType: t,
|
||||||
|
adapterConfig: {
|
||||||
|
model:
|
||||||
|
t === "codex_local"
|
||||||
|
? DEFAULT_CODEX_LOCAL_MODEL
|
||||||
|
: t === "gemini_local"
|
||||||
|
? DEFAULT_GEMINI_LOCAL_MODEL
|
||||||
|
: t === "cursor"
|
||||||
|
? DEFAULT_CURSOR_LOCAL_MODEL
|
||||||
|
: "",
|
||||||
|
effort: "",
|
||||||
|
modelReasoningEffort: "",
|
||||||
|
variant: "",
|
||||||
|
mode: "",
|
||||||
|
...(t === "codex_local"
|
||||||
|
? {
|
||||||
|
dangerouslyBypassApprovalsAndSandbox:
|
||||||
|
DEFAULT_CODEX_LOCAL_BYPASS_APPROVALS_AND_SANDBOX,
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
},
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
set!(nextValues);
|
}}
|
||||||
} else {
|
/>
|
||||||
// Clear all adapter config and explicitly blank out model + effort/mode keys
|
</Field>
|
||||||
// so the old adapter's values don't bleed through via eff()
|
)}
|
||||||
setOverlay((prev) => ({
|
|
||||||
...prev,
|
|
||||||
adapterType: t,
|
|
||||||
adapterConfig: {
|
|
||||||
model:
|
|
||||||
t === "codex_local"
|
|
||||||
? DEFAULT_CODEX_LOCAL_MODEL
|
|
||||||
: t === "gemini_local"
|
|
||||||
? DEFAULT_GEMINI_LOCAL_MODEL
|
|
||||||
: t === "cursor"
|
|
||||||
? DEFAULT_CURSOR_LOCAL_MODEL
|
|
||||||
: "",
|
|
||||||
effort: "",
|
|
||||||
modelReasoningEffort: "",
|
|
||||||
variant: "",
|
|
||||||
mode: "",
|
|
||||||
...(t === "codex_local"
|
|
||||||
? {
|
|
||||||
dangerouslyBypassApprovalsAndSandbox:
|
|
||||||
DEFAULT_CODEX_LOCAL_BYPASS_APPROVALS_AND_SANDBOX,
|
|
||||||
}
|
|
||||||
: {}),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Field>
|
|
||||||
|
|
||||||
{testEnvironment.error && (
|
{testEnvironment.error && (
|
||||||
<div className="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive">
|
<div className="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive">
|
||||||
|
|
@ -634,8 +648,10 @@ export function AgentConfigForm(props: AgentConfigFormProps) {
|
||||||
? "codex"
|
? "codex"
|
||||||
: adapterType === "gemini_local"
|
: adapterType === "gemini_local"
|
||||||
? "gemini"
|
? "gemini"
|
||||||
: adapterType === "cursor"
|
: adapterType === "pi_local"
|
||||||
? "agent"
|
? "pi"
|
||||||
|
: adapterType === "cursor"
|
||||||
|
? "agent"
|
||||||
: adapterType === "opencode_local"
|
: adapterType === "opencode_local"
|
||||||
? "opencode"
|
? "opencode"
|
||||||
: "claude"
|
: "claude"
|
||||||
|
|
@ -794,7 +810,7 @@ export function AgentConfigForm(props: AgentConfigFormProps) {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* ---- Run Policy ---- */}
|
{/* ---- Run Policy ---- */}
|
||||||
{isCreate ? (
|
{isCreate && showCreateRunPolicySection ? (
|
||||||
<div className={cn(!cards && "border-b border-border")}>
|
<div className={cn(!cards && "border-b border-border")}>
|
||||||
{cards
|
{cards
|
||||||
? <h3 className="text-sm font-medium flex items-center gap-2 mb-3"><Heart className="h-3 w-3" /> Run Policy</h3>
|
? <h3 className="text-sm font-medium flex items-center gap-2 mb-3"><Heart className="h-3 w-3" /> Run Policy</h3>
|
||||||
|
|
@ -815,7 +831,7 @@ export function AgentConfigForm(props: AgentConfigFormProps) {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : !isCreate ? (
|
||||||
<div className={cn(!cards && "border-b border-border")}>
|
<div className={cn(!cards && "border-b border-border")}>
|
||||||
{cards
|
{cards
|
||||||
? <h3 className="text-sm font-medium flex items-center gap-2 mb-3"><Heart className="h-3 w-3" /> Run Policy</h3>
|
? <h3 className="text-sm font-medium flex items-center gap-2 mb-3"><Heart className="h-3 w-3" /> Run Policy</h3>
|
||||||
|
|
@ -881,7 +897,7 @@ export function AgentConfigForm(props: AgentConfigFormProps) {
|
||||||
</CollapsibleSection>
|
</CollapsibleSection>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
) : null}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import { queryKeys } from "../lib/queryKeys";
|
||||||
import { MarkdownBody } from "../components/MarkdownBody";
|
import { MarkdownBody } from "../components/MarkdownBody";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { EmptyState } from "../components/EmptyState";
|
import { EmptyState } from "../components/EmptyState";
|
||||||
|
import { AgentConfigForm } from "../components/AgentConfigForm";
|
||||||
import { cn } from "../lib/utils";
|
import { cn } from "../lib/utils";
|
||||||
import {
|
import {
|
||||||
ArrowRight,
|
ArrowRight,
|
||||||
|
|
@ -27,7 +28,6 @@ import {
|
||||||
import { Field, adapterLabels } from "../components/agent-config-primitives";
|
import { Field, adapterLabels } from "../components/agent-config-primitives";
|
||||||
import { defaultCreateValues } from "../components/agent-config-defaults";
|
import { defaultCreateValues } from "../components/agent-config-defaults";
|
||||||
import { getUIAdapter, listUIAdapters } from "../adapters";
|
import { getUIAdapter, listUIAdapters } from "../adapters";
|
||||||
import { ClaudeLocalAdvancedFields } from "../adapters/claude-local/config-fields";
|
|
||||||
import type { CreateConfigValues } from "@paperclipai/adapter-utils";
|
import type { CreateConfigValues } from "@paperclipai/adapter-utils";
|
||||||
import {
|
import {
|
||||||
type FileTreeNode,
|
type FileTreeNode,
|
||||||
|
|
@ -488,7 +488,6 @@ function AdapterPickerList({
|
||||||
{agents.map((agent) => {
|
{agents.map((agent) => {
|
||||||
const selectedType = adapterOverrides[agent.slug] ?? agent.adapterType;
|
const selectedType = adapterOverrides[agent.slug] ?? agent.adapterType;
|
||||||
const isExpanded = expandedSlugs.has(agent.slug);
|
const isExpanded = expandedSlugs.has(agent.slug);
|
||||||
const uiAdapter = getUIAdapter(selectedType);
|
|
||||||
const vals = configValues[agent.slug] ?? { ...defaultCreateValues, adapterType: selectedType };
|
const vals = configValues[agent.slug] ?? { ...defaultCreateValues, adapterType: selectedType };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -531,31 +530,16 @@ function AdapterPickerList({
|
||||||
</div>
|
</div>
|
||||||
{isExpanded && (
|
{isExpanded && (
|
||||||
<div className="border-t border-border bg-accent/10 px-4 py-3 space-y-3">
|
<div className="border-t border-border bg-accent/10 px-4 py-3 space-y-3">
|
||||||
<uiAdapter.ConfigFields
|
<AgentConfigForm
|
||||||
mode="create"
|
mode="create"
|
||||||
isCreate
|
|
||||||
adapterType={selectedType}
|
|
||||||
values={vals}
|
values={vals}
|
||||||
set={(patch) => onChangeConfig(agent.slug, patch)}
|
onChange={(patch) => onChangeConfig(agent.slug, patch)}
|
||||||
config={{}}
|
showAdapterTypeField={false}
|
||||||
eff={() => "" as any}
|
showAdapterTestEnvironmentButton={false}
|
||||||
mark={() => {}}
|
showCreateRunPolicySection={false}
|
||||||
models={[]}
|
|
||||||
hideInstructionsFile
|
hideInstructionsFile
|
||||||
|
sectionLayout="cards"
|
||||||
/>
|
/>
|
||||||
{selectedType === "claude_local" && (
|
|
||||||
<ClaudeLocalAdvancedFields
|
|
||||||
mode="create"
|
|
||||||
isCreate
|
|
||||||
adapterType={selectedType}
|
|
||||||
values={vals}
|
|
||||||
set={(patch) => onChangeConfig(agent.slug, patch)}
|
|
||||||
config={{}}
|
|
||||||
eff={() => "" as any}
|
|
||||||
mark={() => {}}
|
|
||||||
models={[]}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue