@mindstudio-ai/remy 0.1.149 → 0.1.150

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.
@@ -90,6 +90,10 @@ declare class HeadlessSession {
90
90
  /**
91
91
  * Drain the queue in strict FIFO order. Caller must hold `running = true`.
92
92
  * User messages arriving during the drain will be enqueued behind current items.
93
+ *
94
+ * Consecutive background-source items are coalesced into a single turn so
95
+ * the LLM sees all the background results together and produces one
96
+ * acknowledgment, not N separate ones.
93
97
  */
94
98
  private drainQueueLoop;
95
99
  /**
package/dist/headless.js CHANGED
@@ -2778,12 +2778,23 @@ function buildBackgroundResultsMessage(results) {
2778
2778
  ${r.result}
2779
2779
  </tool_result>`
2780
2780
  ).join("\n\n");
2781
- const body = `This is an automated message containing the result of a tool call that has been working in the background. This is not a direct message from the user.
2781
+ const plural = results.length > 1 ? "s" : "";
2782
+ const body = `This is an automated message containing the result${plural} of ${results.length > 1 ? "tool calls" : "a tool call"} that ${results.length > 1 ? "have" : "has"} been working in the background. This is not a direct message from the user.
2782
2783
  <background_results>
2783
2784
  ${xml}
2784
2785
  </background_results>`;
2785
2786
  return automatedMessage("background_results", body);
2786
2787
  }
2788
+ function mergeBackgroundResultsMessages(messages) {
2789
+ const results = [];
2790
+ const toolRe = /<tool_result id="([^"]+)" name="([^"]+)">\n([\s\S]*?)\n<\/tool_result>/g;
2791
+ for (const msg of messages) {
2792
+ for (const m of msg.matchAll(toolRe)) {
2793
+ results.push({ toolCallId: m[1], name: m[2], result: m[3] });
2794
+ }
2795
+ }
2796
+ return buildBackgroundResultsMessage(results);
2797
+ }
2787
2798
 
2788
2799
  // src/subagents/common/cleanMessages.ts
2789
2800
  function findLastSummaryCheckpoint(messages, name) {
@@ -6246,6 +6257,10 @@ var MessageQueue = class {
6246
6257
  snapshot() {
6247
6258
  return [...this.items];
6248
6259
  }
6260
+ /** Return the next item without removing it. */
6261
+ peek() {
6262
+ return this.items[0];
6263
+ }
6249
6264
  get length() {
6250
6265
  return this.items.length;
6251
6266
  }
@@ -6810,6 +6825,10 @@ ${userMessage}` : header;
6810
6825
  /**
6811
6826
  * Drain the queue in strict FIFO order. Caller must hold `running = true`.
6812
6827
  * User messages arriving during the drain will be enqueued behind current items.
6828
+ *
6829
+ * Consecutive background-source items are coalesced into a single turn so
6830
+ * the LLM sees all the background results together and produces one
6831
+ * acknowledgment, not N separate ones.
6813
6832
  */
6814
6833
  async drainQueueLoop() {
6815
6834
  while (true) {
@@ -6817,6 +6836,26 @@ ${userMessage}` : header;
6817
6836
  if (!next) {
6818
6837
  break;
6819
6838
  }
6839
+ if (next.source === "background") {
6840
+ const batch = [next];
6841
+ while (this.queue.peek()?.source === "background") {
6842
+ const more = this.queue.shift();
6843
+ if (more) {
6844
+ batch.push(more);
6845
+ }
6846
+ }
6847
+ const combinedCommand = {
6848
+ action: "message",
6849
+ text: mergeBackgroundResultsMessages(
6850
+ batch.map((b) => b.command.text ?? "")
6851
+ ),
6852
+ ...this.currentOnboardingState && {
6853
+ onboardingState: this.currentOnboardingState
6854
+ }
6855
+ };
6856
+ await this.runSingleTurn(combinedCommand, `background-${Date.now()}`);
6857
+ continue;
6858
+ }
6820
6859
  const nextRid = next.command.requestId ?? `${next.source}-${Date.now()}`;
6821
6860
  await this.runSingleTurn(next.command, nextRid);
6822
6861
  }
package/dist/index.js CHANGED
@@ -3069,12 +3069,23 @@ function buildBackgroundResultsMessage(results) {
3069
3069
  ${r.result}
3070
3070
  </tool_result>`
3071
3071
  ).join("\n\n");
3072
- const body = `This is an automated message containing the result of a tool call that has been working in the background. This is not a direct message from the user.
3072
+ const plural = results.length > 1 ? "s" : "";
3073
+ const body = `This is an automated message containing the result${plural} of ${results.length > 1 ? "tool calls" : "a tool call"} that ${results.length > 1 ? "have" : "has"} been working in the background. This is not a direct message from the user.
3073
3074
  <background_results>
3074
3075
  ${xml}
3075
3076
  </background_results>`;
3076
3077
  return automatedMessage("background_results", body);
3077
3078
  }
3079
+ function mergeBackgroundResultsMessages(messages) {
3080
+ const results = [];
3081
+ const toolRe = /<tool_result id="([^"]+)" name="([^"]+)">\n([\s\S]*?)\n<\/tool_result>/g;
3082
+ for (const msg of messages) {
3083
+ for (const m of msg.matchAll(toolRe)) {
3084
+ results.push({ toolCallId: m[1], name: m[2], result: m[3] });
3085
+ }
3086
+ }
3087
+ return buildBackgroundResultsMessage(results);
3088
+ }
3078
3089
  var init_sentinel = __esm({
3079
3090
  "src/automatedActions/sentinel.ts"() {
3080
3091
  "use strict";
@@ -6948,6 +6959,10 @@ var init_messageQueue = __esm({
6948
6959
  snapshot() {
6949
6960
  return [...this.items];
6950
6961
  }
6962
+ /** Return the next item without removing it. */
6963
+ peek() {
6964
+ return this.items[0];
6965
+ }
6951
6966
  get length() {
6952
6967
  return this.items.length;
6953
6968
  }
@@ -7546,6 +7561,10 @@ ${userMessage}` : header;
7546
7561
  /**
7547
7562
  * Drain the queue in strict FIFO order. Caller must hold `running = true`.
7548
7563
  * User messages arriving during the drain will be enqueued behind current items.
7564
+ *
7565
+ * Consecutive background-source items are coalesced into a single turn so
7566
+ * the LLM sees all the background results together and produces one
7567
+ * acknowledgment, not N separate ones.
7549
7568
  */
7550
7569
  async drainQueueLoop() {
7551
7570
  while (true) {
@@ -7553,6 +7572,26 @@ ${userMessage}` : header;
7553
7572
  if (!next) {
7554
7573
  break;
7555
7574
  }
7575
+ if (next.source === "background") {
7576
+ const batch = [next];
7577
+ while (this.queue.peek()?.source === "background") {
7578
+ const more = this.queue.shift();
7579
+ if (more) {
7580
+ batch.push(more);
7581
+ }
7582
+ }
7583
+ const combinedCommand = {
7584
+ action: "message",
7585
+ text: mergeBackgroundResultsMessages(
7586
+ batch.map((b) => b.command.text ?? "")
7587
+ ),
7588
+ ...this.currentOnboardingState && {
7589
+ onboardingState: this.currentOnboardingState
7590
+ }
7591
+ };
7592
+ await this.runSingleTurn(combinedCommand, `background-${Date.now()}`);
7593
+ continue;
7594
+ }
7556
7595
  const nextRid = next.command.requestId ?? `${next.source}-${Date.now()}`;
7557
7596
  await this.runSingleTurn(next.command, nextRid);
7558
7597
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindstudio-ai/remy",
3
- "version": "0.1.149",
3
+ "version": "0.1.150",
4
4
  "description": "MindStudio coding agent",
5
5
  "repository": {
6
6
  "type": "git",