(MOT-3962) Hide internal worker plumbing from engine::functions::list - #474
Conversation
engine::functions::list is the candidate universe harness's LLM tool-discovery pulls from. It returned every internal orchestration, config-reload, and write-path function unfiltered — router::chat, session::store::*, provider::*::stream, harness::send/turn/stop, console browser watch handlers, and more — even though most of it is already denied to agents in iii-permissions.yaml. Discovery and authorization were two separate gates; this closes the discovery one too. Tags ~94 non-agent-facing registrations across 10 workers with metadata.internal = true, the field engine::functions::list already checks to hide tagged functions by default. Registrations stay fully callable by id — only discovery is hidden. console gets two extra layers: the browser SDK's client.on() now defaults new registrations to internal, and the WS proxy stamps metadata.internal = true onto any registerfunction frame passing through it, so a stale/cached SPA bundle can't leak a registration.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
skill-check — worker0 verified, 41 skipped (no docs/).
Four for four. Nicely done. |
📝 WalkthroughWalkthroughThe change marks internal control-plane, router, provider, session, and hook registrations with ChangesInternal registration visibility
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Browser
participant IiiClient
participant ConsoleProxy
participant IiiEngine
Browser->>IiiClient: register handler with options
IiiClient->>ConsoleProxy: send registerfunction message
ConsoleProxy->>ConsoleProxy: stamp metadata.internal
ConsoleProxy->>IiiEngine: forward stamped message
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
harness/src/functions/mod.rs (1)
114-142: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsolidate
register_internalintoregisterwith aninternal: boolparameter.
register_internalduplicates the entire body ofregistersolely to append.metadata(...). The context-manager crate in this same PR already solved this by addinginternal: boolto itsregisterhelper and conditionally applying metadata. Adopting the same pattern here eliminates ~15 lines of duplicated code and keeps the two crates consistent.♻️ Proposed refactor: replace `register_internal` with an `internal` flag on `register`
Remove
register_internaland addinternal: boolto the existingregisterfunction (not shown, near line 90):fn register<Req, Resp, F, Fut>( iii: &Arc<IIIClient>, deps: &Arc<Deps>, id: &str, description: &str, + internal: bool, handler: F, ) where Req: DeserializeOwned + JsonSchema + Send + 'static, Resp: Serialize + JsonSchema + Send + 'static, F: Fn(Arc<Deps>, Req) -> Fut + Send + Sync + Clone + 'static, Fut: Future<Output = Result<Resp, HarnessError>> + Send + 'static, { let deps = deps.clone(); - iii.register_function( - id, - RegisterFunction::new_async(move |req: Req| { - let deps = deps.clone(); - let handler = handler.clone(); - async move { handler(deps, req).await.map_err(Error::from) } - }) - .description(description), - ); + let reg = RegisterFunction::new_async(move |req: Req| { + let deps = deps.clone(); + let handler = handler.clone(); + async move { handler(deps, req).await.map_err(Error::from) } + }) + .description(description); + let reg = if internal { + reg.metadata(serde_json::json!({ "internal": true })) + } else { + reg + }; + iii.register_function(id, reg); }Then delete
register_internal(lines 114–141) and update call sites:- register_internal(iii, deps, SEND_ID, SEND_DESC, |d, r| async move { + register(iii, deps, SEND_ID, SEND_DESC, true, |d, r| async move { send::handle(&d, r).await }); - register(iii, deps, SPAWN_ID, SPAWN_DESC, |d, r| async move { + register(iii, deps, SPAWN_ID, SPAWN_DESC, false, |d, r| async move { spawn::handle(&d, r).await });Apply the same
true/falseargument to everyregister_internal→registercall site inregister_all.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@harness/src/functions/mod.rs` around lines 114 - 142, Consolidate the duplicated register_internal helper into register by adding an internal: bool parameter to register and conditionally applying the internal metadata when true. Remove register_internal, then update every call in register_all to use register with true for previously internal registrations and false for normal registrations, preserving existing behavior and descriptions.provider-anthropic/src/register.rs (1)
132-163: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider extracting a local
internal_meta()helper for consistency with llm-router.The inline
json!({ "internal": true })is repeated 3× in this file and identically across all 5 provider crates (15 total occurrences). llm-router already uses aninternal_meta()helper for the same pattern. A local helper in each provider crate would improve consistency and centralize future metadata changes.♻️ Suggested helper extraction
+fn internal_meta() -> serde_json::Value { + json!({ "internal": true }) +} + // ... iii.register_function( surface::STREAM_ID, RegisterFunction::new_async_with_bad_request( make_stream(iii.clone(), http.clone()), invalid_request_from_serde, ) .description(surface::STREAM_DESC) - .metadata(json!({ "internal": true })), + .metadata(internal_meta()), );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@provider-anthropic/src/register.rs` around lines 132 - 163, Extract a local internal_meta() helper in the provider module returning the shared internal metadata object, then replace all three inline json!({ "internal": true }) expressions in the function registrations, including STREAM_ID, REFRESH_MODELS_ID, and ON_ROUTER_READY_ID. Apply the same helper pattern consistently across the other provider crates.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@console/web/src/lib/iii-client.ts`:
- Around line 155-162: Preserve the default internal metadata when callers
provide metadata through options. In the handler registration block using
sdk.registerFunction, merge options.metadata with { internal: true } after
spreading options, ensuring caller metadata cannot overwrite the internal flag
while retaining other metadata fields.
---
Nitpick comments:
In `@harness/src/functions/mod.rs`:
- Around line 114-142: Consolidate the duplicated register_internal helper into
register by adding an internal: bool parameter to register and conditionally
applying the internal metadata when true. Remove register_internal, then update
every call in register_all to use register with true for previously internal
registrations and false for normal registrations, preserving existing behavior
and descriptions.
In `@provider-anthropic/src/register.rs`:
- Around line 132-163: Extract a local internal_meta() helper in the provider
module returning the shared internal metadata object, then replace all three
inline json!({ "internal": true }) expressions in the function registrations,
including STREAM_ID, REFRESH_MODELS_ID, and ON_ROUTER_READY_ID. Apply the same
helper pattern consistently across the other provider crates.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0eec7339-dc51-4311-a7f3-6101ebd5fe19
📒 Files selected for processing (25)
console/src/functions/mod.rsconsole/src/proxy.rsconsole/web/src/lib/iii-client.tscontext-manager/src/configuration.rscontext-manager/src/functions/mod.rsharness/src/configuration.rsharness/src/functions/mod.rsharness/src/subscriptions/notify_agent.rsiii-directory/src/configuration.rsiii-directory/src/main.rsllm-router/src/register.rsprovider-anthropic/src/register.rsprovider-openai-codex/src/register.rsprovider-openai/src/register.rsprovider-xai/src/configuration.rsprovider-xai/src/register.rsprovider-zai/src/register.rsscrapling/src/guidance.pysession-manager/src/configuration.rssession-manager/src/functions/mod.rssession-manager/src/functions/store_protocol.rsshell/src/configuration.rsshell/src/main.rsweb/src/configuration.rsweb/src/functions/mod.rs
| // Every handler registered here is a browser-local console plumbing fn | ||
| // (traces, sessions, worktree events, ...) — none are meant for other | ||
| // workers (e.g. harness) to discover, so default them out of | ||
| // `engine::functions::list`. Callers can still override via `options`. | ||
| const ref = sdk.registerFunction(id, wrapped, { | ||
| metadata: { internal: true }, | ||
| ...options, | ||
| }) |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Shallow spread drops internal: true when caller provides metadata in options.
{ metadata: { internal: true }, ...options } performs a shallow merge. If a caller passes options containing any metadata property, the entire default { internal: true } is replaced — not deep-merged. A caller adding { metadata: { custom: "x" } } would unintentionally lose the internal flag.
The proxy stamping in console/src/proxy.rs provides defense-in-depth, so the practical risk is low. But if you want the SPA default to be robust on its own, consider deep-merging or documenting that callers must include internal: true when passing metadata.
♻️ Optional: deep-merge metadata to preserve the default
const ref = sdk.registerFunction(id, wrapped, {
- metadata: { internal: true },
- ...options,
+ ...options,
+ metadata: { internal: true, ...options?.metadata },
})📝 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.
| // Every handler registered here is a browser-local console plumbing fn | |
| // (traces, sessions, worktree events, ...) — none are meant for other | |
| // workers (e.g. harness) to discover, so default them out of | |
| // `engine::functions::list`. Callers can still override via `options`. | |
| const ref = sdk.registerFunction(id, wrapped, { | |
| metadata: { internal: true }, | |
| ...options, | |
| }) | |
| // Every handler registered here is a browser-local console plumbing fn | |
| // (traces, sessions, worktree events, ...) — none are meant for other | |
| // workers (e.g. harness) to discover, so default them out of | |
| // `engine::functions::list`. Callers can still override via `options`. | |
| const ref = sdk.registerFunction(id, wrapped, { | |
| ...options, | |
| metadata: { internal: true, ...options?.metadata }, | |
| }) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@console/web/src/lib/iii-client.ts` around lines 155 - 162, Preserve the
default internal metadata when callers provide metadata through options. In the
handler registration block using sdk.registerFunction, merge options.metadata
with { internal: true } after spreading options, ensuring caller metadata cannot
overwrite the internal flag while retaining other metadata fields.
Summary
engine::functions::listis the candidate universe harness's LLM tool-discovery pulls from, and it was returning every internal orchestration/config-reload/write-path function unfiltered —router::chat,session::store::*,provider::*::stream,harness::send/turn/stop, console browser watch handlers, etc. — even though most of it is already denied to agents iniii-permissions.yaml. Discovery and authorization were two separate gates; this closes the discovery one too (defense-in-depth).metadata.internal = true, the fieldengine::functions::listalready checks (engine/src/workers/engine_fn/mod.rsin../iii) to hide tagged functions by default. Registrations stay fully callable by id — only discovery is hidden. Full per-worker breakdown in the linked ticket.consolegets two extra layers: the browser SDK'sclient.on()now defaults new registrations to internal (console/web/src/lib/iii-client.ts), and the WS proxy stampsmetadata.internal = trueonto anyregisterfunctionframe passing through it (console/src/proxy.rs) so a stale/cached SPA bundle can't leak a registration.../iii(state::set/update/delete,stream::*,iii::durable::publish,iii::queue::*,configuration::*,worker::*) — same fix, different repo.Test plan
cargo checkon all 12 touched Rust cratescargo fmt --checkon all 12 touched Rust cratespy_compileon scrapling'sguidance.pytsc --noEmiton console/webcargo test --test schemas(4 passed)cargo test --test schemas(4 passed)cargo testsurface/functions subsets (49 passed)cargo test --tests(66 passed)cargo test --lib proxy(8 passed, 3 new)engine::functions::listno longer returns the tagged idsMOT-3962: https://linear.app/motia/issue/MOT-3962/hide-internal-worker-plumbing-from-enginefunctionslist
Summary by CodeRabbit
New Features
Bug Fixes