# LLM API

Use the existing host-created SDK and wait for `ready()` to obtain the runtime
Launch Ticket. The game never receives the provider API key. Runtime defaults to
`gemini-3.8-flash` and uses the official OpenAI Go library for provider calls.

## Single request

```ts
await sdk.ready();
const response = await sdk.llm().complete({
  messages: [{ role: 'user', content: 'Write a short NPC greeting.' }],
  max_tokens: 256,
});
console.log(response.choices[0]?.message.content);
console.log(response.usage.total_tokens);
```

## Streaming

```ts
const controller = new AbortController();
for await (const chunk of sdk.llm().stream({
  messages: [{ role: 'user', content: 'Tell a short story.' }],
}, { signal: controller.signal })) {
  const text = chunk.choices[0]?.delta.content;
  if (text) appendText(text);
  if (chunk.usage) console.log(chunk.usage.total_tokens);
}
// controller.abort() cancels the client request. Breaking the loop also releases
// the reader. Runtime can finish collecting usage in the background.
```

The iterator rejects on provider errors, accounting failures, aborts and an
incomplete stream. Receiving some text or a finish_reason is not confirmation
that the whole request succeeded; wait for iteration to complete.

## Multimodal input

```ts
const response = await sdk.llm().complete({
  messages: [{ role: 'user', content: [
    { type: 'text', text: 'Describe what you see and hear.' },
    { type: 'image_url', image_url: { url: imageHttpsUrl } },
    { type: 'input_audio', input_audio: { data: wavBase64, format: 'wav' } },
  ] }],
});
```

Images can use HTTPS URLs or image data URIs. Audio uses base64 WAV/MP3.
The selected upstream model must support the provided modalities. Total request
size is limited to 8 MiB; use image URLs for large images. Supported message
roles are `system`, `developer`, `user`, `assistant`. Tools and video-specific
parts are not exposed in this API.

## User usage

```ts
const usage = await sdk.llm().usage();
// prompt_tokens, completion_tokens, total_tokens, requests, unresolved_requests
```

Totals cover the authenticated user's games. Unknown usage after upstream
interruption is reflected in `unresolved_requests`, not recorded as zero.
Model selection is optional and limited by the runtime's server-side allowlist.
The default output limit is 2048 tokens, maximum 8192. Per-user limits are 30
requests/minute and 4 concurrent requests; exceeding them returns HTTP 429.

Exports (`GameLLM`, `LLMRequest`, `LLMMessage`, `LLMContentPart`, `LLMCompletion`,
`LLMChunk`, `LLMUsage`, `LLMUsageSummary`) are available from the package root,
`/v1`, `/browser` and `/v1/browser`. Custom control transports must implement
optional `stream()` to support streaming; the built-in `HttpControlTransport`
already implements authenticated fetch streaming.
