|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +Shared instructions for coding agents working in this repository. |
| 4 | + |
| 5 | +Keep this file concise, concrete, and repo-specific. If guidance grows large, split it into referenced docs instead of turning this file into a handbook. |
| 6 | + |
| 7 | +## Project Summary |
| 8 | + |
| 9 | +This repository contains the Langfuse Python SDK. |
| 10 | + |
| 11 | +- `langfuse/_client/`: core SDK, OpenTelemetry integration, resource management, decorators, datasets |
| 12 | +- `langfuse/openai.py`: OpenAI instrumentation |
| 13 | +- `langfuse/langchain/`: LangChain integration |
| 14 | +- `langfuse/_task_manager/`: background consumers for media and score ingestion |
| 15 | +- `langfuse/api/`: generated Fern API client, do not hand-edit |
| 16 | +- `tests/unit/`: deterministic local tests, no Langfuse server |
| 17 | +- `tests/e2e/`: real Langfuse-server tests |
| 18 | +- `tests/live_provider/`: live OpenAI / LangChain provider tests |
| 19 | +- `tests/support/`: shared helpers for e2e tests |
| 20 | +- `scripts/select_e2e_shard.py`: CI shard selector for `tests/e2e` |
| 21 | + |
| 22 | +## Working Style |
| 23 | + |
| 24 | +- Prefer small, targeted changes that preserve existing behavior. |
| 25 | +- Do not weaken assertions just to make tests faster or greener. |
| 26 | +- If a test is slow, first optimize setup, teardown, polling, or fixtures. |
| 27 | +- Keep repo-shared instructions here. Keep personal or machine-specific notes out of version control. |
| 28 | + |
| 29 | +## Setup And Quality Commands |
| 30 | + |
| 31 | +```bash |
| 32 | +uv sync --locked |
| 33 | +uv run pre-commit install |
| 34 | +uv run --frozen ruff check . |
| 35 | +uv run --frozen ruff format . |
| 36 | +uv run --frozen mypy langfuse --no-error-summary |
| 37 | +``` |
| 38 | + |
| 39 | +## Test Commands |
| 40 | + |
| 41 | +Use the directory-based test split. |
| 42 | + |
| 43 | +```bash |
| 44 | +# Unit tests |
| 45 | +uv run --frozen pytest -n auto --dist worksteal tests/unit |
| 46 | + |
| 47 | +# All e2e tests that can run concurrently |
| 48 | +uv run --frozen pytest -n 4 --dist worksteal tests/e2e -m "not serial_e2e" |
| 49 | + |
| 50 | +# E2E tests that must run serially |
| 51 | +uv run --frozen pytest tests/e2e -m "serial_e2e" |
| 52 | + |
| 53 | +# Live provider tests |
| 54 | +uv run --frozen pytest -n 4 --dist worksteal tests/live_provider -m "live_provider" |
| 55 | + |
| 56 | +# Single test |
| 57 | +uv run --frozen pytest tests/unit/test_resource_manager.py::test_pause_signals_score_consumer_shutdown |
| 58 | +``` |
| 59 | + |
| 60 | +## Test Topology |
| 61 | + |
| 62 | +### `tests/unit` |
| 63 | + |
| 64 | +- Must not require a running Langfuse server. |
| 65 | +- Prefer in-memory exporters and local fakes over real network calls. |
| 66 | +- If tracing behavior is under test, use the shared in-memory fixtures in `tests/conftest.py`. |
| 67 | + |
| 68 | +### `tests/e2e` |
| 69 | + |
| 70 | +- Use for persisted backend behavior that genuinely needs a real Langfuse server. |
| 71 | +- Prefer bounded polling helpers in `tests/support/` over raw `sleep()` calls. |
| 72 | +- Use `serial_e2e` only for tests that are unsafe under shared-server concurrency. |
| 73 | +- New e2e files should be named `tests/e2e/test_*.py`. |
| 74 | +- Do not add `e2e_core` / `e2e_data` markers. CI shards `tests/e2e` mechanically with `scripts/select_e2e_shard.py`. |
| 75 | + |
| 76 | +### `tests/live_provider` |
| 77 | + |
| 78 | +- This suite uses real provider calls and always runs as one dedicated CI suite. |
| 79 | +- Do not split or shard `tests/live_provider` into separate smoke and extended jobs unless the team explicitly changes that policy. |
| 80 | +- Keep assertions focused on stable provider-facing behavior rather than brittle observation counts. |
| 81 | + |
| 82 | +## CI Contract |
| 83 | + |
| 84 | +The main CI workflow currently runs: |
| 85 | + |
| 86 | +- linting on Python 3.13 |
| 87 | +- mypy on Python 3.13 |
| 88 | +- `tests/unit` on a Python 3.10-3.14 matrix |
| 89 | +- `tests/e2e` in 2 mechanical shards plus a serial subset inside each shard |
| 90 | +- `tests/live_provider` as one always-on suite |
| 91 | + |
| 92 | +If you change the e2e split: |
| 93 | + |
| 94 | +- update `scripts/select_e2e_shard.py`, not marker routing in `tests/conftest.py` |
| 95 | +- make sure new `tests/e2e/test_*.py` files are automatically covered |
| 96 | +- keep `serial_e2e` as the only scheduling-specific pytest marker |
| 97 | + |
| 98 | +If you change CI bootstrap: |
| 99 | + |
| 100 | +- preserve the `LANGFUSE_INIT_*` startup path for the Langfuse server unless there is a strong reason to change it |
| 101 | +- preserve `cancel-in-progress: true` |
| 102 | + |
| 103 | +## Codebase Rules |
| 104 | + |
| 105 | +- Prefer `LANGFUSE_BASE_URL`; `LANGFUSE_HOST` is deprecated and is only kept for compatibility tests. |
| 106 | +- If you touch `langfuse/api/`, regenerate it from the upstream Fern/OpenAPI source instead of hand-editing files. |
| 107 | +- If you touch shutdown, flushing, or worker-thread behavior, run the relevant resource-manager and OTEL-heavy tests. |
| 108 | +- If you change OpenAI or LangChain instrumentation, keep as much coverage as possible in `tests/unit` using exporter-local assertions, and leave only the minimal necessary coverage in `tests/e2e` / `tests/live_provider`. |
| 109 | + |
| 110 | +## Python-Specific Notes |
| 111 | + |
| 112 | +- Exception messages should not inline f-string literals in the `raise` statement. Build the message in a variable first. |
| 113 | +- Prefer ASCII-only edits unless the file already uses Unicode or Unicode is clearly required. |
| 114 | + |
| 115 | +## Release And Docs |
| 116 | + |
| 117 | +```bash |
| 118 | +uv build --no-sources |
| 119 | +uv run --group docs pdoc -o docs/ --docformat google --logo "https://langfuse.com/langfuse_logo.svg" langfuse |
| 120 | +``` |
| 121 | + |
| 122 | +Releases are handled by GitHub Actions. Do not build an ad hoc local release flow into repository instructions. |
| 123 | + |
| 124 | +## External Docs |
| 125 | + |
| 126 | +- Prefer official documentation first when answering product or API questions. |
| 127 | +- For OpenAI API, ChatGPT Apps SDK, or Codex questions, use the official OpenAI developer docs or Docs MCP server if available. |
| 128 | +- If this repository keeps agent-specific files for multiple tools, treat `AGENTS.md` as the shared source of truth and import it from tool-specific files instead of duplicating instructions. |
0 commit comments