openframe-core 3.6.0__tar.gz → 3.7.0__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.
- {openframe_core-3.6.0 → openframe_core-3.7.0}/.github/CHANGELOG.md +128 -1
- {openframe_core-3.6.0 → openframe_core-3.7.0}/PKG-INFO +1 -1
- openframe_core-3.7.0/openframe/core/remote/__init__.py +23 -0
- openframe_core-3.7.0/openframe/core/remote/client.py +135 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/__init__.py +6 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/contracts/__init__.py +6 -0
- openframe_core-3.7.0/openframe/core/testing/contracts/remote.py +79 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/pyproject.toml +1 -1
- {openframe_core-3.6.0 → openframe_core-3.7.0}/.github/requirements/docs.txt +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/.github/requirements/test.txt +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/.github/workflows/app-test.yml +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/.github/workflows/auto-docs.yml +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/.github/workflows/python-build.yml +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/.gitignore +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/.vscode/settings.json +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/LICENSE +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/README.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/assets/images/banner.png +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/assets/images/favicon.png +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/assets/images/logo-dark.png +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/assets/images/logo-light.png +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/assets/javascripts/extra.js +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/assets/stylesheets/extra.css +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/code/cicd/pipeline.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/code/getting-started/index.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/code/modules/config.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/code/modules/exceptions.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/code/modules/health.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/code/modules/inbound.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/code/modules/index.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/code/modules/middleware.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/code/modules/plugins.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/code/modules/ports.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/code/modules/runtime.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/code/modules/telemetry.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/code/modules/testing.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/code/modules/tracing.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/developer-guide/debugging.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/developer-guide/explore.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/developer-guide/first-change.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/developer-guide/how-it-works.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/developer-guide/local-dev.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/developer-guide/quick-start/index.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/index.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/adrs/adr-001-namespace.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/adrs/adr-002-hexagonal.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/adrs/adr-003-async.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/adrs/adr-004-pydantic.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/adrs/adr-005-middleware.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/adrs/adr-006-unified-port-lifecycle.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/adrs/adr-007-schema-contracts.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/adrs/index.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/capability-taxonomy.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/component-lifecycle.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/data-flows.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/design-decisions.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/error-taxonomy.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/package-journey/adapter-lifecycle.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/package-journey/error-propagation.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/package-journey/index.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/package-journey/template-wiring.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/package-journey/tracing-flow.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/system-architecture.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/deployment/cicd.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/deployment/environments.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/deployment/secrets-and-config.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/infrastructure/networking.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/infrastructure/platform.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/infrastructure/storage.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/operations/index.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/operations/monitoring.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/operations/runbooks/adapter-connection-failure.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/operations/runbooks/modal-cold-start-spike.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/operations/runbooks/postgres-pool-exhausted.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/operations/runbooks/queue-consumer-stuck.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/operations/runbooks/redis-connection-lost.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/operations/runbooks/telemetry-export-failing.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/overview/glossary.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/overview/roadmap.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/overview/system-overview.md +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/mkdocs.yml +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/__init__.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/__init__.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/config/__init__.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/config/settings.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/exceptions/__init__.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/exceptions/adapter.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/exceptions/base.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/exceptions/codes.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/exceptions/plugin.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/inbound/__init__.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/inbound/command.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/inbound/context.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/inbound/query.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/inbound/usecase.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/middleware/__init__.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/middleware/telemetry.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/middleware/types.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/plugins/__init__.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/plugins/registry.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/ports/__init__.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/ports/capability.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/ports/context.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/ports/health.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/ports/identity.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/ports/lifecycle.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/ports/outbound/__init__.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/ports/outbound/consumer.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/ports/outbound/producer.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/ports/outbound/repository.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/ports/port.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/resilience/__init__.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/resilience/circuit_breaker.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/runtime/__init__.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/runtime/bootstrap.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/schemas/__init__.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/telemetry/__init__.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/telemetry/setup.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/contracts/consumer.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/contracts/graph_store.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/contracts/inbound.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/contracts/lifecycle.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/contracts/port.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/contracts/producer.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/contracts/repository.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/contracts/vector_store.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/fakes/__init__.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/fakes/consumer.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/fakes/graph_store.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/fakes/inbound.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/fakes/producer.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/fakes/repository.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/fakes/vector_store.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/fixtures.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/tracing/__init__.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/tracing/propagation.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/tracing/proxy.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/py.typed +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/conftest.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_config.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_exceptions.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_inbound.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_inbound_contracts.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_middleware.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_middleware_types.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_plugins.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_ports.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_ports_primitives.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_record_error.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_resilience.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_runtime.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_schemas.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_shutdown_telemetry.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_telemetry_sidecar.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_testing_fakes.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_tracing.py +0 -0
- {openframe_core-3.6.0 → openframe_core-3.7.0}/tests/test_tracing_propagation.py +0 -0
|
@@ -11,6 +11,130 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
+
## v3.7.0 — 2026-10-11
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **`openframe.core.remote`** — `RemoteCommandClient[TIn]`/
|
|
19
|
+
`RemoteQueryClient[TIn, TOut]`, the outbound counterparts of
|
|
20
|
+
`openframe.core.inbound`'s `CommandHandler`/`QueryHandler`, for
|
|
21
|
+
`openframe-protocol`'s M1b (HTTP client, service-to-service calls).
|
|
22
|
+
Structurally identical `execute(input, context) -> result` shape to
|
|
23
|
+
the inbound pair, but deliberately separate Protocol classes in their
|
|
24
|
+
own module — direction matters even when the signature doesn't
|
|
25
|
+
differ, and conflating "something calls into me" with "I call out to
|
|
26
|
+
something" under one name would erase the distinction this
|
|
27
|
+
ecosystem's whole organising principle rests on. No `BasePort`/
|
|
28
|
+
`Identity`/`Capability` involvement: `openframe-protocol`'s own design
|
|
29
|
+
review (draft 8, decision D10) found no dynamic "give me whichever
|
|
30
|
+
remote client fills this role" lookup use case exists — a caller
|
|
31
|
+
always knows exactly which service it's calling — so none of the
|
|
32
|
+
machinery justifying `Capability`-based registry lookup applies here.
|
|
33
|
+
Wired by direct construction in a service's own `bootstrap`, the same
|
|
34
|
+
way `CommandHandler`/`QueryHandler` themselves are never looked up by
|
|
35
|
+
capability.
|
|
36
|
+
- **`openframe.core.testing.RemoteCommandClientContractTests`/
|
|
37
|
+
`RemoteQueryClientContractTests`** — extend the existing
|
|
38
|
+
`CommandHandlerContractTests`/`QueryHandlerContractTests` rather than
|
|
39
|
+
duplicating their test bodies (only the `isinstance` assertion
|
|
40
|
+
differs). No new fakes needed either — `SpyCommandHandler`/
|
|
41
|
+
`SpyQueryHandler` already satisfy the new protocols structurally,
|
|
42
|
+
confirmed directly rather than assumed.
|
|
43
|
+
- 12 new tests. Full suite: 422 passing (up from 410).
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## v3.6.0 — 2026-10-09
|
|
48
|
+
|
|
49
|
+
### Added
|
|
50
|
+
|
|
51
|
+
- **`openframe.core.ports.BaseGraphStore[T]`** — a new outbound port for
|
|
52
|
+
graph-store adapters (FalkorDB and similar), defined in
|
|
53
|
+
`ports/outbound/repository.py` alongside `BaseRepository`/
|
|
54
|
+
`BaseVectorStore` — same rationale as `BaseVectorStore` for staying in
|
|
55
|
+
this file rather than its own. Extends `BaseRepository[T]` directly:
|
|
56
|
+
a graph database's nodes are genuinely id-addressable
|
|
57
|
+
(create/get/update/delete map onto real `CREATE`/`MATCH ... WHERE
|
|
58
|
+
n.<key> = $id`/`SET`/`DETACH DELETE` operations), provided the adapter
|
|
59
|
+
addresses nodes by an application-level unique property (with a
|
|
60
|
+
backing index/constraint the adapter itself must create) rather than
|
|
61
|
+
a backend-internal node identity. FalkorDB's own `id()` function is
|
|
62
|
+
explicitly documented upstream as unstable — deleted nodes' higher
|
|
63
|
+
internal ids can be migrated down to fill vacated lower ones — which
|
|
64
|
+
is exactly why adapters must key off their own property, not a reason
|
|
65
|
+
graph databases don't fit this port. The one operation with no CRUD
|
|
66
|
+
equivalent is pattern-matching/traversal, so `BaseGraphStore` adds
|
|
67
|
+
exactly one new method, `traverse(query, params) -> list[T]`, which
|
|
68
|
+
also serves as the only way to create or query relationships/edges —
|
|
69
|
+
this port deliberately does not give edges their own method, the same
|
|
70
|
+
way it does not invent a bespoke query language. Marked
|
|
71
|
+
`.. stability: experimental`, same as `BaseVectorStore`;
|
|
72
|
+
`BaseRepository` itself is unaffected and remains stable.
|
|
73
|
+
- **`openframe.core.testing.GraphStoreContractTests`** — extends
|
|
74
|
+
`RepositoryContractTests` (inherits the full CRUD suite), adds four
|
|
75
|
+
`traverse()`-specific tests plus a `BaseGraphStore` protocol
|
|
76
|
+
conformance check. Deliberately query-language-agnostic: rather than
|
|
77
|
+
hardcoding Cypher syntax, it asks a `traverse_query_for(entity)`
|
|
78
|
+
fixture for a `(query, params)` pair in whatever language the adapter
|
|
79
|
+
under test actually speaks — mirroring how `VectorStoreContractTests`
|
|
80
|
+
asks for an `entity_vector` extractor instead of assuming a specific
|
|
81
|
+
similarity metric.
|
|
82
|
+
- **`openframe.core.testing.InMemoryGraphStore`** — the matching fake,
|
|
83
|
+
extending `InMemoryRepository`. Its own `traverse()` is a toy lookup
|
|
84
|
+
(recognizes a `params["id"]` convention; the `query` string itself is
|
|
85
|
+
accepted but not interpreted) proving the contract's *shape*, not a
|
|
86
|
+
query-engine simulation.
|
|
87
|
+
- 27 new tests (23 inherited `RepositoryContractTests`/`PortContractTests`
|
|
88
|
+
assertions re-run against `InMemoryGraphStore`, plus 4
|
|
89
|
+
`traverse()`-specific tests). Full suite: 410 passing (up from 383).
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## v3.5.0 — 2026-10-08
|
|
94
|
+
|
|
95
|
+
### Added
|
|
96
|
+
|
|
97
|
+
- **`openframe.core.ports.BaseVectorStore[T]`** — a new outbound port for
|
|
98
|
+
vector-store adapters (Milvus, Qdrant, ChromaDB), defined in
|
|
99
|
+
`ports/outbound/repository.py` alongside `BaseRepository` (not its own
|
|
100
|
+
file — deliberately, so the "why this extends `BaseRepository`"
|
|
101
|
+
rationale lives next to both classes it concerns). Extends
|
|
102
|
+
`BaseRepository[T]` directly rather than sitting as a disjoint sibling
|
|
103
|
+
port — most vector databases are genuinely id-addressable
|
|
104
|
+
(insert/upsert-with-id, fetch-by-id, delete-by-id, list/scroll), so the
|
|
105
|
+
five inherited CRUD methods are real operations for them, not fakes
|
|
106
|
+
forced to satisfy an interface. Adds exactly one new method,
|
|
107
|
+
`search(query_vector, k) -> list[T]`, the one operation with no
|
|
108
|
+
equivalent in `BaseRepository`. A vector store satisfying
|
|
109
|
+
`BaseVectorStore` also satisfies `BaseRepository` for free. Explicitly
|
|
110
|
+
does **not** target FAISS (a bare in-process index with no native
|
|
111
|
+
id→metadata store, and some index types that don't support deletion
|
|
112
|
+
without a full rebuild) or FalkorDB (fundamentally graph-oriented, not
|
|
113
|
+
id-addressable the same way) — both were evaluated and excluded;
|
|
114
|
+
graph databases need their own separate port design, not a forced fit
|
|
115
|
+
here.
|
|
116
|
+
- **`openframe.core.testing.contracts.VectorStoreContractTests`** — the
|
|
117
|
+
matching contract-test mixin, extending `RepositoryContractTests`
|
|
118
|
+
(inherits all its CRUD assertions, adds four search-specific ones).
|
|
119
|
+
Deliberately metric-agnostic: every search assertion uses an
|
|
120
|
+
exact-match query vector rather than asserting a specific similarity
|
|
121
|
+
score or ranking among near-ties, since backends default to different
|
|
122
|
+
metrics (cosine, L2, dot product) that would legitimately rank
|
|
123
|
+
approximately-similar vectors differently — an exact match ranks
|
|
124
|
+
first under any reasonable metric, so that's what the contract tests
|
|
125
|
+
rely on.
|
|
126
|
+
- **`openframe.core.testing.fakes.InMemoryVectorStore`** — the matching
|
|
127
|
+
fake, extending `InMemoryRepository` unchanged and adding a
|
|
128
|
+
brute-force Euclidean-distance `search()`. Proven against the full
|
|
129
|
+
`VectorStoreContractTests` suite in this release's own test suite
|
|
130
|
+
(27 new tests: 23 inherited CRUD/identity/lifecycle + 4 search-specific).
|
|
131
|
+
- All three pieces are `experimental` — new port, new contract-test
|
|
132
|
+
mixin, new fake, all added together ahead of the first real adapter
|
|
133
|
+
packages that will implement `BaseVectorStore` (Milvus, Qdrant,
|
|
134
|
+
ChromaDB).
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
14
138
|
## v3.4.0 — 2026-09-28
|
|
15
139
|
|
|
16
140
|
### Added
|
|
@@ -425,7 +549,10 @@ Dev dependencies: `pytest>=8.0`, `pytest-asyncio>=0.23`, `httpx>=0.27`.
|
|
|
425
549
|
|
|
426
550
|
---
|
|
427
551
|
|
|
428
|
-
[Unreleased]: https://github.com/openframe-org/openframe-core/compare/v3.
|
|
552
|
+
[Unreleased]: https://github.com/openframe-org/openframe-core/compare/v3.7.0...HEAD
|
|
553
|
+
[3.7.0]: https://github.com/openframe-org/openframe-core/compare/v3.6.0...v3.7.0
|
|
554
|
+
[3.6.0]: https://github.com/openframe-org/openframe-core/compare/v3.5.0...v3.6.0
|
|
555
|
+
[3.5.0]: https://github.com/openframe-org/openframe-core/compare/v3.4.0...v3.5.0
|
|
429
556
|
[3.4.0]: https://github.com/openframe-org/openframe-core/compare/v3.3.0...v3.4.0
|
|
430
557
|
[3.3.0]: https://github.com/openframe-org/openframe-core/compare/v3.2.1...v3.3.0
|
|
431
558
|
[3.2.1]: https://github.com/openframe-org/openframe-core/compare/v3.2.0...v3.2.1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: openframe-core
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.7.0
|
|
4
4
|
Summary: OpenFrame Microservice Suite - platform kernel. Port contracts, testing utilities, plugin registry, and composition root.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Furious-Meteors/openframe-core
|
|
6
6
|
Project-URL: Documentation, https://furious-meteors.github.io/openframe-core/
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
openframe.core.remote
|
|
3
|
+
========================
|
|
4
|
+
Outbound counterparts of openframe.core.inbound's CommandHandler/
|
|
5
|
+
QueryHandler — contracts for a service calling *another service built on
|
|
6
|
+
this platform*, as opposed to `openframe.core.ports.outbound` (third-party
|
|
7
|
+
backend adapters, Capability-tagged) or `openframe.core.inbound`
|
|
8
|
+
(callers reaching into this service).
|
|
9
|
+
|
|
10
|
+
Added for openframe-protocol's M1b (HTTP client) — see that repo's design
|
|
11
|
+
spec draft 8, section 5.6, decision D10. No BasePort/Capability
|
|
12
|
+
involvement; see `client.py`'s own docstring for why.
|
|
13
|
+
|
|
14
|
+
.. stability: experimental
|
|
15
|
+
New alongside the first concrete implementation
|
|
16
|
+
(`openframe-protocol-http`'s `HttpRemoteQueryClient`/
|
|
17
|
+
`HttpRemoteCommandClient`). API may change based on real usage.
|
|
18
|
+
"""
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
from openframe.core.remote.client import RemoteCommandClient, RemoteQueryClient
|
|
22
|
+
|
|
23
|
+
__all__ = ["RemoteCommandClient", "RemoteQueryClient"]
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"""
|
|
2
|
+
openframe/core/remote/client.py
|
|
3
|
+
==================================
|
|
4
|
+
RemoteCommandClient, RemoteQueryClient — the outbound counterparts of
|
|
5
|
+
openframe.core.inbound's CommandHandler/QueryHandler (openframe-protocol
|
|
6
|
+
draft 8, section 5.6; D10).
|
|
7
|
+
|
|
8
|
+
Structurally identical to CommandHandler/QueryHandler — same
|
|
9
|
+
`execute(input, context) -> result` shape — but deliberately a separate
|
|
10
|
+
pair of Protocol classes in their own module, not aliases. Two reasons:
|
|
11
|
+
|
|
12
|
+
1. Direction matters even when the signature doesn't differ. This
|
|
13
|
+
ecosystem's entire organising principle (see openframe-protocol's own
|
|
14
|
+
design history) is driving side vs. driven side, and conflating a
|
|
15
|
+
"something calls into me" contract with a "I call out to something"
|
|
16
|
+
contract under one name would erase exactly the distinction that
|
|
17
|
+
took real design work to land on.
|
|
18
|
+
2. `isinstance(x, RemoteQueryClient)` should read as "this is a remote
|
|
19
|
+
call" at the call site, not "this happens to satisfy CommandHandler's
|
|
20
|
+
shape." Structural typing doesn't require the names to differ, but
|
|
21
|
+
the names carry real information a reader relies on.
|
|
22
|
+
|
|
23
|
+
No BasePort/Identity/Capability involvement, by design — see draft 8
|
|
24
|
+
section 4's D10 resolution: there is no dynamic "give me whichever
|
|
25
|
+
remote client fills this role" lookup use case (a caller always knows
|
|
26
|
+
exactly which service it's calling), so none of the machinery that
|
|
27
|
+
justifies Capability-based registry lookup applies here. These are
|
|
28
|
+
wired by direct construction in `bootstrap`, the same way `CommandHandler`/
|
|
29
|
+
`QueryHandler` themselves are never looked up by Capability.
|
|
30
|
+
|
|
31
|
+
Dependency order:
|
|
32
|
+
inbound/context → ports/context
|
|
33
|
+
remote/client → inbound/context (reuses the same RequestContext —
|
|
34
|
+
one request's identity threads through both
|
|
35
|
+
directions of a call it triggers, matching how
|
|
36
|
+
RequestContext is already shared by inbound).
|
|
37
|
+
"""
|
|
38
|
+
from __future__ import annotations
|
|
39
|
+
|
|
40
|
+
from typing import Protocol, TypeVar, runtime_checkable
|
|
41
|
+
|
|
42
|
+
from openframe.core.inbound.context import RequestContext
|
|
43
|
+
|
|
44
|
+
__all__ = ["RemoteCommandClient", "RemoteQueryClient"]
|
|
45
|
+
|
|
46
|
+
TInput = TypeVar("TInput")
|
|
47
|
+
TOutput = TypeVar("TOutput")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@runtime_checkable
|
|
51
|
+
class RemoteCommandClient(Protocol[TInput]):
|
|
52
|
+
"""
|
|
53
|
+
Outbound write-side contract — calls another service to mutate its
|
|
54
|
+
state. The write-side counterpart of
|
|
55
|
+
:class:`~openframe.core.inbound.command.CommandHandler`, for the
|
|
56
|
+
opposite direction.
|
|
57
|
+
|
|
58
|
+
Adapters/clients satisfy this protocol structurally — no inheritance
|
|
59
|
+
needed.
|
|
60
|
+
|
|
61
|
+
Type parameter:
|
|
62
|
+
TInput: The command type this client sends.
|
|
63
|
+
|
|
64
|
+
Runtime check::
|
|
65
|
+
|
|
66
|
+
isinstance(client, RemoteCommandClient) # ✓ works
|
|
67
|
+
isinstance(client, RemoteCommandClient[str]) # ✗ raises TypeError
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
async def execute(
|
|
71
|
+
self,
|
|
72
|
+
command: TInput,
|
|
73
|
+
context: RequestContext | None = None,
|
|
74
|
+
) -> None:
|
|
75
|
+
"""
|
|
76
|
+
Send the command to the remote service.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
command: The command to send.
|
|
80
|
+
context: Optional request context — a real implementation
|
|
81
|
+
propagates `context.correlation_id` onward (e.g. as
|
|
82
|
+
an outgoing `traceparent`), threading one logical
|
|
83
|
+
request's identity through every service it touches.
|
|
84
|
+
|
|
85
|
+
Raises:
|
|
86
|
+
An `AdapterError` subclass on failure — a remote call is, from
|
|
87
|
+
the caller's perspective, exactly as fallible as a database
|
|
88
|
+
call, and should surface through the same exception family
|
|
89
|
+
so callers don't need a separate catch clause for "this
|
|
90
|
+
dependency happens to be another service" versus "this
|
|
91
|
+
dependency happens to be a database."
|
|
92
|
+
"""
|
|
93
|
+
...
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@runtime_checkable
|
|
97
|
+
class RemoteQueryClient(Protocol[TInput, TOutput]):
|
|
98
|
+
"""
|
|
99
|
+
Outbound read-side contract — calls another service and returns its
|
|
100
|
+
result. The read-side counterpart of
|
|
101
|
+
:class:`~openframe.core.inbound.query.QueryHandler`, for the
|
|
102
|
+
opposite direction.
|
|
103
|
+
|
|
104
|
+
Type parameters:
|
|
105
|
+
TInput: The query type this client sends.
|
|
106
|
+
TOutput: The result type this client returns.
|
|
107
|
+
|
|
108
|
+
Runtime check::
|
|
109
|
+
|
|
110
|
+
isinstance(client, RemoteQueryClient) # ✓ works
|
|
111
|
+
isinstance(client, RemoteQueryClient[str, int]) # ✗ raises TypeError
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
async def execute(
|
|
115
|
+
self,
|
|
116
|
+
query: TInput,
|
|
117
|
+
context: RequestContext | None = None,
|
|
118
|
+
) -> TOutput:
|
|
119
|
+
"""
|
|
120
|
+
Send the query to the remote service and return its result.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
query: The query to send.
|
|
124
|
+
context: Optional request context, propagated onward — see
|
|
125
|
+
`RemoteCommandClient.execute`'s own docstring.
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
The remote service's result.
|
|
129
|
+
|
|
130
|
+
Raises:
|
|
131
|
+
An `AdapterError` subclass on failure — see
|
|
132
|
+
`RemoteCommandClient.execute`'s own docstring for why this
|
|
133
|
+
family, not a bespoke one.
|
|
134
|
+
"""
|
|
135
|
+
...
|
|
@@ -42,6 +42,10 @@ from openframe.core.testing.contracts.inbound import (
|
|
|
42
42
|
from openframe.core.testing.contracts.lifecycle import LifecycleContractTests
|
|
43
43
|
from openframe.core.testing.contracts.port import PortContractTests
|
|
44
44
|
from openframe.core.testing.contracts.producer import ProducerContractTests
|
|
45
|
+
from openframe.core.testing.contracts.remote import (
|
|
46
|
+
RemoteCommandClientContractTests,
|
|
47
|
+
RemoteQueryClientContractTests,
|
|
48
|
+
)
|
|
45
49
|
from openframe.core.testing.contracts.repository import RepositoryContractTests
|
|
46
50
|
from openframe.core.testing.contracts.vector_store import VectorStoreContractTests
|
|
47
51
|
from openframe.core.testing.fakes.consumer import FakeConsumer
|
|
@@ -74,4 +78,6 @@ __all__ = [
|
|
|
74
78
|
"UseCaseContractTests",
|
|
75
79
|
"CommandHandlerContractTests",
|
|
76
80
|
"QueryHandlerContractTests",
|
|
81
|
+
"RemoteCommandClientContractTests",
|
|
82
|
+
"RemoteQueryClientContractTests",
|
|
77
83
|
]
|
|
@@ -37,6 +37,10 @@ from openframe.core.testing.contracts.inbound import (
|
|
|
37
37
|
from openframe.core.testing.contracts.lifecycle import LifecycleContractTests
|
|
38
38
|
from openframe.core.testing.contracts.port import PortContractTests
|
|
39
39
|
from openframe.core.testing.contracts.producer import ProducerContractTests
|
|
40
|
+
from openframe.core.testing.contracts.remote import (
|
|
41
|
+
RemoteCommandClientContractTests,
|
|
42
|
+
RemoteQueryClientContractTests,
|
|
43
|
+
)
|
|
40
44
|
from openframe.core.testing.contracts.repository import RepositoryContractTests
|
|
41
45
|
from openframe.core.testing.contracts.vector_store import VectorStoreContractTests
|
|
42
46
|
|
|
@@ -51,4 +55,6 @@ __all__ = [
|
|
|
51
55
|
"UseCaseContractTests",
|
|
52
56
|
"CommandHandlerContractTests",
|
|
53
57
|
"QueryHandlerContractTests",
|
|
58
|
+
"RemoteCommandClientContractTests",
|
|
59
|
+
"RemoteQueryClientContractTests",
|
|
54
60
|
]
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""
|
|
2
|
+
openframe/core/testing/contracts/remote.py
|
|
3
|
+
=============================================
|
|
4
|
+
RemoteCommandClientContractTests, RemoteQueryClientContractTests —
|
|
5
|
+
reusable pytest base classes for `openframe.core.remote`'s outbound
|
|
6
|
+
contracts.
|
|
7
|
+
|
|
8
|
+
Extends `CommandHandlerContractTests`/`QueryHandlerContractTests` rather
|
|
9
|
+
than duplicating their test bodies — `RemoteCommandClient`/
|
|
10
|
+
`RemoteQueryClient` have the identical `execute()` shape (see
|
|
11
|
+
`remote/client.py`'s own docstring for why they're still separate
|
|
12
|
+
Protocol classes despite that). Only the protocol-conformance assertion
|
|
13
|
+
differs; every other test (return-type shape, context handling) is
|
|
14
|
+
inherited unchanged.
|
|
15
|
+
|
|
16
|
+
No top-level pytest import — importable without pytest installed,
|
|
17
|
+
matching every other contract module's own convention.
|
|
18
|
+
|
|
19
|
+
Dependency order:
|
|
20
|
+
testing/contracts/remote → testing/contracts/inbound, remote
|
|
21
|
+
|
|
22
|
+
Subclass usage::
|
|
23
|
+
|
|
24
|
+
class TestMyRemoteQueryClient(RemoteQueryClientContractTests):
|
|
25
|
+
@pytest.fixture
|
|
26
|
+
def query_handler(self) -> MyRemoteQueryClient:
|
|
27
|
+
return MyRemoteQueryClient()
|
|
28
|
+
"""
|
|
29
|
+
from __future__ import annotations
|
|
30
|
+
|
|
31
|
+
from openframe.core.testing.contracts.inbound import (
|
|
32
|
+
CommandHandlerContractTests,
|
|
33
|
+
QueryHandlerContractTests,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
__all__ = ["RemoteCommandClientContractTests", "RemoteQueryClientContractTests"]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class RemoteCommandClientContractTests(CommandHandlerContractTests):
|
|
40
|
+
"""
|
|
41
|
+
Reusable pytest base class for
|
|
42
|
+
:class:`~openframe.core.remote.RemoteCommandClient` contract tests.
|
|
43
|
+
|
|
44
|
+
Subclasses must provide the same `command_handler` fixture
|
|
45
|
+
`CommandHandlerContractTests` itself requires — the fixture name is
|
|
46
|
+
unchanged, only the protocol being checked is.
|
|
47
|
+
|
|
48
|
+
.. stability: experimental
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
async def test_satisfies_command_handler_protocol(self, command_handler) -> None:
|
|
52
|
+
"""Overridden: checks RemoteCommandClient, not CommandHandler."""
|
|
53
|
+
from openframe.core.remote import RemoteCommandClient
|
|
54
|
+
|
|
55
|
+
assert isinstance(command_handler, RemoteCommandClient), (
|
|
56
|
+
f"{type(command_handler).__name__} does not satisfy RemoteCommandClient. "
|
|
57
|
+
"Ensure it has a matching async 'execute' method."
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class RemoteQueryClientContractTests(QueryHandlerContractTests):
|
|
62
|
+
"""
|
|
63
|
+
Reusable pytest base class for
|
|
64
|
+
:class:`~openframe.core.remote.RemoteQueryClient` contract tests.
|
|
65
|
+
|
|
66
|
+
Subclasses must provide the same `query_handler`/`make_query`
|
|
67
|
+
fixtures `QueryHandlerContractTests` itself requires.
|
|
68
|
+
|
|
69
|
+
.. stability: experimental
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
async def test_satisfies_query_handler_protocol(self, query_handler) -> None:
|
|
73
|
+
"""Overridden: checks RemoteQueryClient, not QueryHandler."""
|
|
74
|
+
from openframe.core.remote import RemoteQueryClient
|
|
75
|
+
|
|
76
|
+
assert isinstance(query_handler, RemoteQueryClient), (
|
|
77
|
+
f"{type(query_handler).__name__} does not satisfy RemoteQueryClient. "
|
|
78
|
+
"Ensure it has a matching async 'execute' method."
|
|
79
|
+
)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "openframe-core"
|
|
7
|
-
version = "3.
|
|
7
|
+
version = "3.7.0"
|
|
8
8
|
description = "OpenFrame Microservice Suite - platform kernel. Port contracts, testing utilities, plugin registry, and composition root."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/adrs/adr-001-namespace.md
RENAMED
|
File without changes
|
{openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/adrs/adr-002-hexagonal.md
RENAMED
|
File without changes
|
{openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/adrs/adr-003-async.md
RENAMED
|
File without changes
|
{openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/adrs/adr-004-pydantic.md
RENAMED
|
File without changes
|
{openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/adrs/adr-005-middleware.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/capability-taxonomy.md
RENAMED
|
File without changes
|
{openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/component-lifecycle.md
RENAMED
|
File without changes
|
|
File without changes
|
{openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/design-decisions.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/package-journey/index.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/architecture/system-architecture.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openframe_core-3.6.0 → openframe_core-3.7.0}/docs/technical/deployment/secrets-and-config.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/contracts/graph_store.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/contracts/repository.py
RENAMED
|
File without changes
|
{openframe_core-3.6.0 → openframe_core-3.7.0}/openframe/core/testing/contracts/vector_store.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|