molecule-core/workspace
Hongming Wang f81813f708 feat(rfc): poll-mode chat upload — phase 2 workspace inbox extension
Workspace-side fetcher for the platform-staged chat uploads written by
phase 1. Stack atop feat/poll-mode-chat-upload-phase1.

Wire shape — the platform writes one activity_logs row per uploaded
file with `activity_type=a2a_receive`, `method=chat_upload_receive`,
and a `request_body={file_id, name, mimeType, size, uri}` carrying
the synthetic `platform-pending:<wsid>/<fid>` URI.

Workspace-side flow (new module workspace/inbox_uploads.py):

  1. Fetch via GET /workspaces/:id/pending-uploads/:file_id/content
  2. Stage to /workspace/.molecule/chat-uploads/<32-hex>-<sanitized>
     (same on-disk shape as internal_chat_uploads.py — agent-side
     URI resolvers see no contract change)
  3. POST /workspaces/:id/pending-uploads/:file_id/ack
  4. Cache `platform-pending: → workspace:` so the eventual chat
     message that REFERENCES the upload (separate, later activity row)
     gets URI-rewritten before the agent sees it.

Inbox poller extension (workspace/inbox.py):

  - is_chat_upload_row(row) discriminator on `method`
  - upload-receive rows trigger fetch_and_stage and are NOT enqueued
    as InboxMessages (they're side-effect rows, not chat messages)
  - cursor advances past them regardless of fetch outcome — a
    permanent /content failure must not stall the cursor and block
    real chat traffic
  - message_from_activity calls rewrite_request_body to swap
    platform-pending: URIs to local workspace: URIs in subsequent
    chat messages' file parts. Cache miss leaves the URI untouched
    so the agent surfaces an unresolvable URI rather than the inbox
    silently dropping the part.

Filename sanitization mirrors workspace-server/internal/handlers
/chat_files.go::SanitizeFilename and workspace/internal_chat_uploads
.py::sanitize_filename — pinned by the existing parity test suites.

Coverage: 100% on inbox_uploads.py; the inbox.py extension is fully
covered by three new tests in test_inbox.py (skip-from-queue,
cursor-advance-past-broken-fetch, URI-rewrite ordering).
2026-05-05 04:39:02 -07:00
..
adapters
builtin_tools
lib
molecule_audit
platform_tools feat(mcp): multi-workspace routing for memory + chat_history + workspace_info 2026-05-04 14:17:58 -07:00
plugins_registry
policies
scripts
skill_loader
tests feat(rfc): poll-mode chat upload — phase 2 workspace inbox extension 2026-05-05 04:39:02 -07:00
.coveragerc
a2a_cli.py
a2a_client.py perf(a2a): bound + LRU-evict _peer_metadata cache (#2482) 2026-05-05 01:39:07 -07:00
a2a_executor.py
a2a_mcp_server.py docs(a2a-mcp): close three contract gaps codex agents inherit out-of-the-box 2026-05-05 02:26:35 -07:00
a2a_tools.py feat(delegations): agent-side cutover — sync delegate uses async+poll path (RFC #2829 PR-5) 2026-05-04 21:31:11 -07:00
adapter_base.py feat: drop shared_context — use memory v2 team namespace instead 2026-05-04 16:30:26 -07:00
agent.py
agents_md.py
boot_routes.py test(runtime): pin PR #2756's card-vs-setup decoupling with build_routes helper 2026-05-04 14:59:56 -07:00
build-all.sh
card_helpers.py fix(runtime): isolate card-skill enrichment + transcript handler from adapter shape mismatch 2026-05-04 14:15:27 -07:00
config.py feat: drop shared_context — use memory v2 team namespace instead 2026-05-04 16:30:26 -07:00
configs_dir.py
consolidation.py
coordinator.py feat: drop shared_context — use memory v2 team namespace instead 2026-05-04 16:30:26 -07:00
Dockerfile
entrypoint.sh
event_log.py
events.py
executor_helpers.py
heartbeat.py
inbox_uploads.py feat(rfc): poll-mode chat upload — phase 2 workspace inbox extension 2026-05-05 04:39:02 -07:00
inbox.py feat(rfc): poll-mode chat upload — phase 2 workspace inbox extension 2026-05-05 04:39:02 -07:00
initial_prompt.py
internal_chat_uploads.py
internal_file_read.py
main.py test(runtime): pin PR #2756's card-vs-setup decoupling with build_routes helper 2026-05-04 14:59:56 -07:00
mcp_cli.py fix: bot-lint nits — drop unused imports, add reason to except 2026-05-04 08:16:12 -07:00
molecule_ai_status.py
not_configured_handler.py fix(runtime): redact secret-shaped tokens from JSON-RPC error.data 2026-05-04 15:07:53 -07:00
platform_auth.py feat(mcp): cross-workspace delegation routing (multi-ws PR-2) 2026-05-04 08:32:24 -07:00
platform_inbound_auth.py
plugins.py
preflight.py fix(preflight): downgrade required_env + auth_token failures to warnings 2026-05-04 12:20:34 -07:00
prompt.py feat: drop shared_context — use memory v2 team namespace instead 2026-05-04 16:30:26 -07:00
pytest.ini
rebuild-runtime-images.sh
requirements.txt
runtime_wedge.py
secret_redactor.py fix(runtime): redact secret-shaped tokens from JSON-RPC error.data 2026-05-04 15:07:53 -07:00
shared_runtime.py
smoke_mode.py
transcript_auth.py
watcher.py