-
Notifications
You must be signed in to change notification settings - Fork 0
/
gigachat_streaming.py
130 lines (115 loc) · 4.81 KB
/
gigachat_streaming.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""Пример работы с чатом через gigachain """
import streamlit as st
# Try demo - https://gigachat-streaming.streamlit.app/
from langchain_community.chat_models import GigaChat
from langchain.schema import ChatMessage
st.title("GigaChain Bot")
with st.sidebar:
st.title("GIGACHAT API")
model = st.selectbox(
"GIGACHAT_MODEL",
(
"GigaChat",
"GigaChat-Pro",
"GigaChat-Plus",
),
)
st.title("GIGACHAT API")
base_url = st.selectbox(
"GIGACHAT_BASE_URL",
(
"https://gigachat.devices.sberbank.ru/api/v1",
"https://beta.saluteai.sberdevices.ru/v1",
),
)
st.title("Авторизационные данные")
scope = st.selectbox(
"GIGACHAT_SCOPE",
(
"GIGACHAT_API_PERS",
"GIGACHAT_API_CORP",
),
)
credentials = st.text_input("GIGACHAT_CREDENTIALS", type="password")
st.title("OR")
access_token = st.text_input("GIGACHAT_ACCESS_TOKEN", type="password")
st.title("OR")
user = st.text_input("GIGACHAT_USER")
password = st.text_input("GIGACHAT_PASSWORD", type="password")
# Initialize chat history
if "messages" not in st.session_state:
st.session_state.messages = [
ChatMessage(
role="system",
content="Ты - умный ИИ ассистент, который всегда готов помочь пользователю.",
),
ChatMessage(
role="assistant",
content="Как я могу помочь вам?",
additional_kwargs={"render_content": "Как я могу помочь вам?"},
),
]
# Display chat messages from history on app rerun
for message in st.session_state.messages:
with st.chat_message(message.role):
if message.role == "assistant":
st.markdown(message.additional_kwargs["render_content"], True)
else:
st.markdown(message.content, True)
if prompt := st.chat_input():
if not access_token and not credentials and not (user and password):
st.info("Заполните данные GigaChat для того, чтобы продолжить")
st.stop()
chat = GigaChat(
base_url=base_url,
credentials=credentials,
model=model,
access_token=st.session_state.get("token")
or access_token, # Переиспользуем токен
user=user,
password=password,
scope=scope,
verify_ssl_certs=False,
).bind_tools(tools=[], tool_choice="auto")
message = ChatMessage(role="user", content=prompt)
st.session_state.messages.append(message)
with st.chat_message(message.role):
st.markdown(message.content)
message = ChatMessage(
role="assistant", content="", additional_kwargs={"render_content": ""}
)
st.session_state.messages.append(message)
with st.chat_message(message.role):
message_placeholder = st.empty()
spinner = None
for chunk in chat.stream(st.session_state.messages):
if chunk.type == "FunctionInProgressMessage":
if spinner is None:
spinner = st.spinner(text="")
spinner.__enter__() # Тут хак для показа спинера в streamlit
# не знаю долго ли он проработает, но он здесь просто для красоты
continue
else:
if spinner is not None:
spinner.__exit__(None, None, None)
spinner = None
if chunk.additional_kwargs.get("image_uuid"):
image_uuid = chunk.additional_kwargs.get("image_uuid")
message.additional_kwargs[
"render_content"
] += f"""<img src="data:png;base64,{chat.get_file(image_uuid).content}" style="width: 450px; display: block; border-radius: 10px;" >"""
else:
message.additional_kwargs["render_content"] += chunk.content
message.content += chunk.content
message.additional_kwargs = {
**message.additional_kwargs,
**chunk.additional_kwargs,
}
message_placeholder.markdown(
message.additional_kwargs["render_content"] + "▌", True
)
message_placeholder.markdown(message.additional_kwargs["render_content"], True)
# Каждый раз, когда пользователь нажимает что-то в интерфейсе весь скрипт выполняется заново.
# Сохраняем токен и закрываем соединения
st.session_state.token = chat._client.token
chat._client.close()