Skip to content

Conversation

@PranavPurwar
Copy link

Motivation and Context

Currently, the default agent types are designed to be used only once; they throws an IllegalStateException if you try to run it a second time. This prevents the creation of conversational, or manual feedback based agents.

This change introduces a flag (enforceSingleRun) that allows the agent to be reused for multiple interactions. When reused, the agent keeps its context history and state across runs.

This enables the development of conversational agents that can remember what happened in the previous step.

The change also updates the core run logic to ensure the agent's initial setup is only done once, guaranteeing the reuse of the context object for subsequent calls while correctly tracking the session.

Closes #1217

Example usage:

val agent = AIAgent(
    promptExecutor = simpleGoogleAIExecutor(API_KEY),
    agentConfig = AIAgentConfig(
        prompt = Prompt.build("Simple Prompt") {
            system("You are a helpful assistant.")
        }, model = GoogleModels.Gemini2_5Flash,
        enforceSingleRun = false
    )
)

println(agent.run("What is Koog?")) // Koog is a...
println(agent.run("What was my previous message?")) // "What is Koog?"

Breaking Changes

No. The default behavior of StatefulAIAgent remains single-use (by assuming enforceSingleRun = true if not specified), replicating current behavior and throwing the IllegalStateException on the second run. People wishing to enable reuse must explicitly set the new parameter to false.


Type of the changes

  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update (Documentation will be updated in a follow-up PR, but the capability is included here)
  • Tests improvement
  • Refactoring

Checklist

  • The pull request has a description of the proposed change
  • I read the Contributing Guidelines before opening the pull request
  • The pull request uses develop as the base branch
  • Tests for the changes have been added
  • All new and existing tests passed
Additional steps for pull requests adding a new feature
  • An issue describing the proposed change exists
  • The pull request includes a link to the issue
  • The change was discussed and approved in the issue
  • Docs have been added / updated (Marked for update, likely in a separate PR)

@Rizzen Rizzen requested a review from Ololoshechkin December 4, 2025 13:48
@Rizzen
Copy link
Member

Rizzen commented Dec 4, 2025

Hello! Thank you for a contribution!
In current paradigm we prefer to avoid of reusing the agents and running singular agent in parallel. Currently to run same agent few times we have AIAgentService interface with FunctionalAIAgentService and GraphAIAgentService implementations.

@PranavPurwar
Copy link
Author

Hello! Thank you for a contribution! In current paradigm we prefer to avoid of reusing the agents and running singular agent in parallel. Currently to run same agent few times we have AIAgentService interface with FunctionalAIAgentService and GraphAIAgentService implementations.

Hello! Thanks for the feedback!

I understand the current preference for using AIAgentService, which is the best approach for running multiple, independent agents in parallel.

The AIAgentService creates a fresh context for every call, whereas stateful/conversational agent would require history preservation across sequential calls. For example, a coding assistant that needs to remember previous reviews, file edits, or a planning agent with user feedback.

This change enables that context reuse with ease. Since the old, single run behavior remains the default, it's non-breaking and allows building such stateful agents out of the box easily.

How can we align this stateful capability with the architectural paradigm?

@aozherelyeva aozherelyeva requested review from EugeneTheDev, Rizzen, sdubov and tiginamaria and removed request for sdubov December 9, 2025 10:43
@Rizzen
Copy link
Member

Rizzen commented Dec 10, 2025

The AIAgentService creates a fresh context for every call, whereas stateful/conversational agent would require history preservation across sequential calls.

I understand this scenario, but by default we don't want agent to be implicitly stateful. For these scenarios you could use Persistence feature or pass context to agent input between runs yourself.

@salah-8
Copy link

salah-8 commented Dec 13, 2025

I understand this scenario, but by default we don't want agent to be implicitly stateful. For these scenarios you could use Persistence feature or pass context to agent input between runs yourself.

@Rizzen why not add the option to make it stateful and keep the default as it is?
I think this change will be useful and simple way to use agent as chatbot with multiple messages without unnecessary complexity with the other workarounds.

@PranavPurwar
Copy link
Author

The AIAgentService creates a fresh context for every call, whereas stateful/conversational agent would require history preservation across sequential calls.

I understand this scenario, but by default we don't want agent to be implicitly stateful. For these scenarios you could use Persistence feature or pass context to agent input between runs yourself.

I think this will not be an issue because this PR keeps the default functionality as is. It will only be "stateful", when toggled by the flag. Otherwise the current behavior remains as is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reusing AIAgent sessions

3 participants