Skip to content

feat: replace LangChainProvider with Runner protocol implementation (AIC-2388)#1338

Open
jsonbailey wants to merge 7 commits intonext-ai-releasefrom
jb/aic-2388/js-langchain-runner
Open

feat: replace LangChainProvider with Runner protocol implementation (AIC-2388)#1338
jsonbailey wants to merge 7 commits intonext-ai-releasefrom
jb/aic-2388/js-langchain-runner

Conversation

@jsonbailey
Copy link
Copy Markdown
Contributor

@jsonbailey jsonbailey commented Apr 28, 2026

Summary

Replaces the legacy LangChainProvider extension model with the Runner protocol for the LangChain provider package. This is a breaking changeLangChainProvider is removed.

Removed:

  • LangChainProvider class and its tests — callers must migrate to the new factory/runner pattern

Added:

  • LangChainModelRunnerRunner for chat completions; run(input: string | LDMessage[], outputType?) returns RunnerResult { content, metrics, raw, parsed? }. Structured output is parsed via withStructuredOutput.
  • LangChainAgentRunnerRunner for a single agent. Runs a tool-calling loop using LangChain's native bindTools and ToolMessage. Tool definitions come from config.model.parameters.tools; tool callables come from a caller-supplied ToolRegistry. Populates LDAIMetrics.toolCalls with the names of tools invoked.
  • LangChainRunnerFactory — extends AIProvider; exposes createModel(config) and createAgent(config, tools?). Applies OpenTelemetry instrumentation (via @traceloop/instrumentation-langchain) fire-and-forget in the constructor if available.

Renamed / moved:

  • langchainHelper.tsLangChainHelper.ts (casing fix)
  • createLangChainModel moved from LangChainRunnerFactory into LangChainHelper and exported from the package

Renamed:

  • mapProvidermapProviderName in helper exports

Test plan

  • yarn workspace @launchdarkly/server-sdk-ai-langchain test — all tests pass
  • yarn workspace @launchdarkly/server-sdk-ai-langchain lint — clean
  • yarn workspace @launchdarkly/server-sdk-ai-langchain run build — clean

🤖 Generated with Claude Code


Note

High Risk
High risk because it removes the exported LangChainProvider API and replaces it with new Runner/factory entrypoints, requiring downstream migration and potentially affecting tool-calling and metrics behavior.

Overview
Breaking change: removes LangChainProvider (and its tests) and switches the package API to the LaunchDarkly Runner protocol.

Adds LangChainModelRunner for chat completions (string + optional structured output) and LangChainAgentRunner for tool-calling agents (binds tools from config, executes a caller-supplied ToolRegistry, aggregates token usage, and records invoked tool names). Introduces LangChainRunnerFactory to build these runners and keep the existing optional OpenTelemetry instrumentation, and exports new helpers (createLangChainModel, message conversion, provider-name mapping, and usage/metrics extraction) from index.ts.

Reviewed by Cursor Bugbot for commit 2479fb2. Bugbot is set up for automated code reviews on this repo. Configure here.


Open in Devin Review

@jsonbailey jsonbailey force-pushed the jb/aic-2388/js-openai-runner branch from 07f1af2 to 66bb862 Compare May 1, 2026 14:10
@jsonbailey jsonbailey force-pushed the jb/aic-2388/js-langchain-runner branch from 7a6a7b8 to 58f8249 Compare May 1, 2026 14:13
@jsonbailey jsonbailey force-pushed the jb/aic-2388/js-openai-runner branch from 66bb862 to c9d433a Compare May 4, 2026 21:59
@jsonbailey jsonbailey force-pushed the jb/aic-2388/js-langchain-runner branch from 58f8249 to fa4a5cf Compare May 4, 2026 21:59
@jsonbailey jsonbailey force-pushed the jb/aic-2388/js-openai-runner branch from c9d433a to 42f17c6 Compare May 5, 2026 14:13
@jsonbailey jsonbailey force-pushed the jb/aic-2388/js-langchain-runner branch from fa4a5cf to 1b5dcc1 Compare May 5, 2026 14:13
@jsonbailey jsonbailey force-pushed the jb/aic-2388/js-openai-runner branch from 42f17c6 to 6902ffa Compare May 5, 2026 17:10
jsonbailey and others added 2 commits May 5, 2026 12:28
Adds LangChainModelRunner, LangChainAgentRunner, and LangChainRunnerFactory
that implement the Runner protocol introduced in JS PR 6. The runners take
an LDAICompletionConfig / LDAIAgentConfig at construction and expose
run(prompt: string) returning RunnerResult.

LangChainModelRunner.run(prompt) prepends the config's messages before the
user prompt. LangChainAgentRunner uses LangChain's native bindTools to run
a tool-calling loop, populating LDAIMetrics.toolCalls with the names of
tools the model invoked. Tool implementations are supplied via a
ToolRegistry passed to LangChainRunnerFactory.createAgent.

mapProvider is renamed to mapProviderName on both the helper module and
the LangChainProvider class; the old mapProvider name is kept as a
deprecated alias. The deprecated LangChainProvider class is preserved so
AIProviderFactory continues to work during the migration.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@jsonbailey jsonbailey force-pushed the jb/aic-2388/js-langchain-runner branch from 1b5dcc1 to 175c210 Compare May 5, 2026 17:30
jsonbailey and others added 3 commits May 5, 2026 12:41
…ent on construction

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jsonbailey jsonbailey changed the base branch from jb/aic-2388/js-openai-runner to next-ai-release May 5, 2026 18:50
@jsonbailey jsonbailey changed the title feat: add LangChain Runner protocol implementation (AIC-2388) feat: replace LangChainProvider with Runner protocol implementation (AIC-2388) May 5, 2026
@jsonbailey jsonbailey marked this pull request as ready for review May 5, 2026 20:16
@jsonbailey jsonbailey requested a review from a team as a code owner May 5, 2026 20:16
joker23
joker23 previously approved these changes May 5, 2026
cursor[bot]

This comment was marked as resolved.

@joker23 joker23 self-requested a review May 5, 2026 20:29
@joker23 joker23 dismissed their stale review May 5, 2026 20:30

accidental

devin-ai-integration[bot]

This comment was marked as resolved.

jsonbailey and others added 2 commits May 5, 2026 15:37
Previously the tool-calling loop fell off the end silently and returned
success=true. Now only the clean-exit path (no more tool calls) sets
success=true; hitting the iteration cap returns success=false with a
logger warning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
JSON.stringify(undefined) returns undefined (not a string), producing a
malformed ToolMessage content. Nullish-coalesce to empty string so the
message content is always a valid string.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jsonbailey jsonbailey requested a review from joker23 May 5, 2026 20:44
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2479fb2. Configure here.

}),
);
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent executes tools on final iteration without consuming results

Medium Severity

When MAX_ITERATIONS is exhausted, the loop still executes all tool calls on the final iteration (i=24) even though their results are never sent back to the model. Tools with side effects (database writes, external API calls, mutations) will be triggered unnecessarily, and the latency of those calls is wasted. The loop structure doesn't check whether it's on the last iteration before calling _executeTool. This was flagged in PR discussion by @joker23.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2479fb2. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants