replicas-engine 0.1.776 → 0.1.778

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.
@@ -5,11 +5,11 @@ import {
5
5
  getCodexAspHost,
6
6
  restartCodexAspHost,
7
7
  restartCodexAspHostIfRunning
8
- } from "./chunk-OVQGTUPL.js";
9
- import "./chunk-NPFAPMJ3.js";
10
- import "./chunk-RP4LIWKF.js";
8
+ } from "./chunk-PRDBLI2T.js";
9
+ import "./chunk-Z3ZWANDZ.js";
10
+ import "./chunk-RXBUE7A3.js";
11
11
  import "./chunk-UZSNFLDQ.js";
12
- import "./chunk-3PHLWZEX.js";
12
+ import "./chunk-7WLA6QVZ.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
  export {
15
15
  getCodexAspHost,
@@ -5993,6 +5993,9 @@ var CODEX_CATEGORY_COLORS = {
5993
5993
  input: "#3eeba3",
5994
5994
  output: "#56b6c2"
5995
5995
  };
5996
+ function isRecord2(value) {
5997
+ return typeof value === "object" && value !== null;
5998
+ }
5996
5999
  function numberOrNull(value) {
5997
6000
  return typeof value === "number" && Number.isFinite(value) ? value : null;
5998
6001
  }
@@ -6072,6 +6075,123 @@ function buildCodexTokenUsageContextUsagePayload(usage) {
6072
6075
  updatedAt: usage.updatedAt
6073
6076
  };
6074
6077
  }
6078
+ function normalizeProvider(provider) {
6079
+ return provider === "relay" ? "relay" : provider;
6080
+ }
6081
+ function resolveClaudeContextWindow(provider, model, reportedMaxTokens) {
6082
+ if (provider !== "claude" && provider !== "relay") {
6083
+ return { maxTokens: reportedMaxTokens, usedKnownWindow: false };
6084
+ }
6085
+ const knownWindow = getClaudeModelContextWindow(model);
6086
+ return {
6087
+ maxTokens: knownWindow ?? reportedMaxTokens,
6088
+ usedKnownWindow: knownWindow !== null
6089
+ };
6090
+ }
6091
+ function coerceContextUsagePayload(payload, timestamp) {
6092
+ const provider = payload.provider;
6093
+ if (typeof provider !== "string" || !isValidAgentProvider(provider)) return null;
6094
+ const rawTotalTokens = numberOrNull(payload.totalTokens);
6095
+ const percentageValue = numberOrNull(payload.percentage);
6096
+ if (rawTotalTokens === null || percentageValue === null) {
6097
+ return null;
6098
+ }
6099
+ const model = typeof payload.model === "string" ? payload.model : null;
6100
+ const reportedMaxTokens = numberOrNull(payload.maxTokens);
6101
+ const { maxTokens, usedKnownWindow } = resolveClaudeContextWindow(provider, model, reportedMaxTokens);
6102
+ const rawMaxTokens = usedKnownWindow ? maxTokens : numberOrNull(payload.rawMaxTokens);
6103
+ const clamped = clampTokensToWindow(rawTotalTokens, maxTokens);
6104
+ const totalTokens = clamped.totalTokens;
6105
+ const payloadTotalProcessedTokens = numberOrNull(payload.totalProcessedTokens);
6106
+ const totalProcessedTokens = payloadTotalProcessedTokens !== null ? payloadTotalProcessedTokens : clamped.totalProcessedTokens ?? null;
6107
+ const source = payload.source === "codex_token_count" || payload.source === "claude_usage" || payload.source === "provider_usage" ? payload.source : "claude_context";
6108
+ const categories = Array.isArray(payload.categories) ? compactCategories(payload.categories.map((item) => {
6109
+ if (!isRecord2(item)) return null;
6110
+ const name = typeof item.name === "string" ? item.name : null;
6111
+ const tokens = numberOrNull(item.tokens);
6112
+ const categoryPercentage = numberOrNull(item.percentage);
6113
+ if (!name || tokens === null || categoryPercentage === null) return null;
6114
+ return {
6115
+ name,
6116
+ tokens,
6117
+ percentage: usedKnownWindow ? percentage(tokens, maxTokens) : categoryPercentage,
6118
+ ...typeof item.color === "string" ? { color: item.color } : {},
6119
+ ...typeof item.isDeferred === "boolean" ? { isDeferred: item.isDeferred } : {}
6120
+ };
6121
+ })) : [];
6122
+ const apiUsage = isRecord2(payload.apiUsage) ? {
6123
+ ...numberOrNull(payload.apiUsage.inputTokens) !== null ? { inputTokens: numberOrNull(payload.apiUsage.inputTokens) } : {},
6124
+ ...numberOrNull(payload.apiUsage.outputTokens) !== null ? { outputTokens: numberOrNull(payload.apiUsage.outputTokens) } : {},
6125
+ ...numberOrNull(payload.apiUsage.cacheCreationInputTokens) !== null ? { cacheCreationInputTokens: numberOrNull(payload.apiUsage.cacheCreationInputTokens) } : {},
6126
+ ...numberOrNull(payload.apiUsage.cacheReadInputTokens) !== null ? { cacheReadInputTokens: numberOrNull(payload.apiUsage.cacheReadInputTokens) } : {},
6127
+ ...numberOrNull(payload.apiUsage.cachedInputTokens) !== null ? { cachedInputTokens: numberOrNull(payload.apiUsage.cachedInputTokens) } : {},
6128
+ ...numberOrNull(payload.apiUsage.reasoningOutputTokens) !== null ? { reasoningOutputTokens: numberOrNull(payload.apiUsage.reasoningOutputTokens) } : {},
6129
+ ...numberOrNull(payload.apiUsage.totalTokens) !== null ? { totalTokens: numberOrNull(payload.apiUsage.totalTokens) } : {}
6130
+ } : null;
6131
+ const compactsAutomatically = typeof payload.compactsAutomatically === "boolean" ? payload.compactsAutomatically : void 0;
6132
+ const autoCompactThreshold = normalizeAutoCompactThreshold(payload.autoCompactThreshold, maxTokens);
6133
+ return {
6134
+ provider,
6135
+ source,
6136
+ ...model ? { model } : {},
6137
+ totalTokens,
6138
+ ...totalProcessedTokens !== null ? { totalProcessedTokens } : {},
6139
+ maxTokens,
6140
+ rawMaxTokens,
6141
+ percentage: usedKnownWindow ? percentage(totalTokens, maxTokens) : clampPercentage(percentageValue),
6142
+ ...compactsAutomatically !== void 0 ? { compactsAutomatically } : {},
6143
+ ...autoCompactThreshold !== null ? { autoCompactThreshold } : {},
6144
+ categories,
6145
+ apiUsage,
6146
+ updatedAt: typeof payload.updatedAt === "string" ? payload.updatedAt : timestamp
6147
+ };
6148
+ }
6149
+ function codexTokenCountToContextUsage(event) {
6150
+ const payload = event.payload;
6151
+ if (payload.type !== "token_count") return null;
6152
+ const info = isRecord2(payload.info) ? payload.info : null;
6153
+ if (!info) return null;
6154
+ const lastUsage = isRecord2(info.last_token_usage) ? info.last_token_usage : null;
6155
+ if (!lastUsage) return null;
6156
+ const totalUsage = isRecord2(info.total_token_usage) ? info.total_token_usage : null;
6157
+ const maxTokens = numberOrNull(info.model_context_window);
6158
+ const inputTokens = numberOrNull(lastUsage.input_tokens) ?? 0;
6159
+ const outputTokens = numberOrNull(lastUsage.output_tokens) ?? 0;
6160
+ const cumulativeTotalTokens = numberOrNull(totalUsage?.total_tokens);
6161
+ return buildCodexTokenUsageContextUsagePayload({
6162
+ last: {
6163
+ inputTokens,
6164
+ outputTokens,
6165
+ totalTokens: numberOrNull(lastUsage.total_tokens) ?? inputTokens + outputTokens,
6166
+ cachedInputTokens: numberOrNull(lastUsage.cached_input_tokens),
6167
+ reasoningOutputTokens: numberOrNull(lastUsage.reasoning_output_tokens)
6168
+ },
6169
+ total: cumulativeTotalTokens !== null ? { totalTokens: cumulativeTotalTokens } : null,
6170
+ modelContextWindow: maxTokens,
6171
+ updatedAt: event.timestamp
6172
+ });
6173
+ }
6174
+ function extractLatestContextUsage(events, provider) {
6175
+ if (!events || events.length === 0) return null;
6176
+ let latest = null;
6177
+ for (const event of events) {
6178
+ if (event.type === CONTEXT_USAGE_EVENT_TYPE) {
6179
+ const usage = coerceContextUsagePayload(event.payload, event.timestamp);
6180
+ if (usage && usage.provider === normalizeProvider(provider)) {
6181
+ latest = usage;
6182
+ }
6183
+ continue;
6184
+ }
6185
+ if (provider === "codex") {
6186
+ const usage = codexTokenCountToContextUsage(event);
6187
+ if (usage) {
6188
+ latest = usage;
6189
+ }
6190
+ continue;
6191
+ }
6192
+ }
6193
+ return latest;
6194
+ }
6075
6195
 
6076
6196
  // ../shared/src/pricing.ts
6077
6197
  var AUTOMATED_SOURCES = ["api", "automation"];
@@ -6387,7 +6507,7 @@ var MAX_WARM_HOOK_TIMEOUT_MS = 120 * 60 * 1e3;
6387
6507
  var DEFAULT_START_HOOK_TIMEOUT_MS = 5 * 60 * 1e3;
6388
6508
  var DEFAULT_HOOK_OUTPUT_PREVIEW_CHARS = 1e5;
6389
6509
  var HOOK_EXEC_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
6390
- function isRecord2(value) {
6510
+ function isRecord3(value) {
6391
6511
  return typeof value === "object" && value !== null;
6392
6512
  }
6393
6513
  function clampWarmHookTimeoutMs(timeoutMs) {
@@ -6419,7 +6539,7 @@ function parseWarmHookConfig(value, filename = "replicas.json") {
6419
6539
  if (typeof value === "string") {
6420
6540
  return value;
6421
6541
  }
6422
- if (!isRecord2(value)) {
6542
+ if (!isRecord3(value)) {
6423
6543
  throw new Error(`Invalid ${filename}: "warmHook" must be a string or object`);
6424
6544
  }
6425
6545
  if (!Array.isArray(value.commands) || !value.commands.every((entry) => typeof entry === "string")) {
@@ -6446,11 +6566,11 @@ function resolveWarmHookConfig(value) {
6446
6566
 
6447
6567
  // ../shared/src/replicas-config.ts
6448
6568
  var REPLICAS_CONFIG_FILENAMES = ["replicas.json", "replicas.yaml", "replicas.yml"];
6449
- function isRecord3(value) {
6569
+ function isRecord4(value) {
6450
6570
  return typeof value === "object" && value !== null;
6451
6571
  }
6452
6572
  function parseReplicasConfig(value, filename = "replicas.json") {
6453
- if (!isRecord3(value)) {
6573
+ if (!isRecord4(value)) {
6454
6574
  throw new Error(`Invalid ${filename}: expected an object`);
6455
6575
  }
6456
6576
  const config = {};
@@ -6467,7 +6587,7 @@ function parseReplicasConfig(value, filename = "replicas.json") {
6467
6587
  config.systemPrompt = value.systemPrompt;
6468
6588
  }
6469
6589
  if ("startHook" in value) {
6470
- if (!isRecord3(value.startHook)) {
6590
+ if (!isRecord4(value.startHook)) {
6471
6591
  throw new Error(`Invalid ${filename}: "startHook" must be an object with "commands" array`);
6472
6592
  }
6473
6593
  const { commands, timeout, separate } = value.startHook;
@@ -7629,6 +7749,7 @@ export {
7629
7749
  normalizeAutoCompactThreshold,
7630
7750
  clampTokensToWindow,
7631
7751
  buildCodexTokenUsageContextUsagePayload,
7752
+ extractLatestContextUsage,
7632
7753
  fetchModelsDevCatalog,
7633
7754
  SANDBOX_PATHS,
7634
7755
  REPLICAS_RUNTIME_ENV_ALIASES,
@@ -3,12 +3,12 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  monolithRequest
6
- } from "./chunk-NPFAPMJ3.js";
6
+ } from "./chunk-Z3ZWANDZ.js";
7
7
  import {
8
8
  extractCommandProtectionCommandText,
9
9
  findGitCommitSignals,
10
10
  findPrMergeSignals
11
- } from "./chunk-3PHLWZEX.js";
11
+ } from "./chunk-7WLA6QVZ.js";
12
12
 
13
13
  // src/services/command-protection-service.ts
14
14
  var DEFAULT_COMMAND_PROTECTION_BLOCK_MESSAGE = "Blocked by Replicas command protection.";
@@ -5,18 +5,18 @@ import {
5
5
  ENGINE_ENV,
6
6
  monolithRequest,
7
7
  setAgentCredentialSnapshot
8
- } from "./chunk-NPFAPMJ3.js";
8
+ } from "./chunk-Z3ZWANDZ.js";
9
9
  import {
10
10
  AppServerProcess,
11
11
  buildCodexAgentEnv
12
- } from "./chunk-RP4LIWKF.js";
12
+ } from "./chunk-RXBUE7A3.js";
13
13
  import {
14
14
  CODEX_AUTH_ENV_KEYS,
15
15
  CODEX_AUTH_ENV_KEYS_BY_METHOD,
16
16
  codexAuthEnvFromResponse,
17
17
  createErrorResult,
18
18
  createSuccessResult
19
- } from "./chunk-3PHLWZEX.js";
19
+ } from "./chunk-7WLA6QVZ.js";
20
20
 
21
21
  // src/managers/codex-token-manager.ts
22
22
  import { promises as fs } from "fs";
@@ -232,7 +232,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
232
232
  const data = await response.json();
233
233
  await this.applyCredentialsResponse(data);
234
234
  if (restartOnChange && CODEX_AUTH_ENV_KEYS.some((key, index) => process.env[key] !== previousEnv[index])) {
235
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-HKSTCW5T.js");
235
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-LDNP6IN6.js");
236
236
  await restartCodexAspHostIfRunning2();
237
237
  }
238
238
  if (data.scope) {
@@ -4,7 +4,7 @@ const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  HOOK_EXEC_MAX_BUFFER_BYTES,
6
6
  isVersionBelow
7
- } from "./chunk-3PHLWZEX.js";
7
+ } from "./chunk-7WLA6QVZ.js";
8
8
 
9
9
  // src/utils/codex-agent-env.ts
10
10
  function buildCodexAgentEnv(source = process.env) {
@@ -241,7 +241,7 @@ var DEFAULT_CODEX_ARGS = [
241
241
  var MIN_CODEX_CLI_VERSION = "0.153.3";
242
242
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
243
243
  var codexCliVersionEnsured = null;
244
- var ENGINE_PACKAGE_VERSION = "0.1.776";
244
+ var ENGINE_PACKAGE_VERSION = "0.1.778";
245
245
  var INITIALIZE_METHOD = "initialize";
246
246
  var INITIALIZED_NOTIFICATION = "initialized";
247
247
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -4,7 +4,7 @@ const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  findCodeHostPullRequestUrls,
6
6
  mayCreatePullRequest
7
- } from "./chunk-3PHLWZEX.js";
7
+ } from "./chunk-7WLA6QVZ.js";
8
8
 
9
9
  // src/services/post-tool-pr-notifier.ts
10
10
  async function notifyPostToolUse(toolName, toolInput, toolResult) {
@@ -15,7 +15,7 @@ import {
15
15
  isValidRelayBaseProvider,
16
16
  parsePosixEnvFile,
17
17
  readReplicasRuntimeEnv
18
- } from "./chunk-3PHLWZEX.js";
18
+ } from "./chunk-7WLA6QVZ.js";
19
19
 
20
20
  // src/engine-env.ts
21
21
  import { readFileSync as readFileSync2 } from "fs";
@@ -3,12 +3,12 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  evaluateCommandProtection
6
- } from "./chunk-GICTTMFH.js";
7
- import "./chunk-NPFAPMJ3.js";
6
+ } from "./chunk-DTXZFR5B.js";
7
+ import "./chunk-Z3ZWANDZ.js";
8
8
  import {
9
9
  isRecord
10
10
  } from "./chunk-UZSNFLDQ.js";
11
- import "./chunk-3PHLWZEX.js";
11
+ import "./chunk-7WLA6QVZ.js";
12
12
  import "./chunk-VEQXQN22.js";
13
13
 
14
14
  // src/command-protection-hook.ts
@@ -3,13 +3,13 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  evaluateCommandProtection
6
- } from "./chunk-GICTTMFH.js";
6
+ } from "./chunk-DTXZFR5B.js";
7
7
  import {
8
8
  notifyPostToolUse
9
- } from "./chunk-OX5DTL5R.js";
10
- import "./chunk-NPFAPMJ3.js";
9
+ } from "./chunk-XAJWJBND.js";
10
+ import "./chunk-Z3ZWANDZ.js";
11
11
  import "./chunk-UZSNFLDQ.js";
12
- import "./chunk-3PHLWZEX.js";
12
+ import "./chunk-7WLA6QVZ.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
 
15
15
  // src/deepseek-command-protection-plugin.ts
@@ -8,12 +8,12 @@ import {
8
8
  import {
9
9
  AppServerProcess,
10
10
  buildCodexAgentEnv
11
- } from "./chunk-RP4LIWKF.js";
11
+ } from "./chunk-RXBUE7A3.js";
12
12
  import {
13
13
  AGENT,
14
14
  getMemoryOutputSafetyViolation,
15
15
  headlessAgentRequestSchema
16
- } from "./chunk-3PHLWZEX.js";
16
+ } from "./chunk-7WLA6QVZ.js";
17
17
  import "./chunk-VEQXQN22.js";
18
18
 
19
19
  // src/headless-agent.ts
package/dist/src/index.js CHANGED
@@ -91,7 +91,7 @@ import {
91
91
  evaluateCommandProtection,
92
92
  extractToolCommand,
93
93
  reportCommandProtectionBlock
94
- } from "./chunk-GICTTMFH.js";
94
+ } from "./chunk-DTXZFR5B.js";
95
95
  import {
96
96
  ACCOUNT_RATE_LIMITS_UPDATED_METHOD,
97
97
  AGENT_MESSAGE_DELTA_METHOD,
@@ -124,20 +124,20 @@ import {
124
124
  recordCredentialFallback,
125
125
  recordExhaustedCredential,
126
126
  restartCodexAspHost
127
- } from "./chunk-OVQGTUPL.js";
127
+ } from "./chunk-PRDBLI2T.js";
128
128
  import {
129
129
  ENGINE_ENV,
130
130
  IS_WARMING_MODE,
131
131
  monolithRequest,
132
132
  monolithService,
133
133
  setAgentCredentialSnapshot
134
- } from "./chunk-NPFAPMJ3.js";
134
+ } from "./chunk-Z3ZWANDZ.js";
135
135
  import {
136
136
  AspClient,
137
137
  SUBPROCESS_MAX_BUFFER,
138
138
  execAsync,
139
139
  execFileAsync
140
- } from "./chunk-RP4LIWKF.js";
140
+ } from "./chunk-RXBUE7A3.js";
141
141
  import {
142
142
  isRecord as isRecord2
143
143
  } from "./chunk-UZSNFLDQ.js";
@@ -252,6 +252,7 @@ import {
252
252
  detectLanguageByPath,
253
253
  excludeQueuedAcceptedEvents,
254
254
  extractErrorText,
255
+ extractLatestContextUsage,
255
256
  extractToolResultText,
256
257
  fetchAiGatewayModels,
257
258
  fetchModelsDevCatalog,
@@ -337,7 +338,7 @@ import {
337
338
  spawnRelaySubagentRequestSchema,
338
339
  stripAgentDiagnosticErrors,
339
340
  withTimeout
340
- } from "./chunk-3PHLWZEX.js";
341
+ } from "./chunk-7WLA6QVZ.js";
341
342
  import {
342
343
  __commonJS,
343
344
  __export,
@@ -10655,7 +10656,7 @@ import { join as join37 } from "path";
10655
10656
  import { randomUUID as randomUUID13 } from "crypto";
10656
10657
 
10657
10658
  // ../shared/src/workspace-chat.ts
10658
- var WORKSPACE_CHATS_QUERY_SCHEMA_VERSION = 2;
10659
+ var WORKSPACE_CHATS_QUERY_SCHEMA_VERSION = 3;
10659
10660
  var WORKSPACE_CHATS_QUERY_ROOT = `workspace-chats:v${WORKSPACE_CHATS_QUERY_SCHEMA_VERSION}`;
10660
10661
  function isAcceptedUserMessage(event) {
10661
10662
  return getUserMessage(event) !== null && event.payload.source === ACCEPTED_USER_MESSAGE_SOURCE;
@@ -61368,6 +61369,7 @@ function normalizePersistedChat(chat) {
61368
61369
  return {
61369
61370
  id: chat.id,
61370
61371
  provider: chat.provider,
61372
+ ...typeof chat.model === "string" && chat.model ? { model: chat.model } : {},
61371
61373
  ...chat.provider === "relay" ? { relayBaseProvider: getChatExecutionProvider(chat) } : {},
61372
61374
  title: chat.title,
61373
61375
  createdAt: chat.createdAt,
@@ -61605,9 +61607,14 @@ var ChatService = class {
61605
61607
  const accepting2 = chat.acceptingSendResponses.get(idempotencyKey);
61606
61608
  if (accepting2) return accepting2;
61607
61609
  }
61610
+ const previousAcceptance = chat.lastSendAcceptance;
61608
61611
  const accepting = (async () => {
61609
61612
  chat.acceptingMessages += 1;
61610
61613
  try {
61614
+ await previousAcceptance?.catch(() => {
61615
+ });
61616
+ const savedModel = chat.persisted.model ?? (!request.model ? extractLatestContextUsage((await chat.provider.getHistory()).events, getChatExecutionProvider(chat.persisted))?.model : void 0);
61617
+ request = { ...request, model: request.model ?? savedModel ?? void 0 };
61611
61618
  return await chat.provider.enqueueMessage(
61612
61619
  request,
61613
61620
  (result, acceptedMessage) => this.handleMessageAccepted(
@@ -61622,6 +61629,7 @@ var ChatService = class {
61622
61629
  chat.acceptingMessages -= 1;
61623
61630
  }
61624
61631
  })();
61632
+ chat.lastSendAcceptance = accepting;
61625
61633
  if (!idempotencyKey) return accepting;
61626
61634
  chat.acceptingSendResponses.set(idempotencyKey, accepting);
61627
61635
  try {
@@ -61649,6 +61657,7 @@ var ChatService = class {
61649
61657
  const previousAcceptedEvent = chat.acceptedUserEvents.get(result.messageId);
61650
61658
  const previousPersistedResponses = chat.persisted.acceptedSendResponses;
61651
61659
  const previousLastMessageText = chat.persisted.lastMessageText;
61660
+ const previousModel = chat.persisted.model;
61652
61661
  const previousUpdatedAt = chat.persisted.updatedAt;
61653
61662
  const idempotencyKey = request.idempotencyKey ?? request.messageId;
61654
61663
  if (idempotencyKey) {
@@ -61666,6 +61675,7 @@ var ChatService = class {
61666
61675
  chat.acceptedUserEvents.set(result.messageId, acceptedEvent);
61667
61676
  }
61668
61677
  chat.persisted.lastMessageText = request.message.trim().slice(0, LAST_MESSAGE_PREVIEW_MAX) || null;
61678
+ chat.persisted.model = acceptedMessage.model ?? previousModel;
61669
61679
  chat.persisted.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
61670
61680
  try {
61671
61681
  await this.persistAllChats();
@@ -61679,6 +61689,7 @@ var ChatService = class {
61679
61689
  else chat.acceptedUserEvents.delete(result.messageId);
61680
61690
  chat.persisted.acceptedSendResponses = previousPersistedResponses;
61681
61691
  chat.persisted.lastMessageText = previousLastMessageText;
61692
+ chat.persisted.model = previousModel;
61682
61693
  chat.persisted.updatedAt = previousUpdatedAt;
61683
61694
  throw new ChatMessagePersistenceError(error);
61684
61695
  }
@@ -61701,6 +61712,9 @@ var ChatService = class {
61701
61712
  ...recordedSender ? { sender: recordedSender } : {}
61702
61713
  }
61703
61714
  });
61715
+ if (chat.persisted.model !== previousModel) {
61716
+ await this.publish({ type: "chat.updated", payload: { chat: this.toSummary(chat) } });
61717
+ }
61704
61718
  }
61705
61719
  async appendSender(chatId, sender) {
61706
61720
  try {
@@ -62295,6 +62309,7 @@ var ChatService = class {
62295
62309
  return {
62296
62310
  id: chat.persisted.id,
62297
62311
  provider: chat.persisted.provider,
62312
+ model: chat.persisted.model,
62298
62313
  ...chat.persisted.provider === "relay" ? { relayBaseProvider: getChatExecutionProvider(chat.persisted) } : {},
62299
62314
  title: chat.persisted.title,
62300
62315
  createdAt: chat.persisted.createdAt,
@@ -3,11 +3,11 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  notifyPostToolUse
6
- } from "./chunk-OX5DTL5R.js";
6
+ } from "./chunk-XAJWJBND.js";
7
7
  import {
8
8
  isRecord
9
9
  } from "./chunk-UZSNFLDQ.js";
10
- import "./chunk-3PHLWZEX.js";
10
+ import "./chunk-7WLA6QVZ.js";
11
11
  import "./chunk-VEQXQN22.js";
12
12
 
13
13
  // src/post-tool-pr-hook.ts
@@ -4,7 +4,7 @@ const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  messageRelaySubagentRequestSchema,
6
6
  spawnRelaySubagentRequestSchema
7
- } from "./chunk-3PHLWZEX.js";
7
+ } from "./chunk-7WLA6QVZ.js";
8
8
  import "./chunk-VEQXQN22.js";
9
9
 
10
10
  // src/relay-mcp.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.776",
3
+ "version": "0.1.778",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",