---
title: "Identity, instructions and tools"
description: "Agent definition fields for identity, instructions and tools."
canonical_url: "https://docs.oz0.ai/reference/agent-definition/identity"
---
# Identity, instructions and tools

> Agent definition fields for identity, instructions and tools.

For: Plugin authors looking up agent fields.

Look up the fields below when editing an agent definition.

<field-group>
<field name="name" type="string" :required="true">

Lowercase letters, digits and dashes. Unique per tenant; jobs address the agent by it, on its plugin's task queue (`pool.<plugin>`, or `pool.<plugin>.<labels>` when it requires labels; with [shared pools](https://docs.oz0.ai/concepts/routing#shared-pools), the pool of its plugin's node selector and its labels).

</field>

<field name="description" type="string">

What the agent does. Agents that may delegate to this one see it.

</field>

<field name="runtime" type="string">

Left out, `pydantic-ai`. `pydantic-ai`, `openai-agents` (the OpenAI Agents SDK, which speaks only the OpenAI Responses and Chat formats; see [choosing a framework](https://docs.oz0.ai/build/parts/agents#choosing-a-framework)), `harness:<name>` (with a harness plugin) or `remote:<name>` (the agent's loop runs at a provider, see [Remote agents](https://docs.oz0.ai/build/apps/remote-agents)).

</field>

<field name="instructions" type="string">

The system prompt: a path to a file in the plugin. A Markdown agent has none: its body is the prompt.

</field>

<field name="tools" type="string[]">

`<tool>.<function>` names of this plugin's tools, another plugin's functions by address (`github/oz0_github.get_file`), and built-ins. A bare name of another plugin's function still works and is a lint warning ([OZ-S019](https://docs.oz0.ai/build/plugins/structure/lint-rules#oz-s019)); a function of a plugin `uses:` does not list is a warning, since that plugin must be installed and granted too.

A tool ID belongs to one plugin per tenant, so a name always means one plugin's server, whichever plugin the agent comes from: the address names that plugin, and the loader checks it. A job whose agent lists a tool that two plugins of the tenant provide (a clash from before installs refused that) fails when it starts, with error type `ToolClash`.

An agent on an [ACP harness](https://docs.oz0.ai/build/parts/harnesses/acp#agents-that-speak-acp) gets these tools as one MCP server whose calls run through the job; a JSON-lines harness agent uses only `oz.ask_user` here. Lint warns about other tools on a JSON-lines harness agent, and on an agent whose harness another plugin provides when that harness is not one of the official ones it knows.

</field>

<field name="input" type="string">

`text`: the agent takes text. Declare this or `input_schema`; `plugin lint` warns when an agent has neither, and from v1.0 it is an error.

</field>

<field name="output" type="string">

`text`: the agent answers in text. Declare this or `output_schema`, as for the input.

</field>

<field name="input_schema" type="string">

A path to a JSON Schema file. A job whose input does not match fails with `InvalidInput` before the agent starts.

</field>

<field name="output_schema" type="string">

A path to a JSON Schema file. The model answers in that structure; a non-matching answer goes back to it, at most twice. A matching answer is drawn as a card (a table, key-values, a diff or text); two keywords shape it: `x-oz0-order`, a list of property names shown first, and `x-oz0-diff: {before, after}`, the two properties a diff compares, which lint checks name two different properties ([results drawn as cards](https://docs.oz0.ai/build/parts/contracts-and-limits#results-drawn-as-cards)).

</field>

<field name="failures" type="list">

The kinds of failure the agent may end a job with, beside the platform's own: part of its contract, which callers branch on. Each has `kind` (lowercase letters, digits and `_`, at most 40, unique, never one of the platform's kinds such as `timeout` or `undeclared`), `description` (required, at most 200 characters), and `retryable`, `partial` and `person`, false when left out. At most 32. The agent ends a job with one through `oz.fail`, which it lists under `tools:`. A new kind, or a flag that asks more of callers, is a breaking change ([failure kinds](https://docs.oz0.ai/build/parts/contracts-and-limits/failures#failure-kinds)).

</field>

<field name="harness" type="map">

Options for the harness, passed on as they are, for agents with `runtime: harness:<name>` or `remote:<name>`. A [remote agent](https://docs.oz0.ai/build/apps/remote-agents#the-agent-definition)'s are `tools`,

`requires_approval`, `max_budget_usd`, `session_hour_usd`, `workspace` and `keep_session`; it has no `api_url`, which only a node's operator sets.

An [outside A2A agent](https://docs.oz0.ai/build/apps/remote-agents/a2a#outside-a2a-agents)'s (`runtime: remote:a2a`) are `card`, `skill`, `key`, `signature`, `jwks`, `version`, `auth`, `task_usd`, `poll` and `session_header`. See [Harnesses](https://docs.oz0.ai/build/parts/harnesses) for the Claude Agent SDK's. `requires_approval` lists the harness's tools whose calls each wait for a person's approval, for a harness that asks before each call.

For an [ACP harness](https://docs.oz0.ai/build/parts/harnesses/acp#agents-that-speak-acp), `tools` and `requires_approval` name ACP tool kinds, `mode` sets the session mode, `config` sets the agent's settings by ID, and `needs` adds client capabilities (`fs`, `terminal`) the session cannot work without. A `mode` other than the harness's, or any `config`, voids the harness's `acp.asks`, so such an agent cannot run a routine's fire or a shadow run.

</field>

<field name="skills" type="list">

The [skills](https://docs.oz0.ai/build/parts/skills) the agent gets, each `<plugin>/<skill>` or `<plugin>/*`, or a bare `<skill>` of its own plugin. Unset, it gets every skill of its own plugin; `[]` gives it none. Another plugin's skills load only when its plugin's [`uses:`](https://docs.oz0.ai/reference/plugin-manifest/dependencies#uses) declares them under `skills` and a tenant admin granted that. At most 64 entries.

Its index joins the start-up context after the instructions (under `limits.startup_tokens`), and the agent reads a body with `oz.skill`; a harness session gets them as a read-only folder.

Besides these, the agent gets the [manual](https://docs.oz0.ai/build/parts/skills#a-tools-manual) of each tool whose functions its `tools` names (another plugin's under its grant), whatever `skills` says, `[]` included. A remote agent gets none.

Or an object, `{use: [...], propose: {...}}`: `use` is the list above (left out, its own plugin's skills), and `propose` lets the agent [propose skills](https://docs.oz0.ai/build/parts/skills/usage-and-proposals#skills-an-agent-proposes) with `oz.propose_skill` for a person to review. `propose.into` names the plugin whose skills a proposal changes, `propose.apply` the function that opens the pull request (`<tool>.<function>`, another plugin's under `uses:`), `propose.repository` where that plugin's source lives (`owner/name`), `propose.path` its folder there (the root when left out), and `propose.arguments` fixed arguments of the apply call (at most 16; not `repository`, `base`, `patch`, `title`, `body` or `draft`, which the platform sets).

`propose.review` may only be `required`. Not for a remote agent, and not beside `changes:`. `skills: {}` sets nothing and means what leaving `skills` out means. ::

<field name="tool_loading" type="string">

`eager` (the default: the definition of every function in `tools` is in every model request) or `lazy`: the model gets the built-ins `oz.find_tools` and `oz.call_tool` in place of the plugin functions' definitions, the same two in every request, and finds and calls the functions it needs through them.

Every call is decided, approved, audited and traced as the real function's, and the search offers only what the agent may call now ([lazy tool loading](https://docs.oz0.ai/build/parts/agents#lazy-tool-loading)).

For `pydantic-ai`, `openai-agents` and ACP harness agents; lint warns that it does nothing for a JSON-lines harness or a remote agent. The agent does not list `oz.find_tools` or `oz.call_tool` itself.

</field>
</field>
</field-group>

<field name="tags" type="string[]">

Words that group agents for people's [agent grants](https://docs.oz0.ai/admin/tenants#roles-and-permissions): a membership granted `tag:hr` may start every agent tagged `hr`. At most 16, each lowercase letters, digits, `.`, `_` and `-`, at most 63 characters. Tags place nothing: `labels` decide which nodes run the agent.

</field>

::

[Back to the agent definition](https://docs.oz0.ai/reference/agent-definition).


## Sitemap

See the full [sitemap](https://docs.oz0.ai/sitemap.md) for all pages.
