smarter-types v0.1 Release: One Definition of Smarter’s Manifest Kinds, for the Platform and Its SDK
Every Smarter resource is declared in a manifest with a kind, such as LLMClient, SqlPlugin, Secret, Guardrail, and so on. Until today, the list of kinds lived in two places. The platform defined it, the smarter-api Python SDK kept its own copy, and keeping the two in step was a job for whoever remembered. smarter-types is the end of that. It’s a small package that defines the kinds, the order in which they’re applied, and the Smarter Journal’s enumerations, once, for both of them.
pip install smarter-types
This is the first release. The Smarter platform and smarter-api both depend on it, and install it for you. It’s plain Python, with no Django and no Pydantic. Its only dependency is inflection, so any Python tool that works with Smarter manifests, such as a CI script or a linter, can use it too.
| What you get | In one sentence |
|---|---|
SAMKinds | Every kind of Smarter Application Manifest, 25 of them, and the single definition of which kinds exist. |
| The apply order | apply_order() and apply_rank() sort manifests so that each resource comes after the resources it names. |
| Kind helpers | str_to_kind(), plural(), all_plugins() and all_connections(), for turning what a user typed into a kind, and back. |
| The journal’s enumerations | SmarterJournalThings, SmarterJournalCliCommands and the keys of the cli api’s responses. |
| Typed exceptions | SmarterTypesValueError, which is also a ValueError. |
Using it
from smarter_types import SAMKinds
SAMKinds.str_to_kind("sqlplugin") # "SqlPlugin"
SAMKinds.plural(SAMKinds.API_CONNECTION) # "ApiConnections"
# apply a set of manifests so that each resource comes after the ones it names
manifests = [{"kind": "SqlPlugin"}, {"kind": "SqlConnection"}, {"kind": "Secret"}]
manifests.sort(key=lambda m: SAMKinds.apply_rank(m["kind"]))
[m["kind"] for m in manifests] # ["Secret", "SqlConnection", "SqlPlugin"]
- The apply order is the platform’s own. Manifests refer to each other by name, and the platform resolves every name when it applies a manifest, so a Secret has to exist before the Connection that names it, and a plugin before the LLMClient that lists it.
apply_order()is the order that Smarter itself uses to load its example projects. A name that isn’t a kind ranks last, so a misspelled kind sorts to the end instead of failing first. - Forgiving about case, strict about kinds.
str_to_kind()accepts a kind in any letter case, such assqlpluginorSQLPLUGIN, and raisesSmarterTypesValueErrorfor one that doesn’t exist.plural()gives the plural that the api uses, such asApiConnections. - Values you can compare.
SAMKindsis an enumeration whose values are the kinds exactly as manifests spell them, somanifest["kind"] == SAMKinds.LLM_CLIENT.valueis a comparison that your editor can check. - The journal’s vocabulary.
SmarterJournalThingsis everything the Smarter Journal records, every kind plus the chat configuration, andSmarterJournalCliCommandsis the commands of the cli api, such asapply,describeanddeploy.
Where it fits
The platform and smarter-api re-export these classes from the modules that used to define them, so neither one’s own users had to change an import.
- The Smarter platform pins smarter-types, and
smarter.apps.api.v1.manifests.enum.SAMKindsis the package’s class. A new kind is added to smarter-types first, released, and then picked up by the platform. - smarter-api v0.6, released today, depends on it too, so
from smarter import SAMKindsis the same class. The SDK and the platform can’t disagree about which kinds exist, or the order to apply them in.
If you use the SDK, you already have smarter-types, and don’t need to import it yourself. Install it directly when you want the kinds without the SDK.
Built to be depended on
smarter-types is a dependency of the platform and the SDK, so it’s held to the standards of one.
- Checked against the platform. The port matches the platform’s definitions exactly, with 25 kinds, 26 journal things and 17 cli commands and the same apply order, checked against the platform’s source.
- Tested on Python 3.10 to 3.14 on every push and pull request, 61 tests with 100% branch coverage.
- Typed. The package ships
py.typed, and its annotations are checked with mypy. - Released by a workflow, not a laptop. Each release is tested, rehearsed on TestPyPI, and published to PyPI with trusted publishing, so no PyPI token exists anywhere, and PyPI keeps a provenance attestation that each file was built from the repository by that workflow.
- Documented. docs.smarter-types.smarter.sh has a quickstart, guides to the kinds and the journal’s enumerations and to why the package exists, an api reference generated from the code, and its architecture decision records.
- Licensed like Smarter, under the AGPL-3.0-or-later.
Try it, and tell people about it
- If you script anything around Smarter manifests, sort them with
SAMKinds.apply_rank()instead of keeping your own list. Install it withpip install smarter-types. - Star the repository at github.com/smarter-sh/smarter-types.
- Open an issue for a bug, or for a helper that you find yourself writing around these types. The contributing guide explains how to make a change.
- Look at Smarter, the open-source platform for building and running AI applications that these types describe.
What’s next
- More shared types. Anything else that the platform and the SDK both define, and that needs no Django or Pydantic, is a candidate to move here, so that it too is defined once.
The changelog is on GitHub, with the v0.1.0 release. The package is on PyPI, the docs are at docs.smarter-types.smarter.sh, and the source is at github.com/smarter-sh/smarter-types.
