Skip to content

Profiles

Profiles are named, reusable agent configuration. A profile describes how a model call should run: its backend, instructions, tools, permissions, and optional children. Defining or applying a profile does not start a model call, create a conversation, or run its tools.

A procedure describes executable steps; a profile supplies configuration to those steps. A child profile describes a separate agent invocation that a parent may request. These are different roles even when they share the same tools.

Define a Profile

> profile: reviewer:
    ###
    Reviews one change against repository evidence.
    ###
    > adapter: pydantic
    > model: openai:gpt-5.6-luna
    > effort: medium
    > system: Cite the evidence used for every finding.
    > settings:
        timeout: 120

A profile body contains directives, not an executable procedure body:

Concern Members Meaning
Backend adapter, agent, model, effort Select execution backend and model behavior.
Instructions system, settings Supply instructions and supported runtime/model settings.
Tools use, mcp, skills Expose procedures, external tools, and skill discovery.
Permissions and lifecycle approval, hooks Mediate sensitive calls and lifecycle boundaries.
Context history, artifacts Configure conversation retention and artifact handling.
Tool execution codemode Enable the code-based tool interface.
Child agents subagent, max_agents, workflow, output Define delegation, its budget, orchestration mode, and a default child result type.

Choose either adapter or agent within a profile, not both. Profiles are top-level declarations. Tools referenced by the profile must exist; declaring their names does not implement them.

Profile Documentation

When a ### block is the first profile member, it becomes the profile docstring. The LSP shows it in hover and subagent tool descriptions. A later block remains an ordinary comment.

Document what task the profile owns, what evidence it should return, and any important limitation. Child-agent descriptions depend on this text.

Apply a Profile

Single-line > use: applies a profile when no procedure with that name exists:

> use: reviewer

>> A review of the current change is [review: str].
= <review>

If a procedure and profile share a name, the procedure wins and is registered as a tool. Avoid such collisions.

Merge Rules

Applying a profile merges it into the state already active at that location. It is not a reset to an empty configuration:

Member Composition rule
Backend, model, effort, system, approval, output type, maximum starts, workflow mode A specified value replaces the earlier value. System instructions are replaced, not concatenated.
Settings Merge by key; later values replace the same key. Nested dictionaries are not recursively merged.
Tools and children Merge by name. Later bindings win, and reintroduced names move to the end of the ordered list.
MCP servers Append in declaration/application order.
Hooks Compose per event; a supplied empty handler list clears that event's local handlers. Inherited enforcement is a separate boundary.
Skills, CodeMode, history/compaction Supplied configuration replaces the corresponding earlier configuration.
Artifacts Overlay the explicitly supplied policy fields.
Omitted members Keep their earlier values.

An empty tools list is not a request to revoke tools inherited through profile composition. For a separate restricted agent, define a child with its own tool surface and use delegation. See Hooks for inherited handlers that child code cannot disable.

Direct directives after profile application can override profile members:

> use: reviewer
> effort: high

The result retains the reviewer's configuration and changes effort to high. The selected provider must support that effort value.

Profile application and direct directives follow source order. A direct directive does not have unconditional priority: a profile applied after it can replace it. Procedures capture the configuration at their definition site; see Scoping and Capabilities.

Default Child Result Type

~Finding(path: str, explanation: str)

> profile: reviewer:
    ###
    Reviews supplied evidence and returns actionable findings.
    ###
    > adapter: pydantic
    > model: openai:gpt-5.6-luna
    > system: Base findings only on the evidence supplied in the task.
    > output: list[Finding]

When a parent delegates to reviewer without supplying final_schema, this output type supplies the child's result schema. The returned envelope contains run_id, subagent, task_summary, and the validated final_result. An explicit final_schema on the child call takes precedence over > output:. Without either schema, the child returns its text in task_summary and has no structured result.

This is a child-result contract, not a way to change the types of unrelated template captures. A template's [finding: Finding] still declares its own output type. The profile type must be representable as JSON Schema; declaring two output members is an error.

Export and Import Profiles

Profiles are module values and can be explicitly exported:

> profile: reviewer:
    > adapter: pydantic
    > model: openai:gpt-5.6-luna

> export:
  reviewer

Imported profiles retain private tool and child-profile bindings needed by their contract without flattening those dependencies into the importer's procedure namespace. This lets a package expose a profile facade while keeping helpers private.

Forward References and Validation

A profile can name a child profile declared later. Kedi resolves the complete profile graph and rejects unknown children and cycles.

Within one profile, framework and harness selection remain mutually exclusive. Invalid backend kinds, unknown members, duplicate output/workflow declarations, invalid settings, nonpositive max_agents, missing tools, and unsupported required capabilities produce diagnostics or compile-time errors.

Child Profiles

> profile: coordinator:
    > adapter: pydantic
    > subagent: researcher
    > max_agents: 3
    > workflow: dynamic

> profile: researcher:
    > adapter: pydantic
    > system: Investigate one self-contained question.

Only directly listed children can be delegated to. max_agents bounds the descendant work started by one parent invocation. Workflow mode defaults to delegate; dynamic exposes one sandboxed Python orchestration tool. See Subagents for lifecycle and safety rules.

Choosing Profile Boundaries

Create a profile when a task needs a stable combination of behavior and capabilities. Do not create one merely to alias a model string. Profiles should be narrow enough that their tools, approvals, and child relationships can be reviewed as a coherent security boundary.