importorg.llm4s.config.Llm4sConfigimportorg.llm4s.llmconnect.LLMConnectimportorg.llm4s.agent.Agentimportorg.llm4s.toolapi.ToolRegistry// Create an agent and run a queryvalresult=for{providerConfig<-Llm4sConfig.provider()client<-LLMConnect.getClient(providerConfig)agent=newAgent(client)state<-agent.run(query="What is the capital of France?",tools=ToolRegistry.empty)}yieldstateresultmatch{caseRight(state)=>println(state.lastAssistantMessage)caseLeft(error)=>println(s"Error: $error")}
importorg.llm4s.toolapi.{ToolRegistry,ToolFunction}// Define a tooldefgetWeather(location:String):String={s"The weather in $location is sunny, 72F"}valweatherTool=ToolFunction(name="get_weather",description="Get current weather for a location",function=getWeather_)// Run agent with toolsvalresult=for{providerConfig<-Llm4sConfig.provider()client<-LLMConnect.getClient(providerConfig)agent=newAgent(client)tools=newToolRegistry(Seq(weatherTool))state<-agent.run("What's the weather in Paris?",tools)}yieldstate
Multi-Turn Conversations
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Functional multi-turn patternvalresult=for{providerConfig<-Llm4sConfig.provider()client<-LLMConnect.getClient(providerConfig)agent=newAgent(client)tools=ToolRegistry.empty// First turnstate1<-agent.run("Tell me about Scala",tools)// Follow-up (preserves context)state2<-agent.continueConversation(state1,"How does it compare to Java?")// Another follow-upstate3<-agent.continueConversation(state2,"What about performance?")}yieldstate3
Safety Defaults
Agent step limit: Agent.run(...) defaults to maxSteps = Some(50) to prevent infinite loops. Pass maxSteps = None to allow unlimited steps.
HTTPTool methods: HttpConfig() defaults to GET and HEAD only. Use HttpConfig.withWriteMethods() or HttpConfig().withAllMethods to allow write methods.
Core Concepts
Agent State
The AgentState is an immutable container that tracks:
Conversation history - All messages exchanged
Available tools - Tools the agent can call
Status - InProgress, WaitingForTools, Complete, Failed, or HandoffRequested
System message - Instructions for the LLM
Completion options - Temperature, max tokens, etc.
1
2
// Agent state is immutable - operations return new statesvalnewState=state.addMessage(UserMessage("Follow-up question"))
Agent Lifecycle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Initial Query
|
v
+----------+ LLM Call +------------------+
| InProgress| --------------> | WaitingForTools |
+----------+ +------------------+
^ |
| Tool Execution |
+-------------------------------+
|
v (no more tool calls)
+----------+
| Complete |
+----------+
Tool Execution Strategies
Control how multiple tool calls are executed:
1
2
3
4
5
6
7
8
9
10
importorg.llm4s.agent.ToolExecutionStrategy// Sequential (default) - one at a time, safestagent.run(query,tools)// Parallel - all at once, fastestagent.runWithStrategy(query,tools,ToolExecutionStrategy.Parallel)// Parallel with limit - balance speed and resourcesagent.runWithStrategy(query,tools,ToolExecutionStrategy.ParallelWithLimit(3))
importorg.llm4s.toolapi.builtin.BuiltinTools// Core tools (always safe)BuiltinTools.core// DateTime, Calculator, UUID, JSON// Safe for most use casesBuiltinTools.safe()// + web search, HTTP// With file access (read-only)BuiltinTools.withFiles()// + read-only file access// All tools (use with caution)BuiltinTools.development()// All tools including write access
Available tools:
Tool
Description
DateTimeTool
Current date/time, timezone conversion
CalculatorTool
Mathematical calculations
UUIDTool
Generate unique identifiers
JSONTool
Parse and format JSON
HTTPTool
Make HTTP requests
WebSearchTool
Search the web
FileReadTool
Read files (with restrictions)
ShellTool
Execute shell commands (development only)
Context Window Management
Handle long conversations automatically:
1
2
3
4
5
6
7
8
9
10
11
12
importorg.llm4s.agent.{ContextWindowConfig,PruningStrategy}valconfig=ContextWindowConfig(maxMessages=Some(20),preserveSystemMessage=true,minRecentTurns=2,pruningStrategy=PruningStrategy.OldestFirst)// Use with runMultiTurn for automatic pruningvalqueries=Seq("Question 1","Question 2","Question 3")agent.runMultiTurn(queries,tools,contextConfig=Some(config))
Pruning Strategies:
Strategy
Behavior
OldestFirst
Remove oldest messages first (FIFO)
MiddleOut
Keep first and last messages, remove middle
RecentTurnsOnly(n)
Keep only the last N conversation turns
Custom(fn)
User-defined pruning function
Conversation Persistence
Save and resume conversations:
1
2
3
4
5
6
7
8
// Save state to diskAgentState.saveToFile(state,"/tmp/conversation.json")// Load and resumevalresult=for{loadedState<-AgentState.loadFromFile("/tmp/conversation.json",tools)resumedState<-agent.continueConversation(loadedState,"Continue our conversation")}yieldresumedState
Reasoning Modes
Enable extended thinking for complex problems:
1
2
3
4
5
6
7
8
importorg.llm4s.llmconnect.model.{CompletionOptions,ReasoningEffort}valoptions=CompletionOptions().withReasoning(ReasoningEffort.High)// None, Low, Medium, High.copy(maxTokens=Some(4096))// Use with agentagent.run(query,tools,completionOptions=Some(options))
Supported by OpenAI o1/o3 and Anthropic Claude models.