Skip to main content
Store, list, and load resources and templates, including media in and out. The runtime stores content behind a storage provider and loads it through the resource manager — by storage id, by URL, or from a raw file, as text or as media. A template is one kind of stored resource: content the runtime renders with kwargs. This guide covers managing that content from the CLI.

Wire a storage provider

Storage is dead by default — the skeleton ships no provider. Name a provider module in the manifest to turn the storage surface on:
examples/storage/storage_provider_manifest.yaml
The concrete provider (a local filesystem or an object store) ships as a separate plugin package. With none wired, tai storage info reports the empty state and every CRUD door answers a 501.

The raw resource surface

tai storage is the raw provider-resource surface — upload, list, stat, download, and delete resources by id:
Upload takes exactly one of --text (stored verbatim) or --base64 (decoded to bytes); an existing id is overwritten. A resource id must be a relative path with no .. segment. The full subcommand set:
examples/storage/storage_help.sh

Upload and list templates

Upload a local file as a template under a key, then list what is stored.
Read one back with its input schema:

Render a template

Render a stored template by id, or inline content, as one --text JSON object carrying the source plus any render kwargs (read it from a file or stdin with --text-file to keep a secret off the command line).
Clear the render cache after changing a template out of band:
The clear fans out fleet-wide over the worker bus — it evicts the compiled-template cache on every worker and returns a per-worker fanout report, so a worker it could not reach is named rather than left stale. You only need it for an out-of-band edit made directly on the provider side: a template write or delete through the platform’s own surface already evicts every worker automatically.

Load content in and out

The resource manager loads content by storage id or URL and returns it as text or media. To load a stored resource or a URL from within a tool run, enable the file-loader built-in tool, which returns a file’s content as text or media:
manifest.yml
The resource-management capabilities — upload_template, get_resource_by_id, and list_resources — are operations. Each is always a route and a CLI command, and projects as an MCP tool when api_tools allows it, so a tool run or an MCP client reaches the same surface the CLI does:
get_resource_by_id takes a resource_id and optional render kwargs; with no kwargs it returns the loaded content as-is, and with kwargs (any object, including {}) it renders text as a Jinja template, refusing media with a 400. list_resources answers {"resources": [...]} — the sorted resource ids from the active provider — and upload_template takes a path and returns {"path", "uploaded": true}.
The storage provider is a plugin, so where content lives is swappable. The text and media surfaces are the same regardless of backend — a text-only backend satisfies the binary surface through built-in bridging.

See also