Skip to content

[IN PROGRESS] Non-graph API #560

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
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

Large diffs are not rendered by default.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package ai.koog.agents.core.agent

import ai.koog.agents.core.agent.config.AIAgentConfigBase
import ai.koog.agents.core.agent.context.AIAgentContext
import ai.koog.agents.core.agent.context.AIAgentLLMContext
import ai.koog.agents.core.agent.entity.AIAgentStateManager
import ai.koog.agents.core.agent.entity.AIAgentStorage
import ai.koog.agents.core.agent.entity.AIAgentStorageKey
import ai.koog.agents.core.annotation.InternalAgentsApi
import ai.koog.agents.core.environment.AIAgentEnvironment
import ai.koog.agents.core.feature.AIAgentFeature
import ai.koog.agents.core.feature.AIAgentNonGraphPipeline
import ai.koog.prompt.message.Message

/**
* AIAgentLoopContext represents the execution context for an AI agent operating in a loop.
* It provides access to critical components such as the environment, configuration, large language model (LLM) context,
* state management, and storage. Additionally, it enables the agent to store, retrieve, and manage context-specific data
* during its execution lifecycle.
*
* @property environment The environment interface allowing the agent to interact with the external world,
* including executing tools and reporting problems.
* @property agentId A unique identifier for the agent, differentiating it from other agents in the system.
* @property runId A unique identifier for the current run or instance of the agent's operation.
* @property agentInput The input data passed to the agent, which can be of any type, depending on the agent's context.
* @property config The configuration settings for the agent, including its prompt and model details,
* as well as operational constraints like iteration limits.
* @property llm The context for interacting with the large language model used by the agent, enabling message history
* retrieval and processing.
* @property stateManager The state management component responsible for tracking and updating the agent's state during its execution.
* @property storage A storage interface providing persistent storage capabilities for the agent's data.
* @property strategyName The name of the agent's strategic approach or operational method, determining its behavior
* during execution.
*/
@Suppress("UNCHECKED_CAST")
public class AIAgentLoopContext(

Check warning on line 36 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Constructor `AIAgentLoopContext` coverage is below the threshold 50%

Check warning on line 36 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Class `AIAgentLoopContext` coverage is below the threshold 50%
override val environment: AIAgentEnvironment,

Check warning on line 37 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `getEnvironment` coverage is below the threshold 50%
override val agentId: String,

Check warning on line 38 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `getAgentId` coverage is below the threshold 50%
override val runId: String,

Check warning on line 39 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `getRunId` coverage is below the threshold 50%
override val agentInput: Any?,

Check warning on line 40 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `getAgentInput` coverage is below the threshold 50%
override val config: AIAgentConfigBase,

Check warning on line 41 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `getConfig` coverage is below the threshold 50%
override val llm: AIAgentLLMContext,

Check warning on line 42 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `getLlm` coverage is below the threshold 50%
override val stateManager: AIAgentStateManager,

Check warning on line 43 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `getStateManager` coverage is below the threshold 50%
override val storage: AIAgentStorage,

Check warning on line 44 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `getStorage` coverage is below the threshold 50%
override val strategyName: String,

Check warning on line 45 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `getStrategyName` coverage is below the threshold 50%
public val pipeline: AIAgentNonGraphPipeline

Check warning on line 46 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `getPipeline` coverage is below the threshold 50%
) : AIAgentContext {

private val storeMap: MutableMap<AIAgentStorageKey<*>, Any> = mutableMapOf()

override fun store(key: AIAgentStorageKey<*>, value: Any) {

Check warning on line 51 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `store` coverage is below the threshold 50%
storeMap[key] = value
}

override fun <T> get(key: AIAgentStorageKey<*>): T? = storeMap[key] as T?

Check warning on line 55 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `get` coverage is below the threshold 50%

override fun remove(key: AIAgentStorageKey<*>): Boolean = storeMap.remove(key) != null

Check warning on line 57 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `remove` coverage is below the threshold 50%

@OptIn(InternalAgentsApi::class)
private val features: Map<AIAgentStorageKey<*>, Any> =
pipeline.getAgentFeatures(this)

override fun <Feature : Any> feature(key: AIAgentStorageKey<Feature>): Feature? {

Check warning on line 63 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `feature` coverage is below the threshold 50%
@Suppress("UNCHECKED_CAST")
return features[key] as Feature?
}

override fun <Feature : Any> feature(feature: AIAgentFeature<*, Feature>): Feature? = feature(feature.key)

Check warning on line 68 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `feature` coverage is below the threshold 50%

override suspend fun getHistory(): List<Message> {

Check warning on line 70 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopContext.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `getHistory` coverage is below the threshold 50%
return llm.readSession { prompt.messages }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package ai.koog.agents.core.agent

import ai.koog.agents.core.agent.entity.AIAgentStrategy

/**
* A strategy for implementing AI agent behavior that operates in a loop-based manner.
*
* The [AIAgentLoopStrategy] class allows for the definition of a custom looping logic
* that processes input and produces output by utilizing an [AIAgentLoopContext]. This strategy
* can be used to define iterative decision-making or execution processes for AI agents.
*
* @param Input The type of input data processed by the strategy.
* @param Output The type of output data produced by the strategy.
* @property name The name of the strategy, providing a way to identify and describe the strategy.
* @property loop A suspending function representing the loop logic for the strategy. It accepts
* input data of type [Input] and an [AIAgentLoopContext] to execute the loop and produce the output.
*/
public class AIAgentLoopStrategy<Input, Output>(

Check warning on line 18 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopStrategy.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Constructor `AIAgentLoopStrategy` coverage is below the threshold 50%

Check warning on line 18 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopStrategy.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Class `AIAgentLoopStrategy` coverage is below the threshold 50%
override val name: String,

Check warning on line 19 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopStrategy.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `getName` coverage is below the threshold 50%
public val loop: suspend AIAgentLoopContext.(Input) -> Output

Check warning on line 20 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopStrategy.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `getLoop` coverage is below the threshold 50%
) : AIAgentStrategy<Input, Output, AIAgentLoopContext> {
override suspend fun execute(

Check warning on line 22 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopStrategy.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `execute` coverage is below the threshold 50%
context: AIAgentLoopContext,
input: Input
): Output = context.loop(input)
}

/**
* Creates an instance of a loop strategy for an AI agent.
*
* This function constructs and returns a specific implementation of `AIAgentLoopStrategy`
* using the provided `name` and `loop` parameters. The `loop` function specifies the behavior
* of the agent within its execution loop. It is executed with the given input and the
* `AIAgentLoopContext` to produce an output.
*
* @param name The name of the strategy, describing its purpose or behavior.
* @param loop A suspending function representing the execution behavior of the agent in the loop.
* It takes an input of type `Any?` and an `AIAgentLoopContext`, and produces an output of type `Any?`.
* @return An `AIAgentLoopStrategy` configured with the provided name and loop function.
*/
public fun <Input, Output> loopStrategy(name: String = "loopStrategy", loop: suspend AIAgentLoopContext.(input: Input) -> Output): AIAgentLoopStrategy<Input, Output> =

Check warning on line 41 in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopStrategy.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Method `loopStrategy` coverage is below the threshold 50%
AIAgentLoopStrategy(name, loop)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package ai.koog.agents.core.agent

import ai.koog.agents.core.agent.entity.AIAgentStrategy
import ai.koog.agents.core.agent.entity.AIAgentGraphStrategy
import ai.koog.agents.core.dsl.builder.forwardTo
import ai.koog.agents.core.dsl.builder.strategy
import ai.koog.agents.core.dsl.extension.nodeExecuteMultipleTools
Expand Down Expand Up @@ -30,7 +30,7 @@ import ai.koog.agents.core.dsl.extension.onToolCall
* - SingleRunMode.PARALLEL: Executes multiple tool calls in parallel.
* @return An instance of AIAgentStrategy configured according to the specified single-run mode.
*/
public fun singleRunStrategy(runMode: ToolCalls = ToolCalls.SINGLE_RUN_SEQUENTIAL): AIAgentStrategy<String, String> =
public fun singleRunStrategy(runMode: ToolCalls = ToolCalls.SINGLE_RUN_SEQUENTIAL): AIAgentGraphStrategy<String, String> =
when (runMode) {
ToolCalls.SEQUENTIAL -> singleRunWithParallelAbility(false)
ToolCalls.PARALLEL -> singleRunWithParallelAbility(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import kotlinx.serialization.serializer
* @param json Optional [Json] instance to customize de/serialization behavior.
* @return A special tool that wraps the agent functionality.
*/
public inline fun <reified Input, reified Output> AIAgentBase<Input, Output>.asTool(
public inline fun <reified Input, reified Output> AIAgent<Input, Output>.asTool(
agentName: String,
agentDescription: String,
inputDescriptor: ToolParameterDescriptor,
Expand Down Expand Up @@ -59,7 +59,7 @@ public inline fun <reified Input, reified Output> AIAgentBase<Input, Output>.asT
* @param agentDescription A brief description of what the tool does.
*/
public class AIAgentTool<Input, Output>(
private val agent: AIAgentBase<Input, Output>,
private val agent: AIAgent<Input, Output>,
private val agentName: String,
private val agentDescription: String,
private val inputDescriptor: ToolParameterDescriptor,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package ai.koog.agents.core.agent

import ai.koog.agents.core.agent.GraphAIAgent.FeatureContext
import ai.koog.agents.core.agent.config.AIAgentConfig
import ai.koog.agents.core.agent.config.AIAgentConfigBase
import ai.koog.agents.core.agent.entity.AIAgentGraphStrategy
import ai.koog.agents.core.tools.ToolRegistry
import ai.koog.prompt.dsl.prompt
import ai.koog.prompt.executor.model.PromptExecutor
import ai.koog.prompt.llm.LLModel
import ai.koog.prompt.params.LLMParams
import kotlinx.datetime.Clock
import kotlin.reflect.typeOf
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid

/**
* Convenience builder that creates an instance of [AIAgent], automatically deducing [GraphAIAgent.inputType] and [GraphAIAgent.outputType]
* from [Input] and [Output]
*
* @property promptExecutor Executor used to manage and execute prompt strings.
* @property strategy Strategy defining the local behavior of the agent.
* @property agentConfig Configuration details for the local agent that define its operational parameters.
* @property toolRegistry Registry of tools the agent can interact with, defaulting to an empty registry.
* @property installFeatures Lambda for installing additional features within the agent environment.
* @property clock The clock used to calculate message timestamps
*
* @see [AIAgent] class
*/
@OptIn(ExperimentalUuidApi::class)
public inline fun <reified Input, reified Output> AIAgent(
promptExecutor: PromptExecutor,
strategy: AIAgentGraphStrategy<Input, Output>,
agentConfig: AIAgentConfigBase,
id: String = Uuid.random().toString(),
toolRegistry: ToolRegistry = ToolRegistry.EMPTY,
clock: Clock = Clock.System,
noinline installFeatures: FeatureContext.() -> Unit = {},
): AIAgent<Input, Output> = GraphAIAgent(
inputType = typeOf<Input>(),
outputType = typeOf<Output>(),
promptExecutor = promptExecutor,
strategy = strategy,
agentConfig = agentConfig,
id = id,
toolRegistry = toolRegistry,
clock = clock,
installFeatures = installFeatures,
)

/**
* Convenience builder that creates an instance of an [AIAgent] with string input and output and the specified parameters.
*
* @param executor The [PromptExecutor] responsible for executing prompts.
* @param strategy The [AIAgentGraphStrategy] defining the agent's behavior. Default is a single-run strategy.
* @param systemPrompt The system-level prompt context for the agent. Default is an empty string.
* @param llmModel The language model to be used by the agent.
* @param temperature The sampling temperature for the language model, controlling randomness. Default is 1.0.
* @param toolRegistry The [ToolRegistry] containing tools available to the agent. Default is an empty registry.
* @param maxIterations Maximum number of iterations for the agent's execution. Default is 50.
* @param installFeatures A suspending lambda to install additional features for the agent's functionality. Default is an empty lambda.
*
* @see [AIAgent] class
*/
@OptIn(ExperimentalUuidApi::class)
public fun AIAgent(
executor: PromptExecutor,
llmModel: LLModel,
id: String = Uuid.random().toString(),
strategy: AIAgentGraphStrategy<String, String> = singleRunStrategy(),
systemPrompt: String = "",
temperature: Double = 1.0,
numberOfChoices: Int = 1,
toolRegistry: ToolRegistry = ToolRegistry.EMPTY,
maxIterations: Int = 50,
installFeatures: FeatureContext.() -> Unit = {}
): AIAgent<String, String> = AIAgent(
id = id,
promptExecutor = executor,
strategy = strategy,
agentConfig = AIAgentConfig(
prompt = prompt(
id = "chat",
params = LLMParams(
temperature = temperature,
numberOfChoices = numberOfChoices
)
) {
system(systemPrompt)
},
model = llmModel,
maxAgentIterations = maxIterations,
),
toolRegistry = toolRegistry,
installFeatures = installFeatures
)
Loading
Loading