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 getIn one sentence
SAMKindsEvery kind of Smarter Application Manifest, 25 of them, and the single definition of which kinds exist.
The apply orderapply_order() and apply_rank() sort manifests so that each resource comes after the resources it names.
Kind helpersstr_to_kind(), plural(), all_plugins() and all_connections(), for turning what a user typed into a kind, and back.
The journal’s enumerationsSmarterJournalThings, SmarterJournalCliCommands and the keys of the cli api’s responses.
Typed exceptionsSmarterTypesValueError, 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 as sqlplugin or SQLPLUGIN, and raises SmarterTypesValueError for one that doesn’t exist. plural() gives the plural that the api uses, such as ApiConnections.
  • Values you can compare. SAMKinds is an enumeration whose values are the kinds exactly as manifests spell them, so manifest["kind"] == SAMKinds.LLM_CLIENT.value is a comparison that your editor can check.
  • The journal’s vocabulary. SmarterJournalThings is everything the Smarter Journal records, every kind plus the chat configuration, and SmarterJournalCliCommands is the commands of the cli api, such as apply, describe and deploy.

📖 smarter-types documentation


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.SAMKinds is 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 SAMKinds is 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 with pip 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.