Star A Repository on GitHub
In this example, we will use LangGraph Agent to star a repository on GitHub using Composio Tools1
Install Packages
pip install composio-langgraph
npm i @langchain/langgraph
npm i composio-core
npm i @langchain/openai
npm i @langchain/core
2
Import Libraries & Initialize ComposioToolSet
from typing import Literal
from langchain_openai import ChatOpenAI
from langgraph.graph import MessagesState, StateGraph
from langgraph.prebuilt import ToolNode
from composio_langgraph import Action, ComposioToolSet, App
composio_toolset = ComposioToolSet()
import { LangGraphToolSet } from "composio-core";
import { ToolNode } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
import { StateGraph, END, MessagesAnnotation, START } from "@langchain/langgraph";
import { HumanMessage } from "@langchain/core/messages";
const composioToolset = new LangGraphToolSet();
3
Connect Your GitHub Account
You need to have an active GitHub Integration. Learn how to do this here
composio login
composio add github
request = composio_toolset.initiate_connection(app=App.GITHUB)
print(f"Open this URL to authenticate: {request.redirectUrl}")
const connection = await composioToolset.connectedAccounts.initiate({appName: "github"})
console.log(`Open this URL to authenticate: ${connection.redirectUrl}`);
Donโt forget to set your
COMPOSIO_API_KEY and OPENAI_API_KEY in your environment variables.4
Get And Bind Tools
You can get all the tools for a given app as shown below, but you can get specific actions and filter actions using usecase & tags. Learn more here
tools = composio_toolset.get_tools(
apps=[App.GITHUB]
)
tool_node = ToolNode(tools)
model = ChatOpenAI(temperature=0, streaming=True)
model_with_tools = model.bind_tools(tools)
const tools = await composioToolset.getTools({
apps: ["github"],
});
const toolNode = new ToolNode(tools);
const model = new ChatOpenAI({ temperature: 0, apiKey:""}).bindTools(tools);
5
Define the model calling function
def call_model(state: MessagesState):
"""
Process messages through the LLM and return the response
"""
messages = state["messages"]
response = model_with_tools.invoke(messages)
return {"messages": [response]}
async function callModal(state) {
const { messages } = state;
const response = await model.invoke(messages);
return { messages: [response] };
}
6
Define the decision function for workflow routing
def should_continue(state: MessagesState) -> Literal["tools", "__end__"]:
"""
Determine if the conversation should continue to tools or end
Returns:
- "tools" if the last message contains tool calls
- "__end__" otherwise
"""
messages = state["messages"]
last_message = messages[-1]
if last_message.tool_calls:
return "tools"
return "__end__"
async function shouldContinue(state) {
const { messages } = state;
const lastMessage = messages[messages.length - 1];
if (lastMessage.additional_kwargs.tool_calls) {
return "tools";
} else {
return END;
}
}
7
Define the workflow graph
workflow = StateGraph(MessagesState)
workflow.add_node("agent", call_model)
workflow.add_node("tools", tool_node)
workflow.add_edge("__start__", "agent")
workflow.add_conditional_edges(
"agent",
should_continue,
)
workflow.add_edge("tools", "agent")
app = workflow.compile()
const workflow = new StateGraph(MessagesAnnotation)
.addNode("agent", callModal)
.addEdge(START, "agent")
.addNode("tools", toolNode)
.addConditionalEdges("agent", shouldContinue)
.addEdge("tools", "agent");
const app = workflow.compile();
8
Execute the workflow
for chunk in app.stream(
{
"messages": [
(
"human",
"Star the GitHub Repository composiohq/composio",
)
]
},
stream_mode="values",
):
chunk["messages"][-1].pretty_print()
const stream = await app.invoke({
messages: [
new HumanMessage("Star the GitHub Repository composiohq/composio"),
],
});
console.log(stream.messages[stream.messages.length - 1].content);