replicas-engine 0.1.652 → 0.1.654

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,6 +5,7 @@ var AGENT = {
5
5
  CLAUDE: "claude",
6
6
  CODEX: "codex",
7
7
  CURSOR: "cursor",
8
+ DEEPSEEK: "deepseek",
8
9
  OPENCODE: "opencode",
9
10
  PI: "pi",
10
11
  RELAY: "relay"
@@ -26,6 +27,7 @@ var THINKING_LEVELS_BY_AGENT = {
26
27
  claude: [...STANDARD_THINKING_LEVELS, "ultracode"],
27
28
  codex: [...STANDARD_THINKING_LEVELS, "ultra"],
28
29
  cursor: STANDARD_THINKING_LEVELS,
30
+ deepseek: STANDARD_THINKING_LEVELS,
29
31
  opencode: STANDARD_THINKING_LEVELS,
30
32
  pi: STANDARD_THINKING_LEVELS,
31
33
  relay: [...STANDARD_THINKING_LEVELS, "ultracode"]
@@ -296,6 +298,7 @@ var DEFAULT_CHAT_TITLES = {
296
298
  claude: "Claude Code",
297
299
  codex: "Codex",
298
300
  cursor: "Cursor",
301
+ deepseek: "DeepSeek Harness",
299
302
  opencode: "Opencode",
300
303
  pi: "Pi",
301
304
  relay: "Relay"
@@ -322,6 +325,7 @@ var GPT_5_6_LUNA_MODEL = "gpt-5.6-luna";
322
325
  var DEFAULT_CODEX_MODEL = GPT_5_6_SOL_MODEL;
323
326
  var DEFAULT_CURSOR_MODEL = "composer-2.5";
324
327
  var DEFAULT_OPENCODE_MODEL = "z-ai/glm-5.2";
328
+ var DEFAULT_DEEPSEEK_MODEL = DEFAULT_OPENCODE_MODEL;
325
329
  var DEFAULT_PI_MODEL = DEFAULT_OPENCODE_MODEL;
326
330
  var OPENROUTER_MODELS = [
327
331
  DEFAULT_OPENCODE_MODEL,
@@ -333,6 +337,7 @@ var FALLBACK_AGENT_MODEL = {
333
337
  claude: DEFAULT_CLAUDE_MODEL,
334
338
  codex: DEFAULT_CODEX_MODEL,
335
339
  cursor: DEFAULT_CURSOR_MODEL,
340
+ deepseek: DEFAULT_DEEPSEEK_MODEL,
336
341
  opencode: DEFAULT_OPENCODE_MODEL,
337
342
  pi: DEFAULT_PI_MODEL,
338
343
  relay: DEFAULT_CLAUDE_MODEL
@@ -419,6 +424,7 @@ var AGENT_MODELS = {
419
424
  CLAUDE_HAIKU_4_5_MODEL,
420
425
  "kimi-k2.5"
421
426
  ],
427
+ deepseek: [...OPENROUTER_MODELS],
422
428
  opencode: [...OPENROUTER_MODELS, ...ASTER_MODELS],
423
429
  pi: [...OPENROUTER_MODELS, ...ASTER_MODELS],
424
430
  relay: [CLAUDE_FABLE_5_MODEL, CLAUDE_OPUS_5_MODEL, CLAUDE_OPUS_4_8_MODEL, CLAUDE_SONNET_5_MODEL]
@@ -608,6 +614,9 @@ var AGENT_CREDENTIAL_METHODS_IN_ORDER = {
608
614
  [AGENT.CURSOR]: [
609
615
  { method: CREDENTIAL_METHOD.API_KEY, credentialType: CREDENTIAL_TYPE.CURSOR_API_KEY }
610
616
  ],
617
+ [AGENT.DEEPSEEK]: [
618
+ { method: CREDENTIAL_METHOD.OPENROUTER, credentialType: CREDENTIAL_TYPE.OPENROUTER_API_KEY }
619
+ ],
611
620
  [AGENT.OPENCODE]: [
612
621
  { method: CREDENTIAL_METHOD.OPENCODE_GO, credentialType: CREDENTIAL_TYPE.OPENCODE_GO_API_KEY },
613
622
  { method: CREDENTIAL_METHOD.ASTER, credentialType: CREDENTIAL_TYPE.ASTER_API_KEY },
@@ -955,8 +964,11 @@ function containsKnownSecret(value, secrets) {
955
964
  return flattened.length >= MIN_SECRET_MATCH_CHARS && haystack.includes(flattened);
956
965
  }));
957
966
  }
958
- function isUnsafeMemoryOutput(value, secrets, maxChars) {
959
- return maxChars !== void 0 && value.length > maxChars || containsSecret(value) || containsKnownSecret(value, secrets);
967
+ function getMemoryOutputSafetyViolation(value, secrets, maxChars) {
968
+ if (maxChars !== void 0 && value.length > maxChars) return "max_chars";
969
+ if (containsSecret(value)) return "secret_pattern";
970
+ if (containsKnownSecret(value, secrets)) return "known_secret";
971
+ return null;
960
972
  }
961
973
 
962
974
  // ../shared/src/async.ts
@@ -1462,7 +1474,7 @@ var SLASH_COMMANDS = [
1462
1474
  command: "/plan",
1463
1475
  description: "Switch to plan mode and optionally send a prompt.",
1464
1476
  argumentHint: "[prompt]",
1465
- providers: ["claude", "codex", "cursor", "opencode", "pi", "relay"]
1477
+ providers: ["claude", "codex", "cursor", "deepseek", "opencode", "pi", "relay"]
1466
1478
  },
1467
1479
  {
1468
1480
  command: "/fast",
@@ -4273,6 +4285,162 @@ function parseCursorEvents(events) {
4273
4285
  return messages;
4274
4286
  }
4275
4287
 
4288
+ // ../shared/src/display-message/parsers/deepseek-parser.ts
4289
+ function parseArguments(value) {
4290
+ if (typeof value !== "string") return void 0;
4291
+ const parsed = safeJsonParse(value, value);
4292
+ return isRecord(parsed) ? parsed : stringifyDisplayValue(parsed);
4293
+ }
4294
+ function getDeepseekAssistantMessageText(event, blockType) {
4295
+ if (!isRecord(event) || event.type !== "assistant/message" || !isRecord(event.data) || !isRecord(event.data.message) || !Array.isArray(event.data.message.content)) return "";
4296
+ return event.data.message.content.flatMap((block) => isRecord(block) && block.type === blockType && typeof block.text === "string" ? [block.text] : []).join("");
4297
+ }
4298
+ function parseDeepseekEvents(events) {
4299
+ const messages = [];
4300
+ for (const source of events) {
4301
+ if (source.type === "event_msg" && source.payload.type === "user_message") {
4302
+ if (typeof source.payload.message === "string" && source.payload.message.trim()) {
4303
+ const messageId = source.payload[USER_MESSAGE_ID_PAYLOAD_KEY];
4304
+ messages.push({
4305
+ id: typeof messageId === "string" ? messageId : `deepseek-user-${source.timestamp}`,
4306
+ type: "user",
4307
+ content: source.payload.message,
4308
+ timestamp: source.timestamp
4309
+ });
4310
+ }
4311
+ continue;
4312
+ }
4313
+ if (source.type === "deepseek-error") {
4314
+ messages.push({
4315
+ id: `deepseek-error-${source.timestamp}`,
4316
+ type: "error",
4317
+ message: typeof source.payload.message === "string" ? source.payload.message : "DeepSeek Harness failed",
4318
+ timestamp: source.timestamp
4319
+ });
4320
+ continue;
4321
+ }
4322
+ if (source.type === "deepseek-input-request") {
4323
+ const requestId = typeof source.payload.requestId === "string" ? source.payload.requestId : `deepseek-input-${source.timestamp}`;
4324
+ if (source.payload.kind === "approval") {
4325
+ upsertDisplayMessage(messages, createCallDisplayMessage({
4326
+ id: requestId,
4327
+ server: "deepseek",
4328
+ tool: typeof source.payload.toolName === "string" ? source.payload.toolName : "approval",
4329
+ input: typeof source.payload.reason === "string" ? source.payload.reason : void 0,
4330
+ status: "in_progress",
4331
+ timestamp: source.timestamp,
4332
+ inputRequest: {
4333
+ requestId,
4334
+ status: "pending",
4335
+ options: [
4336
+ { id: "deny", label: "Deny", variant: "secondary" },
4337
+ { id: "allow", label: "Allow once", variant: "primary" }
4338
+ ]
4339
+ }
4340
+ }));
4341
+ } else {
4342
+ const questions = Array.isArray(source.payload.questions) ? source.payload.questions : [];
4343
+ upsertDisplayMessage(messages, createCallDisplayMessage({
4344
+ id: requestId,
4345
+ server: "deepseek",
4346
+ tool: "ask_user",
4347
+ status: "in_progress",
4348
+ timestamp: source.timestamp,
4349
+ inputRequest: {
4350
+ requestId,
4351
+ status: "pending",
4352
+ questions: questions.flatMap((question) => {
4353
+ if (!isRecord(question) || typeof question.id !== "string" || typeof question.question !== "string") return [];
4354
+ const options = Array.isArray(question.options) ? question.options : [];
4355
+ return [{
4356
+ id: question.id,
4357
+ prompt: question.question,
4358
+ multiSelect: question.multiSelect === true,
4359
+ options: options.flatMap((option) => isRecord(option) && typeof option.label === "string" ? [{ id: `${question.id}:${option.label}`, label: option.label, ...typeof option.description === "string" ? { description: option.description } : {} }] : [])
4360
+ }];
4361
+ })
4362
+ }
4363
+ }));
4364
+ }
4365
+ continue;
4366
+ }
4367
+ if (source.type === "deepseek-input-resolved") {
4368
+ const requestId = typeof source.payload.requestId === "string" ? source.payload.requestId : "";
4369
+ const existing = messages.find((message) => message.type === "tool_call" && message.inputRequest?.requestId === requestId);
4370
+ if (existing?.type === "tool_call" && existing.inputRequest) {
4371
+ existing.inputRequest.status = source.payload.status === "aborted" ? "aborted" : "resolved";
4372
+ existing.status = source.payload.status === "aborted" ? "failed" : "completed";
4373
+ }
4374
+ continue;
4375
+ }
4376
+ if (source.type === "deepseek-jobs" && Array.isArray(source.payload.jobs)) {
4377
+ for (const job of source.payload.jobs) {
4378
+ if (!isRecord(job) || typeof job.id !== "string") continue;
4379
+ const existing = messages.find((message) => message.type === "background_task" && message.taskId === job.id);
4380
+ const status = normalizeBackgroundTaskStatus(job.status);
4381
+ const next = {
4382
+ id: existing?.id ?? `deepseek-job-${job.id}`,
4383
+ type: "background_task",
4384
+ taskId: job.id,
4385
+ status,
4386
+ description: typeof job.label === "string" ? job.label : void 0,
4387
+ taskType: typeof job.kind === "string" ? job.kind : void 0,
4388
+ error: status === "failed" && typeof job.detail === "string" ? job.detail : void 0,
4389
+ timestamp: existing?.timestamp ?? source.timestamp
4390
+ };
4391
+ if (existing?.type === "background_task") Object.assign(existing, next);
4392
+ else messages.push(next);
4393
+ }
4394
+ continue;
4395
+ }
4396
+ if (source.type !== "deepseek-session-event" || !isRecord(source.payload.event)) continue;
4397
+ const event = source.payload.event;
4398
+ const data = isRecord(event.data) ? event.data : {};
4399
+ const seq = typeof event.seq === "number" ? event.seq : source.timestamp;
4400
+ if (event.type === "assistant/message") {
4401
+ const content = getDeepseekAssistantMessageText(event, "text");
4402
+ const reasoning = getDeepseekAssistantMessageText(event, "reasoning");
4403
+ if (reasoning.trim()) messages.push({ id: `deepseek-reasoning-${seq}`, type: "reasoning", content: reasoning, status: "completed", timestamp: source.timestamp });
4404
+ if (content.trim()) messages.push({ id: `deepseek-assistant-${seq}`, type: "agent", content, timestamp: source.timestamp });
4405
+ continue;
4406
+ }
4407
+ if (event.type === "tool/call") {
4408
+ const callId = typeof data.callId === "string" ? data.callId : String(seq);
4409
+ upsertDisplayMessage(messages, createCallDisplayMessage({
4410
+ id: `deepseek-tool-${callId}`,
4411
+ server: "deepseek",
4412
+ tool: typeof data.name === "string" ? data.name : "tool",
4413
+ input: parseArguments(data.arguments),
4414
+ status: "in_progress",
4415
+ timestamp: source.timestamp
4416
+ }));
4417
+ continue;
4418
+ }
4419
+ if (event.type === "tool/result") {
4420
+ const callId = typeof data.callId === "string" ? data.callId : String(seq);
4421
+ const existing = messages.find((message) => message.id === `deepseek-tool-${callId}` && message.type === "tool_call");
4422
+ if (existing?.type === "tool_call") {
4423
+ existing.output = stringifyDisplayValue(data.message ?? data.result);
4424
+ existing.status = data.isError === true ? "failed" : "completed";
4425
+ }
4426
+ continue;
4427
+ }
4428
+ if (event.type === "todo/write" && Array.isArray(data.items)) {
4429
+ messages.push({
4430
+ id: `deepseek-todo-${seq}`,
4431
+ type: "todo_list",
4432
+ items: data.items.flatMap((item) => {
4433
+ if (!isRecord(item) || typeof item.content !== "string") return [];
4434
+ const itemStatus = item.status === "in_progress" || item.status === "completed" ? item.status : "pending";
4435
+ return [{ text: item.content, completed: itemStatus === "completed", itemStatus }];
4436
+ }),
4437
+ timestamp: source.timestamp
4438
+ });
4439
+ }
4440
+ }
4441
+ return messages;
4442
+ }
4443
+
4276
4444
  // ../shared/src/display-message/parsers/opencode-parser.ts
4277
4445
  function timestampFromMs(value, fallback) {
4278
4446
  return typeof value === "number" && Number.isFinite(value) ? new Date(value).toISOString() : fallback;
@@ -5431,6 +5599,9 @@ function parseAgentEvents(events, agentType) {
5431
5599
  if (agentType === "cursor") {
5432
5600
  return parseCursorEvents(events);
5433
5601
  }
5602
+ if (agentType === "deepseek") {
5603
+ return parseDeepseekEvents(events);
5604
+ }
5434
5605
  if (agentType === "opencode") {
5435
5606
  return parseOpencodeEvents(events);
5436
5607
  }
@@ -5929,7 +6100,7 @@ var DEFAULT_CODEX_ARGS = [
5929
6100
  var MIN_CODEX_CLI_VERSION = "0.144.6";
5930
6101
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
5931
6102
  var codexCliVersionEnsured = null;
5932
- var ENGINE_PACKAGE_VERSION = "0.1.652";
6103
+ var ENGINE_PACKAGE_VERSION = "0.1.654";
5933
6104
  var INITIALIZE_METHOD = "initialize";
5934
6105
  var INITIALIZED_NOTIFICATION = "initialized";
5935
6106
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -6152,6 +6323,7 @@ export {
6152
6323
  createErrorResult,
6153
6324
  AGENT,
6154
6325
  VALID_AGENT_PROVIDERS,
6326
+ VALID_RELAY_SUBAGENT_PROVIDERS,
6155
6327
  isValidAgentProvider,
6156
6328
  VALID_THINKING_LEVELS,
6157
6329
  codexReasoningEffortForThinkingLevel,
@@ -6192,6 +6364,7 @@ export {
6192
6364
  DEFAULT_CODEX_MODEL,
6193
6365
  DEFAULT_CURSOR_MODEL,
6194
6366
  DEFAULT_OPENCODE_MODEL,
6367
+ DEFAULT_DEEPSEEK_MODEL,
6195
6368
  DEFAULT_PI_MODEL,
6196
6369
  getDefaultAgentModel,
6197
6370
  normalizeClaudeModel,
@@ -6280,6 +6453,7 @@ export {
6280
6453
  getEventTimestampMs,
6281
6454
  areSameUserMessageEvents,
6282
6455
  parseAgentEventJsonlWithCodexAspTranscript,
6456
+ getDeepseekAssistantMessageText,
6283
6457
  extractToolResultText,
6284
6458
  normalizeContentBlocks,
6285
6459
  TaskAccumulator,
@@ -6294,7 +6468,7 @@ export {
6294
6468
  MEMORY_ROOT,
6295
6469
  MEMORY_SUMMARY_FILENAME,
6296
6470
  MEMORY_INDEX_FILENAME,
6297
- isUnsafeMemoryOutput,
6471
+ getMemoryOutputSafetyViolation,
6298
6472
  isSkillRegistryManifest,
6299
6473
  putPresignedFile,
6300
6474
  buildCodexAgentEnv,
@@ -3,11 +3,11 @@ import {
3
3
  AGENT,
4
4
  AppServerProcess,
5
5
  buildCodexAgentEnv,
6
+ getMemoryOutputSafetyViolation,
6
7
  headlessAgentRequestSchema,
7
- isUnsafeMemoryOutput,
8
8
  putPresignedFile,
9
9
  recoverCompletedTurn
10
- } from "./chunk-XUQTF7P5.js";
10
+ } from "./chunk-DDFRCI5Q.js";
11
11
 
12
12
  // src/headless-agent.ts
13
13
  import { createHash } from "crypto";
@@ -59,8 +59,13 @@ async function publishFilesystemOutputs(request) {
59
59
  for (const output of request.outputFiles) {
60
60
  const filePath = resolveFile(request.workingDirectory, output.path);
61
61
  const content = (await readFile(filePath, "utf8")).trim();
62
- if (output.minChars !== void 0 && content.length < output.minChars || isUnsafeMemoryOutput(content, request.sensitiveValues, output.maxChars)) {
63
- throw new Error(`Headless agent output failed validation: ${output.path}`);
62
+ if (output.minChars !== void 0 && content.length < output.minChars) {
63
+ throw new Error(`Headless agent output failed validation: ${output.path} has ${content.length} characters; minimum is ${output.minChars}`);
64
+ }
65
+ const safetyViolation = getMemoryOutputSafetyViolation(content, request.sensitiveValues, output.maxChars);
66
+ if (safetyViolation) {
67
+ const reason = safetyViolation === "max_chars" ? `has ${content.length} characters; maximum is ${output.maxChars}` : safetyViolation === "secret_pattern" ? "contains secret-like content" : "contains an installed credential";
68
+ throw new Error(`Headless agent output failed validation: ${output.path} ${reason}`);
64
69
  }
65
70
  await writeFile(filePath, content, { mode: 384 });
66
71
  const { size } = await stat(filePath);