immich-api 0.2.1__tar.gz → 0.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {immich_api-0.2.1 → immich_api-0.2.3}/.bumpversion.cfg +1 -1
- immich_api-0.2.3/.github/workflows/connector-pr.yml +16 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pre-commit-config.yaml +0 -12
- {immich_api-0.2.1/immich_api.egg-info → immich_api-0.2.3}/PKG-INFO +4 -4
- {immich_api-0.2.1 → immich_api-0.2.3}/docker/Dockerfile +1 -1
- immich_api-0.2.3/immich_api/connector_sources.py +145 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/mcp_server.py +0 -9
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/ontology/immich.ttl +1 -1
- {immich_api-0.2.1 → immich_api-0.2.3/immich_api.egg-info}/PKG-INFO +4 -4
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api.egg-info/SOURCES.txt +9 -8
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api.egg-info/entry_points.txt +0 -3
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api.egg-info/requires.txt +3 -3
- {immich_api-0.2.1 → immich_api-0.2.3}/pyproject.toml +5 -8
- {immich_api-0.2.1 → immich_api-0.2.3}/requirements.txt +1 -1
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/generate_immich_content.py +1 -54
- {immich_api-0.2.1 → immich_api-0.2.3}/specs/README.md +1 -0
- immich_api-0.2.3/specs/connector-content/plan.md +7 -0
- immich_api-0.2.3/specs/connector-content/requirements.md +9 -0
- immich_api-0.2.3/specs/connector-content/spec.md +11 -0
- immich_api-0.2.3/specs/connector-content/status.json +22 -0
- immich_api-0.2.3/specs/connector-content/tasks.md +5 -0
- immich_api-0.2.3/specs/connector-content/test-spec.md +7 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/parity_support.py +3 -3
- immich_api-0.2.3/tests/test_default_content_surfaces.py +43 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_fleet_name.py +2 -10
- immich_api-0.2.3/tests/test_immich_content.py +44 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_kg_ingest.py +0 -30
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_operation_parity.py +75 -11
- immich_api-0.2.1/immich_api/connector_manifest.yml +0 -212
- immich_api-0.2.1/immich_api/connectors/mcp_source_presets.json +0 -3
- immich_api-0.2.1/immich_api/connectors/tool_schema_fingerprints.json +0 -1
- immich_api-0.2.1/scripts/generate_tool_schemas.py +0 -100
- immich_api-0.2.1/scripts/generated_schema_clones.py +0 -148
- immich_api-0.2.1/scripts/verify_generated_schemas.py +0 -111
- immich_api-0.2.1/tests/test_generated_schema_policy.py +0 -159
- immich_api-0.2.1/tests/test_immich_content.py +0 -149
- immich_api-0.2.1/tests/test_source_image.py +0 -24
- {immich_api-0.2.1 → immich_api-0.2.3}/.config/spec-dashboard.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.github/workflows/pages.yml +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.github/workflows/pipeline.yml +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.github/workflows/scanners.yml +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.github/workflows/windows-ci.yml +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/provenance.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/scripts/sync_mkdocs_theme.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/README.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/assets/brands/agent-connector-sdk-logo-v1.png +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/assets/brands/agent-terminal-ui-logo-v1.png +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/assets/brands/agent-utilities-logo-v1.png +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/assets/brands/agent-webui-logo-v1.png +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/assets/brands/epistemic-graph-logo-v1.png +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/assets/brands/geniusbot-logo-v1.png +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/assets/brands/graph-os-logo-v1.png +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/assets/favicon.svg +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/assets/graph-mark.svg +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/assets/runtime-architecture.mmd +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/assets/runtime-architecture.svg +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/base.mkdocs.yml +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/extra.css +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/glossary.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/.pipeline-theme/templates/mkdocs-theme/overrides/main.html +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/LICENSE +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/MANIFEST.in +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/README.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docker/debug.Dockerfile +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docker/mcp.compose.yml +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docker/starship.toml +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/agent-readiness.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/agent-readiness.schema.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/architecture.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/assets/brands/agent-connector-sdk-logo-v1.png +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/assets/brands/agent-terminal-ui-logo-v1.png +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/assets/brands/agent-utilities-logo-v1.png +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/assets/brands/agent-webui-logo-v1.png +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/assets/brands/epistemic-graph-logo-v1.png +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/assets/brands/geniusbot-logo-v1.png +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/assets/brands/graph-os-logo-v1.png +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/assets/favicon.svg +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/assets/graph-mark.svg +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/assets/runtime-architecture.mmd +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/assets/runtime-architecture.svg +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/capabilities/api.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/capabilities/mcp.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/concepts.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/deployment.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/glossary.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/immich-capabilities.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/index.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/installation.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/openapi-parity.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/overview.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/platform.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/spec-delivery.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/stylesheets/extra.css +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/docs/usage.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/__init__.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/__main__.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/album_metadata.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/api/__init__.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/api/api_client_system.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/auth.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/connectors/__init__.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/error_authority.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/error_rendering.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/immich_input_models.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/immich_response_models.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/kg_ingest.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/mcp/__init__.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/mcp/album_sample.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/mcp_config.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/ontology/__init__.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/ontology/schema-provenance.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/ontology/shapes/immich.ttl +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/openapi_auth_scheme.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/openapi_contract.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/openapi_execution.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/openapi_inventory.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/openapi_request.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/openapi_response.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/openapi_runtime.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/__init__.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/check_openapi_parity.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/openapi_discovery.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/openapi_parity.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/openapi_provider_evidence.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/openapi_provider_overlay.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/openapi_provider_responses.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/openapi_schema.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/openapi_schema_budget.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/openapi_schema_inputs.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/openapi_schema_types.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/openapi_security.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/openapi_source_parity.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/openapi_transport_parity.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/unicode_patterns.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/parity/unicode_properties.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/prompts/__init__.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/prompts/immich_album_review.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/prompts/immich_asset_metadata.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/prompts/immich_person_record.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/prompts/immich_specialist.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/prompts/main_agent.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/skills/__init__.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/skills/immich-album-review/SKILL.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/skills/immich-asset-metadata/SKILL.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/skills/immich-health/SKILL.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api/skills/immich-person-record/SKILL.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api.egg-info/dependency_links.txt +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/immich_api.egg-info/top_level.txt +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/mkdocs.yml +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/pytest.ini +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/agent_readiness_tck.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/bootstrap.sh +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/bootstrap_environment.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/bootstrap_sources.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/check_connector_contract.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/check_import_safety.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/check_workspace_source_drift.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/generate_agent_readiness.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/measure_operation_parity.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/reviewed_secret_history.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/security_sanitizer.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/select_python.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/upstream_evidence.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/verify_api_integration.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/scripts/workspace_sources.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/setup.cfg +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/specs/immich-api/plan.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/specs/immich-api/requirements.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/specs/immich-api/spec.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/specs/immich-api/status.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/specs/immich-api/tasks.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/specs/immich-api/test-spec.md +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/__init__.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/conftest.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/fixtures/native-client-budget.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/fixtures/operation-cases.json +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/operation_fixtures.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_album_metadata.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_api_wrapper.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_auth.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_concept_parity.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_error_authority.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_immich_mcp_validation.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_init_dynamics.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_oauth_redirect_response.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_openapi_auth_provider.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_reviewed_secret_history.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_session_auth_isolation.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_startup.py +0 -0
- {immich_api-0.2.1 → immich_api-0.2.3}/tests/test_upstream_evidence.py +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: Connector PR
|
|
2
|
+
|
|
3
|
+
on: pull_request
|
|
4
|
+
|
|
5
|
+
concurrency:
|
|
6
|
+
group: pr-${{ github.workflow }}-${{ github.event.pull_request.number }}
|
|
7
|
+
cancel-in-progress: true
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
gates:
|
|
14
|
+
uses: Knuckles-Team/pipelines/.github/workflows/connector_pr_pipeline.yml@main
|
|
15
|
+
with:
|
|
16
|
+
runner: '"self-hosted"'
|
|
@@ -20,12 +20,6 @@ repos:
|
|
|
20
20
|
stages: [pre-push]
|
|
21
21
|
- id: kiss-census
|
|
22
22
|
stages: [pre-push]
|
|
23
|
-
- id: jscpd-differential
|
|
24
|
-
entry: python scripts/generated_schema_clones.py differential
|
|
25
|
-
stages: [pre-push]
|
|
26
|
-
- id: jscpd-census
|
|
27
|
-
entry: python scripts/generated_schema_clones.py census
|
|
28
|
-
stages: [pre-push]
|
|
29
23
|
- id: public-surface
|
|
30
24
|
- id: security-sanitizer
|
|
31
25
|
- id: secret-history
|
|
@@ -72,12 +66,6 @@ repos:
|
|
|
72
66
|
language: system
|
|
73
67
|
pass_filenames: false
|
|
74
68
|
always_run: true
|
|
75
|
-
- id: connector-tool-schemas
|
|
76
|
-
name: Live SDK input and output schema contracts
|
|
77
|
-
entry: python scripts/generate_tool_schemas.py --check
|
|
78
|
-
language: system
|
|
79
|
-
pass_filenames: false
|
|
80
|
-
always_run: true
|
|
81
69
|
- id: pytest
|
|
82
70
|
name: Generated connector contracts
|
|
83
71
|
entry: python -m pytest tests -q
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: immich-api
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Immich Api API + MCP Server
|
|
5
5
|
Author: Repository Maintainers
|
|
6
6
|
License: MIT
|
|
@@ -16,11 +16,11 @@ Requires-Dist: rfc3986-validator<0.2,>=0.1.1
|
|
|
16
16
|
Requires-Dist: rfc3339-validator<0.2,>=0.1.4
|
|
17
17
|
Requires-Dist: jsonschema<5,>=4.23
|
|
18
18
|
Requires-Dist: regex>=2026.9.29
|
|
19
|
-
Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.
|
|
19
|
+
Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.4.1
|
|
20
20
|
Provides-Extra: mcp
|
|
21
|
-
Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.
|
|
21
|
+
Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.4.1; extra == "mcp"
|
|
22
22
|
Provides-Extra: all
|
|
23
|
-
Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.
|
|
23
|
+
Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.4.1; extra == "all"
|
|
24
24
|
Provides-Extra: test
|
|
25
25
|
Requires-Dist: pytest-xdist>=3.6.0; extra == "test"
|
|
26
26
|
Requires-Dist: pytest; extra == "test"
|
|
@@ -20,7 +20,7 @@ ENV HOST=${HOST} \
|
|
|
20
20
|
XDG_CONFIG_HOME=/tmp/.config \
|
|
21
21
|
XDG_CACHE_HOME=/tmp/.cache
|
|
22
22
|
# Fixed identity for least-privilege runtime and stable volume ownership.
|
|
23
|
-
RUN pip install --only-binary :all: immich-api[mcp]==0.2.
|
|
23
|
+
RUN pip install --only-binary :all: immich-api[mcp]==0.2.3 \
|
|
24
24
|
&& groupadd --system --gid 10001 app \
|
|
25
25
|
&& useradd --system --uid 10001 --gid 10001 --no-create-home \
|
|
26
26
|
--home-dir /tmp --shell /usr/sbin/nologin app
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""Data sources of this connector, declared by tool name (generated by connector-ontology-map migrate).
|
|
2
|
+
|
|
3
|
+
Served live as ``connector://resources``. Regenerate by editing the declarations, not the tools.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
# ruff: noqa: E501
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from agent_connector_sdk.ingest.sources import IngestSourceDeclaration, IngestSourceSpec
|
|
12
|
+
|
|
13
|
+
CONNECTOR: str = "immich"
|
|
14
|
+
|
|
15
|
+
SOURCES: tuple[Any, ...] = ()
|
|
16
|
+
|
|
17
|
+
SCHEMA_MAPPINGS: dict[str, Any] = {
|
|
18
|
+
"ImmichAlbum": {
|
|
19
|
+
"fields": {
|
|
20
|
+
"immichAlbumAlbumName": "xsd:string",
|
|
21
|
+
"immichAlbumAlbumThumbnailAssetId": "xsd:string",
|
|
22
|
+
"immichAlbumAssetCount": "xsd:integer",
|
|
23
|
+
"immichAlbumCreatedAt": "xsd:dateTime",
|
|
24
|
+
"immichAlbumHasSharedLink": "xsd:boolean",
|
|
25
|
+
"immichAlbumId": "xsd:string",
|
|
26
|
+
"immichAlbumShared": "xsd:boolean",
|
|
27
|
+
"immichAlbumUpdatedAt": "xsd:dateTime",
|
|
28
|
+
},
|
|
29
|
+
"ontology_class": "ImmichAlbum",
|
|
30
|
+
},
|
|
31
|
+
"ImmichAlbumMembership": {
|
|
32
|
+
"fields": {
|
|
33
|
+
"immichAlbumMembershipRole": "xsd:string",
|
|
34
|
+
},
|
|
35
|
+
"ontology_class": "ImmichAlbumMembership",
|
|
36
|
+
},
|
|
37
|
+
"ImmichAsset": {
|
|
38
|
+
"fields": {
|
|
39
|
+
"immichAssetDuration": "xsd:integer",
|
|
40
|
+
"immichAssetFileCreatedAt": "xsd:dateTime",
|
|
41
|
+
"immichAssetHeight": "xsd:integer",
|
|
42
|
+
"immichAssetId": "xsd:string",
|
|
43
|
+
"immichAssetIsArchived": "xsd:boolean",
|
|
44
|
+
"immichAssetIsFavorite": "xsd:boolean",
|
|
45
|
+
"immichAssetIsTrashed": "xsd:boolean",
|
|
46
|
+
"immichAssetOriginalMimeType": "xsd:string",
|
|
47
|
+
"immichAssetType": "xsd:string",
|
|
48
|
+
"immichAssetUpdatedAt": "xsd:dateTime",
|
|
49
|
+
"immichAssetVisibility": "xsd:string",
|
|
50
|
+
"immichAssetWidth": "xsd:integer",
|
|
51
|
+
},
|
|
52
|
+
"ontology_class": "ImmichAsset",
|
|
53
|
+
},
|
|
54
|
+
"ImmichAssetStack": {
|
|
55
|
+
"fields": {
|
|
56
|
+
"immichAssetStackAssetCount": "xsd:integer",
|
|
57
|
+
"immichAssetStackId": "xsd:string",
|
|
58
|
+
"immichAssetStackPrimaryAssetId": "xsd:string",
|
|
59
|
+
},
|
|
60
|
+
"ontology_class": "ImmichAssetStack",
|
|
61
|
+
},
|
|
62
|
+
"ImmichLibrary": {
|
|
63
|
+
"fields": {
|
|
64
|
+
"immichLibraryAssetCount": "xsd:integer",
|
|
65
|
+
"immichLibraryCreatedAt": "xsd:dateTime",
|
|
66
|
+
"immichLibraryId": "xsd:string",
|
|
67
|
+
"immichLibraryName": "xsd:string",
|
|
68
|
+
"immichLibraryUpdatedAt": "xsd:dateTime",
|
|
69
|
+
},
|
|
70
|
+
"ontology_class": "ImmichLibrary",
|
|
71
|
+
},
|
|
72
|
+
"ImmichPersonRecord": {
|
|
73
|
+
"fields": {
|
|
74
|
+
"immichPersonRecordId": "xsd:string",
|
|
75
|
+
"immichPersonRecordIsFavorite": "xsd:boolean",
|
|
76
|
+
"immichPersonRecordIsHidden": "xsd:boolean",
|
|
77
|
+
"immichPersonRecordName": "xsd:string",
|
|
78
|
+
"immichPersonRecordUpdatedAt": "xsd:dateTime",
|
|
79
|
+
},
|
|
80
|
+
"ontology_class": "ImmichPersonRecord",
|
|
81
|
+
},
|
|
82
|
+
"ImmichTag": {
|
|
83
|
+
"fields": {
|
|
84
|
+
"immichTagCreatedAt": "xsd:dateTime",
|
|
85
|
+
"immichTagId": "xsd:string",
|
|
86
|
+
"immichTagName": "xsd:string",
|
|
87
|
+
"immichTagUpdatedAt": "xsd:dateTime",
|
|
88
|
+
},
|
|
89
|
+
"ontology_class": "ImmichTag",
|
|
90
|
+
},
|
|
91
|
+
"ImmichUser": {
|
|
92
|
+
"fields": {
|
|
93
|
+
"immichUserId": "xsd:string",
|
|
94
|
+
"immichUserName": "xsd:string",
|
|
95
|
+
},
|
|
96
|
+
"ontology_class": "ImmichUser",
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
RESOURCES: tuple[dict[str, str], ...] = (
|
|
101
|
+
{
|
|
102
|
+
"name": "ImmichAsset",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "ImmichAlbum",
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"name": "ImmichPersonRecord",
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"name": "ImmichUser",
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"name": "ImmichLibrary",
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"name": "ImmichAlbumMembership",
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"name": "ImmichTag",
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"name": "ImmichAssetStack",
|
|
124
|
+
},
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def declaration() -> IngestSourceDeclaration:
|
|
129
|
+
"""The declaration the server assembles from this module."""
|
|
130
|
+
specs: list[IngestSourceSpec] = []
|
|
131
|
+
for item in SOURCES:
|
|
132
|
+
for entry in item["connector_sources"]:
|
|
133
|
+
body: dict[str, Any] = {
|
|
134
|
+
k: v for k, v in entry.items() if k not in ("tool", "mapping")
|
|
135
|
+
}
|
|
136
|
+
spec = {**body, "tools": (entry["tool"],)}
|
|
137
|
+
specs.append(IngestSourceSpec.model_validate(spec))
|
|
138
|
+
return IngestSourceDeclaration.model_validate(
|
|
139
|
+
{
|
|
140
|
+
"connector": CONNECTOR,
|
|
141
|
+
"sources": specs,
|
|
142
|
+
"schema_mappings": SCHEMA_MAPPINGS,
|
|
143
|
+
"resources": RESOURCES,
|
|
144
|
+
}
|
|
145
|
+
)
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import sys
|
|
2
|
-
from pathlib import Path
|
|
3
2
|
|
|
4
3
|
from agent_connector_sdk.config import load_config
|
|
5
|
-
from agent_connector_sdk.mcp.content import ConnectorContent
|
|
6
4
|
from agent_connector_sdk.mcp.server import create_mcp_server
|
|
7
5
|
from agent_connector_sdk.mcp.tool_surface import register_tool_surface
|
|
8
6
|
|
|
@@ -14,18 +12,11 @@ __version__ = "0.1.0"
|
|
|
14
12
|
def get_mcp_instance(*, command_args=None):
|
|
15
13
|
"""Construct one SDK-governed server and its native package content."""
|
|
16
14
|
load_config()
|
|
17
|
-
package_root = Path(__file__).resolve().parent
|
|
18
15
|
args, mcp, middlewares = create_mcp_server(
|
|
19
16
|
name="Immich Api",
|
|
20
17
|
version=__version__,
|
|
21
18
|
instructions="Immich Api API + MCP Server",
|
|
22
19
|
command_args=command_args,
|
|
23
|
-
content=ConnectorContent(
|
|
24
|
-
connector="immich",
|
|
25
|
-
package_root=package_root,
|
|
26
|
-
package_version=__version__,
|
|
27
|
-
manifest_path=package_root / "connector_manifest.yml",
|
|
28
|
-
),
|
|
29
20
|
)
|
|
30
21
|
register_tool_surface(mcp, service="immich-api", tools_module=tool_modules)
|
|
31
22
|
for middleware in middlewares:
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
<urn:sha256:7db8383741eeb5c5c8c87a6221cd1cdd1206c8b1190b83363c64223a00bb020b> a prov:Entity ; rdfs:label "Immich 3.2.2 OpenAPI source bytes" .
|
|
10
10
|
|
|
11
|
-
<http://knuckles.team/kg/immich> a owl:Ontology ;
|
|
11
|
+
<http://knuckles.team/kg/immich> a owl:Ontology ; prov:wasDerivedFrom <urn:sha256:7db8383741eeb5c5c8c87a6221cd1cdd1206c8b1190b83363c64223a00bb020b> ; rdfs:comment "Selected structural DTO model. No live ingestion or identity equivalence is asserted." .
|
|
12
12
|
|
|
13
13
|
:ImmichAsset a owl:Class ; rdfs:comment "Structural projection of AssetResponseDto." ; prov:wasDerivedFrom <urn:sha256:7db8383741eeb5c5c8c87a6221cd1cdd1206c8b1190b83363c64223a00bb020b#/components/schemas/AssetResponseDto> .
|
|
14
14
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: immich-api
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Immich Api API + MCP Server
|
|
5
5
|
Author: Repository Maintainers
|
|
6
6
|
License: MIT
|
|
@@ -16,11 +16,11 @@ Requires-Dist: rfc3986-validator<0.2,>=0.1.1
|
|
|
16
16
|
Requires-Dist: rfc3339-validator<0.2,>=0.1.4
|
|
17
17
|
Requires-Dist: jsonschema<5,>=4.23
|
|
18
18
|
Requires-Dist: regex>=2026.9.29
|
|
19
|
-
Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.
|
|
19
|
+
Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.4.1
|
|
20
20
|
Provides-Extra: mcp
|
|
21
|
-
Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.
|
|
21
|
+
Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.4.1; extra == "mcp"
|
|
22
22
|
Provides-Extra: all
|
|
23
|
-
Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.
|
|
23
|
+
Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.4.1; extra == "all"
|
|
24
24
|
Provides-Extra: test
|
|
25
25
|
Requires-Dist: pytest-xdist>=3.6.0; extra == "test"
|
|
26
26
|
Requires-Dist: pytest; extra == "test"
|
|
@@ -8,6 +8,7 @@ pyproject.toml
|
|
|
8
8
|
pytest.ini
|
|
9
9
|
requirements.txt
|
|
10
10
|
.config/spec-dashboard.json
|
|
11
|
+
.github/workflows/connector-pr.yml
|
|
11
12
|
.github/workflows/pages.yml
|
|
12
13
|
.github/workflows/pipeline.yml
|
|
13
14
|
.github/workflows/scanners.yml
|
|
@@ -66,7 +67,7 @@ immich_api/__init__.py
|
|
|
66
67
|
immich_api/__main__.py
|
|
67
68
|
immich_api/album_metadata.py
|
|
68
69
|
immich_api/auth.py
|
|
69
|
-
immich_api/
|
|
70
|
+
immich_api/connector_sources.py
|
|
70
71
|
immich_api/error_authority.py
|
|
71
72
|
immich_api/error_rendering.py
|
|
72
73
|
immich_api/immich_input_models.py
|
|
@@ -90,8 +91,6 @@ immich_api.egg-info/top_level.txt
|
|
|
90
91
|
immich_api/api/__init__.py
|
|
91
92
|
immich_api/api/api_client_system.py
|
|
92
93
|
immich_api/connectors/__init__.py
|
|
93
|
-
immich_api/connectors/mcp_source_presets.json
|
|
94
|
-
immich_api/connectors/tool_schema_fingerprints.json
|
|
95
94
|
immich_api/mcp/__init__.py
|
|
96
95
|
immich_api/mcp/album_sample.py
|
|
97
96
|
immich_api/ontology/__init__.py
|
|
@@ -134,17 +133,20 @@ scripts/check_import_safety.py
|
|
|
134
133
|
scripts/check_workspace_source_drift.py
|
|
135
134
|
scripts/generate_agent_readiness.py
|
|
136
135
|
scripts/generate_immich_content.py
|
|
137
|
-
scripts/generate_tool_schemas.py
|
|
138
|
-
scripts/generated_schema_clones.py
|
|
139
136
|
scripts/measure_operation_parity.py
|
|
140
137
|
scripts/reviewed_secret_history.py
|
|
141
138
|
scripts/security_sanitizer.py
|
|
142
139
|
scripts/select_python.py
|
|
143
140
|
scripts/upstream_evidence.py
|
|
144
141
|
scripts/verify_api_integration.py
|
|
145
|
-
scripts/verify_generated_schemas.py
|
|
146
142
|
scripts/workspace_sources.py
|
|
147
143
|
specs/README.md
|
|
144
|
+
specs/connector-content/plan.md
|
|
145
|
+
specs/connector-content/requirements.md
|
|
146
|
+
specs/connector-content/spec.md
|
|
147
|
+
specs/connector-content/status.json
|
|
148
|
+
specs/connector-content/tasks.md
|
|
149
|
+
specs/connector-content/test-spec.md
|
|
148
150
|
specs/immich-api/plan.md
|
|
149
151
|
specs/immich-api/requirements.md
|
|
150
152
|
specs/immich-api/spec.md
|
|
@@ -159,9 +161,9 @@ tests/test_album_metadata.py
|
|
|
159
161
|
tests/test_api_wrapper.py
|
|
160
162
|
tests/test_auth.py
|
|
161
163
|
tests/test_concept_parity.py
|
|
164
|
+
tests/test_default_content_surfaces.py
|
|
162
165
|
tests/test_error_authority.py
|
|
163
166
|
tests/test_fleet_name.py
|
|
164
|
-
tests/test_generated_schema_policy.py
|
|
165
167
|
tests/test_immich_content.py
|
|
166
168
|
tests/test_immich_mcp_validation.py
|
|
167
169
|
tests/test_init_dynamics.py
|
|
@@ -171,7 +173,6 @@ tests/test_openapi_auth_provider.py
|
|
|
171
173
|
tests/test_operation_parity.py
|
|
172
174
|
tests/test_reviewed_secret_history.py
|
|
173
175
|
tests/test_session_auth_isolation.py
|
|
174
|
-
tests/test_source_image.py
|
|
175
176
|
tests/test_startup.py
|
|
176
177
|
tests/test_upstream_evidence.py
|
|
177
178
|
tests/fixtures/native-client-budget.json
|
|
@@ -10,8 +10,5 @@ immich-api = immich_api.prompts
|
|
|
10
10
|
[agent_utilities.skill_providers]
|
|
11
11
|
immich-api = immich_api.skills
|
|
12
12
|
|
|
13
|
-
[agent_utilities.source_connector_providers]
|
|
14
|
-
immich-api = immich_api.connectors
|
|
15
|
-
|
|
16
13
|
[console_scripts]
|
|
17
14
|
immich-mcp = immich_api.mcp_server:mcp_server
|
|
@@ -2,13 +2,13 @@ rfc3986-validator<0.2,>=0.1.1
|
|
|
2
2
|
rfc3339-validator<0.2,>=0.1.4
|
|
3
3
|
jsonschema<5,>=4.23
|
|
4
4
|
regex>=2026.9.29
|
|
5
|
-
agent-connector-sdk[mcp]<1.0.0,>=0.
|
|
5
|
+
agent-connector-sdk[mcp]<1.0.0,>=0.4.1
|
|
6
6
|
|
|
7
7
|
[all]
|
|
8
|
-
agent-connector-sdk[mcp]<1.0.0,>=0.
|
|
8
|
+
agent-connector-sdk[mcp]<1.0.0,>=0.4.1
|
|
9
9
|
|
|
10
10
|
[mcp]
|
|
11
|
-
agent-connector-sdk[mcp]<1.0.0,>=0.
|
|
11
|
+
agent-connector-sdk[mcp]<1.0.0,>=0.4.1
|
|
12
12
|
|
|
13
13
|
[test]
|
|
14
14
|
pytest-xdist>=3.6.0
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "immich-api"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.3"
|
|
8
8
|
description = "Immich Api API + MCP Server"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
classifiers = [ "Development Status :: 4 - Beta", "License :: OSI Approved :: MIT License", "Environment :: Console", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3",]
|
|
@@ -14,7 +14,7 @@ dependencies = [
|
|
|
14
14
|
"rfc3339-validator>=0.1.4,<0.2",
|
|
15
15
|
"jsonschema>=4.23,<5",
|
|
16
16
|
"regex>=2026.9.29",
|
|
17
|
-
"agent-connector-sdk[mcp]>=0.
|
|
17
|
+
"agent-connector-sdk[mcp]>=0.4.1,<1.0.0",
|
|
18
18
|
]
|
|
19
19
|
[[project.authors]]
|
|
20
20
|
name = "Repository Maintainers"
|
|
@@ -23,9 +23,9 @@ name = "Repository Maintainers"
|
|
|
23
23
|
text = "MIT"
|
|
24
24
|
|
|
25
25
|
[project.optional-dependencies]
|
|
26
|
-
mcp = [ "agent-connector-sdk[mcp]>=0.
|
|
26
|
+
mcp = [ "agent-connector-sdk[mcp]>=0.4.1,<1.0.0",]
|
|
27
27
|
all = [
|
|
28
|
-
"agent-connector-sdk[mcp]>=0.
|
|
28
|
+
"agent-connector-sdk[mcp]>=0.4.1,<1.0.0",
|
|
29
29
|
]
|
|
30
30
|
test = [
|
|
31
31
|
"pytest-xdist>=3.6.0", "pytest", "pytest-asyncio", "pytest-cov",]
|
|
@@ -46,9 +46,6 @@ immich-api = "immich_api.prompts"
|
|
|
46
46
|
[project.entry-points."agent_utilities.ontology_providers"]
|
|
47
47
|
immich-api = "immich_api.ontology"
|
|
48
48
|
|
|
49
|
-
[project.entry-points."agent_utilities.source_connector_providers"]
|
|
50
|
-
immich-api = "immich_api.connectors"
|
|
51
|
-
|
|
52
49
|
# The one declared connector identity: the fleet name (SDK-CONNECTOR-CONTROL-R071).
|
|
53
50
|
[project.entry-points."agent_connector_sdk.connector"]
|
|
54
51
|
immich = "immich_api"
|
|
@@ -87,7 +84,7 @@ dev = [
|
|
|
87
84
|
]
|
|
88
85
|
|
|
89
86
|
[tool.setuptools.package-data]
|
|
90
|
-
immich_api = [ "openapi_inventory.json", "parity/unicode_properties.json", "openapi_contract.json", "mcp_config.json", "prompts/**", "skills/**", "ontology/**", "connectors/**",
|
|
87
|
+
immich_api = [ "openapi_inventory.json", "parity/unicode_properties.json", "openapi_contract.json", "mcp_config.json", "prompts/**", "skills/**", "ontology/**", "connectors/**", ]
|
|
91
88
|
|
|
92
89
|
[tool.ruff.lint]
|
|
93
90
|
select = [ "E", "F", "I", "UP", "B",]
|
|
@@ -81,7 +81,7 @@ def artifacts():
|
|
|
81
81
|
f'<{source}> a prov:Entity ; rdfs:label "Immich 3.2.2 OpenAPI source bytes" .\n',
|
|
82
82
|
]
|
|
83
83
|
ontology.append(
|
|
84
|
-
f'<http://knuckles.team/kg/immich> a owl:Ontology ;
|
|
84
|
+
f'<http://knuckles.team/kg/immich> a owl:Ontology ; prov:wasDerivedFrom <{source}> ; rdfs:comment "Selected structural DTO model. No live ingestion or identity equivalence is asserted." .\n'
|
|
85
85
|
)
|
|
86
86
|
shapes = [PREFIXES]
|
|
87
87
|
resources, mappings, provenance = [], {}, []
|
|
@@ -180,58 +180,6 @@ def artifacts():
|
|
|
180
180
|
resources.append({"name": class_name, "relations": relations})
|
|
181
181
|
mappings[class_name] = {"ontology_class": class_name, "fields": fields}
|
|
182
182
|
ontology_text, shapes_text = "\n".join(ontology), "\n".join(shapes)
|
|
183
|
-
manifest = json.loads((PACKAGE / "connector_manifest.yml").read_text())
|
|
184
|
-
manifest.update(
|
|
185
|
-
{
|
|
186
|
-
"resources": resources,
|
|
187
|
-
"identity": {
|
|
188
|
-
"id_field": {
|
|
189
|
-
name: "immich" + name.removeprefix("Immich") + "Id"
|
|
190
|
-
for name in mappings
|
|
191
|
-
if name != "ImmichAlbumMembership"
|
|
192
|
-
},
|
|
193
|
-
"title_field": {
|
|
194
|
-
"ImmichAlbum": "immichAlbumAlbumName",
|
|
195
|
-
"ImmichPersonRecord": "immichPersonRecordName",
|
|
196
|
-
"ImmichUser": "immichUserName",
|
|
197
|
-
"ImmichLibrary": "immichLibraryName",
|
|
198
|
-
"ImmichTag": "immichTagName",
|
|
199
|
-
},
|
|
200
|
-
"updated_field": {
|
|
201
|
-
"ImmichAlbum": "immichAlbumUpdatedAt",
|
|
202
|
-
"ImmichAsset": "immichAssetUpdatedAt",
|
|
203
|
-
},
|
|
204
|
-
},
|
|
205
|
-
"schema_mappings": mappings,
|
|
206
|
-
"policy": {
|
|
207
|
-
"pii_fields": {
|
|
208
|
-
"ImmichAlbum": ["immichAlbumAlbumName"],
|
|
209
|
-
"ImmichPersonRecord": ["immichPersonRecordName"],
|
|
210
|
-
"ImmichUser": ["immichUserName"],
|
|
211
|
-
"ImmichTag": ["immichTagName"],
|
|
212
|
-
}
|
|
213
|
-
},
|
|
214
|
-
"provenance": {
|
|
215
|
-
"generated_by": "scripts/generate_immich_content.py",
|
|
216
|
-
"source_artifacts": [
|
|
217
|
-
"openapi_contract.json",
|
|
218
|
-
"ontology/schema-provenance.json",
|
|
219
|
-
"ontology/immich.ttl",
|
|
220
|
-
"ontology/shapes/immich.ttl",
|
|
221
|
-
],
|
|
222
|
-
"integrity": {
|
|
223
|
-
"algorithm": "sha256",
|
|
224
|
-
"hash": hashlib.sha256(ontology_text.encode()).hexdigest(),
|
|
225
|
-
},
|
|
226
|
-
},
|
|
227
|
-
"review_todos": [
|
|
228
|
-
"Structural schema declarations are not evidence of live EG capture or semantic identity alignment.",
|
|
229
|
-
"Only the bounded album metadata projection is implemented for ingestion; remaining DTO classes are structural declarations.",
|
|
230
|
-
"Require explicit source/account binding, existing scoped credentials and a verified EG receipt/readback before enabling ingestion.",
|
|
231
|
-
"Ontology integrity is a byte SHA256, not canonical RDF or release certification.",
|
|
232
|
-
],
|
|
233
|
-
}
|
|
234
|
-
)
|
|
235
183
|
evidence = {
|
|
236
184
|
"status": "schema-derived; live ingestion unverified",
|
|
237
185
|
"source_version": "3.2.2",
|
|
@@ -263,7 +211,6 @@ def artifacts():
|
|
|
263
211
|
evidence, indent=2, sort_keys=True
|
|
264
212
|
)
|
|
265
213
|
+ "\n",
|
|
266
|
-
PACKAGE / "connector_manifest.yml": json.dumps(manifest, indent=2) + "\n",
|
|
267
214
|
}
|
|
268
215
|
|
|
269
216
|
|
|
@@ -10,6 +10,7 @@ Follow the [shared spec standard](https://github.com/Knuckles-Team/pipelines/blo
|
|
|
10
10
|
| `IMMICH` | This repository's concept registry |
|
|
11
11
|
|
|
12
12
|
- [`CONN-IMMICH-API`](immich-api/spec.md) — Integrate Immich Api through the shared connector contracts.
|
|
13
|
+
- [`CONN-IMMICH-API-CONNECTOR-CONTENT`](connector-content/spec.md) — The connector serves its packaged content.
|
|
13
14
|
|
|
14
15
|
The lifecycle generator owns delivery receipts in `status.json`.
|
|
15
16
|
Run `pipelines-hook spec-status --write` after reviewed source changes enter Git history.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# CONN-IMMICH-API-CONNECTOR-CONTENT — Design and implementation plan
|
|
2
|
+
|
|
3
|
+
Governing spec: [spec.md](spec.md).
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
`pyproject.toml` declares `immich` as the connector identity. `create_mcp_server` resolves the packaged content of `immich_api` from it.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# CONN-IMMICH-API-CONNECTOR-CONTENT — Requirements
|
|
2
|
+
|
|
3
|
+
Governing spec: [spec.md](spec.md).
|
|
4
|
+
|
|
5
|
+
Each row is one requirement. A row names the file it touches and the test that proves it. The generator sets each row's state in `status.json`.
|
|
6
|
+
|
|
7
|
+
| ID | Requirement | Acceptance |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `CONN-IMMICH-API-CONNECTOR-CONTENT-R001` | **Default content.** `pyproject.toml` declares `immich` as the single `agent_connector_sdk.connector` entry point. The server lists the packaged `skill://` and `ontology://` resources and the packaged prompts with no `content=` argument. Proving test: `tests/test_default_content_surfaces.py`. | `resources/list` includes `skill://` and `ontology://`; `prompts/list` includes each packaged prompt. |
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# CONN-IMMICH-API-CONNECTOR-CONTENT — The connector serves its packaged content
|
|
2
|
+
|
|
3
|
+
Owner: immich-api. Cross-repo IDs: `SDK-CONNECTOR-CONTROL-R071`, `SDK-CONNECTOR-CONTROL-R073`.
|
|
4
|
+
|
|
5
|
+
## Purpose and user stories
|
|
6
|
+
|
|
7
|
+
The `immich` server serves its packaged skills, prompts and ontology to any client, with no wiring of its own.
|
|
8
|
+
|
|
9
|
+
## Requirements and acceptance
|
|
10
|
+
|
|
11
|
+
See [requirements.md](requirements.md).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 2,
|
|
3
|
+
"spec_id": "CONN-IMMICH-API-CONNECTOR-CONTENT",
|
|
4
|
+
"owner_repo": "immich-api",
|
|
5
|
+
"delivery_state": "VERIFIED",
|
|
6
|
+
"requirement_ids": [
|
|
7
|
+
"CONN-IMMICH-API-CONNECTOR-CONTENT-R001"
|
|
8
|
+
],
|
|
9
|
+
"requirements": [
|
|
10
|
+
{
|
|
11
|
+
"id": "CONN-IMMICH-API-CONNECTOR-CONTENT-R001",
|
|
12
|
+
"title": "Default content",
|
|
13
|
+
"delivery_state": "VERIFIED",
|
|
14
|
+
"landed_in": [
|
|
15
|
+
"9c7f32a3d826"
|
|
16
|
+
],
|
|
17
|
+
"verified_by": [
|
|
18
|
+
"tests/test_default_content_surfaces.py:15"
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# CONN-IMMICH-API-CONNECTOR-CONTENT — Implementation tasks
|
|
2
|
+
|
|
3
|
+
Governing spec: [spec.md](spec.md). Design: [plan.md](plan.md). Rows: [requirements.md](requirements.md).
|
|
4
|
+
|
|
5
|
+
- [x] **CONN-IMMICH-API-CONNECTOR-CONTENT-R001:** Declare the fleet identity and serve the packaged content by default.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# CONN-IMMICH-API-CONNECTOR-CONTENT — Test specification
|
|
2
|
+
|
|
3
|
+
Governing spec: [spec.md](spec.md).
|
|
4
|
+
|
|
5
|
+
| Test ID | Requirement | Proving test | Expected observation |
|
|
6
|
+
|---|---|---|---|
|
|
7
|
+
| T-001 | `CONN-IMMICH-API-CONNECTOR-CONTENT-R001` | `tests/test_default_content_surfaces.py` | The listings include the packaged skills, ontology and prompts. |
|
|
@@ -61,7 +61,6 @@ async def native_initial_discovery(client):
|
|
|
61
61
|
|
|
62
62
|
async def native_discovery(client, name):
|
|
63
63
|
"""Verify one complete tool so discovery has its own bounded test budget."""
|
|
64
|
-
await asyncio.sleep(0.12)
|
|
65
64
|
result = await client.call_tool(
|
|
66
65
|
"search_tools", {"pattern": "^" + re.escape(name) + r"(?:\s|$)"}
|
|
67
66
|
)
|
|
@@ -113,11 +112,12 @@ class DiscoveredClient:
|
|
|
113
112
|
|
|
114
113
|
|
|
115
114
|
@asynccontextmanager
|
|
116
|
-
async def isolated_native_client(server, elicitation_handler):
|
|
115
|
+
async def isolated_native_client(server, elicitation_handler, pace=0.22):
|
|
117
116
|
"""Drain outstanding calls and close the protocol before the next provider."""
|
|
118
117
|
# Each fresh client adds server/discover and result-validation tools/list.
|
|
119
118
|
# Reserve those two requests at the unchanged SDK limit of 10 requests/s.
|
|
120
|
-
|
|
119
|
+
if pace:
|
|
120
|
+
await asyncio.sleep(pace)
|
|
121
121
|
async with Client(
|
|
122
122
|
server, elicitation_handler=elicitation_handler, timeout=10
|
|
123
123
|
) as native:
|