Spaces:
Sleeping
Sleeping
Commit
·
f0f4ec9
1
Parent(s):
0b4deb4
Update app with extraction
Browse files- app.py +50 -24
- requirements.txt +2 -0
app.py
CHANGED
@@ -5,29 +5,30 @@ import time
|
|
5 |
import ipyvue
|
6 |
import reacton
|
7 |
from solara.alias import rv as v
|
|
|
|
|
|
|
|
|
|
|
8 |
|
|
|
9 |
def use_change(el: reacton.core.Element, on_value: Callable[[Any], Any], enabled=True):
|
10 |
"""Trigger a callback when a blur events occurs or the enter key is pressed."""
|
11 |
on_value_ref = solara.use_ref(on_value)
|
12 |
on_value_ref.current = on_value
|
13 |
-
|
14 |
def add_events():
|
15 |
def on_change(widget, event, data):
|
16 |
if enabled:
|
17 |
on_value_ref.current(widget.v_model)
|
18 |
-
|
19 |
widget = cast(ipyvue.VueWidget, solara.get_widget(el))
|
20 |
if enabled:
|
21 |
widget.on_event("blur", on_change)
|
22 |
widget.on_event("keyup.enter", on_change)
|
23 |
-
|
24 |
def cleanup():
|
25 |
if enabled:
|
26 |
widget.on_event("blur", on_change, remove=True)
|
27 |
widget.on_event("keyup.enter", on_change, remove=True)
|
28 |
-
|
29 |
return cleanup
|
30 |
-
|
31 |
solara.use_effect(add_events, [enabled])
|
32 |
|
33 |
|
@@ -44,14 +45,11 @@ def InputTextarea(
|
|
44 |
):
|
45 |
reactive_value = solara.use_reactive(value, on_value)
|
46 |
del value, on_value
|
47 |
-
|
48 |
def set_value_cast(value):
|
49 |
reactive_value.value = str(value)
|
50 |
-
|
51 |
def on_v_model(value):
|
52 |
if continuous_update:
|
53 |
set_value_cast(value)
|
54 |
-
|
55 |
messages = []
|
56 |
if error and isinstance(error, str):
|
57 |
messages.append(error)
|
@@ -74,18 +72,21 @@ def InputTextarea(
|
|
74 |
use_change(text_area, set_value_cast, enabled=not continuous_update)
|
75 |
return text_area
|
76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
|
78 |
class MessageDict(TypedDict):
|
79 |
role: str
|
80 |
content: str
|
81 |
|
82 |
-
# Streamed response emulator
|
83 |
-
def response_generator():
|
84 |
-
response = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
|
85 |
-
for word in response.split():
|
86 |
-
yield word + " "
|
87 |
-
time.sleep(0.05)
|
88 |
-
|
89 |
def add_chunk_to_ai_message(chunk: str):
|
90 |
messages.value = [
|
91 |
*messages.value[:-1],
|
@@ -95,27 +96,52 @@ def add_chunk_to_ai_message(chunk: str):
|
|
95 |
},
|
96 |
]
|
97 |
|
98 |
-
text_block="Alice is 18 years old, Bob is two years older and Charles is 30 years old"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
messages: solara.Reactive[List[MessageDict]] = solara.reactive([])
|
|
|
101 |
@solara.component
|
102 |
def Page():
|
|
|
|
|
103 |
with solara.Column(style={"width": "70%", "padding": "50px"}):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
user_message_count = len([m for m in messages.value if m["role"] == "user"])
|
105 |
def send():
|
106 |
messages.value = [*messages.value, {"role": "user", "content": "Hello"}]
|
107 |
def response(message):
|
108 |
-
|
109 |
-
|
110 |
-
|
|
|
|
|
|
|
111 |
def result():
|
112 |
if messages.value != []:
|
113 |
response(messages.value[-1]["content"])
|
114 |
result = solara.lab.use_task(result, dependencies=[user_message_count])
|
115 |
InputTextarea("Enter text:", value=text_block, continuous_update=True)
|
116 |
-
solara.Button(label="Extract", on_click=send)
|
117 |
-
|
118 |
-
for item in messages.value:
|
119 |
-
if item["role"] != "user":
|
120 |
-
solara.Markdown(item["content"])
|
121 |
Page()
|
|
|
5 |
import ipyvue
|
6 |
import reacton
|
7 |
from solara.alias import rv as v
|
8 |
+
import os
|
9 |
+
import openai
|
10 |
+
from openai import OpenAI
|
11 |
+
import instructor
|
12 |
+
from pydantic import BaseModel, Field
|
13 |
|
14 |
+
# NEEDED FOR INPUT TEXT AREA INSTEAD OF INPUT TEXT
|
15 |
def use_change(el: reacton.core.Element, on_value: Callable[[Any], Any], enabled=True):
|
16 |
"""Trigger a callback when a blur events occurs or the enter key is pressed."""
|
17 |
on_value_ref = solara.use_ref(on_value)
|
18 |
on_value_ref.current = on_value
|
|
|
19 |
def add_events():
|
20 |
def on_change(widget, event, data):
|
21 |
if enabled:
|
22 |
on_value_ref.current(widget.v_model)
|
|
|
23 |
widget = cast(ipyvue.VueWidget, solara.get_widget(el))
|
24 |
if enabled:
|
25 |
widget.on_event("blur", on_change)
|
26 |
widget.on_event("keyup.enter", on_change)
|
|
|
27 |
def cleanup():
|
28 |
if enabled:
|
29 |
widget.on_event("blur", on_change, remove=True)
|
30 |
widget.on_event("keyup.enter", on_change, remove=True)
|
|
|
31 |
return cleanup
|
|
|
32 |
solara.use_effect(add_events, [enabled])
|
33 |
|
34 |
|
|
|
45 |
):
|
46 |
reactive_value = solara.use_reactive(value, on_value)
|
47 |
del value, on_value
|
|
|
48 |
def set_value_cast(value):
|
49 |
reactive_value.value = str(value)
|
|
|
50 |
def on_v_model(value):
|
51 |
if continuous_update:
|
52 |
set_value_cast(value)
|
|
|
53 |
messages = []
|
54 |
if error and isinstance(error, str):
|
55 |
messages.append(error)
|
|
|
72 |
use_change(text_area, set_value_cast, enabled=not continuous_update)
|
73 |
return text_area
|
74 |
|
75 |
+
# EXTRACTION
|
76 |
+
openai.api_key = os.environ['OPENAI_API_KEY']
|
77 |
+
client = instructor.from_openai(OpenAI())
|
78 |
+
|
79 |
+
class Person(BaseModel):
|
80 |
+
name: str
|
81 |
+
age: int
|
82 |
+
|
83 |
+
class People(BaseModel):
|
84 |
+
people: List[Person] = Field(..., default_factory=list)
|
85 |
|
86 |
class MessageDict(TypedDict):
|
87 |
role: str
|
88 |
content: str
|
89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
def add_chunk_to_ai_message(chunk: str):
|
91 |
messages.value = [
|
92 |
*messages.value[:-1],
|
|
|
96 |
},
|
97 |
]
|
98 |
|
99 |
+
text_block="Alice is 18 years old, Bob is two years older and Charles is 30 years old."
|
100 |
+
|
101 |
+
# DISPLAYED OUTPUT
|
102 |
+
@solara.component
|
103 |
+
def ChatInterface():
|
104 |
+
with solara.lab.ChatBox():
|
105 |
+
if len(messages.value)>0:
|
106 |
+
if messages.value[-1]["role"] != "user":
|
107 |
+
solara.Markdown(messages.value[-1]["content"], style={"font-size": "1.2em", "color": "blue"})
|
108 |
|
109 |
messages: solara.Reactive[List[MessageDict]] = solara.reactive([])
|
110 |
+
aux = solara.reactive("")
|
111 |
@solara.component
|
112 |
def Page():
|
113 |
+
with solara.Head():
|
114 |
+
solara.Title("Extractor")
|
115 |
with solara.Column(style={"width": "70%", "padding": "50px"}):
|
116 |
+
solara.Markdown("#Extractor")
|
117 |
+
solara.Markdown("Enter some text and the language model will try to extract names and ages of the people in the text. Done with :heart: by [alonsosilva](https://twitter.com/alonsosilva)")
|
118 |
+
extraction_stream = client.chat.completions.create_partial(
|
119 |
+
model="gpt-3.5-turbo",
|
120 |
+
response_model=People,
|
121 |
+
messages=[
|
122 |
+
{
|
123 |
+
"role": "user",
|
124 |
+
"content": f"Get the information about the people: {text_block}",
|
125 |
+
},
|
126 |
+
],
|
127 |
+
stream=True,
|
128 |
+
)
|
129 |
+
|
130 |
user_message_count = len([m for m in messages.value if m["role"] == "user"])
|
131 |
def send():
|
132 |
messages.value = [*messages.value, {"role": "user", "content": "Hello"}]
|
133 |
def response(message):
|
134 |
+
for extraction in extraction_stream:
|
135 |
+
obj = extraction.model_dump()
|
136 |
+
if f"{obj}" != aux.value:
|
137 |
+
messages.value = [*messages.value, {"role": "assistant", "content": ""}]
|
138 |
+
add_chunk_to_ai_message(f"{obj}")
|
139 |
+
aux.value = f"{obj}"
|
140 |
def result():
|
141 |
if messages.value != []:
|
142 |
response(messages.value[-1]["content"])
|
143 |
result = solara.lab.use_task(result, dependencies=[user_message_count])
|
144 |
InputTextarea("Enter text:", value=text_block, continuous_update=True)
|
145 |
+
solara.Button(label="Extract names and ages of users", on_click=send)
|
146 |
+
ChatInterface()
|
|
|
|
|
|
|
147 |
Page()
|
requirements.txt
CHANGED
@@ -1 +1,3 @@
|
|
1 |
solara==1.31.0
|
|
|
|
|
|
1 |
solara==1.31.0
|
2 |
+
openai==1.17.0
|
3 |
+
instructor==1.1.0
|