Python SDK for Grain — a structured data format for describing AI agents.
Project description
grain-sdk
Python SDK for Grain — a structured data format for describing AI agents.
Install
pip install grain-sdk
Usage
from grain import Grain
# Load from file
agent = Grain.load("./my-agent.agent.yaml")
# Generate system prompt
prompt = agent.to_prompt()
# Channel-specific prompt
slack_prompt = agent.to_prompt("slack")
# Clean YAML for LLM consumption (strips metadata)
yaml = agent.to_string()
Create programmatically
from grain import Grain
agent = (
Grain.create("my-bot", name="My Bot", description="Does helpful things")
.set_personality("warmth", 0.8)
.set_personality("confidence", 0.9)
.add_rule({
"id": "always-greet",
"condition": {"type": "always"},
"action": {"type": "respond-with-style", "style": {"warmth": 0.9}},
})
.add_boundary({
"description": "Never share internal data",
"category": "data",
"enforcement": "hard",
"onViolation": "refuse",
})
.add_tool({"id": "search", "usage": "Search knowledge base"})
)
print(agent.to_prompt())
Immutable mutations
Every method returns a new Grain — the original is never modified.
base = Grain.create("my-bot")
with_rule = base.add_rule({"id": "r1", "condition": {"type": "always"}, "action": {"type": "require-confirmation"}})
len(base.rules) # 0
len(with_rule.rules) # 1
With any LLM provider
from grain import Grain
from openai import OpenAI
agent = Grain.load("./my-agent.agent.yaml")
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": agent.to_prompt()},
{"role": "user", "content": "Hello!"}
]
)
Merge and diff
a = Grain.create("bot-a").set_personality("warmth", 0.3)
b = Grain.create("bot-b").set_personality("warmth", 0.9)
merged = a.merge(b) # b wins on conflicts
changes = a.diff(b) # {"voice.personality.warmth": {"before": 0.3, "after": 0.9}}
Minimal Spec
specVersion: "1.0"
id: my-bot
version: 1.0.0
meta:
name: My Bot
description: Does helpful things
API
Constructors
Grain.create(id, *, name=None, description="")— Create with defaultsGrain.from_string(yaml_or_json)— Parse from stringGrain.load(file_path)— Load from fileGrain.of(spec_dict)— Wrap a plain dict
Mutations (return new Grain)
add_rule(rule)/remove_rule(id)/add_rules(rules)add_boundary(b)/remove_boundary(desc)/add_boundaries(bs)add_tool(t)/remove_tool(name)/add_tools(ts)add_skill(s)/remove_skill(name)/add_skills(ss)add_expertise(domain, proficiency)/remove_expertise(domain)set_personality(dim, value)— validates 0-1 rangeset(path, value)/get(path)— generic deep accessmerge(other)— deep merge, other wins
Properties
id,name,version— scalarspersonality,rules,boundaries,tools,skills,expertise— copiesdata— raw dictis_valid— boolean
Queries
has_rule(id),has_tool(name),has_skill(name)
Output
to_string(channel=None)— Clean YAML for LLMs (strips metadata)to_prompt(channel=None)— Natural language system promptto_yaml()— Full YAML with all metadatato_json()— Full JSONvalidate()— Returnslist[ValidationError]diff(other)— Structural diff
Presets
Presets.personality["professional"]Presets.personality["friendly"]Presets.personality["expert"]Presets.personality["creative"]Presets.personality["executor"]
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
grain_sdk-0.2.1.tar.gz
(23.4 kB
view details)
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
grain_sdk-0.2.1-py3-none-any.whl
(21.0 kB
view details)
File details
Details for the file grain_sdk-0.2.1.tar.gz.
File metadata
- Download URL: grain_sdk-0.2.1.tar.gz
- Upload date:
- Size: 23.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36c7d25c74b440eaa25a8088edec9dc0a3f567189b8f654a140d122e739e21d9
|
|
| MD5 |
9967f059b9d3af5b3c67adc6f0e95e3a
|
|
| BLAKE2b-256 |
e61064f9ed5d3186ba5ca967bcd6032634ebabe8122b7612f35cdb9a4bf55993
|
File details
Details for the file grain_sdk-0.2.1-py3-none-any.whl.
File metadata
- Download URL: grain_sdk-0.2.1-py3-none-any.whl
- Upload date:
- Size: 21.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6bc57e62382d7442944d58f82b6a9ca2eddb8841ffcb11ae5dc8a2474ef44931
|
|
| MD5 |
9392823a0b297c1a8bac680091202603
|
|
| BLAKE2b-256 |
b9cee285d123e5a581b99d48c7b167dffa228019e462d88232fb6f2c38167fef
|