Skip to main content

Software as Content — Conversations that produce evolving software. An open-source Python SDK that gives any agent the ability to generate and evolve interactive apps through conversation.

Project description

SaC SDK

Interaction layer between you and your agents.

License

Live demo · Paper


SaC (Software as Content) is an interaction layer that gives your AI agent the ability to generate and evolve interactive apps as part of the conversation. Instead of replying with text or markdown, your agent builds a live React app — a dashboard, a planner, a comparison tool — and the user clicks, types, and explores. The agent then evolves the same app in response, preserving all context across turns.

This isn't one-shot UI generation. SaC apps are stateful, conversational, and evolving — the agent understands what the user is looking at, what they clicked, and grows the app from there. No existing agent can do this natively.

function calling → agent does things  ·  MCP → agent talks to systems  ·  SaC → agent shows, interacts, and evolves

Quickstart

1. Install

pip install sac-sdk

2. Configure your LLM

cp .env.example .env

Edit .env and add your API key. SaC uses an LLM to generate the apps — any OpenAI-compatible provider works:

# OpenRouter (default), Anthropic, OpenAI, Ollama, etc.
SAC_API_KEY=sk-or-v1-your-key-here

# Optional: custom endpoint for OpenAI direct, Ollama, vLLM, etc.
# SAC_API_BASE=https://api.openai.com/v1/chat/completions

3. Run

sac serve

Open http://localhost:18420, type "3-day Tokyo trip planner with budget", and watch a live React app stream in. Click buttons. Ask it to evolve. This is SaC running a built-in agent loop — no external agent needed.

Connect to your agent

SaC plugs into the agent you already use — through MCP, Skill, or code.

Claude Code (MCP)

pip install sac-sdk
sac setup claude-code        # registers SaC as an MCP server

Restart Claude Code. Then try:

"Create an interactive release-readiness dashboard for this repo using SaC."

Claude Code will generate the app, show you the URL, and enter the interaction loop automatically.

Setup details →

Codex (Skill)

pip install sac-sdk
sac setup codex              # installs the SaC skill
sac serve                    # keep running in a terminal

Setup details →

OpenClaw (Skill)

pip install sac-sdk
sac setup openclaw           # installs the SaC skill
sac serve                    # keep running in a terminal

Setup details →

Python (build your own agent)

from sac import SaC

sac = SaC()
conv = sac.conversation()
app = await conv.generate("3-day Tokyo itinerary")
print(app.url)   # user opens this
# app.code contains the generated TSX

How it works

Your agent ──▶ SaC ──▶ User sees a live app at a URL
                   ◀── User clicks a button / types a message
Your agent ──▶ SaC ──▶ Same URL, app evolves in place
                   ◀── ...

One URL, one conversation. The agent doesn't generate a new page every turn — it evolves the existing app. Users keep their context; the agent keeps its state.

Two channels, one loop: every response is either a UI update (the app evolves) or a chat reply (a text bubble). Users can click buttons in the app OR type in the chat — both go back to the agent through the same callback.

When to use SaC

SaC is for tasks where exploration and interaction matter more than a final answer.

Good fit: trip planning, data analysis dashboards, comparison shopping, project planning, research, financial reviews, decision aids, internal tools

Not the right tool for: simple Q&A, one-shot automations ("set an alarm"), conversations that are purely text

Customize

Every layer is pluggable:

from sac import SaC, FileStore

sac = SaC(
    llm=YourLLMProvider(...),       # any class implementing LLMProvider
    search=YourSearchProvider(...), # any class implementing SearchProvider
    store=FileStore(".sac"),
)

Prompts live in src/sac/runtime/prompts/ and the default design system is in src/sac/renderer/design-systems/default/.

Architecture

src/sac/
├── sac.py / conversation.py    Entry + Conversation primitive
├── runtime/                    Generate + Evolve pipeline, prompts, providers
├── server/
│   ├── http/                   FastAPI + SSE streaming + viewer
│   └── mcp/                    MCP stdio server (Claude Code integration)
└── renderer/                   iframe sandbox + design system

Full architecture →

Project status

Alpha. The core protocol (generate → evolve → callback loop) is stable and runs in production at sac.dynsoft.ai. The SDK surface is being polished toward v1.0.

Contributing

Issues and PRs welcome. Highest-leverage contributions right now:

For local dev: pip install -e .

Citation

@article{xie2026sac,
  title  = {Software as Content: Dynamic Applications as the Human-Agent Interaction Layer},
  author = {Xie, Mulong},
  year   = {2026},
  url    = {https://arxiv.org/abs/2603.21334}
}

License

Apache-2.0 · © 2026 Mulong Xie / Dynsoft Lab


Built by Dynsoft Lab. Questions: mulong@mulongxie.me

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sac_sdk-0.1.0.tar.gz (239.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sac_sdk-0.1.0-py3-none-any.whl (253.8 kB view details)

Uploaded Python 3

File details

Details for the file sac_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: sac_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 239.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for sac_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 34c9d572c859ce95c138ed3391d8ef8e1beba33e037a866ba878d780f0e1e93d
MD5 94748a073603d90c24a2e91b6c76cb98
BLAKE2b-256 c64ef9630f6c589da1ef0cb96d2119f535ff3ed2193db4705105383df1e99345

See more details on using hashes here.

File details

Details for the file sac_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: sac_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 253.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for sac_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a6ce89566782a0d088c1e8ccf1edd5eb361e25f86a471b2638754b37d9e70e88
MD5 908dffd1bf7f40fcf5f090cd64c53055
BLAKE2b-256 4dd25d381173456aeaf7aae2e32580879b08347f0cd8cf76a106bc37ec26abb6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page