Build a Plugin

Create a Studio Plugin with a witwin.toml manifest, register Agent Tools and a solver, contribute a Project template, and load it locally.

A Plugin is a folder with a witwin.toml manifest and Python code that registers into Studio. This guide builds the skeleton of a solver Plugin and loads it from a local folder.

Layout#

wt_example/
  witwin.toml        # the manifest
  pyproject.toml     # makes the Plugin a pip distribution named wt-example
  __init__.py        # importing it registers components, panels, ...
  agent_tools.py     # Agent Tools
  solver_host.py     # the solver process
  templates/         # optional Project templates

The manifest#

id = "example.solver"
name = "Example"
version = "0.1.0"
description = "A minimal solver Plugin."
license = "MIT"
repository = "https://github.com/you/wt_example"
dependencies = ["numpy"]
icon = "box"
 
[[contributes.tools]]
module = "agent_tools"
register = "register"
 
[permissions]
tools = ["read", "scene_write", "execute"]
 
[[contributes.solvers]]
id = "example.solve"
title = "Example solver"
entry = "solver_host.py"
lifecycle = "warm"
idleTimeoutSec = 300
 
[contributes.solvers.runtime]
python = "${project:python}"

[permissions] is a disclosure shown before the user trusts the Plugin; it does not sandbox the code. See the witwin.toml reference for every field.

Write the solver#

Solvers run in their own process on the Project's interpreter (${project:python}), so heavy dependencies such as CUDA builds of PyTorch stay out of Studio. The solver SDK is witwin.studio.solver:

from witwin.studio.solver import serve
 
 
def solve(ctx, scene, config):
    ctx.progress(0.5, "halfway")
    # read the scene, run the computation, return the outputs
    return {"value": 42}
 
 
if __name__ == "__main__":
    serve(solve, scene="document")

scene="document" hands solve the Scene document as a dict, so the solver process never imports the editor's server code and runs on any Project interpreter. ctx.progress reports progress to Studio and to witwin solve.

Load it while you develop#

On the Plugins page, open the + Add menu, choose Add Local Plugin Path and pick the folder. A local Plugin never triggers a dependency install: install its requirements into your environment yourself. If a requirement is missing, the Plugin is listed with the reason and its code is not loaded.

From the command line, pass --plugin-path to witwin solve or witwin host.

Contribute a Project template#

A template is a folder copied into a new Project, plus a content manifest whose sha256 is pinned in witwin.toml:

[[contributes.templates]]
id = "example-sim"
title = "Example Sim"
icon = "box"
version = "1.0.0"
dir = "templates/example-sim"
manifest = "template.manifest.json"
sha256 = "<sha256 of template.manifest.json>"
preview = "templates/example-sim.webp"

The payload must contain witwin.toml, and should be a complete Python Project: a pyproject.toml that depends on your Plugin, plus scripts/ and tests/ that run with witwin.studio alone. .witwin/, results/, plugins/, .venv/ and __pycache__/ are refused.

Commit template payloads with line-ending conversion off (templates/** -text in .gitattributes); otherwise a Windows checkout rewrites line endings and the hashes stop matching.

Publish#

Plugins are distributed from git repositories or the witwin index, never from PyPI. Tag a release in your repository; users add it with git+https://github.com/you/wt_example and the tag.