Skip to content

Capability Definitions

kedi.Capability packages tools, guidance, and owned tool policies for reuse in Kedi programs. It is a contribution to an agent, not an agent constructor or a replacement for a profile.

Unreleased

This page describes the next Kedi release. Pydantic AI and LangChain support eager composition; Pydantic AI also supports deferred loading.

Define and Apply

Put the descriptor in the query environment, then apply it with > use::

import kedi


def read_revision() -> int:
    """Read the source revision from this example's local release record."""
    return 7


reader = kedi.Capability(
    name="reader",
    identity="example.release.reader",
    instructions="Read the current revision.",
    tools=(read_revision,),
    approval=kedi.ApprovalPolicy.allow(),
)


@kedi.query(env={"reader": reader}, approval="deny")
def current_revision() -> int:
    """kedi
    > use: reader
    >> The current source revision is [revision: int].
    = `revision`
    """
    ...

Configure a supporting adapter and model through the normal configuration API before calling current_revision(). The provider dependencies and credentials remain the application's responsibility.

The capability owns read_revision. Its local allow policy does not change the query's deny policy for unrelated tools. The capture is validated as an integer, and the backtick return preserves that native type.

Neither constructing reader nor executing > use: reader calls its tool. Default eager use makes the contribution available to subsequent model calls.

Constructor Contract

All arguments are keyword-only:

Argument Contract
name Required identifier used in diagnostics and discovery.
identity Optional stable qualified identity; defaults to python:<name>. Use a package-qualified value for published bundles.
description Optional discovery/catalog description.
instructions Optional additive user guidance.
tools Sequence of typed callables or ToolSpec objects. Callable metadata and retries use normal Kedi tool conversion. Duplicate exposed names are rejected.
mcp_servers Sequence of McpServerSpec definitions. Transport configuration stays separate from model instructions.
capabilities Nested Kedi descriptors, composed in order after this descriptor's own guidance.
subagents Mapping from child names to existing ProfileDefinition objects; names must match the definitions. This is an advanced binding surface, not a model override.
approval ApprovalPolicy or None, scoped to owned tools. Unlike query configuration, this constructor does not accept string policy names.
hooks HookSettings or event-handler mapping for owned tool lifecycle events only.
requires Sequence of canonical adapter requirements. Invalid names fail at construction.
defer A boolean, default False; no truthiness conversion from strings or numbers.

Callable names and descriptions honor @kedi.tool metadata. A ToolSpec can add an explicit tool policy, which takes precedence over the capability policy. Capability policies do not bypass independent mandatory enforcement.

Host model, effort, settings, history, budgets, artifacts, and tool-reason configuration are not constructor parameters. Use an agent/profile or a separate child invocation for those concerns. user_prompt_submit and disabling inherited hooks are not capability operations.

Composition and Reset

The language capability guide shows the same semantics with Kedi definitions, profile composition, and exported tools.

Capability instructions append to the current user guidance. Applying the same capability again does not duplicate its guidance or tools. An explicit > instructions: replaces all earlier user guidance in that scope, including capability contributions, even when the replacement text equals the old base.

The reset does not unregister tools or discard their policy. Explicit reuse restores the capability guidance once. Runtime-owned template, tool, and artifact contracts are separate and survive user-instruction resets.

Profiles retain their replacement semantics. A procedure retains its definition-site configuration, and a local instruction override does not change the outer agent. See Profiles and Agent Scope.

Deferred Loading

defer=True requires the adapter's deferred_tools support. It registers a discoverable capability whose tools and guidance activate through native loading; it does not create a hidden subagent or switch models. The initial mapping targets Pydantic AI. LangChain deferred use is rejected before inference rather than silently becoming eager.

Native loading may deliver guidance in a tool result. A later instruction reset does not erase that historical message. Deferral also does not promise delayed MCP connection establishment. Nested descriptors retain independent deferred boundaries: after loading the parent, its deferred children become discoverable and require separate loads. A child shared by multiple parents is registered once; any loaded parent or explicit direct use makes it discoverable.

Descriptors may contribute subagents while deferred. Their targets become available only after native activation, including shared delegation, workflow, background, continuation, and lifecycle controls. CodeMode schema discovery does not reveal inactive targets. See nested capability and subagent examples.

Reuse and Native Integration

Definitions snapshot input collections and mutable schema/MCP data while preserving executable tool identity. Each lowering receives its own data copies; activation and suppression state belong to a run, not to the shared descriptor. Do not mutate nested descriptor data as an alternative to defining a new bundle.

Imported Kedi profiles retain privately referenced Python capabilities, including across re-exports. A same-named object in the caller does not replace that private dependency.

as_profile() returns a fresh additive AgentProfile patch for low-level runtime integration. It performs no inference or activation. It is not a shortcut that registers tools on a standalone adapter; normal runtime tool binding is still required.

Native Pydantic AI capability objects are not portable Kedi descriptors. The native capabilities= option passed through kedi.configure or kedi.context still belongs to Pydantic AI. @kedi.query does not gain a capabilities= option; use its existing env plus > use: for Kedi descriptors.