hivemind/adapters/
kilo.rs1use super::opencode::{OpenCodeAdapter, OpenCodeConfig};
4use super::runtime::{
5 AdapterConfig, ExecutionInput, ExecutionReport, InteractiveAdapterEvent,
6 InteractiveExecutionResult, RuntimeAdapter, RuntimeError,
7};
8use std::path::PathBuf;
9use std::time::Duration;
10use uuid::Uuid;
11
12#[derive(Debug, Clone)]
14pub struct KiloConfig {
15 pub base: AdapterConfig,
17 pub model: Option<String>,
19 pub verbose: bool,
21}
22
23impl KiloConfig {
24 pub fn new(binary_path: PathBuf) -> Self {
26 Self {
27 base: AdapterConfig::new("kilo", binary_path).with_timeout(Duration::from_secs(600)),
28 model: None,
29 verbose: false,
30 }
31 }
32
33 #[must_use]
35 pub fn with_model(mut self, model: impl Into<String>) -> Self {
36 self.model = Some(model.into());
37 self
38 }
39
40 #[must_use]
42 pub fn with_verbose(mut self, verbose: bool) -> Self {
43 self.verbose = verbose;
44 self
45 }
46}
47
48impl Default for KiloConfig {
49 fn default() -> Self {
50 Self::new(PathBuf::from("kilo"))
51 }
52}
53
54pub struct KiloAdapter {
56 inner: OpenCodeAdapter,
57}
58
59impl KiloAdapter {
60 pub fn new(config: KiloConfig) -> Self {
62 let mut inner = OpenCodeConfig::new(config.base.binary_path);
63 inner.base.name = "kilo".to_string();
64 inner.base.args = config.base.args;
65 inner.base.env = config.base.env;
66 inner.base.timeout = config.base.timeout;
67 inner.model = config.model;
68 inner.verbose = config.verbose;
69 Self {
70 inner: OpenCodeAdapter::new(inner),
71 }
72 }
73
74 pub fn with_defaults() -> Self {
76 Self::new(KiloConfig::default())
77 }
78
79 pub fn execute_interactive<F>(
80 &mut self,
81 input: &ExecutionInput,
82 on_event: F,
83 ) -> Result<InteractiveExecutionResult, RuntimeError>
84 where
85 F: FnMut(InteractiveAdapterEvent) -> std::result::Result<(), String>,
86 {
87 self.inner.execute_interactive(input, on_event)
88 }
89}
90
91impl RuntimeAdapter for KiloAdapter {
92 fn name(&self) -> &str {
93 self.inner.name()
94 }
95
96 fn initialize(&mut self) -> Result<(), RuntimeError> {
97 self.inner.initialize()
98 }
99
100 fn prepare(&mut self, task_id: Uuid, worktree: &std::path::Path) -> Result<(), RuntimeError> {
101 self.inner.prepare(task_id, worktree)
102 }
103
104 fn execute(&mut self, input: ExecutionInput) -> Result<ExecutionReport, RuntimeError> {
105 self.inner.execute(input)
106 }
107
108 fn terminate(&mut self) -> Result<(), RuntimeError> {
109 self.inner.terminate()
110 }
111
112 fn config(&self) -> &AdapterConfig {
113 self.inner.config()
114 }
115}