Skip to main content

rskit_agent/agent/
run.rs

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    /// Run the agent loop synchronously (all turns, no streaming).
16    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}