Skip to content

Providers and accounts ​

Agent kinds ​

AgentKindSchema is claude, codex, gemini, copilot or apple: the agent CLIs a host may know. A kind in this list is not a promise of a chat for it; whether a CLI opens as a chat, in a terminal or both is a capability of its provider. AgentStatusSchema is 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 is the models of one provider, as a host ships it and as a newer copy can replace it; updatedAt orders the two. The schema asks for an ISO date and time, at least one model, a profile for every model, and a default model that is in the list. A slug is lowercase letters, digits, dots, underscores and hyphens and never starts with a hyphen, since it ends up on a command line. A profile holds the options its models take and their context size, per value of the contextWindow option or under * for one size. The schema does not check that slugs and aliases are unique, or that a defaultChoice names one of its choices.

ModelSelection is { model, options }, the options a record of strings and booleans. Parsing one checks its shape, not that the provider offers that model; the host's catalog normalizes it. ModelInfo is a model as provider.list describes it, with its options as ModelOptionDescriptors: a select with choices and a defaultChoice, or a boolean with a defaultValue.

Providers ​

ProviderInfo is one CLI as provider.list reports it: whether it is installed, its version, its models and defaultModel, its capabilities and its resumeCommand. Draw a control only when the 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.
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.

resumeCommandFor(template, sessionId, flags = []) fills a resumeCommand. It quotes the session id for a shell and puts the flags where the template has a {flags} word. The flags go in as they are: 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'

Runtime modes ​

RuntimeModeSchema is the permission policy of a chat, one vocabulary for every provider: supervised, auto-accept-edits, auto and full-access, from narrowest to widest. Each host adapter maps it onto its CLI; see Providers for the mapping of the built-in ones. A chat keeps the mode it asked for in runtimeMode and the mode the CLI confirmed in effectiveRuntimeMode; show the second when there is one.

Accounts ​

An account of a CLI is one config folder of it, handed to the CLI through the variable it reads that folder from. The person signs in with the CLI itself.

ProviderAccountIdSchema is a slug: a lowercase letter, then up to 63 lowercase letters, digits, underscores or hyphens. It is never a path. No account, or an id equal to the provider's kind, is the CLI's default account.

ProviderAccount is { kind, label?, color?, enabled?, home?, shadowHome?, env? }. Absent enabled is on. home is the config folder, ~ allowed, and absent on the default account. shadowHome is for Codex only: a folder of its own for the login that shares everything else with home. kind stays a plain string, so the record of a CLI an older host does not know still parses and goes back unchanged.

ProviderAccountVariable is { name, value, sensitive, valueRedacted? }, set on the CLI's environment. The host never sends a sensitive value: it sends value: '' with valueRedacted: true, and a save that sends that back keeps the stored secret. secretsAvailable on the snapshot says whether the host can keep one at all.

ProviderAccountStatus is what the CLI said about an account the last time it was asked, never stored. Its state is checking, disabled, not-found, signed-out, ready, folder-missing, unavailable or failed, with email, plan, organization and a message when the CLI gave them. transcripts is where the account writes its conversations: a chat can move to another account only when both write there.

RequestPayload and answer
accounts.listThe snapshot: accounts, statuses, secretsAvailable?, loginCommands?.
accounts.saveThe whole map. An id left out is removed; its folder stays.
accounts.create{ kind, label, color? }, with a label of 1 to 80 characters after trimming. Answers the snapshot and the new id.
accounts.refreshAsks every CLI again and answers when all did.
accounts.watchLogin{ id }: answers at once and asks the CLI every few seconds until the account is signed in.

Terminal agents ​

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

  • AgentInfo is the session a terminal runs: its kind, agentSessionId, transcriptPath, status, and live, which is false once the host restarted and the session can only be resumed. SessionStatusEvent carries it per terminal session.
  • AgentResumePayload names a session to resume.
  • ApprovalRequest is a permission the agent in a terminal waits on, with the choices to offer (allow, remember or deny) and an expiresAt. The CLI asks in its own prompt at the same time, so whoever answers first wins. SessionApprovalsEvent carries a session's whole pending list. ApprovalAnswerPayload names the choice, and ApprovalAnswerResult.accepted is false when the request had already settled.
  • ApprovalPreferencePayload says whether one client wants these requests at all. A client that never sends it gets them.

SuggestedTitleSchema is a title the CLI gave a session, at most SUGGESTED_TITLE_LIMIT (80) characters. A model wrote it, so show it as plain text. SessionIdSchema is a terminal session id, any nonempty string the client picks.

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