zettelforge 2.5.1__tar.gz → 2.5.2__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.
- {zettelforge-2.5.1 → zettelforge-2.5.2}/CHANGELOG.md +77 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/PKG-INFO +1 -1
- {zettelforge-2.5.1 → zettelforge-2.5.2}/config.default.yaml +1 -1
- {zettelforge-2.5.1 → zettelforge-2.5.2}/pyproject.toml +1 -1
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/__init__.py +1 -1
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/config.py +1 -1
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/entity_indexer.py +5 -2
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/fact_extractor.py +3 -1
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/llm_providers/ollama_provider.py +1 -1
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/memory_evolver.py +2 -2
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/note_constructor.py +9 -1
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/synthesis_generator.py +5 -1
- {zettelforge-2.5.1 → zettelforge-2.5.2}/.github/CODEOWNERS +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/.github/SECURITY.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/.github/dependabot.yml +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/.github/pull_request_template.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/.github/workflows/ci.yml +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/.github/workflows/docs.yml +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/.github/workflows/publish.yml +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/.github/workflows/snyk-security.yml +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/.gitignore +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/ARCHITECTURE.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/CODEOWNERS +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/CODE_OF_CONDUCT.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/CONTRIBUTING.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/Dockerfile +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/GOVERNANCE.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/LICENSE +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/MANIFEST.in +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/README.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/SECURITY.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/BENCHMARK_REPORT.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/LOCOMO_BENCHMARK_COMPARISON.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/auto_ralph.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/benchmark_harness.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/cti_benchmark_v2.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/cti_retrieval_benchmark.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/cti_retrieval_results.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/cti_v2_results.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/ctibench_benchmark.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/ctibench_results.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/dataset.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/enterprise-attack.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/evolve_benchmark.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/evolve_results.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/graph_test.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/locomo_benchmark.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/locomo_results.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/locomo_results_v1.3.0_baseline.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/memoryagentbench.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/memoryagentbench_results.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/mempalace_benchmark.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/mempalace_results.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/naive_memory.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/opencti_benchmark.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/ragas_benchmark.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/ragas_cti_results.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/ragas_results.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/results/benchmark_report.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/results/ralph_optimization_log.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/scale_benchmark.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/benchmarks/scale_results.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/config.example.yaml +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docker/docker-compose.yml +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/.well-known/security.txt +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/CNAME +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/THREAT_MODEL.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/architecture-diagram.mmd +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/archive/PACKAGE_SUMMARY.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/archive/README.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/archive/SKILL.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/ZettelForge_Architecture.mmd +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/architecture-overview.mmd +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/architecture-read-path.mmd +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/architecture-write-path.mmd +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/cf-analytics.js +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/demo.gif +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/favicon-16.png +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/favicon-32.png +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/favicon-512.png +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/favicon-64.png +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/favicon-apple-touch.png +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/favicon-old.svg +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/favicon.svg +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/logo.svg +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/social-preview.png +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/threatrecall-lockup-monogram.svg +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/threatrecall-lockup.svg +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/threatrecall-logo-flat.svg +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/threatrecall-logo-philosophy.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/threatrecall-logo.png +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/threatrecall-mark.png +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/zettelforge_architecture-light.svg +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/assets/zettelforge_architecture.svg +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/brand/brandIdentity.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/brand/colors_and_type.css +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/explanation/architecture.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/explanation/epistemic-tiers.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/explanation/stix-in-zettelforge.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/explanation/two-phase-pipeline.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/explanation/zettelkasten-philosophy.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/how-to/configure-lancedb.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/how-to/configure-opencti.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/how-to/configure-pii.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/how-to/configure-typedb.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/how-to/ingest-news-report.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/how-to/integrate-llm-agent.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/how-to/migrate-jsonl-to-sqlite.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/how-to/query-apt-tools.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/how-to/reproduce-benchmarks.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/how-to/resolve-aliases.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/how-to/run-temporal-query.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/how-to/store-threat-actor.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/how-to/troubleshoot.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/how-to/upgrade.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/human-evaluation-rubric.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/index.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/llms.txt +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/narrative/2026-04-16-the-memory-problem.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/overrides/main.html +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/reference/architecture-deep-dive.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/reference/configuration.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/reference/governance-controls.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/reference/memory-manager-api.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/reference/module-inventory.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/reference/retrieval-policies.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/reference/stix-schema.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/rfcs/RFC-001-conversational-entity-extractor.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/rfcs/RFC-002-universal-llm-provider.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/rfcs/RFC-003-adversarial-review.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/rfcs/RFC-003-read-path-depth-routing.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/rfcs/RFC-007-operational-telemetry.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/rfcs/RFC-009-enrichment-pipeline-v2.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/rfcs/RFC-010-enrichment-hotfix.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/rfcs/RFC-011-local-llm-backend-config.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/rfcs/RFC-012-litellm-unified-provider.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/rfcs/RFC-013-presidio-pii-detection.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/stylesheets/brand-tokens.css +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/stylesheets/extra.css +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/stylesheets/fonts/Neuropol.otf +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-09-ctibench-ragas-benchmarks.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-09-fastembed-local-embeddings.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-09-hybrid-typedb-lancedb-architecture.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-09-local-llm-llama-cpp.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-15-anti-aversion-cleanup.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-15-causal-graph.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-15-ctibench-ate-fix.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-15-format-stability.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-15-memory-evolution.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-15-merge-consolidation.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-15-persistence-semantics.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-15-sqlite-migration.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-17-test-suite-audit.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-24-phase-0.5-attribution-prelim.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-25-graph-retriever-silence.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-25-phase-0.5-attribution.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/README.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/specs/2026-04-15-p1-features-prd.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/tutorials/01-quickstart.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/docs/tutorials/02-first-cti-report.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/examples/athf_bridge.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/examples/mcp_claude_code.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/examples/quickstart.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/governance/controls.yaml +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/mkdocs.yml +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/scripts/migrate_jsonl_to_sqlite.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/scripts/rebuild_index.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/scripts/record-demo.sh +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/scripts/typedb-setup.sh +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/scripts/zettelforge-rebuild.service +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/scripts/zettelforge-rebuild.timer +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/server.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/skills/claude-code-skill.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/skills/openclaw-skill.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/__main__.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/alias_resolver.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/backend_factory.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/blended_retriever.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/cache.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/consolidation.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/demo.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/detection/__init__.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/detection/base.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/detection/consumers.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/detection/explainer.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/edition.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/extensions.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/governance_validator.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/graph_retriever.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/integrations/__init__.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/integrations/langchain_retriever.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/intent_classifier.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/json_parse.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/knowledge_graph.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/lance_maintenance.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/llm_client.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/llm_providers/__init__.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/llm_providers/base.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/llm_providers/litellm_provider.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/llm_providers/local_provider.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/llm_providers/mock_provider.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/llm_providers/registry.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/log.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/mcp/__init__.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/mcp/__main__.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/mcp/server.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/memory_manager.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/memory_store.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/memory_updater.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/note_schema.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/observability.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/ocsf.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/ontology.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/pii_validator.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/retry.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/scripts/compact_lance.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/scripts/human_eval_sampler.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/scripts/telemetry_aggregator.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/scripts/telemetry_dashboard.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/sigma/__init__.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/sigma/cli.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/sigma/entities.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/sigma/ingest.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/sigma/parser.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/sigma/schemas/NOTICE.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/sigma/schemas/__init__.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/sigma/schemas/sigma-correlation-rules-schema.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/sigma/schemas/sigma-detection-rule-schema.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/sigma/schemas/sigma-filters-schema.json +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/sigma/tags.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/sqlite_backend.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/storage_backend.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/synthesis_validator.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/telemetry.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/vector_memory.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/vector_retriever.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/yara/__init__.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/yara/cccs_metadata.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/yara/cli.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/yara/entities.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/yara/ingest.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/yara/parser.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/yara/schemas/CCCS_YARA.yml +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/yara/schemas/CCCS_YARA_values.yml +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/yara/schemas/NOTICE.md +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/yara/schemas/__init__.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/src/zettelforge/yara/tags.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/__init__.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/benchmark_scale.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/conftest.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/fixtures/sigma/cloud_example.yml +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/fixtures/sigma/correlation_example.yml +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/fixtures/sigma/process_creation_example.yml +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/fixtures/sigma/tagged_example.yml +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/fixtures/yara/malware_hash.yar +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/fixtures/yara/technique_loader.yar +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/fixtures/yara/webshell.yar +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_basic.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_blended_retriever.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_causal_extraction.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_config.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_consolidation.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_conversational_entities.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_core.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_cti_integration.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_detection_explainer.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_detection_rule_entities.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_edition.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_embedding.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_entity_indexer_races.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_extensions.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_fact_extractor.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_governance.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_governance_spec_drift.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_graph_retriever.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_human_eval_sampler.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_intent_classifier.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_json_parse.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_kg_edge_schema.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_lance_maintenance.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_langchain_retriever.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_llm_client.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_llm_providers.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_logging_compliance.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_mcp_server.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_memory_evolver.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_memory_updater.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_performance.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_pii_validator.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_recall_integration.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_sigma_entities.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_sigma_ingest.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_sigma_parser.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_sqlite_backend.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_sqlite_integration.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_storage_backend.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_telemetry_aggregator.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_telemetry_collector.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_telemetry_dashboard.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_telemetry_integration.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_temporal_graph.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_two_phase_e2e.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_typedb_client.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_yara_entities.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_yara_ingest.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/tests/test_yara_parser.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/web/app.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/web/auth.py +0 -0
- {zettelforge-2.5.1 → zettelforge-2.5.2}/web/mcp_server.py +0 -0
|
@@ -6,6 +6,83 @@ Versioning follows [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [2.5.2] - 2026-04-25
|
|
10
|
+
|
|
11
|
+
Hotfix release. Restores end-to-end functionality of synthesis, causal
|
|
12
|
+
triple extraction, fact extraction, LLM NER, and neighbor evolution
|
|
13
|
+
under any reasoning-style LLM (qwen3.5+, qwen3.6, nemotron-3, etc.).
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **Reasoning-model token starvation across every LLM call site**.
|
|
18
|
+
Reasoning models emit hidden `<think>...</think>` tokens that count
|
|
19
|
+
against `num_predict` but never appear in the final `response` field
|
|
20
|
+
Ollama returns. Pre-2.5.2 token caps (`max_tokens=300`/`400`/`800`/
|
|
21
|
+
`1024`) were exhausted entirely by the thinking phase on these
|
|
22
|
+
models, leaving the JSON answer empty. Symptoms: synthesis fell back
|
|
23
|
+
to `"No specific answer found for: …"` on every query; causal triple
|
|
24
|
+
extraction persisted **0 edges** despite rich CTI text; LLM NER
|
|
25
|
+
silently no-opped; neighbor evolution `parse_failed{schema=...,
|
|
26
|
+
raw=""}` warnings flooded the log.
|
|
27
|
+
|
|
28
|
+
Bumped every `generate(..., max_tokens=...)` call site to give
|
|
29
|
+
reasoning models room to think *and* emit a final answer. Affected
|
|
30
|
+
files:
|
|
31
|
+
|
|
32
|
+
| File | Old cap | New cap |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `note_constructor.py` (causal triples) | 300 | **8000** |
|
|
35
|
+
| `synthesis_generator.py` | 800 | 2500 |
|
|
36
|
+
| `fact_extractor.py` | 400 | 2500 |
|
|
37
|
+
| `entity_indexer.py` (NER) | 300 | 2500 |
|
|
38
|
+
| `memory_evolver.py` (2 sites) | 1024 | 2500 |
|
|
39
|
+
|
|
40
|
+
Causal extraction needs the largest budget because the prompt asks
|
|
41
|
+
the model to enumerate *every* causal relation in a passage; this
|
|
42
|
+
triggers the longest reasoning chains anywhere in the system.
|
|
43
|
+
Empirical against `qwen3.5:9b`: at 4000 tokens the call was
|
|
44
|
+
*stochastically* sufficient (eval_count varied 2.8k–4k+, ~70%
|
|
45
|
+
success), so 8000 is the conservative cap that keeps the success
|
|
46
|
+
rate above 95% on the same model. Other call sites converge with
|
|
47
|
+
less reasoning overhead so 2500 suffices.
|
|
48
|
+
|
|
49
|
+
- **LLM client timeout bumped 60s → 180s**. `LLMConfig.timeout` and
|
|
50
|
+
`OllamaProvider` constructor default were both 60 seconds — well
|
|
51
|
+
below the 60–120s wall-clock time of a 4000–8000 token reasoning
|
|
52
|
+
generation on a 9B-Q4_K_M model. `ReadTimeout` was firing during
|
|
53
|
+
causal extraction even when the model would have returned valid
|
|
54
|
+
JSON given another 30 seconds. Bumped both defaults plus
|
|
55
|
+
`config.default.yaml` to 180s.
|
|
56
|
+
|
|
57
|
+
Verified end-to-end on `qwen3.5:9b`:
|
|
58
|
+
- Synthesis: query "What CVE does DROPBEAR exploit?" returns
|
|
59
|
+
`"CVE-2024-3094"` with 1 source citation (was returning
|
|
60
|
+
`"No specific answer found for: …"` on every call pre-2.5.2).
|
|
61
|
+
- Causal extraction: corpus seeded with APT28/DROPBEAR/CVE-2024-3094
|
|
62
|
+
text yields a 4-triple JSON array in 137s wall time:
|
|
63
|
+
`APT28 → targets → manufacturing sector`,
|
|
64
|
+
`APT28 → uses → DROPBEAR`,
|
|
65
|
+
`DROPBEAR → exploits → CVE-2024-3094`,
|
|
66
|
+
`APT28 → attributed_to → Russian GRU Unit 26165`.
|
|
67
|
+
|
|
68
|
+
### Operational note
|
|
69
|
+
|
|
70
|
+
Slow models. With 8000 tokens of reasoning budget, single causal
|
|
71
|
+
extraction calls now take 60–140s on a 9B model. `remember(sync=True)`
|
|
72
|
+
in this configuration will block 1–3 minutes per note. The default
|
|
73
|
+
async path (background enrichment queue) is the preferred mode.
|
|
74
|
+
Operators on faster hardware or smaller models can lower the caps via
|
|
75
|
+
config/env if needed, but the v2.5.2 defaults trade latency for
|
|
76
|
+
end-to-end correctness on the reference model.
|
|
77
|
+
|
|
78
|
+
### Notes
|
|
79
|
+
|
|
80
|
+
This explains the `evolution_parse_failed` and `causal_triples
|
|
81
|
+
parse_failed` cascades documented in the v2.4.x Vigil incident. The
|
|
82
|
+
v2.4.2 PR #95 Tier 1/2 LLM observability surfaced the empty responses
|
|
83
|
+
but the root-cause attribution to token-cap-vs-thinking-budget waited
|
|
84
|
+
until the v2.5.1 perf-bench run made the failure reproducible end-to-end.
|
|
85
|
+
|
|
9
86
|
## [2.5.1] - 2026-04-25
|
|
10
87
|
|
|
11
88
|
Hotfix release. Surfaced during the v2.5.0 perf benchmark run.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: zettelforge
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.2
|
|
4
4
|
Summary: ZettelForge: Agentic Memory System with vector search, knowledge graph, and synthesis
|
|
5
5
|
Project-URL: Homepage, https://github.com/rolandpg/zettelforge
|
|
6
6
|
Project-URL: Documentation, https://docs.threatrecall.ai
|
|
@@ -214,7 +214,7 @@ llm:
|
|
|
214
214
|
url: http://localhost:11434
|
|
215
215
|
api_key: ""
|
|
216
216
|
temperature: 0.1
|
|
217
|
-
timeout:
|
|
217
|
+
timeout: 180.0 # v2.5.2: bumped from 60s for reasoning-model headroom
|
|
218
218
|
max_retries: 2
|
|
219
219
|
fallback: ""
|
|
220
220
|
local_backend: llama-cpp-python # used when provider=local (RFC-011)
|
|
@@ -57,7 +57,7 @@ from zettelforge.vector_retriever import VectorRetriever
|
|
|
57
57
|
# importable for advanced use but are not part of the advertised public API
|
|
58
58
|
# and are therefore excluded from __all__ below.
|
|
59
59
|
|
|
60
|
-
__version__ = "2.5.
|
|
60
|
+
__version__ = "2.5.2"
|
|
61
61
|
__all__ = [
|
|
62
62
|
# Ontology reference tables (TypedEntityStore / OntologyValidator are
|
|
63
63
|
# importable from zettelforge.ontology but are not part of the public API
|
|
@@ -103,7 +103,7 @@ class LLMConfig:
|
|
|
103
103
|
url: str = "http://localhost:11434"
|
|
104
104
|
api_key: str = "" # supports ${ENV_VAR} references — never commit raw keys
|
|
105
105
|
temperature: float = 0.1
|
|
106
|
-
timeout: float =
|
|
106
|
+
timeout: float = 180.0 # v2.5.2: bumped from 60s — reasoning models at higher num_predict (4000 for causal triples) routinely exceed 60s on a 9B at Q4_K_M
|
|
107
107
|
max_retries: int = 2
|
|
108
108
|
fallback: str = "" # empty preserves implicit local→ollama fallback
|
|
109
109
|
local_backend: str = "llama-cpp-python" # RFC-011: "llama-cpp-python" or "onnxruntime-genai"
|
|
@@ -271,9 +271,12 @@ class EntityExtractor:
|
|
|
271
271
|
from zettelforge.llm_client import generate
|
|
272
272
|
|
|
273
273
|
prompt = f"Extract named entities from this text:\n\n{text[:2000]}\n\nJSON:"
|
|
274
|
+
# 2500-token budget for reasoning-model headroom (v2.5.2; pre-fix
|
|
275
|
+
# 300 was exhausted by qwen3.5+ <think> tokens, leaving the NER
|
|
276
|
+
# JSON empty and entity extraction silently no-opping).
|
|
274
277
|
output = generate(
|
|
275
278
|
prompt,
|
|
276
|
-
max_tokens=
|
|
279
|
+
max_tokens=2500,
|
|
277
280
|
temperature=0.0,
|
|
278
281
|
system=self.NER_SYSTEM_PROMPT,
|
|
279
282
|
)
|
|
@@ -282,7 +285,7 @@ class EntityExtractor:
|
|
|
282
285
|
if parsed is None and output and output.strip():
|
|
283
286
|
_logger.info("retry_parse", site="entity_indexer_ner", attempt=2)
|
|
284
287
|
retry_prompt = prompt + "\n\nRespond with valid JSON only."
|
|
285
|
-
output = generate(retry_prompt, max_tokens=
|
|
288
|
+
output = generate(retry_prompt, max_tokens=2500, temperature=0.3, json_mode=True)
|
|
286
289
|
parsed = extract_json(output, expect="object")
|
|
287
290
|
return self._parse_ner_output_from_parsed(parsed, output, conversational_types)
|
|
288
291
|
|
|
@@ -42,7 +42,9 @@ class FactExtractor:
|
|
|
42
42
|
try:
|
|
43
43
|
from zettelforge.llm_client import generate
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
# 2500-token budget for reasoning-model headroom (see v2.5.2
|
|
46
|
+
# CHANGELOG; pre-fix 400 was exhausted by qwen3.5+ <think> tokens).
|
|
47
|
+
raw_output = generate(prompt, max_tokens=2500, temperature=0.1)
|
|
46
48
|
return self._parse_extraction_response(raw_output)
|
|
47
49
|
except Exception:
|
|
48
50
|
_logger.warning("llm_fact_extraction_failed", exc_info=True)
|
|
@@ -93,7 +93,7 @@ class MemoryEvolver:
|
|
|
93
93
|
)
|
|
94
94
|
|
|
95
95
|
# First attempt
|
|
96
|
-
output = generate(prompt, max_tokens=
|
|
96
|
+
output = generate(prompt, max_tokens=2500, temperature=0.2, json_mode=True)
|
|
97
97
|
result = extract_json(output, expect="object")
|
|
98
98
|
|
|
99
99
|
# Single retry on parse failure (AD-2). Capture what the model
|
|
@@ -108,7 +108,7 @@ class MemoryEvolver:
|
|
|
108
108
|
raw_chars=len(output or ""),
|
|
109
109
|
prompt_preview=prompt[:240],
|
|
110
110
|
)
|
|
111
|
-
output = generate(prompt, max_tokens=
|
|
111
|
+
output = generate(prompt, max_tokens=2500, temperature=0.1, json_mode=True)
|
|
112
112
|
result = extract_json(output, expect="object")
|
|
113
113
|
|
|
114
114
|
if result is None:
|
|
@@ -122,7 +122,15 @@ JSON:"""
|
|
|
122
122
|
try:
|
|
123
123
|
from zettelforge.llm_client import generate
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
# 8000 tokens for causal extraction — the highest cap in the
|
|
126
|
+
# codebase. This prompt asks the model to enumerate every causal
|
|
127
|
+
# relation in a passage, which triggers the longest reasoning
|
|
128
|
+
# chains anywhere in the system. Empirical: qwen3.5:9b at
|
|
129
|
+
# num_predict=4000 was *stochastically* sufficient (~70% success
|
|
130
|
+
# rate), eval_count varied between 2.8k (success) and 4k+ (still
|
|
131
|
+
# in <think> tags when budget exhausted). 8000 keeps the
|
|
132
|
+
# success rate >95% on the same model. v2.5.2 CHANGELOG.
|
|
133
|
+
output = generate(prompt, max_tokens=8000, temperature=0.1)
|
|
126
134
|
|
|
127
135
|
parsed = extract_json(output, expect="array")
|
|
128
136
|
if parsed is None:
|
|
@@ -143,7 +143,11 @@ class SynthesisGenerator:
|
|
|
143
143
|
try:
|
|
144
144
|
from zettelforge.llm_client import generate
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
# 2500-token budget for reasoning-model headroom. Pre-2.5.2 the
|
|
147
|
+
# 800-token cap was exhausted by qwen3.5+/qwen3.6/nemotron-3
|
|
148
|
+
# <think> tokens before any JSON answer was emitted, dropping
|
|
149
|
+
# synthesis to its empty-result fallback on every call.
|
|
150
|
+
raw = generate(full_prompt, max_tokens=2500, temperature=0.1, system=system_prompt)
|
|
147
151
|
result = extract_json(raw, expect="object")
|
|
148
152
|
if result is None:
|
|
149
153
|
_logger.warning("parse_failed", schema="synthesis", raw=(raw or "")[:200])
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{zettelforge-2.5.1 → zettelforge-2.5.2}/docs/rfcs/RFC-001-conversational-entity-extractor.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
|
{zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-09-local-llm-llama-cpp.md
RENAMED
|
File without changes
|
|
File without changes
|
{zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-15-causal-graph.md
RENAMED
|
File without changes
|
{zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-15-ctibench-ate-fix.md
RENAMED
|
File without changes
|
{zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-15-format-stability.md
RENAMED
|
File without changes
|
{zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-15-memory-evolution.md
RENAMED
|
File without changes
|
{zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-15-merge-consolidation.md
RENAMED
|
File without changes
|
|
File without changes
|
{zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-15-sqlite-migration.md
RENAMED
|
File without changes
|
{zettelforge-2.5.1 → zettelforge-2.5.2}/docs/superpowers/research/2026-04-17-test-suite-audit.md
RENAMED
|
File without changes
|