cognitive-memory-layer 0.1.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.
- cognitive_memory_layer-0.1.0/.editorconfig +15 -0
- cognitive_memory_layer-0.1.0/.gitignore +13 -0
- cognitive_memory_layer-0.1.0/.pre-commit-config.yaml +22 -0
- cognitive_memory_layer-0.1.0/CHANGELOG.md +78 -0
- cognitive_memory_layer-0.1.0/CONTRIBUTING.md +171 -0
- cognitive_memory_layer-0.1.0/LICENSE +674 -0
- cognitive_memory_layer-0.1.0/PKG-INFO +269 -0
- cognitive_memory_layer-0.1.0/README.md +217 -0
- cognitive_memory_layer-0.1.0/SECURITY.md +16 -0
- cognitive_memory_layer-0.1.0/coverage.xml +1602 -0
- cognitive_memory_layer-0.1.0/docs/.gitkeep +0 -0
- cognitive_memory_layer-0.1.0/docs/api-reference.md +63 -0
- cognitive_memory_layer-0.1.0/docs/configuration.md +88 -0
- cognitive_memory_layer-0.1.0/docs/examples.md +54 -0
- cognitive_memory_layer-0.1.0/docs/getting-started.md +52 -0
- cognitive_memory_layer-0.1.0/examples/.gitkeep +0 -0
- cognitive_memory_layer-0.1.0/examples/agent_integration.py +62 -0
- cognitive_memory_layer-0.1.0/examples/async_example.py +24 -0
- cognitive_memory_layer-0.1.0/examples/chat_with_memory.py +61 -0
- cognitive_memory_layer-0.1.0/examples/embedded_mode.py +27 -0
- cognitive_memory_layer-0.1.0/examples/quickstart.py +27 -0
- cognitive_memory_layer-0.1.0/pyproject.toml +112 -0
- cognitive_memory_layer-0.1.0/src/cml/__init__.py +46 -0
- cognitive_memory_layer-0.1.0/src/cml/_version.py +1 -0
- cognitive_memory_layer-0.1.0/src/cml/async_client.py +1066 -0
- cognitive_memory_layer-0.1.0/src/cml/client.py +1124 -0
- cognitive_memory_layer-0.1.0/src/cml/config.py +89 -0
- cognitive_memory_layer-0.1.0/src/cml/embedded.py +469 -0
- cognitive_memory_layer-0.1.0/src/cml/embedded_config.py +60 -0
- cognitive_memory_layer-0.1.0/src/cml/embedded_utils.py +91 -0
- cognitive_memory_layer-0.1.0/src/cml/exceptions.py +121 -0
- cognitive_memory_layer-0.1.0/src/cml/integrations/__init__.py +5 -0
- cognitive_memory_layer-0.1.0/src/cml/integrations/openai_helper.py +108 -0
- cognitive_memory_layer-0.1.0/src/cml/models/__init__.py +50 -0
- cognitive_memory_layer-0.1.0/src/cml/models/enums.py +57 -0
- cognitive_memory_layer-0.1.0/src/cml/models/memory.py +3 -0
- cognitive_memory_layer-0.1.0/src/cml/models/requests.py +73 -0
- cognitive_memory_layer-0.1.0/src/cml/models/responses.py +152 -0
- cognitive_memory_layer-0.1.0/src/cml/py.typed +0 -0
- cognitive_memory_layer-0.1.0/src/cml/storage/__init__.py +11 -0
- cognitive_memory_layer-0.1.0/src/cml/storage/sqlite_store.py +401 -0
- cognitive_memory_layer-0.1.0/src/cml/transport/__init__.py +5 -0
- cognitive_memory_layer-0.1.0/src/cml/transport/http.py +310 -0
- cognitive_memory_layer-0.1.0/src/cml/transport/retry.py +111 -0
- cognitive_memory_layer-0.1.0/src/cml/utils/__init__.py +12 -0
- cognitive_memory_layer-0.1.0/src/cml/utils/deprecation.py +50 -0
- cognitive_memory_layer-0.1.0/src/cml/utils/logging.py +38 -0
- cognitive_memory_layer-0.1.0/src/cml/utils/serialization.py +44 -0
- cognitive_memory_layer-0.1.0/tests/__init__.py +1 -0
- cognitive_memory_layer-0.1.0/tests/conftest.py +146 -0
- cognitive_memory_layer-0.1.0/tests/e2e/__init__.py +1 -0
- cognitive_memory_layer-0.1.0/tests/e2e/conftest.py +50 -0
- cognitive_memory_layer-0.1.0/tests/e2e/test_chat_flow.py +34 -0
- cognitive_memory_layer-0.1.0/tests/e2e/test_migration.py +29 -0
- cognitive_memory_layer-0.1.0/tests/embedded/__init__.py +1 -0
- cognitive_memory_layer-0.1.0/tests/embedded/conftest.py +24 -0
- cognitive_memory_layer-0.1.0/tests/embedded/test_lifecycle.py +51 -0
- cognitive_memory_layer-0.1.0/tests/embedded/test_lite_mode.py +56 -0
- cognitive_memory_layer-0.1.0/tests/integration/__init__.py +1 -0
- cognitive_memory_layer-0.1.0/tests/integration/conftest.py +67 -0
- cognitive_memory_layer-0.1.0/tests/integration/test_admin.py +55 -0
- cognitive_memory_layer-0.1.0/tests/integration/test_batch.py +38 -0
- cognitive_memory_layer-0.1.0/tests/integration/test_namespace.py +14 -0
- cognitive_memory_layer-0.1.0/tests/integration/test_sessions.py +38 -0
- cognitive_memory_layer-0.1.0/tests/integration/test_stats.py +20 -0
- cognitive_memory_layer-0.1.0/tests/integration/test_turn.py +37 -0
- cognitive_memory_layer-0.1.0/tests/integration/test_update_forget.py +37 -0
- cognitive_memory_layer-0.1.0/tests/integration/test_write_read.py +35 -0
- cognitive_memory_layer-0.1.0/tests/unit/__init__.py +1 -0
- cognitive_memory_layer-0.1.0/tests/unit/test_client_health.py +57 -0
- cognitive_memory_layer-0.1.0/tests/unit/test_client_memory.py +216 -0
- cognitive_memory_layer-0.1.0/tests/unit/test_config.py +84 -0
- cognitive_memory_layer-0.1.0/tests/unit/test_embedded.py +52 -0
- cognitive_memory_layer-0.1.0/tests/unit/test_exceptions.py +40 -0
- cognitive_memory_layer-0.1.0/tests/unit/test_import.py +64 -0
- cognitive_memory_layer-0.1.0/tests/unit/test_logging.py +14 -0
- cognitive_memory_layer-0.1.0/tests/unit/test_models.py +129 -0
- cognitive_memory_layer-0.1.0/tests/unit/test_phase5.py +326 -0
- cognitive_memory_layer-0.1.0/tests/unit/test_phase6.py +252 -0
- cognitive_memory_layer-0.1.0/tests/unit/test_retry.py +62 -0
- cognitive_memory_layer-0.1.0/tests/unit/test_serialization.py +27 -0
- cognitive_memory_layer-0.1.0/tests/unit/test_transport.py +229 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
root = true
|
|
2
|
+
|
|
3
|
+
[*]
|
|
4
|
+
indent_style = space
|
|
5
|
+
indent_size = 4
|
|
6
|
+
end_of_line = lf
|
|
7
|
+
charset = utf-8
|
|
8
|
+
trim_trailing_whitespace = true
|
|
9
|
+
insert_final_newline = true
|
|
10
|
+
|
|
11
|
+
[*.{yml,yaml,toml}]
|
|
12
|
+
indent_size = 2
|
|
13
|
+
|
|
14
|
+
[*.md]
|
|
15
|
+
trim_trailing_whitespace = false
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.8.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
|
|
9
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
10
|
+
rev: v1.13.0
|
|
11
|
+
hooks:
|
|
12
|
+
- id: mypy
|
|
13
|
+
additional_dependencies: [pydantic>=2.0, httpx>=0.27]
|
|
14
|
+
|
|
15
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
16
|
+
rev: v5.0.0
|
|
17
|
+
hooks:
|
|
18
|
+
- id: trailing-whitespace
|
|
19
|
+
- id: end-of-file-fixer
|
|
20
|
+
- id: check-yaml
|
|
21
|
+
- id: check-toml
|
|
22
|
+
- id: check-added-large-files
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
#### Phase 1: Project setup
|
|
13
|
+
- Initial project structure and build configuration (Hatchling, src layout)
|
|
14
|
+
- Package `cml` with sync and async client classes (`CognitiveMemoryLayer`, `AsyncCognitiveMemoryLayer`)
|
|
15
|
+
- Development tooling: ruff, mypy, pytest, pre-commit, editorconfig
|
|
16
|
+
- CI workflows: py-cml-test (Python 3.11–3.13), py-cml-lint, py-cml-publish (on `py-cml-v*` tags)
|
|
17
|
+
- README, CONTRIBUTING, and CHANGELOG
|
|
18
|
+
|
|
19
|
+
#### Phase 2: Core client SDK
|
|
20
|
+
- **Configuration:** Pydantic `CMLConfig` with validation; loading from direct params, env vars (`CML_*`), and `.env` (python-dotenv)
|
|
21
|
+
- **Exceptions:** Full hierarchy — `CMLError` (with `status_code`, `response_body`), `AuthenticationError`, `AuthorizationError`, `NotFoundError`, `ValidationError`, `RateLimitError` (with `retry_after`), `ServerError`, `ConnectionError`, `TimeoutError`
|
|
22
|
+
- **Transport:** Sync `HTTPTransport` and async `AsyncHTTPTransport` (httpx), path prefix `/api/v1`, standard headers (API key, tenant ID, User-Agent), status-code mapping to exceptions
|
|
23
|
+
- **Retry:** Exponential backoff with jitter for 5xx, 429, connection, and timeout; `RateLimitError` respects `Retry-After` header; retry integrated in transport `request()`
|
|
24
|
+
- **Models:** Enums `MemoryType`, `MemoryStatus`, `MemorySource`, `OperationType`; request models (`WriteRequest`, `ReadRequest`, `TurnRequest`, `UpdateRequest`, `ForgetRequest`); response models (`HealthResponse`, `WriteResponse`, `ReadResponse`, `TurnResponse`, etc., `MemoryItem`)
|
|
25
|
+
- **Clients:** Context manager support (`with` / `async with`), `close()`, `health()` returning `HealthResponse`
|
|
26
|
+
- Unit tests for config, exceptions, retry, transport (mocked), and client health (29 tests)
|
|
27
|
+
|
|
28
|
+
#### Phase 3: Memory operations
|
|
29
|
+
- **Memory API:** `write`, `read`, `turn`, `update`, `forget`, `stats` on both sync and async clients
|
|
30
|
+
- **Sessions:** `create_session`, `get_session_context`; request/response models `CreateSessionRequest`, `SessionContextResponse`
|
|
31
|
+
- **Convenience:** `get_context` (read with format=llm_context), `remember` (alias for write), `search` (alias for read)
|
|
32
|
+
- **Admin:** `delete_all(confirm=True)` (requires confirm; server route may be added later)
|
|
33
|
+
- **Validation:** `forget()` requires at least one of `memory_ids`, `query`, or `before`; docstrings with Args, Returns, Raises
|
|
34
|
+
- Unit tests for memory operations (mocked transport): write/read responses, forget/delete_all validation, get_context, remember/search delegation
|
|
35
|
+
|
|
36
|
+
#### Phase 4: Embedded mode
|
|
37
|
+
- **EmbeddedCognitiveMemoryLayer:** In-process CML engine with same API as HTTP client (write, read, turn, update, forget, stats, get_context, remember, search, create_session, get_session_context, delete_all)
|
|
38
|
+
- **EmbeddedConfig:** Storage mode (lite/standard/full), database, embedding, and LLM config; lite mode uses SQLite + local embeddings
|
|
39
|
+
- **SQLite memory store:** `cml.storage.sqlite_store.SQLiteMemoryStore` implementing engine MemoryStoreBase; in-memory cosine similarity for vector search (~10k records)
|
|
40
|
+
- **Lite mode:** Zero-config `EmbeddedCognitiveMemoryLayer()` uses in-memory SQLite and sentence-transformers; optional `db_path` for persistence
|
|
41
|
+
- **Background workers:** Optional asyncio tasks for consolidation and forgetting when `auto_consolidate` / `auto_forget` are True
|
|
42
|
+
- **Export/import:** `cml.embedded_utils.export_memories_async`, `import_memories_async` (and sync wrappers) for migration between embedded and server
|
|
43
|
+
- **Parent engine:** HippocampalStore accepts MemoryStoreBase; MemoryOrchestrator.create_lite(episodic_store, embedding_client, llm_client); NoOpGraphStore and NoOpFactStore for lite
|
|
44
|
+
- Unit tests for embedded config and mocked orchestrator
|
|
45
|
+
|
|
46
|
+
#### Phase 5: Advanced features
|
|
47
|
+
- **Admin operations:** `consolidate(tenant_id=..., user_id=...)` and `run_forgetting(tenant_id=..., user_id=..., dry_run=..., max_memories=...)` (dashboard routes; require admin API key)
|
|
48
|
+
- **Batch operations:** `batch_write(items, session_id=..., namespace=...)` (sequential) and `batch_read(queries, max_results=..., format=...)` (concurrent on async, sequential on sync)
|
|
49
|
+
- **Tenant management:** `set_tenant(tenant_id)`, `tenant_id` property, `list_tenants()` (admin only)
|
|
50
|
+
- **Event log:** `get_events(limit=..., page=..., event_type=..., since=...)` (admin only)
|
|
51
|
+
- **Component health:** `component_health()` (admin only)
|
|
52
|
+
- **Namespace isolation:** `with_namespace(namespace)` returning `NamespacedClient` / `AsyncNamespacedClient` that inject namespace into write/update/batch_write
|
|
53
|
+
- **Memory iteration:** `iter_memories(memory_types=..., status=..., batch_size=...)` yielding `MemoryItem` with pagination (admin only)
|
|
54
|
+
- **OpenAI integration:** `cml.integrations.CMLOpenAIHelper(memory_client, openai_client, model=...)` with `chat(user_message, session_id=..., system_prompt=..., extra_messages=...)`; optional `MemoryProvider` protocol
|
|
55
|
+
- Unit tests for Phase 5 (mocked transport)
|
|
56
|
+
|
|
57
|
+
#### Phase 6: Developer experience
|
|
58
|
+
- **Structured errors:** CMLError and subclasses include optional `suggestion`, `request_id`; `_raise_for_status` passes actionable suggestions per status code
|
|
59
|
+
- **Logging:** `cml.utils.logging` with `configure_logging(level, handler)`, `_redact()`; DEBUG log for request/response timing in transport; DEBUG/WARNING in retry
|
|
60
|
+
- **Graceful degradation:** `read_safe(query, **kwargs)` on sync and async clients returns empty ReadResponse on ConnectionError/TimeoutError
|
|
61
|
+
- **TypedDict:** `ConsolidationResult`, `ForgettingResult` in models for admin return types
|
|
62
|
+
- **Response __str__:** ReadResponse, WriteResponse, StatsResponse have human-readable `__str__`
|
|
63
|
+
- **Serialization:** `CMLJSONEncoder`, `serialize_for_api()` in `cml.utils.serialization`
|
|
64
|
+
- **Session context manager:** `memory.session(name=..., ttl_hours=...)` (sync and async) yielding SessionScope / AsyncSessionScope with write, read, turn, remember
|
|
65
|
+
- **HTTP/2 and limits:** httpx Client/AsyncClient created with `http2=True` and `Limits(max_connections=100, ...)`
|
|
66
|
+
- **Deprecation:** `cml.utils.deprecation.deprecated(alternative, removal_version)` decorator
|
|
67
|
+
- **Thread safety:** Sync client uses `threading.RLock` in `set_tenant()`
|
|
68
|
+
- **Async loop check:** Async client stores creation event loop and raises RuntimeError if used in a different loop
|
|
69
|
+
- Unit tests for Phase 6 (exceptions, logging, read_safe, __str__, serialization, session, deprecation, thread safety, event loop)
|
|
70
|
+
|
|
71
|
+
#### Phase 8: Documentation and publishing
|
|
72
|
+
- **README:** PyPI and Python version badges, one-line tagline, Documentation links to getting-started, api-reference, configuration, examples
|
|
73
|
+
- **Docs:** getting-started.md, api-reference.md, configuration.md, examples.md in packages/py-cml/docs/
|
|
74
|
+
- **Examples:** quickstart.py, chat_with_memory.py, async_example.py, embedded_mode.py, agent_integration.py in packages/py-cml/examples/
|
|
75
|
+
- **GitHub:** Issue templates (bug_report, feature_request), pull_request_template with Summary, Changes, Testing, Documentation checklists
|
|
76
|
+
- **SECURITY.md:** Supported versions, report via GitHub Security Advisories
|
|
77
|
+
- **CONTRIBUTING:** Releasing py-cml section (version bump, tag py-cml-v*, PyPI publish); fork/venv in dev setup; PR checklist alignment
|
|
78
|
+
- Publish workflow (py-cml-publish.yml on py-cml-v* tag) already in place; no code changes
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Contributing to py-cml
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in the CognitiveMemoryLayer Python SDK. This guide covers development setup and workflow for the `packages/py-cml` package.
|
|
4
|
+
|
|
5
|
+
## Development setup
|
|
6
|
+
|
|
7
|
+
1. Fork and clone the CognitiveMemoryLayer repository (or work in a branch if you have write access).
|
|
8
|
+
2. Create a virtual environment (recommended): `python -m venv .venv` then activate it.
|
|
9
|
+
3. Install the package in editable mode with dev dependencies.
|
|
10
|
+
|
|
11
|
+
From the **repository root**:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install -e "packages/py-cml[dev]"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Or from inside the package:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
cd packages/py-cml
|
|
21
|
+
pip install -e ".[dev]"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
This installs the package in editable mode with dev dependencies (pytest, ruff, mypy, pre-commit). Run `pre-commit install` to enable hooks.
|
|
25
|
+
|
|
26
|
+
## Running tests
|
|
27
|
+
|
|
28
|
+
From `packages/py-cml`:
|
|
29
|
+
|
|
30
|
+
**Unit tests (default; no server required):**
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pytest tests/unit/ -v
|
|
34
|
+
pytest tests/unit/ -v --cov=cml --cov-report=term-missing --cov-branch
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Unit tests cover config, exceptions, retry logic, transport (including 403/422/429/500 and connection/timeout mapping), models (serialization), client health and memory operations (mocked), serialization, and logging. CI runs only unit tests on every push.
|
|
38
|
+
|
|
39
|
+
**Integration tests** (require a running CML server):
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
export CML_TEST_URL=http://localhost:8000 # optional
|
|
43
|
+
export CML_TEST_API_KEY=your-key # optional
|
|
44
|
+
pytest tests/integration/ -v -m integration
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Embedded tests** (require `pip install -e ".[dev,embedded]"` and CML engine):
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pytest tests/embedded/ -v -m embedded
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**E2E tests** (require live server):
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pytest tests/e2e/ -v -m e2e
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Run everything except integration/embedded/e2e:**
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pytest -m "not integration and not embedded and not e2e" -v
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Shared fixtures live in `tests/conftest.py` (`test_config`, `mock_config`, `sync_client`, `async_client`, and mock response helpers). Integration tests use `live_client` from `tests/integration/conftest.py` and skip if the server is unreachable.
|
|
66
|
+
|
|
67
|
+
## Code style and type checking
|
|
68
|
+
|
|
69
|
+
- **Ruff** — linting and formatting:
|
|
70
|
+
```bash
|
|
71
|
+
ruff check src/ tests/
|
|
72
|
+
ruff format src/ tests/
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- **mypy** — type checking (strict):
|
|
76
|
+
```bash
|
|
77
|
+
mypy src/cml/
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Configuration for ruff and mypy lives in `pyproject.toml`.
|
|
81
|
+
|
|
82
|
+
## Pre-commit hooks
|
|
83
|
+
|
|
84
|
+
Install and run pre-commit (from `packages/py-cml` or repo root with config path):
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pre-commit install
|
|
88
|
+
pre-commit run --all-files
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Hooks run ruff (check + format), mypy, and generic checks (trailing whitespace, YAML/TOML, etc.).
|
|
92
|
+
|
|
93
|
+
## Pull request process
|
|
94
|
+
|
|
95
|
+
1. Create a branch from `main`, make changes in `packages/py-cml/`.
|
|
96
|
+
2. Add or update tests; ensure `pytest tests/unit/`, `mypy src/cml/`, and `ruff check src/ tests/` pass.
|
|
97
|
+
3. Update docstrings, README, or CHANGELOG as applicable (see PR template checklist).
|
|
98
|
+
4. Open a PR. CI runs py-cml tests and lint when paths under `packages/py-cml/**` or the workflow file change.
|
|
99
|
+
5. Get review approval and merge.
|
|
100
|
+
|
|
101
|
+
## Commit message conventions
|
|
102
|
+
|
|
103
|
+
- `feat(cml): ...` — new feature
|
|
104
|
+
- `fix(cml): ...` — bug fix
|
|
105
|
+
- `docs(cml): ...` — documentation
|
|
106
|
+
- `test(cml): ...` — tests
|
|
107
|
+
- `chore(py-cml): ...` — build, CI, tooling
|
|
108
|
+
|
|
109
|
+
## Publishing the package to PyPI
|
|
110
|
+
|
|
111
|
+
Releases are published to PyPI when a tag matching `py-cml-v*` is pushed. The workflow (`.github/workflows/py-cml.yml`) uses **PyPI trusted publishing (OIDC)**; no API tokens are stored in the repo.
|
|
112
|
+
|
|
113
|
+
### Prerequisites (one-time)
|
|
114
|
+
|
|
115
|
+
- **PyPI:** Add a [trusted publisher](https://docs.pypi.org/trusted-publishers/) (or pending publisher) for the project `cognitive-memory-layer`:
|
|
116
|
+
- **Repository:** `owner/CognitiveMemoryLayer`
|
|
117
|
+
- **Workflow name:** `py-cml.yml`
|
|
118
|
+
- **Environment name:** `pypi`
|
|
119
|
+
- **GitHub:** Create an environment named **`pypi`** under **Settings → Environments** (no secrets required for trusted publishing).
|
|
120
|
+
|
|
121
|
+
### Before each release
|
|
122
|
+
|
|
123
|
+
1. **Bump version** in `packages/py-cml/pyproject.toml` and `packages/py-cml/src/cml/_version.py` (e.g. `0.1.0` → `0.1.1`).
|
|
124
|
+
2. **Update CHANGELOG.md** — add a `## [X.Y.Z] - YYYY-MM-DD` section and move entries from Unreleased.
|
|
125
|
+
3. **Commit and push to `main`:** e.g. `chore(py-cml): prepare release v0.1.1`
|
|
126
|
+
|
|
127
|
+
### Ways to publish
|
|
128
|
+
|
|
129
|
+
**Option A — From GitHub Actions (no local tag needed)**
|
|
130
|
+
|
|
131
|
+
1. Go to **Actions** → **py-cml: CI and release** → **Run workflow**.
|
|
132
|
+
2. Choose branch **main** (or the branch you pushed the version bump to).
|
|
133
|
+
3. Enter **Version to release** (e.g. `0.1.1`). Leave it empty only if you just want to run lint/test/build.
|
|
134
|
+
4. Click **Run workflow**.
|
|
135
|
+
5. **Two runs:** The first run (manual) only runs **Create release tag** and pushes the tag; lint/test/build/publish are skipped. The **tag push triggers a second run** where only **Build and publish to PyPI** runs. In the Actions list, find the run triggered by the tag (e.g. "Tag py-cml-v0.1.1 pushed" or similar) and confirm that job succeeded.
|
|
136
|
+
|
|
137
|
+
**Option B — From the command line**
|
|
138
|
+
|
|
139
|
+
1. From your repo root (on `main`, with the version bump already pushed):
|
|
140
|
+
```bash
|
|
141
|
+
git pull origin main
|
|
142
|
+
git tag py-cml-v0.1.1 # use the same version as in pyproject.toml
|
|
143
|
+
git push origin py-cml-v0.1.1
|
|
144
|
+
```
|
|
145
|
+
2. The push triggers the workflow; the **Build and publish to PyPI** job runs and uploads the package.
|
|
146
|
+
|
|
147
|
+
**Option C — From GitHub Releases**
|
|
148
|
+
|
|
149
|
+
1. After pushing the version bump to `main`, go to **Releases** → **Draft a new release**.
|
|
150
|
+
2. Choose **Tag:** create a new tag `py-cml-v0.1.1` from `main`.
|
|
151
|
+
3. Set the release title (e.g. `v0.1.1`) and paste the CHANGELOG section. Publish the release.
|
|
152
|
+
4. Creating the tag (via the release) pushes it; the workflow runs and publishes to PyPI.
|
|
153
|
+
|
|
154
|
+
### After publishing
|
|
155
|
+
|
|
156
|
+
- **Optional:** If you used Option B or A, create a **GitHub Release** from the new tag and paste the CHANGELOG section.
|
|
157
|
+
- **Verify:** `pip install cognitive-memory-layer==0.1.1` then `python -c "from cml import CognitiveMemoryLayer; print('OK')"`.
|
|
158
|
+
|
|
159
|
+
### Troubleshooting
|
|
160
|
+
|
|
161
|
+
- **PyPI still shows "0 projects"**
|
|
162
|
+
Check that the **tag-triggered** run (the second run after you used Option A) exists and that **Build and publish to PyPI** completed successfully. If that run is missing, the tag push may not have triggered the workflow (e.g. path filters); use Option B to push the tag from your machine and confirm the run appears.
|
|
163
|
+
- **Pending publishers:** Use only the publisher for **workflow `py-cml.yml`** and **environment `pypi`**. If you have a pending publisher for `py-cml-publish.yml`, remove it (that workflow was merged into `py-cml.yml`).
|
|
164
|
+
|
|
165
|
+
### TestPyPI (optional)
|
|
166
|
+
|
|
167
|
+
To try the release flow without publishing to production PyPI: add a trusted publisher for **TestPyPI** with the same workflow and environment, then push a tag (e.g. `py-cml-v0.1.0a1`) or use **Run workflow** with a pre-release version. Install with `pip install -i https://test.pypi.org/simple/ cognitive-memory-layer==0.1.0a1`.
|
|
168
|
+
|
|
169
|
+
## General repository guidelines
|
|
170
|
+
|
|
171
|
+
For broader contribution guidelines (code of conduct, issue templates, repository structure), see the root [CONTRIBUTING.md](../../CONTRIBUTING.md) of the CognitiveMemoryLayer repository.
|