replicas-engine 0.1.213 → 0.1.214

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 (2) hide show
  1. package/dist/src/index.js +41 -113
  2. package/package.json +1 -1
package/dist/src/index.js CHANGED
@@ -1493,7 +1493,7 @@ function parseReplicasConfigString(content, filename) {
1493
1493
  }
1494
1494
 
1495
1495
  // ../shared/src/engine/environment.ts
1496
- var DAYTONA_SNAPSHOT_ID = "26-05-2026-royal-york-v1";
1496
+ var DAYTONA_SNAPSHOT_ID = "26-05-2026-royal-york-v2";
1497
1497
 
1498
1498
  // ../shared/src/engine/types.ts
1499
1499
  var DEFAULT_CHAT_TITLES = {
@@ -4024,20 +4024,6 @@ var MessageQueueService = class {
4024
4024
  };
4025
4025
 
4026
4026
  // src/managers/coding-agent-manager.ts
4027
- var COMPACT_COMMAND_REGEX = /^\/compact\b\s*(.*)$/s;
4028
- var COMPACT_TURN_MARKER = "\0__replicas_compact_turn__\0";
4029
- var COMPACT_SUMMARY_PROMPT = [
4030
- "The user has requested a session compaction. Produce a thorough summary of this conversation that captures everything needed to continue the work without the prior context.",
4031
- "",
4032
- "Cover at least:",
4033
- "1. The high-level goal we are working toward and the user's most recent intent.",
4034
- "2. Key decisions made and the rationale behind them.",
4035
- "3. Files inspected or modified (paths + the relevant changes).",
4036
- "4. Open questions, blockers, and pending follow-ups.",
4037
- "5. Any environment details, credentials, or external systems already configured.",
4038
- "",
4039
- "Format the response as Markdown with clear headings. The session will be reset after your reply and your summary re-injected as the prelude to the next user turn; write it so a future agent can resume using only that prelude."
4040
- ].join("\n");
4041
4027
  var MAX_INTERRUPT_QUEUE_ITEMS = 1e3;
4042
4028
  var MAX_INTERRUPT_QUEUE_CHARS = 2e5;
4043
4029
  var CodingAgentManager = class {
@@ -4048,9 +4034,7 @@ var CodingAgentManager = class {
4048
4034
  onSaveSessionId;
4049
4035
  onEvent;
4050
4036
  hostOnTurnComplete;
4051
- compactionInFlight = false;
4052
- compactionBuffer = "";
4053
- pendingSessionPrelude = null;
4037
+ compacting = false;
4054
4038
  constructor(options) {
4055
4039
  this.workingDirectory = options.workingDirectory ?? ENGINE_ENV.WORKSPACE_ROOT;
4056
4040
  this.initialSessionId = options.initialSessionId;
@@ -4059,65 +4043,26 @@ var CodingAgentManager = class {
4059
4043
  this.hostOnTurnComplete = options.onTurnComplete;
4060
4044
  }
4061
4045
  onTurnComplete = async () => {
4062
- if (this.compactionInFlight) {
4063
- this.compactionInFlight = false;
4064
- const summary = this.compactionBuffer.trim();
4065
- this.compactionBuffer = "";
4066
- this.pendingSessionPrelude = summary.length > 0 ? summary : null;
4067
- this.emitCompactionStatus("completed");
4068
- try {
4069
- await this.clearSessionState();
4070
- } catch (error) {
4071
- console.error("[CodingAgentManager] Failed to clear session after compaction:", error);
4072
- }
4046
+ if (this.compacting) {
4047
+ this.setCompacting(false);
4073
4048
  }
4074
4049
  await this.hostOnTurnComplete();
4075
4050
  };
4076
4051
  isCompacting() {
4077
- return this.compactionInFlight;
4078
- }
4079
- captureCompactionText(text) {
4080
- if (!this.compactionInFlight) return;
4081
- const trimmed = text.trim();
4082
- if (!trimmed) return;
4083
- this.compactionBuffer = this.compactionBuffer.length > 0 ? `${this.compactionBuffer}
4084
-
4085
- ${trimmed}` : trimmed;
4086
- }
4087
- consumePendingPrelude(message) {
4088
- if (!this.pendingSessionPrelude) return message;
4089
- const prelude = this.pendingSessionPrelude;
4090
- this.pendingSessionPrelude = null;
4091
- return `<prior-session-summary>
4092
- ${prelude}
4093
- </prior-session-summary>
4094
-
4095
- ${message}`;
4052
+ return this.compacting;
4096
4053
  }
4097
- emitCompactionStatus(state) {
4054
+ // Dedup so a noisy stream of native compaction events doesn't spam the UI with redundant status flips.
4055
+ setCompacting(active) {
4056
+ if (this.compacting === active) return;
4057
+ this.compacting = active;
4098
4058
  this.onEvent({
4099
4059
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
4100
4060
  type: COMPACTION_STATUS_EVENT_TYPE,
4101
- payload: { state }
4061
+ payload: { state: active ? "in_progress" : "completed" }
4102
4062
  });
4103
4063
  }
4104
4064
  initializeManager(processMessage) {
4105
- const wrappedProcessMessage = async (request) => {
4106
- if (request.message.startsWith(COMPACT_TURN_MARKER)) {
4107
- this.compactionInFlight = true;
4108
- this.compactionBuffer = "";
4109
- this.emitCompactionStatus("in_progress");
4110
- const summaryPrompt = this.consumePendingPrelude(
4111
- request.message.slice(COMPACT_TURN_MARKER.length)
4112
- );
4113
- return processMessage({ ...request, message: summaryPrompt });
4114
- }
4115
- return processMessage({
4116
- ...request,
4117
- message: this.consumePendingPrelude(request.message)
4118
- });
4119
- };
4120
- this.messageQueue = new MessageQueueService(wrappedProcessMessage);
4065
+ this.messageQueue = new MessageQueueService(processMessage);
4121
4066
  this.initialized = this.initialize();
4122
4067
  }
4123
4068
  async interrupt() {
@@ -4137,7 +4082,7 @@ ${message}`;
4137
4082
  getQueue() {
4138
4083
  return this.messageQueue.getQueue().map((m) => ({
4139
4084
  id: m.id,
4140
- message: m.message.startsWith(COMPACT_TURN_MARKER) ? "/compact" : m.message,
4085
+ message: m.message,
4141
4086
  queuedAt: m.queuedAt,
4142
4087
  ...m.senderUserId ? { senderUserId: m.senderUserId } : {},
4143
4088
  ...m.senderEmail ? { senderEmail: m.senderEmail } : {},
@@ -4152,18 +4097,6 @@ ${message}`;
4152
4097
  }
4153
4098
  async enqueueMessage(request) {
4154
4099
  await this.initialized;
4155
- const compact = request.message.trimStart().match(COMPACT_COMMAND_REGEX);
4156
- if (compact) {
4157
- const guidance = compact[1].trim();
4158
- const prompt = guidance ? `${COMPACT_SUMMARY_PROMPT}
4159
-
4160
- Additional guidance from the user for the summary:
4161
- ${guidance}` : COMPACT_SUMMARY_PROMPT;
4162
- return this.messageQueue.enqueue({
4163
- ...request,
4164
- message: `${COMPACT_TURN_MARKER}${prompt}`
4165
- });
4166
- }
4167
4100
  return this.messageQueue.enqueue(request);
4168
4101
  }
4169
4102
  emitContextUsage(payload) {
@@ -4202,7 +4135,7 @@ ${guidance}` : COMPACT_SUMMARY_PROMPT;
4202
4135
  const queue = this.messageQueue.drainQueue({
4203
4136
  maxItems: MAX_INTERRUPT_QUEUE_ITEMS,
4204
4137
  maxChars: MAX_INTERRUPT_QUEUE_CHARS
4205
- }).map((m) => m.startsWith(COMPACT_TURN_MARKER) ? "/compact" : m);
4138
+ });
4206
4139
  return {
4207
4140
  queue,
4208
4141
  isProcessing: this.messageQueue.isProcessing()
@@ -4479,10 +4412,6 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
4479
4412
  }
4480
4413
  await this.abortAllPendingToolInputs();
4481
4414
  }
4482
- async clearSessionState() {
4483
- this.sessionId = null;
4484
- await this.onSaveSessionId(null);
4485
- }
4486
4415
  async abortAllPendingToolInputs() {
4487
4416
  const pending = Array.from(this.pendingToolInputs.values());
4488
4417
  this.pendingToolInputs.clear();
@@ -4840,15 +4769,20 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
4840
4769
  console.log(`[ClaudeManager] Captured and persisted session ID: ${this.sessionId}`);
4841
4770
  }
4842
4771
  await this.checkForAuthFailure(message);
4843
- if (this.isCompacting() && message.type === "assistant") {
4844
- for (const block of message.message.content) {
4845
- if (block.type === "text") {
4846
- this.captureCompactionText(block.text);
4847
- }
4848
- }
4849
- }
4772
+ this.trackNativeCompaction(message);
4850
4773
  await this.recordEvent(message);
4851
4774
  }
4775
+ // Claude Code intercepts /compact and auto-compaction inside the SDK process; we just observe the status messages to mirror state to the UI.
4776
+ trackNativeCompaction(message) {
4777
+ if (message.type !== "system") return;
4778
+ if (message.subtype === "status" && message.status === "compacting") {
4779
+ this.setCompacting(true);
4780
+ return;
4781
+ }
4782
+ if (message.subtype === "compact_boundary") {
4783
+ this.setCompacting(false);
4784
+ }
4785
+ }
4852
4786
  async recordEvent(event) {
4853
4787
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
4854
4788
  const jsonEvent = {
@@ -5012,11 +4946,6 @@ var CodexManager = class _CodexManager extends CodingAgentManager {
5012
4946
  this.activeAbortController.abort();
5013
4947
  }
5014
4948
  }
5015
- async clearSessionState() {
5016
- this.currentThreadId = null;
5017
- this.currentThread = null;
5018
- await this.onSaveSessionId(null);
5019
- }
5020
4949
  /**
5021
4950
  * Update the developer_instructions in ~/.codex/config.toml
5022
4951
  * This sets the system prompt that Codex will use for this turn
@@ -5290,16 +5219,21 @@ var CodexManager = class _CodexManager extends CodingAgentManager {
5290
5219
  }
5291
5220
  return null;
5292
5221
  }
5293
- bufferCompactionFromEvent(event) {
5294
- if (!this.isCompacting()) return;
5295
- if (event.type !== "response_item") return;
5296
- const payload = event.payload;
5297
- if (payload?.type !== "message" || payload?.role !== "assistant") return;
5298
- const blocks = Array.isArray(payload.content) ? payload.content : [];
5299
- for (const block of blocks) {
5300
- if (block.type === "output_text" && typeof block.text === "string") {
5301
- this.captureCompactionText(block.text);
5302
- }
5222
+ // @openai/codex-sdk doesn't expose manual /compact (TUI-only); we only mirror the auto-compaction rollout entries to the UI.
5223
+ trackNativeCompaction(event) {
5224
+ if (event.type === "compacted") {
5225
+ this.setCompacting(false);
5226
+ return;
5227
+ }
5228
+ if (event.type !== "event_msg") return;
5229
+ const msg = event.payload.msg;
5230
+ if (!msg) return;
5231
+ const itemType = msg.payload?.item?.type;
5232
+ if (itemType !== "context_compaction") return;
5233
+ if (msg.type === "item_started") {
5234
+ this.setCompacting(true);
5235
+ } else if (msg.type === "item_completed") {
5236
+ this.setCompacting(false);
5303
5237
  }
5304
5238
  }
5305
5239
  async startSessionTail(threadId) {
@@ -5352,7 +5286,7 @@ var CodexManager = class _CodexManager extends CodingAgentManager {
5352
5286
  this.emitQuotaStatus(snapshot);
5353
5287
  }
5354
5288
  if (isJsonlEvent2(parsed)) {
5355
- this.bufferCompactionFromEvent(parsed);
5289
+ this.trackNativeCompaction(parsed);
5356
5290
  this.onEvent(parsed);
5357
5291
  emitted += 1;
5358
5292
  }
@@ -5742,11 +5676,6 @@ var CodexAspManager = class extends CodingAgentManager {
5742
5676
  console.warn("[CodexAspManager] Failed to interrupt active turn:", error);
5743
5677
  }
5744
5678
  }
5745
- async clearSessionState() {
5746
- this.currentThreadId = null;
5747
- this.activeTurnId = null;
5748
- await this.onSaveSessionId(null);
5749
- }
5750
5679
  async getHistory() {
5751
5680
  return {
5752
5681
  thread_id: this.currentThreadId,
@@ -5937,7 +5866,6 @@ var CodexAspManager = class extends CodingAgentManager {
5937
5866
  if (!text) {
5938
5867
  return;
5939
5868
  }
5940
- this.captureCompactionText(text);
5941
5869
  const event = this.recordHistoryEvent("response_item", {
5942
5870
  type: "message",
5943
5871
  role: "assistant",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.213",
3
+ "version": "0.1.214",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",