replicas-engine 0.1.1021 → 0.1.1023

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,12 +5,12 @@ import {
5
5
  getCodexAspHost,
6
6
  restartCodexAspHost,
7
7
  restartCodexAspHostIfRunning
8
- } from "./chunk-UTFC3WOD.js";
9
- import "./chunk-EAHICWAF.js";
10
- import "./chunk-NUYJXEFQ.js";
11
- import "./chunk-VAHRPTDQ.js";
8
+ } from "./chunk-6PFWQN6N.js";
9
+ import "./chunk-IFF7ILWV.js";
10
+ import "./chunk-46VEUNV3.js";
11
+ import "./chunk-LBEKAKM7.js";
12
12
  import "./chunk-UZSNFLDQ.js";
13
- import "./chunk-JEOHY7BW.js";
13
+ import "./chunk-EARIHQMZ.js";
14
14
  import "./chunk-VEQXQN22.js";
15
15
  export {
16
16
  getCodexAspHost,
@@ -3,10 +3,10 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  execFileAsync
6
- } from "./chunk-VAHRPTDQ.js";
6
+ } from "./chunk-LBEKAKM7.js";
7
7
  import {
8
8
  isVersionBelow
9
- } from "./chunk-JEOHY7BW.js";
9
+ } from "./chunk-EARIHQMZ.js";
10
10
 
11
11
  // src/utils/codex-agent-env.ts
12
12
  function buildCodexAgentEnv(source = process.env) {
@@ -240,7 +240,7 @@ function getCodexModelProvider(method) {
240
240
  if (method === "foundry") return "azure";
241
241
  return method === "ollama" || method === "openai-compatible" ? "replicas_openai_compatible" : "openai";
242
242
  }
243
- var ENGINE_PACKAGE_VERSION = "0.1.1021";
243
+ var ENGINE_PACKAGE_VERSION = "0.1.1023";
244
244
  var INITIALIZE_METHOD = "initialize";
245
245
  var INITIALIZED_NOTIFICATION = "initialized";
246
246
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -5,15 +5,15 @@ import {
5
5
  ENGINE_ENV,
6
6
  monolithRequest,
7
7
  setAgentCredentialSnapshot
8
- } from "./chunk-EAHICWAF.js";
8
+ } from "./chunk-IFF7ILWV.js";
9
9
  import {
10
10
  AppServerProcess,
11
11
  buildCodexAgentEnv
12
- } from "./chunk-NUYJXEFQ.js";
12
+ } from "./chunk-46VEUNV3.js";
13
13
  import {
14
14
  SUBPROCESS_MAX_BUFFER,
15
15
  execFileAsync
16
- } from "./chunk-VAHRPTDQ.js";
16
+ } from "./chunk-LBEKAKM7.js";
17
17
  import {
18
18
  isRecord
19
19
  } from "./chunk-UZSNFLDQ.js";
@@ -28,7 +28,7 @@ import {
28
28
  listOpenAICompatibleModels,
29
29
  readOllamaAuthEnv,
30
30
  resolveOpenAICompatibleModelsUrl
31
- } from "./chunk-JEOHY7BW.js";
31
+ } from "./chunk-EARIHQMZ.js";
32
32
 
33
33
  // src/managers/codex-token-manager.ts
34
34
  import { promises as fs } from "fs";
@@ -264,7 +264,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
264
264
  await this.applyCredentialUpdate(++this.credentialGeneration, async () => {
265
265
  await this.applyCredentialsResponse(data);
266
266
  setAgentCredentialSnapshot("codex", data);
267
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-2QL45RQM.js");
267
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-LNQ6477C.js");
268
268
  await restartCodexAspHostIfRunning2();
269
269
  });
270
270
  await this.start(true);
@@ -285,7 +285,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
285
285
  const accountChanged = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.codex?.credentialId !== data.credentialId;
286
286
  await this.applyCredentialsResponse(data);
287
287
  if (restartOnChange && (accountChanged || CODEX_AUTH_ENV_KEYS.some((key, index) => process.env[key] !== previousEnv[index]))) {
288
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-2QL45RQM.js");
288
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-LNQ6477C.js");
289
289
  await restartCodexAspHostIfRunning2();
290
290
  }
291
291
  setAgentCredentialSnapshot("codex", data);
@@ -3,18 +3,18 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  monolithRequest
6
- } from "./chunk-EAHICWAF.js";
6
+ } from "./chunk-IFF7ILWV.js";
7
7
  import {
8
8
  SUBPROCESS_MAX_BUFFER,
9
9
  execFileAsync
10
- } from "./chunk-VAHRPTDQ.js";
10
+ } from "./chunk-LBEKAKM7.js";
11
11
  import {
12
12
  extractCommandProtectionCommandText,
13
13
  findCommandProtectionGitLookups,
14
14
  findGitCommitSignals,
15
15
  findPrMergeSignals,
16
16
  parseCommandProtectionRequest
17
- } from "./chunk-JEOHY7BW.js";
17
+ } from "./chunk-EARIHQMZ.js";
18
18
 
19
19
  // src/services/command-protection-service.ts
20
20
  import { readFile, stat } from "fs/promises";
@@ -5,7 +5,7 @@ import {
5
5
  extractCommandProtectionCommandText,
6
6
  isRecord,
7
7
  parseCodeHostPrUrl
8
- } from "./chunk-JEOHY7BW.js";
8
+ } from "./chunk-EARIHQMZ.js";
9
9
 
10
10
  // src/services/published-pull-request-urls.ts
11
11
  function publishedPullRequestUrls(result) {
@@ -39,13 +39,6 @@ var SUBAGENT_MCP_HARNESSES = [AGENT.CLAUDE, AGENT.CODEX];
39
39
  function isValidAgentProvider(value) {
40
40
  return VALID_AGENT_PROVIDERS.some((p) => p === value);
41
41
  }
42
- var LEGACY_RELAY_BASE_PROVIDERS = [AGENT.CLAUDE, AGENT.CODEX, AGENT.OPENCODE, AGENT.PI];
43
- function normalizeLegacyChatProvider(provider, relayBaseProvider) {
44
- if (provider === "relay") {
45
- return LEGACY_RELAY_BASE_PROVIDERS.find((base) => base === relayBaseProvider) ?? AGENT.CLAUDE;
46
- }
47
- return isValidAgentProvider(provider) ? provider : null;
48
- }
49
42
  var VALID_THINKING_LEVELS = ["low", "medium", "high", "xhigh", "max", "ultra", "ultracode"];
50
43
  var STANDARD_THINKING_LEVELS = ["low", "medium", "high", "xhigh", "max"];
51
44
  var THINKING_LEVELS_BY_AGENT = {
@@ -56,9 +49,6 @@ var THINKING_LEVELS_BY_AGENT = {
56
49
  opencode: STANDARD_THINKING_LEVELS,
57
50
  pi: STANDARD_THINKING_LEVELS
58
51
  };
59
- function isValidThinkingLevel(value) {
60
- return VALID_THINKING_LEVELS.some((l) => l === value);
61
- }
62
52
  var CODEX_REASONING_EFFORT_BY_THINKING_LEVEL = {
63
53
  low: "low",
64
54
  medium: "medium",
@@ -196,6 +186,7 @@ var CLAUDE_OPUS_5_MODEL = "claude-opus-5";
196
186
  var CLAUDE_OPUS_4_8_MODEL = "claude-opus-4-8";
197
187
  var CLAUDE_SONNET_5_5_MODEL = "claude-sonnet-5-5";
198
188
  var CLAUDE_SONNET_5_MODEL = "claude-sonnet-5";
189
+ var CLAUDE_HAIKU_5_5_MODEL = "claude-haiku-5-5";
199
190
  var CLAUDE_HAIKU_4_5_MODEL = "claude-haiku-4-5";
200
191
  var CLAUDE_FABLE_5_1_BEDROCK_MODEL = "anthropic.claude-fable-5-1";
201
192
  var CLAUDE_FABLE_5_BEDROCK_MODEL = "anthropic.claude-fable-5";
@@ -204,6 +195,7 @@ var CLAUDE_OPUS_5_BEDROCK_MODEL = "anthropic.claude-opus-5";
204
195
  var CLAUDE_OPUS_4_8_BEDROCK_MODEL = "us.anthropic.claude-opus-4-8";
205
196
  var CLAUDE_SONNET_5_5_BEDROCK_MODEL = "anthropic.claude-sonnet-5-5";
206
197
  var CLAUDE_SONNET_5_BEDROCK_MODEL = "anthropic.claude-sonnet-5";
198
+ var CLAUDE_HAIKU_5_5_BEDROCK_MODEL = "anthropic.claude-haiku-5-5";
207
199
  var CLAUDE_HAIKU_4_5_BEDROCK_MODEL = "us.anthropic.claude-haiku-4-5-20251001-v1:0";
208
200
  var DEFAULT_CLAUDE_MODEL = CLAUDE_OPUS_5_5_MODEL;
209
201
  var GPT_6_ASTRA_MODEL = "gpt-6-astra";
@@ -248,7 +240,7 @@ function getDefaultAgentModel(provider, overrides) {
248
240
  const options = getAgentModelOptions(provider, overrides);
249
241
  if (catalogDefault && options.includes(catalogDefault)) return catalogDefault;
250
242
  const fallback = FALLBACK_AGENT_MODEL[provider];
251
- return options.includes(fallback) ? fallback : options[0];
243
+ return options.includes(fallback) ? fallback : options[0] ?? "";
252
244
  }
253
245
  function normalizeClaudeModel(model) {
254
246
  if (model === "opus" || model === CLAUDE_OPUS_1M_MODEL || model === LEGACY_CLAUDE_OPUS_1M_MODEL) {
@@ -284,6 +276,8 @@ function toClaudeCodeModel(model, bedrock) {
284
276
  return CLAUDE_SONNET_5_5_BEDROCK_MODEL;
285
277
  case CLAUDE_SONNET_5_MODEL:
286
278
  return "sonnet";
279
+ case CLAUDE_HAIKU_5_5_MODEL:
280
+ return CLAUDE_HAIKU_5_5_BEDROCK_MODEL;
287
281
  case CLAUDE_HAIKU_4_5_MODEL:
288
282
  return "haiku";
289
283
  default:
@@ -298,6 +292,7 @@ var CLAUDE_MODEL_CONTEXT_WINDOWS = {
298
292
  [CLAUDE_OPUS_4_8_MODEL]: 1e6,
299
293
  [CLAUDE_SONNET_5_5_MODEL]: 1e6,
300
294
  [CLAUDE_SONNET_5_MODEL]: 1e6,
295
+ [CLAUDE_HAIKU_5_5_MODEL]: 1e6,
301
296
  [CLAUDE_HAIKU_4_5_MODEL]: 2e5,
302
297
  [CLAUDE_FABLE_5_1_BEDROCK_MODEL]: 1e6,
303
298
  [CLAUDE_FABLE_5_BEDROCK_MODEL]: 1e6,
@@ -306,6 +301,7 @@ var CLAUDE_MODEL_CONTEXT_WINDOWS = {
306
301
  [CLAUDE_OPUS_4_8_BEDROCK_MODEL]: 1e6,
307
302
  [CLAUDE_SONNET_5_5_BEDROCK_MODEL]: 1e6,
308
303
  [CLAUDE_SONNET_5_BEDROCK_MODEL]: 1e6,
304
+ [CLAUDE_HAIKU_5_5_BEDROCK_MODEL]: 1e6,
309
305
  [CLAUDE_HAIKU_4_5_BEDROCK_MODEL]: 2e5,
310
306
  "anthropic.claude-opus-4-8": 1e6,
311
307
  "us.anthropic.claude-sonnet-5": 1e6,
@@ -322,18 +318,33 @@ function canUseClaudeFastMode(model) {
322
318
  const normalized = normalizeClaudeModel(model);
323
319
  return normalized === CLAUDE_OPUS_5_5_MODEL || normalized === CLAUDE_OPUS_5_MODEL || normalized === CLAUDE_OPUS_4_8_MODEL || model === "claude-opus-4-7";
324
320
  }
321
+ var CLAUDE_MODEL_MIN_SANDBOX_IMAGE = {
322
+ [CLAUDE_FABLE_5_1_MODEL]: "replicas-sandbox-2026-09-01-v6",
323
+ [CLAUDE_FABLE_5_MODEL]: null,
324
+ [CLAUDE_OPUS_5_5_MODEL]: "replicas-sandbox-2026-09-22-v4",
325
+ [CLAUDE_OPUS_5_MODEL]: null,
326
+ [CLAUDE_OPUS_4_8_MODEL]: null,
327
+ [CLAUDE_SONNET_5_5_MODEL]: "replicas-sandbox-2026-09-28-v7",
328
+ [CLAUDE_SONNET_5_MODEL]: null,
329
+ [CLAUDE_HAIKU_5_5_MODEL]: "replicas-sandbox-2026-10-08-v4",
330
+ [CLAUDE_HAIKU_4_5_MODEL]: null
331
+ };
332
+ var CODEX_MODEL_MIN_SANDBOX_IMAGE = {
333
+ [DEFAULT_CODEX_MODEL]: "replicas-sandbox-2026-09-30-v11",
334
+ [GPT_6_SOL_MODEL]: "replicas-sandbox-2026-09-24-v1",
335
+ [GPT_6_ASTRA_MODEL]: "replicas-sandbox-2026-09-04-v7",
336
+ [GPT_6_LUNA_MODEL]: "replicas-sandbox-2026-09-24-v1",
337
+ [GPT_5_6_SOL_MODEL]: null,
338
+ [GPT_5_6_TERRA_MODEL]: null,
339
+ [GPT_5_6_LUNA_MODEL]: null,
340
+ "gpt-5.5": null,
341
+ "gpt-5.4": null,
342
+ "gpt-5.4-mini": null,
343
+ "gpt-5.2": null
344
+ };
325
345
  var AGENT_MODELS = {
326
- claude: [
327
- CLAUDE_FABLE_5_1_MODEL,
328
- CLAUDE_FABLE_5_MODEL,
329
- CLAUDE_OPUS_5_5_MODEL,
330
- CLAUDE_OPUS_5_MODEL,
331
- CLAUDE_OPUS_4_8_MODEL,
332
- CLAUDE_SONNET_5_5_MODEL,
333
- CLAUDE_SONNET_5_MODEL,
334
- CLAUDE_HAIKU_4_5_MODEL
335
- ],
336
- codex: [DEFAULT_CODEX_MODEL, GPT_6_SOL_MODEL, GPT_6_ASTRA_MODEL, GPT_6_LUNA_MODEL, GPT_5_6_SOL_MODEL, GPT_5_6_TERRA_MODEL, GPT_5_6_LUNA_MODEL, "gpt-5.5", "gpt-5.4", "gpt-5.4-mini", "gpt-5.2"],
346
+ claude: Object.keys(CLAUDE_MODEL_MIN_SANDBOX_IMAGE),
347
+ codex: Object.keys(CODEX_MODEL_MIN_SANDBOX_IMAGE),
337
348
  cursor: [
338
349
  CLAUDE_FABLE_5_1_MODEL,
339
350
  CLAUDE_FABLE_5_MODEL,
@@ -410,22 +421,12 @@ function getAgentModelOptions(provider, overrides) {
410
421
  if (override?.length) return override;
411
422
  if (provider === "claude" || provider === "codex") return DEFAULT_STATIC_AGENT_MODELS[provider];
412
423
  if (provider === "cursor") return DEFAULT_CURSOR_MODELS;
413
- return AGENT_MODELS[provider];
424
+ return AGENT_MODELS[provider] ?? [];
414
425
  }
415
- var CLAUDE_MODEL_MIN_SANDBOX_IMAGE = {
416
- [CLAUDE_FABLE_5_1_MODEL]: "replicas-sandbox-2026-09-01-v6",
417
- [CLAUDE_OPUS_5_5_MODEL]: "replicas-sandbox-2026-09-22-v4",
418
- [CLAUDE_SONNET_5_5_MODEL]: "replicas-sandbox-2026-09-28-v7"
419
- };
420
- var CODEX_MODEL_MIN_SANDBOX_IMAGE = {
421
- [GPT_6_ASTRA_MODEL]: "replicas-sandbox-2026-09-04-v7",
422
- [GPT_6_1_SOL_MODEL]: "replicas-sandbox-2026-09-30-v11",
423
- [GPT_6_SOL_MODEL]: "replicas-sandbox-2026-09-24-v1",
424
- [GPT_6_LUNA_MODEL]: "replicas-sandbox-2026-09-24-v1"
425
- };
426
426
  var SANDBOX_IMAGE_MODEL_FALLBACKS = {
427
427
  [CLAUDE_OPUS_5_5_MODEL]: CLAUDE_OPUS_5_MODEL,
428
428
  [CLAUDE_SONNET_5_5_MODEL]: CLAUDE_SONNET_5_MODEL,
429
+ [CLAUDE_HAIKU_5_5_MODEL]: CLAUDE_HAIKU_4_5_MODEL,
429
430
  [GPT_6_1_SOL_MODEL]: GPT_6_SOL_MODEL,
430
431
  [GPT_6_SOL_MODEL]: GPT_5_6_SOL_MODEL,
431
432
  [GPT_6_ASTRA_MODEL]: GPT_5_6_TERRA_MODEL,
@@ -479,6 +480,7 @@ var MODEL_LABELS = {
479
480
  "composer-2.5": "Composer 2.5",
480
481
  [CLAUDE_OPUS_4_8_MODEL]: "Opus 4.8",
481
482
  "claude-opus-4-7": "Opus 4.7",
483
+ [CLAUDE_HAIKU_5_5_MODEL]: "Haiku 5.5",
482
484
  [CLAUDE_HAIKU_4_5_MODEL]: "Haiku 4.5",
483
485
  "gemini-3.8-flash": "Gemini 3.8 Flash",
484
486
  "gemini-3.1-pro": "Gemini 3.1 Pro",
@@ -910,6 +912,9 @@ function getCredentialMethodLabel(agent, method) {
910
912
  var WORKSPACE_SOURCES = ["api", "dashboard", "slack", "linear", "github", "gitlab", "automation", "mothership"];
911
913
  var CLIENT_MESSAGE_SOURCES = ["web", "desktop", "mobile", "tui"];
912
914
  var MESSAGE_SOURCES = [...CLIENT_MESSAGE_SOURCES, ...WORKSPACE_SOURCES];
915
+ function isClientMessageSource(value) {
916
+ return typeof value === "string" && CLIENT_MESSAGE_SOURCES.some((source) => source === value);
917
+ }
913
918
  function isMessageSource(value) {
914
919
  return typeof value === "string" && MESSAGE_SOURCES.some((source) => source === value);
915
920
  }
@@ -1924,7 +1929,7 @@ var quotaLimitKindSchema = z8.enum(["rate_limit", "out_of_credits"]);
1924
1929
  var chatForkInfoSchema = z8.object({
1925
1930
  source: z8.object({
1926
1931
  chatId: z8.string().min(1),
1927
- provider: z8.string().transform((provider, ctx) => normalizeLegacyChatProvider(provider) ?? (ctx.addIssue({ code: "custom" }), z8.NEVER)),
1932
+ provider: z8.enum(VALID_AGENT_PROVIDERS),
1928
1933
  title: z8.string()
1929
1934
  }),
1930
1935
  trigger: z8.enum(["manual", "auto", "side"]),
@@ -2523,7 +2528,6 @@ ${operation.diff}` : ""}`).join("\n\n");
2523
2528
  return { kind: "plan", title: "Plan", summary: `${items.filter((item) => item.status === "completed").length}/${items.length}`, content: "", items };
2524
2529
  }
2525
2530
  if (message.type === "subagent") return { kind: "task", title: "Subagent", summary: message.description, content: [message.prompt, message.model ? `Model: ${message.model}` : "", message.receiverThreadIds?.length ? `Threads: ${message.receiverThreadIds.join(", ")}` : "", message.output].filter(Boolean).join("\n\n") };
2526
- if (message.type === "subagent_followup") return { kind: "task", title: "Subagent follow-up", summary: message.targetTitle ?? message.chatId, content: [message.message, message.output].filter(Boolean).join("\n\n") };
2527
2531
  if (message.type === "background_task") return { kind: "task", title: message.description ?? message.summary ?? "Background task", summary: message.taskType ?? "", content: [message.prompt, message.outputFile, message.error].filter(Boolean).join("\n\n") };
2528
2532
  if (message.type === "skill") return { kind: "tool", title: `Skill \xB7 ${message.skillName}`, summary: message.args ?? "", content: "" };
2529
2533
  if (message.type === "quota_status") {
@@ -4935,6 +4939,11 @@ var DEFAULT_DEFAULT_SKILLS = {
4935
4939
 
4936
4940
  // ../shared/src/prompts.ts
4937
4941
  var REPLICAS_INSTRUCTIONS_TAG = "replicas_instructions";
4942
+ function wrapInTag(content, tag) {
4943
+ return `<${tag}>
4944
+ ${content}
4945
+ </${tag}>`;
4946
+ }
4938
4947
  function removeTag(text2, tag) {
4939
4948
  const regex = new RegExp(`<${tag}>[\\s\\S]*?</${tag}>`, "g");
4940
4949
  return text2.replace(regex, "").trim();
@@ -6209,19 +6218,6 @@ var TaskAccumulator = class {
6209
6218
  }
6210
6219
  };
6211
6220
 
6212
- // ../shared/src/display-message/parsers/mcp.ts
6213
- function parseMcpToolName(name) {
6214
- const prefix = "mcp__";
6215
- if (!name.startsWith(prefix)) return null;
6216
- const rest = name.slice(prefix.length);
6217
- const sep = rest.indexOf("__");
6218
- if (sep <= 0) return null;
6219
- const server = rest.slice(0, sep);
6220
- const tool = rest.slice(sep + 2);
6221
- if (!server || !tool) return null;
6222
- return { server, tool };
6223
- }
6224
-
6225
6221
  // ../shared/src/display-message/parsers/claude-parser.ts
6226
6222
  var ABORTED_TERMINAL_REASONS = /* @__PURE__ */ new Set(["aborted_streaming", "aborted_tools"]);
6227
6223
  var COMMAND_TOOL_NAMES = /* @__PURE__ */ new Set(["Bash", "bash", "shell"]);
@@ -6571,48 +6567,6 @@ function parseClaudeEvents(events, parentToolUseId) {
6571
6567
  status: "in_progress",
6572
6568
  timestamp: event.timestamp
6573
6569
  });
6574
- } else if (toolName === "mcp__relay-subagent-tools__spawn_agent") {
6575
- const inputObj = typeof toolInput === "string" ? safeJsonParse(toolInput, {}) : toolInput;
6576
- const provider = typeof inputObj.provider === "string" ? inputObj.provider : "unknown";
6577
- const prompt = typeof inputObj.prompt === "string" ? inputObj.prompt : "";
6578
- const model = typeof inputObj.model === "string" ? inputObj.model : void 0;
6579
- const title = typeof inputObj.title === "string" ? inputObj.title : void 0;
6580
- messages.push(createSubagentMessage(messages.length, event.timestamp, {
6581
- toolUseId,
6582
- description: title || `Relay subagent (${provider})`,
6583
- prompt,
6584
- subagentType: provider,
6585
- model,
6586
- thinkingLevel: isValidThinkingLevel(inputObj.thinking_level) ? inputObj.thinking_level : void 0,
6587
- status: "in_progress",
6588
- nestedEvents: [],
6589
- isChatBased: true
6590
- }));
6591
- } else if (toolName === "mcp__relay-subagent-tools__message_agent") {
6592
- const inputObj = typeof toolInput === "string" ? safeJsonParse(toolInput, {}) : toolInput;
6593
- messages.push({
6594
- id: `subagent-followup-${event.timestamp}-${messages.length}`,
6595
- type: "subagent_followup",
6596
- toolUseId,
6597
- chatId: typeof inputObj.chatId === "string" ? inputObj.chatId : "",
6598
- message: typeof inputObj.message === "string" ? inputObj.message : "",
6599
- model: typeof inputObj.model === "string" ? inputObj.model : void 0,
6600
- thinkingLevel: isValidThinkingLevel(inputObj.thinking_level) ? inputObj.thinking_level : void 0,
6601
- status: "in_progress",
6602
- timestamp: event.timestamp
6603
- });
6604
- } else if (toolName === "mcp__relay-subagent-tools__delete_agent") {
6605
- const inputObj = typeof toolInput === "string" ? safeJsonParse(toolInput, {}) : toolInput;
6606
- const mcp = parseMcpToolName(toolName);
6607
- messages.push({
6608
- id: `toolcall-${event.timestamp}-${messages.length}`,
6609
- type: "tool_call",
6610
- server: mcp?.server ?? "relay-subagent-tools",
6611
- tool: mcp?.tool ?? "delete_agent",
6612
- input: inputObj,
6613
- status: "in_progress",
6614
- timestamp: event.timestamp
6615
- });
6616
6570
  } else {
6617
6571
  messages.push({
6618
6572
  id: `toolcall-${event.timestamp}-${messages.length}`,
@@ -6774,15 +6728,6 @@ function parseClaudeEvents(events, parentToolUseId) {
6774
6728
  } else if (message.type === "subagent") {
6775
6729
  message.output = resultContent;
6776
6730
  message.status = status;
6777
- if (!message.chatId && resultContent) {
6778
- const parsed = safeJsonParse(resultContent, {});
6779
- if (parsed.chatId) {
6780
- message.chatId = parsed.chatId;
6781
- }
6782
- }
6783
- } else if (message.type === "subagent_followup") {
6784
- message.output = resultContent;
6785
- message.status = status;
6786
6731
  }
6787
6732
  });
6788
6733
  for (const message of messages) {
@@ -6795,12 +6740,6 @@ function parseClaudeEvents(events, parentToolUseId) {
6795
6740
  message.subagentType ??= toolMessage.subagentType;
6796
6741
  }
6797
6742
  }
6798
- if (message.type !== "subagent_followup") continue;
6799
- const target = messages.find((candidate) => candidate.type === "subagent" && candidate.chatId === message.chatId);
6800
- if (target?.type === "subagent") {
6801
- message.targetTitle = target.description;
6802
- message.targetProvider = target.subagentType;
6803
- }
6804
6743
  }
6805
6744
  const staleIndexes = new Set(supersededUserMessageIndexes);
6806
6745
  for (const streamId of [...completedStreamIds, ...supersededStreamIds]) {
@@ -6812,6 +6751,19 @@ function parseClaudeEvents(events, parentToolUseId) {
6812
6751
  return messages.filter((_, index) => !staleIndexes.has(index));
6813
6752
  }
6814
6753
 
6754
+ // ../shared/src/display-message/parsers/mcp.ts
6755
+ function parseMcpToolName(name) {
6756
+ const prefix = "mcp__";
6757
+ if (!name.startsWith(prefix)) return null;
6758
+ const rest = name.slice(prefix.length);
6759
+ const sep = rest.indexOf("__");
6760
+ if (sep <= 0) return null;
6761
+ const server = rest.slice(0, sep);
6762
+ const tool = rest.slice(sep + 2);
6763
+ if (!server || !tool) return null;
6764
+ return { server, tool };
6765
+ }
6766
+
6815
6767
  // ../shared/src/display-message/parsers/index.ts
6816
6768
  var INTERRUPTION_DEDUP_WINDOW_MS = 15e3;
6817
6769
  function parseAgentEvents(events, agentType) {
@@ -9072,7 +9024,6 @@ function normalizeChatTranscriptMetadata(value) {
9072
9024
  const metadata = {};
9073
9025
  const {
9074
9026
  provider,
9075
- relayBaseProvider,
9076
9027
  credential,
9077
9028
  credentialSource,
9078
9029
  environmentAuthMethod,
@@ -9091,8 +9042,7 @@ function normalizeChatTranscriptMetadata(value) {
9091
9042
  sha256,
9092
9043
  fork
9093
9044
  } = value;
9094
- const normalizedProvider = typeof provider === "string" ? normalizeLegacyChatProvider(provider, relayBaseProvider) : null;
9095
- if (normalizedProvider) metadata.provider = normalizedProvider;
9045
+ if (typeof provider === "string" && isValidAgentProvider(provider)) metadata.provider = provider;
9096
9046
  const parsedCredential = agentCredentialSnapshotSchema.safeParse(credential);
9097
9047
  if (parsedCredential.success) metadata.credential = parsedCredential.data;
9098
9048
  if (credentialSource === "stored" || credentialSource === "environment") metadata.credentialSource = credentialSource;
@@ -9201,6 +9151,7 @@ export {
9201
9151
  detectEnvironmentAuthMethod,
9202
9152
  AGENT_CREDENTIAL_METHODS_IN_ORDER,
9203
9153
  describeCredential,
9154
+ isClientMessageSource,
9204
9155
  agentCredentialSnapshotSchema,
9205
9156
  isSameCredential,
9206
9157
  isAgentChatTurnActivityRecord,
@@ -9309,15 +9260,17 @@ export {
9309
9260
  SANDBOX_SKILL_DIRS,
9310
9261
  HISTORY_ROOT,
9311
9262
  HISTORY_INDEX_FILENAME,
9263
+ REPLICAS_INSTRUCTIONS_TAG,
9264
+ wrapInTag,
9312
9265
  extractErrorText,
9313
9266
  isTransientErrorText,
9314
9267
  extractToolResultText,
9315
9268
  normalizeContentBlocks,
9316
9269
  TaskAccumulator,
9317
- parseMcpToolName,
9318
9270
  coerceClaudeResultPayload,
9319
9271
  stripAgentDiagnosticErrors,
9320
9272
  isClaudeResultError,
9273
+ parseMcpToolName,
9321
9274
  parseAgentEvents,
9322
9275
  parseDisplayMessages,
9323
9276
  extractFinalResponse,
@@ -14,7 +14,7 @@ import {
14
14
  isValidAgentProvider,
15
15
  parsePosixEnvFile,
16
16
  readReplicasRuntimeEnv
17
- } from "./chunk-JEOHY7BW.js";
17
+ } from "./chunk-EARIHQMZ.js";
18
18
 
19
19
  // src/runtime-env-loader.ts
20
20
  import { readFileSync } from "fs";
@@ -3,7 +3,7 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  HOOK_EXEC_MAX_BUFFER_BYTES
6
- } from "./chunk-JEOHY7BW.js";
6
+ } from "./chunk-EARIHQMZ.js";
7
7
 
8
8
  // src/utils/exec.ts
9
9
  import { exec, execFile } from "child_process";
@@ -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-BHY3WVAG.js";
7
- import "./chunk-EAHICWAF.js";
8
- import "./chunk-VAHRPTDQ.js";
6
+ } from "./chunk-7LHSRAKC.js";
7
+ import "./chunk-IFF7ILWV.js";
8
+ import "./chunk-LBEKAKM7.js";
9
9
  import {
10
10
  isRecord
11
11
  } from "./chunk-UZSNFLDQ.js";
12
- import "./chunk-JEOHY7BW.js";
12
+ import "./chunk-EARIHQMZ.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
 
15
15
  // src/command-protection-hook.ts
@@ -7,12 +7,12 @@ import {
7
7
  import {
8
8
  AppServerProcess,
9
9
  buildCodexAgentEnv
10
- } from "./chunk-NUYJXEFQ.js";
11
- import "./chunk-VAHRPTDQ.js";
10
+ } from "./chunk-46VEUNV3.js";
11
+ import "./chunk-LBEKAKM7.js";
12
12
  import {
13
13
  AGENT,
14
14
  headlessAgentRequestSchema
15
- } from "./chunk-JEOHY7BW.js";
15
+ } from "./chunk-EARIHQMZ.js";
16
16
  import "./chunk-VEQXQN22.js";
17
17
 
18
18
  // src/headless-agent.ts
package/dist/src/index.js CHANGED
@@ -32,7 +32,7 @@ import {
32
32
  reportCommandProtectionBlock,
33
33
  resolveDiffBase,
34
34
  runGitCommand
35
- } from "./chunk-BHY3WVAG.js";
35
+ } from "./chunk-7LHSRAKC.js";
36
36
  import {
37
37
  ACCOUNT_RATE_LIMITS_UPDATED_METHOD,
38
38
  AGENT_MESSAGE_DELTA_METHOD,
@@ -57,7 +57,7 @@ import {
57
57
  } from "./chunk-P73LGPQO.js";
58
58
  import {
59
59
  publishedPullRequestUrls
60
- } from "./chunk-TUVAZET4.js";
60
+ } from "./chunk-C457AN4B.js";
61
61
  import {
62
62
  BaseRefreshManager,
63
63
  CodexAspAuthMethodChangedError,
@@ -71,7 +71,7 @@ import {
71
71
  refreshDelayMs,
72
72
  restartCodexAspHost,
73
73
  routineRefreshRequest
74
- } from "./chunk-UTFC3WOD.js";
74
+ } from "./chunk-6PFWQN6N.js";
75
75
  import {
76
76
  ENGINE_ENV,
77
77
  monolithRequest,
@@ -79,16 +79,16 @@ import {
79
79
  readRuntimeEnvFile,
80
80
  reloadEngineEnv,
81
81
  setAgentCredentialSnapshot
82
- } from "./chunk-EAHICWAF.js";
82
+ } from "./chunk-IFF7ILWV.js";
83
83
  import {
84
84
  AspClient,
85
85
  getCodexModelProvider
86
- } from "./chunk-NUYJXEFQ.js";
86
+ } from "./chunk-46VEUNV3.js";
87
87
  import {
88
88
  SUBPROCESS_MAX_BUFFER,
89
89
  execAsync,
90
90
  execFileAsync
91
- } from "./chunk-VAHRPTDQ.js";
91
+ } from "./chunk-LBEKAKM7.js";
92
92
  import {
93
93
  isRecord as isRecord2
94
94
  } from "./chunk-UZSNFLDQ.js";
@@ -164,6 +164,7 @@ import {
164
164
  QUEUED_MESSAGE_REMOVED_EVENT_TYPE,
165
165
  REMOVED_MESSAGE_IDS_PAYLOAD_KEY,
166
166
  REPLICAS_CONFIG_FILENAMES,
167
+ REPLICAS_INSTRUCTIONS_TAG,
167
168
  REPLICAS_RUNTIME_ENV_ALIASES,
168
169
  SANDBOX_SKILL_DIRS,
169
170
  SUBAGENT_MCP_HARNESSES,
@@ -255,6 +256,7 @@ import {
255
256
  isChatMessageSender,
256
257
  isClaudeAuthErrorText,
257
258
  isClaudeResultError,
259
+ isClientMessageSource,
258
260
  isCodexAuthError,
259
261
  isDefaultChat,
260
262
  isExcludedRepoFilePath,
@@ -315,8 +317,9 @@ import {
315
317
  workspaceAudienceSchema,
316
318
  workspaceCredentialProviderSchema,
317
319
  workspaceTokenRequestSchema,
318
- workspaceTokenResponseSchema
319
- } from "./chunk-JEOHY7BW.js";
320
+ workspaceTokenResponseSchema,
321
+ wrapInTag
322
+ } from "./chunk-EARIHQMZ.js";
320
323
  import {
321
324
  cloneMcpConfig,
322
325
  ensureCompatibilityImports,
@@ -10973,7 +10976,7 @@ import { join as join35 } from "path";
10973
10976
  import { randomUUID as randomUUID11 } from "crypto";
10974
10977
 
10975
10978
  // ../shared/src/workspace-chat.ts
10976
- var WORKSPACE_CHATS_QUERY_SCHEMA_VERSION = 11;
10979
+ var WORKSPACE_CHATS_QUERY_SCHEMA_VERSION = 12;
10977
10980
  var WORKSPACE_CHATS_QUERY_ROOT = `workspace-chats:v${WORKSPACE_CHATS_QUERY_SCHEMA_VERSION}`;
10978
10981
  function isAcceptedUserMessage(event) {
10979
10982
  return getUserMessage(event) !== null && event.payload.source === ACCEPTED_USER_MESSAGE_SOURCE;
@@ -11999,10 +12002,15 @@ var CodingAgentManager = class {
11999
12002
  subagentMcpChatId;
12000
12003
  subagentMcpEnabledForTurn = false;
12001
12004
  unreadSteers = /* @__PURE__ */ new Map();
12005
+ lastSenderKey;
12006
+ onLastSenderKeyChanged;
12002
12007
  constructor(options) {
12003
12008
  this.workingDirectory = options.workingDirectory ?? ENGINE_ENV.WORKSPACE_ROOT;
12004
12009
  this.initialSessionId = options.initialSessionId;
12005
- this.onSaveSessionId = options.onSaveSessionId;
12010
+ this.onSaveSessionId = async (sessionId) => {
12011
+ if (!sessionId) await this.saveLastSenderKey(null);
12012
+ await options.onSaveSessionId(sessionId);
12013
+ };
12006
12014
  this.onEvent = options.onEvent;
12007
12015
  this.onUsageUpdate = options.onUsageUpdate ?? (() => {
12008
12016
  });
@@ -12016,6 +12024,9 @@ var CodingAgentManager = class {
12016
12024
  });
12017
12025
  this.onModelSwitched = options.onModelSwitched ?? (async () => {
12018
12026
  });
12027
+ this.lastSenderKey = options.lastSenderKey ?? null;
12028
+ this.onLastSenderKeyChanged = options.onLastSenderKeyChanged ?? (async () => {
12029
+ });
12019
12030
  this.authFallback = options.provider ? new AuthFallbackCoordinator(options.provider, (event) => {
12020
12031
  this.onEvent(event);
12021
12032
  this.getHistorySink()?.append(event);
@@ -12076,13 +12087,33 @@ var CodingAgentManager = class {
12076
12087
  async (request, signal) => {
12077
12088
  await this.refreshSubagentMcp();
12078
12089
  if (signal.aborted) return;
12079
- await processMessage(request, signal);
12090
+ const { request: delivered, senderKey } = this.withSenderLine(request);
12091
+ await this.saveLastSenderKey(senderKey);
12092
+ await processMessage(delivered, signal);
12080
12093
  },
12081
12094
  this.onProcessingChanged,
12082
12095
  this.onMessageStarted
12083
12096
  );
12084
12097
  this.initialized = this.initialize();
12085
12098
  }
12099
+ // Integration turns (Slack, GitHub, Linear) carry no sender fields and name their sender in the text, so they reset the key.
12100
+ withSenderLine(request) {
12101
+ if (request.goalMode || request.message.trimStart().startsWith("/")) return { request, senderKey: this.lastSenderKey };
12102
+ if (!request.senderUserId || !request.senderEmail) return { request, senderKey: null };
12103
+ const via = request.source && !isClientMessageSource(request.source) ? request.source : void 0;
12104
+ const senderKey = `${request.senderUserId}:${via ?? ""}`;
12105
+ if (senderKey === this.lastSenderKey) return { request, senderKey };
12106
+ const name = request.senderDisplayName && request.senderDisplayName !== request.senderEmail ? `${request.senderDisplayName} (${request.senderEmail})` : request.senderEmail;
12107
+ const line = wrapInTag(`From ${name}${via ? ` via ${via}` : ""}.`, REPLICAS_INSTRUCTIONS_TAG);
12108
+ return { request: { ...request, message: `${line}
12109
+
12110
+ ${request.message}` }, senderKey };
12111
+ }
12112
+ async saveLastSenderKey(senderKey) {
12113
+ if (senderKey === this.lastSenderKey) return;
12114
+ this.lastSenderKey = senderKey;
12115
+ await this.onLastSenderKeyChanged(senderKey);
12116
+ }
12086
12117
  /** The workspace preference is resolved per turn so a change applies to the next turn; failures keep the last value. */
12087
12118
  async refreshSubagentMcp() {
12088
12119
  if (!this.subagentMcpChatId || !ENGINE_ENV.REPLICAS_WORKSPACE_ID) return;
@@ -12199,8 +12230,10 @@ var CodingAgentManager = class {
12199
12230
  return { success: false, queue: this.getQueue() };
12200
12231
  }
12201
12232
  let steered = false;
12233
+ const { request: delivered, senderKey } = this.withSenderLine(taken.message);
12202
12234
  try {
12203
- steered = await this.steerRequest(taken.message);
12235
+ steered = await this.steerRequest(delivered);
12236
+ if (steered) await this.saveLastSenderKey(senderKey);
12204
12237
  } catch (error) {
12205
12238
  console.error("[CodingAgentManager] steerRequest threw, keeping message queued:", error);
12206
12239
  }
@@ -12234,6 +12267,11 @@ var CodingAgentManager = class {
12234
12267
  const steers = [...this.unreadSteers.values()].map(({ message }) => message);
12235
12268
  this.unreadSteers.clear();
12236
12269
  this.restoreQueuedMessages(steers.map((message) => ({ message, index: 0 })));
12270
+ if (steers.length > 0) {
12271
+ this.saveLastSenderKey(null).catch((error) => {
12272
+ console.error("[CodingAgentManager] Failed to reset last sender:", error);
12273
+ });
12274
+ }
12237
12275
  }
12238
12276
  markSteerRead(messageId) {
12239
12277
  const steer = this.unreadSteers.get(messageId);
@@ -12268,6 +12306,7 @@ var CodingAgentManager = class {
12268
12306
  if (enginePortProtectionInstruction) {
12269
12307
  parts.push(enginePortProtectionInstruction);
12270
12308
  }
12309
+ parts.push("Each message names its sender when the sender changes. Any account email the harness attaches, such as Claude Code's `userEmail`, belongs to the inference account: never use it to identify or contact the user.");
12271
12310
  parts.push(`Unless the user asks for a different location, clone a repository you will change into ${ENGINE_ENV.WORKSPACE_ROOT}/<repository-name> so the user can review its changes in the workspace. Clones you only read can go anywhere.`);
12272
12311
  if (startHooksInstruction) {
12273
12312
  parts.push(startHooksInstruction);
@@ -60591,6 +60630,7 @@ function normalizePersistedChat(chat) {
60591
60630
  pendingForkHandoff: chat.pendingForkHandoff === true,
60592
60631
  ...chat.chatCredential === "workspace" || agentCredentialSnapshotSchema.safeParse(chat.chatCredential).success ? { chatCredential: chat.chatCredential } : {},
60593
60632
  transcriptAuth: normalizeTranscriptAuth(chat.transcriptAuth),
60633
+ ...typeof chat.lastSenderKey === "string" ? { lastSenderKey: chat.lastSenderKey } : {},
60594
60634
  removedMessageIds: Array.isArray(chat.removedMessageIds) ? chat.removedMessageIds.filter((id) => typeof id === "string").slice(-MAX_REMOVED_MESSAGE_IDS) : [],
60595
60635
  acceptedSendResponses: isRecord2(chat.acceptedSendResponses) ? Object.fromEntries(Object.entries(chat.acceptedSendResponses).filter((entry) => {
60596
60636
  const response = entry[1];
@@ -61534,6 +61574,10 @@ var ChatService = class {
61534
61574
  console.error("[ChatService] Failed to record chat credential:", { chatId: persisted.id, error });
61535
61575
  });
61536
61576
  };
61577
+ const onLastSenderKeyChanged = async (senderKey) => {
61578
+ persisted.lastSenderKey = senderKey ?? void 0;
61579
+ await this.persistAllChats();
61580
+ };
61537
61581
  const onProcessingChanged = (processing) => {
61538
61582
  if (processing) return;
61539
61583
  this.handleProcessingStopped(persisted.id);
@@ -61576,6 +61620,8 @@ var ChatService = class {
61576
61620
  chatId: persisted.id,
61577
61621
  onModelSwitched,
61578
61622
  onChatCredential,
61623
+ lastSenderKey: persisted.lastSenderKey,
61624
+ onLastSenderKeyChanged,
61579
61625
  linearSessionId: persisted.parentChatId === null ? ENGINE_ENV.REPLICAS_LINEAR_SESSION_ID : void 0,
61580
61626
  parentChatId: persisted.parentChatId
61581
61627
  };
@@ -3,13 +3,13 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  publishedPullRequestUrls
6
- } from "./chunk-TUVAZET4.js";
6
+ } from "./chunk-C457AN4B.js";
7
7
  import {
8
8
  isRecord
9
9
  } from "./chunk-UZSNFLDQ.js";
10
10
  import {
11
11
  shouldRefreshPullRequests
12
- } from "./chunk-JEOHY7BW.js";
12
+ } from "./chunk-EARIHQMZ.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
 
15
15
  // src/services/post-tool-pr-notifier.ts
@@ -9,7 +9,7 @@ import {
9
9
  spawnSubagentRequestSchema,
10
10
  subagentResponseSchema,
11
11
  waitSubagentRequestSchema
12
- } from "./chunk-JEOHY7BW.js";
12
+ } from "./chunk-EARIHQMZ.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
 
15
15
  // src/subagent-mcp.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.1021",
3
+ "version": "0.1.1023",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -39,7 +39,7 @@
39
39
  "author": "Replicas",
40
40
  "license": "MIT",
41
41
  "dependencies": {
42
- "@anthropic-ai/claude-agent-sdk": "0.3.290",
42
+ "@anthropic-ai/claude-agent-sdk": "0.3.293",
43
43
  "@anthropic-ai/sdk": "0.128.0",
44
44
  "@connectrpc/connect-node": "1.7.0",
45
45
  "@cursor/sdk": "1.0.36",