Skip to content

Fan out SDK contract wrappers#56

Merged
jadenfix merged 9 commits into
mainfrom
codex/sdk-contract-fanout
Jun 18, 2026
Merged

Fan out SDK contract wrappers#56
jadenfix merged 9 commits into
mainfrom
codex/sdk-contract-fanout

Conversation

@jadenfix

Copy link
Copy Markdown
Contributor

Summary

  • consume the expanded roe-main SDK wrapper contract
  • generate partial Agents/Policies wrappers while preserving hand-written APIs
  • add generated SDK_EXAMPLES.md from the shared SDK examples renderer

Validation

  • uv run ruff check . && uv run ruff format --check . && uv run pytest
  • Docker: uv run ruff check . && uv run ruff format --check . && uv run pytest

@greptile-apps

greptile-apps Bot commented Jun 17, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fans out the expanded roe-main SDK contract into partial generated base classes (_agents_generated.py, _policies_generated.py) while preserving all existing hand-written API behaviour. The generator gains a _render_partial_api_module path that emits Generated*API base classes from wrappers.yml, and the concrete AgentsAPI/PoliciesAPI classes are rewired to inherit from them.

  • Partial-generation pattern: GeneratedAgentsAPI, GeneratedAgentVersionsAPI, GeneratedAgentJobsAPI, and GeneratedPoliciesAPI are emitted to _*_generated.py files; every generated method is currently overridden by the concrete subclass, which injects organization_id and any additional logic (chunking, multipart, etc.).
  • Generator fixes: from uuid import UUID is now emitted unconditionally in partial modules (addressing a latent NameError); needs_any now checks return_type in addition to parameter annotations, with a new unit test pinning both behaviours.
  • SDK_EXAMPLES.md is added as an auto-generated reference for all SDK operations.

Confidence Score: 5/5

Safe to merge. Every generated method in the new base classes is overridden by the concrete subclass, so no user-visible call reaches the generated paths at runtime.

All hand-written API behaviour is fully preserved — the concrete classes override every generated method and continue to inject organization_id. The two generator fixes (unconditional UUID import, return_type check for needs_any) are verified by a new unit test. The latent design fragility requires a future contract change to trigger and is not present in the current diff.

No files require special attention for merging. Reviewers may want to keep an eye on scripts/generate_wrappers.py and openapi/wrappers.yml when the next contract update adds new kind: body operations, to ensure corresponding overrides are added to the concrete API classes.

Important Files Changed

Filename Overview
scripts/generate_wrappers.py Core code-generator; adds _render_partial_api_module for split generated/hand-written APIs. UUID import is now unconditional; needs_any now checks return_type. organization_id is not modelled as a per-operation inject for non-body-inject ops, relying on concrete overrides.
src/roe/api/_agents_generated.py New generated base classes (GeneratedAgentsAPI, GeneratedAgentVersionsAPI, GeneratedAgentJobsAPI). All methods are currently overridden by concrete subclasses, but none pass organization_id — a latent risk when the contract grows.
src/roe/api/_policies_generated.py New generated base class (GeneratedPoliciesAPI). All 5 methods overridden by PoliciesAPI; same missing-organization_id pattern as agents generated file.
src/roe/api/agents.py Concrete AgentsAPI now inherits GeneratedAgentsAPI; all previously hand-written methods retained verbatim with organization_id. AgentVersionsAPI and AgentJobsAPI similarly wired. No behavioral change to existing methods.
src/roe/api/policies.py PoliciesAPI now inherits GeneratedPoliciesAPI. All 5 public methods retained with organization_id injection, PolicyVersionsAPI unchanged. Clean split preserved.
openapi/wrappers.yml Expanded contract adds agents and policies API groups with namespaces; manual vs body/simple distinction is correctly applied. inject_organization_id used only for agents.create.
tests/unit/test_generate_wrappers.py New test pins the UUID-always-imported and return_type-Any fixes. Coverage is good for the top-level path but doesn't exercise the namespace branch of _iter_specs for needs_any.

Class Diagram

%%{init: {'theme': 'neutral'}}%%
classDiagram
    class GeneratedAgentsAPI {
        +config: RoeConfig
        +_raw: AuthenticatedClient
        +_org_id() UUID
        +list()
        +retrieve()
        +create()
        +update()
        +delete()
        +duplicate()
    }
    class AgentsAPI {
        +__init__(config, raw_client)
        +list() [+org_id]
        +retrieve() [+org_id]
        +create() [+org_id]
        +update() [+org_id]
        +delete() [+org_id]
        +duplicate() [+org_id]
        +run()
        +run_many()
        +run_sync()
        +run_version()
        +run_version_sync()
    }
    class GeneratedAgentVersionsAPI {
        +list()
        +retrieve()
        +retrieve_current()
        +create()
        +update()
        +delete()
    }
    class AgentVersionsAPI {
        +__init__(agents_api)
        +list() [+org_id]
        +retrieve() [+org_id]
        +create() [+org_id]
        +update() [+org_id]
        +delete() [+org_id]
    }
    class GeneratedAgentJobsAPI {
        +retrieve_status()
        +retrieve_result()
        +cancel()
        +cancel_all()
        +delete_data()
    }
    class AgentJobsAPI {
        +retrieve_status() [+org_id]
        +retrieve_result() [+org_id]
        +cancel() [+org_id]
        +cancel_all() [+org_id]
        +delete_data() [+org_id]
        +retrieve_status_many()
        +retrieve_result_many()
        +download_reference()
    }
    class GeneratedPoliciesAPI {
        +list()
        +retrieve()
        +create()
        +update()
        +delete()
    }
    class PoliciesAPI {
        +list() [+org_id]
        +retrieve() [+org_id]
        +create() [+org_id]
        +update() [+org_id]
        +delete() [+org_id]
        +versions: PolicyVersionsAPI
    }
    GeneratedAgentsAPI <|-- AgentsAPI
    GeneratedAgentVersionsAPI <|-- AgentVersionsAPI
    GeneratedAgentJobsAPI <|-- AgentJobsAPI
    GeneratedPoliciesAPI <|-- PoliciesAPI
    AgentsAPI --> AgentVersionsAPI : versions
    AgentsAPI --> AgentJobsAPI : jobs
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
classDiagram
    class GeneratedAgentsAPI {
        +config: RoeConfig
        +_raw: AuthenticatedClient
        +_org_id() UUID
        +list()
        +retrieve()
        +create()
        +update()
        +delete()
        +duplicate()
    }
    class AgentsAPI {
        +__init__(config, raw_client)
        +list() [+org_id]
        +retrieve() [+org_id]
        +create() [+org_id]
        +update() [+org_id]
        +delete() [+org_id]
        +duplicate() [+org_id]
        +run()
        +run_many()
        +run_sync()
        +run_version()
        +run_version_sync()
    }
    class GeneratedAgentVersionsAPI {
        +list()
        +retrieve()
        +retrieve_current()
        +create()
        +update()
        +delete()
    }
    class AgentVersionsAPI {
        +__init__(agents_api)
        +list() [+org_id]
        +retrieve() [+org_id]
        +create() [+org_id]
        +update() [+org_id]
        +delete() [+org_id]
    }
    class GeneratedAgentJobsAPI {
        +retrieve_status()
        +retrieve_result()
        +cancel()
        +cancel_all()
        +delete_data()
    }
    class AgentJobsAPI {
        +retrieve_status() [+org_id]
        +retrieve_result() [+org_id]
        +cancel() [+org_id]
        +cancel_all() [+org_id]
        +delete_data() [+org_id]
        +retrieve_status_many()
        +retrieve_result_many()
        +download_reference()
    }
    class GeneratedPoliciesAPI {
        +list()
        +retrieve()
        +create()
        +update()
        +delete()
    }
    class PoliciesAPI {
        +list() [+org_id]
        +retrieve() [+org_id]
        +create() [+org_id]
        +update() [+org_id]
        +delete() [+org_id]
        +versions: PolicyVersionsAPI
    }
    GeneratedAgentsAPI <|-- AgentsAPI
    GeneratedAgentVersionsAPI <|-- AgentVersionsAPI
    GeneratedAgentJobsAPI <|-- AgentJobsAPI
    GeneratedPoliciesAPI <|-- PoliciesAPI
    AgentsAPI --> AgentVersionsAPI : versions
    AgentsAPI --> AgentJobsAPI : jobs
Loading

Reviews (5): Last reviewed commit: "Complete Python partial import tracking" | Re-trigger Greptile

Comment thread scripts/generate_wrappers.py Outdated
Comment thread src/roe/api/_agents_generated.py Outdated
Comment thread .roe-main-release-version Outdated
@jadenfix

Copy link
Copy Markdown
Contributor Author

@greptile review

@jadenfix

Copy link
Copy Markdown
Contributor Author

@greptile review

Comment thread scripts/generate_wrappers.py Outdated
@jadenfix

Copy link
Copy Markdown
Contributor Author

@greptile review

@jadenfix

Copy link
Copy Markdown
Contributor Author

@greptile review

@jadenfix

Copy link
Copy Markdown
Contributor Author

/greptile

1 similar comment
@jadenfix

Copy link
Copy Markdown
Contributor Author

/greptile

@jadenfix jadenfix merged commit 1f5ccbf into main Jun 18, 2026
3 checks passed
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.

2 participants