Skip to content

Conversation

@amos-qualifire
Copy link
Contributor

@amos-qualifire amos-qualifire commented Jan 15, 2026

Description

Related Issue

https://linear.app/qualifire/issue/FIRE-1028/sdk-integration-add-compile-prompt-function-to-receive-the-request

Type of Change

  • 📚 Examples / docs / tutorials / dependencies update
  • 🔧 Bug fix (non-breaking change which fixes an issue)
  • 🥂 Improvement (non-breaking change which improves an existing feature)
  • 🚀 New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to change)
  • 🔐 Security fix

Checklist

  • I've read the CODE_OF_CONDUCT.md document.
  • I've read the CONTRIBUTING.md guide.
  • I've updated the code style using make codestyle.
  • I've written tests for all new methods and classes that I created.
  • I've written the docstring in Google format for all the methods and classes that I used.

Summary by CodeRabbit

  • New Features

    • Added compile_prompt() to the client for compiling prompts with optional params and revision support.
  • Chores

    • Migrated tooling and packaging (build system, dependency management, CI, container build and Make targets) to a new toolchain and packaging backend.
    • Updated configuration for linters/formatters and CI steps; adjusted ignore rules.
  • Other

    • Public data models modernized (may change defaults/serialization).
    • Minor test and documentation updates.

✏️ Tip: You can customize this high-level summary in your review settings.

…l as replace the package manager poetry with uv
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 15, 2026

Walkthrough

Migrates the project from Poetry to UV/Hatchling, updates CI and Docker to use UV, converts many dataclasses to Pydantic models, adds Client.compile_prompt, updates serialization to Pydantic model_dump_json, and adjusts tooling/ignore/config files.

Changes

Cohort / File(s) Summary
Build system & packaging
pyproject.toml, setup.py, requirements.txt
Replaced Poetry build metadata with Hatchling/project config; removed setup.py; pruned requirements.txt entries; added hatch build targets and dependency-groups.
Package manager migration (Poetry → UV)
.pre-commit-config.yaml, Makefile, CLAUDE.md, CONTRIBUTING.md
Replaced Poetry invocations with uv/uv tool commands across docs, make targets, and pre-commit hook entries; updated usage instructions.
CI workflows
.github/workflows/build.yml, .github/workflows/python-publish.yml
Upgraded actions (checkout v4→v6, setup-python→v6); removed Poetry steps and added astral-sh/setup-uv; replaced install/build/test commands with UV equivalents; added TruffleHog scan.
Docker & docs
docker/Dockerfile, docker/README.md
Switched to prebuilt UV toolchain image; use uv sync for deps; added dev-build (INSTALL_DEV) and test-run examples; updated workspace mount path.
Type system
qualifire/types.py
Converted many dataclasses to Pydantic BaseModel models; added validators, new models ToolResponse and CompilePromptResponse; changed several field defaults and added mode/policy fields.
Client API
qualifire/client.py
Added Client.compile_prompt(prompt_id, revision_id=None, params=None) -> CompilePromptResponse; switched request serialization to model_dump_json() and updated imports.
Config & linting
.flake8, .dockerignore, .gitignore
Increased flake8 max-line-length to 120; added __init__.py to flake8 exclude; adjusted .dockerignore to include .mypy_cache, build artifacts, and coverage files; removed Poetry comment from .gitignore.
Tests
tests/test_utils.py
Changed monkeypatch.delenv second arg from None to False in two tests to alter deletion behavior when env var is absent.
Other minor
.pre-commit-config.yaml (local entries)
Local hooks updated to invoke uv tool run ... instead of poetry run ....

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Client
participant API as "Studio API (/api/v1/studio/prompts)"
participant Types as "Pydantic models"
Client->>API: POST /prompts/{prompt_id}/compile?revision={revision}\nBody: {"variables": params}
API-->>Client: 200 OK with JSON payload (compiled prompt)
Client->>Types: parse JSON -> CompilePromptResponse
Client-->>Client: return CompilePromptResponse

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped from Poetry to UV bright,

Pydantic models snug and tight.
A compile call now skips and sings,
Workflows hum and Docker springs.
Build, test, compile — let's take flight! 🚀

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes both main changes: adding a compile_prompt function and replacing Poetry with uv as the package manager.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/FIRE-1028/add-compile-prompt-function

🧹 Recent nitpick comments
.github/workflows/build.yml (1)

26-29: Consider adding test dependencies to pyproject.toml instead of installing separately.

The explicit uv pip install pytest openai after uv sync bypasses the lock file, which can lead to version inconsistencies. If these are test dependencies, add them to the [dependency-groups] or dev dependencies in pyproject.toml so uv sync installs them with locked versions.

♻️ Proposed fix
      - name: Install dependencies
        run: |
          uv sync
-          uv pip install pytest openai

Then ensure pytest and openai are listed in your pyproject.toml dev dependencies:

[dependency-groups]
dev = [
    "pytest>=...",
    "openai>=...",
    # ... other dev deps
]

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0c79a11 and 7e099f2.

📒 Files selected for processing (1)
  • .github/workflows/build.yml
🔇 Additional comments (3)
.github/workflows/build.yml (3)

13-15: LGTM!

The checkout action is correctly updated to v6, and fetch-depth: 0 is appropriately configured to allow TruffleHog to scan the full git history for credentials.


38-40: LGTM!

The test step correctly delegates to the Makefile target.


21-24: The UV setup is correct.

Both astral-sh/setup-uv@v7 and uv version 0.9.22 are valid and current releases as of January 2026.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pyproject.toml (1)

136-147: Coverage configuration sections are incorrectly named and will be ignored.

The coverage configuration has two issues:

  1. Sections at lines 139, 142, and 145 are missing the tool. prefix required in pyproject.toml
  2. [coverage.run] at line 142 duplicates [tool.coverage.run] at line 136

These sections will be silently ignored, meaning branch = true, fail_under = 50, and show_missing = true won't take effect.

🐛 Proposed fix
 [tool.coverage.run]
-source = ["tests"]
-
-[coverage.paths]
-source = "qualifire"
-
-[coverage.run]
-branch = true
+source = ["qualifire"]
+branch = true

-[coverage.report]
+[tool.coverage.paths]
+source = ["qualifire"]
+
+[tool.coverage.report]
 fail_under = 50
 show_missing = true

Also note: source = ["tests"] in [tool.coverage.run] measures coverage of test files themselves rather than the qualifire source code—this is likely unintentional.

🤖 Fix all issues with AI agents
In @.flake8:
- Line 2: The flake8 max-line-length (max-line-length = 120 in .flake8)
conflicts with Black/isort's line-length in pyproject.toml (currently 88); fix
by making them consistent: either change .flake8 max-line-length to 88, or
update pyproject.toml's [tool.black] and [tool.isort] line-length settings to
120 so all three (max-line-length, tool.black.line-length,
tool.isort.line_length) match; update only the setting(s) and run the
formatter/linter to verify no remaining mismatches.

In @.github/workflows/build.yml:
- Around line 33-34: Fix the misspelled GitHub Actions step name by replacing
"Creadentials search in source code - TruffleHog OSS" with "Credentials search
in source code - TruffleHog OSS" in the workflow step that uses
trufflesecurity/trufflehog@v3.69.0 so the step name reads correctly.
- Around line 13-22: Fix the typo "Creadentials" -> "Credentials" in the GitHub
Actions workflow (search for the "Creadentials" string in
.github/workflows/build.yml), remove the redundant step that runs "uv pip
install pytest" because pytest is already pulled in via "uv sync" from
pyproject.toml, and if tests require openai add "openai" to the dev-dependencies
in pyproject.toml so it is installed by "uv sync"; ensure the actions steps
using actions/checkout@v6 and actions/setup-python@v6 remain unchanged.

In `@CONTRIBUTING.md`:
- Around line 5-6: Update the CONTRIBUTING.md sentence that reads "If you dont
have `uv`, you should install..." to correct the typo by replacing "dont" with
"don't" so the sentence reads "If you don't have `uv`, you should
install..."—locate this exact sentence in CONTRIBUTING.md and apply the
single-word fix.

In `@pyproject.toml`:
- Around line 30-33: Update the project URLs to use hyphens and the correct
repository name: replace the current Homepage and Repository values under
[project.urls] so they point to
"https://github.com/qualifire-dev/qualifire-python-sdk" (update the Homepage and
Repository entries accordingly).

In `@qualifire/client.py`:
- Around line 299-326: The compile_prompt method currently calls
response.raise_for_status() which is inconsistent with evaluate() and
invoke_evaluation(); change compile_prompt to check the response (e.g., if not
response.ok) and raise the same style of Exception used elsewhere with a clear
message including response.status_code and response.text (for example: "Error
compiling prompt: <status> - <response_text>") before returning
CompilePromptResponse(**response.json()); keep the rest of the request logic and
header handling intact and reference the compile_prompt function name when
applying the change.

In `@qualifire/types.py`:
- Around line 26-29: The LLMToolCall Pydantic model marks id as Optional[str]
but omits a default, making it required in Pydantic v2; update the LLMToolCall
class so the id field has an explicit default of None (e.g., set id to None) to
make it truly optional and ensure callers can omit it. Reference: class
LLMToolCall and the id field.
🧹 Nitpick comments (5)
qualifire/client.py (1)

299-304: Consider adding a docstring for this public API method.

The evaluate() method has comprehensive documentation. Adding a docstring to compile_prompt would improve API discoverability and usability.

Also, verify if params: Dict[str, str] is intentionally restricted to string values, or if it should be Dict[str, Any] to support other variable types.

Makefile (1)

10-14: Platform-specific UV installation may limit portability.

The brew install uv command only works on macOS. Consider using a platform-agnostic installation method or documenting that this target is macOS-only.

♻️ Suggested improvement for cross-platform support
 #* UV
 .PHONY: uv-download
 uv-download:
-	brew install uv
+	curl -LsSf https://astral.sh/uv/install.sh | sh
 	uv --version
.github/workflows/build.yml (1)

24-27: Potentially redundant dependency installation.

If pytest and openai are already defined as dev dependencies in pyproject.toml, the uv pip install pytest openai step may be redundant after uv sync. Consider whether these are needed or if uv sync already handles them.

pyproject.toml (2)

24-28: Move types-requests to dev dependencies.

types-requests is a type stub package used for static type checking (mypy). It provides no runtime functionality and should be in the [dependency-groups] dev section rather than runtime dependencies.

♻️ Proposed fix
 dependencies = [
     "pydantic>=2.10.6",
     "traceloop-sdk==0.40.4 ; python_version >= '3.10'",
-    "types-requests>=2.32.0.20241016",
 ]

Then add to the dev group:

dev = [
    # ... existing deps ...
    "types-requests>=2.32.0.20241016",
]

14-23: Classifiers are incomplete for supported Python versions.

The classifiers only list Python 3.8 and 3.9, but requires-python = ">=3.8,<4" implies support for 3.10, 3.11, 3.12, etc. Consider adding the missing classifiers for accurate PyPI metadata.

♻️ Proposed fix
 classifiers = [
     "Development Status :: 3 - Alpha",
     "Intended Audience :: Developers",
     "Operating System :: OS Independent",
     "Topic :: Software Development :: Libraries :: Python Modules",
     "License :: OSI Approved :: MIT License",
     "Programming Language :: Python :: 3",
     "Programming Language :: Python :: 3.8",
     "Programming Language :: Python :: 3.9",
+    "Programming Language :: Python :: 3.10",
+    "Programming Language :: Python :: 3.11",
+    "Programming Language :: Python :: 3.12",
 ]
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32c9b15 and 0c79a11.

⛔ Files ignored due to path filters (3)
  • assets/images/coverage.svg is excluded by !**/*.svg
  • poetry.lock is excluded by !**/*.lock
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (17)
  • .dockerignore
  • .flake8
  • .github/workflows/build.yml
  • .github/workflows/python-publish.yml
  • .gitignore
  • .pre-commit-config.yaml
  • CLAUDE.md
  • CONTRIBUTING.md
  • Makefile
  • docker/Dockerfile
  • docker/README.md
  • pyproject.toml
  • qualifire/client.py
  • qualifire/types.py
  • requirements.txt
  • setup.py
  • tests/test_utils.py
💤 Files with no reviewable changes (3)
  • .gitignore
  • setup.py
  • requirements.txt
🧰 Additional context used
📓 Path-based instructions (4)
qualifire/client.py

📄 CodeRabbit inference engine (CLAUDE.md)

qualifire/client.py: The main Client class with evaluate() and invoke_evaluation() methods should be located in qualifire/client.py
API key can be passed directly or via QUALIFIRE_API_KEY environment variable
Base URL defaults to https://proxy.qualifire.ai/ but can be overridden via QUALIFIRE_BASE_URL environment variable

Files:

  • qualifire/client.py
qualifire/{client,types}.py

📄 CodeRabbit inference engine (CLAUDE.md)

Legacy content moderation checks (dangerous_content_check, harassment_check, etc.) are deprecated in favor of unified content_moderation_check

Files:

  • qualifire/client.py
  • qualifire/types.py
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Tests should be located in tests/ directory and use pytest with parametrized test cases

Files:

  • tests/test_utils.py
qualifire/types.py

📄 CodeRabbit inference engine (CLAUDE.md)

qualifire/types.py: All data classes, enums, type definitions including EvaluationRequest, EvaluationResponse, LLMMessage, LLMToolCall, LLMToolDefinition, ModelMode, and SyntaxCheckArgs should be located in qualifire/types.py
The EvaluationRequest dataclass should validate inputs in __post_init__ (e.g., tool_selection_quality_check requires both messages and available_tools)

Files:

  • qualifire/types.py
🧠 Learnings (10)
📚 Learning: 2026-01-07T14:35:35.603Z
Learnt from: CR
Repo: qualifire-dev/qualifire-python-sdk PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-07T14:35:35.603Z
Learning: Run tests with coverage using `make test`; run specific tests with `poetry run pytest` commands

Applied to files:

  • Makefile
  • CONTRIBUTING.md
  • CLAUDE.md
  • .github/workflows/build.yml
📚 Learning: 2026-01-07T14:35:35.603Z
Learnt from: CR
Repo: qualifire-dev/qualifire-python-sdk PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-07T14:35:35.603Z
Learning: Install dependencies and set up environment using `make install` and `make pre-commit-install`

Applied to files:

  • Makefile
  • CONTRIBUTING.md
📚 Learning: 2026-01-07T14:35:35.603Z
Learnt from: CR
Repo: qualifire-dev/qualifire-python-sdk PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-07T14:35:35.603Z
Learning: Format code using `make codestyle` (isort, black, pyupgrade); check without modifying using `make check-codestyle`

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-07T14:35:35.603Z
Learnt from: CR
Repo: qualifire-dev/qualifire-python-sdk PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-07T14:35:35.603Z
Learning: Applies to qualifire/client.py : The main `Client` class with `evaluate()` and `invoke_evaluation()` methods should be located in `qualifire/client.py`

Applied to files:

  • qualifire/client.py
📚 Learning: 2026-01-07T14:35:35.603Z
Learnt from: CR
Repo: qualifire-dev/qualifire-python-sdk PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-07T14:35:35.603Z
Learning: Applies to qualifire/client.py : API key can be passed directly or via `QUALIFIRE_API_KEY` environment variable

Applied to files:

  • tests/test_utils.py
📚 Learning: 2026-01-07T14:35:35.603Z
Learnt from: CR
Repo: qualifire-dev/qualifire-python-sdk PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-07T14:35:35.603Z
Learning: Applies to qualifire/utils.py : Helper functions for API key and base URL resolution from environment variables should be located in `qualifire/utils.py`

Applied to files:

  • tests/test_utils.py
📚 Learning: 2026-01-07T14:35:35.603Z
Learnt from: CR
Repo: qualifire-dev/qualifire-python-sdk PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-07T14:35:35.603Z
Learning: Applies to qualifire/client.py : Base URL defaults to `https://proxy.qualifire.ai/` but can be overridden via `QUALIFIRE_BASE_URL` environment variable

Applied to files:

  • tests/test_utils.py
📚 Learning: 2026-01-07T14:35:35.603Z
Learnt from: CR
Repo: qualifire-dev/qualifire-python-sdk PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-07T14:35:35.603Z
Learning: Applies to qualifire/types.py : All data classes, enums, type definitions including `EvaluationRequest`, `EvaluationResponse`, `LLMMessage`, `LLMToolCall`, `LLMToolDefinition`, `ModelMode`, and `SyntaxCheckArgs` should be located in `qualifire/types.py`

Applied to files:

  • qualifire/types.py
📚 Learning: 2026-01-07T14:35:35.603Z
Learnt from: CR
Repo: qualifire-dev/qualifire-python-sdk PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-07T14:35:35.603Z
Learning: Applies to qualifire/types.py : The `EvaluationRequest` dataclass should validate inputs in `__post_init__` (e.g., tool_selection_quality_check requires both messages and available_tools)

Applied to files:

  • qualifire/types.py
📚 Learning: 2026-01-07T14:35:35.603Z
Learnt from: CR
Repo: qualifire-dev/qualifire-python-sdk PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-07T14:35:35.603Z
Learning: Applies to qualifire/{client,types}.py : Legacy content moderation checks (dangerous_content_check, harassment_check, etc.) are deprecated in favor of unified `content_moderation_check`

Applied to files:

  • qualifire/types.py
🧬 Code graph analysis (1)
qualifire/client.py (1)
qualifire/types.py (1)
  • CompilePromptResponse (157-163)
🪛 checkmake (0.2.2)
Makefile

[warning] 119-119: Missing required phony target "all"

(minphony)


[warning] 119-119: Missing required phony target "clean"

(minphony)

🔇 Additional comments (25)
qualifire/client.py (3)

9-9: LGTM!

The import of CompilePromptResponse is correctly added to support the new compile_prompt method.


236-238: LGTM!

The migration to model_dump_json() is correct for Pydantic v2 and aligns with the dataclass-to-Pydantic migration in types.py.


284-284: LGTM!

Consistent use of model_dump_json() for serialization.

qualifire/types.py (7)

5-6: LGTM!

Correct imports for Pydantic v2 with BaseModel and model_validator.


38-39: LGTM!

Clean migration to Pydantic BaseModel.


70-76: LGTM!

The @model_validator(mode="after") correctly replaces the dataclass __post_init__ pattern. The validation logic is properly preserved for input validation and deprecated field handling. Based on learnings, this maintains the expected validation behavior.


111-127: LGTM!

Consistent validation pattern with EvaluationRequest.


130-138: LGTM!

The claim field correctly uses Optional[str] = None pattern, making it truly optional. Other fields are required as expected.


141-149: LGTM!

Clean model definitions. The evaluationResults field uses camelCase to match the API response format.


152-163: LGTM!

New models ToolResponse and CompilePromptResponse are well-defined and match the expected API contract structure. Based on learnings, all type definitions are correctly placed in qualifire/types.py.

CLAUDE.md (1)

20-23: LGTM!

The test invocation commands are correctly updated to use uv run pytest, consistent with the Poetry-to-UV migration across the repository. Based on learnings, these commands previously used poetry run pytest.

CONTRIBUTING.md (1)

15-15: LGTM!

The updated guidance correctly explains that UV automatically manages virtual environments when using uv run.

tests/test_utils.py (2)

29-29: LGTM!

Using False explicitly for the raising parameter is the correct approach. While None worked due to Python's falsy evaluation, False is semantically clearer and matches the expected boolean type.


54-54: Consistent fix applied here as well.

.dockerignore (1)

31-39: LGTM!

Good additions to exclude build artifacts (dist/, build/, *.egg-info/) and test coverage files (htmlcov/, .coverage, .coverage.*) from Docker builds. These align with the UV/Hatchling migration and keep Docker contexts clean.

.github/workflows/python-publish.yml (2)

34-38: LGTM!

The build commands correctly use UV idioms:

  • uv build for package building
  • uv tool run twine check dist/* for wheel validation without requiring twine as a project dependency

23-32: All action versions are valid and properly released.

  • actions/checkout@v6 is a current release (updated credential handling)
  • actions/setup-python@v6 is a current release (Node 20 → Node 24)
  • astral-sh/setup-uv@v7 is current
  • UV version 0.9.22 was released January 6, 2026

No changes needed.

.pre-commit-config.yaml (1)

16-30: LGTM!

The migration from Poetry to uv tool run for the local isort and black hooks is correct. The settings paths are preserved, maintaining consistent formatting behavior.

Makefile (2)

16-63: LGTM!

The Poetry-to-UV migration is comprehensive and correct:

  • uv sync replaces poetry install
  • uv run replaces poetry run for tool execution
  • uv add --dev replaces poetry add --dev for dependency management

109-121: LGTM!

The new build targets (build, build-wheel, build-sdist) using uv build are good additions that complement the UV migration.

docker/Dockerfile (2)

16-22: Consider adding explicit package installation.

After uv sync installs dependencies and COPY . . adds the source code, the package itself may not be installed in the environment. If this container is intended to run the qualifire package, you may need to add uv pip install -e . or uv pip install . after copying the source.

If this container is purely for development/testing purposes (as suggested by CMD ["/bin/bash"]), this may be intentional.


1-24: LGTM on the UV migration pattern.

The Dockerfile correctly migrates from Poetry to UV:

  • Copies the UV binary from the official image
  • Sets appropriate UV environment variables
  • Uses uv sync --frozen --no-cache for reproducible installs
  • Conditional --no-dev flag for production builds
docker/README.md (1)

25-45: LGTM!

The documentation updates are clear and consistent with the Dockerfile changes:

  • Dev build instructions with INSTALL_DEV=true are helpful
  • Mount path updated to match the new /app working directory
  • Test execution example using uv run pytest is correct
pyproject.toml (2)

34-52: Dev dependencies look reasonable, though some versions are dated.

The dependency constraints are well-structured. Note that some tools have newer major versions available (e.g., black 24.x, pytest 8.x), but the current pinning ensures stability.


54-58: No action needed. The build configuration is correct and matches the package structure. The project uses a flat layout with qualifire/ at the root level, and the build targets correctly include ["qualifire"].

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@@ -1,5 +1,5 @@
[flake8]
max-line-length = 88
max-line-length = 120
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for line-length/max-line configurations in common config files

echo "=== Searching for line-length configurations ==="
rg -n "line.?length|max.?line" --type=toml --type=ini --type=yaml --type=cfg 2>/dev/null | head -50

echo -e "\n=== Checking pyproject.toml for formatter settings ==="
fd -t f "pyproject.toml" -x cat {} 2>/dev/null

echo -e "\n=== Checking setup.cfg for flake8/formatter settings ==="
fd -t f "setup.cfg" -x cat {} 2>/dev/null

echo -e "\n=== Checking .flake8 file ==="
cat .flake8 2>/dev/null || echo "File not found"

echo -e "\n=== Checking for tox.ini ==="
fd -t f "tox.ini" -x cat {} 2>/dev/null

Repository: qualifire-dev/qualifire-python-sdk

Length of output: 3946


Fix configuration mismatch between flake8 and Black/isort.

The .flake8 change to max-line-length = 120 conflicts with pyproject.toml which configures Black and isort to line-length = 88. Update either:

  • Black and isort in pyproject.toml to line-length = 120, or
  • .flake8 back to max-line-length = 88

Without this alignment, you'll have inconsistent line-length enforcement between formatting and linting.

🤖 Prompt for AI Agents
In @.flake8 at line 2, The flake8 max-line-length (max-line-length = 120 in
.flake8) conflicts with Black/isort's line-length in pyproject.toml (currently
88); fix by making them consistent: either change .flake8 max-line-length to 88,
or update pyproject.toml's [tool.black] and [tool.isort] line-length settings to
120 so all three (max-line-length, tool.black.line-length,
tool.isort.line_length) match; update only the setting(s) and run the
formatter/linter to verify no remaining mismatches.

Comment on lines 13 to 22
- uses: actions/checkout@v6
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4.7.0
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install and configure Poetry
uses: snok/install-poetry@v1

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: 1.6.1
version: "0.9.22"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n .github/workflows/build.yml

Repository: qualifire-dev/qualifire-python-sdk

Length of output: 1183


🏁 Script executed:

find . -name "pyproject.toml" -type f | head -5

Repository: qualifire-dev/qualifire-python-sdk

Length of output: 94


🏁 Script executed:

cat -n ./pyproject.toml

Repository: qualifire-dev/qualifire-python-sdk

Length of output: 4540


🌐 Web query:

actions/checkout latest version GitHub

💡 Result:

The current latest release is actions/checkout v6.0.2 (released Jan 9, 2026). [1][2]

Sources:
[1] actions/checkout releases (v6.0.2).
[2] actions/checkout repository README (Checkout v6).


🌐 Web query:

actions/setup-python latest version GitHub v6

💡 Result:

Latest v6 tag is v6.1.0 — released Nov 25, 2025. [1][2]

Sources:
[1] actions/setup-python releases (v6.1.0).
[2] actions/setup-python README / Marketplace showing usage with @v6.


Fix the typo on line 33: "Creadentials" should be "Credentials".

The GitHub Actions versions (checkout@v6 and setup-python@v6) are valid and available. However, the uv pip install pytest on line 27 is redundant since pytest is already listed in pyproject.toml dev dependencies and will be installed via uv sync. Additionally, openai is not declared in pyproject.toml dev dependencies—consider adding it there if it's a required test dependency.

🤖 Prompt for AI Agents
In @.github/workflows/build.yml around lines 13 - 22, Fix the typo
"Creadentials" -> "Credentials" in the GitHub Actions workflow (search for the
"Creadentials" string in .github/workflows/build.yml), remove the redundant step
that runs "uv pip install pytest" because pytest is already pulled in via "uv
sync" from pyproject.toml, and if tests require openai add "openai" to the
dev-dependencies in pyproject.toml so it is installed by "uv sync"; ensure the
actions steps using actions/checkout@v6 and actions/setup-python@v6 remain
unchanged.

Comment on lines 33 to 34
- name: Creadentials search in source code - TruffleHog OSS
uses: trufflesecurity/trufflehog@v3.69.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix typo in step name.

"Creadentials" should be "Credentials".

📝 Proposed fix
-      - name: Creadentials search in source code - TruffleHog OSS
+      - name: Credentials search in source code - TruffleHog OSS
📝 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.

Suggested change
- name: Creadentials search in source code - TruffleHog OSS
uses: trufflesecurity/trufflehog@v3.69.0
- name: Credentials search in source code - TruffleHog OSS
uses: trufflesecurity/trufflehog@v3.69.0
🤖 Prompt for AI Agents
In @.github/workflows/build.yml around lines 33 - 34, Fix the misspelled GitHub
Actions step name by replacing "Creadentials search in source code - TruffleHog
OSS" with "Credentials search in source code - TruffleHog OSS" in the workflow
step that uses trufflesecurity/trufflehog@v3.69.0 so the step name reads
correctly.

Comment on lines +5 to +6
We use `uv` to manage the [dependencies](https://docs.astral.sh/uv/).
If you dont have `uv`, you should install with `make uv-download` or follow the [official installation guide](https://docs.astral.sh/uv/getting-started/installation/).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Minor typo: "dont" → "don't".

Proposed fix
-If you dont have `uv`, you should install with `make uv-download` or follow the [official installation guide](https://docs.astral.sh/uv/getting-started/installation/).
+If you don't have `uv`, you should install with `make uv-download` or follow the [official installation guide](https://docs.astral.sh/uv/getting-started/installation/).
📝 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.

Suggested change
We use `uv` to manage the [dependencies](https://docs.astral.sh/uv/).
If you dont have `uv`, you should install with `make uv-download` or follow the [official installation guide](https://docs.astral.sh/uv/getting-started/installation/).
We use `uv` to manage the [dependencies](https://docs.astral.sh/uv/).
If you don't have `uv`, you should install with `make uv-download` or follow the [official installation guide](https://docs.astral.sh/uv/getting-started/installation/).
🤖 Prompt for AI Agents
In `@CONTRIBUTING.md` around lines 5 - 6, Update the CONTRIBUTING.md sentence that
reads "If you dont have `uv`, you should install..." to correct the typo by
replacing "dont" with "don't" so the sentence reads "If you don't have `uv`, you
should install..."—locate this exact sentence in CONTRIBUTING.md and apply the
single-word fix.

Comment on lines +30 to +33
[project.urls]
Homepage = "https://github.com/qualifire_dev/qualifire"
Repository = "https://github.com/qualifire_dev/qualifire"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

URLs appear incorrect - GitHub uses hyphens, not underscores.

Based on the PR URL (github.com/qualifire-dev/qualifire-python-sdk), these URLs should use hyphens and the correct repository name.

🐛 Proposed fix
 [project.urls]
-Homepage = "https://github.com/qualifire_dev/qualifire"
-Repository = "https://github.com/qualifire_dev/qualifire"
+Homepage = "https://github.com/qualifire-dev/qualifire-python-sdk"
+Repository = "https://github.com/qualifire-dev/qualifire-python-sdk"
📝 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.

Suggested change
[project.urls]
Homepage = "https://github.com/qualifire_dev/qualifire"
Repository = "https://github.com/qualifire_dev/qualifire"
[project.urls]
Homepage = "https://github.com/qualifire-dev/qualifire-python-sdk"
Repository = "https://github.com/qualifire-dev/qualifire-python-sdk"
🤖 Prompt for AI Agents
In `@pyproject.toml` around lines 30 - 33, Update the project URLs to use hyphens
and the correct repository name: replace the current Homepage and Repository
values under [project.urls] so they point to
"https://github.com/qualifire-dev/qualifire-python-sdk" (update the Homepage and
Repository entries accordingly).

Comment on lines +299 to +326
def compile_prompt(
self,
prompt_id: str,
revision_id: Optional[str] = None,
params: Optional[Dict[str, str]] = None,
) -> CompilePromptResponse:
url = f"{self._base_url}/api/v1/studio/prompts/{prompt_id}/compile"
if revision_id:
url = f"{url}?revision={revision_id}"

headers = {
"X-Qualifire-API-Key": self._api_key,
"Content-Type": "application/json",
}

if not params:
params = {}
request_body = json.dumps({"variables": params})

response = requests.post(
url=url,
data=request_body,
headers=headers,
verify=self._verify,
)
response.raise_for_status()

return CompilePromptResponse(**response.json())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Inconsistent error handling pattern.

The compile_prompt method uses response.raise_for_status() which raises an HTTPError, while evaluate() and invoke_evaluation() raise a custom Exception with a formatted message including the response text. This inconsistency could confuse SDK users who expect uniform error handling.

Consider aligning with the existing pattern:

Proposed fix
         response = requests.post(
             url=url,
             data=request_body,
             headers=headers,
             verify=self._verify,
         )
-        response.raise_for_status()
+        if response.status_code != 200:
+            message = f"Qualifire API error: {response.status_code}"
+            if response.text:
+                message += f" - {response.text}"
+            raise Exception(message)

         return CompilePromptResponse(**response.json())
📝 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.

Suggested change
def compile_prompt(
self,
prompt_id: str,
revision_id: Optional[str] = None,
params: Optional[Dict[str, str]] = None,
) -> CompilePromptResponse:
url = f"{self._base_url}/api/v1/studio/prompts/{prompt_id}/compile"
if revision_id:
url = f"{url}?revision={revision_id}"
headers = {
"X-Qualifire-API-Key": self._api_key,
"Content-Type": "application/json",
}
if not params:
params = {}
request_body = json.dumps({"variables": params})
response = requests.post(
url=url,
data=request_body,
headers=headers,
verify=self._verify,
)
response.raise_for_status()
return CompilePromptResponse(**response.json())
def compile_prompt(
self,
prompt_id: str,
revision_id: Optional[str] = None,
params: Optional[Dict[str, str]] = None,
) -> CompilePromptResponse:
url = f"{self._base_url}/api/v1/studio/prompts/{prompt_id}/compile"
if revision_id:
url = f"{url}?revision={revision_id}"
headers = {
"X-Qualifire-API-Key": self._api_key,
"Content-Type": "application/json",
}
if not params:
params = {}
request_body = json.dumps({"variables": params})
response = requests.post(
url=url,
data=request_body,
headers=headers,
verify=self._verify,
)
if response.status_code != 200:
message = f"Qualifire API error: {response.status_code}"
if response.text:
message += f" - {response.text}"
raise Exception(message)
return CompilePromptResponse(**response.json())
🤖 Prompt for AI Agents
In `@qualifire/client.py` around lines 299 - 326, The compile_prompt method
currently calls response.raise_for_status() which is inconsistent with
evaluate() and invoke_evaluation(); change compile_prompt to check the response
(e.g., if not response.ok) and raise the same style of Exception used elsewhere
with a clear message including response.status_code and response.text (for
example: "Error compiling prompt: <status> - <response_text>") before returning
CompilePromptResponse(**response.json()); keep the rest of the request logic and
header handling intact and reference the compile_prompt function name when
applying the change.

Comment on lines +26 to 29
class LLMToolCall(BaseModel):
name: str
arguments: Dict[str, Any]
id: Optional[str]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Missing default for id field makes it required despite Optional annotation.

In Pydantic v2, Optional[str] without a default value means the field is still required (callers must explicitly pass id=None). If the intent is to make id truly optional (can be omitted), add a default value.

Proposed fix
 class LLMToolCall(BaseModel):
     name: str
     arguments: Dict[str, Any]
-    id: Optional[str]
+    id: Optional[str] = None
📝 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.

Suggested change
class LLMToolCall(BaseModel):
name: str
arguments: Dict[str, Any]
id: Optional[str]
class LLMToolCall(BaseModel):
name: str
arguments: Dict[str, Any]
id: Optional[str] = None
🤖 Prompt for AI Agents
In `@qualifire/types.py` around lines 26 - 29, The LLMToolCall Pydantic model
marks id as Optional[str] but omits a default, making it required in Pydantic
v2; update the LLMToolCall class so the id field has an explicit default of None
(e.g., set id to None) to make it truly optional and ensure callers can omit it.
Reference: class LLMToolCall and the id field.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants