docs: update API to registerWorker, add Worker primitive, clean up READMEs#1286
docs: update API to registerWorker, add Worker primitive, clean up READMEs#1286
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThis PR updates documentation and website components to introduce "Worker" as a third primitive alongside Function and Trigger, replaces the Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- engine/README.md: two primitives → three primitives, Three Concepts → Three Primitives, Discovery → Worker, init() → registerWorker/register_worker - sdk/README.md: two primitives → three primitives, init() → registerWorker/register_worker in code and API table - sdk/packages/node/iii/README.md: init() → registerWorker() in code, API table, and modules table - sdk/packages/python/iii/README.md: init() → register_worker() in code and API table - sdk/packages/rust/iii/README.md: init() → register_worker() in code, API table, and Streams example
There was a problem hiding this comment.
Actionable comments posted: 11
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
website/components/sections/CodeExamples.tsx (1)
69-91:⚠️ Potential issue | 🟠 MajorThese examples still use function IDs the engine won't parse.
This first snippet still registers
users::createand bindsfunction_id: 'users::create', and the same::convention repeats throughout the rest of the file (jobs::sendWelcomeEmail,events::user::created, etc.).engine/src/services.rsnow splits function IDs on.only, so these examples are still copy-pasting invalid identifiers.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/components/sections/CodeExamples.tsx` around lines 69 - 91, The examples use the old double-colon function IDs (e.g., 'users::create') which the engine now expects with dots; update all occurrences in this file (notably the iii.registerFunction call and the iii.registerTrigger config where function_id is set) to use dot-separated IDs (e.g., 'users.create') and likewise change other examples like 'jobs::sendWelcomeEmail' and 'events::user::created' to 'jobs.sendWelcomeEmail' and 'events.user.created' so they match engine/src/services.rs parsing.website/components/Terminal.tsx (1)
323-346:⚠️ Potential issue | 🟠 MajorFinish the dot-notation migration in the terminal help.
These changed snippets now use dot-delimited IDs, but the same terminal output still teaches
service::functionon Lines 331-334, keepsfunction_id: "myService::greet"on Line 588, and still showsuserService::getProfile/emailService::sendWelcomeon Lines 603 and 609. Users will get contradictory guidance, and the::examples are rejected by the current parser.Also applies to: 576-581
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/components/Terminal.tsx` around lines 323 - 346, The terminal help still shows legacy double-colon IDs (e.g., "service::function", "myapp::users::create", "data::transform::json", and examples like function_id: "myService::greet" and userService::getProfile/emailService::sendWelcome) while other snippets were migrated to dot notation; update all addLog strings inside the Terminal.tsx help cases (look for occurrences in the addLog calls under the generic help block and the case "triggers" / iii.registerTrigger examples) to use dot-delimited IDs (e.g., service.function, myapp.users.create, data.transform.json, function_id: "myService.greet", userService.getProfile, emailService.sendWelcome) so all examples are consistent with the current parser.website/components/MachineView.tsx (1)
145-146:⚠️ Potential issue | 🟡 MinorBuilt-in system function names use
::instead of.separator.The PR objective is to replace
::with.separators. These built-in function references should be updated for consistency:## Built-in System Functions -- state::get / state::set — { scope, key, value } -- stream::set / stream::list — { stream_name, group_id, item_id, data } +- state.get / state.set — { scope, key, value } +- stream.set / stream.list — { stream_name, group_id, item_id, data }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/components/MachineView.tsx` around lines 145 - 146, Update the built-in system function references that currently use the `::` separator to use `.` instead: replace `state::get` and `state::set` with `state.get` and `state.set`, and replace `stream::set` and `stream::list` with `stream.set` and `stream.list` in the MachineView.tsx component (look for the lines containing those exact symbols to update the displayed references and any related text).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@website/components/MachineView.tsx`:
- Around line 75-76: The file imports getContext from "iii-sdk" which isn't
exported; remove getContext from the top-level import and instead access the
context via the worker instance returned by registerWorker (use
iii.getContext(...) or the equivalent method on the iii object) or, if the SDK
exposes a different named export, replace getContext with that exact exported
name; update all usages in MachineView.tsx that reference getContext to call the
method off the iii instance (or the correct exported symbol) so imports align
with the SDK public API.
- Around line 230-231: The call to iii.trigger uses inconsistent separators:
replace the namespaced string "tools::webSearch" with dot notation to match
"agents.analyzer" so both use the same format; update the invocation of
iii.trigger that currently passes "tools::webSearch" (in the line assigning
sources) to use "tools.webSearch" instead so both triggers use the dot-separated
namespace.
- Line 363: The event key passed to iii.trigger uses an inconsistent '::'
separator; update the call in MachineView.tsx where
iii.trigger("metrics::getLast24h", {}) is used to the project-standard separator
(e.g., iii.trigger("metrics.getLast24h", {})) so the event name matches other
Scheduled Intelligence keys and keeps iii.trigger usage and the metrics variable
consistent.
- Around line 52-59: Update the copy in the MachineView component so it doesn't
call "Worker" a primitive: change the header/table wording to reflect that
Function and Trigger are the two core primitives and Worker (Discovery) is a
concept — e.g., replace "One Engine. Three primitives" with "One Engine. Two
primitives, one concept" or "Three concepts: Function, Trigger, Worker", and
adjust the table caption/notes accordingly (refer to the strings mentioning
"Primitive" and the table rows for Function, Trigger, Worker/Discovery in
MachineView.tsx).
- Around line 341-344: The three iii.trigger calls in MachineView.tsx use
inconsistent event separators; make them consistent by changing the dotted event
names to use the double-colon form used elsewhere: update the ii i.trigger
invocations (the strings passed to iii.trigger for "analytics.track" and
"ml.computeSegment") to "analytics::track" and "ml::computeSegment" so all
triggers use the same "::" separator.
In `@website/components/sections/AgentReadySection.tsx`:
- Around line 116-117: Replace all function ID separators using "::" with "." in
the AgentReadySection file so the trigger calls are consistent; specifically
update iii.trigger invocations such as "tools::webSearch" to "tools.webSearch"
and other IDs like "crm::syncContact" -> "crm.syncContact" and
"ml::computeSegment" -> "ml.computeSegment" (these appear in the same file in
multiple iii.trigger calls). Search for any occurrences of "::" in this file and
perform the string replacements so all iii.trigger calls use dot separators,
keeping the rest of the call signatures (e.g., iii.trigger("tools.webSearch", {
query: topic })) unchanged.
- Around line 74-79: The Python example in AgentReadySection.tsx incorrectly
calls a non-existent get_context() function; update the snippet to import Logger
from iii and instantiate it directly inside research_handler (replace
get_context().logger with Logger(function_name="agent.research")), keeping the
existing register_worker usage and function name research_handler so readers can
locate the change.
In `@website/components/sections/CodeExamples.tsx`:
- Around line 64-72: The examples import getContext from "iii-sdk" but the Node
SDK public entry (index.ts) does not export getContext, causing import errors;
fix this by adding getContext to the public exports of the iii package (export {
getContext } from its internal context module) so that getContext is available
when importing from "iii-sdk", and ensure the existing getContext implementation
and its TypeScript types are re-exported alongside
registerWorker/registerFunction so the example code using getContext (and
functions like registerWorker and iii.registerFunction) compiles and runs.
In `@website/components/sections/EngineSection.tsx`:
- Around line 157-167: The change alters the conceptual model by
renaming/redefining the third item to "Worker" in the EngineSection component
(see the object with id: "worker", name: "Worker", description and highlights),
but the project docs treat "Discovery" as the third concept (Functions, Triggers
are primitives; Discovery is a concept). Reconcile this by either restoring the
original concept label/description to "Discovery" (reverting the
description/highlights to describe automatic
registration/deregistration/discovery) or, if the architecture truly changed,
update the canonical docs and README to reflect the new model and keep the
website text in sync; ensure the object with id "worker" is renamed to match the
chosen model (e.g., id/name "discovery") and adjust description/highlights
accordingly so website wording matches the rest of the project.
In `@website/components/sections/HelloWorldSection.tsx`:
- Around line 29-31: The example calls register_worker("ws://localhost:49134")
at import time but register_worker requires an active asyncio loop; change the
snippet to run inside an async context (e.g., define async def main(): client =
await register_worker(...); await client.connect() and run it with
asyncio.run(main())) or alternatively instantiate the III client explicitly
(III(...)) and call await client.connect() inside an async function so
register_worker/III and client.connect() are executed while an event loop is
running.
In `@website/components/Terminal.tsx`:
- Around line 308-309: The snippet shows register_worker() used as a synchronous
top-level Python call (addLog lines with "from iii import register_worker" and
'iii = register_worker("ws://127.0.0.1:49134")'), which will raise RuntimeError
because register_worker requires an active asyncio event loop; update the
example to call register_worker from within async code (or show the alternative
pattern using III(...) plus await client.connect()) and adjust the displayed
lines so the terminal output demonstrates using an async function or awaiting
connection rather than invoking register_worker at module top level.
---
Outside diff comments:
In `@website/components/MachineView.tsx`:
- Around line 145-146: Update the built-in system function references that
currently use the `::` separator to use `.` instead: replace `state::get` and
`state::set` with `state.get` and `state.set`, and replace `stream::set` and
`stream::list` with `stream.set` and `stream.list` in the MachineView.tsx
component (look for the lines containing those exact symbols to update the
displayed references and any related text).
In `@website/components/sections/CodeExamples.tsx`:
- Around line 69-91: The examples use the old double-colon function IDs (e.g.,
'users::create') which the engine now expects with dots; update all occurrences
in this file (notably the iii.registerFunction call and the iii.registerTrigger
config where function_id is set) to use dot-separated IDs (e.g., 'users.create')
and likewise change other examples like 'jobs::sendWelcomeEmail' and
'events::user::created' to 'jobs.sendWelcomeEmail' and 'events.user.created' so
they match engine/src/services.rs parsing.
In `@website/components/Terminal.tsx`:
- Around line 323-346: The terminal help still shows legacy double-colon IDs
(e.g., "service::function", "myapp::users::create", "data::transform::json", and
examples like function_id: "myService::greet" and
userService::getProfile/emailService::sendWelcome) while other snippets were
migrated to dot notation; update all addLog strings inside the Terminal.tsx help
cases (look for occurrences in the addLog calls under the generic help block and
the case "triggers" / iii.registerTrigger examples) to use dot-delimited IDs
(e.g., service.function, myapp.users.create, data.transform.json, function_id:
"myService.greet", userService.getProfile, emailService.sendWelcome) so all
examples are consistent with the current parser.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 374d9e34-3191-472f-8782-137ef6bed331
📒 Files selected for processing (9)
website/README.mdwebsite/components/MachineView.tsxwebsite/components/Terminal.tsxwebsite/components/sections/AgentReadySection.tsxwebsite/components/sections/CodeExamples.tsxwebsite/components/sections/EngineSection.tsxwebsite/components/sections/HelloWorldSection.tsxwebsite/components/sections/HeroSection.tsxwebsite/pages/ManifestoPage.tsx
| One Engine. Three primitives: Function, Trigger, Worker. | ||
| React simplified frontend with Component and Context. iii does the same for backend. | ||
|
|
||
| | Primitive | Role | | ||
| |------------|-------------------------------------------------------------| | ||
| | Function | Anything that does work — receives input, returns output | | ||
| | Trigger | What makes a Function run — HTTP, cron, queue, state, stream| | ||
| | Discovery | The system knows itself — live registry, no config files | | ||
| | Worker | Any process that registers functions and triggers | |
There was a problem hiding this comment.
Terminology: "Worker" may not be a primitive.
Per project documentation, Function and Trigger are the two core primitives, while Discovery (now Worker) is a concept — a system capability for automatic registration/deregistration, not a primitive itself.
Consider revising to:
- "Two primitives (Function, Trigger) and one concept (Worker)", or
- "Three concepts: Function, Trigger, Worker"
Based on learnings: "primitives" and "concepts" are intentionally different terms. Function and Trigger are the two core primitives, while Function, Trigger, and Discovery are the three concepts.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@website/components/MachineView.tsx` around lines 52 - 59, Update the copy in
the MachineView component so it doesn't call "Worker" a primitive: change the
header/table wording to reflect that Function and Trigger are the two core
primitives and Worker (Discovery) is a concept — e.g., replace "One Engine.
Three primitives" with "One Engine. Two primitives, one concept" or "Three
concepts: Function, Trigger, Worker", and adjust the table caption/notes
accordingly (refer to the strings mentioning "Primitive" and the table rows for
Function, Trigger, Worker/Discovery in MachineView.tsx).
| import { registerWorker, getContext } from "iii-sdk" | ||
| const iii = registerWorker(process.env.III_BRIDGE_URL ?? "ws://localhost:49134") |
There was a problem hiding this comment.
Same getContext export issue as AgentReadySection.tsx.
The TypeScript examples import getContext from "iii-sdk", but this function is not exported from the SDK's public API. This needs to be consistent with the actual SDK exports.
Also applies to: 81-81
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@website/components/MachineView.tsx` around lines 75 - 76, The file imports
getContext from "iii-sdk" which isn't exported; remove getContext from the
top-level import and instead access the context via the worker instance returned
by registerWorker (use iii.getContext(...) or the equivalent method on the iii
object) or, if the SDK exposes a different named export, replace getContext with
that exact exported name; update all usages in MachineView.tsx that reference
getContext to call the method off the iii instance (or the correct exported
symbol) so imports align with the SDK public API.
| const sources = await iii.trigger("tools::webSearch", { query: topic }) | ||
| return iii.trigger("agents::analyzer", { sources, topic }) | ||
| return iii.trigger("agents.analyzer", { sources, topic }) |
There was a problem hiding this comment.
Inconsistent :: separator in code example.
Line 230 uses tools::webSearch while Line 231 uses agents.analyzer. Apply the same . notation throughout.
🔧 Proposed fix
- const sources = await iii.trigger("tools::webSearch", { query: topic })
+ const sources = await iii.trigger("tools.webSearch", { query: topic })📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const sources = await iii.trigger("tools::webSearch", { query: topic }) | |
| return iii.trigger("agents::analyzer", { sources, topic }) | |
| return iii.trigger("agents.analyzer", { sources, topic }) | |
| const sources = await iii.trigger("tools.webSearch", { query: topic }) | |
| return iii.trigger("agents.analyzer", { sources, topic }) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@website/components/MachineView.tsx` around lines 230 - 231, The call to
iii.trigger uses inconsistent separators: replace the namespaced string
"tools::webSearch" with dot notation to match "agents.analyzer" so both use the
same format; update the invocation of iii.trigger that currently passes
"tools::webSearch" (in the line assigning sources) to use "tools.webSearch"
instead so both triggers use the dot-separated namespace.
| iii.trigger("crm::syncContact", { user }), | ||
| iii.trigger("analytics::track", { event: "signup", user }), | ||
| iii.trigger("ml::computeSegment", { user }), | ||
| iii.trigger("analytics.track", { event: "signup", user }), | ||
| iii.trigger("ml.computeSegment", { user }), | ||
| ]) |
There was a problem hiding this comment.
More inconsistent :: separators in Event-Driven Pipelines example.
Lines 341 and 343 use :: while Line 342 uses .:
🔧 Proposed fix
await Promise.all([
- iii.trigger("crm::syncContact", { user }),
+ iii.trigger("crm.syncContact", { user }),
iii.trigger("analytics.track", { event: "signup", user }),
- iii.trigger("ml.computeSegment", { user }),
+ iii.trigger("ml.computeSegment", { user }),
])📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| iii.trigger("crm::syncContact", { user }), | |
| iii.trigger("analytics::track", { event: "signup", user }), | |
| iii.trigger("ml::computeSegment", { user }), | |
| iii.trigger("analytics.track", { event: "signup", user }), | |
| iii.trigger("ml.computeSegment", { user }), | |
| ]) | |
| iii.trigger("crm.syncContact", { user }), | |
| iii.trigger("analytics.track", { event: "signup", user }), | |
| iii.trigger("ml.computeSegment", { user }), | |
| ]) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@website/components/MachineView.tsx` around lines 341 - 344, The three
iii.trigger calls in MachineView.tsx use inconsistent event separators; make
them consistent by changing the dotted event names to use the double-colon form
used elsewhere: update the ii i.trigger invocations (the strings passed to
iii.trigger for "analytics.track" and "ml.computeSegment") to "analytics::track"
and "ml::computeSegment" so all triggers use the same "::" separator.
| const logger = new Logger() | ||
| iii.registerFunction({ id: "monitor.anomalies" }, async () => { | ||
| const { logger } = getContext() | ||
| const metrics = await iii.trigger("metrics::getLast24h", {}) |
There was a problem hiding this comment.
Inconsistent :: separator in Scheduled Intelligence example.
- const metrics = await iii.trigger("metrics::getLast24h", {})
+ const metrics = await iii.trigger("metrics.getLast24h", {})📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const metrics = await iii.trigger("metrics::getLast24h", {}) | |
| const metrics = await iii.trigger("metrics.getLast24h", {}) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@website/components/MachineView.tsx` at line 363, The event key passed to
iii.trigger uses an inconsistent '::' separator; update the call in
MachineView.tsx where iii.trigger("metrics::getLast24h", {}) is used to the
project-standard separator (e.g., iii.trigger("metrics.getLast24h", {})) so the
event name matches other Scheduled Intelligence keys and keeps iii.trigger usage
and the metrics variable consistent.
| const sources = await iii.trigger("tools::webSearch", { query: topic }) | ||
| return iii.trigger("agents::analyzer", { sources, topic }) | ||
| return iii.trigger("agents.analyzer", { sources, topic }) |
There was a problem hiding this comment.
Inconsistent function ID separators — :: vs . notation.
The PR objective states all :: separators should be replaced with . dot separators. Line 116 uses tools::webSearch while Line 117 uses agents.analyzer. This inconsistency appears throughout the file.
Other occurrences using :: that should be updated to .:
- Line 134:
tools::webSearch - Line 154:
tools::webSearch - Lines 409, 431, 462:
tools::webSearch - Lines 491, 493, 517, 518, 543, 545:
crm::syncContact,ml::computeSegment
🔧 Proposed fix for this occurrence
- const sources = await iii.trigger("tools::webSearch", { query: topic })
+ const sources = await iii.trigger("tools.webSearch", { query: topic })📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const sources = await iii.trigger("tools::webSearch", { query: topic }) | |
| return iii.trigger("agents::analyzer", { sources, topic }) | |
| return iii.trigger("agents.analyzer", { sources, topic }) | |
| const sources = await iii.trigger("tools.webSearch", { query: topic }) | |
| return iii.trigger("agents.analyzer", { sources, topic }) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@website/components/sections/AgentReadySection.tsx` around lines 116 - 117,
Replace all function ID separators using "::" with "." in the AgentReadySection
file so the trigger calls are consistent; specifically update iii.trigger
invocations such as "tools::webSearch" to "tools.webSearch" and other IDs like
"crm::syncContact" -> "crm.syncContact" and "ml::computeSegment" ->
"ml.computeSegment" (these appear in the same file in multiple iii.trigger
calls). Search for any occurrences of "::" in this file and perform the string
replacements so all iii.trigger calls use dot separators, keeping the rest of
the call signatures (e.g., iii.trigger("tools.webSearch", { query: topic }))
unchanged.
| import { registerWorker, getContext } from "iii-sdk" | ||
|
|
||
| const iii = init(process.env.III_BRIDGE_URL ?? 'ws://localhost:49134') | ||
| const iii = registerWorker(process.env.III_BRIDGE_URL ?? 'ws://localhost:49134') | ||
|
|
||
| // Register handler - works from any language | ||
| iii.registerFunction( | ||
| { id: 'users::create' }, | ||
| async (req) => { | ||
| const logger = new Logger() | ||
| const { logger } = getContext() |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "-- Node SDK public exports --"
sed -n '1,20p' sdk/packages/node/iii/src/index.ts
echo
echo "-- Website snippets using getContext --"
rg -n 'getContext|Logger' website/components/sections/CodeExamples.tsx website/components/sections/EngineSection.tsxRepository: iii-hq/iii
Length of output: 3689
getContext() is not exported from the Node SDK.
The public sdk/packages/node/iii/src/index.ts does not export getContext, but it is imported in 10+ code examples throughout website/components/sections/CodeExamples.tsx and EngineSection.tsx (lines 64, 155, 259, 368, 500, 600, 718, 829, 969, 1104, 1374, 1496, 1647). All examples will fail with an import error until getContext is added to the SDK's public exports.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@website/components/sections/CodeExamples.tsx` around lines 64 - 72, The
examples import getContext from "iii-sdk" but the Node SDK public entry
(index.ts) does not export getContext, causing import errors; fix this by adding
getContext to the public exports of the iii package (export { getContext } from
its internal context module) so that getContext is available when importing from
"iii-sdk", and ensure the existing getContext implementation and its TypeScript
types are re-exported alongside registerWorker/registerFunction so the example
code using getContext (and functions like registerWorker and
iii.registerFunction) compiles and runs.
| id: "worker", | ||
| icon: Share2, | ||
| name: "Discovery", | ||
| tagline: "The system knows itself.", | ||
| name: "Worker", | ||
| tagline: "Any process that registers functions.", | ||
| description: | ||
| "When a worker connects, every other worker learns what it can do. When it disconnects, its functions vanish. No config files. No service registries. No hardcoded URLs. The engine maintains a live registry.", | ||
| "A Worker is any process that registers Functions and Triggers. Long-running services, ephemeral scripts, agentic workers, or legacy systems via middleware — all connect, register, and participate as first-class members of the mesh.", | ||
| highlights: [ | ||
| "Workers register → everyone is notified instantly", | ||
| "Workers register functions → immediately available to all", | ||
| "Workers disconnect → functions removed, no stale refs", | ||
| "trigger() by name — engine routes to the right worker", | ||
| "Long-running, ephemeral, or agentic — all first-class", | ||
| "Scale up, scale down — topology adapts in real time", |
There was a problem hiding this comment.
Verify that this is a model change, not just a rename.
This update does more than relabel the third tab: the page now teaches Function/Trigger/Worker as the "three primitives" and describes the third item as the worker process itself rather than the discovery capability. If the underlying architecture docs have not changed in lockstep, the website will now present a different mental model than the rest of the project.
Based on learnings: In the iii project README.md: "primitives" and "concepts" are intentionally different terms. Function and Trigger are the two core primitives, while Function, Trigger, and Discovery are the three concepts. Discovery is a concept but not a primitive—it's a system capability for automatic registration/deregistration.
Also applies to: 841-850
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@website/components/sections/EngineSection.tsx` around lines 157 - 167, The
change alters the conceptual model by renaming/redefining the third item to
"Worker" in the EngineSection component (see the object with id: "worker", name:
"Worker", description and highlights), but the project docs treat "Discovery" as
the third concept (Functions, Triggers are primitives; Discovery is a concept).
Reconcile this by either restoring the original concept label/description to
"Discovery" (reverting the description/highlights to describe automatic
registration/deregistration/discovery) or, if the architecture truly changed,
update the canonical docs and README to reflect the new model and keep the
website text in sync; ensure the object with id "worker" is renamed to match the
chosen model (e.g., id/name "discovery") and adjust description/highlights
accordingly so website wording matches the rest of the project.
| from iii import register_worker | ||
|
|
||
| iii = init("ws://localhost:49134") | ||
| iii = register_worker("ws://localhost:49134") |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "-- Python SDK register_worker contract --"
sed -n '52,75p' sdk/packages/python/iii/src/iii/__init__.py
echo
echo "-- Website snippets using register_worker --"
rg -n 'register_worker' website/components/sections/HelloWorldSection.tsx website/components/Terminal.tsxRepository: iii-hq/iii
Length of output: 1779
Wrap the Python example in an async context to satisfy register_worker() runtime requirement.
The register_worker() function requires an active asyncio event loop, but the current example calls it at module import time where no loop exists. This will raise a RuntimeError at runtime. Either wrap the code in an async function, or use the explicit III(...); await client.connect() flow instead.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@website/components/sections/HelloWorldSection.tsx` around lines 29 - 31, The
example calls register_worker("ws://localhost:49134") at import time but
register_worker requires an active asyncio loop; change the snippet to run
inside an async context (e.g., define async def main(): client = await
register_worker(...); await client.connect() and run it with
asyncio.run(main())) or alternatively instantiate the III client explicitly
(III(...)) and call await client.connect() inside an async function so
register_worker/III and client.connect() are executed while an event loop is
running.
| addLog("from iii import register_worker", "success"); | ||
| addLog('iii = register_worker("ws://127.0.0.1:49134")', "success"); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n sdk/packages/python/iii/src/iii/__init__.py | head -80Repository: iii-hq/iii
Length of output: 2804
🏁 Script executed:
wc -l website/components/Terminal.tsxRepository: iii-hq/iii
Length of output: 90
🏁 Script executed:
sed -n '295,340p' website/components/Terminal.tsxRepository: iii-hq/iii
Length of output: 2111
🏁 Script executed:
sed -n '570,615p' website/components/Terminal.tsxRepository: iii-hq/iii
Length of output: 1961
Don't show register_worker() as a synchronous top-level Python call.
register_worker() requires an active asyncio event loop (it calls asyncio.get_running_loop() and raises RuntimeError if no loop is running). The snippet at lines 308-309 shows it as a top-level call, which will fail immediately with: "iii.register_worker() requires an active asyncio event loop. Call it inside async code or use 'client = III(...); await client.connect()'".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@website/components/Terminal.tsx` around lines 308 - 309, The snippet shows
register_worker() used as a synchronous top-level Python call (addLog lines with
"from iii import register_worker" and 'iii =
register_worker("ws://127.0.0.1:49134")'), which will raise RuntimeError because
register_worker requires an active asyncio event loop; update the example to
call register_worker from within async code (or show the alternative pattern
using III(...) plus await client.connect()) and adjust the displayed lines so
the terminal output demonstrates using an async function or awaiting connection
rather than invoking register_worker at module top level.
Only the manifesto "Not another protocol" → "Not another service" was intended. All other protocol references restored.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
website/components/sections/CodeExamples.tsx (1)
69-91:⚠️ Potential issue | 🟠 MajorUpdate the examples to dot-delimited function IDs.
Line 70 and Line 90 still use the legacy
users::createidentifier, and the same::separator is repeated throughout this file (jobs::sendWelcomeEmail,events::user::created,chat::sendMessage, etc.). Since this PR is migrating the docs to dot notation, these snippets are still stale and will conflict with the rest of the updated documentation.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/components/sections/CodeExamples.tsx` around lines 69 - 91, Update the legacy double-colon identifiers to dot-delimited IDs throughout the examples: change occurrences like 'users::create' (used in iii.registerFunction and the iii.registerTrigger config.function_id) to 'users.create' and similarly convert 'jobs::sendWelcomeEmail' -> 'jobs.sendWelcomeEmail', 'events::user::created' -> 'events.user.created', 'chat::sendMessage' -> 'chat.sendMessage' so all examples (e.g., calls to iii.registerFunction, iii.registerTrigger, and iii.triggerVoid) use the new dot notation consistently.website/components/MachineView.tsx (2)
323-323:⚠️ Potential issue | 🟡 MinorInconsistent
::separator in Deep Research example.This line uses
tools::webSearchwhich should betools.webSearchper the PR's objective to replace all::separators with.notation.🔧 Proposed fix
- subQueries.map((q: string) => iii.trigger("tools::webSearch", { query: q })) + subQueries.map((q: string) => iii.trigger("tools.webSearch", { query: q }))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/components/MachineView.tsx` at line 323, The Deep Research trigger call uses the old separator string "tools::webSearch"; update the trigger payload to use the dot notation "tools.webSearch" so the call in the map (iii.trigger("tools::webSearch", { query: q })) becomes iii.trigger("tools.webSearch", { query: q }) to match the project's `tools.webSearch` convention.
145-148:⚠️ Potential issue | 🟡 MinorDocumentation uses
::but code examples use.for system functions.The "Built-in System Functions" section documents
state::get,state::set,stream::set,stream::list, but the code examples throughout the file invoke these asstate.set,state.get,stream.set,stream.list(e.g., lines 241, 253, 266, 298, 302, etc.).Consider aligning the documentation with the code examples for consistency.
🔧 Proposed fix
## Built-in System Functions -- state::get / state::set — { scope, key, value } -- stream::set / stream::list — { stream_name, group_id, item_id, data } +- state.get / state.set — { scope, key, value } +- stream.set / stream.list — { stream_name, group_id, item_id, data } - publish — { topic, data } - enqueue — { topic, data }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/components/MachineView.tsx` around lines 145 - 148, The documentation currently lists built-in system functions using the `::` form (e.g., `state::get`, `stream::set`) while the component's code examples and usages call them with dot notation (`state.get`, `stream.set`); update the "Built-in System Functions" text in MachineView (the JSX/strings that show `state::get / state::set — { scope, key, value }`, `stream::set / stream::list — { stream_name, group_id, item_id, data }`, etc.) to use the dot notation to match the examples and actual calls (state.get, state.set, stream.set, stream.list, publish, enqueue), ensuring all occurrences in that component are replaced for consistency.
♻️ Duplicate comments (1)
website/components/sections/CodeExamples.tsx (1)
64-64:⚠️ Potential issue | 🟠 MajorDon't document
getContext()as a publiciii-sdkimport.These snippets now import
getContextfrom"iii-sdk", but the Node SDK public entrypoint still doesn't export it. That makes the updated examples copy/paste broken until the SDK re-exportsgetContextor the docs switch back to a supported API.#!/bin/bash set -euo pipefail echo "-- Node SDK public exports --" sed -n '1,20p' sdk/packages/node/iii/src/index.ts echo echo "-- getContext imports in CodeExamples --" rg -n 'import \{ registerWorker, getContext \} from "iii-sdk"' website/components/sections/CodeExamples.tsx echo echo "-- getContext usages in CodeExamples --" rg -n '\bgetContext\(' website/components/sections/CodeExamples.tsxAlso applies to: 155-155, 259-259, 368-368, 500-500, 600-600, 718-718, 829-829, 969-969, 1104-1104, 1374-1374, 1496-1496, 1647-1647
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/components/sections/CodeExamples.tsx` at line 64, The examples import getContext from "iii-sdk" which is not a public export; remove getContext from the import (keep only registerWorker) and update every usage of getContext(...) in CodeExamples.tsx to use the context passed into your worker handler (the ctx/workerContext parameter provided by registerWorker) or otherwise use a supported public API; update all occurrences (previously importing getContext and calls to getContext) to reference the handler parameter or a documented API instead so the examples remain copy/pasteable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@sdk/packages/rust/iii/README.md`:
- Line 59: The README sentence for register_worker() incorrectly implies
OpenTelemetry is always enabled; update the wording around the register_worker()
description to state that it spawns a background task for WebSocket
communication and automatic reconnection, and that OpenTelemetry instrumentation
is included only when the crate is compiled with the otel feature (i.e.,
feature-gate the otel instrumentation wording), referencing the
register_worker() function and the otel feature flag.
---
Outside diff comments:
In `@website/components/MachineView.tsx`:
- Line 323: The Deep Research trigger call uses the old separator string
"tools::webSearch"; update the trigger payload to use the dot notation
"tools.webSearch" so the call in the map (iii.trigger("tools::webSearch", {
query: q })) becomes iii.trigger("tools.webSearch", { query: q }) to match the
project's `tools.webSearch` convention.
- Around line 145-148: The documentation currently lists built-in system
functions using the `::` form (e.g., `state::get`, `stream::set`) while the
component's code examples and usages call them with dot notation (`state.get`,
`stream.set`); update the "Built-in System Functions" text in MachineView (the
JSX/strings that show `state::get / state::set — { scope, key, value }`,
`stream::set / stream::list — { stream_name, group_id, item_id, data }`, etc.)
to use the dot notation to match the examples and actual calls (state.get,
state.set, stream.set, stream.list, publish, enqueue), ensuring all occurrences
in that component are replaced for consistency.
In `@website/components/sections/CodeExamples.tsx`:
- Around line 69-91: Update the legacy double-colon identifiers to dot-delimited
IDs throughout the examples: change occurrences like 'users::create' (used in
iii.registerFunction and the iii.registerTrigger config.function_id) to
'users.create' and similarly convert 'jobs::sendWelcomeEmail' ->
'jobs.sendWelcomeEmail', 'events::user::created' -> 'events.user.created',
'chat::sendMessage' -> 'chat.sendMessage' so all examples (e.g., calls to
iii.registerFunction, iii.registerTrigger, and iii.triggerVoid) use the new dot
notation consistently.
---
Duplicate comments:
In `@website/components/sections/CodeExamples.tsx`:
- Line 64: The examples import getContext from "iii-sdk" which is not a public
export; remove getContext from the import (keep only registerWorker) and update
every usage of getContext(...) in CodeExamples.tsx to use the context passed
into your worker handler (the ctx/workerContext parameter provided by
registerWorker) or otherwise use a supported public API; update all occurrences
(previously importing getContext and calls to getContext) to reference the
handler parameter or a documented API instead so the examples remain
copy/pasteable.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3ba74e1d-e829-41a1-a28a-a89067e36c24
📒 Files selected for processing (8)
sdk/README.mdsdk/packages/node/iii/README.mdsdk/packages/python/iii/README.mdsdk/packages/rust/iii/README.mdwebsite/components/MachineView.tsxwebsite/components/sections/CodeExamples.tsxwebsite/components/sections/HelloWorldSection.tsxwebsite/pages/ManifestoPage.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- website/pages/ManifestoPage.tsx
- sdk/packages/node/iii/README.md
| | Invoke (fire-and-forget) | `iii.trigger_void(id, data)?` | Invoke a function without waiting (fire-and-forget) | | ||
|
|
||
| `init()` spawns a background task that handles WebSocket communication, automatic reconnection, and OpenTelemetry instrumentation. | ||
| `register_worker()` spawns a background task that handles WebSocket communication, automatic reconnection, and OpenTelemetry instrumentation. |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, check if the file exists and read around line 59
ls -la sdk/packages/rust/iii/README.md 2>/dev/null && echo "=== README.md context ===" && sed -n '50,70p' sdk/packages/rust/iii/README.mdRepository: iii-hq/iii
Length of output: 1505
🏁 Script executed:
# Check the implementation in src/lib.rs
cat -n sdk/packages/rust/iii/src/lib.rs | sed -n '40,55p'Repository: iii-hq/iii
Length of output: 589
🏁 Script executed:
# Look for the otel feature gate in the file
grep -n "otel" sdk/packages/rust/iii/src/lib.rs | head -20Repository: iii-hq/iii
Length of output: 564
🏁 Script executed:
# Check Cargo.toml for the otel feature definition
cat sdk/packages/rust/iii/Cargo.toml | grep -A 10 "\[features\]"Repository: iii-hq/iii
Length of output: 230
Feature-gate the OpenTelemetry wording.
register_worker() always starts the socket/reconnect task, but OpenTelemetry instrumentation is only compiled in when the otel feature is enabled (not in default features). As written, Line 59 makes the default build sound instrumented when it is not.
✏️ Suggested wording
-`register_worker()` spawns a background task that handles WebSocket communication, automatic reconnection, and OpenTelemetry instrumentation.
+`register_worker()` spawns a background task that handles WebSocket communication and automatic reconnection. OpenTelemetry instrumentation is available when the `otel` feature is enabled.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| `register_worker()` spawns a background task that handles WebSocket communication, automatic reconnection, and OpenTelemetry instrumentation. | |
| `register_worker()` spawns a background task that handles WebSocket communication and automatic reconnection. OpenTelemetry instrumentation is available when the `otel` feature is enabled. |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@sdk/packages/rust/iii/README.md` at line 59, The README sentence for
register_worker() incorrectly implies OpenTelemetry is always enabled; update
the wording around the register_worker() description to state that it spawns a
background task for WebSocket communication and automatic reconnection, and that
OpenTelemetry instrumentation is included only when the crate is compiled with
the otel feature (i.e., feature-gate the otel instrumentation wording),
referencing the register_worker() function and the otel feature flag.
Summary
init()toregisterWorker()/register_worker()per PR Rename init function #1266::function path separators with.(e.g.,users::create→users.create)call()/callVoid()/call_void()notes from all SDK READMEsFiles changed
Website:
website/components/sections/HelloWorldSection.tsxwebsite/components/sections/EngineSection.tsxwebsite/components/sections/CodeExamples.tsxwebsite/components/sections/AgentReadySection.tsxwebsite/components/sections/HeroSection.tsxwebsite/components/MachineView.tsxwebsite/components/Terminal.tsxwebsite/pages/ManifestoPage.tsxwebsite/README.mdREADMEs:
README.md(root)engine/README.mdsdk/README.mdsdk/packages/node/iii/README.mdsdk/packages/python/iii/README.mdsdk/packages/rust/iii/README.mdTest plan
Summary by CodeRabbit
New Features
getContext()/get_context()API.Updates
init()→registerWorker()(Node.js/TypeScript),register_worker()(Python/Rust).users::create) to dot-separated notation (e.g.,users.create).