Skip to content

Conversation

@ibetitsmike
Copy link
Contributor

Summary

Refactors chat attachments plumbing from the confusing imageParts naming to generic fileParts, and extends attachments beyond images to include PDFs (application/pdf).

Implementation

  • ORPC + shared types: imagePartsfileParts, ImagePartFilePart, MuxImagePartMuxFilePart.
  • Chat input:
    • Renamed draft storage to inputAttachments:* and generalized UI to ChatAttachments.
    • Accepts image + PDF attachments via paste/drag-drop and stores them as data URLs.
  • Rendering:
    • User messages now render non-image attachments as a small file link/chip; images still render inline.
  • Model gating:
    • Added getModelCapabilities() helper backed by models.json to detect supports_pdf_input and max_pdf_size_mb.
    • Frontend blocks sending PDFs for models that don’t support PDF input (and enforces per-model max PDF size when available).
    • Backend adds defense-in-depth checks for the same constraints.

Validation

  • make static-check

Risks

  • LocalStorage draft key for unsent attachments is intentionally not backward-compatible (old inputImages:* drafts won’t restore).

Generated with mux • Model: openai:gpt-5.2 • Thinking: xhigh • Cost: $7.74

@github-actions github-actions bot added enhancement New feature or functionality refactor labels Jan 24, 2026
Copy link

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

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: edfcb8fb8d

ℹ️ 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".

@ibetitsmike ibetitsmike added this pull request to the merge queue Jan 26, 2026
Merged via the queue into main with commit 7426982 Jan 26, 2026
38 of 40 checks passed
@ibetitsmike ibetitsmike deleted the mike/attachments-pdf branch January 26, 2026 10:36
ethanndickson added a commit that referenced this pull request Jan 26, 2026
#1896 regressed #1146 by awaiting sendMessage before calling
onWorkspaceCreated. This caused the 'Creating workspace' splash to
block until sendMessage resolved, which waits for init to complete.
For devcontainer/SSH runtimes, init can take minutes.

Restore the fire-and-forget pattern: navigate immediately after
workspace.create() succeeds. Draft input/attachments are now
cleared only after sendMessage succeeds (via .then()), preserving
them if the send fails.

Added regression test that verifies onWorkspaceCreated is called
before sendMessage resolves (using a never-resolving promise mock).
github-merge-queue bot pushed a commit that referenced this pull request Jan 26, 2026
## Summary

Fixes a regression where the "Creating workspace" splash blocked until
`sendMessage` completed. For devcontainer/SSH runtimes, this could take
minutes since `sendMessage` waits for init (container build) to finish.

## Background

**Regressed in #1896** ("feat: support PDF attachments") which changed
`void api.workspace.sendMessage(...)` (fire-and-forget) to `await
api.workspace.sendMessage(...)` and moved `onWorkspaceCreated` after it.

This undid the fix from **#1146** ("perf: exit splash screen immediately
after workspace.create()").

## Implementation

- Move `onWorkspaceCreated` and `setIsSending(false)` to immediately
after `workspace.create()` succeeds
- Change `sendMessage` back to fire-and-forget with `void`
- Clear draft input/attachments only after `sendMessage` succeeds (via
`.then()`), preserving them if the send fails

## Validation

- Added regression test that verifies `onWorkspaceCreated` is called
before `sendMessage` resolves (using a never-resolving promise mock)
- Existing tests pass
- `make static-check` passes

---

_Generated with `mux` • Model: `anthropic:claude-opus-4-5` • Thinking:
`high` • Cost: `$7.42`_

<!-- mux-attribution: model=anthropic:claude-opus-4-5 thinking=high
costs=7.42 -->
ethanndickson added a commit that referenced this pull request Jan 26, 2026
## Summary

Fixes a regression where the "Creating workspace" splash blocked until
`sendMessage` completed. For devcontainer/SSH runtimes, this could take
minutes since `sendMessage` waits for init (container build) to finish.

## Background

**Regressed in #1896** ("feat: support PDF attachments") which changed
`void api.workspace.sendMessage(...)` (fire-and-forget) to `await
api.workspace.sendMessage(...)` and moved `onWorkspaceCreated` after it.

This undid the fix from **#1146** ("perf: exit splash screen immediately
after workspace.create()").

## Implementation

- Move `onWorkspaceCreated` and `setIsSending(false)` to immediately
after `workspace.create()` succeeds
- Change `sendMessage` back to fire-and-forget with `void`
- Clear draft input/attachments only after `sendMessage` succeeds (via
`.then()`), preserving them if the send fails

## Validation

- Added regression test that verifies `onWorkspaceCreated` is called
before `sendMessage` resolves (using a never-resolving promise mock)
- Existing tests pass
- `make static-check` passes

---

_Generated with `mux` • Model: `anthropic:claude-opus-4-5` • Thinking:
`high` • Cost: `$7.42`_

<!-- mux-attribution: model=anthropic:claude-opus-4-5 thinking=high
costs=7.42 -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or functionality refactor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant