Actions¶
zelos_sdk.actions defines actions that the Zelos app, the CLI and Zelos AI can run.
zelos_sdk.action and zelos_sdk.actions_registry are the same objects as zelos_sdk.actions.action and zelos_sdk.actions.actions_registry.
Actions system for Zelos SDK
This module provides a comprehensive action definition, registration, and execution system.
Action(callable_obj, title, description=None, timeout=30.0, fields=None, instance=None, standalone=False, submit_text=None, read_only=False)
¶
Defines an executable action with input validation and schema generation.
This class wraps a callable (function or method) with metadata, parameter validation, and execution management. It supports both synchronous and asynchronous execution with timeout handling.
Examples:
>>> @action("Add Numbers", "Add two numbers")
... @action.number("x")
... @action.number("y")
... def add(x: int, y: int) -> int:
... return x + y
Initialize an action with its callable and metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
callable_obj
|
Callable[..., T]
|
Function or method to execute |
required |
title
|
str
|
Human-readable title for the action |
required |
description
|
Optional[str]
|
Optional description of what the action does |
None
|
timeout
|
float
|
Maximum execution time in seconds |
30.0
|
fields
|
Optional[List[BaseField]]
|
List of input field definitions |
None
|
instance
|
Optional[Any]
|
Class instance if this is a bound method |
None
|
standalone
|
bool
|
Whether the action can run without the extension running |
False
|
submit_text
|
Optional[str]
|
Label for the run button in the app; defaults to "Execute" |
None
|
read_only
|
bool
|
Whether the action changes nothing, so Zelos AI runs it without asking |
False
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If timeout is not positive, or title or submit_text is empty |
TypeError
|
If callable_obj is async (not supported), submit_text is not a string, or read_only is not a bool |
execute(**kwargs)
¶
Execute the action with the given parameters.
Validates all inputs, checks required fields, and executes the underlying callable. Only synchronous functions are supported.
The method handles different return types: - Regular values: Wrapped as ActionExecuteResult.done(value) - None: Returned as ActionExecuteResult.done({}) - ActionExecuteResult: Returned as-is (explicit status control) - Exceptions: Raised as ActionExecutionError (error)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kwargs
|
Any
|
Keyword arguments to pass to the callable |
{}
|
Returns:
| Type | Description |
|---|---|
Union[T, ActionExecuteResult]
|
ActionExecuteResult with value and status |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If input validation fails or required fields are missing |
ActionExecutionError
|
If execution fails |
to_schema(current_values=None)
¶
Build a JSON Schema for this action's inputs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
current_values
|
Optional[Dict[str, Any]]
|
Optional dict of current form data, used for dynamic choices |
None
|
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
A dictionary representing the JSON Schema |
to_schema_json(current_values=None)
¶
Serialize the JSON Schema to a string, preserving property order.
RJSF renders form fields in the order properties appear in the schema,
so the PyO3 bridge calls this directly — doing json.dumps on the
Python side keeps insertion order (Python dicts preserve it since 3.7)
and avoids a serde_json::Value round-trip in Rust (its Map is
backed by BTreeMap, which would re-sort keys alphabetically).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
current_values
|
Optional[Dict[str, Any]]
|
Optional dict of current form data, forwarded to |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The JSON Schema encoded as a JSON string |
to_ui_schema()
¶
UI Schema for this action's inputs and provides hints for rendering form inputs in a user interface.
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
A dictionary representing the UI Schema |
to_ui_schema_json()
¶
Serialize the UI Schema to a string, preserving key order.
See to_schema_json for why this lives on the Python side.
Returns:
| Type | Description |
|---|---|
str
|
The UI Schema encoded as a JSON string |
ActionDecorator()
¶
Provides the @action decorator interface for defining actions with input fields.
This class enables a fluent decorator syntax for creating actions and defining their input parameters. It supports both function and method decoration.
Examples:
>>> @action("Add Numbers", "Add two numbers")
... @action.number("x")
... @action.number("y")
... def add(x: int, y: int) -> int:
... return x + y
Or with keyword arguments:¶
>>> @action(title="Add Numbers", description="Add two numbers")
... @action.number("x")
... def add(x: int, y: int) -> int:
... return x + y
Initialize the decorator with its input field decorator.
__call__(title_or_func=None, description=None, timeout=30.0, standalone=False, submit_text=None, read_only=False, **kwargs)
¶
Create an action decorator or decorate a function directly. Supports both positional and keyword arguments.
Can be used as
@action @action("title") @action("title", "description") @action(title="title") @action(title="title", description="description") @action("title", standalone=True) @action("title", submit_text="Flash") @action("title", read_only=True)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title_or_func
|
Union[str, Callable[..., T], F]
|
Function to decorate or the action title |
None
|
description
|
Optional[str]
|
Optional description of what the action does |
None
|
timeout
|
float
|
Maximum execution time in seconds |
30.0
|
standalone
|
bool
|
Whether this action can run without the extension running.
Standalone actions must have a static schema — see |
False
|
submit_text
|
Optional[str]
|
Label for the run button in the app; defaults to "Execute" |
None
|
read_only
|
bool
|
Whether the action changes nothing: no device, file, config or trace. Zelos AI runs a read-only action without asking first, so declare it only when that holds for every input. |
False
|
kwargs
|
Any
|
Additional keyword arguments (title can be passed here) |
{}
|
Returns:
| Type | Description |
|---|---|
Union[F, Callable[[F], F]]
|
Decorated function or a decorator function |
Raises:
| Type | Description |
|---|---|
ValueError
|
If timeout is not positive or title is invalid |
array(name, **kwargs)
¶
Defines an array input field for handling lists of items.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the field. |
required |
Keyword arguments, forwarded to the field schema:
item: A dictionary defining the schema for items in the array.title: A human-readable title for the field.description: A description of the field.required: Whether the field is required. Defaults to True.min_items: The minimum number of items in the array.max_items: The maximum number of items in the array.unique_items: Whether all items in the array must be unique.
Returns:
| Type | Description |
|---|---|
Callable[[F], F]
|
A decorator that registers the array field. |
boolean(name, **kwargs)
¶
Defines a boolean (true/false) input field for an action.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the field. |
required |
Keyword arguments, forwarded to the field schema:
title: A human-readable title for the field.description: A description of the field.required: Whether the field is required. Defaults to True.default: A default value for the field (True or False).widget: The UI widget to use (e.g., "toggle", "checkbox").
Returns:
| Type | Description |
|---|---|
Callable[[F], F]
|
A decorator that registers the boolean field. |
date(name, **kwargs)
¶
Defines a date input field for an action. Expects dates in "YYYY-MM-DD" format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the field. |
required |
Keyword arguments, forwarded to the field schema:
title: A human-readable title for the field.description: A description of the field.required: Whether the field is required. Defaults to True.default: A default value for the field (e.g., "2024-01-01").
Returns:
| Type | Description |
|---|---|
Callable[[F], F]
|
A decorator that registers the date field. |
email(name, **kwargs)
¶
Defines an email input field for an action with built-in validation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the field. |
required |
Keyword arguments, forwarded to the field schema:
title: A human-readable title for the field.description: A description of the field.required: Whether the field is required. Defaults to True.default: A default value for the field.
Returns:
| Type | Description |
|---|---|
Callable[[F], F]
|
A decorator that registers the email field. |
file(name, **kwargs)
¶
Defines a single file input field for an action. The file is received as a data URL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the field. |
required |
Keyword arguments, forwarded to the field schema:
title: A human-readable title for the field.description: A description of the field.required: Whether the field is required. Defaults to True.accept: A string of comma-separated file types to accept (e.g., ".png,.jpg").
Returns:
| Type | Description |
|---|---|
Callable[[F], F]
|
A decorator that registers the file field. |
files(name, **kwargs)
¶
Defines a multiple file input field for an action. Files are received as a list of data URLs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the field. |
required |
Keyword arguments, forwarded to the field schema:
title: A human-readable title for the field.description: A description of the field.required: Whether the field is required. Defaults to True.accept: A string of comma-separated file types to accept (e.g., ".png,.jpg").
Returns:
| Type | Description |
|---|---|
Callable[[F], F]
|
A decorator that registers the files field. |
integer(name, **kwargs)
¶
Defines an integer input field for an action.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the field. |
required |
Keyword arguments, forwarded to the field schema:
title: A human-readable title for the field.description: A description of the field.required: Whether the field is required. Defaults to True.default: A default value for the field.minimum: The minimum allowed value.maximum: The maximum allowed value.
Returns:
| Type | Description |
|---|---|
Callable[[F], F]
|
A decorator that registers the integer field. |
number(name, **kwargs)
¶
Defines a number (float or integer) input field for an action.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the field. |
required |
Keyword arguments, forwarded to the field schema:
title: A human-readable title for the field.description: A description of the field.required: Whether the field is required. Defaults to True.default: A default value for the field.minimum: The minimum allowed value.maximum: The maximum allowed value.
Returns:
| Type | Description |
|---|---|
Callable[[F], F]
|
A decorator that registers the number field. |
object(name, **kwargs)
¶
Defines an object input field for handling nested key-value data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the field. |
required |
Keyword arguments, forwarded to the field schema:
properties: A dictionary defining the schema for the object's properties.title: A human-readable title for the field.description: A description of the field.required: Whether the field is required. Defaults to True.
Returns:
| Type | Description |
|---|---|
Callable[[F], F]
|
A decorator that registers the object field. |
select(name, **kwargs)
¶
Defines a select (dropdown) input field for an action.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the field. |
required |
Keyword arguments, forwarded to the field schema:
choices: A list of options or a callable that returns a list of options.title: A human-readable title for the field.description: A description of the field.required: Whether the field is required. Defaults to True.default: A default value for the field.depends_on: A field name or list of field names that this field's choices depend on.
Returns:
| Type | Description |
|---|---|
Callable[[F], F]
|
A decorator that registers the select field. |
text(name, **kwargs)
¶
Defines a text input field for an action.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the field. |
required |
Keyword arguments, forwarded to the field schema:
title: A human-readable title for the field.description: A description of the field.required: Whether the field is required. Defaults to True.default: A default value for the field.min_length: The minimum allowed length for the text.max_length: The maximum allowed length for the text.pattern: A regex pattern to validate the text against.widget: The UI widget to use (e.g., "textarea").
Returns:
| Type | Description |
|---|---|
Callable[[F], F]
|
A decorator that registers the text field. |
ActionExecuteResult
¶
Python-exposed result type for action execution
done(value)
classmethod
¶
Create a DONE result (completed without pass/fail classification).
error(value)
classmethod
¶
Create an ERROR result with the given value.
failed(value)
classmethod
¶
Create a FAIL result with the given value.
failure(value)
classmethod
¶
Alias for failed() — backward compat with old ActionResult.failure().
passed(value)
classmethod
¶
Create a PASS result with the given value.
success(value)
classmethod
¶
Alias for passed() — backward compat with old ActionResult.success().
ActionExecuteStatus
¶
Bases: Enum
Python-exposed enum for action execution status
ActionExecutionError
¶
Bases: Exception
Exception raised when executing an action fails.
ActionValidationError
¶
Bases: Exception
Exception raised for validation errors in actions.
ActionsClient(url=...)
¶
Python wrapper for the Actions gRPC client
cancel()
¶
Stop the background serving task.
Returns:
| Type | Description |
|---|---|
None
|
None |
execute(action_path, params)
¶
Execute an action.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
action_path
|
str
|
Full action path (e.g., "service/action" or "service/name/action") |
required |
params
|
dict
|
Parameters for the action |
required |
Returns:
| Name | Type | Description |
|---|---|---|
object |
Any
|
Result from the action execution |
list()
¶
List available actions.
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
Dictionary mapping service names to lists of action names |
serve(name, actions_registry=...)
¶
Start serving actions in a background task (non-blocking).
This method spawns a background task that handles the bidirectional stream and automatically reconnects if the stream fails.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name for this service |
required |
actions_registry
|
ActionsRegistry
|
The actions registry to serve |
...
|
ActionsRegistry()
¶
Python wrapper for the Rust ActionsRegistry
This registry manages action registration and provides local action execution, providing a thin wrapper around the Rust ActionsRegistry for Python usage.
execute(action_path, params)
¶
Execute an action in this registry (synchronous wrapper).
Returns:
| Name | Type | Description |
|---|---|---|
ActionExecuteResult |
Any
|
Result containing value and status |
get_action_schema(action_path, current_values)
¶
Get schema for an action in this registry.
Schemas come back to Python through json.loads so the schema's
properties dict preserves insertion order (matching RJSF's top-down
rendering convention) — a serde_json::Value round-trip would
alphabetize keys via BTreeMap.
list()
¶
List all registered actions in this registry.
register(obj, name=None)
¶
Register a Python action or object with this registry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
Action | object
|
Either an Action object or a class instance with @action decorated methods |
required |
name
|
str
|
Custom name/path for the action(s). If not provided, uses object name. |
None
|
Examples:
ArrayField(name, item, additional_items=None, min_items=None, max_items=None, unique_items=False, **kwargs)
¶
Bases: BaseField
Field for handling arrays of items, supporting both fixed and variable lengths.
BaseField(name, title=None, description=None, required=True, default=None, widget=None, ui_options=None, placeholder=None, requires=None, **kwargs)
¶
BooleanField(name, **kwargs)
¶
DateField(name, **kwargs)
¶
Bases: TextField
Field for date input, inherits from TextField with a predefined pattern and format.
EmailField(name, **kwargs)
¶
FieldType
¶
Bases: Enum
Enumeration of supported field types for action inputs.
has_value(value)
classmethod
¶
Check if a value is a valid field type.
FileField(name, accept=None, **kwargs)
¶
FilesField(name, accept=None, **kwargs)
¶
IntegerField(name, minimum=None, maximum=None, multiple_of=None, **kwargs)
¶
NumberField(name, minimum=None, maximum=None, multiple_of=None, **kwargs)
¶
Bases: BaseField
Field for numerical input (integer or float) with optional min and max constraints.
SelectField(name, choices, depends_on=None, **kwargs)
¶
Bases: BaseField
Field for selecting options from a predefined list. Supports dynamic choices based on dependencies.
TextField(name, min_length=None, max_length=None, pattern=None, **kwargs)
¶
ValidationError(field_name, message, code='invalid')
¶
Bases: Exception
Exception raised for validation errors in fields.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
field_name
|
str
|
The name of the field where validation failed. |
required |
message
|
str
|
Description of the validation error. |
required |
code
|
str
|
Error code categorizing the type of validation error. |
'invalid'
|
Widget
¶
Bases: Enum
Enumeration of supported UI widgets for action inputs.
Widgets are grouped by their primary type and usage.
has_value(value)
classmethod
¶
Check if a value is a valid widget type.
create_field(name, type, **kwargs)
¶
Factory method to create a field based on its type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the field. |
required |
type
|
str
|
The type of the field. |
required |
kwargs
|
Any
|
Additional keyword arguments for field initialization. |
{}
|
Returns:
| Type | Description |
|---|---|
BaseField
|
An instance of a subclass of BaseField. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the field type is unsupported or required arguments are missing. |
discover_actions(entry_point_group='zelos_sdk.actions', skip_errors=True, registry=None)
¶
Discover and register all actions from entry points.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entry_point_group
|
str
|
Entry point group to scan for actions |
'zelos_sdk.actions'
|
skip_errors
|
bool
|
If True, continue after errors; if False, raise exceptions |
True
|
Returns:
| Type | Description |
|---|---|
Dict[str, List[str]]
|
Dictionary mapping entry point names to lists of registered actions |
Raises:
| Type | Description |
|---|---|
ActionDiscoveryError
|
If discovery fails and skip_errors is False |
get_global_actions_registry()
¶
Get the global actions registry
get_standalone_actions()
¶
Return every standalone=True action registered by import-time decoration.
Populated in registration order and keyed by the action's registry path
("convert" for a module-level function, "Class/method" for a static
method) — the same path the live actions registry serves it under.
Returns:
| Type | Description |
|---|---|
Dict[str, Action]
|
Copy of the standalone action index, path -> Action |
init_global_actions_client(name, url=..., actions_registry=...)
¶
Initialize the global actions client with a background task
This creates a global actions client that runs in the background without blocking or interfering with Python's signal handling. The client will automatically reconnect if the connection is lost and can be cleanly shut down via atexit handlers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name for this service |
required |
url
|
str
|
Server URL (e.g., "grpc://localhost:2300") |
...
|
actions_registry
|
ActionsRegistry
|
The actions registry to serve |
...
|
init_global_actions_registry()
¶
Initialize the global actions registry
register_field_type(type_name)
¶
Decorator to register a field class with a given type name.