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        scope: Option<String>,
117        project_root: Option<String>,
118    ) -> Result<String, String> {
119        AppService::pkg_link(self, path, name, force, scope, project_root).await
120    }
121
122    async fn pkg_unlink(&self, name: String) -> Result<String, String> {
123        AppService::pkg_unlink(self, name).await
124    }
125
126    async fn pkg_list(&self, project_root: Option<String>) -> Result<String, String> {
127        AppService::pkg_list(self, project_root).await
128    }
129
130    async fn pkg_install(&self, url: String, name: Option<String>) -> Result<String, String> {
131        AppService::pkg_install(self, url, name).await
132    }
133
134    async fn pkg_remove(
135        &self,
136        name: &str,
137        project_root: Option<String>,
138        version: Option<String>,
139    ) -> Result<String, String> {
140        AppService::pkg_remove(self, name, project_root, version).await
141    }
142
143    async fn pkg_repair(
144        &self,
145        name: Option<String>,
146        project_root: Option<String>,
147    ) -> Result<String, String> {
148        AppService::pkg_repair(self, name, project_root).await
149    }
150
151    // ─── Logging ─────────────────────────────────────────────
152
153    async fn add_note(
154        &self,
155        session_id: &str,
156        content: &str,
157        title: Option<&str>,
158    ) -> Result<String, String> {
159        AppService::add_note(self, session_id, content, title).await
160    }
161
162    async fn log_view(
163        &self,
164        session_id: Option<&str>,
165        limit: Option<usize>,
166        max_chars: Option<usize>,
167    ) -> Result<String, String> {
168        AppService::log_view(self, session_id, limit, max_chars).await
169    }
170
171    async fn stats(
172        &self,
173        strategy_filter: Option<&str>,
174        days: Option<u64>,
175    ) -> Result<String, String> {
176        AppService::stats(self, strategy_filter, days)
177    }
178
179    // ─── Project lifecycle ────────────────────────────────────
180
181    async fn init(&self, project_root: Option<String>) -> Result<String, String> {
182        AppService::init(self, project_root).await
183    }
184
185    async fn update(&self, project_root: Option<String>) -> Result<String, String> {
186        AppService::update(self, project_root).await
187    }
188
189    async fn migrate(&self, project_root: Option<String>) -> Result<String, String> {
190        AppService::migrate(self, project_root).await
191    }
192
193    // ─── Cards ───────────────────────────────────────────────
194
195    async fn card_list(&self, pkg: Option<String>) -> Result<String, String> {
196        AppService::card_list(self, pkg.as_deref())
197    }
198
199    async fn card_get(&self, card_id: &str) -> Result<String, String> {
200        AppService::card_get(self, card_id)
201    }
202
203    async fn card_find(
204        &self,
205        pkg: Option<String>,
206        where_: Option<serde_json::Value>,
207        order_by: Option<serde_json::Value>,
208        limit: Option<usize>,
209        offset: Option<usize>,
210    ) -> Result<String, String> {
211        AppService::card_find(self, pkg, where_, order_by, limit, offset)
212    }
213
214    async fn card_alias_list(&self, pkg: Option<String>) -> Result<String, String> {
215        AppService::card_alias_list(self, pkg.as_deref())
216    }
217
218    async fn card_get_by_alias(&self, name: &str) -> Result<String, String> {
219        AppService::card_get_by_alias(self, name)
220    }
221
222    async fn card_alias_set(
223        &self,
224        name: &str,
225        card_id: &str,
226        pkg: Option<String>,
227        note: Option<String>,
228    ) -> Result<String, String> {
229        AppService::card_alias_set(self, name, card_id, pkg.as_deref(), note.as_deref())
230    }
231
232    async fn card_append(
233        &self,
234        card_id: &str,
235        fields: serde_json::Value,
236    ) -> Result<String, String> {
237        AppService::card_append(self, card_id, fields)
238    }
239
240    async fn card_install(&self, url: String) -> Result<String, String> {
241        AppService::card_install(self, url).await
242    }
243
244    async fn card_samples(
245        &self,
246        card_id: &str,
247        offset: Option<usize>,
248        limit: Option<usize>,
249        where_: Option<serde_json::Value>,
250    ) -> Result<String, String> {
251        AppService::card_samples(self, card_id, offset.unwrap_or(0), limit, where_)
252    }
253
254    async fn card_lineage(
255        &self,
256        card_id: &str,
257        direction: Option<String>,
258        depth: Option<usize>,
259        include_stats: Option<bool>,
260        relation_filter: Option<Vec<String>>,
261    ) -> Result<String, String> {
262        AppService::card_lineage(
263            self,
264            card_id,
265            direction.as_deref(),
266            depth,
267            include_stats,
268            relation_filter,
269        )
270    }
271
272    async fn card_sink_backfill(&self, sink: String, dry_run: bool) -> Result<String, String> {
273        AppService::card_sink_backfill(self, super::card::SinkBackfillParams { sink, dry_run })
274    }
275
276    // ─── Hub ─────────────────────────────────────────────────
277
278    async fn hub_reindex(
279        &self,
280        output_path: Option<String>,
281        source_dir: Option<String>,
282    ) -> Result<String, String> {
283        let svc = self.clone();
284        tokio::task::spawn_blocking(move || {
285            AppService::hub_reindex(&svc, output_path.as_deref(), source_dir.as_deref())
286        })
287        .await
288        .map_err(|e| format!("hub_reindex task panicked: {e}"))?
289    }
290
291    async fn hub_info(&self, pkg: String) -> Result<String, String> {
292        let svc = self.clone();
293        tokio::task::spawn_blocking(move || AppService::hub_info(&svc, &pkg))
294            .await
295            .map_err(|e| format!("hub_info task panicked: {e}"))?
296    }
297
298    async fn hub_search(
299        &self,
300        query: Option<String>,
301        category: Option<String>,
302        installed_only: Option<bool>,
303        limit: Option<usize>,
304    ) -> Result<String, String> {
305        let svc = self.clone();
306        tokio::task::spawn_blocking(move || {
307            AppService::hub_search(
308                &svc,
309                query.as_deref(),
310                category.as_deref(),
311                installed_only,
312                limit,
313            )
314        })
315        .await
316        .map_err(|e| format!("hub_search task panicked: {e}"))?
317    }
318
319    // ─── Diagnostics ─────────────────────────────────────────
320
321    async fn info(&self) -> String {
322        AppService::info(self)
323    }
324}