replicas-engine 0.1.98 → 0.1.100

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 +35 -20
  2. package/package.json +1 -1
package/dist/src/index.js CHANGED
@@ -1091,7 +1091,7 @@ function parseReplicasConfigString(content, filename) {
1091
1091
  }
1092
1092
 
1093
1093
  // ../shared/src/engine/environment.ts
1094
- var DAYTONA_SNAPSHOT_ID = "13-04-2026-phantom-subagent-fix";
1094
+ var DAYTONA_SNAPSHOT_ID = "13-04-2026-relay-codex-gating";
1095
1095
 
1096
1096
  // ../shared/src/engine/types.ts
1097
1097
  var DEFAULT_CHAT_TITLES = {
@@ -1643,6 +1643,7 @@ var PreviewService = class {
1643
1643
  var previewService = new PreviewService();
1644
1644
 
1645
1645
  // src/services/chat/chat-service.ts
1646
+ import { existsSync as existsSync7 } from "fs";
1646
1647
  import { mkdir as mkdir10, readFile as readFile8, rm, writeFile as writeFile8 } from "fs/promises";
1647
1648
  import { homedir as homedir9 } from "os";
1648
1649
  import { join as join11 } from "path";
@@ -3076,23 +3077,27 @@ async function getChatFinalResponse(chatId) {
3076
3077
  }
3077
3078
  return "[No response from subagent]";
3078
3079
  }
3079
- function buildSpawnAgentTool(parentChatId) {
3080
+ function buildSpawnAgentTool(parentChatId, codexAvailable = false) {
3081
+ const providerEnum = codexAvailable ? z.enum(["claude", "codex", "relay"]) : z.enum(["claude", "relay"]);
3082
+ const providerDesc = codexAvailable ? "Which agent to use. Prefer codex for code writing, claude for exploration/analysis, relay for complex multi-step orchestration." : "Which agent to use. Use claude for code writing, exploration, and analysis. Use relay for complex multi-step orchestration.";
3083
+ const useCases = codexAvailable ? `- Complex code writing tasks (use provider 'codex' with a capable model)
3084
+ - Codebase exploration that would consume many tokens (use provider 'claude')` : `- Complex code writing tasks (use provider 'claude')
3085
+ - Codebase exploration that would consume many tokens (use provider 'claude')`;
3080
3086
  return tool(
3081
3087
  "spawn_agent",
3082
3088
  `Spawn a new subagent to perform a task. The subagent runs in its own chat with a fresh context window.
3083
3089
 
3084
3090
  Use this for:
3085
- - Complex code writing tasks (use provider 'codex' with a capable model)
3086
- - Codebase exploration that would consume many tokens (use provider 'claude')
3091
+ ${useCases}
3087
3092
  - Browser testing, large test runs, or other token-heavy operations
3088
3093
  - Any task you want to delegate to preserve your own context
3089
3094
 
3090
3095
  The tool blocks until the subagent completes and returns its final response.
3091
3096
  You will also receive the chatId so you can send follow-up messages or clean up the chat.`,
3092
3097
  {
3093
- provider: z.enum(["claude", "codex", "relay"]).describe("Which agent to use. Prefer codex for code writing, claude for exploration/analysis, relay for complex multi-step orchestration."),
3098
+ provider: providerEnum.describe(providerDesc),
3094
3099
  prompt: z.string().describe("The full prompt/instructions for the subagent. Be detailed - it has no context from your conversation."),
3095
- model: z.string().optional().describe("Model override. Claude: opus, sonnet, haiku. Codex: gpt-5.4, gpt-5.3-codex, etc."),
3100
+ model: z.string().optional().describe(codexAvailable ? "Model override. Claude: opus, sonnet, haiku. Codex: gpt-5.4, gpt-5.3-codex, etc." : "Model override. Claude: opus, sonnet, haiku."),
3096
3101
  title: z.string().optional().describe("Optional title for the subagent chat (for identification)."),
3097
3102
  timeout_minutes: z.number().positive().optional().describe("Timeout in minutes for the subagent to complete (default: 10). Set higher for large tasks to avoid losing work.")
3098
3103
  },
@@ -3208,11 +3213,11 @@ var deleteAgentTool = tool(
3208
3213
  }
3209
3214
  }
3210
3215
  );
3211
- function createRelayMcpServer(parentChatId) {
3216
+ function createRelayMcpServer(parentChatId, codexAvailable = false) {
3212
3217
  return createSdkMcpServer({
3213
3218
  name: "relay-subagent-tools",
3214
3219
  version: "1.0.0",
3215
- tools: [buildSpawnAgentTool(parentChatId), messageAgentTool, deleteAgentTool]
3220
+ tools: [buildSpawnAgentTool(parentChatId, codexAvailable), messageAgentTool, deleteAgentTool]
3216
3221
  });
3217
3222
  }
3218
3223
 
@@ -3314,12 +3319,17 @@ function getUsingToolsSection() {
3314
3319
  ];
3315
3320
  return [`# Using your tools`, ...prependBullets(items)].join("\n");
3316
3321
  }
3317
- function getDelegationSection() {
3322
+ function getDelegationSection(codexAvailable) {
3323
+ const providerList = codexAvailable ? "claude, codex, or relay" : "claude or relay";
3324
+ const spawnDesc = `Create a new subagent with a specific provider (${providerList}), send it a prompt, and wait for its response. Returns the chatId and the agent's final response. You can set a custom timeout via the timeout_minutes parameter (default: 10 minutes).`;
3325
+ const agentSelectionLines = codexAvailable ? `Use provider 'codex' for heavy code writing, implementation, and large refactors. Suggested models: gpt-5.4 (default), gpt-5.3-codex.
3326
+
3327
+ Use provider 'claude' for codebase exploration, code review, planning, complex debugging, and tasks requiring nuanced architectural understanding. Suggested models: opus (default), sonnet (faster).` : `Use provider 'claude' for all tasks including code writing, codebase exploration, code review, planning, complex debugging, and tasks requiring nuanced architectural understanding. Suggested models: opus (default), sonnet (faster).`;
3318
3328
  return `# Delegation
3319
3329
 
3320
3330
  You have three subagent tools for spawning and managing agents that run in separate context windows:
3321
3331
 
3322
- - **spawn_agent**: Create a new subagent with a specific provider (claude or codex), send it a prompt, and wait for its response. Returns the chatId and the agent's final response. You can set a custom timeout via the timeout_minutes parameter (default: 10 minutes).
3332
+ - **spawn_agent**: ${spawnDesc}
3323
3333
  - **message_agent**: Send a follow-up message to an existing subagent by chatId. Use for iteration, corrections, or additional requests in the same context.
3324
3334
  - **delete_agent**: Delete a subagent chat when you no longer need it.
3325
3335
 
@@ -3357,9 +3367,7 @@ The default subagent timeout is 10 minutes. For tasks you expect to take longer
3357
3367
 
3358
3368
  ## Agent selection
3359
3369
 
3360
- Use provider 'codex' for heavy code writing, implementation, and large refactors. Suggested models: gpt-5.4 (default), gpt-5.3-codex.
3361
-
3362
- Use provider 'claude' for codebase exploration, code review, planning, complex debugging, and tasks requiring nuanced architectural understanding. Suggested models: opus (default), sonnet (faster).
3370
+ ${agentSelectionLines}
3363
3371
 
3364
3372
  ## Effective delegation
3365
3373
 
@@ -3412,14 +3420,15 @@ function getEnvironmentSection() {
3412
3420
  ...prependBullets(envItems.filter((x) => x !== null))
3413
3421
  ].join("\n");
3414
3422
  }
3415
- function buildRelaySystemPrompt(customInstructions) {
3423
+ function buildRelaySystemPrompt(options) {
3424
+ const { customInstructions, codexAvailable } = options ?? {};
3416
3425
  const sections = [
3417
3426
  getIntroSection(),
3418
3427
  getSystemSection(),
3419
3428
  getDoingTasksSection(),
3420
3429
  getActionsSection(),
3421
3430
  getUsingToolsSection(),
3422
- getDelegationSection(),
3431
+ getDelegationSection(codexAvailable ?? false),
3423
3432
  getToneAndStyleSection(),
3424
3433
  getOutputEfficiencySection(),
3425
3434
  getEnvironmentSection(),
@@ -3446,12 +3455,13 @@ var RELAY_TOOLS = [
3446
3455
  var RelayManager = class {
3447
3456
  inner;
3448
3457
  constructor(options) {
3458
+ const codexAvailable = options.codexAvailable ?? false;
3449
3459
  this.inner = new ClaudeManager({
3450
3460
  ...options,
3451
- systemPromptOverride: buildRelaySystemPrompt,
3461
+ systemPromptOverride: (customInstructions) => buildRelaySystemPrompt({ customInstructions, codexAvailable }),
3452
3462
  tools: RELAY_TOOLS,
3453
3463
  mcpServers: {
3454
- "relay-subagent-tools": createRelayMcpServer(options.chatId)
3464
+ "relay-subagent-tools": createRelayMcpServer(options.chatId, codexAvailable)
3455
3465
  },
3456
3466
  envOverrides: {
3457
3467
  CLAUDE_CODE_STREAM_CLOSE_TIMEOUT: "900000"
@@ -3550,6 +3560,10 @@ var ENGINE_DIR2 = join11(homedir9(), ".replicas", "engine");
3550
3560
  var CHATS_FILE = join11(ENGINE_DIR2, "chats.json");
3551
3561
  var CLAUDE_HISTORY_DIR = join11(ENGINE_DIR2, "claude-histories");
3552
3562
  var RELAY_HISTORY_DIR = join11(ENGINE_DIR2, "relay-histories");
3563
+ var CODEX_AUTH_PATH2 = join11(homedir9(), ".codex", "auth.json");
3564
+ function isCodexAvailable() {
3565
+ return existsSync7(CODEX_AUTH_PATH2) || Boolean(ENGINE_ENV.OPENAI_API_KEY);
3566
+ }
3553
3567
  function isPersistedChat(value) {
3554
3568
  if (!isRecord(value)) {
3555
3569
  return false;
@@ -3761,7 +3775,8 @@ var ChatService = class {
3761
3775
  onSaveSessionId: saveSession,
3762
3776
  onTurnComplete: onProviderTurnComplete,
3763
3777
  onEvent: onProviderEvent,
3764
- chatId: persisted.id
3778
+ chatId: persisted.id,
3779
+ codexAvailable: isCodexAvailable()
3765
3780
  });
3766
3781
  } else {
3767
3782
  provider = new CodexManager({
@@ -3972,7 +3987,7 @@ var planService = new PlanService();
3972
3987
  import { execFile as execFile2 } from "child_process";
3973
3988
  import { promisify as promisify3 } from "util";
3974
3989
  import { readFile as readFile11 } from "fs/promises";
3975
- import { existsSync as existsSync7 } from "fs";
3990
+ import { existsSync as existsSync8 } from "fs";
3976
3991
  import { join as join14 } from "path";
3977
3992
 
3978
3993
  // src/services/warm-hook-logs-service.ts
@@ -4074,7 +4089,7 @@ async function executeHookScript(params) {
4074
4089
  async function readRepoWarmHook(repoPath) {
4075
4090
  for (const filename of REPLICAS_CONFIG_FILENAMES) {
4076
4091
  const configPath = join14(repoPath, filename);
4077
- if (!existsSync7(configPath)) {
4092
+ if (!existsSync8(configPath)) {
4078
4093
  continue;
4079
4094
  }
4080
4095
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.98",
3
+ "version": "0.1.100",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",