weakincentives 0.1.0__tar.gz → 0.2.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.

Potentially problematic release.


This version of weakincentives might be problematic. Click here for more details.

Files changed (64) hide show
  1. {weakincentives-0.1.0 → weakincentives-0.2.0}/.github/workflows/release.yml +4 -1
  2. weakincentives-0.2.0/AGENTS.md +95 -0
  3. weakincentives-0.2.0/CHANGELOG.md +29 -0
  4. weakincentives-0.2.0/Makefile +58 -0
  5. weakincentives-0.2.0/PKG-INFO +173 -0
  6. weakincentives-0.2.0/README.md +146 -0
  7. weakincentives-0.2.0/ROADMAP.md +64 -0
  8. weakincentives-0.2.0/WARP.md +3 -0
  9. weakincentives-0.2.0/concat_all.py +63 -0
  10. weakincentives-0.2.0/openai_example.py +278 -0
  11. weakincentives-0.2.0/pyproject.toml +102 -0
  12. weakincentives-0.2.0/specs/ADAPTERS.md +168 -0
  13. weakincentives-0.2.0/specs/DATACLASS_SERDE.md +159 -0
  14. weakincentives-0.2.0/specs/PROMPTS.md +158 -0
  15. weakincentives-0.2.0/specs/STRUCTURED_OUTPUT.md +222 -0
  16. weakincentives-0.2.0/specs/TOOLS.md +166 -0
  17. weakincentives-0.2.0/src/weakincentives/__init__.py +15 -0
  18. weakincentives-0.2.0/src/weakincentives/adapters/__init__.py +30 -0
  19. weakincentives-0.2.0/src/weakincentives/adapters/core.py +85 -0
  20. weakincentives-0.2.0/src/weakincentives/adapters/openai.py +361 -0
  21. weakincentives-0.2.0/src/weakincentives/prompts/__init__.py +45 -0
  22. weakincentives-0.2.0/src/weakincentives/prompts/_types.py +27 -0
  23. weakincentives-0.2.0/src/weakincentives/prompts/errors.py +57 -0
  24. weakincentives-0.2.0/src/weakincentives/prompts/prompt.py +440 -0
  25. weakincentives-0.2.0/src/weakincentives/prompts/response_format.py +54 -0
  26. weakincentives-0.2.0/src/weakincentives/prompts/section.py +120 -0
  27. weakincentives-0.2.0/src/weakincentives/prompts/structured.py +140 -0
  28. weakincentives-0.2.0/src/weakincentives/prompts/text.py +89 -0
  29. weakincentives-0.2.0/src/weakincentives/prompts/tool.py +236 -0
  30. weakincentives-0.2.0/src/weakincentives/serde/__init__.py +31 -0
  31. weakincentives-0.2.0/src/weakincentives/serde/dataclass_serde.py +1016 -0
  32. weakincentives-0.2.0/tests/adapters/test_openai_adapter.py +717 -0
  33. weakincentives-0.2.0/tests/prompts/test_exceptions.py +52 -0
  34. weakincentives-0.2.0/tests/prompts/test_prompt_edge_cases.py +244 -0
  35. weakincentives-0.2.0/tests/prompts/test_prompt_init.py +163 -0
  36. weakincentives-0.2.0/tests/prompts/test_prompt_integration.py +126 -0
  37. weakincentives-0.2.0/tests/prompts/test_prompt_render.py +239 -0
  38. weakincentives-0.2.0/tests/prompts/test_prompt_tools.py +214 -0
  39. weakincentives-0.2.0/tests/prompts/test_prompt_tools_integration.py +89 -0
  40. weakincentives-0.2.0/tests/prompts/test_section_base.py +73 -0
  41. weakincentives-0.2.0/tests/prompts/test_section_tools.py +87 -0
  42. weakincentives-0.2.0/tests/prompts/test_structured_output.py +276 -0
  43. weakincentives-0.2.0/tests/prompts/test_text_section.py +83 -0
  44. weakincentives-0.2.0/tests/prompts/test_tool_dataclass.py +314 -0
  45. weakincentives-0.2.0/tests/prompts/test_typing_specializations.py +92 -0
  46. weakincentives-0.2.0/tests/serde/test_dataclass_serde.py +1318 -0
  47. weakincentives-0.2.0/tests/test_example.py +17 -0
  48. weakincentives-0.2.0/tests/test_openai_example.py +158 -0
  49. weakincentives-0.2.0/uv.lock +865 -0
  50. weakincentives-0.1.0/Makefile +0 -37
  51. weakincentives-0.1.0/PKG-INFO +0 -21
  52. weakincentives-0.1.0/README.md +0 -12
  53. weakincentives-0.1.0/WARP.md +0 -104
  54. weakincentives-0.1.0/pyproject.toml +0 -33
  55. weakincentives-0.1.0/src/weakincentives/__init__.py +0 -2
  56. weakincentives-0.1.0/tests/test_example.py +0 -11
  57. weakincentives-0.1.0/uv.lock +0 -186
  58. {weakincentives-0.1.0 → weakincentives-0.2.0}/.github/workflows/ci.yml +0 -0
  59. {weakincentives-0.1.0 → weakincentives-0.2.0}/.gitignore +0 -0
  60. {weakincentives-0.1.0 → weakincentives-0.2.0}/.python-version +0 -0
  61. {weakincentives-0.1.0 → weakincentives-0.2.0}/LICENSE +0 -0
  62. {weakincentives-0.1.0 → weakincentives-0.2.0}/hooks/pre-commit +0 -0
  63. {weakincentives-0.1.0 → weakincentives-0.2.0}/install-hooks.sh +0 -0
  64. {weakincentives-0.1.0 → weakincentives-0.2.0}/src/weakincentives/py.typed +0 -0
@@ -29,10 +29,13 @@ jobs:
29
29
 
30
30
  - name: Install dependencies
31
31
  run: uv sync
32
-
32
+
33
33
  - name: Run checks
34
34
  run: make check
35
35
 
36
+ - name: Restore clean lockfile
37
+ run: git checkout -- uv.lock
38
+
36
39
  - name: Build package
37
40
  run: uv build
38
41
 
@@ -0,0 +1,95 @@
1
+ # AGENTS.md
2
+
3
+ This handbook is the primary source of truth for autonomous or assisted agents working in the `weakincentives` repository. WARP and other entrypoints should defer to this document.
4
+
5
+ ## Project Snapshot
6
+
7
+ - **Goal**: Build tooling for "side effect free" background agents; current codebase is intentionally minimal and pre-alpha.
8
+ - **Language**: Python 3.14 (see `.python-version`).
9
+ - **Package manager**: [`uv`](https://github.com/astral-sh/uv) orchestrates dependency management and task execution.
10
+ - **Build backend**: `hatchling` (configured in `pyproject.toml`).
11
+
12
+ ## Repository Tour
13
+
14
+ - `src/weakincentives/`: Library source. Currently contains the prompt scaffolding and supporting modules.
15
+ - `tests/`: Pytest suite. `tests/test_example.py` demonstrates the expected structure and ensures the package imports.
16
+ - `specs/`: Design docs and product specifications. `PROMPTS.md` defines the prompt abstraction requirements—read this before adding prompt-related code.
17
+ - `Makefile`: Canonical task surface (formatting, linting, typing, tests, aggregate checks, clean-up).
18
+ - `uv.lock`: Dependency lockfile maintained by `uv`.
19
+ - `hooks/` & `install-hooks.sh`: Symlink-based Git hook installer. Hooks expect `make check` to pass before commits land.
20
+ - Version tags (`vX.Y.Z`, the `v` prefix is required) in git control the published package version; cut them manually when releasing.
21
+
22
+ ## Environment & Setup
23
+
24
+ 1. Install Python 3.14 (pyenv users can run `pyenv install 3.14.0` if needed).
25
+ 1. Install `uv` locally.
26
+ 1. Sync dependencies and development tooling:
27
+ ```bash
28
+ uv sync
29
+ ./install-hooks.sh
30
+ ```
31
+ The hook installer wires every script in `hooks/` into `.git/hooks/` via symlinks.
32
+
33
+ ## Day-to-Day Commands
34
+
35
+ All commands are defined in `Makefile` and should be executed with `uv` to ensure a consistent virtualenv. The targets are configured to run in quiet mode—by default they suppress success chatter and surface only warnings or errors. Mirror this style when invoking tools manually so downstream agents process as few tokens as possible.
36
+
37
+ - `make format`: Auto-format via `ruff format -q`.
38
+ - `make format-check`: Formatting audit without changes (`ruff format -q --check`).
39
+ - `make lint` / `make lint-fix`: Static analysis with Ruff in quiet mode (`ruff check --preview -q`; add `--fix` when autofixing).
40
+ - `make bandit`: Security linting via `build/run_bandit.py`, which patches Python 3.14 AST regressions before invoking Bandit.
41
+ - `make deptry`: Dependency graph audit on `src/weakincentives` that surfaces unused or missing requirements while staying quiet on success.
42
+ - `make pip-audit`: Dependency vulnerability audit that stays silent on success via `build/run_pip_audit.py`.
43
+ - `make markdown-check`: Runs `mdformat --check` through `build/run_mdformat.py` to ensure Markdown stays consistently formatted. This command now runs inside `make check`.
44
+ - `make typecheck`: Runs `ty check -qq --error-on-warning` for silent success.
45
+ - `make test`: Executes pytest through `build/run_pytest.py`, only emitting failures or warnings while enforcing coverage (`--cov-fail-under=80`).
46
+ - `make check`: Aggregates format-check, lint, typecheck, Bandit, deptry, pip-audit, markdown-check, and tests with minimal output.
47
+ - `make all`: Runs format, lint-fix, Bandit, pip-audit, typecheck, and tests while staying quiet on success.
48
+ - `make clean`: Purges caches (`__pycache__`, `.pytest_cache`, `.ruff_cache`, `*.pyc`).
49
+
50
+ Prefer `make check` before every commit; git hooks will call the same pipeline.
51
+
52
+ **You MUST run `make check` before committing any changes.**
53
+
54
+ ## Optional Dependencies
55
+
56
+ - `openai` is exposed as an extra. Install it with `uv sync --extra openai` during development or `pip install weakincentives[openai]` for consumers. Adapter modules guard imports and raise clear guidance when the extra is missing, so the core package stays lean.
57
+ - `make test` (and thus `make check` / `make all`) automatically run with all extras enabled via `uv run --all-extras`, ensuring adapter integrations stay validated.
58
+
59
+ ## Testing & Quality Expectations
60
+
61
+ - Pytest is configured in `pyproject.toml` to collect coverage on `src/weakincentives` and fail if coverage dips below 80%.
62
+ - Type hints are part of the public contract (`py.typed`). Keep new code fully typed and run `make typecheck` when touching typing-sensitive areas.
63
+ - Ruff is both the formatter and the linter. Obey the default line length of 88 and the Python target version `py314`.
64
+ - Lint runs enable `I`, `UP`, `B`, `SIM`, `C4`, `ANN`, `RET`, `RSE`, `PTH`, and `ISC` rule families; fix or explicitly justify any violations when contributing.
65
+
66
+ ## TDD Workflow Recipe
67
+
68
+ - Read the relevant spec in `specs/` and any prior plans to anchor scope, capture target module paths, and list the concrete behaviors you will validate.
69
+ - Break the work into thin iterations that each pair a specific test module or case (for example `tests/prompts/test_text_section.py`) with the minimal production changes required in `src/weakincentives/`.
70
+ - For every iteration, author the failing test first, run it directly with `uv run pytest tests/path_to_test.py -k target_case`, and confirm it asserts the desired API, errors, and context payloads.
71
+ - Implement only the code needed to satisfy the new test (including exports and defaults), then rerun the targeted test and expand to `make test` once the local loop is green.
72
+ - Refactor immediately after the test passes: deduplicate helpers, thread depth or placeholder metadata, and update docs so the next iteration starts from a clean slate.
73
+ - Repeat the loop until the feature-level acceptance scenario is covered, finish with `make check`, and capture the final iteration summary in the commit message or handoff notes.
74
+
75
+ ## Release & Versioning Notes
76
+
77
+ - Package releases read their version from the latest git tag (`vX.Y.Z`, must include the `v`). Use `git tag vX.Y.Z` followed by `git push origin vX.Y.Z` when you’re ready to release.
78
+ - No publishing automation exists yet—coordinate manual releases outside this repository.
79
+
80
+ ## Adding Features
81
+
82
+ - Mirror the structure in `tests/` when adding new modules—write tests alongside new code and keep them deterministic.
83
+ - Follow test-driven development best practices while iterating; commit to the red→green→refactor loop so features stay focused and covered.
84
+ - Reference `specs/PROMPTS.md` before modifying or introducing prompt-related functionality.
85
+ - Write commit messages with useful descriptions that summarize the change set; avoid placeholder or empty messages.
86
+ - Keep the `README.md` concise; extended onboarding belongs here in `AGENTS.md`.
87
+ - When introducing new tooling, extend the `Makefile` so agents can discover it without hunting through scripts.
88
+
89
+ ## Quick Facts
90
+
91
+ - `README.md` offers a public-facing overview; this document captures agent-facing operational details.
92
+ - The codebase is intentionally small; expect to create new modules under `src/weakincentives/` rather than modifying many existing files.
93
+ - All documentation should be ASCII unless the surrounding file already uses other characters.
94
+
95
+ Use this document as the authoritative onboarding and execution guide for automated agents. Update it whenever workflows or tooling change.
@@ -0,0 +1,29 @@
1
+ # Changelog
2
+
3
+ Release highlights for weakincentives.
4
+
5
+ ## v0.2.0 - 2025-10-29
6
+
7
+ ### Highlights
8
+
9
+ - Launched the prompt composition system with typed `Prompt`, `Section`, and `TextSection` building blocks, structured rendering, and placeholder validation backed by comprehensive tests.
10
+ - Added tool orchestration primitives including the `Tool` dataclass, shared dataclass handling, duplicate detection, and prompt-level aggregation utilities.
11
+ - Delivered stdlib-only dataclass serde helpers (`parse`, `dump`, `clone`, `schema`) for lightweight validation and JSON serialization.
12
+
13
+ ### Integrations
14
+
15
+ - Introduced an optional OpenAI adapter behind the `openai` extra that builds configured clients and provides friendly guidance when the dependency is missing.
16
+
17
+ ### Developer Experience
18
+
19
+ - Tightened the quality gate with quiet wrappers for Ruff, Ty, pytest (100% coverage), Bandit, Deptry, and pip-audit, all wired through `make check`.
20
+ - Adopted Hatch VCS versioning, refreshed `pyproject.toml` metadata, and standardized automation scripts for releases.
21
+
22
+ ### Documentation
23
+
24
+ - Replaced `WARP.md` with a comprehensive `AGENTS.md` handbook describing workflows, TDD guidance, and integration expectations.
25
+ - Added prompt and tool specifications under `specs/` and refreshed the README to highlight the new primitives and developer tooling.
26
+
27
+ ## v0.1.0 - 2025-10-22
28
+
29
+ Initial repository bootstrap with the package scaffold, testing and linting toolchain, CI configuration, and contributor documentation.
@@ -0,0 +1,58 @@
1
+ .PHONY: format check test lint typecheck bandit deptry pip-audit markdown-check all clean
2
+
3
+ # Format code with ruff
4
+ format:
5
+ @uv run ruff format -q .
6
+
7
+ # Check formatting without making changes
8
+ format-check:
9
+ @uv run ruff format -q --check .
10
+
11
+ # Run ruff linter
12
+ lint:
13
+ @uv run ruff check --preview -q .
14
+
15
+ # Run ruff linter with fixes
16
+ lint-fix:
17
+ @uv run ruff check --fix -q .
18
+
19
+ # Run Bandit security scanner
20
+ bandit:
21
+ @uv run python build/run_bandit.py -q -r src/weakincentives
22
+
23
+ # Check for unused or missing dependencies with deptry
24
+ deptry:
25
+ @uv run python build/run_deptry.py
26
+
27
+ # Run pip-audit for dependency vulnerabilities
28
+ pip-audit:
29
+ @uv run python build/run_pip_audit.py
30
+
31
+ # Validate Markdown formatting
32
+ markdown-check:
33
+ @uv run python build/run_mdformat.py
34
+
35
+ # Run type checkers
36
+ typecheck:
37
+ @uv run --all-extras ty check --error-on-warning -qq . || \
38
+ (echo "ty check failed; rerunning with verbose output..." >&2; \
39
+ uv run --all-extras ty check --error-on-warning .)
40
+ @uv run --all-extras pyright --project pyproject.toml || \
41
+ (echo "pyright failed; rerunning with verbose output..." >&2; \
42
+ uv run --all-extras pyright --project pyproject.toml --verbose)
43
+
44
+ # Run tests with coverage (100% minimum)
45
+ test:
46
+ @uv run --all-extras python build/run_pytest.py --strict-config --strict-markers --maxfail=1 --cov-fail-under=100 -q --no-header --no-summary --cov-report=
47
+
48
+ # Run all checks (format check, lint, typecheck, bandit, deptry, pip-audit, markdown, test)
49
+ check: format-check lint typecheck bandit deptry pip-audit markdown-check test
50
+
51
+ # Run all checks and fixes
52
+ all: format lint-fix bandit deptry pip-audit typecheck test
53
+
54
+ # Clean cache files
55
+ clean:
56
+ rm -rf .pytest_cache .ruff_cache __pycache__
57
+ find . -type d -name "__pycache__" -exec rm -rf {} +
58
+ find . -type f -name "*.pyc" -delete
@@ -0,0 +1,173 @@
1
+ Metadata-Version: 2.4
2
+ Name: weakincentives
3
+ Version: 0.2.0
4
+ Summary: Tools for developing and optimizing side effect free background agents
5
+ Project-URL: Homepage, https://weakincentives.com/
6
+ Project-URL: Documentation, https://github.com/weakincentives/weakincentives#readme
7
+ Project-URL: Repository, https://github.com/weakincentives/weakincentives
8
+ Project-URL: Issue Tracker, https://github.com/weakincentives/weakincentives/issues
9
+ Author-email: Andrei Savu <andrei@weakincentives.com>
10
+ License: Apache-2.0
11
+ License-File: LICENSE
12
+ Keywords: agents,ai,background-agents,optimization,side-effect-free,weak-incentives
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: Apache Software License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.14
24
+ Provides-Extra: openai
25
+ Requires-Dist: openai>=2.6.1; extra == 'openai'
26
+ Description-Content-Type: text/markdown
27
+
28
+ # Weak Incentives
29
+
30
+ Tools for developing and optimizing side effect free background agents. The library ships prompt composition primitives, structured tool metadata, and optional provider adapters so you can scaffold deterministic automation flows quickly. All commands below assume Astral's `uv` CLI.
31
+
32
+ ## For Library Users
33
+
34
+ ### Installation
35
+
36
+ - `uv add weakincentives`
37
+ - Add `uv add "weakincentives[openai]"` (or `uv sync --extra openai` when cloning the repo) to enable the OpenAI adapter helpers.
38
+
39
+ ### Key Features
40
+
41
+ - Fully typed prompt composition primitives (`Prompt`, `Section`, `TextSection`, `Tool`, `ToolResult`) for assembling deterministic Markdown prompts with attached tool metadata.
42
+ - Stdlib-only dataclass serde utilities (`parse`, `dump`, `clone`, `schema`) for Pydantic-like ergonomics without third-party dependencies.
43
+ - Optional OpenAI adapter that gates imports behind a friendly error and returns the SDK client when the extra is present.
44
+ - Quiet-by-default package with minimal runtime dependencies so background agents stay lean and predictable.
45
+
46
+ ### Quickstart
47
+
48
+ ````python
49
+ from dataclasses import dataclass
50
+
51
+ from weakincentives.prompts import (
52
+ Prompt,
53
+ TextSection,
54
+ Tool,
55
+ ToolResult,
56
+ parse_output,
57
+ )
58
+
59
+
60
+ @dataclass
61
+ class ResearchGuidance:
62
+ topic: str
63
+
64
+
65
+ @dataclass
66
+ class SourceLookup:
67
+ source_id: str
68
+
69
+
70
+ @dataclass
71
+ class SourceDetails:
72
+ source_id: str
73
+ title: str
74
+
75
+
76
+ @dataclass
77
+ class ResearchSummary:
78
+ summary: str
79
+ citations: list[str]
80
+
81
+
82
+ def lookup_source(params: SourceLookup) -> ToolResult[SourceDetails]:
83
+ details = SourceDetails(source_id=params.source_id, title="Ada Lovelace Archive")
84
+ return ToolResult(message=f"Loaded {details.title}", payload=details)
85
+
86
+
87
+ catalog_tool = Tool[SourceLookup, SourceDetails](
88
+ name="catalog_lookup",
89
+ description="Look up a primary source identifier and return structured details.",
90
+ handler=lookup_source,
91
+ )
92
+
93
+ research_section = TextSection[ResearchGuidance](
94
+ title="Task",
95
+ body=(
96
+ "Research ${topic}. Use the `catalog_lookup` tool for citations and return"
97
+ " a JSON summary with citations."
98
+ ),
99
+ tools=[catalog_tool],
100
+ )
101
+
102
+ prompt = Prompt[ResearchSummary](
103
+ name="research_run",
104
+ sections=[research_section],
105
+ )
106
+
107
+ rendered = prompt.render(ResearchGuidance(topic="Ada Lovelace"))
108
+ print(rendered.text)
109
+ print([tool.name for tool in rendered.tools])
110
+
111
+ reply = """```json
112
+ {
113
+ "summary": "Ada Lovelace pioneered computing...",
114
+ "citations": ["catalog_lookup:ada-archive"]
115
+ }
116
+ ```"""
117
+
118
+ parsed = parse_output(reply, rendered)
119
+ print(parsed.summary)
120
+ print(parsed.citations)
121
+ ````
122
+
123
+ ### Optional Extras
124
+
125
+ Use the OpenAI helpers once the extra is installed:
126
+
127
+ ```python
128
+ from weakincentives.adapters import OpenAIAdapter
129
+
130
+ adapter = OpenAIAdapter(model="gpt-4o-mini", client_kwargs={"api_key": "sk-..."})
131
+ ```
132
+
133
+ If the dependency is missing, the adapter raises a runtime error with installation guidance.
134
+
135
+ ## For Library Developers
136
+
137
+ ### Environment Setup
138
+
139
+ 1. Install Python 3.14 (pyenv users can run `pyenv install 3.14.0`).
140
+ 1. Install [`uv`](https://github.com/astral-sh/uv).
141
+ 1. Sync the virtualenv and optional git hooks:
142
+ ```bash
143
+ uv sync
144
+ ./install-hooks.sh # optional – wires git hooks that call make check
145
+ ```
146
+ 1. Use `uv run ...` when invoking ad-hoc scripts so everything stays inside the managed environment.
147
+
148
+ ### Development Workflow
149
+
150
+ - `make format` / `make format-check` — run Ruff formatters.
151
+ - `make lint` / `make lint-fix` — lint with Ruff.
152
+ - `make typecheck` — execute Ty with warnings promoted to errors.
153
+ - `make test` — run pytest via `build/run_pytest.py` with `--cov-fail-under=100`.
154
+ - `make bandit`, `make deptry`, `make pip-audit` — security, dependency, and vulnerability audits.
155
+ - `make check` — aggregate the quiet quality gate; run this before every commit (git hooks enforce it).
156
+
157
+ ### Project Layout
158
+
159
+ - `src/weakincentives/` — package root for the Python module.
160
+ - `src/weakincentives/prompts/` — prompt, section, and tool primitives.
161
+ - `src/weakincentives/adapters/` — optional provider integrations.
162
+ - `tests/` — pytest suites covering prompts, tools, and adapters.
163
+ - `specs/` — design docs; see `specs/PROMPTS.md` for prompt requirements.
164
+ - `build/` — thin wrappers that keep CLI tools quiet inside `uv`.
165
+ - `hooks/` — symlink-friendly git hooks (install via `./install-hooks.sh`).
166
+
167
+ ### Release Notes
168
+
169
+ Version numbers come from git tags named `vX.Y.Z`. Tag the repository manually before pushing a release.
170
+
171
+ ### More Documentation
172
+
173
+ `AGENTS.md` captures the full agent handbook, workflows, and TDD expectations. `ROADMAP.md` and `specs/` document upcoming work and prompt requirements.
@@ -0,0 +1,146 @@
1
+ # Weak Incentives
2
+
3
+ Tools for developing and optimizing side effect free background agents. The library ships prompt composition primitives, structured tool metadata, and optional provider adapters so you can scaffold deterministic automation flows quickly. All commands below assume Astral's `uv` CLI.
4
+
5
+ ## For Library Users
6
+
7
+ ### Installation
8
+
9
+ - `uv add weakincentives`
10
+ - Add `uv add "weakincentives[openai]"` (or `uv sync --extra openai` when cloning the repo) to enable the OpenAI adapter helpers.
11
+
12
+ ### Key Features
13
+
14
+ - Fully typed prompt composition primitives (`Prompt`, `Section`, `TextSection`, `Tool`, `ToolResult`) for assembling deterministic Markdown prompts with attached tool metadata.
15
+ - Stdlib-only dataclass serde utilities (`parse`, `dump`, `clone`, `schema`) for Pydantic-like ergonomics without third-party dependencies.
16
+ - Optional OpenAI adapter that gates imports behind a friendly error and returns the SDK client when the extra is present.
17
+ - Quiet-by-default package with minimal runtime dependencies so background agents stay lean and predictable.
18
+
19
+ ### Quickstart
20
+
21
+ ````python
22
+ from dataclasses import dataclass
23
+
24
+ from weakincentives.prompts import (
25
+ Prompt,
26
+ TextSection,
27
+ Tool,
28
+ ToolResult,
29
+ parse_output,
30
+ )
31
+
32
+
33
+ @dataclass
34
+ class ResearchGuidance:
35
+ topic: str
36
+
37
+
38
+ @dataclass
39
+ class SourceLookup:
40
+ source_id: str
41
+
42
+
43
+ @dataclass
44
+ class SourceDetails:
45
+ source_id: str
46
+ title: str
47
+
48
+
49
+ @dataclass
50
+ class ResearchSummary:
51
+ summary: str
52
+ citations: list[str]
53
+
54
+
55
+ def lookup_source(params: SourceLookup) -> ToolResult[SourceDetails]:
56
+ details = SourceDetails(source_id=params.source_id, title="Ada Lovelace Archive")
57
+ return ToolResult(message=f"Loaded {details.title}", payload=details)
58
+
59
+
60
+ catalog_tool = Tool[SourceLookup, SourceDetails](
61
+ name="catalog_lookup",
62
+ description="Look up a primary source identifier and return structured details.",
63
+ handler=lookup_source,
64
+ )
65
+
66
+ research_section = TextSection[ResearchGuidance](
67
+ title="Task",
68
+ body=(
69
+ "Research ${topic}. Use the `catalog_lookup` tool for citations and return"
70
+ " a JSON summary with citations."
71
+ ),
72
+ tools=[catalog_tool],
73
+ )
74
+
75
+ prompt = Prompt[ResearchSummary](
76
+ name="research_run",
77
+ sections=[research_section],
78
+ )
79
+
80
+ rendered = prompt.render(ResearchGuidance(topic="Ada Lovelace"))
81
+ print(rendered.text)
82
+ print([tool.name for tool in rendered.tools])
83
+
84
+ reply = """```json
85
+ {
86
+ "summary": "Ada Lovelace pioneered computing...",
87
+ "citations": ["catalog_lookup:ada-archive"]
88
+ }
89
+ ```"""
90
+
91
+ parsed = parse_output(reply, rendered)
92
+ print(parsed.summary)
93
+ print(parsed.citations)
94
+ ````
95
+
96
+ ### Optional Extras
97
+
98
+ Use the OpenAI helpers once the extra is installed:
99
+
100
+ ```python
101
+ from weakincentives.adapters import OpenAIAdapter
102
+
103
+ adapter = OpenAIAdapter(model="gpt-4o-mini", client_kwargs={"api_key": "sk-..."})
104
+ ```
105
+
106
+ If the dependency is missing, the adapter raises a runtime error with installation guidance.
107
+
108
+ ## For Library Developers
109
+
110
+ ### Environment Setup
111
+
112
+ 1. Install Python 3.14 (pyenv users can run `pyenv install 3.14.0`).
113
+ 1. Install [`uv`](https://github.com/astral-sh/uv).
114
+ 1. Sync the virtualenv and optional git hooks:
115
+ ```bash
116
+ uv sync
117
+ ./install-hooks.sh # optional – wires git hooks that call make check
118
+ ```
119
+ 1. Use `uv run ...` when invoking ad-hoc scripts so everything stays inside the managed environment.
120
+
121
+ ### Development Workflow
122
+
123
+ - `make format` / `make format-check` — run Ruff formatters.
124
+ - `make lint` / `make lint-fix` — lint with Ruff.
125
+ - `make typecheck` — execute Ty with warnings promoted to errors.
126
+ - `make test` — run pytest via `build/run_pytest.py` with `--cov-fail-under=100`.
127
+ - `make bandit`, `make deptry`, `make pip-audit` — security, dependency, and vulnerability audits.
128
+ - `make check` — aggregate the quiet quality gate; run this before every commit (git hooks enforce it).
129
+
130
+ ### Project Layout
131
+
132
+ - `src/weakincentives/` — package root for the Python module.
133
+ - `src/weakincentives/prompts/` — prompt, section, and tool primitives.
134
+ - `src/weakincentives/adapters/` — optional provider integrations.
135
+ - `tests/` — pytest suites covering prompts, tools, and adapters.
136
+ - `specs/` — design docs; see `specs/PROMPTS.md` for prompt requirements.
137
+ - `build/` — thin wrappers that keep CLI tools quiet inside `uv`.
138
+ - `hooks/` — symlink-friendly git hooks (install via `./install-hooks.sh`).
139
+
140
+ ### Release Notes
141
+
142
+ Version numbers come from git tags named `vX.Y.Z`. Tag the repository manually before pushing a release.
143
+
144
+ ### More Documentation
145
+
146
+ `AGENTS.md` captures the full agent handbook, workflows, and TDD expectations. `ROADMAP.md` and `specs/` document upcoming work and prompt requirements.
@@ -0,0 +1,64 @@
1
+ # Roadmap
2
+
3
+ ## Near-Term Initiatives
4
+
5
+ ### Session State Container
6
+
7
+ - Formalize a `Session` abstraction that captures conversation state, tool outputs, and transient metadata.
8
+ - Define serialization hooks so sessions can persist across process restarts without leaking sensitive data.
9
+ - Thread the session object through existing prompt and tool layers, backed by integration tests that assert idempotent replay.
10
+
11
+ ### Notes System Retrospectives
12
+
13
+ - Establish a notes pattern that captures retrospectives for individual prompt invocations and entire sessions.
14
+ - Model notes as entities that can attach to `Section` objects and `Tool` objects to preserve context.
15
+ - Outline lifecycle and storage expectations so notes integrate cleanly with existing session state abstractions.
16
+
17
+ ### Single Turn Prompt Optimizations
18
+
19
+ - Profile current single-turn flows to surface latency and token usage hot spots.
20
+ - Experiment with prompt compression techniques and instruction restructuring to maintain quality while reducing cost.
21
+ - Add benchmarks or harness scripts that assert improvements before regression.
22
+
23
+ ### Named Entities Handling (Input and Output)
24
+
25
+ - Introduce utilities for detecting and tagging named entities across inputs.
26
+ - Preserve, normalize, or obfuscate entities in outputs according to privacy and compliance guidelines.
27
+ - Validate the pipeline with targeted tests that cover multilingual and domain-specific vocabularies.
28
+
29
+ ### Built-In Planning & Virtual Filesystem Tools
30
+
31
+ - Provide first-class tool definitions for planning/todo workflows and virtual filesystem operations for agents.
32
+ - Establish section templates that ensure tools render consistently in prompts and downstream telemetry.
33
+ - Ship representative examples and regression tests demonstrating safe defaults and extensibility points.
34
+
35
+ ### Sandboxed Code Execution
36
+
37
+ - Provide hardened sandboxes so agents can run generated code with strict CPU, memory, filesystem, and network guardrails.
38
+ - Surface sandbox lifecycle APIs that expose logs, artifacts, and exit metadata without leaking host resources.
39
+ - Add validation suites and stress tests that assert isolation boundaries hold across supported runtimes.
40
+
41
+ ### Agentic Reasoning Loop
42
+
43
+ - Design an orchestrator that coordinates system prompts, user turns, tool routing, and session state updates.
44
+ - Integrate entity resolvers and named-entity policies to normalize inputs before tool calls and responses.
45
+ - Document the execution phases (think, act, observe) with diagrams and tests that enforce correct transitions.
46
+
47
+ ### Tracing & Observability
48
+
49
+ - Capture structured trace data from agent runs, including tool calls and message content classification.
50
+ - Export telemetry to persistent storage with configurable redaction for sensitive fields and PII.
51
+ - Provide replay and visualization utilities that allow developers to inspect state transitions and timing.
52
+
53
+ ### Subagents & Parallel Execution
54
+
55
+ - Enable the primary agent to spawn scoped subagents with dedicated sessions for independent objectives.
56
+ - Coordinate concurrent execution, result aggregation, and conflict resolution when subagents touch shared resources.
57
+ - Provide lifecycle hooks so subagents inherit policies, tools, and logging while remaining cancellable.
58
+
59
+ ## Out of Scope (For Now)
60
+
61
+ - Graph-based agent composers—current focus is flexible orchestration over rigid node/edge pipelines.
62
+ - Retrieval and memory connectors—the library assumes ambient context rather than external knowledge stores.
63
+ - Human-in-the-loop gating—agents should operate autonomously once launched inside controlled environments.
64
+ - Evaluation frameworks beyond prompt optimization—the only supported eval loops will target prompt tuning scenarios.
@@ -0,0 +1,3 @@
1
+ # WARP.md
2
+
3
+ `AGENTS.md` is the canonical guide for working in this repository. Please follow the workflows documented there.
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env python3
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+
14
+ from __future__ import annotations
15
+
16
+ import sys
17
+ from pathlib import Path
18
+
19
+
20
+ def iter_project_files(target: Path) -> list[Path]:
21
+ if not target.exists():
22
+ return []
23
+ return [
24
+ path
25
+ for path in sorted(target.rglob("*"))
26
+ if path.is_file() and path.suffix != ".pyc"
27
+ ]
28
+
29
+
30
+ def emit_file(path: Path, project_root: Path) -> None:
31
+ relative_path = path.relative_to(project_root).as_posix()
32
+ sys.stdout.write(f"{relative_path}\n")
33
+ with path.open("r", encoding="utf-8", errors="replace") as stream:
34
+ contents = stream.read()
35
+ sys.stdout.write(contents)
36
+ if not contents.endswith("\n"):
37
+ sys.stdout.write("\n")
38
+
39
+
40
+ def main() -> None:
41
+ project_root = Path(__file__).resolve().parent
42
+ prelude_files = [project_root / "README.md", project_root / "ROADMAP.md"]
43
+ postlude_files = [
44
+ project_root / "pyproject.toml",
45
+ project_root / "openai_example.py",
46
+ ]
47
+ targets = [project_root / "specs", project_root / "src"]
48
+
49
+ for path in prelude_files:
50
+ if path.exists():
51
+ emit_file(path, project_root)
52
+
53
+ for target in targets:
54
+ for path in iter_project_files(target):
55
+ emit_file(path, project_root)
56
+
57
+ for path in postlude_files:
58
+ if path.exists():
59
+ emit_file(path, project_root)
60
+
61
+
62
+ if __name__ == "__main__":
63
+ main()