cc33b2a813
Co-authored-by: ayattara <alassane.yattara@savoirfairelinux.com> Co-authored-by: Carlos Florencio <carlosmflorencio@gmail.com>
127 lines
5.5 KiB
Markdown
127 lines
5.5 KiB
Markdown
---
|
|
created: 2026-09-14
|
|
status: complete
|
|
requirements:
|
|
- REQ-PLUGINS-DIRECT-PROFILE-INVOCATION-001
|
|
system_design:
|
|
- ../../specs/plugins/system-design/plugin-direct-profile-invocation.md
|
|
legacy_specs: []
|
|
---
|
|
|
|
# Implementation Plan: Plugin Direct Agent Profile Invocation
|
|
|
|
> Historical delivery record. [The replacement plan](../plugin-explicit-utility-invocation/plan.md) 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](https://github.com/yattdev/kandev-plugin-notes/pull/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](../../decisions/0048-plugin-host-utility-agent-invoke.md).
|
|
|
|
### 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
|
|
|
|
- [x] [Task 01: Direct profile invocation and settings rendering](task-01-direct-profile-invocation.md)
|
|
- [x] [Task 02: Notes companion manifest, errors, and evidence](task-02-notes-companion-delivery.md)
|
|
|
|
## 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.
|