From ea9ce27e55aa541a7d5eb6b4fe6df171b13e6728 Mon Sep 17 00:00:00 2001 From: "Pawla Abdul (Bot)" Date: Sun, 12 Apr 2026 17:28:13 +0000 Subject: [PATCH] Remove duplicate UI fields already provided by the platform The adapter config schema was re-declaring model, promptTemplate, env, extraArgs, timeoutSec, and graceSec which the Paperclip platform already surfaces as standard fields, causing duplicate controls in the agent configuration UI. Co-Authored-By: Paperclip --- src/server/config-schema.test.ts | 45 +++++++++++------------------ src/server/config-schema.ts | 49 ++------------------------------ 2 files changed, 18 insertions(+), 76 deletions(-) diff --git a/src/server/config-schema.test.ts b/src/server/config-schema.test.ts index 5147793..7c2edbc 100644 --- a/src/server/config-schema.test.ts +++ b/src/server/config-schema.test.ts @@ -21,15 +21,18 @@ describe("getConfigSchema", () => { expect(uniqueGroups).toContain("Core"); expect(uniqueGroups).toContain("Kubernetes"); - expect(uniqueGroups).toContain("Operational"); }); - it("has model as required text field", () => { + it("does not include platform-provided fields", () => { const schema = getConfigSchema(); - const modelField = schema.fields.find((f: ConfigFieldSchema) => f.key === "model"); - expect(modelField).toBeDefined(); - expect(modelField!.type).toBe("text"); - expect(modelField!.required).toBe(true); + const keys = schema.fields.map((f: ConfigFieldSchema) => f.key); + // These fields are provided by the platform and should not be duplicated + expect(keys).not.toContain("model"); + expect(keys).not.toContain("promptTemplate"); + expect(keys).not.toContain("env"); + expect(keys).not.toContain("extraArgs"); + expect(keys).not.toContain("timeoutSec"); + expect(keys).not.toContain("graceSec"); }); it("has imagePullPolicy as select with correct options", () => { @@ -60,22 +63,6 @@ describe("getConfigSchema", () => { expect(field!.default).toBe(300); }); - it("timeoutSec defaults to 0", () => { - const schema = getConfigSchema(); - const field = schema.fields.find((f: ConfigFieldSchema) => f.key === "timeoutSec"); - expect(field).toBeDefined(); - expect(field!.type).toBe("number"); - expect(field!.default).toBe(0); - }); - - it("graceSec defaults to 60", () => { - const schema = getConfigSchema(); - const field = schema.fields.find((f: ConfigFieldSchema) => f.key === "graceSec"); - expect(field).toBeDefined(); - expect(field!.type).toBe("number"); - expect(field!.default).toBe(60); - }); - it("retainJobs is a toggle", () => { const schema = getConfigSchema(); const field = schema.fields.find((f: ConfigFieldSchema) => f.key === "retainJobs"); @@ -98,14 +85,14 @@ describe("getConfigSchema", () => { } }); - it("has env and extraArgs as textarea", () => { + it("has nodeSelector and tolerations as textarea", () => { const schema = getConfigSchema(); - const envField = schema.fields.find((f: ConfigFieldSchema) => f.key === "env"); - expect(envField).toBeDefined(); - expect(envField!.type).toBe("textarea"); + const nodeField = schema.fields.find((f: ConfigFieldSchema) => f.key === "nodeSelector"); + expect(nodeField).toBeDefined(); + expect(nodeField!.type).toBe("textarea"); - const extraArgsField = schema.fields.find((f: ConfigFieldSchema) => f.key === "extraArgs"); - expect(extraArgsField).toBeDefined(); - expect(extraArgsField!.type).toBe("textarea"); + const tolField = schema.fields.find((f: ConfigFieldSchema) => f.key === "tolerations"); + expect(tolField).toBeDefined(); + expect(tolField!.type).toBe("textarea"); }); }); \ No newline at end of file diff --git a/src/server/config-schema.ts b/src/server/config-schema.ts index fbe406e..2e116af 100644 --- a/src/server/config-schema.ts +++ b/src/server/config-schema.ts @@ -3,15 +3,7 @@ import type { AdapterConfigSchema } from "@paperclipai/adapter-utils"; export function getConfigSchema(): AdapterConfigSchema { return { fields: [ - // Core fields - { - key: "model", - label: "Model", - type: "text", - hint: "OpenCode model id in provider/model format (e.g. anthropic/claude-sonnet-4-6)", - required: true, - group: "Core", - }, + // Core fields (model, promptTemplate, env, extraArgs are provided by the platform) { key: "variant", label: "Variant", @@ -27,27 +19,6 @@ export function getConfigSchema(): AdapterConfigSchema { hint: "Inject runtime config with permission.external_directory=allow", group: "Core", }, - { - key: "promptTemplate", - label: "Prompt Template", - type: "text", - hint: "Run prompt template", - group: "Core", - }, - { - key: "extraArgs", - label: "Extra Arguments", - type: "textarea", - hint: "JSON array of additional CLI args appended to the opencode command", - group: "Core", - }, - { - key: "env", - label: "Environment Variables", - type: "textarea", - hint: "KEY=VALUE pairs, one per line. Overrides inherited vars from the Deployment.", - group: "Core", - }, // Kubernetes fields { @@ -148,23 +119,7 @@ export function getConfigSchema(): AdapterConfigSchema { group: "Kubernetes", }, - // Operational fields - { - key: "timeoutSec", - label: "Timeout (seconds)", - type: "number", - default: 0, - hint: "Run timeout in seconds; 0 means no timeout", - group: "Operational", - }, - { - key: "graceSec", - label: "Grace Period (seconds)", - type: "number", - default: 60, - hint: "Additional grace before adapter gives up after Job deadline", - group: "Operational", - }, + // Operational fields (timeoutSec and graceSec are provided by the platform) ], }; } \ No newline at end of file