Provider Feature Manifests

Copy Markdown View Source

CliSubprocessCore.ProviderFeatures is the public, canonical metadata layer for the built-in provider profiles.

It exists so higher-level adapter layers can discover provider-native terminology and partial common-surface support without reimplementing profile knowledge in separate lookup tables.

What It Owns

  • provider-native permission mode metadata
  • rendered CLI args for those permission modes
  • partial feature manifests for built-in providers

The partial-feature manifest covers Ollama-backed model routing, structured output, and completion-only invocation. Permission metadata covers each first-party provider's native permission terminology.

Permission Metadata

Use permission_mode!/2 or permission_args/2 when a caller needs to present or render the provider-native form of a normalized approval choice.

iex> CliSubprocessCore.ProviderFeatures.permission_mode!(:codex, :yolo)
%{
  native_mode: :yolo,
  cli_args: ["--dangerously-bypass-approvals-and-sandbox"],
  cli_excerpt: "--dangerously-bypass-approvals-and-sandbox",
  label: "yolo"
}

iex> CliSubprocessCore.ProviderFeatures.permission_args(:amp, :dangerously_allow_all)
["--dangerously-allow-all"]

iex> CliSubprocessCore.ProviderFeatures.permission_args(:cursor, :bypass)
["--force"]

iex> CliSubprocessCore.ProviderFeatures.permission_args(:cursor, :plan)
["--mode", "plan"]

iex> CliSubprocessCore.ProviderFeatures.permission_args(:antigravity, :bypass)
["--dangerously-skip-permissions"]

This keeps provider profiles authoritative for the real CLI contract while still giving adapter layers a stable public lookup surface.

Important boundary:

  • this metadata is about provider-native permission terminology and rendered CLI args
  • it is not a general sandbox, approval-policy, or thread-options catalog
  • if a provider has extra knobs outside the shared permission concept, those remain in the provider profile or the provider SDK layer

Examples:

  • Codex --dangerously-bypass-approvals-and-sandbox appears here because it is the provider-native rendering of a permission choice
  • Cursor :ask is not a permission mode. It is an operational Cursor mode rendered by the Cursor profile or SDK as --mode ask.
  • Antigravity --sandbox is provider-native runtime behavior, while --dangerously-skip-permissions is the permission-mode rendering.

Partial Features

Use partial_feature!/2 when you need to know whether a built-in provider supports a feature that is shared by some, but not all, providers.

iex> CliSubprocessCore.ProviderFeatures.partial_feature!(:claude, :ollama)
%{
  supported?: true,
  activation: %{provider_backend: :ollama},
  model_strategy: :canonical_or_direct_external,
  notes: [...]
}

Codex's manifest also carries compatibility metadata for the shared Ollama route:

iex> CliSubprocessCore.ProviderFeatures.partial_feature!(:codex, :ollama)
%{
  supported?: true,
  activation: %{provider_backend: :oss, oss_provider: "ollama"},
  model_strategy: :direct_external,
  compatibility: %{
    acceptance: :runtime_validated_external_model,
    default_model: "gpt-oss:20b",
    validated_models: ["gpt-oss:20b"]
  },
  notes: [...]
}

Current built-in :ollama support:

  • Claude: supported through provider_backend: :ollama
  • Codex: supported through provider_backend: :oss, oss_provider: "ollama"
  • Cursor: unsupported on the common CLI surface
  • Amp: unsupported on the common CLI surface
  • Antigravity: unsupported on the common CLI surface

For Codex, the compatibility manifest describes the validated default and the acceptance rule separately:

  • acceptance: any Ollama model that passes runtime validation
  • validated default: gpt-oss:20b
  • non-default models: allowed, but may run with upstream fallback metadata

Structured output and completion-only

Every built-in provider has an explicit manifest entry for :structured_output and :completion_only; absence is never interpreted as support.

ProviderStructured outputCompletion-only
Claudesupported, inline JSON schemasupported
Codexsupported, owner-tracked schema filesupported
Cursorunsupportedunsupported
Ampunsupportedunsupported
Antigravityunsupportedunsupported

Amp and Antigravity remain ordinary coding-agent providers. Their completion-only entries are unsupported because no verified provider posture proves the absence of tools, MCP, prompt extensions, and writes. Antigravity --sandbox or strict permissions alone do not establish that stronger contract.

Provider profiles call require_option/4 before command resolution when one of these common options is requested:

{:error,
 %CliSubprocessCore.ProviderFeatures.Error{
   provider: :amp,
   feature: :structured_output,
   option: :output_schema,
   support_state: :unsupported
 }} =
  CliSubprocessCore.ProviderProfiles.Amp.build_invocation(
    prompt: "return JSON",
    output_schema: %{"type" => "object"}
  )

This failure is typed and occurs before a provider process is started.

Design Rule

CliSubprocessCore.ProviderFeatures should only describe built-in provider profile behavior that the core itself owns.

It should not become a generic SDK catalog or an adapter-specific policy layer. Higher-level packages such as ASM may wrap this metadata to describe their own common surfaces, but the source of truth for built-in CLI behavior stays here.

Session-Control Capability Vocabulary

Provider manifests may now advertise the following session-control capabilities when the runtime really supports them:

  • :session_history
  • :session_resume
  • :session_pause
  • :session_intervene

These names are intentionally shared with the upper orchestration layers. A profile should only publish them when the runtime can surface a truthful provider-native history/resume/pause path; the manifest is not the place for speculative claims.