# Package com.codename1.ai

package com.codename1.ai

Codename One's AI / LLM client surface plus the value types, streaming primitives, and chat-binding helpers that sit on top of it.

`com.codename1.ai.LlmClient` provides a provider-agnostic chat / embeddings / image-generation API. Four static factories pick the backend; the rest of the surface is shared across all of them:

    LlmClient gpt    = LlmClient.openai(SecureStorage.getInstance().get("openai_key"));
    LlmClient claude = LlmClient.anthropic(key);
    LlmClient gemini = LlmClient.gemini(key);
    LlmClient ollama = LlmClient.ollama();                   // localhost:11434
    LlmClient local  = LlmClient.localOpenAiCompatible(
                           "http://10.0.0.5:8080/v1", "", "qwen2.5-7b");

All calls return `AsyncResource` so they compose naturally with the rest of the framework. Streaming chat fires per-token deltas via a `StreamingListener` and completes the returned resource with the aggregated `ChatResponse` once the stream closes; cancelling the resource kills the underlying socket.

##### Error handling

Every failure surfaces as a single `LlmException` whose `LlmException.getType()` returns one of the `LlmException.ErrorType` enum values (`AUTH`, `RATE_LIMIT`, `INVALID_REQUEST`, `CONTEXT_LENGTH`, `MODEL_OVERLOADED`, `SERVER`, `NETWORK`, `UNKNOWN`). The recommended idiom is one `catch` + `switch`:

    try {
        ChatResponse r = client.chat(req).get();
        // ...
    } catch (AsyncExecutionException ae) {
        if (ae.getCause() instanceof LlmException) {
            LlmException e = (LlmException) ae.getCause();
            switch (e.getType()) {
                case RATE_LIMIT:        scheduleRetry(e.getRetryAfterSeconds()); break;
                case AUTH:              showLoginScreen(); break;
                case CONTEXT_LENGTH:    trimHistory();    break;
                default:                showError(e);
            }
        }
    }

##### Tools / function calling

Construct a `Tool` with an optional `ToolHandler` and pass it via `ChatRequest.Builder.tools`; when the model emits a `ToolCall` the caller invokes `ToolCall.execute(java.util.List)` to dispatch to the matching handler and feed the JSON result back as a `ToolResultPart` on the next turn.

##### ChatView integration

`com.codename1.components.ChatView` is a backend-agnostic messaging UI. Use `LlmChatBinding.bind(ChatView, LlmClient, ChatRequest)` to wire it to an `LlmClient` in one call; for peer-to-peer chats (e.g. a WhatsApp clone) attach an `ActionListener` directly to the view's `setOnSend(...)` and stream peer responses through `view.addMessage(ChatMessage.assistant(text))`.

##### Image generation

`ImageGenerator.openai(key)` returns DALL-E results as a `com.codename1.ui.Image`. `ImageGenerator.onDevice()` resolves against the optional `cn1-ai-stablediffusion` cn1lib when present; absent that cn1lib's native bridge it completes with an `LlmException`.

- Related Packages
  Package
  Description
  com.codename1.ai.inference
  Reusable on-device inference sessions for `.tflite` models.
  com.codename1.ai.language
  Vendor-neutral on-device language identification, translation, and smart reply.
  com.codename1.ai.vision
  Vendor-neutral on-device vision APIs for still images and live camera frames: barcodes and QR codes, OCR, faces, image labels, body pose, person segmentation, and document correction.
- Class
  Description
  ChatMessage
  A single turn in a chat conversation.
  ChatRequest
  The full request to `LlmClient.chat(ChatRequest)` / `LlmClient.chatStream(ChatRequest, StreamingListener)`.
  ChatRequest.Builder
  Mutable fluent builder for `ChatRequest`.
  ChatResponse
  The terminal response from a chat call.
  ConversationStore
  JSON-backed persistent conversation history.
  Embedding
  One vector returned by an embedding provider.
  EmbeddingRequest
  Request payload for `LlmClient.embed(EmbeddingRequest)`.
  EmbeddingRequest.Builder
  Mutable builder for an immutable `EmbeddingRequest`.
  EmbeddingResponse
  Immutable provider response containing embeddings, token accounting, and the model name reported by the service.
  GenerateImageRequest
  Request payload for `ImageGenerator.generate(GenerateImageRequest)`.
  ImageGenerator
  Cloud-first image generation.
  ImagePart
  Image content within a multimodal `ChatMessage`.
  LlmChatBinding
  Convenience wiring that turns a `ChatView` into an LLM-driven chat surface in one call.
  LlmClient
  Provider-agnostic chat / embeddings client.
  LlmException
  The single checked-error type raised by `LlmClient`.
  LlmException.ErrorType
  Coarse-grained classification of every failure path the client can surface.
  MessagePart
  A single content fragment within a `ChatMessage`.
  PromptTemplate
  Trivial `{placeholder}` substitution.
  ResponseFormat
  Constrains the model's output format.
  RetryPolicy
  Decides whether and how long to wait before retrying a failed `LlmClient` call.
  Role
  Author of a `ChatMessage`.
  SafetyFilter
  Pre-flight gate that inspects messages before they're sent to the model.
  StreamingListener
  Callback for `LlmClient.chatStream(ChatRequest, StreamingListener)`.
  StreamingListener.Adapter
  No-op default implementation.
  TextPart
  A plain-text fragment of a `ChatMessage`.
  Tokenizer
  Rough best-effort token counting.
  Tool
  A function the model can call.
  ToolCall
  A tool/function invocation produced by the model.
  ToolChoice
  Controls how aggressively the model will call tools.
  ToolHandler
  Executor backing a `Tool`.
  ToolResultPart
  The result of a tool invocation, sent back to the model so it can continue reasoning.
  Usage
  Token accounting returned by the provider.