This guide covers breaking changes and deprecations introduced in v0.3.0. The primary change is replacing exception-throwing APIs with type-safe Result[T] alternatives.
// Beforevalstate=agent.initialize(query,tools)// throws on failure// Afteragent.initializeSafe(query,tools)match{caseRight(state)=>// continuecaseLeft(err)=>println(s"Init failed: ${err.formatted}")}
Chaining with the LLM for-comprehension
The new safe APIs compose naturally in for-comprehensions alongside other Result-returning code:
1
2
3
4
5
6
7
8
for{providerConfig<-Llm4sConfig.provider()client<-LLMConnect.getClient(providerConfig)tools<-BuiltinTools.coreSafeagent=newAgent(client)registry=newToolRegistry(tools)state<-agent.run("What time is it?",registry)}yieldstate
Why lazy val for Deprecated Wrappers
The deprecated tool vals (DateTimeTool.tool, etc.) are lazy val rather than val intentionally.
A regular val is evaluated eagerly when the enclosing object is first loaded. This means accessing DateTimeTool.toolSafe (the safe API) would also trigger evaluation of DateTimeTool.tool (the deprecated one), potentially throwing before you ever called the deprecated method.
lazy val defers evaluation until the member is explicitly accessed, so only callers of the deprecated API see the exception. Users of toolSafe are unaffected.
Compiler Warnings
After migrating, enable fatal deprecation warnings to catch any remaining uses:
1
2
// build.sbtscalacOptions+="-Xfatal-warnings"
Or check for remaining deprecated usages without failing the build: