API Contracts

smarter.models.chat

Models of the Smarter Chat api contract, version 2: an LLMClient’s configuration, its prompt api’s request and response, and the prompt’s progress events.

These mirror smarter.apps.prompt.contract.models in the Smarter platform, whose JSON Schema is chat-contract.schema.json. The SDK always asks for version 2 of the contract (with the X-Smarter-Capabilities: chat-contract-v2 request header), so the deprecated version 1 models are not mirrored.

Two deliberate differences from the platform’s models, both so that an SDK keeps working when the platform is upgraded:

  • every model allows extra fields, including the models of Django rows, whose platform models forbid them, and

  • values that the platform may add to, such as a plugin’s class or a progress event’s type, are str rather than Literal. Their known values are listed in the field descriptions.

The SDK’s tests validate the platform’s published example of every contract model against these models. See scripts/sync-contracts.sh.

smarter.models.chat.CHAT_CONTRACT_V2

The version of the Smarter Chat api contract that the SDK reads.

smarter.models.chat.CHAT_CONTRACT_V2_CAPABILITY

The X-Smarter-Capabilities value with which the SDK asks for version 2 of the contract.

smarter.models.chat.LLM_MESSAGE_ROLES

The message roles that the LLM providers accept.

Smarter’s own roles, smarter and smarter_error, are informational.

smarter.models.chat.PromptChatApiContentPart

A part of a message whose content is a list of parts, by its type.

class smarter.models.chat.PromptChatApiTextPart

Bases: smarter.models.base.SmarterModel

A text part of a message’s content.

type: Literal
text: str
class smarter.models.chat.PromptChatApiImageUrl

Bases: smarter.models.base.SmarterModel

An image, by its url or as a data url.

url: str
detail: Optional
class smarter.models.chat.PromptChatApiImagePart

Bases: smarter.models.base.SmarterModel

An image part of a message’s content.

type: Literal
image_url: PromptChatApiImageUrl
class smarter.models.chat.PromptChatApiInputAudio

Bases: smarter.models.base.SmarterModel

Audio, base64 encoded.

data: str
format: Literal
class smarter.models.chat.PromptChatApiAudioPart

Bases: smarter.models.base.SmarterModel

An audio part of a message’s content.

type: Literal
input_audio: PromptChatApiInputAudio
class smarter.models.chat.PromptChatApiFileRef

Bases: smarter.models.base.SmarterModel

A file, base64 encoded, or by the provider’s file id.

file_data: Optional
file_id: Optional
filename: Optional
class smarter.models.chat.PromptChatApiFilePart

Bases: smarter.models.base.SmarterModel

A file part of a message’s content.

type: Literal
file: PromptChatApiFileRef
class smarter.models.chat.PromptChatApiRefusalPart

Bases: smarter.models.base.SmarterModel

The LLM’s refusal, as a part of a message’s content.

type: Literal
refusal: str
class smarter.models.chat.PromptChatApiFunctionCall

Bases: smarter.models.base.SmarterModel

The function that a tool call calls.

name: str
arguments: str

The function’s arguments, as a JSON string.

class smarter.models.chat.PromptChatApiToolCall

Bases: smarter.models.base.SmarterModel

A tool call of an assistant message.

id: str
type: str
function: PromptChatApiFunctionCall
class smarter.models.chat.PromptChatApiMessage

Bases: smarter.models.base.SmarterModel

A message of a chat thread, in the format of the OpenAI api.

Smarter adds its own roles: smarter for informational messages (e.g. the prompt’s configuration, the tools presented to the LLM, and its token charges), and smarter_error. These are saved in the session’s history, and are never sent to the LLM.

role: str

system, assistant, user, tool, smarter or smarter_error.

content: Union

The message’s text, or a list of content parts.

tool_calls: Optional

An assistant message’s tool calls.

tool_call_id: Optional

The tool call that a tool message answers.

name: Optional

The name of a tool message’s function.

property text

The message’s text: its content, or the text of its text parts, joined by blank lines.

class smarter.models.chat.PromptChatApiJournalMetadata

Bases: smarter.models.base.SmarterModel

The metadata of a chat response.

command: Optional

The journal’s command, e.g. prompt.

thing: Optional

The journal’s thing, e.g. LLMClient.

key: Optional
class smarter.models.chat.PromptChatApiErrorBody

Bases: smarter.models.base.SmarterModel

The error of a chat error response.

errorClass: str

The name of the error’s class, e.g. NotFound or LLMProviderError.

description: str

A human-readable description.

status: int

The http status.

class smarter.models.chat.PromptChatApiErrorResponse

Bases: smarter.models.base.SmarterModel

A chat error response.

error: PromptChatApiErrorBody
api: Optional
metadata: Optional
class smarter.models.chat.PromptChatApiEnvelope

Bases: smarter.models.base.SmarterModel

The fields that every chat response adds beside data.

api: str

The api version, e.g. “smarter.sh/v1”.

metadata: PromptChatApiJournalMetadata
class smarter.models.chat.PromptChatApiStyleSection

Bases: smarter.models.base.SmarterModel

The colors of one section of the chat ui.

background_color: Optional
color: Optional
border_color: Optional
info_color: Optional
editor_background_color: Optional
placeholder_color: Optional
class smarter.models.chat.PromptChatApiStyles

Bases: smarter.models.base.SmarterModel

The LLMClient’s chat ui styles.

app_logo_url: Optional
app_background_image_url: Optional
app_background_image_size: Optional
assistant_avatar_url: Optional
user_avatar_url: Optional
font_family: Optional
google_font: Optional
font_size: Optional
border_radius: Optional
main_container: Optional
conversation_header: Optional
message_list: Optional
incoming_message: Optional
outgoing_message: Optional
message_input: Optional
buttons: Optional
typing_indicator: Optional
class smarter.models.chat.PromptChatApiLLMClient

Bases: smarter.models.base.SmarterModel

The LLMClient, as its configuration describes it.

id: int
name: str
url_llmclient: Optional

The url of the LLMClient’s prompt api.

version: Optional
deployed: Optional
provider: Optional
default_model: Optional
default_system_role: Optional

The system prompt of a new chat session.

app_name: Optional
app_assistant: Optional
app_welcome_message: Optional
app_example_prompts: Optional
app_placeholder: Optional
app_info_url: Optional
app_file_attachment: Optional
styles: Optional
class smarter.models.chat.PromptChatApiOrmModel

Bases: smarter.models.base.SmarterModel

The fields of a Django row that the contract returns.

id: int
created_at: Optional
updated_at: Optional
class smarter.models.chat.PromptChatApiPluginMeta

Bases: smarter.models.chat.PromptChatApiOrmModel

A plugin’s metadata.

name: str
description: Optional
version: Optional
tags: list
annotations: Union
plugin_class: str

api, skill, sql, static, websearch or imagesearch.

class smarter.models.chat.PromptChatApiLLMClientPlugin

Bases: smarter.models.chat.PromptChatApiOrmModel

A plugin of the LLMClient.

llmclient: int
plugin_meta: PromptChatApiPluginMeta
class smarter.models.chat.PromptChatApiLLMClientFunction

Bases: smarter.models.chat.PromptChatApiOrmModel

A built-in function of the LLMClient.

llmclient: int
name: Optional

get_current_weather, date_calculator or calculator.

class smarter.models.chat.PromptChatApiPromptRequest

Bases: smarter.models.base.SmarterModel

The prompt api’s request body.

session_key: Optional
messages: list
class smarter.models.chat.PromptChatApiLLMClientRequest

Bases: smarter.models.chat.PromptChatApiOrmModel

A request that Smarter sent to the LLM.

llmclient: int
request: Optional
session_key: Optional
is_aggregation: Optional
class smarter.models.chat.PromptChatApiPromptToolCall

Bases: smarter.models.chat.PromptChatApiOrmModel

A tool call of the chat session.

prompt: int
plugin: Optional
function_name: Optional
function_args: Optional
request: JsonValue
response: JsonValue
class smarter.models.chat.PromptChatApiPromptPluginUsage

Bases: smarter.models.chat.PromptChatApiOrmModel

A use of a plugin in the chat session.

prompt: int
plugin: int
input_text: Optional
class smarter.models.chat.PromptChatApiPluginSelection

Bases: smarter.models.chat.PromptChatApiOrmModel

A plugin selector’s decision in the chat session.

plugin_selector: int
search_term: Optional
messages: Optional
session_key: Optional
class smarter.models.chat.PromptChatApiHistory

Bases: smarter.models.base.SmarterModel

The chat session’s history.

chat_history: list

The session’s messages, which restore the chat thread.

prompt_tool_call_history: Optional
prompt_plugin_usage_history: Optional
plugin_selector_history: Optional
llmclient_request_history: Optional
class smarter.models.chat.PromptChatApiMetaData

Bases: smarter.models.base.SmarterModel

The LLMClient’s state.

ready: Optional
is_valid: Optional
is_deployed: Optional
class smarter.models.chat.PromptChatApiListMetaData

Bases: smarter.models.base.SmarterModel

The counts of a list of the LLMClient’s plugins or functions.

total_plugins: Optional
plugins_returned: Optional
total_functions: Optional
functions_returned: Optional
class smarter.models.chat.PromptChatApiPluginList

Bases: smarter.models.base.SmarterModel

The LLMClient’s plugins.

meta_data: PromptChatApiListMetaData
plugins: list
class smarter.models.chat.PromptChatApiFunctionList

Bases: smarter.models.base.SmarterModel

The LLMClient’s built-in functions.

meta_data: PromptChatApiListMetaData
functions: list
class smarter.models.chat.PromptChatApiConfig

Bases: smarter.models.base.SmarterModel

An LLMClient’s chat configuration: the LLMClient, the chat session’s key and history, and its plugins and functions.

A new session’s configuration has an empty history. Pass its session_key to the prompt api to continue the session.

contract: int
session_key: str

The chat session’s key.

sandbox_mode: bool

True for a workbench url.

debug_mode: bool

The platform’s ENABLE_REACTAPP_DEBUG_MODE waffle switch.

meta_data: PromptChatApiMetaData
llmclient: PromptChatApiLLMClient
history: PromptChatApiHistory
plugins: PromptChatApiPluginList
functions: Optional
class smarter.models.chat.PromptChatApiConfigRequest

Bases: smarter.models.base.SmarterModel

The configuration api’s request body.

session_key: Optional

The chat session’s key, or None for a new session.

class smarter.models.chat.PromptChatApiConfigResponse

Bases: smarter.models.chat.PromptChatApiEnvelope

The configuration api’s response.

data: PromptChatApiConfig
class smarter.models.chat.PromptChatApiChoice

Bases: smarter.models.base.SmarterModel

A choice of a chat completion.

index: int
finish_reason: Optional

e.g. stop, length or tool_calls.

message: Optional
class smarter.models.chat.PromptChatApiTokenDetails

Bases: smarter.models.base.SmarterModel

The breakdown of a completion’s tokens.

reasoning_tokens: Optional
cached_tokens: Optional
audio_tokens: Optional
class smarter.models.chat.PromptChatApiUsage

Bases: smarter.models.base.SmarterModel

A chat completion’s token usage.

prompt_tokens: Optional
completion_tokens: Optional
total_tokens: Optional
prompt_tokens_details: Optional
completion_tokens_details: Optional
class smarter.models.chat.PromptChatApiCompletion

Bases: smarter.models.base.SmarterModel

The LLM’s chat completion, in the format of the OpenAI api.

id: Optional
object: Optional
created: Optional
model: Optional
choices: list
usage: Optional
system_fingerprint: Optional
service_tier: Optional
class smarter.models.chat.PromptChatApiPromptResult

Bases: smarter.models.base.SmarterModel

The result of a prompt.

contract: int
status: int

The prompt’s http status: 200, or the LLM provider’s error status.

messages: list

The messages that the prompt added to the chat thread, in order.

completion: Optional

The LLM’s chat completion.

plugins: list

The plugins that Smarter selected.

tools: list

The functions that the LLM could call.

property assistant_messages

The assistant messages that the prompt added, which are the LLM’s replies and tool calls.

property text

The text of the LLM’s final reply: the last assistant message that has content, or an empty string.

class smarter.models.chat.PromptChatApiPromptResponse

Bases: smarter.models.chat.PromptChatApiEnvelope

The prompt api’s response.

A failed prompt has error too, and its data.messages include a smarter_error message.

data: PromptChatApiPromptResult
error: Optional
property text

The text of the LLM’s final reply.

See PromptChatApiPromptResult.text.

class smarter.models.chat.PromptChatApiProgressEvent

Bases: smarter.models.base.SmarterModel

The data of a progress event: a step of a running prompt.

Events may carry more fields, depending on their type, e.g. tool and arguments.

type: str

llm_request, tool_requested, tool_responded, plugin_called, mcp_tool_called, mcp_tool_responded or mcp_tool_failed.

message: str

A short sentence, which a chat ui can display as is.

class smarter.models.chat.PromptChatApiProgressResult

Bases: smarter.models.base.SmarterModel

The data of the final result event.

status: int

The prompt’s http status.

response: Union

Exactly the JSON of a non-streaming response.

smarter.models.journal

Models of the Smarter Journal api contract: the envelope of every journaled response, its error body, and a journal entry.

The Smarter platform journals its api responses. Each one carries api (the api version, e.g. smarter.sh/v1) and metadata (the command and the resource kind, which the platform calls its “thing”) beside its own data, message or error.

These models mirror smarter.lib.journal.contract.models in the Smarter platform, whose JSON Schema is journal-contract.schema.json. The SDK’s tests validate the platform’s schema against them. See scripts/sync-contracts.sh.

class smarter.models.journal.SAMJournalApiMetadata

Bases: smarter.models.base.SmarterModel

The metadata of a journaled response: its command and thing, and the key of its journal entry.

command: str

The journal’s command, e.g. apply.

thing: str

The journal’s thing, e.g. Guardrail. The string ‘None’ when there is none.

key: Optional

The key of the response’s journal entry, when the journal is enabled.

class smarter.models.journal.SAMJournalApiErrorBody

Bases: smarter.models.base.SmarterModel

The error of a journaled error response.

Every error of the cli api has this shape.

errorClass: str

The name of the exception’s class, e.g. SAMBrokerErrorNotFound.

stacktrace: Optional

The server’s stack trace, when the platform includes it.

description: Optional

A human-readable description of the error.

status: int

The http status.

args: JsonValue

The exception’s arguments, or the request’s url.

cause: Optional

The exception’s cause.

context: Optional

The exception’s context, or the response’s thing and command.

thing: Optional

The journal’s thing, e.g. Guardrail.

command: Optional

The journal’s command, e.g. describe.

class smarter.models.journal.SAMJournalApiEnvelope

Bases: smarter.models.base.SmarterModel

The fields that every journaled response adds beside its own data.

api: str

The api version, e.g. “smarter.sh/v1”.

metadata: Optional
class smarter.models.journal.SAMJournalApiErrorResponse

Bases: smarter.models.journal.SAMJournalApiEnvelope

The body of a journaled error response.

error: SAMJournalApiErrorBody
class smarter.models.journal.SmarterJournaledResponse

Bases: smarter.models.journal.SAMJournalApiEnvelope, typing.Generic

A successful journaled response: the envelope, the response’s data, and an optional message.

data is typed by the endpoint, e.g. SmarterJournaledResponse[WhoAmI].

data: Optional
message: Optional

A human-readable message, e.g. ‘LLMClient calculator applied’.

class smarter.models.journal.SmarterJournalMessage

Bases: smarter.models.journal.SAMJournalApiEnvelope

A journaled response that carries only a message, e.g. the response of delete or deploy.

message: Optional
class smarter.models.journal.JournalEntry

Bases: smarter.models.base.SmarterCamelModel

A Smarter Journal entry, as /api/v1/journal/ returns it.

The list returns entries without request and response. Retrieving one entry by its key includes them. Only superusers may read the journal, because the request documents hold the callers’ credentials.

key: str
created_at: Optional = alias ``createdAt``
user: Optional

The username of the caller, or None for an anonymous request.

thing: str
command: str
status_code: int = alias ``statusCode``
request: JsonValue
response: JsonValue
class smarter.models.journal.JournalPagination

Bases: smarter.models.base.SmarterCamelModel

The description of one page of the journal’s entries.

page: int
page_size: int = alias ``pageSize``
num_pages: int = alias ``numPages``
count: int
search: str
ordering: str
sort_fields: list = alias ``sortFields``
class smarter.models.journal.JournalPage

Bases: smarter.models.base.SmarterModel

One page of the journal’s entries.

objects: list
pagination: JournalPagination

smarter.models.react

Pydantic models of the Smarter platform’s Django-React integration: a React app’s Vite manifest, and the assets that a template includes.

The platform’s web console pages are React apps that Django hosts. SmarterReactTemplateTagManager (in smarter.lib.django.templatetags) reads each app’s Vite-generated manifest.json, and each <app>_react_assets template tag returns the files that a template includes. These models are a copy of the platform’s smarter.lib.django.templatetags.smarter_react_contract, which is pure Pydantic, so that tools that build or check React apps for a Smarter platform can use them without the platform.

  • ViteManifest is a Vite-generated React manifest.json: a map of ViteManifestChunk keyed by source path. The manager validates the file against it when it loads it, and collects an entry point’s assets with its methods.

  • ReactAppAssets is what every <app>_react_assets template tag returns: the ordered JS and CSS files that a Django template includes for a React app.

The manifest is a third-party shape. ViteManifestChunk declares the fields that Vite documents, and allows extra fields, which newer Vite (or Rolldown) versions add, so that a Vite upgrade doesn’t break page rendering. Smarter’s own addition, the _custom entry that every package’s vite.config.ts writes after the build, is a ReactAppBuildInfo.

smarter.models.react.ReactAssetType

The kinds of asset that a React app’s entry point loads.

smarter.models.react.BUILD_INFO_KEY

The key of the build information that each React package’s vite.config.ts adds to its manifest.json.

class smarter.models.react.ViteManifestChunk

Bases: pydantic.main.BaseModel

One entry of a Vite-generated manifest.json: a chunk, or a static asset.

See https://vite.dev/guide/backend-integration. Extra fields are allowed, because Vite and Rolldown add their own.

Example:

"index.html": {
    "file": "assets/index.js",
    "name": "index",
    "src": "index.html",
    "isEntry": true,
    "imports": ["_rolldown-runtime.js", "_xterm.js"],
    "css": ["assets/index-DvLY75bJ.css"]
}
file: str

The output file of this chunk, relative to the app’s static directory.

name: Optional

The chunk’s name.

names: list

The names of a static asset.

src: Optional

The chunk’s source path.

is_entry: bool = alias ``isEntry``

Whether this chunk is an entry point.

is_dynamic_entry: bool = alias ``isDynamicEntry``

Whether this chunk is a dynamic entry point.

imports: list

The manifest keys of statically imported chunks.

dynamic_imports: list = alias ``dynamicImports``

The manifest keys of dynamically imported chunks.

css: list

The CSS files that this chunk loads.

assets: list

The other static files that this chunk references.

class smarter.models.react.ReactAppBuildInfo

Bases: pydantic.main.BaseModel

The build information that each React package’s vite.config.ts adds to its manifest.json, as _custom.

Example:

"_custom": {
    "buildTime": "2026-10-12T01:09:47.988Z",
    "version": "0.3.0",
    "buildEnv": "production"
}
build_time: datetime = alias ``buildTime``

When the app was built.

version: str

The version of the app’s npm package.

build_env: str = alias ``buildEnv``

The build’s NODE_ENV, e.g. production.

class smarter.models.react.ViteManifest

Bases: pydantic.main.BaseModel

A React app’s Vite-generated manifest.json: its chunks, keyed by source path, and Smarter’s build information.

In the file, the build information is the _custom entry, beside the chunks. Validating a manifest.json splits it out into build_info, and dumping the model puts it back, so model_dump(by_alias=True) has the file’s shape.

See https://vite.dev/guide/backend-integration.

chunks: dict

The manifest’s chunks, keyed by source path.

build_info: Optional

The ``_custom`` build information, if the package’s vite.config.ts adds it.

classmethod split_build_info(data: object) → object

Split a manifest.json’s _custom entry from its chunks.

Input that already has chunks, e.g. keyword arguments, is left as is.

Parameters:

data – The manifest.json’s content.

Returns:

The model’s fields.

Return type:

object

join_build_info(handler: pydantic_core.core_schema.SerializerFunctionWrapHandler) → dict[str, Any]

Dump the manifest in the shape of manifest.json, with the build information as its _custom entry.

Parameters:

handler – Pydantic’s default serializer.

Returns:

The chunks, keyed by source path, and _custom.

Return type:

SmarterDictType

entry_key() → str | None

Find the key of the manifest’s entry point, the first chunk with "isEntry": true.

Returns:

The entry point’s key, or None if the manifest has no entry point.

Return type:

Optional[str]

collect_assets(key: str, asset_type: Literal['js', 'css'], seen: set[str] | None = None) → list[str]

Recursively collect the JS or CSS files of a chunk and of its static imports.

A chunk’s own files come first, followed by those of each of its imports, depth first, in the order they are listed. Each chunk is visited once, so circular imports terminate.

Parameters:
  • key – The manifest key of the chunk to collect assets for.

  • asset_type – "js" for the chunks’ file, "css" for their css files.

  • seen – The keys already visited, used by the recursion.

Returns:

The asset file paths, relative to the app’s static directory.

Return type:

list[str]

class smarter.models.react.ReactAppAssets

Bases: pydantic.main.BaseModel

The ordered JS and CSS files of a React app’s entry point, which a Django template includes.

Every <app>_react_assets template tag returns one. Templates read its attributes, e.g. {% for css_file in assets.css %}.

Example:

{
    "js": [
        "assets/index-CZK_Bxxh.js",
        "assets/rolldown-runtime-B3igc2qu.js",
        "assets/xterm-D5XSfLrr.js"
    ],
    "css": [
        "assets/index-58MXwt-L.css",
        "assets/xterm-kHJ-D0s7.css"
    ]
}
js: list

The JS files, the entry point’s first.

css: list

The CSS files, the entry point’s first.