projectdavid 1.33.12__py3-none-any.whl → 1.33.13__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 projectdavid might be problematic. Click here for more details.

@@ -11,9 +11,15 @@ LOG = UtilsInterface.LoggingUtility()
11
11
 
12
12
 
13
13
  class SynchronousInferenceStream:
14
+ # ------------------------------------------------------------ #
15
+ # GLOBAL EVENT LOOP (single hidden thread for sync wrapper)
16
+ # ------------------------------------------------------------ #
14
17
  _GLOBAL_LOOP = asyncio.new_event_loop()
15
18
  asyncio.set_event_loop(_GLOBAL_LOOP)
16
19
 
20
+ # ------------------------------------------------------------ #
21
+ # Init / setup
22
+ # ------------------------------------------------------------ #
17
23
  def __init__(self, inference) -> None:
18
24
  self.inference_client = inference
19
25
  self.user_id: Optional[str] = None
@@ -32,6 +38,7 @@ class SynchronousInferenceStream:
32
38
  run_id: str,
33
39
  api_key: str,
34
40
  ) -> None:
41
+ """Populate IDs once, so callers only provide provider/model."""
35
42
  self.user_id = user_id
36
43
  self.thread_id = thread_id
37
44
  self.assistant_id = assistant_id
@@ -39,7 +46,10 @@ class SynchronousInferenceStream:
39
46
  self.run_id = run_id
40
47
  self.api_key = api_key
41
48
 
42
- def stream_chunks(
49
+ # ------------------------------------------------------------ #
50
+ # Core sync-to-async streaming wrapper
51
+ # ------------------------------------------------------------ #
52
+ def stream_chunks( # noqa: PLR0915
43
53
  self,
44
54
  provider: str,
45
55
  model: str,
@@ -48,9 +58,15 @@ class SynchronousInferenceStream:
48
58
  timeout_per_chunk: float = 280.0,
49
59
  suppress_fc: bool = True,
50
60
  ) -> Generator[dict, None, None]:
61
+ """
62
+ Sync generator that mirrors async `inference_client.stream_inference_response`
63
+ but (optionally) removes raw <fc> … </fc> output *and* JSON
64
+ `{"type": "function_call" …}` objects from the stream.
65
+ """
51
66
 
52
67
  resolved_api_key = api_key or self.api_key
53
68
 
69
+ # ---------- async inner generator -------------------------------- #
54
70
  async def _stream_chunks_async():
55
71
  async for chk in self.inference_client.stream_inference_response(
56
72
  provider=provider,
@@ -65,6 +81,7 @@ class SynchronousInferenceStream:
65
81
 
66
82
  agen = _stream_chunks_async().__aiter__()
67
83
 
84
+ # ---------- FC-suppressor plumbing -------------------------------- #
68
85
  if suppress_fc:
69
86
  _suppressor = FunctionCallSuppressor()
70
87
  _peek_gate = PeekGate(_suppressor)
@@ -72,11 +89,15 @@ class SynchronousInferenceStream:
72
89
  def _filter_text(txt: str) -> str:
73
90
  return _peek_gate.feed(txt)
74
91
 
92
+ LOG.debug("[SyncStream] Function-call suppression ACTIVE")
75
93
  else:
76
94
 
77
95
  def _filter_text(txt: str) -> str:
78
96
  return txt
79
97
 
98
+ LOG.debug("[SyncStream] Function-call suppression DISABLED")
99
+
100
+ # ---------- helper to flush residual buffered text ---------------- #
80
101
  def _drain_filters() -> Optional[dict]:
81
102
  if not suppress_fc:
82
103
  return None
@@ -97,18 +118,17 @@ class SynchronousInferenceStream:
97
118
  }
98
119
  return None
99
120
 
121
+ # ---------- main sync loop ---------------------------------------- #
100
122
  while True:
101
123
  try:
102
124
  chunk = self._GLOBAL_LOOP.run_until_complete(
103
125
  asyncio.wait_for(agen.__anext__(), timeout=timeout_per_chunk)
104
126
  )
105
127
 
106
- # Always attach run_id
128
+ # Always attach run_id for front-end helpers
107
129
  chunk["run_id"] = self.run_id
108
130
 
109
- # ------------------------------------------------------
110
- # allow status chunks to bypass suppression suppression
111
- # -------------------------------------------------------
131
+ # ----- bypass filters for status / code-exec related -------- #
112
132
  if chunk.get("type") == "status":
113
133
  yield chunk
114
134
  continue
@@ -124,9 +144,19 @@ class SynchronousInferenceStream:
124
144
  yield chunk
125
145
  continue
126
146
 
147
+ # ----- NEW: swallow raw JSON function_call objects ---------- #
148
+ if suppress_fc and chunk.get("type") == "function_call":
149
+ LOG.debug(
150
+ "[SyncStream] Swallowing JSON function_call chunk: %s",
151
+ chunk.get("name") or "<unnamed>",
152
+ )
153
+ continue
154
+
155
+ # ----- text-level suppression ------------------------------- #
127
156
  if isinstance(chunk.get("content"), str):
128
157
  chunk["content"] = _filter_text(chunk["content"])
129
158
  if chunk["content"] == "":
159
+ # Entire segment was inside <fc> … </fc>
130
160
  continue
131
161
 
132
162
  yield chunk
@@ -134,21 +164,26 @@ class SynchronousInferenceStream:
134
164
  except StopAsyncIteration:
135
165
  if tail := _drain_filters():
136
166
  yield tail
137
- LOG.info("Stream completed normally.")
167
+ LOG.info("[SyncStream] Stream completed normally.")
138
168
  break
139
169
 
140
170
  except asyncio.TimeoutError:
141
171
  if tail := _drain_filters():
142
172
  yield tail
143
- LOG.error("[TimeoutError] Chunk wait expired aborting stream.")
173
+ LOG.error("[SyncStream] Timeout waiting for next chunk.")
144
174
  break
145
175
 
146
- except Exception as exc:
176
+ except Exception as exc: # noqa: BLE001
147
177
  if tail := _drain_filters():
148
178
  yield tail
149
- LOG.error("Unexpected streaming error: %s", exc, exc_info=True)
179
+ LOG.error(
180
+ "[SyncStream] Unexpected streaming error: %s", exc, exc_info=True
181
+ )
150
182
  break
151
183
 
184
+ # ------------------------------------------------------------ #
185
+ # House-keeping
186
+ # ------------------------------------------------------------ #
152
187
  @classmethod
153
188
  def shutdown_loop(cls) -> None:
154
189
  if cls._GLOBAL_LOOP and not cls._GLOBAL_LOOP.is_closed():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: projectdavid
3
- Version: 1.33.12
3
+ Version: 1.33.13
4
4
  Summary: Python SDK for interacting with the Entities Assistant API.
5
5
  Author-email: Francis Neequaye Armah <francis.neequaye@projectdavid.co.uk>
6
6
  License: PolyForm Noncommercial License 1.0.0
@@ -16,7 +16,7 @@ projectdavid/clients/files_client.py,sha256=XkIDzbQFGDrd88taf0Kouc_4YJOPIYEHiIyW
16
16
  projectdavid/clients/inference_client.py,sha256=xz4ACPv5Tkis604QxO5mJX1inH_TGDfQP-31geETYpE,6609
17
17
  projectdavid/clients/messages_client.py,sha256=467xeIt3VYs6cG8-bl-eDRi_auWOPmfd5tSJDmQSJUI,17232
18
18
  projectdavid/clients/runs.py,sha256=-fXOq5L9w2efDPmZkNxb0s2yjl6oN0XN4_aLXqaeceo,25270
19
- projectdavid/clients/synchronous_inference_wrapper.py,sha256=mN5WAHmv0aRoeMIb7XPgv3cuqrMPzu378UsZ02jEvRY,5090
19
+ projectdavid/clients/synchronous_inference_wrapper.py,sha256=qh94rtNlLqgIxiA_ZbQ1ncOwQTi9aBj5os3sMExLh4E,7070
20
20
  projectdavid/clients/threads_client.py,sha256=ekzU5w14zftmtmFkiec3NC90Of-_KVSUY1qH9cmfSFg,6771
21
21
  projectdavid/clients/tools_client.py,sha256=GkCVOmwpAoPqVt6aYmH0G1HIFha3iEwR9IIf9teR0j8,11487
22
22
  projectdavid/clients/users_client.py,sha256=eCuUb9qvyH1GUFhZu6TRL9zdoK-qzHSs8-Vmrk_0mmg,13729
@@ -35,8 +35,8 @@ projectdavid/utils/monitor_launcher.py,sha256=3YAgJdeuaUvq3JGvpA4ymqFsAnk29nH5q9
35
35
  projectdavid/utils/peek_gate.py,sha256=5whMRnDOQjATRpThWDJkvY9ScXuJ7Sd_-9rvGgXeTAQ,2532
36
36
  projectdavid/utils/run_monitor.py,sha256=F_WkqIP-qnWH-4llIbileWWLfRj2Q1Cg-ni23SR1rec,3786
37
37
  projectdavid/utils/vector_search_formatter.py,sha256=YTe3HPGec26qGY7uxY8_GS8lc4QaN6aNXMzkl29nZpI,1735
38
- projectdavid-1.33.12.dist-info/licenses/LICENSE,sha256=_8yjiEGttpS284BkfhXxfERqTRZW_tUaHiBB0GTJTMg,4563
39
- projectdavid-1.33.12.dist-info/METADATA,sha256=NmKw2v_K20Uq-H0yEjxkDpAGdMi4wQdIjLrtP-Sthr8,11555
40
- projectdavid-1.33.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
41
- projectdavid-1.33.12.dist-info/top_level.txt,sha256=kil8GU4s7qYRfNnzGnFHhZnSNRSxgNG-J4HLgQMmMtw,13
42
- projectdavid-1.33.12.dist-info/RECORD,,
38
+ projectdavid-1.33.13.dist-info/licenses/LICENSE,sha256=_8yjiEGttpS284BkfhXxfERqTRZW_tUaHiBB0GTJTMg,4563
39
+ projectdavid-1.33.13.dist-info/METADATA,sha256=wFCKMGJBgK8yku6jOoE2IPsdB9-kfIGL1kBYF89yfNM,11555
40
+ projectdavid-1.33.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
41
+ projectdavid-1.33.13.dist-info/top_level.txt,sha256=kil8GU4s7qYRfNnzGnFHhZnSNRSxgNG-J4HLgQMmMtw,13
42
+ projectdavid-1.33.13.dist-info/RECORD,,