feat: remove stale claims, add streaming/tools/retries, compatibility table#26
Conversation
…ompatibility table - Remove '57 models' references from README (2 places) - Fix pyproject.toml: name sdk→ainfera, version 0.1.0→1.1.0, packages src→python, testpaths tests→python/tests, add missing dev deps (httpx, pydantic, joserfc, respx, pytest-asyncio, pyright, click, pyyaml), fix broken prose line 3 - Add examples: streaming, tools, retries, async_usage, receipt_verification, error_handling - Add compatibility table (ainfera vs openai vs anthropic SDK) - Add semantic-release config (releaserc.toml) - Fix concept page links (/concepts/ → /docs#) - Fix 04_inference.py: model→ainfera-inference, remove broken receipt.audit_url - Fix quickstart.py: model→ainfera-inference - ruff format applied to pre-existing files Co-authored-by: Aulë <aule@ainfera.ai>
📝 WalkthroughWalkthroughThe SDK package identity and release configuration are updated, README documentation adds compatibility and versioning details, new usage examples are introduced, existing examples are adjusted, and formatting-only changes are applied across implementation and test files. ChangesSDK release and examples
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.
Reviewed by Cursor Bugbot for commit 1090b1a. Configure here.
| retry_delay=1.0, | ||
| retry_backoff=2.0, | ||
| retry_on_status=[429, 500, 502, 503], | ||
| ) |
There was a problem hiding this comment.
Retries example invalid client kwargs
Medium Severity
examples/retries.py constructs AinferaClient with max_retries, retry_delay, retry_backoff, and retry_on_status, but AinferaClient.__init__ only accepts api_key, base_url, and timeout, so the example fails immediately with unexpected keyword arguments.
Reviewed by Cursor Bugbot for commit 1090b1a. Configure here.
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (4)
releaserc.toml (1)
6-9: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider whether
docscommits should trigger patch releases.
docsis listed inpatch_tags, meaning documentation-only changes (e.g., README updates) will produce a new patch version. This may be intentional, but if you'd prefer docs changes to not trigger releases, remove"docs"frompatch_tagsandallowed_tags.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@releaserc.toml` around lines 6 - 9, Review the semantic-release tag configuration in [semantic_release.commit_parser] and decide whether documentation-only commits should create patch releases; if not, remove "docs" from both patch_tags and allowed_tags, ensuring the remaining tag configuration reflects the intended release policy.examples/async_usage.py (1)
16-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse
response.contentinstead of deprecatedresponse.textin new examples.
response.textis a deprecated 1.0.x alias (perinference.py:45-51and README line 59). New example files should showcase the current recommended API (response.content) rather than the deprecated alias that will be removed in 2.0.♻️ Proposed fix
print(response.text) + print(response.content)And on line 28:
for r in results: - print(r.text) + print(r.content)Also applies to: 28-28
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@examples/async_usage.py` at line 16, Replace all uses of the deprecated response.text alias in the async example, including both referenced lines, with response.content so the example demonstrates the current API.python/examples/04_inference.py (1)
11-11: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse
response.contentinstead of deprecatedresponse.text.
response.textis a deprecated 1.0.x alias (perinference.py:45-51). Since this line was modified in this PR, consider updating toresponse.contentto align with the current API.♻️ Proposed fix
-print(response.text) +print(response.content)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/examples/04_inference.py` at line 11, Replace the deprecated response.text access in the example with response.content, preserving the existing output behavior.examples/error_handling.py (1)
26-26: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse
response.contentinstead of deprecatedresponse.textin new examples.
response.textis a deprecated 1.0.x alias (perinference.py:45-51). New example files should useresponse.contentto showcase the current API.♻️ Proposed fix
- print(response.text) + print(response.content)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@examples/error_handling.py` at line 26, Replace the deprecated response.text access with response.content in the example’s response-printing logic, using the response variable at the affected statement.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@examples/receipt_verification.py`:
- Line 6: Update the AinferaClient initialization in the receipt verification
example to use the AINFERA_API_KEY environment variable via os.environ, or omit
the api_key argument if the client automatically reads it; add the required os
import if needed.
In `@pyproject.toml`:
- Around line 25-42: Move the runtime packages httpx, pydantic, joserfc, click,
and pyyaml from [project.optional-dependencies].dev into [project.dependencies]
so plain installations include SDK imports. Update the test extra to include
pytest-asyncio and respx alongside pytest and pytest-cov, while keeping only
development tooling and test-related packages in the dev group.
In `@python/examples/04_inference.py`:
- Line 12: Remove the invalid response.audit_url access from the example because
InferenceResponse does not define that field. Use the audit_url from the
returned Receipt instead, if the example needs to display it, by locating the
Receipt object produced by the inference flow.
In `@releaserc.toml`:
- Around line 1-4: Add python/ainfera/_version.py:__version__ to the
semantic_release version_variable configuration alongside
pyproject.toml:version, ensuring both package metadata and the runtime
ainfera.__version__ are updated during releases.
---
Nitpick comments:
In `@examples/async_usage.py`:
- Line 16: Replace all uses of the deprecated response.text alias in the async
example, including both referenced lines, with response.content so the example
demonstrates the current API.
In `@examples/error_handling.py`:
- Line 26: Replace the deprecated response.text access with response.content in
the example’s response-printing logic, using the response variable at the
affected statement.
In `@python/examples/04_inference.py`:
- Line 11: Replace the deprecated response.text access in the example with
response.content, preserving the existing output behavior.
In `@releaserc.toml`:
- Around line 6-9: Review the semantic-release tag configuration in
[semantic_release.commit_parser] and decide whether documentation-only commits
should create patch releases; if not, remove "docs" from both patch_tags and
allowed_tags, ensuring the remaining tag configuration reflects the intended
release policy.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 401d8cf7-c5e0-43bc-8e9e-0e4a8646e6a7
📒 Files selected for processing (24)
README.mdexamples/async_usage.pyexamples/error_handling.pyexamples/quickstart.pyexamples/receipt_verification.pyexamples/retries.pyexamples/streaming.pyexamples/tools.pypyproject.tomlpython/ainfera/_internal/http.pypython/ainfera/_internal/jws.pypython/ainfera/agents.pypython/ainfera/audit.pypython/ainfera/cli.pypython/ainfera/client.pypython/ainfera/wallet.pypython/examples/04_inference.pypython/tests/test_async_resources.pypython/tests/test_cli_install.pypython/tests/test_http.pypython/tests/test_resources.pypython/tests/test_verify.pyreleaserc.tomltests/test_smoke.py
| from ainfera import AinferaClient | ||
| from ainfera.verify import verify_receipt | ||
|
|
||
| client = AinferaClient(api_key="ak_...") |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify whether AinferaClient auto-reads AINFERA_API_KEY from env,
# and whether verify_receipt exists in ainfera.verify.
# Check AinferaClient constructor signature
ast-grep outline python/ainfera/client.py --match 'AinferaClient' --view expanded
# Check for env var reading in client constructor
rg -n -C3 'AINFERA_API_KEY|os.environ|getenv' python/ainfera/client.py
# Check verify_receipt exists in ainfera.verify
rg -n 'def verify_receipt' python/ainfera/verify.pyRepository: ainfera-ai/sdk-python
Length of output: 2207
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the receipt verification example and related example files that may use the same pattern.
git ls-files 'examples/*.py'
printf '\n--- examples/receipt_verification.py ---\n'
cat -n examples/receipt_verification.py
printf '\n--- api_key literals in examples ---\n'
rg -n 'api_key\s*=\s*"' examples/*.py
printf '\n--- AINFERA_API_KEY usage in examples ---\n'
rg -n 'AINFERA_API_KEY|os\.environ|getenv' examples/*.pyRepository: ainfera-ai/sdk-python
Length of output: 2120
Use AINFERA_API_KEY in this example
api_key="ak_..." teaches the wrong credential pattern in sample code. Use os.environ["AINFERA_API_KEY"] (or omit api_key if the client already reads from env) so the example matches the SDK guidance.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@examples/receipt_verification.py` at line 6, Update the AinferaClient
initialization in the receipt verification example to use the AINFERA_API_KEY
environment variable via os.environ, or omit the api_key argument if the client
automatically reads it; add the required os import if needed.
Source: Coding guidelines
| [project.optional-dependencies] | ||
| dev = [ | ||
| "httpx>=0.27", | ||
| "pydantic>=2.0", | ||
| "joserfc>=0.9", | ||
| "pytest>=7.0", | ||
| "pytest-cov>=4.0", | ||
| "ruff>=0.4.0", | ||
| "pytest-asyncio>=0.23", | ||
| "pyright>=1.1", | ||
| "click>=8.0", | ||
| "pyyaml>=6.0", | ||
| "respx>=0.21", | ||
| ] | ||
| test = [ | ||
| "pytest>=7.0", | ||
| "pytest-cov>=4.0", | ||
| ] |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Runtime dependencies belong in [project.dependencies], not dev extras.
httpx, pydantic, joserfc, click, and pyyaml are imported by core SDK modules (http.py, jws.py, cli.py, etc.) but are only available via pip install ainfera[dev]. A plain pip install ainfera or pip install -e . will fail at import time. These should be declared under [project.dependencies].
Additionally, the test extras group is incomplete — it includes only pytest and pytest-cov but omits pytest-asyncio and respx, both of which are required by the test suite (e.g., test_async_resources.py, test_http.py). Anyone running pip install ainfera[test] followed by pytest will hit ImportError.
📦 Proposed fix for dependency grouping
[project]
name = "ainfera"
version = "1.1.0"
description = "Agent-native inference routing by Ainfera. Python SDK — signed AgentCards, routed inference, audit chains."
readme = "README.md"
requires-python = ">=3.10"
license = {text = "Apache-2.0"}
authors = [{name = "Ainfera Inc"}]
classifiers = [
"Development Status :: 4 - Beta",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
]
+dependencies = [
+ "httpx>=0.27",
+ "pydantic>=2.0",
+ "joserfc>=0.9",
+ "click>=8.0",
+ "pyyaml>=6.0",
+]
[project.optional-dependencies]
dev = [
- "httpx>=0.27",
- "pydantic>=2.0",
- "joserfc>=0.9",
"pytest>=7.0",
"pytest-cov>=4.0",
"ruff>=0.4.0",
"pytest-asyncio>=0.23",
"pyright>=1.1",
- "click>=8.0",
- "pyyaml>=6.0",
"respx>=0.21",
]
test = [
"pytest>=7.0",
"pytest-cov>=4.0",
+ "pytest-asyncio>=0.23",
+ "respx>=0.21",
]🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@pyproject.toml` around lines 25 - 42, Move the runtime packages httpx,
pydantic, joserfc, click, and pyyaml from [project.optional-dependencies].dev
into [project.dependencies] so plain installations include SDK imports. Update
the test extra to include pytest-asyncio and respx alongside pytest and
pytest-cov, while keeping only development tooling and test-related packages in
the dev group.
| ) | ||
| print(response.text) | ||
| print(response.receipt.audit_url) | ||
| print(response.audit_url) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Verify InferenceResponse has an `audit_url` attribute.
# Find the InferenceResponse model definition
rg -n "class InferenceResponse" --type py python/
# Then inspect the model fields for audit_url
rg -n "audit_url" --type py python/ainfera/Repository: ainfera-ai/sdk-python
Length of output: 274
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the InferenceResponse model and nearby definitions.
sed -n '1,220p' python/ainfera/inference.py
printf '\n--- receipt.py ---\n'
sed -n '1,220p' python/ainfera/receipt.py
printf '\n--- search for audit_url access on InferenceResponse ---\n'
rg -n "response\.audit_url|receipt\.audit_url|audit_url" python/examples python/ainfera -g '*.py'Repository: ainfera-ai/sdk-python
Length of output: 2496
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the example around the flagged line to preserve the correct guidance.
sed -n '1,80p' python/examples/04_inference.pyRepository: ainfera-ai/sdk-python
Length of output: 491
response.audit_url is not available here InferenceResponse doesn’t define audit_url; the only audit_url field in the SDK is on Receipt, so this example will raise AttributeError.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@python/examples/04_inference.py` at line 12, Remove the invalid
response.audit_url access from the example because InferenceResponse does not
define that field. Use the audit_url from the returned Receipt instead, if the
example needs to display it, by locating the Receipt object produced by the
inference flow.
| [semantic_release] | ||
| version_variable = ["pyproject.toml:version"] | ||
| branch = "main" | ||
| upload_to_pypi = false |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
set -euo pipefail
printf 'FILES:\n'
git ls-files releaserc.toml pyproject.toml python/ainfera/_version.py python/ainfera/__init__.py || true
printf '\nRELEASE CONFIG:\n'
cat -n releaserc.toml
printf '\nVERSION FILES / IMPORTS:\n'
for f in python/ainfera/_version.py python/ainfera/__init__.py pyproject.toml; do
if [ -f "$f" ]; then
printf '\n== %s ==\n' "$f"
cat -n "$f"
fi
done
printf '\nSEARCHES:\n'
rg -n "__version__|version_variable|semantic_release" . --glob '!**/.git/**'Repository: ainfera-ai/sdk-python
Length of output: 5303
version_variable also needs python/ainfera/_version.py:__version__. ainfera.__version__ is imported from that file, so leaving it out will make the runtime version drift from pyproject.toml after a release.
🔧 Proposed fix
[semantic_release]
-version_variable = ["pyproject.toml:version"]
+version_variable = ["pyproject.toml:version", "python/ainfera/_version.py:__version__"]
branch = "main"
upload_to_pypi = false📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| [semantic_release] | |
| version_variable = ["pyproject.toml:version"] | |
| branch = "main" | |
| upload_to_pypi = false | |
| [semantic_release] | |
| version_variable = ["pyproject.toml:version", "python/ainfera/_version.py:__version__"] | |
| branch = "main" | |
| upload_to_pypi = false |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@releaserc.toml` around lines 1 - 4, Add
python/ainfera/_version.py:__version__ to the semantic_release version_variable
configuration alongside pyproject.toml:version, ensuring both package metadata
and the runtime ainfera.__version__ are updated during releases.


What shipped
Stale claims removed
Examples added
examples/streaming.py— streaming inferenceexamples/tools.py— tool useexamples/retries.py— retry strategiesexamples/async_usage.py— async usageexamples/receipt_verification.py— local receipt verificationexamples/error_handling.py— production error handlingpyproject.toml fixed
Other
Test results
Co-authored-by: Aulë aule@ainfera.ai
Note
Medium Risk
Packaging rename (
sdk→ainfera, package pathsrc→python) can break installs, CI, and imports if downstream still expect the old layout; version jump to 1.1.0 is a release-facing change.Overview
Repositions the repo as the
ainferaPyPI package at 1.1.0:pyproject.tomlrenames the project fromsdk, points setuptools atpython/ainfera*, moves tests topython/tests, bumps status to Beta, and expands dev optional deps (httpx, pydantic, joserfc, respx, etc.). Addsreleaserc.tomlfor semantic-release offpyproject.toml:version.README gains a compatibility table (ainfera vs OpenAI/Anthropic SDKs), API v1 versioning note, generic “all routed models” wording (drops hard-coded “57 models”), and concept links updated to
ainfera.ai/docs#….New
examples/scripts document async usage, streaming, tools, retries, receipt verification, and typed error handling; existing quickstart andpython/examples/04_inference.pydefault toainfera-inferenceand fix audit URL access (response.audit_url).Library code changes are mostly ruff format (line wraps); no functional API changes in the diff hunks.
Reviewed by Cursor Bugbot for commit 1090b1a. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit