@runtypelabs/sdk 1.9.1 → 1.10.0

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.
package/dist/index.cjs CHANGED
@@ -1966,7 +1966,7 @@ var TOOL_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_]{1,63}$/;
1966
1966
  var DEFAULT_MAX_CODE_LENGTH = 12e3;
1967
1967
  var DEFAULT_MAX_TIMEOUT_MS = 3e4;
1968
1968
  var DEFAULT_BLOCKED_CODE_PATTERNS = [
1969
- /\b(?:child_process|fs|net|tls|http|https|os)\b/i,
1969
+ /\b(?:child_process|fs|net|tls|os)\b/i,
1970
1970
  /\b(?:process|Deno|Bun)\b/i,
1971
1971
  /\b(?:require|import)\s*\(/i,
1972
1972
  /\beval\s*\(/i,
@@ -2785,7 +2785,7 @@ var executionPhase = {
2785
2785
  `After that, you may update "${normalizedPlanPath}" with progress.`
2786
2786
  ].join(" ");
2787
2787
  }
2788
- if (normalizedPathArg && normalizedPathArg !== normalizedPlanPath) {
2788
+ if (!ctx.state.isCreationTask && normalizedPathArg && normalizedPathArg !== normalizedPlanPath) {
2789
2789
  const allowedWriteTargets = new Set(
2790
2790
  [
2791
2791
  normalizedPlanPath,
@@ -2802,6 +2802,23 @@ var executionPhase = {
2802
2802
  ].join(" ");
2803
2803
  }
2804
2804
  }
2805
+ if (ctx.state.isCreationTask && normalizedPathArg && normalizedPathArg !== normalizedPlanPath) {
2806
+ const outputRoot = ctx.state.outputRoot ? ctx.state.outputRoot.trim().replace(/\\/g, "/").replace(/\/+/g, "/").replace(/\/$/, "") || void 0 : void 0;
2807
+ if (!outputRoot) {
2808
+ return [
2809
+ `Blocked by marathon execution guard: creation tasks require outputRoot. Writes outside the plan are not allowed.`,
2810
+ `Plan path: "${normalizedPlanPath}". Create files only under the configured output root.`
2811
+ ].join(" ");
2812
+ }
2813
+ const rootPrefix = outputRoot + "/";
2814
+ const isUnderRoot = normalizedPathArg === outputRoot || normalizedPathArg.startsWith(rootPrefix);
2815
+ if (!isUnderRoot) {
2816
+ return [
2817
+ `Blocked by marathon execution guard: ${toolName} must target the plan or paths under outputRoot "${outputRoot}/".`,
2818
+ `"${normalizedPathArg}" is outside the allowed output root.`
2819
+ ].join(" ");
2820
+ }
2821
+ }
2805
2822
  }
2806
2823
  return void 0;
2807
2824
  },
@@ -2814,6 +2831,17 @@ var executionPhase = {
2814
2831
  },
2815
2832
  buildRecoveryMessage(state) {
2816
2833
  const recent = state.sessions.slice(-2);
2834
+ if (recent.length >= 2 && recent.every(
2835
+ (session) => session.verificationAttempted === true && session.wroteFiles !== true
2836
+ )) {
2837
+ return [
2838
+ "Recovery instruction:",
2839
+ "You have attempted verification in multiple sessions but none passed, and no files were written.",
2840
+ "If the project lacks test/lint/build tooling, verification cannot succeed.",
2841
+ "Focus on completing any remaining implementation. Signal TASK_COMPLETE when done.",
2842
+ "Do not retry run_check unless you have a specific command likely to succeed."
2843
+ ].join("\n");
2844
+ }
2817
2845
  const normalizedPlanPath = typeof state.planPath === "string" && state.planPath.trim() ? normalizeCandidatePath(state.planPath) : void 0;
2818
2846
  const recentPlanOnlyLoop = Boolean(normalizedPlanPath) && recent.length === 2 && recent.every((session) => {
2819
2847
  const specificActionKeys = (session.actionKeys || []).map((actionKey) => actionKey.replace(/\\/g, "/")).filter((actionKey) => !actionKey.startsWith("server:"));
@@ -2856,6 +2884,57 @@ var executionPhase = {
2856
2884
  };
2857
2885
  function classifyVariant(message) {
2858
2886
  const lower = message.toLowerCase();
2887
+ const modificationVerbs = [
2888
+ "fix",
2889
+ "update",
2890
+ "change",
2891
+ "modify",
2892
+ "edit",
2893
+ "refactor",
2894
+ "improve",
2895
+ "add to",
2896
+ "remove",
2897
+ "delete",
2898
+ "rename",
2899
+ "migrate"
2900
+ ];
2901
+ const hasModificationVerb = modificationVerbs.some(
2902
+ (v) => lower.startsWith(v) || new RegExp(`\\b${v}\\b`).test(lower)
2903
+ );
2904
+ const creationPatterns = [
2905
+ /^create\b/,
2906
+ /^build\b/,
2907
+ /^make\b/,
2908
+ /^generate\b/,
2909
+ /^scaffold\b/,
2910
+ /^set up\b/,
2911
+ /^setup\b/,
2912
+ /^bootstrap\b/,
2913
+ /^initialize\b/,
2914
+ /^init\b/,
2915
+ /^write a\b/,
2916
+ /^write an\b/,
2917
+ /^implement a\b/,
2918
+ /^implement an\b/,
2919
+ /^start a\b/,
2920
+ /^start an\b/,
2921
+ /^new\b/
2922
+ ];
2923
+ const hasCreationStart = creationPatterns.some((p) => p.test(lower));
2924
+ const creationVerbs = [
2925
+ "build",
2926
+ "create",
2927
+ "make",
2928
+ "generate",
2929
+ "scaffold",
2930
+ "implement"
2931
+ ];
2932
+ const hasCreationVerb = creationVerbs.some(
2933
+ (v) => new RegExp(`\\b${v}\\b`).test(lower)
2934
+ );
2935
+ if ((hasCreationStart || hasCreationVerb) && !hasModificationVerb) {
2936
+ return "create";
2937
+ }
2859
2938
  const externalVerbs = [
2860
2939
  "fetch",
2861
2940
  "browse",
@@ -2895,49 +2974,9 @@ function classifyVariant(message) {
2895
2974
  ];
2896
2975
  const hasExternalVerb = externalVerbs.some((v) => lower.includes(v));
2897
2976
  const hasExternalTarget = externalTargets.some((t) => lower.includes(t));
2898
- const modificationVerbs = [
2899
- "fix",
2900
- "update",
2901
- "change",
2902
- "modify",
2903
- "edit",
2904
- "refactor",
2905
- "improve",
2906
- "add to",
2907
- "remove",
2908
- "delete",
2909
- "rename",
2910
- "migrate"
2911
- ];
2912
- const hasModificationVerb = modificationVerbs.some(
2913
- (v) => lower.startsWith(v) || new RegExp(`\\b${v}\\b`).test(lower)
2914
- );
2915
2977
  if (hasExternalVerb && hasExternalTarget && !hasModificationVerb) {
2916
2978
  return "external";
2917
2979
  }
2918
- const creationPatterns = [
2919
- /^create\b/,
2920
- /^build\b/,
2921
- /^make\b/,
2922
- /^generate\b/,
2923
- /^scaffold\b/,
2924
- /^set up\b/,
2925
- /^setup\b/,
2926
- /^bootstrap\b/,
2927
- /^initialize\b/,
2928
- /^init\b/,
2929
- /^write a\b/,
2930
- /^write an\b/,
2931
- /^implement a\b/,
2932
- /^implement an\b/,
2933
- /^start a\b/,
2934
- /^start an\b/,
2935
- /^new\b/
2936
- ];
2937
- const hasCreationStart = creationPatterns.some((p) => p.test(lower));
2938
- if (hasCreationStart && !hasModificationVerb) {
2939
- return "create";
2940
- }
2941
2980
  return "modify";
2942
2981
  }
2943
2982
  async function generateBootstrapContext(message, localTools, variant) {
@@ -4775,6 +4814,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
4775
4814
  bestCandidateVerified: false,
4776
4815
  verificationAttempted: false,
4777
4816
  verificationPassed: false,
4817
+ verificationBlocked: false,
4778
4818
  localToolLoopGuardTriggered: false
4779
4819
  };
4780
4820
  }
@@ -4996,6 +5036,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
4996
5036
  if (typeof parsed.success !== "boolean") return void 0;
4997
5037
  return {
4998
5038
  success: parsed.success,
5039
+ ...typeof parsed.blocked === "boolean" ? { blocked: parsed.blocked } : {},
4999
5040
  ...typeof parsed.command === "string" ? { command: parsed.command } : {},
5000
5041
  ...typeof parsed.output === "string" ? { output: parsed.output } : {},
5001
5042
  ...typeof parsed.error === "string" ? { error: parsed.error } : {}
@@ -5223,9 +5264,11 @@ var _AgentsEndpoint = class _AgentsEndpoint {
5223
5264
  bestCandidateVerified: Boolean(resumeState.bestCandidateVerified),
5224
5265
  ...resumeState.verificationRequired !== void 0 ? { verificationRequired: resumeState.verificationRequired } : {},
5225
5266
  lastVerificationPassed: Boolean(resumeState.lastVerificationPassed),
5267
+ ...resumeState.consecutiveBlockedVerificationSessions !== void 0 ? { consecutiveBlockedVerificationSessions: resumeState.consecutiveBlockedVerificationSessions } : {},
5226
5268
  ...resumeState.isCreationTask !== void 0 ? { isCreationTask: resumeState.isCreationTask } : {},
5227
5269
  ...resumeState.workflowVariant !== void 0 ? { workflowVariant: resumeState.workflowVariant } : {},
5228
- ...resumeState.workflowState !== void 0 ? { workflowState: resumeState.workflowState } : {}
5270
+ ...resumeState.workflowState !== void 0 ? { workflowState: resumeState.workflowState } : {},
5271
+ ...typeof resumeState.outputRoot === "string" && resumeState.outputRoot.trim() ? { outputRoot: resumeState.outputRoot.trim().replace(/\\/g, "/").replace(/\/+/g, "/") } : {}
5229
5272
  };
5230
5273
  }
5231
5274
  buildPhaseInstructions(state, workflow) {
@@ -5352,6 +5395,10 @@ var _AgentsEndpoint = class _AgentsEndpoint {
5352
5395
  } else if (state.workflowPhase === "execution") {
5353
5396
  trace.executionFileWritten = true;
5354
5397
  trace.verificationPassed = false;
5398
+ if (!this.isMarathonArtifactPath(normalizedPathArg)) {
5399
+ trace.bestCandidatePath = normalizedPathArg;
5400
+ trace.bestCandidateReason = "written by agent during execution";
5401
+ }
5355
5402
  if (normalizedBestCandidatePath && normalizedPathArg === normalizedBestCandidatePath) {
5356
5403
  trace.bestCandidateWritten = true;
5357
5404
  }
@@ -5361,6 +5408,9 @@ var _AgentsEndpoint = class _AgentsEndpoint {
5361
5408
  if (verificationResult) {
5362
5409
  trace.verificationAttempted = true;
5363
5410
  trace.verificationPassed = verificationResult.success;
5411
+ if (verificationResult.blocked) {
5412
+ trace.verificationBlocked = true;
5413
+ }
5364
5414
  }
5365
5415
  const summarizedResult = verificationResult ? [
5366
5416
  verificationResult.command || "verification",
@@ -5683,6 +5733,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
5683
5733
  };
5684
5734
  state.workflowVariant = classifiedVariant;
5685
5735
  state.isCreationTask = seededResumeState?.isCreationTask ?? state.workflowVariant === "create";
5736
+ state.outputRoot = seededResumeState?.outputRoot ?? (state.isCreationTask ? "public/" : void 0);
5686
5737
  this.updateWorkflowPhase(state, this.createEmptyToolTrace(), workflow);
5687
5738
  let recordId;
5688
5739
  const localToolNames = options.localTools ? Object.keys(options.localTools) : void 0;
@@ -5755,6 +5806,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
5755
5806
  messages,
5756
5807
  debugMode: options.debugMode,
5757
5808
  model: options.model,
5809
+ ...options.reasoning !== void 0 ? { reasoning: options.reasoning } : {},
5758
5810
  ...options.toolIds?.length ? { tools: { toolIds: options.toolIds } } : {},
5759
5811
  ...requestContextManagement ? { contextManagement: requestContextManagement } : {}
5760
5812
  };
@@ -5853,6 +5905,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
5853
5905
  hadTextOutput: Boolean(sessionResult.result.trim()),
5854
5906
  verificationAttempted: sessionTrace.verificationAttempted,
5855
5907
  verificationPassed: sessionTrace.verificationPassed,
5908
+ verificationBlocked: sessionTrace.verificationBlocked || void 0,
5856
5909
  bestCandidatePath: sessionTrace.bestCandidatePath || void 0,
5857
5910
  actionKeys: sessionTrace.actionKeys.slice(-5),
5858
5911
  completedAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -5893,6 +5946,21 @@ var _AgentsEndpoint = class _AgentsEndpoint {
5893
5946
  }
5894
5947
  if (sessionTrace.verificationAttempted) {
5895
5948
  state.lastVerificationPassed = sessionTrace.verificationPassed;
5949
+ if (sessionTrace.verificationBlocked && !sessionTrace.verificationPassed) {
5950
+ state.consecutiveBlockedVerificationSessions = (state.consecutiveBlockedVerificationSessions || 0) + 1;
5951
+ } else {
5952
+ state.consecutiveBlockedVerificationSessions = 0;
5953
+ }
5954
+ }
5955
+ if ((state.consecutiveBlockedVerificationSessions || 0) >= 2 && state.verificationRequired) {
5956
+ state.verificationRequired = false;
5957
+ state.lastVerificationPassed = true;
5958
+ if (!state.planWritten) {
5959
+ state.planWritten = true;
5960
+ }
5961
+ if (!state.bestCandidateVerified) {
5962
+ state.bestCandidateVerified = true;
5963
+ }
5896
5964
  }
5897
5965
  const modelKey = options.model || "default";
5898
5966
  if (!state.costByModel) state.costByModel = {};
@@ -6471,9 +6539,12 @@ Do NOT redo any of the above work.`
6471
6539
  const replayHistoryMessages = this.sanitizeReplayHistoryMessages(
6472
6540
  continuationContext.previousMessages
6473
6541
  );
6542
+ const continuationGuardrail = "IMPORTANT: You are continuing a previously completed task. The conversation above shows your prior work. Do NOT redo any of it. Build on what was already accomplished. If there is nothing new to do, respond with TASK_COMPLETE.";
6474
6543
  const defaultContinueMessage = "Continue the task. Review your prior work above and proceed with any remaining work. If everything is already complete, respond with TASK_COMPLETE.";
6475
6544
  const userMessage = continuationContext.newUserMessage || defaultContinueMessage;
6476
6545
  const userContent = [
6546
+ continuationGuardrail,
6547
+ "",
6477
6548
  userMessage,
6478
6549
  phaseBlock,
6479
6550
  toolsBlock,
@@ -6484,10 +6555,6 @@ Do NOT redo any of the above work.`
6484
6555
  ].join("\n");
6485
6556
  const fullHistoryMessages = [
6486
6557
  ...replayHistoryMessages,
6487
- {
6488
- role: "system",
6489
- content: "IMPORTANT: You are continuing a previously completed task. The conversation above shows your prior work. Do NOT redo any of it. Build on what was already accomplished. If there is nothing new to do, respond with TASK_COMPLETE."
6490
- },
6491
6558
  {
6492
6559
  role: "user",
6493
6560
  content: userContent