Skip to content

Handler runtime

The handler preset has two runtime profiles. Python 3.12 is generally available. Node.js 22 is released through a capability- and policy-gated rollout; it can be prepared in source while its creation or dispatch switch remains disabled for a particular environment.

Runtime Entry file Export Result
Python 3.12 /app/handler.py callable handle(input) any value accepted by json.dumps
Node.js 22 /app/handler.ts named handle(input) a JSON value or a promise of one

For both runtimes:

  • input is a JSON object and defaults to {}
  • returning normally succeeds the run
  • an uncaught exception or a non-serializable result fails it
  • the handler module is initialized once per runtime process
  • invocation-specific data must not be stored in mutable module globals

Magmell supplies siloga_agent; do not add it to requirements.txt.

import siloga_agent
def handle(input: dict):
token = siloga_agent.secret("TOKEN")
siloga_agent.log("starting", item_id=input.get("id"))
with siloga_agent.span("work"):
result = work(input, token)
siloga_agent.metric("result.items", len(result))
siloga_agent.event("work.complete")
return result

siloga_agent.secret(name) returns the current invocation’s string value or None. Python ContextVar keeps secret and event state scoped to the invocation.

@siloga/magmell-agent is the in-handler Agent SDK, distinct from the @siloga/magmell control-plane client. Declare its exact compatible version as a devDependency; the platform supplies the protected runtime copy.

import { event, log, metric, secret, span } from '@siloga/magmell-agent'
export async function handle(input: { id?: string }) {
const token = secret('TOKEN')
log('starting', { itemId: input.id })
return span('work', async () => {
const result = await work(input, token)
metric('result.items', result.length)
event('work.complete')
return result
})
}

secret(name) returns string | undefined. Node’s AsyncLocalStorage scopes secrets and events across awaited work, including when multiple invocations overlap. Calls made after an invocation has finished do not emit into a later invocation.

See the Agent SDK reference for exact helper signatures.

Both runtimes expose the same concepts:

Helper Purpose
log structured diagnostic message with debug, default, warning, or error level
event named point-in-time domain event
metric named measurement with structured dimensions
span timed operation, emitted even when the operation raises or rejects

Values are normalized to bounded JSON at emission time. Unsupported or oversized event data is replaced with a diagnostic marker so it cannot corrupt the full invocation response. Events emitted before an exception are retained.

Runtime processes can handle overlapping invocations. The platform helper context is isolated, but your own module globals are not. Module scope is suitable for immutable configuration and reusable clients; keep request-specific values inside handle and its asynchronous call chain.

Nested source files are supported, while runtime-owned paths, credentials, absolute paths, and path traversal are rejected. handler.py, handler.ts, package.json, and package-lock.json must be top-level when applicable. A deployment may instead select the command preset to run an exact entrypoint argv; see command deployments. Ordered setup steps run during the build; see Setup and dependencies.

Before offering Node deployments, a gateway reports node-22 from /v1/capabilities with separate creation_enabled and dispatch_enabled states. The former gates deployment creation; the latter gates runs. Clients must check the state for the operation they are about to perform rather than assuming that recognition of the runtime ID means every phase is live.