Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ai.koog.agents.features.longtermmemory.aws.request.AgentcoreCompositeSear
import ai.koog.agents.features.longtermmemory.aws.request.AgentcoreListingSearchRequest
import ai.koog.agents.features.longtermmemory.aws.request.AgentcoreSearchRequest
import ai.koog.agents.features.longtermmemory.aws.request.AgentcoreSimilaritySearchRequest
import ai.koog.agents.longtermmemory.retrieval.SearchStrategy
import ai.koog.agents.longtermmemory.retrieval.search.SearchStrategy
import ai.koog.rag.base.storage.search.SearchRequest

/**
Expand All @@ -18,7 +18,7 @@ import ai.koog.rag.base.storage.search.SearchRequest
* REFLECTIONS (actor-scoped).
*
* The outer query string produced by
* [ai.koog.agents.longtermmemory.retrieval.QueryExtractor] is injected into each
* [ai.koog.agents.longtermmemory.retrieval.search.SearchQueryProvider] is injected into each
* similarity subrequest at [create] time. Listing subrequests do not use the query.
*
* Example:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package ai.koog.agents.features.longtermmemory.aws.dsl

import ai.koog.agents.core.annotation.ExperimentalAgentsApi
import ai.koog.agents.features.longtermmemory.aws.AgentcoreCompositeSearchStrategy
import ai.koog.agents.features.longtermmemory.aws.AgentcoreCompositeSearchStrategy.AgentcoreSearchSubrequest
import ai.koog.agents.features.longtermmemory.aws.AgentcoreNamespaceResolver
Expand All @@ -11,6 +10,7 @@ import ai.koog.agents.features.longtermmemory.aws.augmentation.AgentcorePromptAu
import ai.koog.agents.longtermmemory.feature.LongTermMemory
import ai.koog.agents.longtermmemory.retrieval.augmentation.PromptAugmenter
import ai.koog.agents.longtermmemory.retrieval.augmentation.SystemPromptAugmenter
import ai.koog.agents.longtermmemory.retrieval.search.SearchStrategy
import aws.sdk.kotlin.services.bedrockagentcore.BedrockAgentCoreClient

/**
Expand Down Expand Up @@ -48,7 +48,6 @@ public annotation class AgentcoreLtmDsl
* @param memoryId the AgentCore memory store identifier.
* @param block DSL block appending one or more retrieval subrequests.
*/
@ExperimentalAgentsApi
public fun LongTermMemory.RetrievalSettingsBuilder.agentcore(
client: BedrockAgentCoreClient,
memoryId: String,
Expand Down Expand Up @@ -283,7 +282,7 @@ public class AgentcoreRetrievalBuilder internal constructor(

internal data class Configured(
val storage: AgentcoreSearchStorage,
val searchStrategy: ai.koog.agents.longtermmemory.retrieval.SearchStrategy,
val searchStrategy: SearchStrategy,
val namespace: String?,
val promptAugmenter: PromptAugmenter,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package ai.koog.agents.features.longtermmemory.aws.dsl

import ai.koog.agents.core.annotation.ExperimentalAgentsApi
import ai.koog.agents.features.longtermmemory.aws.AgentcoreCompositeSearchStrategy
import ai.koog.agents.features.longtermmemory.aws.AgentcoreNamespaceResolver
import ai.koog.agents.features.longtermmemory.aws.AgentcoreNamespaceScope
Expand Down Expand Up @@ -30,7 +29,6 @@ import kotlin.test.assertTrue
* DSL directly against a [LongTermMemory.RetrievalSettingsBuilder] and inspect the
* resulting strategy / storage / augmenter / namespace without talking to AWS.
*/
@OptIn(ExperimentalAgentsApi::class)
class AgentcoreRetrievalDslTest {

private val client = mockk<BedrockAgentCoreClient>(relaxed = true)
Expand Down
13 changes: 7 additions & 6 deletions agents/agents-features/agents-features-longterm-memory/Module.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ The agents-features-longterm-memory module adds long-term memory capabilities to
- **Retrieval (RAG)**: Searches a memory store for context relevant to the user's query and augments the LLM prompt before each call
- **Ingestion**: Extracts and persists conversation messages into a memory store for future retrieval
- **Flexible storage**: Plug any backend via `SearchStorage` / `WriteStorage` interfaces from the `rag-base` module; an in-memory `InMemoryRecordStorage` is included for testing
- **Configurable timing**: Ingest per-LLM-call or on agent completion
- **Prompt augmentation modes**: System prompt or user prompt or custom implementation
- **On-completion ingestion**: The accumulated session prompt/history is ingested once when the agent run completes
- **Prompt augmentation modes**: System prompt, user prompt, or custom implementation

### Key Components

Expand All @@ -19,10 +19,11 @@ The agents-features-longterm-memory module adds long-term memory capabilities to
| [`LongTermMemory`](src/commonMain/kotlin/ai/koog/agents/longtermmemory/feature/LongTermMemory.kt) | Agent feature with DSL config for retrieval & ingestion |
| [`SearchStorage`](../../../../../../rag/rag-base/src/commonMain/kotlin/ai/koog/rag/base/storage/SearchStorage.kt) | Interface for searching memory records (defined in `rag-base`) |
| [`WriteStorage`](../../../../../../rag/rag-base/src/commonMain/kotlin/ai/koog/rag/base/storage/WriteStorage.kt) | Interface for adding memory records (defined in `rag-base`) |
| [`SearchStrategy`](src/commonMain/kotlin/ai/koog/agents/longtermmemory/retrieval/SearchStrategy.kt) | Converts user query into a `SearchRequest`; `SimilaritySearchStrategy` is the default implementation |
| [`QueryExtractor`](src/commonMain/kotlin/ai/koog/agents/longtermmemory/retrieval/QueryExtractor.kt) | Extracts the search query string from a `Prompt` for retrieval |
| [`LastUserMessageQueryExtractor`](src/commonMain/kotlin/ai/koog/agents/longtermmemory/retrieval/QueryExtractor.kt) | Default `QueryExtractor` that uses the last user message content |
| [`ExtractionStrategy`](src/commonMain/kotlin/ai/koog/agents/longtermmemory/ingestion/extraction/ExtractionStrategy.kt) | Transforms messages into `TextDocument`s for storage |
| [`SearchStrategy`](src/commonMain/kotlin/ai/koog/agents/longtermmemory/retrieval/search/SearchStrategy.kt) | Converts user query into a `SearchRequest`; `SimilaritySearchStrategy` is the default implementation |
| [`SearchQueryProvider`](src/commonMain/kotlin/ai/koog/agents/longtermmemory/retrieval/search/SearchQueryProvider.kt) | Provides the search query string from a `Prompt` for retrieval |
| [`LastUserMessageQueryProvider`](src/commonMain/kotlin/ai/koog/agents/longtermmemory/retrieval/search/LastUserMessageQueryProvider.kt) | Default `SearchQueryProvider` that uses the last user message content |
| [`DocumentExtractor`](src/commonMain/kotlin/ai/koog/agents/longtermmemory/ingestion/extraction/DocumentExtractor.kt) | Transforms messages into `TextDocument`s for storage |
| [`MessagePassingDocumentExtractor`](src/commonMain/kotlin/ai/koog/agents/longtermmemory/ingestion/extraction/MessagePassingDocumentExtractor.kt) | Default `DocumentExtractor`; filters messages by role (`User`/`Assistant` by default) |
| [`PromptAugmenter`](src/commonMain/kotlin/ai/koog/agents/longtermmemory/retrieval/augmentation/PromptAugmenter.kt) | Interface for augmenting prompts with relevant context |
| [`SystemPromptAugmenter`](src/commonMain/kotlin/ai/koog/agents/longtermmemory/retrieval/augmentation/SystemPromptAugmenter.kt) | Inserts retrieved context as a system message |
| [`UserPromptAugmenter`](src/commonMain/kotlin/ai/koog/agents/longtermmemory/retrieval/augmentation/UserPromptAugmenter.kt) | Inserts retrieved context as a user message |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package ai.koog.agents.longtermmemory.feature

/**
* Policy controlling how failures from the underlying memory storage are handled
* by the [LongTermMemory] feature.
*
* Failures caused by [kotlin.coroutines.cancellation.CancellationException] are always
* propagated regardless of the selected policy.
*/
public enum class FailurePolicy {
/**
* Re-throw the underlying error wrapped into a dedicated [LongTermMemory] exception
* (either [LongTermMemoryRetrievalException] or [LongTermMemoryIngestionException]).
*
* For retrieval, this stops the LLM call before it is executed, which is usually
* safer than answering without the required memory context.
*
* For ingestion, this aborts the agent run instead of silently dropping memory records,
* which is useful for durable audit/logging use cases where losing memory is worse
* than failing the run.
*/
FAIL_FAST,

/**
* Log the error and continue. For retrieval this means proceeding to the LLM call
* with no augmentation (treated as "no relevant memories"). For ingestion this means
* the records are dropped.
*/
LOG_AND_CONTINUE,
}

/**
* Thrown when retrieval from the [LongTermMemory] storage fails and the configured
* [FailurePolicy] is [FailurePolicy.FAIL_FAST].
*/
public class LongTermMemoryRetrievalException(
message: String,
cause: Throwable,
) : Exception(message, cause)

/**
* Thrown when ingestion into the [LongTermMemory] storage fails and the configured
* [FailurePolicy] is [FailurePolicy.FAIL_FAST].
*/
public class LongTermMemoryIngestionException(
message: String,
cause: Throwable,
) : Exception(message, cause)
Loading