Ganesh Chintalapati commited on
Commit
f1c4e59
·
1 Parent(s): 9328f50

final version v2

Browse files
Files changed (1) hide show
  1. core.py +66 -21
core.py CHANGED
@@ -33,13 +33,16 @@ async def query_model(
33
  if msg.get("gemini"):
34
  gemini_messages.append({"role": "assistant", "content": msg["gemini"]})
35
 
36
- # Append the user query to messages and yield immediately to show in UI
37
  if "OpenAI" in providers:
38
  openai_messages.append({"role": "user", "content": query})
 
39
  if "Anthropic" in providers:
40
  anthropic_messages.append({"role": "user", "content": query})
 
41
  if "Gemini" in providers:
42
  gemini_messages.append({"role": "user", "content": query})
 
43
 
44
  # Yield initial state with user query
45
  logger.info(f"Yielding initial state with user query: {query}")
@@ -47,31 +50,73 @@ async def query_model(
47
 
48
  tasks = []
49
  if "OpenAI" in providers:
50
- tasks.append(("OpenAI", ask_openai(query, history)))
51
  if "Anthropic" in providers:
52
- tasks.append(("Anthropic", ask_anthropic(query, history)))
53
  if "Gemini" in providers:
54
- tasks.append(("Gemini", ask_gemini(query, history)))
55
 
56
- async def collect_chunks(provider: str, generator: AsyncGenerator[str, None]) -> Tuple[str, str]:
57
- response = ""
 
 
 
 
58
  async for chunk in generator:
59
  response += chunk
60
- return provider, response
61
-
62
- awaitables = [collect_chunks(provider, gen) for provider, gen in tasks]
63
- responses = await asyncio.gather(*awaitables)
64
-
65
- for provider, response in responses:
66
- if provider == "OpenAI":
67
- openai_response = response
68
- openai_messages.append({"role": "assistant", "content": response})
69
- elif provider == "Anthropic":
70
- anthropic_response = response
71
- anthropic_messages.append({"role": "assistant", "content": response})
72
- elif provider == "Gemini":
73
- gemini_response = response
74
- gemini_messages.append({"role": "assistant", "content": response})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
  updated_history = history + [{
77
  "user": query,
 
33
  if msg.get("gemini"):
34
  gemini_messages.append({"role": "assistant", "content": msg["gemini"]})
35
 
36
+ # Append the user query and prepare for assistant response
37
  if "OpenAI" in providers:
38
  openai_messages.append({"role": "user", "content": query})
39
+ openai_messages.append({"role": "assistant", "content": ""})
40
  if "Anthropic" in providers:
41
  anthropic_messages.append({"role": "user", "content": query})
42
+ anthropic_messages.append({"role": "assistant", "content": ""})
43
  if "Gemini" in providers:
44
  gemini_messages.append({"role": "user", "content": query})
45
+ gemini_messages.append({"role": "assistant", "content": ""})
46
 
47
  # Yield initial state with user query
48
  logger.info(f"Yielding initial state with user query: {query}")
 
50
 
51
  tasks = []
52
  if "OpenAI" in providers:
53
+ tasks.append(("OpenAI", ask_openai(query, history), openai_response, openai_messages))
54
  if "Anthropic" in providers:
55
+ tasks.append(("Anthropic", ask_anthropic(query, history), anthropic_response, anthropic_messages))
56
  if "Gemini" in providers:
57
+ tasks.append(("Gemini", ask_gemini(query, history), gemini_response, gemini_messages))
58
 
59
+ async def collect_chunks(
60
+ provider: str,
61
+ generator: AsyncGenerator[str, None],
62
+ response: str,
63
+ messages: List[Dict[str, str]]
64
+ ) -> AsyncGenerator[Tuple[str, str, List[Dict[str, str]]], None]:
65
  async for chunk in generator:
66
  response += chunk
67
+ messages[-1] = {"role": "assistant", "content": response}
68
+ yield provider, response, messages
69
+
70
+ generator_states = [(provider, collect_chunks(provider, gen, resp, msgs), None) for provider, gen, resp, msgs in tasks]
71
+ active_generators = generator_states[:]
72
+
73
+ while active_generators:
74
+ tasks_to_wait = []
75
+ new_generator_states = []
76
+
77
+ for provider, gen, active_task in active_generators:
78
+ if active_task is None or active_task.done():
79
+ try:
80
+ task = asyncio.create_task(gen.__anext__())
81
+ new_generator_states.append((provider, gen, task))
82
+ tasks_to_wait.append(task)
83
+ logger.debug(f"Created task for {provider}")
84
+ except StopAsyncIteration:
85
+ logger.info(f"Generator for {provider} completed")
86
+ continue
87
+ else:
88
+ new_generator_states.append((provider, gen, active_task))
89
+ tasks_to_wait.append(active_task)
90
+
91
+ if not tasks_to_wait:
92
+ break
93
+
94
+ done, _ = await asyncio.wait(tasks_to_wait, return_when=asyncio.FIRST_COMPLETED)
95
+
96
+ for provider, gen, task in new_generator_states:
97
+ if task in done:
98
+ try:
99
+ provider, response, messages = task.result()
100
+ if provider == "OpenAI":
101
+ openai_response = response
102
+ openai_messages = messages
103
+ elif provider == "Anthropic":
104
+ anthropic_response = response
105
+ anthropic_messages = messages
106
+ elif provider == "Gemini":
107
+ gemini_response = response
108
+ gemini_messages = messages
109
+ logger.info(f"Yielding update for {provider}: {response[:50]}...")
110
+ yield "", openai_messages, anthropic_messages, gemini_messages, history
111
+ new_generator_states[new_generator_states.index((provider, gen, task))] = (provider, gen, None)
112
+ except StopAsyncIteration:
113
+ logger.info(f"Generator for {provider} completed")
114
+ new_generator_states.remove((provider, gen, task))
115
+ else:
116
+ if (provider, gen, task) not in new_generator_states:
117
+ new_generator_states.append((provider, gen, task))
118
+
119
+ active_generators = new_generator_states
120
 
121
  updated_history = history + [{
122
  "user": query,