|
17 | 17 | --enable-auto-tool-choice --tool-call-parser hermes |
18 | 18 | """ |
19 | 19 | import json |
| 20 | +from typing import Any |
20 | 21 |
|
21 | 22 | from openai import OpenAI |
22 | 23 |
|
23 | 24 | # Modify OpenAI's API key and API base to use vLLM's API server. |
24 | 25 | openai_api_key = "EMPTY" |
25 | 26 | openai_api_base = "http://localhost:8000/v1" |
26 | 27 |
|
27 | | -client = OpenAI( |
28 | | - # defaults to os.environ.get("OPENAI_API_KEY") |
29 | | - api_key=openai_api_key, |
30 | | - base_url=openai_api_base, |
31 | | -) |
32 | | - |
33 | | -models = client.models.list() |
34 | | -model = models.data[0].id |
35 | | - |
36 | 28 | tools = [{ |
37 | 29 | "type": "function", |
38 | 30 | "function": { |
|
78 | 70 | "Can you tell me what the temperate will be in Dallas, in fahrenheit?" |
79 | 71 | }] |
80 | 72 |
|
81 | | -chat_completion = client.chat.completions.create(messages=messages, |
82 | | - model=model, |
83 | | - tools=tools) |
84 | | - |
85 | | -print("Chat completion results:") |
86 | | -print(chat_completion) |
87 | | -print("\n\n") |
88 | | - |
89 | | -tool_calls_stream = client.chat.completions.create(messages=messages, |
90 | | - model=model, |
91 | | - tools=tools, |
92 | | - stream=True) |
93 | | - |
94 | | -chunks = [] |
95 | | -for chunk in tool_calls_stream: |
96 | | - chunks.append(chunk) |
97 | | - if chunk.choices[0].delta.tool_calls: |
98 | | - print(chunk.choices[0].delta.tool_calls[0]) |
99 | | - else: |
100 | | - print(chunk.choices[0].delta) |
101 | | - |
102 | | -arguments = [] |
103 | | -tool_call_idx = -1 |
104 | | -for chunk in chunks: |
105 | | - |
106 | | - if chunk.choices[0].delta.tool_calls: |
107 | | - tool_call = chunk.choices[0].delta.tool_calls[0] |
108 | | - |
109 | | - if tool_call.index != tool_call_idx: |
110 | | - if tool_call_idx >= 0: |
111 | | - print( |
112 | | - f"streamed tool call arguments: {arguments[tool_call_idx]}" |
113 | | - ) |
114 | | - tool_call_idx = chunk.choices[0].delta.tool_calls[0].index |
115 | | - arguments.append("") |
116 | | - if tool_call.id: |
117 | | - print(f"streamed tool call id: {tool_call.id} ") |
118 | | - |
119 | | - if tool_call.function: |
120 | | - if tool_call.function.name: |
121 | | - print(f"streamed tool call name: {tool_call.function.name}") |
122 | | - |
123 | | - if tool_call.function.arguments: |
124 | | - arguments[tool_call_idx] += tool_call.function.arguments |
125 | | - |
126 | | -if len(arguments): |
127 | | - print(f"streamed tool call arguments: {arguments[-1]}") |
128 | | - |
129 | | -print("\n\n") |
130 | | - |
131 | | -messages.append({ |
132 | | - "role": "assistant", |
133 | | - "tool_calls": chat_completion.choices[0].message.tool_calls |
134 | | -}) |
135 | 73 |
|
136 | | - |
137 | | -# Now, simulate a tool call |
138 | 74 | def get_current_weather(city: str, state: str, unit: 'str'): |
139 | 75 | return ("The weather in Dallas, Texas is 85 degrees fahrenheit. It is " |
140 | 76 | "partly cloudly, with highs in the 90's.") |
141 | 77 |
|
142 | 78 |
|
143 | | -available_tools = {"get_current_weather": get_current_weather} |
144 | | - |
145 | | -completion_tool_calls = chat_completion.choices[0].message.tool_calls |
146 | | -for call in completion_tool_calls: |
147 | | - tool_to_call = available_tools[call.function.name] |
148 | | - args = json.loads(call.function.arguments) |
149 | | - result = tool_to_call(**args) |
150 | | - print(result) |
| 79 | +def handle_tool_calls_stream( |
| 80 | + client: OpenAI, |
| 81 | + messages: list[dict[str, str]], |
| 82 | + model: str, |
| 83 | + tools: list[dict[str, Any]], |
| 84 | +) -> list[Any]: |
| 85 | + tool_calls_stream = client.chat.completions.create(messages=messages, |
| 86 | + model=model, |
| 87 | + tools=tools, |
| 88 | + stream=True) |
| 89 | + chunks = [] |
| 90 | + print("chunks: ") |
| 91 | + for chunk in tool_calls_stream: |
| 92 | + chunks.append(chunk) |
| 93 | + if chunk.choices[0].delta.tool_calls: |
| 94 | + print(chunk.choices[0].delta.tool_calls[0]) |
| 95 | + else: |
| 96 | + print(chunk.choices[0].delta) |
| 97 | + return chunks |
| 98 | + |
| 99 | + |
| 100 | +def handle_tool_calls_arguments(chunks: list[Any]) -> list[str]: |
| 101 | + arguments = [] |
| 102 | + tool_call_idx = -1 |
| 103 | + print("arguments: ") |
| 104 | + for chunk in chunks: |
| 105 | + if chunk.choices[0].delta.tool_calls: |
| 106 | + tool_call = chunk.choices[0].delta.tool_calls[0] |
| 107 | + if tool_call.index != tool_call_idx: |
| 108 | + if tool_call_idx >= 0: |
| 109 | + print(f"streamed tool call arguments: " |
| 110 | + f"{arguments[tool_call_idx]}") |
| 111 | + tool_call_idx = chunk.choices[0].delta.tool_calls[0].index |
| 112 | + arguments.append("") |
| 113 | + if tool_call.id: |
| 114 | + print(f"streamed tool call id: {tool_call.id} ") |
| 115 | + |
| 116 | + if tool_call.function: |
| 117 | + if tool_call.function.name: |
| 118 | + print( |
| 119 | + f"streamed tool call name: {tool_call.function.name}") |
| 120 | + |
| 121 | + if tool_call.function.arguments: |
| 122 | + arguments[tool_call_idx] += tool_call.function.arguments |
| 123 | + |
| 124 | + return arguments |
| 125 | + |
| 126 | + |
| 127 | +def main(): |
| 128 | + # Initialize OpenAI client |
| 129 | + client = OpenAI( |
| 130 | + # defaults to os.environ.get("OPENAI_API_KEY") |
| 131 | + api_key=openai_api_key, |
| 132 | + base_url=openai_api_base, |
| 133 | + ) |
| 134 | + |
| 135 | + # Get available models and select one |
| 136 | + models = client.models.list() |
| 137 | + model = models.data[0].id |
| 138 | + |
| 139 | + chat_completion = client.chat.completions.create(messages=messages, |
| 140 | + model=model, |
| 141 | + tools=tools) |
| 142 | + |
| 143 | + print("-" * 70) |
| 144 | + print("Chat completion results:") |
| 145 | + print(chat_completion) |
| 146 | + print("-" * 70) |
| 147 | + |
| 148 | + # Stream tool calls |
| 149 | + chunks = handle_tool_calls_stream(client, messages, model, tools) |
| 150 | + print("-" * 70) |
| 151 | + |
| 152 | + # Handle arguments from streamed tool calls |
| 153 | + arguments = handle_tool_calls_arguments(chunks) |
| 154 | + |
| 155 | + if len(arguments): |
| 156 | + print(f"streamed tool call arguments: {arguments[-1]}\n") |
| 157 | + |
| 158 | + print("-" * 70) |
| 159 | + |
| 160 | + # Add tool call results to the conversation |
151 | 161 | messages.append({ |
152 | | - "role": "tool", |
153 | | - "content": result, |
154 | | - "tool_call_id": call.id, |
155 | | - "name": call.function.name |
| 162 | + "role": "assistant", |
| 163 | + "tool_calls": chat_completion.choices[0].message.tool_calls |
156 | 164 | }) |
157 | 165 |
|
158 | | -chat_completion_2 = client.chat.completions.create(messages=messages, |
159 | | - model=model, |
160 | | - tools=tools, |
161 | | - stream=False) |
162 | | -print("\n\n") |
163 | | -print(chat_completion_2) |
| 166 | + # Now, simulate a tool call |
| 167 | + available_tools = {"get_current_weather": get_current_weather} |
| 168 | + |
| 169 | + completion_tool_calls = chat_completion.choices[0].message.tool_calls |
| 170 | + for call in completion_tool_calls: |
| 171 | + tool_to_call = available_tools[call.function.name] |
| 172 | + args = json.loads(call.function.arguments) |
| 173 | + result = tool_to_call(**args) |
| 174 | + print("tool_to_call result: ", result) |
| 175 | + messages.append({ |
| 176 | + "role": "tool", |
| 177 | + "content": result, |
| 178 | + "tool_call_id": call.id, |
| 179 | + "name": call.function.name |
| 180 | + }) |
| 181 | + |
| 182 | + chat_completion_2 = client.chat.completions.create(messages=messages, |
| 183 | + model=model, |
| 184 | + tools=tools, |
| 185 | + stream=False) |
| 186 | + print("Chat completion2 results:") |
| 187 | + print(chat_completion_2) |
| 188 | + print("-" * 70) |
| 189 | + |
| 190 | + |
| 191 | +if __name__ == "__main__": |
| 192 | + main() |
0 commit comments