kcode-openai-api 0.1.1

OpenAI transcription, image analysis, and GPT Image generation
Documentation
# kcode-openai-api Agent Integration Reference

`kcode-openai-api` is a standalone asynchronous Rust 2024 library for the
direct OpenAI API features Kennedy uses. It owns OpenAI transport, request
validation, response normalization, and credential lifetime. The integrating
server owns HTTP routes, authentication, authorization, secret retrieval,
application request limits, logging, cancellation, and storage policy.

The Cargo package is `kcode-openai-api`; its Rust crate path is
`kcode_openai_api`. Credential-bearing dependency versions and source-review
conclusions are recorded in `DependencyAudit.md`.

Kennedy's ordinary text generation is intentionally absent. It runs through
the separately authenticated Codex CLI and does not use the OpenAI API key.

## Open a client

```rust,no_run
use kcode_openai_api::{OpenAi, Result};

fn open(api_key: String) -> Result<OpenAi> {
    OpenAi::open(api_key)
}
```

`OpenAi::open` validates and takes ownership of the API key. The trimmed key is
zeroized on final drop, redacted from `Debug`, placed in an HTTP header value
marked sensitive, and sent only as a bearer credential. It is never placed in
a URL, request body, returned value, or error. The client disables environment
proxy discovery, redirects, automatic retries, and referrers, and permits HTTPS
only.

Clones share the key and HTTP connection pool. There is no database path,
persistence mode, file output, credential discovery, or recovery behavior.

## Audio transcription

```rust,no_run
use kcode_openai_api::{AudioInput, OpenAi, Result, TranscriptionRequest};

async fn transcribe(openai: &OpenAi, webm: Vec<u8>) -> Result<String> {
    let audio = AudioInput::new("voice-note.webm", "audio/webm", webm)?;
    let result = openai
        .transcribe(TranscriptionRequest::new(audio))
        .await?;
    Ok(result.text)
}
```

`TranscriptionRequest::new` uses `gpt-4o-transcribe`, JSON output, and the
faithful-transcription prompt already used by Kennedy. Callers may replace or
remove the prompt and may provide a lowercase ISO-639-1 language code.

The recording remains in memory and is uploaded once as multipart form data.
It must be non-empty, at most 25 MiB, have a safe basename, use a documented
FLAC, MP3, MP4, MPEG, MPGA, M4A, OGG, WAV, or WebM extension, and carry a
corresponding supported audio/video MIME type. The normalized result contains
non-empty transcript text, optional typed token-or-duration usage, and the
provider request ID when available.

This method is batch transcription only. Streaming, diarization, timestamps,
speaker reference samples, translations, and arbitrary transcription model
selection are outside the current Kennedy surface.

## Image generation

```rust,no_run
use kcode_openai_api::{
    ImageFormat, ImageGenerationRequest, ImageQuality, ImageSize, OpenAi,
    Result,
};

async fn generate(openai: &OpenAi) -> Result<Vec<u8>> {
    let mut request = ImageGenerationRequest::new(
        "A clean editorial illustration of a radio telescope at dusk",
    );
    request.size = ImageSize::dimensions(1536, 1024)?;
    request.quality = ImageQuality::High;
    request.output_format = ImageFormat::WebP;
    request.output_compression = Some(90);

    let result = openai.generate_image(request).await?;
    Ok(result.image.data)
}
```

`generate_image` always uses the Image API's non-streaming
`POST /v1/images/generations` operation with `gpt-image-2` and requests exactly
one image. It returns decoded bytes in memory, the actual/fallback output
format, optional selected size and quality metadata, optional typed token usage,
creation time, and the provider request ID.

Defaults are automatic size, automatic quality, PNG output, automatic opaque
background selection, standard automatic moderation, and no explicit
compression. JPEG and WebP accept compression from 0 through 100. GPT Image 2
does not support transparent output, so the public background enum cannot
request it.

Explicit dimensions must use 16-pixel increments, keep each edge at or below
3,840 pixels, stay within a 3:1 aspect ratio, and contain 655,360 through
8,294,400 total pixels. The prompt must contain 1 through 32,000 characters.
The optional `user` value is forwarded only to OpenAI's end-user abuse
monitoring field; the integrating server should use a stable, privacy-preserving
identifier rather than personal data.

This first surface does not include image edits, reference images, multiple
outputs, streaming partial images, Responses API conversational image turns,
or arbitrary image-model selection.

## Errors and data handling

Local validation fails before network access. Transport errors are reduced to
timeout or reachability classes. Provider failures retain only the HTTP status,
a control-cleaned provider code and message, and the request ID. The complete
provider error body is not returned. Successful and error response bodies are
bounded to 128 MiB.

No automatic retries are performed because transcription and image generation
are billable operations and a timed-out request may already have completed at
OpenAI. The caller may make a policy-aware retry after considering the error
class and provider request ID.

The crate never writes audio, transcripts, generated images, prompts, usage,
or credentials to disk. Returned byte and text values are ordinary owned Rust
values; their later storage and logging are caller responsibilities.

## Managed-library maintenance

The literal root package version in `Cargo.toml` is canonical. No parallel
version file is required. All maintained files are ordinary UTF-8 text. Keep
`target/`, credentials, recordings, generated images, and other binary output
outside the managed library. The standard kcode check performs fetch,
formatting, build, Clippy with warnings denied, tests, and doc tests.