copilotoffice 2.2.0 → 2.3.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.
@@ -31,7 +31,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var events_watcher_exports = {};
32
32
  __export(events_watcher_exports, {
33
33
  EventsWatcher: () => EventsWatcher,
34
- formatToolStatus: () => formatToolStatus
34
+ buildAskUserRelay: () => buildAskUserRelay,
35
+ formatToolStatus: () => formatToolStatus,
36
+ normalizeAskUserArgs: () => normalizeAskUserArgs
35
37
  });
36
38
  module.exports = __toCommonJS(events_watcher_exports);
37
39
  var fs = __toESM(require("fs"));
@@ -223,8 +225,57 @@ function formatToolStatus(toolName, args) {
223
225
  return `Using ${toolName}`;
224
226
  }
225
227
  }
228
+ function normalizeAskUserArgs(args) {
229
+ const a = args ?? {};
230
+ const questionRaw = a.question ?? a.prompt ?? a.message ?? a.text ?? "";
231
+ const question = typeof questionRaw === "string" ? questionRaw : String(questionRaw ?? "");
232
+ const rawOptions = a.options ?? a.choices ?? a.answers ?? a.selections ?? [];
233
+ const options = [];
234
+ if (Array.isArray(rawOptions)) {
235
+ for (const opt of rawOptions) {
236
+ if (typeof opt === "string") {
237
+ options.push({ text: opt });
238
+ } else if (opt && typeof opt === "object") {
239
+ const o = opt;
240
+ const text = o.text ?? o.label ?? o.value ?? o.name ?? "";
241
+ options.push({ text: typeof text === "string" ? text : String(text ?? "") });
242
+ }
243
+ }
244
+ }
245
+ const freeformRaw = a.freeform ?? a.allowFreeform ?? a.allowFreeText ?? a.allowCustom ?? a.freeText ?? false;
246
+ const freeform = Boolean(freeformRaw);
247
+ return { question, options, freeform };
248
+ }
249
+ function buildAskUserRelay(event, backendName) {
250
+ const d = event.data ?? {};
251
+ if (event.type === "user_input.requested") {
252
+ const options = Array.isArray(d.choices) ? d.choices.map((c) => ({
253
+ text: typeof c === "string" ? c : String(c?.text ?? c?.label ?? c?.value ?? "")
254
+ })) : [];
255
+ return {
256
+ toolId: String(d.toolCallId ?? ""),
257
+ requestId: String(d.requestId ?? ""),
258
+ question: String(d.question ?? ""),
259
+ options,
260
+ freeform: Boolean(d.allowFreeform)
261
+ };
262
+ }
263
+ if (event.type === "tool.execution_start" && d.toolName === "ask_user" && backendName === "node-pty") {
264
+ const norm = normalizeAskUserArgs(d.arguments);
265
+ return {
266
+ toolId: String(d.toolCallId ?? ""),
267
+ requestId: "",
268
+ question: norm.question,
269
+ options: norm.options,
270
+ freeform: norm.freeform
271
+ };
272
+ }
273
+ return null;
274
+ }
226
275
  // Annotate the CommonJS export names for ESM import in node:
227
276
  0 && (module.exports = {
228
277
  EventsWatcher,
229
- formatToolStatus
278
+ buildAskUserRelay,
279
+ formatToolStatus,
280
+ normalizeAskUserArgs
230
281
  });
@@ -156,7 +156,9 @@ var TerminalRelay = class _TerminalRelay {
156
156
  * server→main copilot/terminal events without going through the renderer.
157
157
  * Emits: 'copilot-event' (agentId, event), 'copilot-turn-start' (agentId),
158
158
  * 'copilot-turn-end' (agentId), 'copilot-tool-start' (agentId, toolName, toolId, status),
159
+ * 'copilot-ask-user' (agentId, toolId, requestId, question, options, freeform),
159
160
  * 'session-meta-updated' (agentId, meta), 'terminal-exit' (agentId, exitCode).
161
+ * Accepts (via mainSubmitAnswer): 'submit-answer' (officeId, agentId, requestId?, answer, wasFreeform).
160
162
  */
161
163
  this.mainEvents = new import_events.EventEmitter();
162
164
  this.server = null;
@@ -317,6 +319,22 @@ var TerminalRelay = class _TerminalRelay {
317
319
  mainSubmitPrompt(officeId, agentId, prompt, label) {
318
320
  return this.request({ type: "submit-prompt", requestId: this.id(), officeId, agentId, prompt, label });
319
321
  }
322
+ /**
323
+ * spec 015: answer a pending `ask_user` interaction. Distinct from
324
+ * mainSubmitPrompt — resolves the pending user-input interaction (SDK/ui-server)
325
+ * or injects keystrokes (node-pty). `requestId` is the single-resolution key.
326
+ */
327
+ mainSubmitAnswer(officeId, agentId, a) {
328
+ return this.request({
329
+ type: "submit-answer",
330
+ requestId: this.id(),
331
+ officeId,
332
+ agentId,
333
+ answerRequestId: a.requestId,
334
+ answer: a.answer,
335
+ wasFreeform: a.wasFreeform
336
+ });
337
+ }
320
338
  /** Fire-and-forget: control whether copilot-events are mirrored to main for an agent without a viewer. */
321
339
  mainSetAgentForwarding(officeId, agentId, enabled) {
322
340
  this.send({ type: "set-agent-forwarding", officeId, agentId, enabled });
@@ -370,6 +388,12 @@ var TerminalRelay = class _TerminalRelay {
370
388
  case "copilot-tool-start":
371
389
  this.mainEvents.emit("copilot-tool-start", msg.agentId, msg.toolName, msg.toolId, msg.status);
372
390
  break;
391
+ case "copilot-ask-user":
392
+ this.mainEvents.emit("copilot-ask-user", msg.agentId, msg.toolId, msg.requestId, msg.question, msg.options, msg.freeform);
393
+ break;
394
+ case "copilot-ask-user-complete":
395
+ this.mainEvents.emit("copilot-ask-user-complete", msg.agentId, msg.requestId);
396
+ break;
373
397
  case "session-meta-updated":
374
398
  this.mainEvents.emit("session-meta-updated", msg.agentId, msg.meta);
375
399
  break;
@@ -392,6 +416,12 @@ var TerminalRelay = class _TerminalRelay {
392
416
  case "copilot-tool-start":
393
417
  win.webContents.send("copilot-tool-start", msg.agentId, msg.toolName, msg.toolId, msg.status);
394
418
  break;
419
+ case "copilot-ask-user":
420
+ win.webContents.send("copilot-ask-user", msg.agentId, msg.toolId, msg.requestId, msg.question, msg.options, msg.freeform);
421
+ break;
422
+ case "copilot-ask-user-complete":
423
+ win.webContents.send("copilot-ask-user-complete", msg.agentId, msg.requestId);
424
+ break;
395
425
  case "copilot-tool-complete":
396
426
  win.webContents.send("copilot-tool-complete", msg.agentId, msg.toolId, msg.success);
397
427
  break;
@@ -136,6 +136,12 @@ import_electron.contextBridge.exposeInMainWorld("copilotBridge", {
136
136
  import_electron.ipcRenderer.on("copilot-tool-start", handler);
137
137
  return () => import_electron.ipcRenderer.removeListener("copilot-tool-start", handler);
138
138
  },
139
+ // spec 015: additive ask_user relay (renderer parity — no Phaser consumer required).
140
+ onCopilotAskUser: (callback) => {
141
+ const handler = (_event, agentId, toolId, requestId, question, options, freeform) => callback(agentId, toolId, requestId, question, options, freeform);
142
+ import_electron.ipcRenderer.on("copilot-ask-user", handler);
143
+ return () => import_electron.ipcRenderer.removeListener("copilot-ask-user", handler);
144
+ },
139
145
  onCopilotToolComplete: (callback) => {
140
146
  const handler = (_event, agentId, toolId, success) => callback(agentId, toolId, success);
141
147
  import_electron.ipcRenderer.on("copilot-tool-complete", handler);
@@ -168,6 +174,7 @@ import_electron.contextBridge.exposeInMainWorld("copilotBridge", {
168
174
  removeCopilotListeners: () => {
169
175
  import_electron.ipcRenderer.removeAllListeners("copilot-event");
170
176
  import_electron.ipcRenderer.removeAllListeners("copilot-tool-start");
177
+ import_electron.ipcRenderer.removeAllListeners("copilot-ask-user");
171
178
  import_electron.ipcRenderer.removeAllListeners("copilot-tool-complete");
172
179
  import_electron.ipcRenderer.removeAllListeners("copilot-turn-end");
173
180
  import_electron.ipcRenderer.removeAllListeners("copilot-turn-start");