Publish as model
A published Core appears in ScaiGrid's model catalogue and is callable through POST /v1/inference/chat exactly like any other backend. This is how you let arbitrary ScaiGrid clients chat with the agent without knowing they're talking to a ScaiCore program.
This page is about the ScaiGrid wrapper's publish surface. For how the program itself answers — its DSL, its flows, its tool calls — see /docs/scaicore.
What publish does#
When you call POST /cores/{id}/publish, the wrapper:
- Creates a
BackendModelrow withprovider_type=scaicoreandconnection_config.core_idset. - Creates a
FrontendModelrow with slugscaicore/{tenant_slug}/{core_slug}, the Core's name, description (pulled frommetadata.descriptionorsource.identity.persona), the Core's avatar, andcapabilities = {tool_use: true, streaming: false}. - Wires the front-end model to the back-end with a
ModelBackendlink. - Writes
published,published_model_id,published_backend_id,published_sluginto the Core's metadata so unpublish can find it again. - Optionally adds the new model slug to any model groups you list — with scope validation: non-super-admins cannot add to
globalgroups or to partner / tenant groups they don't belong to.
The Core stays running (or whatever state it was in). Publication is metadata-only — the Core itself doesn't restart.
Publish#
1 2 3 4 | |
1 2 3 4 5 6 | |
1 2 3 4 5 6 7 8 9 10 | |
group_ids is optional. If omitted (or if the caller lacks models:manage), the new model exists in the catalogue but is not added to any group — clients with group-restricted access will not see it.
If the Core is already published, the call returns a 400 VALIDATION_ERROR ("Core is already published as a model"). Use sync to update an existing publication.
Call the published model#
The slug is your standard ScaiGrid model id:
1 2 3 4 5 6 7 | |
Routing, accounting, audit, and rate-limiting all work the same as for any other model. The dispatcher resolves the scaicore provider and forwards the request into the Core through its HostEnvironment.
Sync after edits#
If you change the Core's name, description, persona, or avatar after publishing, the FrontendModel row goes stale. The publishing service exposes a sync() method that re-reads the Core and rewrites the FrontendModel's display_name, description, system_prompt_template, avatar_url, and metadata_. Today this is called internally on edit paths; there is no separate HTTP endpoint for it.
Unpublish#
1 2 | |
Unpublish removes the slug from every model group it was added to, deletes the FrontendModel (which cascades the ModelBackend link), deletes the BackendModel, and clears the published_* keys from the Core's metadata. The Core itself is untouched.
If the Core was never published, you get a 400 VALIDATION_ERROR ("Core is not published").
Scope rules for group_ids#
The wrapper validates each requested group against the caller's scope:
| Caller | Allowed groups |
|---|---|
| Super admin | Any (global, partner, tenant). |
| Partner admin | partner scoped to your partner; tenant scoped to your tenants. |
| Tenant admin | tenant scoped to your tenant. |
Groups outside your scope are silently dropped from the request — the publish still succeeds, but the model is not added to those groups. There is no error for "you tried to add to a group you can't see." If you need the explicit feedback, list groups via the standard /v1/models/groups endpoints first.
What you can't do (yet)#
- Stream from a published Core. Capabilities are set with
streaming: false. The Core's response is materialised then returned; long-running flows that yield tokens incrementally are not exposed through/v1/inference/chatstreaming today. - Direct OpenAI-compat dispatch. Published Cores work through the native
/v1/inference/chatendpoint. The/oai/v1/compat layer routes through the same dispatcher, so it will work, but the wrapper is built around the native API as primary (see ScaiGrid's API hierarchy notes).
Common gotchas#
- No groups, no visibility. Publishing without
group_idsleaves the model out of every group. Clients with group-restricted scopes won't see it. If you want public visibility for the tenant, add the slug to your tenant's default model group. - Slug collisions. Slug is
scaicore/{tenant_slug}/{core_slug}— already-unique-by-design, no collision possible unless you somehow forge a tenant slug. If you do hit a collision, the underlying DB write will fail with a uniqueness error. - Re-publish requires unpublish. Calling
publishon an already-published Core errors out. Unpublish first, then publish again. Edits to the published row usesync(), not republish.