Skip to content

feat(bcs): fire system message on session file upload complete#445

Open
zh-bupt wants to merge 1 commit into
devfrom
feat/session-file-upload-system-message-final
Open

feat(bcs): fire system message on session file upload complete#445
zh-bupt wants to merge 1 commit into
devfrom
feat/session-file-upload-system-message-final

Conversation

@zh-bupt

@zh-bupt zh-bupt commented Jul 25, 2026

Copy link
Copy Markdown
Collaborator

What

When a bot or human completes a session file upload, fire a GenericNotification system message to the other bots (via chat.inject) and the frontend ws, using the fixed text format:

{prefix} {uploader} 上传了一个文件 {fileName} ({fileId},{readableSize}),下载链接:{url}
  • prefix is Bot for a bot uploader, 用户 for a human.
  • Example: Bot 测试Agent 上传了一个文件 readme.md (THISISFILEID,12 KB),下载链接:https://bcn.alipay.com/sessions/SESSION_ID/files/THISISFILEID/content

How

Reuses the existing SystemMessageEvent::GenericNotification path — no new event kind, producer, or bootstrap registration. All changes live in one file: crates/adapters/http/bcs-http/src/routes/session_files.rs.

  • complete_upload captures the session and, on success, calls a new best-effort notify_file_uploaded helper. notify is best-effort and only runs on the Ok path, so it never fails the upload response.
  • Recipients = the session's bot participants excluding the uploader. If there are no other bots, the notification is skipped entirelyGenericNotificationMessageProducer falls back to all bot participants on empty receivers, which would self-inject the uploader.
  • Download link uses bcs_endpoint (from BcsConfig.bcs_endpoint) with an http://{bind}:{port} fallback and a URL-encoded session id. The link is permanent and resolves for all recipients (bot bearers / human session members).
  • Uploader name: bot via registry.get(..)->capabilities.name (fallback id); human via nick_name (fallback staff_no).

New private helpers in the route module: human_readable_size, file_download_url, file_upload_receivers, uploader_display_name; plus a RecordingSystemMessage test spy wired into the in-module TestApp fixture.

Diff scope

session_files.rs only — +405 / −7.

Testing

cargo test -p bcs-http --lib74 passed / 0 failed; cargo build -p bcs-http warning-free.

Coverage:

  • Bot-uploader integration test (HTTP through the router) — asserts the exact message text, group_id, and receivers == [other-bot].
  • Failure test — a failed complete-upload (404) fires no notify.
  • Guard unit test — uploader is the only bot → no notify (no self-inject, no frontend broadcast).
  • Human-uploader unit test — produces a 用户 ... message delivered to all bots.

When a bot or human completes a session file upload, fire a
GenericNotification system message to the other bots (via chat.inject)
and the frontend ws, using the fixed text format:

  {prefix} {uploader} 上传了一个文件 {fileName} ({fileId},{readableSize}),下载链接:{url}

prefix is "Bot" for a bot uploader and "用户" for a human. Reuses the
existing GenericNotification path — no new event kind, producer, or
bootstrap registration. Recipients are the session's bot participants
excluding the uploader; if there are no other bots the notification is
skipped entirely (the generic producer falls back to all bots on empty
receivers, which would self-inject the uploader). Notify is best-effort
and only runs on the successful upload path, so it never fails the
upload response. The download link uses bcs_endpoint with an
http://{bind}:{port} fallback and a URL-encoded session id.

Adds four private helpers in the session_files route module:
human_readable_size, file_download_url, file_upload_receivers,
uploader_display_name; a RecordingSystemMessage test spy wired into the
in-module TestApp fixture; and integration + unit tests covering the
bot/human uploader cases and the empty-receivers guard.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant