mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-31 08:39:24 +00:00
refactor: deduplicate tool code and remove dead stubs (#98)
* refactor: deduplicate tool parameter extraction and remove dead stub tools Delete 4 never-registered stub tools (marketplace, restaurant, ecommerce, taskrabbit) removing ~625 lines of dead code. Add require_str/require_param helpers to tool.rs and refactor ~30 call sites across 10 tool files from 4-6 line inline extractions to single-line calls. Consolidate worker HTTP client with get_json/post_json helpers, reducing boilerplate in 4 methods. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: return JSON from orchestrator /complete endpoint The report_complete handler returned bare StatusCode::OK (no body), which broke the post_json helper that expects a JSON response. Return {"status": "ok"} for consistency with other worker endpoints. Addresses review feedback on PR #98. Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: Claude Opus 4.6 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
9fed8453c7
commit
ca8d5c6b5e
+54
-70
@@ -129,11 +129,15 @@ impl WorkerHttpClient {
|
||||
format!("{}/worker/{}/{}", self.orchestrator_url, self.job_id, path)
|
||||
}
|
||||
|
||||
/// Fetch the job description from the orchestrator.
|
||||
pub async fn get_job(&self) -> Result<JobDescription, WorkerError> {
|
||||
/// Send a GET request, check the status, and deserialize the JSON body.
|
||||
async fn get_json<T: serde::de::DeserializeOwned>(
|
||||
&self,
|
||||
path: &str,
|
||||
context: &str,
|
||||
) -> Result<T, WorkerError> {
|
||||
let resp = self
|
||||
.client
|
||||
.get(self.url("job"))
|
||||
.get(self.url(path))
|
||||
.bearer_auth(&self.token)
|
||||
.send()
|
||||
.await
|
||||
@@ -145,15 +149,51 @@ impl WorkerHttpClient {
|
||||
if !resp.status().is_success() {
|
||||
return Err(WorkerError::OrchestratorRejected {
|
||||
job_id: self.job_id,
|
||||
reason: format!("GET /job returned {}", resp.status()),
|
||||
reason: format!("{} returned {}", context, resp.status()),
|
||||
});
|
||||
}
|
||||
|
||||
resp.json().await.map_err(|e| WorkerError::LlmProxyFailed {
|
||||
reason: format!("failed to parse job description: {}", e),
|
||||
reason: format!("{}: failed to parse response: {}", context, e),
|
||||
})
|
||||
}
|
||||
|
||||
/// Send a POST request with a JSON body, check the status, and deserialize the response.
|
||||
async fn post_json<B: Serialize, T: serde::de::DeserializeOwned>(
|
||||
&self,
|
||||
path: &str,
|
||||
body: &B,
|
||||
context: &str,
|
||||
) -> Result<T, WorkerError> {
|
||||
let resp = self
|
||||
.client
|
||||
.post(self.url(path))
|
||||
.bearer_auth(&self.token)
|
||||
.json(body)
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| WorkerError::LlmProxyFailed {
|
||||
reason: format!("{}: {}", context, e),
|
||||
})?;
|
||||
|
||||
if !resp.status().is_success() {
|
||||
let status = resp.status();
|
||||
let body = resp.text().await.unwrap_or_default();
|
||||
return Err(WorkerError::LlmProxyFailed {
|
||||
reason: format!("{}: orchestrator returned {}: {}", context, status, body),
|
||||
});
|
||||
}
|
||||
|
||||
resp.json().await.map_err(|e| WorkerError::LlmProxyFailed {
|
||||
reason: format!("{}: failed to parse response: {}", context, e),
|
||||
})
|
||||
}
|
||||
|
||||
/// Fetch the job description from the orchestrator.
|
||||
pub async fn get_job(&self) -> Result<JobDescription, WorkerError> {
|
||||
self.get_json("job", "GET /job").await
|
||||
}
|
||||
|
||||
/// Proxy an LLM completion request through the orchestrator.
|
||||
pub async fn llm_complete(
|
||||
&self,
|
||||
@@ -166,29 +206,9 @@ impl WorkerHttpClient {
|
||||
stop_sequences: request.stop_sequences.clone(),
|
||||
};
|
||||
|
||||
let resp = self
|
||||
.client
|
||||
.post(self.url("llm/complete"))
|
||||
.bearer_auth(&self.token)
|
||||
.json(&proxy_req)
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| WorkerError::LlmProxyFailed {
|
||||
reason: e.to_string(),
|
||||
})?;
|
||||
|
||||
if !resp.status().is_success() {
|
||||
let status = resp.status();
|
||||
let body = resp.text().await.unwrap_or_default();
|
||||
return Err(WorkerError::LlmProxyFailed {
|
||||
reason: format!("orchestrator returned {}: {}", status, body),
|
||||
});
|
||||
}
|
||||
|
||||
let proxy_resp: ProxyCompletionResponse =
|
||||
resp.json().await.map_err(|e| WorkerError::LlmProxyFailed {
|
||||
reason: format!("failed to parse LLM response: {}", e),
|
||||
})?;
|
||||
let proxy_resp: ProxyCompletionResponse = self
|
||||
.post_json("llm/complete", &proxy_req, "LLM complete")
|
||||
.await?;
|
||||
|
||||
Ok(CompletionResponse {
|
||||
content: proxy_resp.content,
|
||||
@@ -212,29 +232,9 @@ impl WorkerHttpClient {
|
||||
tool_choice: request.tool_choice.clone(),
|
||||
};
|
||||
|
||||
let resp = self
|
||||
.client
|
||||
.post(self.url("llm/complete_with_tools"))
|
||||
.bearer_auth(&self.token)
|
||||
.json(&proxy_req)
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| WorkerError::LlmProxyFailed {
|
||||
reason: e.to_string(),
|
||||
})?;
|
||||
|
||||
if !resp.status().is_success() {
|
||||
let status = resp.status();
|
||||
let body = resp.text().await.unwrap_or_default();
|
||||
return Err(WorkerError::LlmProxyFailed {
|
||||
reason: format!("orchestrator returned {}: {}", status, body),
|
||||
});
|
||||
}
|
||||
|
||||
let proxy_resp: ProxyToolCompletionResponse =
|
||||
resp.json().await.map_err(|e| WorkerError::LlmProxyFailed {
|
||||
reason: format!("failed to parse tool completion response: {}", e),
|
||||
})?;
|
||||
let proxy_resp: ProxyToolCompletionResponse = self
|
||||
.post_json("llm/complete_with_tools", &proxy_req, "LLM tool complete")
|
||||
.await?;
|
||||
|
||||
Ok(ToolCompletionResponse {
|
||||
content: proxy_resp.content,
|
||||
@@ -337,25 +337,9 @@ impl WorkerHttpClient {
|
||||
|
||||
/// Signal job completion to the orchestrator.
|
||||
pub async fn report_complete(&self, report: &CompletionReport) -> Result<(), WorkerError> {
|
||||
let resp = self
|
||||
.client
|
||||
.post(self.url("complete"))
|
||||
.bearer_auth(&self.token)
|
||||
.json(report)
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| WorkerError::ConnectionFailed {
|
||||
url: self.orchestrator_url.clone(),
|
||||
reason: e.to_string(),
|
||||
})?;
|
||||
|
||||
if !resp.status().is_success() {
|
||||
return Err(WorkerError::OrchestratorRejected {
|
||||
job_id: self.job_id,
|
||||
reason: format!("completion report rejected: {}", resp.status()),
|
||||
});
|
||||
}
|
||||
|
||||
let _: serde_json::Value = self
|
||||
.post_json("complete", report, "report complete")
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user