- Repo: dvcrn/ex_openai
lib/ex_openai/generatedis committed and is the runtime SDK surface.- Do not hand-edit generated files unless the task is explicitly about generated output inspection. Normal changes should go into the generators under
lib/ex_openai/codegen, then regenerate sources. - After changing codegen or
lib/ex_openai/docs/docs.yaml, run:mise exec -- mix generate_openai_sourcesmise exec -- mix compile --warnings-as-errorsmise exec -- mix test
- Run
mise exec -- mix formaton the whole repo, not on a single file subset. Formatting is expected to cover all files.
docs/codegen.mdfor the overall codegen architecture and regeneration flow.docs/parsingv2.mdfor howdocs.yamlis parsed intoSchemaandPathstructs and then converted into typespecs.docs/streaming.mdfor streaming semantics, callback shapes, andStreamingClientbehavior.docs/configuration.mdfor runtime configuration and HTTP client options.docs/examples.mdfor user-facing usage examples.- Before relying on a doc example, verify it against the current generated API and tests.
- If behavior changes, update the matching doc in
docs/and any mirrored example inREADME.md.
- For authoritative validation, prefer a clean build:
mise exec -- mix cleanmise exec -- mix compile --warnings-as-errorsmise exec -- mix dialyzer --no-compile --format dialyzer
- Warm recompiles can emit module redefinition warnings for generated modules. Treat the clean build as the source of truth.
mix dialyzeris expected to pass from a clean build.- If you create scratch Dialyzer probes, keep them outside normal compilation flow. Manually compiled probes can pollute
_buildand create misleading warnings. - When Dialyzer noise appears across many generated endpoint modules, check shared generator/runtime contracts first, especially
ExOpenAI.Codegen.DocsParser.Schema.t/0.
stream: trueAPI calls return{:ok, reference()}, not a PID.- Chat streaming callbacks receive
%ExOpenAI.Components.CreateChatCompletionStreamResponse{}chunks. - Legacy
/completionsstreaming uses%ExOpenAI.Components.CreateCompletionResponse{}chunks. - Stream callback examples must handle partial deltas safely. Do not assume
choice.delta.contentalways exists; useMap.get(choice.delta, :content, "").
- Stream and union response conversion relies on discriminator metadata normalized in
ExOpenAI.Codegen.DocsParser.Schema. - If you change discriminator parsing, keep the runtime
%Schema{}shape compatible withExOpenAI.Codegen.ResponseConverter. - Prefer testing unions and streaming conversion using real examples from
lib/ex_openai/docs/docs.yaml, not synthetic schemas.
- When adding generator tests, prefer real excerpts and shapes from
lib/ex_openai/docs/docs.yaml. - If a test uses a synthetic schema, document why the real spec does not currently contain that exact shape.
- Large keyword option specs are valid, but in practice Dialyzer only gets strong value from the positional arguments and broad return shape.
- If stronger static typing is needed, prefer API shape changes such as separate streaming functions over making keyword-list specs more complex.