99 (tool_search + tool_execute). The LLM discovers and runs tools on-demand,
1010 keeping token usage constant regardless of catalog size.
1111
12- This example demonstrates approach 2 with OpenAI and LangChain clients .
12+ This example demonstrates approach 2 with a Gemini client (OpenAI-compatible) .
1313
1414Prerequisites:
1515 - STACKONE_API_KEY environment variable
1616 - STACKONE_ACCOUNT_ID environment variable
1717 - GOOGLE_API_KEY environment variable (for Gemini)
18- - OPENAI_API_KEY environment variable (optional, for LangChain example)
1918
2019Run with:
2120 uv run python examples/meta_tools_example.py
@@ -68,8 +67,7 @@ def example_gemini() -> None:
6867 execute = {"account_ids" : [account_id ]} if account_id else None ,
6968 )
7069
71- # 2. Get meta tools in OpenAI format
72- meta_tools = toolset .get_meta_tools ()
70+ # 2. Get tools in OpenAI format
7371 openai_tools = toolset .openai (mode = "search_and_execute" )
7472
7573 # 3. Create Gemini client (OpenAI-compatible) and run agent loop
@@ -100,8 +98,7 @@ def example_gemini() -> None:
10098 messages .append (choice .message .model_dump (exclude_none = True ))
10199 for tool_call in choice .message .tool_calls :
102100 print (f" -> { tool_call .function .name } ({ tool_call .function .arguments } )" )
103- tool = meta_tools .get_tool (tool_call .function .name )
104- result = tool .execute (tool_call .function .arguments ) if tool else {"error" : "Unknown tool" }
101+ result = toolset .execute (tool_call .function .name , tool_call .function .arguments )
105102 messages .append (
106103 {
107104 "role" : "tool" ,
@@ -113,64 +110,6 @@ def example_gemini() -> None:
113110 print ()
114111
115112
116- def example_langchain () -> None :
117- """Complete LangChain integration with meta tools.
118-
119- Shows: init toolset -> bind tools to ChatOpenAI -> agent loop -> final answer.
120- """
121- print ("=" * 60 )
122- print ("Example 2: LangChain client with meta tools" )
123- print ("=" * 60 )
124- print ()
125-
126- try :
127- from langchain_core .messages import AIMessage , HumanMessage , ToolMessage
128- from langchain_google_genai import ChatGoogleGenerativeAI
129- except ImportError :
130- print ("Skipped: pip install langchain-google-genai" )
131- print ()
132- return
133-
134- if not os .getenv ("GOOGLE_API_KEY" ):
135- print ("Skipped: Set GOOGLE_API_KEY to run this example." )
136- print ()
137- return
138-
139- # 1. Init toolset
140- account_id = os .getenv ("STACKONE_ACCOUNT_ID" )
141- toolset = StackOneToolSet (
142- account_id = account_id ,
143- search = {"method" : "semantic" , "top_k" : 3 },
144- execute = {"account_ids" : [account_id ]} if account_id else None ,
145- )
146-
147- # 2. Get meta tools in LangChain format and bind to model
148- meta_tools = toolset .get_meta_tools ()
149- langchain_tools = meta_tools .to_langchain ()
150- model = ChatGoogleGenerativeAI (model = "gemini-3-pro-preview" ).bind_tools (langchain_tools )
151-
152- # 3. Run agent loop
153- messages = [HumanMessage (content = "List my upcoming Calendly events for the next week." )]
154-
155- for _step in range (10 ):
156- response : AIMessage = model .invoke (messages )
157-
158- # 4. If no tool calls, print final answer and stop
159- if not response .tool_calls :
160- print (f"Answer: { response .content } " )
161- break
162-
163- # 5. Execute tool calls and feed results back
164- messages .append (response )
165- for tool_call in response .tool_calls :
166- print (f" -> { tool_call ['name' ]} ({ json .dumps (tool_call ['args' ])} )" )
167- tool = meta_tools .get_tool (tool_call ["name" ])
168- result = tool .execute (tool_call ["args" ]) if tool else {"error" : "Unknown tool" }
169- messages .append (ToolMessage (content = json .dumps (result ), tool_call_id = tool_call ["id" ]))
170-
171- print ()
172-
173-
174113def main () -> None :
175114 """Run all meta tools examples."""
176115 api_key = os .getenv ("STACKONE_API_KEY" )
@@ -179,7 +118,6 @@ def main() -> None:
179118 return
180119
181120 example_gemini ()
182- example_langchain ()
183121
184122
185123if __name__ == "__main__" :
0 commit comments