Agent-trigger: permanent deltaker vs @bot-nevnelse
To spor for agent-respons: 1. Permanent: agent er member_of → svar på alle meldinger 2. @bot-nevnelse: bruker skriver @bot → engangs-svar, agent trenger ikke være deltaker Femkompis-problemet løst: @bot i en gruppechat gir ett svar, ikke evig bot-loop. Dedikerte bot-chatter (member_of) fungerer som før. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f52d23de54
commit
6cf421dbc7
2 changed files with 58 additions and 34 deletions
|
|
@ -203,6 +203,14 @@ async fn load_agent_config(db: &PgPool, agent_node_id: Uuid) -> Result<AgentConf
|
|||
})
|
||||
}
|
||||
|
||||
/// Finn standard-agenten for @bot-nevnelser (den aktive agenten med høyest prioritet).
|
||||
pub async fn find_default_agent(db: &PgPool) -> Result<Option<Uuid>, sqlx::Error> {
|
||||
sqlx::query_scalar(
|
||||
"SELECT node_id FROM agent_identities WHERE is_active = true ORDER BY created_at ASC LIMIT 1",
|
||||
).fetch_optional(db).await
|
||||
}
|
||||
|
||||
/// Finn agent som er permanent deltaker i en kommunikasjonsnode.
|
||||
pub async fn find_agent_participant(db: &PgPool, communication_id: Uuid) -> Result<Option<Uuid>, sqlx::Error> {
|
||||
// Finn agent-deltaker uansett is_active — kill switch sjekkes i handleren.
|
||||
// Dette sikrer at jobben opprettes slik at eksterne handlers (Claude Code) kan plukke den.
|
||||
|
|
|
|||
|
|
@ -808,46 +808,62 @@ pub async fn create_node(
|
|||
None
|
||||
};
|
||||
|
||||
// -- Agent-trigger: sjekk om kommunikasjonsnoden har en agent-deltaker --
|
||||
// -- Agent-trigger: to spor --
|
||||
// 1. Permanent deltaker: agent er member_of → svar på alle meldinger
|
||||
// 2. @bot-nevnelse: bruker nevner @bot i teksten → engangs-svar
|
||||
if let Some(ctx_id) = req.context_id {
|
||||
let db_clone = state.db.clone();
|
||||
let user_node_id = user.node_id;
|
||||
let created_node_id = node_id;
|
||||
let message_content = content.clone();
|
||||
tokio::spawn(async move {
|
||||
match crate::agent::find_agent_participant(&db_clone, ctx_id).await {
|
||||
Ok(Some(agent_id)) if agent_id != effective_identity => {
|
||||
// Agent funnet, og melding er ikke fra agenten selv
|
||||
let payload = serde_json::json!({
|
||||
"communication_id": ctx_id.to_string(),
|
||||
"message_id": created_node_id.to_string(),
|
||||
"agent_node_id": agent_id.to_string(),
|
||||
"sender_node_id": user_node_id.to_string()
|
||||
});
|
||||
match crate::jobs::enqueue(&db_clone, "agent_respond", payload, None, 8).await {
|
||||
Ok(job_id) => {
|
||||
tracing::info!(
|
||||
job_id = %job_id,
|
||||
communication_id = %ctx_id,
|
||||
agent_node_id = %agent_id,
|
||||
"agent_respond-jobb lagt i kø"
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!(
|
||||
communication_id = %ctx_id,
|
||||
error = %e,
|
||||
"Kunne ikke legge agent_respond-jobb i kø"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(_) => {} // Ingen agent, eller melding fra agenten selv
|
||||
// Spor 1: Permanent deltaker (agent er member_of i chatten)
|
||||
let permanent_agent = match crate::agent::find_agent_participant(&db_clone, ctx_id).await {
|
||||
Ok(Some(agent_id)) if agent_id != effective_identity => Some(agent_id),
|
||||
Ok(_) => None,
|
||||
Err(e) => {
|
||||
tracing::error!(
|
||||
communication_id = %ctx_id,
|
||||
error = %e,
|
||||
"Feil ved agent-deltaker-sjekk"
|
||||
);
|
||||
tracing::error!(communication_id = %ctx_id, error = %e, "Feil ved agent-deltaker-sjekk");
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
// Spor 2: @bot-nevnelse (agent er IKKE deltaker, men nevnes i teksten)
|
||||
let mention_agent = if permanent_agent.is_none() && message_content.contains("@bot") {
|
||||
match crate::agent::find_default_agent(&db_clone).await {
|
||||
Ok(Some(agent_id)) if agent_id != effective_identity => Some(agent_id),
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Trigger jobb for den agenten som matcher
|
||||
if let Some(agent_id) = permanent_agent.or(mention_agent) {
|
||||
let trigger = if permanent_agent.is_some() { "permanent" } else { "mention" };
|
||||
let payload = serde_json::json!({
|
||||
"communication_id": ctx_id.to_string(),
|
||||
"message_id": created_node_id.to_string(),
|
||||
"agent_node_id": agent_id.to_string(),
|
||||
"sender_node_id": user_node_id.to_string(),
|
||||
"trigger": trigger
|
||||
});
|
||||
match crate::jobs::enqueue(&db_clone, "agent_respond", payload, None, 8).await {
|
||||
Ok(job_id) => {
|
||||
tracing::info!(
|
||||
job_id = %job_id,
|
||||
communication_id = %ctx_id,
|
||||
agent_node_id = %agent_id,
|
||||
trigger = trigger,
|
||||
"agent_respond-jobb lagt i kø"
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!(
|
||||
communication_id = %ctx_id,
|
||||
error = %e,
|
||||
"Kunne ikke legge agent_respond-jobb i kø"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue