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
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -357,14 +357,14 @@ jobs:
# component, sibling of fp-cloud-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-cloud-cli's two versions on purpose. This package declares
# The matrix spans the whole supported range 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
# the same, across five — every version requires-python advertises; the bound exists so a stalled
# the same, across four — every version requires-python advertises; the bound exists so a stalled
# package mirror cannot hold a release for six hours (#726).
timeout-minutes: 10
defaults:
Expand All @@ -373,7 +373,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
python-version: ["3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/[email protected]

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

### Dependencies

- `failproofai-sdk` drops Python 3.10, which reached end of life this month, clearing the 47 Dependabot alerts against its dev/test lockfile. `pillow` (41) and `filelock` (6) are fixed only in releases that require Python 3.11 (13.0.0 and 4.2.1), so the lockfile's 3.10 slice was held on 12.3.0 and 4.1.0 behind two version-pinned OSV exceptions due to expire on 2026-11-20. `requires-python` is now `>=3.11`, the SDK's CI matrix runs 3.11–3.14, both exceptions are gone, and the 3.10-only `tomli` and `onnxruntime` entries leave the `dev` and `crewai` extras. On 3.10, pip keeps resolving `0.0.1b6`; `fp-cloud-cli` still supports 3.10 (#953)
- Put the `ai-4`, `langchain-0.3`, `llamaindex-0.11` and `mastra-0` SDK integration fixtures back on the releases they exist to test, and stop Dependabot moving them. Its grouped security update #935, opened three minutes after #934 restored the first three, moved them again: `[email protected]` → `5.0.52`, `@langchain/[email protected]` → `1.3.0`, `[email protected]` → `0.12.1` (each with `[email protected]` → `4.6.7`), and `@mastra/[email protected]` → `1.79.0`. `__tests__/ci/ts-sdk-fixture-pins.test.ts` and the `frameworks` and `runtimes` integration shards have failed on `main` since, and so on every open PR. All four are back on their #934 manifests and lockfiles, and `.github/dependabot.yml` gives each a security-updates-only entry whose `ignore` ranges hold its framework on its line, and zod on 3 where the framework requires it, so the move is no longer proposed; the pin test now fails if a floor fixture loses that entry (#950)
- Restore the `ai-4`, `langchain-0.3` and `llamaindex-0.11` SDK integration fixtures to the releases they exist to test: `[email protected]`, `@langchain/[email protected]` with `@langchain/[email protected]`, and `[email protected]`, each with `[email protected]`. Dependabot's grouped security update (#931) reached the zod fix by moving them to `[email protected]`, `@langchain/[email protected]` and `[email protected]`, the pin move `SECURITY.md` rules out, so the matrix silently stopped testing three supported floors. `llamaindex-0.11` then stopped installing (`@llamaindex/[email protected]` peers on `zod@^3.23.8`, so `npm ci` failed `ERESOLVE`), and because global setup installs every fixture first, the `frameworks` and `runtimes` integration shards failed on `main`. #931 also moved the `runtimes` fixture to `[email protected]` while its Deno program still imported `npm:[email protected]`, which Deno could no longer find; it now imports the installed version. `__tests__/ci/ts-sdk-fixture-pins.test.ts` fails on either move before anything installs (#934)
- Patch the fixable SDK integration fixture advisories with fixture-local `overrides`, moving no pin: `undici` 7.29.1 → 7.30.1 in `ai-5` (GHSA-xjj6-f33q-929c, GHSA-4qv8-2p9j-2685, GHSA-f72v-6w45-q472); `fast-uri` 3.1.8 → 3.1.9 in `llamaindex-0.11` (GHSA-w74x-v6f9-j3xg, GHSA-wjr9-j795-jxcr, GHSA-xhq7-xmqj-769h, GHSA-333x-w4r6-6crp); and in `mastra-1`, `@modelcontextprotocol/server` 2.0.0 → 2.3.0 and `@modelcontextprotocol/client` 2.2.0 → 2.3.0 (GHSA-jm63-cq47-j5jp, GHSA-46jr-4wx8-v453, GHSA-rvq5-wwqv-78pq, GHSA-6prh-2h8m-c8cw), both pinned exactly by `@mastra/[email protected]`, each now with its own `@modelcontextprotocol/[email protected]` nested under it (#934)
Expand Down
4 changes: 2 additions & 2 deletions __tests__/ci/failproofai-sdk-workflows.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,9 @@ describe("the failproofai-sdk CI job", () => {
});

it("tests every Python version pyproject advertises", () => {
// Claiming >=3.10 and testing one of them is how a 3.10 user finds the break.
// Claiming >=3.11 and testing one of them is how a 3.11 user finds the break.
// Kept in step with `requires-python` and the classifiers by hand.
expect(job.strategy.matrix["python-version"]).toEqual(["3.10", "3.11", "3.12", "3.13", "3.14"]);
expect(job.strategy.matrix["python-version"]).toEqual(["3.11", "3.12", "3.13", "3.14"]);
});

it("requires the spool contract rather than letting it skip", () => {
Expand Down
2 changes: 1 addition & 1 deletion docs/ar/reference/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ icon: "python"
</Card>
</Columns>

Python 3.10 أو أحدث. بدون متطلبات وقت التشغيل.
Python 3.11 أو أحدث. بدون متطلبات وقت التشغيل.

## التثبيت

Expand Down
2 changes: 1 addition & 1 deletion docs/de/reference/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Was jede Einstellung, Methode und jedes Feld bewirkt. Wenn Sie zum ersten Mal in
</Card>
</Columns>

Python 3.10 oder neuer. Keine Laufzeitabhängigkeiten.
Python 3.11 oder neuer. Keine Laufzeitabhängigkeiten.

## Installation

Expand Down
2 changes: 1 addition & 1 deletion docs/es/reference/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Qué hace cada configuración, método y campo. Si es la primera vez que instrum
</Card>
</Columns>

Python 3.10 o superior. Sin dependencias en tiempo de ejecución.
Python 3.11 o superior. Sin dependencias en tiempo de ejecución.

## Instalar

Expand Down
2 changes: 1 addition & 1 deletion docs/fr/reference/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Ce que font chaque paramètre, méthode et champ. Si vous instrumentez pour la p
</Card>
</Columns>

Python 3.10 ou supérieur. Aucune dépendance d'exécution.
Python 3.11 ou supérieur. Aucune dépendance d'exécution.

## Installation

Expand Down
2 changes: 1 addition & 1 deletion docs/he/reference/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ icon: "python"
</Card>
</Columns>

Python 3.10 או חדש יותר. ללא תלויות זמן ריצה.
Python 3.11 או חדש יותר. ללא תלויות זמן ריצה.

## התקנה

Expand Down
2 changes: 1 addition & 1 deletion docs/hi/reference/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ icon: "python"
</Card>
</Columns>

Python 3.10 या नया। कोई runtime dependency नहीं।
Python 3.11 या नया। कोई runtime dependency नहीं।

## इंस्टॉल करें

Expand Down
2 changes: 1 addition & 1 deletion docs/it/reference/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Cosa fanno ogni impostazione, metodo e campo. Se stai strumentando per la prima
</Card>
</Columns>

Python 3.10 o più recente. Nessuna dipendenza di runtime.
Python 3.11 o più recente. Nessuna dipendenza di runtime.

## Installazione

Expand Down
2 changes: 1 addition & 1 deletion docs/ja/reference/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ icon: "python"
</Card>
</Columns>

Python 3.10 以降が必要です。実行時の依存関係はありません。
Python 3.11 以降が必要です。実行時の依存関係はありません。

## インストール

Expand Down
2 changes: 1 addition & 1 deletion docs/ko/reference/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ icon: "python"
</Card>
</Columns>

Python 3.10 이상. 런타임 의존성 없음.
Python 3.11 이상. 런타임 의존성 없음.

## 설치

Expand Down
2 changes: 1 addition & 1 deletion docs/pt-br/reference/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ O que cada configuração, método e campo faz. Se você está instrumentando pe
</Card>
</Columns>

Python 3.10 ou superior. Sem dependências em tempo de execução.
Python 3.11 ou superior. Sem dependências em tempo de execução.

## Instalação

Expand Down
2 changes: 1 addition & 1 deletion docs/reference/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ What every setting, method and field does. If you are instrumenting for the firs
</Card>
</Columns>

Python 3.10 or newer. No runtime dependencies. Using a framework? [LangChain, CrewAI, LlamaIndex and Pydantic AI](/start/integrations) instrument themselves with one call.
Python 3.11 or newer. No runtime dependencies. Using a framework? [LangChain, CrewAI, LlamaIndex and Pydantic AI](/start/integrations) instrument themselves with one call.

<Note>
There is a **TypeScript SDK** too, and the two write the same events into the same spool. A fleet with Node agents and Python agents produces one set of sessions, not two. Pick per service, not per company.
Expand Down
2 changes: 1 addition & 1 deletion docs/ru/reference/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ icon: "python"
</Card>
</Columns>

Python 3.10 или новее. Без зависимостей времени выполнения.
Python 3.11 или новее. Без зависимостей времени выполнения.

## Установка

Expand Down
2 changes: 1 addition & 1 deletion docs/tr/reference/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Her ayarın, metodun ve alanın ne işe yaradığı. İlk kez enstrümantasyon y
</Card>
</Columns>

Python 3.10 veya daha yeni. Runtime bağımlılığı yok.
Python 3.11 veya daha yeni. Runtime bağımlılığı yok.

## Kurulum

Expand Down
2 changes: 1 addition & 1 deletion docs/vi/reference/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Mỗi cài đặt, phương thức và trường làm gì. Nếu bạn lần đ
</Card>
</Columns>

Python 3.10 hoặc mới hơn. Không có phụ thuộc thời gian chạy.
Python 3.11 hoặc mới hơn. Không có phụ thuộc thời gian chạy.

## Cài đặt

Expand Down
2 changes: 1 addition & 1 deletion docs/zh/reference/custom-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ icon: "python"
</Card>
</Columns>

需要 Python 3.10 或更高版本,无运行时依赖。
需要 Python 3.11 或更高版本,无运行时依赖。

## 安装

Expand Down
52 changes: 3 additions & 49 deletions osv-scanner.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
# Two mechanisms, and the reason to reach for each:
#
# [[IgnoredVulns]] silences ONE advisory by id, and is what every entry below
# but the last uses. It is the narrowest thing that works: any OTHER advisory
# uses. It is the narrowest thing that works: any OTHER advisory
# against the same package still blocks, including a newly FIXABLE one — which
# is the signal worth keeping, because a fixable finding is one we would act on.
#
# [[PackageOverrides]] silences every advisory against a package, and is used
# once, for the pillow entry at the bottom. It also suppresses fixable findings,
# [[PackageOverrides]] silences every advisory against a package, and no entry
# below uses it at present. It also suppresses fixable findings,
# so it costs exactly the signal above; see SECURITY.md for the narrow case that
# justifies it and the conditions attached. Note the different date key there —
# `effectiveUntil`, not `ignoreUntil`.
Expand Down Expand Up @@ -108,49 +108,3 @@ reason = "chromadb 1.5.9 (published 2026-06-12, surfaced 2026-08-24). No fixed v
id = "GHSA-8mgp-746c-j5xp"
ignoreUntil = 2026-11-20
reason = "nltk 3.10.3 (surfaced 2026-09-03, CVSS 8.3). No fixed version. Transitive via llama-index-core, dev/test lockfile only; the SDK ships zero runtime dependencies. Re-review by 2026-11-20."

# ---------------------------------------------------------------------------
# pillow 12.3.0 — the Python 3.10 slice of sdk/python/uv.lock. A package
# override rather than an id list, because this is the case SECURITY.md keeps
# one for.
#
# Every fix for these advisories is in pillow 13.0.0, which requires Python
# >= 3.11. The SDK still supports 3.10, so the lock forks: 13.0.0 for 3.11 and
# up, and 12.3.0, the last release that installs on 3.10, for 3.10 alone. No
# release fixes that slice and none will: Pillow has dropped 3.10, which reaches
# end of life in October 2026 (PEP 619). The advisories are still arriving —
# 9 on the 2026-10-20 scan, 28 by 2026-10-22 — so an id list would turn this
# gate red on an unrelated PR with every new one.
#
# pillow is transitive via crewai (through pdfplumber) and llama-index-core, in
# the dev/test lockfile only; the SDK declares no runtime dependencies. The
# override is pinned to 12.3.0, so 13.0.0 — what every other supported Python
# resolves — stays fully gated, and any change to the 3.10 slice re-opens it.
# Dropping 3.10 from `requires-python` retires it. Same re-review date as the
# entries above.
# ---------------------------------------------------------------------------

[[PackageOverrides]]
name = "pillow"
version = "12.3.0"
ecosystem = "PyPI"
vulnerability.ignore = true
effectiveUntil = 2026-11-20
reason = "pillow 12.3.0 is only the Python 3.10 slice of sdk/python/uv.lock: every fix is in 13.0.0, which requires Python >= 3.11 and is what 3.11+ resolves. Transitive via crewai and llama-index-core, dev/test lockfile only. Re-review by 2026-11-20."

# ---------------------------------------------------------------------------
# filelock 4.1.0 is another Python 3.10-only dev/test lockfile slice. Its
# fixed 4.2.1 release requires Python >= 3.11, while uv resolves 4.2.4 for
# Python 3.11+. Six advisories affect 4.1.0 and none has a 3.10-compatible
# fix. It is transitive via huggingface-hub; the SDK has no runtime deps.
# Pin this override to 4.1.0 so newer versions and a changed 3.10 slice
# remain scanned. Remove it when Python 3.10 support ends.
# ---------------------------------------------------------------------------

[[PackageOverrides]]
name = "filelock"
version = "4.1.0"
ecosystem = "PyPI"
vulnerability.ignore = true
effectiveUntil = 2026-11-20
reason = "filelock 4.1.0 is only the Python 3.10 slice of the SDK dev/test lockfile. All six current fixes require 4.2.1 and Python >= 3.11; newer Python uses 4.2.4. The SDK has no runtime dependencies. Re-review by 2026-11-20."
12 changes: 8 additions & 4 deletions sdk/python/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ see `scripts/changelog-section.py`.

## 0.0.1b7 — 2026-10-16

Open for the next release. `0.0.1b6` published on 2026-10-16 and the `bump` job
moved the version here automatically; nothing has landed against `0.0.1b7` yet.
Add entries as changes merge — this section becomes the GitHub Release body when
it ships.
### Requires Python 3.11 or newer

- **Python 3.10 is no longer supported.** It reached end of life in October 2026,
and the libraries the framework extras pull in have started leaving it: the
fixes for 47 advisories against Pillow and filelock ship only in releases that
require Python 3.11. `requires-python` is now `>=3.11`. On 3.10, pip keeps
installing `0.0.1b6`, the last release that supports it. The SDK still has no
runtime dependencies, and nothing else about it changes.

## 0.0.1b6 — 2026-10-15

Expand Down
4 changes: 2 additions & 2 deletions sdk/python/failproofai_sdk/evaluator/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ def _raw_eval(source: str, kind: str) -> Callable[[Any], Any]:

def run(session: Any) -> Any:
# `session` goes in the (fresh, per-call) GLOBALS, not locals: on
# CPython 3.10 a list/set/dict comprehension resolves a free name like
# CPython 3.11 a list/set/dict comprehension resolves a free name like
# `session` from globals, so an allowed source such as
# `all([session.event_count > 0 for _ in range(1)])` raises NameError
# if `session` is only a local. Globals stay fresh per call for
Expand All @@ -618,7 +618,7 @@ def run(session: Any) -> Any:

def run(session: Any) -> Any:
# `session` goes in the (fresh, per-call) GLOBALS, not locals: on
# CPython 3.10 a list/set/dict comprehension resolves a free name like
# CPython 3.11 a list/set/dict comprehension resolves a free name like
# `session` from globals, so an allowed source such as
# `all([session.event_count > 0 for _ in range(1)])` raises NameError
# if `session` is only a local. Globals stay fresh per call for
Expand Down
9 changes: 2 additions & 7 deletions sdk/python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "failproofai-sdk"
dynamic = ["version"]
requires-python = ">=3.10"
requires-python = ">=3.11"
description = "Emit agent telemetry to FailproofAI Cloud — zero-dependency, stdlib only"
readme = "README.md"
license = { file = "LICENSE" }
Expand All @@ -15,7 +15,6 @@ classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
Expand Down Expand Up @@ -47,10 +46,7 @@ Changelog = "https://github.com/FailproofAI/failproofai/blob/main/sdk/python/CHA
[project.optional-dependencies]
# Test-only, and it stays that way — `dependencies` above is empty and
# `tests/test_zero_dependencies.py` fails if anything lands here without a reason.
# `tomli` is `tomllib`'s backport: 3.10 has no stdlib TOML parser, and that test
# reads this file to prove the promise, so on 3.10 it needs one rather than
# skipping the check on the oldest interpreter we advertise.
dev = ["pytest>=7", "tomli>=2; python_version<'3.11'", "pytest-asyncio>=1.3,<2", "opentelemetry-sdk>=1.39,<2"]
dev = ["pytest>=7", "pytest-asyncio>=1.3,<2", "opentelemetry-sdk>=1.39,<2"]

# Convenience aliases that pull the FRAMEWORK in. The adapter code always ships
# in the base wheel and lazy-imports, so these gate nothing on our side — most
Expand All @@ -68,7 +64,6 @@ langchain = ["langchain-core>=1.4.7,<2"] # langgraph 1.2's own floor
langgraph = ["langgraph>=1.2,<2"] # first release with GraphCallbackHandler
crewai = [
"crewai>=1.13,<2", # started_event_id + normalized usage
"onnxruntime>=1.14,<1.24; python_version < '3.11'", # 1.24+ dropped CPython 3.10 wheels
]
llamaindex = ["llama-index-core>=0.14.23,<0.15"]
pydantic-ai = ["pydantic-ai-slim>=2.0,<3"] # 2.0 removed Agent(instrument=...)
Expand Down
15 changes: 0 additions & 15 deletions sdk/python/skill/references/frameworks.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,21 +117,6 @@ you never touch.
| `Command(resume=...)` | `agent_resume` + `human_input` |
| intermediate chains | **nothing**, unless you name them in `include_chains` |

**Python 3.10 async nodes must forward `RunnableConfig`.** LangGraph cannot
automatically propagate callback context from an async node into a child
`ainvoke()` on Python 3.10. Without this, the child model or tool appears as a
separate root run:

```python
from langchain_core.runnables import RunnableConfig

async def plan(state, config: RunnableConfig):
reply = await model.ainvoke(state["messages"], config=config)
return {"messages": [reply]}
```

Python 3.11 and later propagate this context automatically.

`session_id` resolution, in order — the first that produces a value wins:

1. `instrument("langchain", session_id=...)`;
Expand Down
5 changes: 1 addition & 4 deletions sdk/python/tests/test_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,7 @@ def test_a_guide_only_names_event_methods_that_exist(guide):
@pytest.mark.parametrize("guide", _guides() + [DOCS / "README.md"], ids=lambda p: str(p.parent.name or "index"))
def test_a_guide_only_names_extras_that_exist(guide):
"""A wrong extra in an install line is a five-minute dead end."""
try: # Python 3.11+
import tomllib
except ModuleNotFoundError:
import tomli as tomllib
import tomllib

manifest = tomllib.loads((DOCS.parent / "pyproject.toml").read_text(encoding="utf-8"))
extras = set(manifest["project"]["optional-dependencies"])
Expand Down
2 changes: 1 addition & 1 deletion sdk/python/tests/test_evaluator_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ def _no_spawn(*args, **kwargs):
def test_comprehension_body_can_read_session():
# A list/set/dict comprehension resolves a free name like `session` from
# GLOBALS. When `session` was only in eval locals, such a source raised
# NameError on CPython 3.10 (a supported version). Both sandbox paths must
# NameError on CPython 3.11 (a supported version). Both sandbox paths must
# now evaluate a session-dependent comprehension (COR-001).
assert (
compile_condition("len([session.event_count for i in range(1)]) > 0")(Session())
Expand Down
11 changes: 4 additions & 7 deletions sdk/python/tests/test_packaging.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
"""Packaging contracts, read from `importlib.metadata` — never from pyproject.

Two reasons this file never opens `pyproject.toml`:

1. `tomllib` is 3.11+ and this SDK's floor is 3.10, so parsing it here would
make the packaging tests skip exactly on the leg that catches 3.10 problems.
2. `pyproject.toml` is the *input*. What ships is the wheel's `METADATA`, and
the failure mode these tests exist to catch — an extra that silently drags
the wrong `failproofai_sdk` off PyPI — happens at install time, from METADATA.
This file never opens `pyproject.toml`, because it is the *input*. What ships is
the wheel's `METADATA`, and the failure mode these tests exist to catch — an extra
that silently drags the wrong `failproofai_sdk` off PyPI — happens at install time,
from METADATA.

The rules being enforced:

Expand Down
Loading
Loading