Skip to content
LACE
  • v0.1 Current
  • Python
  • TypeScript Soon

lace-app-sdk

What gets installed — project layout

A new LACE app is a small, conventional Python package plus two manifests. Everything else is derived from those.

The file tree

acme.field_intake/
├── app/
│   ├── __init__.py
│   ├── data.py            # AppDataCollectionSchema — typed, tenant-scoped collections
│   ├── tools.py           # @tool handlers + AppToolDescriptor registration
│   ├── agents.py          # AgentDefinition + AppAgentProvider
│   ├── routes.py          # AppRouteProvider (FastAPI routes)
│   ├── migrations.py      # AppDataMigrations / schema evolution
│   ├── jobs.py            # @app_task handlers (optional)
│   └── policy.py          # AppPolicyProvider (optional)
├── ui/                    # federated runtime-UI (optional, Module Federation)
│   ├── src/
│   ├── package.json
│   └── vite.config.ts
├── tests/
│   ├── test_routes.py
│   ├── test_tools.py
│   └── conftest.py
├── lace_app_manifest.json # canonical manifest — what the publisher seals
├── LaceApp.yaml           # sidecar / deploy descriptor (image, limits, env, health)
├── compose.yaml           # local dev stack (from SDK templates/lace_compose.yaml)
├── pyproject.toml         # depends on lace-app-sdk (+ gunicorn/uvicorn/fastapi)
├── .lace/                 # local state (git-ignored): dev state, build cache
└── README.md

Two manifests, one app

FileOwnsWhen it changes
lace_app_manifest.jsonThe canonical LaceAppManifestapp_id, data_collections, tools[], route_providers, agent_providers, tool_modules, pipeline_providers, runtime_ui, etc. The publisher seals this.Written by write_app_manifest() or derived from app/data.py at package time.
LaceApp.yamlSidecar runtime wiring — base_image, health_check_path, env_vars, resource_limits, network_policy, storage.At scaffold + on deploy (image digest pinned).

Canonical example — what lace_app_manifest.json looks like after you call write_app_manifest():

jsonlace_app_manifest.json
{
  "app_id": "acme.field_intake",
  "display_name": "Field Intake",
  "version": "0.1.0",
  "data_collections": [ ... ],
  "route_providers": ["app.routes:RouteProvider"],
  "agent_providers": ["app.agents:AgentProvider"],
  "tool_modules": ["app.tools"],
  "migration_provider": "app.migrations:Migrations"
}

The app/ package

  • app/data.py — one or more AppDataCollectionSchema objects. Each declares a JSON Schema, required fields, identity fields, unique constraints, searchable/sortable fields, and physical storage capabilities (EVENT_LOG, FULL_TEXT_INDEX). See data collections.
  • app/tools.py — tools declared with @tool(tool_id=..., description_for_model=..., input_schema=...). The descriptor is pure data (no dotted refs); the handler lives in the sidecar and is looked up via AppToolRegistry keyed by (app_id, tool_id). See tools.
  • app/agents.py — an AgentDefinition (model policy, instructions, capabilities, orchestration) plus an AppAgentProvider that returns it. The sidecar runs a real agentic loop. See agents.
  • app/routes.py — an AppRouteProvider that mounts FastAPI routes at /apps/<app_id>/api/*. See routes & UI.
  • app/migrations.py — optional AppDataMigrations for schema evolution (applied through the platform lifecycle).

SDK dependencies

terminalbash
# base install — pure-pydantic contracts + CLI, no lace runtime needed
pip install lace-app-sdk
lace-app --help  # works

# inside the monorepo / sidecar — full runtime bindings
pip install lace-app-sdk[runtime]
WhatDepends onNotes
lace-app-sdk (base)pydantic>=2 onlyEvery pure contract (_contracts/*) + all --help/auth/create/clone verbs work with no lace installed.
lace-app-sdk[runtime]lace monorepo + sidecar depsRequired for lace-app dev (migration-apply) and lace-app test proof harness. Installed automatically in the sidecar and when running inside the monorepo.
Your app's pyproject.tomlfastapi, uvicorn, lace-app-sdkSidecar image bakes these. Pin what you need; the platform pins the sidecar base.

Templates & scaffolding

The SDK ships a compose template at lace_app_sdk/templates/lace_compose.yaml and starter scaffolds in lace.builder.starter_scaffolds. lace-app create --template notes copies the notes_app example (see src/lace_app_sdk/examples/notes_app/) — a complete minimal app with data, routes, and an agent.

What is git-ignored

.lace/, __pycache__/, .venv/, dist/, dist_sdk/. Commit lace_app_manifest.json — the publisher reads it.

Next: the SDK itself — facade, not fork or manifest reference.