Skip to main content

rishi

Rishi gives local and hosted models one Chat API. A conversation is portable Python history, so one backend can continue where another stopped.

Install

Base rishi includes LiteRT and the hosted backends. Add an extra for another local runtime:

pip install rishi              # LiteRT, hosted APIs, Claude Code, and GitHub Copilot
pip install 'rishi[llama]'     # local GGUF models
pip install 'rishi[mlx]'       # Apple Silicon
pip install 'rishi[ollama]'    # Ollama models
pip install 'rishi[all]'       # every available backend

Extras combine, for example rishi[llama,mlx]. Hosted providers need their usual credentials. Backend modules load only when selected.

Chat

Chat(model) creates one conversation. Each call appends to chat.hist. resp_text returns the answer text.

chat = Chat(gemma4_e2b)
print(resp_text(chat('Give one fact about lobsters.')))
print(resp_text(chat('Give one more.')))
chat.close()
Lobsters are crustaceans, which means they have a hard exoskeleton and eight legs.
Lobsters are known for their ability to change their color and texture to blend in with their surroundings, a behavior called camouflage.

Streaming

Pass stream=True to iterate markdown strings rendered by Urai. Rishi normalizes each backend’s events; use stream='raw' to receive those chunk dictionaries instead.

chat = Chat(gemma4_e2b)
for markdown in chat('Write a two-line poem about rain.', stream=True):
    print(markdown, end='', flush=True)
chat.close()
Soft drops tap on the pane,
Washing the world clean again.

Image

Place an image beside the prompt. Path, bytes, and PIL.Image inputs use the same message API.

chat = Chat(gemma4_e2b)
image = repo_root()/'nbs/images.jpeg'
display(Image.open(image))
print(resp_text(chat(['Describe this image in one sentence.', image])))
chat.close()

A medium-sized, reddish-brown German Shepherd is looking attentively off to the side with its mouth slightly open.

Audio

Place an audio file beside the prompt. Use a model with an audio input tower, such as Gemma 4 LiteRT.

chat = Chat(gemma4_e2b)
audio = repo_root()/'nbs/speech.wav'
print(resp_text(chat(['Transcribe this clip.', audio])))
chat.close()
Dancing in the masquerade, idol truth in plain sight jaded, pop, roll, click, dot, who will I be today or not? But such a tide as moving seems asleep, too full for sound and foam, when that drew from out the boundless deep turns again home, twilight and evening bell and after that.

One conversation across seven backends

Every backend stores the same canonical messages in chat.hist. Each leg below receives the previous leg through messages=, adds one turn, and passes the enlarged history on.

The example downloads four local models. The remote, Claude Code, and Copilot legs require their usual credentials.

legs = [
    ('LiteRT', gemma4_e2b, {}),
    ('Ollama', f'ollama/{ollama_qwen}', {'think': True}),
    ('MLX', mlx_qwen, {}),
    ('llama.cpp', llama_qwen, {'n_ctx': 4096}),
    ('cloud', 'gpt-4.1', {}),
    ('Claude', 'claude/haiku', {}),
    ('Copilot', 'copilot/gpt-4.1', {}),
]

history = []
for i, (name, model, options) in enumerate(legs):
    chat = Chat(model, messages=history, **options)
    prompt = (
        'The code word is amber. Start a travel log with one short sentence.'
        if i == 0 else
        f'What is the code word? Add one short sentence saying {name} received this conversation.'
    )
    reply = chat(prompt)
    print(f'{name}: {resp_text(reply)}')
    history = list(chat.hist)
    chat.close()

print([m['role'] for m in history])
LiteRT: Amber awaits.
Ollama: The code word is **amber**. Ollama received this conversation.

Fetching 9 files:   0%|                                                                                                                 | 0/9 [00:00<?, ?it/s]Fetching 9 files: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████| 9/9 [00:00<00:00, 1912.59it/s]

MLX: The code word is **amber**. MLX received this conversation.

llama_context: n_ctx_seq (4096) < n_ctx_train (40960) -- the full capacity of the model will not be utilized

llama.cpp: The code word is **amber**. llama.cpp received this conversation.
cloud: The code word is amber. Cloud received this conversation.
Claude: The code word is amber. Claude received this conversation.
Copilot: The code word is amber. Copilot received this conversation.
['user', 'assistant', 'user', 'assistant', 'user', 'assistant', 'user', 'assistant', 'user', 'assistant', 'user', 'assistant', 'user', 'assistant']

Backend guides

notebook backend-specific topics
00_core.ipynb runtime registration, compatibility names, skill install
01_llama.ipynb GGUF loading, GPU offload, KV cache, mtmd media
02_litert.ipynb .litertlm loading, GPU and NPU, bench()
03_mlx.ipynb MLX text and media models, speculative decoding, caches
04_remote.ipynb hosted providers and server-side tools
06_claude.ipynb Claude Code sessions, transcripts, MCP policy
07_copilot.ipynb authentication, editor headers, model listing
08_ollama.ipynb daemon lifecycle, thinking levels, /api/show

Metadata

Release files for rishi 0.1.43

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rishi 0.1.43
File Size Uploaded Provenance
rishi-0.1.43.tar.gz 78.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for rishi 0.1.43
File Interpreter ABI Platform
rishi-0.1.43-py3-none-any.whl Python 3 none any Details

Total release size: 165.3 kB

Release files / rishi-0.1.43.tar.gz

Download URL rishi-0.1.43.tar.gz
Size 78.1 kB
Tags Source
SHA-256 checksum
How to use checksums
7dac6444c5e766ae938c0648cfaae05f88bfbdbe7cff611905bd994087093145
BLAKE2b-256 checksum
How to use checksums
253c5d1e14a9c650369f6190373c2e96840ac887bdf449321c45d394e0395214
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / rishi-0.1.43-py3-none-any.whl

Download URL rishi-0.1.43-py3-none-any.whl
Size 87.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bd6a0a588479234b232739ecac4f4e7a03d32836d98a9b511ed6afa86a0af8bb
BLAKE2b-256 checksum
How to use checksums
685ddb94ba402ed51af2f186a3b147ba8bdd9fcc1b26b62c71e6990c6b9c9a2c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Security for rishi 0.1.43

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.43 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page