Skip to content

Add Image Extraction Support to NestBot#3925

Merged
arkid15r merged 12 commits intoOWASP:feature/nestbot-ai-assistantfrom
rudransh-shrivastava:feature/nestbot-ai-assistant-image-extraction
Feb 14, 2026
Merged

Add Image Extraction Support to NestBot#3925
arkid15r merged 12 commits intoOWASP:feature/nestbot-ai-assistantfrom
rudransh-shrivastava:feature/nestbot-ai-assistant-image-extraction

Conversation

@rudransh-shrivastava
Copy link
Collaborator

@rudransh-shrivastava rudransh-shrivastava commented Feb 12, 2026

Proposed change

Resolves #2188

Add image extraction support to NestBot
image
image

Problem: This seems out of scope for this PR. I am just adding additional context using images.
image

Checklist

  • Required: I followed the contributing workflow
  • Required: I verified that my code works as intended and resolves the issue as described
  • Required: I ran make check-test locally: all warnings addressed, tests passed
  • I used AI for code, documentation, tests, or communication related to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Summary by CodeRabbit

  • New Features

    • Users can now share images with the AI assistant in Slack; the assistant generates concise image descriptions and incorporates them into replies for more relevant responses.
    • Slack handling now downloads and filters images (by type and size) before sending them to the AI.
  • Permissions

    • Bot scope extended to allow reading files so image attachments can be processed.
  • Tests

    • Expanded test coverage for image download, filtering, encoding, vision enrichment, and end-to-end AI response behavior.

Walkthrough

Adds image-based context to the Slack AI assistant: downloads and encodes images from app_mention events, obtains concise image descriptions via a vision-capable OpenAi client, appends that context to user queries before routing, adds files:read bot scope, and includes unit tests for the new behavior.

Changes

Cohort / File(s) Summary
Assistant & OpenAI client
backend/apps/ai/flows/assistant.py, backend/apps/common/open_ai.py
Introduce image-based context enrichment: process_query now accepts images, uses OpenAi + DEFAULT_VISION_MODEL and IMAGE_DESCRIPTION_PROMPT to generate image descriptions, and OpenAi gains set_images() and user_content for multimodal requests.
Slack integration & utilities
backend/apps/slack/MANIFEST.yaml, backend/apps/slack/events/app_mention.py, backend/apps/slack/common/handlers/ai.py, backend/apps/slack/utils.py
Add files:read bot scope. app_mention filters/downloads image files (size + mime), encodes to base64 data URIs, and forwards images to AI handlers. New download_file() utility (uses requests) added; handlers updated to accept images.
AI & Slack tests
backend/tests/apps/ai/flows/assistant_test.py, backend/tests/apps/common/open_ai_test.py, backend/tests/apps/slack/common/handlers/ai_test.py, backend/tests/apps/slack/events/app_mention_test.py, backend/tests/apps/slack/utils_test.py
Add and update tests covering image enrichment, OpenAi vision calls, set_images/user_content, image filtering, download behavior, base64 data URI encoding, and related error cases.
Question detector tests
backend/tests/apps/slack/common/question_detector_test.py
Test refactor to mock/embed an embedder via get_embedder() and update expectations from retriever to embedder.
AI constants
backend/apps/ai/common/constants.py
Add DEFAULT_VISION_MODEL constant ("gpt-4o-mini").

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Added question detector to nestbot mentions #2473: Modifies process_ai_query in backend/apps/slack/common/handlers/ai.py — likely overlapping changes to the same handler signatures.
  • Agentic rag #2432: Changes Slack AI handler functions (get_blocks/process_ai_query) and RAG/agent selection — related to the AI routing and handler surfaces touched here.
  • Nestbot MVP #2113: Extends the assistant with image handling and OpenAi client changes, touching the same assistant and Slack flow files.

Suggested labels

Nestbot-ai-assistant, backend

Suggested reviewers

  • kasya
🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add Image Extraction Support to NestBot' accurately and clearly summarizes the main change in the changeset: adding image support to the NestBot assistant.
Description check ✅ Passed The description is related to the changeset, referencing issue #2188 and describing the image extraction feature addition with visual examples of expected behavior.
Linked Issues check ✅ Passed The PR successfully implements the core requirements from issue #2188: image extraction support for Slack messages, vision model integration for image-to-text conversion, and context enrichment for user queries.
Out of Scope Changes check ✅ Passed All code changes are directly related to the image extraction objective. Changes span image download capability, vision model integration, API modifications to thread images through the system, and comprehensive test coverage.
Docstring Coverage ✅ Passed Docstring coverage is 96.43% which is sufficient. The required threshold is 80.00%.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into feature/nestbot-ai-assistant

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

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

No actionable comments were generated in the recent review. 🎉


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@rudransh-shrivastava rudransh-shrivastava changed the title Add image extraction support to NestBot Add Image Extraction Support to NestBot Feb 12, 2026
- channels:read
- chat:write
- commands
- files:read
Copy link
Collaborator Author

@rudransh-shrivastava rudransh-shrivastava Feb 12, 2026

Choose a reason for hiding this comment

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

This requires app re-installation.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 13 files

Confidence score: 3/5

  • Potential runtime error in backend/apps/slack/events/app_mention.py: missing size can yield None <= MAX_IMAGE_SIZE and raise TypeError, which could break image handling in Slack mentions.
  • Score reflects a concrete, user-impacting bug risk despite overall limited scope of changes.
  • Pay close attention to backend/apps/slack/events/app_mention.py and backend/apps/common/open_ai.py - fix missing size default and align docstring return type.
Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="backend/apps/common/open_ai.py">

<violation number="1" location="backend/apps/common/open_ai.py:103">
P3: Docstring return type `list[dict]` doesn't match the actual return type annotation `list[ChatCompletionContentPartParam]`. Update the docstring to match.</violation>
</file>

<file name="backend/apps/slack/events/app_mention.py">

<violation number="1" location="backend/apps/slack/events/app_mention.py:38">
P1: `file.get("size")` returns `None` when the key is absent, and `None <= MAX_IMAGE_SIZE` raises `TypeError` in Python 3. Provide a default value to handle missing size gracefully.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

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.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@backend/apps/common/open_ai.py`:
- Around line 10-13: Remove the duplicate conditional import: keep the runtime
import "from openai.types.chat import ChatCompletionContentPartParam" (since
ChatCompletionContentPartParam is used at runtime for the annotation on the
function around line 106) and delete the TYPE_CHECKING guarded re-import block;
ensure the TYPE_CHECKING symbol and its conditional import are removed so
there's only one import of ChatCompletionContentPartParam.

In `@backend/apps/slack/events/app_mention.py`:
- Around line 35-39: The list comprehension that builds images_raw can raise
TypeError when a file dict lacks "size"; change the predicate in images_raw to
guard/default the size (e.g., use file.get("size", 0) or check "size" in file
before comparing) and ensure you still filter by mimetype using
ALLOWED_MIMETYPES and the MAX_IMAGE_SIZE constant; update the comprehension that
references files, ALLOWED_MIMETYPES, and MAX_IMAGE_SIZE so missing size keys do
not cause None <= MAX_IMAGE_SIZE comparisons.
🧹 Nitpick comments (3)
backend/apps/slack/events/app_mention.py (1)

97-104: Consider limiting the number of images processed.

There's no cap on how many images are downloaded and base64-encoded. A user attaching many images (e.g., 20 small PNGs) could cause significant latency and large payloads sent to OpenAI. Consider adding a reasonable limit (e.g., 5 images).

♻️ Suggested change
+MAX_IMAGES = 5
+
         image_uris = []
-        for image in images_raw:
+        for image in images_raw[:MAX_IMAGES]:
             content = download_file(image.get("url_private"), client.token)
backend/apps/ai/flows/assistant.py (1)

80-89: Image context augmentation looks solid.

The flow correctly guards against empty/None images, handles complete() returning None, and appends context only when available. One consideration: this makes an additional synchronous OpenAI API call (to gpt-4o) on the request path before routing even begins. For messages with images, this adds latency and cost.

Consider setting a lower max_tokens for the description (e.g., 300) since the prompt asks for conciseness, to reduce latency and cost:

             image_context = (
-                OpenAi(model="gpt-4o")
+                OpenAi(model="gpt-4o", max_tokens=300)
                 .set_prompt(IMAGE_DESCRIPTION_PROMPT)
backend/tests/apps/slack/events/app_mention_test.py (1)

89-117: LGTM — oversized image filtering test.

Good boundary test with a 3MB file exceeding the 2MB limit. Consider adding an edge-case test at exactly the boundary (2MB) to verify whether the limit is inclusive or exclusive.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="backend/apps/slack/events/app_mention.py">

<violation number="1" location="backend/apps/slack/events/app_mention.py:38">
P2: Defaulting to `0` when `size` is missing means files with unknown sizes will *pass* the size check (since `0 <= MAX_IMAGE_SIZE`). This defeats the purpose of the size guard. If the size is unknown, it's safer to exclude the file by defaulting to a value that exceeds the limit.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

coderabbitai[bot]
coderabbitai bot previously approved these changes Feb 12, 2026
coderabbitai[bot]
coderabbitai bot previously approved these changes Feb 12, 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.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@backend/apps/slack/events/app_mention.py`:
- Line 100: images_raw may contain file entries missing the "url_private" key,
so calling download_file(image.get("url_private"), client.token) can pass None
and cause a downstream requests error; update the filter that builds images_raw
(or add a short guard before the call) to require image.get("url_private") is
truthy, and only call download_file when image.get("url_private") returns a
non-None string; reference the images_raw construction and the
download_file(...) invocation to locate and change the predicate or add the
guard.
🧹 Nitpick comments (1)
backend/apps/slack/events/app_mention.py (1)

98-105: Consider capping the number of images to bound memory and API cost.

There's no limit on how many images are downloaded, base64-encoded (each up to ~2.67 MB after encoding), and sent to the vision model. A user could attach many files to a single message. Consider adding a cap, e.g., process at most 3–5 images.

♻️ Suggested change
+MAX_IMAGES = 5
+
 ALLOWED_MIMETYPES = ("image/jpeg", "image/png", "image/webp")
 MAX_IMAGE_SIZE = 2 * 1024 * 1024  # 2 MB
         image_uris = []
-        for image in images_raw:
+        for image in images_raw[:MAX_IMAGES]:
             content = download_file(image.get("url_private"), client.token)

coderabbitai[bot]
coderabbitai bot previously approved these changes Feb 12, 2026
@rudransh-shrivastava rudransh-shrivastava marked this pull request as ready for review February 12, 2026 20:24
@sonarqubecloud
Copy link

@arkid15r arkid15r enabled auto-merge (squash) February 14, 2026 03:23
Copy link
Collaborator

@arkid15r arkid15r left a comment

Choose a reason for hiding this comment

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

LGTM 👍

@arkid15r arkid15r merged commit 74b4467 into OWASP:feature/nestbot-ai-assistant Feb 14, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement image-to-text extraction for Slack user message attached images

2 participants