Skip to content

Feat/silent processing#2127

Open
ufobat wants to merge 2 commits intosipeed:mainfrom
ufobat:feat/silent-processing
Open

Feat/silent processing#2127
ufobat wants to merge 2 commits intosipeed:mainfrom
ufobat:feat/silent-processing

Conversation

@ufobat
Copy link
Copy Markdown

@ufobat ufobat commented Mar 28, 2026

Description

Adds silent_processing to agents.defaults. When enabled, the agent processes every inbound message fully — tool calls execute, session history is written — but if the LLM produces no text output, no message is sent to the channel. The automatic empty-response fallback ("The model returned an empty response...") is suppressed. Explicit LLM text responses are sent as normal.

This enables observer agents that monitor group conversations and perform background work (e.g. write_file calls to maintain memory) without producing chat noise on every silent turn.

Type of Change

  • New feature (non-breaking, opt-in via config)

🤖 AI Code Generation

  • 🤖 Fully AI-generated — reviewed and tested by contributor

Related Issue

Closes #2126

Technical Context

PicoClaw's processOptions.DefaultResponse was already a string field, always set to the hardcoded constant. This PR makes the value conditional on a new AgentDefaults.SilentProcessing flag — when true, DefaultResponse is "". The existing guard if finalContent == "" && ts.opts.DefaultResponse != "" then leaves finalContent empty, and publishResponseIfNeeded already has an early-return for empty strings.

Two session history fixes: the assistant message write is gated on finalContent != "" to avoid writing empty assistant messages (which cause provider errors on the next turn); the Session.Save call is separated from the assistant write so the session is always flushed to disk — without this, user messages added to the in-memory session during a silent turn would be lost on restart.

Both the empty-response fallback and the tool-iteration-limit message are suppressed in silent mode. This is intentional: a background observer agent must not surface internal diagnostics to the channel.

Test Environment

  • Hardware: Raspberry Pi 4 (ARM64, Debian)
  • Provider: Ollama (local, Qwen model)
  • Channel: Telegram group chat
  • Verified: agent writes to memory/MEMORY.md via write_file on each group message; no response appears in Telegram when LLM produces no text output

Evidence

Config used for verification:

{
  "agents": {
    "defaults": {
      "silent_processing": true
    }
  }
}

Checklist

  • Code follows the existing style and passes make check
  • Tests added: empty response suppressed in silent mode, text response still sent in silent mode, default fallback preserved in normal mode
  • Docs updated: docs/configuration.md (new section with group observer pattern), docs/chat-apps.md (silent observer example); both clarify the distinction between silent_processing and group_trigger.mention_only
  • No breaking changes — existing deployments unaffected (silent_processing defaults to false)
  • Rebased onto current main

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Mar 28, 2026

CLA assistant check
All committers have signed the CLA.

@ufobat
Copy link
Copy Markdown
Author

ufobat commented Mar 28, 2026

@lxowalle @Zhaoyikaiii — tagging per CONTRIBUTING.md reviewer list for agent changes.

@ufobat ufobat force-pushed the feat/silent-processing branch from b8d38f8 to bdba1fb Compare March 28, 2026 13:14
ufobat added 2 commits March 28, 2026 14:16
When silent_processing is true in agents.defaults, the agent runs fully
(tool calls, memory writes) but suppresses the empty-response fallback
when the LLM produces no text. The channel layer skips sending empty
content, so nothing reaches the user. Explicit LLM text is sent as normal.

Also skips writing empty assistant messages to session history, which
would cause provider errors on the next turn.
When silent_processing is true in agents.defaults, the agent runs fully
on every message (tool calls execute, session is flushed to disk) but
suppresses the empty-response fallback when the LLM produces no text.
The channel layer already skips sending empty content, so nothing reaches
the user. Explicit LLM text responses are sent as normal.

Empty assistant messages are not written to session history to avoid
provider errors on the next turn. The session itself is always saved so
the user message is not lost from history on silent turns.

Both the empty-response fallback and the tool-iteration-limit message are
suppressed in silent mode — a background observer agent must not surface
internal diagnostics to the channel.
@ufobat ufobat force-pushed the feat/silent-processing branch from bdba1fb to a2aff99 Compare March 28, 2026 13:16
@sipeed-bot sipeed-bot bot added type: enhancement New feature or request domain: agent domain: config go Pull requests that update go code labels Mar 28, 2026
@sipeed sipeed deleted a comment Mar 31, 2026
@sipeed-bot
Copy link
Copy Markdown

sipeed-bot bot commented Apr 17, 2026

@ufobat Hi! This PR has been inactive for over a week. If there's no update in the next 7 days, it will be closed automatically. If you're still working on it, just leave a comment to keep it open!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain: agent domain: config go Pull requests that update go code type: enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] silent_processing: suppress empty-response fallback for observer agents

2 participants