@borgee/agents-host 0.2.68 → 0.2.73

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.
@@ -2,6 +2,7 @@ import { buildCollaborationCapabilityDeclarationSummaryLines, } from './collabor
2
2
  import { MAIN_SESSION_DELEGATION_LINES } from './main-session-delegation.js';
3
3
  import { buildResolvedWorkspaceGuidanceLines } from './resolved-workspace.js';
4
4
  import { buildSkillManualLines, buildSkillManualReadLine } from './skill-manual.js';
5
+ import { PARENT_CHANNEL_TASK_BOUNDARY_LINES } from './task-channel-boundary.js';
5
6
  function buildStableSkillLines(context) {
6
7
  if (!context?.skillRuntime) {
7
8
  return [];
@@ -16,7 +17,7 @@ function buildStableGatewayLines(context) {
16
17
  }
17
18
  const lines = [`Gateway credential file: ${context.gatewayCredentialPath}`];
18
19
  if (context.runtimeSurface?.task.currentThread === 'parent-channel') {
19
- lines.push('This channel is a parent channel, not a task thread.', 'For parent-channel task operations, use the packaged borgee-agent task rail through this gateway credential file.', 'Do not invent a bare task or bare borgee command.');
20
+ lines.push('This channel is a parent channel, not a task thread.', ...PARENT_CHANNEL_TASK_BOUNDARY_LINES, 'For parent-channel task operations, use the packaged borgee-agent task rail through this gateway credential file.', 'Do not invent a bare task or bare borgee command.');
20
21
  if (context.runtimeSurface.task.currentTaskShorthand === 'requires-task-id') {
21
22
  lines.push('In this parent channel, task get, task update, task history, and task property commands require an explicit task id.');
22
23
  }
@@ -6,6 +6,7 @@ import { buildCollaborationOutcomeSummaryLines } from './collaboration-outcome.j
6
6
  import { MAIN_SESSION_DELEGATION_LINES } from './main-session-delegation.js';
7
7
  import { buildResolvedWorkspaceGuidanceLines } from './resolved-workspace.js';
8
8
  import { buildSkillManualLines, buildSkillManualReadLine } from './skill-manual.js';
9
+ import { PARENT_CHANNEL_TASK_BOUNDARY_LINES } from './task-channel-boundary.js';
9
10
  import { buildTaskThreadCollaborationSummaryLines } from './task-thread-collaboration.js';
10
11
  function providerLabel(provider) {
11
12
  if (provider === 'copilot') {
@@ -46,6 +47,7 @@ function buildLocalhostGatewayPromptLines(context) {
46
47
  : 'This turn runs in a parent channel, not a task thread.');
47
48
  if (context.runtimeSurface?.task.currentThread === 'parent-channel'
48
49
  && (context.collaborationTurnMode ?? 'ordinary') === 'ordinary') {
50
+ lines.push(...PARENT_CHANNEL_TASK_BOUNDARY_LINES);
49
51
  if (context.runtimeSurface.task.parentChannelTaskCollection === 'available') {
50
52
  lines.push('Task list and task create are available in this parent channel.');
51
53
  lines.push(`For parent-channel task operations on this turn, read the packaged borgee-agent manual at ${context.skillRuntime.skillMarkdownPath} and follow that command grammar exactly.`);
@@ -132,6 +134,7 @@ function buildClaudeOrdinaryGatewayTaskLines(context) {
132
134
  const lines = [
133
135
  `Gateway credential file for this turn: ${context.gatewayCredentialPath}`,
134
136
  'This turn runs in a parent channel, not a task thread.',
137
+ ...PARENT_CHANNEL_TASK_BOUNDARY_LINES,
135
138
  'Task list and task create are available in this parent channel.',
136
139
  `For parent-channel task operations on this turn, read the packaged borgee-agent manual at ${context.skillRuntime.skillMarkdownPath} and follow that command grammar exactly.`,
137
140
  'For task creation and task updates in this parent channel, use the packaged borgee-agent task rail through this gateway credential file.',
@@ -169,7 +172,7 @@ function buildClaudeProjectedBriefTurnDeltaLines(context) {
169
172
  lines.push(...taskLines);
170
173
  }
171
174
  else {
172
- lines.push(`Gateway credential file for this turn: ${context.gatewayCredentialPath}`, 'This turn runs in a parent channel, not a task thread.');
175
+ lines.push(`Gateway credential file for this turn: ${context.gatewayCredentialPath}`, 'This turn runs in a parent channel, not a task thread.', ...PARENT_CHANNEL_TASK_BOUNDARY_LINES);
173
176
  if (context.runtimeSurface.task.parentChannelTaskCollection === 'available') {
174
177
  lines.push('Task list and task create are available in this parent channel.');
175
178
  }
@@ -0,0 +1 @@
1
+ export declare const PARENT_CHANNEL_TASK_BOUNDARY_LINES: readonly ["This parent channel is limited to creating and assigning tasks, coordinating them, and giving brief confirmations.", "After a task is created and assigned, do not start or continue its implementation, tool calls, or work progress in this parent channel; leave that work to the assigned task thread.", "Never work on the same task in the parent channel and its task thread at the same time."];
@@ -0,0 +1,5 @@
1
+ export const PARENT_CHANNEL_TASK_BOUNDARY_LINES = [
2
+ 'This parent channel is limited to creating and assigning tasks, coordinating them, and giving brief confirmations.',
3
+ 'After a task is created and assigned, do not start or continue its implementation, tool calls, or work progress in this parent channel; leave that work to the assigned task thread.',
4
+ 'Never work on the same task in the parent channel and its task thread at the same time.',
5
+ ];
@@ -3814,6 +3814,47 @@ var BppTransport = class {
3814
3814
  getResolvedAgentId() {
3815
3815
  return this.currentAgentId();
3816
3816
  }
3817
+ /** Fire-and-forget metadata-only lifecycle rail. Callers durably retry until ACK. */
3818
+ sendExecutionTelemetry(frame) {
3819
+ const base = {
3820
+ agent_id: this.currentAgentId(),
3821
+ execution_id: frame.executionId,
3822
+ telemetry_context: frame.telemetryContext,
3823
+ event_id: frame.eventId
3824
+ };
3825
+ switch (frame.type) {
3826
+ case "execution_started":
3827
+ this.send({
3828
+ type: frame.type,
3829
+ ...base,
3830
+ started_at: frame.startedAt
3831
+ });
3832
+ break;
3833
+ case "execution_usage":
3834
+ this.send({
3835
+ type: frame.type,
3836
+ ...base,
3837
+ usage_granularity: frame.usageGranularity,
3838
+ ...frame.callIndex === void 0 ? {} : { call_index: frame.callIndex },
3839
+ provider: frame.provider,
3840
+ model: frame.model,
3841
+ input_tokens: frame.inputTokens,
3842
+ output_tokens: frame.outputTokens,
3843
+ cache_read_tokens: frame.cacheReadTokens,
3844
+ cache_write_tokens: frame.cacheWriteTokens,
3845
+ observed_at: frame.observedAt
3846
+ });
3847
+ break;
3848
+ case "execution_finished":
3849
+ this.send({
3850
+ type: frame.type,
3851
+ ...base,
3852
+ succeeded: frame.succeeded,
3853
+ ended_at: frame.endedAt
3854
+ });
3855
+ break;
3856
+ }
3857
+ }
3817
3858
  async connect(ctx) {
3818
3859
  this.ctx = ctx;
3819
3860
  this.closed = false;
@@ -3991,7 +4032,12 @@ var BppTransport = class {
3991
4032
  plugin_id: ctx.pluginId ?? "",
3992
4033
  token: "",
3993
4034
  version: PROTOCOL_VERSION,
3994
- capabilities: JSON.stringify(["semantic_action", "inbound_message", "read_file"])
4035
+ capabilities: JSON.stringify([
4036
+ "semantic_action",
4037
+ "inbound_message",
4038
+ "read_file",
4039
+ "execution_telemetry"
4040
+ ])
3995
4041
  };
3996
4042
  this.sendTo(ws, connectFrame);
3997
4043
  try {
@@ -4069,6 +4115,11 @@ var BppTransport = class {
4069
4115
  case "inbound_message":
4070
4116
  this.handleInbound(env);
4071
4117
  break;
4118
+ case "execution_telemetry_ack":
4119
+ this.handlers?.onExecutionTelemetryAck?.({
4120
+ eventId: env.event_id
4121
+ });
4122
+ break;
4072
4123
  case "semantic_action_result":
4073
4124
  this.handleActionResult(env);
4074
4125
  break;
@@ -4260,7 +4311,12 @@ var BppTransport = class {
4260
4311
  const specific = this.stopTurnHandler;
4261
4312
  const generic = this.serverRequestHandler;
4262
4313
  try {
4263
- const answer = specific ? await specific(channelId) : generic ? await generic(STOP_TURN_ACTION, data) : { aborted: false };
4314
+ const answer = specific ? await specific(channelId) : generic ? await generic(STOP_TURN_ACTION, data) : (
4315
+ // No handler is not the same as "unsupported": nothing was aborted,
4316
+ // which is what false already says, and the rail carries no third
4317
+ // value to draw that distinction with.
4318
+ { aborted: false }
4319
+ );
4264
4320
  this.send({ type: "response", id, data: this.asStopTurnResult(answer) });
4265
4321
  } catch (err) {
4266
4322
  this.logger?.warn("bpp.stop_turn_handler_failed", err);
@@ -4345,7 +4401,10 @@ var BppTransport = class {
4345
4401
  frame.paths = action.activity.paths;
4346
4402
  break;
4347
4403
  case "plan":
4348
- frame.plan = action.activity.entries.map((entry) => ({ label: entry.label, status: entry.status }));
4404
+ frame.plan = action.activity.entries.map((entry) => ({
4405
+ label: entry.label,
4406
+ status: entry.status
4407
+ }));
4349
4408
  break;
4350
4409
  case "output":
4351
4410
  frame.stream = action.activity.stream;
@@ -4467,7 +4526,11 @@ function encodeActionPayload(action) {
4467
4526
  case "delete_message":
4468
4527
  return { message_id: action.messageId };
4469
4528
  case "react":
4470
- return { message_id: action.messageId, emoji: action.emoji, removed: action.removed ?? false };
4529
+ return {
4530
+ message_id: action.messageId,
4531
+ emoji: action.emoji,
4532
+ removed: action.removed ?? false
4533
+ };
4471
4534
  case "create_dm":
4472
4535
  return { user_id: action.userId };
4473
4536
  case "get_me":
@@ -4484,6 +4547,7 @@ function encodeActionPayload(action) {
4484
4547
  return {};
4485
4548
  case "create_channel":
4486
4549
  return {
4550
+ guild_id: action.guildId,
4487
4551
  name: action.name,
4488
4552
  topic: action.topic,
4489
4553
  visibility: action.visibility,
@@ -4652,9 +4716,23 @@ function mapInbound(frame) {
4652
4716
  kind,
4653
4717
  channelId: frame.channel_id,
4654
4718
  channelType: frame.channel_type,
4719
+ ...frame.conversation_context ? {
4720
+ conversationContext: {
4721
+ guildId: frame.conversation_context.guild_id,
4722
+ topLevelChannelId: frame.conversation_context.top_level_channel_id,
4723
+ ...frame.conversation_context.thread_id ? { threadId: frame.conversation_context.thread_id } : {},
4724
+ ...frame.conversation_context.task_id ? { taskId: frame.conversation_context.task_id } : {}
4725
+ }
4726
+ } : {},
4655
4727
  authorName: frame.author_name,
4656
4728
  createdAt: frame.created_at
4657
4729
  };
4730
+ if (frame.execution_id && frame.telemetry_context) {
4731
+ base.executionGrant = {
4732
+ executionId: frame.execution_id,
4733
+ telemetryContext: frame.telemetry_context
4734
+ };
4735
+ }
4658
4736
  switch (kind) {
4659
4737
  case "message":
4660
4738
  case "mention": {
@@ -4842,7 +4920,8 @@ var Client = class {
4842
4920
  message: /* @__PURE__ */ new Set(),
4843
4921
  configUpdate: /* @__PURE__ */ new Set(),
4844
4922
  permissionDenied: /* @__PURE__ */ new Set(),
4845
- connectionState: /* @__PURE__ */ new Set()
4923
+ connectionState: /* @__PURE__ */ new Set(),
4924
+ executionTelemetryAck: /* @__PURE__ */ new Set()
4846
4925
  };
4847
4926
  constructor(opts, transport) {
4848
4927
  this.opts = opts;
@@ -4914,6 +4993,7 @@ var Client = class {
4914
4993
  async createChannel(input) {
4915
4994
  return await this.t.perform({
4916
4995
  op: "create_channel",
4996
+ guildId: input.guildId,
4917
4997
  name: input.name,
4918
4998
  topic: input.topic,
4919
4999
  visibility: input.visibility,
@@ -4955,6 +5035,9 @@ var Client = class {
4955
5035
  activity: input.activity
4956
5036
  }).catch((err) => this.logger.warn("reportActivity failed", err));
4957
5037
  }
5038
+ reportExecutionTelemetry(frame) {
5039
+ this.t.sendExecutionTelemetry?.(frame);
5040
+ }
4958
5041
  reportTurnActivity(input) {
4959
5042
  return new TurnActivityReporter({
4960
5043
  ...input,
@@ -5076,7 +5159,8 @@ var Client = class {
5076
5159
  onStateChange: (s) => {
5077
5160
  this._state = s;
5078
5161
  this.emit("connectionState", s);
5079
- }
5162
+ },
5163
+ onExecutionTelemetryAck: (ack) => this.emit("executionTelemetryAck", ack)
5080
5164
  };
5081
5165
  }
5082
5166
  context() {