fix: keep a named agent on its thread after an empty question and flag a missing Slack signing secret

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
hugocasa
2026-10-08 19:45:16 +02:00
co-authored by Claude Opus 5.5
parent 31d6fec188
commit 7d25a90d50
4 changed files with 23 additions and 3 deletions
+4
View File
@@ -13468,12 +13468,16 @@ paths:
slack_team_name:
type: string
description: the connected Slack workspace; absent when Slack is not connected
signing_secret_set:
type: boolean
description: agents answer in Slack only when the instance sets SLACK_SIGNING_SECRET
channels:
type: array
items:
$ref: "#/components/schemas/SlackChannelAgent"
required:
- channels
- signing_secret_set
/w/{workspace}/flow_conversations/update/{conversation_id}:
post:
+9 -3
View File
@@ -82,6 +82,8 @@ async fn list_channel_agents(
struct AgentSlack {
/// The connected Slack workspace's name; `None` when Slack is not connected.
slack_team_name: Option<String>,
/// Agents answer only when the instance verifies Slack's request signatures.
signing_secret_set: bool,
channels: Vec<ChannelAgent>,
}
@@ -111,7 +113,11 @@ async fn list_agent_channels(
.fetch_all(&mut *tx)
.await?;
tx.commit().await?;
Ok(Json(AgentSlack { slack_team_name, channels }))
#[cfg(feature = "oauth2")]
let signing_secret_set = crate::SLACK_SIGNING_SECRET.is_some();
#[cfg(not(feature = "oauth2"))]
let signing_secret_set = false;
Ok(Json(AgentSlack { slack_team_name, signing_secret_set, channels }))
}
#[derive(Deserialize)]
@@ -653,14 +659,14 @@ async fn answer(
}
};
record_thread_agent(db, &msg.team_id, &channel, &thread_root, w_id, &agent_path).await?;
if question.is_empty() {
return reply
.send(format!("What would you like to ask `{agent_path}`?"), None)
.await;
}
record_thread_agent(db, &msg.team_id, &channel, &thread_root, w_id, &agent_path).await?;
// Keyed with the workspace's secret: any member could rebuild the plain thread and user ids
// and load this person's conversation, tool results included, through the run API.
let workspace_key = get_workspace_key(w_id, db).await?;
@@ -19,6 +19,7 @@
workspace,
isAdmin,
slackTeamName,
signingSecretSet,
channels,
onChanged
}: {
@@ -27,6 +28,8 @@
isAdmin: boolean
/** Unset when Slack is not connected to the workspace. */
slackTeamName: string | undefined
/** Agents answer in Slack only when the instance verifies Slack's request signatures. */
signingSecretSet: boolean
channels: SlackChannelAgent[]
onChanged: () => void
} = $props()
@@ -148,6 +151,12 @@
<span class="text-2xs text-hint">A workspace admin can connect it.</span>
{/if}
{:else}
{#if !signingSecretSet}
<Alert type="warning" title="Agents can't answer in Slack yet" size="xs">
The instance needs SLACK_SIGNING_SECRET set to the Slack app's signing secret, so
Windmill can tell who sent a message.
</Alert>
{/if}
<div class="flex flex-col gap-1">
<span class="text-xs font-semibold text-emphasis">Ask it anywhere</span>
<span class="text-xs text-secondary">
@@ -214,6 +214,7 @@
workspace={ws}
isAdmin={!!($userStore?.is_admin || $userStore?.is_super_admin)}
slackTeamName={slack.current?.slack_team_name}
signingSecretSet={slack.current?.signing_secret_set ?? true}
channels={slack.current?.channels ?? []}
onChanged={() => slack.refetch()}
/>