Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when working with iii SDK APIs across Node.js, browser, Python, or Rust: package installation, worker initialization, function/trigger registration, invocation, channels, logging, OpenTelemetry, and language-specific caveats.
.claude/skills/iii-hq-iii-sdk-reference/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-21 | ✗→✓ | ▲ Improved | 40% | 0% |
| case-22 | ✗→✓ | ▲ Improved | 185% | 0% |
| case-01 | ✗→✓ | ▲ Improved | -16% | 0% |
| case-02 | ✗→✓ | ▲ Improved | -6% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 6% | 0% |
Use this skill for language-specific SDK details. Use iii-core-primitives for the common model and iii-error-handling for exception handling.
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
| SDK | Package | Best for | Important caveat | | --- | --- | --- | --- | | Node.js | iii-sdk | Server-side TypeScript/JavaScript workers | Supports custom headers, Logger, OpenTelemetry, HTTP-invoked functions | | Browser | iii-browser-sdk | Web apps and interactive UI callbacks | Connect through an RBAC-protected listener; keep secrets server-side | | Python | iii-sdk | Sync or async Python workers | Use trigger_async inside async handlers | | Rust | iii-sdk | High-performance tokio workers | Handler error type should map into iii_sdk::Error |
Logger/OpenTelemetry, HTTP request/response types, stream, queue, and worker-connection types live in the helpers package — @iii-dev/helpers (Node, with submodules like /observability and /http) or iii-helpers (Python iii_helpers.*, Rust iii_helpers::*) — installed alongside the SDK.
| Capability | Node | Python | Rust | | --- | --- | --- | --- | | Connect worker | registerWorker(url, options?) | register_worker(address, options?) | register_worker(url, InitOptions) | | Register local function | registerFunction(id, handler, options?) | register_function(id, handler, **options) | register_function(RegisterFunction::new(...)) | | Register trigger | registerTrigger({ type, function_id, config }) | register_trigger({...}) | register_trigger(RegisterTriggerInput { ... }) | | Invoke function | trigger({ function_id, payload }) | trigger(request) / trigger_async(request) | trigger(TriggerRequest) | | Durable enqueue | TriggerAction.Enqueue({ queue }) | {"type": "enqueue", "queue": name} | TriggerAction::Enqueue { queue } | | Channels | createChannel() | create_channel() / create_channel_async() | create_channel(None).await |
typescriptimport { 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, and custom trigger types.
typescriptimport { 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. Browser workers cannot send custom WebSocket headers and must not hold backend secrets.
pythonfrom 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 camelCase statusCode.
rustuse 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( RegisterFunction::new("users::lookup", |input: serde_json::Value| { 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.
readerRef or writerRef through a function payload.channel API details, and language-specific syntax.
architecture.
invocation mode decisions, use iii-core-primitives.
iii-engine-config.
iii-error-handling.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-21 | fail→pass | 6,467 | 1,544 | -76% | 1 | 1 | 0% | 1,177 | 1,647 | +40% | 0 | 0 | — |
case-22 | fail→pass | 3,605 | 1,198 | -67% | 1 | 1 | 0% | 551 | 1,572 | +185% | 0 | 0 | — |
case-01 | fail→pass | 14,230 | 4,328 | -70% | 1 | 1 | 0% | 2,966 | 2,480 | -16% | 0 | 0 | — |
case-02 | fail→pass | 14,185 | 5,169 | -64% | 1 | 1 | 0% | 2,641 | 2,482 | -6% | 0 | 0 | — |
case-03 | fail→pass | 11,343 | 4,632 | -59% | 1 | 1 | 0% | 2,317 | 2,452 | +6% | 0 | 0 | — |
case-04 | pass→pass | 14,123 | 9,611 | -32% | 1 | 1 | 0% | 2,832 | 3,199 | +13% | 0 | 0 | — |
case-05 | fail→fail | 14,460 | 10,134 | -30% | 1 | 1 | 0% | 2,781 | 3,531 | +27% | 0 | 0 | — |
case-06 | pass→pass | 15,031 | 10,185 | -32% | 1 | 1 | 0% | 2,657 | 3,277 | +23% | 0 | 0 | — |
case-07 | fail→pass | 14,483 | 1,887 | -87% | 1 | 1 | 0% | 2,979 | 1,782 | -40% | 0 | 0 | — |
case-08 | fail→pass | 10,417 | 1,951 | -81% | 1 | 1 | 0% | 2,221 | 1,813 | -18% | 0 | 0 | — |
case-09 | pass→pass | 7,612 | 2,355 | -69% | 1 | 1 | 0% | 1,361 | 1,841 | +35% | 0 | 0 | — |
case-10 | fail→pass | 11,458 | 1,993 | -83% | 1 | 1 | 0% | 2,461 | 1,789 | -27% | 0 | 0 | — |
case-11 | pass→pass | 13,075 | 2,304 | -82% | 1 | 1 | 0% | 2,370 | 1,815 | -23% | 0 | 0 | — |
case-12 | fail→pass | 13,207 | 2,259 | -83% | 1 | 1 | 0% | 2,740 | 1,895 | -31% | 0 | 0 | — |
case-13 | fail→pass | 13,547 | 7,091 | -48% | 1 | 1 | 0% | 2,518 | 2,849 | +13% | 0 | 0 | — |
case-14 | fail→pass | 7,519 | 2,571 | -66% | 1 | 1 | 0% | 1,272 | 1,925 | +51% | 0 | 0 | — |
case-15 | fail→pass | 13,071 | 4,585 | -65% | 1 | 1 | 0% | 2,594 | 2,315 | -11% | 0 | 0 | — |
case-16 | fail→pass | 23,462 | 18,008 | -23% | 1 | 1 | 0% | 3,998 | 1,808 | -55% | 0 | 0 | — |
case-17 | pass→pass | 13,622 | 3,537 | -74% | 1 | 1 | 0% | 2,293 | 1,981 | -14% | 0 | 0 | — |
case-18 | fail→pass | 9,660 | 2,009 | -79% | 1 | 1 | 0% | 1,691 | 1,692 | +0% | 0 | 0 | — |
case-19 | pass→pass | 20,002 | 2,125 | -89% | 1 | 1 | 0% | 3,093 | 1,750 | -43% | 0 | 0 | — |
case-20 | fail→pass | 13,236 | 6,122 | -54% | 1 | 1 | 0% | 2,238 | 2,249 | +0% | 0 | 0 | — |
case-23 | fail→pass | 9,195 | 2,967 | -68% | 1 | 1 | 0% | 1,652 | 1,910 | +16% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +70 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.