Skip to content

Model Provider Adapters ​

Initiative 1 adds a permanent, model-agnostic provider adapter layer to the platform. This page explains the architecture; see OpenAI Adapter for the first concrete implementation, Provider Connections (Initiative 2) for how a tenant's own credentials — never CARC's — get injected into a managed execution, and Execution Profiles (Initiative 3) for the canonical execution contract that ties an adapter, a connection, and a model configuration together.

The proof this initiative makes ​

The same Runtime Control Engine — unchanged policy, evidence, risk, approval, recording, replay, and metrics logic — governs three kinds of Agent Run:

  • synthetic — the engine's own in-process reference agent
  • externally submitted: a company ran its own model and handed the engine a finished output (External Agent Runs)
  • managed — the platform executed a real external model itself, through a provider adapter (this page)

The Runtime Control Engine never imports a provider SDK type and never knows which provider produced an output. It only ever evaluates a standardized result.

Agent Registry vs. Adapter Registry — two separate concepts ​

Agent RegistryAdapter Registry
AnswersWhich agent is this, who owns it, what may it do, is it trusted to run?How does the platform talk to an external model/agent provider?
EntityRegisteredAgentRegisteredAdapter (secret-free wire summary)
Governswhether an agent may runhow an execution request reaches a real provider
Connected byRegisteredAgent.adapter_id (nullable — an agent may have no adapter at all)—

An agent with no adapter_id can still be used via bring-your-own execution or the synthetic path — it simply cannot be executed through the managed endpoint below.

Initiative 2 adds a third, equally separate concept: the Provider Connection, which supplies WHOSE credentials a managed execution uses.

Initiative 3 adds a fourth: the Execution Profile, the canonical execution contract — model, inference parameters, timeouts/retries. As of Initiative 3, a RegisteredAgent no longer references adapter_id/provider_connection_id directly for managed execution; it references exactly one ExecutionProfile via execution_profile_id, and the profile itself carries adapter_id + provider_connection_id. RegisteredAgent.adapter_id is kept only as a deprecated, display-only field for backward compatibility — see Execution Profiles for the full resolution order and the migration story for agents registered before Initiative 3.

Target architecture ​

text
Business Application
  |
  Agent Registry            <- governs whether the agent may run
  |
  Execution Profile           <- resolves HOW execution happens (model, params, timeouts) (Initiative 3)
  |
  Provider Connection           <- resolves WHOSE tenant-owned credentials are used (Initiative 2)
  |
  Adapter Registry                 <- resolves WHICH protocol/implementation handles it
  |
  Agent Provider Adapter             <- generic contract, TRANSIENT credentialed instance
  |
  External Model Provider (the tenant's own account)
  |
  Standardized execution result (text + citations + safe metadata)
  |
  AgentExecutionMapper                 <- bridges into AgentOutput, still no provider SDK types
  |
  Runtime Control Engine      <- UNCHANGED evidence/policy/risk/Decision Controller
  |
  Runtime Session -> Agent Run -> Decision Context Record -> Decision Replay

See Execution Profiles for the full resolution order (19 ordered checks) and Provider Connections for the credential-resolution architecture (CredentialStore) — including why the Adapter Registry's own boot-time instance is never used to execute a customer's request.

Managed execution vs. bring-your-own execution ​

Bring Your Own ExecutionManaged Adapter Execution
EndpointPOST /runtime/agent-runsPOST /runtime/agents/:agentId/execute
Who runs the modelThe caller, on its own infrastructureThe platform, via a registered adapter
Caller suppliesA finished, structured AgentOutputRaw subject context/instructions; the platform produces the output
execution_origin on the resulting AgentRun"external""managed"
Whose provider credentials are usedN/A — CARC never sees themYours — a tenant-owned Provider Connection, never CARC's
When to useYou already run your own agent/model/frameworkYou want the platform to call a supported provider on your behalf, using your own account

Both land in the exact same evidence/policy/risk/Decision Controller pipeline and both are visible through the same Runtime Session, Agent Run, Decision Context Record, and Decision Replay APIs.

The generic adapter contract ​

Every provider adapter (OpenAI, Azure OpenAI, Google Gemini, Anthropic, a self-hosted model, a local model, a custom AI endpoint) implements the same AgentProviderAdapter interface (@giggle-ai/agent-adapter-core):

ts
interface AgentProviderAdapter {
  readonly adapterId: string;
  readonly provider: string;
  readonly version: string;
  getCapabilities(): AgentAdapterCapabilities;
  validateConfiguration(): Promise<AdapterValidationResult>;
  execute(request: AgentExecutionRequest): Promise<AgentExecutionResult>;
}

execute() never runs runtime policy, evidence, risk, or approval logic — it only calls the provider and returns a generic { output, citations, modelProvider, modelVersion, adapterId, executionMetadata } envelope. The engine's AgentExecutionMapper bridges that into a full AgentOutput before the unchanged evidence/policy/risk pipeline runs.

Adapter lifecycle ​

text
registered ("unavailable")
    |
    validateAdapter()
    |
    +-- available     <- configuration valid, ready for managed execution
    +-- misconfigured <- required configuration (e.g. an API key) missing/invalid
    +-- unavailable   <- configuration valid but not currently usable
    +-- deprecated    <- historical only, never selected for new executions

Adapters are registered only by the engine's own composition root at boot — there is no HTTP endpoint to create or edit adapter configuration.

Configuration and security considerations ​

  • Provider secrets (API keys, base URLs) live only in the adapter package's own config module and the process environment — never in a RegisteredAgent, never in a RegisteredAdapter's wire representation, never logged.
  • GET /runtime/adapters* responses only ever return the secret-free RegisteredAdapterSummary shape.
  • An unconfigured or unreachable provider never affects engine health/readiness — see GET /ready's degraded field.
  • No provider prompt or response text is ever logged — only safe metadata (token counts, latency, provider request id, finish reason).

APIs ​

text
GET  /runtime/adapters
GET  /runtime/adapters/:id
POST /runtime/adapters/:id/validate
GET  /runtime/adapters/:id/health
POST /runtime/agents/:agentId/execute

See SDK Guide and REST API Guide for usage, and OpenAI Adapter for the first concrete provider implementation.

Developer Platform v1: Consequential Agent Runtime Control Platform