Skip to content
Open
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
99 changes: 93 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,26 @@ Python SDK for building, deploying, and governing AI agents on the aiXplain plat

---

## Primary Goal

- Keep the SDK stable for existing users while improving the current `development` branch.
- Default to the `v2` SDK surface for new work.
- Preserve backward compatibility for the legacy `v1` surface and legacy import paths.

---

## Source of Truth

- Package metadata and dependencies live in `pyproject.toml`.
- Formatting and docstring rules live in `ruff.toml`.
- Pre-commit behavior lives in `.pre-commit-config.yaml`.
- CI behavior lives in `.github/workflows/`.
- Public package bootstrapping and legacy import compatibility live in `aixplain/__init__.py` and `aixplain/_compat.py`.

If this file conflicts with code, tests, or CI, follow the code and tests and update this file in the same change when appropriate.

---

## Setup and Commands

```bash
Expand All @@ -23,7 +43,13 @@ pip install -e ".[test]"

### Environment

Set `AIXPLAIN_API_KEY` (required) before using the SDK. `BACKEND_URL` defaults to production (`https://platform-api.aixplain.com`).
The SDK supports either `TEAM_API_KEY` or `AIXPLAIN_API_KEY`. New code must not assume only one of those environment variables exists. `BACKEND_URL` defaults to production (`https://platform-api.aixplain.com`).

Additional environment variables for execution URLs:
- `MODELS_RUN_URL`
- `PIPELINES_RUN_URL`

In `v2`, prefer instance-scoped configuration through `Aixplain(...)` and its context rather than new global state.

### Test

Expand Down Expand Up @@ -54,7 +80,7 @@ ruff format . # Format
pre-commit install
```

Hooks run: trailing-whitespace, end-of-file-fixer, check-merge-conflict, check-added-large-files, ruff (lint + format), and unit tests.
Hooks run: trailing-whitespace, end-of-file-fixer, check-merge-conflict, check-added-large-files, ruff (lint + format for `aixplain/v2/`), and unit tests with coverage.

---

Expand All @@ -66,8 +92,8 @@ Hooks run: trailing-whitespace, end-of-file-fixer, check-merge-conflict, check-a
- **Docstrings**: Google style (enforced by ruff `pydocstyle`). Docstring rules are **not** enforced in `tests/`.
- **Type hints**: Required on all public functions. Use `typing` (`Optional`, `Union`, `List`, `Dict`, `TypeVar`, generics).
- **Naming**: `PascalCase` for classes, `snake_case` for functions and methods, `UPPER_SNAKE_CASE` for constants.
- **Exceptions**: Use the custom hierarchy in `aixplain/exceptions/` (`AixplainBaseException` and subclasses). Never raise bare `Exception`.
- **Imports**: Use `from __future__ import annotations` or `TYPE_CHECKING` guards to break circular imports. Use conditional imports for optional dependencies.
- **Exceptions**: Use the custom hierarchy in `aixplain/exceptions/` (`AixplainBaseException` and subclasses). Never raise bare `Exception`. Preserve useful context in error messages and include status or response details when available.
- **Imports**: Use `from __future__ import annotations` or `TYPE_CHECKING` guards to break circular imports. Use conditional imports for optional dependencies. Do not add a new dependency unless it is necessary and justified by the repository's existing design.
- **Validation**: Pydantic for runtime validation. `dataclasses-json` for JSON serialization.
- **License header**: Include the Apache 2.0 license header at the top of every source file.

Expand All @@ -89,9 +115,11 @@ The SDK exposes two API layers maintained in parallel:

| Directory | Purpose |
|---|---|
| `aixplain/v2/` | Current SDK surface. Prefer this for new features and fixes unless the task is explicitly about legacy behavior. |
| `aixplain/v1/` | Legacy SDK implementation. Touch this for compatibility fixes, bug fixes, or explicitly requested v1 work. |
| `aixplain/_compat.py` | Legacy import redirector. Existing imports like `aixplain.modules` and `aixplain.factories` must continue to work. |
| `aixplain/modules/` | Domain objects (Agent, Model, Pipeline, TeamAgent, tools) |
| `aixplain/factories/` | V1 factory classes for creating and managing resources |
| `aixplain/v2/` | V2 resource classes with mixins and hook system |
| `aixplain/enums/` | Enumerations (Function, Supplier, Language, Status, etc.) |
| `aixplain/exceptions/` | Custom exception hierarchy with error codes and categories |
| `aixplain/utils/` | Shared helpers (config, HTTP requests, file utilities, caching) |
Expand All @@ -109,14 +137,73 @@ The SDK exposes two API layers maintained in parallel:

---

## Change Scope Rules

- Make the smallest change that fully solves the task.
- Do not do opportunistic refactors unless they are required to complete the requested work safely.
- Do not silently move functionality between `v1` and `v2`.
- Do not remove compatibility paths, deprecated parameters, or legacy import routes unless the task explicitly requires a breaking change.

### V2 Rules

- Treat `aixplain/v2/` as the default surface for all new SDK behavior.
- Keep `v2` self-contained. Do not import from legacy paths such as `aixplain.modules`, `aixplain.factories`, `aixplain.enums`, or `aixplain.utils`.
- Internal Python identifiers in `v2` should be `snake_case`. Convert to the API's `camelCase` only at the network or serialization boundary.
- Prefer typed, explicit resource and client code over dynamic dict-heavy plumbing.
- Preserve the multi-instance pattern centered on `Aixplain(api_key=...)`.
- Do not add import-time behavior in `v2` that forces users onto the legacy env-var validation chain.

### V1 and Compatibility Rules

- Treat `aixplain/v1/` as a compatibility surface.
- For new capabilities, prefer adding them in `v2` unless the task explicitly asks for `v1`.
- When fixing `v1`, preserve current public behavior unless the bug fix requires a narrow, well-justified change.
- Keep legacy imports working through `aixplain/_compat.py`.
- Do not introduce changes in `v1` that break users importing from historical paths like `aixplain.modules.*` or `aixplain.factories.*`.

---

## Testing

- **Framework**: pytest (configured in `pytest.ini`, `testpaths = tests`).
- **Unit tests**: `tests/unit/` -- fast, mocked, no network calls.
- **Functional tests**: `tests/functional/` -- integration tests against real or staged services.
- **Mock data**: `tests/mock_responses/` -- JSON fixtures for API responses.
- **CI**: GitHub Actions runs 16 parallel test suites (unit, agent, model, pipeline, v2, finetune, etc.) on Python 3.9 with a 45-minute timeout.
- **CI**: GitHub Actions runs parallel test suites (unit, agent, model, pipeline, v2, finetune, etc.) on Python 3.9 with a 45-minute timeout.
- **Docstrings in tests**: Not enforced (ruff ignores `D` rules for `tests/**/*.py`).
- For `v2` work, prefer targeted unit tests under `tests/unit/v2/`.
- For legacy work, add or update the narrowest relevant unit or functional tests.

---

## New Files

- New Python source files should include the repository's Apache 2.0 header format used in package modules.
- Place new files inside the existing package layout. Do not invent a new top-level package or directory for SDK code without explicit direction.

---

## Common Mistakes to Avoid

- Do not add `v1` imports inside `aixplain/v2/`.
- Do not leak Python `snake_case` field names into API payloads that expect `camelCase`.
- Do not break legacy import compatibility by bypassing or removing `_compat.py`.
- Do not hardcode a single API-key env-var assumption.
- Do not make `v2` depend on import-time side effects from legacy modules.
- Do not edit generated docs or unrelated documentation unless the task requires it.

---

## Review Checklist

Before finishing, check the following:

- Is the change in the correct surface, `v2` or `v1`?
- Did you preserve backward compatibility where expected?
- Did you avoid `v1` imports from `v2`?
- Did you keep internal names `snake_case` and API payload keys `camelCase` where required?
- Did you update or add focused tests?
- Did you avoid unrelated refactors?

---

Expand Down
Loading