Skip to content

feat(discord): emit IMAGE markers for inbound image attachments (RMN-1826)#1826

Open
xero7689 wants to merge 1171 commits intozeroclaw-labs:masterfrom
xero7689:feat/discord-inbound-image-marker
Open

feat(discord): emit IMAGE markers for inbound image attachments (RMN-1826)#1826
xero7689 wants to merge 1171 commits intozeroclaw-labs:masterfrom
xero7689:feat/discord-inbound-image-marker

Conversation

@xero7689
Copy link
Contributor

@xero7689 xero7689 commented Feb 25, 2026

Summary

  • process_attachments() silently dropped image/* attachments with a debug log
  • Add a 2-line image/* branch that emits [IMAGE:<cdn_url>] markers
  • Follows the same pattern already used in qq.rs and linq.rs

Linked Issue

Closes #1825

Label Snapshot (required)

  • Risk label: risk: low
  • Size label: size: XS
  • Scope labels: channel, tool: discord

Change Metadata

  • Change type: feature
  • Primary scope: channel

Validation Evidence (required)

cargo test process_attachments
# test channels::discord::tests::process_attachments_empty_list_returns_empty ... ok
# test channels::discord::tests::process_attachments_skips_unsupported_types ... ok
# test channels::discord::tests::process_attachments_image_produces_image_marker ... ok
# test channels::discord::tests::process_attachments_multiple_images_produce_markers ... ok
# test result: ok. 4 passed; 0 failed

cargo clippy -- -D warnings
# No new errors introduced by this PR.

cargo fmt --all -- --check
# No formatting issues.

Manually verified: sent image attachment over Discord, agent received [IMAGE:<cdn_url>] marker and forwarded to vision-capable provider successfully.

Security Impact (required)

  • New permissions/capabilities? No.
  • New external network calls? No — CDN URL is provided by Discord in the attachment payload; no additional fetch.
  • Secrets/tokens handling changed? No.
  • File system access scope changed? No.
  • Risk description: No new attack surface. The CDN URL originates from Discord's own payload, not user-controlled input.

Privacy and Data Hygiene (required)

  • Data-hygiene status: pass
  • Test fixtures use cdn.discordapp.com placeholder paths and neutral filenames only.

Compatibility / Migration

  • Backward compatible? Yes — additive only. Deployments without vision-capable providers are unaffected (marker is emitted but rejected at the provider layer with an existing error path).
  • Config/env changes? No.
  • Migration needed? No.

i18n Follow-Through (required)

  • i18n follow-through triggered? No — no docs or user-facing wording changes.

Side Effects / Blast Radius (required)

Rollback Plan (required)

  • Rollback: revert the image/* branch in process_attachments() — single focused change, no config impact.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Image attachments from Discord are now recognized and marked with identifiers in the output, providing consistent treatment with text attachments.
  • Tests

    • Implemented tests to validate image attachment identification and marker generation, covering both individual and multiple image scenarios to ensure proper functionality.

Linear

Refs RMN-1826

@github-actions github-actions bot added channel Auto scope: src/channels/** changed. size: XS Auto size: <=80 non-doc changed lines. risk: medium Auto risk: src/** or dependency/config changes. channel: discord Auto module: channel/discord changed. and removed channel Auto scope: src/channels/** changed. labels Feb 25, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'tools', 'path_filters', 'review_instructions'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
📝 Walkthrough

Walkthrough

The process_attachments() function in src/channels/discord.rs now handles image attachments by inserting [IMAGE:<url>] markers, extending existing support for text attachments. Two tests verify single and multiple image attachment handling.

Changes

Cohort / File(s) Summary
Image Attachment Processing
src/channels/discord.rs
Added image/* MIME type handling to process_attachments() to emit [IMAGE:<cdn_url>] markers for image attachments. Includes tests for single and multiple image attachment scenarios.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Suggested labels

size: XS

Suggested reviewers

  • theonlyhennygod
  • chumyin

Poem

🐰 A hop, a skip, through Discord's door,
Images now shine where none before!
[IMAGE:link] in markers we weave,
Vision-bound channels now truly believe. 🖼️✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR fully addresses all acceptance criteria from issue #1825: image/* attachments produce [IMAGE:<cdn_url>] markers, non-image attachments are skipped, tests cover single and multiple images, and the 2-line implementation matches the proposed solution.
Out of Scope Changes check ✅ Passed All changes are in scope: only src/channels/discord.rs modified with the image/* branch addition and corresponding tests, matching the stated 2-line architecture impact.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The pull request description is comprehensive and well-structured, covering all required template sections including summary, linked issues, labels, change metadata, validation evidence, security/privacy impact, compatibility, i18n assessment, and rollback plan.
Title check ✅ Passed The title accurately and specifically describes the main change: adding IMAGE marker emission for inbound image attachments in the Discord channel handler.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added channel Auto scope: src/channels/** changed. and removed channel Auto scope: src/channels/** changed. labels Feb 25, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/channels/discord.rs (1)

1453-1454: Tighten multi-image assertion to enforce output contract.

contains checks can miss regressions in delimiter/order/extra content. Prefer asserting the full expected string.

Suggested test tightening
-        assert!(result.contains("[IMAGE:https://cdn.discordapp.com/attachments/1/2/a.jpg]"));
-        assert!(result.contains("[IMAGE:https://cdn.discordapp.com/attachments/1/2/b.png]"));
+        assert_eq!(
+            result,
+            "[IMAGE:https://cdn.discordapp.com/attachments/1/2/a.jpg]\n---\n[IMAGE:https://cdn.discordapp.com/attachments/1/2/b.png]"
+        );
As per coding guidelines, "Keep tests deterministic (no flaky timing/network dependence without guardrails)".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/channels/discord.rs` around lines 1453 - 1454, The test currently uses
loose checks on the variable result via assert!(result.contains(...)) for two
image tokens; tighten it by asserting the exact expected output string
(including delimiters and order) instead of contains so regressions in
formatting or extra content fail the test—construct the exact expected value
containing
"[IMAGE:https://cdn.discordapp.com/attachments/1/2/a.jpg][IMAGE:https://cdn.discordapp.com/attachments/1/2/b.png]"
(or with the exact spacing/newline/delimiter your contract requires) and replace
the two contains assertions with a single equality assertion (e.g.,
assert_eq!(result, expected)) referring to result in the same test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/channels/discord.rs`:
- Around line 1453-1454: The test currently uses loose checks on the variable
result via assert!(result.contains(...)) for two image tokens; tighten it by
asserting the exact expected output string (including delimiters and order)
instead of contains so regressions in formatting or extra content fail the
test—construct the exact expected value containing
"[IMAGE:https://cdn.discordapp.com/attachments/1/2/a.jpg][IMAGE:https://cdn.discordapp.com/attachments/1/2/b.png]"
(or with the exact spacing/newline/delimiter your contract requires) and replace
the two contains assertions with a single equality assertion (e.g.,
assert_eq!(result, expected)) referring to result in the same test.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d2b0593 and 862ba5e.

📒 Files selected for processing (1)
  • src/channels/discord.rs

Copy link
Contributor

@dwillitzer dwillitzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed by ZeroClaw-Nigel team. Discord-only addition for IMAGE markers. Follows existing patterns. Safe to merge.

@github-actions
Copy link

github-actions bot commented Feb 28, 2026

PR intake checks found warnings (non-blocking)

Fast safe checks found advisory issues. CI lint/test/build gates still enforce merge quality.

  • Incomplete required PR template fields: summary problem, summary why it matters, summary what changed, validation commands, security risk/mitigation, privacy status, rollback plan

Action items:

  1. Complete required PR template sections/fields.
  2. Link this PR to exactly one active Linear issue key (RMN-xxx/CDV-xxx/COM-xxx).
  3. Remove tabs, trailing whitespace, and merge conflict markers from added lines.
  4. Re-run local checks before pushing:
    • ./scripts/ci/rust_quality_gate.sh
    • ./scripts/ci/rust_strict_delta_gate.sh
    • ./scripts/ci/docs_quality_gate.sh

Detected Linear keys: RMN-1826

Run logs: https://github.com/zeroclaw-labs/zeroclaw/actions/runs/22543656370

Detected blocking line issues (sample):

  • none

Detected advisory line issues (sample):

  • none

@github-actions github-actions bot added channel Auto scope: src/channels/** changed. and removed channel Auto scope: src/channels/** changed. labels Feb 28, 2026
@chumyin chumyin changed the title feat(discord): emit IMAGE markers for inbound image attachments feat(discord): emit IMAGE markers for inbound image attachments (RMN-1826) Mar 1, 2026
@github-actions github-actions bot added channel Auto scope: src/channels/** changed. and removed channel Auto scope: src/channels/** changed. labels Mar 1, 2026
…blue-live

feat(web): Electric Blue dashboard with polished UI
fix(security): deny approval-required tools on non-CLI channels
…main-rebased

feat(hardware): replay pico toolchain + prompt wiring on main [RMN-1837]
…rm-heartbeat

feat(heartbeat): add lightweight proactive task dedupe and per-tick caps
…kill-invocation-links

fix(skills): allow safe cross-skill markdown references
…odex-ws-sse-fallback

fix(provider): fallback to sse on codex websocket no-response
…roup-sender-identity

fix(channels): include telegram sender identity in group LLM prompts
…ctivation-warning

fix(config): report initialized state correctly on load
…apcat-channel

feat(channels): add napcat/onebot onboarding and config UI
…nhanced-recall-safe

feat(memory): multi-query expansion with error-safe recall
…emantic-vectordb-guard

feat(security): add semantic vectordb guard and corpus updater
…udit-log-init

fix(audit): initialize log file when audit logging is enabled
…g_readme_i18n_20260304

feat(site): add es/pt/it locale support with UI selector
…odeowners-tri-owner-20260304

chore(codeowners): align main with dev tri-owner approver routing
…09-main-20260305

feat(integrations): support lmstudio custom connector endpoint
…97-main-20260305

fix(cron,security,onboarding): unify shell policy and custom-home-safe persistence
…09-main-20260305

chore: remove Linear and Hetzner integrations
@theonlyhennygod theonlyhennygod self-assigned this Mar 5, 2026
theonlyhennygod
theonlyhennygod previously approved these changes Mar 5, 2026
Copy link
Collaborator

@theonlyhennygod theonlyhennygod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved for rebase/merge pass.

xero7689 and others added 2 commits March 5, 2026 09:43
Discord's process_attachments() previously silenced image/* MIME types
with a debug log. Add a branch that emits [IMAGE:<cdn_url>] markers so
the multimodal pipeline can forward them to vision-capable providers.

Follows the same pattern already used in qq.rs and linq.rs for inbound
image handling. No new dependencies; reuses the existing HTTP client.

Co-Authored-By: xero7689 <shzlee217@gmail.com>
@willsarg willsarg changed the base branch from main to master March 7, 2026 18:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: discord Auto module: channel/discord changed. risk: medium Auto risk: src/** or dependency/config changes. size: XS Auto size: <=80 non-doc changed lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Discord inbound image attachments as [IMAGE:] markers

8 participants