/** * @license * Copyright 2026 Qwen * SPDX-License-Identifier: Apache-2.0 */ import { type QwenPeerDiscoveryOptions, type PeerEndpointFactory } from './qwen-peer-discovery.js'; import type { BackendAdaptor, BackendCapabilities, BackendEvent, BackendHandle, CancelJobResult, ContentBlock, PermissionDecision, PromptReceipt, InstructionReceipt, InstructionDelivery, PeerSessionReport, PeerReportContext, SessionSummary } from './types.js'; /** * Structural subset of DaemonClient used by this adaptor. Unit tests inject * a fake; production passes a real DaemonClient (or omits it to have one * constructed from `baseUrl`/`token`). */ export interface DaemonClientLike { capabilities(): Promise<{ features?: readonly string[]; workspaceCwd?: string; }>; createOrAttachSession(req: Record, clientId?: string): Promise<{ sessionId: string; hasActivePrompt?: boolean; clientId?: string; }>; listWorkspaceSessions(workspaceCwd: string, options?: Record): Promise>>; promptNonBlocking(sessionId: string, req: Record, signal?: AbortSignal, clientId?: string): Promise>; subscribeEvents(sessionId: string, opts?: Record): AsyncGenerator<{ id?: number; v: 1; type: string; data: unknown; promptId?: string; originatorClientId?: string; }>; enqueueMidTurnMessage(sessionId: string, message: string, opts?: Record): Promise<{ accepted: boolean; messageId?: string; }>; cancel(sessionId: string, clientId?: string): Promise; removePendingPrompt(sessionId: string, promptId: string, opts?: { clientId?: string; }): Promise<{ removed: boolean; }>; respondToSessionPermission(sessionId: string, requestId: string, response: Record, clientId?: string): Promise; uploadSessionAttachment(sessionId: string, data: Blob, name: string, mimeType: string, opts?: Record): Promise>; updateSessionMetadata(sessionId: string, metadata: { displayName?: string; }, clientId?: string): Promise<{ displayName?: string; }>; } export interface QwenCodeAdaptorOptions { /** qwen serve base URL, e.g. `http://127.0.0.1:4170`. */ baseUrl: string; token?: string; managedServe?: { command: string; }; /** Default cwd for new sessions; falls back to the daemon's workspaceCwd. */ defaultCwd?: string; /** Stable client identity used for permission-vote attribution. */ clientId?: string; /** * Backend name (what the voice model sees in session_list). Defaults to * 'qwen-code'; a configured name lets two qwen-code backends coexist * without colliding in the registry's byName map or the scoped-id keys. */ name?: string; /** Injection seam for unit tests. */ client?: DaemonClientLike; peerDiscovery?: QwenPeerDiscoveryOptions; /** Test seam for the official peer endpoint. */ peerEndpointFactory?: PeerEndpointFactory; } export declare class QwenCodeAdaptor implements BackendAdaptor { readonly name: string; private client; private readonly managedServe?; private endpoint; private closed; private readonly options; private readonly sessions; /** Every cwd sessions were created in; listSessions unions across them. */ private readonly sessionCwds; private workspaceCwd; private readonly peers?; readonly listDiscoveredSessions?: () => Promise; readonly sendInstruction?: (handle: BackendHandle, text: string) => Promise; readonly listInstructionDeliveries?: () => InstructionDelivery[]; readonly subscribeInstructionDeliveries?: (listener: () => void) => () => void; readonly createReportContext?: (target: BackendHandle) => PeerReportContext | undefined; readonly subscribeReports?: (listener: (report: PeerSessionReport) => boolean) => () => void; constructor(options: QwenCodeAdaptorOptions); capabilities(): BackendCapabilities; preflight(): Promise; private checkCapabilities; createSession(opts?: { cwd?: string; label?: string; }): Promise; startDiscovery(callId: string): Promise; stopDiscovery(callId: string): Promise; listSessions(): Promise; private listManagedSessions; prompt(handle: BackendHandle, blocks: readonly ContentBlock[], opts?: { steer?: boolean; }): Promise; events(handle: BackendHandle, opts?: { signal?: AbortSignal; }): AsyncIterable; isBusy(handle: BackendHandle): boolean; cancel(handle: BackendHandle): Promise; cancelJob(handle: BackendHandle, jobRef: string): Promise; respondPermission(handle: BackendHandle, requestId: string, decision: PermissionDecision): Promise<'delivered' | 'already_resolved'>; close(): Promise; private localSessionCwd; private isDiscoveryHandle; private trackSession; private buildPromptBlocks; private normalize; }