agents/agents-features/agents-features-snapshot/src/jvmTest/kotlin/CheckpointsTests.kt [575:706]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - val cli = CLI { systemMessage -> when (systemMessage) { "Is the Earth a sphere?" -> "Yes" "Why?" -> "Because when ships sail away, they start to disappear from the bottom" "Who discovered this?" -> "Ferdinand Magellan" else -> null } } val askQuestion = AskCLIQuestion(cli) val localToolRegistry = ToolRegistry { tool(askQuestion) } var counter = 0 var isFirstRun = true val checkpointStorage = InMemoryPersistenceStorageProvider() fun agentInterrupted(): Boolean = isFirstRun && (counter++ > 1) val tracer = TestTracer() val agentService: GraphAIAgentService = AIAgentService( promptExecutor = getMockExecutor { mockLLMToolCall(askQuestion, "Is the Earth a sphere?") onRequestEquals "Test my Earth knowledge" mockLLMToolCall(askQuestion, "Why?") onRequestEquals "Yes" mockLLMToolCall(askQuestion, "Why?") onRequestEquals "Yes" mockLLMToolCall( askQuestion, "Who discovered this?" ) onRequestEquals "Because when ships sail away, they start to disappear from the bottom" mockLLMAnswer("Excellent job! You are smart") onRequestEquals "Ferdinand Magellan" }, strategy = strategy("simple-with-interrupt") { val callLLM by nodeLLMRequest() val executeTool by nodeExecuteTool() val sendToolResult by nodeLLMSendToolResult() val nodeThrow by node { throw Exception("TERMINATED AFTER THIRD TOOL CALL") } edge(nodeStart forwardTo callLLM) edge(callLLM forwardTo executeTool onToolCall { true }) edge(callLLM forwardTo nodeFinish onAssistantMessage { true }) edge(executeTool forwardTo sendToolResult onCondition { !agentInterrupted() }) edge(executeTool forwardTo nodeThrow onCondition { agentInterrupted() }) edge(sendToolResult forwardTo executeTool onToolCall { true }) edge(sendToolResult forwardTo nodeFinish onAssistantMessage { true }) }, agentConfig = agentConfig, toolRegistry = localToolRegistry ) { install(Persistence) { storage = checkpointStorage enableAutomaticPersistence = true } install(Tracing) { addMessageProcessor(tracer) } } val agent = agentService.createAgent() println("Running agent first time") val output = runCatching { agent.run("Test my Earth knowledge") }.getOrElse { it.message } println("Finished first run") assertEquals("TERMINATED AFTER THIRD TOOL CALL", output) assertEquals( """ Trace: - enter node: `__start__` - exit node: `__start__` - enter node: `callLLM` - LLM call: `Test my Earth knowledge` - LLM response: `{"__wrapped_value__":"Is the Earth a sphere?"}` - exit node: `callLLM` - enter node: `executeTool` - tool call: `ask` ({"__wrapped_value__":"Is the Earth a sphere?"}) - tool result: `ask` == "Yes" - exit node: `executeTool` - enter node: `sendToolResult` - LLM call: `Yes` - LLM response: `{"__wrapped_value__":"Why?"}` - exit node: `sendToolResult` - enter node: `executeTool` - tool call: `ask` ({"__wrapped_value__":"Why?"}) - tool result: `ask` == "Because when ships sail away, they start to disappear from the bottom" - exit node: `executeTool` - enter node: `sendToolResult` - LLM call: `Because when ships sail away, they start to disappear from the bottom` - LLM response: `{"__wrapped_value__":"Who discovered this?"}` - exit node: `sendToolResult` - enter node: `executeTool` - tool call: `ask` ({"__wrapped_value__":"Who discovered this?"}) - tool result: `ask` == "Ferdinand Magellan" - exit node: `executeTool` - enter node: `nodeThrow` """.trimIndent(), tracer.traceAsString().trimIndent() ) val lastCheckpoint = checkpointStorage.getLatestCheckpoint(agent.id)!! val lastMessageHistory = lastCheckpoint.messageHistory.joinToString("\n") { msg -> when (msg) { is Message.System -> "- system: ${msg.content}" is Message.Tool.Result -> "- tool result `${msg.tool}` == ${msg.content}" is Message.User -> "- user: ${msg.content}" is Message.Assistant -> "- assistant: ${msg.content}" is Message.Reasoning -> "- reasoning: ${msg.content}" is Message.Tool.Call -> "- tool call `${msg.tool}` (${msg.content})" } } assertEquals( """ - system: You are a test agent. - user: Test my Earth knowledge - tool call `ask` ({"__wrapped_value__":"Is the Earth a sphere?"}) - tool result `ask` == Yes - tool call `ask` ({"__wrapped_value__":"Why?"}) - tool result `ask` == Because when ships sail away, they start to disappear from the bottom - tool call `ask` ({"__wrapped_value__":"Who discovered this?"}) """.trimIndent(), lastMessageHistory ) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - agents/agents-features/agents-features-snapshot/src/jvmTest/kotlin/CheckpointsTests.kt [749:880]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - val cli = CLI { systemMessage -> when (systemMessage) { "Is the Earth a sphere?" -> "Yes" "Why?" -> "Because when ships sail away, they start to disappear from the bottom" "Who discovered this?" -> "Ferdinand Magellan" else -> null } } val askQuestion = AskCLIQuestion(cli) val localToolRegistry = ToolRegistry { tool(askQuestion) } var counter = 0 var isFirstRun = true val checkpointStorage = InMemoryPersistenceStorageProvider() fun agentInterrupted(): Boolean = isFirstRun && (counter++ > 1) val tracer = TestTracer() val agentService: GraphAIAgentService = AIAgentService( promptExecutor = getMockExecutor { mockLLMToolCall(askQuestion, "Is the Earth a sphere?") onRequestEquals "Test my Earth knowledge" mockLLMToolCall(askQuestion, "Why?") onRequestEquals "Yes" mockLLMToolCall(askQuestion, "Why?") onRequestEquals "Yes" mockLLMToolCall( askQuestion, "Who discovered this?" ) onRequestEquals "Because when ships sail away, they start to disappear from the bottom" mockLLMAnswer("Excellent job! You are smart") onRequestEquals "Ferdinand Magellan" }, strategy = strategy("simple-with-interrupt") { val callLLM by nodeLLMRequest() val executeTool by nodeExecuteTool() val sendToolResult by nodeLLMSendToolResult() val nodeThrow by node { throw Exception("TERMINATED AFTER THIRD TOOL CALL") } edge(nodeStart forwardTo callLLM) edge(callLLM forwardTo executeTool onToolCall { true }) edge(callLLM forwardTo nodeFinish onAssistantMessage { true }) edge(executeTool forwardTo sendToolResult onCondition { !agentInterrupted() }) edge(executeTool forwardTo nodeThrow onCondition { agentInterrupted() }) edge(sendToolResult forwardTo executeTool onToolCall { true }) edge(sendToolResult forwardTo nodeFinish onAssistantMessage { true }) }, agentConfig = agentConfig, toolRegistry = localToolRegistry ) { install(Persistence) { storage = checkpointStorage enableAutomaticPersistence = true } install(Tracing) { addMessageProcessor(tracer) } } val agent = agentService.createAgent() println("Running agent first time") val output = runCatching { agent.run("Test my Earth knowledge") }.getOrElse { it.message } println("Finished first run") assertEquals("TERMINATED AFTER THIRD TOOL CALL", output) assertEquals( """ Trace: - enter node: `__start__` - exit node: `__start__` - enter node: `callLLM` - LLM call: `Test my Earth knowledge` - LLM response: `{"__wrapped_value__":"Is the Earth a sphere?"}` - exit node: `callLLM` - enter node: `executeTool` - tool call: `ask` ({"__wrapped_value__":"Is the Earth a sphere?"}) - tool result: `ask` == "Yes" - exit node: `executeTool` - enter node: `sendToolResult` - LLM call: `Yes` - LLM response: `{"__wrapped_value__":"Why?"}` - exit node: `sendToolResult` - enter node: `executeTool` - tool call: `ask` ({"__wrapped_value__":"Why?"}) - tool result: `ask` == "Because when ships sail away, they start to disappear from the bottom" - exit node: `executeTool` - enter node: `sendToolResult` - LLM call: `Because when ships sail away, they start to disappear from the bottom` - LLM response: `{"__wrapped_value__":"Who discovered this?"}` - exit node: `sendToolResult` - enter node: `executeTool` - tool call: `ask` ({"__wrapped_value__":"Who discovered this?"}) - tool result: `ask` == "Ferdinand Magellan" - exit node: `executeTool` - enter node: `nodeThrow` """.trimIndent(), tracer.traceAsString().trimIndent() ) val lastCheckpoint = checkpointStorage.getLatestCheckpoint(agent.id)!! val lastMessageHistory = lastCheckpoint.messageHistory.joinToString("\n") { msg -> when (msg) { is Message.System -> "- system: ${msg.content}" is Message.Tool.Result -> "- tool result `${msg.tool}` == ${msg.content}" is Message.User -> "- user: ${msg.content}" is Message.Assistant -> "- assistant: ${msg.content}" is Message.Reasoning -> "- reasoning: ${msg.content}" is Message.Tool.Call -> "- tool call `${msg.tool}` (${msg.content})" } } assertEquals( """ - system: You are a test agent. - user: Test my Earth knowledge - tool call `ask` ({"__wrapped_value__":"Is the Earth a sphere?"}) - tool result `ask` == Yes - tool call `ask` ({"__wrapped_value__":"Why?"}) - tool result `ask` == Because when ships sail away, they start to disappear from the bottom - tool call `ask` ({"__wrapped_value__":"Who discovered this?"}) """.trimIndent(), lastMessageHistory ) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -