prefactor-langchain 0.2.1__tar.gz → 0.2.2__tar.gz
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.
- {prefactor_langchain-0.2.1 → prefactor_langchain-0.2.2}/PKG-INFO +2 -2
- {prefactor_langchain-0.2.1 → prefactor_langchain-0.2.2}/examples/simple_agent.py +24 -4
- {prefactor_langchain-0.2.1 → prefactor_langchain-0.2.2}/pyproject.toml +2 -2
- {prefactor_langchain-0.2.1 → prefactor_langchain-0.2.2}/src/prefactor_langchain/__init__.py +1 -1
- {prefactor_langchain-0.2.1 → prefactor_langchain-0.2.2}/src/prefactor_langchain/middleware.py +6 -1
- {prefactor_langchain-0.2.1 → prefactor_langchain-0.2.2}/.gitignore +0 -0
- {prefactor_langchain-0.2.1 → prefactor_langchain-0.2.2}/README.md +0 -0
- {prefactor_langchain-0.2.1 → prefactor_langchain-0.2.2}/examples/.env.example +0 -0
- {prefactor_langchain-0.2.1 → prefactor_langchain-0.2.2}/examples/README.md +0 -0
- {prefactor_langchain-0.2.1 → prefactor_langchain-0.2.2}/src/prefactor_langchain/metadata_extractor.py +0 -0
- {prefactor_langchain-0.2.1 → prefactor_langchain-0.2.2}/src/prefactor_langchain/schemas.py +0 -0
- {prefactor_langchain-0.2.1 → prefactor_langchain-0.2.2}/src/prefactor_langchain/spans.py +0 -0
- {prefactor_langchain-0.2.1 → prefactor_langchain-0.2.2}/tests/test_metadata_extractor.py +0 -0
- {prefactor_langchain-0.2.1 → prefactor_langchain-0.2.2}/tests/test_middleware.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: prefactor-langchain
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: LangChain integration for Prefactor observability
|
|
5
5
|
Author-email: Prefactor Pty Ltd <josh@prefactor.tech>
|
|
6
6
|
License: MIT
|
|
7
7
|
Requires-Python: <4.0.0,>=3.11.0
|
|
8
8
|
Requires-Dist: langchain-core>=1.0.0
|
|
9
|
-
Requires-Dist: prefactor-core>=0.1
|
|
9
|
+
Requires-Dist: prefactor-core>=0.2.1
|
|
10
10
|
Description-Content-Type: text/markdown
|
|
11
11
|
|
|
12
12
|
# prefactor-langchain
|
|
@@ -22,7 +22,9 @@ Example:
|
|
|
22
22
|
python simple_agent.py
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
|
+
import ast
|
|
25
26
|
import asyncio
|
|
27
|
+
import operator
|
|
26
28
|
import os
|
|
27
29
|
from datetime import datetime
|
|
28
30
|
|
|
@@ -36,11 +38,29 @@ from prefactor_langchain import PrefactorMiddleware
|
|
|
36
38
|
# ---------------------------------------------------------------------------
|
|
37
39
|
|
|
38
40
|
|
|
41
|
+
_OPS = {
|
|
42
|
+
ast.Add: operator.add,
|
|
43
|
+
ast.Sub: operator.sub,
|
|
44
|
+
ast.Mult: operator.mul,
|
|
45
|
+
ast.Div: operator.truediv,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _safe_eval(node: ast.expr) -> float:
|
|
50
|
+
if isinstance(node, ast.Constant):
|
|
51
|
+
return node.n # type: ignore[return-value]
|
|
52
|
+
if isinstance(node, ast.BinOp):
|
|
53
|
+
return _OPS[type(node.op)](_safe_eval(node.left), _safe_eval(node.right))
|
|
54
|
+
if isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.USub):
|
|
55
|
+
return -_safe_eval(node.operand)
|
|
56
|
+
raise ValueError(f"Unsupported expression: {ast.dump(node)}")
|
|
57
|
+
|
|
58
|
+
|
|
39
59
|
@tool
|
|
40
60
|
def calculator(expression: str) -> str:
|
|
41
|
-
"""Evaluate a mathematical expression."""
|
|
61
|
+
"""Evaluate a mathematical expression safely."""
|
|
42
62
|
try:
|
|
43
|
-
result =
|
|
63
|
+
result = _safe_eval(ast.parse(expression, mode="eval").body)
|
|
44
64
|
return f"Result: {result}"
|
|
45
65
|
except Exception as e:
|
|
46
66
|
return f"Error: {str(e)}"
|
|
@@ -100,7 +120,7 @@ async def run_agent_step(
|
|
|
100
120
|
SpanContextStack propagates correctly so langchain:agent is automatically
|
|
101
121
|
parented to workflow:agent_step.
|
|
102
122
|
"""
|
|
103
|
-
instance = await middleware.
|
|
123
|
+
instance = await middleware.ensure_initialized()
|
|
104
124
|
|
|
105
125
|
async with instance.span("workflow:agent_step") as ctx:
|
|
106
126
|
await ctx.start({"message_count": len(messages)})
|
|
@@ -136,7 +156,7 @@ async def run_workflow(
|
|
|
136
156
|
langchain:tool (if the agent calls a tool)
|
|
137
157
|
workflow:post_process
|
|
138
158
|
"""
|
|
139
|
-
instance = await middleware.
|
|
159
|
+
instance = await middleware.ensure_initialized()
|
|
140
160
|
|
|
141
161
|
async with instance.span("workflow:run") as root:
|
|
142
162
|
await root.start({"label": label, "query": query})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "prefactor-langchain"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.2"
|
|
4
4
|
description = "LangChain integration for Prefactor observability"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { text = "MIT" }
|
|
@@ -9,7 +9,7 @@ authors = [
|
|
|
9
9
|
]
|
|
10
10
|
requires-python = ">=3.11.0, <4.0.0"
|
|
11
11
|
dependencies = [
|
|
12
|
-
"prefactor-core>=0.1
|
|
12
|
+
"prefactor-core>=0.2.1",
|
|
13
13
|
"langchain-core>=1.0.0",
|
|
14
14
|
]
|
|
15
15
|
|
{prefactor_langchain-0.2.1 → prefactor_langchain-0.2.2}/src/prefactor_langchain/middleware.py
RENAMED
|
@@ -274,7 +274,7 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
274
274
|
# Derive a stable schema version ID from the registry + agent_name so
|
|
275
275
|
# that the same configuration always maps to the same version
|
|
276
276
|
# (idempotent across runs) and any change produces a new, distinct ID.
|
|
277
|
-
agent_version_name = "langchain-agent"
|
|
277
|
+
agent_version_name = self._agent_name or "langchain-agent"
|
|
278
278
|
schema_version_id = f"langchain-{self._agent_id}"
|
|
279
279
|
if self._client._config.schema_registry is not None:
|
|
280
280
|
raw = self._client._config.schema_registry.to_agent_schema_version(
|
|
@@ -303,6 +303,10 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
303
303
|
logger.debug("Initialized agent instance %s", self._instance.id)
|
|
304
304
|
return self._instance
|
|
305
305
|
|
|
306
|
+
async def ensure_initialized(self) -> AgentInstanceHandle:
|
|
307
|
+
"""Initialize the middleware and return the agent instance handle."""
|
|
308
|
+
return await self._ensure_initialized()
|
|
309
|
+
|
|
306
310
|
async def close(self) -> None:
|
|
307
311
|
"""Close the middleware and cleanup resources.
|
|
308
312
|
|
|
@@ -580,6 +584,7 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
580
584
|
def _schedule() -> None:
|
|
581
585
|
task = loop.create_task(_emit())
|
|
582
586
|
pending.append(task)
|
|
587
|
+
task.add_done_callback(pending.remove)
|
|
583
588
|
|
|
584
589
|
loop.call_soon_threadsafe(_schedule)
|
|
585
590
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|