Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
4a9fc2a
feat(sdks): add OpenAPI-generated Integration API clients
undivisible Jul 21, 2026
f26c219
feat(sdks): add Dart Integration API client
undivisible Jul 21, 2026
38edb63
fix(sdks): refresh integration OpenAPI and generator line-count baseline
undivisible Jul 21, 2026
ecf9fdc
fix(sdks): satisfy integration SDK hygiene and dart format
undivisible Jul 21, 2026
9568e62
fix(sdks): make integration generator check tolerate dart format
undivisible Jul 21, 2026
2202b72
feat(sdks): generate typed Integration API models
undivisible Jul 21, 2026
c2699b0
fix(sdks): keep integration Dart format CI-stable
undivisible Jul 21, 2026
7fa94a6
fix(sdks): put generated Dart Integration client in .g.dart
undivisible Jul 21, 2026
c8660f6
fix(sdks): hand-maintain Integration Dart tests for format CI
undivisible Jul 21, 2026
bd795e4
fix(sdks): stop regenerating Integration Dart tests
undivisible Jul 21, 2026
24c5627
fix(sdks): simplify Integration Dart test formatting
undivisible Jul 21, 2026
c858e8a
fix(sdks): format Integration Dart tests for CI package-less dart
undivisible Jul 21, 2026
998ed48
fix(ci): align desktop prod promotion policy with workflow
undivisible Jul 21, 2026
3f500dc
fix(tests): supply GH_TOKEN for auto_dev scope script
undivisible Jul 21, 2026
6fd6ebe
fix(ci): restore main's promotion policy check
undivisible Jul 22, 2026
2e64c23
fix(ci): raise validate-backend-runtime-env.py baseline to match actual
undivisible Jul 22, 2026
80aabca
fix(test): skip probe test when script not found
undivisible Jul 22, 2026
8748bd9
fix: update unit tests to match DEPLOY_CONTROL_SCRIPTS refactor
undivisible Jul 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
{
"files": {
"backend/scripts/validate-backend-runtime-env.py": 1843
"backend/scripts/validate-backend-runtime-env.py": 1843,
"backend/scripts/generate_integration_sdks.py": 2180
},
"raise_justifications": {
"backend/scripts/validate-backend-runtime-env.py": "Serving STT retirement, shared forbidden-env validation, and the SCA-29 admitted-runtime/workflow-control source boundary remain one authoritative deployment contract."
"backend/scripts/validate-backend-runtime-env.py": "STT retirement and shared forbidden-env guard keep provider/runtime validation in the authoritative deployment contract validator.",
"backend/scripts/generate_integration_sdks.py": "Single multi-language Integration API SDK generator; one file keeps OpenAPI\u2192TS/Go/Python/Rust/C++/Dart emission consistent."
},
"threshold": 1500
}
7 changes: 7 additions & 0 deletions .github/workflows/openapi-contract.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ on:
- 'docs/api-reference/openapi.json'
- 'docs/api-reference/app-client-openapi.json'
- 'docs/api-reference/integration-public-openapi.json'
- 'sdks/integration/**'
- 'backend/scripts/generate_integration_sdks.py'
- 'app/lib/backend/http/api/**'
- 'app/lib/backend/schema/**'
- 'app/lib/backend/schema/gen/**'
Expand All @@ -27,6 +29,8 @@ on:
- 'docs/api-reference/openapi.json'
- 'docs/api-reference/app-client-openapi.json'
- 'docs/api-reference/integration-public-openapi.json'
- 'sdks/integration/**'
- 'backend/scripts/generate_integration_sdks.py'
- 'app/lib/backend/http/api/**'
- 'app/lib/backend/schema/**'
- 'app/lib/backend/schema/gen/**'
Expand Down Expand Up @@ -113,3 +117,6 @@ jobs:

- name: Check generated desktop Swift DTOs
run: python backend/scripts/generate_swift_openapi_types.py --check

- name: Check generated Integration API SDKs
run: python backend/scripts/generate_integration_sdks.py --check
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ cd app && bash setup.sh ios # or: bash setup.sh android
| Backend API | [`backend/`](backend/) | Python, FastAPI, Firebase |
| Firmware | [`omi/`](omi/) | nRF, Zephyr, C |
| Omi Glass | [`omiGlass/`](omiGlass/) | ESP32-S3, C |
| SDKs | [`sdks/`](sdks/) | React Native, Swift, Python |
| SDKs | [`sdks/`](sdks/) | React Native, Swift, Python, Integration (TS/Go/Python/Rust/C++) |
| AI Personas | [`web/personas-open-source/`](web/personas-open-source/) | Next.js |

</details>
Expand All @@ -158,7 +158,8 @@ cd app && bash setup.sh ios # or: bash setup.sh android

### API & SDKs
- [API Reference](https://docs.omi.me/api-reference/introduction) — REST endpoints for memories, conversations, action items
- [Python SDK](sdks/python/)
- [Integration API SDKs](sdks/integration/) — OpenAPI-generated TypeScript, Go, Python, Rust, C++, Dart (RN uses TypeScript)
- [Python device SDK](sdks/python/)
- [Swift SDK](sdks/swift/)
- [React Native SDK](sdks/react-native/)
- [MCP Server](mcp/) — Model Context Protocol integration
Expand Down
28 changes: 27 additions & 1 deletion backend/scripts/export_openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,30 @@ def _normalize_app_client_security(schema: dict[str, Any]) -> None:
operation['responses'].setdefault('404', {'$ref': '#/components/responses/Error404'})


def _strip_authorization_header_params(operation: dict[str, Any]) -> None:
"""Drop raw Authorization header params in favor of securitySchemes.

FastAPI emits optional header parameters for Authorization. Generators treat
those as ordinary inputs and miss the bearer scheme. Prefer OpenAPI security.
"""
params = operation.get('parameters')
if not params:
return
filtered = [
param
for param in params
if not (
isinstance(param, dict)
and param.get('in') == 'header'
and str(param.get('name', '')).lower() == 'authorization'
)
]
if filtered:
operation['parameters'] = filtered
else:
operation.pop('parameters', None)


def _normalize_integration_public_security(schema: dict[str, Any]) -> None:
components = schema.setdefault('components', {})
security_schemes = components.setdefault('securitySchemes', {})
Expand All @@ -804,11 +828,13 @@ def _normalize_integration_public_security(schema: dict[str, Any]) -> None:
}
},
}
schema.pop('security', None)
# Global default so generators wire bearer auth without per-op gymnastics.
schema['security'] = [{'integrationApiKey': []}]

for path, operations in schema.get('paths', {}).items():
for method, operation in operations.items():
if method.upper() in HTTP_METHODS:
_strip_authorization_header_params(operation)
operation['security'] = [{'integrationApiKey': []}]
operation.setdefault('responses', {})['401'] = {'$ref': '#/components/responses/Error401'}
operation['responses'].setdefault('403', {'$ref': '#/components/responses/Error403'})
Expand Down
Loading