Search Modaic documentation

Find a Modaic guide or API reference

Models with the SDK

Models hold a versioned decision configuration and the examples, decisions, and jobs associated with it.

List models

from modaic import Modaic

modaic = Modaic()
available = modaic.models.list()

for model in available.models:
    print(model.name, model.type, model.repository_id)

The response includes Modaic base models and repository models the API key can access.

Create and configure a model

model = modaic.models.create(
    workspace="acme",
    slug="support-priority",
    description="Prioritizes support tickets and identifies refund requests.",
    model="mo-fast",
    questions={
        "priority": {
            "type": "choice",
            "instructions": "Choose the support priority.",
            "criteria": {
                "low": "No financial or time-sensitive impact.",
                "normal": "Routine customer issue.",
                "high": "Financial impact or an urgent blocker.",
            },
        }
    },
)

print(model.id)

The initial criteria are saved when the model is created. With questions supplied, model defaults to mo-fast if omitted.

Update a model

configured = modaic.models.update(
    model.id,
    questions={
        "priority": {
            "type": "choice",
            "criteria": {
                "normal": "Routine customer issue.",
                "high": "Financial impact or an urgent blocker.",
            },
        }
    },
    message="Simplify priority levels",
)
print(configured.commit.commit_sha if configured.commit else None)

Configuration updates create immutable commits. Pass branch to update a branch other than the default.

Alignment stores its optimized instructions in the same questions you set here. Once a model has an alignment checkpoint, an update whose questions differ from the stored ones fails with 409 alignment_would_be_discarded instead of silently reverting the model. Leave questions out to keep the aligned instructions, or pass discardAlignment: true (TypeScript) / discard_alignment=True (Python) to replace them and reset the checkpoint.

Branches, tags, and rollback

Every model is a Git repository, and the SDK exposes its history. models.get returns commit, the default branch's head, so you can update safely and tag what you want to keep.

model = modaic.models.get(workspace="acme", model="support-priority")

# Refuse to overwrite anything newer than what we read. The check applies to
# configuration changes (`model` or `questions`), not description-only updates.
updated = modaic.models.update(
    model.id,
    questions={
        "priority": {
            "type": "choice",
            "instructions": "Choose the support priority for this ticket.",
            "criteria": {
                "normal": "Routine customer issue.",
                "high": "Financial impact or an urgent blocker.",
            },
        }
    },
    expected_head_sha=model.commit.commit_sha,
)

# Name the new commit and pin production to it.
modaic.models.create_tag(model.id, name="v1", commit_sha=updated.commit.commit_sha)
modaic.decisions.create(model="acme/support-priority", revision="v1", state={"ticket": "..."})

# Undo a bad update: move main back to an earlier commit.
commits = modaic.models.list_commits(model.id, branch="main").commits
modaic.models.rollback(
    model.id,
    branch="main",
    target_commit_sha=commits[1].sha,
    expected_head_sha=commits[0].sha,
    message="Restore checkpoint 1",
)

A rollback is a new commit with the target's files, so model.json returns with its checkpoint and metrics. listBranches / list_branches, createBranch / create_branch, deleteBranch / delete_branch, listTags / list_tags, and deleteTag / delete_tag complete the set.

Get and delete a model

model = modaic.models.get(workspace="acme", model="support-priority")
print(model.id, model.default_branch, model.configuration)

modaic.models.delete(model.id)

Model deletion is permanent and removes the model's examples, decisions, and job history. Use the model ID returned by create() or get().

Was this page helpful?