Generators API¶
The generators.py module is Foo’s AI generation layer. It contains provider wrapper classes for
generating text, searching with model-backed tools, handling provider-specific configuration,
extracting response text, and exposing selected AI workflows to the Streamlit application.
This module should remain focused on AI-provider interaction and response handling. It should not contain Streamlit layout code, database persistence logic, document loading logic, HTML scraping logic, or output-file serialization.
🧭 Purpose¶
The Generators API provides a consistent wrapper layer around supported AI providers.
The module supports:
- Provider-specific client initialization.
- Prompt and instruction handling.
- Text generation.
- Web-search-assisted generation.
- Tool configuration.
- Response-format configuration.
- Reasoning or thinking configuration where supported.
- Image generation or image analysis for providers that support those workflows.
- Document summarization.
- File search.
- Translation.
- Transcription.
- Provider response extraction.
- Structured diagnostic logging in handled exception paths.
The module allows the Streamlit UI to call provider wrapper classes without embedding
provider-specific request construction directly in app.py.
🧱 Module Role¶
generators.py sits between Foo’s application layer and external AI providers.
Streamlit UI
|
v
generators.py
|
+--> OpenAI / Chat
+--> xAI Grok
+--> Google Gemini
+--> Anthropic Claude
+--> Mistral
The UI should collect user options and pass them to generator classes. The generator classes should validate the inputs, build provider-specific requests, call the provider, extract results, and return documented values.
🧩 Class Overview¶
The module defines these primary classes:
| Class | Purpose |
|---|---|
Generator |
Base generator class with shared generator state and a placeholder fetch(...) method. |
Grok |
xAI Grok wrapper for response generation and web-search workflows. |
Gemini |
Google Gemini wrapper for generation, thinking configuration, and search workflows. |
Claude |
Anthropic Claude wrapper for text generation and web-search-style workflows. |
Mistral |
Mistral wrapper for generation and schema creation. |
Chat |
OpenAI-oriented wrapper for text, image, document, file-search, web-search, translation, and transcription workflows. |
Each provider wrapper has its own configuration and helper methods because each provider exposes different models, request parameters, tools, reasoning options, and response structures.
⚙️ Base Generator¶
The Generator class provides shared generator state and a common shape for provider wrappers.
It tracks default generation settings such as:
modelinstructionsmessagestextprompttoolstemperaturetop_percentmax_tokensresponse_formatstreamstore
The base class is intentionally minimal. Provider-specific classes are responsible for implementing the real request behavior.
Conceptual usage:
from generators import Generator
generator = Generator()
print(generator.model)
print(generator.temperature)
The base fetch(...) method is a placeholder-style method. Use a provider-specific wrapper such as
Chat, Grok, Gemini, Claude, or Mistral for actual generation workflows.
💬 Chat¶
Chat is the OpenAI-oriented generation wrapper.
It supports a broad set of AI workflows, including:
- Text generation.
- Image generation.
- Image analysis.
- Document summarization.
- Web search.
- File search.
- Translation.
- Transcription.
- Response-format selection.
- Reasoning-effort options.
- Tool construction.
- Provider response extraction.
- Application data export through
get_data()anddump().
Primary methods include:
| Method | Purpose |
|---|---|
normalize_domains(...) |
Normalizes allowed domains for web-search workflows. |
supports_reasoning(...) |
Indicates whether the selected model supports reasoning configuration. |
build_instructions(...) |
Builds provider instructions from prompt and context fields. |
build_text_format(...) |
Builds response-format configuration. |
build_tools(...) |
Builds provider tool definitions. |
extract_output_text(...) |
Extracts text from provider response objects. |
fetch(...) |
Executes the primary generation workflow. |
generate_text(...) |
Generates text from a prompt. |
generate_image(...) |
Generates an image from a prompt. |
analyze_image(...) |
Analyzes image input. |
summarize_document(...) |
Summarizes document content. |
search_web(...) |
Performs a web-search-assisted generation workflow. |
search_files(...) |
Performs a file-search workflow. |
translate(...) |
Translates supplied text. |
transcribe(...) |
Transcribes supplied audio. |
get_format_options(...) |
Returns supported response-format options. |
get_model_options(...) |
Returns supported model options. |
get_effort_options(...) |
Returns supported reasoning-effort options. |
get_data(...) |
Returns current wrapper state as a dictionary. |
dump(...) |
Serializes wrapper state. |
Use Chat when the workflow targets OpenAI-compatible generation features.
🧪 Chat Example: Generate Text¶
from generators import Chat
chat = Chat()
result = chat.generate_text(
prompt="Summarize the purpose of Foo in one paragraph."
)
print(result)
Use this pattern for simple text generation where no image, file-search, transcription, or web-search workflow is required.
🧪 Chat Example: Search the Web¶
from generators import Chat
chat = Chat()
result = chat.search_web(
prompt="Find current documentation guidance for MkDocs and mkdocstrings."
)
print(result)
Use web-search workflows when the prompt depends on current information or external source discovery.
🧪 Chat Example: Summarize a Document¶
from generators import Chat
chat = Chat()
summary = chat.summarize_document(
prompt="Summarize this document for a technical maintainer."
)
print(summary)
Use document summarization when loaded document text or file-search context is already available to the workflow.
🐦 Grok¶
Grok is the xAI Grok provider wrapper.
It supports provider-specific behavior for:
- Domain normalization.
- Reasoning-effort detection.
- Reasoning-object detection.
- Reasoning-model detection.
- Instruction construction.
- Tool construction.
- Response-format construction.
- Response creation.
- Text extraction.
- Text generation.
- Web search.
Primary methods include:
| Method | Purpose |
|---|---|
normalize_domains(...) |
Normalizes web-search domain restrictions. |
supports_reasoning_effort(...) |
Indicates whether the selected model supports reasoning effort. |
supports_reasoning_object(...) |
Indicates whether the selected model supports a reasoning object. |
is_reasoning_model(...) |
Indicates whether the selected model is a reasoning model. |
build_instructions(...) |
Builds instructions for the Grok request. |
build_tools(...) |
Builds Grok-compatible tool definitions. |
build_response_format(...) |
Builds response-format configuration. |
extract_output_text(...) |
Extracts output text from Grok response structures. |
create_response(...) |
Creates a provider response using the configured request payload. |
fetch(...) |
Executes the primary generation workflow. |
generate_text(...) |
Generates text. |
search_web(...) |
Executes web-search-assisted generation. |
Use Grok when the workflow targets xAI models or Grok-backed search/generation features.
🧪 Grok Example¶
from generators import Grok
grok = Grok()
result = grok.generate_text(
prompt="Explain the role of Foo's fetcher layer."
)
print(result)
Use the API reference below for exact argument signatures and supported configuration fields.
💎 Gemini¶
Gemini is the Google Gemini provider wrapper.
It supports provider-specific behavior for:
- Domain normalization.
- Stop-sequence normalization.
- Thinking-level support checks.
- Thinking-budget support checks.
- System-instruction construction.
- Thinking-configuration construction.
- Tool construction.
- Request-configuration construction.
- Text extraction.
- Text generation.
- Web-search-assisted generation.
Primary methods include:
| Method | Purpose |
|---|---|
normalize_domains(...) |
Normalizes domain restrictions. |
normalize_stop_sequences(...) |
Normalizes stop-sequence input. |
supports_thinking_level(...) |
Indicates whether the model supports thinking-level configuration. |
supports_thinking_budget(...) |
Indicates whether the model supports thinking-budget configuration. |
build_system_instruction(...) |
Builds Gemini system instruction content. |
build_thinking_config(...) |
Builds thinking configuration where supported. |
build_tools(...) |
Builds Gemini-compatible tool configuration. |
build_config(...) |
Builds the provider request configuration. |
extract_text(...) |
Extracts response text from Gemini response objects. |
fetch(...) |
Executes the primary generation workflow. |
generate_text(...) |
Generates text. |
search_web(...) |
Executes web-search-assisted generation. |
Use Gemini when the workflow targets Google Gemini generation models or Gemini-backed
search/generation behavior.
🧪 Gemini Example¶
from generators import Gemini
gemini = Gemini()
result = gemini.generate_text(
prompt="Describe the difference between loaders and fetchers in Foo."
)
print(result)
Use model-specific configuration methods when the selected Gemini model supports thinking or tool behavior.
🧠 Claude¶
Claude is the Anthropic Claude provider wrapper.
It supports provider-specific behavior for:
- Domain normalization.
- Thinking support checks.
- Provider response text extraction.
- Text generation.
- Web-search-style generation.
Primary methods include:
| Method | Purpose |
|---|---|
_normalize_domains(...) |
Normalizes allowed domains for search-style workflows. |
_supports_thinking(...) |
Indicates whether the selected model supports thinking configuration. |
_extract_text(...) |
Extracts text from Claude response structures. |
fetch(...) |
Executes the primary generation workflow. |
generate_text(...) |
Generates text. |
search_web(...) |
Executes web-search-assisted or search-style generation. |
Methods beginning with an underscore are internal helpers. They are documented because they exist in
the source and may appear in the generated API reference, but application workflows should normally
call fetch(...), generate_text(...), or search_web(...).
🧪 Claude Example¶
from generators import Claude
claude = Claude()
result = claude.generate_text(
prompt="Write a short explanation of Foo's data-management layer."
)
print(result)
Use the API reference for exact supported fields and provider-specific behavior.
🌊 Mistral¶
Mistral is the Mistral provider wrapper.
It supports:
- Provider response text extraction.
- Primary fetch/generation behavior.
- Schema creation.
Primary methods include:
| Method | Purpose |
|---|---|
_extract_text(...) |
Extracts text from Mistral response objects. |
fetch(...) |
Executes the primary Mistral workflow. |
create_schema(...) |
Creates a schema definition for tool-style use. |
Use Mistral when the workflow targets a Mistral-backed text-generation or schema-oriented
operation.
🧪 Mistral Example¶
from generators import Mistral
mistral = Mistral()
result = mistral.fetch(
prompt="Summarize the Foo architecture."
)
print(result)
Use the exact method signatures from the generated API reference.
🧰 Tool Construction¶
Several generator wrappers build tool definitions for provider requests.
Tool construction can include:
- Web-search tools.
- File-search tools.
- Response-format tools.
- Provider-native function or tool objects.
- Domain restrictions.
- Search context size.
- Parallel tool settings.
- Tool-choice settings.
Tool behavior differs by provider. For that reason, each provider wrapper owns its own
build_tools(...) or equivalent helper.
General pattern:
Keep tool construction inside provider wrappers. Do not duplicate provider-specific tool payloads in
app.py.
🧾 Response Extraction¶
Each provider returns a different response shape.
The generator layer includes extraction helpers such as:
extract_output_text(...)extract_text(...)_extract_text(...)
These methods isolate provider-specific parsing logic so the rest of the application can work with returned strings instead of provider response objects.
Conceptual pattern:
If a provider changes its response format, update the extraction helper instead of changing the Streamlit UI.
⚙️ Reasoning and Thinking Configuration¶
Several providers expose reasoning or thinking configuration, but the feature is not uniform across providers.
Foo keeps provider-specific checks in the provider classes:
| Provider Class | Capability Checks |
|---|---|
Chat |
supports_reasoning(...) |
Grok |
supports_reasoning_effort(...), supports_reasoning_object(...), is_reasoning_model(...) |
Gemini |
supports_thinking_level(...), supports_thinking_budget(...) |
Claude |
_supports_thinking(...) |
This avoids applying a provider option to a model that does not support it.
🔎 Search-Assisted Generation¶
Several generator classes include search_web(...).
Search-assisted generation should be used when the response depends on external information, source discovery, or current web content.
Typical search-assisted workflow:
Prompt
|
v
Normalize domains / search options
|
v
Build provider tools
|
v
Call provider
|
v
Extract text
|
v
Return response string
Use allowed-domain options when a workflow should be constrained to specific sources.
🧪 Output and State Inspection¶
Chat includes methods for inspecting or serializing current wrapper state:
| Method | Purpose |
|---|---|
get_format_options(...) |
Returns response-format options. |
get_model_options(...) |
Returns model options. |
get_effort_options(...) |
Returns reasoning-effort options. |
get_data(...) |
Returns current wrapper data as a dictionary. |
dump(...) |
Serializes wrapper data. |
These methods are useful for Streamlit controls, diagnostics, and configuration review.
🔐 Error Handling¶
Generator classes use Foo’s structured error logging pattern where handled exception paths exist.
The preferred pattern is:
except Exception as e:
exception = Error(e)
exception.module = "generators"
exception.cause = "Chat"
exception.method = "generate_text( self, prompt: str ) -> str"
Logger().write(exception)
raise exception
Error metadata should be stable and reviewer-safe.
Do not include:
- API keys.
- Tokens.
- Full prompts when they may contain user data.
- Full documents.
- Full provider responses.
- Raw image data.
- Audio content.
- File contents.
- Credentials.
- Sensitive request payloads.
The logger should help identify the failing module, class, and method without capturing sensitive content.
🛡️ Provider Configuration Guidance¶
When adding or modifying provider wrappers:
- Keep API keys in
config.pyor environment-backed configuration. - Do not hard-code credentials.
- Validate required prompt or input values before calling the provider.
- Keep provider-specific payload construction inside the provider class.
- Keep response parsing inside extraction helpers.
- Preserve existing return behavior.
- Preserve existing fallback behavior.
- Use stable error metadata.
- Avoid logging prompts, documents, files, tokens, or raw provider responses.
- Document meaningful return values.
- Keep UI rendering out of
generators.py.
🧪 Testing Generators¶
When testing generator classes, verify:
- Missing prompts are rejected or handled as documented.
- Provider clients initialize only when required configuration exists.
- Tool payloads are built correctly for the selected provider.
- Reasoning or thinking options are only applied to supported models.
- Response extraction handles normal provider responses.
- Response extraction handles empty or unexpected provider responses.
- Search workflows honor domain restrictions when supported.
- Return values match the documented type.
- Existing exception handlers log before re-raising.
- Error metadata does not include sensitive content.
- The Streamlit UI can display returned values without type errors.
Provider tests may require credentials. Keep tests that require live providers separate from tests that validate local helper behavior.
🧩 Relationship to Streamlit UI¶
app.py should call generator classes as service wrappers.
The UI should handle:
- Mode selection.
- Prompt input.
- Model selection.
- Temperature and token settings.
- Tool-selection controls.
- Response display.
- Error display.
- Passing output to writers or persistence workflows.
The generator classes should handle:
- Provider configuration.
- Provider request building.
- Provider calls.
- Provider response extraction.
- Provider-specific validation.
- Provider-specific tool construction.
This separation prevents provider logic from spreading across the UI code.
🗄️ Relationship to Persistence¶
Generator outputs may be persisted through data.py.
Good SQLite candidates include:
- Prompt metadata.
- Model name.
- Provider name.
- Workflow mode.
- Generation timestamp.
- Response summary.
- Tool configuration metadata.
- Source references.
- Usage metadata when available.
Good Chroma candidates include:
- Generated summaries.
- Generated knowledge-base entries.
- Generated explanations.
- Text output intended for semantic retrieval.
Do not store secrets, credentials, or sensitive user content unless the workflow explicitly requires secure persistence.
🧾 Relationship to Writers¶
Generator outputs can be exported through writers.py.
Good export candidates include:
- Markdown summaries.
- Research notes.
- Generated documentation drafts.
- Extracted explanations.
- Search-assisted responses.
- Translation output.
- Transcription output.
- Document summaries.
Generator classes should return content. Writer classes should serialize it.
📖 API Documentation¶
The generated API reference for this module is rendered below.