1use rskit_ai::semconv;
2use rskit_errors::AppResult;
3use rskit_hook::CancellationToken;
4use rskit_llm::types::Message;
5use rskit_observability::set_span_attribute;
6use tracing::Instrument;
7
8use super::Agent;
9use crate::runtime::state::RunState;
10use crate::runtime::stop;
11use crate::runtime::turn::{self, TurnOutcome};
12use crate::types::{AgentResult, StopReason};
13
14impl Agent {
15 pub async fn run(&self, messages: Vec<Message>) -> AppResult<AgentResult> {
17 let run_span = tracing::info_span!(
18 "agent.run",
19 "gen_ai.system" = "agent",
20 "gen_ai.operation.name" = semconv::Operation::AgentRun.as_str(),
21 "gen_ai.request.model" = %self.config.model,
22 );
23 set_span_attribute(&run_span, semconv::SYSTEM, "agent");
24 set_span_attribute(
25 &run_span,
26 semconv::OPERATION_NAME,
27 semconv::Operation::AgentRun.as_str(),
28 );
29 set_span_attribute(
30 &run_span,
31 semconv::REQUEST_MODEL,
32 self.config.model.as_str(),
33 );
34
35 async move {
36 let mut state = RunState::new(&self.config.system_prompt, messages);
37
38 if let Some(stop_reason) = stop::initial_stop(&self.config) {
39 return Ok(state.finish(0, stop_reason));
40 }
41
42 let hook_token = CancellationToken::new();
43
44 for turn in 0..self.config.max_turns {
45 match turn::run_turn(
46 self.provider.as_ref(),
47 &self.config,
48 &mut state,
49 turn,
50 &hook_token,
51 )
52 .await?
53 {
54 TurnOutcome::Continue => {}
55 TurnOutcome::Stop { turn_count, reason } => {
56 return Ok(state.finish(turn_count, reason));
57 }
58 }
59 }
60
61 Ok(state.finish(self.config.max_turns, StopReason::MaxTurns))
62 }
63 .instrument(run_span)
64 .await
65 }
66}