@spotpatch/agent 1.2.4 → 1.3.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.js CHANGED
@@ -1848,7 +1848,7 @@ var AGENT_TOOL_DEFINITIONS = Object.freeze([
1848
1848
  }),
1849
1849
  Object.freeze({
1850
1850
  name: AGENT_TOOL_NAMES.readFile,
1851
- description: "Read a bounded inclusive line range from one allowed UTF-8 text file. Choose paths returned by list_files or search_text. A retryable TOOL_PATH_DENIED result means no file was read or changed: do not retry that path; discover an allowed path instead.",
1851
+ description: "Read a bounded inclusive line range from one allowed UTF-8 text file. Choose an exact path supplied by trusted SpotPatch context or returned by list_files or search_text. A retryable TOOL_PATH_DENIED result means no file was read or changed: do not retry that path; discover an allowed path instead.",
1852
1852
  parameters: Object.freeze({
1853
1853
  type: "object",
1854
1854
  properties: Object.freeze({
@@ -1902,6 +1902,11 @@ var AGENT_TOOL_DEFINITIONS = Object.freeze([
1902
1902
  })
1903
1903
  })
1904
1904
  ]);
1905
+ var AGENT_TOOL_DEFINITIONS_WITHOUT_CHECKS = Object.freeze(
1906
+ AGENT_TOOL_DEFINITIONS.filter(
1907
+ (definition) => definition.name !== AGENT_TOOL_NAMES.runCheck
1908
+ )
1909
+ );
1905
1910
 
1906
1911
  // src/tools/tool-executor.ts
1907
1912
  var SEARCH_READ_CONCURRENCY = 8;
@@ -2855,6 +2860,7 @@ import {
2855
2860
  var MAX_PROJECT_CONVENTION_CHARACTERS = 3500;
2856
2861
  var MAX_VALIDATION_CHECK_CHARACTERS = 1200;
2857
2862
  var MINIMUM_SELECTION_CONTEXT_CHARACTERS = 1024;
2863
+ var VALIDATION_SYSTEM_INSTRUCTION = "- Run each relevant configured check after the final write so failures can be corrected. Do not rerun an unchanged check, and do not claim a check passed unless run_check returned a passed status.\n";
2858
2864
  var AGENT_SYSTEM_INSTRUCTIONS = `You are editing code only inside a disposable, isolated Git worktree.
2859
2865
 
2860
2866
  Follow these rules exactly:
@@ -2871,8 +2877,11 @@ Follow these rules exactly:
2871
2877
  - If any tool returns a retryable TOOL_ARGUMENTS_INVALID result, no file changed. Retry once with a new tool call ID using only the declared fields and value types.
2872
2878
  - If read_file returns a retryable TOOL_PATH_DENIED result, no file was read or changed. Do not retry that path. Use list_files or search_text and choose an allowed path returned by the tool; never probe protected, external, generated, credential, environment, or lock files.
2873
2879
  - Never modify credentials, environment files, lockfiles, generated output, Git metadata, or dependencies.
2874
- - Run each relevant configured check after the final write so failures can be corrected. Do not rerun an unchanged check, and do not claim a check passed unless run_check returned a passed status.
2880
+ ${VALIDATION_SYSTEM_INSTRUCTION.trimEnd()}
2875
2881
  - Finish with a concise factual summary after all needed tool calls. Do not include secrets or absolute paths.`;
2882
+ function resolveAgentSystemInstructions(trustedFast) {
2883
+ return trustedFast ? AGENT_SYSTEM_INSTRUCTIONS.replace(VALIDATION_SYSTEM_INSTRUCTION, "") : AGENT_SYSTEM_INSTRUCTIONS;
2884
+ }
2876
2885
  function redactedJson(value) {
2877
2886
  return JSON.stringify(
2878
2887
  value,
@@ -3064,7 +3073,8 @@ function composeAgentUserPrompt(annotation, maximumCharacters, context = {}) {
3064
3073
  (target, index) => `Target ${String(index + 1)}:
3065
3074
  ${redactSensitiveText2(target.instruction.trim())}`
3066
3075
  ).join("\n\n");
3067
- const requestBlock = `${requestPrefix}${request}`;
3076
+ const trustedFastBlock = context.trustedFast ? "\n\nTrusted direct execution is enabled. Start from each target's supplied code.relativePath or source.relativePath. When an exact path is present, do not call list_files first. Read each affected file once unless a write is rejected, make the smallest exact replacement that satisfies the request, and finish immediately after the successful write. No project validation check is available in this mode." : "";
3077
+ const requestBlock = `${requestPrefix}${request}${trustedFastBlock}`;
3068
3078
  const checksPrefix = "\n\nConfigured validation checks (IDs and labels only):\n<validation_checks>\n";
3069
3079
  const checksSuffix = "\n</validation_checks>";
3070
3080
  if (requestBlock.length + contextPrefix.length + suffix.length + MINIMUM_SELECTION_CONTEXT_CHARACTERS > maximumCharacters) {
@@ -3167,6 +3177,8 @@ async function executeToolCalls(calls, turn, executor, callbacks, signal) {
3167
3177
  return Object.freeze(results);
3168
3178
  }
3169
3179
  async function executeAgentChange(options) {
3180
+ const trustedFast = options.execution.applyMode === "trusted-auto";
3181
+ const activeChecks = trustedFast ? Object.freeze({}) : options.execution.checks;
3170
3182
  const controller = new AbortController();
3171
3183
  const unlink = linkSignal(options.signal, controller);
3172
3184
  let jobTimedOut = false;
@@ -3198,7 +3210,7 @@ async function executeAgentChange(options) {
3198
3210
  })
3199
3211
  );
3200
3212
  const executor = createAgentToolExecutor({
3201
- checks: options.execution.checks,
3213
+ checks: activeChecks,
3202
3214
  limits: options.execution.limits,
3203
3215
  worktreeRoot: worktree.root,
3204
3216
  onCheck(result2) {
@@ -3214,16 +3226,17 @@ async function executeAgentChange(options) {
3214
3226
  provider: options.provider,
3215
3227
  model: options.model,
3216
3228
  credential: options.credential,
3217
- instructions: AGENT_SYSTEM_INSTRUCTIONS,
3229
+ instructions: resolveAgentSystemInstructions(trustedFast),
3218
3230
  userPrompt: composeAgentUserPrompt(
3219
3231
  options.annotation,
3220
3232
  options.promptMaxCharacters ?? 16e3,
3221
3233
  Object.freeze({
3222
- checks: options.execution.checks,
3223
- projectConventions
3234
+ checks: activeChecks,
3235
+ projectConventions,
3236
+ trustedFast
3224
3237
  })
3225
3238
  ),
3226
- tools: AGENT_TOOL_DEFINITIONS,
3239
+ tools: trustedFast ? AGENT_TOOL_DEFINITIONS_WITHOUT_CHECKS : AGENT_TOOL_DEFINITIONS,
3227
3240
  limits: options.execution.limits,
3228
3241
  ...options.fetch === void 0 ? {} : { fetch: options.fetch }
3229
3242
  });
@@ -3260,7 +3273,7 @@ async function executeAgentChange(options) {
3260
3273
  options.callbacks?.onPhase?.(
3261
3274
  Object.freeze({
3262
3275
  phase: "validating",
3263
- message: "Validating proposed changes."
3276
+ message: trustedFast ? "Preparing trusted change for direct apply." : "Validating proposed changes."
3264
3277
  })
3265
3278
  );
3266
3279
  const initialChangeSet = await collectAgentChangeSet(
@@ -3269,7 +3282,7 @@ async function executeAgentChange(options) {
3269
3282
  options.execution.limits,
3270
3283
  controller.signal
3271
3284
  );
3272
- const requiredChecks = initialChangeSet.diff.length === 0 ? [] : Object.values(options.execution.checks).filter((check) => check.required);
3285
+ const requiredChecks = initialChangeSet.diff.length === 0 ? [] : Object.values(activeChecks).filter((check) => check.required);
3273
3286
  const finalChecks = [];
3274
3287
  let ranFinalCheck = false;
3275
3288
  for (const check of requiredChecks) {