Agents API¶
The agent runtime lives in kavalai.agents. The headline class is
Agent — a multi-step reasoning loop that calls
tools through a FunctionKernel until it produces a final,
optionally structured, answer.
Agent¶
-
class kavalai.agents.agent.ToolCall(*, name: str, literal_args: str =
'{}', planner_context_args: str ='{}', input_args: str ='{}', call_id: str | None =None)[source]¶ Bases:
BaseModelThis data structure represents tool call requests.
Arguments are expected to be JSON encoded to help LLM models encode the data.
-
model_config : ClassVar[ConfigDict] =
{'extra': 'forbid'}¶ Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
-
model_config : ClassVar[ConfigDict] =
-
kavalai.agents.agent.get_step_output_type(ResponseModel=
typing.Type[pydantic.main.BaseModel])[source]¶
-
class kavalai.agents.agent.Agent(llm_client: BaseLlmClient, *, kernel: FunctionKernel | None =
None, run_context: RunContext | None =None, prompt_template: Template | None =None, debug: bool =False)[source]¶ Bases:
object-
async prompt(prompt: str, response_model: type[BaseModel] | None =
None, max_steps: int =10) str | BaseModel[source]¶ Run the agent loop, calling tools until it produces a final output.
The agent iterates up to
max_stepstimes. On each step the LLM returns aStepOutputwith optionaltool_callsand an optional finaloutput. Tool calls are executed through theFunctionKerneland their results are fed back into the prompt so the model can reason over them on the next step. The loop stops once the model returns anoutputwithout requesting further tool calls, or whenmax_stepsis reached.
-
async prompt(prompt: str, response_model: type[BaseModel] | None =
Run context¶
Copyright 2026 OÜ KAVAL AI (registry code 17393877)
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
-
class kavalai.agents.run_context.RunContext(*, agent_id: UUID | None =
None, session_id: UUID | None =None, run_id: UUID | None =None, data: dict ={}, templates: dict[str, str] ={}, agent_service: Any | None =None)[source]¶ Bases:
BaseModelRuntime data for a single interaction.
-
model_config : ClassVar[ConfigDict] =
{'arbitrary_types_allowed': True}¶ Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- resolve_context_value(path: str)[source]¶
Resolve a dotted path like ‘input.user_message’ from context data.
- async render_prompt(prompt: str) str[source]¶
Render a prompt string by replacing {{ templates.NAME }}, {{ context.PATH }}, and {{ history.PATH }} with their resolved values.
- async resolve_input_info(info: ArgumentInfo)[source]¶
Resolve a TypeInputInfo to its actual value.
-
model_config : ClassVar[ConfigDict] =
Workflow configuration models¶
Copyright 2026 OÜ KAVAL AI (registry code 17393877)
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Shared workflow building blocks reused across the codebase (input wiring,
server/tool declarations and the workflow exception). The v2 workflow engine
lives in kavalai.workflow.
- exception kavalai.agents.workflow_model.WorkflowException[source]¶
Bases:
ExceptionBase exception for errors building, validating or running a workflow.
-
class kavalai.agents.workflow_model.ArgumentInfo(*, type: 'literal' | 'context' | 'history', value: BaseModel | str | int | float | bool | None =
None, name: str | None =None)[source]¶ Bases:
BaseModelDescribes input arguments in workflow YAML files.
The ‘type’ field describes where the input argument should be retrieved from. ‘literal’ - use value as specified ‘context’ - retrieve from agent run context ‘history’ - retrieve from previous agent run contexts.
-
model_config : ClassVar[ConfigDict] =
{}¶ Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
-
model_config : ClassVar[ConfigDict] =
-
class kavalai.agents.workflow_model.RestServer(*, name: str, url: str | None =
None, url_env: str | None =None, username_env: str | None =None, password_env: str | None =None)[source]¶ Bases:
BaseModelDefines a REST server.
We also support HTTP Basic Auth for REST server endpoints, which are defined via environment variables username_env and password_env.
Note that url_env can also be read from the env file.
- check_url_configs() RestServer[source]¶
-
model_config : ClassVar[ConfigDict] =
{}¶ Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
-
class kavalai.agents.workflow_model.McpServer(*, name: str, command: str | None =
None, command_env: str | None =None, args: list[str] =[], env: dict[str, str] ={}, url: str | None =None, url_env: str | None =None)[source]¶ Bases:
BaseModelDefines an MCP server.
-
model_config : ClassVar[ConfigDict] =
{}¶ Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
-
model_config : ClassVar[ConfigDict] =
- class kavalai.agents.workflow_model.PythonFunction(*, name: str, path: str)[source]¶
Bases:
BaseModelDeclares a Python tool available to a workflow.
- Variables:¶
-
model_config : ClassVar[ConfigDict] =
{}¶ Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class kavalai.agents.workflow_model.TemplateModel(*, name: str, value: str)[source]¶
Bases:
BaseModelA named, reusable text template referenced within a workflow.
- Variables:¶
-
model_config : ClassVar[ConfigDict] =
{}¶ Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
Agent service & persistence¶
Copyright 2026 OÜ KAVAL AI (registry code 17393877)
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- class kavalai.agents.agent_service.AgentService(session_maker: async_sessionmaker[AsyncSession])[source]¶
Bases:
objectProvider common database operation for Agents.
-
async get_or_create_agent(name: str, description: str | None =
None, input_schema: dict | None =None, output_schema: dict | None =None, workflow: dict | None =None) Agent[source]¶ Finds an agent by name or creates a new one if not found.
-
async get_or_create_session(agent_id: UUID, session_id: UUID | None =
None, external_id: UUID | None =None) Session | None[source]¶
-
async create_run(session_id: UUID, input_data: dict | None =
None, context: dict | None =None) Run[source]¶ Creates a new run entry for a specific session.
-
async initialize_workflow_run(agent_name: str, agent_description: str | None =
None, input_schema: dict | None =None, output_schema: dict | None =None, workflow: dict | None =None, session_id: UUID | None =None, external_id: str | None =None, input_data: dict | None =None) tuple[Agent, Session, Run][source]¶ Initialize agent, session, and run in a single database transaction.
This is an optimized batch operation that reduces 3 DB roundtrips to 1, improving performance especially for remote databases.
- Returns:¶
tuple of (agent, session, run)
-
async update_run(run_id: UUID, *, output_data: dict | None =
None, context: dict | None =None) Run[source]¶ Updates an existing run with final output_data and/or context.
-
async add_task(session_id: UUID, run_id: UUID, name: str | None =
None, agent_id: UUID | None =None, inputs: dict | None =None, output: dict | None =None, prompt: str | None =None, errors: list[str] | None =None, duration_seconds: float | None =None, node_type: str | None =None) Task[source]¶ Records a specific unit of work (Task) performed within a run.
-
async add_model_call_stats(stats: ModelCallStat, agent_id: UUID | None =
None) ModelCallStat[source]¶ Records LLM/Embedding call statistics.
- async get_history_value(session_id: UUID, key: str) Any | None[source]¶
Retrieves a value from the context of previous runs in the same session.
If key is a dotted path (e.g., “output.search_results”), resolves it as such.
If key is a plain name (e.g., “search_results”), searches recursively for the first matching key in the context dicts of previous runs (newest first).
Returns the most recent value found for the given key.
-
async get_chat_history(session_id: UUID, limit: int =
50) list[ChatMessage][source]¶ Retrieves the conversation history for a session, ordered from oldest to newest.
-
async get_or_create_agent(name: str, description: str | None =
Copyright 2026 OÜ KAVAL AI (registry code 17393877)
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- class kavalai.agents.sessions.SessionSummary(*, session_id: UUID, agent_id: UUID, agent_name: str, runs_count: int, tasks_count: int, messages_count: int, first_message: str | None, last_message: str | None, errors_count: int, created_at: datetime, updated_at: datetime)[source]¶
Bases:
BaseModelRow-level summary of a session for the Conversations list.
Aggregates a session’s owning agent, its run/task/message and error counts, and a preview of its first and last messages.
-
model_config : ClassVar[ConfigDict] =
{}¶ Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
-
model_config : ClassVar[ConfigDict] =
-
class kavalai.agents.sessions.TaskSummary(*, id: UUID, agent_id: UUID | None, session_id: UUID, run_id: UUID, inputs: Any | None, output: Any | None, name: str | None =
None, prompt: str | None =None, errors: list[str] | None =None, duration_seconds: float | None =None, created_at: datetime, updated_at: datetime)[source]¶ Bases:
BaseModelSummary of a single task (workflow-node execution) for the Tasks view.
Exposes the task’s inputs, output, name, prompt, any errors and duration.
-
model_config : ClassVar[ConfigDict] =
{'from_attributes': True}¶ Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
-
model_config : ClassVar[ConfigDict] =
- class kavalai.agents.sessions.RunSummary(*, id: UUID, session_id: UUID, input_data: Any | None, output_data: Any | None, context: Any | None, tasks_count: int, created_at: datetime, updated_at: datetime)[source]¶
Bases:
BaseModelSummary of a single workflow run for the Runs view.
Exposes the run’s input/output data, resolved context and the number of tasks it executed.
-
model_config : ClassVar[ConfigDict] =
{'from_attributes': True}¶ Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
-
model_config : ClassVar[ConfigDict] =
- class kavalai.agents.sessions.ChatMessageSummary(*, id: UUID, agent_id: UUID, session_id: UUID, run_id: UUID | None, role: str, content: str, created_at: datetime, updated_at: datetime)[source]¶
Bases:
BaseModelSummary of a single chat message for the conversation transcript.
Exposes the message’s role, content and the run it is associated with.
-
model_config : ClassVar[ConfigDict] =
{'from_attributes': True}¶ Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
-
model_config : ClassVar[ConfigDict] =
- class kavalai.agents.sessions.SessionDetails(*, session_id: UUID, messages: list[ChatMessageSummary], runs: list[RunSummary], tasks: list[TaskSummary])[source]¶
Bases:
BaseModelFull detail of one session: its messages, runs and tasks.
Powers the per-conversation detail view in the backoffice, bundling the session’s chat transcript together with all of its runs and tasks.
- messages : list[ChatMessageSummary]¶
- runs : list[RunSummary]¶
- tasks : list[TaskSummary]¶
-
model_config : ClassVar[ConfigDict] =
{}¶ Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class kavalai.agents.sessions.SessionsResponse[source]¶
Bases:
TypedDict- sessions : list[SessionSummary]¶
-
async kavalai.agents.sessions.get_sessions_summary(session: AsyncSession, agent_id: UUID | None =
None, search: str | None =None, start_date: datetime | None =None, end_date: datetime | None =None, limit: int =50, offset: int =0) SessionsResponse[source]¶
- async kavalai.agents.sessions.get_session_details(session: AsyncSession, session_id: UUID) SessionDetails[source]¶
Remote agent client¶
Copyright 2026 OÜ KAVAL AI (registry code 17393877)
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
-
class kavalai.agents.client.AgentClient(base_url: str, username: str | None =
None, password: str | None =None, timeout: float =60.0)[source]¶ Bases:
objectAsync HTTP client for invoking a remote Kaval.AI agent server.
Wraps the agent server’s
/run_agentand/stream_agentendpoints, discovering the agent’s input/output schemas from its OpenAPI spec and transparently maintaining the conversationsession_idacross calls so successive invocations share the same session. Optional HTTP Basic Auth is used when bothusernameandpasswordare provided.- Parameters:¶
- async discover_schemas()[source]¶
Fetch the server’s OpenAPI spec and derive the agent’s schemas.
Populates
self.input_schemaandself.output_schemawith the Pydantic models for the agent’s request and response payloads. Called automatically byrun_agent()andstream_agent()on first use, but may be invoked directly to inspect the schemas up front.
-
async run_agent(data: BaseModel, external_id: str | None =
None) BaseModel[source]¶ Run the agent once and return its complete response.
Sends
datato the server’s/run_agentendpoint, blocking until the run finishes. Updatesself.session_idfrom the response so the next call continues the same conversation.
-
async stream_agent(data: BaseModel, external_id: str | None =
None)[source]¶ Run the agent and stream its output incrementally.
Sends
datato the server’s/stream_agent(Server-Sent Events) endpoint and yields eachdata:chunk as a string as it arrives, letting callers consume partial output before the run completes.
RAG service¶
Copyright 2026 OÜ KAVAL AI (registry code 17393877)
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
-
class kavalai.agents.rag_service.RagServiceResult(*, id: UUID, model: str, collection_name: str, source_id: str, content: str | None =
None, embedding_size: int, rag_metadata: dict, similarity: float, created_at: datetime | None =None, updated_at: datetime | None =None, query_index: int | None =None)[source]¶ Bases:
BaseModelRepresents a single result from a RAG query.
- Variables:¶
- id : UUID¶
Unique identifier of the indexed item.
- model : str¶
The embedding model used for this item.
- collection_name : str¶
The name of the collection this item belongs to.
- source_id : str¶
An external identifier for the source of this item.
- content : Optional[str]¶
The original text content that was indexed.
- embedding_size : int¶
The dimension of the embedding vector.
- rag_metadata : dict¶
Additional metadata associated with the item.
- similarity : float¶
The similarity score (1.0 - distance) relative to the query.
- created_at : Optional[datetime]¶
Timestamp when the item was created.
- updated_at : Optional[datetime]¶
Timestamp when the item was last updated.
- query_index : Optional[int]¶
Index of the query in batch queries (for batch_query results).
-
model_config : ClassVar[ConfigDict] =
{}¶ Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
-
class kavalai.agents.rag_service.RagService(session_maker: async_sessionmaker[AsyncSession] | Callable[[], AbstractAsyncContextManager[AsyncSession]], model: str, agent: Agent | None =
None, normalizer: Normalizer | None =None)[source]¶ Bases:
objectService for indexing and querying text using embeddings (Retrieval-Augmented Generation).
This service provides methods to batch index text, delete items, query similarities, and compute similarity matrices against indexed content.
-
classmethod from_uri(uri: str, model: str, agent: Agent | None =
None, normalizer: Normalizer | None =None) RagService[source]¶ Create a RagService from a database URI.
-
classmethod from_session_maker(session_maker: async_sessionmaker[AsyncSession], model: str, agent: Agent | None =
None, normalizer: Normalizer | None =None) RagService[source]¶ Create a RagService from a session maker.
-
async batch_index(*, texts: list[str], metadata_list: list[dict], source_ids: list[str] | None =
None, collection_name: str ='default') list[RagIndex][source]¶ Index multiple text items in a single batch.
- Parameters:¶
- texts : list[str]¶
List of text strings to index.
- metadata_list : list[dict]¶
List of metadata dictionaries for each text.
- source_ids : Optional[list[str]]¶
Optional list of source identifiers. If not provided, “default” is used.
- collection_name : str¶
Name of the collection to add items to. Defaults to “default”.
- Returns:¶
List of created RagIndex database objects.
- Return type:¶
list[RagIndex]
- Raises:¶
ValueError – If the lengths of texts, metadata_list, or source_ids do not match.
- async delete_by_source_ids(collection_name: str, source_ids: list[str])[source]¶
Delete items from a collection by their source identifiers.
-
async index(text: str, source_metadata: dict | None =
None, collection_name: str ='default', source_id: str ='default')[source]¶ Index a single text blob with metadata.
-
async query(text: str, top_k: int =
5, collection_name: str | None =None, source_ids: list[str] | None =None, keep_best: bool =False) list[RagServiceResult][source]¶ Query the indexed items for similarities to the input text.
- Parameters:¶
- text : str¶
The query text.
- top_k : int¶
Number of top results to return. Defaults to 5.
- collection_name : Optional[str]¶
If provided, filter by collection name.
- source_ids : Optional[list[str]]¶
If provided, filter by source identifiers.
- keep_best : bool¶
If True, only the best result per source_id is returned. Useful when a single source is split into multiple indexed items.
- Returns:¶
List of results with similarity scores.
- Return type:¶
-
async batch_query(texts: list[str], top_k: int =
5, collection_name: str | None =None, source_ids: list[str] | None =None) list[list[RagServiceResult]][source]¶ Query the indexed items for similarities to multiple input texts in a single database call.
This method uses PostgreSQL CROSS JOIN LATERAL to efficiently process multiple queries in a single round trip to the database, significantly improving performance for batch operations.
-
async compute_similarity_matrix(texts: list[str], source_ids: list[str], method: str =
'min') list[list[float]][source]¶ Compute a similarity matrix between multiple texts and multiple source identifiers.
This method generates embeddings for all input texts and performs a single database query to find similarities against all specified source_ids.
- Parameters:¶
- texts : list[str]¶
List of query texts (rows in the matrix).
- source_ids : list[str]¶
List of source identifiers to compare against (columns in the matrix).
- method : str¶
Aggregate method to use when multiple items exist for a source_id. “min” (default) uses the shortest distance (highest similarity). “avg” uses the average distance.
- Returns:¶
- A 2D matrix where matrix[i][j] is the similarity between
texts[i] and source_ids[j].
- Return type:¶
-
async learn_normalizer(collection_name: str | None =
None) Normalizer[source]¶ Learns a normalizer from the current RAG index.
-
classmethod from_uri(uri: str, model: str, agent: Agent | None =