@wrongstack/core 0.6.0 → 0.6.1

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 (35) hide show
  1. package/dist/{agent-bridge-BKNiE1VH.d.ts → agent-bridge-DaCvA_uK.d.ts} +1 -1
  2. package/dist/coordination/index.d.ts +5 -5
  3. package/dist/coordination/index.js +178 -54
  4. package/dist/coordination/index.js.map +1 -1
  5. package/dist/defaults/index.d.ts +10 -10
  6. package/dist/defaults/index.js +534 -75
  7. package/dist/defaults/index.js.map +1 -1
  8. package/dist/{events-DPQKFX7W.d.ts → events-CzkeaVVl.d.ts} +8 -2
  9. package/dist/execution/index.d.ts +149 -6
  10. package/dist/execution/index.js +345 -16
  11. package/dist/execution/index.js.map +1 -1
  12. package/dist/extension/index.d.ts +2 -2
  13. package/dist/{goal-store-BQ3YX1h1.d.ts → goal-store-DVCfj7Ff.d.ts} +20 -0
  14. package/dist/{index-B0qTujQW.d.ts → index-BkKLQjea.d.ts} +1 -1
  15. package/dist/{index-DkdRz6yK.d.ts → index-i9rPR53g.d.ts} +11 -4
  16. package/dist/index.d.ts +50 -16
  17. package/dist/index.js +769 -86
  18. package/dist/index.js.map +1 -1
  19. package/dist/infrastructure/index.d.ts +2 -2
  20. package/dist/kernel/index.d.ts +2 -2
  21. package/dist/kernel/index.js.map +1 -1
  22. package/dist/{multi-agent-Cpp7FXUl.d.ts → multi-agent-MfI6dmv-.d.ts} +30 -5
  23. package/dist/observability/index.d.ts +1 -1
  24. package/dist/{path-resolver--g_hKJ7V.d.ts → path-resolver-CWINz5XR.d.ts} +1 -1
  25. package/dist/{plan-templates-CKJs_sYh.d.ts → plan-templates-Bne1pB4d.d.ts} +1 -1
  26. package/dist/{provider-runner-hl4Il3xS.d.ts → provider-runner-CZYIzeBp.d.ts} +1 -1
  27. package/dist/sdd/index.d.ts +2 -2
  28. package/dist/storage/index.d.ts +3 -3
  29. package/dist/storage/index.js +3 -0
  30. package/dist/storage/index.js.map +1 -1
  31. package/dist/{tool-executor-B03CRwu-.d.ts → tool-executor-40Q6shR-.d.ts} +1 -1
  32. package/dist/types/index.d.ts +7 -7
  33. package/dist/types/index.js +16 -1
  34. package/dist/types/index.js.map +1 -1
  35. package/package.json +5 -1
@@ -1245,13 +1245,17 @@ var ToolExecutor = class {
1245
1245
  const ctrl = new AbortController();
1246
1246
  const timer = setTimeout(() => ctrl.abort(new Error("tool timeout")), timeoutMs);
1247
1247
  const combined = AbortSignal.any([parentSignal, ctrl.signal]);
1248
+ let cleanupCalled = false;
1249
+ let caught = false;
1248
1250
  try {
1249
1251
  if (typeof tool.executeStream === "function") {
1250
1252
  return await this.runStreamedTool(tool, input, ctx, combined, toolUseId);
1251
1253
  }
1252
1254
  return await tool.execute(input, ctx, { signal: combined });
1253
1255
  } catch (err) {
1256
+ caught = true;
1254
1257
  if (combined.aborted && typeof tool.cleanup === "function") {
1258
+ cleanupCalled = true;
1255
1259
  try {
1256
1260
  await tool.cleanup(input, ctx);
1257
1261
  } catch {
@@ -1260,6 +1264,16 @@ var ToolExecutor = class {
1260
1264
  throw err;
1261
1265
  } finally {
1262
1266
  clearTimeout(timer);
1267
+ if (combined.aborted && !caught) {
1268
+ if (!cleanupCalled && typeof tool.cleanup === "function") {
1269
+ try {
1270
+ await tool.cleanup(input, ctx);
1271
+ } catch {
1272
+ }
1273
+ }
1274
+ const reason = combined.reason instanceof Error ? combined.reason : new Error(typeof combined.reason === "string" ? combined.reason : "aborted");
1275
+ throw reason;
1276
+ }
1263
1277
  }
1264
1278
  }
1265
1279
  async runStreamedTool(tool, input, ctx, signal, toolUseId) {
@@ -1317,7 +1331,8 @@ var ToolExecutor = class {
1317
1331
  if (subjectKey) {
1318
1332
  const v = obj[subjectKey];
1319
1333
  if (typeof v === "string") {
1320
- return subjectKey === "path" || subjectKey === "file" || subjectKey === "files" ? normalizePath(v) : escapeGlob(v);
1334
+ const isPathKey = subjectKey === "path" || subjectKey === "file" || subjectKey === "files";
1335
+ return isPathKey ? normalizePath(v) : escapeGlob(v);
1321
1336
  }
1322
1337
  }
1323
1338
  if (toolName === "bash" && typeof obj.command === "string") {
@@ -1639,6 +1654,8 @@ function appendJournal(goal, entry) {
1639
1654
 
1640
1655
  // src/execution/eternal-autonomy.ts
1641
1656
  var execFileP = promisify(execFile);
1657
+ var BRAINSTORM_DONE = /* @__PURE__ */ Symbol("brainstorm-done");
1658
+ var GOAL_COMPLETE_MARKER = /^\s*\[goal[_\s-]?complete\]\s*$/im;
1642
1659
  var EternalAutonomyEngine = class {
1643
1660
  constructor(opts) {
1644
1661
  this.opts = opts;
@@ -1648,6 +1665,14 @@ var EternalAutonomyEngine = class {
1648
1665
  state = "idle";
1649
1666
  stopRequested = false;
1650
1667
  consecutiveFailures = 0;
1668
+ consecutiveBrainstormDone = 0;
1669
+ /**
1670
+ * Count of consecutive transient (recoverable) provider failures. Drives
1671
+ * the exponential backoff between iterations. Reset on the first
1672
+ * successful iteration so a single bad afternoon doesn't permanently
1673
+ * slow the loop down.
1674
+ */
1675
+ consecutiveTransientRetries = 0;
1651
1676
  currentCtrl = null;
1652
1677
  iterationsSinceCompact = 0;
1653
1678
  goalPath;
@@ -1717,9 +1742,16 @@ var EternalAutonomyEngine = class {
1717
1742
  this.stopRequested = true;
1718
1743
  return false;
1719
1744
  }
1745
+ const missionState = goal.goalState ?? "active";
1746
+ if (missionState !== "active") {
1747
+ this.stopRequested = true;
1748
+ return false;
1749
+ }
1720
1750
  const action = await this.decide(goal);
1721
1751
  if (!action) {
1722
- await sleep(5e3);
1752
+ if (!this.stopRequested) {
1753
+ await sleep(5e3);
1754
+ }
1723
1755
  return false;
1724
1756
  }
1725
1757
  const ctrl = new AbortController();
@@ -1730,13 +1762,29 @@ var EternalAutonomyEngine = class {
1730
1762
  );
1731
1763
  let status = "success";
1732
1764
  let note;
1765
+ let finalText = "";
1766
+ let isTransientFailure = false;
1733
1767
  const tc = this.opts.agent.ctx?.tokenCounter;
1734
1768
  const beforeUsage = tc?.total?.();
1735
1769
  const beforeCost = tc?.estimateCost?.().total;
1736
1770
  try {
1737
1771
  const result = await this.opts.agent.run(
1738
1772
  [{ type: "text", text: action.directive }],
1739
- { signal: ctrl.signal }
1773
+ {
1774
+ signal: ctrl.signal,
1775
+ // Enable per-call autonomous continuation so the agent can chain
1776
+ // multiple internal tool/response cycles end-to-end on one
1777
+ // directive instead of returning to the engine after a single
1778
+ // round-trip. The model uses `[continue]` / `[done]` markers
1779
+ // (or the `continue_to_next_iteration` tool) to control the
1780
+ // inner loop. Without this flag the engine produced shallow
1781
+ // iterations and almost never let a real task finish.
1782
+ autonomousContinue: true,
1783
+ // Cap the inner loop so a runaway agent.run can't burn through
1784
+ // the iteration timeout — the engine's own outer loop is the
1785
+ // long-running thing, each tick should be bounded.
1786
+ maxIterations: this.opts.iterationMaxAgentSteps ?? 50
1787
+ }
1740
1788
  );
1741
1789
  if (result.status === "aborted") {
1742
1790
  status = "aborted";
@@ -1744,22 +1792,30 @@ var EternalAutonomyEngine = class {
1744
1792
  } else if (result.status === "failed") {
1745
1793
  status = "failure";
1746
1794
  note = result.error?.describe?.() ?? "agent run failed";
1795
+ isTransientFailure = result.error?.recoverable === true;
1747
1796
  } else if (result.status === "max_iterations") {
1748
1797
  status = "failure";
1749
1798
  note = `max iterations (${result.iterations})`;
1750
1799
  } else {
1751
1800
  status = "success";
1752
- const tail = (result.finalText ?? "").slice(0, 240).replace(/\s+/g, " ").trim();
1801
+ finalText = result.finalText ?? "";
1802
+ const tail = finalText.slice(0, 240).replace(/\s+/g, " ").trim();
1753
1803
  if (tail) note = tail;
1754
1804
  }
1755
1805
  } catch (err) {
1756
1806
  const isAbort = err instanceof Error && (err.name === "AbortError" || err.message.includes("abort"));
1757
1807
  status = isAbort ? "aborted" : "failure";
1758
1808
  note = err instanceof Error ? err.message : String(err);
1809
+ if (!isAbort && typeof err?.recoverable === "boolean") {
1810
+ isTransientFailure = err.recoverable;
1811
+ }
1759
1812
  } finally {
1760
1813
  clearTimeout(timer);
1761
1814
  this.currentCtrl = null;
1762
1815
  }
1816
+ if (action.source === "todo" && action.todoId && status !== "success") {
1817
+ await this.bumpTodoAttempt(action.todoId);
1818
+ }
1763
1819
  const afterUsage = tc?.total?.();
1764
1820
  const afterCost = tc?.estimateCost?.().total;
1765
1821
  const tokens = beforeUsage && afterUsage ? {
@@ -1792,6 +1848,14 @@ var EternalAutonomyEngine = class {
1792
1848
  costUsd
1793
1849
  });
1794
1850
  if (status === "failure") {
1851
+ if (isTransientFailure) {
1852
+ this.consecutiveTransientRetries++;
1853
+ const delay = this.computeTransientBackoffMs();
1854
+ if (delay > 0) {
1855
+ await this.sleepInterruptible(delay);
1856
+ }
1857
+ return false;
1858
+ }
1795
1859
  this.consecutiveFailures++;
1796
1860
  return false;
1797
1861
  }
@@ -1800,6 +1864,12 @@ var EternalAutonomyEngine = class {
1800
1864
  this.consecutiveFailures++;
1801
1865
  return false;
1802
1866
  }
1867
+ this.consecutiveTransientRetries = 0;
1868
+ if (GOAL_COMPLETE_MARKER.test(finalText)) {
1869
+ await this.markGoalCompleted(action, finalText);
1870
+ this.stopRequested = true;
1871
+ return true;
1872
+ }
1803
1873
  this.iterationsSinceCompact++;
1804
1874
  await this.maybeCompact().catch((err) => {
1805
1875
  this.opts.onError?.(
@@ -1863,11 +1933,12 @@ var EternalAutonomyEngine = class {
1863
1933
  async decide(goal) {
1864
1934
  const forceBrainstorm = this.consecutiveFailures >= (this.opts.failureBudget ?? 3);
1865
1935
  if (!forceBrainstorm) {
1866
- const todo = this.pickPendingTodo();
1936
+ const todo = this.pickPendingTodo(goal);
1867
1937
  if (todo) {
1868
1938
  return {
1869
1939
  source: "todo",
1870
1940
  task: todo.content,
1941
+ todoId: todo.id,
1871
1942
  directive: this.buildDirective(goal, "todo", todo.content)
1872
1943
  };
1873
1944
  }
@@ -1881,17 +1952,38 @@ var EternalAutonomyEngine = class {
1881
1952
  }
1882
1953
  }
1883
1954
  const brainstormed = await this.brainstormTask(goal);
1955
+ if (brainstormed === BRAINSTORM_DONE) {
1956
+ this.consecutiveBrainstormDone++;
1957
+ const threshold = this.opts.brainstormDoneStopThreshold ?? 3;
1958
+ if (this.consecutiveBrainstormDone >= threshold) {
1959
+ await this.markGoalCompleted(
1960
+ { source: "brainstorm", task: "no further work", directive: "" },
1961
+ `brainstorm returned DONE ${this.consecutiveBrainstormDone}x in a row`
1962
+ );
1963
+ this.stopRequested = true;
1964
+ }
1965
+ return null;
1966
+ }
1884
1967
  if (!brainstormed) return null;
1968
+ this.consecutiveBrainstormDone = 0;
1885
1969
  return {
1886
1970
  source: "brainstorm",
1887
1971
  task: brainstormed,
1888
1972
  directive: this.buildDirective(goal, "brainstorm", brainstormed)
1889
1973
  };
1890
1974
  }
1891
- pickPendingTodo() {
1975
+ pickPendingTodo(goal) {
1892
1976
  const todos = this.opts.agent.ctx.todos;
1893
1977
  if (!Array.isArray(todos)) return null;
1894
- return todos.find((t) => t.status === "pending") ?? null;
1978
+ const attempts = goal.todoAttempts ?? {};
1979
+ const ceiling = this.opts.todoMaxAttempts ?? 3;
1980
+ for (const t of todos) {
1981
+ if (t.status !== "pending") continue;
1982
+ const used = attempts[t.id] ?? 0;
1983
+ if (used >= ceiling) continue;
1984
+ return t;
1985
+ }
1986
+ return null;
1895
1987
  }
1896
1988
  async pickGitTask() {
1897
1989
  let out;
@@ -1928,7 +2020,10 @@ ${lastFew}` : "No prior iterations yet.",
1928
2020
  "- One sentence, imperative form, under 200 chars.",
1929
2021
  "- No preamble, no explanation, no markdown \u2014 just the task line.",
1930
2022
  "- If recent iterations show repeated failures on the same target, pivot.",
1931
- "- If the goal appears fully accomplished, output exactly: DONE"
2023
+ "- If the goal appears fully accomplished AND you can name a concrete",
2024
+ " artifact / test / output that proves it, output exactly: DONE",
2025
+ "- Be conservative with DONE: if the recent journal contains failures",
2026
+ " or aborted entries, the goal is almost certainly NOT done."
1932
2027
  ].join("\n");
1933
2028
  try {
1934
2029
  const ctrl = new AbortController();
@@ -1940,9 +2035,11 @@ ${lastFew}` : "No prior iterations yet.",
1940
2035
  );
1941
2036
  if (result.status !== "done") return null;
1942
2037
  const text = (result.finalText ?? "").trim();
1943
- if (!text || text === "DONE") return null;
2038
+ if (!text) return null;
2039
+ if (/^DONE\.?$/i.test(text)) return BRAINSTORM_DONE;
1944
2040
  const firstLine = text.split("\n").find((l) => l.trim().length > 0)?.trim();
1945
2041
  if (!firstLine) return null;
2042
+ if (/^DONE\.?$/i.test(firstLine)) return BRAINSTORM_DONE;
1946
2043
  return firstLine.slice(0, 240);
1947
2044
  } finally {
1948
2045
  clearTimeout(timer);
@@ -1952,19 +2049,82 @@ ${lastFew}` : "No prior iterations yet.",
1952
2049
  }
1953
2050
  }
1954
2051
  buildDirective(goal, source, task) {
2052
+ const recentJournal = goal.journal.slice(-5).map((e) => ` #${e.iteration} [${e.status}] ${e.task}${e.note ? ` \u2014 ${e.note.slice(0, 80)}` : ""}`).join("\n");
1955
2053
  return [
1956
- "[ETERNAL AUTONOMY \u2014 iteration directive]",
2054
+ "\u2550\u2550\u2550 ETERNAL AUTONOMY \u2014 iteration directive \u2550\u2550\u2550",
1957
2055
  "",
1958
- `Goal: ${goal.goal}`,
2056
+ `Mission: ${goal.goal}`,
2057
+ `Iteration: #${goal.iterations + 1}`,
1959
2058
  `Source: ${source}`,
1960
2059
  `Task: ${task}`,
1961
2060
  "",
1962
- "Execute this task end-to-end using the tools available to you. Make the",
1963
- "changes, run tests if relevant, and commit / push as appropriate. Do not",
1964
- "ask for confirmation \u2014 YOLO mode is active. When the task is done, stop;",
1965
- "the loop will pick the next action."
2061
+ recentJournal ? `Recent journal (last 5):
2062
+ ${recentJournal}` : "No prior iterations.",
2063
+ "",
2064
+ "\u2500\u2500 EXECUTION PROTOCOL \u2500\u2500",
2065
+ "You are inside a long-running autonomous loop. Each iteration you",
2066
+ "execute ONE concrete task that advances the Mission. No user is",
2067
+ "available to clarify \u2014 make defensible decisions and move forward.",
2068
+ "",
2069
+ "1. EXECUTE END-TO-END",
2070
+ " \u2022 Use multiple tool calls freely. Emit `[continue]` on its own line",
2071
+ " to chain to the next internal step without returning.",
2072
+ " \u2022 When this iteration's Task is finished (real artifact / passing",
2073
+ " test / applied diff / clean output), emit `[done]` on its own line.",
2074
+ " \u2022 Do not stop on the first obstacle \u2014 try at least 3 distinct",
2075
+ " approaches before giving up. YOLO is active; no confirmations.",
2076
+ "",
2077
+ "2. UPDATE TODO STATE (when Source is `todo`)",
2078
+ " \u2022 Mark this todo `in_progress` via the todos tool before tool work.",
2079
+ " \u2022 Mark it `completed` on success, with a one-line outcome note.",
2080
+ " \u2022 If you cannot make progress after 2 distinct attempts, mark it",
2081
+ " `cancelled` with the obstacle. The loop will skip it next time.",
2082
+ "",
2083
+ "3. MISSION-COMPLETE PROTOCOL",
2084
+ " \u2022 If \u2014 and ONLY if \u2014 the OVERALL Mission (not just this Task) is",
2085
+ " verifiably accomplished, emit on its own line:",
2086
+ " [GOAL_COMPLETE]",
2087
+ " followed by a one-paragraph verification recipe (artifact path,",
2088
+ " test command, or 10-second reproduction). This halts the loop.",
2089
+ " \u2022 NEVER emit [GOAL_COMPLETE] on optimism, partial progress, or",
2090
+ ' "looks fine". Required: a concrete artifact that proves it AND',
2091
+ " no recent journal failures contradicting completion.",
2092
+ " \u2022 If unsure, emit `[done]` instead and let the next iteration",
2093
+ " decide. The loop is patient; false completion is not.",
2094
+ "",
2095
+ "4. NO INTERACTIVITY",
2096
+ " \u2022 Do not ask questions, do not request confirmation, do not propose",
2097
+ " options. Pick the best path and execute. The user is asleep."
1966
2098
  ].join("\n");
1967
2099
  }
2100
+ /**
2101
+ * Exponential backoff for transient provider errors. `2^N * base`
2102
+ * capped at `transientBackoffMaxMs`. Zero base disables backoff.
2103
+ * Public-private to keep `runOneIteration` readable; the value is
2104
+ * recomputed each call from the current retry count, so callers
2105
+ * don't have to track state.
2106
+ */
2107
+ computeTransientBackoffMs() {
2108
+ const base = this.opts.transientBackoffBaseMs ?? 2e3;
2109
+ const cap = this.opts.transientBackoffMaxMs ?? 6e4;
2110
+ if (base <= 0) return 0;
2111
+ const exponent = Math.max(0, this.consecutiveTransientRetries - 1);
2112
+ return Math.min(cap, base * Math.pow(2, exponent));
2113
+ }
2114
+ /**
2115
+ * Sleep that wakes early if `stopRequested` flips. Polls every 250 ms
2116
+ * so SIGINT / `/autonomy stop` can land in the middle of a long
2117
+ * backoff instead of waiting up to a minute for the timer.
2118
+ */
2119
+ async sleepInterruptible(totalMs) {
2120
+ const step = 250;
2121
+ let remaining = totalMs;
2122
+ while (remaining > 0 && !this.stopRequested) {
2123
+ const chunk = Math.min(step, remaining);
2124
+ await sleep(chunk);
2125
+ remaining -= chunk;
2126
+ }
2127
+ }
1968
2128
  async appendIterationEntry(entry) {
1969
2129
  const current = await loadGoal(this.goalPath);
1970
2130
  if (!current) {
@@ -1973,6 +2133,39 @@ ${lastFew}` : "No prior iterations yet.",
1973
2133
  const updated = appendJournal(current, entry);
1974
2134
  await saveGoal(this.goalPath, updated);
1975
2135
  }
2136
+ /**
2137
+ * Persistent per-todo failure counter. Skipped silently when the goal
2138
+ * file has been removed (graceful clear). Each non-success iteration
2139
+ * against a todo source bumps the counter by 1; `pickPendingTodo` reads
2140
+ * the counter to rotate past stuck todos once they cross `todoMaxAttempts`.
2141
+ */
2142
+ async bumpTodoAttempt(todoId) {
2143
+ const current = await loadGoal(this.goalPath);
2144
+ if (!current) return;
2145
+ const attempts = { ...current.todoAttempts ?? {} };
2146
+ attempts[todoId] = (attempts[todoId] ?? 0) + 1;
2147
+ await saveGoal(this.goalPath, { ...current, todoAttempts: attempts });
2148
+ }
2149
+ /**
2150
+ * Flip the mission to `completed` and journal it. Called from two
2151
+ * paths: (a) `[GOAL_COMPLETE]` marker in a successful iteration's
2152
+ * finalText, (b) `brainstorm` returning DONE consecutively past the
2153
+ * configured threshold. Idempotent — re-entry is a no-op once the
2154
+ * goal is already `completed`.
2155
+ */
2156
+ async markGoalCompleted(action, note) {
2157
+ const current = await loadGoal(this.goalPath);
2158
+ if (!current) return;
2159
+ if (current.goalState === "completed") return;
2160
+ const withFlag = { ...current, goalState: "completed" };
2161
+ const withEntry = appendJournal(withFlag, {
2162
+ source: action.source,
2163
+ task: `MISSION COMPLETE \u2014 ${action.task}`.slice(0, 240),
2164
+ status: "success",
2165
+ note: note.slice(0, 240)
2166
+ });
2167
+ await saveGoal(this.goalPath, withEntry);
2168
+ }
1976
2169
  async appendFailure(task, note) {
1977
2170
  await this.appendIterationEntry({ source: "manual", task, status: "failure", note });
1978
2171
  }
@@ -1987,6 +2180,142 @@ function sleep(ms) {
1987
2180
  return new Promise((resolve) => setTimeout(resolve, ms));
1988
2181
  }
1989
2182
 
2183
+ // src/execution/autonomy-prompt-contributor.ts
2184
+ function makeAutonomyPromptContributor(opts) {
2185
+ return async (ctx) => {
2186
+ if (ctx.subagent) return [];
2187
+ if (!opts.enabled()) return [];
2188
+ let goal;
2189
+ try {
2190
+ goal = await loadGoal(opts.goalPath);
2191
+ } catch {
2192
+ return [];
2193
+ }
2194
+ if (!goal) return [];
2195
+ const missionState = goal.goalState ?? "active";
2196
+ if (missionState !== "active") return [];
2197
+ const tailSize = opts.journalTailSize ?? 5;
2198
+ const journalTail = goal.journal.slice(-tailSize).map((e) => {
2199
+ const note = e.note ? ` \u2014 ${e.note.slice(0, 80)}` : "";
2200
+ return ` #${e.iteration} [${e.status}] ${e.task}${note}`;
2201
+ });
2202
+ const text = [
2203
+ "## ETERNAL AUTONOMY \u2014 active mission",
2204
+ "",
2205
+ "You are inside a long-running autonomous loop. The user is asleep",
2206
+ "and is not available to confirm decisions. Each turn you receive a",
2207
+ "directive describing one concrete sub-task that advances the mission.",
2208
+ "",
2209
+ `Mission: ${goal.goal}`,
2210
+ `Iteration: #${goal.iterations}`,
2211
+ journalTail.length > 0 ? `Recent journal (last ${journalTail.length}):
2212
+ ${journalTail.join("\n")}` : "Recent journal: (none \u2014 this is the first iteration)",
2213
+ "",
2214
+ "### Loop control markers",
2215
+ "Emit these on their own line in your final text \u2014 case-insensitive,",
2216
+ "whitespace-tolerant, but they must occupy the entire line:",
2217
+ "- `[continue]` \u2014 chain to the next internal step without returning.",
2218
+ "- `[done]` \u2014 the current sub-task is finished; return to the engine.",
2219
+ "- `[GOAL_COMPLETE]` \u2014 emit ONLY when the OVERALL mission is",
2220
+ " verifiably done. Must be followed by a one-paragraph verification",
2221
+ " recipe (artifact path, test command, or 10-second reproduction).",
2222
+ " The engine halts on this marker \u2014 false positives waste real",
2223
+ " human time. If unsure, emit `[done]` and let the next iteration",
2224
+ " decide.",
2225
+ "",
2226
+ "### Operating principles",
2227
+ "- YOLO is active. Do NOT ask for confirmation, do NOT propose",
2228
+ " options. Pick the best path and execute it.",
2229
+ "- Use tools freely; multiple calls per turn are normal and expected.",
2230
+ "- When working on a todo, mark it `in_progress` via the todos tool",
2231
+ " before tool work and `completed` (or `cancelled` with a reason)",
2232
+ " when done. The loop reads todo state between iterations.",
2233
+ "- If an approach fails twice in a row, pivot. Don't grind on the",
2234
+ " same wall \u2014 try a different angle, file a cancel on the todo, or",
2235
+ " surface the obstacle via `[done]` and let the next iteration",
2236
+ " re-plan."
2237
+ ].join("\n");
2238
+ return [
2239
+ {
2240
+ type: "text",
2241
+ text,
2242
+ cache_control: { type: "ephemeral" }
2243
+ }
2244
+ ];
2245
+ };
2246
+ }
2247
+
2248
+ // src/execution/goal-preamble.ts
2249
+ function buildGoalPreamble(goal) {
2250
+ return [
2251
+ "[GOAL \u2014 LOCKED IN. You will work on this until it is verifiably done.",
2252
+ "The user granted you full autonomy. Read these constraints once, then act.",
2253
+ "",
2254
+ "YOUR GOAL:",
2255
+ "---",
2256
+ goal,
2257
+ "---",
2258
+ "",
2259
+ "AUTHORITY YOU HAVE:",
2260
+ "- Spawn as many subagents as the work needs (delegate / spawn_subagent).",
2261
+ " Parallel + recursive fan-out are both fine. There is no spawn budget.",
2262
+ "- Use any provider/model per subagent \u2014 pick the right tool for each",
2263
+ " piece of work. Heavy reasoning model for planning, fast model for",
2264
+ " batch work, specialist model for domain code.",
2265
+ "- Run unlimited tool calls and iterations. There is NO hidden budget.",
2266
+ " The Agent loop auto-extends every 100 iterations forever.",
2267
+ "- Retry failed tools with different inputs, alternative paths, fresh",
2268
+ " subagents. Switch providers mid-run if one is rate-limited.",
2269
+ "- Re-plan freely when an approach hits a dead end. You are not obliged",
2270
+ " to stick with the first plan you proposed.",
2271
+ "",
2272
+ 'WHAT "DONE" MEANS \u2014 non-negotiable:',
2273
+ "- You can name a concrete artifact (a passing test, a written file at",
2274
+ " a specific path, a fixed bug verified by re-running the failing case,",
2275
+ " a clean grep that previously had matches).",
2276
+ "- You can tell the user HOW to verify it themselves in 10 seconds.",
2277
+ '- You have NOT hedged. None of: "looks like it should work", "I',
2278
+ ' believe this fixes it", "the changes appear correct".',
2279
+ "",
2280
+ "WHAT IS NOT DONE \u2014 never report any of these as completion:",
2281
+ "- An error message you didn't recover from.",
2282
+ '- An empty result, a 0-line file, a "no matches found" you accepted',
2283
+ " without questioning the search.",
2284
+ '- "Should I continue?" / "Want me to also...?" / "Let me know if you',
2285
+ ' want X." Those are hedges. The user already told you to finish the',
2286
+ " goal \u2014 just do it.",
2287
+ "- Partial progress dressed up as success. Fixed 3 of 5 bugs = 60%",
2288
+ " done, not done.",
2289
+ "- A subagent's failed/timeout/stopped TaskResult that you didn't",
2290
+ " respond to with a fresh attempt (different role, different model,",
2291
+ " tighter prompt).",
2292
+ "",
2293
+ "PERSISTENCE PROTOCOL:",
2294
+ "- If blocked, try at least 3 different angles before reporting the",
2295
+ " problem to the user. Different tool inputs, different subagent",
2296
+ " roles, different providers, different decomposition of the task.",
2297
+ "- If a tool fails, read its error, alter the input, try again. Do",
2298
+ " not just report the failure back.",
2299
+ "- If a subagent returns useless output, respawn with a tighter prompt",
2300
+ ' or a different role. Do not accept "I could not determine\u2026" as the',
2301
+ " final answer.",
2302
+ "- Use `ask_subagent` for one-shot questions when you don't need a",
2303
+ " full delegated task.",
2304
+ "",
2305
+ "REPORTING:",
2306
+ "- Stream short progress notes between major actions so the user can",
2307
+ " monitor. Do not go silent for 50 tool calls then dump a wall of",
2308
+ " text \u2014 but also do not narrate every tool call.",
2309
+ "- Use the shared scratchpad (if available) to leave breadcrumbs",
2310
+ " subagents can read.",
2311
+ "- Final response must include: (a) what was accomplished, (b) how",
2312
+ " to verify, (c) any caveats (residual TODOs, things the user",
2313
+ " should know about).",
2314
+ "",
2315
+ "BEGIN.]"
2316
+ ].join("\n");
2317
+ }
2318
+
1990
2319
  // src/types/provider.ts
1991
2320
  var ProviderError = class extends WrongStackError {
1992
2321
  status;
@@ -2299,6 +2628,6 @@ function parseDescription(raw) {
2299
2628
  return { trigger, scope };
2300
2629
  }
2301
2630
 
2302
- export { AutoCompactionMiddleware, AutonomousRunner, DefaultErrorHandler, DefaultRetryPolicy, DefaultSkillLoader, DoneConditionChecker, EternalAutonomyEngine, HybridCompactor, IntelligentCompactor, SelectiveCompactor, ToolExecutor };
2631
+ export { AutoCompactionMiddleware, AutonomousRunner, DefaultErrorHandler, DefaultRetryPolicy, DefaultSkillLoader, DoneConditionChecker, EternalAutonomyEngine, HybridCompactor, IntelligentCompactor, SelectiveCompactor, ToolExecutor, buildGoalPreamble, makeAutonomyPromptContributor };
2303
2632
  //# sourceMappingURL=index.js.map
2304
2633
  //# sourceMappingURL=index.js.map