Repository navigation
Make Engine Settings Consistent - #1112
Conversation
This comment has been minimized.
This comment has been minimized.
|
❌ Error processing validation An error occurred while processing the system response. Please try again. Details
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Missing Vitest coverage for the newly exported Kody rule violation: Every exported schema or utility ships with tests and must typecheck |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Designer UI pass: approve with nits. The neutral Access / Billing / Models block is a clear win over the per-engine sales copy, and dropping Box from Engines and the matrix matches where it belongs (Computer settings). Small polish before merge:
None of these block. Approve once 1–3 land. |
Code Review Completed! 🔥The code review was successfully completed based on your current configurations. Kody Guide: Usage and ConfigurationInteracting with Kody
Current Kody ConfigurationReview OptionsThe following review options are enabled or disabled:
|
|
Landing repair at Validation: 28 tests across four files passed; final The unmasked screenshot fixture is deterministic: its model IDs are literal fixture values, not live endpoint discovery. The review thread has a concrete explanation and is resolved. |
|
Double ASCII space on line 309 of Kody rule violation: Sentence gap by surface: two ASCII spaces in files, U+00A0 plus a space in rendered copy and GitHub text |
| export const instanceModelsSchema = z.array(z.object({ | ||
| id: modelText, | ||
| label: modelText, | ||
| }).strip()).max(100).superRefine((models, context) => { |
There was a problem hiding this comment.
The z.object({...}) schema on lines 6–9 uses .strip(), silently discarding unknown keys and violating Rule 20's requirement for .strict(). This masks client/server contract drift when HTTP callers send extra fields, so replace .strip() with .strict() to reject unknown keys at the instance HTTP boundary.
Kody rule violation: Validate all boundary data with Zod schemas instead of type assertions
Prompt for LLM
File server/instance-models.ts:
Line 6 to 9:
The `z.object({...})` schema on lines 6–9 uses `.strip()`, silently discarding unknown keys and violating Rule 20's requirement for `.strict()`. This masks client/server contract drift when HTTP callers send extra fields, so replace `.strip()` with `.strict()` to reject unknown keys at the instance HTTP boundary.
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.
Fixes #1111.
Summary
Engine settings and the capability matrix now present one shared, neutral set of engine facts instead of per-engine marketing copy and special-case callouts. The engine matrix also drops the ASCII.dev Box row, uses provider brand marks, and can be scoped to engines that have live instances, while Settings → Engines keeps Box out of its list and hides the built-in OpenAI-compatible row until it is actually configured.
Changes
Shared engine facts (
EngineCallout)aria-expanded) with an always-visible, neutral facts block showing Access, Billing, and Models.modelsprop so callers can pass the live instance model ids; when omitted, the registry's default models are used.+N moresuffix, and fall back to a "Discovered from the configured endpoint" message when no ids are available.instanceIdanddefaultOpenprops and the disclosure/aria-controlswiring.Settings → Engines (
EnginesSettings)EngineCalloutwith the instance's configured model options, replacing the hardcoded driver-kind list, the Box-specific notice, and the custom-engine callout.openai-compatrow is hidden unlessopenaiCompat.configuredoropenaiCompat.urlis set; custom instances are always shown.Engine availability (
engine-status)listedInEnginesSettingsnow always excludesboxAgent, regardless of configuration, so ASCII.dev Box stays in Computer settings rather than the Engines list. The corresponding test was updated accordingly.Capability matrix (
EngineCapabilitiesMatrix)ProviderMarkbrand icon plus the display name, replacing the colored uppercase text badge.engineMarkKindmapping so driver-kind ids (e.g.deepseek-harness→dshAgent,opencode→opencodeGo) resolve to the correct provider mark.instancesare supplied, the matrix filters its rows to engines that have a matching live instance.Tests
EngineCallout.test.tsxwas rewritten for the new neutral-facts behavior, model-list handling, truncation, and driver-kind resolution.EngineCapabilitiesMatrix.test.tsxnow iterates aMATRIX_ENGINE_IDSset that excludesbox, asserts Box is absent, and checks thatProviderMarkis used instead ofcapabilityBadgeColor.Summary
Makes the engine settings display consistent by always showing the full set of supported engines and adding proper icon/mark mappings for additional engine types.
Changes
Engine Capabilities Matrix (
src/components/EngineCapabilitiesMatrix.tsx)Added mark kind mappings for three engine IDs:
qwen→qwenAgent,hermes→hermesAgent, andpi→piAgent. These engines now render with their dedicated marks instead of falling back to the genericentry.idvalue.Removed instance-based filtering of the engine list. Previously, when
props.instanceswas provided, the matrix only displayed engines that had a corresponding listed instance, and the now-unusedlistedIdslookup was computed for that purpose. With this change, the matrix always renders the full set of engines fromENGINE_DISPLAY_ORDER/ENGINE_CAPABILITIES(excludingbox), so the settings view no longer varies based on which engines the user has installed or configured.Functional Impact
Engine settings are now consistent for all users: every supported engine appears in the capabilities matrix regardless of local instances, and the newly mapped engines (Qwen, Hermes, Pi) display their correct identifying marks rather than a generic fallback.
Summary
Makes the visibility rule for the built-in OpenAI-compatible engine consistent by extracting it into a single shared helper, and updates the visual test harness/spec so that it exercises that visibility behavior (hidden until configured, shown once an endpoint URL or configuration flag exists) rather than the previous More Info callout layout shapes.
Changes
src/components/EnginesSettings.tsxshowBuiltInOpenAiCompatible(configured, url)that returnsBoolean(configured || url).EnginesSettingswith a call to that helper, so the built-in OpenAI-compatible instance is only listed when it is configured or has a URL. The helper is now the single source of truth for this rule.src/components/EngineCalloutVisualFixture.tsxEngineCalloutBodylayout shapes (Clutch with provider marks, MiniMax with none) to two Engine Settings states:openai-hidden-state: no OpenAI-compatible endpoint configured; only Codex is rendered.openai-configured-state: an endpoint URL is configured; an OpenAI-Compatible row with two models is rendered.showBuiltInOpenAiCompatiblehelper to drive whether the OpenAI-Compatible row appears in each section, plusEngineCalloutandProviderMarkfor rendering the rows.tests/e2e/engine-callout.visual.spec.tsmaxDiffPixels: 0,maxDiffPixelRatio: 0,threshold: 0(previouslymaxDiffPixelRatio: 0.02,threshold: 0.2).720x620and renames the snapshot files toengine-settings-openai-hidden.pngandengine-settings-openai-configured.png.Review findings (from automated review)
tests/e2e/engine-callout.visual.spec.ts:46: thetoHaveScreenshotcall usesstableShotwithout amaskoption, leaving the dynamic model-list region of the configured OpenAI-compatible block unmasked.showBuiltInOpenAiCompatibleis exported without the Vitest coverage required by rule 2 in the same diff.Summary
Aligns how engines are presented across settings surfaces, so the Box (ASCII.dev) engine and locally injected models are only surfaced where they belong.
Changes
Engine Settings no longer lists the Box engine. The ASCII.dev Box agent is now excluded from Engine Settings, since it is configured under Computer settings instead. The corresponding test suite was updated: the previous assertions that validated Box's engine callout copy inside Engine Settings were replaced with a single test asserting that the Box driver kind (
boxAgent) is not referenced in the Engine Settings source.Locally injected models are hidden from the "Why this engine" callout. In
ModelPicker.tsx, the model list passed to theEngineCalloutis now filtered to exclude injected local models before mapping to model IDs. This keeps the callout's engine/model listing consistent with the models users can actually select.Impact
Users will no longer see the Box engine presented as a selectable engine within Engine Settings, and the engine callout will no longer reference injected local models. This reduces confusion between where the Box agent is configured (Computer settings) and where standard engines are configured (Engine Settings), and prevents internal/injected models from leaking into user-facing engine explanations.
Summary
Makes engine/model settings consistent by allowing instance configuration patches to update or clear the configured model list through the same patch flow.
Changes
patchInstanceConfigto accept an optionalmodelsfield containing model definitions withidandlabel.modelsarray is provided, it replacesnextConfig.userModels.modelsarray is provided,userModelsis removed from the instance configuration.Impact
Callers can now update or clear an instance’s model list alongside other engine settings such as CLI, full-auto, enabled, key, and external credential options. Empty model lists correctly clear the stored model configuration instead of leaving stale values.
Make Engine Settings Consistent
Summary
Adds the ability to register custom model entries for an engine instance from Engine Settings, and moves the built-in OpenAI-compatible visibility helper into the shared engine-status module so all surfaces answer consistently.
Changes
Custom user models per instance
server/instance-models.tsdefines a shared validation schema for user-supplied model entries: each entry has anidandlabel, both trimmed, non-empty, at most 200 characters, and free of newlines; the list is capped at 100 entries and duplicate IDs are rejected.modelsarray, validated against that schema, and returns a 400 with the message "models must contain at most 100 unique IDs with valid labels" when validation fails.userModelsfrom an instance's config and merges them into the live model options list, tagging each withcustom: trueand overwriting any existing option with the same ID.Engine Settings UI
AddModelFormthat collects a model slug and display name, blocks duplicates against the engine's current model list, submits the merged list of existing custom models plus the new entry, and surfaces validation or save errors inline.EnginesSettingsandEngineRownow carry the optionalmodelspayload.Engine status helper
showBuiltInOpenAiCompatiblefromEnginesSettings.tsxintosrc/lib/engine-status.ts(behavior unchanged: visible when either the configured flag or a URL is present), updatedEngineCalloutVisualFixtureto import it from the shared module, and added unit tests covering the unconfigured, empty-URL, configured, and URL-only cases.Tests
server/instance-models.test.tscovering trimming, stripping of unknown fields, accepting an explicitly cleared catalog, and rejection of malformed, empty, multiline, over-length, duplicate, and over-100-entry inputs.Review Findings
The automated review reported 2 findings on this change:
server/instance-models.ts:6— The instance-models object schema uses.strip()and should be.strict()to reject unknown keys at the HTTP boundary.