Apply group response rules before busy-session steering. Initialize usable private-message and group-mention routes for new bots, including Wizard-created pipelines, and preserve member-configured rules across saves and retries.
Fix empty pipeline configuration, refresh the processor sidebar after automatic creation, and show creation feedback. Align routing regressions and use Node 24 for the browser CI job.
Correct the task's erroneous agent attribution while preserving every code tree and the original human contribution.
Co-authored-by: multica-agent <[email protected]>
Allow routed Dify form callbacks to resume without another mention or
prefix while keeping ordinary messages subject to group response rules.
Cover mention, prefix, regex, random probability, and combined rules.
Stop treating an explicit Pipeline route as permission to bypass group
response rules. Routed group messages must still satisfy the configured
mention or prefix matchers.
Preserve the bypass for verified interaction submissions that resume an
existing run. Cover ordinary messages, mentions, prefixes, and interaction
callbacks with regression tests.
- Coerce/default/drop invalid or unknown legacy fields with warnings instead of blocking
- Never block on LocalAgent model; prune dangling KB/tool/MCP references
- Mark custom (non-builtin) 4.10 runners as unsupported_runner instead of failing
- Pin runner plugins to current marketplace versions (0.2.x); fall back to latest when a pin is withdrawn
- Raise plugin install/upgrade timeout to 600s for slow dependency installs
- Assistant configure_pipeline writes the 4.11 runner shape
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A saved pipeline may carry the post-migration shape
{'ai': {'runner': {'id': ''}, 'runner_config': {}}} while no runner has been
selected yet. The planner matched the empty id against the certified
'plugin:author/name/component' form, failed, and returned a malformed-id
blocker, so the whole 'migrate all' batch stopped with both pipelines reported
as blocked even though there was no legacy section and nothing to convert.
A blank id with no legacy runner section now reports not_legacy: no work is
needed and no target is synthesized. A blank id that still coexists with a
legacy section remains an explicit invalid_runner_id blocker, because that
ambiguous state must be resolved by the operator rather than guessed.
* fix(cntfilter): allow legacy sensitive-word lists over 64 patterns
Legacy sensitive-words.json files shipped ~70 rules. After v4.10.7,
BanWordFilter treated the 64-pattern safe_regex cap as a hard failure
and blocked every message. Raise the cap only on the sensitive-word
path, keep the 50ms CPU budget, and truncate oversized lists with a
one-time warning.
Fixes#2443
* fix(cntfilter): reject oversized sensitive-word lists
---------
Co-authored-by: dadachann <[email protected]>
The local-agent runner's system prompt is a static string with no
template-variable support, so the model had no anchor for "today" and
resolved relative time references (e.g. "this quarter", "latest")
against whichever period was best represented in training data instead
of the real date, sometimes confidently answering with stale
information for time-sensitive questions.
PreProcessor now appends a short, deterministically-computed
"Current date: ..." note to the system prompt on every request for
local-agent pipelines, alongside guidance to verify time-sensitive
facts with a search tool rather than answering from memory. The
existing skill-awareness prompt injection is refactored to share the
same append-to-system-prompt helper.
* feat(box): bidirectional attachment transfer for sandbox
Materialize inbound attachments into the sandbox workspace so agents can
process user-sent files, and collect agent-produced files from the outbox
to attach them back to the reply.
- box(service): add materialize_inbound_attachments / collect_outbound
attachments. Prefer direct host-filesystem read/write on the bind-mounted
workspace (no size limit), falling back to chunked exec only for
non-shared backends (e2b/remote). Clear per-query inbox/outbox dirs at
turn start to avoid query_id-reuse collisions.
- provider(localagent): inject inbound attachment descriptors into the
sandbox and append a system note telling the agent the inbox/outbox paths.
- pipeline(wrapper): collect outbox files on the final stream chunk and
append them as attachment components to the response chain.
- web(debug-dialog): render File components with a download link when
base64/url is present; add base64/path fields to the File entity.
- tests: cover inbound/outbound, large-file transfer without truncation,
and stale-dir clearing (86 passing).
* feat(box): support voice/file attachment round-trip end-to-end
Extends the bidirectional attachment transfer to audio and arbitrary files
through the real webchat UI, and fixes the model-payload errors that
non-image attachments triggered.
- platform(websocket_adapter): resolve Voice/File component storage keys to
base64 (previously only Image), so audio/documents reach the sandbox inbox.
- web(debug-dialog): accept audio/* and any file in the uploader (was
image-only), classify by mimetype, upload Voice/File via the documents
endpoint, and render non-image staged attachments as a chip.
- provider(litellmchat): drop non-image file parts (file_base64 / file_url)
when building the OpenAI/LiteLLM payload. These come from Voice/File
attachments — including ones replayed from conversation history — and the
agent reads their bytes from the sandbox, not the model. Without this the
provider rejects the request: 'invalid content type=file_base64'.
- provider(localagent): also strip those parts from the current user message
alongside the sandbox-path note (model-facing clarity; the requester is the
real safety net for history).
- tests: cover the requester strip/keep behavior (file dropped, image kept and
reshaped to image_url, mixed history, plain-string content).
* test(box): cover inbound/outbound attachment helpers; fix ruff format
- ruff format localagent.py (CI ruff format --check was failing)
- add unit tests for ResponseWrapper outbound-attachment helpers (wrapper.py 78%->98%)
- add unit tests for LocalAgentRunner._inject_inbound_attachments
- add unit tests for WebSocketAdapter._process_image_components (0%->covered)
Lifts PR patch coverage from 68.97% to ~88% (>75% target).