dasein-core 0.2.10__py3-none-any.whl → 0.2.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.
- dasein/api.py +155 -6
- {dasein_core-0.2.10.dist-info → dasein_core-0.2.13.dist-info}/METADATA +1 -1
- {dasein_core-0.2.10.dist-info → dasein_core-0.2.13.dist-info}/RECORD +6 -6
- {dasein_core-0.2.10.dist-info → dasein_core-0.2.13.dist-info}/WHEEL +0 -0
- {dasein_core-0.2.10.dist-info → dasein_core-0.2.13.dist-info}/licenses/LICENSE +0 -0
- {dasein_core-0.2.10.dist-info → dasein_core-0.2.13.dist-info}/top_level.txt +0 -0
dasein/api.py
CHANGED
@@ -881,9 +881,17 @@ class CognateProxy:
|
|
881
881
|
# Initialize KPI tracking
|
882
882
|
self._last_run_kpis = None
|
883
883
|
|
884
|
+
# Initialize wrapped LLM (will be set by _wrap_agent_llm if applicable)
|
885
|
+
self._wrapped_llm = None
|
886
|
+
|
884
887
|
# Wrap the agent's LLM with our trace capture wrapper
|
885
888
|
self._wrap_agent_llm()
|
886
889
|
|
890
|
+
# CRITICAL: Update langgraph_params to use wrapped LLM for recreation
|
891
|
+
if self._is_langgraph and self._langgraph_params and self._wrapped_llm:
|
892
|
+
print(f" [DASEIN][WRAPPER] Updating langgraph_params to use wrapped LLM")
|
893
|
+
self._langgraph_params['model'] = self._wrapped_llm
|
894
|
+
|
887
895
|
# Inject universal dead-letter tool
|
888
896
|
self._inject_deadletter_tool()
|
889
897
|
|
@@ -1680,7 +1688,69 @@ Follow these rules when planning your actions."""
|
|
1680
1688
|
self._deadletter_fn = None
|
1681
1689
|
|
1682
1690
|
def _wrap_agent_llm(self):
|
1683
|
-
"""
|
1691
|
+
"""Wrap LLM instance (for SQL agent callbacks) AND monkey-patch (for Pipecleaner)."""
|
1692
|
+
try:
|
1693
|
+
# STEP 1: Wrap the main agent LLM with DaseinLLMWrapper (captures all _generate calls)
|
1694
|
+
# This is critical for SQL agents where callbacks don't propagate properly
|
1695
|
+
llm = self._find_llm_recursively(self._agent, max_depth=5)
|
1696
|
+
if llm:
|
1697
|
+
wrapped_llm = DaseinLLMWrapper(llm, self._callback_handler, verbose=self._verbose)
|
1698
|
+
# Replace the original LLM with our wrapped version
|
1699
|
+
self._replace_llm_in_structure(self._agent, llm, wrapped_llm, max_depth=5)
|
1700
|
+
self._wrapped_llm = wrapped_llm
|
1701
|
+
self._vprint(f"[DASEIN][WRAPPER] Successfully wrapped {type(llm).__name__} LLM")
|
1702
|
+
else:
|
1703
|
+
self._vprint(f"[DASEIN][WRAPPER] Could not find any LLM in agent structure")
|
1704
|
+
self._wrapped_llm = None
|
1705
|
+
|
1706
|
+
# STEP 2: Monkey-patch LLM classes for Pipecleaner deduplication
|
1707
|
+
# This is critical for research agents with Summary calls that need deduplication
|
1708
|
+
self._monkey_patch_llm_classes()
|
1709
|
+
|
1710
|
+
except Exception as e:
|
1711
|
+
self._vprint(f"[DASEIN][WRAPPER] Failed to wrap agent LLM: {e}")
|
1712
|
+
import traceback
|
1713
|
+
traceback.print_exc()
|
1714
|
+
self._wrapped_llm = None
|
1715
|
+
|
1716
|
+
def _replace_llm_in_structure(self, obj, original_llm, wrapped_llm, max_depth=5, path=""):
|
1717
|
+
"""Replace the original LLM with wrapped LLM in the structure."""
|
1718
|
+
if max_depth <= 0:
|
1719
|
+
return
|
1720
|
+
|
1721
|
+
# Special handling for RunnableSequence - check steps
|
1722
|
+
if hasattr(obj, 'steps') and hasattr(obj, '__iter__'):
|
1723
|
+
for i, step in enumerate(obj.steps):
|
1724
|
+
if step is original_llm:
|
1725
|
+
self._vprint(f"[DASEIN][WRAPPER] Replacing LLM at {path}.steps[{i}]")
|
1726
|
+
obj.steps[i] = wrapped_llm
|
1727
|
+
return
|
1728
|
+
# Check if step has bound attribute (RunnableBinding)
|
1729
|
+
if hasattr(step, 'bound') and step.bound is original_llm:
|
1730
|
+
self._vprint(f"[DASEIN][WRAPPER] Replacing LLM at {path}.steps[{i}].bound")
|
1731
|
+
step.bound = wrapped_llm
|
1732
|
+
return
|
1733
|
+
# Recursively search in the step
|
1734
|
+
self._replace_llm_in_structure(step, original_llm, wrapped_llm, max_depth - 1, f"{path}.steps[{i}]")
|
1735
|
+
|
1736
|
+
# Search in attributes
|
1737
|
+
for attr_name in dir(obj):
|
1738
|
+
if attr_name.startswith('_'):
|
1739
|
+
continue
|
1740
|
+
try:
|
1741
|
+
attr_value = getattr(obj, attr_name)
|
1742
|
+
if attr_value is original_llm:
|
1743
|
+
self._vprint(f"[DASEIN][WRAPPER] Replacing LLM at {path}.{attr_name}")
|
1744
|
+
setattr(obj, attr_name, wrapped_llm)
|
1745
|
+
return
|
1746
|
+
# Recursively search in the attribute
|
1747
|
+
if hasattr(attr_value, '__dict__') or hasattr(attr_value, '__iter__'):
|
1748
|
+
self._replace_llm_in_structure(attr_value, original_llm, wrapped_llm, max_depth - 1, f"{path}.{attr_name}")
|
1749
|
+
except:
|
1750
|
+
continue
|
1751
|
+
|
1752
|
+
def _monkey_patch_llm_classes(self):
|
1753
|
+
"""Monkey-patch ALL LLM classes found in agent + tools for Pipecleaner deduplication."""
|
1684
1754
|
try:
|
1685
1755
|
# Find ALL LLMs in agent structure + tools
|
1686
1756
|
print(f"[DASEIN][WRAPPER] Searching for ALL LLMs in agent+tools...")
|
@@ -1713,10 +1783,10 @@ Follow these rules when planning your actions."""
|
|
1713
1783
|
print(f"[DASEIN][WRAPPER] Patching {llm_class.__name__} (found in {location})...")
|
1714
1784
|
|
1715
1785
|
# Check what methods the LLM class has
|
1716
|
-
#
|
1786
|
+
# Patch both user-facing AND internal methods since SQL agents bypass invoke
|
1717
1787
|
print(f"[DASEIN][WRAPPER] Checking LLM methods...")
|
1718
1788
|
methods_to_patch = []
|
1719
|
-
for method in ['invoke', 'ainvoke']: #
|
1789
|
+
for method in ['invoke', 'ainvoke', '_generate', '_agenerate']: # Include internal methods for SQL agents
|
1720
1790
|
if hasattr(llm_class, method):
|
1721
1791
|
print(f"[DASEIN][WRAPPER] - Has {method}")
|
1722
1792
|
methods_to_patch.append(method)
|
@@ -1811,7 +1881,7 @@ Follow these rules when planning your actions."""
|
|
1811
1881
|
prompt_strings.append(msg.content)
|
1812
1882
|
elif isinstance(msg, str):
|
1813
1883
|
prompt_strings.append(msg)
|
1814
|
-
|
1884
|
+
else:
|
1815
1885
|
prompt_strings.append(str(msg))
|
1816
1886
|
|
1817
1887
|
# =============================================================
|
@@ -1929,6 +1999,7 @@ Follow these rules when planning your actions."""
|
|
1929
1999
|
break
|
1930
2000
|
|
1931
2001
|
if should_dedupe:
|
2002
|
+
try:
|
1932
2003
|
# Deduplicate each prompt
|
1933
2004
|
from .pipecleaner import get_or_create_corpus
|
1934
2005
|
import hashlib
|
@@ -1969,14 +2040,53 @@ Follow these rules when planning your actions."""
|
|
1969
2040
|
kwargs['messages'] = messages_to_dedupe
|
1970
2041
|
elif 'prompts' in kwargs:
|
1971
2042
|
kwargs['prompts'] = messages_to_dedupe
|
2043
|
+
except Exception as e:
|
2044
|
+
print(f"[🔥 HOTPATH] ⚠️ Deduplication error: {e}")
|
2045
|
+
import traceback
|
2046
|
+
traceback.print_exc()
|
1972
2047
|
except Exception as e:
|
1973
|
-
print(f"[🔥 HOTPATH] ⚠️
|
2048
|
+
print(f"[🔥 HOTPATH] ⚠️ Error in pipecleaner preprocessing: {e}")
|
1974
2049
|
import traceback
|
1975
2050
|
traceback.print_exc()
|
1976
2051
|
|
1977
2052
|
try:
|
2053
|
+
# CRITICAL FIX: Ensure callbacks propagate to _generate/_agenerate
|
2054
|
+
# AgentExecutor doesn't pass run_manager to these internal methods
|
2055
|
+
# So we need to manually inject the callback handler
|
2056
|
+
if meth_name in ['_generate', '_agenerate'] and callback_handler:
|
2057
|
+
if 'run_manager' not in kwargs and hasattr(callback_handler, 'on_llm_start'):
|
2058
|
+
# Manually trigger on_llm_start since no run_manager
|
2059
|
+
import uuid
|
2060
|
+
run_id = uuid.uuid4()
|
2061
|
+
# Extract messages for on_llm_start
|
2062
|
+
messages = args[0] if args else []
|
2063
|
+
prompts = []
|
2064
|
+
for msg in (messages if isinstance(messages, list) else [messages]):
|
2065
|
+
if hasattr(msg, 'content'):
|
2066
|
+
prompts.append(str(msg.content))
|
2067
|
+
else:
|
2068
|
+
prompts.append(str(msg))
|
2069
|
+
|
2070
|
+
# Call on_llm_start
|
2071
|
+
callback_handler.on_llm_start(
|
2072
|
+
serialized={'name': type(self_llm).__name__},
|
2073
|
+
prompts=prompts,
|
2074
|
+
run_id=run_id
|
2075
|
+
)
|
2076
|
+
|
2077
|
+
# Store run_id for on_llm_end
|
2078
|
+
if not hasattr(self_llm, '_dasein_pending_run_ids'):
|
2079
|
+
self_llm._dasein_pending_run_ids = []
|
2080
|
+
self_llm._dasein_pending_run_ids.append(run_id)
|
2081
|
+
|
1978
2082
|
result = await orig_method(self_llm, *args, **kwargs)
|
1979
2083
|
|
2084
|
+
# Call on_llm_end if we called on_llm_start
|
2085
|
+
if meth_name in ['_generate', '_agenerate'] and callback_handler:
|
2086
|
+
if hasattr(self_llm, '_dasein_pending_run_ids') and self_llm._dasein_pending_run_ids:
|
2087
|
+
run_id = self_llm._dasein_pending_run_ids.pop(0)
|
2088
|
+
callback_handler.on_llm_end(result, run_id=run_id)
|
2089
|
+
|
1980
2090
|
# 🚨 MICROTURN ENFORCEMENT - DISABLED
|
1981
2091
|
# Microturn can interfere with tool execution, so it's disabled
|
1982
2092
|
# TODO: Re-enable with proper gating if needed for specific use cases
|
@@ -2205,8 +2315,43 @@ Follow these rules when planning your actions."""
|
|
2205
2315
|
traceback.print_exc()
|
2206
2316
|
|
2207
2317
|
try:
|
2318
|
+
# CRITICAL FIX: Ensure callbacks propagate to _generate/_agenerate
|
2319
|
+
# AgentExecutor doesn't pass run_manager to these internal methods
|
2320
|
+
# So we need to manually inject the callback handler
|
2321
|
+
if meth_name in ['_generate', '_agenerate'] and callback_handler:
|
2322
|
+
if 'run_manager' not in kwargs and hasattr(callback_handler, 'on_llm_start'):
|
2323
|
+
# Manually trigger on_llm_start since no run_manager
|
2324
|
+
import uuid
|
2325
|
+
run_id = uuid.uuid4()
|
2326
|
+
# Extract messages for on_llm_start
|
2327
|
+
messages = args[0] if args else []
|
2328
|
+
prompts = []
|
2329
|
+
for msg in (messages if isinstance(messages, list) else [messages]):
|
2330
|
+
if hasattr(msg, 'content'):
|
2331
|
+
prompts.append(str(msg.content))
|
2332
|
+
else:
|
2333
|
+
prompts.append(str(msg))
|
2334
|
+
|
2335
|
+
# Call on_llm_start
|
2336
|
+
callback_handler.on_llm_start(
|
2337
|
+
serialized={'name': type(self_llm).__name__},
|
2338
|
+
prompts=prompts,
|
2339
|
+
run_id=run_id
|
2340
|
+
)
|
2341
|
+
|
2342
|
+
# Store run_id for on_llm_end
|
2343
|
+
if not hasattr(self_llm, '_dasein_pending_run_ids'):
|
2344
|
+
self_llm._dasein_pending_run_ids = []
|
2345
|
+
self_llm._dasein_pending_run_ids.append(run_id)
|
2346
|
+
|
2208
2347
|
result = orig_method(self_llm, *args, **kwargs)
|
2209
2348
|
|
2349
|
+
# Call on_llm_end if we called on_llm_start
|
2350
|
+
if meth_name in ['_generate', '_agenerate'] and callback_handler:
|
2351
|
+
if hasattr(self_llm, '_dasein_pending_run_ids') and self_llm._dasein_pending_run_ids:
|
2352
|
+
run_id = self_llm._dasein_pending_run_ids.pop(0)
|
2353
|
+
callback_handler.on_llm_end(result, run_id=run_id)
|
2354
|
+
|
2210
2355
|
# 🚨 MICROTURN ENFORCEMENT - DISABLED (can interfere with tool execution)
|
2211
2356
|
# TODO: Re-enable with proper gating if needed
|
2212
2357
|
|
@@ -3701,7 +3846,11 @@ Follow these rules when planning your actions."""
|
|
3701
3846
|
print(f"[DASEIN] 🔧 Pre-loading embedding model for pipecleaner (found filter search rules)...")
|
3702
3847
|
from .pipecleaner import _get_embedding_model
|
3703
3848
|
try:
|
3704
|
-
|
3849
|
+
# Suppress protobuf warnings from sentence-transformers
|
3850
|
+
import warnings
|
3851
|
+
with warnings.catch_warnings():
|
3852
|
+
warnings.filterwarnings('ignore', category=Warning)
|
3853
|
+
_get_embedding_model() # Warm up the model
|
3705
3854
|
print(f"[DASEIN] ✅ Embedding model pre-loaded successfully")
|
3706
3855
|
except Exception as e:
|
3707
3856
|
print(f"[DASEIN] ⚠️ Failed to pre-load embedding model: {e}")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
dasein/__init__.py,sha256=RY0lhaaWB6yJ_5YMRmaHDvQ0eFbc0BGbYNe5OVyxzYE,2316
|
2
2
|
dasein/advice_format.py,sha256=5-h4J24L_B2Y9dlmyDuIYtmPCWOGAYoinBEXqpcNg2s,5386
|
3
|
-
dasein/api.py,sha256=
|
3
|
+
dasein/api.py,sha256=qJVnKdeuCGsaDuwcPP6kiaEJKbO15DsPoMHtuNvSvuM,257060
|
4
4
|
dasein/capture.py,sha256=D4DvknI2wbmVup5WqvNcgw-zW5riEstYG81Rl98uz6o,110942
|
5
5
|
dasein/config.py,sha256=lXO8JG4RXbodn3gT5yEnuB0VRwWdrRVwhX3Rm06IZmU,1957
|
6
6
|
dasein/events.py,sha256=mG-lnOvQoZUhXbrPSjrG4RME6ywUcbSZ04PscoJ15GI,12896
|
@@ -45,7 +45,7 @@ dasein/services/post_run_client.py,sha256=UjK3eqf7oWGSuWkKe0vQmeMS0yUUOhYFD4-SZ7
|
|
45
45
|
dasein/services/pre_run_client.py,sha256=tXmz_PQaSfq0xwypiWUAqNkXOmREZ6EwXLC4OM89J-A,4317
|
46
46
|
dasein/services/service_adapter.py,sha256=YHk41lR3PXh8WTmxOzzwKf6hwPYGqIdApI92vQKlkAY,7350
|
47
47
|
dasein/services/service_config.py,sha256=8_4tpV4mZvfaOc5_yyHbOyL4rYsPHzkLTEY1rtYgLs8,1629
|
48
|
-
dasein_core-0.2.
|
48
|
+
dasein_core-0.2.13.dist-info/licenses/LICENSE,sha256=7FHjIFEKl_3hSc3tGUVEWmufC_3oi8rh_2zVuL7jMKs,1091
|
49
49
|
dasein/models/en_core_web_sm/en_core_web_sm-3.7.1.dist-info/LICENSE,sha256=OTPBdpebaLxtC8yQLH1sEw8dEn9Hbxe6XNuo2Zz9ABI,1056
|
50
50
|
dasein/models/en_core_web_sm/en_core_web_sm-3.7.1.dist-info/LICENSES_SOURCES,sha256=INnfrNIVESJR8VNB7dGkex-Yvzk6IS8Q8ZT_3H7pipA,2347
|
51
51
|
dasein/models/en_core_web_sm/en_core_web_sm-3.7.1.dist-info/METADATA,sha256=-vGqRxa_M2RwKtLjBhc4JlBQdJ3k7CwOnseT_ReYcic,2958
|
@@ -53,7 +53,7 @@ dasein/models/en_core_web_sm/en_core_web_sm-3.7.1.dist-info/RECORD,sha256=dDb6U7
|
|
53
53
|
dasein/models/en_core_web_sm/en_core_web_sm-3.7.1.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
|
54
54
|
dasein/models/en_core_web_sm/en_core_web_sm-3.7.1.dist-info/entry_points.txt,sha256=OkWs-KxPJtDdpvIFCVXzDC9ECtejhPxv7pP3Tgk2cNg,47
|
55
55
|
dasein/models/en_core_web_sm/en_core_web_sm-3.7.1.dist-info/top_level.txt,sha256=56OIuRbEuhr12HsM9XpCMnTtHRMgNC5Hje4Xeo8wF2c,15
|
56
|
-
dasein_core-0.2.
|
57
|
-
dasein_core-0.2.
|
58
|
-
dasein_core-0.2.
|
59
|
-
dasein_core-0.2.
|
56
|
+
dasein_core-0.2.13.dist-info/METADATA,sha256=dnUU3veXoiKLGCw4QWJ7Zjc3aKgiXS6ZYPbnizjrERQ,10297
|
57
|
+
dasein_core-0.2.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
58
|
+
dasein_core-0.2.13.dist-info/top_level.txt,sha256=6yYY9kltjvvPsg9K6KyMKRtzEr5qM7sHXN7VzmrDtp0,7
|
59
|
+
dasein_core-0.2.13.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|