activegraph 1.0.4__tar.gz → 1.0.5__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.
- {activegraph-1.0.4 → activegraph-1.0.5}/PKG-INFO +9 -1
- {activegraph-1.0.4 → activegraph-1.0.5}/README.md +7 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/__init__.py +1 -1
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph.egg-info/PKG-INFO +9 -1
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph.egg-info/SOURCES.txt +1 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph.egg-info/requires.txt +1 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/pyproject.toml +7 -1
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_doc_links.py +20 -0
- activegraph-1.0.5/tests/test_llms_txt.py +184 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/__main__.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/behaviors/__init__.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/behaviors/base.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/behaviors/decorators.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/cli/__init__.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/cli/main.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/cli/quickstart.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/core/__init__.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/core/clock.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/core/event.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/core/graph.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/core/ids.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/core/patch.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/core/view.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/errors.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/frame.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/llm/__init__.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/llm/anthropic.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/llm/cache.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/llm/errors.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/llm/openai.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/llm/parsing.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/llm/prompt.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/llm/provider.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/llm/recorded.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/llm/types.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/observability/__init__.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/observability/logging.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/observability/metrics.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/observability/migration.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/observability/prometheus.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/observability/status.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/__init__.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/diligence/__init__.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/diligence/behaviors.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/diligence/fixtures/__init__.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/diligence/fixtures/companies.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/diligence/object_types.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/diligence/prompts/document_researcher.md +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/diligence/prompts/memo_synthesizer.md +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/diligence/prompts/question_generator.md +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/diligence/prompts/risk_identifier.md +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/diligence/settings.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/diligence/tools.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/loader.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/scaffold.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/policy.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/runtime/__init__.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/runtime/_live.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/runtime/behavior_graph.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/runtime/budget.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/runtime/config_errors.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/runtime/diff.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/runtime/errors.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/runtime/exec_errors.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/runtime/patterns.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/runtime/queue.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/runtime/registration_errors.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/runtime/registry.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/runtime/runtime.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/runtime/scheduler.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/runtime/view_builder.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/store/__init__.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/store/base.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/store/conformance.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/store/errors.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/store/memory.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/store/postgres.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/store/serde.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/store/sqlite.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/store/url.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/tools/__init__.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/tools/base.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/tools/cache.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/tools/context.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/tools/decorators.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/tools/errors.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/tools/graph_query.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/tools/recorded.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/tools/web_fetch.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/trace/__init__.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/trace/causal.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph/trace/printer.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph.egg-info/dependency_links.txt +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph.egg-info/entry_points.txt +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/activegraph.egg-info/top_level.txt +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/setup.cfg +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_activate_after.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_causal_cross_tool.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_cli.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_clock.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_diff.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_diligence_pack.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_diligence_with_tools.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_doc_site_reachable.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_errors_format.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_event.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_fork.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_graph.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_ids.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_anthropic.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_behavior.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_budget.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_causal.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_claim_extraction.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_default_model.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_determinism.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_failure.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_openai.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_prompt.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_provider_fixtures.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_replay.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_tool_loop.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_trace.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_trace_snapshot.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_llm_types.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_migration.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_observability_logging.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_observability_metrics.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_operate_example.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_pack_scaffold.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_packs.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_patch.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_pattern_matcher.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_pattern_parser.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_pattern_subscriptions.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_persistence.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_postgres_store.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_quickstart.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_quickstart_snapshot.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_replay.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_replay_trace_snapshot.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_requeue_unfired.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_resume_example.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_runtime.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_runtime_status.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_serde.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_store_conformance.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_store_url.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_tool_replay.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_tool_trace_snapshot.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_tools.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_trace.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_tutorial_snippets.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_v1_0_1_patches.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_v1_0_3_behavior_failed_ux.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_v1_0_3_tool_multiturn.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_version_sync.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_view.py +0 -0
- {activegraph-1.0.4 → activegraph-1.0.5}/tests/test_wheel_completeness.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: activegraph
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.5
|
|
4
4
|
Summary: An event-sourced reactive graph runtime for long-running, auditable, agentic systems.
|
|
5
5
|
Author: Active Graph contributors
|
|
6
6
|
License: MIT
|
|
@@ -49,6 +49,7 @@ Provides-Extra: docs
|
|
|
49
49
|
Requires-Dist: mkdocs>=1.6; extra == "docs"
|
|
50
50
|
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
|
|
51
51
|
Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
|
|
52
|
+
Requires-Dist: mkdocs-llmstxt>=0.2; extra == "docs"
|
|
52
53
|
|
|
53
54
|
# Active Graph
|
|
54
55
|
|
|
@@ -219,6 +220,13 @@ in [`docs/concepts/relations.md`](https://docs.activegraph.ai/concepts/relations
|
|
|
219
220
|
per-error catalog.
|
|
220
221
|
- **[10-minute tutorial](https://docs.activegraph.ai/quickstart/)** — install
|
|
221
222
|
to a working custom behavior, including fork-and-diff.
|
|
223
|
+
- **AI coding assistants** — the docs are machine-readable at
|
|
224
|
+
[docs.activegraph.ai/llms.txt](https://docs.activegraph.ai/llms.txt)
|
|
225
|
+
(structured index) and
|
|
226
|
+
[docs.activegraph.ai/llms-full.txt](https://docs.activegraph.ai/llms-full.txt)
|
|
227
|
+
(concatenated full content), generated from the same source markdown
|
|
228
|
+
as the rendered site. Built for AI agents evaluating the framework
|
|
229
|
+
via Claude Code, Cursor, Replit, and similar tooling.
|
|
222
230
|
- **[CHANGELOG.md](CHANGELOG.md)** — every release, with per-version
|
|
223
231
|
migration notes.
|
|
224
232
|
- **[CONTRACT.md](CONTRACT.md)** — locked design decisions, version
|
|
@@ -167,6 +167,13 @@ in [`docs/concepts/relations.md`](https://docs.activegraph.ai/concepts/relations
|
|
|
167
167
|
per-error catalog.
|
|
168
168
|
- **[10-minute tutorial](https://docs.activegraph.ai/quickstart/)** — install
|
|
169
169
|
to a working custom behavior, including fork-and-diff.
|
|
170
|
+
- **AI coding assistants** — the docs are machine-readable at
|
|
171
|
+
[docs.activegraph.ai/llms.txt](https://docs.activegraph.ai/llms.txt)
|
|
172
|
+
(structured index) and
|
|
173
|
+
[docs.activegraph.ai/llms-full.txt](https://docs.activegraph.ai/llms-full.txt)
|
|
174
|
+
(concatenated full content), generated from the same source markdown
|
|
175
|
+
as the rendered site. Built for AI agents evaluating the framework
|
|
176
|
+
via Claude Code, Cursor, Replit, and similar tooling.
|
|
170
177
|
- **[CHANGELOG.md](CHANGELOG.md)** — every release, with per-version
|
|
171
178
|
migration notes.
|
|
172
179
|
- **[CONTRACT.md](CONTRACT.md)** — locked design decisions, version
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: activegraph
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.5
|
|
4
4
|
Summary: An event-sourced reactive graph runtime for long-running, auditable, agentic systems.
|
|
5
5
|
Author: Active Graph contributors
|
|
6
6
|
License: MIT
|
|
@@ -49,6 +49,7 @@ Provides-Extra: docs
|
|
|
49
49
|
Requires-Dist: mkdocs>=1.6; extra == "docs"
|
|
50
50
|
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
|
|
51
51
|
Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
|
|
52
|
+
Requires-Dist: mkdocs-llmstxt>=0.2; extra == "docs"
|
|
52
53
|
|
|
53
54
|
# Active Graph
|
|
54
55
|
|
|
@@ -219,6 +220,13 @@ in [`docs/concepts/relations.md`](https://docs.activegraph.ai/concepts/relations
|
|
|
219
220
|
per-error catalog.
|
|
220
221
|
- **[10-minute tutorial](https://docs.activegraph.ai/quickstart/)** — install
|
|
221
222
|
to a working custom behavior, including fork-and-diff.
|
|
223
|
+
- **AI coding assistants** — the docs are machine-readable at
|
|
224
|
+
[docs.activegraph.ai/llms.txt](https://docs.activegraph.ai/llms.txt)
|
|
225
|
+
(structured index) and
|
|
226
|
+
[docs.activegraph.ai/llms-full.txt](https://docs.activegraph.ai/llms-full.txt)
|
|
227
|
+
(concatenated full content), generated from the same source markdown
|
|
228
|
+
as the rendered site. Built for AI agents evaluating the framework
|
|
229
|
+
via Claude Code, Cursor, Replit, and similar tooling.
|
|
222
230
|
- **[CHANGELOG.md](CHANGELOG.md)** — every release, with per-version
|
|
223
231
|
migration notes.
|
|
224
232
|
- **[CONTRACT.md](CONTRACT.md)** — locked design decisions, version
|
|
@@ -120,6 +120,7 @@ tests/test_llm_tool_loop.py
|
|
|
120
120
|
tests/test_llm_trace.py
|
|
121
121
|
tests/test_llm_trace_snapshot.py
|
|
122
122
|
tests/test_llm_types.py
|
|
123
|
+
tests/test_llms_txt.py
|
|
123
124
|
tests/test_migration.py
|
|
124
125
|
tests/test_observability_logging.py
|
|
125
126
|
tests/test_observability_metrics.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "activegraph"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.5"
|
|
8
8
|
description = "An event-sourced reactive graph runtime for long-running, auditable, agentic systems."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -65,6 +65,12 @@ docs = [
|
|
|
65
65
|
"mkdocs>=1.6",
|
|
66
66
|
"mkdocs-material>=9.5",
|
|
67
67
|
"mkdocstrings[python]>=0.24",
|
|
68
|
+
# v1.0.5 #1: generates /llms.txt and /llms-full.txt at the site
|
|
69
|
+
# root so AI coding assistants fetching docs.activegraph.ai get
|
|
70
|
+
# clean markdown instead of mkdocs-rendered HTML. Same maintainer
|
|
71
|
+
# as mkdocstrings; native dual-output via the `full_output:` config
|
|
72
|
+
# key. Surfaced by the v1.0.4 external user-test.
|
|
73
|
+
"mkdocs-llmstxt>=0.2",
|
|
68
74
|
]
|
|
69
75
|
|
|
70
76
|
[project.scripts]
|
|
@@ -66,6 +66,22 @@ _DOCS_URL_RE = re.compile(
|
|
|
66
66
|
)
|
|
67
67
|
|
|
68
68
|
|
|
69
|
+
# URLs that are generated at build time and do NOT correspond to a
|
|
70
|
+
# `docs/*.md` source file. These bypass the source-presence check
|
|
71
|
+
# because their existence is verified by a dedicated build-time gate
|
|
72
|
+
# rather than by source-tree presence.
|
|
73
|
+
#
|
|
74
|
+
# `/llms.txt` and `/llms-full.txt` (CONTRACT v1.0.5 #1) are emitted by
|
|
75
|
+
# the `mkdocs-llmstxt` plugin during `mkdocs build`; their existence
|
|
76
|
+
# and well-formedness are verified by `tests/test_llms_txt.py`. Any
|
|
77
|
+
# URL added here must have a paired build-time test asserting the
|
|
78
|
+
# file lands at the site root.
|
|
79
|
+
_BUILD_GENERATED_URLS = frozenset({
|
|
80
|
+
"/llms.txt",
|
|
81
|
+
"/llms-full.txt",
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
|
|
69
85
|
def _strip_trailing_punct(s: str) -> str:
|
|
70
86
|
"""URLs in prose often end at sentence boundaries; trim trailing
|
|
71
87
|
punctuation that isn't part of the URL."""
|
|
@@ -181,6 +197,10 @@ def test_every_referenced_docs_url_has_a_source_page() -> None:
|
|
|
181
197
|
missing: dict[Path, list[tuple[str, list[Path]]]] = {}
|
|
182
198
|
unmapped: list[tuple[str, list[Path]]] = []
|
|
183
199
|
for url_path, sources in referenced.items():
|
|
200
|
+
if url_path in _BUILD_GENERATED_URLS:
|
|
201
|
+
# Existence guaranteed by tests/test_llms_txt.py at build
|
|
202
|
+
# time; no docs/*.md source to check.
|
|
203
|
+
continue
|
|
184
204
|
expected = _url_to_source_path(url_path)
|
|
185
205
|
if expected is None:
|
|
186
206
|
unmapped.append((url_path, sources))
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"""llms.txt / llms-full.txt generation gate. CONTRACT v1.0.5 #1.
|
|
2
|
+
|
|
3
|
+
Builds the mkdocs site into a temp directory and asserts that
|
|
4
|
+
``site/llms.txt`` and ``site/llms-full.txt`` exist after the build,
|
|
5
|
+
are well-formed (H1, blockquote summary, at least one H2 section),
|
|
6
|
+
and reference the nav-anchor pages named in CONTRACT v1.0.5 #1's
|
|
7
|
+
contract claim. The "content coverage" assertion is the boundary
|
|
8
|
+
guard against the failure mode where the build succeeds but emits
|
|
9
|
+
an llms.txt that contains only the H1 — file existence alone is
|
|
10
|
+
not sufficient.
|
|
11
|
+
|
|
12
|
+
Standing Rule §2 shape: the test anchors on the contract boundary
|
|
13
|
+
the v1.0.5 #1 amendment names ("both files exist after build and
|
|
14
|
+
are well-formed"), not on the implementation path of the
|
|
15
|
+
`mkdocs-llmstxt` plugin. If a future release swaps the plugin for
|
|
16
|
+
a custom build script or a different plugin, this test stays
|
|
17
|
+
correct without modification.
|
|
18
|
+
|
|
19
|
+
Marked ``slow`` because ``mkdocs build`` takes several seconds.
|
|
20
|
+
Local ``pytest`` skips it by default; the ``.github/workflows/docs.yml``
|
|
21
|
+
workflow runs it explicitly via ``pytest -m slow tests/test_llms_txt.py``.
|
|
22
|
+
The precedent is ``tests/test_doc_site_reachable.py`` (CONTRACT v1.1
|
|
23
|
+
#9), which uses the same marker for the same reason.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
import shutil
|
|
29
|
+
import subprocess
|
|
30
|
+
from pathlib import Path
|
|
31
|
+
|
|
32
|
+
import pytest
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
36
|
+
MKDOCS_CONFIG = REPO_ROOT / "mkdocs.yml"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@pytest.fixture(scope="module")
|
|
40
|
+
def built_site(tmp_path_factory: pytest.TempPathFactory) -> Path:
|
|
41
|
+
"""Run ``mkdocs build`` into a temp dir; return the site/ path.
|
|
42
|
+
|
|
43
|
+
Module-scoped: the build is shared across every assertion in
|
|
44
|
+
this file. The fixture skips the entire module if ``mkdocs`` is
|
|
45
|
+
not installed — keeps the gate honest about its hard dependency
|
|
46
|
+
on the docs-build environment without polluting unrelated test
|
|
47
|
+
runs.
|
|
48
|
+
"""
|
|
49
|
+
if shutil.which("mkdocs") is None:
|
|
50
|
+
pytest.skip("mkdocs binary not available; install '.[docs]' to run")
|
|
51
|
+
|
|
52
|
+
site_dir = tmp_path_factory.mktemp("llms_txt_gate") / "site"
|
|
53
|
+
result = subprocess.run(
|
|
54
|
+
[
|
|
55
|
+
"mkdocs",
|
|
56
|
+
"build",
|
|
57
|
+
"--config-file",
|
|
58
|
+
str(MKDOCS_CONFIG),
|
|
59
|
+
"--site-dir",
|
|
60
|
+
str(site_dir),
|
|
61
|
+
"--clean",
|
|
62
|
+
],
|
|
63
|
+
capture_output=True,
|
|
64
|
+
text=True,
|
|
65
|
+
cwd=REPO_ROOT,
|
|
66
|
+
)
|
|
67
|
+
if result.returncode != 0:
|
|
68
|
+
# Surface the actual mkdocs error so a failing gate is
|
|
69
|
+
# diagnosable from the CI log — not just "build failed."
|
|
70
|
+
pytest.fail(
|
|
71
|
+
"mkdocs build failed:\n"
|
|
72
|
+
f"stdout:\n{result.stdout}\nstderr:\n{result.stderr}"
|
|
73
|
+
)
|
|
74
|
+
return site_dir
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@pytest.mark.slow
|
|
78
|
+
def test_llms_txt_exists(built_site: Path) -> None:
|
|
79
|
+
"""Contract: ``/llms.txt`` is generated at site root after build."""
|
|
80
|
+
llms = built_site / "llms.txt"
|
|
81
|
+
assert llms.is_file(), (
|
|
82
|
+
f"site/llms.txt missing after mkdocs build (expected at {llms}). "
|
|
83
|
+
"Check the `llmstxt` plugin block in mkdocs.yml."
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@pytest.mark.slow
|
|
88
|
+
def test_llms_full_txt_exists(built_site: Path) -> None:
|
|
89
|
+
"""Contract: ``/llms-full.txt`` is generated at site root after build."""
|
|
90
|
+
llms_full = built_site / "llms-full.txt"
|
|
91
|
+
assert llms_full.is_file(), (
|
|
92
|
+
f"site/llms-full.txt missing after mkdocs build (expected at {llms_full}). "
|
|
93
|
+
"Check the `full_output:` key in the `llmstxt` plugin block."
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@pytest.mark.slow
|
|
98
|
+
def test_llms_txt_h1_and_blockquote(built_site: Path) -> None:
|
|
99
|
+
"""Contract: ``llms.txt`` starts with the H1 and a blockquote summary.
|
|
100
|
+
|
|
101
|
+
The plugin derives the H1 from ``site_name`` and the blockquote
|
|
102
|
+
from ``site_description``. The assertion shape catches both the
|
|
103
|
+
plugin-not-running case and the case where ``mkdocs.yml`` loses
|
|
104
|
+
one of those keys (which would break the llms.txt convention
|
|
105
|
+
described at llmstxt.org).
|
|
106
|
+
"""
|
|
107
|
+
content = (built_site / "llms.txt").read_text(encoding="utf-8")
|
|
108
|
+
lines = content.splitlines()
|
|
109
|
+
|
|
110
|
+
assert lines[0] == "# Active Graph", (
|
|
111
|
+
f"llms.txt does not start with the expected H1; got: {lines[0]!r}"
|
|
112
|
+
)
|
|
113
|
+
# The blockquote summary line — first non-empty line after the H1.
|
|
114
|
+
blockquote = next((ln for ln in lines[1:] if ln.strip()), "")
|
|
115
|
+
assert blockquote.startswith("> "), (
|
|
116
|
+
f"llms.txt does not carry a blockquote summary; got: {blockquote!r}"
|
|
117
|
+
)
|
|
118
|
+
assert len(blockquote) > len("> "), (
|
|
119
|
+
"llms.txt blockquote summary is empty after the '> ' marker"
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@pytest.mark.slow
|
|
124
|
+
def test_llms_txt_has_section_headers(built_site: Path) -> None:
|
|
125
|
+
"""Contract: ``llms.txt`` carries H2 sections (navigation aid shape)."""
|
|
126
|
+
content = (built_site / "llms.txt").read_text(encoding="utf-8")
|
|
127
|
+
h2_count = sum(1 for ln in content.splitlines() if ln.startswith("## "))
|
|
128
|
+
assert h2_count >= 4, (
|
|
129
|
+
f"llms.txt has {h2_count} H2 section headers; expected at least 4 "
|
|
130
|
+
"(Quickstart / Concepts / Cookbook / Reference at minimum). "
|
|
131
|
+
"A file with the H1 but no sections is not useful as a nav aid."
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@pytest.mark.slow
|
|
136
|
+
def test_llms_txt_references_nav_anchor_pages(built_site: Path) -> None:
|
|
137
|
+
"""Contract: ``llms.txt`` references the nav-anchor pages by name.
|
|
138
|
+
|
|
139
|
+
The v1.0.5 #1 amendment names three anchors for the coverage
|
|
140
|
+
check: ``concepts/graph.md``, ``quickstart.md``, and at least
|
|
141
|
+
one cookbook page. These are the load-bearing entry points for
|
|
142
|
+
a first-time AI reader walking the index; if any one is
|
|
143
|
+
missing, the file fails to deliver on its navigation-aid
|
|
144
|
+
purpose.
|
|
145
|
+
"""
|
|
146
|
+
content = (built_site / "llms.txt").read_text(encoding="utf-8")
|
|
147
|
+
|
|
148
|
+
assert "concepts/graph/" in content, (
|
|
149
|
+
"llms.txt does not reference docs/concepts/graph.md — the "
|
|
150
|
+
"primary entry point for the framework's primitive model."
|
|
151
|
+
)
|
|
152
|
+
assert "quickstart/" in content, (
|
|
153
|
+
"llms.txt does not reference docs/quickstart.md — the "
|
|
154
|
+
"ten-minute tutorial that the README points new users at."
|
|
155
|
+
)
|
|
156
|
+
assert "cookbook/" in content, (
|
|
157
|
+
"llms.txt does not reference any cookbook page — at least "
|
|
158
|
+
"one of common-patterns.md / debugging.md / multi-run-scripts.md "
|
|
159
|
+
"is expected."
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
@pytest.mark.slow
|
|
164
|
+
def test_llms_full_txt_well_formed(built_site: Path) -> None:
|
|
165
|
+
"""Contract: ``llms-full.txt`` carries the H1 + actual page bodies.
|
|
166
|
+
|
|
167
|
+
Asserts on a distinctive prose marker from ``docs/quickstart.md``
|
|
168
|
+
so a file that contains the H1 and blockquote but no concatenated
|
|
169
|
+
bodies fails. The marker is the tutorial's opening sentence,
|
|
170
|
+
voice-locked since v1.0-rc1 and unlikely to churn.
|
|
171
|
+
"""
|
|
172
|
+
content = (built_site / "llms-full.txt").read_text(encoding="utf-8")
|
|
173
|
+
|
|
174
|
+
assert content.startswith("# Active Graph"), (
|
|
175
|
+
"llms-full.txt does not start with the expected H1"
|
|
176
|
+
)
|
|
177
|
+
# Distinctive phrase from docs/quickstart.md's first paragraph —
|
|
178
|
+
# if llms-full.txt contains it, the quickstart body made it
|
|
179
|
+
# into the concatenated output.
|
|
180
|
+
assert "Ten minutes from install to a working custom behavior" in content, (
|
|
181
|
+
"llms-full.txt does not contain the quickstart body marker; "
|
|
182
|
+
"the file may be the index-only output instead of the "
|
|
183
|
+
"concatenated full content."
|
|
184
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/diligence/prompts/document_researcher.md
RENAMED
|
File without changes
|
{activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/diligence/prompts/memo_synthesizer.md
RENAMED
|
File without changes
|
{activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/diligence/prompts/question_generator.md
RENAMED
|
File without changes
|
{activegraph-1.0.4 → activegraph-1.0.5}/activegraph/packs/diligence/prompts/risk_identifier.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|