replicas-engine 0.1.207 → 0.1.209

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 +78 -7
  2. package/package.json +1 -1
package/dist/src/index.js CHANGED
@@ -22,6 +22,7 @@ import { join } from "path";
22
22
 
23
23
  // ../shared/src/event.ts
24
24
  var CODEX_QUOTA_STATUS_EVENT_TYPE = "codex-quota-status";
25
+ var COMPACTION_STATUS_EVENT_TYPE = "compaction-status";
25
26
  var CONTEXT_USAGE_EVENT_TYPE = "context-usage";
26
27
 
27
28
  // ../shared/src/languages.ts
@@ -396,7 +397,7 @@ function parseReplicasConfigString(content, filename) {
396
397
  }
397
398
 
398
399
  // ../shared/src/engine/environment.ts
399
- var DAYTONA_SNAPSHOT_ID = "23-05-2026-royal-york-v5";
400
+ var DAYTONA_SNAPSHOT_ID = "24-05-2026-royal-york-v1";
400
401
 
401
402
  // ../shared/src/engine/types.ts
402
403
  var DEFAULT_CHAT_TITLES = {
@@ -2926,6 +2927,20 @@ var MessageQueueService = class {
2926
2927
  };
2927
2928
 
2928
2929
  // src/managers/coding-agent-manager.ts
2930
+ var COMPACT_COMMAND_REGEX = /^\/compact\b\s*(.*)$/s;
2931
+ var COMPACT_TURN_MARKER = "\0__replicas_compact_turn__\0";
2932
+ var COMPACT_SUMMARY_PROMPT = [
2933
+ "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.",
2934
+ "",
2935
+ "Cover at least:",
2936
+ "1. The high-level goal we are working toward and the user's most recent intent.",
2937
+ "2. Key decisions made and the rationale behind them.",
2938
+ "3. Files inspected or modified (paths + the relevant changes).",
2939
+ "4. Open questions, blockers, and pending follow-ups.",
2940
+ "5. Any environment details, credentials, or external systems already configured.",
2941
+ "",
2942
+ "Format the response as Markdown with clear headings. The session will be reset after your reply, so write the summary as the only context a future agent will have."
2943
+ ].join("\n");
2929
2944
  var MAX_INTERRUPT_QUEUE_ITEMS = 1e3;
2930
2945
  var MAX_INTERRUPT_QUEUE_CHARS = 2e5;
2931
2946
  var CodingAgentManager = class {
@@ -2935,16 +2950,47 @@ var CodingAgentManager = class {
2935
2950
  initialSessionId;
2936
2951
  onSaveSessionId;
2937
2952
  onEvent;
2938
- onTurnComplete;
2953
+ hostOnTurnComplete;
2954
+ compactionInFlight = false;
2939
2955
  constructor(options) {
2940
2956
  this.workingDirectory = options.workingDirectory ?? ENGINE_ENV.WORKSPACE_ROOT;
2941
2957
  this.initialSessionId = options.initialSessionId;
2942
2958
  this.onSaveSessionId = options.onSaveSessionId;
2943
2959
  this.onEvent = options.onEvent;
2944
- this.onTurnComplete = options.onTurnComplete;
2960
+ this.hostOnTurnComplete = options.onTurnComplete;
2961
+ }
2962
+ onTurnComplete = async () => {
2963
+ if (this.compactionInFlight) {
2964
+ this.compactionInFlight = false;
2965
+ this.emitCompactionStatus("completed");
2966
+ try {
2967
+ await this.clearSessionState();
2968
+ } catch (error) {
2969
+ console.error("[CodingAgentManager] Failed to clear session after compaction:", error);
2970
+ }
2971
+ }
2972
+ await this.hostOnTurnComplete();
2973
+ };
2974
+ isCompacting() {
2975
+ return this.compactionInFlight;
2976
+ }
2977
+ emitCompactionStatus(state) {
2978
+ this.onEvent({
2979
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2980
+ type: COMPACTION_STATUS_EVENT_TYPE,
2981
+ payload: { state }
2982
+ });
2945
2983
  }
2946
2984
  initializeManager(processMessage) {
2947
- this.messageQueue = new MessageQueueService(processMessage);
2985
+ const wrappedProcessMessage = async (request) => {
2986
+ if (request.message.startsWith(COMPACT_TURN_MARKER)) {
2987
+ this.compactionInFlight = true;
2988
+ this.emitCompactionStatus("in_progress");
2989
+ return processMessage({ ...request, message: request.message.slice(COMPACT_TURN_MARKER.length) });
2990
+ }
2991
+ return processMessage(request);
2992
+ };
2993
+ this.messageQueue = new MessageQueueService(wrappedProcessMessage);
2948
2994
  this.initialized = this.initialize();
2949
2995
  }
2950
2996
  async interrupt() {
@@ -2964,7 +3010,7 @@ var CodingAgentManager = class {
2964
3010
  getQueue() {
2965
3011
  return this.messageQueue.getQueue().map((m) => ({
2966
3012
  id: m.id,
2967
- message: m.message,
3013
+ message: m.message.startsWith(COMPACT_TURN_MARKER) ? "/compact" : m.message,
2968
3014
  queuedAt: m.queuedAt,
2969
3015
  ...m.senderUserId ? { senderUserId: m.senderUserId } : {},
2970
3016
  ...m.senderEmail ? { senderEmail: m.senderEmail } : {},
@@ -2979,6 +3025,18 @@ var CodingAgentManager = class {
2979
3025
  }
2980
3026
  async enqueueMessage(request) {
2981
3027
  await this.initialized;
3028
+ const compact = request.message.trimStart().match(COMPACT_COMMAND_REGEX);
3029
+ if (compact) {
3030
+ const guidance = compact[1].trim();
3031
+ const prompt = guidance ? `${COMPACT_SUMMARY_PROMPT}
3032
+
3033
+ Additional guidance from the user for the summary:
3034
+ ${guidance}` : COMPACT_SUMMARY_PROMPT;
3035
+ return this.messageQueue.enqueue({
3036
+ ...request,
3037
+ message: `${COMPACT_TURN_MARKER}${prompt}`
3038
+ });
3039
+ }
2982
3040
  return this.messageQueue.enqueue(request);
2983
3041
  }
2984
3042
  emitContextUsage(payload) {
@@ -3017,7 +3075,7 @@ var CodingAgentManager = class {
3017
3075
  const queue = this.messageQueue.drainQueue({
3018
3076
  maxItems: MAX_INTERRUPT_QUEUE_ITEMS,
3019
3077
  maxChars: MAX_INTERRUPT_QUEUE_CHARS
3020
- });
3078
+ }).map((m) => m.startsWith(COMPACT_TURN_MARKER) ? "/compact" : m);
3021
3079
  return {
3022
3080
  queue,
3023
3081
  isProcessing: this.messageQueue.isProcessing()
@@ -3294,6 +3352,10 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
3294
3352
  }
3295
3353
  await this.abortAllPendingToolInputs();
3296
3354
  }
3355
+ async clearSessionState() {
3356
+ this.sessionId = null;
3357
+ await this.onSaveSessionId(null);
3358
+ }
3297
3359
  async abortAllPendingToolInputs() {
3298
3360
  const pending = Array.from(this.pendingToolInputs.values());
3299
3361
  this.pendingToolInputs.clear();
@@ -3816,6 +3878,11 @@ var CodexManager = class _CodexManager extends CodingAgentManager {
3816
3878
  this.activeAbortController.abort();
3817
3879
  }
3818
3880
  }
3881
+ async clearSessionState() {
3882
+ this.currentThreadId = null;
3883
+ this.currentThread = null;
3884
+ await this.onSaveSessionId(null);
3885
+ }
3819
3886
  /**
3820
3887
  * Update the developer_instructions in ~/.codex/config.toml
3821
3888
  * This sets the system prompt that Codex will use for this turn
@@ -4690,6 +4757,9 @@ var RelayManager = class {
4690
4757
  isProcessing() {
4691
4758
  return this.inner.isProcessing();
4692
4759
  }
4760
+ isCompacting() {
4761
+ return this.inner.isCompacting();
4762
+ }
4693
4763
  getQueue() {
4694
4764
  return this.inner.getQueue();
4695
4765
  }
@@ -5113,6 +5183,7 @@ var ChatService = class {
5113
5183
  updatedAt: chat.persisted.updatedAt,
5114
5184
  processing: chat.provider.isProcessing(),
5115
5185
  awaitingInput: chat.provider.isAwaitingInput?.() ?? false,
5186
+ isCompacting: chat.provider.isCompacting?.() ?? false,
5116
5187
  parentChatId: chat.persisted.parentChatId
5117
5188
  };
5118
5189
  }
@@ -5155,7 +5226,7 @@ var ChatService = class {
5155
5226
  }
5156
5227
  }).catch(() => {
5157
5228
  });
5158
- if (event.type === "replicas-tool-input-request" || event.type === "replicas-tool-input-resolved") {
5229
+ if (event.type === "replicas-tool-input-request" || event.type === "replicas-tool-input-resolved" || event.type === "compaction-status") {
5159
5230
  this.publish({
5160
5231
  type: "chat.updated",
5161
5232
  payload: { chat: this.toSummary(chat) }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.207",
3
+ "version": "0.1.209",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",