JSPM

@reallyartificial/grain

0.2.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 21
  • Score
    100M100P100Q50056F
  • License MIT

Grain — a structured data format for describing AI agents.

Package Exports

  • @reallyartificial/grain

Readme

@reallyartificial/grain

TypeScript SDK for Grain — a structured data format for describing AI agents.

Install

npm install @reallyartificial/grain

Usage

import { Grain } from "@reallyartificial/grain"

// Load from file
const agent = Grain.load("./my-agent.agent.yaml")

// Generate system prompt
const prompt = agent.toPrompt()

// Channel-specific prompt
const slackPrompt = agent.toPrompt("slack")

// Clean YAML for LLM consumption (strips metadata)
const yaml = agent.toString()

Create programmatically

import { Grain, Presets } from "@reallyartificial/grain"

const agent = Grain.create("my-bot", { name: "My Bot", description: "Does helpful things" })
  .setPersonality("warmth", 0.8)
  .setPersonality("confidence", 0.9)
  .addRule({
    id: "always-greet",
    condition: { type: "always" },
    action: { type: "respond-with-style", style: { warmth: 0.9 } },
  })
  .addBoundary({
    description: "Never share internal data",
    category: "data",
    enforcement: "hard",
    onViolation: "refuse",
  })
  .addTool({ id: "search", usage: "Search knowledge base" })

console.log(agent.toPrompt())

Immutable mutations

Every method returns a new Grain — the original is never modified.

const base = Grain.create("my-bot")
const withRule = base.addRule({ id: "r1", condition: { type: "always" }, action: { type: "require-confirmation" } })

console.log(base.rules.length)     // 0
console.log(withRule.rules.length)  // 1

Merge and diff

const a = Grain.create("bot-a").setPersonality("warmth", 0.3)
const b = Grain.create("bot-b").setPersonality("warmth", 0.9)

const merged = a.merge(b)          // b wins on conflicts
const changes = a.diff(b)          // { "voice.personality.warmth": { before: 0.3, after: 0.9 } }

CLI

npx @reallyartificial/grain validate my-agent.agent.yaml
npx @reallyartificial/grain generate my-agent.agent.yaml --channel slack
npx @reallyartificial/grain info my-agent.agent.yaml

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, opts?) — Create with defaults
  • Grain.from(yamlOrJson) — Parse from string
  • Grain.load(filePath) — Load from file
  • Grain.of(spec) — Wrap a plain AgentSpec object

Mutations (return new Grain)

  • addRule(rule) / removeRule(id) / addRules(rules)
  • addBoundary(b) / removeBoundary(desc) / addBoundaries(bs)
  • addTool(t) / removeTool(name) / addTools(ts)
  • addSkill(s) / removeSkill(name) / addSkills(ss)
  • addExpertise(domain, proficiency) / removeExpertise(domain)
  • setPersonality(dim, value) — validates 0-1 range
  • set(path, value) / get(path) — generic deep access
  • merge(other) — deep merge, other wins

Accessors

  • id, name, version — scalars
  • personality, rules, boundaries, tools, skills, expertise — copies
  • data — raw frozen AgentSpec
  • isValid — boolean

Queries

  • hasRule(id), hasTool(name), hasSkill(name)

Output

  • toString(channel?) — Clean YAML for LLMs (strips metadata)
  • toPrompt(channel?) — Natural language system prompt
  • toYAML() — Full YAML with all metadata
  • toJSON() — Full JSON
  • validate() — Returns ValidationError[]
  • diff(other) — Structural diff

Presets

  • Presets.personality.professional
  • Presets.personality.friendly
  • Presets.personality.expert
  • Presets.personality.creative
  • Presets.personality.executor

License

MIT