Skip to content

feat: implement official LangChain integration (Pattern B) #2#10

Open
vinamradev wants to merge 2 commits into
jamjet-labs:mainfrom
vinamradev:patch-3
Open

feat: implement official LangChain integration (Pattern B) #2#10
vinamradev wants to merge 2 commits into
jamjet-labs:mainfrom
vinamradev:patch-3

Conversation

@vinamradev

@vinamradev vinamradev commented Jul 4, 2026

Copy link
Copy Markdown

Closes #2

What does this PR do?

This PR adds the official LangChain integration for JamJet using Pattern B. It wraps the LangChain AgentExecutor inside a JamJet workflow step using Pydantic state models to ensure full durability and checkpointing on process restarts.

Deliverables included:

  • Full main.py implementation with sample LangChain tools.
  • Completed README.md as per the python integration template.

Summary by CodeRabbit

  • New Features

    • Added a runnable example workflow that demonstrates agent-based task execution and returns a computed result.
    • Included a simple built-in calculation example to show how tool usage works end to end.
  • Documentation

    • Updated the Python integration template README with a clearer example author link.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a new main.py example implementing a durable JamJet workflow that wraps a LangChain AgentExecutor with a calculate_square tool, using a Pydantic State model for input/output. Also updates the integration template README's "Built by" attribution link.

Changes

LangChain Workflow Example

Layer / File(s) Summary
Workflow setup, state contract, and tool definition
main.py
Initializes Workflow("langchain-example"), defines a Pydantic State model with query and optional result, and adds a calculate_square LangChain tool.
Durable workflow step and entrypoint
main.py
Implements the async run(state) step that validates OPENAI_API_KEY, builds a ChatOpenAI model, ChatPromptTemplate, AgentExecutor, invokes the agent via run_in_executor, and returns updated state; adds a __main__ block to exercise the step.
Template README attribution update
integrations/_template/python/README.md
Replaces the placeholder GitHub handle in the "Built by" line with a concrete GitHub profile link.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Main as __main__
  participant Workflow as run(state)
  participant Agent as AgentExecutor
  participant LLM as ChatOpenAI

  Main->>Workflow: run(initial State)
  Workflow->>LLM: construct ChatOpenAI
  Workflow->>Agent: create_openai_tools_agent + AgentExecutor
  Workflow->>Agent: invoke({"input": state.query}) via run_in_executor
  Agent->>LLM: process query with calculate_square tool
  LLM-->>Agent: output
  Agent-->>Workflow: agent output
  Workflow-->>Main: State with result
Loading

Possibly related PRs

  • jamjet-labs/jamjet-examples#1: Added the integrations/_template/python/README.md template scaffolding whose "Built by" attribution line is edited in this PR.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: adding the official LangChain integration using Pattern B.
Linked Issues check ✅ Passed The PR implements the requested JamJet × LangChain Pattern B example and updates the integration README as expected.
Out of Scope Changes check ✅ Passed The README author-credit update and new main.py example both align with the linked integration work.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
main.py (2)

1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: replace the ambiguous × in the docstring.

Ruff flags the × (U+00D7 MULTIPLICATION SIGN) as ambiguous (RUF002). If you want a clean lint run, use an ASCII x or reword (e.g. "LangChain + JamJet").

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@main.py` at line 1, The module docstring uses the ambiguous `×` character,
which triggers Ruff’s RUF002 warning. Update the top-level docstring in
`main.py` to use an ASCII alternative such as `x` or rephrase it (for example,
using `+`) so the import-level documentation stays lint-clean.

Source: Linters/SAST tools


59-65: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Use ainvoke here instead of run_in_executor

AgentExecutor supports async execution directly, so this can await the agent without the extra thread hop or asyncio.get_event_loop() call.

♻️ Proposed refactor
-    # Execute the agent synchronously inside the async thread pool wrapper
-    # (Since LangChain invoke runs synchronously by default here)
-    loop = asyncio.get_event_loop()
-    response = await loop.run_in_executor(
-        None, 
-        lambda: agent_executor.invoke({"input": state.query})
-    )
+    # Execute the agent using LangChain's native async interface
+    response = await agent_executor.ainvoke({"input": state.query})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@main.py` around lines 59 - 65, The async execution in the agent flow still
uses `asyncio.get_event_loop()` and `run_in_executor` in the
`AgentExecutor.invoke` path, which adds an unnecessary thread hop. Update this
call site to use `AgentExecutor.ainvoke` directly and await it with the same
input payload, keeping the surrounding async flow in `main.py` unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@integrations/_template/python/README.md`:
- Around line 61-62: The attribution text in the README has malformed markdown,
so the profile link is not rendered correctly. Update the integration
attribution in the README template so the author handle is written with valid
link syntax and the “JamJet × {{Framework}} integration” text remains plain
readable text. Use the unique placeholder block around the attribution near the
{{Framework}} integration heading to find and correct it.

---

Nitpick comments:
In `@main.py`:
- Line 1: The module docstring uses the ambiguous `×` character, which triggers
Ruff’s RUF002 warning. Update the top-level docstring in `main.py` to use an
ASCII alternative such as `x` or rephrase it (for example, using `+`) so the
import-level documentation stays lint-clean.
- Around line 59-65: The async execution in the agent flow still uses
`asyncio.get_event_loop()` and `run_in_executor` in the `AgentExecutor.invoke`
path, which adds an unnecessary thread hop. Update this call site to use
`AgentExecutor.ainvoke` directly and await it with the same input payload,
keeping the surrounding async flow in `main.py` unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6adfe022-03d1-474b-992f-9e0d8efc6d7e

📥 Commits

Reviewing files that changed from the base of the PR and between 0aab285 and 760fca6.

📒 Files selected for processing (2)
  • integrations/_template/python/README.md
  • main.py

Comment on lines +61 to 62
[(https://github.com/vinamradev) — first JamJet ×
{{Framework}} integration.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the broken markdown link.

The attribution renders as malformed markdown here, so the profile won’t be clickable and the text will look odd in the README.

Suggested fix
-[(https://github.com/vinamradev) — first JamJet ×
-{{Framework}} integration.
+[vinamradev](https://github.com/vinamradev) — first JamJet ×
+{{Framework}} integration.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
[(https://github.com/vinamradev) — first JamJet ×
{{Framework}} integration.
[vinamradev](https://github.com/vinamradev) — first JamJet ×
{{Framework}} integration.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@integrations/_template/python/README.md` around lines 61 - 62, The
attribution text in the README has malformed markdown, so the profile link is
not rendered correctly. Update the integration attribution in the README
template so the author handle is written with valid link syntax and the “JamJet
× {{Framework}} integration” text remains plain readable text. Use the unique
placeholder block around the attribution near the {{Framework}} integration
heading to find and correct it.

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.

[Wanted] LangChain integration example

1 participant