|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +sttp-openai is a Scala library providing a non-official client wrapper for OpenAI (and OpenAI-compatible) APIs. It's built on top of the sttp HTTP client library and supports both sync and async operations with various effect systems (cats-effect, ZIO, Akka/Pekko Streams, Ox). |
| 8 | + |
| 9 | +## Project Structure |
| 10 | + |
| 11 | +### Root Directory Layout |
| 12 | +``` |
| 13 | +sttp-openai/ |
| 14 | +├── core/ # Main library code |
| 15 | +├── streaming/ # Effect-system specific streaming implementations |
| 16 | +│ ├── fs2/ # cats-effect/fs2 streaming support |
| 17 | +│ ├── zio/ # ZIO streaming support |
| 18 | +│ ├── akka/ # Akka Streams support (Scala 2.13 only) |
| 19 | +│ ├── pekko/ # Pekko Streams support |
| 20 | +│ └── ox/ # Ox direct-style streaming (Scala 3 only) |
| 21 | +├── examples/ # Runnable examples using scala-cli |
| 22 | +├── model_update_scripts/ # Automation for updating OpenAI model definitions |
| 23 | +├── project/ # sbt build configuration |
| 24 | +├── generated-docs/ # Generated documentation (mdoc output) |
| 25 | +└── .github/workflows/ # CI/CD GitHub Actions |
| 26 | +``` |
| 27 | + |
| 28 | +### Core Module Structure (`core/src/main/scala/sttp/openai/`) |
| 29 | +``` |
| 30 | +sttp.openai/ |
| 31 | +├── OpenAI.scala # Raw sttp requests returning Either[OpenAIException, A] |
| 32 | +├── OpenAISyncClient.scala # High-level sync client that may throw exceptions |
| 33 | +├── OpenAIExceptions.scala # Exception hierarchy for API errors |
| 34 | +├── json/ # JSON serialization utilities |
| 35 | +│ ├── SnakePickle.scala # Snake_case conversion for uPickle |
| 36 | +│ └── SttpUpickleApiExtension.scala |
| 37 | +└── requests/ # API endpoint definitions (mirrors OpenAI API structure) |
| 38 | +``` |
| 39 | + |
| 40 | +### Requests Package Organization (`requests/`) |
| 41 | +The `requests/` package closely mirrors OpenAI's API structure. Each directory contains request/response models and configurations: |
| 42 | + |
| 43 | +``` |
| 44 | +requests/ |
| 45 | +├── completions/ # Text completion APIs |
| 46 | +│ ├── chat/ # Chat completions (most complex) |
| 47 | +│ │ ├── message/ # Message types, content, tools |
| 48 | +│ │ ├── ChatRequestBody.scala |
| 49 | +│ │ ├── ChatRequestResponseData.scala |
| 50 | +│ │ ├── ChatChunkRequestResponseData.scala # Streaming responses |
| 51 | +│ │ └── ToolCall.scala |
| 52 | +│ ├── CompletionsRequestBody.scala |
| 53 | +│ └── CompletionsResponseData.scala |
| 54 | +├── audio/ # Audio APIs |
| 55 | +│ ├── speech/ # Text-to-speech |
| 56 | +│ ├── transcriptions/ # Speech-to-text |
| 57 | +│ └── translations/ # Audio translation |
| 58 | +├── images/ # Image generation APIs |
| 59 | +│ ├── creation/ # Image generation |
| 60 | +│ ├── edit/ # Image editing |
| 61 | +│ └── variations/ # Image variations |
| 62 | +├── embeddings/ # Text embeddings API |
| 63 | +├── assistants/ # OpenAI Assistants API |
| 64 | +├── threads/ # Conversation threads |
| 65 | +│ ├── messages/ # Thread messages |
| 66 | +│ └── runs/ # Thread runs and tool calls |
| 67 | +├── vectorstore/ # Vector stores and file management |
| 68 | +│ └── file/ # Vector store file operations |
| 69 | +├── files/ # File upload/management |
| 70 | +├── models/ # Model listing and management |
| 71 | +├── moderations/ # Content moderation |
| 72 | +├── finetuning/ # Model fine-tuning |
| 73 | +├── batch/ # Batch API requests |
| 74 | +├── admin/ # Admin/organization APIs |
| 75 | +├── responses/ # Response generation API |
| 76 | +└── upload/ # Multipart upload handling |
| 77 | +``` |
| 78 | + |
| 79 | +### Streaming Modules Pattern |
| 80 | +Each streaming module follows a consistent structure: |
| 81 | +``` |
| 82 | +streaming/{effect-system}/src/main/scala/sttp/openai/streaming/{effect}/ |
| 83 | +└── package.scala # Extension methods for streaming chat completions |
| 84 | +``` |
| 85 | + |
| 86 | +**Supported Effect Systems:** |
| 87 | +- **fs2**: `Stream[F, ChatChunkResponse]` with cats-effect |
| 88 | +- **zio**: `ZStream[Any, OpenAIException, ChatChunkResponse]` |
| 89 | +- **akka**: `Source[ChatChunkResponse, NotUsed]` (Scala 2.13 only) |
| 90 | +- **pekko**: `Source[ChatChunkResponse, NotUsed]` |
| 91 | +- **ox**: `Flow[ChatChunkResponse]` direct-style (Scala 3 only) |
| 92 | + |
| 93 | +### Build Configuration (`project/`) |
| 94 | +``` |
| 95 | +project/ |
| 96 | +├── Dependencies.scala # Centralized version and dependency management |
| 97 | +├── plugins.sbt # sbt plugins configuration |
| 98 | +└── build.properties # sbt version |
| 99 | +``` |
| 100 | + |
| 101 | +### Navigation Tips |
| 102 | +- **Find API endpoint code**: Look in `core/src/main/scala/sttp/openai/requests/{api-category}/` |
| 103 | +- **Model definitions**: Search for `ChatCompletionModel`, `EmbeddingModel`, etc. in respective request body files |
| 104 | +- **Streaming implementation**: Check `streaming/{effect-system}/src/main/scala/` |
| 105 | +- **Examples**: All runnable examples are in `examples/src/main/scala/examples/` |
| 106 | +- **Tests**: Each module has tests in `{module}/src/test/` following same package structure |
| 107 | + |
| 108 | +## Development Commands |
| 109 | + |
| 110 | +### Build and Test |
| 111 | +```bash |
| 112 | +# Compile the project |
| 113 | +sbt compile |
| 114 | + |
| 115 | +# Run all tests (excluding integration tests) |
| 116 | +sbt test |
| 117 | + |
| 118 | +# Run integration tests (requires OPENAI_API_KEY) |
| 119 | +./run-integration-tests.sh |
| 120 | + |
| 121 | +# Compile documentation |
| 122 | +sbt compileDocumentation |
| 123 | + |
| 124 | +# Format code |
| 125 | +sbt scalafmtAll |
| 126 | +``` |
| 127 | + |
| 128 | +### Cross-platform Building |
| 129 | +The project uses sbt-projectmatrix for cross-building: |
| 130 | +- Scala 2.13.16 and Scala 3.3.6 support |
| 131 | +- Core module supports both versions |
| 132 | +- Streaming modules (fs2, zio, pekko, ox) have specific version requirements |
| 133 | +- Akka module only supports Scala 2.13 |
| 134 | +- Ox module only supports Scala 3 |
| 135 | + |
| 136 | +### Testing Strategy |
| 137 | +- Unit tests for all modules in `*/src/test` |
| 138 | +- Integration tests that hit real OpenAI API (cost-efficient, minimal inputs) |
| 139 | +- Integration tests automatically skip if `OPENAI_API_KEY` not set |
| 140 | +- Use `sbt "testOnly *OpenAIIntegrationSpec"` for integration tests only |
| 141 | + |
| 142 | +## Architecture |
| 143 | + |
| 144 | +### Core Module Structure |
| 145 | +- **OpenAI**: Raw sttp-client4 requests returning `Either[OpenAIException, A]` |
| 146 | +- **OpenAISyncClient**: High-level synchronous client with blocking methods that may throw `OpenAIException` |
| 147 | +- **Streaming Support**: Separate modules for different streaming libraries (fs2, zio, akka/pekko, ox) |
| 148 | + |
| 149 | +### Key Components |
| 150 | +- **Requests Package**: Contains all API endpoint definitions organized by OpenAI API categories |
| 151 | + - `completions.chat` - Chat completions API |
| 152 | + - `audio` - Speech synthesis, transcriptions, translations |
| 153 | + - `images` - Image generation, editing, variations |
| 154 | + - `embeddings` - Text embeddings |
| 155 | + - `files`, `assistants`, `threads` - OpenAI platform features |
| 156 | +- **JSON Handling**: Uses uPickle with SnakePickle for snake_case conversion |
| 157 | +- **Error Handling**: Comprehensive OpenAIException hierarchy for different API errors |
| 158 | + |
| 159 | +### Streaming Architecture |
| 160 | +Each streaming module provides: |
| 161 | +- Extension methods for streaming chat completions |
| 162 | +- Backend-specific implementations (HttpClientFs2Backend, etc.) |
| 163 | +- Stream types: `Stream[F, ChatChunkResponse]` for fs2, `ZStream` for ZIO, etc. |
| 164 | + |
| 165 | +### Client Implementations |
| 166 | +- **Sync Client**: Uses DefaultSyncBackend, blocks on responses |
| 167 | +- **Async Client**: Use OpenAI class with chosen backend (cats-effect, ZIO, etc.) |
| 168 | +- **Custom Backends**: Support for any sttp backend through `.send(backend)` |
| 169 | + |
| 170 | +## Model Management |
| 171 | + |
| 172 | +The project includes automated scripts for updating OpenAI model definitions: |
| 173 | + |
| 174 | +### Model Update Workflow |
| 175 | +1. **Scrape Models**: `scala-cli model_update_scripts/scrape_models.scala` |
| 176 | + - Uses Playwright + Firefox to scrape OpenAI docs |
| 177 | + - Generates `models.json` with current model mappings |
| 178 | +2. **Update Code**: `scala-cli model_update_scripts/update_code_with_new_models.scala --apply` |
| 179 | + - Updates Scala case objects with new models |
| 180 | + - Maintains alphabetical ordering |
| 181 | + - Only adds models (manual removal required) |
| 182 | +3. **Format**: Run `sbt scalafmtAll` after updates |
| 183 | + |
| 184 | +## Code Style |
| 185 | + |
| 186 | +- **Formatting**: Uses Scalafmt with max column 140, Scala 3 dialect |
| 187 | +- **Naming**: Snake case for JSON fields (handled by SnakePickle) |
| 188 | +- **Imports**: SortImports rule applied, RedundantBraces/Parens removed |
| 189 | +- **Case Objects**: Models defined as case objects extending sealed traits |
| 190 | +- **Companion Values**: Some models maintain values sets for easy access |
| 191 | + |
| 192 | +## Dependencies |
| 193 | + |
| 194 | +- **sttp-client4**: HTTP client foundation (v4.0.11) |
| 195 | +- **upickle/ujson**: JSON serialization (v4.3.2) |
| 196 | +- **tapir**: API specification and JSON schema generation (v1.11.44) |
| 197 | +- **scalatest**: Testing framework (v3.2.19) |
| 198 | +- **Effect Libraries**: fs2, ZIO, Akka/Pekko Streams, Ox for streaming |
| 199 | + |
| 200 | +## Examples |
| 201 | + |
| 202 | +The `examples/` module contains runnable examples using scala-cli: |
| 203 | +- Basic chat completion |
| 204 | +- Streaming with different backends |
| 205 | +- OpenAI-compatible APIs (Ollama, Grok) |
| 206 | +- Structured outputs with JSON Schema |
| 207 | +- Function calling |
| 208 | + |
| 209 | +## CI/CD |
| 210 | + |
| 211 | +- **GitHub Actions**: Uses SoftwareMill's shared workflows |
| 212 | +- **Java 21**: Build and test environment |
| 213 | +- **Scala Steward**: Automated dependency updates |
| 214 | +- **Auto-merge**: For dependency PRs from softwaremill-ci |
| 215 | +- **Publishing**: Automatic releases on version tags |
| 216 | + |
| 217 | +## Integration Testing |
| 218 | + |
| 219 | +Integration tests require a real OpenAI API key but are designed to be cost-efficient: |
| 220 | +- Minimal inputs to reduce API costs |
| 221 | +- Automatic skipping when API key unavailable |
| 222 | +- 30-second timeouts |
| 223 | +- Rate limiting handling |
| 224 | +- See `INTEGRATION_TESTING.md` for detailed setup |
0 commit comments