my harness for niri
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

nudge model to submit discord_send tool call if none was provided if the user turn was a discord message #1

open opened by niri.pet targeting main from niri.pet/niri: main

Detects when the model responds to a Discord message with conversational text but fails to call discord_send. Injects a system reminder so the next turn actually delivers the message.

This is a common hallucination pattern — the model writes a reply 'in its head' and calls wait/rest instead, leaving the Discord user in silence.

Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:sxywkdxliruthtz3j4nqqpd2/sh.tangled.repo.pull/3mkrdg72kf422
+53
Diff #0
+53
src/runner/loop.ts
··· 1 + import type OpenAI from "openai" 1 2 import { recordMetric } from "../metrics.js" 2 3 import { emit } from "../stream.js" 3 4 import { ··· 70 71 return shouldRest ? CycleOutcome.Rest : CycleOutcome.ToolsDone 71 72 } 72 73 74 + /** 75 + * Detects when the assistant responded to a Discord message with 76 + * conversational text but did not call discord_send. Injects a system 77 + * nudge so the next turn actually delivers the message. 78 + */ 79 + function applyDiscordSendNudge(state: LoopState, turnMessages: OpenAI.Chat.ChatCompletionMessage[]): void { 80 + // Check if any incoming user message in this turn came from Discord 81 + const hasDiscordInput = turnMessages.some( 82 + (m) => m.role === "user" && typeof m.content === "string" && /\[discord\/(?:dm|batch|channel)\]/i.test(m.content), 83 + ) 84 + if (!hasDiscordInput) return 85 + 86 + // Check if the assistant called discord_send in this turn 87 + const hasDiscordSend = turnMessages.some( 88 + (m) => 89 + m.role === "assistant" && 90 + Array.isArray(m.tool_calls) && 91 + m.tool_calls.some((tc) => tc.type === "function" && tc.function.name === "discord_send"), 92 + ) 93 + if (hasDiscordSend) return 94 + 95 + // Also check if a tool result from discord_send exists (edge case: tool result is separate message) 96 + const hasDiscordSendResult = turnMessages.some( 97 + (m) => 98 + m.role === "tool" && 99 + typeof m.content === "string" && 100 + m.content.includes('"ok":true') && 101 + m.content.includes("discord_send"), 102 + ) 103 + if (hasDiscordSendResult) return 104 + 105 + // Find the assistant's text content in this turn 106 + const assistantText = turnMessages.find( 107 + (m) => m.role === "assistant" && typeof m.content === "string" && m.content.trim().length > 0, 108 + ) 109 + if (!assistantText || typeof assistantText !== "object") return 110 + 111 + // The assistant wrote something in response to a Discord message but 112 + // never actually sent it. Nudge. 113 + const nudge = `[system] you wrote a response to a Discord message but did not call discord_send. your message was not delivered. call discord_send now or explicitly decide not to reply.` 114 + console.warn("[runner] discord_send nudge: assistant responded to Discord input without calling discord_send") 115 + state.conversation.push({ role: "user", content: nudge }) 116 + } 117 + 73 118 function applyContextNudge(state: LoopState): void { 74 119 const tokenNudgeThreshold = USE_FALLBACK ? FALLBACK_TOKEN_NUDGE_THRESHOLD : TOKEN_NUDGE_THRESHOLD 75 120 const contextProvider = USE_FALLBACK ? "fallback" : "primary" ··· 148 193 const interruptedByUserEvent = hasIncomingUserMessage(turnMessages) 149 194 const turnSignature = buildTurnSignature(turnMessages) 150 195 196 + // Nudge when the assistant produces conversational text in response to 197 + // a Discord message but forgets to call discord_send. This is a common 198 + // hallucination pattern — the model writes a reply "in its head" and 199 + // then calls wait/rest, leaving the Discord user in silence. 200 + if (outcome !== CycleOutcome.Rest) { 201 + applyDiscordSendNudge(state, turnMessages) 202 + } 203 + 151 204 if (interruptedByUserEvent || !turnSignature) { 152 205 previousTurnSignature = null 153 206 consecutiveIdenticalToolTurns = 0

History

1 round 0 comments
sign up or login to add to the discussion
niri.pet submitted #0
1 commit
expand
feat: add discord_send nudge when assistant forgets to send
merge conflicts detected
expand
  • src/runner/loop.ts:1
expand 0 comments