keble-task 2.22.0__tar.gz → 2.22.1__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.
- keble_task-2.22.1/AGENTS.md +32 -0
- keble_task-2.22.1/AiAgentChangesLogs.md +44 -0
- keble_task-2.22.1/CLAUDE.md +33 -0
- keble_task-2.22.1/PKG-INFO +74 -0
- keble_task-2.22.1/README.md +58 -0
- keble_task-2.22.1/keble_task/testing/__init__.py +12 -0
- keble_task-2.22.1/keble_task/testing/config.py +169 -0
- keble_task-2.22.1/keble_task/testing/factories.py +67 -0
- keble_task-2.22.0/AiAgentChangesLogs.md → keble_task-2.22.1/logs/AiAgentChangesLogs.20260630.md +13 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/pyproject.poetry.toml +2 -2
- {keble_task-2.22.0 → keble_task-2.22.1}/pyproject.toml +4 -3
- {keble_task-2.22.0 → keble_task-2.22.1}/tests/conftest.py +28 -30
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/contract/events}/test_emit_drain_contract.py +1 -1
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/contract/schemas}/test_metadata_jsonable_read.py +1 -2
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/integration/actions}/test_task_actions.py +1 -1
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/integration/agent}/test_agent_query_registry.py +1 -1
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/integration/agent}/test_agent_registry.py +1 -1
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/integration/core}/test_main.py +1 -1
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/integration/costs}/test_task_costs.py +1 -1
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/integration/relations}/test_task_relations.py +1 -1
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/integration/tree}/test_tree_and_public_id_edges.py +1 -1
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/live/llm}/test_agent_registry_live.py +5 -4
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/unit/core}/test_metadata_flow.py +3 -49
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/unit/core}/test_retry_attempt_logging.py +1 -1
- keble_task-2.22.1/tests/unit/testing/test_config.py +96 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/uv.lock +8 -51
- keble_task-2.22.0/AGENTS.md +0 -18
- keble_task-2.22.0/CLAUDE.md +0 -15
- keble_task-2.22.0/PKG-INFO +0 -1083
- keble_task-2.22.0/README.md +0 -1067
- keble_task-2.22.0/tests/config.py +0 -85
- keble_task-2.22.0/tests/pytest.ini +0 -3
- keble_task-2.22.0/tests/schemas/__init__.py +0 -0
- keble_task-2.22.0/tests/utils.py +0 -3
- {keble_task-2.22.0 → keble_task-2.22.1}/.gitattributes +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/.gitignore +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/.python-version +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/deps/keble_typing-0.3.3-py3-none-any.whl +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/improve.README.md +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/keble_task/__init__.py +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/keble_task/actions.py +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/keble_task/agent/__init__.py +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/keble_task/agent/chat_provider.py +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/keble_task/agent/deps.py +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/keble_task/agent/tools/__init__.py +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/keble_task/agent/tools/mutation.py +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/keble_task/agent/tools/query.py +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/keble_task/crud.py +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/keble_task/exceptions.py +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/keble_task/main.py +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/keble_task/schemas/__init__.py +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/keble_task/schemas/for_agent.py +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/keble_task/task_tree.py +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/keble_task/utils.py +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/poetry.lock +0 -0
- {keble_task-2.22.0 → keble_task-2.22.1}/pyrightconfig.json +0 -0
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/contract/schemas}/__init__.py +0 -0
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/contract}/schemas/test_for_agent.py +0 -0
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/contract/schemas}/test_no_local_datetime_helpers.py +0 -0
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/integration/public}/test_public_indexable.py +0 -0
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/unit/agent}/test_agent_chat_provider.py +0 -0
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/unit/core}/test_exceptions.py +0 -0
- {keble_task-2.22.0/tests → keble_task-2.22.1/tests/unit/schemas}/test_schemas.py +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Keble Task Agent Instructions
|
|
2
|
+
|
|
3
|
+
Follow the root `TESTING_GUIDELINE.md` when changing tests in this repo.
|
|
4
|
+
|
|
5
|
+
## Testing Rules
|
|
6
|
+
|
|
7
|
+
- Keep default tests offline from external providers. The live LLM test must
|
|
8
|
+
stay marked `live` and `llm` and must require `RUN_LLM_LIVE=1`.
|
|
9
|
+
- Put executable tests under canonical layer folders only: `tests/unit/`,
|
|
10
|
+
`tests/contract/`, `tests/integration/`, `tests/live/`, `tests/evals/`, or
|
|
11
|
+
`tests/db_stack/`.
|
|
12
|
+
- Do not add flat `tests/test_*.py`, `tests/schemas/`, `tests/mock/`, or
|
|
13
|
+
`tests/irl/` folders.
|
|
14
|
+
- Do not recreate root-level `tests/config.py`, `tests/utils.py`, or an
|
|
15
|
+
importable root `tests` package. Shared test doubles and settings belong in
|
|
16
|
+
`keble_task.testing`.
|
|
17
|
+
- Tests that use Mongo/Redis fixtures are integration DB tests and must be
|
|
18
|
+
marked with `integration`, `db`, `mongo`, and `redis`.
|
|
19
|
+
- Use `keble_task.testing.config` for test credentials. It reads explicit env /
|
|
20
|
+
`tests/.env` / the umbrella `keble.backend/.env`, maps backend Azure provider
|
|
21
|
+
lists into the live LLM canary, and keeps test database names isolated.
|
|
22
|
+
- Use shared fixtures from `keble_db.testing` as the DB testing toolkit expands;
|
|
23
|
+
do not introduce ad-hoc shared local database writes.
|
|
24
|
+
- Do not add empty pytest lifecycle hooks, empty test folders, `pass`, `...`, or
|
|
25
|
+
status-only tests as placeholders. Add meaningful assertions or remove the
|
|
26
|
+
placeholder module.
|
|
27
|
+
- Do not add full stack or live-provider behavior to the default test command.
|
|
28
|
+
- Run `uv run pytest -m "not live and not slow and not eval and not local_stack and not db_stack and not container"`
|
|
29
|
+
and `npx --yes pyright .` after test-infrastructure changes.
|
|
30
|
+
- Update `README.md`, `AGENTS.md`, `CLAUDE.md`, and `AiAgentChangesLogs.md`
|
|
31
|
+
whenever testing behavior, markers, fixtures, commands, or dependencies
|
|
32
|
+
change.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Ai Agent Changes Logs
|
|
2
|
+
|
|
3
|
+
Historical entries before 2026-06-30 23:13 were moved to `logs/AiAgentChangesLogs.20260630.md`.
|
|
4
|
+
|
|
5
|
+
## 2026-07-02 00:58 CST
|
|
6
|
+
State: branch `refactor/harden-pytests-keble-task`; pytest hardening follow-up for `prompts/202060701/1.5-harden-pytests-and-remove-redundant.md`.
|
|
7
|
+
|
|
8
|
+
zma:
|
|
9
|
+
- Execute the cross-repo pytest hardening plan repo by repo.
|
|
10
|
+
- Reconsider over-trimmed IRL tests, remove weak placeholders, and use `keble.backend/.env` credentials instead of skipping DB/LLM tests for missing repo-local env.
|
|
11
|
+
|
|
12
|
+
Ai:
|
|
13
|
+
- Bumped `keble-task` to `2.22.1` and raised the `keble-db` dependency to `>=1.8.1`.
|
|
14
|
+
- Updated `keble_task.testing.config` to read explicit env / `tests/.env` / backend `.env` for Mongo and Redis, and to map the first backend Azure endpoint/token/deployment into the live LLM canary.
|
|
15
|
+
- Added unit coverage for backend env fallback, Azure provider-list mapping, and explicit-env precedence.
|
|
16
|
+
- Removed empty pytest lifecycle hooks from `tests/conftest.py` and updated docs to forbid placeholder test modules/hooks.
|
|
17
|
+
- Pending proof before merge: default pytest, unit, integration, live LLM guard, pyright, and package build.
|
|
18
|
+
|
|
19
|
+
## 2026-07-01 03:32
|
|
20
|
+
State: Strict testing-folder follow-up for `keble-task`; no runtime task API behavior, schemas, or dependencies changed.
|
|
21
|
+
|
|
22
|
+
zma:
|
|
23
|
+
- Continue the cross-repo testing refactor after tightening `TESTING_GUIDELINE.md` marker and folder allowances.
|
|
24
|
+
- Enforce canonical test layer folders and package-owned shared test helpers.
|
|
25
|
+
|
|
26
|
+
Ai:
|
|
27
|
+
- Moved test settings into `keble_task.testing.config`.
|
|
28
|
+
- Moved shared in-memory task test doubles and factories into `keble_task.testing.factories`.
|
|
29
|
+
- Removed root `tests/config.py`, `tests/utils.py`, `tests/pytest.ini`, and `tests/__init__.py` so tests no longer import through `tests.*`.
|
|
30
|
+
- Updated docs to keep future shared task test helpers under `keble_task.testing`.
|
|
31
|
+
|
|
32
|
+
## 2026-06-30 23:13
|
|
33
|
+
State: Documentation-only README compaction and AI log archival; no runtime code, schemas, dependencies, or tests were changed.
|
|
34
|
+
|
|
35
|
+
zma:
|
|
36
|
+
- Auto compact and summarize README.md files across repos unless already small.
|
|
37
|
+
- Cross-check retained README information for validity and keep only critical, necessary information.
|
|
38
|
+
- Move lengthy AiAgentChangesLogs.md files into repo-local logs/AiAgentChangesLogs.2026****.md.
|
|
39
|
+
- Merge the documentation changes to main repo by repo.
|
|
40
|
+
|
|
41
|
+
Ai:
|
|
42
|
+
- Archived the previous long agent change log into `logs/AiAgentChangesLogs.20260630.md`.
|
|
43
|
+
- Compacted `README.md` to current purpose, validated wiring, install/test gates, and high-risk side effects.
|
|
44
|
+
- Kept only critical current README facts cross-checked against manifests, config, source roots, compose scripts, or existing guideline files.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Keble Task Claude Instructions
|
|
2
|
+
|
|
3
|
+
Follow the root `TESTING_GUIDELINE.md` for all task package test work.
|
|
4
|
+
|
|
5
|
+
Keep default tests free of live providers. Mongo/Redis tests are integration DB
|
|
6
|
+
tests; live LLM tests require `RUN_LLM_LIVE=1` and either explicit `LIVE_LLM_*`
|
|
7
|
+
credentials or backend Azure provider settings loaded from `keble.backend/.env`.
|
|
8
|
+
Use the shared marker vocabulary across Keble repos and prefer
|
|
9
|
+
`keble_db.testing` helpers as shared DB fixtures become available.
|
|
10
|
+
|
|
11
|
+
Executable tests must live under canonical layer folders only:
|
|
12
|
+
`tests/unit/`, `tests/contract/`, `tests/integration/`, `tests/live/`,
|
|
13
|
+
`tests/evals/`, or `tests/db_stack/`. Do not add flat `tests/test_*.py`,
|
|
14
|
+
`tests/schemas/`, `tests/mock/`, or `tests/irl/` folders. Mongo/Redis tests
|
|
15
|
+
must carry `integration`, `db`, `mongo`, and `redis` markers.
|
|
16
|
+
|
|
17
|
+
Do not recreate root-level `tests/config.py`, `tests/utils.py`, or an
|
|
18
|
+
importable root `tests` package. Shared settings, factories, and test doubles
|
|
19
|
+
belong in `keble_task.testing`.
|
|
20
|
+
|
|
21
|
+
Do not add empty pytest lifecycle hooks, placeholder test modules, `pass`, `...`,
|
|
22
|
+
or status-only assertions. If a repo lacks a reusable DB or provider fixture,
|
|
23
|
+
enrich `keble_db.testing` or this package's testing helper surface first.
|
|
24
|
+
|
|
25
|
+
Required checks after test-infrastructure changes:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
uv run pytest -m "not live and not slow and not eval and not local_stack and not db_stack and not container"
|
|
29
|
+
uv run pytest -m unit
|
|
30
|
+
uv run pytest -m integration
|
|
31
|
+
uv run pytest -m "live and llm"
|
|
32
|
+
npx --yes pyright .
|
|
33
|
+
```
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: keble-task
|
|
3
|
+
Version: 2.22.1
|
|
4
|
+
Author-email: zhenhao-ma <bob0103779@gmail.com>
|
|
5
|
+
Requires-Python: <3.14,>=3.13
|
|
6
|
+
Requires-Dist: keble-db<2.0.0,>=1.8.1
|
|
7
|
+
Requires-Dist: keble-helpers<2.0.0,>=1.40.0
|
|
8
|
+
Requires-Dist: pydantic-ai-slim<2.0.0,>=1.41.0
|
|
9
|
+
Requires-Dist: tenacity<10.0.0,>=9
|
|
10
|
+
Provides-Extra: test
|
|
11
|
+
Requires-Dist: httpx[socks]<1.0.0,>=0.27; extra == 'test'
|
|
12
|
+
Requires-Dist: pydantic-ai-slim[openai]<2.0.0,>=1.41.0; extra == 'test'
|
|
13
|
+
Requires-Dist: pytest-asyncio<1.0.0,>=0; extra == 'test'
|
|
14
|
+
Requires-Dist: pytest<9.0.0,>=8; extra == 'test'
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# keble-task
|
|
18
|
+
|
|
19
|
+
`keble-task` owns generic Keble task schemas, task relations, task-room graph
|
|
20
|
+
context, lifecycle/action events, task cost records, and agent query/mutation
|
|
21
|
+
tool contracts.
|
|
22
|
+
|
|
23
|
+
## Verified State
|
|
24
|
+
|
|
25
|
+
Checked on 2026-06-30 against `pyproject.toml`, package exports,
|
|
26
|
+
`keble_task/`, and tests.
|
|
27
|
+
|
|
28
|
+
- Package: `keble-task 2.22.1`
|
|
29
|
+
- Python: `>=3.13,<3.14`
|
|
30
|
+
- Critical deps: `keble-helpers`, `keble-db`, `pydantic-ai-slim`, `tenacity`
|
|
31
|
+
- Source roots: `schemas/`, `actions/`, `crud/`, `main/`, `agent/`, `utils/`
|
|
32
|
+
- Public exports: `TaskClient`, CRUD classes, task/task-relation schemas,
|
|
33
|
+
task-cost schemas, lifecycle/action events, and agent tool providers.
|
|
34
|
+
|
|
35
|
+
## Runtime Contract
|
|
36
|
+
|
|
37
|
+
- Task identity, stage, relations, and cost accounting belong here. Feature
|
|
38
|
+
packages should attach domain metadata instead of redefining task rows.
|
|
39
|
+
- First-class long-running features should be real `TaskType` flows in the
|
|
40
|
+
consuming service, not generic subagent workflows plus parallel adapters.
|
|
41
|
+
- Lifecycle and action events must stay typed and stable for backend
|
|
42
|
+
websocket fanout and frontend task-list rendering.
|
|
43
|
+
- Mongo CRUD changes must expose indexed query shapes directly and keep index
|
|
44
|
+
creation in startup wiring, not request handlers.
|
|
45
|
+
|
|
46
|
+
## Testing
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
uv sync --group test
|
|
50
|
+
uv run pytest -m "not live and not slow and not eval and not local_stack and not db_stack and not container"
|
|
51
|
+
uv run npx --yes pyright .
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Package-owned test helpers live under `keble_task.testing`; do not recreate
|
|
55
|
+
root-level `tests/config.py`, `tests/utils.py`, root test packages, or legacy
|
|
56
|
+
source folders such as `tests/schemas/`.
|
|
57
|
+
|
|
58
|
+
Mongo/Redis integration settings load explicit process env first, then
|
|
59
|
+
`tests/.env`, then the umbrella `keble.backend/.env` through
|
|
60
|
+
`keble_db.testing.resolve_test_env`. Live LLM settings load explicit `LIVE_LLM_*`
|
|
61
|
+
values first and otherwise map the first backend Azure endpoint/token/deployment
|
|
62
|
+
entry. Set `KEBLE_BACKEND_ENV_FILE=/path/to/.env` from unusual worktree or CI
|
|
63
|
+
layouts. Keep the package-owned test database and collection names isolated.
|
|
64
|
+
|
|
65
|
+
## Change Logs
|
|
66
|
+
|
|
67
|
+
Historical release notes and long AI change history live under `logs/`.
|
|
68
|
+
|
|
69
|
+
## Side Effect If Changes
|
|
70
|
+
|
|
71
|
+
- Backend task APIs, owner task lists, task room sockets, cost accounting,
|
|
72
|
+
and frontend task rows depend on these schemas/events.
|
|
73
|
+
- Relation or graph-context changes can affect all feature rooms that load
|
|
74
|
+
child tasks or background sessions.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# keble-task
|
|
2
|
+
|
|
3
|
+
`keble-task` owns generic Keble task schemas, task relations, task-room graph
|
|
4
|
+
context, lifecycle/action events, task cost records, and agent query/mutation
|
|
5
|
+
tool contracts.
|
|
6
|
+
|
|
7
|
+
## Verified State
|
|
8
|
+
|
|
9
|
+
Checked on 2026-06-30 against `pyproject.toml`, package exports,
|
|
10
|
+
`keble_task/`, and tests.
|
|
11
|
+
|
|
12
|
+
- Package: `keble-task 2.22.1`
|
|
13
|
+
- Python: `>=3.13,<3.14`
|
|
14
|
+
- Critical deps: `keble-helpers`, `keble-db`, `pydantic-ai-slim`, `tenacity`
|
|
15
|
+
- Source roots: `schemas/`, `actions/`, `crud/`, `main/`, `agent/`, `utils/`
|
|
16
|
+
- Public exports: `TaskClient`, CRUD classes, task/task-relation schemas,
|
|
17
|
+
task-cost schemas, lifecycle/action events, and agent tool providers.
|
|
18
|
+
|
|
19
|
+
## Runtime Contract
|
|
20
|
+
|
|
21
|
+
- Task identity, stage, relations, and cost accounting belong here. Feature
|
|
22
|
+
packages should attach domain metadata instead of redefining task rows.
|
|
23
|
+
- First-class long-running features should be real `TaskType` flows in the
|
|
24
|
+
consuming service, not generic subagent workflows plus parallel adapters.
|
|
25
|
+
- Lifecycle and action events must stay typed and stable for backend
|
|
26
|
+
websocket fanout and frontend task-list rendering.
|
|
27
|
+
- Mongo CRUD changes must expose indexed query shapes directly and keep index
|
|
28
|
+
creation in startup wiring, not request handlers.
|
|
29
|
+
|
|
30
|
+
## Testing
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
uv sync --group test
|
|
34
|
+
uv run pytest -m "not live and not slow and not eval and not local_stack and not db_stack and not container"
|
|
35
|
+
uv run npx --yes pyright .
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Package-owned test helpers live under `keble_task.testing`; do not recreate
|
|
39
|
+
root-level `tests/config.py`, `tests/utils.py`, root test packages, or legacy
|
|
40
|
+
source folders such as `tests/schemas/`.
|
|
41
|
+
|
|
42
|
+
Mongo/Redis integration settings load explicit process env first, then
|
|
43
|
+
`tests/.env`, then the umbrella `keble.backend/.env` through
|
|
44
|
+
`keble_db.testing.resolve_test_env`. Live LLM settings load explicit `LIVE_LLM_*`
|
|
45
|
+
values first and otherwise map the first backend Azure endpoint/token/deployment
|
|
46
|
+
entry. Set `KEBLE_BACKEND_ENV_FILE=/path/to/.env` from unusual worktree or CI
|
|
47
|
+
layouts. Keep the package-owned test database and collection names isolated.
|
|
48
|
+
|
|
49
|
+
## Change Logs
|
|
50
|
+
|
|
51
|
+
Historical release notes and long AI change history live under `logs/`.
|
|
52
|
+
|
|
53
|
+
## Side Effect If Changes
|
|
54
|
+
|
|
55
|
+
- Backend task APIs, owner task lists, task room sockets, cost accounting,
|
|
56
|
+
and frontend task rows depend on these schemas/events.
|
|
57
|
+
- Relation or graph-context changes can affect all feature rooms that load
|
|
58
|
+
child tasks or background sessions.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Package-owned testing helpers for Keble task tests and downstream suites."""
|
|
2
|
+
|
|
3
|
+
from .config import Settings, build_db, settings
|
|
4
|
+
from .factories import InMemoryCRUDTask, make_task
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"InMemoryCRUDTask",
|
|
8
|
+
"Settings",
|
|
9
|
+
"build_db",
|
|
10
|
+
"make_task",
|
|
11
|
+
"settings",
|
|
12
|
+
]
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"""Environment-backed settings for Keble task integration and live tests."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
from keble_db import Db, DbSettingsABC
|
|
9
|
+
from keble_db.testing import backend_env_values, resolve_test_env
|
|
10
|
+
from pydantic import Field
|
|
11
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _resolve_first_backend_json_list_value(
|
|
17
|
+
*,
|
|
18
|
+
explicit_env_name: str,
|
|
19
|
+
backend_env_name: str,
|
|
20
|
+
) -> str | None:
|
|
21
|
+
"""Resolve a live-test value from explicit env or backend JSON-list config.
|
|
22
|
+
|
|
23
|
+
The package live LLM canary needs one OpenAI-compatible endpoint, token, and
|
|
24
|
+
deployment. Backend stores provider values as JSON-style lists, so task tests
|
|
25
|
+
use the first configured value only when the package-specific `LIVE_LLM_*`
|
|
26
|
+
variable is absent.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
explicit_value = resolve_test_env(explicit_env_name)
|
|
30
|
+
if explicit_value is not None:
|
|
31
|
+
return explicit_value
|
|
32
|
+
|
|
33
|
+
backend_value = backend_env_values().get(backend_env_name)
|
|
34
|
+
if backend_value is None:
|
|
35
|
+
return None
|
|
36
|
+
|
|
37
|
+
parsed_value = json.loads(backend_value)
|
|
38
|
+
if not isinstance(parsed_value, list) or not parsed_value:
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
first_value = parsed_value[0]
|
|
42
|
+
if not isinstance(first_value, str) or first_value.strip() == "":
|
|
43
|
+
return None
|
|
44
|
+
|
|
45
|
+
return first_value.strip()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class Settings(DbSettingsABC, BaseSettings):
|
|
49
|
+
"""Settings protocol implementation used only by opt-in pytest layers."""
|
|
50
|
+
|
|
51
|
+
model_config = SettingsConfigDict(
|
|
52
|
+
env_file="./tests/.env", env_file_encoding="utf-8", case_sensitive=True
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
MONGO_DB_URI: str | None = Field(
|
|
56
|
+
default_factory=lambda: resolve_test_env("MONGO_DB_URI")
|
|
57
|
+
)
|
|
58
|
+
MONGO_DB_DATABASE: str = "__keble_task__pytest__"
|
|
59
|
+
TASK_COLLECTION: str = "__keble_task__pytest__task__"
|
|
60
|
+
TASK_RELATION_COLLECTION: str = "__keble_task__pytest__task_relation__"
|
|
61
|
+
TASK_COST_COLLECTION: str = "__keble_task__pytest__task_cost__"
|
|
62
|
+
|
|
63
|
+
REDIS_URI: str | None = Field(default_factory=lambda: resolve_test_env("REDIS_URI"))
|
|
64
|
+
|
|
65
|
+
LIVE_LLM_ENDPOINT: str | None = Field(
|
|
66
|
+
default_factory=lambda: _resolve_first_backend_json_list_value(
|
|
67
|
+
explicit_env_name="LIVE_LLM_ENDPOINT",
|
|
68
|
+
backend_env_name="AZURE_PROVIDER_ENDPOINTS",
|
|
69
|
+
)
|
|
70
|
+
)
|
|
71
|
+
LIVE_LLM_API_TOKEN: str | None = Field(
|
|
72
|
+
default_factory=lambda: _resolve_first_backend_json_list_value(
|
|
73
|
+
explicit_env_name="LIVE_LLM_API_TOKEN",
|
|
74
|
+
backend_env_name="AZURE_PROVIDER_API_TOKENS",
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
LIVE_LLM_CHAT_DEPLOYMENT: str | None = Field(
|
|
78
|
+
default_factory=lambda: _resolve_first_backend_json_list_value(
|
|
79
|
+
explicit_env_name="LIVE_LLM_CHAT_DEPLOYMENT",
|
|
80
|
+
backend_env_name="AZURE_OPENAI_CHAT_MODELS_DEPLOYMENTS",
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def qdrant_host(self) -> str | None:
|
|
86
|
+
"""Return no Qdrant host because task tests do not use Qdrant."""
|
|
87
|
+
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def qdrant_port(self) -> int | None:
|
|
92
|
+
"""Return no Qdrant port because task tests do not use Qdrant."""
|
|
93
|
+
|
|
94
|
+
return None
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def qdrant_collection(self) -> str | None:
|
|
98
|
+
"""Return no Qdrant collection because task tests do not use Qdrant."""
|
|
99
|
+
|
|
100
|
+
return None
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def mongo_db_uri(self) -> str | None:
|
|
104
|
+
"""Expose the configured Mongo URI through the keble-db protocol."""
|
|
105
|
+
|
|
106
|
+
return self.MONGO_DB_URI
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def mongo_db_database(self) -> str:
|
|
110
|
+
"""Expose the configured Mongo database through the keble-db protocol."""
|
|
111
|
+
|
|
112
|
+
return self.MONGO_DB_DATABASE
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def redis_uri(self) -> str | None:
|
|
116
|
+
"""Expose the configured Redis URI through the keble-db protocol."""
|
|
117
|
+
|
|
118
|
+
return self.REDIS_URI
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def sql_write_uri(self) -> str | None:
|
|
122
|
+
"""Return no SQL write URI because task tests do not use SQL."""
|
|
123
|
+
|
|
124
|
+
return None
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def sql_read_uri(self) -> str | None:
|
|
128
|
+
"""Return no SQL read URI because task tests do not use SQL."""
|
|
129
|
+
|
|
130
|
+
return None
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def sql_uri(self) -> str | None:
|
|
134
|
+
"""Return no SQL URI because task tests do not use SQL."""
|
|
135
|
+
|
|
136
|
+
return None
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def neo4j_uri(self) -> str | None:
|
|
140
|
+
"""Return no Neo4j URI because task tests do not use Neo4j."""
|
|
141
|
+
|
|
142
|
+
return None
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def neo4j_user(self) -> str | None:
|
|
146
|
+
"""Return no Neo4j user because task tests do not use Neo4j."""
|
|
147
|
+
|
|
148
|
+
return None
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def neo4j_password(self) -> str | None:
|
|
152
|
+
"""Return no Neo4j password because task tests do not use Neo4j."""
|
|
153
|
+
|
|
154
|
+
return None
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def neo4j_database(self) -> str | None:
|
|
158
|
+
"""Return no Neo4j database because task tests do not use Neo4j."""
|
|
159
|
+
|
|
160
|
+
return None
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
settings = Settings()
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def build_db() -> Db:
|
|
167
|
+
"""Build a keble-db adapter only after a test opts into real services."""
|
|
168
|
+
|
|
169
|
+
return Db(settings)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""Reusable task test doubles and factories."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import uuid
|
|
6
|
+
from datetime import datetime, timezone
|
|
7
|
+
|
|
8
|
+
from bson import ObjectId
|
|
9
|
+
from keble_helpers import SharingScope, Status
|
|
10
|
+
|
|
11
|
+
from keble_task.schemas import TaskMongoObject, TaskStage
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class InMemoryCRUDTask:
|
|
15
|
+
"""Minimal in-memory CRUDTask stand-in for TaskClient unit tests."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, task: TaskMongoObject) -> None:
|
|
18
|
+
"""Store one task row by Mongo ObjectId for deterministic unit tests."""
|
|
19
|
+
|
|
20
|
+
self._tasks = {task.id: task}
|
|
21
|
+
|
|
22
|
+
async def aincrement_attempts(self, amongo, *, _id: ObjectId) -> TaskMongoObject:
|
|
23
|
+
"""Increment attempts on the stored task and return the updated row."""
|
|
24
|
+
|
|
25
|
+
task = self._tasks[_id]
|
|
26
|
+
updated = task.model_copy(update={"attempts": int(task.attempts) + 1})
|
|
27
|
+
self._tasks[_id] = updated
|
|
28
|
+
return updated
|
|
29
|
+
|
|
30
|
+
async def aupdate(self, amongo, *, _id: ObjectId, obj_in: dict) -> None:
|
|
31
|
+
"""Apply a partial update to the stored task row."""
|
|
32
|
+
|
|
33
|
+
task = self._tasks[_id]
|
|
34
|
+
self._tasks[_id] = task.model_copy(update=obj_in)
|
|
35
|
+
|
|
36
|
+
async def afirst_by_id(self, amongo, *, _id: ObjectId) -> TaskMongoObject | None:
|
|
37
|
+
"""Return the stored task for an ObjectId, if it exists."""
|
|
38
|
+
|
|
39
|
+
return self._tasks.get(_id)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def make_task(
|
|
43
|
+
*,
|
|
44
|
+
expected_token: int = 1,
|
|
45
|
+
consumed_token: int = 0,
|
|
46
|
+
metadata: dict | None = None,
|
|
47
|
+
) -> TaskMongoObject:
|
|
48
|
+
"""Build a valid task row for TaskClient unit and contract tests."""
|
|
49
|
+
|
|
50
|
+
return TaskMongoObject(
|
|
51
|
+
id=ObjectId(),
|
|
52
|
+
stage=TaskStage.PENDING,
|
|
53
|
+
task_type=str(uuid.uuid4()),
|
|
54
|
+
progress_key=str(uuid.uuid4()),
|
|
55
|
+
title=None,
|
|
56
|
+
subtitle=None,
|
|
57
|
+
image="https://example.com/x.png",
|
|
58
|
+
metadata=metadata,
|
|
59
|
+
sharing_scope=SharingScope.PRIVATE,
|
|
60
|
+
status=Status.ACTIVE,
|
|
61
|
+
owner=str(uuid.uuid4()),
|
|
62
|
+
expected_token=expected_token,
|
|
63
|
+
consumed_token=consumed_token,
|
|
64
|
+
attempts=0,
|
|
65
|
+
timeout_mins=120,
|
|
66
|
+
created=datetime.now(timezone.utc),
|
|
67
|
+
)
|
keble_task-2.22.0/AiAgentChangesLogs.md → keble_task-2.22.1/logs/AiAgentChangesLogs.20260630.md
RENAMED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
## 2026-06-30 22:07 CST
|
|
2
|
+
State: `keble-task` strict test folder normalization on branch `refactor/testing-normalization-keble-task`.
|
|
3
|
+
|
|
4
|
+
zma:
|
|
5
|
+
- Continue the strict cross-repo testing cleanup from `prompts/20260630/1.3 cross-repos-tests-boost.md`.
|
|
6
|
+
- Enforce canonical test folders and marker allowances from the updated root `TESTING_GUIDELINE.md`.
|
|
7
|
+
|
|
8
|
+
Ai:
|
|
9
|
+
- Moved executable tests from flat `tests/test_*.py` and legacy `tests/schemas/` into canonical `tests/unit`, `tests/contract`, `tests/integration`, and `tests/live` roots.
|
|
10
|
+
- Updated pytest collection marking to classify tests by canonical layer folder and mark Mongo/Redis task-client tests with `integration`, `db`, `mongo`, and `redis`.
|
|
11
|
+
- Added missing `redis` and `container` marker registrations to keep the repo aligned with the shared marker vocabulary.
|
|
12
|
+
- Updated README/AGENTS/CLAUDE to forbid new flat or legacy test folders and to use the stricter default test command.
|
|
13
|
+
|
|
1
14
|
## 2026-06-30 13:42 CST
|
|
2
15
|
State: branch `refactor/testing-layers-keble-task`; package line moving from `2.21.0` to `2.22.0`.
|
|
3
16
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "keble-task"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.22.1"
|
|
4
4
|
description = ""
|
|
5
5
|
authors = ["zhenhao-ma <bob0103779@gmail.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -10,7 +10,7 @@ classifiers = [
|
|
|
10
10
|
[tool.poetry.dependencies]
|
|
11
11
|
python = ">=3.13,<3.14"
|
|
12
12
|
keble-helpers = ">=1.12.6,<2.0.0"
|
|
13
|
-
keble-db = ">=1.
|
|
13
|
+
keble-db = ">=1.8.1,<2.0.0"
|
|
14
14
|
pydantic-ai-slim = ">=1.41.0,<2.0.0"
|
|
15
15
|
tenacity = ">=9,<10.0.0"
|
|
16
16
|
|
|
@@ -4,11 +4,11 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "keble-task"
|
|
7
|
-
version = "2.22.
|
|
7
|
+
version = "2.22.1"
|
|
8
8
|
description = ""
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13,<3.14"
|
|
11
|
-
dependencies = ["keble-helpers>=1.40.0,<2.0.0", "keble-db>=1.
|
|
11
|
+
dependencies = ["keble-helpers>=1.40.0,<2.0.0", "keble-db>=1.8.1,<2.0.0", "pydantic-ai-slim>=1.41.0,<2.0.0", "tenacity>=9,<10.0.0"]
|
|
12
12
|
|
|
13
13
|
[[project.authors]]
|
|
14
14
|
name = "zhenhao-ma"
|
|
@@ -24,7 +24,6 @@ test = ["pytest>=8,<9.0.0", "pytest-asyncio>=0,<1.0.0", "pydantic-ai-slim[openai
|
|
|
24
24
|
default-groups = ["test"]
|
|
25
25
|
|
|
26
26
|
[tool.uv.sources]
|
|
27
|
-
keble-db = {path = "../keble-py/keble-db"}
|
|
28
27
|
keble-helpers = {path = "../keble-py/keble-helpers"}
|
|
29
28
|
|
|
30
29
|
[tool.hatch.build]
|
|
@@ -42,8 +41,10 @@ markers = [
|
|
|
42
41
|
"db: any real database test",
|
|
43
42
|
"postgres: PostgreSQL tests",
|
|
44
43
|
"mongo: MongoDB tests",
|
|
44
|
+
"redis: Redis tests",
|
|
45
45
|
"qdrant: Qdrant tests",
|
|
46
46
|
"neo4j: Neo4j tests",
|
|
47
|
+
"container: tests that start Testcontainers resources",
|
|
47
48
|
"db_stack: multi-database integration tests",
|
|
48
49
|
"keepa: Keepa-related tests",
|
|
49
50
|
"keepa_contract: recorded Keepa contract tests",
|