Skip to content
This repository was archived by the owner on Apr 8, 2026. It is now read-only.

Commit ee31e00

Browse files
author
Jobdori
committed
Merge jobdori/stub-implementations: AskUserQuestion + RemoteTrigger real implementations
2 parents 20d663c + 80ad9f4 commit ee31e00

1 file changed

Lines changed: 99 additions & 16 deletions

File tree

rust/crates/tools/src/lib.rs

Lines changed: 99 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -993,15 +993,50 @@ fn maybe_enforce_permission_check(
993993

994994
#[allow(clippy::needless_pass_by_value)]
995995
fn run_ask_user_question(input: AskUserQuestionInput) -> Result<String, String> {
996-
let mut result = json!({
997-
"question": input.question,
998-
"status": "pending",
999-
"message": "Waiting for user response"
1000-
});
1001-
if let Some(options) = &input.options {
1002-
result["options"] = json!(options);
996+
use std::io::{self, BufRead, Write};
997+
998+
// Display the question to the user via stdout
999+
let stdout = io::stdout();
1000+
let stdin = io::stdin();
1001+
let mut out = stdout.lock();
1002+
1003+
writeln!(out, "\n[Question] {}", input.question).map_err(|e| e.to_string())?;
1004+
1005+
if let Some(ref options) = input.options {
1006+
for (i, option) in options.iter().enumerate() {
1007+
writeln!(out, " {}. {}", i + 1, option).map_err(|e| e.to_string())?;
1008+
}
1009+
write!(out, "Enter choice (1-{}): ", options.len()).map_err(|e| e.to_string())?;
1010+
} else {
1011+
write!(out, "Your answer: ").map_err(|e| e.to_string())?;
10031012
}
1004-
to_pretty_json(result)
1013+
out.flush().map_err(|e| e.to_string())?;
1014+
1015+
// Read user response from stdin
1016+
let mut response = String::new();
1017+
stdin.lock().read_line(&mut response).map_err(|e| e.to_string())?;
1018+
let response = response.trim().to_string();
1019+
1020+
// If options were provided, resolve the numeric choice
1021+
let answer = if let Some(ref options) = input.options {
1022+
if let Ok(idx) = response.parse::<usize>() {
1023+
if idx >= 1 && idx <= options.len() {
1024+
options[idx - 1].clone()
1025+
} else {
1026+
response.clone()
1027+
}
1028+
} else {
1029+
response.clone()
1030+
}
1031+
} else {
1032+
response.clone()
1033+
};
1034+
1035+
to_pretty_json(json!({
1036+
"question": input.question,
1037+
"answer": answer,
1038+
"status": "answered"
1039+
}))
10051040
}
10061041

10071042
#[allow(clippy::needless_pass_by_value)]
@@ -1275,14 +1310,62 @@ fn run_mcp_auth(input: McpAuthInput) -> Result<String, String> {
12751310

12761311
#[allow(clippy::needless_pass_by_value)]
12771312
fn run_remote_trigger(input: RemoteTriggerInput) -> Result<String, String> {
1278-
to_pretty_json(json!({
1279-
"url": input.url,
1280-
"method": input.method.unwrap_or_else(|| "GET".to_string()),
1281-
"headers": input.headers,
1282-
"body": input.body,
1283-
"status": "triggered",
1284-
"message": "Remote trigger stub response"
1285-
}))
1313+
let method = input.method.unwrap_or_else(|| "GET".to_string());
1314+
let client = Client::new();
1315+
1316+
let mut request = match method.to_uppercase().as_str() {
1317+
"GET" => client.get(&input.url),
1318+
"POST" => client.post(&input.url),
1319+
"PUT" => client.put(&input.url),
1320+
"DELETE" => client.delete(&input.url),
1321+
"PATCH" => client.patch(&input.url),
1322+
"HEAD" => client.head(&input.url),
1323+
other => return Err(format!("unsupported HTTP method: {other}")),
1324+
};
1325+
1326+
// Apply custom headers
1327+
if let Some(ref headers) = input.headers {
1328+
if let Some(obj) = headers.as_object() {
1329+
for (key, value) in obj {
1330+
if let Some(val) = value.as_str() {
1331+
request = request.header(key.as_str(), val);
1332+
}
1333+
}
1334+
}
1335+
}
1336+
1337+
// Apply body
1338+
if let Some(ref body) = input.body {
1339+
request = request.body(body.clone());
1340+
}
1341+
1342+
// Execute with a 30-second timeout
1343+
let request = request.timeout(Duration::from_secs(30));
1344+
1345+
match request.send() {
1346+
Ok(response) => {
1347+
let status = response.status().as_u16();
1348+
let body = response.text().unwrap_or_default();
1349+
let truncated_body = if body.len() > 8192 {
1350+
format!("{}\n\n[response truncated — {} bytes total]", &body[..8192], body.len())
1351+
} else {
1352+
body
1353+
};
1354+
to_pretty_json(json!({
1355+
"url": input.url,
1356+
"method": method,
1357+
"status_code": status,
1358+
"body": truncated_body,
1359+
"success": status >= 200 && status < 300
1360+
}))
1361+
}
1362+
Err(e) => to_pretty_json(json!({
1363+
"url": input.url,
1364+
"method": method,
1365+
"error": e.to_string(),
1366+
"success": false
1367+
})),
1368+
}
12861369
}
12871370

12881371
#[allow(clippy::needless_pass_by_value)]

0 commit comments

Comments
 (0)