feat(ai): add LangChain v1 agent middleware - #4556
Conversation
|
@greptileai review |
Prompt To Fix All With AI### Issue 1
packages/ai/src/langchain/middleware/index.ts:129
**Explicit trace breaks parent linkage**
When `traceId` is configured, the callback fallback assigns that trace ID as each model or tool event's `$ai_parent_id`, while the emitted agent root has a distinct generated `$ai_span_id`, causing the child events to detach from the agent root in the trace hierarchy.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "feat(ai): add LangChain v1 agent middlew..." | Re-trigger Greptile |
|
@greptileai review |
|
Reviews (2): Last reviewed commit: "fix(ai): preserve middleware trace hiera..." | Re-trigger Greptile |
Refresh the AI package manifest and lockfile with the dependency updates already on main so GitHub can update the PR branch without conflicts.
Keep the LangChain-only lockfile entries together so the current main lockfile can merge without content conflicts. This changes ordering only.
marandaneto
left a comment
There was a problem hiding this comment.
Automated advisory code review.
|
|
||
| return createMiddleware({ | ||
| name: 'PostHogMiddleware', | ||
| stateSchema: postHogStateSchema, |
There was a problem hiding this comment.
blocking: Preserve custom agent state in traces — LangChain projects lifecycle-hook state through this middleware schema, which only declares the _posthog* fields plus built-ins. With a custom createAgent({ stateSchema }), fields such as tenant or workflow context remain in the agent result but are silently absent from $ai_input_state and $ai_output_state; a custom-state probe reproduced the omission.
| ) | ||
| const invocationParams = { | ||
| ...request.modelSettings, | ||
| tools: request.tools, |
There was a problem hiding this comment.
blocking: Normalize tools before capture — request.tools contains DynamicStructuredTool instances, so standard tool(...) values serialize in $ai_tools as a generic {"type":"not_implemented","id":["langchain","tools","DynamicStructuredTool"]}, losing the actual name, description, and schema. Normalize these instances to capture-ready definitions before passing them to the callback handler.
|
thanks @gouveags |
Problem
@posthog/aisupports LangChain through its callback handler, but it does not expose a middleware-native integration for LangChain v1 agents. Users adopting the v1 middleware API therefore have no first-party middleware for capturing agent traces, model generations, and tool spans.Closes #2907.
Changes
createPostHogMiddlewareat@posthog/ai/langchain/middleware.@posthog/ai/langchaincallback-only, so existing users do not need the optionallangchainruntime.Use either the callback or the middleware, not both, to avoid duplicate events. On a terminal agent failure, LangChain does not invoke
afterAgent; the failed model or tool event is still captured, but no root trace is emitted.Release info Sub-libraries affected
Libraries affected
Checklist
If releasing new changes
pnpm changesetto generate a changeset file🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Gabriel directed the contribution. I used Codex for implementation, test design, and independent review. The middleware lives in a separate subpath so callback-only users do not load the optional
langchainruntime, while event normalization continues to use the existing callback handler. A public session link is unavailable in this environment.