iii-hq/iii

iii-sdk-reference

Use when working with iii SDK APIs across Node.js, browser, Python, Rust, or Go: package installation, worker initialization, function/trigger registration, observers, invocation, local dispatch, channels, logging, OpenTelemetry, and language-specific caveats.

Ver código fuente

Cómo usar

  1. Copia el comando y revisa el paquete antes de instalarlo en tu entorno de agente.
  2. Consulta las herramientas, credenciales y entornos necesarios en el documento original.
  3. Describe las entradas y el resultado deseado; contrasta la salida con las fuentes.
npx skills add https://github.com/iii-hq/iii --skill iii-sdk-reference

Antes de empezar

  • La instalación no incluye suscripción al modelo, cuota API ni permisos sobre tus archivos.
  • Las estrellas e instalaciones reflejan actividad, no una prueba independiente de calidad o seguridad.
Documento original del Skill

Contenido del repositorio de origen con títulos, ejemplos, código, tablas, enlaces e imágenes preservados.

SDK Reference

Use this skill for language-specific SDK details. Use iii-core-primitives for the common model and iii-error-handling for exception handling.

Install

bash
# TypeScript / Node.js
npm install iii-sdk

# Browser apps
npm install iii-browser-sdk

# Python
pip install iii-sdk

# Rust
cargo add iii-sdk

# Go
go get github.com/iii-hq/iii/sdk/packages/go/iii

Choose the SDK

SDKPackageBest forImportant caveat
Node.jsiii-sdkServer-side TypeScript/JavaScript workersSupports custom headers, Logger, OpenTelemetry, HTTP-invoked functions
Browseriii-browser-sdkWeb apps and interactive UI callbacksConnect through the rbac-proxy worker's public port, never the engine port; keep secrets server-side
Pythoniii-sdkSync or async Python workersUse trigger_async inside async handlers
Rustiii-sdkHigh-performance tokio workersHandler error type should map into iii_sdk::Error
Gogithub.com/iii-hq/iii/sdk/packages/go/iiiGo servicesHandlers take (ctx, json.RawMessage); pass the handler's ctx to Trigger

Logger/OpenTelemetry, HTTP request/response types, stream, queue, and worker-connection types live in the helpers package, installed alongside the SDK: @iii-dev/helpers (Node, with submodules like /observability and /http) or iii-helpers (Python iii_helpers.*, Rust iii_helpers::*).

Common API Map

CapabilityNode / browserPythonRustGo
Connect workerregisterWorker(url, options?)register_worker(address, options?)register_worker(url, InitOptions)iii.RegisterWorker(url, opts...)
Register local functionregisterFunction(id, handler, options?)register_function(id, handler, **options)register_function("id", RegisterFunction::new(...))client.RegisterFunction(id, handler, opts...)
Register trigger (deprecated in 0.25)registerTrigger({ type, function_id, config })register_trigger({...})register_trigger(RegisterTriggerInput::new(type, function_id, config))client.RegisterTrigger(id, type, functionID, config)
Observe a functionobserve(source, target, options?)observe(source, target, options)observe(Source::function(id)..., target) / observe_with(.., ObserverOptions)client.Observe(iii.Source{...}, target, opts...)
Owner hooksregisterFunction(id, h, { observe: {...} })register_function(id, h, observe=ObserveHooks(...))RegisterFunction::new(h).observe(Observe::owner()...)RegisterFunctionOptions{Observe: &iii.ObserveHooks{...}}
Current invocationcurrentInvocation()current_invocation()iii_sdk::current_invocation()iii.InvocationFromContext(ctx)
Invoke functiontrigger({ function_id, payload })trigger(request) / trigger_async(request)trigger(TriggerRequest)client.Trigger(ctx, iii.TriggerRequest{...})
Durable enqueueTriggerAction.Enqueue({ queue }){"type": "enqueue", "queue": name}TriggerAction::Enqueue { queue }iii.EnqueueAction(queue)
ChannelscreateChannel(iii) (iii-sdk/helpers)create_channel(iii) / create_channel_async(iii) (iii.helpers)iii_sdk::helpers::create_channel(&iii, None).awaitclient.CreateChannel(ctx, nil)

Node.js

typescript
import { registerWorker } from "iii-sdk";
import { Logger } from "@iii-dev/helpers/observability";

const iii = registerWorker("ws://localhost:49134", {
  workerName: "node-worker",
  invocationTimeoutMs: 30000,
});

iii.registerFunction("users::lookup", async (input) => {
  new Logger().info("looking up user", { userId: input.userId });
  return { userId: input.userId, name: "Ada" };
});

Node supports custom WebSocket headers, Logger, OpenTelemetry options, HTTP-invoked function registration, trigger metadata, channels, observers, and owner hooks. Custom trigger types (registerTriggerType) still work but are deprecated in 0.25.

Browser

typescript
import { registerWorker, TriggerAction } from "iii-browser-sdk";

const iii = registerWorker("wss://api.example.com/worker?token=session-token");

const result = await iii.trigger({
  function_id: "backend::get-user",
  payload: { userId: "123" },
});

await iii.trigger({
  function_id: "analytics::track",
  payload: { event: "page_view" },
  action: TriggerAction.Void(),
});

Do not expose the private engine worker port to untrusted browsers; put the rbac-proxy worker in front of it (iii trigger compose::add worker=rbac-proxy). Browser workers cannot send custom WebSocket headers and must not hold backend secrets.

Since 0.25 the browser trigger also sends metadata, traceparent and baggage, and handlers receive metadata as their second argument. Browsers have no AsyncLocalStorage: iii.currentInvocation() is only known until the handler's first await, so read it first and wrap later calls in iii.withInvocation(inv, () => ...).

Python

python
from iii import InitOptions, register_worker
from iii_helpers.observability import Logger

iii = register_worker(
    address="ws://localhost:49134",
    options=InitOptions(worker_name="python-worker"),
)

def lookup_user(data):
    Logger().info("looking up user", {"userId": data["userId"]})
    return {"userId": data["userId"], "name": "Ada"}

iii.register_function("users::lookup", lookup_user)

Python handlers may be sync or async. Use await iii.trigger_async(request) inside async handlers, and iii.trigger(request) in sync contexts. HttpResponse (from iii_helpers.http) uses status_code, like the other helpers packages.

Rust

rust
use iii_sdk::{register_worker, InitOptions, RegisterFunction};
use serde_json::json;

let iii = register_worker("ws://127.0.0.1:49134", InitOptions::default());

iii.register_function(
    "users::lookup",
    RegisterFunction::new(|input: serde_json::Value| -> Result<serde_json::Value, iii_sdk::Error> {
        Ok(json!({ "userId": input["userId"], "name": "Ada" }))
    }).description("Look up a user"),
);

Rust supports typed handlers and schema extraction when input/output types derive schemars::JsonSchema. Add the otel feature when using OpenTelemetry helpers. register_trigger and register_trigger_type carry #[deprecated(since = "0.25.0")]: calls compile with a warning (use #[allow(deprecated)] where you still need them). A local call runs on the caller's task, and a sync handler (RegisterFunction::new) runs inline: make a blocking handler async or opt out with .local_dispatch(false).

Go

go
client := iii.RegisterWorker(iii.DefaultEngineURL, iii.WithNamespace("orders"))

client.RegisterFunction("users::lookup", func(ctx context.Context, data json.RawMessage) (any, error) {
	var in struct{ UserID string `json:"userId"` }
	if err := json.Unmarshal(data, &in); err != nil {
		return nil, err
	}
	return map[string]string{"userId": in.UserID, "name": "Ada"}, nil
})

Per-invocation metadata rides on ctx (iii.MetadataFromContext(ctx)). Inside a handler, pass its ctx to client.Trigger so the call carries the caller and the observe depth.

Observers and local dispatch (0.25)

  • observe(source, target, options?) is in every SDK; registerTrigger and registerTriggerType

are deprecated (one warning per process, still working). The built-in providers (http, cron, queue, state, stream, pub/sub, database) have not migrated, so keep registerTrigger for them. Details and examples per language: iii-observe.

  • A call to a function the same worker registered runs in-process once the engine confirmed it.

Force the engine path per call with dispatch: 'remote' (Node, browser, Python "dispatch": "remote"), Rust TriggerRequest::new(..).dispatch(Dispatch::Remote), Go Dispatch: iii.DispatchRemote; or per function with localDispatch: false (local_dispatch=False, .local_dispatch(false), LocalDispatch: &off).

  • registerFunction returns a FunctionRef with isObserved() / observers() (Python

is_observed(), Rust is_observed(), Go client.IsObserved(id)).

Channels

  • Use channels for binary data, large payloads, or streaming transfer between workers.
  • Pass readerRef or writerRef through a function payload.
  • Reconstruct readers/writers from refs in consumers when the SDK requires it.

Namespaces

A worker belongs to one namespace: options.namespace (InitOptions.namespace) → the III_NAMESPACE environment variable → the engine's default. Compose sets III_NAMESPACE to its daemon's namespace (iii compose -n dev ...) for every worker it starts, so a whole project lands in one namespace without any code change. Routing is strict: a function is only reachable in the namespace it registered in.

  • iii.trigger({ function_id }) resolves in the calling worker's namespace. Calls to your own

functions and to other workers declared in the same worker-compose.yaml need no namespace.

  • Engine-owned functions register in default: engine::*, configuration::*, stream::*

(from iii-stream) and the observability::* sources. engine::* and configuration::* resolve there implicitly (since 0.24.5); for the others pass namespace: "default" on the call, or on an observe source, when your worker runs in a Compose namespace.

  • registerTrigger binds in the worker's namespace. Leave trigger_namespace unset; the engine

looks for the trigger type's provider in your namespace first and the engine's own second, which is what lets a project ship its own http provider or fall back to the engine's cron.

  • Never prefix a function id with a namespace. The id stays orders::validate; the namespace is a

separate field.

  • From the CLI, iii trigger -n dev orders::validate ... selects the namespace; omitting -n

resolves in default.

typescript
// Same-project worker: no namespace
await iii.trigger({ function_id: "orders::validate", payload: order });

// Engine-owned configuration worker: resolves in `default` without a namespace;
// naming it explicitly is equivalent
const cfg = await iii.trigger({
  function_id: "configuration::get",
  namespace: "default",
  payload: { id: "orders" },
});
python
cfg = await iii.trigger_async(
    {"function_id": "configuration::get", "namespace": "default", "payload": {"id": "orders"}}
)
rust
let cfg = iii
    .trigger(TriggerRequest::new("configuration::get", json!({ "id": "orders" })).namespace("default"))
    .await?;

When to Use

  • Use this skill for package names, SDK exports, initialization options, browser security constraints,

channel API details, and language-specific syntax.

  • Use this when a task asks for Python, Rust, or Go examples and the issue is SDK syntax rather

than iii architecture.

Boundaries

  • For the common Function/Trigger/Worker model, built-in trigger schemas, custom triggers, and

invocation mode decisions, use iii-core-primitives.

  • For the observe model, filters, owner hooks, and the trigger migration, use iii-observe.
  • For deployment config, engine-owned workers, RBAC (rbac-proxy), and ports, use

iii-engine-config.

  • For retryability and exception classes, use iii-error-handling.
del mismo repositorio

Más Skills

Todos los Skills