storkit: merge 404_bug_whatsapp_and_slack_missing_assign_command_handler
This commit is contained in:
@@ -939,6 +939,32 @@ async fn handle_incoming_message(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(assign_cmd) = crate::chat::transport::matrix::assign::extract_assign_command(
|
||||||
|
message,
|
||||||
|
&ctx.bot_name,
|
||||||
|
&ctx.bot_user_id,
|
||||||
|
) {
|
||||||
|
let response = match assign_cmd {
|
||||||
|
crate::chat::transport::matrix::assign::AssignCommand::Assign { story_number, model } => {
|
||||||
|
slog!("[slack] Handling assign command from {user} in {channel}: story {story_number} model {model}");
|
||||||
|
crate::chat::transport::matrix::assign::handle_assign(
|
||||||
|
&ctx.bot_name,
|
||||||
|
&story_number,
|
||||||
|
&model,
|
||||||
|
&ctx.project_root,
|
||||||
|
&ctx.agents,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
crate::chat::transport::matrix::assign::AssignCommand::BadArgs => {
|
||||||
|
format!("Usage: `{} assign <number> <model>`", ctx.bot_name)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let response = markdown_to_slack(&response);
|
||||||
|
let _ = ctx.transport.send_message(channel, &response, "").await;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// No command matched — forward to LLM for conversational response.
|
// No command matched — forward to LLM for conversational response.
|
||||||
slog!("[slack] No command matched, forwarding to LLM for {user} in {channel}");
|
slog!("[slack] No command matched, forwarding to LLM for {user} in {channel}");
|
||||||
handle_llm_message(ctx, channel, user, message).await;
|
handle_llm_message(ctx, channel, user, message).await;
|
||||||
@@ -1899,4 +1925,61 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert!(result.is_none(), "'help' should not be recognised as start");
|
assert!(result.is_none(), "'help' should not be recognised as start");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── assign command extraction ──────────────────────────────────────
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn assign_command_extracted_from_plain_message_slack() {
|
||||||
|
let result = crate::chat::transport::matrix::assign::extract_assign_command(
|
||||||
|
"assign 42 opus",
|
||||||
|
"Timmy",
|
||||||
|
"@timmy:home.local",
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
matches!(
|
||||||
|
result,
|
||||||
|
Some(crate::chat::transport::matrix::assign::AssignCommand::Assign { .. })
|
||||||
|
),
|
||||||
|
"plain 'assign 42 opus' should be recognised on Slack"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn assign_command_extracted_with_bot_name_prefix_slack() {
|
||||||
|
let result = crate::chat::transport::matrix::assign::extract_assign_command(
|
||||||
|
"Timmy assign 42 sonnet",
|
||||||
|
"Timmy",
|
||||||
|
"@timmy:home.local",
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
matches!(
|
||||||
|
result,
|
||||||
|
Some(crate::chat::transport::matrix::assign::AssignCommand::Assign { .. })
|
||||||
|
),
|
||||||
|
"'Timmy assign 42 sonnet' should be recognised on Slack"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn assign_command_returns_bad_args_without_model_slack() {
|
||||||
|
let result = crate::chat::transport::matrix::assign::extract_assign_command(
|
||||||
|
"assign 42",
|
||||||
|
"Timmy",
|
||||||
|
"@timmy:home.local",
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
result,
|
||||||
|
Some(crate::chat::transport::matrix::assign::AssignCommand::BadArgs)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn non_assign_slack_message_not_extracted() {
|
||||||
|
let result = crate::chat::transport::matrix::assign::extract_assign_command(
|
||||||
|
"status",
|
||||||
|
"Timmy",
|
||||||
|
"@timmy:home.local",
|
||||||
|
);
|
||||||
|
assert!(result.is_none(), "'status' should not be recognised as assign on Slack");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,6 +220,32 @@ pub(super) async fn handle_incoming_message(ctx: &WhatsAppWebhookContext, sender
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(assign_cmd) = crate::chat::transport::matrix::assign::extract_assign_command(
|
||||||
|
message,
|
||||||
|
&ctx.bot_name,
|
||||||
|
&ctx.bot_user_id,
|
||||||
|
) {
|
||||||
|
let response = match assign_cmd {
|
||||||
|
crate::chat::transport::matrix::assign::AssignCommand::Assign { story_number, model } => {
|
||||||
|
slog!("[whatsapp] Handling assign command from {sender}: story {story_number} model {model}");
|
||||||
|
crate::chat::transport::matrix::assign::handle_assign(
|
||||||
|
&ctx.bot_name,
|
||||||
|
&story_number,
|
||||||
|
&model,
|
||||||
|
&ctx.project_root,
|
||||||
|
&ctx.agents,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
crate::chat::transport::matrix::assign::AssignCommand::BadArgs => {
|
||||||
|
format!("Usage: `{} assign <number> <model>`", ctx.bot_name)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let formatted = markdown_to_whatsapp(&response);
|
||||||
|
let _ = ctx.transport.send_message(sender, &formatted, "").await;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// No command matched — forward to LLM for conversational response.
|
// No command matched — forward to LLM for conversational response.
|
||||||
slog!("[whatsapp] No command matched, forwarding to LLM for {sender}");
|
slog!("[whatsapp] No command matched, forwarding to LLM for {sender}");
|
||||||
handle_llm_message(ctx, sender, message).await;
|
handle_llm_message(ctx, sender, message).await;
|
||||||
@@ -707,4 +733,61 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert!(result.is_none(), "'status' should not be recognised as rmtree");
|
assert!(result.is_none(), "'status' should not be recognised as rmtree");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── assign command extraction ──────────────────────────────────────
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn assign_command_extracted_from_plain_message() {
|
||||||
|
let result = crate::chat::transport::matrix::assign::extract_assign_command(
|
||||||
|
"assign 42 opus",
|
||||||
|
"Timmy",
|
||||||
|
"@timmy:home.local",
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
matches!(
|
||||||
|
result,
|
||||||
|
Some(crate::chat::transport::matrix::assign::AssignCommand::Assign { .. })
|
||||||
|
),
|
||||||
|
"plain 'assign 42 opus' should be recognised"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn assign_command_extracted_with_bot_name_prefix() {
|
||||||
|
let result = crate::chat::transport::matrix::assign::extract_assign_command(
|
||||||
|
"Timmy assign 42 sonnet",
|
||||||
|
"Timmy",
|
||||||
|
"@timmy:home.local",
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
matches!(
|
||||||
|
result,
|
||||||
|
Some(crate::chat::transport::matrix::assign::AssignCommand::Assign { .. })
|
||||||
|
),
|
||||||
|
"'Timmy assign 42 sonnet' should be recognised"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn assign_command_returns_bad_args_without_model() {
|
||||||
|
let result = crate::chat::transport::matrix::assign::extract_assign_command(
|
||||||
|
"assign 42",
|
||||||
|
"Timmy",
|
||||||
|
"@timmy:home.local",
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
result,
|
||||||
|
Some(crate::chat::transport::matrix::assign::AssignCommand::BadArgs)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn non_assign_whatsapp_message_not_extracted() {
|
||||||
|
let result = crate::chat::transport::matrix::assign::extract_assign_command(
|
||||||
|
"status",
|
||||||
|
"Timmy",
|
||||||
|
"@timmy:home.local",
|
||||||
|
);
|
||||||
|
assert!(result.is_none(), "'status' should not be recognised as assign");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user