mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-28 11:41:04 +00:00
docs(channels): document attachments and block streaming features
- Add Attachments interface docs with handling examples - Document block streaming configuration and behavior - Update architecture diagrams to show attachment resolution - Add Attachment type to exported types reference - Update plugin-example README Covers new structured attachment support and block streaming that delivers responses as multiple progressive messages. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
3e0f213ea3
commit
39103eea5f
4 changed files with 161 additions and 41 deletions
|
|
@ -68,23 +68,61 @@ export class MyChannel extends ChannelBase {
|
|||
|
||||
The normalized message object you build from platform data. The boolean flags drive gate logic, so they must be accurate.
|
||||
|
||||
| Field | Type | Required | Notes |
|
||||
| ---------------- | ------- | -------- | -------------------------------------------------------------------------- |
|
||||
| `channelName` | string | Yes | Use `this.name` |
|
||||
| `senderId` | string | Yes | Must be stable across messages (used for session routing + access control) |
|
||||
| `senderName` | string | Yes | Display name |
|
||||
| `chatId` | string | Yes | Must distinguish DMs from groups |
|
||||
| `text` | string | Yes | Strip bot @mentions |
|
||||
| `threadId` | string | No | For `sessionScope: "thread"` |
|
||||
| `messageId` | string | No | Platform message ID — useful for response correlation |
|
||||
| `isGroup` | boolean | Yes | GroupGate relies on this |
|
||||
| `isMentioned` | boolean | Yes | GroupGate relies on this |
|
||||
| `isReplyToBot` | boolean | Yes | GroupGate relies on this |
|
||||
| `referencedText` | string | No | Quoted message — prepended as context |
|
||||
| `imageBase64` | string | No | Base64-encoded image for multimodal models |
|
||||
| `imageMimeType` | string | No | e.g., `image/jpeg` |
|
||||
| Field | Type | Required | Notes |
|
||||
| ---------------- | ------------ | -------- | -------------------------------------------------------------------------- |
|
||||
| `channelName` | string | Yes | Use `this.name` |
|
||||
| `senderId` | string | Yes | Must be stable across messages (used for session routing + access control) |
|
||||
| `senderName` | string | Yes | Display name |
|
||||
| `chatId` | string | Yes | Must distinguish DMs from groups |
|
||||
| `text` | string | Yes | Strip bot @mentions |
|
||||
| `threadId` | string | No | For `sessionScope: "thread"` |
|
||||
| `messageId` | string | No | Platform message ID — useful for response correlation |
|
||||
| `isGroup` | boolean | Yes | GroupGate relies on this |
|
||||
| `isMentioned` | boolean | Yes | GroupGate relies on this |
|
||||
| `isReplyToBot` | boolean | Yes | GroupGate relies on this |
|
||||
| `referencedText` | string | No | Quoted message — prepended as context |
|
||||
| `imageBase64` | string | No | Base64-encoded image (legacy — prefer `attachments`) |
|
||||
| `imageMimeType` | string | No | e.g., `image/jpeg` (legacy — prefer `attachments`) |
|
||||
| `attachments` | Attachment[] | No | Structured media attachments (see below) |
|
||||
|
||||
For **files**: download from your platform, save to a temp directory, include the file path in `text`.
|
||||
### Attachments
|
||||
|
||||
Use the `attachments` array for images, files, audio, and video. `handleInbound()` resolves them automatically: images with base64 `data` are sent to the model as vision input, files with a `filePath` get their path appended to the prompt so the agent can read them.
|
||||
|
||||
```typescript
|
||||
interface Attachment {
|
||||
type: 'image' | 'file' | 'audio' | 'video';
|
||||
data?: string; // base64-encoded data (images, small files)
|
||||
filePath?: string; // absolute path to local file (large files saved to disk)
|
||||
mimeType: string; // e.g. 'application/pdf', 'image/jpeg'
|
||||
fileName?: string; // original file name from the platform
|
||||
}
|
||||
```
|
||||
|
||||
Example — handling a file upload in your adapter:
|
||||
|
||||
```typescript
|
||||
import { writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { tmpdir } from 'node:os';
|
||||
|
||||
const buf = await downloadFromPlatform(fileId);
|
||||
const dir = join(tmpdir(), 'channel-files');
|
||||
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
||||
const filePath = join(dir, fileName);
|
||||
writeFileSync(filePath, buf);
|
||||
|
||||
envelope.attachments = [
|
||||
{
|
||||
type: 'file',
|
||||
filePath,
|
||||
mimeType: 'application/pdf',
|
||||
fileName,
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
The legacy `imageBase64`/`imageMimeType` fields still work for backwards compatibility but `attachments` is preferred for new code.
|
||||
|
||||
## Extension Manifest
|
||||
|
||||
|
|
@ -126,7 +164,11 @@ override async handleInbound(envelope: Envelope): Promise<void> {
|
|||
|
||||
**Tool call hooks** — override `onToolCall()` to display agent activity (e.g., "Running shell command...").
|
||||
|
||||
**Media** — download from your platform, set `imageBase64`/`imageMimeType` on the Envelope before calling `handleInbound()`.
|
||||
**Streaming hooks** — override `onResponseChunk(chatId, chunk, sessionId)` for per-chunk progressive display (e.g., editing a message in-place). Override `onResponseComplete(chatId, fullText, sessionId)` to customize final delivery.
|
||||
|
||||
**Block streaming** — set `blockStreaming: "on"` in the channel config. The base class automatically splits responses into multiple messages at paragraph boundaries. No plugin code needed — it works alongside `onResponseChunk`.
|
||||
|
||||
**Media** — populate `envelope.attachments` with images/files. See [Attachments](#attachments) above.
|
||||
|
||||
## Reference Implementations
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue