* chore: ignore local worktrees
* docs(channels): design identity and task lifecycle p0
* docs(channels): plan identity and task lifecycle p0
* feat(channels): add identity and task lifecycle metadata
* fix(channels): suppress cancelled tool call lifecycle
* docs: add channel lifecycle status adapter design
* docs: add channel lifecycle status adapter plan
* feat(channels): map telegram lifecycle to typing
* feat(channels): map weixin lifecycle to typing
* fix(channels): reset weixin typing state after failed start
* feat(channels): map dingtalk lifecycle to reactions
* feat(channels): add feishu card status labels
* fix(channels): preserve feishu collapsible status labels
* feat(channels): show feishu lifecycle card status
* fix(channels): cover loop lifecycle metadata
* fix(channels): preserve feishu terminal card status
* chore: remove internal task reports from branch
* fix(channels): clear late lifecycle status starts
* fix(channels): harden lifecycle event edges
* fix(channels): clean adapter lifecycle state
* fix(channels): finalize cancelled lifecycle before cleanup
* fix(feishu): keep cancelled card status visible
* docs(channels): add lifecycle status no-op coverage
* fix(channels): address lifecycle review suggestions
* docs(channels): align lifecycle status documentation
* fix(channels): route adapter stop through lifecycle cancel
* fix(channels): close lifecycle cancellation races
* fix(channels): keep first feishu terminal status
* fix(telegram): guard lifecycle typing updates
* test(qqbot): cover lifecycle status no-ops
* fix(feishu): preserve completed card race status
* docs(lifecycle): align status review docs
* fix(channels): separate pending cancel state
* fix(channels): clean adapter lifecycle status edges
* fix(channels): order clear cancellation lifecycle
* fix(feishu): preserve user stop status label
* fix(channels): suppress loop chunks during pending cancel
* test(channels): use active session in cancel regression
* fix(channels): harden adapter cancellation tests
* fix(channels): sanitize lifecycle tool fields
* fix(channels): route shared tool call lifecycle
* fix(channels): preserve pending cancel intent
* fix(channels): preserve pending cancel intent
* fix(telegram): track typing by session
* fix(feishu): preserve stop status during finalization
* fix(channels): preserve responses after failed cancel
* fix(channels): tighten lifecycle cancellation reasons
* fix(channels): close lifecycle cancel races and validate identity config
Address the outstanding review findings on #6105:
- carry a typed reason on ChannelLoopSkippedError and report disabled
loops as 'dropped' instead of 'timeout'
- treat a turn as committed once delivery starts: /cancel re-checks
deliveryStarted after the cancel RPC settles, and neither prompt path
lets a late-settling cancel rewrite a delivered turn into cancelled
(or follow a /clear cancellation with completed)
- tag failed lifecycle events with phase: agent vs delivery
- validate identity/memoryScope shape at config parse time instead of
throwing an opaque TypeError on the first prompt of every session
- guard onPromptStart hooks, pass job.id to loop onPromptStart/End,
append the boundary block after operator instructions, gate
/who + /status identity lines on configured identity/memoryScope,
cache the boundary prompt, and route error logs through
lifecycleError()
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* test(qqbot): keep lifecycle mock in sync
* fix(channels): unify cancel state machine and adapter lifecycle edges
Address the remaining review findings on #6114:
- /cancel now delegates to requestActivePromptCancellation — one cancel
state machine for slash command and adapter stop buttons; the helper
refuses to claim success once delivery started and sanitizes its logs
- share isTerminalTaskLifecycleType from channel-base instead of four
hand-rolled terminal checks
- DingTalk: only attach reactions for message ids seen inbound (loop job
ids no longer trigger doomed emotion API calls), log reaction API
failures, and recall reactions when a session dies
- Feishu: track userStopped on the card state so every wind-down path
renders 已停止生成 after a Stop click, and pass terminal labels through
updateCard's statusLabel param at the remaining baked-text sites
- Weixin: guard the typing .then() against a racing disconnect
- document onTaskLifecycle as the canonical hook (onPromptStart/End are
back-compat), fix TS4111 bracket access in the DingTalk test
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(channels): keep failed terminal event when cancel settles post-delivery
Self-review follow-up: once delivery started, the catch paths no longer
reconcile a pending cancel — a late-resolving cancel RPC used to flip
cancelled=true there, suppressing the failed emit while the /cancel
handler (seeing deliveryStarted) also declined to emit, leaving a
started task with no terminal lifecycle event at all.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(channels): close self-review findings on adapter lifecycle edges
- DingTalk: track inbound message ids in a capped insertion-ordered set
instead of the TTL-swept dedup map, so a turn queued minutes behind a
long predecessor still attaches its reaction
- Feishu: reset userStopped when the cancel RPC fails (later wind-down
must render the real terminal status), and give handleStop's plain
message fallback the same ---/label shape the strip regex expects
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(channels): hold streamed chunks while a cancel is pending
Chunks arriving while a /cancel RPC is in flight were pushed straight
into the BlockStreamer, which can send a block on a size/paragraph
threshold before the cancel resolves — leaking output a successful
cancel can never recall. Hold the pending-window chunks instead: replay
them (block streaming + text_chunk transcript) when the cancel fails,
discard them when it succeeds. onResponseChunk stays live through the
window so adapter-accumulated display state has no permanent hole on a
failed cancel; adapters gate visible updates on their own stop flags.
Also stop passing the loop job id to onPromptStart/onPromptEnd (and the
/clear eviction path): the hook contract is inbound platform message
ids, and adapters act on them — cards and reactions keyed to a fake id.
Lifecycle events still carry job.id for correlation.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(feishu): strip every status-label layout from quoted-reply context
Replace the two $-anchored strip regexes in extractCardText with one
line-granular status-block filter. The anchored patterns missed four
layouts the cards actually render: the two-block truncation card
(notice block + label block), terminal labels joined mid-string before
a collapsible panel body, the 停止失败,请重试 label (never in the
alternation), and label-only stopped cards where the divider leads the
text. Tests now assert the real rendered shapes.
Also update the adapter-cancellation suppression test to the new
hold-and-replay chunk semantics from the base layer.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(feishu): ignore loop job ids in prompt hooks
* fix(channels): defer adapter chunks while cancel is pending
* fix(feishu): preserve bare status text in quotes
* fix(channels): release held chunks on failed cancel
* fix(feishu): preserve generated stop fallback status
* fix(telegram): clear typing on dead sessions
* fix(feishu): share status label definitions
---------
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- 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>
- Update channel-base to use built dist/ output with proper exports
- Add README with quick start guide and usage instructions
- Add qwen-extension.json manifest for extension discovery
- Add start-server CLI for running the mock WebSocket server
- Update dependencies from local file: to npm version
This enables the plugin-example package to be published and installed
as a standalone extension for testing the channel plugin system.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>