scriptling.runtime.plugin
Declare a Scriptling script as a first-class plugin server.
scriptling.runtime.plugin lets a setup script expose itself via the full
Scriptling plugin protocol — the same protocol used by compiled Go or C plugin
executables. When the server starts, clients can load it with scriptling=True
and receive auto-generated plugin.<name> proxy libraries with wrappers for
every registered function, constant, and class.
Available in the agent variant of Scriptling only (registered alongside
scriptling.ai.agent).
Available Functions
| Function | Description |
|---|---|
serve(name, version="", description="") |
Declare this script as a plugin server |
register_function(name, handler) |
Register a callable function |
register_constant(name, value) |
Register a read-only constant |
register_class(handler) |
Register a class with full object lifecycle |
Function Reference
scriptling.runtime.plugin.serve(name, version="", description="")
Declare this script as a Scriptling plugin server.
Parameters:
name(str): Library name. Clients import it asplugin.<name>.version(str, optional): Version string (e.g."1.0.0").description(str, optional): Human-readable description surfaced in plugin metadata.
Must be called before runtime.start_server(). A warning is printed to stderr
if called after the server has started.
scriptling.runtime.plugin.register_function(name, handler)
Register a function for the plugin server.
Parameters:
name(str): Function name exposed to plugin clients.handler(str): Handler as"library.function"string.
The handler receives individual positional arguments decoded from the plugin
transport — not a raw params blob. Each call runs on a fresh, isolated
evaluator (the same concurrency model as runtime.http and runtime.jsonrpc
handlers).
Callbacks: If a client passes a callable (function or lambda) as an argument, the handler receives it as a callable object and can invoke it normally. Callbacks are only supported over the stdio transport; HTTP connections are request/response only.
Raise an exception from the handler to produce an error response on the client side.
scriptling.runtime.plugin.register_constant(name, value)
Register a constant exported by the plugin server.
Parameters:
name(str): Constant name exposed to plugin clients.value(any): Any JSON-serialisable value:bool,int,float,str,list,dict, orNone.
Constants are included in the scriptling.handshake schema and delivered to
clients as part of the auto-generated proxy library. Clients read them as plain
attributes: plugin.myservice.VERSION.
scriptling.runtime.plugin.register_class(handler)
Register a class exported by the plugin server.
Parameters:
handler(str): Class as"library.ClassName"string.
The exposed class name is taken from the last segment of handler
(e.g. "mymodule.Config" → "Config"). The server handles the complete
object lifecycle:
object.new— calls the constructor (__init__), stores the instance server-side, returns a remote handle.object.call_method— calls a method on the stored instance.object.destroy— calls__del__(if defined) and removes the instance.
The class and its method closures are resolved once at server startup. Must be
called before runtime.start_server().
Transports
| Transport | Functions | Constants | Classes | Callbacks |
|---|---|---|---|---|
| stdio | ✓ | ✓ | ✓ | ✓ |
| HTTP | ✓ | ✓ | ✓ | — (request/response only) |
Run as a stdio plugin server:
scriptling --json-rpc setup.pyRun as an HTTP plugin server (plugin protocol served at POST /json-rpc):
scriptling --server :8000 --json-rpc setup.pyExamples
Basic function server
# setup.py
import scriptling.runtime.plugin as plugin_srv
import scriptling.runtime as runtime
plugin_srv.serve("calculator", "1.0", "Basic arithmetic operations")
plugin_srv.register_function("add", "handlers.add")
plugin_srv.register_function("multiply", "handlers.multiply")
plugin_srv.register_constant("VERSION", "1.0.0")
runtime.start_server()# handlers.py
def add(a, b):
return a + b
def multiply(a, b):
return a * b# client script
import scriptling.plugin as plugin
plugin.load("calculator", "scriptling", scriptling=True, args=["--json-rpc", "setup.py"])
import plugin.calculator
print(plugin.calculator.VERSION) # "1.0.0"
print(plugin.calculator.add(3, 4)) # 7
print(plugin.calculator.multiply(3, 4)) # 12Classes
# setup.py
import scriptling.runtime.plugin as plugin_srv
import scriptling.runtime as runtime
plugin_srv.serve("formatter", "1.0")
plugin_srv.register_class("handlers.Template")
runtime.start_server()# handlers.py
class Template:
def __init__(self, prefix):
self.prefix = prefix
def render(self, name):
return self.prefix + name# client script
import plugin.formatter
t = plugin.formatter.Template("Hello, ")
print(t.render("world")) # "Hello, world"Callbacks (stdio only)
# setup.py
import scriptling.runtime.plugin as plugin_srv
import scriptling.runtime as runtime
plugin_srv.serve("transform", "1.0")
plugin_srv.register_function("apply", "handlers.apply")
runtime.start_server()# handlers.py
def apply(fn, items):
return [fn(x) for x in items]# client script
import plugin.transform
result = plugin.transform.apply(lambda x: x * 2, [1, 2, 3])
print(result) # [2, 4, 6]Keeping the setup script alive
Use runtime.start_server(wait=False) with a server_running() loop when the
setup script needs to maintain state or perform cleanup on shutdown:
import scriptling.runtime.plugin as plugin_srv
import scriptling.runtime as runtime
plugin_srv.serve("stateful", "1.0")
plugin_srv.register_function("greet", "handlers.greet")
plugin_srv.register_constant("VERSION", "1.0.0")
runtime.start_server(wait=False)
while runtime.server_running():
yield_now()
# cleanup runs here after shutdown signalComparison with Go Plugins
| Go plugin | Scriptling plugin server | |
|---|---|---|
| Language | Go | Scriptling (Python-like) |
| Distribution | Compiled binary | Script file |
| Handler isolation | Shared process state | Fresh evaluator per call |
| Type safety | Typed via FunctionBuilder |
Duck-typed |
| Functions | RegisterFunc |
register_function |
| Constants | Constant |
register_constant |
| Classes | RegisterClass |
register_class |
| Callbacks | stdio and HTTP | stdio only |
Notes
runtime.start_server()is optional. If the setup script exits without calling it, the server starts automatically (backward-compatible behaviour). Call it explicitly when you needwait=Falselifecycle control.- All registration calls (
register_function,register_constant,register_class) must happen beforeruntime.start_server(). Calls after server start are silently ignored with a stderr warning. - Handler functions run on fresh evaluators and cannot share in-memory state.
Use
runtime.kvfor cross-request state.