topchester-ai 0.64.0 → 0.65.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/bin.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as runTopchesterCli } from "./cli-CnI4QA2l.mjs";
2
+ import { t as runTopchesterCli } from "./cli-2v1iJ0YF.mjs";
3
3
  //#region src/bin.ts
4
4
  await runTopchesterCli();
5
5
  //#endregion
@@ -1843,7 +1843,7 @@ async function deleteWorkspaceFile(workspaceRoot, path) {
1843
1843
  const finishTaskTool = defineTool({
1844
1844
  name: "finish_task",
1845
1845
  description: "Finish the current task only after the requested work has actually been completed with tools. Do not use this to claim edits, file reads, or validation that did not happen.",
1846
- prompt: "finish_task: complete the task with a brief final response only after tool results prove the work is done. For implementation tasks, do not call finish_task until source files were changed by edit_file, write_file, apply_patch, or another mutating tool, unless no code change is truly required. Example: {\"tool\":\"finish_task\",\"args\":{\"final_response\":\"Changed src/foo.ts and ran pnpm test foo.test.ts.\",\"files_changed\":[\"src/foo.ts\"],\"validation\":[\"pnpm test foo.test.ts\"],\"remaining_issues\":[]}}",
1846
+ prompt: "finish_task: complete the task with a brief final response only after tool results prove the work is done. In benchmark or require-finish mode, this is the only valid terminal action; normal assistant messages are progress notes and do not finish the task. For implementation tasks, do not call finish_task until source files were changed by edit_file, write_file, apply_patch, or another mutating tool, unless no code change is truly required. Example: {\"tool\":\"finish_task\",\"args\":{\"final_response\":\"Changed src/foo.ts and ran pnpm test foo.test.ts.\",\"files_changed\":[\"src/foo.ts\"],\"validation\":[\"pnpm test foo.test.ts\"],\"remaining_issues\":[]}}",
1847
1847
  argsSchema: z.object({
1848
1848
  final_response: z.string().describe("Brief final response for the user."),
1849
1849
  files_changed: z.array(z.string()).optional().describe("Workspace-relative files actually changed by successful edit tools."),
@@ -12855,6 +12855,22 @@ function formatNoEditCompletionFailure(draftAnswer) {
12855
12855
  const trimmedDraft = draftAnswer.trim();
12856
12856
  return ["I could not complete the implementation because no successful source-file edit occurred in this turn.", trimmedDraft ? `The model tried to finish with this unsupported summary:\n${trimmedDraft}` : ""].filter(Boolean).join("\n");
12857
12857
  }
12858
+ function formatFinishTaskRequiredRepairInstruction(protocol, draftAnswer) {
12859
+ const toolInstruction = protocol === "text-xml" ? "Reply now with only one XML tool call for the next implementation or validation step, or call finish_task if the work is complete." : protocol === "text-json" ? "Reply now with only one tool JSON object for the next implementation or validation step, or call finish_task if the work is complete." : "Use the available tool calling path now for the next implementation or validation step, or call finish_task if the work is complete.";
12860
+ const trimmedDraft = draftAnswer.trim();
12861
+ return [
12862
+ "This run requires finish_task as the only terminal action.",
12863
+ "A normal assistant message is treated as a progress note, not completion.",
12864
+ "Do not summarize next steps in prose. Use tools to perform the next step.",
12865
+ "Call finish_task only when the requested work is complete and its files_changed, validation, and remaining_issues fields are accurate.",
12866
+ toolInstruction,
12867
+ trimmedDraft ? `Previous progress note that did not finish the task:\n${trimmedDraft}` : ""
12868
+ ].filter(Boolean).join("\n");
12869
+ }
12870
+ function formatFinishTaskRequiredFailure(draftAnswer) {
12871
+ const trimmedDraft = draftAnswer.trim();
12872
+ return ["I stopped because this run requires finish_task, but the model kept replying with normal assistant messages instead of using tools.", trimmedDraft ? `Last progress note:\n${trimmedDraft}` : ""].filter(Boolean).join("\n");
12873
+ }
12858
12874
  function getTextToolCallSources(protocol) {
12859
12875
  return protocol === "text-xml" ? ["text-xml"] : protocol === "text-json" ? ["text-json"] : ["text-json", "text-xml"];
12860
12876
  }
@@ -13153,7 +13169,9 @@ const DEFAULT_MAX_TOOL_CALLS_PER_TURN = 75;
13153
13169
  const MAX_TOOL_CALLS_PER_TURN_ENV = "TOPCHESTER_MAX_TOOL_CALLS_PER_TURN";
13154
13170
  const PLAN_TODO_MODE_ENV = "TOPCHESTER_PLAN_TODO_MODE";
13155
13171
  const MAX_PLAN_TODO_UPDATES_PER_TURN_ENV = "TOPCHESTER_MAX_PLAN_TODO_UPDATES_PER_TURN";
13172
+ const REQUIRE_FINISH_TASK_ENV = "TOPCHESTER_REQUIRE_FINISH_TASK";
13156
13173
  const DEFAULT_COMPACT_MAX_PLAN_TODO_UPDATES_PER_TURN = 3;
13174
+ const MAX_FINISH_TASK_REQUIRED_REPAIRS = 3;
13157
13175
  const DEFAULT_TASK_CONCURRENCY = 3;
13158
13176
  var TopchesterAgentRuntime = class TopchesterAgentRuntime {
13159
13177
  context;
@@ -13280,12 +13298,14 @@ var TopchesterAgentRuntime = class TopchesterAgentRuntime {
13280
13298
  let requestedPlanClosure = false;
13281
13299
  let invalidToolCallRepairs = 0;
13282
13300
  let noEditCompletionRepairs = 0;
13301
+ let finishTaskRequiredRepairs = 0;
13283
13302
  let hasSourceMutation = false;
13284
13303
  const maxToolCallsPerTurn = readMaxToolCallsPerTurn();
13285
13304
  const planTodoMode = readPlanTodoMode();
13286
13305
  const maxPlanTodoUpdatesPerTurn = readMaxPlanTodoUpdatesPerTurn(planTodoMode);
13287
13306
  let planTodoUpdates = 0;
13288
13307
  const implementationTask = isImplementationTaskRequest(message);
13308
+ const requireFinishTask = isFinishTaskRequiredByEnv() && isToolAllowed(permissions, "finish_task");
13289
13309
  const projectInstructionToolState = { shownSourceKeys: /* @__PURE__ */ new Set() };
13290
13310
  const persistedProjectInstructionKeys = /* @__PURE__ */ new Set();
13291
13311
  try {
@@ -13396,6 +13416,18 @@ var TopchesterAgentRuntime = class TopchesterAgentRuntime {
13396
13416
  yield agentEvent.status("ready");
13397
13417
  return;
13398
13418
  }
13419
+ if (requireFinishTask) {
13420
+ if (finishTaskRequiredRepairs < MAX_FINISH_TASK_REQUIRED_REPAIRS) {
13421
+ finishTaskRequiredRepairs += 1;
13422
+ nextPrompt = `${nextPrompt}\n\n${formatFinishTaskRequiredRepairInstruction(result.toolProtocol, finalText)}`;
13423
+ continue;
13424
+ }
13425
+ const finalMessage = formatFinishTaskRequiredFailure(finalText);
13426
+ yield agentEvent.assistantMessage(finalMessage, formatAgentMessageMeta(result.modelId, totalDurationMs, tokenUsageTotals));
13427
+ for await (const event of this.streamStopHookEvents(session, finalMessage, "failed", abortSignal)) yield event;
13428
+ yield agentEvent.status("ready");
13429
+ return;
13430
+ }
13399
13431
  if (planTodoMode === "normal" && hasOpenTaskPlan(plan)) {
13400
13432
  if (!requestedPlanClosure) {
13401
13433
  requestedPlanClosure = true;
@@ -14046,6 +14078,10 @@ function readMaxToolCallsPerTurn() {
14046
14078
  function readPlanTodoMode() {
14047
14079
  return process.env[PLAN_TODO_MODE_ENV]?.trim().toLowerCase() === "compact" ? "compact" : "normal";
14048
14080
  }
14081
+ function isFinishTaskRequiredByEnv() {
14082
+ const raw = process.env[REQUIRE_FINISH_TASK_ENV]?.trim().toLowerCase();
14083
+ return raw === "1" || raw === "true" || raw === "yes" || raw === "on";
14084
+ }
14049
14085
  function readMaxPlanTodoUpdatesPerTurn(mode) {
14050
14086
  const raw = process.env[MAX_PLAN_TODO_UPDATES_PER_TURN_ENV]?.trim();
14051
14087
  if (!raw) return mode === "compact" ? DEFAULT_COMPACT_MAX_PLAN_TODO_UPDATES_PER_TURN : void 0;
@@ -16493,4 +16529,4 @@ function formatDryRunSyncStatus(status) {
16493
16529
  //#endregion
16494
16530
  export { runTopchesterCli as t };
16495
16531
 
16496
- //# sourceMappingURL=cli-CnI4QA2l.mjs.map
16532
+ //# sourceMappingURL=cli-2v1iJ0YF.mjs.map