(agentId: string)
| 255 | * Execute a single iteration of the agent's loop |
| 256 | */ |
| 257 | export async function executeAgentIteration(agentId: string): Promise<void> { |
| 258 | const loopData = activeLoops[agentId]; |
| 259 | if (!loopData?.isRunning) { |
| 260 | // This log is outside an iteration, so no ID is needed. |
| 261 | Logger.debug(agentId, `Skipping execution for stopped agent`); |
| 262 | return; |
| 263 | } |
| 264 | |
| 265 | // --- ITERATION START --- |
| 266 | const iterationId = `iter_${new Date().toISOString()}_${Math.random().toString(36).substring(2, 9)}`; |
| 267 | const iterationStartTime = Date.now(); |
| 268 | |
| 269 | try { |
| 270 | const agent = await getAgent(agentId); |
| 271 | const agentCode = await getAgentCode(agentId) || ''; |
| 272 | if (!agent) throw new Error(`Agent ${agentId} not found`); |
| 273 | |
| 274 | // Logger dispatches the window event automatically |
| 275 | Logger.info(agentId, `Iteration started`, { |
| 276 | logType: 'iteration-start', |
| 277 | iterationId, |
| 278 | content: { |
| 279 | model: agent.model_name, |
| 280 | interval: agent.loop_interval_seconds, |
| 281 | intervalMs: loopData.intervalMs, |
| 282 | iterationStartTime |
| 283 | } |
| 284 | }); |
| 285 | |
| 286 | const preprocessResult = await preProcess(agentId, agent.system_prompt, iterationId); |
| 287 | |
| 288 | // Determine response source: cached or from model |
| 289 | let response: string; |
| 290 | let fromCache = false; |
| 291 | |
| 292 | // Check if we should use cached response (no significant change detected) |
| 293 | const shouldUseCache = agent.only_on_significant_change && |
| 294 | !(await detectSignificantChange(agentId, preprocessResult)); |
| 295 | |
| 296 | if (shouldUseCache) { |
| 297 | // Use cached response |
| 298 | const cachedResponse = activeLoops[agentId]?.lastResponse; |
| 299 | if (!cachedResponse) { |
| 300 | throw new Error("No cached response available - this shouldn't happen after first iteration"); |
| 301 | } |
| 302 | response = cachedResponse; |
| 303 | fromCache = true; |
| 304 | } else { |
| 305 | // Call the model |
| 306 | Logger.info(agentId, `Prompt`, { logType: 'model-prompt', iterationId, content: preprocessResult }); |
| 307 | |
| 308 | let token: string | undefined; |
| 309 | if (loopData.getToken) { |
| 310 | try { |
| 311 | Logger.debug(agentId, 'Requesting fresh API token...', { iterationId }); |
| 312 | token = await loopData.getToken(); |
| 313 | } catch (error) { |
| 314 | Logger.warn(agentId, `Could not retrieve auth token: ${error}. Continuing without it.`, { iterationId }); |
no test coverage detected