Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions docs/design/session-attachment-references.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Session attachment references

## Problem

Embedding image base64 and file bytes in daemon requests, queues, events, and
replay data duplicates potentially large payloads. Attachments also need to
remain previewable after the daemon restarts.

## Design

The daemon writes image and arbitrary file bytes to the workspace runtime's attachment
directory and returns a filename-based reference:

```ts
{
type: 'image' | 'resource';
attachmentId: string;
mimeType: string;
size: number;
}
```

The attachment ID is the stored filename. Duplicate names use the platform
convention `name (1).ext`, `name (2).ext`, and so on. There is no in-memory
attachment index or sidecar metadata; MIME type and size are derived from the
stored file when it is read.

Prompt and mid-turn APIs carry references through queues, events, and
transcript metadata. The bridge resolves them only when dispatching to the ACP
child. The TypeScript session client hydrates the same references for previews
and replay rendering through the authenticated attachment route.
Text resources resolve as ACP text; other file formats resolve as ACP blobs, so
their original bytes are not decoded or altered in the browser.

## Ownership and lifecycle

- Storage lives at `~/.qwen/tmp/<workspace-hash>/attachments/session-<id>/`
(or the equivalent custom runtime directory).
- The resolved live-session owner and client authorization protect every
upload, read, and removal operation.
- Closing a daemon or detaching a client closes handles but keeps the files.
- Permanently deleting a session removes its attachment directory.
- No TTL, sweeper, retained-media cache, or restart reconstruction index is
used.
- Each attachment is limited to 8 MiB. Sessions have no cumulative attachment
size or count limit.

The unified capability is `session_attachments`; the unified HTTP surface is
`/session/:id/attachments`. There is no `session_media`, `/media`, or `mediaId`
compatibility path.
46 changes: 0 additions & 46 deletions docs/design/session-media-references.md

This file was deleted.

60 changes: 60 additions & 0 deletions docs/design/web-shell-drop-intent-choice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Web Shell dropped-file intent choice

## Problem

The composer currently infers intent from file type: image-only drops become
prompt attachments, while ordinary or mixed drops upload to the workspace and
insert `@` references. File type does not express user intent. A user may want
an image persisted in the workspace, or a text file attached only to the next
prompt.

## Design

When workspace upload is available, a drop containing one or more files opens
one modal with their names, sizes, and three actions:

- **Reference content** uses the existing prompt-attachment ingestion path.
The original browser files remain local to the draft. On submit they upload
unchanged to the daemon's session attachment store under the
workspace-scoped Qwen runtime temp directory. Prompt JSON carries
filename-based attachment IDs; the bridge resolves them only at dispatch.
- **Upload to workspace** uses the existing upload queue, configured upload
directory, progress UI, and server-confirmed `@` reference insertion.
- **Cancel** discards the drop.

Every file type can be referenced. Multi-file drops use the same choice as
single files; the browser does not pre-disable referencing based on the
the files already present in the current draft.

The browser `File` objects are copied synchronously during the drop event, so
the choice does not depend on a `DataTransfer` after the event returns. The
dialog closes if the composer target changes or upload becomes unavailable.

When workspace upload is unavailable, drops keep the existing attachment
behavior instead of showing an upload action that cannot succeed. Host-level
`fileUploadEnabled={false}` retains its existing contract and disables all
file drag-in. Clipboard paste and the `@` panel upload item are unchanged.

File attachment chips are interactive before and after optimistic submission.
Opening one shows the referenced file in the right-side preview panel.
Completed workspace uploads and their file tags open the same panel by reading
the uploaded workspace path. Image attachments retain their existing thumbnail
and image-panel behavior.

## Storage and compatibility

The default attachment root is
`~/.qwen/tmp/<workspace-hash>/attachments/`, resolved through
`Storage.getProjectTempDir()` so custom runtime directories continue to work.
Each session owns `session-<encoded-session-id>/`. Files use their stored names
as attachment IDs, with ` (1)` suffixes for duplicates. Daemon shutdown and
client detach keep the directory; permanent session deletion removes it.

Images and files use the same `session_attachments` capability,
`/attachments` routes, and `attachmentId` references. There is no retained
media cache, TTL cleanup, in-memory filename index, or legacy `mediaId` path.

## Scope

Attachment admission limits are enforced by ingestion and the daemon rather
than by the choice dialog.
2 changes: 1 addition & 1 deletion integration-tests/cli/qwen-serve-routes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ describe('qwen serve — capabilities envelope', () => {
'session_side_task',
'session_prompt',
'session_turn_status',
'session_media',
'session_attachments',
Comment thread
ytahdn marked this conversation as resolved.
'session_mid_turn_message_mutation',
'session_mid_turn_message_query',
'session_cancel',
Expand Down
6 changes: 3 additions & 3 deletions packages/acp-bridge/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@
"types": "./dist/sessionArtifacts.d.ts",
"import": "./dist/sessionArtifacts.js"
},
"./sessionMedia": {
"types": "./dist/sessionMedia.d.ts",
"import": "./dist/sessionMedia.js"
"./sessionAttachments": {
"types": "./dist/sessionAttachments.d.ts",
"import": "./dist/sessionAttachments.js"
},
"./daemonEventTypes": {
"types": "./dist/daemonEventTypes.d.ts",
Expand Down
Loading
Loading