Skip to main content

argus-cortex

Shared foundation for the Argus suite: taxonomy, versioned wire-schema tooling, and the local/remote AI backend contract.

Part of the Argus suite (quarry → curator → lens → forge → proof). This is the library the stages import so the code they share — the target taxonomy, the wire-schema versioning discipline, and the way they call local or hosted models — lives in one place instead of being copy-pasted per repo.

What's here

  • argus_cortex.taxonomy — TargetProfile / TargetStyle / TargetCategory, the "moat" types every stage inherits verbatim.
  • argus_cortex.wire — the versioned wire-schema toolkit: check_version() (major-compatibility gate), make_versioned_base() (a Pydantic base that stamps + checks a version field like proof_version / manifest_version), and wire_schema() / render_schema() for the committed-schema schema --check CLI pattern.
  • argus_cortex.backends — the AI-backend contract generalised from argus-lens: Backend / LocalBackend / RemoteBackend (point at a hosted service by base_url, host/port, or a known RemoteProvider), plus with_retries() and resolve_device(). httpx lives behind the [remote] extra.
  • argus_cortex.server — shared write-guard + env-flag scaffolding for the suite's FastAPI micro-servers: WriteGuard (a pure-ASGI method-gate that never buffers streaming responses), the constant_refuse() / cross_site_refuse() predicates (read-only/replay mode and cross-site-write protection are two configs of the one guard), the UNSAFE_METHODS / TRUTHY / FALSY constants, and env_flag() (warns on a mistyped protection flag rather than silently disabling it). Starlette lives behind the [server] extra.
  • argus_cortex.xmp — the suite's one XMP sidecar implementation (hoisted from argus-lens): write_xmp() / read_xmp() / merge_xmp() / parse_xmp() over an XmpData model covering dc (keywords, description), xmp (Rating, Label), lr (hierarchical keywords), Iptc4xmpExt (PersonInImage), mwg-rs face/pet regions, and argus:ContentRating. Writes merge: each property you set replaces that property (latest write wins), everything else in the sidecar — Lightroom develop settings, GPS, another stage's fields — is preserved. None leaves a property alone, an empty value removes it. Writes are atomic; an unparseable existing sidecar raises XmpError instead of being clobbered. Stdlib only.
  • argus_cortex.store — the optional stateful services layer (the suite's persistent "memory"). External and opt-in — every store is configured by CORTEX_* env vars and no-ops when its URL is unset.
    • Phase 1 — Postgres lineage store. Persists the source_asset → caption → human_edit → dataset_membership → training_run DAG for LoRA reproducibility, edit capture, and the feedback loop. Backed by a psycopg connection pool (concurrent asyncio.to_thread calls are safe; a dropped connection is replaced), with a transaction() boundary for atomic multi-step writes. open_lineage_store() returns a no-op store when CORTEX_PG_URL is unset; psycopg lives behind the [postgres] extra.
    • Phase 2 — Qdrant vector store. Stores image + tag-set embeddings for retrieval-augmented few-shot and near-duplicate curation; put a caption_id/asset_id in a point's payload and a search hit joins straight back to the lineage. open_vector_store() no-ops when CORTEX_QDRANT_URL is unset; qdrant-client lives behind the [qdrant] extra. cortex stores vectors it's handed — computing embeddings is the caller's job.
    • Phase 3 — MinIO/S3 blob store. Owns image bytes when cortex can't rely on the filesystem/Immich (exported/selected training images). Blobs are content-addressed on sha256 (content_key() == source_asset.sha256), so storage, dedup, and lineage join share one identity. open_blob_store() no-ops when CORTEX_S3_ENDPOINT/CORTEX_S3_BUCKET are unset; the minio client lives behind the [s3] extra.
from argus_cortex.wire import make_versioned_base, render_schema
from argus_cortex.backends import RemoteBackend, RemoteProvider

# per-package versioned base (readable field name kept local, logic shared)
_Versioned = make_versioned_base("proof_version", "1.0", ("1",))

# reach a hosted scorer by IP/port, or a known provider
scorer = RemoteBackend.from_host("192.168.1.20", 9000, api_key="…")
nim = RemoteBackend.from_provider(RemoteProvider.NVIDIA_NIM, api_key="…")
from argus_cortex.xmp import XmpData, XmpRegion, XmpRegions, write_xmp

# lens writes captions/keywords …
write_xmp("pics/beach.jpg", XmpData(keywords=["beach", "sunset"], description="a beach at sunset"))
# … curator later adds faces + a content rating to the same sidecar; lens's fields survive
write_xmp(
    "pics/beach.jpg",
    XmpData(
        persons=["Ada"],
        regions=XmpRegions(width=4000, height=3000, regions=[XmpRegion(x=0.52, y=0.4, w=0.1, h=0.18, name="Ada")]),
        content_rating="safe",
    ),
)
from argus_cortex.store import open_lineage_store, SourceAsset, Caption, HumanEdit

# no-op if CORTEX_PG_URL is unset; PostgresLineageStore if it's set
store = open_lineage_store()          # reads CORTEX_* from the environment
store.ensure_schema()                 # idempotent bootstrap of the lineage tables

# one atomic unit — the asset + caption + edit commit together or not at all
with store.transaction():
    asset_id = store.record_asset(SourceAsset(uri="immich://…", sha256="…"))
    # lens emits a CaptionResult; cortex ingests it (cortex never imports lens)
    cap_id = store.record_caption(asset_id, Caption.from_caption_result(result, profile={...}))
    store.record_edit(cap_id, HumanEdit(edited_caption="…", editor="alice"))

# the (model_caption, edited_caption) pairs the summariser feedback loop trains on
pairs = store.caption_edit_pairs()
from argus_cortex.store import open_vector_store, IMAGE_COLLECTION

# no-op if CORTEX_QDRANT_URL is unset; QdrantVectorStore if it's set
vec = open_vector_store()
vec.ensure_collection(IMAGE_COLLECTION, dim=512)   # idempotent

# store an embedding you computed, tagged with its lineage id
vec.upsert(IMAGE_COLLECTION, point_id=cap_id, vector=embedding, payload={"caption_id": cap_id})

# retrieve similar past captions to steer the summariser (few-shot)
hits = vec.search(IMAGE_COLLECTION, vector=query_embedding, top_k=5)
similar_caption_ids = [h.payload["caption_id"] for h in hits]   # join back to Postgres
from argus_cortex.store import open_blob_store

# no-op if CORTEX_S3_ENDPOINT / CORTEX_S3_BUCKET are unset; S3BlobStore if set
blobs = open_blob_store()
blobs.ensure_bucket()

# content-addressed: the returned key IS the sha256 (== source_asset.sha256)
sha = blobs.put_content_addressed(image_bytes, content_type="image/jpeg")
data = blobs.get(sha)                    # bytes, or None if absent
link = blobs.url(sha, expires=3600)      # presigned GET URL

Install

uv pip install argus-cortex              # core (pydantic only)
uv pip install "argus-cortex[remote]"    # + httpx for RemoteBackend
uv pip install "argus-cortex[server]"    # + starlette for argus_cortex.server (WriteGuard, env_flag)
uv pip install "argus-cortex[postgres]"  # + psycopg for the lineage store
uv pip install "argus-cortex[qdrant]"    # + qdrant-client for the vector store
uv pip install "argus-cortex[s3]"        # + minio for the blob store

The stateful services are configured via CORTEX_* env vars — see .env.example. Each is optional: leave a URL unset and that feature degrades to a no-op.

Develop

make install   # venv + editable install with the "dev" extras
make test
make lint

CI / Release

  • CI runs via the shared argus-ci reusable workflow.
  • Release publishes to PyPI (OIDC trusted publishing) on v* tags. No container image — this is a library.
  • Versioning is derived from git tags via hatch-vcs — tag vX.Y.Z to cut a release.

This repo was scaffolded from argus-pkg-template. Run copier update to pull template changes (CI, release, tooling).

Metadata

Release files for argus-cortex 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for argus-cortex 0.3.0
File Size Uploaded Provenance
argus_cortex-0.3.0.tar.gz 58.3 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for argus-cortex 0.3.0
File Interpreter ABI Platform
argus_cortex-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 102.7 kB

Release files / argus_cortex-0.3.0.tar.gz

Download URL argus_cortex-0.3.0.tar.gz
Size 58.3 kB
Tags Source
SHA-256 checksum
How to use checksums
c122987cb9c01e7f851a580eea4f558492dd81230696da32db26ec1e40cf6b09
BLAKE2b-256 checksum
How to use checksums
0f630a72c47e0047f120598adbae5209148127581491129a716b5c4f3620ef5a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

Release files / argus_cortex-0.3.0-py3-none-any.whl

Download URL argus_cortex-0.3.0-py3-none-any.whl
Size 44.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6acc66b7f394ee078ad863bec644009c58c4055286e2378117f7dbd917ea1796
BLAKE2b-256 checksum
How to use checksums
66999da1f5d68ee44bd4c83a757b1375b36cc814610d38bdd6390dc8a1e18c56
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

Security for argus-cortex 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for argus_cortex-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page