Skip to content

Add entities namespace and activate memory pipeline hooks#4

Merged
ethanj merged 1 commit into
mainfrom
sync/python-3d31807
Jun 11, 2026
Merged

Add entities namespace and activate memory pipeline hooks#4
ethanj merged 1 commit into
mainfrom
sync/python-3d31807

Conversation

@ethanj

@ethanj ethanj commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds the entities namespace (EntitiesClient / AsyncEntitiesClient) over /v1/entities, activates memory pipeline hooks that were previously accepted at registration but never invoked, and introduces two narrower error subclasses for TS SDK parity.

Changes

Entities namespace

  • Add atomicmemory/entities/ package: types.py (Pydantic wire models), client.py (sync), async_client.py (async), errors.py (EntitiesClientError).
  • Wire client.entities onto AtomicMemoryClient and AsyncAtomicMemoryClient using the same transport config, closed with the client.
  • Export all entity types and both client classes from the package root.
  • Operations: profile, list, get, delete, attributes, memory_history, patch_settings, merge.
  • Python field names match the snake_case wire 1:1 — no camelCase mapping layer.

Memory pipeline hooks

  • MemoryService and AsyncMemoryService now execute registered pipeline hooks: preprocess_ingest (may split one input into many; per-item results merge in order), postprocess_ingest, preprocess_search, postprocess_search, preprocess_get, postprocess_get, and postprocess_list.
  • delete and package take no pipeline hooks, matching TS semantics.
  • Add AsyncMemoryProcessingPipeline and NOOP_ASYNC_PIPELINE; export from atomicmemory.memory.
  • MemoryProcessingPipeline hook signatures are now synchronous; the async surface uses AsyncMemoryProcessingPipeline.

Error subclasses

  • Add UnsupportedOperationError (subclass of ProviderError) and InvalidScopeError (subclass of ValidationError); existing except ProviderError / except ValidationError handlers keep working.
  • Export both from the package root.

API key handling

  • api_key fields in AtomicMemoryClientConfig and EntitiesClientConfig changed to SecretStr to prevent accidental logging. The secret value is extracted only at the transport call site.

Client close semantics

  • AtomicMemoryClient.close() aligned with AsyncAtomicMemoryClient.close(): first-error-wins across all three namespaces; previously a later namespace's failure silently replaced an earlier one.

CI

  • Add .github/workflows/publish-pypi.yml: manual, version-gated OIDC Trusted Publishing workflow; guarded to run only on the public repository.

Why

  • The entities namespace is required for agent workflows that read entity profiles, inspect attribute triples, and merge duplicate entities — previously only accessible via raw HTTP.
  • Pipeline hooks have been part of the registration API since the initial release but had no effect; callers supplying hooks for content splitting or result logging received no errors and no execution.
  • UnsupportedOperationError and InvalidScopeError allow callers to catch specific failure modes without parsing error messages, matching the TS SDK's discriminated error hierarchy.
  • SecretStr ensures API keys are redacted in Pydantic repr and default logging paths without changing the external dict-based config interface.

Validation

  • tests/entities/ — 7 new test modules covering sync/async client round-trips, input validation, response validation, and type models (~1,280 lines).
  • tests/test_pipeline_hooks.py / tests/test_pipeline_hooks_async.py — hook invocation order, split-ingest merging, postprocess receives processed request (~460 lines).
  • tests/test_error_subclasses.py — subclass hierarchy, isinstance compatibility with parent handlers (~256 lines).
  • tests/test_api_key_redaction.pySecretStr repr, no plaintext key in error messages (~149 lines).
  • tests/_pipeline_fakes.py — shared fake pipeline/provider infrastructure extracted from client tests.

## Summary

Adds the `entities` namespace (`EntitiesClient` / `AsyncEntitiesClient`) over `/v1/entities`, activates memory pipeline hooks that were previously accepted at registration but never invoked, and introduces two narrower error subclasses for TS SDK parity.

## Changes

### Entities namespace
- Add `atomicmemory/entities/` package: `types.py` (Pydantic wire models), `client.py` (sync), `async_client.py` (async), `errors.py` (`EntitiesClientError`).
- Wire `client.entities` onto `AtomicMemoryClient` and `AsyncAtomicMemoryClient` using the same transport config, closed with the client.
- Export all entity types and both client classes from the package root.
- Operations: `profile`, `list`, `get`, `delete`, `attributes`, `memory_history`, `patch_settings`, `merge`.
- Python field names match the snake_case wire 1:1 — no camelCase mapping layer.

### Memory pipeline hooks
- `MemoryService` and `AsyncMemoryService` now execute registered pipeline hooks: `preprocess_ingest` (may split one input into many; per-item results merge in order), `postprocess_ingest`, `preprocess_search`, `postprocess_search`, `preprocess_get`, `postprocess_get`, and `postprocess_list`.
- `delete` and `package` take no pipeline hooks, matching TS semantics.
- Add `AsyncMemoryProcessingPipeline` and `NOOP_ASYNC_PIPELINE`; export from `atomicmemory.memory`.
- `MemoryProcessingPipeline` hook signatures are now synchronous; the async surface uses `AsyncMemoryProcessingPipeline`.

### Error subclasses
- Add `UnsupportedOperationError` (subclass of `ProviderError`) and `InvalidScopeError` (subclass of `ValidationError`); existing `except ProviderError` / `except ValidationError` handlers keep working.
- Export both from the package root.

### API key handling
- `api_key` fields in `AtomicMemoryClientConfig` and `EntitiesClientConfig` changed to `SecretStr` to prevent accidental logging. The secret value is extracted only at the transport call site.

### Client close semantics
- `AtomicMemoryClient.close()` aligned with `AsyncAtomicMemoryClient.close()`: first-error-wins across all three namespaces; previously a later namespace's failure silently replaced an earlier one.

### CI
- Add `.github/workflows/publish-pypi.yml`: manual, version-gated OIDC Trusted Publishing workflow; guarded to run only on the public repository.

## Why

- The `entities` namespace is required for agent workflows that read entity profiles, inspect attribute triples, and merge duplicate entities — previously only accessible via raw HTTP.
- Pipeline hooks have been part of the registration API since the initial release but had no effect; callers supplying hooks for content splitting or result logging received no errors and no execution.
- `UnsupportedOperationError` and `InvalidScopeError` allow callers to catch specific failure modes without parsing error messages, matching the TS SDK's discriminated error hierarchy.
- `SecretStr` ensures API keys are redacted in Pydantic repr and default logging paths without changing the external dict-based config interface.

## Validation

- `tests/entities/` — 7 new test modules covering sync/async client round-trips, input validation, response validation, and type models (~1,280 lines).
- `tests/test_pipeline_hooks.py` / `tests/test_pipeline_hooks_async.py` — hook invocation order, split-ingest merging, postprocess receives processed request (~460 lines).
- `tests/test_error_subclasses.py` — subclass hierarchy, `isinstance` compatibility with parent handlers (~256 lines).
- `tests/test_api_key_redaction.py` — `SecretStr` repr, no plaintext key in error messages (~149 lines).
- `tests/_pipeline_fakes.py` — shared fake pipeline/provider infrastructure extracted from client tests.
@ethanj ethanj merged commit 842b205 into main Jun 11, 2026
4 checks passed
@ethanj ethanj deleted the sync/python-3d31807 branch June 11, 2026 18:13
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.

1 participant