vv_agent/sdk/client/runtime/
runners.rs1use crate::config::{apply_resolved_model_limits, ResolvedModelConfig};
2use crate::llm::{LlmClient, ScriptedLlmClient};
3use crate::runtime::AgentRuntime;
4use crate::sdk::session::AgentSessionRunRequest;
5use crate::sdk::types::{AgentDefinition, AgentRun, AgentSDKOptions};
6
7use super::controls::run_controls_from_request;
8use super::llm::build_llm_from_options;
9use super::options::configure_runtime_from_options;
10use crate::sdk::client::task::{merge_request_metadata, task_from_definition_with_task_name};
11
12pub trait RunAgent {
13 fn run(&self, definition: &AgentDefinition, prompt: String) -> Result<AgentRun, String> {
14 self.run_with_session(definition, AgentSessionRunRequest::new(prompt))
15 }
16
17 fn run_with_session(
18 &self,
19 definition: &AgentDefinition,
20 request: AgentSessionRunRequest,
21 ) -> Result<AgentRun, String>;
22}
23
24impl<C: LlmClient + Clone + 'static> RunAgent for AgentRuntime<C> {
25 fn run_with_session(
26 &self,
27 definition: &AgentDefinition,
28 request: AgentSessionRunRequest,
29 ) -> Result<AgentRun, String> {
30 let controls = run_controls_from_request(&request);
31 let workspace = request.workspace.clone();
32 let mut task = task_from_definition_with_task_name(
33 definition,
34 request.prompt,
35 workspace.as_deref(),
36 request.task_name.as_deref(),
37 );
38 merge_request_metadata(&mut task, request.metadata);
39 task.initial_messages = request.initial_messages;
40 task.initial_shared_state = request.shared_state;
41 let result = self
42 .run_with_controls(task, controls)
43 .map_err(|err| err.to_string())?;
44 Ok(AgentRun {
45 agent_name: definition.model.clone(),
46 result,
47 resolved: unresolved_definition_model(definition),
48 })
49 }
50}
51
52impl RunAgent for ScriptedLlmClient {
53 fn run_with_session(
54 &self,
55 definition: &AgentDefinition,
56 request: AgentSessionRunRequest,
57 ) -> Result<AgentRun, String> {
58 let runtime = AgentRuntime::new(self.clone());
59 let controls = run_controls_from_request(&request);
60 let workspace = request.workspace.clone();
61 let mut task = task_from_definition_with_task_name(
62 definition,
63 request.prompt,
64 workspace.as_deref(),
65 request.task_name.as_deref(),
66 );
67 merge_request_metadata(&mut task, request.metadata);
68 task.initial_messages = request.initial_messages;
69 task.initial_shared_state = request.shared_state;
70 runtime
71 .run_with_controls(task, controls)
72 .map_err(|err| err.to_string())
73 .map(|result| AgentRun {
74 agent_name: definition.model.clone(),
75 resolved: unresolved_definition_model(definition),
76 result,
77 })
78 }
79}
80
81#[derive(Clone)]
82pub(in crate::sdk::client) struct SettingsRunAgent {
83 pub(in crate::sdk::client) options: AgentSDKOptions,
84}
85
86impl RunAgent for SettingsRunAgent {
87 fn run_with_session(
88 &self,
89 definition: &AgentDefinition,
90 request: AgentSessionRunRequest,
91 ) -> Result<AgentRun, String> {
92 let backend = definition
93 .backend
94 .clone()
95 .unwrap_or_else(|| self.options.default_backend.clone());
96 let (llm, resolved) = build_llm_from_options(&self.options, &backend, &definition.model)?;
97 let mut runtime = AgentRuntime::new(llm);
98 configure_runtime_from_options(&mut runtime, &self.options);
99
100 let controls = run_controls_from_request(&request);
101 let effective_workspace = request
102 .workspace
103 .clone()
104 .unwrap_or_else(|| self.options.workspace.clone());
105 let mut task = task_from_definition_with_task_name(
106 definition,
107 request.prompt,
108 Some(effective_workspace.as_path()),
109 request.task_name.as_deref(),
110 );
111 task.model = resolved.model_id.clone();
112 apply_resolved_model_limits(&mut task, &resolved);
113 merge_request_metadata(&mut task, request.metadata);
114 task.initial_messages = request.initial_messages;
115 task.initial_shared_state = request.shared_state;
116 let result = runtime
117 .run_with_controls(task, controls)
118 .map_err(|err| err.to_string())?;
119 Ok(AgentRun {
120 agent_name: definition.model.clone(),
121 result,
122 resolved,
123 })
124 }
125}
126
127fn unresolved_definition_model(definition: &AgentDefinition) -> ResolvedModelConfig {
128 ResolvedModelConfig::new(
129 definition
130 .backend
131 .clone()
132 .unwrap_or_else(|| "moonshot".to_string()),
133 definition.model.clone(),
134 definition.model.clone(),
135 definition.model.clone(),
136 Vec::new(),
137 )
138}