Skip to main content

algocline_app/service/
engine_api_impl.rs

1use algocline_core::{EngineApi, QueryResponse};
2use async_trait::async_trait;
3
4use super::AppService;
5
6/// Delegates each [`EngineApi`] method to the corresponding `AppService`
7/// inherent method via fully-qualified syntax (`AppService::method(self, …)`).
8///
9/// This avoids ambiguity between the trait method and the inherent method
10/// of the same name, preventing accidental infinite recursion if the
11/// inherent method is ever removed or renamed.
12#[async_trait]
13impl EngineApi for AppService {
14    // ─── Core execution ──────────────────────────────────────
15
16    async fn run(
17        &self,
18        code: Option<String>,
19        code_file: Option<String>,
20        ctx: Option<serde_json::Value>,
21        project_root: Option<String>,
22    ) -> Result<String, String> {
23        AppService::run(self, code, code_file, ctx, project_root).await
24    }
25
26    async fn advice(
27        &self,
28        strategy: &str,
29        task: Option<String>,
30        opts: Option<serde_json::Value>,
31        project_root: Option<String>,
32    ) -> Result<String, String> {
33        AppService::advice(self, strategy, task, opts, project_root).await
34    }
35
36    async fn continue_single(
37        &self,
38        session_id: &str,
39        response: String,
40        query_id: Option<&str>,
41        usage: Option<algocline_core::TokenUsage>,
42    ) -> Result<String, String> {
43        AppService::continue_single(self, session_id, response, query_id, usage).await
44    }
45
46    async fn continue_batch(
47        &self,
48        session_id: &str,
49        responses: Vec<QueryResponse>,
50    ) -> Result<String, String> {
51        AppService::continue_batch(self, session_id, responses).await
52    }
53
54    // ─── Session status ──────────────────────────────────────
55
56    async fn status(&self, session_id: Option<&str>) -> Result<String, String> {
57        AppService::status(self, session_id).await
58    }
59
60    // ─── Evaluation ──────────────────────────────────────────
61
62    async fn eval(
63        &self,
64        scenario: Option<String>,
65        scenario_file: Option<String>,
66        scenario_name: Option<String>,
67        strategy: &str,
68        strategy_opts: Option<serde_json::Value>,
69        auto_card: bool,
70    ) -> Result<String, String> {
71        AppService::eval(
72            self,
73            scenario,
74            scenario_file,
75            scenario_name,
76            strategy,
77            strategy_opts,
78            auto_card,
79        )
80        .await
81    }
82
83    async fn eval_history(&self, strategy: Option<&str>, limit: usize) -> Result<String, String> {
84        AppService::eval_history(self, strategy, limit)
85    }
86
87    async fn eval_detail(&self, eval_id: &str) -> Result<String, String> {
88        AppService::eval_detail(self, eval_id)
89    }
90
91    async fn eval_compare(&self, eval_id_a: &str, eval_id_b: &str) -> Result<String, String> {
92        AppService::eval_compare(self, eval_id_a, eval_id_b).await
93    }
94
95    // ─── Scenarios ───────────────────────────────────────────
96
97    async fn scenario_list(&self) -> Result<String, String> {
98        AppService::scenario_list(self)
99    }
100
101    async fn scenario_show(&self, name: &str) -> Result<String, String> {
102        AppService::scenario_show(self, name)
103    }
104
105    async fn scenario_install(&self, url: String) -> Result<String, String> {
106        AppService::scenario_install(self, url).await
107    }
108
109    // ─── Packages ────────────────────────────────────────────
110
111    async fn pkg_link(
112        &self,
113        path: String,
114        name: Option<String>,
115        force: Option<bool>,
116    ) -> Result<String, String> {
117        AppService::pkg_link(self, path, name, force).await
118    }
119
120    async fn pkg_unlink(&self, name: String) -> Result<String, String> {
121        AppService::pkg_unlink(self, name).await
122    }
123
124    async fn pkg_list(&self, project_root: Option<String>) -> Result<String, String> {
125        AppService::pkg_list(self, project_root).await
126    }
127
128    async fn pkg_install(&self, url: String, name: Option<String>) -> Result<String, String> {
129        AppService::pkg_install(self, url, name).await
130    }
131
132    async fn pkg_remove(
133        &self,
134        name: &str,
135        project_root: Option<String>,
136        version: Option<String>,
137    ) -> Result<String, String> {
138        AppService::pkg_remove(self, name, project_root, version).await
139    }
140
141    // ─── Logging ─────────────────────────────────────────────
142
143    async fn add_note(
144        &self,
145        session_id: &str,
146        content: &str,
147        title: Option<&str>,
148    ) -> Result<String, String> {
149        AppService::add_note(self, session_id, content, title).await
150    }
151
152    async fn log_view(
153        &self,
154        session_id: Option<&str>,
155        limit: Option<usize>,
156        max_chars: Option<usize>,
157    ) -> Result<String, String> {
158        AppService::log_view(self, session_id, limit, max_chars).await
159    }
160
161    async fn stats(
162        &self,
163        strategy_filter: Option<&str>,
164        days: Option<u64>,
165    ) -> Result<String, String> {
166        AppService::stats(self, strategy_filter, days)
167    }
168
169    // ─── Project lifecycle ────────────────────────────────────
170
171    async fn init(&self, project_root: Option<String>) -> Result<String, String> {
172        AppService::init(self, project_root).await
173    }
174
175    async fn update(&self, project_root: Option<String>) -> Result<String, String> {
176        AppService::update(self, project_root).await
177    }
178
179    async fn migrate(&self, project_root: Option<String>) -> Result<String, String> {
180        AppService::migrate(self, project_root).await
181    }
182
183    // ─── Cards ───────────────────────────────────────────────
184
185    async fn card_list(&self, pkg: Option<String>) -> Result<String, String> {
186        AppService::card_list(self, pkg.as_deref())
187    }
188
189    async fn card_get(&self, card_id: &str) -> Result<String, String> {
190        AppService::card_get(self, card_id)
191    }
192
193    async fn card_find(
194        &self,
195        pkg: Option<String>,
196        scenario: Option<String>,
197        model: Option<String>,
198        sort: Option<String>,
199        limit: Option<usize>,
200        min_pass_rate: Option<f64>,
201    ) -> Result<String, String> {
202        AppService::card_find(self, pkg, scenario, model, sort, limit, min_pass_rate)
203    }
204
205    async fn card_alias_list(&self, pkg: Option<String>) -> Result<String, String> {
206        AppService::card_alias_list(self, pkg.as_deref())
207    }
208
209    async fn card_get_by_alias(&self, name: &str) -> Result<String, String> {
210        AppService::card_get_by_alias(self, name)
211    }
212
213    async fn card_alias_set(
214        &self,
215        name: &str,
216        card_id: &str,
217        pkg: Option<String>,
218        note: Option<String>,
219    ) -> Result<String, String> {
220        AppService::card_alias_set(self, name, card_id, pkg.as_deref(), note.as_deref())
221    }
222
223    async fn card_append(
224        &self,
225        card_id: &str,
226        fields: serde_json::Value,
227    ) -> Result<String, String> {
228        AppService::card_append(self, card_id, fields)
229    }
230
231    async fn card_install(&self, url: String) -> Result<String, String> {
232        AppService::card_install(self, url).await
233    }
234
235    async fn card_samples(
236        &self,
237        card_id: &str,
238        offset: Option<usize>,
239        limit: Option<usize>,
240    ) -> Result<String, String> {
241        AppService::card_samples(self, card_id, offset.unwrap_or(0), limit)
242    }
243
244    // ─── Hub ─────────────────────────────────────────────────
245
246    async fn hub_reindex(
247        &self,
248        output_path: Option<String>,
249        source_dir: Option<String>,
250    ) -> Result<String, String> {
251        let svc = self.clone();
252        tokio::task::spawn_blocking(move || {
253            AppService::hub_reindex(&svc, output_path.as_deref(), source_dir.as_deref())
254        })
255        .await
256        .map_err(|e| format!("hub_reindex task panicked: {e}"))?
257    }
258
259    async fn hub_info(&self, pkg: String) -> Result<String, String> {
260        let svc = self.clone();
261        tokio::task::spawn_blocking(move || AppService::hub_info(&svc, &pkg))
262            .await
263            .map_err(|e| format!("hub_info task panicked: {e}"))?
264    }
265
266    async fn hub_search(
267        &self,
268        query: Option<String>,
269        category: Option<String>,
270        installed_only: Option<bool>,
271        limit: Option<usize>,
272    ) -> Result<String, String> {
273        let svc = self.clone();
274        tokio::task::spawn_blocking(move || {
275            AppService::hub_search(
276                &svc,
277                query.as_deref(),
278                category.as_deref(),
279                installed_only,
280                limit,
281            )
282        })
283        .await
284        .map_err(|e| format!("hub_search task panicked: {e}"))?
285    }
286
287    // ─── Diagnostics ─────────────────────────────────────────
288
289    async fn info(&self) -> String {
290        AppService::info(self)
291    }
292}