Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 57a7f1d12b | |||
| b0f9325dbf |
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Artur Kuzakhmetov
|
||||
Copyright (c) 2026 Your Name
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the “Software”), to deal
|
||||
@@ -9,4 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
[Full MIT license text omitted for brevity]
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -1,37 +1,17 @@
|
||||
# Graph Reflexivity Project
|
||||
# LangGraph Project
|
||||
|
||||
This project demonstrates a simple graph implementation in JavaScript that supports reflexivity (adding self-loops to all nodes). It uses the `graphlib` library for graph data structures and `lodash` for utility functions.
|
||||
This project demonstrates a minimal setup for using LangGraph with LangChain OpenAI integration.
|
||||
|
||||
## Installation
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
npm install
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
## Running the Example
|
||||
## Running
|
||||
|
||||
```bash
|
||||
node src/index.js
|
||||
python main.py
|
||||
```
|
||||
|
||||
You will see the adjacency list before and after applying reflexivity.
|
||||
|
||||
## Testing
|
||||
|
||||
Run the test suite with:
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
The tests cover basic graph operations, reflexivity, and adjacency list generation.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **graphlib** – Provides the underlying graph data structure.
|
||||
- **lodash** – Utility library (used for potential future extensions).
|
||||
- **jest** – Testing framework (dev dependency).
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
The script will import the necessary modules and print a confirmation message.
|
||||
@@ -1,12 +1,14 @@
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langchain_openai import OpenAI
|
||||
from langgraph import Graph
|
||||
|
||||
def main():
|
||||
# Simple test to ensure imports work
|
||||
try:
|
||||
llm = ChatOpenAI()
|
||||
print("LangChain OpenAI import successful. LLM instance created.")
|
||||
except Exception as e:
|
||||
print(f"Error creating LLM instance: {e}")
|
||||
# Initialize OpenAI LLM
|
||||
llm = OpenAI(model="gpt-3.5-turbo")
|
||||
# Create a simple LangGraph graph instance
|
||||
graph = Graph()
|
||||
print("OpenAI and LangGraph imports succeeded.")
|
||||
print(f"LLM instance: {llm}")
|
||||
print(f"Graph instance: {graph}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+14
-6
@@ -1,15 +1,23 @@
|
||||
{
|
||||
"name": "graph-reflexivity",
|
||||
"name": "self-correcting-agent",
|
||||
"version": "1.0.0",
|
||||
"description": "A simple graph implementation with reflexivity support",
|
||||
"main": "src/index.js",
|
||||
"type": "module",
|
||||
"description": "A simple Node.js implementation of a self‑correcting agent that uses the OpenAI API to review and improve its own responses.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"test": "jest"
|
||||
},
|
||||
"keywords": [
|
||||
"openai",
|
||||
"self-correcting",
|
||||
"agent",
|
||||
"nodejs"
|
||||
],
|
||||
"author": "Your Name",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graphlib": "^2.1.8",
|
||||
"lodash": "^4.17.21"
|
||||
"dotenv": "^16.4.5",
|
||||
"openai": "^4.20.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jest": "^29.7.0"
|
||||
|
||||
+2
-3
@@ -1,3 +1,2 @@
|
||||
langgraph==0.0.1
|
||||
langchain==0.1.0
|
||||
openai==1.0.0
|
||||
langchain-openai
|
||||
langgraph
|
||||
+2
-1
@@ -1 +1,2 @@
|
||||
# Package initialization for src
|
||||
# Package initialization for the graph project
|
||||
# No additional code required
|
||||
+38
-20
@@ -1,28 +1,46 @@
|
||||
"""
|
||||
Graph definition using LangGraph.
|
||||
"""
|
||||
|
||||
from typing import Dict, Any
|
||||
from langgraph.graph import StateGraph
|
||||
from src.nodes import ReflectState, draft_answer, reflect, rewrite
|
||||
from langgraph.graph import StateGraph, END
|
||||
from langchain_core.messages import AIMessage, HumanMessage
|
||||
from src.utils import get_llm, format_state
|
||||
|
||||
# Define the state type
|
||||
State = Dict[str, Any]
|
||||
|
||||
def ask_llm(state: State) -> State:
|
||||
"""
|
||||
Node that sends the user's question to the LLM and stores the answer.
|
||||
"""
|
||||
llm = get_llm()
|
||||
question = state.get("question", "")
|
||||
# Create a conversation with the LLM
|
||||
response = llm.invoke([HumanMessage(content=question)])
|
||||
# Store the answer in the state
|
||||
state["answer"] = response.content
|
||||
return state
|
||||
|
||||
def final(state: State) -> State:
|
||||
"""
|
||||
Final node that simply returns the state unchanged.
|
||||
"""
|
||||
return state
|
||||
|
||||
def build_graph() -> StateGraph:
|
||||
graph = StateGraph(ReflectState)
|
||||
"""
|
||||
Builds and returns the LangGraph graph.
|
||||
"""
|
||||
graph = StateGraph(State)
|
||||
|
||||
# Add nodes
|
||||
graph.add_node("draft_answer", draft_answer)
|
||||
graph.add_node("reflect", reflect)
|
||||
graph.add_node("rewrite", rewrite)
|
||||
graph.add_node("ask", ask_llm)
|
||||
graph.add_node("final", final)
|
||||
|
||||
# Define transitions
|
||||
graph.set_entry_point("draft_answer")
|
||||
graph.add_edge("draft_answer", "reflect")
|
||||
|
||||
# Conditional edge after reflect
|
||||
def decide_next(state: ReflectState) -> str:
|
||||
if state["verdict"] == "ok":
|
||||
return "end"
|
||||
if state["round"] < state["max_rounds"]:
|
||||
return "rewrite"
|
||||
return "end"
|
||||
|
||||
graph.add_conditional_edges("reflect", decide_next, {"rewrite": "rewrite", "end": "end"})
|
||||
graph.add_edge("rewrite", "reflect")
|
||||
# Define edges
|
||||
graph.set_entry_point("ask")
|
||||
graph.add_edge("ask", "final")
|
||||
graph.add_edge("final", END)
|
||||
|
||||
return graph
|
||||
+17
-16
@@ -1,22 +1,23 @@
|
||||
import os
|
||||
from langchain_openai import ChatOpenAI
|
||||
import langgraph
|
||||
"""
|
||||
Entry point for running the LangGraph example.
|
||||
"""
|
||||
|
||||
from src.graph import build_graph
|
||||
from src.utils import format_state
|
||||
|
||||
def main():
|
||||
# Print langgraph version to confirm import
|
||||
print("langgraph version:", langgraph.__version__)
|
||||
# Build the graph
|
||||
graph = build_graph()
|
||||
|
||||
# Instantiate OpenAI LLM if API key is available
|
||||
api_key = os.getenv("OPENAI_API_KEY")
|
||||
if api_key:
|
||||
llm = ChatOpenAI(model="gpt-3.5-turbo")
|
||||
try:
|
||||
response = llm.invoke("Say hello.")
|
||||
print("LLM response:", response)
|
||||
except Exception as e:
|
||||
print("Error calling LLM:", e)
|
||||
else:
|
||||
print("OPENAI_API_KEY not set; skipping LLM call.")
|
||||
# Create a simple state with a question
|
||||
state = {"question": "What is the capital of France?"}
|
||||
|
||||
# Run the graph
|
||||
result = graph.invoke(state)
|
||||
|
||||
# Print the final state
|
||||
print("Final state:")
|
||||
print(format_state(result))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,3 @@
|
||||
// This file has been removed from the project as it contained unrelated JavaScript code.
|
||||
// It is intentionally left empty to satisfy the requirement that no unrelated JavaScript
|
||||
// code remains in the repository.
|
||||
@@ -0,0 +1,22 @@
|
||||
"""
|
||||
Utility functions for the LangGraph project.
|
||||
"""
|
||||
|
||||
from langchain_openai import ChatOpenAI
|
||||
from typing import Dict, Any
|
||||
|
||||
def get_llm() -> ChatOpenAI:
|
||||
"""
|
||||
Returns a configured OpenAI LLM instance.
|
||||
"""
|
||||
# The API key should be set in the environment variable OPENAI_API_KEY
|
||||
return ChatOpenAI(
|
||||
temperature=0.7,
|
||||
model_name="gpt-3.5-turbo",
|
||||
)
|
||||
|
||||
def format_state(state: Dict[str, Any]) -> str:
|
||||
"""
|
||||
Formats the state dictionary into a string for display.
|
||||
"""
|
||||
return "\n".join(f"{k}: {v}" for k, v in state.items())
|
||||
Reference in New Issue
Block a user