projectdavid 1.32.5__py3-none-any.whl → 1.32.6__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,12 +11,14 @@ LOG = UtilsInterface.LoggingUtility()
11
11
 
12
12
 
13
13
  class SynchronousInferenceStream:
14
+ """Wrap an async streaming generator and expose it synchronously."""
15
+
14
16
  _GLOBAL_LOOP = asyncio.new_event_loop()
15
17
  asyncio.set_event_loop(_GLOBAL_LOOP)
16
18
 
17
- # --------------------------------------------------------------
18
- # ctor / setup
19
- # --------------------------------------------------------------
19
+ # ------------------------------------------------------------------ #
20
+ # construction / setup
21
+ # ------------------------------------------------------------------ #
20
22
  def __init__(self, inference) -> None:
21
23
  self.inference_client = inference
22
24
  self.user_id: Optional[str] = None
@@ -42,9 +44,9 @@ class SynchronousInferenceStream:
42
44
  self.run_id = run_id
43
45
  self.api_key = api_key
44
46
 
45
- # --------------------------------------------------------------
47
+ # ------------------------------------------------------------------ #
46
48
  # main streaming entry-point
47
- # --------------------------------------------------------------
49
+ # ------------------------------------------------------------------ #
48
50
  def stream_chunks(
49
51
  self,
50
52
  provider: str,
@@ -54,6 +56,13 @@ class SynchronousInferenceStream:
54
56
  timeout_per_chunk: float = 280.0,
55
57
  suppress_fc: bool = True,
56
58
  ) -> Generator[dict, None, None]:
59
+ """
60
+ Yield provider chunks synchronously. When *suppress_fc* is True we
61
+
62
+ 1. completely drop top-level `type="function_call"` chunks, and
63
+ 2. scrub inline `<fc> … </fc>` sections inside text using the
64
+ PeekGate + FunctionCallSuppressor chain.
65
+ """
57
66
 
58
67
  resolved_api_key = api_key or self.api_key
59
68
 
@@ -71,33 +80,68 @@ class SynchronousInferenceStream:
71
80
 
72
81
  agen = _stream_chunks_async().__aiter__()
73
82
 
83
+ # ---------- build inline filter --------------------------------
84
+ if suppress_fc:
85
+ suppressor = FunctionCallSuppressor()
86
+ peek_gate = PeekGate(suppressor)
87
+
88
+ def _filter_text(txt: str) -> str:
89
+ return peek_gate.feed(txt)
90
+
91
+ else:
92
+
93
+ def _filter_text(txt: str) -> str: # no-op
94
+ return txt
95
+
96
+ # ---------- main loop ------------------------------------------
74
97
  while True:
75
98
  try:
76
99
  chunk = self._GLOBAL_LOOP.run_until_complete(
77
100
  asyncio.wait_for(agen.__anext__(), timeout=timeout_per_chunk)
78
101
  )
79
102
 
80
- # Suppress only actual top-level function_call chunks
103
+ # drop provider-labelled function_call objects
81
104
  if suppress_fc and chunk.get("type") == "function_call":
82
- LOG.debug("[SUPPRESSOR] blocked top-level function_call chunk")
105
+ LOG.debug("[SUPPRESSOR] stripped top-level function_call chunk")
83
106
  continue
84
107
 
85
- # Allow all other content implicitly
108
+ # never touch hot-code or code-interpreter file previews
109
+ if chunk.get("type") == "hot_code":
110
+ yield chunk
111
+ continue
112
+
113
+ if (
114
+ chunk.get("stream_type") == "code_execution"
115
+ and chunk.get("chunk", {}).get("type") == "code_interpreter_stream"
116
+ ):
117
+ yield chunk
118
+ continue
119
+
120
+ # ③ filter inline text (<fc> blocks) *only* when content is str
121
+ if isinstance(chunk.get("content"), str):
122
+ chunk["content"] = _filter_text(chunk["content"])
123
+ if chunk["content"] == "":
124
+ # Either the text is still in PeekGate’s buffer
125
+ # or it was fully suppressed – skip for now.
126
+ continue
127
+
86
128
  yield chunk
87
129
 
88
130
  except StopAsyncIteration:
89
131
  LOG.info("Stream completed normally.")
90
132
  break
91
133
  except asyncio.TimeoutError:
92
- LOG.error("[TimeoutError] Timeout occurred, stopping stream.")
134
+ LOG.error(
135
+ "[Timeout] chunk wait exceeded %.1f s – aborting", timeout_per_chunk
136
+ )
93
137
  break
94
- except Exception as e:
95
- LOG.error("Unexpected error during streaming completions: %s", e)
138
+ except Exception as exc: # pylint: disable=broad-except
139
+ LOG.error("Unexpected streaming error: %s", exc, exc_info=True)
96
140
  break
97
141
 
98
- # --------------------------------------------------------------
142
+ # ------------------------------------------------------------------ #
99
143
  # housekeeping
100
- # --------------------------------------------------------------
144
+ # ------------------------------------------------------------------ #
101
145
  @classmethod
102
146
  def shutdown_loop(cls) -> None:
103
147
  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.32.5
3
+ Version: 1.32.6
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
@@ -15,7 +15,7 @@ projectdavid/clients/files_client.py,sha256=XkIDzbQFGDrd88taf0Kouc_4YJOPIYEHiIyW
15
15
  projectdavid/clients/inference_client.py,sha256=xz4ACPv5Tkis604QxO5mJX1inH_TGDfQP-31geETYpE,6609
16
16
  projectdavid/clients/messages_client.py,sha256=467xeIt3VYs6cG8-bl-eDRi_auWOPmfd5tSJDmQSJUI,17232
17
17
  projectdavid/clients/runs.py,sha256=-fXOq5L9w2efDPmZkNxb0s2yjl6oN0XN4_aLXqaeceo,25270
18
- projectdavid/clients/synchronous_inference_wrapper.py,sha256=S0m-8lI9s4jk11n3CkK7msG-tIDknL56Mj3wIw5DKds,3682
18
+ projectdavid/clients/synchronous_inference_wrapper.py,sha256=msshrx_sJxi0Zn-RJpLTPF1HImK7FFHNBTF9m-g2kKE,5463
19
19
  projectdavid/clients/threads_client.py,sha256=ekzU5w14zftmtmFkiec3NC90Of-_KVSUY1qH9cmfSFg,6771
20
20
  projectdavid/clients/tools_client.py,sha256=GkCVOmwpAoPqVt6aYmH0G1HIFha3iEwR9IIf9teR0j8,11487
21
21
  projectdavid/clients/users_client.py,sha256=eCuUb9qvyH1GUFhZu6TRL9zdoK-qzHSs8-Vmrk_0mmg,13729
@@ -34,8 +34,8 @@ projectdavid/utils/monitor_launcher.py,sha256=3YAgJdeuaUvq3JGvpA4ymqFsAnk29nH5q9
34
34
  projectdavid/utils/peek_gate.py,sha256=5whMRnDOQjATRpThWDJkvY9ScXuJ7Sd_-9rvGgXeTAQ,2532
35
35
  projectdavid/utils/run_monitor.py,sha256=F_WkqIP-qnWH-4llIbileWWLfRj2Q1Cg-ni23SR1rec,3786
36
36
  projectdavid/utils/vector_search_formatter.py,sha256=YTe3HPGec26qGY7uxY8_GS8lc4QaN6aNXMzkl29nZpI,1735
37
- projectdavid-1.32.5.dist-info/licenses/LICENSE,sha256=_8yjiEGttpS284BkfhXxfERqTRZW_tUaHiBB0GTJTMg,4563
38
- projectdavid-1.32.5.dist-info/METADATA,sha256=B783XTa8MFgSdxwkl5DMnkUbOOOs-smWtBl2OEsL_qg,10781
39
- projectdavid-1.32.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
40
- projectdavid-1.32.5.dist-info/top_level.txt,sha256=kil8GU4s7qYRfNnzGnFHhZnSNRSxgNG-J4HLgQMmMtw,13
41
- projectdavid-1.32.5.dist-info/RECORD,,
37
+ projectdavid-1.32.6.dist-info/licenses/LICENSE,sha256=_8yjiEGttpS284BkfhXxfERqTRZW_tUaHiBB0GTJTMg,4563
38
+ projectdavid-1.32.6.dist-info/METADATA,sha256=pz7BV3J79Ot0hDnTo0jEBPSARuUo-ohc3FAVEZh2-3Q,10781
39
+ projectdavid-1.32.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
40
+ projectdavid-1.32.6.dist-info/top_level.txt,sha256=kil8GU4s7qYRfNnzGnFHhZnSNRSxgNG-J4HLgQMmMtw,13
41
+ projectdavid-1.32.6.dist-info/RECORD,,