tikendraw commited on
Commit
e4bde4c
·
1 Parent(s): 22507c4

third push

Browse files
Files changed (6) hide show
  1. .env_example +1 -1
  2. app/app.py +51 -51
  3. app/app_config.py +5 -2
  4. app/utils.py +35 -7
  5. core/types.py +24 -6
  6. input_config.json +2 -1
.env_example CHANGED
@@ -1,2 +1,2 @@
1
  MODEL_NAME=openai/gpt-3.5-turbo
2
- MODEL_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 
1
  MODEL_NAME=openai/gpt-3.5-turbo
2
+ MODEL_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
app/app.py CHANGED
@@ -2,11 +2,12 @@
2
  from calendar import c
3
  from dataclasses import dataclass
4
  from math import exp
 
 
5
  from webbrowser import get
6
  from litellm.types.utils import ModelResponse
7
  import streamlit as st
8
- from streamlit.runtime.uploaded_file_manager import UploadedFile
9
- from app.utils import generate_answer, dict_to_markdown
10
  from core.types import ThoughtStepsDisplay, ThoughtSteps, BigMessage , Message
11
  from .app_config import InputConfig, ENV_FILE_PATH, CONFIG_FILE_PATH
12
  from core.llms.base_llm import BaseLLM
@@ -16,18 +17,18 @@ from PIL import Image
16
  from core.prompts.think_mark_think import SYSTEM_PROMPT
17
 
18
  st.set_page_config(page_title="Open-o1", page_icon="🧠", layout="wide")
19
- st.title('Open-O1')
20
- st.write('Welcome to Open-O1!')
21
 
22
  def config_sidebar(config:InputConfig) -> InputConfig:
23
  st.sidebar.header('Configuration')
24
- model_name = st.sidebar.text_input('Enter Model Name: e.g. provider/model-name',value=config.model_name, placeholder='openai/gpt-3.5-turbo')
25
- model_api_key = st.sidebar.text_input('Enter API Key: ',type='password',value=config.model_api_key, placeholder='sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
26
- max_tokens = st.sidebar.number_input('Enter Max Tokens per Thought: ',value=config.max_tokens, min_value=1)
27
- max_steps = st.sidebar.number_input('Enter Max Thinking Steps: ',value=config.max_steps, min_value=1, step=1, )
28
- temperature = st.sidebar.number_input('Enter Temperature: ',value=config.temperature, min_value=0.0, step=0.1, max_value=10.0)
29
- timeout = st.sidebar.number_input('Enter timeout(seconds): ',value=config.timeout, min_value=0.0,step = 1.0)
30
- sleeptime = st.sidebar.number_input('Enter Sleep Time(seconds): (time bw requests to avoid rate limit)',value=config.sleeptime, min_value=0.0, step = 1.0)
 
31
 
32
  config.model_name = model_name
33
  config.model_api_key = model_api_key
@@ -36,6 +37,8 @@ def config_sidebar(config:InputConfig) -> InputConfig:
36
  config.temperature = temperature
37
  config.timeout = timeout
38
  config.sleeptime = sleeptime
 
 
39
 
40
  if st.sidebar.button('Save config'):
41
  config.save(env_file=ENV_FILE_PATH, config_file=CONFIG_FILE_PATH)
@@ -43,43 +46,27 @@ def config_sidebar(config:InputConfig) -> InputConfig:
43
 
44
  return config
45
 
46
- def load_llm(config:InputConfig, tools=None) -> BaseLLM:
47
- return LLM(api_key=config.model_api_key, model=config.model_name, tools=tools)
48
-
49
-
50
- def image_buffer_to_pillow_image(image_buffer:UploadedFile) -> Image.Image:
51
- return Image.open(image_buffer)
52
-
53
-
54
- def process_user_input(user_input:str, image:Image.Image=None)->dict:
55
- if image:
56
- message = [user_message_with_images(user_msg_str=user_input, images=[image])]
57
- else:
58
- message = [{"role": "user", "content": user_input}]
59
- return message
60
-
61
-
62
 
63
 
64
  def main():
 
 
 
65
 
66
  config = InputConfig.load(env_file=ENV_FILE_PATH, config_file=CONFIG_FILE_PATH)
67
  config = config_sidebar(config=config)
68
  llm = load_llm(config)
69
 
70
- current_tab = ''
71
 
72
  current_tab='o1_tab'
73
- messages_attr_name = f"{current_tab}_messages"
74
  big_message_attr_name = f"{current_tab}_big_messages"
75
 
76
 
77
  clear_chat_bt = st.sidebar.button('Clear Chat')
78
  if clear_chat_bt:
79
- delattr(st.session_state, messages_attr_name)
80
 
81
 
82
- message_attr = set_and_get_state_attr(messages_attr_name, default_value=[])
83
  big_message_attr = set_and_get_state_attr(big_message_attr_name, default_value=[])
84
 
85
  # this prints the older messages
@@ -93,7 +80,7 @@ def main():
93
  if message.role == 'user':
94
  st.markdown(message.content)
95
  else:
96
- print_thought(message.to_thought_steps_display(), is_final=True)
97
 
98
 
99
 
@@ -118,30 +105,42 @@ def main():
118
  if message["role"] == "user":
119
  message["content"] = f"{message['content']}, json format"
120
 
 
121
 
122
- for num,step in enumerate(generate_answer(
123
- messages=messages,
124
- max_steps=config.max_steps,
125
- stream=False,
126
- max_tokens=config.max_tokens,
127
- temperature=config.temperature,
128
- sleeptime=config.sleeptime,
129
- timeout=config.timeout,
130
- llm=llm,
131
- response_format={ "type": "json_object" }
132
-
133
- ),1):
134
-
135
- thoughts.append(step)
136
- print_thought(step.to_thought_steps_display(), is_final=False)
 
 
 
 
 
 
 
 
 
 
137
 
138
  last_step = thoughts.pop()
139
- message_attr.append(BigMessage(
 
 
140
  role="assistant",
141
  content=last_step,
142
  thoughts=thoughts
143
  ))
144
- # st.markdown(dict_to_markdown(step.model_dump()))
145
 
146
 
147
 
@@ -155,8 +154,9 @@ def print_thought(thought:ThoughtStepsDisplay, is_final:bool=False):
155
  if is_final:
156
  st.markdown(thought.md())
157
  else:
158
- st.markdown(f'\n```json\n{thought.model_dump_json()}\n```\n', unsafe_allow_html=True)
159
-
 
160
 
161
 
162
 
 
2
  from calendar import c
3
  from dataclasses import dataclass
4
  from math import exp
5
+ from shutil import which
6
+ import time
7
  from webbrowser import get
8
  from litellm.types.utils import ModelResponse
9
  import streamlit as st
10
+ from app.utils import generate_answer, load_llm
 
11
  from core.types import ThoughtStepsDisplay, ThoughtSteps, BigMessage , Message
12
  from .app_config import InputConfig, ENV_FILE_PATH, CONFIG_FILE_PATH
13
  from core.llms.base_llm import BaseLLM
 
17
  from core.prompts.think_mark_think import SYSTEM_PROMPT
18
 
19
  st.set_page_config(page_title="Open-o1", page_icon="🧠", layout="wide")
20
+
 
21
 
22
  def config_sidebar(config:InputConfig) -> InputConfig:
23
  st.sidebar.header('Configuration')
24
+ model_name = st.sidebar.text_input('Model Name: e.g. provider/model-name',value=config.model_name, placeholder='openai/gpt-3.5-turbo')
25
+ model_api_key = st.sidebar.text_input('API Key: ',type='password',value=config.model_api_key, placeholder='sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
26
+ max_tokens = st.sidebar.number_input('Max Tokens per Thought: ',value=config.max_tokens, min_value=1)
27
+ max_steps = st.sidebar.number_input('Max Thinking Steps: ',value=config.max_steps, min_value=1, step=1, )
28
+ temperature = st.sidebar.number_input('Temperature: ',value=config.temperature, min_value=0.0, step=0.1, max_value=10.0)
29
+ timeout = st.sidebar.number_input('Timeout(seconds): ',value=config.timeout, min_value=0.0,step = 1.0)
30
+ sleeptime = st.sidebar.number_input('Sleep Time(seconds)',value=config.sleeptime, min_value=0.0, step = 1.0, help='Time between requests to avoid hitting rate limit')
31
+ force_max_steps = st.sidebar.checkbox('Force Max Steps', value=config.force_max_steps, help="If checked, will generate given number of max steps. If not checked, assistant can stop at few step thinking it has the write answer.")
32
 
33
  config.model_name = model_name
34
  config.model_api_key = model_api_key
 
37
  config.temperature = temperature
38
  config.timeout = timeout
39
  config.sleeptime = sleeptime
40
+ config.force_max_steps = force_max_steps
41
+
42
 
43
  if st.sidebar.button('Save config'):
44
  config.save(env_file=ENV_FILE_PATH, config_file=CONFIG_FILE_PATH)
 
46
 
47
  return config
48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
 
51
  def main():
52
+ st.title('Open-O1')
53
+ st.write('Welcome to Open-O1!')
54
+
55
 
56
  config = InputConfig.load(env_file=ENV_FILE_PATH, config_file=CONFIG_FILE_PATH)
57
  config = config_sidebar(config=config)
58
  llm = load_llm(config)
59
 
 
60
 
61
  current_tab='o1_tab'
 
62
  big_message_attr_name = f"{current_tab}_big_messages"
63
 
64
 
65
  clear_chat_bt = st.sidebar.button('Clear Chat')
66
  if clear_chat_bt:
67
+ delattr(st.session_state, big_message_attr_name)
68
 
69
 
 
70
  big_message_attr = set_and_get_state_attr(big_message_attr_name, default_value=[])
71
 
72
  # this prints the older messages
 
80
  if message.role == 'user':
81
  st.markdown(message.content)
82
  else:
83
+ print_thought(message.content.to_thought_steps_display(), is_final=True)
84
 
85
 
86
 
 
105
  if message["role"] == "user":
106
  message["content"] = f"{message['content']}, json format"
107
 
108
+ start_time = time.time()
109
 
110
+ with st.status("Thinking...", expanded=True) as status:
111
+
112
+ for step in generate_answer(
113
+ messages=messages,
114
+ max_steps=config.max_steps,
115
+ stream=False,
116
+ max_tokens=config.max_tokens,
117
+ temperature=config.temperature,
118
+ sleeptime=config.sleeptime,
119
+ timeout=config.timeout,
120
+ llm=llm,
121
+ force_max_steps=config.force_max_steps,
122
+ response_format={ "type": "json_object" }
123
+
124
+ ):
125
+
126
+ thoughts.append(step)
127
+
128
+ st.write(step.to_thought_steps_display().md())
129
+
130
+ status.update(label=step.step_title, state="running", expanded=False)
131
+
132
+ status.update(
133
+ label=f"Thought for {time.time()-start_time:.2f} seconds", state="complete", expanded=False
134
+ )
135
 
136
  last_step = thoughts.pop()
137
+ print_thought(last_step.to_thought_steps_display(), is_final=True)
138
+
139
+ big_message_attr.append(BigMessage(
140
  role="assistant",
141
  content=last_step,
142
  thoughts=thoughts
143
  ))
 
144
 
145
 
146
 
 
154
  if is_final:
155
  st.markdown(thought.md())
156
  else:
157
+ # st.markdown(f'\n```json\n{thought.model_dump_json()}\n```\n', unsafe_allow_html=True)
158
+ with st.expander(f'{thought.step_title}'):
159
+ st.markdown(thought.md())
160
 
161
 
162
 
app/app_config.py CHANGED
@@ -24,6 +24,7 @@ class InputConfig:
24
  temperature: float = 0.2
25
  timeout: float = 30.0
26
  sleeptime: float = 0.0
 
27
 
28
  @classmethod
29
  def load(cls, env_file=ENV_FILE_PATH, config_file=CONFIG_FILE_PATH):
@@ -46,7 +47,8 @@ class InputConfig:
46
  max_steps=config_dict.get('max_steps', cls.max_steps),
47
  temperature=config_dict.get('temperature', cls.temperature),
48
  timeout=config_dict.get('timeout', cls.timeout),
49
- sleeptime=config_dict.get('sleeptime', cls.sleeptime)
 
50
  )
51
 
52
  def save(self, env_file=ENV_FILE_PATH, config_file=CONFIG_FILE_PATH):
@@ -74,7 +76,8 @@ class InputConfig:
74
  'max_steps': self.max_steps,
75
  'temperature': self.temperature,
76
  'timeout': self.timeout,
77
- 'sleeptime': self.sleeptime
 
78
  }
79
  with open(config_file, 'w') as f:
80
  json.dump(config_dict, f, indent=4)
 
24
  temperature: float = 0.2
25
  timeout: float = 30.0
26
  sleeptime: float = 0.0
27
+ force_max_steps: bool = True
28
 
29
  @classmethod
30
  def load(cls, env_file=ENV_FILE_PATH, config_file=CONFIG_FILE_PATH):
 
47
  max_steps=config_dict.get('max_steps', cls.max_steps),
48
  temperature=config_dict.get('temperature', cls.temperature),
49
  timeout=config_dict.get('timeout', cls.timeout),
50
+ sleeptime=config_dict.get('sleeptime', cls.sleeptime),
51
+ force_max_steps=config_dict.get('force_max_steps', cls.force_max_steps)
52
  )
53
 
54
  def save(self, env_file=ENV_FILE_PATH, config_file=CONFIG_FILE_PATH):
 
76
  'max_steps': self.max_steps,
77
  'temperature': self.temperature,
78
  'timeout': self.timeout,
79
+ 'sleeptime': self.sleeptime,
80
+ 'force_max_steps': self.force_max_steps
81
  }
82
  with open(config_file, 'w') as f:
83
  json.dump(config_dict, f, indent=4)
app/utils.py CHANGED
@@ -11,10 +11,16 @@ import os
11
  import time
12
  from core.utils import parse_with_fallback
13
  from termcolor import colored
 
 
 
 
 
14
 
15
 
16
 
17
- def generate_answer(messages: list[dict], max_steps: int = 20, llm: BaseLLM = None, sleeptime: float = 0.0, **kwargs):
 
18
  thoughts = []
19
 
20
  for i in range(max_steps):
@@ -24,13 +30,16 @@ def generate_answer(messages: list[dict], max_steps: int = 20, llm: BaseLLM = No
24
 
25
  print(colored(f"{i+1} - {response}", 'yellow'))
26
 
27
- if thought:
28
- thoughts.append(thought)
29
- messages.append({"role": "assistant", "content": thought.model_dump_json()})
30
- messages.append({"role": "user", "content": REVIEW_PROMPT})
 
 
 
 
31
 
32
- yield thought
33
- time.sleep(sleeptime)
34
 
35
  # Get the final answer after all thoughts are processed
36
  messages += [{"role": "user", "content": FINAL_ANSWER_PROMPT}]
@@ -66,3 +75,22 @@ def dict_to_markdown(d:dict) -> str:
66
  md += f"{value}\n"
67
  return md
68
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  import time
12
  from core.utils import parse_with_fallback
13
  from termcolor import colored
14
+ from app.app_config import InputConfig
15
+ from core.llms.litellm_llm import LLM
16
+ from core.llms.utils import user_message_with_images
17
+ from PIL import Image
18
+ from streamlit.runtime.uploaded_file_manager import UploadedFile
19
 
20
 
21
 
22
+
23
+ def generate_answer(messages: list[dict], max_steps: int = 20, llm: BaseLLM = None, sleeptime: float = 0.0, force_max_steps: bool = False, **kwargs):
24
  thoughts = []
25
 
26
  for i in range(max_steps):
 
30
 
31
  print(colored(f"{i+1} - {response}", 'yellow'))
32
 
33
+ thoughts.append(thought)
34
+ messages.append({"role": "assistant", "content": thought.model_dump_json()})
35
+ yield thought
36
+
37
+ if thought.is_final_answer and not thought.next_step and not force_max_steps:
38
+ break
39
+
40
+ messages.append({"role": "user", "content": REVIEW_PROMPT})
41
 
42
+ time.sleep(sleeptime)
 
43
 
44
  # Get the final answer after all thoughts are processed
45
  messages += [{"role": "user", "content": FINAL_ANSWER_PROMPT}]
 
75
  md += f"{value}\n"
76
  return md
77
 
78
+
79
+
80
+
81
+ def load_llm(config:InputConfig, tools=None) -> BaseLLM:
82
+ return LLM(api_key=config.model_api_key, model=config.model_name, tools=tools)
83
+
84
+
85
+ def image_buffer_to_pillow_image(image_buffer:UploadedFile) -> Image.Image:
86
+ return Image.open(image_buffer)
87
+
88
+
89
+ def process_user_input(user_input:str, image:Image.Image=None)->dict:
90
+ if image:
91
+ message = [user_message_with_images(user_msg_str=user_input, images=[image])]
92
+ else:
93
+ message = [{"role": "user", "content": user_input}]
94
+ return message
95
+
96
+
core/types.py CHANGED
@@ -30,15 +30,15 @@ class ThoughtStepsDisplay(BaseModel):
30
 
31
 
32
  def md(self):
33
- return dedent(f'''
34
- {self.step_title}
35
- ### Thought
36
  {self.thought}
37
- ### Answer
38
  {self.answer}
39
- ### Critic
40
  {self.critic}
41
- ''')
42
 
43
 
44
 
@@ -56,3 +56,21 @@ class BigMessage(BaseModel):
56
  class Message(BaseModel):
57
  role:str
58
  content:str
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
 
32
  def md(self):
33
+ return f'''
34
+ #### {self.step_title}
35
+
36
  {self.thought}
37
+
38
  {self.answer}
39
+
40
  {self.critic}
41
+ '''
42
 
43
 
44
 
 
56
  class Message(BaseModel):
57
  role:str
58
  content:str
59
+
60
+ class InputConfig(BaseModel):
61
+ prompt: str = Field(..., description="prompt to use")
62
+ model: str = Field(..., description="model to use")
63
+ max_tokens: int = Field(..., description="max tokens to use")
64
+ temperature: float = Field(..., description="temperature to use")
65
+ top_p: float = Field(..., description="top p to use")
66
+ n: int = Field(..., description="number of responses to generate")
67
+ stream: bool = Field(..., description="whether to stream the response")
68
+ stop: list[str] | None = Field(..., description="stop sequences")
69
+ force_max_steps: bool = Field(False, description="force max steps")
70
+
71
+ def to_dict(self):
72
+ return self.model_dump()
73
+
74
+ def to_json(self):
75
+ return json.dumps(self.to_dict())
76
+
input_config.json CHANGED
@@ -3,5 +3,6 @@
3
  "max_steps": 3,
4
  "temperature": 0.2,
5
  "timeout": 30.0,
6
- "sleeptime": 2.0
 
7
  }
 
3
  "max_steps": 3,
4
  "temperature": 0.2,
5
  "timeout": 30.0,
6
+ "sleeptime": 2.0,
7
+ "force_max_steps": true
8
  }