pennsieve-ai-utils
Shared utilities for the Pennsieve AI Co-Scientist stages:
pennsieve-ai-scoutpennsieve-ai-hypothesizepennsieve-ai-analyzepennsieve-ai-write
Each stage used to carry its own copy of the blackboard schema, the governor
LLM client, the model-role resolver, the agent helpers and the literature
tools. They now import them from here. The package is published to PyPI as
pennsieve-ai-utils (same release flow as pennsieve-llm: push a vX.Y.Z
tag), so the Pennsieve App Store build of each stage can pip install it
without GitHub credentials.
See RUNBOOK.md for local stage supervision, stopping, review bundles and the remaining Pennsieve Test deployment work.
pip install pennsieve-ai-utils
What's here
| Module | Owns | Used by |
|---|---|---|
pennsieve_ai_utils.blackboard |
Canonical Blackboard JSON contract, schema_version migrations, unknown-field preservation |
all stages |
pennsieve_ai_utils.llm |
LLMClient: governor transport via pennsieve-llm, role-based model selection, preflight, self-healing on 403/404, usage.jsonl logging |
all stages |
pennsieve_ai_utils.models |
Role table (reasoning, synthesis, bulk), capability ranking, allow-list discovery, operator pins |
llm |
pennsieve_ai_utils.agents |
call_json, extract_json, first_text, format_datasets, attack-tag helpers, load_prompt |
every agent |
pennsieve_ai_utils.processor |
Pennsieve processor env contract (INPUT_DIR/OUTPUT_DIR/run IDs), SIGTERM handling, upstream blackboard loading, output persistence |
every main.py |
pennsieve_ai_utils.tools |
CrossRef, DataCite, DOI lookup, JATS/Markdown chunkers, Bedrock embeddings + reranker, RAG store reader | scout, hypothesize, write |
pennsieve_ai_utils.workflow |
Local four-stage supervisor, handoff gates, review bundles (python -m pennsieve_ai_utils.workflow) |
operators |
Stage-specific science — pipelines, prompts, Discover/DANDI/OpenNeuro inspection, notebook execution, manuscript rendering — stays in each app.
Blackboard contract
from pennsieve_ai_utils import Blackboard
bb = Blackboard.load("blackboard.json")
bb.record_model_assignment(
stage="hypothesize",
role="reasoning",
assignment={"model_id": "us.anthropic.claude-sonnet-4-6"},
)
bb.save("blackboard.json")
- One superset schema carries fields produced by every stage.
schema_versionenables explicit migrations; documents without a version are treated as legacy version 0.- Unknown fields are preserved at their original object level on a load/save round trip.
- Model provenance is cumulative by stage (
model_assignments[stage][role]) rather than overwritten by the next application.
LLM client
from pennsieve_ai_utils.llm import LLMClient
from pennsieve_ai_utils.agents import call_json
client = LLMClient(stage="hypothesize", roles=("reasoning", "synthesis"))
assignments = client.preflight() # raises ModelNotAvailable if a floor can't be met
for role, assignment in assignments.items():
bb.record_model_assignment(stage="hypothesize", role=role, assignment=assignment)
verdict = call_json(client, agent="critic", system=..., user=..., run_id=bb.run_id,
model="reasoning")
Agents address models by role, never by vendor tier. The legacy names
opus / sonnet / haiku still resolve as aliases of
reasoning / synthesis / bulk, and VP_MODEL_<ROLE> pins keep working.
Preflight asks the governor's GET /v1/models for the allow-list first and
falls back to tripping a model_not_allowed 403 on older governors. Each
assigned model is then verified with a one-token call so an IAM block or a
retired Bedrock model fails at startup rather than twenty minutes in.
The client needs LLM_GOVERNOR_FUNCTION_NAME (platform-injected) or
PENNSIEVE_LLM_MOCK=1 for offline tests — see
LLM access on compute nodes.
Processor helpers
from pennsieve_ai_utils.processor import (
ProcessorEnv, install_sigterm_handler, load_upstream_blackboard, write_outputs,
)
install_sigterm_handler()
env = ProcessorEnv.from_environ()
bb = load_upstream_blackboard(env.input_dir / "blackboard.json",
stage="analyze", upstream="Hypothesize",
run_id=env.execution_run_id)
...
write_outputs(bb, env.output_dir, client.usage_log)
These follow the
Pennsieve processor contract:
read from INPUT_DIR, write to OUTPUT_DIR, exit non-zero on failure.
Releasing
# bump version in pyproject.toml, commit, then:
git tag v0.2.0 && git push origin v0.2.0
.github/workflows/publish-pypi.yml builds and publishes via PyPI Trusted
Publishing. One-time setup on pypi.org: add this repository as a trusted
publisher for the pennsieve-ai-utils project (GitHub environment pypi).
Apps pin pennsieve-ai-utils>=0.2,<0.3 and pick up patch releases on rebuild.
Development
python -m pip install -e ".[dev]"
python -m ruff check src tests
python -m pytest
Metadata
Release files for pennsieve-ai-utils 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pennsieve_ai_utils-0.2.1.tar.gz | 59.4 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pennsieve_ai_utils-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 114.0 kB
Release files / pennsieve_ai_utils-0.2.1.tar.gz
| Download URL | pennsieve_ai_utils-0.2.1.tar.gz |
|---|---|
| Size | 59.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
21e4c9002f8351e22420465a63930edb4b829b2a67e284734d28441d4d489f98
|
|
BLAKE2b-256 checksum How to use checksums |
f9ea6e37716cd0ecd3e1a5a130feda95b637065b6a6d3568e67e02a73e64429e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 18, 2026.
Transparency logRelease files / pennsieve_ai_utils-0.2.1-py3-none-any.whl
| Download URL | pennsieve_ai_utils-0.2.1-py3-none-any.whl |
|---|---|
| Size | 54.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
91ca4d5a4f03241d4d23987f3f5fa1ebb533a6de2603d7c0f919592e2fbc595d
|
|
BLAKE2b-256 checksum How to use checksums |
d1964f1e52efc47eca7ebcd3f2c2a657e90bad8947e989fa6da982dccd201db5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 18, 2026.
Transparency logSecurity for pennsieve-ai-utils 0.2.1
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.
Attestation for pennsieve_ai_utils-0.2.1.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 Sep 18, 2026.
Transparency logA 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.