Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
3566bce
feat(fp-cli): open-source the Cloud CLI as `fp-cli`, command `fp`
NiveditJain Aug 17, 2026
e4f8890
docs(changelog): record the fp-cli open-sourcing (#702)
NiveditJain Aug 17, 2026
c4d9a71
feat(fp-cli): re-establish the agent-skill mirror, now as skills/fp-cli
NiveditJain Aug 17, 2026
ae14887
fix(fp-cli): remove a customer identifier, restore publish authorization
NiveditJain Aug 17, 2026
29d04e8
fix(fp-cli): stop a stdin read draining a query, and a tripwire namin…
NiveditJain Aug 17, 2026
7900b01
chore: re-trigger CI after GitHub 429s in Set up job
NiveditJain Aug 17, 2026
dc6364e
chore: re-trigger CI again — GitHub Actions still in a partial outage
NiveditJain Aug 17, 2026
80affea
chore: re-trigger CI (attempt 4) — one job per run still losing setup…
NiveditJain Aug 17, 2026
7670c90
feat(sdk): open-source the telemetry SDK as `failproofai-sdk` in sdk/…
NiveditJain Aug 17, 2026
cd52279
fix(sdk): make the zero-dependency check work on Python 3.10
NiveditJain Aug 17, 2026
7691199
test(sdk): stop the configure() thread-safety test depending on execu…
NiveditJain Aug 17, 2026
3b302ca
fix(sdk): address four CodeRabbit findings — all four were real
NiveditJain Aug 17, 2026
bc039ac
fix(fp-cli): two docs claims that contradict the shipped code
NiveditJain Aug 17, 2026
b30c492
fix(fp-cli): two --help examples that fail when you run them
SiddarthAA Aug 18, 2026
10364f3
fix(sdk): seven ways the SDK lost events without saying so
SiddarthAA Aug 18, 2026
18ef5c3
feat(fp-cli): move the session into ~/.failproofai/fpcli/cli-auth.json
SiddarthAA Aug 18, 2026
acfca52
fix(fp-cli): name the right stale session file for FP_HOME users
SiddarthAA Aug 18, 2026
e3c7e71
fix(fp-cli): three help strings still printed the pre-move config path
SiddarthAA Aug 18, 2026
ce2012d
feat(fp-cli): adopt a pre-move session instead of signing the machine…
SiddarthAA Aug 18, 2026
3b3d666
test(fp-cli): adoption must not resurrect a session after logout
SiddarthAA Aug 18, 2026
5bacab7
fix(sdk): stop the test suite writing into the developer's real spool
SiddarthAA Aug 18, 2026
33cc78a
feat(sdk)!: default the spool to ~/.failproofai/custom-agents
SiddarthAA Aug 18, 2026
d1b16b1
Merge origin/main into feat/fp-cli
SiddarthAA Aug 18, 2026
2fa3e57
test(sdk): pin what the SDK may create inside ~/.failproofai
SiddarthAA Aug 18, 2026
cc28451
fix(sdk): four review findings — durability, u32 range, NaN, cancella…
SiddarthAA Aug 18, 2026
c99dc2d
fix(sdk): five bugs found by adversarial testing, two of them crashes
SiddarthAA Aug 18, 2026
2fe57f4
test(sdk): stop the spool-contract test aborting the suite outside th…
SiddarthAA Aug 18, 2026
bb1cc99
test(fp-cli): guard the credential path against drifting from the reg…
SiddarthAA Aug 19, 2026
3c8bc31
[fp-cli] fp policies, fp fleet and fp guardrails — the dashboard's en…
SiddarthAA Aug 19, 2026
7215375
Merge origin/main into feat/fp-cli
SiddarthAA Aug 20, 2026
ee735f5
[sdk] Native support for LangChain/LangGraph, CrewAI, LlamaIndex and …
SiddarthAA Aug 20, 2026
84a7b3c
ci: ignore an unfixable chromadb advisory that cannot reach a user
SiddarthAA Aug 20, 2026
ae10911
docs(changelog): one Docs section per version, not two
SiddarthAA Aug 20, 2026
6d416b4
ci: ignore the advisory under its primary id, not only its alias
SiddarthAA Aug 20, 2026
3a0e57b
ci: make the root osv-scanner.toml govern every lockfile it scans
SiddarthAA Aug 20, 2026
0c0ff4c
fix(fp-cli): stop the customer tripwire from publishing the name it h…
SiddarthAA Aug 20, 2026
e3271fc
docs(sdk): correct the spool root the README tells readers to look in
SiddarthAA Aug 20, 2026
9bbccaa
fix(failproofaid): --help printed nothing and started the daemon
SiddarthAA Aug 20, 2026
320598a
ci(sdk): actually run the framework integration suites
SiddarthAA Aug 20, 2026
ad48c92
chore(fp-cli): stop fixtures and help text naming a real domain
SiddarthAA Aug 20, 2026
f1e68f7
fix(fp-cli): `fp issues show <malformed-id>` never reached its not-fo…
SiddarthAA Aug 20, 2026
de388b1
fix(collect): park a batch the server stored none of, instead of dele…
SiddarthAA Aug 20, 2026
6372ecf
fix(fp-cli): resolve a member by the email the caller actually typed
SiddarthAA Aug 20, 2026
b672543
fix(sdk): document model_response's real keyword, and guard the class
SiddarthAA Aug 20, 2026
bed3d39
docs(integrations): let the page shape match what is being explained
SiddarthAA Aug 20, 2026
ab4d76c
docs(skill): correct three stale claims, and guard the prose
SiddarthAA Aug 20, 2026
d7dd7cc
fix(sdk): stop $AGENTEYE_HOME from moving the spool off the umbrella
SiddarthAA Aug 20, 2026
a720f38
fix(fp-cli): sum every policy source in the decision timeline, not se…
SiddarthAA Aug 20, 2026
9634840
docs(cloud-cli): stop denying commands the CLI has, and name the real…
SiddarthAA Aug 20, 2026
362de76
docs(fp-cli): compose needs policies:write, not agent:use
SiddarthAA Aug 20, 2026
95e4b24
feat(sdk): raise LangChain's capture limit, and tie the event budget …
SiddarthAA Aug 21, 2026
05b47fa
Merge origin/main into feat/fp-cli
NiveditJain Aug 21, 2026
45a1faf
fix(sdk): stop the shipped SIGTERM recipe from deadlocking the host p…
SiddarthAA Aug 24, 2026
4737073
fix(sdk): make the adapters' size budget, privacy switch and error ac…
SiddarthAA Aug 24, 2026
e6025f7
fix(sdk): stop the sdist poisoning a real spool, and make four guards…
SiddarthAA Aug 24, 2026
7c4c10f
fix(fp-cli): stop the CLI reporting success it did not have, and leak…
SiddarthAA Aug 24, 2026
f16eae8
fix(collect): stop the delivery-health signal reporting success while…
SiddarthAA Aug 24, 2026
790a7b0
docs: correct nine claims the code disproves, and guard the two that …
SiddarthAA Aug 24, 2026
e354054
ci: make the publish gate test the adapters, and the workflow guards …
SiddarthAA Aug 24, 2026
aa87d6a
docs(changelog): record the review fixes under 1.0.2-beta.0
SiddarthAA Aug 24, 2026
236534f
fix(fp-cli): relock for the corrected typer floor
SiddarthAA Aug 24, 2026
01f6799
Merge remote-tracking branch 'origin/main' into feat/fp-cli
SiddarthAA Aug 24, 2026
bd9b68e
Merge remote-tracking branch 'origin/feat/fp-cli' into feat/fp-cli
SiddarthAA Aug 24, 2026
4ce3b58
fix(sdk): bound the queue by measured bytes, and stop an oversized ev…
SiddarthAA Aug 24, 2026
e4b51bf
fix(collect): stop a partially-accepted batch destroying the events i…
SiddarthAA Aug 24, 2026
21cec5b
fix(fp-cli): stop a failed membership lookup reading as "you belong t…
SiddarthAA Aug 24, 2026
915a592
ci: keep the publishing identity and the mirror's code out of the sam…
SiddarthAA Aug 24, 2026
35c4d52
docs(changelog): record the second-review fixes
SiddarthAA Aug 24, 2026
8306b91
fix(fp-cli): stop a busy machine being reported as a broken policy
SiddarthAA Aug 24, 2026
2f18ac4
chore(release): open both Python packages at 0.0.1b1
NiveditJain Aug 24, 2026
51738dd
feat(ci): version management pipelines for fp-cli and failproofai-sdk
NiveditJain Aug 24, 2026
01977ab
docs(claude): record the Python packages' release scheme
NiveditJain Aug 24, 2026
cc9a710
fix(ci): close the re-run bypass in the PyPI publish guard
NiveditJain Aug 24, 2026
8762e27
fix(sdk): stop the writer thread flushing into whichever test is running
NiveditJain Aug 24, 2026
9c81113
docs(ci): point PyPI setup at the page that exists for an unregistere…
NiveditJain Aug 24, 2026
2ecb250
feat(ci): GitHub Releases and changelogs for both Python packages
NiveditJain Aug 24, 2026
e385535
refactor: rename the Cloud CLI distribution to fp-cloud-cli
NiveditJain Aug 24, 2026
60f4dc8
docs: restructure the agent-instrumentation docs, and make the star c…
SiddarthAA Aug 24, 2026
dd8cf5a
Merge remote-tracking branch 'origin/feat/fp-cli' into feat/fp-cli
SiddarthAA Aug 24, 2026
146cacf
fix(docs): move the 14 locale SDK reference copies with their English…
NiveditJain Aug 24, 2026
dac8639
test: cover the live star count and the Python package registration
NiveditJain Aug 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,35 @@ updates:
rust-dependencies:
patterns:
- "*"

# The `fp` CLI (PyPI: fp-cli) — the only Python in the repo. Its lockfile is
# `fp-cli/uv.lock`, so the ecosystem is `uv`, and the directory is the package
# root rather than `/`. Grouped for the same reason as the Rust tree: the whole
# dependency set is verified together by one pytest run, and separate PRs each
# rebuild the lockfile the others just changed.
- package-ecosystem: uv
directory: /fp-cli
schedule:
interval: weekly
day: monday
open-pull-requests-limit: 5
groups:
python-dependencies:
patterns:
- "*"

# The telemetry SDK (PyPI: failproofai-sdk). Its own lockfile and its own uv
# ecosystem entry — dependabot resolves per directory, so fp-cli's entry above
# does not see this tree at all. The only things in the lockfile are the test
# runner and its transitive deps: the package itself declares NO runtime
# dependencies, and `tests/test_zero_dependencies.py` fails if that changes.
- package-ecosystem: uv
directory: /sdk/python
schedule:
interval: weekly
day: monday
open-pull-requests-limit: 5
groups:
python-dependencies:
patterns:
- "*"
151 changes: 151 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,157 @@ jobs:
target
key: cargo-${{ runner.os }}-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock', 'crates/*/Cargo.toml') }}

# The `fp` CLI (PyPI: fp-cli). The only Python in this repo, and the only job that
# tests it — none of the bun/cargo jobs above look at fp-cli/ at all. It is matrixed
# across the Python versions pyproject.toml's requires-python advertises, because
# claiming >=3.10 and testing only one of them is how a 3.10 user finds the break.
fp-cli:
runs-on: ubuntu-latest
defaults:
run:
working-directory: fp-cli
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.13"]
steps:
- uses: actions/checkout@v7.0.1

- uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: fp-cli/uv.lock

- name: Install dependencies
run: uv sync --locked --extra dev --python ${{ matrix.python-version }}

- name: Test
run: uv run pytest tests/ -q

- name: Build the distribution
run: uv build

# A stale `include = [...]` in [tool.setuptools.packages.find] builds a
# SUCCESSFUL but EMPTY wheel — pip installs it and the console script then
# ImportErrors. Nothing else in this job would notice, so assert the payload.
- name: Verify the wheel actually contains the package
run: |
python3 - <<'PY'
import glob, sys, zipfile
wheel = glob.glob("dist/*.whl")[0]
names = zipfile.ZipFile(wheel).namelist()
modules = [n for n in names if n.startswith("fp_cli/") and n.endswith(".py")]
print(f"{wheel}: {len(modules)} modules")
if len(modules) < 20:
sys.exit(f"wheel looks empty — only {len(modules)} modules under fp_cli/")
PY

# `fp` is the contract users type. Prove the entry point resolves from a clean
# install of the built artifact, not from the source tree.
- name: Smoke-test the installed console script
run: |
uv venv /tmp/fp-smoke
VIRTUAL_ENV=/tmp/fp-smoke uv pip install dist/*.whl
/tmp/fp-smoke/bin/fp --version
/tmp/fp-smoke/bin/fp help > /tmp/fp-help.txt
if grep -qi agenteye /tmp/fp-help.txt; then
echo '::error::retired product name present in the fp help output'
exit 1
fi

# The telemetry SDK (PyPI: failproofai-sdk, import failproofai_sdk). Second Python
# component, sibling of fp-cli above, and deliberately its own job: it shares no
# lockfile, no dependencies and no release cadence with the CLI.
#
# The matrix is wider than fp-cli's two versions on purpose. This package declares
# no dependencies at all, so it has no third-party floor quietly constraining which
# interpreters it is really exercised on — and it is installed into other people's
# agent processes, whose Python version we do not choose. Every version
# requires-python advertises is tested.
failproofai-sdk:
runs-on: ubuntu-latest
defaults:
run:
working-directory: sdk/python
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@v7.0.1

- uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: sdk/python/uv.lock

- name: Install dependencies
run: uv sync --locked --extra dev --python ${{ matrix.python-version }}

# FAILPROOFAI_SDK_REQUIRE_CONTRACT makes test_spool_contract.py FAIL rather than
# skip when it cannot find crates/fpai-collect or src/hooks/fp-home.ts. Those
# assertions are the only check that this SDK writes where the daemon reads, and
# a guard that can silently degrade to a skip is not a guard — its predecessor in
# the agenteye repo skipped in every CI run for exactly this reason.
- name: Test
env:
FAILPROOFAI_SDK_REQUIRE_CONTRACT: "1"
run: uv run pytest tests/ -q

- name: Build the distribution
run: uv build

# A stale `include = [...]` in [tool.setuptools.packages.find] builds a
# SUCCESSFUL but EMPTY wheel — pip installs it and the import then fails.
# py.typed goes the same way if package-data stops naming it, and nothing
# else in this job would notice either. Assert the payload.
- name: Verify the wheel actually contains the package
run: |
python3 - <<'PY'
import glob, sys, zipfile
wheel = glob.glob("dist/*.whl")[0]
names = zipfile.ZipFile(wheel).namelist()
modules = [n for n in names if n.startswith("failproofai_sdk/") and n.endswith(".py")]
print(f"{wheel}: {len(modules)} modules")
if len(modules) < 7:
sys.exit(f"wheel looks empty — only {len(modules)} modules under failproofai_sdk/")
if not any(n.endswith("py.typed") for n in names):
sys.exit("py.typed is missing from the wheel — the type hints do not count without it")
if not any(n.endswith("LICENSE") for n in names):
sys.exit("LICENSE is missing from the wheel")
PY

# `--no-deps` is the assertion, not an optimisation. "Zero dependencies" is the
# reason this package is safe to drop into someone else's agent, so prove it
# against the built artifact rather than the source tree: install it with nothing
# else present, emit real events, and read them back off disk.
- name: Smoke-test the installed package with no dependencies
run: |
uv venv /tmp/sdk-smoke
VIRTUAL_ENV=/tmp/sdk-smoke uv pip install --no-deps dist/*.whl
AGENTEYE_HOME=/tmp/sdk-spool /tmp/sdk-smoke/bin/python -c "
import failproofai_sdk as s
print(s.__version__)
s.event.agent_start(session_id='smoke', agent_id='a', goal='ci')
s.event.tool_use(session_id='smoke', agent_id='a', tool_name='t', tool_call_id='c')
s.event.tool_result(session_id='smoke', agent_id='a', tool_name='t', tool_call_id='c', output='ok')
"
python3 - <<'PY'
import glob, json, sys
batches = glob.glob("/tmp/sdk-spool/events/*.jsonl")
if not batches:
sys.exit("the installed wheel wrote no event batch")
events = [json.loads(line) for p in batches for line in open(p) if line.strip()]
types = {e["type"] for e in events}
if types != {"agent_start", "tool_use", "tool_result"}:
sys.exit(f"unexpected events from the installed wheel: {sorted(types)}")
# Emitted by the artifact, so this also proves the wire format survived
# packaging rather than only surviving an in-tree import.
if not all("environment" in e for e in events):
sys.exit("an event reached disk without the `environment` field")
print(f"{len(events)} events written by the installed artifact")
PY

test:
runs-on: ubuntu-latest
strategy:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/osv-scanner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ jobs:
scan-args: |-
--lockfile=bun.lock
--lockfile=Cargo.lock
--lockfile=fp-cli/uv.lock
--lockfile=sdk/python/uv.lock
# Only the schedule run notifies — nothing on main touched the lockfile,
# so nobody is watching it the way a PR author watches their own checks
# or a push failure shows up against the commit they just merged. Same
Expand Down
167 changes: 167 additions & 0 deletions .github/workflows/publish-failproofai-sdk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
name: Publish failproofai-sdk to PyPI

# The telemetry SDK (PyPI project: failproofai-sdk) ships on its own cadence, separate
# from the npm package, the daemon binaries in publish.yml, and its sibling fp-cli. It
# is a pure-Python wheel with no platform matrix and no release assets, so it has
# nothing to share with those pipelines beyond credentials it does not use.
#
# AUTHENTICATION IS PyPI TRUSTED PUBLISHING (OIDC) — there is no PYPI_API_TOKEN secret.
# This requires a one-time, out-of-band setup on PyPI that CANNOT be done from a PR:
#
# PyPI project `failproofai-sdk` -> Manage -> Publishing -> Add a new pending publisher
# Owner: FailproofAI
# Repository: failproofai
# Workflow name: publish-failproofai-sdk.yml
# Environment: pypi-failproofai-sdk <- REQUIRED, do not leave blank
#
# Until that publisher exists the `publish` job fails at the upload step with an OIDC
# error. Configure it BEFORE the first release, not after.
#
# The environment is load-bearing, not decoration. Every check in this file lives on the
# ref being dispatched, so a writer can delete them on a branch and click Run — the OIDC
# token is minted for whatever the workflow then asks for. Two settings OUTSIDE this file
# are what a branch edit cannot reach:
#
# 1. Repo -> Settings -> Environments -> `pypi-failproofai-sdk`:
# Deployment branches: `main` only (and add required reviewers if you want a
# second pair of eyes on every release).
# A job referencing this environment from any other ref is refused before it starts.
# NOTE: GitHub creates a missing environment implicitly, WITHOUT protection rules —
# so this is not self-configuring; set it up by hand.
# 2. The `Environment: pypi-failproofai-sdk` field above. PyPI then rejects a token
# whose `environment` claim is missing or different, which is what stops someone
# from simply deleting the `environment:` line below.

on:
workflow_dispatch:
inputs:
dry_run:
description: Build and verify, but do not upload to PyPI
type: boolean
default: false

concurrency:
group: publish-failproofai-sdk
cancel-in-progress: false

jobs:
publish:
runs-on: ubuntu-latest
# Gates this job on the repo-level environment rules described in the header, and puts
# the environment name in the OIDC token PyPI checks. Both halves are outside this file.
environment: pypi-failproofai-sdk
defaults:
run:
working-directory: sdk/python
permissions:
# Naming ANY scope sets every unnamed one to `none` — it is not an addition to the
# defaults. `contents: read` is therefore not redundant: without it `actions/checkout`
# gets a token that cannot read this repository.
contents: read
id-token: write # required for Trusted Publishing
steps:
# Authentication is OIDC, so there is no token to withhold: repo write access IS
# publish access, and `workflow_dispatch` can target ANY ref. Without these two
# checks one "Run workflow" click on an unreviewed branch ships that branch to
# public PyPI as an official failproofai-sdk release, unreviewable and
# unrecallable (PyPI versions cannot be reused).
#
# These are the readable guard, not the enforcement: they live on the ref being
# dispatched, so a writer could delete them on a branch. The `environment:` above
# plus its two out-of-file settings (see the header) are what actually hold.
- name: Authorize actor and branch
env:
ACTOR: ${{ github.actor }}
REF: ${{ github.ref_name }}
run: |
if [ "$ACTOR" != "NiveditJain" ]; then
echo "::error::Unauthorized. Only NiveditJain can publish failproofai-sdk."
exit 1
fi
if [ "$REF" != "main" ]; then
echo "::error::Refusing to publish from '$REF'. failproofai-sdk publishes from main only."
exit 1
fi

- uses: actions/checkout@v7.0.1

- uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: sdk/python/uv.lock

- name: Install dependencies
run: uv sync --locked --extra dev

# Never publish a version whose tests do not pass. This duplicates the ci job on
# purpose: a workflow_dispatch can target any ref, including one CI never ran.
# FAILPROOFAI_SDK_REQUIRE_CONTRACT turns a missing daemon source into a failure
# rather than a skip, so the spool contract cannot go unverified on a release.
- name: Test
env:
FAILPROOFAI_SDK_REQUIRE_CONTRACT: "1"
run: uv run pytest tests/ -q

- name: Build
run: uv build

- name: Verify the artifacts before uploading
run: |
python3 - <<'PY'
import glob, sys, zipfile
wheel = glob.glob("dist/*.whl")[0]
names = zipfile.ZipFile(wheel).namelist()
modules = [n for n in names if n.startswith("failproofai_sdk/") and n.endswith(".py")]
if len(modules) < 7:
sys.exit(f"refusing to publish an empty wheel ({len(modules)} modules)")
if not any(n.endswith("LICENSE") for n in names):
sys.exit("refusing to publish without a LICENSE in the wheel")
# py.typed is the only thing that makes the annotations count for a
# type checker, and it is absent from the wheel unless package-data
# names it — a build that silently drops it looks identical here
# otherwise.
if not any(n.endswith("py.typed") for n in names):
sys.exit("refusing to publish without py.typed in the wheel")
print(f"{wheel}: {len(modules)} modules, licence and py.typed present")
PY

# The CI job proves the artifact installs with no dependencies and emits real
# events; the publish path must not prove less than CI does. A wheel whose zip
# looks right but which cannot import, or which quietly acquired a dependency,
# is exactly the failure this catches — and it is unrecallable once uploaded.
- name: Smoke-test the artifact exactly as a user would receive it
run: |
uv venv /tmp/sdk-publish-smoke
# --no-deps is the assertion, not an optimisation: this package must
# install and work with nothing else present.
VIRTUAL_ENV=/tmp/sdk-publish-smoke uv pip install --no-deps dist/*.whl
AGENTEYE_HOME=/tmp/sdk-publish-spool /tmp/sdk-publish-smoke/bin/python -c "
import failproofai_sdk as s
print(s.__version__)
s.event.agent_start(session_id='smoke', agent_id='a', goal='publish check')
s.event.tool_use(session_id='smoke', agent_id='a', tool_name='t', tool_call_id='c')
s.event.tool_result(session_id='smoke', agent_id='a', tool_name='t', tool_call_id='c', output='ok')
"
python3 - <<'PY'
import glob, json, sys
batches = glob.glob("/tmp/sdk-publish-spool/events/*.jsonl")
if not batches:
sys.exit("the installed wheel wrote no event batch")
events = [json.loads(l) for p in batches for l in open(p) if l.strip()]
types = {e["type"] for e in events}
if types != {"agent_start", "tool_use", "tool_result"}:
sys.exit(f"unexpected events from the installed wheel: {sorted(types)}")
print(f"{len(events)} events written by the installed artifact")
PY

- name: Report the version being published
run: |
VERSION=$(uv run python -c 'from failproofai_sdk._version import __version__; print(__version__)')
echo "failproofai-sdk version: ${VERSION}"
echo "### Publishing \`failproofai-sdk\` ${VERSION}" >> "${GITHUB_STEP_SUMMARY}"

- name: Publish to PyPI
if: ${{ !inputs.dry_run }}
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: sdk/python/dist/
Loading
Loading