MCPcopy Create free account
hub / github.com/MatterAIOrg/OrbCode / runTurn

Method runTurn

src/core/agent.ts:350–416  ·  view source on GitHub ↗
(userText: string)

Source from the content-addressed store, hash-verified

348 }
349
350 async runTurn(userText: string): Promise<void> {
351 const { onEvent } = this.options.callbacks
352 this.abortController = new AbortController()
353
354 await this.maybeFireSessionStart()
355
356 // UserPromptSubmit may block the prompt outright or attach extra context.
357 let promptContext = ""
358 if (this.hooks.hasHooks("UserPromptSubmit")) {
359 const result = await this.hooks.run("UserPromptSubmit", { prompt: userText })
360 if (result.blocked || result.stopAll) {
361 const reason = result.blockReason || result.stopReason || "Prompt blocked by a hook."
362 onEvent({ type: "system", message: reason, isError: true })
363 this.abortController = undefined
364 onEvent({ type: "turn-end" })
365 return
366 }
367 if (result.additionalContext) promptContext = result.additionalContext
368 }
369
370 if (!this.title) {
371 this.title = userText.replace(/\s+/g, " ").trim().slice(0, 80)
372 }
373
374 let userContent = `<user_query>\n${userText}\n</user_query>`
375 if (!this.firstMessageSent) {
376 userContent = `${this.buildEnvironmentDetails()}\n\n${userContent}`
377 this.firstMessageSent = true
378 }
379 // SessionStart context sits above the prompt; UserPromptSubmit context
380 // is appended after it. Both reach the model but neither is shown as
381 // user-typed text (they live outside the <user_query> markers).
382 if (this.pendingStartContext) {
383 userContent = `${wrapHookContext("SessionStart", this.pendingStartContext)}\n\n${userContent}`
384 this.pendingStartContext = ""
385 }
386 if (promptContext) {
387 userContent = `${userContent}\n\n${wrapHookContext("UserPromptSubmit", promptContext)}`
388 }
389 this.messages.push({ role: "user", content: userContent })
390
391 try {
392 this.stopHookActive = false
393 for (let step = 0; step < MAX_STEPS_PER_TURN; step++) {
394 const done = await this.runStep()
395 if (!done) continue
396 // The model is ready to stop; Stop hooks may force it to continue.
397 if (await this.shouldContinueAfterStop()) continue
398 break
399 }
400 } catch (error) {
401 if ((error as Error).name === "AbortError" || this.abortController.signal.aborted) {
402 onEvent({ type: "error", message: "Interrupted." })
403 // Keep the conversation consistent: note the interruption for the model.
404 this.messages.push({
405 role: "user",
406 content: "System reminder: The user interrupted this response before it finished.",
407 })

Callers 3

runHeadlessFunction · 0.95
AppFunction · 0.80

Calls 8

maybeFireSessionStartMethod · 0.95
runStepMethod · 0.95
persistMethod · 0.95
wrapHookContextFunction · 0.85
hasHooksMethod · 0.80
runMethod · 0.80

Tested by

no test coverage detected