zcode-acp-server 0.1.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/LICENSE +201 -0
- package/README.md +167 -0
- package/README.zh-CN.md +163 -0
- package/dist/backend/client.d.ts +103 -0
- package/dist/backend/client.d.ts.map +1 -0
- package/dist/backend/client.js +344 -0
- package/dist/backend/client.js.map +1 -0
- package/dist/backend/credentials.d.ts +31 -0
- package/dist/backend/credentials.d.ts.map +1 -0
- package/dist/backend/credentials.js +93 -0
- package/dist/backend/credentials.js.map +1 -0
- package/dist/backend/index.d.ts +7 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +6 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/listener.d.ts +63 -0
- package/dist/backend/listener.d.ts.map +1 -0
- package/dist/backend/listener.js +138 -0
- package/dist/backend/listener.js.map +1 -0
- package/dist/backend/resolve.d.ts +11 -0
- package/dist/backend/resolve.d.ts.map +1 -0
- package/dist/backend/resolve.js +116 -0
- package/dist/backend/resolve.js.map +1 -0
- package/dist/backend/types.d.ts +164 -0
- package/dist/backend/types.d.ts.map +1 -0
- package/dist/backend/types.js +15 -0
- package/dist/backend/types.js.map +1 -0
- package/dist/config/model-cache.d.ts +20 -0
- package/dist/config/model-cache.d.ts.map +1 -0
- package/dist/config/model-cache.js +62 -0
- package/dist/config/model-cache.js.map +1 -0
- package/dist/config/options.d.ts +36 -0
- package/dist/config/options.d.ts.map +1 -0
- package/dist/config/options.js +171 -0
- package/dist/config/options.js.map +1 -0
- package/dist/config/runtime-model.d.ts +33 -0
- package/dist/config/runtime-model.d.ts.map +1 -0
- package/dist/config/runtime-model.js +96 -0
- package/dist/config/runtime-model.js.map +1 -0
- package/dist/handlers/dispatch.d.ts +15 -0
- package/dist/handlers/dispatch.d.ts.map +1 -0
- package/dist/handlers/dispatch.js +183 -0
- package/dist/handlers/dispatch.js.map +1 -0
- package/dist/handlers/extensions.d.ts +43 -0
- package/dist/handlers/extensions.d.ts.map +1 -0
- package/dist/handlers/extensions.js +310 -0
- package/dist/handlers/extensions.js.map +1 -0
- package/dist/handlers/io.d.ts +40 -0
- package/dist/handlers/io.d.ts.map +1 -0
- package/dist/handlers/io.js +55 -0
- package/dist/handlers/io.js.map +1 -0
- package/dist/handlers/server-requests.d.ts +34 -0
- package/dist/handlers/server-requests.d.ts.map +1 -0
- package/dist/handlers/server-requests.js +357 -0
- package/dist/handlers/server-requests.js.map +1 -0
- package/dist/handlers/session.d.ts +46 -0
- package/dist/handlers/session.d.ts.map +1 -0
- package/dist/handlers/session.js +738 -0
- package/dist/handlers/session.js.map +1 -0
- package/dist/handlers/slash.d.ts +16 -0
- package/dist/handlers/slash.d.ts.map +1 -0
- package/dist/handlers/slash.js +107 -0
- package/dist/handlers/slash.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +93 -0
- package/dist/index.js.map +1 -0
- package/dist/interaction/adapter.d.ts +136 -0
- package/dist/interaction/adapter.d.ts.map +1 -0
- package/dist/interaction/adapter.js +353 -0
- package/dist/interaction/adapter.js.map +1 -0
- package/dist/server.d.ts +73 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +97 -0
- package/dist/server.js.map +1 -0
- package/dist/tasks-index.d.ts +39 -0
- package/dist/tasks-index.d.ts.map +1 -0
- package/dist/tasks-index.js +152 -0
- package/dist/tasks-index.js.map +1 -0
- package/dist/translators/event-translator.d.ts +40 -0
- package/dist/translators/event-translator.d.ts.map +1 -0
- package/dist/translators/event-translator.js +214 -0
- package/dist/translators/event-translator.js.map +1 -0
- package/dist/translators/index.d.ts +6 -0
- package/dist/translators/index.d.ts.map +1 -0
- package/dist/translators/index.js +5 -0
- package/dist/translators/index.js.map +1 -0
- package/dist/translators/projection-differ.d.ts +48 -0
- package/dist/translators/projection-differ.d.ts.map +1 -0
- package/dist/translators/projection-differ.js +239 -0
- package/dist/translators/projection-differ.js.map +1 -0
- package/dist/translators/tool-helpers.d.ts +60 -0
- package/dist/translators/tool-helpers.d.ts.map +1 -0
- package/dist/translators/tool-helpers.js +308 -0
- package/dist/translators/tool-helpers.js.map +1 -0
- package/dist/translators/types.d.ts +58 -0
- package/dist/translators/types.d.ts.map +1 -0
- package/dist/translators/types.js +27 -0
- package/dist/translators/types.js.map +1 -0
- package/dist/utils.d.ts +111 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +110 -0
- package/dist/utils.js.map +1 -0
- package/docs/ARCHITECTURE.md +299 -0
- package/docs/DEVELOPMENT.md +193 -0
- package/docs/PROTOCOL.md +649 -0
- package/docs/TROUBLESHOOTING.md +251 -0
- package/package.json +66 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handle zcode-initiated server→client requests during a turn.
|
|
3
|
+
*
|
|
4
|
+
* ZCode's interaction broker dispatches three request kinds, all bridged onto
|
|
5
|
+
* ACP `session/requestPermission` (Zed supports it natively; elicitation is
|
|
6
|
+
* not supported):
|
|
7
|
+
* - interaction/requestPermission (tool auth) → direct option mapping
|
|
8
|
+
* - interaction/requestUserInput (ExitPlanMode) → approve/reject options
|
|
9
|
+
* - interaction/requestUserInput (AskUserQuestion) → per-question popups
|
|
10
|
+
* (single-select: one popup; multi-select: per-option Include/Skip)
|
|
11
|
+
*
|
|
12
|
+
* Reannounce dedup: ZCode reannounces unanswered requests every ~1s sharing
|
|
13
|
+
* the same requestId/toolCallId. The first request forwards to the client;
|
|
14
|
+
* reannounces either get the cached result (if it arrived) or just record
|
|
15
|
+
* their zcode id for a later unified reply.
|
|
16
|
+
*/
|
|
17
|
+
import { acpPermissionResponseToExitPlanMode, acpPermissionResponseToZcode, buildAskUserAcpParams, buildAskUserElicitationForm, buildExitPlanModeElicitationForm, exitPlanModeToAcpPermission, isAskUserQuestion, isExitPlanMode, isPermissionRequest, parseAskUserElicitationResponse, parseAskUserResponse, parseExitPlanModeElicitationResponse, splitAskUserQuestions, zcodePermissionToAcp, } from "../interaction/adapter.js";
|
|
18
|
+
import { log, warn } from "../utils.js";
|
|
19
|
+
import { sendSessionUpdate } from "./io.js";
|
|
20
|
+
/** Per-server reannounce dedup state (lazy-initialised). */
|
|
21
|
+
export function getPendingInteractions(server) {
|
|
22
|
+
const existing = server
|
|
23
|
+
._pendingInteractions;
|
|
24
|
+
if (existing)
|
|
25
|
+
return existing;
|
|
26
|
+
const fresh = new Map();
|
|
27
|
+
server._pendingInteractions =
|
|
28
|
+
fresh;
|
|
29
|
+
return fresh;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Drain and handle all pending zcode server→client requests. Returns true if
|
|
33
|
+
* any were handled (used by the turn loop to refresh the no-progress timer).
|
|
34
|
+
*/
|
|
35
|
+
export async function handleServerRequests(server, backend, cx, acpSid, turn) {
|
|
36
|
+
const pending = getPendingInteractions(server);
|
|
37
|
+
let handled = false;
|
|
38
|
+
for (;;) {
|
|
39
|
+
const req = backend.pollServerRequests().shift() ?? null;
|
|
40
|
+
if (!req)
|
|
41
|
+
return handled;
|
|
42
|
+
handled = true;
|
|
43
|
+
await handleOne(server, backend, cx, acpSid, req, pending, turn);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async function handleOne(server, backend, cx, acpSid, req, pending, turn) {
|
|
47
|
+
const method = req.method;
|
|
48
|
+
const zcodeReqId = req.id;
|
|
49
|
+
const params = req.params;
|
|
50
|
+
const ask = isAskUserQuestion(method, params);
|
|
51
|
+
const perm = isPermissionRequest(method);
|
|
52
|
+
const epm = isExitPlanMode(params);
|
|
53
|
+
if (!perm && !(isUserInputRequestUnchecked(method) && (epm || ask))) {
|
|
54
|
+
warn(` ⚠ unhandled server→client request: ${method} (id=${zcodeReqId})`);
|
|
55
|
+
sendZcodeError(backend, zcodeReqId, `bridge unsupported: ${method}`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// Reannounce dedup.
|
|
59
|
+
const dedupKey = params.requestId ??
|
|
60
|
+
params.toolCallId ??
|
|
61
|
+
null;
|
|
62
|
+
if (dedupKey && pending.has(dedupKey)) {
|
|
63
|
+
const entry = pending.get(dedupKey);
|
|
64
|
+
if (entry.result !== undefined) {
|
|
65
|
+
// Result already cached (client responded earlier): reply directly with
|
|
66
|
+
// {id, result} so zcode resolves the reannounced request. Must NOT use
|
|
67
|
+
// notify() (that writes {method, params}, not a valid response).
|
|
68
|
+
backend.sendReply(zcodeReqId, entry.result);
|
|
69
|
+
log(` ⟳ reannounce, returning cached result (zcode_id=${zcodeReqId})`);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
entry.zcodeIds.push(zcodeReqId);
|
|
73
|
+
log(` ⟳ reannounce, recording zcode_id=${zcodeReqId} (no re-prompt)`);
|
|
74
|
+
}
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (dedupKey)
|
|
78
|
+
pending.set(dedupKey, { zcodeIds: [zcodeReqId] });
|
|
79
|
+
let zcodeResp;
|
|
80
|
+
if (ask) {
|
|
81
|
+
zcodeResp = await handleAskUserQuestion(server, cx, acpSid, params, turn);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
zcodeResp = await handleSinglePermission(server, cx, acpSid, params, epm, perm, turn);
|
|
85
|
+
}
|
|
86
|
+
// Reply to the first zcode id + all reannounced ones, and cache for late reannounces.
|
|
87
|
+
sendInteractionReply(backend, pending, dedupKey, zcodeReqId, zcodeResp);
|
|
88
|
+
}
|
|
89
|
+
/** Single requestPermission (tool auth / ExitPlanMode). */
|
|
90
|
+
async function handleSinglePermission(server, cx, acpSid, params, epm, perm, turn) {
|
|
91
|
+
const p = params;
|
|
92
|
+
// Emit a tool_call first so Zed renders the popup (it requires the toolCallId
|
|
93
|
+
// to have been emitted before request_permission).
|
|
94
|
+
const toolCallId = p.toolCallId ?? "";
|
|
95
|
+
const rawInput = p.input;
|
|
96
|
+
const tcTitle = epm
|
|
97
|
+
? "Ready to code?"
|
|
98
|
+
: perm
|
|
99
|
+
? `tool permission (${p.toolName ?? "?"})`
|
|
100
|
+
: "interaction";
|
|
101
|
+
const tcKind = epm ? "switch_mode" : "other";
|
|
102
|
+
const toolName = epm ? "ExitPlanMode" : (p.toolName ?? "");
|
|
103
|
+
const tcUpdate = {
|
|
104
|
+
sessionUpdate: "tool_call",
|
|
105
|
+
toolCallId,
|
|
106
|
+
title: tcTitle,
|
|
107
|
+
kind: tcKind,
|
|
108
|
+
status: "pending",
|
|
109
|
+
rawInput,
|
|
110
|
+
_meta: { claudeCode: { toolName } },
|
|
111
|
+
};
|
|
112
|
+
if (epm && rawInput && typeof rawInput === "object") {
|
|
113
|
+
const planText = rawInput.plan;
|
|
114
|
+
if (planText) {
|
|
115
|
+
tcUpdate.content = [{ type: "content", content: { type: "text", text: planText } }];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
await sendSessionUpdate(cx, acpSid, tcUpdate);
|
|
119
|
+
// ExitPlanMode: prefer elicitation form when the client supports it.
|
|
120
|
+
if (epm && server.supportsElicitationForm()) {
|
|
121
|
+
const formParams = buildExitPlanModeElicitationForm(p, acpSid, toolCallId || undefined);
|
|
122
|
+
log(` ⟳ ExitPlanMode forwarding elicitation/create (form)`);
|
|
123
|
+
const elicResp = await requestWithTimeout(cx, "elicitation/create", formParams, "elicitation/create", undefined, turn);
|
|
124
|
+
if (elicResp === null) {
|
|
125
|
+
return { action: "decline", reason: "elicitation failed" };
|
|
126
|
+
}
|
|
127
|
+
return parseExitPlanModeElicitationResponse(elicResp);
|
|
128
|
+
}
|
|
129
|
+
// Tool auth, or ExitPlanMode without elicitation: use request_permission.
|
|
130
|
+
const acpParams = perm
|
|
131
|
+
? zcodePermissionToAcp(p, acpSid)
|
|
132
|
+
: exitPlanModeToAcpPermission(p, acpSid);
|
|
133
|
+
const acpReqId = server.nextId();
|
|
134
|
+
log(` ⟳ ${toolName || "permission"}, forwarding session/request_permission (acp_id=${acpReqId})`);
|
|
135
|
+
const acpResp = await requestWithTimeout(cx, "session/request_permission", acpParams, "request_permission", undefined, turn);
|
|
136
|
+
if (acpResp === null) {
|
|
137
|
+
return { action: "decline", reason: "timeout or cancelled" };
|
|
138
|
+
}
|
|
139
|
+
return perm
|
|
140
|
+
? acpPermissionResponseToZcode(acpResp)
|
|
141
|
+
: acpPermissionResponseToExitPlanMode(acpResp);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* AskUserQuestion: sequential per-question, multi-select per-option.
|
|
145
|
+
*
|
|
146
|
+
* Single-select: one popup per question; Skip/cancel/timeout → overall decline.
|
|
147
|
+
* Multi-select: one Include/Skip popup per option; Include picks comma-joined.
|
|
148
|
+
*/
|
|
149
|
+
async function handleAskUserQuestion(server, cx, acpSid, params, turn) {
|
|
150
|
+
const qs = splitAskUserQuestions(params);
|
|
151
|
+
if (qs === null) {
|
|
152
|
+
warn(" ⚠ AskUserQuestion: no valid questions, declining");
|
|
153
|
+
return { action: "decline", reason: "no valid questions" };
|
|
154
|
+
}
|
|
155
|
+
const toolCallId = params.toolCallId ?? "";
|
|
156
|
+
const rawInput = params.input;
|
|
157
|
+
// Preferred path: form-based elicitation renders all questions in one form.
|
|
158
|
+
if (server.supportsElicitationForm()) {
|
|
159
|
+
return handleAskUserViaElicitation(server, cx, acpSid, params, toolCallId, rawInput, turn);
|
|
160
|
+
}
|
|
161
|
+
// Fallback path: per-question request_permission popups.
|
|
162
|
+
const answers = {};
|
|
163
|
+
for (let idx = 0; idx < qs.length; idx++) {
|
|
164
|
+
const q = qs[idx];
|
|
165
|
+
if (!q.multiSelect) {
|
|
166
|
+
// Single-select: one popup.
|
|
167
|
+
await emitAskToolCall(cx, acpSid, toolCallId, idx, q.question, rawInput);
|
|
168
|
+
const acpParams = buildAskUserAcpParams(params, acpSid, q.options);
|
|
169
|
+
acpParams.toolCall.toolCallId = `${toolCallId}_${idx}`;
|
|
170
|
+
const resp = await askOnce(server, cx, acpParams, idx + 1, qs.length, q.question, turn);
|
|
171
|
+
const selected = parseAskUserResponse(resp);
|
|
172
|
+
if (selected === null) {
|
|
173
|
+
warn(` ⚠ AskUserQuestion [${idx + 1}] skip/cancel/timeout, declining`);
|
|
174
|
+
return { action: "decline", reason: "skipped or cancelled" };
|
|
175
|
+
}
|
|
176
|
+
answers[q.question] = selected;
|
|
177
|
+
log(` ✓ AskUserQuestion [${idx + 1}] answer: ${selected}`);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
// Multi-select: per-option yes/no. options is [opt0_yes, opt0_no, opt1_yes, opt1_no, ...].
|
|
181
|
+
const pairs = [];
|
|
182
|
+
for (let i = 0; i < q.options.length; i += 2) {
|
|
183
|
+
const yesOpt = q.options[i];
|
|
184
|
+
const noOpt = q.options[i + 1];
|
|
185
|
+
if (!yesOpt || !noOpt)
|
|
186
|
+
continue;
|
|
187
|
+
pairs.push({ label: yesOpt.optionId.replace(/:yes$/, ""), pair: [yesOpt, noOpt] });
|
|
188
|
+
}
|
|
189
|
+
const picked = [];
|
|
190
|
+
for (let sub = 0; sub < pairs.length; sub++) {
|
|
191
|
+
const { label, pair } = pairs[sub];
|
|
192
|
+
const promptText = `${q.question}\n— include "${label}"?`;
|
|
193
|
+
await emitAskToolCall(cx, acpSid, toolCallId, `${idx}_${sub}`, promptText, rawInput);
|
|
194
|
+
const acpParams = buildAskUserAcpParams(params, acpSid, pair);
|
|
195
|
+
acpParams.toolCall.toolCallId = `${toolCallId}_${idx}_${sub}`;
|
|
196
|
+
const resp = await askOnce(server, cx, acpParams, idx + 1, qs.length, label, turn);
|
|
197
|
+
if (parseAskUserResponse(resp) === "yes") {
|
|
198
|
+
picked.push(label);
|
|
199
|
+
log(` ✓ AskUserQuestion [${idx + 1}] multi picked: ${label}`);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
log(` · AskUserQuestion [${idx + 1}] multi skipped: ${label}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
answers[q.question] = picked.join(", ");
|
|
206
|
+
log(` ✓ AskUserQuestion [${idx + 1}] multi answer: ${answers[q.question] || "(none)"}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
log(` ✓ AskUserQuestion all answered (${Object.keys(answers).length}), replying`);
|
|
210
|
+
return { action: "accept", content: { answers } };
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* AskUserQuestion via elicitation form — one form for all questions.
|
|
214
|
+
*
|
|
215
|
+
* When the client supports form-based elicitation, render a single form with
|
|
216
|
+
* one field per question instead of N sequential popups. Falls back to
|
|
217
|
+
* `decline` on any failure so the caller can degrade gracefully.
|
|
218
|
+
*/
|
|
219
|
+
async function handleAskUserViaElicitation(_server, cx, acpSid, params, toolCallId, rawInput, turn) {
|
|
220
|
+
const toolName = "AskUserQuestion";
|
|
221
|
+
await sendSessionUpdate(cx, acpSid, {
|
|
222
|
+
sessionUpdate: "tool_call",
|
|
223
|
+
toolCallId,
|
|
224
|
+
title: "questions",
|
|
225
|
+
kind: "other",
|
|
226
|
+
status: "pending",
|
|
227
|
+
rawInput,
|
|
228
|
+
_meta: { claudeCode: { toolName } },
|
|
229
|
+
});
|
|
230
|
+
const formParams = buildAskUserElicitationForm(params, acpSid, toolCallId || undefined);
|
|
231
|
+
log(` ⟳ AskUserQuestion forwarding elicitation/create (form, ${Object.keys(formParams.requestedSchema.properties).length} fields)`);
|
|
232
|
+
const acpResp = await requestWithTimeout(cx, "elicitation/create", formParams, "elicitation/create", undefined, turn);
|
|
233
|
+
if (acpResp === null) {
|
|
234
|
+
return { action: "decline", reason: "elicitation failed" };
|
|
235
|
+
}
|
|
236
|
+
const answers = parseAskUserElicitationResponse(acpResp, params);
|
|
237
|
+
if (answers === null) {
|
|
238
|
+
warn(" ⚠ AskUserQuestion elicitation declined/cancelled");
|
|
239
|
+
return { action: "decline", reason: "declined or cancelled" };
|
|
240
|
+
}
|
|
241
|
+
log(` ✓ AskUserQuestion elicitation answered (${Object.keys(answers).length})`);
|
|
242
|
+
return { action: "accept", content: { answers } };
|
|
243
|
+
}
|
|
244
|
+
/** Emit the prerequisite tool_call for an AskUserQuestion popup. */
|
|
245
|
+
async function emitAskToolCall(cx, acpSid, toolCallId, idxSuffix, qText, rawInput) {
|
|
246
|
+
await sendSessionUpdate(cx, acpSid, {
|
|
247
|
+
sessionUpdate: "tool_call",
|
|
248
|
+
toolCallId: `${toolCallId}_${idxSuffix}`,
|
|
249
|
+
title: qText,
|
|
250
|
+
kind: "other",
|
|
251
|
+
status: "pending",
|
|
252
|
+
rawInput,
|
|
253
|
+
_meta: { claudeCode: { toolName: "AskUserQuestion" } },
|
|
254
|
+
content: [{ type: "content", content: { type: "text", text: qText } }],
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
/** Send one requestPermission and await the response. */
|
|
258
|
+
async function askOnce(_server, cx, acpParams, _qNum, _qTotal, _label, turn) {
|
|
259
|
+
const acpReqId = _server.nextId();
|
|
260
|
+
log(` ⟳ AskUserQuestion forwarding session/request_permission (acp_id=${acpReqId})`);
|
|
261
|
+
return requestWithTimeout(cx, "session/request_permission", acpParams, "request_permission", undefined, turn);
|
|
262
|
+
}
|
|
263
|
+
// ---------- request helpers ----------
|
|
264
|
+
/**
|
|
265
|
+
* Interaction request timeout. Python's `_await_client_response` uses 600s and
|
|
266
|
+
* this matches it — long enough for slow models, retries, and user deliberation
|
|
267
|
+
* (well past the turn loop's 120s no-progress guard), while still bounding a
|
|
268
|
+
* dead client so it cannot pin a turn forever (the turn loop's
|
|
269
|
+
* `await handleServerRequests` would otherwise block indefinitely and the 120s
|
|
270
|
+
* no-progress timer could never re-check).
|
|
271
|
+
*/
|
|
272
|
+
const INTERACTION_TIMEOUT_MS = 600_000;
|
|
273
|
+
/**
|
|
274
|
+
* Send a client-side request with a timeout and turn-cancel awareness. Resolves
|
|
275
|
+
* to the client response, or `null` on timeout/error/cancel (callers treat null
|
|
276
|
+
* as decline). The underlying `cx.request` promise stays pending after a
|
|
277
|
+
* timeout/cancel (the SDK has no abort), but we no longer await it; it settles
|
|
278
|
+
* naturally when the client eventually responds or the connection closes.
|
|
279
|
+
*
|
|
280
|
+
* Turn cancel: while awaiting the client response we poll `turn.cancelled`
|
|
281
|
+
* every 100ms (mirrors Python `_await_client_response`, which drains + checks
|
|
282
|
+
* cancel every 0.1s). Without this, a user pressing stop during a permission
|
|
283
|
+
* popup would be ignored until the client responds or 600s elapses, because the
|
|
284
|
+
* turn loop's `await handleServerRequests` blocks here.
|
|
285
|
+
*/
|
|
286
|
+
async function requestWithTimeout(cx, method, params, label, timeoutMs = INTERACTION_TIMEOUT_MS, turn) {
|
|
287
|
+
let timer;
|
|
288
|
+
let cancelTimer;
|
|
289
|
+
const timeout = new Promise((resolve) => {
|
|
290
|
+
timer = setTimeout(() => {
|
|
291
|
+
warn(` ⚠ ${label} timed out after ${timeoutMs}ms`);
|
|
292
|
+
resolve(null);
|
|
293
|
+
}, timeoutMs);
|
|
294
|
+
});
|
|
295
|
+
const racers = [
|
|
296
|
+
cx.request(method, params).catch((e) => {
|
|
297
|
+
warn(` ⚠ ${label} failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
298
|
+
return null;
|
|
299
|
+
}),
|
|
300
|
+
timeout,
|
|
301
|
+
];
|
|
302
|
+
// Race a cancel poll so the user can abort a pending popup. Resolves null on
|
|
303
|
+
// cancel; callers already treat null as decline. Only added when a turn is
|
|
304
|
+
// available (turn-less callers, e.g. tests, skip cancel awareness).
|
|
305
|
+
if (turn) {
|
|
306
|
+
racers.push(new Promise((resolve) => {
|
|
307
|
+
cancelTimer = setInterval(() => {
|
|
308
|
+
if (turn.cancelled) {
|
|
309
|
+
warn(` ⚠ ${label} aborted (turn cancelled)`);
|
|
310
|
+
resolve(null);
|
|
311
|
+
}
|
|
312
|
+
}, 100);
|
|
313
|
+
// unref so this polling interval cannot keep the event loop (and thus
|
|
314
|
+
// the process) alive while awaiting a client response (up to 600s).
|
|
315
|
+
cancelTimer.unref?.();
|
|
316
|
+
}));
|
|
317
|
+
}
|
|
318
|
+
try {
|
|
319
|
+
return await Promise.race(racers);
|
|
320
|
+
}
|
|
321
|
+
finally {
|
|
322
|
+
if (timer)
|
|
323
|
+
clearTimeout(timer);
|
|
324
|
+
if (cancelTimer)
|
|
325
|
+
clearInterval(cancelTimer);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// ---------- reply helpers ----------
|
|
329
|
+
/** Reply to the first zcode id + all reannounced ones, cache for late reannounces. */
|
|
330
|
+
function sendInteractionReply(backend, pending, dedupKey, firstZcodeId, result) {
|
|
331
|
+
const ids = dedupKey && pending.has(dedupKey) ? pending.get(dedupKey).zcodeIds : [firstZcodeId];
|
|
332
|
+
if (dedupKey && pending.has(dedupKey)) {
|
|
333
|
+
pending.get(dedupKey).result = result;
|
|
334
|
+
}
|
|
335
|
+
for (const id of ids) {
|
|
336
|
+
sendZcodeReply(backend, id, result);
|
|
337
|
+
}
|
|
338
|
+
log(` ✓ replied to zcode (${ids.length} request(s))`);
|
|
339
|
+
// Schedule cleanup so late reannounces (after the result) still hit the cache briefly.
|
|
340
|
+
if (dedupKey) {
|
|
341
|
+
setTimeout(() => pending.delete(dedupKey), 30_000).unref();
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/** Send a zcode response (result) for a server→client request id. */
|
|
345
|
+
function sendZcodeReply(backend, zcodeId, result) {
|
|
346
|
+
// zcode expects {id, result} — but our backend.notify sends {method, params}. Use a raw write.
|
|
347
|
+
// The backend's notify is for notifications; replies need the id. We route via a private seam.
|
|
348
|
+
backend.sendReply(zcodeId, result);
|
|
349
|
+
}
|
|
350
|
+
/** Send a zcode error response. */
|
|
351
|
+
function sendZcodeError(backend, zcodeId, message) {
|
|
352
|
+
backend.sendError(zcodeId, -32601, message);
|
|
353
|
+
}
|
|
354
|
+
function isUserInputRequestUnchecked(method) {
|
|
355
|
+
return method === "interaction/requestUserInput";
|
|
356
|
+
}
|
|
357
|
+
//# sourceMappingURL=server-requests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-requests.js","sourceRoot":"","sources":["../../src/handlers/server-requests.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session lifecycle handlers: initialize, new, list, resume, load, prompt, cancel.
|
|
3
|
+
*
|
|
4
|
+
* These map ACP session methods to ZCode app-server calls. `session/prompt` runs
|
|
5
|
+
* the event-driven turn loop (subscribe-before-send ordering, no-progress
|
|
6
|
+
* timeout, stall reconciliation). ZCode events are translated via
|
|
7
|
+
* EventTranslator and dispatched as ACP `session/update` notifications.
|
|
8
|
+
*/
|
|
9
|
+
import type * as acp from "@agentclientprotocol/sdk";
|
|
10
|
+
import type { ZcodeAcpServer } from "../server.js";
|
|
11
|
+
/** `session/new` → zcode `session/create` (mode hardcoded yolo). */
|
|
12
|
+
export declare function newSession(server: ZcodeAcpServer, params: acp.NewSessionRequest): Promise<acp.NewSessionResponse>;
|
|
13
|
+
/** `session/list` → zcode `session/list`. */
|
|
14
|
+
export declare function listSessions(server: ZcodeAcpServer, params: acp.ListSessionsRequest): Promise<acp.ListSessionsResponse>;
|
|
15
|
+
/** `session/resume` → zcode `session/resume` (with runtimeModel overlay for resumed sessions). */
|
|
16
|
+
export declare function resumeSession(server: ZcodeAcpServer, params: acp.ResumeSessionRequest, cx: acp.AgentContext): Promise<acp.ResumeSessionResponse>;
|
|
17
|
+
/**
|
|
18
|
+
* `session/load` → zcode `session/resume` + stream conversation history back as
|
|
19
|
+
* `session/update` notifications (text/reasoning/简化 tool_call).
|
|
20
|
+
*/
|
|
21
|
+
export declare function loadSession(server: ZcodeAcpServer, params: acp.LoadSessionRequest, cx: acp.AgentContext): Promise<acp.LoadSessionResponse>;
|
|
22
|
+
/** `session/prompt` → subscribe-before-send, run the event-driven turn loop. */
|
|
23
|
+
export declare function prompt(server: ZcodeAcpServer, params: acp.PromptRequest, cx: acp.AgentContext, requestId: number): Promise<acp.PromptResponse>;
|
|
24
|
+
/**
|
|
25
|
+
* `session/set_config_option` → dispatch model/mode/thought and emit the
|
|
26
|
+
* resulting config_option_update (+ current_mode_update for mode).
|
|
27
|
+
*/
|
|
28
|
+
export declare function setConfigOptionHandler(server: ZcodeAcpServer, params: acp.SetSessionConfigOptionRequest, cx: acp.AgentContext): Promise<acp.SetSessionConfigOptionResponse>;
|
|
29
|
+
/**
|
|
30
|
+
* `session/cancel` → mark the pending turn cancelled. The turn loop observes
|
|
31
|
+
* the flag and forwards `session/stop` itself (mirrors Python: cancel only
|
|
32
|
+
* sets the flag; stop is sent by `_run_event_turn`). Eagerly sending stop
|
|
33
|
+
* here would race with a turn that already completed.
|
|
34
|
+
*/
|
|
35
|
+
export declare function cancel(server: ZcodeAcpServer, params: acp.CancelNotification): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Flatten the todos payload from `session/read`. Prefers the top-level `todos`;
|
|
38
|
+
* when empty, flattens `todoGroups` — the real backend dump carries todos as a
|
|
39
|
+
* list of groups (each with `entries` or `todos`), not a single object. Mirrors
|
|
40
|
+
* Python `_build_snapshot`. Exported for unit testing.
|
|
41
|
+
*/
|
|
42
|
+
export declare function flattenTodos(todos: unknown[] | undefined, todoGroups: Array<{
|
|
43
|
+
entries?: unknown[];
|
|
44
|
+
todos?: unknown[];
|
|
45
|
+
}> | undefined): unknown[];
|
|
46
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/handlers/session.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,KAAK,GAAG,MAAM,0BAA0B,CAAC;AAuBrD,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,cAAc,CAAC;AAiBhE,oEAAoE;AACpE,wBAAsB,UAAU,CAC9B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,GAAG,CAAC,iBAAiB,GAC5B,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAuCjC;AAED,6CAA6C;AAC7C,wBAAsB,YAAY,CAChC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,GAAG,CAAC,mBAAmB,GAC9B,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAmBnC;AAED,kGAAkG;AAClG,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,GAAG,CAAC,oBAAoB,EAChC,EAAE,EAAE,GAAG,CAAC,YAAY,GACnB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CA6BpC;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,GAAG,CAAC,kBAAkB,EAC9B,EAAE,EAAE,GAAG,CAAC,YAAY,GACnB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CA+FlC;AAED,gFAAgF;AAChF,wBAAsB,MAAM,CAC1B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,GAAG,CAAC,aAAa,EACzB,EAAE,EAAE,GAAG,CAAC,YAAY,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAgG7B;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,GAAG,CAAC,6BAA6B,EACzC,EAAE,EAAE,GAAG,CAAC,YAAY,GACnB,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAa7C;AAED;;;;;GAKG;AACH,wBAAsB,MAAM,CAC1B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,GAAG,CAAC,kBAAkB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAUf;AA0WD;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,OAAO,EAAE,GAAG,SAAS,EAC5B,UAAU,EAAE,KAAK,CAAC;IAAE,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,GAAG,SAAS,GACxE,OAAO,EAAE,CASX"}
|