Files
kandev/docs/plans/plugin-direct-profile-invocation/plan.md
T
2026-09-15 09:40:39 +01:00

5.5 KiB

created, status, requirements, system_design, legacy_specs
created status requirements system_design legacy_specs
2026-09-14 complete
REQ-PLUGINS-DIRECT-PROFILE-INVOCATION-001
../../specs/plugins/system-design/plugin-direct-profile-invocation.md

Implementation Plan: Plugin Direct Agent Profile Invocation

Historical delivery record. The replacement plan supersedes implicit host selection. Previous completed checks do not verify the replacement API.

Overview

Plugins that delegate a one-shot LLM step currently select execution identity through the legacy utility_agent config field, which models the choice as a custom utility prompt and hides the agent profile that actually executes. This plan adds a direct agent_profile selection to the Host invocation contract, wires the host to execute the selected profile via ExecuteProfilePrompt, and keeps declaration-gated legacy behavior untouched. The companion kandev-plugin-notes PR 7 consumes the new format: agent-profile field at exact Notes head f8548f9d7a1eaabf19d27bb0b0af8f75d8eaeec4.

The smallest reproduction of the addressed defect is:

  1. Open Settings > Plugins > Notes. The Utility Agent field lists rows from the utility/custom-prompt catalog, not the platform's agent profiles.
  2. Selecting a row persists a utility-prompt ID that fails at invocation with a generic error rather than executing the configured agent profile.

Scope

In scope

  • The agent-profile config renderer format, shared-profile-picker reuse, and eligibility filtering in the web app.
  • Direct profile routing, typed FailedPrecondition translation, and legacy fallback bounding in the backend plugins host.
  • Hydration merging in the plugin config form and store profile-list hydration revision checks.
  • Accessibility and display-label reload for the picker.
  • The companion Notes manifest, webhook error translation, tests, docs, and packaging evidence for the Notes half of the delivery.

Out of scope

  • Changing the public Host.InvokeUtilityAgent signature or agent_invoke gate semantics.
  • Changing utility-agent resolution for plugins that declare only format: utility-agent.
  • New database or config migration for the dual selector formats.

Technical approach

Settings rendering

Extend config-schema.ts with the agent-profile format renderer and route it through utility-agent-profile-picker.tsx in agentRegistration mode. Eligibility requires enabled, non-deleted, global, non-CLI-passthrough, inference-capable profiles; unavailable saved IDs render replaceably. plugin-config-form.tsx merges hydration results so concurrent profile snapshot and config updates do not overwrite each other, and use-settings-data.ts/hydrator.ts guard store revisions against stale profile snapshots with WebSocket-triggered retry.

Host execution

host_utility.go gates on agent_invoke first, validates the declared format, resolves the profile once at call start, and executes with ExecuteProfilePrompt(profileID, prompt). Missing/ineligible selections return typed FailedPrecondition before runner start; non-not-found store errors pass through unchanged in services.go. Legacy utility_agent routing runs only when no direct selection exists and the active manifest declares that selector, per ADR 0048.

Notes companion

The plugin uses the daemonized target server, refreshes Host.InvokeUtilityAgent enhancement to send the selected profile ID, translates FailedPrecondition to an actionable HTTP 412 setup message, updates its manifest contract test, README, packaging, and test-tooling pins, and carries final visual QA evidence for the picker, mobile settings, and enhancement preview.

Tests

  • Backend focused Go tests for direct routing, eligibility/error classes, capability gating, and legacy fallback preservation.
  • Frontend unit tests for config-schema formats, picker eligibility and required fields, hydration merge, store snapshot revision, and WS retry.
  • Notes Go tests for the manifest contract, webhook error mapping, and enhancement payload, plus node --test ui/bundle.test.mjs wiring smoke.

Work orders

Verification results

  • Backend: focused internal/plugins and internal/backendapp Go tests passed, including the direct-profile routing, eligibility, cancellation, and store-failure cases; static checks passed.
  • Frontend: config-schema and picker tests, plugin-config-form hydration tests, settings hydration and WS agent-handler tests, web typecheck, and lint all passed at CI for the delivery head.
  • Notes: Go test suite, node --test ui/bundle.test.mjs, package smoke, doc validation, and packaging metadata checks passed.
  • Notes PR evidence and committed screenshots confirmed the picker, mobile layout, and enhancement preview behavior.

Risks

  • Concurrent profile-list hydration and plugin-config hydration can clobber state; merge and revision guards prevent lossy overwrites.
  • Legacy stored utility_agent values must remain executable for trusted pre-transition manifests, so fallback gating is explicitly bounded in ADR 0048 and regression-tested.
  • Config failures must not be misclassified as operational failures, or web hooks will mislead operators with wrong HTTP status messages.