override suspend fun run()

in agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/StatefulSingleUseAIAgent.kt [89:161]


    override suspend fun run(agentInput: Input): Output {
        agentStateMutex.withLock {
            if (state !is NotStarted) {
                throw IllegalStateException(
                    "Agent was already started. Please use AIAgentService.createAgentAndRun(agentInput) to run an agent multiple times."
                )
            }
            state = AIAgentState.Starting()
        }

        val runId = Uuid.random().toString()

        // Unique identifier for a group of agent-run events
        val agentRunEventId = Uuid.random().toString()
        val context = prepareContext(agentInput, runId, agentRunEventId)

        return withPreparedPipeline(context, agentRunEventId) {
            agentStateMutex.withLock {
                @OptIn(InternalAgentsApi::class)
                state = AIAgentState.Running(context.parentContext ?: context)
            }

            logger.debug { formatLog(id, runId, "Starting agent execution") }
            pipeline.onAgentStarting<Input, Output>(
                agentRunEventId,
                context.executionInfo,
                runId,
                this@StatefulSingleUseAIAgent,
                context
            )

            val result = try {
                context.with(partName = strategy.name) { executionInfo, eventId ->
                    runCatchingCancellable {
                        context.pipeline.onStrategyStarting(eventId, executionInfo, strategy, context)
                        val result = strategy.execute(context = context, input = agentInput)

                        logger.trace { "Finished executing strategy (name: ${strategy.name}) with result: $result" }
                        context.pipeline.onStrategyCompleted(
                            eventId,
                            executionInfo,
                            strategy,
                            context,
                            result,
                            typeOf<Any?>()
                        )

                        result
                    }.onFailure {
                        context.environment.reportProblem(it)
                    }.getOrThrow()
                }
            } catch (e: Throwable) {
                logger.error(e) { "Execution exception reported by server!" }
                pipeline.onAgentExecutionFailed(agentRunEventId, context.executionInfo, id, runId, e, context)
                agentStateMutex.withLock { state = AIAgentState.Failed(e) }
                throw e
            }

            logger.debug { formatLog(id, runId, "Finished agent execution") }
            pipeline.onAgentCompleted(agentRunEventId, context.executionInfo, id, runId, result, context)

            agentStateMutex.withLock {
                state = if (result != null) {
                    AIAgentState.Finished(result)
                } else {
                    AIAgentState.Failed(Exception("result is null"))
                }
            }

            result ?: error("result is null")
        }
    }