amness 0.0.0-stage → 0.1.2

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 (235) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +237 -2
  3. package/dist/cli/acpcli.d.ts +7 -0
  4. package/dist/cli/acpcli.js +14 -0
  5. package/dist/cli/amness.d.ts +2 -0
  6. package/dist/cli/amness.js +694 -0
  7. package/dist/cli/benchcli.d.ts +5 -0
  8. package/dist/cli/benchcli.js +160 -0
  9. package/dist/cli/config.d.ts +79 -0
  10. package/dist/cli/config.js +111 -0
  11. package/dist/cli/demo.d.ts +13 -0
  12. package/dist/cli/demo.js +44 -0
  13. package/dist/cli/detect.d.ts +2 -0
  14. package/dist/cli/detect.js +20 -0
  15. package/dist/cli/evalcli.d.ts +15 -0
  16. package/dist/cli/evalcli.js +198 -0
  17. package/dist/cli/format.d.ts +5 -0
  18. package/dist/cli/format.js +55 -0
  19. package/dist/cli/headless.d.ts +2 -0
  20. package/dist/cli/headless.js +169 -0
  21. package/dist/cli/keystore.d.ts +9 -0
  22. package/dist/cli/keystore.js +108 -0
  23. package/dist/cli/model.d.ts +11 -0
  24. package/dist/cli/model.js +19 -0
  25. package/dist/cli/plugincli.d.ts +2 -0
  26. package/dist/cli/plugincli.js +176 -0
  27. package/dist/cli/schedulecli.d.ts +2 -0
  28. package/dist/cli/schedulecli.js +66 -0
  29. package/dist/cli/state.d.ts +11 -0
  30. package/dist/cli/state.js +19 -0
  31. package/dist/cli/tui/ansi.d.ts +38 -0
  32. package/dist/cli/tui/ansi.js +142 -0
  33. package/dist/cli/tui/app.d.ts +328 -0
  34. package/dist/cli/tui/app.js +1358 -0
  35. package/dist/cli/tui/blocks.d.ts +151 -0
  36. package/dist/cli/tui/blocks.js +128 -0
  37. package/dist/cli/tui/brand.d.ts +9 -0
  38. package/dist/cli/tui/brand.js +16 -0
  39. package/dist/cli/tui/canvas.d.ts +92 -0
  40. package/dist/cli/tui/canvas.js +199 -0
  41. package/dist/cli/tui/cards.d.ts +44 -0
  42. package/dist/cli/tui/cards.js +215 -0
  43. package/dist/cli/tui/clipboard.d.ts +5 -0
  44. package/dist/cli/tui/clipboard.js +29 -0
  45. package/dist/cli/tui/commands.d.ts +10 -0
  46. package/dist/cli/tui/commands.js +650 -0
  47. package/dist/cli/tui/complete.d.ts +39 -0
  48. package/dist/cli/tui/complete.js +113 -0
  49. package/dist/cli/tui/custom.d.ts +9 -0
  50. package/dist/cli/tui/custom.js +34 -0
  51. package/dist/cli/tui/diffview.d.ts +25 -0
  52. package/dist/cli/tui/diffview.js +130 -0
  53. package/dist/cli/tui/editor.d.ts +60 -0
  54. package/dist/cli/tui/editor.js +230 -0
  55. package/dist/cli/tui/full.d.ts +86 -0
  56. package/dist/cli/tui/full.js +630 -0
  57. package/dist/cli/tui/keys.d.ts +31 -0
  58. package/dist/cli/tui/keys.js +134 -0
  59. package/dist/cli/tui/markdown.d.ts +37 -0
  60. package/dist/cli/tui/markdown.js +155 -0
  61. package/dist/cli/tui/mentions.d.ts +15 -0
  62. package/dist/cli/tui/mentions.js +48 -0
  63. package/dist/cli/tui/modal.d.ts +26 -0
  64. package/dist/cli/tui/modal.js +107 -0
  65. package/dist/cli/tui/overlays.d.ts +98 -0
  66. package/dist/cli/tui/overlays.js +237 -0
  67. package/dist/cli/tui/pager.d.ts +15 -0
  68. package/dist/cli/tui/pager.js +66 -0
  69. package/dist/cli/tui/pricing.d.ts +9 -0
  70. package/dist/cli/tui/pricing.js +23 -0
  71. package/dist/cli/tui/rich.d.ts +16 -0
  72. package/dist/cli/tui/rich.js +72 -0
  73. package/dist/cli/tui/screen.d.ts +30 -0
  74. package/dist/cli/tui/screen.js +62 -0
  75. package/dist/cli/tui/session.d.ts +77 -0
  76. package/dist/cli/tui/session.js +103 -0
  77. package/dist/cli/tui/sidebar.d.ts +84 -0
  78. package/dist/cli/tui/sidebar.js +114 -0
  79. package/dist/cli/tui/text.d.ts +15 -0
  80. package/dist/cli/tui/text.js +94 -0
  81. package/dist/cli/tui/theme.d.ts +59 -0
  82. package/dist/cli/tui/theme.js +148 -0
  83. package/dist/cli/tui/themes.d.ts +56 -0
  84. package/dist/cli/tui/themes.js +80 -0
  85. package/dist/cli/tui/tokens.d.ts +39 -0
  86. package/dist/cli/tui/tokens.js +71 -0
  87. package/dist/cli/tui/view.d.ts +60 -0
  88. package/dist/cli/tui/view.js +178 -0
  89. package/dist/cli/ui.d.ts +34 -0
  90. package/dist/cli/ui.js +224 -0
  91. package/dist/src/acp.d.ts +28 -0
  92. package/dist/src/acp.js +111 -0
  93. package/dist/src/agents.d.ts +23 -0
  94. package/dist/src/agents.js +71 -0
  95. package/dist/src/anthropic.d.ts +30 -0
  96. package/dist/src/anthropic.js +91 -0
  97. package/dist/src/approver.d.ts +15 -0
  98. package/dist/src/approver.js +40 -0
  99. package/dist/src/bench.d.ts +67 -0
  100. package/dist/src/bench.js +201 -0
  101. package/dist/src/bundle.d.ts +36 -0
  102. package/dist/src/bundle.js +55 -0
  103. package/dist/src/chaos.d.ts +15 -0
  104. package/dist/src/chaos.js +26 -0
  105. package/dist/src/code.d.ts +187 -0
  106. package/dist/src/code.js +590 -0
  107. package/dist/src/codeindex.d.ts +65 -0
  108. package/dist/src/codeindex.js +300 -0
  109. package/dist/src/deep.d.ts +62 -0
  110. package/dist/src/deep.js +177 -0
  111. package/dist/src/diff.d.ts +8 -0
  112. package/dist/src/diff.js +74 -0
  113. package/dist/src/dynamic.d.ts +42 -0
  114. package/dist/src/dynamic.js +133 -0
  115. package/dist/src/embed.d.ts +8 -0
  116. package/dist/src/embed.js +25 -0
  117. package/dist/src/evalcases.d.ts +11 -0
  118. package/dist/src/evalcases.js +196 -0
  119. package/dist/src/evals.d.ts +197 -0
  120. package/dist/src/evals.js +340 -0
  121. package/dist/src/gitflow.d.ts +27 -0
  122. package/dist/src/gitflow.js +56 -0
  123. package/dist/src/grade.d.ts +42 -0
  124. package/dist/src/grade.js +96 -0
  125. package/dist/src/guidance.d.ts +15 -0
  126. package/dist/src/guidance.js +68 -0
  127. package/dist/src/hardcases.d.ts +2 -0
  128. package/dist/src/hardcases.js +94 -0
  129. package/dist/src/harness.d.ts +411 -0
  130. package/dist/src/harness.js +725 -0
  131. package/dist/src/hooks.d.ts +44 -0
  132. package/dist/src/hooks.js +116 -0
  133. package/dist/src/images.d.ts +13 -0
  134. package/dist/src/images.js +27 -0
  135. package/dist/src/index.d.ts +57 -0
  136. package/dist/src/index.js +57 -0
  137. package/dist/src/ledger.d.ts +58 -0
  138. package/dist/src/ledger.js +78 -0
  139. package/dist/src/live.d.ts +16 -0
  140. package/dist/src/live.js +80 -0
  141. package/dist/src/lsp.d.ts +31 -0
  142. package/dist/src/lsp.js +147 -0
  143. package/dist/src/memory.d.ts +128 -0
  144. package/dist/src/memory.js +390 -0
  145. package/dist/src/metrics.d.ts +3 -0
  146. package/dist/src/metrics.js +42 -0
  147. package/dist/src/mining.d.ts +49 -0
  148. package/dist/src/mining.js +126 -0
  149. package/dist/src/openai.d.ts +50 -0
  150. package/dist/src/openai.js +307 -0
  151. package/dist/src/parallel.d.ts +66 -0
  152. package/dist/src/parallel.js +135 -0
  153. package/dist/src/patch.d.ts +45 -0
  154. package/dist/src/patch.js +219 -0
  155. package/dist/src/permissions.d.ts +46 -0
  156. package/dist/src/permissions.js +245 -0
  157. package/dist/src/plugins.d.ts +148 -0
  158. package/dist/src/plugins.js +225 -0
  159. package/dist/src/pluginscan.d.ts +8 -0
  160. package/dist/src/pluginscan.js +20 -0
  161. package/dist/src/procs.d.ts +41 -0
  162. package/dist/src/procs.js +94 -0
  163. package/dist/src/profiles.d.ts +36 -0
  164. package/dist/src/profiles.js +61 -0
  165. package/dist/src/progress.d.ts +29 -0
  166. package/dist/src/progress.js +75 -0
  167. package/dist/src/prompts.d.ts +10 -0
  168. package/dist/src/prompts.js +28 -0
  169. package/dist/src/ratelimit.d.ts +34 -0
  170. package/dist/src/ratelimit.js +116 -0
  171. package/dist/src/replay.d.ts +25 -0
  172. package/dist/src/replay.js +99 -0
  173. package/dist/src/review.d.ts +20 -0
  174. package/dist/src/review.js +49 -0
  175. package/dist/src/route.d.ts +9 -0
  176. package/dist/src/route.js +30 -0
  177. package/dist/src/router.d.ts +61 -0
  178. package/dist/src/router.js +126 -0
  179. package/dist/src/sandbox.d.ts +13 -0
  180. package/dist/src/sandbox.js +68 -0
  181. package/dist/src/schedule.d.ts +20 -0
  182. package/dist/src/schedule.js +59 -0
  183. package/dist/src/schema.d.ts +13 -0
  184. package/dist/src/schema.js +36 -0
  185. package/dist/src/secrets.d.ts +10 -0
  186. package/dist/src/secrets.js +41 -0
  187. package/dist/src/shell.d.ts +34 -0
  188. package/dist/src/shell.js +95 -0
  189. package/dist/src/skills.d.ts +20 -0
  190. package/dist/src/skills.js +112 -0
  191. package/dist/src/snapshot.d.ts +20 -0
  192. package/dist/src/snapshot.js +93 -0
  193. package/dist/src/stats.d.ts +24 -0
  194. package/dist/src/stats.js +62 -0
  195. package/dist/src/strategies.d.ts +16 -0
  196. package/dist/src/strategies.js +35 -0
  197. package/dist/src/suites.d.ts +30 -0
  198. package/dist/src/suites.js +112 -0
  199. package/dist/src/trace.d.ts +63 -0
  200. package/dist/src/trace.js +153 -0
  201. package/dist/src/tune.d.ts +38 -0
  202. package/dist/src/tune.js +49 -0
  203. package/dist/src/web.d.ts +19 -0
  204. package/dist/src/web.js +56 -0
  205. package/dist/src/worktree.d.ts +24 -0
  206. package/dist/src/worktree.js +85 -0
  207. package/docs/agent-loop.md +222 -0
  208. package/docs/architecture.md +228 -0
  209. package/docs/bench.md +292 -0
  210. package/docs/budgets.md +185 -0
  211. package/docs/build-your-own-harness.md +424 -0
  212. package/docs/cookbook.md +375 -0
  213. package/docs/development.md +150 -0
  214. package/docs/evaluation.md +450 -0
  215. package/docs/features.md +1320 -0
  216. package/docs/getting-started.md +205 -0
  217. package/docs/headless.md +188 -0
  218. package/docs/images/approval.png +0 -0
  219. package/docs/images/chat.png +0 -0
  220. package/docs/images/daylight.png +0 -0
  221. package/docs/images/loop.png +0 -0
  222. package/docs/images/palette.png +0 -0
  223. package/docs/images/running.png +0 -0
  224. package/docs/images/subagent-done.png +0 -0
  225. package/docs/images/subagent-running.png +0 -0
  226. package/docs/images/welcome.png +0 -0
  227. package/docs/index.md +25 -0
  228. package/docs/library.md +267 -0
  229. package/docs/plugins.md +691 -0
  230. package/docs/providers.md +175 -0
  231. package/docs/safety.md +250 -0
  232. package/docs/usage.md +348 -0
  233. package/docs/why.md +155 -0
  234. package/docs/writing-guide.md +39 -0
  235. package/package.json +66 -4
@@ -0,0 +1,411 @@
1
+ import { type Schema } from "./schema.ts";
2
+ export type ToolCall = {
3
+ id: string;
4
+ type?: "function";
5
+ function: {
6
+ name: string;
7
+ arguments: string;
8
+ };
9
+ };
10
+ export type Usage = {
11
+ prompt_tokens?: number;
12
+ completion_tokens?: number;
13
+ total_tokens?: number; /** part of the prompt served from the provider's cache */
14
+ cached_tokens?: number; /** set when the provider reported nothing and the harness estimated (about 4 characters per token) */
15
+ estimated?: boolean; /** part of the output spent on hidden reasoning */
16
+ reasoning_tokens?: number;
17
+ };
18
+ export type Message = {
19
+ role: "system" | "user" | "assistant" | "tool";
20
+ content: string | null; /** pictures attached to a user message (base64) */
21
+ images?: {
22
+ mime: string;
23
+ data: string;
24
+ }[];
25
+ tool_calls?: ToolCall[];
26
+ tool_call_id?: string;
27
+ usage?: Usage;
28
+ /** Provider-native content blocks (e.g. Claude thinking blocks). Kept verbatim in history and handed back to the adapter. */
29
+ raw?: unknown;
30
+ };
31
+ export type ToolSpec = {
32
+ name: string;
33
+ description: string;
34
+ parameters: Schema;
35
+ };
36
+ /** Any chat model: messages + tool specs in, assistant message out (attach `usage` if known). See openai.ts. */
37
+ export type ModelOpts = {
38
+ signal?: AbortSignal; /** Cap on generated tokens for this call (used for cache keep-alive pings; adapters may ignore it). */
39
+ maxTokens?: number; /** Called with each piece of assistant text as it is generated (streaming adapters only). */
40
+ onText?: (delta: string) => void; /** Called with pieces of the model's reasoning summary, where the provider exposes one. */
41
+ onThinking?: (delta: string) => void;
42
+ };
43
+ export type Model = ((messages: Message[], tools: ToolSpec[], opts?: ModelOpts) => Promise<Message>) & {
44
+ /** Set by adapters whose provider binds reasoning to the exact history (Claude): the harness then never edits past turns. */
45
+ appendOnly?: boolean;
46
+ /** Which wire API the adapter is using right now (e.g. "responses" / "chat"); adapters may change it at runtime. */
47
+ api?: () => string;
48
+ };
49
+ export type ToolCtx = {
50
+ registry: Registry;
51
+ step: number; /** id of this tool call (subagent events carry it as `parent` so a UI can nest them under their card) */
52
+ callId?: string; /** Aborted when the run is interrupted; long-running tools should honour it. */
53
+ signal?: AbortSignal; /** Publish a custom event (e.g. a live file diff) to `onEvent`. */
54
+ emit?: (e: Event) => void;
55
+ };
56
+ export type Tool<A = any> = {
57
+ name: string;
58
+ description: string;
59
+ schema: Schema;
60
+ run: (args: A, ctx: ToolCtx) => unknown | Promise<unknown>;
61
+ /** Hidden from the model until it finds it via `tool_search` (keeps prompts small when you have many tools). */
62
+ deferred?: boolean;
63
+ /** Availability per turn; the tool is only shown (and callable) while this returns true. */
64
+ when?: (s: {
65
+ step: number;
66
+ messages: Message[];
67
+ }) => boolean;
68
+ /** Needs human approval before running. A function may return true, or a string reason, to flag a specific call. */
69
+ risky?: boolean | ((args: A) => boolean | string);
70
+ /** Human-readable preview of what this call will do (a diff, a command), shown in the approval prompt. */
71
+ preview?: (args: A) => string | undefined;
72
+ /** Never changes anything (safe in plan mode, safe to run in a read-only subagent). */
73
+ readOnly?: boolean;
74
+ /** Its output comes from outside (the web, an MCP server): it is wrapped as untrusted data, and commands that copy text from it need approval. */
75
+ untrusted?: boolean;
76
+ /** Per-call answer to "may this run at the same time as other calls?", for tools where it depends on the arguments. Overrides `readOnly`/`parallel` for scheduling. */
77
+ concurrent?: (args: any) => boolean;
78
+ /** Safe to run at the same time as other calls even though it is not read-only (e.g. a subagent working in its own context). Everything else runs one at a time, in call order. */
79
+ parallel?: boolean;
80
+ };
81
+ export declare const defineTool: <A = any>(t: Tool<A>) => Tool<A>;
82
+ /** The live set of tools. Mutate it between or during runs (tools receive it as `ctx.registry`); changes show up next turn. */
83
+ export declare class Registry {
84
+ tools: Map<string, Tool<any>>;
85
+ loaded: Set<string>;
86
+ constructor(ts?: Tool[]);
87
+ add(...ts: Tool[]): this;
88
+ remove(name: string): boolean;
89
+ get(name: string): Tool<any> | undefined;
90
+ hasDeferred(): boolean;
91
+ visible(s: {
92
+ step: number;
93
+ messages: Message[];
94
+ }): Tool<any>[];
95
+ /** Keyword-rank the not-yet-loaded deferred tools by name + description. */
96
+ search(q: string, n?: number): Tool<any>[];
97
+ }
98
+ export type Event = {
99
+ kind: "toolstart";
100
+ id: string;
101
+ name: string;
102
+ args: string;
103
+ } | {
104
+ kind: "tool";
105
+ id?: string;
106
+ name: string;
107
+ args: string;
108
+ result: string;
109
+ } | {
110
+ kind: "text";
111
+ delta: string;
112
+ } | {
113
+ kind: "thinking";
114
+ delta: string;
115
+ } | {
116
+ kind: "assistant";
117
+ text: string;
118
+ streamed: boolean;
119
+ } | {
120
+ kind: "todos";
121
+ todos: {
122
+ content: string;
123
+ status: "pending" | "in_progress" | "done";
124
+ }[];
125
+ } | {
126
+ kind: "steer";
127
+ text: string;
128
+ } | {
129
+ kind: "nudge" | "loop" | "rejected" | "repair" | "denied" | "budget" | "tools" | "aborted";
130
+ detail: string;
131
+ } | {
132
+ kind: "edit";
133
+ path: string;
134
+ created: boolean;
135
+ added: number;
136
+ removed: number;
137
+ diff: string; /** File content before the edit (null = it did not exist); lets a UI offer undo. */
138
+ before?: string | null;
139
+ } | {
140
+ kind: "turn";
141
+ step: number;
142
+ tokens: number;
143
+ prompt: number;
144
+ completion: number;
145
+ cached: number;
146
+ reasoning: number;
147
+ } | {
148
+ kind: "rollover";
149
+ detail: string;
150
+ }
151
+ /** Context that was shrunk without losing anything current (chars; roughly 4 per token). */
152
+ | {
153
+ kind: "trim";
154
+ saved: number;
155
+ what: string;
156
+ }
157
+ /** The request prefix changed since the last call, so the provider's prompt cache will miss from `at` onward (message index; -1 = tool definitions). */
158
+ | {
159
+ kind: "cachebreak";
160
+ reason: string;
161
+ at: number;
162
+ }
163
+ /** Where the loop is: lets a UI show live progress. `step` is 0-based; `n` is the number of tool calls in the batch. */
164
+ | {
165
+ kind: "phase";
166
+ phase: "model" | "tools" | "verify" | "compact";
167
+ step: number;
168
+ max: number;
169
+ n?: number;
170
+ }
171
+ /** A lifecycle hook ran: what it did (blocked, added context, warned). */
172
+ | {
173
+ kind: "hook";
174
+ event: string;
175
+ detail: string;
176
+ blocked: boolean;
177
+ }
178
+ /** What the run really did, from recorded facts (not the model's words): shown after an accepted finish. */
179
+ /** The independent reviewer's verdict on a finish. */
180
+ | {
181
+ kind: "review";
182
+ pass: boolean;
183
+ findings: string[];
184
+ inconclusive?: boolean;
185
+ }
186
+ /** Only when `record` is set: the messages a run started from, and every message the model produced (for trace replay). */
187
+ | {
188
+ kind: "run";
189
+ messages: Message[];
190
+ } | {
191
+ kind: "model";
192
+ message: Message;
193
+ }
194
+ /** Why a call was allowed without asking, forced to ask, or refused: the rule, the floor or the taint check. */
195
+ | {
196
+ kind: "policy";
197
+ tool: string;
198
+ action: "allow" | "ask" | "deny";
199
+ reason: string;
200
+ } | {
201
+ kind: "audit";
202
+ changed: string[];
203
+ testsAfterLastEdit: boolean | undefined;
204
+ notes: string[];
205
+ } | {
206
+ kind: "finish";
207
+ summary: string;
208
+ };
209
+ /** Shared token/time cap. Pass one instance to a harness (and its subagents) to bound the whole run. */
210
+ /** Servers that report no token usage (many local ones) would make every cap useless, so estimate it: about 4 characters per token. Marked, so a UI can show it as approximate. */
211
+ export declare function ensureUsage(m: Message, sent: Message[]): Message;
212
+ export declare class Budget {
213
+ tokens: number;
214
+ promptTokens: number;
215
+ completionTokens: number; /** prompt tokens the provider served from its cache */
216
+ cachedTokens: number;
217
+ calls: number;
218
+ t0: number;
219
+ maxTokens: number;
220
+ maxMs: number;
221
+ constructor(o?: {
222
+ maxTokens?: number;
223
+ maxMs?: number;
224
+ });
225
+ /** Set on a slice made by `slice()`: everything it spends is charged to the parent too. */
226
+ parent?: Budget;
227
+ /** A smaller budget for a subagent: at most `share` of what is left here (and no more than `max` tokens). Its spending counts against this budget as well. */
228
+ slice(share: number, max?: number): Budget;
229
+ add(m: Message): void;
230
+ /** What the cap is measured in: tokens, with cached input counted at a tenth (it costs about that much, and a long session re-reads its history every turn). */
231
+ get effective(): number;
232
+ get ms(): number;
233
+ /** How much of the tightest cap is used, 0 to 1 (0 when there is no cap). */
234
+ get fraction(): number;
235
+ exceeded(): string | null;
236
+ }
237
+ export type Approve = (req: {
238
+ name: string;
239
+ args: any;
240
+ reason?: string;
241
+ preview?: string;
242
+ id?: string; /** from the built-in safety floor: "don't ask again" shortcuts must not skip this prompt */
243
+ floor?: boolean;
244
+ }) => Promise<boolean | string> | boolean | string;
245
+ /** Turn-off switches, mainly so evals can measure what each guard is worth. */
246
+ export type Guard = "nudge" | "loop" | "compact" | "stuck" | "wrapup" | "condense" | "schedule" | "ledger" | "stagnation" | "review" | "redact";
247
+ export type Options = {
248
+ model: Model;
249
+ /** A fixed list, or a live Registry you can add to / remove from at any time. */
250
+ tools?: Tool[] | Registry;
251
+ system?: string;
252
+ /** Gate for `finish`: return true/undefined to accept, or a string / {ok:false, feedback} to reject with feedback. */
253
+ verify?: (summary: string) => Promise<true | string | void | {
254
+ ok: boolean;
255
+ feedback?: string;
256
+ }> | true | string | void;
257
+ maxSteps?: number;
258
+ /** Chars of transcript before old tool output is elided. */
259
+ contextBudget?: number;
260
+ budget?: Budget;
261
+ /** Asked before any `risky` tool call. Return true to allow, or false / a string (shown to the model) to deny. No handler = deny. */
262
+ approve?: Approve;
263
+ /** Your own context strategy: called before each model request with the conversation; return a new list of messages to replace it, or nothing to keep it. */
264
+ context?: (msgs: Message[], info: {
265
+ step: number;
266
+ promptTokens: number;
267
+ budget: number;
268
+ }) => Message[] | void | Promise<Message[] | void>;
269
+ /** Policy as code: called with each tool call before it runs (see plugins.ts checkPolicies). */
270
+ policy?: (call: {
271
+ tool: string;
272
+ args: Record<string, unknown>;
273
+ }) => Promise<{
274
+ action: "allow" | "ask" | "deny";
275
+ reason?: string;
276
+ plugin?: string;
277
+ } | undefined>;
278
+ /** Called at the start of every turn with the full transcript; persist it to resume after a crash or pause. */
279
+ checkpoint?: (messages: Message[]) => void;
280
+ off?: Guard[];
281
+ /**
282
+ * Long-run memory management without editing history: when the context passes a threshold, the model writes a handoff
283
+ * note and the run continues in a fresh context seeded with the task + that note. Works for every provider.
284
+ */
285
+ rollover?: {
286
+ afterTokens?: number;
287
+ afterChars?: number;
288
+ };
289
+ /** Receives each handoff note (persist it; it is also a portable summary of the work so far). */
290
+ onHandoff?: (note: string) => void;
291
+ /** Rules that allow, force-ask or deny a call before the permission mode is consulted (see `Permissions`). Deny wins; allow skips the prompt. */
292
+ permissions?: {
293
+ check(tool: string, args: Record<string, any>): {
294
+ action: "allow" | "ask" | "deny" | "none";
295
+ rule?: string;
296
+ reason?: string;
297
+ floor?: boolean;
298
+ };
299
+ };
300
+ /** Turns without any objective improvement (failing-test count, new files edited, new code) before the loop reflects, then stops. Default 8; 0 switches it off. */
301
+ stagnationTurns?: number;
302
+ /** An independent reviewer consulted before a finish is accepted (after the ledger and the verify gate). A failing review sends its findings back; at most twice, then the work is accepted and flagged. */
303
+ reviewer?: (ctx: {
304
+ task: string;
305
+ summary: string;
306
+ messages: Message[];
307
+ }) => Promise<{
308
+ pass: boolean;
309
+ findings: string[];
310
+ inconclusive?: boolean;
311
+ }>;
312
+ /** What to do when a shell command contains text copied from an untrusted tool result (a web page, an MCP server): `ask` (default) forces an approval, whatever the mode or allow rules; `deny` refuses; `off` ignores it. */
313
+ taint?: "ask" | "deny" | "off";
314
+ /** Mask secrets (API keys, tokens, private keys, credential assignments) in tool results before the model sees them. Default on in the coding agent. */
315
+ redact?: boolean;
316
+ /** Claims ledger (see `Ledger`): records edits and commands, and rejects a `finish` whose summary claims things that did not happen. */
317
+ ledger?: {
318
+ onEdit(e: {
319
+ path: string;
320
+ added: number;
321
+ removed: number;
322
+ created: boolean;
323
+ diff?: string;
324
+ }): void;
325
+ onCommand(cmd: string, result: string): void;
326
+ check(summary: string, o?: {
327
+ gated?: boolean;
328
+ }): string[];
329
+ audit(task: string): {
330
+ changed: string[];
331
+ testsAfterLastEdit: boolean | undefined;
332
+ notes: string[];
333
+ };
334
+ };
335
+ /** Model for the handoff note written when the context rolls over (often a cheaper one). Default: `model`. */
336
+ compactModel?: Model;
337
+ /** Emit `run` and `model` events with full message content, so a trace can be replayed later (see `replay`). Larger traces; off unless asked. */
338
+ record?: boolean;
339
+ /** Lifecycle hooks (see `Hooks`). PreToolUse can block or rewrite a call, PostToolUse can add context to a result, Stop can reject a finish, PreCompact can veto trimming. */
340
+ hooks?: {
341
+ run(event: "PreToolUse" | "PostToolUse" | "PreCompact" | "Stop" | "SessionStart" | "UserPromptSubmit" | "PreModel" | "PostModel", payload: Record<string, unknown>): Promise<{
342
+ block?: string;
343
+ context?: string;
344
+ args?: Record<string, unknown>;
345
+ tools?: string[];
346
+ then?: string;
347
+ warnings: string[];
348
+ }>;
349
+ };
350
+ /** Interrupt the run: it stops at the next safe point (history stays consistent, so it can be resumed). */
351
+ signal?: AbortSignal | (() => AbortSignal | undefined);
352
+ /** Polled at the start of every turn: messages the user typed while the agent was working ("steering"). They join the conversation immediately. */
353
+ inbox?: () => string[];
354
+ onEvent?: (e: Event) => void;
355
+ };
356
+ export declare const HANDOFF_PROMPT = "Your context is about to be reset. Write a handoff note for yourself; you will continue from it with no other memory of this session. Do not call tools; reply with the note only (under 500 words), in this shape:\nGOAL: what the user wants, in your own words\nDONE: what is finished, with exact file paths and decisions made\nSTATE: what you verified (commands run, results), what is still failing\nNEXT: the concrete next steps, in order\nGOTCHAS: facts learned the hard way (commands, quirks, dead ends not to repeat)";
357
+ /** Ask the model to summarise the transcript so far. Tool specs are passed because some APIs require them when history contains tool calls. */
358
+ export declare function makeHandoff(model: Model, specs: ToolSpec[], msgs: Message[], budget?: Budget): Promise<string>;
359
+ export type RunResult = {
360
+ text: string;
361
+ finished: boolean;
362
+ steps: number;
363
+ messages: Message[];
364
+ stopped?: "budget" | "maxSteps" | "aborted" | "stuck" | "blocked";
365
+ tokens: number;
366
+ };
367
+ export declare const DEFAULT_SYSTEM = "You are an autonomous agent. Work until the task is DONE, then call `finish`.\n- Act, don't narrate. If you say you will do something, do it in the same turn with a tool call.\n- Don't ask permission or clarification unless truly blocked; choose a sensible default and state it in `finish`.\n- Never invent tool output, data or identifiers. If unsure, check with a tool.\n- Verify your work before finishing. Only call `finish` when verified.\n- If an approach fails twice, change approach instead of repeating it.\n- Tool errors are information: read them, fix your call, retry.\n- `finish(summary)`: what you did, how you verified, assumptions made.";
368
+ export declare const clip: (s: string, n?: number) => string;
369
+ /**
370
+ * Shrink a tool observation before it enters the transcript, keeping what the next action depends on
371
+ * (CoACT's "action-preserving" rule, done with rules instead of a trained compressor): strip terminal control codes and
372
+ * progress-bar redraws, collapse repeated lines, and when still too long keep head and tail plus the error-looking lines from the middle.
373
+ */
374
+ export declare function condense(s: string, max?: number): string;
375
+ /** Same call repeated later in the transcript: the older output is stale, so drop it first (cheapest compaction, loses nothing current). */
376
+ export declare function supersede(msgs: Message[], keep?: number, isRead?: (tool: string) => boolean): number;
377
+ /** Elide old tool outputs once the transcript passes `budget` chars; the last `keep` messages stay intact. */
378
+ export declare function compact(msgs: Message[], budget?: number, keep?: number): number;
379
+ type PrefixSig = {
380
+ tools: string;
381
+ msgs: string[];
382
+ };
383
+ /** Cheap fingerprint of what the provider caches: the tool definitions, then each message in order. */
384
+ export declare const prefixSignature: (msgs: Message[], specs: ToolSpec[]) => PrefixSig;
385
+ /** Where (and why) this request stops matching the previous one. Pure appends return undefined: that is the cache-friendly case. */
386
+ export declare function firstCacheBreak(prev: PrefixSig | undefined, now: PrefixSig): {
387
+ reason: string;
388
+ at: number;
389
+ } | undefined;
390
+ /** A call reduced to what it does, so trivial differences (key order, extra spaces in a command) do not hide a repeat. */
391
+ export declare function canonicalCall(name: string, args: unknown): string;
392
+ /** A repeating pattern of 2 to 4 different calls at the end of `hist` (A B A B A B, A B C A B C A B C...). Exact repeats of one call are handled separately. */
393
+ export declare function findCycle(hist: string[], minReps?: number): string[] | undefined;
394
+ /** Does this command contain a run of three or more words (or one very long word) copied verbatim from an untrusted tool result? Returns the tool it came from. */
395
+ export declare function taintedBy(cmd: string, pool: {
396
+ source: string;
397
+ text: string;
398
+ }[]): string | undefined;
399
+ export declare function createHarness(o: Options): {
400
+ run: (task: string, opts?: {
401
+ resume?: Message[];
402
+ }) => Promise<RunResult>;
403
+ extract: <T = unknown>(prompt: string, schema: Schema, attempts?: number) => Promise<T>;
404
+ warm: (msgs: Message[], opts?: {
405
+ signal?: AbortSignal;
406
+ }) => Promise<{
407
+ prompt: number;
408
+ cached: number;
409
+ }>;
410
+ };
411
+ export {};