Skip to content

Commit 001e00e

Browse files
qinqi-aliqwencoder
andcommitted
fix(serve): ACP conformance — session/set_mode, sessionCapabilities, agentInfo
1. Add standard `session/set_mode` handler (Zed SDK calls setSessionMode(modeId), not set_config_option for modes) 2. Advertise `sessionCapabilities: { list: {}, resume: {} }` so Zed can discover session/list and session/resume support 3. Add `agentInfo: { name: "qwen-code", version: "0.17.0" }` for Zed display 4. Remove incorrect `configOptions: true` from agentCapabilities (config options are per-session in session/new response) Generated with AI Co-authored-by: Qwen-Coder <[email protected]>
1 parent 8f02791 commit 001e00e

1 file changed

Lines changed: 56 additions & 5 deletions

File tree

‎packages/cli/src/serve/acpHttp/dispatch.ts‎

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -398,18 +398,18 @@ export class AcpDispatcher {
398398
const negotiated = Math.max(1, Math.min(requested, ACP_PROTOCOL_VERSION));
399399
return {
400400
protocolVersion: negotiated,
401+
agentInfo: { name: 'qwen-code', version: '0.17.0' },
401402
agentCapabilities: {
402403
loadSession: true,
403-
// Mirror acpAgent.ts promptCapabilities: #resolvePrompt handles audio
404-
// blocks identically to image (both become inlineData Parts).
405404
promptCapabilities: {
406405
image: true,
407406
audio: true,
408407
embeddedContext: true,
409408
},
410-
// Model + mode are exposed via the STANDARD `session/set_config_option`
411-
// (categories `model`/`mode`); advertise that here.
412-
configOptions: true,
409+
sessionCapabilities: {
410+
list: {},
411+
resume: {},
412+
},
413413
// Vendor extensions are advertised under `_meta` keyed by domain
414414
// (ACP convention, e.g. `_meta: { "zed.dev": … }`). Clients
415415
// feature-detect before calling `_qwen/…` methods.
@@ -795,6 +795,57 @@ export class AcpDispatcher {
795795

796796
// STANDARD method (SDK 0.14.1, non-`unstable_`): model + mode live
797797
// here under categories `model`/`mode`, routed to the existing bridge
798+
// Standard ACP method: set session mode (approval mode).
799+
case 'session/set_mode': {
800+
const sessionId = String(params['sessionId'] ?? '');
801+
if (!this.requireOwned(conn, sessionId, id)) return;
802+
const modeId = params['modeId'];
803+
if (typeof modeId !== 'string') {
804+
if (id !== undefined) {
805+
this.replySession(
806+
conn,
807+
sessionId,
808+
id,
809+
undefined,
810+
error(
811+
id,
812+
RPC.INVALID_PARAMS,
813+
'`modeId` is required and must be a string',
814+
),
815+
);
816+
}
817+
return;
818+
}
819+
if (!APPROVAL_MODES.includes(modeId as ApprovalMode)) {
820+
if (id !== undefined) {
821+
this.replySession(
822+
conn,
823+
sessionId,
824+
id,
825+
undefined,
826+
error(
827+
id,
828+
RPC.INVALID_PARAMS,
829+
`invalid mode "${modeId}" (expected one of: ${APPROVAL_MODES.join(', ')})`,
830+
),
831+
);
832+
}
833+
return;
834+
}
835+
const ctx = this.sessionCtx(conn, sessionId, loopback);
836+
await this.bridge.setSessionApprovalMode(
837+
sessionId,
838+
modeId as ApprovalMode,
839+
{ persist: params['persist'] === true },
840+
ctx,
841+
);
842+
const opts = await this.configOptionsFor(sessionId);
843+
this.replySession(conn, sessionId, id, {
844+
configOptions: opts ?? [],
845+
});
846+
return;
847+
}
848+
798849
// setters. Replaces the old vendor `_qwen/session/set_model`.
799850
case 'session/set_config_option': {
800851
const sessionId = String(params['sessionId'] ?? '');

0 commit comments

Comments
 (0)