_common library

Classes

AiBroker
Base broker — every provider implements this. Capabilities (chat, embed, translate, image, tts, …) live on separate interfaces in per-modality folders (lib/src/chat/, lib/src/embed/, lib/src/translate/, …). Concrete provider classes implement only the capability interfaces their service actually supports.
AiBrokerRegistry
Process-wide registry. Wire brokers once at startup, then look them up by AiBroker.id from anywhere in the app.
AiCompletion
The assistant's reply plus what the provider said about it: why it stopped and how many tokens it used. Returned by AiBroker.completeWithMeta and AiBroker.chatWithMeta.
AiMessage
AnthropicBroker
Anthropic Claude (/v1/messages). system is a top-level field, not a role — keep it out of ChatRequest.messages.
AskCommand
aib ask "<question>" — one-shot RAG:
ChainedKeyResolver
Tries each underlying resolver in order, returns the first non-empty hit. Used by the CLI to layer direct flags → .env file → env vars.
ChatBroker
Chat / completion / streaming capability. Implemented by every chat-capable provider in this package (OpenAiBroker, AnthropicBroker, GeminiBroker).
ChatRequest
What every broker call boils down to. system is the persistent instruction; messages is the turn history (oldest first). Both complete* and chat* build the same wire payload — complete* is just chat* with one user message.
Chunker
Splits a source document into TextChunks suitable for embedding.
Client
The interface for HTTP clients that take care of maintaining persistent connections across multiple requests to the same server.
CollectionInfo
Read-only snapshot of a collection's pin + counts.
CollectionsCommand
aib collections — lists collections in the workbench DB. The --exists <name> flag turns it into a script-friendly probe: exit 0 if present, exit 1 if not, no output.
CorpusStore
SQLite-backed store for chunked text + embeddings.
EmbedBroker
Text-embedding capability. Implemented by OpenAiBroker and GeminiBroker; not by AnthropicBroker (Anthropic doesn't host first-party embeddings — pair Anthropic with OpenAI or Gemini for the embed side).
Embedder
Wraps AiBroker.embed with batching so callers can hand it an arbitrary number of inputs without worrying about per-provider per-call ceilings.
EnvKeyResolver
Reads keys from Platform.environment using a per-broker env var name. Defaults follow the SDK conventions each provider documents:
FileKeyResolver
Reads keys from a plain-text file. The format is intentionally loose so users can keep notes alongside their keys:
GeminiBroker
Google Gemini (generateContent / streamGenerateContent). Pagination on listModels caps at 5 pages × 50; only gemini-* ids that support generateContent are kept.
GoogleTranslateBroker
Google Cloud Translation v2 (/language/translate/v2). Uses simple API-key auth — no service-account JSON. Cloud Translation is a separate service from Gemini and uses a different API key issued from the Google Cloud Console with the Cloud Translation API enabled.
Hit
One retrieval result. score is cosine similarity in [-1, 1], higher is better.
HttpDate
Utility functions for working with dates with HTTP specific date formats.
IngestCommand
aib ingest <path>... — reads text files, chunks them, embeds, and writes into a CorpusStore collection.
KeyResolver
Where API keys come from. Flutter apps with secure storage implement this against their own store; CLI / backend code can use the built-in EnvKeyResolver or MapKeyResolver.
LineSplitter
A StreamTransformer that splits a String into individual lines.
LlmTranslator
Wraps any ChatBroker so it can be used wherever a TranslateBroker is expected. The translation request is converted into a system prompt that includes the target language plus every supplied hint (domain, tone, glossary, free-form context).
MapKeyResolver
In-memory resolver — for tests, or for apps that already hold keys in a runtime-built map.
OpenAiBroker
OpenAI provider — implements ChatBroker (/v1/chat/completions) and EmbedBroker (/v1/embeddings). Filters listModels to gpt-* / o<digit>* so the picker doesn't show whisper / embeddings / dall-e.
Platform
Information about the environment in which the current program is running.
Request
An HTTP request where the entire request body is known in advance.
Response
An HTTP response where the entire response body is known in advance.
SearchCommand
aib search <query> — embeds the query with the collection's pinned model, returns cosine top-K snippets. Default output is human- readable; --json produces a single JSON object suitable for piping into Claude (slash-command style).
SentenceWindowChunker
Sentence-aware sliding window. Packs sentences greedily into windows of approximately targetChars characters with overlapChars of trailing context carried forward into the next window.
SseEvent
One parsed Server-Sent Event. OpenAI and Anthropic both use SSE for their streaming endpoints (Gemini uses a JSON-array stream — see the Gemini broker for that codepath).
StreamController<T>
A controller with the stream it controls.
StreamedResponse
An HTTP response where the response body is received asynchronously after the headers have been received.
StreamSubscription<T>
A subscription on events from a Stream.
TextChunk
One chunk of source text. Carries enough metadata to cite back to the original document (source path + ordinal within that document) plus arbitrary meta for higher-level info (page number, heading path, etc.).
TranslateBroker
Translation capability. Implemented natively by GoogleTranslateBroker (Google Cloud Translation v2). Any ChatBroker can also be wrapped in LlmTranslator to act as a TranslateBroker powered by an LLM — useful when context matters and the dedicated translation service isn't available.
TranslateCommand
ai_broker translate <text> — translate via Google Cloud Translation (default) or via any ChatBroker (--broker openai / anthropic / gemini), with optional context hints and a client-side glossary.
TranslationResult
Output of TranslateBroker.translate. translated is always set; detectedFrom is non-null when the caller passed from: null and the provider reported a detected source language; modelUsed is set when the implementation routed through a specific model (LLM translators) and null otherwise.

Enums

AiFinishReason
Why a provider stopped writing, in one vocabulary for every broker.
AiRole
Who authored a message in a chat. system lives on ChatRequest.system, not here — every provider treats system instructions specially (Anthropic puts them at top-level; Gemini uses systemInstruction; OpenAI uses a role:system message). We only model the back-and-forth.

Constants

immutable → const Immutable
Annotation on an immutable class.
retryableStatusCodes → const Set<int>
Status codes that mean "try again later, the request itself is fine": rate limits (429), transient server errors (500, 502, 504) and upstream overload (503, Anthropic's 529). Quota-exceeded (a hard 429 with quota in the body) is not retryable — callers pass isHardFailure to surface that to the user instead of burning attempts.
utf8 → const Utf8Codec
An instance of the default implementation of the Utf8Codec.
visibleForTesting → const Object
Annotation on a public declaration that should only be used in tests.

Functions

addKeyArgs(ArgParser parser) → void
Wires the standard key-source flags into parser. Every command that needs an API key calls this from its constructor:
brokerForId(String id) → AiBroker
Resolves the AiBroker for id. Throws UsageException for unknown ids so the CLI surfaces a clean error.
buildAibRunner({AiBroker brokerFactory(String)?, KeyResolver? keyResolver}) → CommandRunner<int>
Builds the aib / ai_broker CLI. Returns a configured CommandRunner so tests (and bin/ai_broker.dart) can construct + run it without duplicating wiring.
decodeSseStream(Stream<List<int>> source) → Stream<SseEvent>
Decodes a UTF-8 byte stream into SseEvents. Buffers across chunk boundaries (one event may span several Stream<List<int>> chunks), joins multi-line data: payloads with \n per the SSE spec, and filters out keep-alive comments.
defaultChatModelFor(String brokerId) → String
Default chat model id for an LLM-based translator wrapping the given chat broker. Used by TranslateCommand when the user picks --broker openai|anthropic|gemini without overriding --model.
defaultWorkbenchDbPath() → String
Default workbench DB path: ~/.ai_broker/corpus.db. Honors AIB_DB env var override. The directory is created lazily by callers as needed.
jsonDecode(String source, {Object? reviver(Object? key, Object? value)?}) → dynamic
Parses the string and returns the resulting Json object.
jsonEncode(Object? object, {Object? toEncodable(Object? nonEncodable)?}) → String
Converts object to a JSON string.
openSsePost({required Uri uri, required Map<String, String> headers, required String body, required String providerLabel, Client? client}) → Future<Stream<List<int>>>
Opens a POST request and returns the response body as a byte stream. Throws AiBrokerException on non-2xx (the body is buffered in that path so we can include the error message).
resolverFromArgs(ArgResults args) → KeyResolver
Builds a KeyResolver from CLI args using this precedence (first non-empty hit wins):
retryRequest({required Future<Response> send(), required String providerLabel, int maxAttempts = 5, Duration baseDelay = const Duration(seconds: 5), Duration maxRetryAfter = const Duration(seconds: 60), bool isHardFailure(Response)?, Future<void> wait(Duration) = _sleep}) → Future<Response>
HTTP retry with exponential backoff: up to maxAttempts tries, waiting baseDelay × 2ⁿ between them. Shared by every broker so retry policy lives in one place.
stripCodeFence(String text) → String
Strips a markdown code fence from text. Model output for "give me code" prompts usually arrives wrapped in ```lang\n...\n```, even after an explicit "code only" instruction, and often with a sentence of prose before or after the block. Call this on the broker's raw text before parsing or writing it to a file.

Exceptions / Errors

AiBrokerException
Thrown for any broker-layer failure that callers can present to the user — auth, rate-limit-after-retries, empty response, malformed response.
ClientException
An exception caused by an error in a pkg/http client.
HttpException
MissingKeyException
TimeoutException
Thrown when a scheduled timeout happens while waiting for an async result.