Skip to content

Finish interface-neutral Agent control surface and remove CLI/A2A runtime reach-through #3221

Description

@acoliver

Parent

Part of #2619. This is the focused completion slice for the thin-interface objective in #1595; it does not replace #1595's history.

Problem

Moving initial construction behind createAgent is not enough if the interactive CLI, A2A, or another host must later reach into Config, ProviderManager, scheduler, MCP manager, tool registry, history internals, or provider runtime helpers to perform normal operations.

That makes CLI a privileged co-owner of the runtime. Every new interface would have to reproduce its command handlers, provider/profile mutations, refresh behavior, lifecycle ordering, and internal imports.

The desired model is:

CLI / A2A / SDK / future UI
  - parse and validate interface input
  - submit typed intent to Agent
  - subscribe to Agent events/state
  - render or transport results

Agent public API
  - owns runtime operations and state transitions
  - presents interface-neutral commands, queries, and events

It is acceptable for CLI to parse commands such as selecting a provider/model, applying a profile, reloading MCP servers, or changing a setting. The CLI must send typed declarative intent; it must not implement the underlying runtime transition itself.

Scope

1. Inventory interface reach-through

Regenerate an inventory of production CLI and A2A imports/calls that access runtime internals, including:

  • Config construction and service getters;
  • ProviderManager/OAuthManager and provider runtime mutators/accessors;
  • scheduler and tool-registry access;
  • MCP manager/reload/discovery access;
  • history/session internals;
  • settings/profile mutation paths;
  • subagent/runtime identity helpers;
  • direct imports from core/providers/tools/MCP implementation subpaths;
  • CLI dependencies on provider SDKs such as @anthropic-ai/sdk and openai.

Classify each site as presentation-only, typed host input, public Agent operation/query/event needed, or obsolete internal reach-through.

2. Characterize behavior through interfaces

Before migration, add Bun behavioral tests that pin user-visible behavior for representative interactive, noninteractive, and A2A operations:

  • startup and shutdown;
  • chat/stream and cancellation;
  • provider/model/profile changes;
  • auth prompts and outcomes;
  • tool approval, progress, completion, and errors;
  • MCP reload/discovery status;
  • session/history queries needed by commands;
  • subagent progress/events;
  • diagnostics exposed to users.

Tests should drive the host adapter and Agent API boundary, not private Config getters or mocked call sequences. Visual/terminal changes must also be verified through the tmux harness.

3. Define a narrow interface-neutral control surface

Add only the public Agent operations, typed command inputs, read-only state views, and events that real host behavior requires. Prefer focused capability interfaces over a generic execute-any-command API.

Public contracts must not expose:

  • Config or ConfigParameters;
  • SettingsService;
  • ProviderManager or OAuthManager;
  • scheduler/registry/MCP implementation classes;
  • runtime registry IDs or ambient scope helpers;
  • credentials;
  • generic runtime/service bags;
  • concrete provider or agent factory types.

Coordinate profile/provider commands with #2635/#2643 so profile application remains transactional and per-agent. Preserve #2758's intentional trusted plugin contribution seam without exposing it to ordinary interface code.

4. Convert CLI into an adapter

  • Keep CLI-owned argument parsing, terminal prompts, Ink/React rendering, keyboard handling, accessibility, and presentation settings.
  • Translate CLI input into typed Agent API operations.
  • Replace direct runtime mutations and service access with Agent operations/state/events.
  • Remove CLI runtime-construction and concrete-factory responsibilities in coordination with the sibling Architecture epic: thin interfaces, Agent API-owned runtime assembly, explicit ownership, and acyclic package boundaries #2619 runtime-assembly issue.
  • Remove direct provider SDK dependencies and provider-specific implementation imports when no presentation-only use remains.
  • Ensure interactive and noninteractive modes use the same Agent operations rather than separate runtime paths.

5. Convert A2A and prove replaceability

  • Make A2A task/session handling use the same Agent API operations and event model as CLI where capabilities overlap.
  • Keep HTTP/request transport and request-scoped concerns in A2A.
  • Do not recreate Config/provider/scheduler/MCP assembly in A2A.
  • Add a small non-CLI host test fixture that starts an Agent, performs a representative configuration change and chat/tool flow, observes events, and disposes it without importing CLI.

6. Enforce the host boundary

Coordinate with #2618 rather than adding a separate parser/checker:

  • express permitted package/public-subpath imports in the generalized package API manifests;
  • make ESLint deep-import enforcement fail closed for CLI and A2A;
  • remove each consumer's wildcard TypeScript/vitest aliases as its imports migrate;
  • reject direct CLI/A2A imports of provider implementation/runtime internals, scheduler internals, MCP implementation classes, and Config construction APIs;
  • retain intentional interface dependencies such as Ink, terminal helpers, A2A transport, and narrow public Agent contracts.

The guard must allow typed low-level data contracts that are genuinely part of the public API; it must enforce ownership rather than ban every shared type.

Coordination

Non-goals

  • Moving terminal rendering or CLI argument parsing into agents.
  • Creating one giant Agent god-interface or stringly typed command dispatcher.
  • Exposing internal service objects for convenience.
  • Reimplementing profile transactions, package guards, or plugin manifests owned by related issues.
  • Requiring CLI and A2A to have identical presentation or transport behavior.

Acceptance criteria

  • CLI and A2A perform shared runtime operations through public Agent API commands/queries/events, not through Config or concrete runtime services.
  • CLI production code does not construct Config, provider managers, schedulers, MCP managers, tool registries, or agent/provider factory bundles.
  • CLI production dependencies no longer include provider SDKs that are only required by provider implementations.
  • Interactive and noninteractive CLI paths share Agent operations for provider/profile changes, auth, tools, session control, and shutdown where their behavior overlaps.
  • A2A does not duplicate CLI runtime assembly and can start/use/dispose an Agent without importing CLI.
  • A non-CLI host fixture demonstrates that a new interface can use shipped runtime behavior without copying bootstrap code.
  • Public Agent contracts expose no Config, SettingsService, ProviderManager, OAuthManager, credentials, registry IDs, generic service bags, or concrete implementation factories.
  • Generalized Finish package boundary enforcement: trim 117-subpath core exports, remove tsconfig bypasses, break core-mcp cycle (Fixes #2618) #2618 boundary checks reject prohibited CLI/A2A internal imports and cannot be bypassed by wildcard aliases.
  • Existing interactive, noninteractive, A2A, profile, OAuth, MCP, tool, subagent, and session behavior remains covered by Bun behavioral tests.
  • Terminal behavior is verified in the tmux harness when visual/UI code changes.
  • Full project verification and the StepFun smoke test pass.

Metadata

Metadata

Assignees

Labels

APIAPIs and things to plugin and extend LLxprt CodeCode Quality / ModularizationIssues to do with the quality of llxprt code and its maintainability.architectureArchitectural refactor / clean designconfigurationllxprt system configuration

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions