prefactor-langchain 0.2.3__tar.gz → 0.2.4__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.3 → prefactor_langchain-0.2.4}/.gitignore +1 -0
- {prefactor_langchain-0.2.3 → prefactor_langchain-0.2.4}/PKG-INFO +63 -2
- {prefactor_langchain-0.2.3 → prefactor_langchain-0.2.4}/README.md +62 -1
- {prefactor_langchain-0.2.3 → prefactor_langchain-0.2.4}/pyproject.toml +1 -1
- {prefactor_langchain-0.2.3 → prefactor_langchain-0.2.4}/src/prefactor_langchain/__init__.py +9 -1
- {prefactor_langchain-0.2.3 → prefactor_langchain-0.2.4}/src/prefactor_langchain/middleware.py +78 -13
- prefactor_langchain-0.2.4/src/prefactor_langchain/schemas.py +687 -0
- {prefactor_langchain-0.2.3 → prefactor_langchain-0.2.4}/tests/test_middleware.py +241 -0
- prefactor_langchain-0.2.4/tests/test_schemas.py +257 -0
- prefactor_langchain-0.2.3/src/prefactor_langchain/schemas.py +0 -294
- {prefactor_langchain-0.2.3 → prefactor_langchain-0.2.4}/examples/.env.example +0 -0
- {prefactor_langchain-0.2.3 → prefactor_langchain-0.2.4}/examples/README.md +0 -0
- {prefactor_langchain-0.2.3 → prefactor_langchain-0.2.4}/examples/simple_agent.py +0 -0
- {prefactor_langchain-0.2.3 → prefactor_langchain-0.2.4}/src/prefactor_langchain/metadata_extractor.py +0 -0
- {prefactor_langchain-0.2.3 → prefactor_langchain-0.2.4}/src/prefactor_langchain/spans.py +0 -0
- {prefactor_langchain-0.2.3 → prefactor_langchain-0.2.4}/tests/test_metadata_extractor.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: prefactor-langchain
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: LangChain integration for Prefactor observability
|
|
5
5
|
Author-email: Prefactor Pty Ltd <josh@prefactor.tech>
|
|
6
6
|
License: MIT
|
|
@@ -24,13 +24,26 @@ pip install prefactor-langchain
|
|
|
24
24
|
### Factory pattern (quickest setup)
|
|
25
25
|
|
|
26
26
|
```python
|
|
27
|
-
from prefactor_langchain import PrefactorMiddleware
|
|
27
|
+
from prefactor_langchain import LangChainToolSchemaConfig, PrefactorMiddleware
|
|
28
28
|
|
|
29
29
|
middleware = PrefactorMiddleware.from_config(
|
|
30
30
|
api_url="https://api.prefactor.ai",
|
|
31
31
|
api_token="your-api-token",
|
|
32
32
|
agent_id="my-agent",
|
|
33
33
|
agent_name="My Agent", # optional
|
|
34
|
+
tool_schemas={
|
|
35
|
+
"send_email": LangChainToolSchemaConfig(
|
|
36
|
+
span_type="send-email",
|
|
37
|
+
input_schema={
|
|
38
|
+
"type": "object",
|
|
39
|
+
"properties": {
|
|
40
|
+
"to": {"type": "string", "format": "email"},
|
|
41
|
+
"subject": {"type": "string"},
|
|
42
|
+
},
|
|
43
|
+
"required": ["to", "subject"],
|
|
44
|
+
},
|
|
45
|
+
)
|
|
46
|
+
},
|
|
34
47
|
)
|
|
35
48
|
|
|
36
49
|
# Use with LangChain's create_agent()
|
|
@@ -38,6 +51,7 @@ middleware = PrefactorMiddleware.from_config(
|
|
|
38
51
|
# - Agent execution (langchain:agent)
|
|
39
52
|
# - LLM calls (langchain:llm)
|
|
40
53
|
# - Tool executions (langchain:tool)
|
|
54
|
+
# - Tool-specific executions (for example langchain:tool:send-email)
|
|
41
55
|
|
|
42
56
|
result = agent.invoke({"messages": [...]})
|
|
43
57
|
|
|
@@ -73,6 +87,47 @@ await middleware.close() # closes the agent instance only
|
|
|
73
87
|
await client.close()
|
|
74
88
|
```
|
|
75
89
|
|
|
90
|
+
### SchemaRegistry composition
|
|
91
|
+
|
|
92
|
+
Use a shared ``SchemaRegistry`` when you want custom workflow span types and
|
|
93
|
+
LangChain tool schemas to be published together.
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from prefactor_core import SchemaRegistry
|
|
97
|
+
from prefactor_langchain import (
|
|
98
|
+
LangChainToolSchemaConfig,
|
|
99
|
+
PrefactorMiddleware,
|
|
100
|
+
register_langchain_schemas,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
registry = SchemaRegistry()
|
|
104
|
+
registry.register_type(
|
|
105
|
+
name="workflow:run",
|
|
106
|
+
params_schema={"type": "object"},
|
|
107
|
+
result_schema={"type": "object"},
|
|
108
|
+
)
|
|
109
|
+
register_langchain_schemas(
|
|
110
|
+
registry,
|
|
111
|
+
tool_schemas={
|
|
112
|
+
"send_email": LangChainToolSchemaConfig(
|
|
113
|
+
span_type="send-email",
|
|
114
|
+
input_schema={
|
|
115
|
+
"type": "object",
|
|
116
|
+
"properties": {"to": {"type": "string"}},
|
|
117
|
+
"required": ["to"],
|
|
118
|
+
},
|
|
119
|
+
)
|
|
120
|
+
},
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
middleware = PrefactorMiddleware.from_config(
|
|
124
|
+
api_url="https://api.prefactor.ai",
|
|
125
|
+
api_token="your-api-token",
|
|
126
|
+
agent_id="my-agent",
|
|
127
|
+
schema_registry=registry,
|
|
128
|
+
)
|
|
129
|
+
```
|
|
130
|
+
|
|
76
131
|
### Pre-configured instance (spans outside the agent)
|
|
77
132
|
|
|
78
133
|
Pass an `AgentInstanceHandle` you created yourself when you also need to
|
|
@@ -111,6 +166,12 @@ await instance.finish()
|
|
|
111
166
|
await client.close()
|
|
112
167
|
```
|
|
113
168
|
|
|
169
|
+
If you pass ``tool_schemas=...`` with a pre-created instance, the middleware
|
|
170
|
+
uses those mappings to emit the right tool span types at runtime. The instance's
|
|
171
|
+
already-registered schema version is not mutated, so you must register matching
|
|
172
|
+
tool schemas before creating the instance if you want those per-tool span types
|
|
173
|
+
to appear in the backend schema version.
|
|
174
|
+
|
|
114
175
|
## Span Types
|
|
115
176
|
|
|
116
177
|
This package creates LangChain-specific spans with the `langchain:*` namespace:
|
|
@@ -13,13 +13,26 @@ pip install prefactor-langchain
|
|
|
13
13
|
### Factory pattern (quickest setup)
|
|
14
14
|
|
|
15
15
|
```python
|
|
16
|
-
from prefactor_langchain import PrefactorMiddleware
|
|
16
|
+
from prefactor_langchain import LangChainToolSchemaConfig, PrefactorMiddleware
|
|
17
17
|
|
|
18
18
|
middleware = PrefactorMiddleware.from_config(
|
|
19
19
|
api_url="https://api.prefactor.ai",
|
|
20
20
|
api_token="your-api-token",
|
|
21
21
|
agent_id="my-agent",
|
|
22
22
|
agent_name="My Agent", # optional
|
|
23
|
+
tool_schemas={
|
|
24
|
+
"send_email": LangChainToolSchemaConfig(
|
|
25
|
+
span_type="send-email",
|
|
26
|
+
input_schema={
|
|
27
|
+
"type": "object",
|
|
28
|
+
"properties": {
|
|
29
|
+
"to": {"type": "string", "format": "email"},
|
|
30
|
+
"subject": {"type": "string"},
|
|
31
|
+
},
|
|
32
|
+
"required": ["to", "subject"],
|
|
33
|
+
},
|
|
34
|
+
)
|
|
35
|
+
},
|
|
23
36
|
)
|
|
24
37
|
|
|
25
38
|
# Use with LangChain's create_agent()
|
|
@@ -27,6 +40,7 @@ middleware = PrefactorMiddleware.from_config(
|
|
|
27
40
|
# - Agent execution (langchain:agent)
|
|
28
41
|
# - LLM calls (langchain:llm)
|
|
29
42
|
# - Tool executions (langchain:tool)
|
|
43
|
+
# - Tool-specific executions (for example langchain:tool:send-email)
|
|
30
44
|
|
|
31
45
|
result = agent.invoke({"messages": [...]})
|
|
32
46
|
|
|
@@ -62,6 +76,47 @@ await middleware.close() # closes the agent instance only
|
|
|
62
76
|
await client.close()
|
|
63
77
|
```
|
|
64
78
|
|
|
79
|
+
### SchemaRegistry composition
|
|
80
|
+
|
|
81
|
+
Use a shared ``SchemaRegistry`` when you want custom workflow span types and
|
|
82
|
+
LangChain tool schemas to be published together.
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
from prefactor_core import SchemaRegistry
|
|
86
|
+
from prefactor_langchain import (
|
|
87
|
+
LangChainToolSchemaConfig,
|
|
88
|
+
PrefactorMiddleware,
|
|
89
|
+
register_langchain_schemas,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
registry = SchemaRegistry()
|
|
93
|
+
registry.register_type(
|
|
94
|
+
name="workflow:run",
|
|
95
|
+
params_schema={"type": "object"},
|
|
96
|
+
result_schema={"type": "object"},
|
|
97
|
+
)
|
|
98
|
+
register_langchain_schemas(
|
|
99
|
+
registry,
|
|
100
|
+
tool_schemas={
|
|
101
|
+
"send_email": LangChainToolSchemaConfig(
|
|
102
|
+
span_type="send-email",
|
|
103
|
+
input_schema={
|
|
104
|
+
"type": "object",
|
|
105
|
+
"properties": {"to": {"type": "string"}},
|
|
106
|
+
"required": ["to"],
|
|
107
|
+
},
|
|
108
|
+
)
|
|
109
|
+
},
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
middleware = PrefactorMiddleware.from_config(
|
|
113
|
+
api_url="https://api.prefactor.ai",
|
|
114
|
+
api_token="your-api-token",
|
|
115
|
+
agent_id="my-agent",
|
|
116
|
+
schema_registry=registry,
|
|
117
|
+
)
|
|
118
|
+
```
|
|
119
|
+
|
|
65
120
|
### Pre-configured instance (spans outside the agent)
|
|
66
121
|
|
|
67
122
|
Pass an `AgentInstanceHandle` you created yourself when you also need to
|
|
@@ -100,6 +155,12 @@ await instance.finish()
|
|
|
100
155
|
await client.close()
|
|
101
156
|
```
|
|
102
157
|
|
|
158
|
+
If you pass ``tool_schemas=...`` with a pre-created instance, the middleware
|
|
159
|
+
uses those mappings to emit the right tool span types at runtime. The instance's
|
|
160
|
+
already-registered schema version is not mutated, so you must register matching
|
|
161
|
+
tool schemas before creating the instance if you want those per-tool span types
|
|
162
|
+
to appear in the backend schema version.
|
|
163
|
+
|
|
103
164
|
## Span Types
|
|
104
165
|
|
|
105
166
|
This package creates LangChain-specific spans with the `langchain:*` namespace:
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
"""Prefactor LangChain - LangChain integration for Prefactor observability."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
from prefactor_langchain.metadata_extractor import (
|
|
4
6
|
extract_error_info,
|
|
5
7
|
extract_token_usage,
|
|
6
8
|
)
|
|
7
9
|
from prefactor_langchain.middleware import PrefactorMiddleware
|
|
8
10
|
from prefactor_langchain.schemas import (
|
|
11
|
+
DEFAULT_LANGCHAIN_AGENT_SCHEMA,
|
|
9
12
|
LANGCHAIN_AGENT_SCHEMA,
|
|
10
13
|
LANGCHAIN_LLM_SCHEMA,
|
|
11
14
|
LANGCHAIN_TOOL_SCHEMA,
|
|
15
|
+
LangChainToolSchemaConfig,
|
|
16
|
+
compile_langchain_agent_schema,
|
|
12
17
|
register_langchain_schemas,
|
|
13
18
|
)
|
|
14
19
|
from prefactor_langchain.spans import (
|
|
@@ -20,7 +25,7 @@ from prefactor_langchain.spans import (
|
|
|
20
25
|
ToolSpan,
|
|
21
26
|
)
|
|
22
27
|
|
|
23
|
-
__version__ = "0.2.
|
|
28
|
+
__version__ = "0.2.4"
|
|
24
29
|
|
|
25
30
|
__all__ = [
|
|
26
31
|
# Middleware
|
|
@@ -30,6 +35,9 @@ __all__ = [
|
|
|
30
35
|
"extract_error_info",
|
|
31
36
|
# Schemas
|
|
32
37
|
"register_langchain_schemas",
|
|
38
|
+
"compile_langchain_agent_schema",
|
|
39
|
+
"LangChainToolSchemaConfig",
|
|
40
|
+
"DEFAULT_LANGCHAIN_AGENT_SCHEMA",
|
|
33
41
|
"LANGCHAIN_AGENT_SCHEMA",
|
|
34
42
|
"LANGCHAIN_LLM_SCHEMA",
|
|
35
43
|
"LANGCHAIN_TOOL_SCHEMA",
|
{prefactor_langchain-0.2.3 → prefactor_langchain-0.2.4}/src/prefactor_langchain/middleware.py
RENAMED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"""LangChain middleware for automatic tracing via prefactor-core."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import asyncio
|
|
4
6
|
import hashlib
|
|
5
7
|
import json
|
|
6
8
|
import logging
|
|
9
|
+
from collections.abc import Mapping
|
|
7
10
|
from typing import TYPE_CHECKING, Any, AsyncContextManager, Callable
|
|
8
11
|
|
|
9
12
|
from langchain.agents.middleware import AgentMiddleware
|
|
@@ -20,7 +23,7 @@ if TYPE_CHECKING:
|
|
|
20
23
|
pass
|
|
21
24
|
|
|
22
25
|
from .metadata_extractor import extract_token_usage
|
|
23
|
-
from .schemas import register_langchain_schemas
|
|
26
|
+
from .schemas import LangChainToolSchemaConfig, register_langchain_schemas
|
|
24
27
|
from .spans import AgentSpan, LLMSpan, ToolSpan
|
|
25
28
|
|
|
26
29
|
logger = logging.getLogger("prefactor_langchain.middleware")
|
|
@@ -111,6 +114,8 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
111
114
|
agent_id: str = "langchain-agent",
|
|
112
115
|
agent_name: str | None = None,
|
|
113
116
|
instance: AgentInstanceHandle | None = None,
|
|
117
|
+
tool_schemas: Mapping[str, LangChainToolSchemaConfig | Mapping[str, Any]]
|
|
118
|
+
| None = None,
|
|
114
119
|
):
|
|
115
120
|
"""Initialize the middleware with a pre-configured client or instance.
|
|
116
121
|
|
|
@@ -148,6 +153,9 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
148
153
|
self._current_parent_span_id: str | None = None
|
|
149
154
|
self._loop: asyncio.AbstractEventLoop | None = None
|
|
150
155
|
self._pending_emit_futures: list[asyncio.Task[None]] = []
|
|
156
|
+
self._tool_span_types = (
|
|
157
|
+
self._register_tool_schemas(None, tool_schemas) if tool_schemas else {}
|
|
158
|
+
)
|
|
151
159
|
return
|
|
152
160
|
|
|
153
161
|
if client is None:
|
|
@@ -179,6 +187,10 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
179
187
|
self._current_parent_span_id: str | None = None
|
|
180
188
|
self._loop: asyncio.AbstractEventLoop | None = None
|
|
181
189
|
self._pending_emit_futures: list[asyncio.Task[None]] = []
|
|
190
|
+
self._tool_span_types = {}
|
|
191
|
+
|
|
192
|
+
if tool_schemas:
|
|
193
|
+
self._tool_span_types = self._register_tool_schemas(client, tool_schemas)
|
|
182
194
|
|
|
183
195
|
@classmethod
|
|
184
196
|
def from_config(
|
|
@@ -189,6 +201,8 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
189
201
|
agent_name: str | None = None,
|
|
190
202
|
schema_registry: SchemaRegistry | None = None,
|
|
191
203
|
include_langchain_schemas: bool = True,
|
|
204
|
+
tool_schemas: Mapping[str, LangChainToolSchemaConfig | Mapping[str, Any]]
|
|
205
|
+
| None = None,
|
|
192
206
|
) -> "PrefactorMiddleware":
|
|
193
207
|
"""Factory method to create middleware from configuration.
|
|
194
208
|
|
|
@@ -203,6 +217,8 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
203
217
|
schema_registry: Optional SchemaRegistry for registering span schemas.
|
|
204
218
|
include_langchain_schemas: If True and schema_registry is provided,
|
|
205
219
|
automatically register LangChain-specific schemas.
|
|
220
|
+
tool_schemas: Optional per-tool schema configuration for tool-specific
|
|
221
|
+
span types.
|
|
206
222
|
|
|
207
223
|
Returns:
|
|
208
224
|
A configured PrefactorMiddleware instance with lazy initialization.
|
|
@@ -223,8 +239,12 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
223
239
|
|
|
224
240
|
# Create or augment schema registry
|
|
225
241
|
registry = schema_registry or SchemaRegistry()
|
|
226
|
-
|
|
227
|
-
|
|
242
|
+
tool_span_types: dict[str, str] = {}
|
|
243
|
+
if include_langchain_schemas or tool_schemas:
|
|
244
|
+
tool_span_types = register_langchain_schemas(
|
|
245
|
+
registry,
|
|
246
|
+
tool_schemas=tool_schemas,
|
|
247
|
+
)
|
|
228
248
|
|
|
229
249
|
config = PrefactorCoreConfig(
|
|
230
250
|
http_config=http_config,
|
|
@@ -245,9 +265,32 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
245
265
|
middleware._current_parent_span_id = None
|
|
246
266
|
middleware._loop = None
|
|
247
267
|
middleware._pending_emit_futures = []
|
|
268
|
+
middleware._tool_span_types = tool_span_types
|
|
248
269
|
logger.debug("PrefactorMiddleware created via from_config()")
|
|
249
270
|
return middleware
|
|
250
271
|
|
|
272
|
+
def _register_tool_schemas(
|
|
273
|
+
self,
|
|
274
|
+
client: PrefactorCoreClient | None,
|
|
275
|
+
tool_schemas: Mapping[str, LangChainToolSchemaConfig | Mapping[str, Any]],
|
|
276
|
+
) -> dict[str, str]:
|
|
277
|
+
"""Register tool schemas into a client registry when available."""
|
|
278
|
+
if client is None:
|
|
279
|
+
return register_langchain_schemas(
|
|
280
|
+
SchemaRegistry(),
|
|
281
|
+
tool_schemas=tool_schemas,
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
registry = client._config.schema_registry
|
|
285
|
+
if registry is None:
|
|
286
|
+
registry = SchemaRegistry()
|
|
287
|
+
client._config.schema_registry = registry
|
|
288
|
+
|
|
289
|
+
return register_langchain_schemas(
|
|
290
|
+
registry,
|
|
291
|
+
tool_schemas=tool_schemas,
|
|
292
|
+
)
|
|
293
|
+
|
|
251
294
|
async def _ensure_initialized(self) -> AgentInstanceHandle:
|
|
252
295
|
"""Ensure the agent instance is initialized (lazily created if needed).
|
|
253
296
|
|
|
@@ -419,6 +462,18 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
419
462
|
"tool_name": tool_call.get("name", "unknown"),
|
|
420
463
|
"arguments": tool_call.get("args", {}),
|
|
421
464
|
}
|
|
465
|
+
if hasattr(request, "tool") and hasattr(request.tool, "name"):
|
|
466
|
+
return {
|
|
467
|
+
"tool_name": getattr(request.tool, "name", "unknown"),
|
|
468
|
+
"arguments": getattr(request, "args", {}),
|
|
469
|
+
}
|
|
470
|
+
if hasattr(request, "name"):
|
|
471
|
+
return {
|
|
472
|
+
"tool_name": request.name,
|
|
473
|
+
"arguments": getattr(
|
|
474
|
+
request, "input", getattr(request, "args", {})
|
|
475
|
+
),
|
|
476
|
+
}
|
|
422
477
|
return {}
|
|
423
478
|
except Exception as e:
|
|
424
479
|
logger.error("Error extracting tool inputs: %s", e, exc_info=True)
|
|
@@ -460,12 +515,14 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
460
515
|
result["error"] = span_data.error.to_dict()
|
|
461
516
|
return result
|
|
462
517
|
|
|
463
|
-
def _build_tool_params(self, span_data: Any) -> dict[str, Any]:
|
|
518
|
+
def _build_tool_params(self, span_data: Any, schema_name: str) -> dict[str, Any]:
|
|
464
519
|
"""Build the payload (params) dict for a tool span."""
|
|
465
520
|
params: dict[str, Any] = {}
|
|
466
521
|
if span_data.tool_name:
|
|
467
522
|
params["tool_name"] = span_data.tool_name
|
|
468
|
-
if
|
|
523
|
+
if schema_name != "langchain:tool":
|
|
524
|
+
params["inputs"] = span_data.arguments
|
|
525
|
+
elif span_data.inputs:
|
|
469
526
|
params["inputs"] = span_data.inputs
|
|
470
527
|
return params
|
|
471
528
|
|
|
@@ -554,7 +611,7 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
554
611
|
self._current_parent_span_id = span_id
|
|
555
612
|
return span_id
|
|
556
613
|
|
|
557
|
-
def _emit_child_span(self, span_data: Any) -> None:
|
|
614
|
+
def _emit_child_span(self, span_data: Any, schema_name: str | None = None) -> None:
|
|
558
615
|
"""Schedule a child span (LLM/tool) emission with parent tracking.
|
|
559
616
|
|
|
560
617
|
Uses the current parent span ID from _current_parent_span_id.
|
|
@@ -566,15 +623,15 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
566
623
|
return
|
|
567
624
|
|
|
568
625
|
instance = self._instance
|
|
569
|
-
schema_name
|
|
626
|
+
schema_name = schema_name or span_data.type
|
|
570
627
|
parent_span_id = self._current_parent_span_id
|
|
571
628
|
pending = self._pending_emit_futures
|
|
572
629
|
|
|
573
630
|
if schema_name == "langchain:llm":
|
|
574
631
|
params = self._build_llm_params(span_data)
|
|
575
632
|
result = self._build_llm_result(span_data)
|
|
576
|
-
elif schema_name
|
|
577
|
-
params = self._build_tool_params(span_data)
|
|
633
|
+
elif schema_name.startswith("langchain:tool"):
|
|
634
|
+
params = self._build_tool_params(span_data, schema_name)
|
|
578
635
|
result = self._build_tool_result(span_data)
|
|
579
636
|
else:
|
|
580
637
|
return
|
|
@@ -899,7 +956,9 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
899
956
|
type="langchain:tool",
|
|
900
957
|
inputs=inputs,
|
|
901
958
|
tool_name=tool_name,
|
|
959
|
+
arguments=inputs.get("arguments", {}),
|
|
902
960
|
)
|
|
961
|
+
schema_name = self._resolve_tool_schema_name(tool_name)
|
|
903
962
|
|
|
904
963
|
try:
|
|
905
964
|
response = handler(request)
|
|
@@ -907,13 +966,13 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
907
966
|
outputs = self._extract_tool_output(response)
|
|
908
967
|
span_data.complete(outputs=outputs)
|
|
909
968
|
|
|
910
|
-
self._emit_child_span(span_data)
|
|
969
|
+
self._emit_child_span(span_data, schema_name=schema_name)
|
|
911
970
|
logger.debug("Tool call completed (%s)", tool_name)
|
|
912
971
|
return response
|
|
913
972
|
|
|
914
973
|
except Exception as e:
|
|
915
974
|
span_data.fail(e)
|
|
916
|
-
self._emit_child_span(span_data)
|
|
975
|
+
self._emit_child_span(span_data, schema_name=schema_name)
|
|
917
976
|
logger.error("Tool call failed: %s", e, exc_info=True)
|
|
918
977
|
raise
|
|
919
978
|
|
|
@@ -941,10 +1000,12 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
941
1000
|
type="langchain:tool",
|
|
942
1001
|
inputs=inputs,
|
|
943
1002
|
tool_name=tool_name,
|
|
1003
|
+
arguments=inputs.get("arguments", {}),
|
|
944
1004
|
)
|
|
1005
|
+
schema_name = self._resolve_tool_schema_name(tool_name)
|
|
945
1006
|
|
|
946
|
-
async with instance.span(
|
|
947
|
-
await ctx.start(self._build_tool_params(span_data))
|
|
1007
|
+
async with instance.span(schema_name) as ctx:
|
|
1008
|
+
await ctx.start(self._build_tool_params(span_data, schema_name))
|
|
948
1009
|
try:
|
|
949
1010
|
response = await handler(request)
|
|
950
1011
|
|
|
@@ -959,3 +1020,7 @@ class PrefactorMiddleware(AgentMiddleware):
|
|
|
959
1020
|
await ctx.fail(self._build_tool_result(span_data))
|
|
960
1021
|
logger.error("Tool call failed: %s", e, exc_info=True)
|
|
961
1022
|
raise
|
|
1023
|
+
|
|
1024
|
+
def _resolve_tool_schema_name(self, tool_name: str) -> str:
|
|
1025
|
+
"""Resolve a tool's configured span type, if one exists."""
|
|
1026
|
+
return self._tool_span_types.get(tool_name, "langchain:tool")
|