Multimodal orchestration for LLM analysis
Project description
Pollux
Multimodal orchestration for LLM APIs.
You describe what to analyze. Pollux handles source patterns, context caching, deferred delivery, and multimodal content.
Documentation · Getting Started · Building With Deferred Delivery
Quick Start
import asyncio
from pollux import Config, Source, run
result = asyncio.run(
run(
"What are the key findings and their implications?",
source=Source.from_file("earnings-report.pdf"),
config=Config(provider="gemini", model="gemini-2.5-flash-lite"),
)
)
print(result.text)
# Revenue grew 18% YoY to $4.2B, driven by cloud services. Operating
# margins improved from 29% to 34%. Management's $2B buyback and raised
# guidance signal confidence in sustained growth.
run() returns an Output: result.text is the answer, with result.structured,
result.usage, and other facets alongside it.
To use OpenAI instead: Config(provider="openai", model="gpt-5-nano").
For Anthropic: Config(provider="anthropic", model="claude-haiku-4-5").
For OpenRouter: Config(provider="openrouter", model="google/gemma-3-27b-it:free").
For a self-hosted OpenAI-compatible server (text, image, and audio):
Config(provider="local", model="gemma3:4b", base_url="http://localhost:11434/v1").
Single-model servers can omit model.
For a full walkthrough (install, key setup, first result), see Getting Started.
Which Entry Point Should I Use?
| If you want to... | Use |
|---|---|
| Ask one prompt and get an answer now | run() |
| Ask many prompts against shared source(s) | run_many() |
| Hold a multi-turn thread or run a tool-using agent loop | interact() / Session |
| Submit non-urgent work and collect it later | defer() |
Pollux keeps realtime and deferred work on separate entry points. If the result
can wait, submit it once, persist the handle, and collect the same
ResultEnvelope later.
What Pollux Handles
Say you have a document and ten questions about it. Without orchestration, each API call re-uploads the file, and your code has to manage caching, retries, and concurrency. Pollux uploads once, caches the content when the provider supports it, fans out your prompts concurrently, and hands back results.
The same Source interface handles PDFs, images, video, YouTube URLs, and
arXiv papers. Your code does not need per-format upload branches.
Gemini-specific video clipping and FPS controls are available via
Source.with_gemini_video_settings(...); see the sending-content docs for the
intended scope.
Need structured output? Pass a Pydantic model as output and get a
validated instance alongside the raw text. Switching providers is a config
change: provider="gemini" to provider="openai".
One Upload, Many Prompts
Got three questions about the same paper? run_many() fans them out concurrently:
import asyncio
from pollux import Config, Source, run_many
envelope = asyncio.run(
run_many(
["Summarize the methodology.", "List key findings.", "Identify limitations."],
sources=[Source.from_file("paper.pdf")],
config=Config(provider="gemini", model="gemini-2.5-flash-lite"),
)
)
for answer in envelope.answers:
print(answer)
run_many() returns an OutputCollection: answers is the per-prompt text in
input order, with outputs, structured, usage, and status alongside it.
Add more sources when each prompt should see the same shared context. For
per-file collection work, wrap run_many() in your own outer loop over files;
that gives you one result record per file while Pollux handles each file's
prompt set.
Multi-Turn Threads and Agent Loops
When you need conversation history or tool calls, use interact() over an
Environment and Input. A Session reuses one provider across turns:
import asyncio
from pollux import Config, Environment, Input, Session
async def main():
env = Environment(instructions="Be concise.")
async with Session(Config(provider="anthropic", model="claude-haiku-4-5")) as session:
first = await session.interact(env, Input("Name a primary color."))
print(first.text)
# Continue the same thread from the prior turn's continuation:
second = await session.interact(
env, Input("Now name its complement.", continuation=first.continuation)
)
print(second.text)
asyncio.run(main())
Output.tool_calls exposes any tools the model wants to run; return their
results on the next Input to drive an agent loop. For tool declarations,
dispatch, and streaming, see
Building an Agent Loop.
When the Work Can Wait
Deferred delivery is for long fan-out work, backfills, and scheduled analysis where no one is waiting on the answer in the current process.
import asyncio
from pollux import (
Config,
Source,
collect_deferred,
defer,
inspect_deferred,
)
config = Config(provider="openai", model="gpt-5-nano")
handle = asyncio.run(
defer(
"Summarize the report in five bullets.",
source=Source.from_file("market-report.pdf"),
config=config,
)
)
snapshot = asyncio.run(inspect_deferred(handle))
if snapshot.is_terminal:
result = asyncio.run(collect_deferred(handle))
print(result.answers[0])
In production code, persist handle.to_dict() and restore it later with
DeferredHandle.from_dict(...). For the full lifecycle, read
Submitting Work for Later Collection
and
Building With Deferred Delivery.
Where Pollux Ends
Pollux owns content delivery, context caching, and provider translation. Prompt design, workflow orchestration, and what you do with results are yours. See Core Concepts for the full boundary model.
Installation
pip install pollux-ai
Set your provider's API key:
export GEMINI_API_KEY="your-key-here" # or
export OPENAI_API_KEY="your-key-here" # or
export ANTHROPIC_API_KEY="your-key-here" # or
export OPENROUTER_API_KEY="your-key-here"
Keys from: Google AI Studio · OpenAI · Anthropic · OpenRouter
For provider="local", no API key is required; point base_url (or
POLLUX_LOCAL_BASE_URL) at a self-hosted OpenAI-compatible server.
Documentation
- Getting Started: first result in 2 minutes
- Core Concepts: mental model and vocabulary
- Building an Agent Loop: multi-turn threads, tool calls, and streaming
- Submitting Work for Later Collection: deferred lifecycle API
- Migrating to 2.0: moving from the v1 API
- Building With Deferred Delivery: when deferred is worth it
- API Reference: entry points and types
- Cookbook: runnable end-to-end recipes
Full docs at polluxlib.dev.
Contributing
See CONTRIBUTING and TESTING.md for guidelines.
Built during Google Summer of Code 2025 with Google DeepMind. Learn more
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pollux_ai-2.0.0rc1.tar.gz.
File metadata
- Download URL: pollux_ai-2.0.0rc1.tar.gz
- Upload date:
- Size: 815.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
07c70d2940421289b4c45febf5108b1f738dfeb7b035d712a93938e9ac6cfc98
|
|
| MD5 |
12cd22f38f63bdb5074318e25c9c49ec
|
|
| BLAKE2b-256 |
a2628d42828726a44ba4a8fa552762e8687a86d467e64107888e1b5ee9e95d61
|
Provenance
The following attestation bundles were made for pollux_ai-2.0.0rc1.tar.gz:
Publisher:
release.yml on seanbrar/pollux
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pollux_ai-2.0.0rc1.tar.gz -
Subject digest:
07c70d2940421289b4c45febf5108b1f738dfeb7b035d712a93938e9ac6cfc98 - Sigstore transparency entry: 1849238349
- Sigstore integration time:
-
Permalink:
seanbrar/pollux@804469bab73ea300accf4826983f2344ceb8df12 -
Branch / Tag:
refs/heads/release/2.0.0 - Owner: https://github.com/seanbrar
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@804469bab73ea300accf4826983f2344ceb8df12 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file pollux_ai-2.0.0rc1-py3-none-any.whl.
File metadata
- Download URL: pollux_ai-2.0.0rc1-py3-none-any.whl
- Upload date:
- Size: 125.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8fe8e8702ca98d55e6717a3993ecfaf36bf97f10fe71eebef346cf355ea6ca65
|
|
| MD5 |
b152f4ec193683df547e21744b7ab7a4
|
|
| BLAKE2b-256 |
ab4d093340cd2c4ced48c445181b7e64594136320a6e46c411454de1eeb98a2a
|
Provenance
The following attestation bundles were made for pollux_ai-2.0.0rc1-py3-none-any.whl:
Publisher:
release.yml on seanbrar/pollux
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pollux_ai-2.0.0rc1-py3-none-any.whl -
Subject digest:
8fe8e8702ca98d55e6717a3993ecfaf36bf97f10fe71eebef346cf355ea6ca65 - Sigstore transparency entry: 1849238458
- Sigstore integration time:
-
Permalink:
seanbrar/pollux@804469bab73ea300accf4826983f2344ceb8df12 -
Branch / Tag:
refs/heads/release/2.0.0 - Owner: https://github.com/seanbrar
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@804469bab73ea300accf4826983f2344ceb8df12 -
Trigger Event:
workflow_dispatch
-
Statement type: