@qwen-code/channel-base 0.19.11 → 0.19.12-preview.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -72,9 +72,9 @@ Migration note for existing TypeScript plugins: if your adapter constructor or f
72
72
  Channel adapters can run in two host modes:
73
73
 
74
74
  - `qwen channel start [name]` is the standalone service. It uses `AcpBridge` over a `qwen-code --acp` child process and remains the default channel command.
75
- - `qwen serve --channel <name>` and `qwen serve --channel all` are experimental daemon-managed modes. `qwen serve` starts one out-of-process channel worker, the worker connects back to the daemon through the SDK, and adapters receive a `DaemonChannelBridge`-backed `ChannelAgentBridge` facade.
75
+ - `qwen serve --channel <name>` and `qwen serve --channel all` are experimental daemon-managed modes. Named channels are grouped by owning workspace and `qwen serve` starts one out-of-process worker per owning runtime. Each worker connects back to the daemon through the SDK, and adapters receive a `DaemonChannelBridge`-backed `ChannelAgentBridge` facade. `--channel all` stays primary-only.
76
76
 
77
- In daemon-managed mode, one daemon is bound to one workspace. Every selected channel's `cwd` must resolve to that same workspace. The optional `shellCommand` method is exposed to adapters only when the daemon advertises the `session_shell_command` capability.
77
+ In daemon-managed mode, every named channel's `cwd` must resolve to exactly one registered, trusted workspace. Its worker receives that runtime's cwd and environment overlay; an ambiguous or untrusted selection fails instead of using primary. The optional `shellCommand` method is exposed to adapters only when the daemon advertises the `session_shell_command` capability.
78
78
 
79
79
  ## Architecture
80
80
 
@@ -320,6 +320,7 @@ interface Envelope {
320
320
  senderId: string; // stable, unique sender ID
321
321
  senderName: string; // display name
322
322
  chatId: string; // distinguishes DMs from groups
323
+ chatName?: string; // inbound group display name, when provided
323
324
  text: string; // message text (@mentions stripped)
324
325
  messageId?: string; // platform message ID
325
326
  threadId?: string; // for thread-scoped sessions
@@ -62,6 +62,13 @@ export interface BridgeSessionInfo {
62
62
  }
63
63
  export interface ChannelAgentBridgeSessionOptions {
64
64
  approvalMode?: string;
65
+ /**
66
+ * Channel instance name (e.g. `feishu-main`) stamped as the daemon `sourceId`
67
+ * on **new** sessions — creation-time attribution paired with
68
+ * `sourceType: 'channel'`. Ignored by `loadSession`: loading an existing
69
+ * session never re-stamps its creation attribution.
70
+ */
71
+ sourceId?: string;
65
72
  }
66
73
  export interface ChannelAgentBridge {
67
74
  readonly availableCommands: AvailableCommand[];
@@ -1,4 +1,4 @@
1
- import type { ChannelConfig, ChannelMemoryCallbacks, ChannelMemoryIntentClassifier, ChannelRuntimeIdentity, ChannelRuntimeMemoryScope, ChannelTaskLifecycleEvent, Envelope, SessionTarget } from './types.js';
1
+ import type { ChannelConfig, ChannelMemoryCallbacks, ChannelMemoryIntentClassifier, ChannelRuntimeIdentity, ChannelRuntimeMemoryScope, ChannelTaskLifecycleEvent, Envelope, ObservedChannelContactObservation, SessionTarget } from './types.js';
2
2
  import { GroupGate } from './GroupGate.js';
3
3
  import { DmGate } from './DmGate.js';
4
4
  import { SenderGate } from './SenderGate.js';
@@ -27,6 +27,9 @@ export interface ChannelBaseOptions {
27
27
  registerBridgeEvents?: boolean;
28
28
  groupHistoryPath?: string;
29
29
  loopController?: ChannelLoopController;
30
+ observedContacts?: {
31
+ observe(channelName: string, observation: ObservedChannelContactObservation): void | Promise<void>;
32
+ };
30
33
  }
31
34
  export interface ChannelLoopController {
32
35
  create(input: ChannelLoopInput): Promise<ChannelLoop>;
@@ -59,7 +62,11 @@ export declare abstract class ChannelBase {
59
62
  private readonly memoryIntentClassifier?;
60
63
  private groupHistory;
61
64
  private readonly loopController?;
65
+ private readonly observedContacts?;
66
+ private readonly observedContactEnvelopes;
62
67
  private instructedSessions;
68
+ private unattendedMemorySessions;
69
+ private channelMemoryReads;
63
70
  private commands;
64
71
  /** Per-session promise chain to serialize prompt + send (followup mode). */
65
72
  private sessionQueues;
@@ -70,7 +77,8 @@ export declare abstract class ChannelBase {
70
77
  * so a cleared session can't be resurrected by an already-queued prompt.
71
78
  */
72
79
  private sessionGenerations;
73
- private pendingClears;
80
+ private pendingChannelMemoryMutations;
81
+ private pendingChannelMemoryMutationDeliveries;
74
82
  /** Per-session active prompt tracking for dispatch modes. */
75
83
  private activePrompts;
76
84
  /** Per-session message buffer for collect mode. */
@@ -113,7 +121,10 @@ export declare abstract class ChannelBase {
113
121
  protected supportsProactiveTarget(target: SessionTarget): boolean;
114
122
  protected supportsProactiveWebhookTarget(target: SessionTarget): boolean;
115
123
  protected pushProactive(target: SessionTarget, text: string): Promise<void>;
116
- private prependUnattendedSessionContext;
124
+ private prepareUnattendedSessionContext;
125
+ private channelMemoryReadKey;
126
+ private beginChannelMemoryRead;
127
+ private releaseChannelMemoryRead;
117
128
  private drainCollectBufferForCurrentPrompt;
118
129
  /** Replace the bridge instance (used after crash recovery restart). */
119
130
  setBridge(bridge: ChannelAgentBridge): void;
@@ -209,8 +220,9 @@ export declare abstract class ChannelBase {
209
220
  private findActiveSessionId;
210
221
  private channelMemoryTarget;
211
222
  private formatChannelMemoryContext;
223
+ private formatRelevantChannelMemoryContext;
212
224
  private shouldInjectChannelMemory;
213
- private invalidateSessionContext;
225
+ private invalidateUnattendedMemory;
214
226
  private dropQueuedTurnIfStale;
215
227
  private getChannelMemory;
216
228
  private entriesForChannelMemoryIds;
@@ -218,8 +230,10 @@ export declare abstract class ChannelBase {
218
230
  private renderChannelMemoryCandidates;
219
231
  private handleChannelMemoryIntent;
220
232
  private shouldClassifyChannelMemoryIntent;
221
- private clearPendingKey;
222
- private setPendingClear;
233
+ private channelMemoryPendingKey;
234
+ private deliverPendingChannelMemoryMutation;
235
+ private takePendingChannelMemoryMutation;
236
+ private deletePendingChannelMemoryMutation;
223
237
  private classifyChannelMemoryIntent;
224
238
  private channelMemoryErrorMessage;
225
239
  private channelMemoryUserErrorMessage;
@@ -316,6 +330,7 @@ export declare abstract class ChannelBase {
316
330
  protected logPreflightRejected(reason: string): void;
317
331
  protected logDebugPayload(platform: string, payload: unknown): void;
318
332
  handleInbound(envelope: Envelope): Promise<void>;
333
+ private recordObservedContact;
319
334
  protected markPreflighted(envelope: Envelope): void;
320
335
  /**
321
336
  * Process an inbound message after preflight gates have passed.