Skip to content

Commit c119f6e

Browse files
committed
First pass at teaching Chat() to speak litellm
1 parent 693b78f commit c119f6e

File tree

5 files changed

+92
-0
lines changed

5 files changed

+92
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type": "app",
3+
"id": "chat-ai-litellm",
4+
"title": "Chat AI using LiteLLM"
5+
}

Diff for: shiny/templates/chat/hello-providers/litellm/app.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# ------------------------------------------------------------------------------------
2+
# A basic Shiny Chat example powered by OpenAI's GPT-4o model using the `litellm` library.
3+
# To run it, you'll need OpenAI API key.
4+
# To get setup, follow the instructions at https://platform.openai.com/docs/quickstart
5+
# ------------------------------------------------------------------------------------
6+
import litellm
7+
from app_utils import load_dotenv
8+
9+
from shiny.express import ui
10+
11+
# Load a .env file (if it exists) to get the OpenAI API key
12+
load_dotenv()
13+
14+
chat = ui.Chat(id="chat")
15+
chat.ui()
16+
17+
18+
@chat.on_user_submit
19+
async def _():
20+
messages = chat.messages()
21+
response = await litellm.acompletion(model="gpt-4o", messages=messages, stream=True)
22+
await chat.append_message_stream(response)
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import os
2+
from pathlib import Path
3+
from typing import Any
4+
5+
app_dir = Path(__file__).parent
6+
env_file = app_dir / ".env"
7+
8+
9+
def load_dotenv(dotenv_path: os.PathLike[str] = env_file, **kwargs: Any) -> None:
10+
"""
11+
A convenience wrapper around `dotenv.load_dotenv` that warns if `dotenv` is not installed.
12+
It also returns `None` to make it easier to ignore the return value.
13+
"""
14+
try:
15+
import dotenv
16+
17+
dotenv.load_dotenv(dotenv_path=dotenv_path, **kwargs)
18+
except ImportError:
19+
import warnings
20+
21+
warnings.warn(
22+
"Could not import `dotenv`. If you want to use `.env` files to "
23+
"load environment variables, please install it using "
24+
"`pip install python-dotenv`.",
25+
stacklevel=2,
26+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
shiny
2+
python-dotenv
3+
tokenizers
4+
openai
5+
litellm

Diff for: shiny/ui/_chat_normalize.py

+34
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ class GenerateContentResponse:
1818
text: str
1919

2020
from langchain_core.messages import BaseMessage, BaseMessageChunk
21+
from litellm.types.utils import ( # pyright: ignore[reportMissingTypeStubs]
22+
ModelResponse,
23+
)
2124
from openai.types.chat import ChatCompletion, ChatCompletionChunk
2225

2326

@@ -137,6 +140,36 @@ def can_normalize_chunk(self, chunk: Any) -> bool:
137140
return False
138141

139142

143+
class LiteLlmNormalizer(OpenAINormalizer):
144+
def normalize(self, message: Any) -> ChatMessage:
145+
x = cast("ModelResponse", message)
146+
return super().normalize(x)
147+
148+
def normalize_chunk(self, chunk: Any) -> ChatMessage:
149+
x = cast("ModelResponse", chunk)
150+
return super().normalize_chunk(x)
151+
152+
def can_normalize(self, message: Any) -> bool:
153+
try:
154+
from litellm.types.utils import ( # pyright: ignore[reportMissingTypeStubs]
155+
ModelResponse,
156+
)
157+
158+
return isinstance(message, ModelResponse)
159+
except Exception:
160+
return False
161+
162+
def can_normalize_chunk(self, chunk: Any) -> bool:
163+
try:
164+
from litellm.types.utils import ( # pyright: ignore[reportMissingTypeStubs]
165+
ModelResponse,
166+
)
167+
168+
return isinstance(chunk, ModelResponse)
169+
except Exception:
170+
return False
171+
172+
140173
class AnthropicNormalizer(BaseMessageNormalizer):
141174
def normalize(self, message: Any) -> ChatMessage:
142175
x = cast("AnthropicMessage", message)
@@ -248,6 +281,7 @@ def __init__(self) -> None:
248281
"anthropic": AnthropicNormalizer(),
249282
"google": GoogleNormalizer(),
250283
"langchain": LangChainNormalizer(),
284+
"litellm": LiteLlmNormalizer(),
251285
"ollama": OllamaNormalizer(),
252286
"dict": DictNormalizer(),
253287
"string": StringNormalizer(),

0 commit comments

Comments
 (0)