replicas-engine 0.1.336 → 0.1.337

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 +70 -32
  2. package/package.json +1 -1
package/dist/src/index.js CHANGED
@@ -15,6 +15,10 @@ function isRecord(value) {
15
15
  }
16
16
 
17
17
  // ../shared/src/agent.ts
18
+ var VALID_AGENT_PROVIDERS = ["claude", "codex", "cursor", "relay"];
19
+ var VALID_CODING_AGENT_PROVIDERS = VALID_AGENT_PROVIDERS.filter(
20
+ (provider) => provider !== "relay"
21
+ );
18
22
  var CODEX_REASONING_EFFORT_BY_THINKING_LEVEL = {
19
23
  low: "low",
20
24
  medium: "medium",
@@ -291,7 +295,7 @@ var WORKSPACE_SIZES = ["small", "large"];
291
295
  var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
292
296
 
293
297
  // ../shared/src/e2b.ts
294
- var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-06-22-v2";
298
+ var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-06-22-v3";
295
299
 
296
300
  // ../shared/src/runtime-env.ts
297
301
  function parsePosixEnvFile(content) {
@@ -7497,7 +7501,7 @@ var AspClient = class {
7497
7501
  // src/managers/codex-asp/app-server-process.ts
7498
7502
  var DEFAULT_CODEX_BINARY = "codex";
7499
7503
  var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
7500
- var ENGINE_PACKAGE_VERSION = "0.1.336";
7504
+ var ENGINE_PACKAGE_VERSION = "0.1.337";
7501
7505
  var INITIALIZE_METHOD = "initialize";
7502
7506
  var INITIALIZED_NOTIFICATION = "initialized";
7503
7507
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -9385,8 +9389,29 @@ var CursorManager = class extends CodingAgentManager {
9385
9389
  // src/managers/relay-tools.ts
9386
9390
  import { createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
9387
9391
  import { z } from "zod";
9392
+
9393
+ // src/managers/relay-providers.ts
9394
+ function getAvailableRelayProviders(availability) {
9395
+ const codexAvailable = availability.codexAvailable ?? false;
9396
+ const cursorAvailable = availability.cursorAvailable ?? false;
9397
+ const providers = ["claude"];
9398
+ if (codexAvailable) providers.push("codex");
9399
+ if (cursorAvailable) providers.push("cursor");
9400
+ providers.push("relay");
9401
+ return providers;
9402
+ }
9403
+ function getAvailableCodeProviders(availability) {
9404
+ return getAvailableRelayProviders(availability).filter((provider) => provider === "codex" || provider === "cursor");
9405
+ }
9406
+
9407
+ // src/managers/relay-tools.ts
9388
9408
  var POLL_INTERVAL_MS = 2e3;
9389
9409
  var DEFAULT_SUBAGENT_TIMEOUT_MS = 6e5;
9410
+ function extractTextBlocks(content, textBlockType, separator = "\n") {
9411
+ if (!Array.isArray(content)) return null;
9412
+ const texts = content.map((block) => block && typeof block === "object" && "type" in block && block.type === textBlockType && "text" in block && typeof block.text === "string" ? block.text : "").filter(Boolean);
9413
+ return texts.length > 0 ? texts.join(separator) : null;
9414
+ }
9390
9415
  async function engineFetch(path5, options) {
9391
9416
  const baseUrl = `http://localhost:${ENGINE_ENV.REPLICAS_ENGINE_PORT}`;
9392
9417
  return fetch(`${baseUrl}${path5}`, {
@@ -9439,21 +9464,12 @@ async function getChatFinalResponse(chatId) {
9439
9464
  }
9440
9465
  if (event.type === "claude-assistant") {
9441
9466
  const message = payload.message;
9442
- if (message?.content) {
9443
- const textBlocks = message.content.filter((block) => block.type === "text" && block.text).map((block) => block.text);
9444
- if (textBlocks.length > 0) {
9445
- return textBlocks.join("\n");
9446
- }
9447
- }
9467
+ const text = extractTextBlocks(message?.content, "text");
9468
+ if (text) return text;
9448
9469
  }
9449
9470
  if (event.type === "response_item" && payload.type === "message" && payload.role === "assistant") {
9450
- const content = payload.content;
9451
- if (Array.isArray(content)) {
9452
- const texts = content.filter((block) => block.type === "output_text" && block.text).map((block) => block.text);
9453
- if (texts.length > 0) {
9454
- return texts.join("\n");
9455
- }
9456
- }
9471
+ const text = extractTextBlocks(payload.content, "output_text");
9472
+ if (text) return text;
9457
9473
  }
9458
9474
  if (event.type === "event_msg" && payload.type === "agent_reasoning") {
9459
9475
  const text = payload.text;
@@ -9461,13 +9477,22 @@ async function getChatFinalResponse(chatId) {
9461
9477
  return text;
9462
9478
  }
9463
9479
  }
9480
+ if (event.type === "cursor-assistant") {
9481
+ const message = payload.message;
9482
+ const text = extractTextBlocks(message?.content, "text", "");
9483
+ if (text) return text;
9484
+ }
9464
9485
  }
9465
9486
  return "[No response from subagent]";
9466
9487
  }
9467
- function buildSpawnAgentTool(parentChatId, codexAvailable = false) {
9468
- const providerEnum = codexAvailable ? z.enum(["claude", "codex", "relay"]) : z.enum(["claude", "relay"]);
9469
- 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.";
9470
- const useCases = codexAvailable ? `- Complex code writing tasks (use provider 'codex' with a capable model)
9488
+ function buildSpawnAgentTool(parentChatId, availability = {}) {
9489
+ const codexAvailable = availability.codexAvailable ?? false;
9490
+ const cursorAvailable = availability.cursorAvailable ?? false;
9491
+ const availableProviders = getAvailableRelayProviders(availability);
9492
+ const providerEnum = z.enum(availableProviders);
9493
+ const codeProviders = getAvailableCodeProviders(availability);
9494
+ const providerDesc = codeProviders.length > 0 ? `Which agent to use. Prefer ${codeProviders.join(" or ")} 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.";
9495
+ const useCases = codeProviders.length > 0 ? `- Complex code writing tasks (use provider '${codeProviders.join("' or '")}' with a capable model)
9471
9496
  - Codebase exploration that would consume many tokens (use provider 'claude')` : `- Complex code writing tasks (use provider 'claude')
9472
9497
  - Codebase exploration that would consume many tokens (use provider 'claude')`;
9473
9498
  return tool(
@@ -9484,9 +9509,13 @@ You will also receive the chatId so you can send follow-up messages or clean up
9484
9509
  {
9485
9510
  provider: providerEnum.describe(providerDesc),
9486
9511
  prompt: z.string().describe("The full prompt/instructions for the subagent. Be detailed - it has no context from your conversation."),
9487
- model: z.string().optional().describe(codexAvailable ? `Model override. Claude: ${AGENT_MODELS.claude.join(", ")} (opus[1m] is the default, 1M context, use for very large codebases or huge context tasks). Codex: gpt-5.5, gpt-5.4, gpt-5.3-codex, etc.` : `Model override. Claude: ${AGENT_MODELS.claude.join(", ")} (opus[1m] is the default, 1M context, use for very large codebases or huge context tasks).`),
9512
+ model: z.string().optional().describe([
9513
+ `Model override. Claude: ${AGENT_MODELS.claude.join(", ")} (opus[1m] is the default, 1M context, use for very large codebases or huge context tasks).`,
9514
+ codexAvailable ? "Codex: gpt-5.5, gpt-5.4, gpt-5.3-codex, etc." : null,
9515
+ cursorAvailable ? `Cursor: ${AGENT_MODELS.cursor.join(", ")}.` : null
9516
+ ].filter(Boolean).join(" ")),
9488
9517
  thinking_level: z.enum(["low", "medium", "high", "max"]).optional().describe(
9489
- "Controls how much thinking/reasoning the subagent applies. low = light thinking, medium = moderate, high = deep reasoning, max = maximum effort. Defaults: Claude = high, Codex = medium."
9518
+ "Controls how much thinking/reasoning the subagent applies. low = light thinking, medium = moderate, high = deep reasoning, max = maximum effort. Defaults: Claude = high, Codex = medium, Cursor = medium."
9490
9519
  ),
9491
9520
  title: z.string().optional().describe("Optional title for the subagent chat (for identification)."),
9492
9521
  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.")
@@ -9554,7 +9583,7 @@ The tool blocks until the subagent completes and returns its response.`,
9554
9583
  message: z.string().describe("The follow-up message to send."),
9555
9584
  model: z.string().optional().describe("Optional model override for this message."),
9556
9585
  thinking_level: z.enum(["low", "medium", "high", "max"]).optional().describe(
9557
- "Controls how much thinking/reasoning the subagent applies. low = light thinking, medium = moderate, high = deep reasoning, max = maximum effort. Defaults: Claude = high, Codex = medium."
9586
+ "Controls how much thinking/reasoning the subagent applies. low = light thinking, medium = moderate, high = deep reasoning, max = maximum effort. Defaults: Claude = high, Codex = medium, Cursor = medium."
9558
9587
  ),
9559
9588
  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.")
9560
9589
  },
@@ -9612,11 +9641,11 @@ var deleteAgentTool = tool(
9612
9641
  }
9613
9642
  }
9614
9643
  );
9615
- function createRelayMcpServer(parentChatId, codexAvailable = false) {
9644
+ function createRelayMcpServer(parentChatId, availability = {}) {
9616
9645
  return createSdkMcpServer({
9617
9646
  name: "relay-subagent-tools",
9618
9647
  version: "1.0.0",
9619
- tools: [buildSpawnAgentTool(parentChatId, codexAvailable), messageAgentTool, deleteAgentTool]
9648
+ tools: [buildSpawnAgentTool(parentChatId, availability), messageAgentTool, deleteAgentTool]
9620
9649
  });
9621
9650
  }
9622
9651
 
@@ -9718,11 +9747,15 @@ function getUsingToolsSection() {
9718
9747
  ];
9719
9748
  return [`# Using your tools`, ...prependBullets(items)].join("\n");
9720
9749
  }
9721
- function getDelegationSection(codexAvailable) {
9722
- const providerList = codexAvailable ? "claude, codex, or relay" : "claude or relay";
9750
+ function getDelegationSection(codexAvailable, cursorAvailable) {
9751
+ const providerList = getAvailableRelayProviders({ codexAvailable, cursorAvailable }).join(", ");
9723
9752
  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).`;
9724
9753
  const claudeModelList = AGENT_MODELS.claude.join(", ");
9725
- const agentSelectionLines = codexAvailable ? `Use provider 'codex' for heavy code writing, implementation, and large refactors. Suggested models: gpt-5.5 (default), gpt-5.4, gpt-5.3-codex.
9754
+ const extraAgentLines = [
9755
+ codexAvailable ? `Use provider 'codex' for heavy code writing, implementation, and large refactors. Suggested models: gpt-5.5 (default), gpt-5.4, gpt-5.3-codex.` : null,
9756
+ cursorAvailable ? `Use provider 'cursor' for fast iteration on code changes. Suggested models: ${AGENT_MODELS.cursor.join(", ")}.` : null
9757
+ ].filter(Boolean);
9758
+ const agentSelectionLines = extraAgentLines.length > 0 ? `${extraAgentLines.join("\n\n")}
9726
9759
 
9727
9760
  Use provider 'claude' for codebase exploration, code review, planning, complex debugging, and tasks requiring nuanced architectural understanding. Suggested models: ${claudeModelList} (opus[1m] is the default, 1M context window, use for very large codebases; sonnet is 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: ${claudeModelList} (opus[1m] is the default, 1M context window, use for very large codebases; sonnet is faster).`;
9728
9761
  return `# Delegation
@@ -9842,14 +9875,14 @@ function getEnvironmentSection() {
9842
9875
  ].join("\n");
9843
9876
  }
9844
9877
  function buildRelaySystemPrompt(options) {
9845
- const { customInstructions, codexAvailable } = options ?? {};
9878
+ const { customInstructions, codexAvailable, cursorAvailable } = options ?? {};
9846
9879
  const sections = [
9847
9880
  getIntroSection(),
9848
9881
  getSystemSection(),
9849
9882
  getDoingTasksSection(),
9850
9883
  getActionsSection(),
9851
9884
  getUsingToolsSection(),
9852
- getDelegationSection(codexAvailable ?? false),
9885
+ getDelegationSection(codexAvailable ?? false, cursorAvailable ?? false),
9853
9886
  getToneAndStyleSection(),
9854
9887
  getOutputEfficiencySection(),
9855
9888
  getEnvironmentSection(),
@@ -9880,12 +9913,13 @@ var RelayManager = class {
9880
9913
  inner;
9881
9914
  constructor(options) {
9882
9915
  const codexAvailable = options.codexAvailable ?? false;
9916
+ const cursorAvailable = options.cursorAvailable ?? false;
9883
9917
  this.inner = new ClaudeManager({
9884
9918
  ...options,
9885
- systemPromptOverride: (customInstructions) => buildRelaySystemPrompt({ customInstructions, codexAvailable }),
9919
+ systemPromptOverride: (customInstructions) => buildRelaySystemPrompt({ customInstructions, codexAvailable, cursorAvailable }),
9886
9920
  tools: RELAY_TOOLS,
9887
9921
  mcpServers: {
9888
- "relay-subagent-tools": createRelayMcpServer(options.chatId, codexAvailable)
9922
+ "relay-subagent-tools": createRelayMcpServer(options.chatId, { codexAvailable, cursorAvailable })
9889
9923
  },
9890
9924
  envOverrides: {
9891
9925
  CLAUDE_CODE_STREAM_CLOSE_TIMEOUT: "900000"
@@ -10252,6 +10286,9 @@ function isChatMessageSender(value) {
10252
10286
  function isCodexAvailable() {
10253
10287
  return existsSync7(CODEX_AUTH_PATH2) || Boolean(ENGINE_ENV.OPENAI_API_KEY);
10254
10288
  }
10289
+ function isCursorAvailable() {
10290
+ return Boolean(ENGINE_ENV.CURSOR_API_KEY);
10291
+ }
10255
10292
  function isSameAcceptedUserEvent(event, acceptedEvent) {
10256
10293
  if (areSameUserMessageEvents(event, acceptedEvent)) return true;
10257
10294
  const eventMessage = getUserMessage(event);
@@ -10693,7 +10730,8 @@ var ChatService = class {
10693
10730
  onTurnComplete: onProviderTurnComplete,
10694
10731
  onEvent: onProviderEvent,
10695
10732
  chatId: persisted.id,
10696
- codexAvailable: isCodexAvailable()
10733
+ codexAvailable: isCodexAvailable(),
10734
+ cursorAvailable: isCursorAvailable()
10697
10735
  });
10698
10736
  } else if (persisted.provider === "cursor") {
10699
10737
  provider = new CursorManager({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.336",
3
+ "version": "0.1.337",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",