Skip to main content

anda_core/model/
completion.rs

1use serde::{Deserialize, Serialize};
2use std::{collections::BTreeMap, fmt};
3
4use crate::{
5    AgentOutput, BoxError, ContentPart, Document, Documents, FunctionDefinition, Json, Message,
6    Resource,
7};
8
9/// LLM completion capability exposed by an agent context.
10pub trait CompletionFeatures: Sized {
11    /// Generates a completion for the request and optional resources.
12    fn completion(
13        &self,
14        req: CompletionRequest,
15        resources: Vec<Resource>,
16    ) -> impl Future<Output = Result<AgentOutput, BoxError>> + Send;
17
18    /// Returns the name of the model.
19    fn model_name(&self) -> String;
20}
21
22/// Provider-agnostic reasoning/thinking effort requested for a completion.
23#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
24#[serde(rename_all = "lowercase")]
25pub enum ModelEffort {
26    Minimal,
27    Low,
28    Medium,
29    High,
30    Max,
31}
32
33impl ModelEffort {
34    pub fn as_str(self) -> &'static str {
35        match self {
36            Self::Minimal => "minimal",
37            Self::Low => "low",
38            Self::Medium => "medium",
39            Self::High => "high",
40            Self::Max => "max",
41        }
42    }
43}
44
45impl fmt::Display for ModelEffort {
46    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47        f.write_str(self.as_str())
48    }
49}
50
51/// Provider-neutral completion request.
52#[derive(Debug, Clone, Default)]
53pub struct CompletionRequest {
54    /// System instructions sent to the completion provider.
55    pub instructions: String,
56
57    /// Role used for `prompt` and `content`; defaults to `user` when omitted.
58    pub role: Option<String>,
59
60    /// The chat history to be sent to the completion model provider.
61    pub chat_history: Vec<Message>,
62
63    /// Provider-specific history used by model adapters. It is empty for most callers.
64    pub raw_history: Vec<Json>,
65
66    /// The documents to embed into the prompt.
67    pub documents: Documents,
68
69    /// Prompt sent to the completion provider using `role`.
70    /// It can be empty.
71    pub prompt: String,
72
73    /// The content parts to be sent to the completion model provider.
74    /// It can be empty.
75    pub content: Vec<ContentPart>,
76
77    /// The tools to be sent to the completion model provider.
78    pub tools: Vec<FunctionDefinition>,
79
80    /// Whether the tool choice is required.
81    pub tool_choice_required: bool,
82
83    /// Sampling temperature requested from the provider, usually in the `[0.0, 2.0]` range.
84    pub temperature: Option<f64>,
85
86    /// Upper bound for the number of tokens that can be generated for a response.
87    pub max_output_tokens: Option<usize>,
88
89    /// An object specifying the JSON format that the model must output.
90    pub output_schema: Option<Json>,
91
92    /// The stop sequence to be sent to the completion model provider.
93    pub stop: Option<Vec<String>>,
94
95    /// The name or label of the model to be used for the completion request.
96    pub model: Option<String>,
97
98    /// Optional reasoning/thinking effort for providers and models that support it.
99    pub effort: Option<ModelEffort>,
100}
101
102impl CompletionRequest {
103    /// Adds a document to the request.
104    pub fn context(mut self, id: String, text: String) -> Self {
105        self.documents.docs.push(Document {
106            content: text.into(),
107            metadata: BTreeMap::from([("id".to_string(), id.into())]),
108        });
109        self
110    }
111
112    /// Adds multiple documents to the request.
113    pub fn append_documents(mut self, docs: Documents) -> Self {
114        self.documents.docs.extend(docs.docs);
115        self
116    }
117
118    /// Adds multiple tools to the request.
119    pub fn append_tools(mut self, tools: Vec<FunctionDefinition>) -> Self {
120        self.tools.extend(tools);
121        self
122    }
123}