Skip to content

feat(engine): expose generated HTTP functions as worker groups#1635

Closed
rohitg00 wants to merge 14 commits into
mainfrom
artifact-http-invocation-workers
Closed

feat(engine): expose generated HTTP functions as worker groups#1635
rohitg00 wants to merge 14 commits into
mainfrom
artifact-http-invocation-workers

Conversation

@rohitg00

@rohitg00 rohitg00 commented May 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • track generated worker groups for externally registered functions without starting generated worker processes
  • expose converted OpenAPI/MCP sources as normal engine-runtime worker groups in engine::workers::list
  • keep generated functions directly triggerable through normal iii function ids
  • consume and strip the private metadata.iii.generatedWorker hint before public function metadata is stored
  • accept the older private metadata.iii.virtualWorker key as a compatibility alias
  • trust local generated-function bridges only when both the registering worker session and invocation URL are loopback
  • enable iii-http-functions by default so converted OpenAPI/MCP calls can register without extra config
  • cover the generated HTTP worker-group path from the Node, Python, and Rust SDK test suites

Validation

  • cargo fmt --all -- --check
  • cargo test -p iii --test generated_worker_bridge_e2e
  • cargo test -p iii generated_worker --lib
  • cargo test -p iii test_list_worker_infos_includes_generated_group_without_private_public_shape --lib
  • cargo test -p iii http_functions --lib
  • cargo check -p iii --tests
  • cargo test -p iii --test http_e2e_security
  • cargo test -p iii --test http_e2e_error_handling
  • cargo fmt -p iii-sdk -- --check
  • pnpm install --filter iii-sdk --frozen-lockfile
  • pnpm --filter iii-sdk exec tsc --noEmit
  • python3 -m compileall -q sdk/packages/python/iii/src sdk/packages/python/iii/tests/test_http_external_functions_integration.py
  • cargo test -p iii-sdk --test http_external_functions exposes_generated_http_functions --no-run
  • spec-to-worker repo: cargo fmt, cargo test, cargo clippy --all-targets --all-features -- -D warnings

Spec-to-Worker E2E Contract

The paired worker PR is iii-experimental/spec-to-worker#13. It now uses generic fixtures and docs instead of Context7-specific examples. The expected contract is:

  • OpenAPI conversion registers normal iii functions for each operation
  • MCP HTTP conversion registers normal iii functions for each discovered tool
  • MCP stdio conversion registers normal iii functions for each discovered tool
  • engine::workers::list shows the generated source as a normal engine-runtime worker group
  • public worker/function payloads do not expose private routing metadata or generated process details
  • no generated worker process is started; routing remains engine-owned through HTTP invocation

Notes

spec-to-worker::convert registers normal iii functions backed by HTTP invocation. The engine exposes a user-facing worker grouping for discovery, while routing remains engine-owned and no backing worker process is started for that group. Other workers see ordinary worker/function shapes, not private generated routing details.

@vercel

vercel Bot commented May 13, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
iii-website Ready Ready Preview, Comment May 14, 2026 5:13pm

Request Review

@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a VirtualWorkerRegistry and crate wiring, propagates a trusted_internal HTTP flag with loopback detection, conditions URL validation on trust, and integrates claim/remove ownership across engine registration, unregister, and cleanup with tests for behavior and rollback.

Changes

Virtual Workers and HTTP Trust

Layer / File(s) Summary
Virtual Worker Registry Foundation
engine/src/lib.rs, engine/src/virtual_workers.rs
Introduces VirtualWorkerRegistry and VirtualWorkerInfo, implements claim_function, remove_function, contains_function, and take_virtual_worker_name; includes unit tests for metadata stripping and registry cleanup.
HTTP trust fields and deps
engine/Cargo.toml, engine/src/invocation/http_function.rs, engine/src/invocation/http_invoker.rs
Adds url dependency. HttpFunctionConfig gains trusted_internal: bool (serde default/skip-if-false). HttpEndpointParams adds trusted_internal and invoke_http skips URL validation when true.
Engine integration and lifecycle changes
engine/src/engine/mod.rs
Engine adds virtual_workers: Arc<VirtualWorkerRegistry>, is_loopback_http_url, extracts iii.virtualWorker during RegisterFunction, sets HttpFunctionConfig.trusted_internal from virtual-worker trust OR loopback, claims/removes functions in registry during register/unregister, and uses ownership-guarded removal in cleanup_worker. Adds tests for loopback, virtual-worker tracking, and registration rollback.
HttpFunctions worker and invoker propagation
engine/src/workers/http_functions/mod.rs, engine/src/invocation/http_invoker.rs
HttpFunctionsWorker propagates trusted_internal into HttpEndpointParams; register_http_function skips URL allowlist validation when trusted_internal is true; worker registration macro enabled by default; test helper sets trusted_internal:false.
Worker visibility filtering and tests
engine/src/workers/engine_fn/mod.rs, engine/tests/*, engine/src/workers/worker/rbac_session.rs, engine/src/worker_connections/mod.rs
EngineFunctionsWorker::list_worker_infos filters out virtual functions. Multiple tests and helpers updated to explicitly set trusted_internal:false (invoker unit tests, e2e security/error tests, RBAC/session and worker-connection tests). RBAC Session/AuthResult carry trusted_internal.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • iii-hq/iii#1502: Adds ownership-gated cleanup/registration behavior in engine/src/engine/mod.rs, similar ownership-safety goals.
  • iii-hq/iii#1585: Also modifies engine/src/workers/engine_fn/mod.rs worker listing logic; relates to worker/function visibility handling.

Suggested reviewers

  • sergiofilhowz
  • guibeira

🐰 I hop through code with tiny paws and cheer,
A registry sprouts—virtual names appear,
Loopback whispers trust, validations bow,
Functions find homes, then leave when owners vow,
A rabbit's wink: tests green, the path is clear.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'expose generated HTTP functions as worker groups' is vague about the core mechanism (virtual-worker tracking) and doesn't clarify that this is engine-side support for HTTP-invoked functions. Consider a more specific title like 'feat(engine): support virtual HTTP-invoked worker groups' or 'feat(engine): track and expose externally registered HTTP functions as worker groups' to better convey the main change.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description covers all required sections (What/Why/Notes) with clear detail about virtual-worker tracking, metadata stripping, trust mechanisms, and SDK test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch artifact-http-invocation-workers

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
engine/src/engine/mod.rs (1)

1200-1215: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Roll back service_registry when external registration aborts.

register_service_from_function_id runs before the HTTP module lookup and before register_http_function. Both failure paths return after only releasing external_function_owners, so a failed external registration leaves a stale service entry behind even though no function was created.

🩹 Suggested rollback
                 let Some(http_module) = self
                     .service_registry
                     .get_service::<HttpFunctionsWorker>("http_functions")
                 else {
+                    self.service_registry
+                        .remove_function_from_services(&reg_id);
                     tracing::error!(
                         worker_id = %worker.id,
                         function_id = %reg_id,
                         "HTTP functions module not loaded"
                     );
                     self.release_external_function_if_owner(&worker.id, &reg_id);
                     return Ok(());
                 };
@@
                     if let Err(err) = http_module.register_http_function(config).await {
                         tracing::error!(
                             worker_id = %worker.id,
                             function_id = %reg_id,
                             error = ?err,
                             "Failed to register HTTP invocation function"
                         );
+                        self.service_registry
+                            .remove_function_from_services(&reg_id);
                         self.release_external_function_if_owner(&worker.id, &reg_id);
                         return Ok(());
                     }

Also applies to: 1235-1243

🤖 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 `@engine/src/engine/mod.rs` around lines 1200 - 1215, The code calls
self.service_registry.register_service_from_function_id(&reg_id) before
attempting to look up the HTTP module and before calling register_http_function,
so when the lookup or subsequent registration fails the service entry remains
stale; update the failure paths (the branch after
get_service::<HttpFunctionsWorker>("http_functions") returns None and the
similar branch around register_http_function) to roll back the earlier
registration by removing/unregistering the service from self.service_registry
(e.g. call the appropriate unregister/remove method using reg_id) before calling
release_external_function_if_owner and returning, ensuring
register_service_from_function_id and register_http_function are symmetrical
(register then unregister on any abort).
🤖 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 `@engine/src/engine/mod.rs`:
- Line 1186: The code currently derives virtual_worker_name from
Message::RegisterFunction.metadata via take_virtual_worker_name(&mut
reg_metadata), which lets an untrusted worker set metadata.iii.virtualWorker and
thereby flip trusted_internal when invocation.url points to localhost; change
this so the virtual worker flag is not accepted from worker-supplied metadata
but is instead determined from a server-side trust signal tied to the
authenticated worker/session (e.g., authenticated worker identity or session
record), and use that server-verified property when computing trusted_internal;
update the other occurrences (around the block referenced at 1228-1230) to
follow the same pattern so no decision about URL-validation bypass is made from
reg_metadata or any Message::RegisterFunction.metadata.
- Around line 2264-2356: The test
test_external_function_virtual_worker_is_internal never triggers the
loopback/trusted-internal logic because Message::RegisterFunction's
HttpInvocationRef.url uses "http://example.com/…"; update that URL to a loopback
address (e.g., "http://127.0.0.1/…" or "http://localhost/…") so the
trusted-internal branch is exercised, and add an assertion on the virtual
worker's trusted/internal flag (inspect the VirtualWorker struct field used to
record this, e.g., virtual_worker.trusted_internal or similar) after
registration to verify the flag is set true; keep the rest of the test flow
(unregister and cleanup) unchanged.

In `@engine/src/virtual_workers.rs`:
- Around line 1-5: Add the project's standard license header comment block to
the top of engine/src/virtual_workers.rs above the existing use statements
(e.g., above "use std::collections::HashSet;" and the other imports like "use
dashmap::DashMap;", "use serde_json::Value;", "use uuid::Uuid;") so the file
passes the license-header check; ensure the header exactly matches the
repository's canonical header format and encoding.

---

Outside diff comments:
In `@engine/src/engine/mod.rs`:
- Around line 1200-1215: The code calls
self.service_registry.register_service_from_function_id(&reg_id) before
attempting to look up the HTTP module and before calling register_http_function,
so when the lookup or subsequent registration fails the service entry remains
stale; update the failure paths (the branch after
get_service::<HttpFunctionsWorker>("http_functions") returns None and the
similar branch around register_http_function) to roll back the earlier
registration by removing/unregistering the service from self.service_registry
(e.g. call the appropriate unregister/remove method using reg_id) before calling
release_external_function_if_owner and returning, ensuring
register_service_from_function_id and register_http_function are symmetrical
(register then unregister on any abort).
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 4dd3c242-2748-4168-962b-9190eb824cb9

📥 Commits

Reviewing files that changed from the base of the PR and between 54c841a and b8c09d4.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • engine/Cargo.toml
  • engine/src/engine/mod.rs
  • engine/src/invocation/http_function.rs
  • engine/src/invocation/http_invoker.rs
  • engine/src/lib.rs
  • engine/src/virtual_workers.rs
  • engine/src/workers/engine_fn/mod.rs
  • engine/src/workers/http_functions/mod.rs
  • engine/tests/http_e2e_error_handling.rs
  • engine/tests/http_e2e_security.rs

Comment thread engine/src/engine/mod.rs Outdated
Comment thread engine/src/engine/mod.rs
Comment thread engine/src/virtual_workers.rs Outdated
Comment thread engine/src/generated_workers.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 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 `@engine/src/engine/mod.rs`:
- Around line 272-279: The is_loopback_http_url function incorrectly checks
host_str() so IPv6 addresses like ::1 (serialized as "[::1]") and other
127.0.0.x addresses are missed; update is_loopback_http_url to parse the URL and
use Url::host() with pattern match on url.host() and call Host::is_loopback()
(or otherwise inspect Host::Ipv4/Ipv6 variants) while still checking
url.scheme() == "http" so all loopback forms are detected; locate the
is_loopback_http_url function and replace the host_str-based logic with
Url::host() + Host::is_loopback().
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 31534426-1a63-434a-9abc-6e7f8d321ace

📥 Commits

Reviewing files that changed from the base of the PR and between b8c09d4 and 8391005.

📒 Files selected for processing (5)
  • engine/src/engine/mod.rs
  • engine/src/virtual_workers.rs
  • engine/src/worker_connections/mod.rs
  • engine/src/workers/worker/rbac_session.rs
  • engine/tests/rbac_infrastructure_e2e.rs
✅ Files skipped from review due to trivial changes (1)
  • engine/src/worker_connections/mod.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • engine/src/virtual_workers.rs

Comment thread engine/src/engine/mod.rs
@rohitg00 rohitg00 changed the title feat(engine): support virtual HTTP-invoked workers feat(engine): expose generated HTTP functions as worker groups May 14, 2026
@rohitg00 rohitg00 marked this pull request as ready for review May 14, 2026 17:30
@rohitg00 rohitg00 closed this May 14, 2026
@rohitg00 rohitg00 deleted the artifact-http-invocation-workers branch May 14, 2026 17:33
@rohitg00

Copy link
Copy Markdown
Contributor Author

Superseded by #1640 after renaming the head branch to generated-http-functions and adding the worker CI cache fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant