org.llm4s.agent

package org.llm4s.agent

Members list

Packages

Memory system for agent context and knowledge retention.

Memory system for agent context and knowledge retention.

The memory package provides a comprehensive system for agents to remember information across conversations, learn about entities, and retrieve relevant context for responses.

== Core Concepts ==

'''Memory Types:'''

  • Conversation - Messages from conversation history
  • Entity - Facts about people, organizations, concepts
  • Knowledge - Information from external documents
  • UserFact - Learned user preferences and background
  • Task - Records of completed tasks and outcomes

'''Components:'''

== Quick Start ==

import org.llm4s.agent.memory._

// Create a memory manager
val manager = SimpleMemoryManager.empty

// Record a user fact
val updated = manager.recordUserFact(
 "User prefers Scala over Java",
 userId = Some("user123")
)

// Record an entity fact
val entityId = EntityId.fromName("Scala")
val withEntity = updated.flatMap(_.recordEntityFact(
 entityId = entityId,
 entityName = "Scala",
 fact = "Scala is a programming language",
 entityType = "technology"
))

// Retrieve relevant context for a query
val context = withEntity.flatMap(_.getRelevantContext("Tell me about Scala"))

== Memory Filtering ==

Filters can be composed for complex queries:

import org.llm4s.agent.memory.MemoryFilter._

// Simple filters
val conversationsOnly = conversations
val importantOnly = important(0.7)

// Combined filters
val recentImportant = after(weekAgo) && important(0.5)
val entityOrKnowledge = entities || knowledge

// Recall with filter
store.recall(recentImportant, limit = 10)

== Storage Backends ==

Multiple backends are available:

  • memory.InMemoryStore - Fast, ephemeral storage for testing
  • (Future) SQLiteStore - Persistent local storage
  • (Future) VectorStore - Semantic search with embeddings

Attributes

See also

memory.SimpleMemoryManager for basic memory management

memory.MemoryFilter for filtering options

Type members

Classlikes

final class Agent

An agent family compiled onto the graph runtime: a model/tool loop whose conversations are threads of a org.llm4s.agent.graph.GraphRuntime. Built with Agent.builder.

An agent family compiled onto the graph runtime: a model/tool loop whose conversations are threads of a org.llm4s.agent.graph.GraphRuntime. Built with Agent.builder.

for
 agent  <- Agent.builder("assistant", client).withTools(registry).build()
 first  <- agent.run("What is the weather in Paris?")
 second <- agent.continueConversation(first, "And in London?")
yield second.answer

Every run is a turn on a thread. A run that reaches the graph's end is Right with status Completed, StepLimitReached or TokenLimitReached; one a guardrail blocks is Right with Blocked, the blocked turn absent from the thread; one that parks on approvals, questions or breakpoints is Right with Suspended, and continues with resume. Anything else is Left: a blank query and the runtime's refusals (ThreadBusy, TenantMismatch, IncompleteRun, PendingInterrupts, ...) leave the thread unchanged, as does another middleware's beforeAgent or afterAgent failure (a Block without a guardrail; a blank query or answer from a hook is one), which also ends the run; a failed run - a provider error, a tool's Fatal, a model or tool wrapper's failure, cancellation, a deadline - leaves the thread for recover. So does a run that lost its claim on the thread (GraphError.ClaimLost), once the thread is free: recover is refused with ThreadBusy while another runtime sharing the store holds it - retry - and if a successor finished the work, the thread's state shows it (recover then reports NothingToRecover). If the lease merely lapsed, with no successor, recover continues the interrupted turn.

Attributes

Companion
object
Supertypes
class Object
trait Matchable
class Any
object Agent

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
Agent.type
final class AgentBuilder

An agent's settings, immutable: every with* returns a new builder, and build compiles it, with every agent reachable through its handoffs, into an Agent. Start one with Agent.builder.

An agent's settings, immutable: every with* returns a new builder, and build compiles it, with every agent reachable through its handoffs, into an Agent. Start one with Agent.builder.

Tools, middleware, prompt and step limit belong to the agent, not to a run: the compiled graph's version covers them, so a thread is only ever continued by the graph it ran on. The runtime and tracing are the root's: a handoff target's are ignored.

Attributes

Companion
object
Supertypes
class Object
trait Matchable
class Any
object AgentBuilder

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
object AgentId

Attributes

Supertypes
class Object
trait Matchable
class Any
Self type
AgentId.type
enum AgentNode

A node of an agent's loop that a static breakpoint can hold: see AgentBuilder.withInterruptBefore and AgentBuilder.withInterruptAfter. Each task the breakpoint holds is an interrupt of its own, reported in AgentStatus.Suspended.breakpoints and continued with AgentResult.proceed.

A node of an agent's loop that a static breakpoint can hold: see AgentBuilder.withInterruptBefore and AgentBuilder.withInterruptAfter. Each task the breakpoint holds is an interrupt of its own, reported in AgentStatus.Suspended.breakpoints and continued with AgentResult.proceed.

A step continued after a review runs at another node: a model call after a wrapModelCall question at <id>/asked/<middleware>/wrapModelCall, a tool call after an approval or a question at <id>/approval, <id>/ask/<tool> or <id>/asked/<middleware>/wrapToolCall, and an answer after an afterAgent question at <id>/asked/<middleware>/afterAgent. A breakpoint after a node holds these too, so nothing the step does escapes it; a breakpoint before one does not, since the reviewer has just seen the step.

Attributes

Supertypes
trait Enum
trait Serializable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all
final case class AgentResult

The outcome of one agent run: where it ran, how it ended, and the thread's state at its end. A readable value, built only by Agent; a conversation continues by its threadId.

The outcome of one agent run: where it ran, how it ended, and the thread's state at its end. A readable value, built only by Agent; a conversation continues by its threadId.

Value parameters

activeAgent

the agent the thread is with at the run's end: the next turn starts with it

messages

the thread's full history, without system prompts

runId

this run

status

how the turn ended, or what it waits for

threadId

the conversation's thread

usage

token usage accumulated over the thread, per model

Attributes

Companion
object
Supertypes
trait Serializable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all
object AgentResult

Attributes

Companion
class
Supertypes
trait Product
trait Mirror
class Object
trait Matchable
class Any
Self type
final class AgentRun

A running agent turn, from Agent.start: cancel it, or await its AgentResult. The turn runs on its own thread, owned by the runtime, whether or not anyone awaits it.

A running agent turn, from Agent.start: cancel it, or await its AgentResult. The turn runs on its own thread, owned by the runtime, whether or not anyone awaits it.

Attributes

Supertypes
class Object
trait Matchable
class Any

How an agent's turn ended, or why it is waiting.

How an agent's turn ended, or why it is waiting.

Attributes

Supertypes
trait Enum
trait Serializable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all
case class ContextWindowConfig(maxTokens: Option[Int], maxMessages: Option[Int], preserveSystemMessage: Boolean, minRecentTurns: Int, pruningStrategy: PruningStrategy)

Configuration for automatic context window management.

Configuration for automatic context window management.

Provides flexible strategies for pruning conversation history to stay within token or message count limits.

Value parameters

maxMessages

Maximum number of messages to keep (simpler alternative to token-based)

maxTokens

Maximum number of tokens to keep (if specified, requires tokenCounter)

minRecentTurns

Minimum number of recent turns to preserve (even if limit exceeded)

preserveSystemMessage

Always keep the system message (recommended)

pruningStrategy

Strategy for pruning messages when limits are exceeded

Attributes

Supertypes
trait Serializable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all
final case class Handoff(id: String, target: Option[AgentBuilder], transferReason: Option[String], preserveContext: Boolean)

A transfer an agent's model may make to another agent of its family. build() compiles the root and every agent reachable through handoffs into one graph, keyed by agent id. The model is offered the handoff as a tool named handoff_to_<id>; calling it, as the only call of its message, moves the conversation to the target, which stays active - the next turn starts with it

A transfer an agent's model may make to another agent of its family. build() compiles the root and every agent reachable through handoffs into one graph, keyed by agent id. The model is offered the handoff as a tool named handoff_to_<id>; calling it, as the only call of its message, moves the conversation to the target, which stays active - the next turn starts with it

  • until it hands off again.

The target is either a builder (Handoff.to, Handoff.of), which brings that agent into the family, or an agent id alone (Handoff.toId), which names an agent some builder of the family defines. Builders are immutable, so a cycle - the specialist handing back to the agent that handed to it - names the earlier agent by id:

val physics = Agent.builder("physics", client)
 .withSystemPrompt("You are a physicist.")
 .withHandoffs(Handoff.toId("triage", "Questions that are not about physics"))
val triage = Agent.builder("triage", client)
 .withHandoffs(Handoff.to("physics", physics, "Requires physics expertise"))
 .build()

Value parameters

id

the target's agent id, [a-zA-Z0-9_-]{1,52}; build() refuses one that differs from target's, and an id-only target no builder of the family defines

preserveContext

when false, the target is sent only the user's last question before the transfer and the transfer onwards; the stored history is unchanged either way

target

the agent to hand off to, or None when it is named by id alone

transferReason

offered to the model in the handoff tool's description

Attributes

Companion
object
Supertypes
trait Serializable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all
object Handoff

Attributes

Companion
class
Supertypes
trait Product
trait Mirror
class Object
trait Matchable
class Any
Self type
Handoff.type
sealed trait PruningStrategy

Strategies for pruning conversation history when context limits are exceeded.

Strategies for pruning conversation history when context limits are exceeded.

Attributes

Companion
object
Supertypes
class Object
trait Matchable
class Any
Known subtypes

Attributes

Companion
trait
Supertypes
trait Sum
trait Mirror
class Object
trait Matchable
class Any
Self type

Types

opaque type AgentId

Stable identifier of an agent in a family: it prefixes the agent's graph nodes and is persisted as a thread's active agent. Must match [a-zA-Z0-9_-]{1,52}.

Stable identifier of an agent in a family: it prefixes the agent's graph nodes and is persisted as a thread's active agent. Must match [a-zA-Z0-9_-]{1,52}.

Attributes