kiln-agents
A native Python port of kiln — build and orchestrate AI
agents. Same primitives as the TypeScript/npm package (@abhishekvardanbotta/kiln), reimplemented
natively in Python: no Node runtime involved.
pip install kiln-agents
What's ported
- Unified providers — OpenAI, Groq, and Ollama via one shared
httpx-based adapter (same design as the TS version: one class, three providers, swap a base URL + env var name). Gemini and Claude are declared but not implemented yet, matching the TS package's current status. ctx.ai.run()— the tool-calling loop: call the model, execute any requested tool calls, feed the results back, repeat, up tomax_steps.ctx.ai.object()— self-correcting structured output. Takes a pydantic model as the schema (Python's equivalent of the TS version's zod schema), writes the schema instruction into the prompt, validates the response, and retries with the exact validation error fed back on failure.connect_mcp()— real Model Context Protocol support via the officialmcpPython SDK. Any MCP server's tools become normal kilnToolobjects.orchestrate()— the DAG orchestrator:depends_on, per-step retries, a concurrency pool (asyncio.Semaphore-based), and cascading"skipped"status for steps whose dependency failed — ported line-for-line from the TSOrchestrator.
What's not ported (by design, this release)
The kiln CLI — kiln init/pack/install/serve/logs, the .agent package format, and
~/.kiln project/registry management — is TypeScript-only for now. This package is the embeddable
SDK: you define_agent(...) directly in your own Python code and run it in-process, the same pattern
the TS SDK uses when embedded in a Node backend (no CLI, no separate project folder). If you need a
long-running HTTP surface for a non-Python caller, run the TS package's kiln serve instead — this
package is for using kiln from Python, not for running the CLI.
Quickstart
import asyncio
from pydantic import BaseModel
from kiln_agents import create_kiln, define_agent
class Forecast(BaseModel):
city: str
temperature_c: float
summary: str
async def forecast_execute(ctx):
city = ctx.input["city"]
return await ctx.ai.object(
messages=[{"role": "user", "content": f"Give a short weather forecast for {city}."}],
schema=Forecast,
)
forecaster = define_agent(
name="forecaster",
provider="groq", # "openai" | "groq" | "ollama"
model="llama-3.3-70b-versatile",
execute=forecast_execute,
)
async def main():
kiln = create_kiln()
result = await kiln.run_inline_agent(forecaster, {"city": "Tokyo"})
print(result.output)
asyncio.run(main())
Orchestrating multiple agents
from kiln_agents import create_kiln, PipelineStep, PipelineRunContext
kiln = create_kiln()
result = await kiln.orchestrate([
PipelineStep(id="forecaster", agent=forecaster, input={"city": "Paris"}),
PipelineStep(
id="advisor",
agent=advisor,
depends_on=["forecaster"],
retries=2,
input=lambda ctx: {"forecast": ctx.outputs["forecaster"]},
),
])
print(result.outputs["advisor"])
print([step.status for step in result.steps]) # "succeeded" | "failed" | "skipped"
Tools
from pydantic import BaseModel
from kiln_agents import define_tool
class GetForecastInput(BaseModel):
city: str
async def get_forecast(input: GetForecastInput, ctx):
return {"city": input.city, "temperature_c": 21.0, "summary": "Clear skies."}
get_forecast_tool = define_tool(
name="get_forecast",
description="Fetch a real weather forecast for a city.",
parameters=GetForecastInput,
execute=get_forecast,
)
# Pass tools=[get_forecast_tool] into define_agent(...), then either:
# await ctx.tools["get_forecast"]({"city": "Tokyo"}) # call it directly
# await ctx.ai.run(messages=[...]) # or let the model decide to call it
MCP
from kiln_agents import connect_mcp
mcp = await connect_mcp("npx", args=["-y", "@some/mcp-server"])
# mcp.tools is list[Tool] — pass straight into define_agent(tools=[...])
...
await mcp.close() # always close when done
Provider setup
| provider | env var | notes |
|---|---|---|
openai |
OPENAI_API_KEY |
base URL https://api.openai.com/v1 |
groq |
GROQ_API_KEY |
base URL https://api.groq.com/openai/v1 |
ollama |
OLLAMA_HOST (optional) |
defaults to localhost:11434; give it bare host:port |
gemini, claude |
— | stub only, raises KilnError("<name> is not implemented yet.") |
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kiln_agents-0.1.0.tar.gz.
File metadata
- Download URL: kiln_agents-0.1.0.tar.gz
- Upload date:
- Size: 17.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6416d02207cd41e4762ae12284ec26e73b42652c935eb603394c2a54c2bb859a
|
|
| MD5 |
68f8892d726f8aa84736bc3e078d3b51
|
|
| BLAKE2b-256 |
fce1da06f93394c0a24a369f26b1d1365be95f7b031d9a438b0fe990b40f0fa4
|
File details
Details for the file kiln_agents-0.1.0-py3-none-any.whl.
File metadata
- Download URL: kiln_agents-0.1.0-py3-none-any.whl
- Upload date:
- Size: 20.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa4f6c17edd79436d4111e697764cc5658c82492a9f51357572019f8ce058736
|
|
| MD5 |
f576741be10da5cf7669e49d21d2efdf
|
|
| BLAKE2b-256 |
28fda8872cafe81682372de3b20e1df5e899a58849cd36601b0e001052ba5435
|