ai-agent-book 精选快照(<2MB 代码与文档,来自 github.com/bojieli/ai-agent-book)
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def run_cleanup(site: Path) -> None:
|
||||
helper = Path(__file__).parents[1] / "scripts" / "clean_site_files.py"
|
||||
subprocess.run([sys.executable, str(helper), str(site)], check=True)
|
||||
|
||||
|
||||
def test_cleanup_preserves_rendered_json_links_only(tmp_path):
|
||||
site = tmp_path / "site"
|
||||
site.mkdir()
|
||||
linked = site / "evidence.json"
|
||||
referenced = site / "reference.json"
|
||||
root_linked = site / "root.json"
|
||||
orphan = site / "raw-results.json"
|
||||
code_example = site / "secret.json"
|
||||
source = site / "experiment.py"
|
||||
(site / "nested").mkdir()
|
||||
(site / "nested" / "README.md").write_text(
|
||||
"""[evidence](../evidence%2Ejson?download=1#receipt)
|
||||
[root](/root.json)
|
||||
[reference][run]
|
||||
[run]: ../reference.json
|
||||
|
||||
`[not a link](../secret.json)`
|
||||
|
||||
```md
|
||||
This example deliberately contains a blank line because Python-Markdown can
|
||||
otherwise interpret the entire fence as one multiline inline-code span.
|
||||
|
||||
[not a link](../secret.json)
|
||||
```
|
||||
"""
|
||||
)
|
||||
for path in [linked, referenced, root_linked, orphan, code_example]:
|
||||
path.write_text('{"status": "complete"}\n')
|
||||
source.write_text("print('not a site asset')\n")
|
||||
|
||||
run_cleanup(site)
|
||||
|
||||
assert linked.exists()
|
||||
assert referenced.exists()
|
||||
assert root_linked.exists()
|
||||
assert not orphan.exists()
|
||||
assert not code_example.exists()
|
||||
assert not source.exists()
|
||||
|
||||
|
||||
def test_cleanup_rejects_external_links_and_escaping_symlinks(tmp_path):
|
||||
site = tmp_path / "site"
|
||||
site.mkdir()
|
||||
outside = tmp_path / "outside.json"
|
||||
outside.write_text('{"secret": true}\n')
|
||||
(site / "README.md").write_text(
|
||||
"[external](https://example.com/evidence.json)\n"
|
||||
"[escape](../outside.json)\n"
|
||||
"[symlink](escape.json)\n"
|
||||
)
|
||||
(site / "escape.json").symlink_to(outside)
|
||||
(site / "escape.md").symlink_to(tmp_path / "missing.md")
|
||||
|
||||
run_cleanup(site)
|
||||
|
||||
assert outside.exists()
|
||||
assert not (site / "escape.json").exists()
|
||||
assert not (site / "escape.md").exists()
|
||||
Reference in New Issue
Block a user