@borgee/agents-host 0.2.73 → 0.2.84

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.
Files changed (50) hide show
  1. package/README.md +17 -30
  2. package/dist/agents-host-supervisor.d.ts +1 -0
  3. package/dist/agents-host-supervisor.js +3 -1
  4. package/dist/agents-host.d.ts +6 -4
  5. package/dist/agents-host.js +117 -16
  6. package/dist/background-runs.d.ts +23 -0
  7. package/dist/background-runs.js +153 -0
  8. package/dist/chat/chat-control-plane.d.ts +6 -1
  9. package/dist/chat/sdk-chat-control-plane.d.ts +4 -2
  10. package/dist/chat/sdk-chat-control-plane.js +7 -0
  11. package/dist/context/claude-file-brief.js +3 -3
  12. package/dist/context/injection.d.ts +18 -12
  13. package/dist/context/injection.js +53 -53
  14. package/dist/context/prompt.js +10 -10
  15. package/dist/context/resolved-working-folder.d.ts +3 -0
  16. package/dist/context/resolved-working-folder.js +106 -0
  17. package/dist/context/turn-preparation.js +1 -1
  18. package/dist/local-config.d.ts +7 -0
  19. package/dist/local-config.js +158 -12
  20. package/dist/managed-daemon.js +42 -35
  21. package/dist/plugin-sdk.js +179 -9
  22. package/dist/plugin-sdk.js.map +3 -3
  23. package/dist/policy/authorization-audit.d.ts +1 -1
  24. package/dist/policy/copilot-permission.d.ts +9 -0
  25. package/dist/policy/copilot-permission.js +120 -1
  26. package/dist/progress-to-activity.d.ts +1 -1
  27. package/dist/progress-to-activity.js +1 -0
  28. package/dist/providers/claude/adapter.d.ts +1 -1
  29. package/dist/providers/claude/adapter.js +7 -0
  30. package/dist/providers/claude/cli-client.js +4 -3
  31. package/dist/providers/codex/adapter.d.ts +1 -1
  32. package/dist/providers/codex/adapter.js +7 -0
  33. package/dist/providers/codex/cli-client.js +8 -7
  34. package/dist/providers/codex/project-doc.js +6 -6
  35. package/dist/providers/copilot/adapter.d.ts +6 -2
  36. package/dist/providers/copilot/adapter.js +27 -1
  37. package/dist/providers/copilot/cli-client.d.ts +37 -10
  38. package/dist/providers/copilot/cli-client.js +751 -122
  39. package/dist/providers/copilot/sdk-session.d.ts +149 -0
  40. package/dist/providers/copilot/sdk-session.js +981 -0
  41. package/dist/providers/create-provider.js +33 -0
  42. package/dist/providers/provider-adapter.d.ts +16 -1
  43. package/dist/providers/provider-adapter.js +13 -0
  44. package/dist/types.d.ts +32 -11
  45. package/package.json +3 -2
  46. package/skills/borgee-agent/references/task-properties.md +3 -3
  47. package/skills/borgee-agent/scripts/borgee-agent.mjs +1 -1
  48. package/skills/borgee-agent/scripts/borgee-agent.py +1 -1
  49. package/dist/context/resolved-workspace.d.ts +0 -3
  50. package/dist/context/resolved-workspace.js +0 -106
@@ -3757,6 +3757,8 @@ var WS_CLOSE_AUTH_FAILED = 4004;
3757
3757
  var RESULT_STATUS_OK = "ok";
3758
3758
  var STOP_TURN_ACTION = "stop_turn";
3759
3759
  var STOP_TURN_CHANNEL_ID_INVALID = "stop_turn_channel_id_invalid";
3760
+ var STOP_BACKGROUND_RUN_ACTION = "stop_background_run";
3761
+ var STOP_BACKGROUND_RUN_TARGET_INVALID = "stop_background_run_target_invalid";
3760
3762
  var SERVER_REQUEST_FAILED = "server_request_failed";
3761
3763
  var BppTransport = class {
3762
3764
  performTimeoutMs;
@@ -3777,6 +3779,7 @@ var BppTransport = class {
3777
3779
  // send issued during a reconnect never races ahead of the handshake.
3778
3780
  online = false;
3779
3781
  terminal = false;
3782
+ stopBackgroundRunHandler;
3780
3783
  inboundChain = Promise.resolve();
3781
3784
  configChain = Promise.resolve();
3782
3785
  configAcks = /* @__PURE__ */ new Map();
@@ -3811,6 +3814,9 @@ var BppTransport = class {
3811
3814
  setStopTurnHandler(handler) {
3812
3815
  this.stopTurnHandler = handler;
3813
3816
  }
3817
+ setStopBackgroundRunHandler(handler) {
3818
+ this.stopBackgroundRunHandler = handler;
3819
+ }
3814
3820
  getResolvedAgentId() {
3815
3821
  return this.currentAgentId();
3816
3822
  }
@@ -3881,7 +3887,7 @@ var BppTransport = class {
3881
3887
  }
3882
3888
  }
3883
3889
  }
3884
- // ---- perform (上行) ----
3890
+ // ---- Outbound operations ----
3885
3891
  async perform(action, opts) {
3886
3892
  if (action.op === "report_task_started") {
3887
3893
  this.sendTaskStarted(action);
@@ -3927,7 +3933,7 @@ var BppTransport = class {
3927
3933
  this.send(frame);
3928
3934
  });
3929
3935
  }
3930
- // ---- socket 生命周期 ----
3936
+ // ---- Socket lifecycle ----
3931
3937
  // Transition the given socket to ONLINE. Bails if the socket is stale (a reconnect replaced it),
3932
3938
  // so a handshake completing on a prior socket cannot flip online across a reconnect.
3933
3939
  goOnline(source) {
@@ -4097,7 +4103,7 @@ var BppTransport = class {
4097
4103
  this.heartbeatTimer = void 0;
4098
4104
  }
4099
4105
  }
4100
- // ---- 下行分发 ----
4106
+ // ---- Inbound dispatch ----
4101
4107
  onMessage(raw, source) {
4102
4108
  if (source !== this.ws)
4103
4109
  return;
@@ -4286,6 +4292,10 @@ var BppTransport = class {
4286
4292
  await this.answerStopTurn(id, data);
4287
4293
  return;
4288
4294
  }
4295
+ if (action === STOP_BACKGROUND_RUN_ACTION) {
4296
+ await this.answerStopBackgroundRun(id, data);
4297
+ return;
4298
+ }
4289
4299
  if (!this.serverRequestHandler) {
4290
4300
  this.send({ type: "response", id, error: "no_server_request_handler" });
4291
4301
  return;
@@ -4336,7 +4346,38 @@ var BppTransport = class {
4336
4346
  }
4337
4347
  return { aborted };
4338
4348
  }
4339
- // ---- task 生命周期上行 ----
4349
+ async answerStopBackgroundRun(id, data) {
4350
+ const channelId = data.channel_id;
4351
+ const runId = data.run_id;
4352
+ if (typeof channelId !== "string" || channelId === "" || typeof runId !== "string" || runId === "") {
4353
+ this.send({ type: "response", id, error: STOP_BACKGROUND_RUN_TARGET_INVALID });
4354
+ return;
4355
+ }
4356
+ try {
4357
+ const answer = this.stopBackgroundRunHandler ? await this.stopBackgroundRunHandler(channelId, runId) : {
4358
+ outcome: "unsupported",
4359
+ reason: "Targeted background-run cancellation is not registered"
4360
+ };
4361
+ this.send({ type: "response", id, data: this.asStopBackgroundRunResult(answer) });
4362
+ } catch (err) {
4363
+ this.logger?.warn("bpp.stop_background_run_handler_failed", err);
4364
+ this.send({ type: "response", id, error: SERVER_REQUEST_FAILED });
4365
+ }
4366
+ }
4367
+ asStopBackgroundRunResult(answer) {
4368
+ const candidate = answer;
4369
+ if (!candidate || !["stopped", "not_found", "unsupported"].includes(candidate.outcome)) {
4370
+ return {
4371
+ outcome: "unsupported",
4372
+ reason: "Targeted background-run cancellation returned an unusable answer"
4373
+ };
4374
+ }
4375
+ return {
4376
+ outcome: candidate.outcome,
4377
+ ...typeof candidate.reason === "string" && candidate.reason !== "" ? { reason: candidate.reason } : {}
4378
+ };
4379
+ }
4380
+ // ---- Task lifecycle output ----
4340
4381
  sendTaskStarted(action) {
4341
4382
  const frame = {
4342
4383
  type: "task_started",
@@ -4384,7 +4425,13 @@ var BppTransport = class {
4384
4425
  reason: "",
4385
4426
  stream: "",
4386
4427
  text: "",
4387
- turn_state: ""
4428
+ turn_state: "",
4429
+ run_id: "",
4430
+ run_state: "",
4431
+ started_at: 0,
4432
+ finished_at: 0,
4433
+ stop_supported: false,
4434
+ stop_unsupported_reason: ""
4388
4435
  };
4389
4436
  switch (action.activity.shape) {
4390
4437
  case "activity":
@@ -4413,13 +4460,23 @@ var BppTransport = class {
4413
4460
  case "turn":
4414
4461
  frame.turn_state = action.activity.state;
4415
4462
  break;
4463
+ case "background_run":
4464
+ frame.run_id = action.activity.runId;
4465
+ frame.label = action.activity.label;
4466
+ frame.run_state = action.activity.state;
4467
+ frame.started_at = action.activity.startedAt;
4468
+ frame.finished_at = action.activity.finishedAt ?? 0;
4469
+ frame.reason = action.activity.reason ?? "";
4470
+ frame.stop_supported = action.activity.stopSupported;
4471
+ frame.stop_unsupported_reason = action.activity.stopUnsupportedReason ?? "";
4472
+ break;
4416
4473
  }
4417
4474
  this.send(frame);
4418
4475
  }
4419
4476
  sendTyping(action) {
4420
4477
  this.send({ type: "typing", channel_id: action.channelId });
4421
4478
  }
4422
- // ---- 低层发送 ----
4479
+ // ---- Low-level output ----
4423
4480
  send(frame) {
4424
4481
  if (!this.isOpen())
4425
4482
  return;
@@ -4519,7 +4576,8 @@ function encodeActionPayload(action) {
4519
4576
  return {
4520
4577
  channel_id: action.channelId,
4521
4578
  content: action.body,
4522
- reply_to_id: action.replyToId
4579
+ reply_to_id: action.replyToId,
4580
+ content_type: action.contentType
4523
4581
  };
4524
4582
  case "edit_message":
4525
4583
  return { message_id: action.messageId, content: action.body };
@@ -4614,7 +4672,7 @@ function decodeActionResult(op, payloadJSON) {
4614
4672
  case "delete_message":
4615
4673
  case "react":
4616
4674
  return void 0;
4617
- // 客户端方法返回 void
4675
+ // These client methods return void.
4618
4676
  case "read_channel_history": {
4619
4677
  const arr = Array.isArray(p) ? p : [];
4620
4678
  return arr.map((m) => ({
@@ -4954,7 +5012,8 @@ var Client = class {
4954
5012
  op: "send_message",
4955
5013
  channelId: input.channelId,
4956
5014
  body: input.body,
4957
- replyToId: input.replyToId
5015
+ replyToId: input.replyToId,
5016
+ contentType: input.contentType
4958
5017
  });
4959
5018
  }
4960
5019
  async editMessage(input) {
@@ -5141,6 +5200,9 @@ var Client = class {
5141
5200
  onStopTurn(handler) {
5142
5201
  this.t.setStopTurnHandler?.(handler);
5143
5202
  }
5203
+ onStopBackgroundRun(handler) {
5204
+ this.t.setStopBackgroundRunHandler?.(handler);
5205
+ }
5144
5206
  emit(event, payload) {
5145
5207
  for (const h of this.listeners[event]) {
5146
5208
  try {
@@ -5177,8 +5239,116 @@ var Client = class {
5177
5239
  function createBorgeePlugin(opts) {
5178
5240
  return new Client(opts, new BppTransport());
5179
5241
  }
5242
+
5243
+ // ../sdk/plugin-ts/dist/draft-message.js
5244
+ var THROTTLE_MS = 250;
5245
+ var DraftMessageController = class {
5246
+ client;
5247
+ channelId;
5248
+ replyToId;
5249
+ messageId = null;
5250
+ currentBody = "";
5251
+ pendingBody = null;
5252
+ timer = null;
5253
+ sealed = false;
5254
+ writeChain = Promise.resolve();
5255
+ constructor(client, channelId, replyToId) {
5256
+ this.client = client;
5257
+ this.channelId = channelId;
5258
+ this.replyToId = replyToId;
5259
+ }
5260
+ /**
5261
+ * Offer the whole body as it currently reads — not a delta. Nothing is written
5262
+ * for up to {@link THROTTLE_MS}, and only the last body offered in that window
5263
+ * is; blank text is ignored, which is why a producer that has not yet emitted
5264
+ * anything visible never creates an empty message.
5265
+ */
5266
+ update(text) {
5267
+ if (this.sealed || !text.trim())
5268
+ return;
5269
+ this.pendingBody = text;
5270
+ if (this.timer)
5271
+ return;
5272
+ this.timer = setTimeout(() => {
5273
+ this.timer = null;
5274
+ void this.flushPending().catch(() => {
5275
+ });
5276
+ }, THROTTLE_MS);
5277
+ }
5278
+ /**
5279
+ * Seal the draft at `finalText` and resolve once that text is on the wire.
5280
+ * Empty final text means the draft said nothing worth keeping, so the message
5281
+ * is deleted rather than left showing a body the producer has disowned.
5282
+ */
5283
+ async finalize(finalText) {
5284
+ this.sealed = true;
5285
+ if (this.timer) {
5286
+ clearTimeout(this.timer);
5287
+ this.timer = null;
5288
+ }
5289
+ if (finalText.trim()) {
5290
+ this.pendingBody = finalText;
5291
+ await this.flushPending();
5292
+ this.messageId = null;
5293
+ return;
5294
+ }
5295
+ await this.enqueue(async () => {
5296
+ if (!this.messageId)
5297
+ return;
5298
+ await this.client.deleteMessage({ messageId: this.messageId });
5299
+ this.messageId = null;
5300
+ });
5301
+ }
5302
+ /** Seal the draft and remove whatever it published. */
5303
+ async discard() {
5304
+ this.sealed = true;
5305
+ if (this.timer) {
5306
+ clearTimeout(this.timer);
5307
+ this.timer = null;
5308
+ }
5309
+ this.pendingBody = null;
5310
+ await this.enqueue(async () => {
5311
+ if (!this.messageId)
5312
+ return;
5313
+ await this.client.deleteMessage({ messageId: this.messageId });
5314
+ this.messageId = null;
5315
+ });
5316
+ }
5317
+ /** Whether a message has actually been published yet. */
5318
+ get hasMessage() {
5319
+ return this.messageId !== null;
5320
+ }
5321
+ async flushPending() {
5322
+ await this.enqueue(async () => {
5323
+ const body = this.pendingBody;
5324
+ if (!body || body === this.currentBody)
5325
+ return;
5326
+ if (this.messageId) {
5327
+ await this.client.editMessage({ messageId: this.messageId, body });
5328
+ } else {
5329
+ const posted = await this.client.sendMessage({
5330
+ channelId: this.channelId,
5331
+ body,
5332
+ replyToId: this.replyToId
5333
+ });
5334
+ this.messageId = posted.messageId;
5335
+ }
5336
+ this.currentBody = body;
5337
+ });
5338
+ }
5339
+ /**
5340
+ * Run `op` after every write queued before it. The same callback handles both
5341
+ * settlements deliberately: a rejected write must not wedge the chain, and a
5342
+ * producer that keeps typing after one failed edit still gets its next one.
5343
+ */
5344
+ enqueue(op) {
5345
+ this.writeChain = this.writeChain.then(op, op);
5346
+ return this.writeChain;
5347
+ }
5348
+ };
5180
5349
  export {
5181
5350
  BorgeeError,
5351
+ DraftMessageController,
5182
5352
  PermissionDeniedError,
5183
5353
  createBorgeePlugin
5184
5354
  };