meshagent-openai 0.0.3__py3-none-any.whl → 0.0.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of meshagent-openai might be problematic. Click here for more details.

@@ -4,7 +4,7 @@ from meshagent.api import WebSocketClientProtocol, RoomClient, RoomException
4
4
  from meshagent.tools.blob import Blob, BlobStorage
5
5
  from meshagent.tools import Toolkit, ToolContext, Tool
6
6
  from meshagent.api.messaging import Response, LinkResponse, FileResponse, JsonResponse, TextResponse, EmptyResponse
7
- from meshagent.agents.schema import prompt_schema
7
+ from meshagent.api.schema_util import prompt_schema
8
8
  from meshagent.agents.adapter import ToolResponseAdapter, LLMAdapter
9
9
  from uuid import uuid4
10
10
  import json
@@ -198,7 +198,7 @@ class OpenAICompletionsToolResponseAdapter(ToolResponseAdapter):
198
198
  else:
199
199
  raise Exception("unexpected return type: {type}".format(type=type(response)))
200
200
 
201
- async def append_messages(self, *, context: AgentChatContext, tool_call: Any, room: RoomClient, response: Response) -> list:
201
+ async def create_messages(self, *, context: AgentChatContext, tool_call: Any, room: RoomClient, response: Response) -> list:
202
202
 
203
203
  message = {
204
204
  "role" : "tool",
@@ -209,7 +209,7 @@ class OpenAICompletionsToolResponseAdapter(ToolResponseAdapter):
209
209
 
210
210
  room.developer.log_nowait(type="llm.message", data={ "context" : context.id, "participant_id" : room.local_participant.id, "participant_name" : room.local_participant.get_attribute("name"), "message" : message })
211
211
 
212
- context.messages.append(message)
212
+ return [ message ]
213
213
 
214
214
 
215
215
 
@@ -330,16 +330,17 @@ class OpenAICompletionsAdapter(LLMAdapter):
330
330
  )
331
331
  tool_response = await tool_bundle.execute(context=tool_context, tool_call=tool_call)
332
332
  logger.info(f"tool response {tool_response}")
333
- await tool_adapter.append_messages(context=context, tool_call=tool_call, room=room, response=tool_response)
333
+ return await tool_adapter.create_messages(context=context, tool_call=tool_call, room=room, response=tool_response)
334
+
334
335
  except Exception as e:
335
336
  logger.error(f"unable to complete tool call {tool_call}", exc_info=e)
336
337
  room.developer.log_nowait(type="llm.error", data={ "participant_id" : room.local_participant.id, "participant_name" : room.local_participant.get_attribute("name"), "error" : f"{e}" })
337
338
 
338
- return {
339
+ return [{
339
340
  "role" : "tool",
340
341
  "content" : json.dumps({"error":f"unable to complete tool call: {e}"}),
341
342
  "tool_call_id" : tool_call.id,
342
- }
343
+ }]
343
344
 
344
345
 
345
346
  for tool_call in message.tool_calls:
@@ -3,8 +3,8 @@ from meshagent.agents.agent import Agent, AgentChatContext, AgentCallContext
3
3
  from meshagent.api import WebSocketClientProtocol, RoomClient, RoomException
4
4
  from meshagent.tools.blob import Blob, BlobStorage
5
5
  from meshagent.tools import Toolkit, ToolContext, Tool
6
- from meshagent.api.messaging import Response, LinkResponse, FileResponse, JsonResponse, TextResponse, EmptyResponse
7
- from meshagent.agents.schema import prompt_schema
6
+ from meshagent.api.messaging import Response, LinkResponse, FileResponse, JsonResponse, TextResponse, EmptyResponse, RawOutputs
7
+ from meshagent.api.schema_util import prompt_schema
8
8
  from meshagent.agents.adapter import ToolResponseAdapter, LLMAdapter
9
9
  from uuid import uuid4
10
10
  import json
@@ -12,14 +12,13 @@ from jsonschema import validate
12
12
  from typing import List, Dict
13
13
 
14
14
  from openai import AsyncOpenAI, APIStatusError, NOT_GIVEN
15
- from openai.types.chat import ChatCompletionMessageToolCall
16
- from openai.types.responses import ResponseFunctionToolCall
15
+ from openai.types.responses import ResponseFunctionToolCall, ResponseStreamEvent
17
16
 
18
17
  from copy import deepcopy
19
18
  from abc import abstractmethod, ABC
20
19
  import os
21
20
  import jsonschema
22
- from typing import Optional, Any
21
+ from typing import Optional, Any, Callable
23
22
 
24
23
  import logging
25
24
  import re
@@ -65,12 +64,13 @@ class ResponsesToolBundle:
65
64
  self._toolkits = toolkits
66
65
  self._executors = dict[str, Toolkit]()
67
66
  self._safe_names = {}
67
+ self._tools_by_name = {}
68
68
 
69
69
  open_ai_tools = []
70
70
 
71
71
  for toolkit in toolkits:
72
72
  for v in toolkit.tools:
73
-
73
+
74
74
  k = v.name
75
75
 
76
76
  name = safe_tool_name(k)
@@ -81,22 +81,29 @@ class ResponsesToolBundle:
81
81
  self._executors[k] = toolkit
82
82
 
83
83
  self._safe_names[name] = k
84
+ self._tools_by_name[name] = v
85
+
86
+ if v.name != "computer_call":
87
+
88
+ fn = {
89
+ "type" : "function",
90
+ "name" : name,
91
+ "description" : v.description,
92
+ "parameters" : {
93
+ **v.input_schema,
94
+ },
95
+ "strict": True,
96
+ }
84
97
 
85
- fn = {
86
- "type" : "function",
87
- "name" : name,
88
- "description" : v.description,
89
- "parameters" : {
90
- **v.input_schema,
91
- },
92
- "strict": True,
93
- }
94
98
 
99
+ if v.defs != None:
100
+ fn["parameters"]["$defs"] = v.defs
101
+
102
+ open_ai_tools.append(fn)
95
103
 
96
- if v.defs != None:
97
- fn["parameters"]["$defs"] = v.defs
98
-
99
- open_ai_tools.append(fn)
104
+ else:
105
+
106
+ open_ai_tools.append(v.options)
100
107
 
101
108
  if len(open_ai_tools) == 0:
102
109
  open_ai_tools = None
@@ -127,7 +134,10 @@ class ResponsesToolBundle:
127
134
  except Exception as e:
128
135
  logger.error("failed calling %s %s", tool_call.id, name, exc_info=e)
129
136
  raise
130
-
137
+
138
+ def get_tool(self, name: str) -> Tool | None:
139
+ return self._tools_by_name.get(name, None)
140
+
131
141
  def contains(self, name: str) -> bool:
132
142
  return name in self._open_ai_tools
133
143
 
@@ -150,7 +160,8 @@ class OpenAIResponsesToolResponseAdapter(ToolResponseAdapter):
150
160
  "url" : response.url,
151
161
  })
152
162
 
153
- elif isinstance(response, JsonResponse):
163
+ elif isinstance(response, JsonResponse):
164
+
154
165
  return json.dumps(response.json)
155
166
 
156
167
  elif isinstance(response, TextResponse):
@@ -193,34 +204,45 @@ class OpenAIResponsesToolResponseAdapter(ToolResponseAdapter):
193
204
  else:
194
205
  raise Exception("unexpected return type: {type}".format(type=type(response)))
195
206
 
196
- async def append_messages(self, *, context: AgentChatContext, tool_call: ResponseFunctionToolCall, room: RoomClient, response: Response) -> list:
207
+ async def create_messages(self, *, context: AgentChatContext, tool_call: ResponseFunctionToolCall, room: RoomClient, response: Response) -> list:
197
208
 
198
- message = {
199
- "output" : await self.to_plain_text(room=room, response=response),
200
- "call_id" : tool_call.call_id,
201
- "type" : "function_call_output"
202
- }
203
-
209
+ if isinstance(response, RawOutputs):
210
+
211
+ for output in response.outputs:
204
212
 
205
- room.developer.log_nowait(type="llm.message", data={ "context" : context.id, "participant_id" : room.local_participant.id, "participant_name" : room.local_participant.get_attribute("name"), "message" : message })
206
-
207
- context.messages.append(message)
213
+ room.developer.log_nowait(type="llm.message", data={ "context" : context.id, "participant_id" : room.local_participant.id, "participant_name" : room.local_participant.get_attribute("name"), "message" : output })
214
+
215
+ return response.outputs
216
+ else:
217
+ output = await self.to_plain_text(room=room, response=response)
218
+
219
+ message = {
220
+ "output" : output,
221
+ "call_id" : tool_call.call_id,
222
+ "type" : "function_call_output"
223
+ }
208
224
 
209
225
 
226
+ room.developer.log_nowait(type="llm.message", data={ "context" : context.id, "participant_id" : room.local_participant.id, "participant_name" : room.local_participant.get_attribute("name"), "message" : message })
227
+
228
+ return [ message ]
229
+
230
+
210
231
 
211
232
 
212
- class OpenAIResponsesAdapter(LLMAdapter):
233
+ class OpenAIResponsesAdapter(LLMAdapter[ResponsesToolBundle]):
213
234
  def __init__(self,
214
235
  model: str = os.getenv("OPENAI_MODEL"),
215
236
  parallel_tool_calls : Optional[bool] = None,
216
237
  client: Optional[AsyncOpenAI] = None,
217
238
  reasoning_effort: Optional[str] = None,
239
+ retries : int = 10,
218
240
  ):
219
241
  self._model = model
220
242
  self._parallel_tool_calls = parallel_tool_calls
221
243
  self._client = client
222
244
  self._reasoning_effort = reasoning_effort
223
-
245
+ self._retries = retries
224
246
 
225
247
  def create_chat_context(self):
226
248
  system_role = "system"
@@ -228,6 +250,8 @@ class OpenAIResponsesAdapter(LLMAdapter):
228
250
  system_role = "developer"
229
251
  elif self._model.startswith("o3"):
230
252
  system_role = "developer"
253
+ elif self._model.startswith("computer-use"):
254
+ system_role = "developer"
231
255
 
232
256
  context = AgentChatContext(
233
257
  system_role=system_role
@@ -235,6 +259,40 @@ class OpenAIResponsesAdapter(LLMAdapter):
235
259
 
236
260
  return context
237
261
 
262
+ async def check_for_termination(self, *, context: AgentChatContext, room: RoomClient) -> bool:
263
+
264
+ if len(context.previous_messages) > 0:
265
+ last_message = context.previous_messages[-1]
266
+ logger.info(f"last_message {last_message}")
267
+
268
+ for message in context.messages:
269
+
270
+ if message.get("type", "message") != "message":
271
+ logger.info(f"found {message.get("type", "message")}")
272
+
273
+ return False
274
+
275
+ return True
276
+
277
+ def _get_client(self, *, room: RoomClient) -> AsyncOpenAI:
278
+ if self._client != None:
279
+ openai = self._client
280
+ else:
281
+ token : str = room.protocol.token
282
+ url : str = room.room_url
283
+
284
+ room_proxy_url = f"{url}/v1"
285
+
286
+ openai=AsyncOpenAI(
287
+ api_key=token,
288
+ base_url=room_proxy_url,
289
+ default_headers={
290
+ "Meshagent-Session" : room.session_id
291
+ }
292
+ )
293
+
294
+ return openai
295
+
238
296
  # Takes the current chat context, executes a completion request and processes the response.
239
297
  # If a tool calls are requested, invokes the tools, processes the tool calls results, and appends the tool call results to the context
240
298
  async def next(self,
@@ -244,28 +302,14 @@ class OpenAIResponsesAdapter(LLMAdapter):
244
302
  toolkits: Toolkit,
245
303
  tool_adapter: Optional[ToolResponseAdapter] = None,
246
304
  output_schema: Optional[dict] = None,
305
+ event_handler: Optional[Callable[[ResponseStreamEvent],None]] = None
247
306
  ):
248
307
  if tool_adapter == None:
249
308
  tool_adapter = OpenAIResponsesToolResponseAdapter()
250
309
 
251
310
  try:
252
- if self._client != None:
253
- openai = self._client
254
- else:
255
-
256
-
257
- token : str = room.protocol.token
258
- url : str = room.room_url
259
-
260
- room_proxy_url = f"{url}/v1"
261
311
 
262
- openai=AsyncOpenAI(
263
- api_key=token,
264
- base_url=room_proxy_url,
265
- default_headers={
266
- "Meshagent-Session" : room.session_id
267
- }
268
- )
312
+ openai = self._get_client(room=room)
269
313
 
270
314
  tool_bundle = ResponsesToolBundle(toolkits=[
271
315
  *toolkits,
@@ -276,17 +320,23 @@ class OpenAIResponsesAdapter(LLMAdapter):
276
320
  logger.info("OpenAI Tools: %s", json.dumps(open_ai_tools))
277
321
  else:
278
322
  logger.info("OpenAI Tools: Empty")
323
+ open_ai_tools = NOT_GIVEN
279
324
 
280
325
  response_schema = output_schema
281
326
  response_name = "response"
282
327
 
283
-
284
- while context.messages[-1].get("role") != "assistant" if context.messages else True:
328
+
329
+ while True:
330
+
285
331
  logger.info("model: %s, context: %s, output_schema: %s", self._model, context.messages, output_schema)
286
332
  ptc = self._parallel_tool_calls
287
333
  extra = {}
288
334
  if ptc != None and self._model.startswith("o") == False:
289
335
  extra["parallel_tool_calls"] = ptc
336
+
337
+ trunc = NOT_GIVEN
338
+ if self._model == "computer-use-preview":
339
+ trunc = "auto"
290
340
 
291
341
  text = NOT_GIVEN
292
342
  if output_schema != None:
@@ -305,19 +355,36 @@ class OpenAIResponsesAdapter(LLMAdapter):
305
355
  "effort" : self._reasoning_effort
306
356
  }
307
357
 
308
- response = await openai.responses.create(
309
- model = self._model,
310
- input = context.messages,
311
- tools = open_ai_tools,
312
- text = text,
313
- reasoning=reasoning,
314
- )
358
+ previous_response_id = NOT_GIVEN
359
+ if context.previous_response_id != None:
360
+ previous_response_id = context.previous_response_id
315
361
 
316
- room.developer.log_nowait(type="llm.message", data={ "context" : context.id, "participant_id" : room.local_participant.id, "participant_name" : room.local_participant.get_attribute("name"), "response" : response.to_dict() })
362
+ stream = event_handler != None
317
363
 
318
- for message in response.output:
319
- context.messages.append(message)
364
+ for i in range(self._retries + 1):
365
+ if range == self._retries:
366
+ raise RoomException("exceeded maximum attempts calling openai")
367
+ try:
368
+ response = await openai.responses.create(
369
+ stream=stream,
370
+ model = self._model,
371
+ input = context.messages,
372
+ tools = open_ai_tools,
373
+ text = text,
374
+ previous_response_id=previous_response_id,
375
+ reasoning=reasoning,
376
+ truncation=trunc
377
+ )
378
+ break
379
+ except Exception as e:
380
+ logger.error(f"error calling openai attempt: {i+1}", exc_info=e)
381
+ if i == self._retries:
382
+ raise
320
383
 
384
+
385
+ async def handle_message(message):
386
+
387
+
321
388
  if message.type == "function_call":
322
389
 
323
390
  tasks = []
@@ -330,56 +397,139 @@ class OpenAIResponsesAdapter(LLMAdapter):
330
397
  )
331
398
  tool_response = await tool_bundle.execute(context=tool_context, tool_call=tool_call)
332
399
  logger.info(f"tool response {tool_response}")
333
- await tool_adapter.append_messages(context=context, tool_call=tool_call, room=room, response=tool_response)
400
+ return await tool_adapter.create_messages(context=context, tool_call=tool_call, room=room, response=tool_response)
334
401
  except Exception as e:
335
402
  logger.error(f"unable to complete tool call {tool_call}", exc_info=e)
336
403
  room.developer.log_nowait(type="llm.error", data={ "participant_id" : room.local_participant.id, "participant_name" : room.local_participant.get_attribute("name"), "error" : f"{e}" })
337
404
 
338
- return {
405
+ return [{
339
406
  "output" : json.dumps({"error":f"unable to complete tool call: {e}"}),
340
407
  "call_id" : tool_call.call_id,
341
408
  "type" : "function_call_output"
342
- }
409
+ }]
343
410
 
344
411
 
345
412
  tasks.append(asyncio.create_task(do_tool_call(message)))
346
413
 
347
414
  results = await asyncio.gather(*tasks)
348
415
 
416
+ all_results = []
349
417
  for result in results:
350
- if result != None:
351
- room.developer.log_nowait(type="llm.message", data={ "context" : context.id, "participant_id" : room.local_participant.id, "participant_name" : room.local_participant.get_attribute("name"), "message" : result })
352
- context.messages.append(result)
353
-
354
- elif response.output_text != None:
418
+ room.developer.log_nowait(type="llm.message", data={ "context" : context.id, "participant_id" : room.local_participant.id, "participant_name" : room.local_participant.get_attribute("name"), "message" : result })
419
+ all_results.extend(result)
420
+
421
+ return all_results, False
355
422
 
356
- content = response.output_text
423
+ elif message.type == "computer_call" and tool_bundle.get_tool("computer_call"):
424
+ tool_context = ToolContext(
425
+ room=room,
426
+ caller=room.local_participant,
427
+ )
428
+ outputs = (await tool_bundle.get_tool("computer_call").execute(context=tool_context, arguments=message.to_dict(mode="json"))).outputs
429
+
430
+ return outputs, False
431
+
432
+ elif message.type == "reasoning":
433
+ reasoning = tool_bundle.get_tool("reasoning_tool")
434
+ if reasoning != None:
435
+ await tool_bundle.get_tool("reasoning_tool").execute(context=tool_context, arguments=message.to_dict(mode="json"))
357
436
 
358
- logger.info("RESPONSE FROM OPENAI %s", content)
359
- if response_schema == None:
360
- return content
437
+ elif message.type == "message":
361
438
 
362
- # First try to parse the result
363
- try:
364
- full_response = json.loads(content)
365
- # sometimes open ai packs two JSON chunks seperated by newline, check if that's why we couldn't parse
366
- except json.decoder.JSONDecodeError as e:
367
- for part in content.splitlines():
368
- if len(part.strip()) > 0:
369
- full_response = json.loads(part)
439
+ contents = message.content
440
+ if response_schema == None:
441
+ return [], False
442
+ else:
443
+ for content in contents:
444
+ # First try to parse the result
445
+ try:
446
+ full_response = json.loads(content.text)
447
+ # sometimes open ai packs two JSON chunks seperated by newline, check if that's why we couldn't parse
448
+ except json.decoder.JSONDecodeError as e:
449
+ for part in content.text.splitlines():
450
+ if len(part.strip()) > 0:
451
+ full_response = json.loads(part)
452
+
453
+ try:
454
+ self.validate(response=full_response, output_schema=response_schema)
455
+ except Exception as e:
456
+ logger.error("recieved invalid response, retrying", exc_info=e)
457
+ error = { "role" : "user", "content" : "encountered a validation error with the output: {error}".format(error=e)}
458
+ room.developer.log_nowait(type="llm.message", data={ "context" : message.id, "participant_id" : room.local_participant.id, "participant_name" : room.local_participant.get_attribute("name"), "message" : error })
459
+ context.messages.append(error)
460
+ continue
370
461
 
371
- try:
372
- self.validate(response=full_response, output_schema=response_schema)
373
- except Exception as e:
374
- logger.error("recieved invalid response, retrying", exc_info=e)
375
- error = { "role" : "user", "content" : "encountered a validation error with the output: {error}".format(error=e)}
376
- room.developer.log_nowait(type="llm.message", data={ "context" : context.id, "participant_id" : room.local_participant.id, "participant_name" : room.local_participant.get_attribute("name"), "message" : error })
377
- context.messages.append(error)
378
- continue
379
-
380
- return full_response
462
+ return [ full_response ], True
381
463
  else:
382
464
  raise RoomException("Unexpected response from OpenAI {response}".format(response=message))
465
+
466
+ return [], False
467
+
468
+ if stream == False:
469
+ room.developer.log_nowait(type="llm.message", data={ "context" : context.id, "participant_id" : room.local_participant.id, "participant_name" : room.local_participant.get_attribute("name"), "response" : response.to_dict() })
470
+
471
+ context.create_response(response.id)
472
+
473
+ final_outputs = []
474
+
475
+ for message in response.output:
476
+ outputs, done = await handle_message(message=message)
477
+ if done:
478
+ final_outputs.extend(outputs)
479
+ else:
480
+ for output in outputs:
481
+ context.messages.append(output)
482
+
483
+ if len(final_outputs) > 0:
484
+
485
+ return final_outputs[0]
486
+
487
+ else:
488
+
489
+ final_outputs = []
490
+ all_outputs = []
491
+ async for e in response:
492
+
493
+ event : ResponseStreamEvent = e
494
+
495
+ event_handler(event)
496
+
497
+ if event.type == "response.completed":
498
+ context.create_response(event.response.id)
499
+
500
+ context.messages.extend(all_outputs)
501
+
502
+ term = await self.check_for_termination(context=context, room=room)
503
+ if term:
504
+ text = ""
505
+ for output in event.response.output:
506
+ if output.type == "message":
507
+ for content in output.content:
508
+ text += content.text
509
+
510
+ return text
511
+
512
+
513
+ all_outputs = []
514
+
515
+ elif event.type == "response.output_item.done":
516
+
517
+ context.previous_messages.append(event.item.to_dict())
518
+
519
+ outputs, done = await handle_message(message=event.item)
520
+ if done:
521
+ final_outputs.extend(outputs)
522
+ else:
523
+ for output in outputs:
524
+ all_outputs.append(output)
525
+
526
+ if len(final_outputs) > 0:
527
+
528
+ return final_outputs[0]
529
+
530
+
531
+
532
+
383
533
  except APIStatusError as e:
384
534
  raise RoomException(f"Error from OpenAI: {e}")
385
535
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: meshagent-openai
3
- Version: 0.0.3
3
+ Version: 0.0.4
4
4
  Summary: OpenAI Building Blocks for Meshagent
5
5
  Home-page:
6
6
  License: Apache License 2.0
@@ -14,9 +14,9 @@ Requires-Dist: pyjwt>=2.0.0
14
14
  Requires-Dist: pytest>=8.3.4
15
15
  Requires-Dist: pytest-asyncio>=0.24.0
16
16
  Requires-Dist: openai>=1.66.2
17
- Requires-Dist: meshagent-api>=0.0.3
18
- Requires-Dist: meshagent-agents>=0.0.3
19
- Requires-Dist: meshagent-tools>=0.0.3
17
+ Requires-Dist: meshagent-api>=0.0.4
18
+ Requires-Dist: meshagent-agents>=0.0.4
19
+ Requires-Dist: meshagent-tools>=0.0.4
20
20
  Dynamic: description-content-type
21
21
  Dynamic: license
22
22
  Dynamic: project-url
@@ -0,0 +1,9 @@
1
+ meshagent/openai/__init__.py,sha256=qAqthmkQBsTqmrnVbtGOeaWCz9o5N48uEUCX7irzEsg,141
2
+ meshagent/openai/tools/__init__.py,sha256=RBU_J4qRDuBaaUdi6jpgpuMlIbvT30QmTBrZrYLwsUU,185
3
+ meshagent/openai/tools/completions_adapter.py,sha256=I74OC6JMbGb_C7qCYc0lWpJPs3uwuX9TfIDyn9Jou6U,15340
4
+ meshagent/openai/tools/responses_adapter.py,sha256=WGUCHYXq_ZzvjjUOlD59G0lazRSntQqg6BgU7N18W5M,21766
5
+ meshagent_openai-0.0.4.dist-info/LICENSE,sha256=eTt0SPW-sVNdkZe9PS_S8WfCIyLjRXRl7sUBWdlteFg,10254
6
+ meshagent_openai-0.0.4.dist-info/METADATA,sha256=MVMIQmzR7Vi_wXmNDvFOyoh-JzzYQh-48YMce6tYB2A,752
7
+ meshagent_openai-0.0.4.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
8
+ meshagent_openai-0.0.4.dist-info/top_level.txt,sha256=GlcXnHtRP6m7zlG3Df04M35OsHtNXy_DY09oFwWrH74,10
9
+ meshagent_openai-0.0.4.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- meshagent/openai/__init__.py,sha256=qAqthmkQBsTqmrnVbtGOeaWCz9o5N48uEUCX7irzEsg,141
2
- meshagent/openai/tools/__init__.py,sha256=RBU_J4qRDuBaaUdi6jpgpuMlIbvT30QmTBrZrYLwsUU,185
3
- meshagent/openai/tools/completions_adapter.py,sha256=sotgpBusJ-pkTOLWqvavokit3bysYBj4nNBat4PFnBw,15319
4
- meshagent/openai/tools/responses_adapter.py,sha256=ybvIMRpIrwDr3O1CW7m_Efma926IqFv5jPawZX-WYtQ,15609
5
- meshagent_openai-0.0.3.dist-info/LICENSE,sha256=eTt0SPW-sVNdkZe9PS_S8WfCIyLjRXRl7sUBWdlteFg,10254
6
- meshagent_openai-0.0.3.dist-info/METADATA,sha256=vgZd2DmRaQAu8cokGl9N6Jn6BFE88kqoNbHKHBC0rP4,752
7
- meshagent_openai-0.0.3.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
8
- meshagent_openai-0.0.3.dist-info/top_level.txt,sha256=GlcXnHtRP6m7zlG3Df04M35OsHtNXy_DY09oFwWrH74,10
9
- meshagent_openai-0.0.3.dist-info/RECORD,,