Skip to content

Conversation

@gomesalexandre
Copy link
Contributor

@gomesalexandre gomesalexandre commented Apr 30, 2025

⚠️ Make sure to keep the default merge option here, not squash and merge:

image Screenshot 2025-04-30 at 09 47 05

Description

This adds langchain as a separate project, taken from https://github.com/gomesalexandre/shapeshift-langchainjs
Also

Notes:

  • this excludes it from CI for the time being, as we'll need to tweak a few things in CI world to make this happy.
  • this only adds it as a separate project for now - will give a go to integrating this in agent in a follow-up, the idea would be to share tools/libs across nx projects, and to have two instances of langchain, one which is is its own project for debug/chat UI purposes, and the other which would live as a web environment langchainjs and consume the same tools.

Since there is a lot of boilerplate, here is the files you want to explicitly look at, mainly:

  • apps/langchain/src/agent/graph.ts - the agent graph for the agent running as a dedicated langgraph project. Don't focus on agent/tool logic there, it exists just as a PoC for now.
  • apps/agentic-chat/src/lib/langchain.ts - the in-browser agent i.e the one that's actually consumed by the app
  • /tools - agentic tools as a nx utils package (bebop rate and tokens search with portals), shared between the agentic standalone app and the agentic chat
  • /utils - various utils as a nx utils package (BN utils for now), shared between the agentic standalone app and the agentic chat

Issue

Testing

  • yarn
  • Build libs (not sure this is required, but doesn't hurt to) with npx nx build @agentic-chat/utils && npx nx build @agentic-chat/tools
  • cp .env.example .env and populate Portals and OpenAPI API keys

Langgraph app

Chat UI

  • npx nx serve agentic-chat

@gomesalexandre gomesalexandre marked this pull request as draft April 30, 2025 06:55
@nx-cloud
Copy link

nx-cloud bot commented Apr 30, 2025

View your CI Pipeline Execution ↗ for commit b0c51ef.

Command Status Duration Result
nx affected -t lint test build ✅ Succeeded 3s View ↗

☁️ Nx Cloud last updated this comment at 2025-05-12 07:01:46 UTC

@gomesalexandre gomesalexandre marked this pull request as ready for review April 30, 2025 07:57
@gomesalexandre gomesalexandre marked this pull request as draft April 30, 2025 16:30
@gomesalexandre gomesalexandre changed the title feat: add langchain project feat: add langchain project and langchainjs wire-up Apr 30, 2025
@gomesalexandre gomesalexandre marked this pull request as ready for review April 30, 2025 20:25
Comment on lines +19 to +54
const [isProcessing, setIsProcessing] = useState(false);

const handleSendMessage = async (content: string) => {
try {
setIsProcessing(true);

// Add user message
const userMessage: Message = {
id: (messages.length + 1).toString(),
sender: 'user',
content,
};
setMessages((prev) => [...prev, userMessage]);

// Process message through LangGraph
const aiResponse = await runMessageGraph(content);

const handleSendMessage = (content: string) => {
const newMessage: Message = {
id: (messages.length + 1).toString(), // Simple ID generation for example
sender: 'user',
content,
};
setMessages([...messages, newMessage]);
// Here you would typically trigger an AI response
// Add AI response
const aiMessage: Message = {
id: (messages.length + 2).toString(),
sender: 'ai',
content: aiResponse,
};
setMessages((prev) => [...prev, aiMessage]);
} catch (error) {
console.error('Error processing message:', error);
// Add error message
const errorMessage: Message = {
id: (messages.length + 2).toString(),
sender: 'ai',
content: 'Sorry, I encountered an error processing your message.',
};
setMessages((prev) => [...prev, errorMessage]);
} finally {
setIsProcessing(false);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Vibe-coded logic to get things working as a PoC

Copy link
Member

@0xApotheosis 0xApotheosis left a comment

Choose a reason for hiding this comment

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

Brilliant ser, I like the use of nx libraries and projects to separate concerns and allow for reusability.

Some comments, feel free to tackle in this PR, or in a later one in the name of progress.

}).bindTools(tools);

// Define the function that determines whether to continue or not
function shouldContinue({ messages }: typeof MessagesAnnotation.State) {
Copy link
Member

Choose a reason for hiding this comment

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

Is there a tooling reason we don't use const/arrow function styles here, or just because this is LLM generated code for now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No reason, absolutely could! Will tackle in the follow-up PR not to rug the stack 🙏🏽

Comment on lines +42 to +47
const workflow = new StateGraph(MessagesAnnotation)
.addNode('agent', callModel)
.addEdge(START, 'agent')
.addNode('tools', toolNode)
.addEdge('tools', 'agent')
.addConditionalEdges('agent', shouldContinue);
Copy link
Member

Choose a reason for hiding this comment

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

For the visual learners.

Screenshot 2025-05-10 at 12 13 42 pm

Copy link
Contributor Author

Choose a reason for hiding this comment

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

One thing to note here @0xApotheosis - langchain project and the webapp do work a bit differently because of the use of the (deprecated) system prompts in langchain projecs mostly, I haven't really gone back to it on the follow-up PR which wires up things a bit more, but it still exists for our convenience.
Not sure if we'll end up using the langchain project in the end (i.e langsmith app + https://agentchat.vercel.app/) but if we do, we'll probably want to ensure that we don't go with langgraph ReAct flavour there (reason + act) but rather go with the legacy langchain agents flow i.e the same used in the webapp, to ensure that the two models work similarly.

Copy link
Member

Choose a reason for hiding this comment

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

Should this be ignored?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Seems to only be used for the README so might as well remove it 🙏🏽
b0c51ef

import qs from 'qs';
import { PortalsResponse, TokenSearchResult } from './types';

export const tokensSearch = tool(
Copy link
Member

Choose a reason for hiding this comment

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

From a developer experience perspective we might want to use a pattern that separated the function param from the fields param, e.g.

const fn = ...
const fields = ...
export const tokenSearch = tool(fn, fields)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Happy to tackle in the follow-up PR as a few things change there tools-wise!

- gnosis
- base
Use text proximity i.e if the user says on Binance Smart Chain, they mean bsc, if they say Avax, they mean avalanche, etc.
Copy link
Member

Choose a reason for hiding this comment

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

🧠

@gomesalexandre gomesalexandre merged commit dd328e3 into main May 12, 2025
1 check passed
This was referenced May 14, 2025
@0xApotheosis 0xApotheosis deleted the feat_langchain branch May 16, 2025 05:33
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.

Set up LangChain

3 participants