Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
136 changes: 136 additions & 0 deletions .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Publishes agent-learning-kit to PyPI (Trusted Publishing) on merge to main,
# only when the pyproject version is not yet on PyPI.
# Release: bump `version` in pyproject.toml + `uv lock`, merge, approve the
# `pypi` environment deployment. PyPI publisher: pending publisher at
# https://pypi.org/manage/account/publishing/ (repo agent-learning-kit,
# workflow publish-pypi.yml, environment pypi).
name: publish-pypi

on:
push:
branches: [main]

permissions:
contents: read

concurrency:
group: publish-pypi-main
cancel-in-progress: false

env:
PYPI_PROJECT: agent-learning-kit
UV_VERSION: "0.12.9"

jobs:
check:
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
publish: ${{ steps.v.outputs.publish }}
version: ${{ steps.v.outputs.version }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
with:
version: ${{ env.UV_VERSION }}
- id: v
env:
REF: ${{ github.ref }}
SHA: ${{ github.sha }}
HEADLINE: ${{ github.event.head_commit.message }}
shell: bash
run: |
set -euo pipefail
[[ "$REF" == refs/heads/main ]] || { echo "::error::refusing to publish from $REF"; exit 1; }
version="$(uv version --short)"
[[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+([a-z0-9.]*)$ ]] || { echo "::error::unexpected version shape"; exit 1; }
echo "version=$version" >> "$GITHUB_OUTPUT"
wheel="agent_learning_kit-${version}-py3-none-any.whl"; sdist="agent_learning_kit-${version}.tar.gz"
body="$(mktemp)"
code="$(curl -sS --max-time 30 --retry 3 --retry-delay 2 -o "$body" -w '%{http_code}' \
"https://pypi.org/pypi/${PYPI_PROJECT}/json")"
case "$code" in
404) publish=true; why="first release" ;;
200) if jq -e --arg v "$version" --arg w "$wheel" --arg s "$sdist" \
'(.releases[$v] // []) | map(.filename) | (index($w) != null and index($s) != null)' "$body" >/dev/null
then publish=false; why="already on PyPI"
else publish=true; why="not on PyPI"; fi ;;
*) echo "::error::PyPI lookup returned HTTP $code"; exit 1 ;;
esac
echo "publish=$publish" >> "$GITHUB_OUTPUT"
{
echo "## ${PYPI_PROJECT} **${version}** — ${why}"
echo "- commit: \`${SHA}\` — ${HEADLINE%%$'\n'*}"
} >> "$GITHUB_STEP_SUMMARY"

build:
needs: check
if: needs.check.outputs.publish == 'true'
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
with:
version: ${{ env.UV_VERSION }}
- run: uv build
- run: |
set -euo pipefail
uv venv .smoke --python 3.12
uv pip install --python .smoke/bin/python dist/*.whl
.smoke/bin/python -c "import fi.simulate.hosted.child_entrypoint, fi.alk.harness"
.smoke/bin/alk --help > /dev/null
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: dist
path: dist/
if-no-files-found: error

publish:
needs: [check, build]
if: needs.check.outputs.publish == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
environment: pypi
permissions:
id-token: write
contents: read
env:
VERSION: ${{ needs.check.outputs.version }}
steps:
- id: recheck
shell: bash
run: |
set -euo pipefail
wheel="agent_learning_kit-${VERSION}-py3-none-any.whl"; sdist="agent_learning_kit-${VERSION}.tar.gz"
body="$(mktemp)"
code="$(curl -sS --max-time 30 --retry 3 --retry-delay 2 -o "$body" -w '%{http_code}' \
"https://pypi.org/pypi/${PYPI_PROJECT}/json")"
if [[ "$code" == 200 ]] && jq -e --arg v "$VERSION" --arg w "$wheel" --arg s "$sdist" \
'(.releases[$v] // []) | map(.filename) | (index($w) != null and index($s) != null)' "$body" >/dev/null; then
echo "go=false" >> "$GITHUB_OUTPUT"
elif [[ "$code" == 200 || "$code" == 404 ]]; then
echo "go=true" >> "$GITHUB_OUTPUT"
else
echo "::error::PyPI lookup returned HTTP $code"; exit 1
fi
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
if: steps.recheck.outputs.go == 'true'
with:
name: dist
path: dist/
- if: steps.recheck.outputs.go == 'true'
shell: bash
run: |
set -euo pipefail
expected=$(printf '%s\n' "agent_learning_kit-${VERSION}-py3-none-any.whl" "agent_learning_kit-${VERSION}.tar.gz" | sort)
[[ "$(ls -1 dist/ | sort)" == "$expected" ]] || { echo "::error::dist/ does not match version ${VERSION}"; ls -la dist/; exit 1; }
- uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
if: steps.recheck.outputs.go == 'true'
with:
attestations: true
skip-existing: true
86 changes: 43 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<p align="center">
<img src="docs/assets/futureagi-mark-email.png" alt="Future AGI" width="72" />
<img src="https://raw.githubusercontent.com/future-agi/agent-learning-kit/main/docs/assets/futureagi-mark-email.png" alt="Future AGI" width="72" />
</p>

<h1 align="center">Agent Learning Kit</h1>
Expand All @@ -9,20 +9,20 @@
</p>

<p align="center">
<a href="LICENSE">Apache-2.0</a>
<a href="https://github.com/future-agi/agent-learning-kit/blob/main/LICENSE">Apache-2.0</a>
·
<a href="docs/index.md">Docs</a>
<a href="https://github.com/future-agi/agent-learning-kit/blob/main/docs/index.md">Docs</a>
·
<a href="CONTRIBUTING.md">Contributing</a>
<a href="https://github.com/future-agi/agent-learning-kit/blob/main/CONTRIBUTING.md">Contributing</a>
·
<a href="SECURITY.md">Security</a>
<a href="https://github.com/future-agi/agent-learning-kit/blob/main/SECURITY.md">Security</a>
·
<a href="ROADMAP.md">V1 roadmap</a>
<a href="https://github.com/future-agi/agent-learning-kit/blob/main/ROADMAP.md">V1 roadmap</a>
·
<a href="LIBRARIES.md">Library inventory</a>
<a href="https://github.com/future-agi/agent-learning-kit/blob/main/LIBRARIES.md">Library inventory</a>
</p>

![Agent Learning lifecycle blueprint](docs/assets/hero-agent-blueprint.jpg)
![Agent Learning lifecycle blueprint](https://raw.githubusercontent.com/future-agi/agent-learning-kit/main/docs/assets/hero-agent-blueprint.jpg)

Agent Learning Kit is the local-first SDK and CLI for testing, simulating,
red-teaming, and optimizing AI agents.
Expand Down Expand Up @@ -53,10 +53,10 @@ Point it at an agent's source and it reads what that agent verifiably is, builds
tools act on, and writes test scenarios that are each proved before they are kept. It is driven
as a conversation, in a terminal or on a web page.

- **[Start here](src/fi/alk/harness/README.md)**: setup from nothing, then how to use it
- **[The web page](harness-ui/README.md)**: the same harness as a chat, on `localhost:8777`
- **[How it works](src/fi/alk/harness/HOW-IT-WORKS.md)** and
**[why it is shaped this way](src/fi/alk/harness/DESIGN.md)**
- **[Start here](https://github.com/future-agi/agent-learning-kit/blob/main/src/fi/alk/harness/README.md)**: setup from nothing, then how to use it
- **[The web page](https://github.com/future-agi/agent-learning-kit/blob/main/harness-ui/README.md)**: the same harness as a chat, on `localhost:8777`
- **[How it works](https://github.com/future-agi/agent-learning-kit/blob/main/src/fi/alk/harness/HOW-IT-WORKS.md)** and
**[why it is shaped this way](https://github.com/future-agi/agent-learning-kit/blob/main/src/fi/alk/harness/DESIGN.md)**

OpenEnv/Gymnasium shapes are compatibility inputs, not the product center.
Agent Learning Kit is the primary runtime and release contract, and the bar is
Expand All @@ -65,22 +65,22 @@ OpenEnv/Gymnasium-shaped traces remain compatibility evidence inside that bar.

## Install

PyPI and npm publishing land at the v1 launch. Today, install from source:
Install from PyPI:

```bash
git clone https://github.com/future-agi/agent-learning-kit
cd agent-learning-kit
pip install -e .
pip install agent-learning-kit
```

(or `uv sync` for contributors)

At launch:
To develop against source (contributors):

```bash
pip install agent-learning-kit
git clone https://github.com/future-agi/agent-learning-kit
cd agent-learning-kit
uv sync # or: pip install -e .
```

(npm publishing of the TypeScript SDK lands at the v1 launch.)

Optional Python extras:

```bash
Expand All @@ -90,7 +90,7 @@ pip install "agent-learning-kit[all]"
```

TypeScript evaluation package (npm at launch; today build from
[`typescript/agent-learning-kit`](typescript/agent-learning-kit)):
[`typescript/agent-learning-kit`](https://github.com/future-agi/agent-learning-kit/blob/main/typescript/agent-learning-kit)):

```bash
pnpm add @future-agi/agent-learning-kit
Expand All @@ -111,7 +111,7 @@ Then run the golden path against the bundled example manifests. The
credential, so any placeholder value works.

> Prefer the SDK spine over the CLI?
> [Spec + Runner](docs/simulate/spec-and-runner.md) runs the same simulation as
> [Spec + Runner](https://github.com/future-agi/agent-learning-kit/blob/main/docs/simulate/spec-and-runner.md) runs the same simulation as
> one `SimulationSpec` fed to one `SimulationRunner` — the plug-and-play surface
> behind every simulation.

Expand Down Expand Up @@ -154,7 +154,7 @@ Optional platform mode: to use Future AGI platform-backed evaluation, set
`AGENT_LEARNING_API_KEY` (it takes precedence over the `FUTURE_AGI_API_KEY`
and `FI_API_KEY` aliases), or call `configure(api_key="...")` from
`fi.alk`. See
[docs/reference/configure.md](docs/reference/configure.md).
[docs/reference/configure.md](https://github.com/future-agi/agent-learning-kit/blob/main/docs/reference/configure.md).

Cut local release proof:

Expand Down Expand Up @@ -203,30 +203,30 @@ The public SDK is `agent-learning-kit`, the Python namespace is
The active `ai-evaluation` code is included here under `src/fi/evals`, with its
TypeScript SDK source under `typescript/agent-learning-kit/src`. The
`simulate-sdk` and `agent-opt` engine code is included under `src/fi/simulate`
and `src/fi/opt`. See [LIBRARIES.md](LIBRARIES.md) for the complete source map.
and `src/fi/opt`. See [LIBRARIES.md](https://github.com/future-agi/agent-learning-kit/blob/main/LIBRARIES.md) for the complete source map.
The ai-evaluation source inventory used by `agent-learn release-check` lives at
the ai-evaluation source inventory (maintained in the internal-docs repo).

## Repository Map

- [`examples/`](examples): runnable cookbooks and manifests.
- [`src/fi/alk`](src/fi/alk): public Python SDK facade and CLI.
- [`src/fi/evals`](src/fi/evals): active `ai-evaluation` engine code.
- [`src/fi/simulate`](src/fi/simulate): migrated `simulate-sdk` engine code.
- [`src/fi/opt`](src/fi/opt): migrated `agent-opt` engine code.
- [`typescript/agent-learning-kit`](typescript/agent-learning-kit): public
- [`examples/`](https://github.com/future-agi/agent-learning-kit/blob/main/examples): runnable cookbooks and manifests.
- [`src/fi/alk`](https://github.com/future-agi/agent-learning-kit/blob/main/src/fi/alk): public Python SDK facade and CLI.
- [`src/fi/evals`](https://github.com/future-agi/agent-learning-kit/blob/main/src/fi/evals): active `ai-evaluation` engine code.
- [`src/fi/simulate`](https://github.com/future-agi/agent-learning-kit/blob/main/src/fi/simulate): migrated `simulate-sdk` engine code.
- [`src/fi/opt`](https://github.com/future-agi/agent-learning-kit/blob/main/src/fi/opt): migrated `agent-opt` engine code.
- [`typescript/agent-learning-kit`](https://github.com/future-agi/agent-learning-kit/blob/main/typescript/agent-learning-kit): public
TypeScript package, including the active evaluation SDK source.
- [`docs/index.md`](docs/index.md): full documentation index.
- [`ROADMAP.md`](ROADMAP.md): public v1 roadmap and post-v1 extensions.
- [`LIBRARIES.md`](LIBRARIES.md): source map for the consolidated engines.
- [`CONTRIBUTING.md`](CONTRIBUTING.md): local development and PR workflow.
- [`SECURITY.md`](SECURITY.md): vulnerability reporting policy.
- [`LICENSE`](LICENSE): Apache-2.0 license.
- [`NOTICE`](NOTICE): Apache notice metadata.
- [`docs/index.md`](https://github.com/future-agi/agent-learning-kit/blob/main/docs/index.md): full documentation index.
- [`ROADMAP.md`](https://github.com/future-agi/agent-learning-kit/blob/main/ROADMAP.md): public v1 roadmap and post-v1 extensions.
- [`LIBRARIES.md`](https://github.com/future-agi/agent-learning-kit/blob/main/LIBRARIES.md): source map for the consolidated engines.
- [`CONTRIBUTING.md`](https://github.com/future-agi/agent-learning-kit/blob/main/CONTRIBUTING.md): local development and PR workflow.
- [`SECURITY.md`](https://github.com/future-agi/agent-learning-kit/blob/main/SECURITY.md): vulnerability reporting policy.
- [`LICENSE`](https://github.com/future-agi/agent-learning-kit/blob/main/LICENSE): Apache-2.0 license.
- [`NOTICE`](https://github.com/future-agi/agent-learning-kit/blob/main/NOTICE): Apache notice metadata.

## Development

New public SDK development belongs here. See [DEVELOPMENT.md](DEVELOPMENT.md)
New public SDK development belongs here. See [DEVELOPMENT.md](https://github.com/future-agi/agent-learning-kit/blob/main/DEVELOPMENT.md)
for the boundary between this package and the backing engine repos.

```bash
Expand Down Expand Up @@ -271,12 +271,12 @@ extensions land post-v1 without weakening any gate.

## Community

- Contributions: [CONTRIBUTING.md](CONTRIBUTING.md)
- Code of conduct: [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)
- Security reports: [SECURITY.md](SECURITY.md)
- License: [Apache-2.0](LICENSE)
- Contributions: [CONTRIBUTING.md](https://github.com/future-agi/agent-learning-kit/blob/main/CONTRIBUTING.md)
- Code of conduct: [CODE_OF_CONDUCT.md](https://github.com/future-agi/agent-learning-kit/blob/main/CODE_OF_CONDUCT.md)
- Security reports: [SECURITY.md](https://github.com/future-agi/agent-learning-kit/blob/main/SECURITY.md)
- License: [Apache-2.0](https://github.com/future-agi/agent-learning-kit/blob/main/LICENSE)

## Deep Dive

The full documentation set — quickstarts, per-track guides, framework pages,
and reference material — starts at [docs/index.md](docs/index.md).
and reference material — starts at [docs/index.md](https://github.com/future-agi/agent-learning-kit/blob/main/docs/index.md).
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[build-system]
requires = ["hatchling"]
# Bounded: the build backend is the one artifact input uv.lock does not cover.
requires = ["hatchling>=1.27,<2"]
build-backend = "hatchling.build"

[project]
Expand Down
Loading