linkedparticles-core 1.192.2__tar.gz → 1.192.10__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.
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/PKG-INFO +8 -8
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/constraints.txt +8 -8
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/config.py +18 -3
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/contradiction_disclosure.py +1 -2
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/held_release.py +3 -3
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/agent.py +51 -9
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/general.py +2 -2
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/mcp_memory.py +2 -2
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/subject_scope.py +2 -2
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/render/markdown.py +2 -2
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/pyproject.toml +47 -16
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_extraction_agent.py +41 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/LICENSE +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/NOTICE +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/README.md +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/artifacts/conformance/README.md +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/artifacts/conformance/profile.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/artifacts/conformance/similarity_vectors.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/artifacts/schemas/context.jsonld +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/artifacts/schemas/interchange.schema.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/artifacts/schemas/particle.schema.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/artifacts/schemas/shacl/CorpusSnapshotShape.ttl +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/artifacts/schemas/shacl/ParticleShape.ttl +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/artifacts/schemas/shacl/ProvenanceChainShape.ttl +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/artifacts/schemas/shacl/SubjectShape.ttl +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/artifacts/schemas/shacl/TrustStatementShape.ttl +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/artifacts/schemas/trust_lens.schema.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/__init__.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/__init__.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/_resources.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/contract.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/fixtures.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/jsonschema.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/profile.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/runner.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/shacl.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/types.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/validator.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/__init__.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/_resources.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/cascade_gate.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/claims.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/closure_measure.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/conflict_resolution.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/conflict_review.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/consolidation_cadence.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/duplicate_key.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/equivalence.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/fingerprint.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/generics.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/granularity.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/jsonld_context.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/ladders.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/modality.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/observer_scope.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/past_value.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/predicate_profile.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/probe_verdict.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/progress.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/provenance.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/reanchor.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/rung_ladder.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/schema.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/scoring/__init__.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/scoring/confidence.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/scoring/decay.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/scoring/relevance.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/scoring/utility.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/spend_budget.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/stance.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/status.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/validity.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/vocabulary.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/vocabulary_jsonld.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/vocabulary_report.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/egress.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/embeddings.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/__init__.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/append_delta.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/calibration.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/components.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/docstrings.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/github/__init__.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/github/_shared.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/github/gist.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/github/pages.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/github/repo.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/hackernews.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/incremental.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/journal.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/mastodon.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/migration_preview.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/modality.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/nomisma.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/numista/__init__.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/numista/_shared.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/numista/coin.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/numista/issuer.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/numista/listing.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/polarity.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/property_keys.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/rdf.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/reddit.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/registry.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/scope.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/session_state.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/structure.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/subject_gate.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/taxonomy.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/tool_turns.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/trust_lens.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/vocabulary.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/wikidata.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/http.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/interchange/__init__.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/interchange/codec.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/interchange/jsonl.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/interchange/yaml_ld.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/__init__.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/adapters/__init__.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/adapters/anthropic.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/adapters/local.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/adapters/openai_compat.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/batch_budget.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/breaker.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/client.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/errors.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/fencing.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/logprobs.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/pool.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/registry.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/replay.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/spend_budget.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/llm/usage.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/py.typed +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/render/__init__.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/secrets.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/url_canonical.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/url_safety.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/__init__.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/_client_fixtures.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/_upstream.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/MANIFEST.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/hackernews-thread-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/hackernews-thread-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/hackernews-thread-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/journal-entry-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/journal-entry-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/journal-entry-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/mastodon-thread-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/mastodon-thread-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/mastodon-thread-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/mcp-memory-export-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/mcp-memory-export-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/mcp-memory-export-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/nomisma-concept-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/nomisma-concept-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/nomisma-concept-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/numista-coin-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/numista-coin-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/numista-coin-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/numista-issuer-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/numista-issuer-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/numista-issuer-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/numista-listing-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/numista-listing-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/numista-listing-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/rdf-graph-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/rdf-graph-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/rdf-graph-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/reddit-thread-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/reddit-thread-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/reddit-thread-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/taxonomy-coins-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/taxonomy-coins-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/taxonomy-coins-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/trust-lens-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/trust-lens-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/trust-lens-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/web-article-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/web-article-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/web-article-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/web-article-002/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/web-article-002/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/web-article-002/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/web-essay-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/web-essay-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/web-essay-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/web-interview-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/web-interview-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/web-interview-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/wikidata-entity-001/content.bin +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/wikidata-entity-001/manifest.yaml +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conformance/fixtures/wikidata-entity-001/snapshot.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/conftest.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/fixtures/scope/normative-rule-file.md +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/fixtures/scope/normative-rule-file.recorded.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/fixtures/scope/rule-file-agents-md.md +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/fixtures/scope/rule-file-agents-md.recorded.json +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_calibration_isotonic.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_confidence.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_config_client_sections.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_config_sample.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_conformance_fixture_gen.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_conformance_similarity_vectors.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_conformance_validator.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_core_contradiction_disclosure.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_core_held_release.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_core_observer_scope.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_core_provenance.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_core_vocabulary.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_egress_policy.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_embeddings.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_extraction_vision.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_interchange_schema.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_llm_batch_budget.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_llm_logprobs.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_llm_pool.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_llm_replay.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_llm_usage.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_schema.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_secrets.py +0 -0
- {linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_url_canonical.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: linkedparticles-core
|
|
3
|
-
Version: 1.192.
|
|
3
|
+
Version: 1.192.10
|
|
4
4
|
Summary: Store-free client library for Particles: define, validate, serialize, and extract provenance-tracked belief particles
|
|
5
5
|
Project-URL: Homepage, https://linkedparticles.org
|
|
6
6
|
Project-URL: Documentation, https://docs.linkedparticles.org
|
|
@@ -29,7 +29,7 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
29
29
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
30
30
|
Classifier: Typing :: Typed
|
|
31
31
|
Requires-Python: >=3.11
|
|
32
|
-
Requires-Dist: anthropic>=0
|
|
32
|
+
Requires-Dist: anthropic>=1.0
|
|
33
33
|
Requires-Dist: html2text>=2024.2
|
|
34
34
|
Requires-Dist: httpx>=0.27
|
|
35
35
|
Requires-Dist: jsonschema>=4.22
|
|
@@ -37,17 +37,17 @@ Requires-Dist: lxml-stubs>=0.5.1
|
|
|
37
37
|
Requires-Dist: numpy>=1.26
|
|
38
38
|
Requires-Dist: opentelemetry-api>=1.27
|
|
39
39
|
Requires-Dist: pydantic>=2.7
|
|
40
|
-
Requires-Dist: pyld<4,>=
|
|
41
|
-
Requires-Dist: pypdf>=6.
|
|
42
|
-
Requires-Dist: pyshacl<0.
|
|
40
|
+
Requires-Dist: pyld<4,>=3.0
|
|
41
|
+
Requires-Dist: pypdf>=6.19.0
|
|
42
|
+
Requires-Dist: pyshacl<0.41,>=0.40
|
|
43
43
|
Requires-Dist: pyyaml>=6.0
|
|
44
44
|
Requires-Dist: rdflib<8,>=7.0
|
|
45
45
|
Requires-Dist: scipy>=1.13
|
|
46
|
-
Requires-Dist: sentence-transformers>=
|
|
47
|
-
Requires-Dist: sqlalchemy[asyncio]<2.2,>=2.
|
|
46
|
+
Requires-Dist: sentence-transformers>=5.6.0
|
|
47
|
+
Requires-Dist: sqlalchemy[asyncio]<2.2,>=2.1
|
|
48
48
|
Requires-Dist: torch
|
|
49
49
|
Provides-Extra: vision
|
|
50
|
-
Requires-Dist: pypdfium2>=
|
|
50
|
+
Requires-Dist: pypdfium2>=5.0; extra == 'vision'
|
|
51
51
|
Description-Content-Type: text/markdown
|
|
52
52
|
|
|
53
53
|
# linkedparticles-core
|
|
@@ -10,7 +10,7 @@ annotated-doc==0.0.5
|
|
|
10
10
|
# typer
|
|
11
11
|
annotated-types==0.8.0
|
|
12
12
|
# via pydantic
|
|
13
|
-
anthropic==1.
|
|
13
|
+
anthropic==1.13.0
|
|
14
14
|
# via linkedparticles
|
|
15
15
|
anyio==4.14.2 ; python_full_version < '3.15'
|
|
16
16
|
# via
|
|
@@ -67,9 +67,9 @@ distro==1.9.0
|
|
|
67
67
|
# via langsmith
|
|
68
68
|
docstring-parser==0.18.0
|
|
69
69
|
# via anthropic
|
|
70
|
-
fastapi==0.
|
|
70
|
+
fastapi==0.143.0
|
|
71
71
|
# via linkedparticles
|
|
72
|
-
filelock==4.
|
|
72
|
+
filelock==4.1.1
|
|
73
73
|
# via
|
|
74
74
|
# huggingface-hub
|
|
75
75
|
# linkedparticles
|
|
@@ -148,7 +148,7 @@ jsonschema==4.26.0
|
|
|
148
148
|
# mcp
|
|
149
149
|
jsonschema-specifications==2025.9.1
|
|
150
150
|
# via jsonschema
|
|
151
|
-
langchain-core==1.6.
|
|
151
|
+
langchain-core==1.6.10
|
|
152
152
|
# via linkedparticles
|
|
153
153
|
langchain-protocol==0.0.19
|
|
154
154
|
# via langchain-core
|
|
@@ -266,7 +266,7 @@ protobuf==7.36.2
|
|
|
266
266
|
# opentelemetry-proto
|
|
267
267
|
pycparser==3.0 ; implementation_name != 'PyPy' and platform_python_implementation != 'PyPy'
|
|
268
268
|
# via cffi
|
|
269
|
-
pydantic==2.
|
|
269
|
+
pydantic==2.14.1
|
|
270
270
|
# via
|
|
271
271
|
# anthropic
|
|
272
272
|
# fastapi
|
|
@@ -275,7 +275,7 @@ pydantic==2.13.5
|
|
|
275
275
|
# linkedparticles
|
|
276
276
|
# mcp
|
|
277
277
|
# pydantic-settings
|
|
278
|
-
pydantic-core==2.
|
|
278
|
+
pydantic-core==2.50.1
|
|
279
279
|
# via pydantic
|
|
280
280
|
pydantic-settings==2.15.0
|
|
281
281
|
# via mcp
|
|
@@ -287,7 +287,7 @@ pyld==3.3.0
|
|
|
287
287
|
# via linkedparticles
|
|
288
288
|
pyparsing==3.3.3
|
|
289
289
|
# via rdflib
|
|
290
|
-
pypdf==6.
|
|
290
|
+
pypdf==6.20.1
|
|
291
291
|
# via linkedparticles
|
|
292
292
|
pypdfium2==5.14.0
|
|
293
293
|
# via linkedparticles
|
|
@@ -356,7 +356,7 @@ sniffio==1.3.1
|
|
|
356
356
|
# via
|
|
357
357
|
# anthropic
|
|
358
358
|
# langsmith
|
|
359
|
-
sqlalchemy==2.1.
|
|
359
|
+
sqlalchemy==2.1.4
|
|
360
360
|
# via
|
|
361
361
|
# alembic
|
|
362
362
|
# linkedparticles
|
|
@@ -956,6 +956,12 @@ class ExtractionConfig(BaseModel):
|
|
|
956
956
|
# The largest delta chunk sent in one call. Each chunk after the first
|
|
957
957
|
# takes the end of the chunk before it as its context.
|
|
958
958
|
append_chunk_chars: int = Field(default=7500, ge=1000)
|
|
959
|
+
# the agent extractor's prompt (the Stop hook's ask and its API
|
|
960
|
+
# proxy) tells the model how many claims text of its size usually yields,
|
|
961
|
+
# as a thoroughness guide, never a quota. 1.9 is the median claims per
|
|
962
|
+
# 1000 characters of the general extractor's transcript deltas in the
|
|
963
|
+
# maintainers' store (262 reads, measured 2026-10-16).
|
|
964
|
+
agent_expected_claims_per_kchar: float = Field(default=1.9, gt=0.0)
|
|
959
965
|
# a pair the §6.6 contradiction probe confirms is read a second
|
|
960
966
|
# time, before the write loop, with each claim's source kind, name, time
|
|
961
967
|
# and passage (on ``llm.verification``). A pair the reading does not
|
|
@@ -2801,12 +2807,21 @@ class AgentExtractionConfig(BaseModel):
|
|
|
2801
2807
|
# An ask unanswered after this many seconds is expired.
|
|
2802
2808
|
ask_ttl_seconds: int = Field(default=900, ge=60)
|
|
2803
2809
|
# A submission covers its span only with at least this many accepted claims
|
|
2804
|
-
# per 1000 characters.
|
|
2805
|
-
# extractor's own transcript deltas in the maintainers' store
|
|
2806
|
-
|
|
2810
|
+
# per 1000 characters. 1.27 is the 10th percentile of the general
|
|
2811
|
+
# extractor's own transcript deltas in the maintainers' store (262 delta
|
|
2812
|
+
# reads, measured 2026-10-16; it was 2.7 on 2026-10-09, before the
|
|
2813
|
+
# session-state and tool-turn filters thinned transcript extraction).
|
|
2814
|
+
min_claims_per_kchar: float = Field(default=1.27, ge=0.0)
|
|
2807
2815
|
# ...and with no more than this share of candidates dropped for evidence
|
|
2808
2816
|
# not found in the span. Placeholder until the shadow week measures it.
|
|
2809
2817
|
max_evidence_drop_ratio: float = Field(default=0.5, ge=0.0, le=1.0)
|
|
2818
|
+
# In shadow mode, keep each submission's accepted candidates (claim text,
|
|
2819
|
+
# stated confidence, evidence) in a local JSONL file, so a later labelling
|
|
2820
|
+
# pass can fit a calibration map on real session claims. The
|
|
2821
|
+
# operator event log keeps counts only. Off writes nothing.
|
|
2822
|
+
keep_shadow_candidates: bool = True
|
|
2823
|
+
# None ⇒ ``<claude_code.state_dir>/agent-extraction-shadow.jsonl``.
|
|
2824
|
+
shadow_candidates_path: str | None = None
|
|
2810
2825
|
|
|
2811
2826
|
@field_validator("mode", mode="before")
|
|
2812
2827
|
@classmethod
|
|
@@ -76,8 +76,7 @@ DISCLOSURE_ACTOR = "memory-consolidate"
|
|
|
76
76
|
READING_STANDING = "standing/1"
|
|
77
77
|
#: The instruction for a pair with a claim from a time-stamped record (a
|
|
78
78
|
#: session transcript, another append-only log): a value observed at a later
|
|
79
|
-
#: time may be a change, and only the same moment or a fixed fact confirms
|
|
80
|
-
#:.
|
|
79
|
+
#: time may be a change, and only the same moment or a fixed fact confirms.
|
|
81
80
|
READING_OBSERVED = "observed/1"
|
|
82
81
|
|
|
83
82
|
_EXCERPT_CHARS = 120
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/held_release.py
RENAMED
|
@@ -31,9 +31,9 @@ from particles.core.observer_scope import PairPrecondition
|
|
|
31
31
|
from particles.core.schema import Particle
|
|
32
32
|
from particles.core.status import Status, StatusReason
|
|
33
33
|
|
|
34
|
-
#: The retirements an autonomous pass writes: rung 2.5 and its sweep
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
#: The retirements an autonomous pass writes: rung 2.5 and its sweep,
|
|
35
|
+
#: the re-anchor pass, and the document sweep.
|
|
36
|
+
#: A claim a person retired is not among them, and a record
|
|
37
37
|
#: behind one stays with review.
|
|
38
38
|
AUTONOMOUS_RETIREMENTS: frozenset[StatusReason] = frozenset(
|
|
39
39
|
{
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/agent.py
RENAMED
|
@@ -55,7 +55,7 @@ log = logging.getLogger(__name__)
|
|
|
55
55
|
EXTRACTOR_ID = "claude-code-agent"
|
|
56
56
|
#: The agent prompt's version. A calibration map applies only to the version
|
|
57
57
|
#: it was fitted under, so bump this on any prompt change.
|
|
58
|
-
EXTRACTOR_VERSION = "0.
|
|
58
|
+
EXTRACTOR_VERSION = "0.2.0"
|
|
59
59
|
|
|
60
60
|
#: The MCP tool the agent submits through.
|
|
61
61
|
SUBMIT_TOOL = "extraction_submit"
|
|
@@ -78,16 +78,54 @@ _JSON_ONLY = "Return ONLY a JSON array. No prose before or after. Each element:"
|
|
|
78
78
|
_AGENT_SCHEMA_FIELD = ',\n "evidence": "<verbatim passage from the source text>"'
|
|
79
79
|
|
|
80
80
|
_SUBMIT_INSTRUCTION = """\
|
|
81
|
-
Particles memory: before you finish, extract
|
|
81
|
+
Particles memory: before you finish, extract the claims in the session text below.
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
The text is the part of this conversation not yet recorded. When you have
|
|
84
|
+
extracted it, call the `{tool}` tool exactly once with `ask_id` set to
|
|
85
|
+
"{ask_id}" and `candidates` set to the JSON array described. If the text
|
|
86
|
+
holds no claim the rules admit, call it with an empty array. Do not summarise
|
|
87
|
+
what you recorded afterwards; reply with one short line.
|
|
88
|
+
|
|
89
|
+
{thoroughness}
|
|
88
90
|
|
|
89
91
|
"""
|
|
90
92
|
|
|
93
|
+
#: Shared by the ask and the API proxy, so the proxy's benchmark and
|
|
94
|
+
#: calibration measure the prompt the agent is given. The shadow week found the
|
|
95
|
+
#: 0.1.0 ask yielding about 0.4x the general extractor's claims on the same
|
|
96
|
+
#: transcripts: the agent read "durable claims ... worth recording" as an
|
|
97
|
+
#: invitation to curate ("keeping things modest"), took a whole span in one
|
|
98
|
+
#: pass where the general extractor reads 7,500-character chunks, and wrote
|
|
99
|
+
#: every schema field of every candidate, nulls included.
|
|
100
|
+
_THOROUGHNESS = """\
|
|
101
|
+
Extract exactly as a background extractor reading this text would: every
|
|
102
|
+
individual claim the rules admit, not a summary and not a selection of
|
|
103
|
+
highlights. Do not leave a claim out because it seems minor, obvious, or true
|
|
104
|
+
only for now; what is kept is decided later, not here. Work through the text
|
|
105
|
+
in order, a few paragraphs at a time, and finish each part before moving on.
|
|
106
|
+
|
|
107
|
+
The text is about {kchars} thousand characters long. Text like this usually
|
|
108
|
+
yields about {expected} claims. That is a guide to how thorough to be, never a
|
|
109
|
+
quota: do not invent, split, or repeat claims to reach it, and record fewer
|
|
110
|
+
when the text holds fewer.
|
|
111
|
+
|
|
112
|
+
Keep each candidate compact. Always give content, subjects, confidence_value
|
|
113
|
+
and evidence; leave out every other field whose value would be null or the
|
|
114
|
+
default (uncertainty_nature EPISTEMIC, scope WORLD, assertion_modality
|
|
115
|
+
FALSIFIABLE, polarity ASSERTED)."""
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def expected_claims(span_chars: int) -> int:
|
|
119
|
+
"""How many claims a span this size usually yields: the ask's thoroughness guide."""
|
|
120
|
+
rate = get_config().extraction.agent_expected_claims_per_kchar
|
|
121
|
+
return max(1, round(rate * span_chars / 1000))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def thoroughness(span_text: str) -> str:
|
|
125
|
+
"""The completeness and compactness instructions for a span of this size."""
|
|
126
|
+
chars = len(span_text)
|
|
127
|
+
return _THOROUGHNESS.format(kchars=max(1, round(chars / 1000)), expected=expected_claims(chars))
|
|
128
|
+
|
|
91
129
|
|
|
92
130
|
def agent_rules(reference_date: str) -> str:
|
|
93
131
|
"""The agent extractor's rules: the general extractor's, plus the evidence field.
|
|
@@ -115,7 +153,9 @@ def build_ask(ask_id: str, span_text: str, *, reference_date: str | None = None)
|
|
|
115
153
|
date = reference_date or datetime.now(UTC).date().isoformat()
|
|
116
154
|
rules = agent_rules(date).replace(_JSON_ONLY, "The `candidates` array. Each element:")
|
|
117
155
|
return (
|
|
118
|
-
_SUBMIT_INSTRUCTION.format(
|
|
156
|
+
_SUBMIT_INSTRUCTION.format(
|
|
157
|
+
tool=SUBMIT_TOOL, ask_id=ask_id, thoroughness=thoroughness(span_text)
|
|
158
|
+
)
|
|
119
159
|
+ rules
|
|
120
160
|
+ "\n\n"
|
|
121
161
|
+ data_fence_instruction(nonce)
|
|
@@ -328,7 +368,9 @@ class AgentExtractor:
|
|
|
328
368
|
text = content_to_text(content)
|
|
329
369
|
nonce = make_nonce()
|
|
330
370
|
date = datetime.now(UTC).date().isoformat()
|
|
331
|
-
system =
|
|
371
|
+
system = (
|
|
372
|
+
thoroughness(text) + "\n\n" + agent_rules(date) + "\n\n" + data_fence_instruction(nonce)
|
|
373
|
+
)
|
|
332
374
|
try:
|
|
333
375
|
raw, provider_model = await complete_with_provider_model(
|
|
334
376
|
"extraction",
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/general.py
RENAMED
|
@@ -555,8 +555,8 @@ _EXTRACT_SCHEMA_TAIL = """
|
|
|
555
555
|
}"""
|
|
556
556
|
|
|
557
557
|
|
|
558
|
-
#: The rule a delta read carries when its prompt holds a context section
|
|
559
|
-
|
|
558
|
+
#: The rule a delta read carries when its prompt holds a context section.
|
|
559
|
+
#: In the prompt proper, never inlined in the chunk text, so the
|
|
560
560
|
#: instruction is a trusted rule rather than words inside the fenced data.
|
|
561
561
|
APPEND_CONTEXT_RULE = """
|
|
562
562
|
- The user message holds two fenced sections. The one labelled "context" is
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/mcp_memory.py
RENAMED
|
@@ -113,8 +113,8 @@ OBSERVATION_TAG = "memory-compat:observation"
|
|
|
113
113
|
RELATION_TAG = "memory-compat:relation"
|
|
114
114
|
#: Marks a Subject as deleted through the façade.
|
|
115
115
|
TOMBSTONE_TAG = "memory-compat:deleted"
|
|
116
|
-
#: Marks a particle as arriving by migration rather than by an agent write
|
|
117
|
-
|
|
116
|
+
#: Marks a particle as arriving by migration rather than by an agent write.
|
|
117
|
+
#: Distinct from ``CalibrationSource.IMPORTED`` on purpose: the
|
|
118
118
|
#: calibration source says *how the number was produced*, this says *which run
|
|
119
119
|
#: put the record here*, so an operator can find or retract one import.
|
|
120
120
|
IMPORT_TAG = "migration:mcp-memory"
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/extraction/subject_scope.py
RENAMED
|
@@ -40,8 +40,8 @@ from particles.core.schema import ParticleType
|
|
|
40
40
|
from particles.extraction.polarity import is_non_asserted
|
|
41
41
|
from particles.extraction.scope import is_excluded_document_meta
|
|
42
42
|
|
|
43
|
-
#: Key on the ``properties`` dict carrying the subject-scope record. Prefixed
|
|
44
|
-
|
|
43
|
+
#: Key on the ``properties`` dict carrying the subject-scope record. Prefixed;
|
|
44
|
+
#: the ``extraction:`` namespace is registered in §5.
|
|
45
45
|
SUBJECT_SCOPE_KEY = "extraction:subject_scope"
|
|
46
46
|
|
|
47
47
|
#: The one value that marks a claim as author-scoped. Absence of the key means
|
|
@@ -568,8 +568,8 @@ def is_within_directory(directory: Path, path: Path) -> bool:
|
|
|
568
568
|
return False
|
|
569
569
|
|
|
570
570
|
|
|
571
|
-
#: Ownership ledger a one-file-per-subject exporter keeps at its export root
|
|
572
|
-
|
|
571
|
+
#: Ownership ledger a one-file-per-subject exporter keeps at its export root:
|
|
572
|
+
#: the root-relative paths of every ``.md`` file its last run wrote.
|
|
573
573
|
EXPORT_MANIFEST_NAME = ".particles-export.json"
|
|
574
574
|
|
|
575
575
|
#: Append-only journal of files a run has written that its prior manifest did
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
# version and advance together.
|
|
20
20
|
[project]
|
|
21
21
|
name = "linkedparticles-core"
|
|
22
|
-
version = "1.192.
|
|
22
|
+
version = "1.192.10"
|
|
23
23
|
description = "Store-free client library for Particles: define, validate, serialize, and extract provenance-tracked belief particles"
|
|
24
24
|
readme = "README.md"
|
|
25
25
|
requires-python = ">=3.11"
|
|
@@ -63,14 +63,33 @@ classifiers = [
|
|
|
63
63
|
# by a module in this distribution. It is a subset of the engine's, never a
|
|
64
64
|
# superset: installing the engine installs this, so a package needed by both
|
|
65
65
|
# is declared in both and resolved once.
|
|
66
|
+
#
|
|
67
|
+
# These ranges are the published compatibility claim, and they are allowed to
|
|
68
|
+
# be wider than the development upstream's own floors, which a dependency bot
|
|
69
|
+
# raises to each new release. Three rules bound them, and a test in the
|
|
70
|
+
# upstream checks all three against its own pyproject and lockfile:
|
|
71
|
+
#
|
|
72
|
+
# 1. Every range admits the version the upstream's suite runs against.
|
|
73
|
+
# 2. A next-breaking upper bound is the upstream's bound, moved when it is,
|
|
74
|
+
# and the floor beneath it sits on the release line just below it: the
|
|
75
|
+
# bound declares that line the only one vetted.
|
|
76
|
+
# 3. No floor reaches back into an older major than the upstream's floor,
|
|
77
|
+
# since the code is ported to and tested on that major alone.
|
|
78
|
+
#
|
|
79
|
+
# Where a published advisory affects a path this layer exercises, the floor
|
|
80
|
+
# is the first release that fixes it, and the advisory is named beside it.
|
|
66
81
|
dependencies = [
|
|
67
82
|
"pydantic>=2.7",
|
|
68
83
|
"pyyaml>=6.0",
|
|
69
84
|
"httpx>=0.27",
|
|
70
|
-
|
|
85
|
+
# The 1.x SDK surface: the `omit` sentinel, and sampling parameters passed
|
|
86
|
+
# through `extra_body` since 1.0 dropped the typed keyword arguments.
|
|
87
|
+
"anthropic>=1.0",
|
|
71
88
|
"numpy>=1.26",
|
|
72
89
|
"scipy>=1.13",
|
|
73
|
-
|
|
90
|
+
# GHSA-jhr6-gm9c-rqjv (fixed in 5.6.0): the encoder model is loaded at
|
|
91
|
+
# runtime, so the fix is a floor here.
|
|
92
|
+
"sentence-transformers>=5.6.0",
|
|
74
93
|
# Declared explicitly *only* so `[tool.uv.sources]` below can route it to
|
|
75
94
|
# the CPU-only wheel index — uv sources apply to a project's direct
|
|
76
95
|
# dependencies, and torch is otherwise transitive via
|
|
@@ -81,22 +100,25 @@ dependencies = [
|
|
|
81
100
|
# async session; the import is executed at module load even though no
|
|
82
101
|
# Client module opens a connection. Declared so a store-free install still
|
|
83
102
|
# imports, and with `[asyncio]` because that import needs greenlet, which
|
|
84
|
-
# SQLAlchemy stopped installing by default in 2.1.
|
|
85
|
-
# minor: 2.1 changed ORM and typing behaviour this
|
|
86
|
-
|
|
103
|
+
# SQLAlchemy stopped installing by default in 2.1. Floored at 2.1 and
|
|
104
|
+
# bounded below the next minor: 2.1 changed ORM and typing behaviour this
|
|
105
|
+
# code depends on.
|
|
106
|
+
"sqlalchemy[asyncio]>=2.1,<2.2",
|
|
87
107
|
# JSON-LD / RDF / SHACL parsing stack — these handle attacker-influenced
|
|
88
108
|
# input (interchange import, conformance validation), so they carry tested
|
|
89
109
|
# next-breaking upper bounds in addition to the floor: a future breaking
|
|
90
110
|
# major of any of them must be vetted before adoption rather than pulled in
|
|
91
111
|
# silently by a downstream `pip install`.
|
|
92
|
-
"pyld>=
|
|
93
|
-
"pyshacl>=0.
|
|
112
|
+
"pyld>=3.0,<4",
|
|
113
|
+
"pyshacl>=0.40,<0.41",
|
|
94
114
|
"rdflib>=7.0,<8",
|
|
95
115
|
"jsonschema>=4.22",
|
|
96
116
|
# Deposited PDFs are attacker-influenced input on the runtime path, so this
|
|
97
|
-
# floor
|
|
98
|
-
#
|
|
99
|
-
|
|
117
|
+
# is a direct dependency floor rather than an environment constraint. 6.19.0
|
|
118
|
+
# is the first release with every published advisory fixed, the latest
|
|
119
|
+
# being GHSA-php9-fj8v-98fj, GHSA-v247-6f48-mgcj and GHSA-w23x-9jrw-r45c
|
|
120
|
+
# (CVE-2026-71852 / CVE-2026-71870 were fixed in 6.15.0).
|
|
121
|
+
"pypdf>=6.19.0",
|
|
100
122
|
"html2text>=2024.2",
|
|
101
123
|
"lxml-stubs>=0.5.1",
|
|
102
124
|
# Observability API only: a small, pure-Python, no-op-by-default package.
|
|
@@ -113,7 +135,7 @@ dependencies = [
|
|
|
113
135
|
# extractor imports it lazily and raises an actionable ImportError when vision
|
|
114
136
|
# extraction is enabled without it, so the base install stays lean.
|
|
115
137
|
vision = [
|
|
116
|
-
"pypdfium2>=
|
|
138
|
+
"pypdfium2>=5.0",
|
|
117
139
|
]
|
|
118
140
|
|
|
119
141
|
# PyPI renders these beside the description and maps the recognized names
|
|
@@ -221,11 +243,20 @@ explicit = true
|
|
|
221
243
|
[tool.uv.sources]
|
|
222
244
|
torch = [{ index = "pytorch-cpu", marker = "sys_platform != 'darwin'" }]
|
|
223
245
|
|
|
224
|
-
#
|
|
225
|
-
#
|
|
226
|
-
#
|
|
227
|
-
# the
|
|
246
|
+
# `exclude-newer` is the seven-day supply-chain cooldown: a resolve here never
|
|
247
|
+
# picks a release published in the last week, which is the window in which a
|
|
248
|
+
# compromised upload is usually caught and yanked. It is a relative span, so the
|
|
249
|
+
# committed `uv.lock` (cut by the export from this file) records the span and
|
|
250
|
+
# not a timestamp, and `uv sync --locked` stays satisfied as the days pass. The
|
|
251
|
+
# lock and this line travel together: drop the line and `uv lock --check`
|
|
252
|
+
# reports the lock stale.
|
|
253
|
+
#
|
|
254
|
+
# The `constraint-dependencies` are security floors on packages that are not
|
|
255
|
+
# direct dependencies. They arrive transitively, so a floor here raises the
|
|
256
|
+
# minimum without adding a spurious direct dependency. Revisit each line once
|
|
257
|
+
# the parent's own floor moves past the fixed version.
|
|
228
258
|
[tool.uv]
|
|
259
|
+
exclude-newer = "7 days"
|
|
229
260
|
constraint-dependencies = [
|
|
230
261
|
"idna>=3.15", # CVE-2026-45409, runtime hostname path
|
|
231
262
|
"setuptools>=83.0.0", # PYSEC-2026-3447, build path (pulled in by torch)
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/tests/test_extraction_agent.py
RENAMED
|
@@ -94,6 +94,18 @@ class TestVerifySubmission:
|
|
|
94
94
|
)
|
|
95
95
|
assert verified.accepted[0].uncertainty_nature.value == "ALEATORY"
|
|
96
96
|
|
|
97
|
+
def test_a_compact_candidate_takes_the_defaults(self) -> None:
|
|
98
|
+
# The 0.2.0 ask tells the agent to leave out null and default fields.
|
|
99
|
+
compact = {
|
|
100
|
+
"content": "Staging runs Postgres 17.",
|
|
101
|
+
"subjects": ["staging database"],
|
|
102
|
+
"confidence_value": 0.9,
|
|
103
|
+
"evidence": "Postgres 17",
|
|
104
|
+
}
|
|
105
|
+
verified = agent.verify_submission([compact], SPAN)
|
|
106
|
+
assert len(verified.accepted) == 1 and not verified.malformed
|
|
107
|
+
assert verified.accepted[0].uncertainty_nature.value == "EPISTEMIC"
|
|
108
|
+
|
|
97
109
|
|
|
98
110
|
class TestCoverage:
|
|
99
111
|
cfg = AgentExtractionConfig(min_claims_per_kchar=2.0, max_evidence_drop_ratio=0.5)
|
|
@@ -203,6 +215,35 @@ class TestPrompt:
|
|
|
203
215
|
assert '<session nonce="' in ask and "hello" in ask
|
|
204
216
|
assert "{reference_date}" not in ask
|
|
205
217
|
|
|
218
|
+
def test_ask_asks_for_every_claim_and_names_the_expected_count(self) -> None:
|
|
219
|
+
span = "## User\n\n" + "x" * 9990
|
|
220
|
+
ask = agent.build_ask("ask-123", span, reference_date="2026-10-09")
|
|
221
|
+
assert "durable" not in ask.split("Rules:")[0]
|
|
222
|
+
assert "not a selection of" in ask
|
|
223
|
+
# 10,000 characters at the default 1.9 claims per 1000.
|
|
224
|
+
assert "about 10 thousand characters" in ask and "about 19 claims" in ask
|
|
225
|
+
assert "never a\nquota" in ask
|
|
226
|
+
|
|
227
|
+
def test_expected_count_follows_config(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
228
|
+
cfg = agent.get_config().extraction
|
|
229
|
+
monkeypatch.setattr(cfg, "agent_expected_claims_per_kchar", 3.0)
|
|
230
|
+
assert agent.expected_claims(20_000) == 60
|
|
231
|
+
assert agent.expected_claims(10) == 1
|
|
232
|
+
|
|
233
|
+
async def test_the_proxy_is_given_the_same_guide(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
234
|
+
seen: dict[str, str] = {}
|
|
235
|
+
|
|
236
|
+
async def fake(purpose: str, user: str, **kwargs: Any) -> tuple[str, str]:
|
|
237
|
+
seen["system"] = kwargs["system"]
|
|
238
|
+
return "[]", "anthropic:test"
|
|
239
|
+
|
|
240
|
+
monkeypatch.setattr("particles.llm.complete_with_provider_model", fake)
|
|
241
|
+
await agent.AgentExtractor().extract(
|
|
242
|
+
None, # type: ignore[arg-type]
|
|
243
|
+
SPAN.encode(),
|
|
244
|
+
)
|
|
245
|
+
assert agent.thoroughness(SPAN) in seen["system"]
|
|
246
|
+
|
|
206
247
|
def test_rules_carry_the_general_extractor_rules(self) -> None:
|
|
207
248
|
rules = agent.agent_rules("2026-10-09")
|
|
208
249
|
assert "One particle = one falsifiable assertion" in rules
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/artifacts/conformance/README.md
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/artifacts/conformance/profile.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/artifacts/schemas/context.jsonld
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
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/__init__.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/_resources.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/contract.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/fixtures.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/jsonschema.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/profile.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/runner.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/shacl.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/types.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/conformance/validator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/cascade_gate.py
RENAMED
|
File without changes
|
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/closure_measure.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/conflict_resolution.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/conflict_review.py
RENAMED
|
File without changes
|
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/duplicate_key.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/equivalence.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/fingerprint.py
RENAMED
|
File without changes
|
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/granularity.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/jsonld_context.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/observer_scope.py
RENAMED
|
File without changes
|
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/predicate_profile.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/probe_verdict.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/rung_ladder.py
RENAMED
|
File without changes
|
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/scoring/__init__.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/scoring/confidence.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/scoring/decay.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/scoring/relevance.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/scoring/utility.py
RENAMED
|
File without changes
|
{linkedparticles_core-1.192.2 → linkedparticles_core-1.192.10}/particles/core/spend_budget.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|