Skip to content

feat(condo): DOMA-13253 add file in ai chat#7678

Merged
tolmachev21 merged 5 commits into
mainfrom
feat/condo/DOMA-13253/add-file-in-ai-chat
Jun 9, 2026
Merged

feat(condo): DOMA-13253 add file in ai chat#7678
tolmachev21 merged 5 commits into
mainfrom
feat/condo/DOMA-13253/add-file-in-ai-chat

Conversation

@tolmachev21

@tolmachev21 tolmachev21 commented May 27, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Attach files to AI chat messages: upload panel above the composer, progress, vertical file list with remove, and attachments included when sending. Composer now sends on Enter (no Shift); sends allowed when text or ready attachments exist.
  • Validation

    • Client-side limits and checks for allowed types, per-file size, and max file count with user-facing messages/tooltips.
  • Internationalization

    • Attachment UI strings added in English, Spanish, and Russian.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

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
📝 Walkthrough

Walkthrough

Adds end-to-end file attachment support to AI Chat: client upload hook and UI, attachment display component and styles, send integration with analytics, server-side FileRecord resolution to public URLs, schema validation tests, and i18n strings.

Changes

AI Chat Attachment Feature

Layer / File(s) Summary
Configuration and attachment constraints
apps/condo/domains/common/constants/featureflags.js, apps/condo/domains/ai/constants.js
Feature flag AI_CHAT_ATTACHMENTS_CONFIG plus exported constants for file model, max attachments, size limit, allowed MIME types/extensions; CHAT_WITH_CONDO flow input schema extended to validate attachments items.
Attachment display component and styling
apps/condo/domains/ai/components/AIChatFile/AIChatDocument.tsx, apps/condo/domains/ai/components/AIChatFile/AIChatDocument.module.css, apps/condo/domains/ai/components/AIChatFile/index.ts
New AIChatDocument component renders filename, status icon/spinner, optional remove button, and error styling; CSS module defines row/list layout and truncation; index re-exports component and types.
File upload hook and attachment state management
apps/condo/domains/ai/hooks/useAIChatAttachments.tsx
useAIChatAttachments parses feature-flag config, enforces beforeUpload rules (size/count), implements AntD customRequest upload with metadata and analytics, provides Upload trigger and AttachmentsPanel rendering via AIChatDocument, and exposes readyAttachments, canSendWithAttachments, clearAttachments, uploading state, and messages.
Chat component types and hook integration
apps/condo/domains/ai/components/AIChat/AIChat.tsx
Adds MessageAttachmentDisplay type, extends MessageContent with attachments, imports and integrates useAIChatAttachments to compute canSendMessage from text and attachments.
Message submission with attachments
apps/condo/domains/ai/components/AIChat/AIChat.tsx
Extends executeAIMessage to accept attachmentsForRequest; message send includes attachments_count analytics, appends attachment metadata to user message content, passes attachments into executor payload when present, clears attachments after send, and gates Enter-to-send on readiness.
Chat composer UI layout and attachments panel rendering
apps/condo/domains/ai/components/AIChat/AIChat.tsx, apps/condo/domains/ai/components/AIChat/AIChat.module.css
Composer shows attachments panel above textarea; CSS updates .input-field, .composer-attachments, .user-message-container, .user-message-bubble, and .user-message-attachments for sizing, stacking, spacing, and full-width behavior.
User message rendering with attachments
apps/condo/domains/ai/components/AIChat/AIChatMessage.tsx
User message bubble renders only when trimmed text or attachments exist; attachments rendered as AIChatDocument; copy actions shown only when trimmed text present.
Server-side attachment URL resolution
apps/condo/domains/ai/tasks/executeAIFlow.js
For CHAT_WITH_CONDO, worker resolves each attachment by loading FileRecord (skipping ACL), validating file model type, generating public URL via FileAdapter, and replacing attachments with normalized entries including url, name, mimeType, and size.
Attachment validation test suite
apps/condo/domains/ai/schema/ExecutionAIFlowTask.test.js
Adds tests validating attachments: allows metadata without url; rejects entries with url, unsupported MIME types, oversized files, and too many attachments.
Analytics types and events
apps/condo/domains/common/utils/analytics.ts
Adds attachments_count to message-send event payload and registers ai_assistant_attachment_upload event type.
UI string translations
apps/condo/lang/en/en.json, apps/condo/lang/es/es.json, apps/condo/lang/ru/ru.json
Adds attachment-related i18n keys for attach label, tooltips describing limits, text-only hint, max-files message, and unsupported type message.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • open-condo-software/condo#7587: Overlaps modifications to AIChat.tsx/AIChatMessage.tsx message structure and rendering; may conflict or require coordination.

Suggested labels

✋🙂 Review please

Suggested reviewers

  • toplenboren
  • nomerdvadcatpyat

Poem

🐰 I stitched tiny files into a chatty string,
Paperclips twirled while upload spinners sing,
Server handed links, schema gave a nod,
Messages now carry petals on the pod,
Hooray — attachments hopped in, quick as a spring!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'add file in ai chat' directly describes the main feature being implemented across all changes: file attachment support in the AI chat component.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/condo/DOMA-13253/add-file-in-ai-chat

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.

@tolmachev21 tolmachev21 changed the title WIP feat(condo): DOMA-13253 add file in ai chat feat(condo): DOMA-13253 add file in ai chat May 28, 2026
@tolmachev21 tolmachev21 marked this pull request as ready for review May 29, 2026 09:54

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c1a935c985

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/condo/domains/ai/tasks/executeAIFlow.js
Comment thread apps/condo/domains/ai/tasks/executeAIFlow.js

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/condo/domains/ai/components/AIChatFile/AIChatDocument.tsx`:
- Around line 72-80: The remove button's aria-label is hardcoded to English;
update the Button in AIChatDocument (the Button with className removeButton and
onClick handler onRemove) to use a localized string instead of the literal
'Remove attachment' by importing/using the app's i18n/intl utility (or
translation hook) and passing the translated value into aria-label so screen
readers receive the localized label.

In `@apps/condo/domains/ai/hooks/useAIChatAttachments.tsx`:
- Around line 192-200: readyAttachments currently falls back to
application/octet-stream because the upload success path only stores { id } in
file.response, so browser-empty RcFile.type values never get a persisted MIME;
update the upload success handler (the code that sets file.response after
upload) to include a mimetype property (e.g., mimeType: file.type ||
serverResponse.mimetype || 'application/octet-stream') and then update the
readyAttachments mapping to prefer file.response.mimeType when present (use
file.type || file.response.mimeType || 'application/octet-stream'); reference
the readyAttachments computation and the upload success assignment that
currently only stores id to locate and change both places.
- Around line 203-214: beforeUpload currently only checks the existing fileList
and lets multiple selected files through, causing uploads to start that exceed
maxAttachments; fix by tracking in-flight/accepted-but-not-yet-added files and
refusing extra files in beforeUpload. Add a ref/state like pendingAcceptedCount
and in beforeUpload check (fileList.filter(f=>f.status!=='error').length +
pendingAcceptedCount >= maxAttachments) and return Upload.LIST_IGNORE when the
cap would be exceeded; increment pendingAcceptedCount when returning true and
decrement it in the upload completion/error handlers (and onRemove). Also keep
the existing size check (maxFileSizeBytes) and ensure customRequest and upload
completion handlers (the code referenced at customRequest and the
completion/error callbacks around line ~271) decrement pendingAcceptedCount so
no orphaned uploads occur.

In `@apps/condo/domains/ai/tasks/executeAIFlow.js`:
- Around line 105-117: Stop resolving files with skipAccessControl; either fetch
the FileRecord using the normal context or explicitly verify ownership before
proceeding: after FileRecord.getOne (where skipAccessControl: true is used)
check a definitive ownership field on the returned fileRecord (e.g.,
fileRecord.createdById or fileRecord.ownerId) against the current actor (from
context.session or the ai flow task owner) and throw an error if they don't
match; alternatively remove context.createContext({ skipAccessControl: true })
and re-run FileRecord.getOne with the regular context so existing ACLs enforce
access; keep the existing modelNames check
(EXECUTION_AI_FLOW_TASK_FILE_MODEL_NAME) and still throw when not matched.
- Around line 129-142: The code currently builds resolvedAttachments using
untrusted request fields (attachment.name, attachment.mimeType,
attachment.size); after resolving fileRecord you must use the canonical stored
metadata from fileRecord (e.g., fileRecord.originalFilename or fileRecord.name,
fileRecord.fileMimeType, fileRecord.size) when constructing resolvedAttachments
and when calling fileAdapter.publicUrl; replace uses of attachment.name,
attachment.mimeType, and attachment.size with the corresponding fileRecord
properties and only include size if fileRecord.size is present so downstream
cannot receive spoofed client-provided metadata.

In `@apps/condo/lang/ru/ru.json`:
- Line 391: The translation string identified by the key
"ai.chat.attachments.tooltip.addFiles" uses lowercase "мб." for the file size
unit; update the value to use the consistent uppercase "МБ" (e.g., "Добавить
файлы (макс. {max} шт., каждый {maxFileSizeMb} МБ)") so it matches other locale
entries and UI copy.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: da74c8f2-ea5f-4491-b3c7-ddcec892ede5

📥 Commits

Reviewing files that changed from the base of the PR and between 0e268f8 and c1a935c.

📒 Files selected for processing (14)
  • apps/condo/domains/ai/components/AIChat/AIChat.module.css
  • apps/condo/domains/ai/components/AIChat/AIChat.tsx
  • apps/condo/domains/ai/components/AIChat/AIChatMessage.tsx
  • apps/condo/domains/ai/components/AIChatFile/AIChatDocument.module.css
  • apps/condo/domains/ai/components/AIChatFile/AIChatDocument.tsx
  • apps/condo/domains/ai/components/AIChatFile/index.ts
  • apps/condo/domains/ai/constants.js
  • apps/condo/domains/ai/hooks/useAIChatAttachments.tsx
  • apps/condo/domains/ai/schema/ExecutionAIFlowTask.test.js
  • apps/condo/domains/ai/tasks/executeAIFlow.js
  • apps/condo/domains/common/constants/featureflags.js
  • apps/condo/lang/en/en.json
  • apps/condo/lang/es/es.json
  • apps/condo/lang/ru/ru.json

Comment thread apps/condo/domains/ai/components/AIChatFile/AIChatDocument.tsx Outdated
Comment thread apps/condo/domains/ai/hooks/useAIChatAttachments.tsx Outdated
Comment thread apps/condo/domains/ai/hooks/useAIChatAttachments.tsx Outdated
Comment thread apps/condo/domains/ai/tasks/executeAIFlow.js
Comment thread apps/condo/domains/ai/tasks/executeAIFlow.js Outdated
Comment thread apps/condo/lang/ru/ru.json Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
apps/condo/domains/ai/components/AIChatFile/AIChatDocument.module.css (1)

28-28: ⚡ Quick win

Consider removing !important from margin override.

The !important declaration is a code smell that suggests the styles are fighting against the Typography.Paragraph component's defaults. Consider using Typography.Text instead of Typography.Paragraph in the component, or applying the margin reset through a more specific selector.

♻️ Alternative approach if switching to Typography.Text

If the component can use Typography.Text semantically instead of Typography.Paragraph, the margin override becomes unnecessary:

 .baseName {
   flex: 0 1 auto;
   min-width: 0;
-  margin-bottom: 0 !important;
   color: var(--condo-global-color-black);
 }

Then update the component to use Typography.Text which doesn't have default bottom margin.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/condo/domains/ai/components/AIChatFile/AIChatDocument.module.css` at
line 28, Remove the `!important` margin override in AIChatDocument.module.css
and instead either (A) change the component using this style (AIChatDocument /
AIChatFile) to use Typography.Text in place of Typography.Paragraph so no bottom
margin reset is needed, or (B) keep using Typography.Paragraph but apply the
reset with a more specific selector (e.g., target the component's module class
combined with the paragraph element) to override the default without
`!important`; update the JSX to match the chosen approach (switch element or
selector) and delete the `!important` token from the CSS.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/condo/domains/ai/components/AIChatFile/AIChatDocument.module.css`:
- Line 28: Remove the `!important` margin override in AIChatDocument.module.css
and instead either (A) change the component using this style (AIChatDocument /
AIChatFile) to use Typography.Text in place of Typography.Paragraph so no bottom
margin reset is needed, or (B) keep using Typography.Paragraph but apply the
reset with a more specific selector (e.g., target the component's module class
combined with the paragraph element) to override the default without
`!important`; update the JSX to match the chosen approach (switch element or
selector) and delete the `!important` token from the CSS.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6896be2b-1252-4c5d-a708-39ca0945cd8d

📥 Commits

Reviewing files that changed from the base of the PR and between c1a935c and 7b69cef.

📒 Files selected for processing (6)
  • apps/condo/domains/ai/components/AIChatFile/AIChatDocument.module.css
  • apps/condo/domains/ai/components/AIChatFile/AIChatDocument.tsx
  • apps/condo/domains/ai/hooks/useAIChatAttachments.tsx
  • apps/condo/lang/en/en.json
  • apps/condo/lang/es/es.json
  • apps/condo/lang/ru/ru.json
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/condo/lang/en/en.json
  • apps/condo/domains/ai/components/AIChatFile/AIChatDocument.tsx
  • apps/condo/domains/ai/hooks/useAIChatAttachments.tsx

Comment thread apps/condo/domains/ai/constants.js Outdated
Comment thread apps/condo/domains/common/constants/featureflags.js Outdated
})
})

describe('Attachments validation', () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

you need to add langfuse datasets too

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

not in this pr tho

Comment thread apps/condo/domains/ai/hooks/useAIChatAttachments.tsx Outdated
Comment thread apps/condo/domains/ai/hooks/useAIChatAttachments.tsx Outdated
Comment thread apps/condo/domains/ai/hooks/useAIChatAttachments.tsx Outdated
Comment thread apps/condo/domains/ai/hooks/useAIChatAttachments.tsx Outdated
Comment thread apps/condo/domains/ai/components/AIChat/AIChat.tsx Outdated
@tolmachev21 tolmachev21 force-pushed the feat/condo/DOMA-13253/add-file-in-ai-chat branch from 0bc43df to 95b445c Compare June 5, 2026 05:53
@tolmachev21 tolmachev21 force-pushed the feat/condo/DOMA-13253/add-file-in-ai-chat branch from 95b445c to 0bc43df Compare June 5, 2026 05:59
@tolmachev21 tolmachev21 force-pushed the feat/condo/DOMA-13253/add-file-in-ai-chat branch from 0bc43df to dd052b5 Compare June 5, 2026 06:34
Comment thread apps/condo/domains/ai/hooks/useAIChatAttachments.ts Outdated
Comment thread apps/condo/domains/ai/hooks/useAIChatAttachments.ts Outdated
Comment thread apps/condo/domains/ai/components/AIChat/AIChat.module.css Outdated
Comment thread apps/condo/domains/ai/components/AIChat/AIChatInput.module.css Outdated
Comment thread apps/condo/domains/ai/hooks/useAIChatAttachments.ts
@tolmachev21 tolmachev21 force-pushed the feat/condo/DOMA-13253/add-file-in-ai-chat branch from 3a8de6d to 19f6bf0 Compare June 9, 2026 06:09
@sonarqubecloud

sonarqubecloud Bot commented Jun 9, 2026

Copy link
Copy Markdown

@tolmachev21 tolmachev21 merged commit 9e9ef2f into main Jun 9, 2026
44 checks passed
@tolmachev21 tolmachev21 deleted the feat/condo/DOMA-13253/add-file-in-ai-chat branch June 9, 2026 08:49
tolmachev21 added a commit that referenced this pull request Jun 10, 2026
* feat(condo): DOMA-13253 add file attachments to ai chat

* feat(condo): DOMA-13253 fix lint

* feat(condo): DOMA-13253 fix tests

* feat(condo): DOMA-13253 small fix after review

* feat(condo): DOMA-13253 small fix after review 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants