Agent skill
iii-channels
Binary streaming between workers via channels. Use when building data pipelines, file transfers, streaming responses, or any pattern requiring binary data transfer between functions.
Install this agent skill to your Project
npx add-skill https://github.com/iii-hq/iii/tree/main/skills/iii-channels
SKILL.md
Channels
Comparable to: Unix pipes, gRPC streaming, WebSocket data streams
Key Concepts
Use the concepts below when they fit the task. Not every worker needs channels.
- A Channel is a WebSocket-backed binary stream between two endpoints (writer and reader)
createChannel()returns a writer/reader pair plus serializable refs that can be passed to other workers- StreamChannelRef is a serializable reference (channel_id, access_key, direction) that can be included in function payloads
- Writers send binary data (chunked into 64KB frames) and text messages
- Readers consume binary chunks via
readAll()or receive text messages via callbacks - Consumers must construct a reader from a serializable
StreamChannelRef(e.g.,ChannelReader::new(...)) rather than using the producer-side reader object returned bycreateChannel() - Channels work cross-worker and cross-language — a Python writer can stream to a Rust reader
Architecture
A function creates a channel via createChannel(), receiving a writer and reader pair. The writer ref or reader ref is passed to another function (potentially in a different worker/language) via a trigger payload. The engine brokers the WebSocket connection between the two endpoints. Binary data flows directly between workers through the engine's channel endpoint.
iii Primitives Used
| Primitive | Purpose |
|---|---|
createChannel(bufferSize?) |
Create a channel, returns writer + reader pair |
ChannelWriter.write(data) |
Send binary data (chunked into 64KB frames) |
ChannelWriter.sendMessage(msg) |
Send a text message through the channel |
ChannelWriter.close() |
Close the writer end |
ChannelReader.readAll() |
Read entire stream into a single buffer |
ChannelReader.onMessage(callback) |
Register callback for text messages |
StreamChannelRef |
Serializable reference to pass between workers |
Reference Implementation
- TypeScript: ../references/channels.js
- Python: ../references/channels.py
- Rust: ../references/channels.rs
Each reference shows the same patterns (channel creation, binary streaming, text messages, cross-function handoff) in its respective language.
Common Patterns
Code using this pattern commonly includes, when relevant:
const channel = await iii.createChannel()— create a channel pair (producer access)channel.writer.stream.write(buffer)/channel.writer.write(data)— send binary datachannel.writer.sendMessage(JSON.stringify({ type: 'metadata', ... }))— send text metadatachannel.writer.close()— signal end of stream- Pass
channel.readerReforchannel.writerRefin trigger payloads for cross-worker streaming - Consumer must reconstruct the reader from the ref: e.g.,
new ChannelReader(iii.address, readerRef) const data = await reader.readAll()— read entire stream (consumer behavior)reader.onMessage(msg => { ... })— handle text messages (consumer behavior)
Adapting This Pattern
Use the adaptations below when they apply to the task.
- Use channels for large data transfers that shouldn't be serialized into JSON payloads
- Pass
readerRefto a processing function andwriterRefto a producing function for pipeline patterns - Use text messages for metadata/signaling alongside binary data streams
- Set
bufferSizewhen the reader may be slower than the writer to apply backpressure - Channels work cross-language — a TypeScript producer can stream to a Rust consumer
Pattern Boundaries
- For key-value state persistence, prefer
iii-state-management. - For stream CRUD (named streams with groups/keys), prefer
iii-realtime-streams. - For pub/sub messaging, prefer triggers with
subscribetype. - Stay with
iii-channelswhen the primary problem is binary data streaming between workers.
When to Use
- Use this skill when the task is primarily about
iii-channelsin the iii engine. - Triggers when the request directly asks for this pattern or an equivalent implementation.
Boundaries
- Never use this skill as a generic fallback for unrelated tasks.
- You must not apply this skill when a more specific iii skill is a better fit.
- Always verify environment and safety constraints before applying examples from this skill.
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
iii-dead-letter-queues
Inspects and redrives jobs that exhausted all retries. Use when handling failed queue jobs, debugging processing errors, or implementing retry strategies.
iii-cron-scheduling
Registers cron triggers with 7-field expressions to run functions on recurring schedules. Use when scheduling periodic jobs, timed automation, crontab replacements, cleanup routines, report generation, health checks, batch processing, or any task that should run every N seconds, minutes, hours, or on a weekly/monthly calendar.
iii-http-invoked-functions
Registers external HTTP endpoints as iii functions using registerFunction(id, HttpInvocationConfig). Use when adapting legacy APIs, third-party webhooks, or immutable services into triggerable iii functions, especially when prompts ask for endpoint maps like { path, id } iterated into registerFunction calls.
iii-event-driven-cqrs
Implements CQRS with event sourcing on the iii engine. Use when building command/query separation, event-sourced systems, or fan-out architectures where commands publish domain events and multiple read model projections subscribe independently.
iii-agentic-backend
Creates and orchestrates multi-agent pipelines on the iii engine. Use when building AI agent collaboration, agent orchestration, research/review/synthesis chains, or any system where specialized agents hand off work through queues and shared state.
iii-engine-config
Configures the iii engine via iii-config.yaml — workers, adapters, queue configs, ports, and environment variables. Use when deploying, tuning, or customizing the engine.
Didn't find tool you were looking for?