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

157 lines
6.3 KiB
Markdown

---
id: "01-direct-profile-invocation"
title: "Direct profile invocation and settings rendering"
status: done
wave: 1
depends_on: []
plan: "plan.md"
requirements:
- REQ-PLUGINS-DIRECT-PROFILE-INVOCATION-001
acceptance_criteria:
- AC-PLUGINS-DIRECT-PROFILE-INVOCATION-001.1
- AC-PLUGINS-DIRECT-PROFILE-INVOCATION-001.2
- AC-PLUGINS-DIRECT-PROFILE-INVOCATION-001.3
- AC-PLUGINS-DIRECT-PROFILE-INVOCATION-001.4
- AC-PLUGINS-DIRECT-PROFILE-INVOCATION-001.5
- AC-PLUGINS-DIRECT-PROFILE-INVOCATION-001.6
- AC-PLUGINS-DIRECT-PROFILE-INVOCATION-001.7
system_design:
- ../../specs/plugins/system-design/plugin-direct-profile-invocation.md
---
# Task 01: Direct Profile Invocation and Settings Rendering
> 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.
## Summary
Add the direct `agent-profile` config format to Settings > Plugins, render
only eligible platform profiles through the shared picker, and route
`Host.InvokeUtilityAgent` to `ExecuteProfilePrompt` on the stored profile ID
with typed configuration errors and bounded legacy fallback.
## In scope
- Add the `agent-profile` renderer, picker-mode eligibility filtering, and
unavailable-selection replaceable rendering.
- Register the companion Notes settings picker via the daemonized target
server and the platform agent registry.
- Keep the plugin config form's hydration merge and the store profile-list
revision guard so profile/config updates do not overwrite each other.
- Route direct selections to `ExecuteProfilePrompt`; return typed
`FailedPrecondition` for missing/ineligible selections before any runner
starts.
- Adapt host-utility manager errors to gRPC codes with not-found/config
classes; pass non-not-found store failures through unchanged.
- Bound legacy `utility_agent` fallback to trusted declared-selector
configurations per ADR 0048.
- Cover the paths with backend and frontend focused tests, docs updates, and
PR validation evidence.
## Out of scope
- Notes-side manifest, webhook translation, packaging, and QA evidence (Task
02).
- `Host.InvokeUtilityAgent` signature or gate semantic changes.
- Utility-agent behavior for manifests that declare only the legacy format.
## Acceptance
- Notes's Utility Agent settings field lists eligible profiles, not utility
or custom-prompt rows, on desktop and mobile widths.
- Selecting a profile persists its stable ID, marks the shared settings
contributor dirty, saves, and reloads showing the same display label.
- Disabled, deleted, workspace-scoped, and CLI-passthrough profiles cannot be
newly selected; previously saved unavailable selections render replaceably.
- `Host.InvokeUtilityAgent` with a declared, selected profile executes that
profile directly with no utility/custom-prompt lookup; missing or
ineligible selections return typed `FailedPrecondition`, and
non-`agent_invoke` plugins are denied before profile lookup.
- Direct selection takes precedence over a coexisting legacy value;
legacy-only behavior is unchanged.
## Verification
```bash
cd apps/backend
go test ./internal/plugins/... ./internal/backendapp/...
cd ../apps && pnpm --filter @kandev/web test -- --run \
lib/plugins/config-schema.test.ts \
components/settings/utility-agent-profile-picker.test.ts \
components/settings/plugins/plugin-config-form.agent-profile.test.tsx \
hooks/domains/settings/use-settings-data.test.tsx \
lib/state/hydration/hydrator.test.ts \
lib/state/slices/settings/types.test.ts \
lib/ws/handlers/agents.test.ts
pnpm --filter @kandev/web typecheck
pnpm --filter @kandev/web lint
```
## Files likely touched
- `apps/web/lib/plugins/config-schema.ts`
- `apps/web/components/settings/utility-agent-profile-picker.tsx`
- `apps/web/components/settings/plugins/plugin-config-form.tsx`
- `apps/web/hooks/domains/settings/use-settings-data.ts`
- `apps/web/lib/state/hydration/hydrator.ts`
- `apps/web/lib/state/slices/settings/types.ts`
- `apps/web/lib/types/backend.ts`
- `apps/web/lib/types/http-agents.ts`
- `apps/web/lib/ws/handlers/agents.ts`
- `apps/backend/internal/plugins/host_utility.go`
- `apps/backend/internal/plugins/host.go`
- `apps/backend/internal/plugins/service.go`
- `apps/backend/internal/backendapp/services.go`
- `apps/backend/internal/agent/settings/controller/profile_crud.go`
- `apps/backend/pkg/pluginsdk/host.go`
- `docs/decisions/0048-plugin-host-utility-agent-invoke.md`
- `docs/public/plugins-authoring.md`
- `docs/public/plugins-manifest.md`
- `docs/screenshots/pr-validation/2870/*`
## Dependencies
None.
## Risks
- Legacy fallback must remain available for stored configs that still expect
it; explicit bounds and tests prevent silent removal.
- Concurrent hydration of config and profile snapshots can cause lossy
overwrites without merge and revision guards.
- Eligibility criteria must match the agents system's rules, so the shared
registration provider is anchored to the same store used by the settings
API.
## Parallelism
`sequential`
## Inputs
- `docs/specs/plugins/requirements/plugin-direct-profile-invocation.md`
- `docs/specs/plugins/system-design/plugin-direct-profile-invocation.md`
- `docs/specs/agents/requirements/utility-agent-profiles.md`
- `docs/decisions/0048-plugin-host-utility-agent-invoke.md`
- `apps/web/lib/plugins/config-schema.ts`
- `apps/web/components/settings/utility-agent-profile-picker.tsx`
- `apps/backend/internal/plugins/host_utility.go`
## Results
- Added the `agent-profile` renderer and shared-picker `agentRegistration`
mode with utility-execution eligibility (enabled, global, non-CLI,
inference-capable) and replaceable unavailable-selection rendering.
- Registered the daemonized target server so Notes renders platform profiles
with correct labels, persisted the saved stable ID, and surfaced the
profile name in the enhancement preview.
- Preserved legacy `utility_agent` fallback for trusted declared-selector
configs, bounded per ADR 0048 and regression-tested.
- Wired hydration merges and store revision guards so profile snapshot and
plugin-config updates do not clobber each other; profile WS updates retry
when a render would go stale.
- Verification: focused backend `go test` and web vitest/lint/typecheck all
passing at the delivery head, with PR validation screenshots added.