Skip to content

refactor(workflow-executor): drop direct @langchain dependency#1638

Merged
Scra3 merged 2 commits into
feat/prd-214-server-step-mapperfrom
chore/executor-drop-langchain-dep
Jun 9, 2026
Merged

refactor(workflow-executor): drop direct @langchain dependency#1638
Scra3 merged 2 commits into
feat/prd-214-server-step-mapperfrom
chore/executor-drop-langchain-dep

Conversation

@Scra3

@Scra3 Scra3 commented Jun 9, 2026

Copy link
Copy Markdown
Member

Why

The executor declared and imported @langchain/openai directly, while @forestadmin/ai-proxy already owns the langchain coupling (model construction, message/tool types). This removes that duplicated dependency edge.

What

  • ServerAiAdapter no longer instantiates ChatOpenAI itself. It builds a single synthetic openai AiConfiguration whose configuration.fetch is rewritten to hit the Forest AI proxy (/liana/v1/ai-proxy) with forest-secret-key, hands it to the AiClient it already owns, and delegates getModel() to AiClient.getModel() (→ createBaseChatModel). Runtime behavior is identical; the provider/model is still chosen server-side.
  • The remaining BaseChatModel type imports (server-ai-adapter, ai-client-adapter, always-error-ai-model-port, ports/ai-model-port) now come from the @forestadmin/ai-proxy façade, which already re-exports it.
  • @langchain/openai removed from packages/workflow-executor/package.json. The executor now imports from @langchain/* zero times — grep -rn "@langchain" src is empty.

Notes

  • yarn.lock is unchanged: @langchain/openai is still pulled transitively by ai-proxy, so only the workspace dependency edge is dropped.
  • server-ai-adapter.test.ts reworked: it now asserts the config handed to AiClient (provider/model/maxRetries + the fetch redirect to the proxy with forest-secret-key) and that getModel() delegates to the client.

Verification

  • yarn workspace @forestadmin/workflow-executor build
  • yarn workspace @forestadmin/workflow-executor lint ✅ (7 pre-existing warnings)
  • yarn workspace @forestadmin/workflow-executor test → 967 passed ✅
  • yarn workspace @forestadmin/ai-proxy test → 443 passed ✅

🤖 Generated with Claude Code

Note

Remove direct @langchain/openai dependency from workflow-executor in favor of @forestadmin/ai-proxy

  • Removes @langchain/openai from package.json and re-sources BaseChatModel and related types through @forestadmin/ai-proxy.
  • Refactors ServerAiAdapter to instantiate AiClient (from ai-proxy) with a pre-built proxy configuration via a new buildProxyConfiguration static method, replacing direct ChatOpenAI construction.
  • getModel now delegates to AiClient.getModel() rather than constructing the model inline; the proxy URL rewriting and header swap (Authorizationforest-secret-key) move into the configuration builder.

Changes since #1638 opened

  • Modified StepExecutorFactory.create factory method to return executors that surface WorkflowExecutorError.userMessage in stepOutcome.error when factory construction fails with a WorkflowExecutorError, replacing the previous generic error message [45c47af]
  • Refactored AiClient mocking infrastructure in test files to use explicit jest.fn mocks for constructor argument capture and method delegation [45c47af]
  • Added test coverage verifying that StepExecutorFactory.create surfaces userMessage from WorkflowExecutorError instances in stepOutcome.error [45c47af]

Macroscope summarized b5cbae2.

ServerAiAdapter now builds its model through AiClient.getModel (passing a
single openai config whose fetch is rewritten to the Forest AI proxy) instead
of instantiating ChatOpenAI directly. The remaining BaseChatModel type imports
are routed through the @forestadmin/ai-proxy facade, which already re-exports
the langchain types the executor needs.

This removes @langchain/openai from the package's dependencies — the executor
no longer imports from @langchain/* at all; ai-proxy owns the langchain coupling.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@qltysh

qltysh Bot commented Jun 9, 2026

Copy link
Copy Markdown

Qlty


Coverage Impact

This PR will not change total coverage.

Modified Files with Diff Coverage (2)

RatingFile% DiffUncovered Line #s
Coverage rating: A Coverage rating: A
packages/workflow-executor/src/executors/step-executor-factory.ts100.0%
Coverage rating: B Coverage rating: B
packages/workflow-executor/src/adapters/server-ai-adapter.ts100.0%
Total100.0%
🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

@PMerlet PMerlet left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

…context build failure

The StepExecutorFactory catch returned a generic "An unexpected error
occurred." for every construction failure, discarding the userMessage carried
by domain errors (e.g. AiModelPortError, StepStateError) thrown while building
the execution context — mirroring base-step-executor's existing handling.

Also strengthen ServerAiAdapter tests: assert the delegation arguments
(loadRemoteTools/closeConnections), the load-bearing apiKey placeholder and the
config name, and reset mocks per test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@qltysh

qltysh Bot commented Jun 9, 2026

Copy link
Copy Markdown

1 new issue

Tool Category Rule Count
qlty Structure Function with many returns (count = 8): create 1

@Scra3 Scra3 merged commit 37aa1fb into feat/prd-214-server-step-mapper Jun 9, 2026
29 checks passed
@Scra3 Scra3 deleted the chore/executor-drop-langchain-dep branch June 9, 2026 11:45
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