# Agent

> An agent definition.

`@kindgi/specs/agent.schema.json`, schema version 1.6.0.

An agent definition. Declarative composition of instructions + capabilities + tools + memory retrieval + guardrails + conversation policy. The same definition is durable across restarts and versioned like flows — provenance references agents by (id, version).

- `id` (string, required): Agent identifier. Convention: '\<pack>.\<agent>' (e.g. 'acme.citation-verifier').

- `version` (string, required): Semver identifying this iteration of the agent. Different versions are different agents for audit purposes.

- `name` (string, required): Human-readable display name.

- `description` (string): Prose describing what the agent does. Shown in catalog + provenance metadata.

- `instructions` (string or [PromptRef](https://docs.kindgi.com/v0.1.8/reference/schemas/agent.md#promptref), required): System-prompt rendered at the top of every turn. LiquidJS template — {{ variable }} substitution, {% if %} / {% for %} control flow, {{ value | filter }} filters. Every referenced variable must be a declared PromptParameter or a framework auto-var (today, now, agent._, conversation._, settings). Rendered with strictVariables — unresolved refs are hard errors. Or a prompt block by range ({ prompt, version }): its template and parameters are used instead, at the version pinned when the agent version is published.

- `settings` (array of [BlockRef](https://docs.kindgi.com/v0.1.8/reference/schemas/agent.md#blockref)): Settings blocks the agent reads, by range: tools read them as ToolContext.settings\['\<id>'], templates as settings\["\<id>"]. Pinned when the agent version is published.

- `modelSettings` ([BlockRef](https://docs.kindgi.com/v0.1.8/reference/schemas/agent.md#blockref)): A model-settings block by range: its temperature and maxOutputTokens go into the turn's model calls. Pinned when the agent version is published.

- `parameters` (array of [PromptParameter](https://docs.kindgi.com/v0.1.8/reference/schemas/agent.md#promptparameter)): Typed parameters supplied at invoke time. UI reads this to build a configuration form; runtime validates required parameters are provided before the model call.

- `capabilities` (array of object, required): Capability declarations consumed by the router at turn time. One entry per resource kind the agent needs (e.g. LLM inference, embedding, gpu-compute). The router matches each entry by its kind (`Capability.kind`, default `llm-inference`) and its requirements; the array shape lets new kinds arrive without a schema break.

- `tools` (array of [ToolRef](https://docs.kindgi.com/v0.1.8/reference/schemas/agent.md#toolref), required): Tools the agent may invoke, as `{ id, version }` references; an empty array makes the agent chat-only. At run start each reference resolves to the highest registered version that satisfies its range; an unresolvable reference fails the turn. Schema-version 1.1.0 replaced the bare-string tool ids of 1.0.0, which `defineAgent` already rejected.

- `retrieval` (array of [RetrievalIntent](https://docs.kindgi.com/v0.1.8/reference/schemas/agent.md#retrievalintent), required): Fact-retrieval intents run before every turn to ground the model's context. Each sees only what the run may (its project and org, the user it acts for, its conversation and that conversation's end user, and tenant-wide facts); retrieved facts reach the model as a labelled data block, never as instructions. Schema-version 1.4.0 adds the `same-user` scope and `memory`; 1.5.0 adds `memory.remember`; 1.6.0 adds `source: conversations` and `same-segment`.

- `memory` (object): How the agent uses what it retrieves.

  - `instructionTypes` (array of string): Fact types that are instructions for this agent: a retrieved fact of one of these types that a person verified goes into the system message under 'Policies (verified)'. Default: none, every retrieved fact is data.

  - `remember` (object): Lets the agent remember: its turns offer the built-in tool `kindgi_remember` (built-in tools are `kindgi_<verb>`; an agent can't list one in `tools`). The model picks the type, the text (up to 2,000 characters), an optional slot `key` and when it stops being true; the scope comes from here and the run. Every remembered fact is `unverified`, attributed to the agent version and the call that wrote it, and expires after `keepDays` unless a person verifies it. A person approves it before any read sees it when the scope is wider than one person (`same-project`, `tenant`) or the text reads like an instruction.

    - `types` (array of string, required): The fact types it may write.
    - `scope` (`"same-user"` | `"same-conversation"` | `"same-project"` | `"tenant"`, required): Where its facts go: the conversation's end user (else the user the run acts for), the conversation, the run's project, or the tenant. Each but `tenant` includes the run's project.
    - `keepDays` (integer): Days an unverified fact is kept. Default 30.

- `guardrails` (array of string, required): Guardrail ids the agent is subject to. Resolved at turn start against the guardrails bound for the run (an unknown id fails the turn); evaluated on each turn's final response, before it is stored.

- `preferredProvider` (string): Preferred model provider id. Soft hint: the router prefers this provider when it satisfies the agent's capabilities and tenant policy, and otherwise routes normally.

- `preferredModel` (string): Preferred model name within the selected provider. Soft hint, combined with preferredProvider.

- `conversationPolicy` ([ConversationPolicy](https://docs.kindgi.com/v0.1.8/reference/schemas/agent.md#conversationpolicy))

- `budget` ([TurnBudget](https://docs.kindgi.com/v0.1.8/reference/schemas/agent.md#turnbudget))

- `tags` (array of string): Free-form filter tags for the catalog. Not consumed by execution.

- `output` ([AgentOutputSpec](https://docs.kindgi.com/v0.1.8/reference/schemas/agent.md#agentoutputspec))

- `toolErrors` ([ToolErrorsSpec](https://docs.kindgi.com/v0.1.8/reference/schemas/agent.md#toolerrorsspec))

## Definitions

### PromptRef

- `prompt` (string, required)
- `version` (string, required): A semver range.

### BlockRef

- `id` (string, required)
- `version` (string, required): A semver range.

### ToolErrorsSpec

What the turn does when a tool call fails (schema-version 1.3.0): the failure goes back to the model as the call's result, so it can correct the call, up to `maxRetries` times per turn, for the kinds in `retryOn`. Default: one retry, for `invalid-arguments` and `unknown-tool`. A tenant `tool-errors` policy can lower it.

- `maxRetries` (integer): Failed calls sent back to the model per turn. Default 1.
- `retryOn` (array of `"invalid-arguments"` | `"unknown-tool"` | `"tool-error"`): Which failures are sent back: arguments that don't fit the input schema, a tool the agent doesn't have, a tool that ran and failed. Default `invalid-arguments`, `unknown-tool`.

### AgentOutputSpec

A typed result (schema-version 1.2.0): the final answer must be JSON matching `schema`. An invalid answer is sent back to the model with the problems listed, up to `maxRepairs` times; then the turn fails with `output-schema-violation`.

- `schema` (object, required): JSON Schema (draft 2020-12) the final answer must match.
- `name` (string): A name for the output, shown to the model and in errors. Default `output`.
- `maxRepairs` (integer): How many times the model is asked to repair an invalid answer. Default 1.

### ToolRef

A typed tool reference: a tool id plus a semver range. Bare-string ids are not accepted — every reference names both.

- `id` (string, required): Tool id (e.g. 'acme.verify-citation'). Must not be blank.
- `version` (string, required): npm-style semver range: '1.2.3' pins exactly, '^1.2.3' allows compatible updates, '\~1.2.3' patch updates only, '>=1.0.0 <2.0.0' an explicit range. Must not be blank; the range grammar is checked when the reference resolves at run start.

### PromptParameter

- `name` (string, required): Variable name referenced in the instructions template. Must NOT collide with reserved auto-var namespaces: today, now, agent, conversation.
- `description` (string): UI-facing description of what the caller should supply.
- `type` (`"string"` | `"number"` | `"boolean"` | `"date"`, required)
- `required` (boolean): Default true. Set false to allow the parameter to be omitted.
- `default` (object): Value used when the caller omits this parameter. Must match the declared type.

### RetrievalIntent

- `source` (`"facts"` | `"conversations"`): What it reads: facts (the default), or messages of this agent's earlier conversations, quoted in the turn's `<memory>` block as earlier conversation, never as turns. Schema-version 1.6.0.
- `types` (array of string): The fact types it retrieves: required for facts, absent for conversations.
- `roles` (array of `"user"` | `"agent"`): For conversations: whose messages it recalls. Default \["user"], the people's own words. Adding "agent" recalls the agent's earlier answers too, which can carry its mistakes: they are quoted as unverified earlier answers, and publishing warns.
- `scope` (`"same-conversation"` | `"same-user"` | `"same-segment"` | `"same-project"` | `"tenant"`, required): What the intent selects within what the run may see. Facts: this conversation's; the run's end user's only (`same-user`: none when the run names no `participantId`); the run's project's (none without a project); or every fact of the type it may see (`tenant`). Conversations: this end user's other conversations with the agent (`same-user`: none when the run names no `participantId`); this conversation's messages older than the history window (`same-conversation`); conversations in the run's segment path (`same-segment`) or its project (`same-project`), whoever had them: those two quote other people's conversations. `same-segment` is for conversations only, `tenant` for facts only.
- `limit` (integer): Cap on facts (or recalled messages) per turn. Default 10.
- `mode` (`"keyword"` | `"semantic"` | `"both"`): With the user's message as the query: full-text (`keyword`), by meaning (`semantic`, which fails the turn with `semantic-unavailable` on a runtime without embeddings), or both fused by rank (without embeddings, the keyword half). Absent: the newest facts (or messages), no query.

### ConversationPolicy

- `historyLimit` (integer)
- `autoCloseAfterInactiveSeconds` (integer)
- `hitlAfterTurns` (integer)

### TurnBudget

- `maxSteps` (integer): Maximum model→tool→model iterations per turn. Default 8.
- `maxCostUsd` (number): Maximum USD spend per turn.
- `maxWallMs` (integer): Wall-clock cap in ms. Default 120000.
