Skip to content

design pi config

sinrimin edited this page Oct 20, 2026 · 1 revision

design-pi-config.md — pi dedicated runtime-config panel (#65)

Fifth and last per-target panel, the #60/#62/#63/#64 pattern applied to pi. This closes the per-target panel family: all five AgentTargets with runtime config now have a dedicated panel. Durable companions: design-phase-9-harness-runtime.md (§4.3 the W16 writer this extends), research-provider-model-params.md (§3.6 pi ground truth), design-claude-code-config.md / -opencode- / -codex- / -deepseek-config.md (the pattern's first four instances).

Division of the form

The provider row keeps ONLY the connection (provider / credential / base URL). The pi panel owns everything model-shaped: the default model, the switchable rows (settings enabledModels), and per-model detail. The generic default-model grid and extra-models rows are hidden for target === 'pi'.

Ground truth (pi-coding-agent 0.85.1 on the rig — ModelDefinitionSchema

in core/model-config.js, re-verified 2026-10-17)

Per model entry: id (required), name, api, baseUrl, reasoning (BOOLEAN capability flag), thinkingLevelMap, input (('text'|'image')[]), cost, contextWindow, maxTokens, samplingParams (Record<string, unknown>), headers, compat. Sampling merge order (pi-ai resolveSamplingParams): {...model.samplingParams, ...samplingParamsByThinkingLevel[level], ...requestParams}.

The W16 writer already landed name/contextWindow/maxTokens/input from the #51 seed; the panel adds the overlay plus pi's OWN knob vocabulary:

  • reasoning: true — a simple boolean capability declaration (panel-only; the seed carries no such field). Symmetric with opencode's 推理 checkbox.
  • samplingParams — free key/value pairs edited with the #56 TagCombobox + Switch/JSON idiom (opencode's options editor verbatim). Effective on the openai wires, silently ignored on anthropic — the registry's documented warn-not-reject stance; the panel hint says so. serverTools deliberately does NOT ride samplingParams.tools (the research §4.2 clobber risk).

OUT of v1 (same class as dsh's wire-dict gaps): thinkingLevelMap + samplingParamsByThinkingLevel (per-level wire spellings), cost (the registry carries no pricing), headers, compat. No behavior section — pi's settings.json (55 fields, none sampling) is already fully managed by the W16 writer (defaultProvider/defaultModel/enabledModels).

The wire

spec.pi — additive optional field (piConfigSchema: per-model name / contextWindow / maxOutputTokens / vision / reasoning / samplingParams, ≤17 entries), zod-validated both ends; old daemons strip it. The four-spot wiring: core PiConfigData mirror, service row, toView passthrough, sdk re-exports.

Writer semantics

applyPiConfig's models array gains the panel overlay, per field: panel value (spec.pi.models) > #51 modelEntries seed > omitted (reasoning/samplingParams are panel-only — the seed carries neither). A bare id with no detail and no seed stays { id } byte-identical (test-pinned). settings.json and the key file are untouched by #65.

Rig-verified end to end (survey-box, 2026-10-17): volcengine-openai route (no registry models — free-text ids, no seed interference) — panel name + contextWindow + vision + reasoning + samplingParams {enable_thinking: true, top_p: 0.9} → exact models.json; the doubao extra stayed a bare {id}; pi auth check --provider harness-nexus → "ready" (pi itself loaded the written schema); reload prefill round-trip exact (tags, switch, JSON value all restored).

Panel UX

pi-panel.tsx, i18n pi* keys (en/zh side by side):

  • 模型 — default model (registry select when available, free-text otherwise) + the extra-models rows. Hint: the enabled list is the switchable set.
  • 模型详情 — collapsible per-model groups: 显示名 / 上下文窗口 / 输出上限 / 视觉 + 推理 checkboxes / 采样参数 (TagCombobox keys; boolean keys ride a Switch, others a raw JSON input parsed at the apply boundary — the #56 idiom). The validation issue renders INLINE below the groups (the #63 lesson).

Note for eval/browser drivers: TagCombobox commits via Enter keydown on its input (aria-label contains the field label); the listbox add-option click path is flaky under synthetic events.

Clone this wiki locally