use serde_json::{json, Value};
use crate::proxy::DaemonClient;
fn to_string(v: Value) -> Result<String, String> {
serde_json::to_string(&v).map_err(|e| e.to_string())
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct CoderStartOptions {
pub engine: Option<String>,
pub max_iterations: Option<u32>,
pub model: Option<String>,
pub repair_invokes: Option<u32>,
pub transient_retries: Option<u32>,
pub discussion_id: Option<String>,
}
pub async fn start(
client: &DaemonClient,
repo: &str,
intent: &str,
opts: &CoderStartOptions,
) -> Result<String, String> {
let mut params = json!({ "repo": repo, "intent": intent });
if let Some(engine) = opts
.engine
.as_deref()
.map(str::trim)
.filter(|s| !s.is_empty())
{
params["engine"] = json!(engine);
}
if let Some(n) = opts.max_iterations {
params["max_iterations"] = json!(n);
}
if let Some(model) = opts
.model
.as_deref()
.map(str::trim)
.filter(|m| !m.is_empty())
{
params["model"] = json!(model);
}
if let Some(n) = opts.repair_invokes {
params["repair_invokes"] = json!(n);
}
if let Some(n) = opts.transient_retries {
params["transient_retries"] = json!(n);
}
if let Some(id) = opts
.discussion_id
.as_deref()
.map(str::trim)
.filter(|s| !s.is_empty())
{
params["discussion_id"] = json!(id);
}
client.call("coder.start", params).await.and_then(to_string)
}
pub async fn confirm_contract(
client: &DaemonClient,
session_id: &str,
contract_json: Option<&str>,
) -> Result<String, String> {
let mut params = json!({ "session_id": session_id });
if let Some(contract) = contract_json {
params["contract"] =
serde_json::from_str(contract).map_err(|e| format!("invalid contract JSON: {e}"))?;
}
client
.call("coder.confirm_contract", params)
.await
.and_then(to_string)
}
pub async fn list(client: &DaemonClient) -> Result<String, String> {
client
.call("coder.list", json!({}))
.await
.and_then(to_string)
}
pub async fn get(client: &DaemonClient, session_id: &str) -> Result<String, String> {
client
.call("coder.get", json!({ "session_id": session_id }))
.await
.and_then(to_string)
}
pub async fn respond(
client: &DaemonClient,
session_id: &str,
text: &str,
) -> Result<String, String> {
client
.call(
"coder.respond",
json!({ "session_id": session_id, "text": text }),
)
.await
.and_then(to_string)
}
pub async fn approve_merge(
client: &DaemonClient,
session_id: &str,
approve: bool,
) -> Result<String, String> {
client
.call(
"coder.approve_merge",
json!({ "session_id": session_id, "approve": approve }),
)
.await
.and_then(to_string)
}
pub async fn cancel(client: &DaemonClient, session_id: &str) -> Result<String, String> {
client
.call("coder.cancel", json!({ "session_id": session_id }))
.await
.and_then(to_string)
}
pub async fn watch(client: &DaemonClient, renew: Option<bool>) -> Result<String, String> {
let params = if renew == Some(true) {
json!({ "renew": true })
} else {
json!({})
};
client.call("coder.watch", params).await.and_then(to_string)
}
pub async fn unwatch(client: &DaemonClient) -> Result<String, String> {
client
.call("coder.unwatch", json!({}))
.await
.and_then(to_string)
}
pub async fn revise_contract(
client: &DaemonClient,
session_id: &str,
request: &str,
) -> Result<String, String> {
client
.call(
"coder.revise_contract",
json!({ "session_id": session_id, "request": request }),
)
.await
.and_then(to_string)
}
pub async fn discuss_start(client: &DaemonClient, repo: &str) -> Result<String, String> {
client
.call("coder.discuss.start", json!({ "repo": repo }))
.await
.and_then(to_string)
}
pub async fn discuss_send(
client: &DaemonClient,
discussion_id: &str,
text: &str,
) -> Result<String, String> {
client
.call(
"coder.discuss.send",
json!({ "discussion_id": discussion_id, "text": text }),
)
.await
.and_then(to_string)
}
pub async fn discuss_promote(client: &DaemonClient, discussion_id: &str) -> Result<String, String> {
client
.call(
"coder.discuss.promote",
json!({ "discussion_id": discussion_id }),
)
.await
.and_then(to_string)
}
pub async fn discuss_close(client: &DaemonClient, discussion_id: &str) -> Result<String, String> {
client
.call(
"coder.discuss.close",
json!({ "discussion_id": discussion_id }),
)
.await
.and_then(to_string)
}
pub async fn discuss_list(client: &DaemonClient) -> Result<String, String> {
client
.call("coder.discuss.list", json!({}))
.await
.and_then(to_string)
}