Skip to content

Providers and models ​

A provider is one agent CLI the host can run. This page covers how a CLI is named, what provider.list says about it, its model catalog and the permission modes a chat runs in. Accounts covers the config folders a CLI signs in with.

Agent kinds ​

AgentKindSchema is open: lowercase letters, digits and hyphens, starting with a letter, at most AGENT_KIND_MAX_LENGTH characters. A host can offer its own CLI under a new kind, and older clients still read it. KNOWN_AGENT_KINDS lists the kinds this version names (claude, codex, gemini, copilot, apple), with the type KnownAgentKind and the guard isKnownAgentKind. AgentKind accepts any string and still autocompletes the known ones.

Whether a CLI opens as a chat, in a terminal or both is a capability of its provider. For a kind without its own mark or color, fall back to the provider's name from provider.list, a generic icon and its capabilities. UsageProviderSchema stays closed, as every usage provider needs a reader in code.

ts
import { AgentKindSchema, isKnownAgentKind } from '@adecore/agent-contracts/agent';

AgentKindSchema.parse('grok'); // 'grok'
AgentKindSchema.safeParse('../grok').success; // false
isKnownAgentKind('grok'); // false

AgentStatusSchema (AgentStatus) is a chat's or a terminal session's status: running, needs-you, idle, error or exited.

Models ​

ts
import { ModelCatalogDataSchema, ModelSelectionSchema } from '@adecore/agent-contracts/model';

const catalog = ModelCatalogDataSchema.parse({
    updatedAt: '2026-10-05T00:00:00Z',
    defaultModel: 'example-model',
    profiles: {
        standard: { options: [], contextWindowTokens: { '*': 32000 } }
    },
    models: [{ slug: 'example-model', name: 'Example model', profile: 'standard' }]
});

const selection = ModelSelectionSchema.parse({ model: catalog.defaultModel, options: {} });

A catalog holds one provider's models. A newer copy can replace the shipped one, and updatedAt orders them. The schema requires an ISO date and time, at least one model, a profile per model, and a default model from the list. A slug is lowercase letters, digits, dots, underscores and hyphens, never starting with a hyphen, as it goes on a command line. A profile holds its models' options and context size, per contextWindow option value or under *. The schema does not check that slugs and aliases are unique or that a defaultChoice exists.

ModelCatalogData is the whole catalog. Each of its models is a ModelCatalogEntry (ModelCatalogEntrySchema) with a slug, a name and the name of its profile, and optionally a badge, a vendor, aliases, legacy and a minCliVersion. Each profile is a ModelCatalogProfile (ModelCatalogProfileSchema): options and contextWindowTokens.

ModelSelection is { model, options }, with options as strings and booleans. Parsing checks the shape only, and the host's catalog normalizes it. ModelInfo (ModelInfoSchema) is a model as provider.list describes it, with options as ModelOptionDescriptors (ModelOptionDescriptorSchema): a select with choices and a defaultChoice, or a boolean with a defaultValue. A choice is a ModelOptionChoice (ModelOptionChoiceSchema), { id, label, description? }.

Providers ​

provider.list returns a ProviderListResult. ProviderInfo (ProviderInfoSchema) is one CLI in it: installed, version, models, defaultModel, capabilities and resumeCommand. The capabilities are ProviderCapabilities (ProviderCapabilitiesSchema). Draw a control only when its capability is there:

Capability
chat, terminalWhere the CLI can open: as a chat, in a terminal, or both.
hooksThe host reads the CLI's hooks; without them a terminal shows the session status only.
streamsToolOutputOutput arrives while a tool call runs.
diffsHow a file change arrives: unified, before-after or none.
attachments, mentionsWhether a message may carry files and @ paths.
denyReason, allowAlwaysWhether a denial carries a reason, and whether a rule can be remembered.
asyncQuestionsA question the person may leave while the turn goes on.
steerA message sent while a turn runs can join that turn; absent where it cannot.
compactionFolding the context: native, as a prompt (prompt), or none.
reportsCost, reportsContextWindow, reportsThinkingWhat the CLI tells about a turn.
slashCommandsWhether the CLI takes slash commands.
goalsHow /goal reaches the CLI: calls that pause, resume and clear (native), the slash command only (command), or absent.

install, a ProviderInstall, tells a person how to get a CLI that is not installed, for an install page such as the one in the providers pane. It is absent when the host knows no way.

Field
descriptionOne line on what the CLI is.
commandsOne command per ProviderPlatform (ProviderPlatformSchema: darwin, linux, win32). Leave out a system without a one-line install.
guideUrlThe CLI's own install guide, optional.
signInThe ways it signs in, preferred first, each a ProviderSignIn (ProviderSignInSchema): { kind: 'command', command } runs in a terminal, { kind: 'env', variable } is a key in the environment, { kind: 'chat' } asks in the first chat.
ts
import { ProviderInstallSchema } from '@adecore/agent-contracts/model';

ProviderInstallSchema.parse({
    description: 'A coding agent in a terminal.',
    commands: { darwin: 'brew install example-cli', linux: 'curl -fsSL https://example.com/install.sh | sh' },
    signIn: [{ kind: 'command', command: 'example-cli login' }, { kind: 'env', variable: 'EXAMPLE_API_KEY' }]
});

resumeCommandFor(template, sessionId, flags = []) fills a resumeCommand. It shell-quotes the session id and puts the flags at {flags}. The flags go in unquoted, so quote any that come from outside.

ts
import { resumeCommandFor } from '@adecore/agent-contracts/model';

resumeCommandFor('example-cli {flags} --resume {id}', "it's-1", ['--read-only']);
// example-cli --read-only --resume 'it'\''s-1'

pickerGroupsOf(providers) splits anything with a kind and name into ProviderPickerGroups, { frontier, others, api }, each sorted by name. A picker lists them in that order, with separators between nonempty groups. FRONTIER_PROVIDER_KINDS holds the frontier kinds and API_PROVIDER_KINDS the providers billed per key. Every other kind goes in others. providerGroupOf(kind) returns one kind's ProviderPickerGroup, for drawing separators in an ordered list.

ts
import { pickerGroupsOf } from '@adecore/agent-contracts/model';

const { frontier, others, api } = pickerGroupsOf(providers);
const ordered = [...frontier, ...others, ...api];

Runtime modes ​

RuntimeModeSchema (RuntimeMode) is a chat's permission policy, shared by every provider: supervised, auto-accept-edits, auto and full-access, narrowest first. Each host adapter maps it onto its CLI (see Providers). A chat keeps the requested mode in runtimeMode and the confirmed one in effectiveRuntimeMode. Show the second when present.

Terminal agents ​

A CLI can also run in a terminal, where the host reads its hooks. These contracts live outside the agent tables:

  • AgentRequestSchema (AgentRequest) is a terminal hook request: id, source, kind (approval or question), toolName, nullable title, text and createdAt. It reports the request. The terminal still owns the answer.
  • AgentInfo (AgentInfoSchema) is a terminal session: kind, agentSessionId, transcriptPath, status, optional requests, and live, false after a host restart when the session can only be resumed. SessionStatusEvent (SessionStatusEventSchema) carries it per session.
  • AgentResumePayload (AgentResumePayloadSchema) names a session to resume.
  • ApprovalRequest (ApprovalRequestSchema) is a permission the terminal agent waits on, with choices and an expiresAt. A choice is an ApprovalChoice (ApprovalChoiceSchema): allow, remember or deny. The CLI asks in its own prompt too, and the first answer wins. SessionApprovalsEvent (SessionApprovalsEventSchema) carries a session's pending list. ApprovalAnswerPayload (ApprovalAnswerPayloadSchema) names the choice. ApprovalAnswerResult.accepted (ApprovalAnswerResultSchema) is false when the request had already settled.
  • ApprovalPreferencePayload (ApprovalPreferencePayloadSchema) says whether a client wants these requests. A client that never sends it gets them.

SuggestedTitleSchema is a session title from the CLI, at most SUGGESTED_TITLE_LIMIT characters. A model wrote it, so show it as plain text. SessionIdSchema (SessionId, from @adecore/agent-contracts/ids) is a terminal session id, any nonempty string the client picks.

Licenses and third-party notices are listed in each package.