Repository navigation
feat(engine-api): add FastAPI reference adapter and /policies gap-fix (Epic 0, issue #3066) - #3085
Conversation
Stand up the reference FastAPI adapter for the AGT Studio Engine API contract: a create_app() factory exposing the 12 v1 HTTP operations (11 read-only plus POST /api/v1/policy/save), each carrying capability flags, the section 10 error envelope, section 11 pagination, a filesystem-backed policy registry, and a loopback-only CLI entry point. Fixes the counts-only gap on GET /api/v1/policies by returning paginated PolicySummary objects. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
🤖 AI Agent: security-scanner — View details
No security issues found. |
🤖 AI Agent: breaking-change-detector — API Compatibility
API Compatibility
|
🤖 AI Agent: code-reviewer — View details
TL;DR: 0 blockers, 1 warning. Solid implementation with minor follow-up needed.
Action items: None (no blockers). Warnings:
|
🤖 AI Agent: test-generator — `agentmesh/engine_api/app.py`
|
🤖 AI Agent: docs-sync-checker — Docs Sync
Docs Sync
|
|
🟡 Contributor Check: MEDIUM
Automated check by AGT Contributor Check. |
PR Review Summary
Verdict: AI review comments are untrusted advisory output. The summary reports workflow-generated completion status only, not model-authored pass/fail claims. |
Remove TODO markers from the placeholder route docstrings (the no-stubs gate forbids them), reword them as plain prose that points to the later epic. Replace the test fixture string otanumber and the word Indirected so the spell-check passes, and register starlette in the cspell dictionary. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com>
…astAPI 0.118+ FastAPI 0.118+/Starlette 1.x stopped flattening include_router() sub-routes into app.router.routes, wrapping them in an _IncludedRouter proxy instead. inject_capability_extension iterates app.routes for top-level APIRoute instances, so every operation was silently skipped (no x-capability-flags, empty Studio allowlist) under the newer FastAPI used in CI. Register each route module's APIRoute objects directly on the app so they stay visible to the capability hook across all supported FastAPI versions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com>
… root The POST /api/v1/policy/test route forwarded the request-supplied policy_dir straight into the file-reading replay engine, which CodeQL flagged as py/path-injection (the override could steer the engine at arbitrary server paths). Resolve the override and the configured policy root to real absolute paths and require the override to stay within that root via os.path.commonpath, raising 422 FIXTURE_LOAD_ERROR otherwise. Update the two tests that relied on out-of-root overrides to use in-root directories and add a rejection test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com>
Both are standard-library identifiers (os.path.commonpath, tmp_path_factory.mktemp) introduced by the policy_dir containment guard and its tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com>
…ride The commonpath-based guard cleared the runtime risk but CodeQL still traced the request body into the replay sink because the guard was an indirect boolean. Switch to the recognized path-traversal sanitizer: return the untainted engine root for the equality case and guard the subdirectory return with a direct realpath startswith check, which breaks the py/path-injection data flow. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com>
…ed-import findings The package-level agentmesh import and the two agentmesh.engine_api imports in TestPackageExports were flagged as unused. Convert them to importlib.import_module calls so the side effect (firing the package deprecation warning once before create_app is wrapped) is preserved without binding an unused import name. Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com> Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com>
83b945e to
a99e7dc
Compare
📦 Dependency diff (SBOM)Comparing main → ricky-g/issue-3066-engine-api-fastapi-adapter. ✅ No dependency changes detected. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 71 out of 74 changed files in this pull request and generated 3 comments.
Files not reviewed (3)
- agent-governance-python/agent-mesh/packages/mcp-proxy/package-lock.json: Generated file
- agent-governance-python/agent-os/extensions/mcp-server/package-lock.json: Generated file
- agent-governance-python/agentmesh-integrations/mastra-agentmesh/package-lock.json: Generated file
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1523e5b8-938c-415c-a8ad-52be4cbda287 Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1523e5b8-938c-415c-a8ad-52be4cbda287 Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1523e5b8-938c-415c-a8ad-52be4cbda287 Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com>
a99e7dc to
75135bc
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 35 out of 35 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
agent-governance-python/agent-mesh/src/agentmesh/engine_api/routes/policies.py:9
- The PR description says it fixes the counts-only gap on
agentmesh.server.policy_server'sGET /api/v1/policies, but this PR only adds the corrected paginated behavior in the new Engine API reference adapter. In the current tree,agentmesh/server/policy_server.pystill returns a totals dict for/api/v1/policies.
Either (a) update the PR description (and/or issue scope) to clarify the gap is fixed via the new reference adapter only, or (b) include the legacy policy_server.py change in this PR (if that is still a requirement).
``GET /api/v1/policies`` returns a paginated list of :class:`PolicySummary` objects.
This reference adapter implements the contract shape; the legacy
``agentmesh.server.policy_server`` endpoint still returns totals only.
``GET /api/v1/policies/{id}`` returns full :class:`PolicyDetail` or a
``POLICY_NOT_FOUND`` envelope.
|
MohammadHaroonAbuomar Thank you for the review. The seven Autofix commits now have DCO signoffs, all follow-up findings are addressed, and the corrected history retains current |
Summary
Stand up the reference FastAPI adapter for the AGT Studio Engine API contract: one app, one process, one OpenAPI document exposing all 12 v1 HTTP operations (11 read-only plus the single mutating
POST /api/v1/policy/save), each decorated with thecapability_flagslibrary from PR #3027. Also fixes the long-standing counts-only gap onGET /api/v1/policiesso it returns paginatedPolicySummaryobjects instead of a totals dict.Problem
The Engine API contract (
docs/studio/engine-api-contract.md) and its machine-readable companion (docs/studio/openapi.yaml) had no reference server implementation. Studio panels in later epics need one URL that discovers the entire surface withx-capability-flagson every operation. Separately,agentmesh.server.policy_serveronly returned counts forGET /api/v1/policies, not the per-policy summaries the contract requires.Changes
engine_api/app.pycreate_app(policy_dir=None)factory: resolves the policy dir (arg, thenAGENTMESH_POLICY_DIR, then default), wires the error envelope, includes every route module, and appliesinject_capability_extensionlast.engine_api/__init__.pycreate_appexport via PEP 562__getattr__so the capability library stays importable without FastAPI installed.engine_api/__main__.pypython -m agentmesh.engine_api) running uvicorn, default bind127.0.0.1:8080(loopback only).engine_api/errors.pyRequestValidationErrorand unhandled exceptions to the envelope shape.engine_api/pagination.pyPaginationParamsdependency (page >= 1 default 1, limit 1..100 default 20) and thePaginationresponse model.engine_api/models.pydatetimeso the generated OpenAPI emitsformat: date-time.engine_api/policy_registry.pysave()validates the resolved target stays inside the policy directory.engine_api/routes/policies.pyGET /api/v1/policies(paginated summaries, the gap fix) andGET /api/v1/policies/{id}(404POLICY_NOT_FOUND).engine_api/routes/policy_ops.pyvalidatePolicy,testPolicy, andsavePolicy(the only mutating op; persists then reloads).engine_api/routes/{health,versions,audit,trust,agents,decisions}.pytests/engine_api/*Testing
pytest agent-governance-python/agent-mesh/tests/engine_api/: 136 passed.ruff check --select E,F,W --ignore E501on changed files: clean. Full package config (E, F, I, N, W, UP) also clean.openapi.pylines from PR feat(engine-api): add capability-metadata library for AGT Studio #3027).{id}path parameter rename, thedate-timetyping, and thesave()path-traversal guard.Follow-ups (intentionally out of scope here)
/api/v1/eventsis explicitly deferred to Epic 7a (issue build(deps-dev): Bump eslint from 8.57.1 to 10.0.2 in /packages/agent-os/extensions/copilot #16) per this issue's Scope (out): not implemented, registered, or stubbed. The contract's 426 Upgrade Required behavior for that reserved path lands with the WebSocket work.HTTPValidationErrorfor 422 rather than the section 10 envelope, and does not enumerate per-operation 4XX/5XX error responses. Runtime behavior already returns the envelope for every error; aligning the generated schema with the envelope is a documentation-only refinement worth a separate change.Closes #3066.