feat(relay): unify messenger file delivery#41
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces a messenger-neutral file delivery model for PiRelay, including a new local /relay send-file command for explicitly sending safe workspace files to paired Telegram/Discord/Slack bindings, completes Slack live file uploads via Slack’s external upload flow, and unifies final-output delivery behavior across messengers (chunking vs Markdown document fallback) with updated docs/specs/tests.
Changes:
- Added local
/relay send-filewith workspace-relative path validation and delivery to one messenger instance or all active bindings. - Implemented Slack external upload flow (
files.getUploadURLExternal→ byte upload →files.completeUploadExternal) and wired Slack runtime image commands to actual uploads. - Introduced shared final-output delivery policy utilities (mode-aware, paragraph-aware chunking, Markdown fallback) plus expanded test coverage and documentation/spec updates.
Reviewed changes
Copilot reviewed 36 out of 36 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/slack-runtime.test.ts | Adds Slack live upload tests + runtime tests for image upload behaviors and updated completion/no-image expectations. |
| tests/runtime.test.ts | Updates Telegram runtime test to set binding progress mode for completion behavior validation. |
| tests/relay/setup-wizard.test.ts | Ensures generated Slack manifests include files:write. |
| tests/relay/final-output.test.ts | Adds unit tests for shared final-output chunking and document fallback behavior. |
| tests/relay/file-delivery.test.ts | Adds tests for workspace file validation/loading (path safety, symlink escape, binary/size/type rejection). |
| tests/relay/clipboard.test.ts | Increases clipboard helper timeouts to reduce flakiness. |
| tests/relay-setup.test.ts | Adds parsing/completion tests for /relay send-file. |
| tests/integration.test.ts | Adds integration coverage for local /relay send-file delivery (Slack target + all target/paused/unsafe-path cases). |
| tests/channel-adapter.test.ts | Adds tests for paragraph-aware chunk packing behavior. |
| README.md | Documents /relay send-file, Slack files:write scope, and updated mode-aware final-output behavior. |
| openspec/changes/add-slack-file-upload-delivery/tasks.md | Tracks implementation tasks for Slack uploads, local file delivery, and final-output policy. |
| openspec/changes/add-slack-file-upload-delivery/specs/slack-relay-adapter/spec.md | Specifies Slack outbound file delivery requirements and error-handling expectations. |
| openspec/changes/add-slack-file-upload-delivery/specs/relay-file-delivery/spec.md | Specifies local file delivery safety rules, target resolution, and final-output fallback policy. |
| openspec/changes/add-slack-file-upload-delivery/specs/relay-configuration/spec.md | Specifies Slack setup guidance requirements for file upload permissions. |
| openspec/changes/add-slack-file-upload-delivery/specs/relay-channel-adapters/spec.md | Defines adapter capability expectations for document/file delivery consistency. |
| openspec/changes/add-slack-file-upload-delivery/specs/messenger-relay-sessions/spec.md | Specifies Slack image retrieval semantics + shared final-output policy across messengers. |
| openspec/changes/add-slack-file-upload-delivery/proposal.md | Describes motivation and scope for unified file delivery and final-output consistency. |
| openspec/changes/add-slack-file-upload-delivery/design.md | Captures design decisions, safety boundaries, and trade-offs for file delivery and output policy. |
| openspec/changes/add-slack-file-upload-delivery/.openspec.yaml | Adds OpenSpec metadata for the change set. |
| extensions/relay/runtime/extension-runtime.ts | Implements /relay send-file command handling, target resolution, and per-messenger delivery dispatch. |
| extensions/relay/core/final-output.ts | Adds shared final-output policy helpers (mode gate, Markdown file creation, chunk/file fallback). |
| extensions/relay/core/file-delivery.ts | Adds workspace outbound file loading + validation (path safety, symlink escape prevention, MIME/type checks). |
| extensions/relay/core/channel-adapter.ts | Replaces naive text chunking with paragraph-aware chunk packing logic. |
| extensions/relay/config/setup.ts | Extends local command parsing/completion + updates Slack setup guidance with files:write. |
| extensions/relay/config/setup-wizard.ts | Updates Slack checklist and manifest snippet to include files:write. |
| extensions/relay/adapters/telegram/runtime.ts | Refactors Markdown file naming via shared helper + refuses remote send-file + applies mode-aware completion behavior in notifications. |
| extensions/relay/adapters/slack/runtime.ts | Enables Slack image commands via uploads, adds send-file refusal, and uses shared final-output fallback on completion. |
| extensions/relay/adapters/slack/live-client.ts | Implements Slack external upload flow and adjusts live-ops creation for outbound use without Socket Mode token. |
| extensions/relay/adapters/slack/adapter.ts | Threads Slack thread timestamp through file uploads and button prompts. |
| extensions/relay/adapters/discord/runtime.ts | Adds completion final-output fallback, refuses remote send-file, and adds outbound sendFileToBoundRoute. |
| docs/testing.md | Updates manual testing checklist for /relay send-file and Slack files:write setup. |
| docs/slack-live-integration.md | Documents required Slack files:write scope for image/file delivery. |
| docs/slack-app-manifests/pirelay-live-bot-b.yaml | Adds files:write to checked-in Slack app manifest. |
| docs/slack-app-manifests/pirelay-live-bot-a.yaml | Adds files:write to checked-in Slack app manifest. |
| docs/config.md | Updates Slack setup guidance to include files:write and its impact on file/fallback delivery. |
| docs/adapters.md | Clarifies local-only nature of generic file delivery (/relay send-file) and remote refusal behavior. |
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 36 out of 36 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
extensions/relay/adapters/telegram/runtime.ts:1876
- In the non-InProcess (broker) path,
sendSessionNotificationmay sendroute.notification.lastAssistantTextverbatim when progress mode is not quiet. For large completions this can exceed Telegram’s message size limits and fail delivery, sinceBrokerTunnelRuntimeultimately callssendPlainTextonce (no chunking / document fallback). Consider keeping broker fallback tolastSummary+ “/full” hint, or implement bounded paragraph-aware chunking (and ideally the same Markdown-document fallback) for the broker send path so large outputs are still deliverable.
const mode = progressModeFor(route.binding, config);
const fallback = status === "completed"
? (shouldSendFullFinalOutput(mode) ? route.notification.lastAssistantText : route.notification.lastSummary) ?? summarizeTextDeterministically(route.notification.lastAssistantText ?? "Pi task completed.")
: route.notification.lastFailure ?? `Pi task ${status}.`;
const imageHint = status === "completed" && !route.notification.structuredAnswer && route.notification.latestImages?.count
? `\n\n🖼 ${route.notification.latestImages.count} image output/file(s) available. Use /images to download.`
: "";
await runtime.sendToBoundChat(route.sessionKey, `${fallback}${imageHint}`);
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/relay send-filefor safe workspace file delivery to Telegram, Discord, Slack, or all paired messengersValidation