Skip to content

fix(collect-worker-interface): collect function schemas from engine::functions::info - #285

Merged
ytallo merged 1 commit into
mainfrom
fix/collect-worker-interface-schemas
Jun 18, 2026
Merged

fix(collect-worker-interface): collect function schemas from engine::functions::info#285
ytallo merged 1 commit into
mainfrom
fix/collect-worker-interface-schemas

Conversation

@ytallo

@ytallo ytallo commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Problem

The publish-time --assert-typed-schemas check (collect_worker_interface.py) fails for every worker, reporting all request_schema/response_schema as untyped (empty {}). It surfaced when releasing llm-router/v0.2.3, whose handlers are in fact correctly typed.

Root cause

The collector gathers each function's schema from engine::functions::list, but that endpoint returns only a FunctionSummaryfunction_id, worker_name, description, with no schema fields. The typed request/response schemas are exposed solely by engine::functions::info (FunctionDetail), under the keys request_schema/response_schema. normalize_worker_interface also read the never-present request_format key.

Result: details.get("request_format")None{} for every function of every worker, so the assertion can never pass against a live engine. The schemas are correctly extracted by the SDK and stored by the engine — only the collection queried the wrong endpoint/keys.

Confirmed on a live engine: functions::list returns 3 keys (no schemas); functions::info returns the full typed schemas.

Fix

  • collect_worker_interface.py: enrich each target function's row from engine::functions::info (best-effort, per function) before normalizing.
  • build_publish_payload.py: read request_schema/response_schema (info-API key names), falling back to request_format for back-compat.

Verification

  • 97/97 collector tests pass, including new coverage for the enrichment merge and the normalize path.
  • Live end-to-end against a real engine + llm-router: all 14 functions resolve with typed request/response schemas and --assert-typed-schemas exits 0 (was 1).

Note

The reusable publish workflow runs at the release tag's ref, so this needs a new tag (e.g. llm-router/v0.2.4) to take effect in the pipeline — re-running the old job re-runs the pre-fix script.

Summary by CodeRabbit

  • New Features

    • Enhanced function metadata collection with automatic enrichment of typed schemas for improved completeness and accuracy
    • Improved schema field handling in build payload generation with better preference handling for strongly-typed schema definitions
    • Robust error handling for missing or unavailable schema information during collection
  • Tests

    • Added comprehensive test coverage for schema enrichment, normalization, and edge case handling

…functions::info

engine::functions::list returns only a FunctionSummary
(function_id/worker_name/description) — the typed request/response schemas
live solely on engine::functions::info (FunctionDetail), keyed
request_schema/response_schema. The collector read schemas from ::list under
the never-present request_format key, so every function normalized to an empty
{} schema and the --assert-typed-schemas publish check failed for every worker
regardless of how its handlers were typed.

Enrich each target function's row from engine::functions::info before
normalizing, and read request_schema/response_schema (with a request_format
fallback). Adds unit coverage for the enrichment merge and the normalize path.
@vercel

vercel Bot commented Jun 17, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
workers Ready Ready Preview, Comment Jun 17, 2026 8:18pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 827f4a23-6ace-48e2-b707-f1bfc0831d99

📥 Commits

Reviewing files that changed from the base of the PR and between 9419c0a and 0612e61.

📒 Files selected for processing (4)
  • .github/scripts/build_publish_payload.py
  • .github/scripts/collect_worker_interface.py
  • .github/scripts/tests/test_enrich_function_schemas.py
  • .github/scripts/tests/test_normalize_worker_interface.py

📝 Walkthrough

Walkthrough

Adds _fetch_function_detail and enrich_functions_with_schemas to collect_worker_interface.py to fetch typed request_schema/response_schema from engine::functions::info and merge them into targeted function rows. main() is wired to call this enrichment before normalization. normalize_worker_interface in build_publish_payload.py is updated to prefer the typed schema fields over the legacy request_format/response_format fields.

Changes

Typed Schema Enrichment Pipeline

Layer / File(s) Summary
Schema fetch, merge, and normalization logic
.github/scripts/collect_worker_interface.py, .github/scripts/build_publish_payload.py
Adds _fetch_function_detail (calls engine::functions::info, emits warning and returns None on failure) and enrich_functions_with_schemas (merges request_schema, response_schema, metadata, and description into targeted list rows). main() resolves target function IDs and calls enrichment before normalization. normalize_worker_interface now reads request_schema/response_schema first, falling back to request_format/response_format.
Tests for enrichment and normalized schema surfacing
.github/scripts/tests/test_enrich_function_schemas.py, .github/scripts/tests/test_normalize_worker_interface.py
test_enrich_function_schemas.py covers schema merging into targeted rows, untargeted rows staying unchanged, and graceful handling of missing detail. test_normalize_worker_interface.py adds a test asserting that info-enriched rows surface typed schemas through normalize_worker_interface.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • iii-hq/workers#67: Modifies the same collect_worker_interface.py / build_publish_payload.py pipeline around request_schema/response_schema wiring from engine function details.
  • iii-hq/workers#220: Touches normalize_worker_interface in build_publish_payload.py for request_schema/response_schema handling and updates worker/function resolution tests for the same normalized schema fields.

Suggested reviewers

  • sergiofilhowz

Poem

🐇 Hop, hop, hooray for schemas so typed!
From ::info I fetch what ::list can't provide,
I merge the request and response with care,
And leave the untargeted rows right there.
Legacy fallbacks still waiting in line —
But typed schemas first, by design! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.46% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: fixing function schema collection by querying the engine::functions::info endpoint.
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.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/collect-worker-interface-schemas

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.

@github-actions

Copy link
Copy Markdown
Contributor

skill-check — worker

0 verified, 22 skipped (no docs/).

Layer Result
structure
vale
ai
render

Four for four. Nicely done.

@ytallo
ytallo merged commit f2cfe33 into main Jun 18, 2026
12 of 13 checks passed
ytallo added a commit that referenced this pull request Jun 18, 2026
…290)

Every published worker trigger showed empty invocation_schema/return_schema
(rendered "unknown" in the registry). The publish pipeline collected trigger
types from engine::triggers::list, which returns only a TriggerTypeSummary
(id/worker_name/description) with no schemas, and build_publish_payload read
the obsolete trigger_request_format/call_request_format keys. The typed
schemas live solely on engine::triggers::info (TriggerTypeDetail), under
configuration_schema (binding config) and request_schema (delivered payload).

This is the trigger-side twin of the function-schema fix (#285), which
enriched functions from engine::functions::info but left triggers behind.

- collect_worker_interface.py: enrich each publishable trigger type from
  engine::triggers::info before normalizing (mirrors
  enrich_functions_with_schemas); warn (non-fatal) on triggers still
  publishing without a typed invocation_schema.
- build_publish_payload.py: read configuration_schema -> invocation_schema
  and request_schema -> return_schema, with the legacy keys as fallback.
- tests: trigger enrichment + normalize field-mapping coverage.

Trigger schemas are a warning, not a hard gate: some trigger types take no
binding config (e.g. iii-directory's directory::*::on-change) and are
legitimately schema-less.

Claude-Session: https://claude.ai/code/session_017CciKnWZzsLprzZ6XFHZJ2
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