agent-nuvira 3.1.3 → 3.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.
Files changed (164) hide show
  1. package/dist/agents/agents/reasoner.d.ts +8 -0
  2. package/dist/agents/agents/reasoner.d.ts.map +1 -1
  3. package/dist/agents/agents/reasoner.js +53 -2
  4. package/dist/agents/agents/reasoner.js.map +1 -1
  5. package/dist/agents/agents/writer.d.ts +24 -0
  6. package/dist/agents/agents/writer.d.ts.map +1 -1
  7. package/dist/agents/agents/writer.js +200 -0
  8. package/dist/agents/agents/writer.js.map +1 -1
  9. package/dist/agents/composite-plan.d.ts +143 -0
  10. package/dist/agents/composite-plan.d.ts.map +1 -0
  11. package/dist/agents/composite-plan.js +399 -0
  12. package/dist/agents/composite-plan.js.map +1 -0
  13. package/dist/agents/long-form-plan.d.ts +156 -0
  14. package/dist/agents/long-form-plan.d.ts.map +1 -0
  15. package/dist/agents/long-form-plan.js +274 -0
  16. package/dist/agents/long-form-plan.js.map +1 -0
  17. package/dist/agents/orchestrator.d.ts +107 -0
  18. package/dist/agents/orchestrator.d.ts.map +1 -1
  19. package/dist/agents/orchestrator.js +501 -35
  20. package/dist/agents/orchestrator.js.map +1 -1
  21. package/dist/agents/prompt-assembly.d.ts +8 -0
  22. package/dist/agents/prompt-assembly.d.ts.map +1 -1
  23. package/dist/agents/prompt-assembly.js +17 -0
  24. package/dist/agents/prompt-assembly.js.map +1 -1
  25. package/dist/cli/chat.d.ts +33 -0
  26. package/dist/cli/chat.d.ts.map +1 -1
  27. package/dist/cli/chat.js +161 -7
  28. package/dist/cli/chat.js.map +1 -1
  29. package/dist/cli/execute.d.ts +12 -0
  30. package/dist/cli/execute.d.ts.map +1 -1
  31. package/dist/cli/execute.js +150 -2
  32. package/dist/cli/execute.js.map +1 -1
  33. package/dist/cli/loop-executor.d.ts +17 -0
  34. package/dist/cli/loop-executor.d.ts.map +1 -1
  35. package/dist/cli/loop-executor.js +160 -1
  36. package/dist/cli/loop-executor.js.map +1 -1
  37. package/dist/cli/models.d.ts.map +1 -1
  38. package/dist/cli/models.js +10 -0
  39. package/dist/cli/models.js.map +1 -1
  40. package/dist/cli/trace.d.ts +19 -0
  41. package/dist/cli/trace.d.ts.map +1 -1
  42. package/dist/cli/trace.js +109 -2
  43. package/dist/cli/trace.js.map +1 -1
  44. package/dist/gateway/registry.d.ts +31 -0
  45. package/dist/gateway/registry.d.ts.map +1 -1
  46. package/dist/gateway/registry.js +162 -13
  47. package/dist/gateway/registry.js.map +1 -1
  48. package/dist/inference/model-entitlement.d.ts +46 -0
  49. package/dist/inference/model-entitlement.d.ts.map +1 -0
  50. package/dist/inference/model-entitlement.js +98 -0
  51. package/dist/inference/model-entitlement.js.map +1 -0
  52. package/dist/inference/tool-call-utils.d.ts +10 -0
  53. package/dist/inference/tool-call-utils.d.ts.map +1 -1
  54. package/dist/inference/tool-call-utils.js +90 -0
  55. package/dist/inference/tool-call-utils.js.map +1 -1
  56. package/dist/learning/autonomy-policy.d.ts +370 -0
  57. package/dist/learning/autonomy-policy.d.ts.map +1 -0
  58. package/dist/learning/autonomy-policy.js +544 -0
  59. package/dist/learning/autonomy-policy.js.map +1 -0
  60. package/dist/learning/cost-tracker.d.ts +14 -0
  61. package/dist/learning/cost-tracker.d.ts.map +1 -1
  62. package/dist/learning/cost-tracker.js +22 -0
  63. package/dist/learning/cost-tracker.js.map +1 -1
  64. package/dist/learning/credential-fingerprint.d.ts +58 -0
  65. package/dist/learning/credential-fingerprint.d.ts.map +1 -0
  66. package/dist/learning/credential-fingerprint.js +126 -0
  67. package/dist/learning/credential-fingerprint.js.map +1 -0
  68. package/dist/learning/deliverable-class.d.ts +178 -0
  69. package/dist/learning/deliverable-class.d.ts.map +1 -0
  70. package/dist/learning/deliverable-class.js +504 -0
  71. package/dist/learning/deliverable-class.js.map +1 -0
  72. package/dist/learning/engine-router.d.ts +12 -1
  73. package/dist/learning/engine-router.d.ts.map +1 -1
  74. package/dist/learning/engine-router.js +28 -0
  75. package/dist/learning/engine-router.js.map +1 -1
  76. package/dist/learning/long-form.d.ts +252 -0
  77. package/dist/learning/long-form.d.ts.map +1 -0
  78. package/dist/learning/long-form.js +521 -0
  79. package/dist/learning/long-form.js.map +1 -0
  80. package/dist/learning/model-first-router.d.ts +17 -0
  81. package/dist/learning/model-first-router.d.ts.map +1 -1
  82. package/dist/learning/model-first-router.js +27 -0
  83. package/dist/learning/model-first-router.js.map +1 -1
  84. package/dist/learning/model-registry.d.ts +66 -4
  85. package/dist/learning/model-registry.d.ts.map +1 -1
  86. package/dist/learning/model-registry.js +67 -6
  87. package/dist/learning/model-registry.js.map +1 -1
  88. package/dist/learning/model-warmup.d.ts +97 -2
  89. package/dist/learning/model-warmup.d.ts.map +1 -1
  90. package/dist/learning/model-warmup.js +165 -60
  91. package/dist/learning/model-warmup.js.map +1 -1
  92. package/dist/learning/prompt-layers.d.ts +61 -0
  93. package/dist/learning/prompt-layers.d.ts.map +1 -0
  94. package/dist/learning/prompt-layers.js +140 -0
  95. package/dist/learning/prompt-layers.js.map +1 -0
  96. package/dist/learning/provider-limits.d.ts +66 -0
  97. package/dist/learning/provider-limits.d.ts.map +1 -0
  98. package/dist/learning/provider-limits.js +184 -0
  99. package/dist/learning/provider-limits.js.map +1 -0
  100. package/dist/learning/reasoning-trace.d.ts +125 -1
  101. package/dist/learning/reasoning-trace.d.ts.map +1 -1
  102. package/dist/learning/reasoning-trace.js +85 -2
  103. package/dist/learning/reasoning-trace.js.map +1 -1
  104. package/dist/learning/resilient-call.d.ts +36 -1
  105. package/dist/learning/resilient-call.d.ts.map +1 -1
  106. package/dist/learning/resilient-call.js +80 -5
  107. package/dist/learning/resilient-call.js.map +1 -1
  108. package/dist/learning/unattended-job.d.ts +350 -0
  109. package/dist/learning/unattended-job.d.ts.map +1 -0
  110. package/dist/learning/unattended-job.js +636 -0
  111. package/dist/learning/unattended-job.js.map +1 -0
  112. package/dist/learning/unattended-progress.d.ts +95 -0
  113. package/dist/learning/unattended-progress.d.ts.map +1 -0
  114. package/dist/learning/unattended-progress.js +147 -0
  115. package/dist/learning/unattended-progress.js.map +1 -0
  116. package/dist/learning/working-state.d.ts +109 -0
  117. package/dist/learning/working-state.d.ts.map +1 -0
  118. package/dist/learning/working-state.js +244 -0
  119. package/dist/learning/working-state.js.map +1 -0
  120. package/dist/nlu/conversation-gate.d.ts +33 -0
  121. package/dist/nlu/conversation-gate.d.ts.map +1 -1
  122. package/dist/nlu/conversation-gate.js +68 -3
  123. package/dist/nlu/conversation-gate.js.map +1 -1
  124. package/dist/tools/coding-tools.d.ts.map +1 -1
  125. package/dist/tools/coding-tools.js +95 -19
  126. package/dist/tools/coding-tools.js.map +1 -1
  127. package/dist/tools/edit-verification.d.ts +142 -0
  128. package/dist/tools/edit-verification.d.ts.map +1 -0
  129. package/dist/tools/edit-verification.js +262 -0
  130. package/dist/tools/edit-verification.js.map +1 -0
  131. package/dist/tools/git-tool.d.ts.map +1 -1
  132. package/dist/tools/git-tool.js +37 -4
  133. package/dist/tools/git-tool.js.map +1 -1
  134. package/dist/tools/registry.d.ts +30 -2
  135. package/dist/tools/registry.d.ts.map +1 -1
  136. package/dist/tools/registry.js +40 -11
  137. package/dist/tools/registry.js.map +1 -1
  138. package/dist/tools/run-cli.d.ts.map +1 -1
  139. package/dist/tools/run-cli.js +40 -13
  140. package/dist/tools/run-cli.js.map +1 -1
  141. package/dist/tools/run-terminal.d.ts +6 -1
  142. package/dist/tools/run-terminal.d.ts.map +1 -1
  143. package/dist/tools/run-terminal.js +158 -18
  144. package/dist/tools/run-terminal.js.map +1 -1
  145. package/dist/tools/tool-loop.d.ts +109 -0
  146. package/dist/tools/tool-loop.d.ts.map +1 -1
  147. package/dist/tools/tool-loop.js +362 -2
  148. package/dist/tools/tool-loop.js.map +1 -1
  149. package/dist/web-dashboard/chat-console.d.ts +8 -0
  150. package/dist/web-dashboard/chat-console.d.ts.map +1 -1
  151. package/dist/web-dashboard/chat-console.js +9 -0
  152. package/dist/web-dashboard/chat-console.js.map +1 -1
  153. package/dist/web-dashboard/chat-retry.d.ts.map +1 -1
  154. package/dist/web-dashboard/chat-retry.js +10 -2
  155. package/dist/web-dashboard/chat-retry.js.map +1 -1
  156. package/dist/web-dashboard/server.d.ts.map +1 -1
  157. package/dist/web-dashboard/server.js +80 -8
  158. package/dist/web-dashboard/server.js.map +1 -1
  159. package/dist/web-dashboard/src/types.d.ts +81 -4
  160. package/dist/web-dashboard/src/types.d.ts.map +1 -1
  161. package/package.json +1 -1
  162. package/src/web-dashboard/public/assets/{index-Co7Hk2FT.js → index-kCUkORm7.js} +2 -2
  163. package/src/web-dashboard/public/assets/{index-Co7Hk2FT.js.map → index-kCUkORm7.js.map} +1 -1
  164. package/src/web-dashboard/public/index.html +1 -1
@@ -0,0 +1,636 @@
1
+ /**
2
+ * Unattended jobs — the engine that finishes long work WITHOUT the user having
3
+ * to say "continue" (enterprise-grade hardening, G11).
4
+ *
5
+ * THE BUG THIS CLOSES. The long-form ledger (G8) made a 100-page book
6
+ * *possible*: it split the ask into bounded units and recorded progress. But it
7
+ * left the CADENCE manual. Every batch ended with
8
+ *
9
+ * "Reply \"continue\" and I will write the next batch"
10
+ *
11
+ * so a 39-unit book needed ~10 human turns. The user asked for a book and got a
12
+ * job they had to keep pressing. That is a shortcut, not a delivery: "write me
13
+ * a 100-page book" is itself the authorization to spend the time, and an
14
+ * assistant that stops after 4 of 39 units to ask whether to continue has
15
+ * substituted a protocol for the work.
16
+ *
17
+ * WHAT THIS MODULE IS. A persisted queue of IN-PROGRESS WORK, plus a runner
18
+ * that keeps executing it until it is done, blocked on a genuine question, or
19
+ * out of its own time budget. It is deliberately NOT the retry queue
20
+ * (`deferred-task.ts`):
21
+ *
22
+ * | | deferred-task | unattended-job |
23
+ * |---|---|---|
24
+ * | triggered by | a FAILURE | unfinished WORK |
25
+ * | authorization | the user replying "yes" | the original ask |
26
+ * | wait shape | backoff between attempts | run continuously |
27
+ * | budget | ~6h of retries | hours of actual work (default 10h) |
28
+ * | stops on | attempts/TTL | completion, a real question, or no progress |
29
+ *
30
+ * Merging the two would make "keep retrying the model" and "keep writing the
31
+ * book" the same switch, and the consent semantics of each are opposites.
32
+ *
33
+ * THREE GUARANTEES THE RUNNER ENFORCES
34
+ * 1. PROGRESS IS MEASURED, NOT CLAIMED. A batch that did not move the ledger
35
+ * is a stall even if every step reported success. Three stalls in a row
36
+ * stop the run and ask, because an agent looping without progress is the
37
+ * exact "goes in a loop and never delivers" behaviour this exists to end.
38
+ * 2. IT STOPS FOR QUESTIONS, NOT FOR PERMISSION. The only thing that pauses
39
+ * work is a decision the user genuinely owns (see `autonomy-policy.ts`).
40
+ * 3. IT NEVER RUNS UNBOUNDED. A deadline (default 10 hours), a stall cap, a
41
+ * failure cap and a per-drain batch cap.
42
+ *
43
+ * Storage: `<memory>/unattended-jobs.json`. Best-effort writes — bookkeeping
44
+ * must never break the turn that scheduled the work.
45
+ */
46
+ import { envBuff, resolveNuviraHome } from '../config/paths.js';
47
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
48
+ import { join } from 'node:path';
49
+ // ─── Constants ──────────────────────────────────────────────────────────────
50
+ /**
51
+ * How long a job may keep working before it gives up and reports.
52
+ *
53
+ * Ten hours because the ask this module exists for is "a 100/200-page book" or
54
+ * "a phased build", and the user's requirement is explicit: those must run to
55
+ * completion unattended rather than in 4-turn increments. It is a CEILING, not
56
+ * a target — a job that finishes in ten minutes leaves the queue immediately.
57
+ */
58
+ export const DEFAULT_DEADLINE_MS = 10 * 3_600_000;
59
+ /** Consecutive no-progress batches before the run stops and asks. */
60
+ export const MAX_STALLED_BATCHES = 3;
61
+ /** Consecutive hard failures (provider errors, verification failures). */
62
+ export const MAX_CONSECUTIVE_FAILURES = 6;
63
+ /** Batches one drain may run before yielding (keeps a tick responsive). */
64
+ export const MAX_BATCHES_PER_DRAIN = 6;
65
+ /**
66
+ * How long a job may sit in `running` before it is treated as abandoned.
67
+ *
68
+ * A batch is claimed before it runs; if the process dies mid-batch — a restart,
69
+ * a reboot, a crash, all normal over a ten-hour job — nothing resets it and a
70
+ * `running` job is invisible to every query. The work would be stranded
71
+ * silently, which is the failure mode the whole ledger exists to prevent. The
72
+ * ceiling is generous (well past a single batch) so a live batch is never
73
+ * stolen.
74
+ */
75
+ export const STALE_RUNNING_MS = 25 * 60_000;
76
+ /** Bounded store — a queue is a convenience, not a backlog. */
77
+ const MAX_JOBS = 25;
78
+ /**
79
+ * Per-batch economy rows kept for the run report. A 100-page book is ~39
80
+ * batches, so the cap is far above a normal run; a job that somehow runs
81
+ * thousands of batches keeps its most recent window rather than an unbounded
82
+ * file.
83
+ */
84
+ const MAX_BATCH_STATS = 100;
85
+ const FILE_NAME = 'unattended-jobs.json';
86
+ const CURRENT_VERSION = 1;
87
+ function envBuffSafe(name) {
88
+ try {
89
+ return envBuff(name);
90
+ }
91
+ catch {
92
+ return undefined;
93
+ }
94
+ }
95
+ /** Memory dir, honouring the same test/dev override the long-form ledger uses. */
96
+ function memoryDir() {
97
+ const override = envBuffSafe('MEMORY_DIR');
98
+ if (override)
99
+ return override;
100
+ try {
101
+ return join(resolveNuviraHome(), 'memory');
102
+ }
103
+ catch {
104
+ return join(process.cwd(), '.nuvira-memory');
105
+ }
106
+ }
107
+ function storePath() {
108
+ return join(memoryDir(), FILE_NAME);
109
+ }
110
+ function isJobShape(value) {
111
+ if (!value || typeof value !== 'object')
112
+ return false;
113
+ const j = value;
114
+ return (typeof j.id === 'string' &&
115
+ typeof j.goal === 'string' &&
116
+ typeof j.projectPath === 'string' &&
117
+ typeof j.createdAt === 'number' &&
118
+ typeof j.deadline === 'number' &&
119
+ typeof j.continuationPrompt === 'string' &&
120
+ !!j.surface &&
121
+ typeof j.surface.platform === 'string' &&
122
+ typeof j.surface.channelId === 'string');
123
+ }
124
+ /**
125
+ * Self-heal jobs abandoned mid-batch (see STALE_RUNNING_MS), applied on READ so
126
+ * no process has to remember a recovery pass, and written back so the next
127
+ * reader sees the repair too.
128
+ */
129
+ function recoverStaleRunning(jobs, now) {
130
+ let repaired = false;
131
+ for (const job of jobs) {
132
+ if (job.status !== 'running')
133
+ continue;
134
+ const startedAt = job.lastRunAt || job.createdAt;
135
+ if (now - startedAt <= STALE_RUNNING_MS)
136
+ continue;
137
+ job.status = 'pending';
138
+ job.stopReason = undefined;
139
+ repaired = true;
140
+ }
141
+ if (repaired)
142
+ writeJobs(jobs);
143
+ return jobs;
144
+ }
145
+ /** Read the queue. Best-effort: a corrupt file is an empty queue, never a throw. */
146
+ export function loadUnattendedJobs(now = Date.now()) {
147
+ try {
148
+ const path = storePath();
149
+ if (!existsSync(path))
150
+ return [];
151
+ const parsed = JSON.parse(readFileSync(path, 'utf-8'));
152
+ if (!parsed || !Array.isArray(parsed.jobs))
153
+ return [];
154
+ return recoverStaleRunning(parsed.jobs.filter(isJobShape), now);
155
+ }
156
+ catch {
157
+ return [];
158
+ }
159
+ }
160
+ function writeJobs(jobs) {
161
+ try {
162
+ const dir = memoryDir();
163
+ if (!existsSync(dir))
164
+ mkdirSync(dir, { recursive: true });
165
+ // Newest first, bounded: the oldest job is the one most likely to have been
166
+ // forgotten, and dropping it silently beats an unbounded file.
167
+ const ordered = [...jobs].sort((a, b) => b.updatedAt - a.updatedAt).slice(0, MAX_JOBS);
168
+ const payload = { version: CURRENT_VERSION, jobs: ordered };
169
+ writeFileSync(storePath(), JSON.stringify(payload, null, 2), 'utf-8');
170
+ }
171
+ catch {
172
+ // Best-effort — bookkeeping must never break the turn that scheduled work.
173
+ }
174
+ }
175
+ function newId() {
176
+ try {
177
+ if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
178
+ return `job-${crypto.randomUUID().slice(0, 8)}`;
179
+ }
180
+ }
181
+ catch {
182
+ /* fall through */
183
+ }
184
+ return `job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
185
+ }
186
+ // ─── Lifecycle ──────────────────────────────────────────────────────────────
187
+ /** Stable identity for "the ongoing work in this project, for this surface". */
188
+ function jobIdentity(kind, projectPath, surface) {
189
+ return `${kind}|${projectPath}|${surface.platform}:${surface.channelId}`;
190
+ }
191
+ /**
192
+ * Schedule ongoing work — or return the job already carrying it.
193
+ *
194
+ * Idempotent per (kind, project, surface) on purpose: every batch of a book
195
+ * re-enters this function, and treating each re-entry as a new job would spawn
196
+ * a duplicate worker per batch and have them race on the same chapters.
197
+ */
198
+ export function startUnattendedJob(input) {
199
+ const jobs = loadUnattendedJobs();
200
+ const now = Date.now();
201
+ const identity = jobIdentity(input.kind, input.projectPath, input.surface);
202
+ const existing = jobs.find((j) => jobIdentity(j.kind, j.projectPath, j.surface) === identity && j.status !== 'cancelled' && j.status !== 'done');
203
+ if (existing) {
204
+ // A live job keeps its own counters and deadline — re-entering must not
205
+ // reset the time budget, or a job that keeps re-planning could run forever.
206
+ existing.goal = input.goal;
207
+ existing.updatedAt = now;
208
+ if (input.continuationPrompt)
209
+ existing.continuationPrompt = input.continuationPrompt;
210
+ writeJobs(jobs);
211
+ return { job: existing, created: false };
212
+ }
213
+ const job = {
214
+ id: newId(),
215
+ kind: input.kind,
216
+ goal: input.goal,
217
+ projectPath: input.projectPath,
218
+ surface: input.surface,
219
+ continuationPrompt: input.continuationPrompt ?? 'continue',
220
+ createdAt: now,
221
+ updatedAt: now,
222
+ lastRunAt: 0,
223
+ deadline: now + Math.max(60_000, input.deadlineMs ?? DEFAULT_DEADLINE_MS),
224
+ batches: 0,
225
+ stalledBatches: 0,
226
+ failures: 0,
227
+ status: 'pending',
228
+ progress: 0,
229
+ notify: input.notify !== false,
230
+ ...(input.expectedArtifacts?.length ? { expectedArtifacts: input.expectedArtifacts } : {}),
231
+ };
232
+ writeJobs([job, ...jobs]);
233
+ return { job, created: true };
234
+ }
235
+ export function getUnattendedJob(id) {
236
+ return loadUnattendedJobs().find((j) => j.id === id);
237
+ }
238
+ /** The live job for a surface (newest first), if any. */
239
+ export function findUnattendedJob(surface) {
240
+ return loadUnattendedJobs().find((j) => j.surface.platform === surface.platform &&
241
+ j.surface.channelId === surface.channelId &&
242
+ (j.status === 'pending' || j.status === 'running' || j.status === 'blocked'));
243
+ }
244
+ /** Every job still waiting for a turn (for status surfaces, newest first). */
245
+ export function listUnattendedJobs() {
246
+ return loadUnattendedJobs();
247
+ }
248
+ /**
249
+ * Jobs ready to run now: pending, inside their deadline, and not out of road.
250
+ *
251
+ * `blocked` jobs are deliberately excluded — they are waiting on the user, not
252
+ * on the scheduler.
253
+ */
254
+ export function dueUnattendedJobs(now = Date.now(), owns = () => true) {
255
+ return loadUnattendedJobs(now).filter((j) => j.status === 'pending' &&
256
+ j.deadline > now &&
257
+ j.stalledBatches < MAX_STALLED_BATCHES &&
258
+ j.failures < MAX_CONSECUTIVE_FAILURES &&
259
+ owns(j));
260
+ }
261
+ /** Jobs whose time budget ran out — the user must be told, not ghosted. */
262
+ export function expiredUnattendedJobs(now = Date.now(), owns = () => true) {
263
+ return loadUnattendedJobs(now).filter((j) => j.status === 'pending' && j.deadline <= now && owns(j));
264
+ }
265
+ /**
266
+ * Stop a job with a reason, without touching its counters.
267
+ *
268
+ * Used by the runner to expire jobs whose time budget ran out — the reason
269
+ * must be RECORDED (the user is told why the promised work stopped), and doing
270
+ * it here keeps the runner free of ledger-write logic.
271
+ */
272
+ export function stopUnattendedJob(id, status, reason, now = Date.now()) {
273
+ const jobs = loadUnattendedJobs(now);
274
+ const job = jobs.find((j) => j.id === id);
275
+ if (!job)
276
+ return undefined;
277
+ job.status = status;
278
+ job.stopReason = reason;
279
+ job.updatedAt = now;
280
+ if (status === 'done')
281
+ job.progress = 100;
282
+ writeJobs(jobs);
283
+ return job;
284
+ }
285
+ /** Stop a job (the user said stop, or the work is being replaced). */
286
+ export function cancelUnattendedJob(id, reason = 'cancelled by the user') {
287
+ const jobs = loadUnattendedJobs();
288
+ const job = jobs.find((j) => j.id === id);
289
+ if (!job)
290
+ return;
291
+ job.status = 'cancelled';
292
+ job.stopReason = reason;
293
+ job.updatedAt = Date.now();
294
+ writeJobs(jobs);
295
+ }
296
+ /** Drop every job for a surface (`stop`, `cancel`, a fresh unrelated ask). */
297
+ export function cancelUnattendedJobsFor(surface, reason = 'cancelled by the user') {
298
+ const jobs = loadUnattendedJobs();
299
+ let changed = 0;
300
+ for (const job of jobs) {
301
+ if (job.surface.platform !== surface.platform || job.surface.channelId !== surface.channelId)
302
+ continue;
303
+ if (job.status === 'done' || job.status === 'cancelled' || job.status === 'failed')
304
+ continue;
305
+ job.status = 'cancelled';
306
+ job.stopReason = reason;
307
+ job.updatedAt = Date.now();
308
+ changed++;
309
+ }
310
+ if (changed > 0)
311
+ writeJobs(jobs);
312
+ return changed;
313
+ }
314
+ /** Claim a job for one batch. Returns the claimed job, or undefined. */
315
+ export function claimUnattendedJob(id, now = Date.now()) {
316
+ const jobs = loadUnattendedJobs(now);
317
+ const job = jobs.find((j) => j.id === id);
318
+ if (!job || job.status !== 'pending')
319
+ return undefined;
320
+ job.status = 'running';
321
+ job.lastRunAt = now;
322
+ job.updatedAt = now;
323
+ writeJobs(jobs);
324
+ return job;
325
+ }
326
+ /**
327
+ * Record what one batch actually did, and decide what happens next.
328
+ *
329
+ * This is where "no manual cadence" is enforced: the batch's own outcome
330
+ * determines whether the job keeps running, stops because it is DONE, or stops
331
+ * because it needs the user — nobody has to say "continue".
332
+ *
333
+ * @returns the updated job (undefined when the id is unknown).
334
+ */
335
+ export function recordBatchOutcome(id, outcome, now = Date.now()) {
336
+ const jobs = loadUnattendedJobs(now);
337
+ const job = jobs.find((j) => j.id === id);
338
+ if (!job)
339
+ return undefined;
340
+ job.batches += 1;
341
+ job.updatedAt = now;
342
+ job.stopReason = undefined;
343
+ job.pendingQuestion = undefined;
344
+ if (outcome.progressLine)
345
+ job.progressLine = outcome.progressLine;
346
+ // ── Per-batch economy (G27), recorded for failures too. ──────────────────
347
+ // A batch that died on a provider error still burned tokens; a report that
348
+ // counted only the batches that reached the success path would understate
349
+ // the bill of exactly the runs most likely to be expensive. `progress` here
350
+ // is the batch's MEASURED completion (a finished batch measures 100).
351
+ if (outcome.costUsd !== undefined)
352
+ job.costUsd = round6((job.costUsd ?? 0) + outcome.costUsd);
353
+ if (outcome.tokens !== undefined)
354
+ job.tokens = (job.tokens ?? 0) + outcome.tokens;
355
+ job.batchStats = [
356
+ ...(job.batchStats ?? []),
357
+ {
358
+ index: job.batches,
359
+ progress: typeof outcome.progress === 'number' ? outcome.progress : job.progress,
360
+ ...(outcome.progressLine ? { progressLine: outcome.progressLine } : {}),
361
+ ...(outcome.costUsd !== undefined ? { costUsd: outcome.costUsd } : {}),
362
+ ...(outcome.tokens !== undefined ? { tokens: outcome.tokens } : {}),
363
+ ...(outcome.durationMs !== undefined ? { durationMs: outcome.durationMs } : {}),
364
+ ...(outcome.error ? { error: outcome.error.slice(0, 200) } : {}),
365
+ },
366
+ ].slice(-MAX_BATCH_STATS);
367
+ // ── A hard failure is checked FIRST, before completion. ──────────────────
368
+ // A batch that failed verification can leave every file on disk and still
369
+ // not be a delivered deliverable (a site that does not present the chapters).
370
+ // Letting `finished` win would report success over exactly the failure the
371
+ // verify step exists to catch.
372
+ if (outcome.error) {
373
+ job.failures += 1;
374
+ if (job.failures >= MAX_CONSECUTIVE_FAILURES) {
375
+ job.status = 'failed';
376
+ job.stopReason = `stopped after ${job.failures} consecutive failed batches — last error: ${outcome.error.slice(0, 300)}`;
377
+ writeJobs(jobs);
378
+ return job;
379
+ }
380
+ job.status = 'pending';
381
+ writeJobs(jobs);
382
+ return job;
383
+ }
384
+ // ── Finished: the deliverable exists. ────────────────────────────────────
385
+ if (outcome.finished) {
386
+ job.status = 'done';
387
+ job.progress = 100;
388
+ job.stopReason = 'complete';
389
+ writeJobs(jobs);
390
+ return job;
391
+ }
392
+ // ── A genuine question: stop the RUN, not the work. ──────────────────────
393
+ // Marked blocked rather than failed so the answer resumes from the ledger.
394
+ if (outcome.question) {
395
+ job.status = 'blocked';
396
+ job.pendingQuestion = outcome.question;
397
+ job.stopReason = 'waiting on a decision only the user can make';
398
+ writeJobs(jobs);
399
+ return job;
400
+ }
401
+ job.failures = 0;
402
+ // ── Progress is MEASURED. A batch that did not move is a stall. ──────────
403
+ const measured = typeof outcome.progress === 'number' ? outcome.progress : job.progress;
404
+ const moved = measured > job.progress;
405
+ job.progress = Math.max(job.progress, measured);
406
+ job.stalledBatches = moved ? 0 : job.stalledBatches + 1;
407
+ if (job.stalledBatches >= MAX_STALLED_BATCHES) {
408
+ job.status = 'blocked';
409
+ job.stopReason = `no measurable progress in ${job.stalledBatches} batches`;
410
+ job.pendingQuestion =
411
+ `I've run ${job.stalledBatches} batches with NO measurable progress — the deliverable has not grown ` +
412
+ `(still ${job.progress}% — ${job.progressLine ?? 'no progress recorded'}). ` +
413
+ 'Something is genuinely wrong that I cannot resolve on my own; how would you like me to proceed?';
414
+ writeJobs(jobs);
415
+ return job;
416
+ }
417
+ if (now >= job.deadline) {
418
+ job.status = 'failed';
419
+ job.stopReason = 'time budget exhausted before the work finished';
420
+ writeJobs(jobs);
421
+ return job;
422
+ }
423
+ job.status = 'pending';
424
+ writeJobs(jobs);
425
+ return job;
426
+ }
427
+ /** Resume a blocked job after the user answered. */
428
+ export function resumeUnattendedJob(id, extraDeadlineMs = 0, now = Date.now()) {
429
+ const jobs = loadUnattendedJobs(now);
430
+ const job = jobs.find((j) => j.id === id);
431
+ if (!job)
432
+ return undefined;
433
+ job.status = 'pending';
434
+ job.pendingQuestion = undefined;
435
+ job.stopReason = undefined;
436
+ // An answer is fresh authorization: the stall counter and the clock both get
437
+ // a new run at it, or the job would stop again on the very next batch.
438
+ job.stalledBatches = 0;
439
+ job.failures = 0;
440
+ if (extraDeadlineMs > 0)
441
+ job.deadline = Math.max(job.deadline, now + extraDeadlineMs);
442
+ job.updatedAt = now;
443
+ writeJobs(jobs);
444
+ return job;
445
+ }
446
+ // ─── Reporting ──────────────────────────────────────────────────────────────
447
+ /** Percentage complete, clamped. */
448
+ export function jobPercent(job) {
449
+ return Math.max(0, Math.min(100, Math.round(job.progress)));
450
+ }
451
+ /** USD at micro-cent precision — the same rounding the cost ledger uses. */
452
+ function round6(value) {
453
+ return Math.round(value * 100000) / 100000;
454
+ }
455
+ /** A compact human duration (`850ms`, `12.4s`, `3m 07s`, `1h 12m`). */
456
+ export function formatDuration(ms) {
457
+ if (!Number.isFinite(ms) || ms < 0)
458
+ return '—';
459
+ if (ms < 1000)
460
+ return `${Math.round(ms)}ms`;
461
+ const seconds = ms / 1000;
462
+ if (seconds < 60)
463
+ return `${seconds.toFixed(1)}s`;
464
+ const minutes = Math.floor(seconds / 60);
465
+ if (minutes < 60)
466
+ return `${minutes}m ${String(Math.round(seconds % 60)).padStart(2, '0')}s`;
467
+ const hours = Math.floor(minutes / 60);
468
+ return `${hours}h ${String(minutes % 60).padStart(2, '0')}m`;
469
+ }
470
+ /**
471
+ * Per-batch cost and latency report for an unattended run (G27).
472
+ *
473
+ * WHY. The run reported a batch COUNT and a percentage, which answers neither
474
+ * of the two questions a long unattended job actually raises: what did it
475
+ * cost, and is it slowing down. Those had to be reconstructed by hand from the
476
+ * cost ledger afterwards.
477
+ *
478
+ * HONESTY. A dash means the surface did not measure that column — never a
479
+ * fabricated 0, which would read as "free" for a batch that simply was not
480
+ * metered. Token/cost columns come from the persisted cost ledger's timestamps
481
+ * (see `costSince`), so a resumed job in a new process reports accurately.
482
+ *
483
+ * @returns a printable block, or '' when no batch measured anything.
484
+ */
485
+ export function formatBatchReport(job) {
486
+ const stats = job.batchStats ?? [];
487
+ if (stats.length === 0)
488
+ return '';
489
+ const rows = [];
490
+ for (const s of stats) {
491
+ const tokens = s.tokens === undefined ? '—' : s.tokens.toLocaleString('en-US');
492
+ const cost = s.costUsd === undefined ? '—' : `$${s.costUsd.toFixed(5)}`;
493
+ const time = s.durationMs === undefined ? '—' : formatDuration(s.durationMs);
494
+ const note = s.error ? ` ✗ ${s.error.replace(/\s+/g, ' ').slice(0, 60)}` : '';
495
+ rows.push(` ${String(s.index).padStart(5)} ${`${Math.round(s.progress)}%`.padStart(6)} ` +
496
+ `${tokens.padStart(11)} ${cost.padStart(10)} ${time.padStart(8)}${note}`);
497
+ }
498
+ const totalTokens = job.tokens;
499
+ const totalCost = job.costUsd;
500
+ const timedRows = stats.filter((s) => s.durationMs !== undefined);
501
+ const totalMs = timedRows.reduce((sum, s) => sum + (s.durationMs ?? 0), 0);
502
+ const averageMs = timedRows.length > 0 ? totalMs / timedRows.length : undefined;
503
+ const totals = ` ${'total'.padStart(5)} ${`${jobPercent(job)}%`.padStart(6)} ` +
504
+ `${(totalTokens === undefined ? '—' : totalTokens.toLocaleString('en-US')).padStart(11)} ` +
505
+ `${(totalCost === undefined ? '—' : `$${totalCost.toFixed(5)}`).padStart(10)} ` +
506
+ `${(averageMs === undefined ? '—' : `~${formatDuration(averageMs)} avg`).padStart(8)}`;
507
+ return [
508
+ '',
509
+ '📊 Per-batch cost & latency',
510
+ ` ${'batch'.padStart(5)} ${'done'.padStart(6)} ${'tokens'.padStart(11)} ${'cost'.padStart(10)} ${'time'.padStart(8)}`,
511
+ ...rows,
512
+ totals,
513
+ ].join('\n');
514
+ }
515
+ /**
516
+ * The honest status line for a job.
517
+ *
518
+ * Deliberately quotes MEASURED progress and says explicitly that no reply is
519
+ * needed — the user's complaint was having to reply at all, so a progress
520
+ * report that ends by asking for one would repeat the mistake in miniature.
521
+ */
522
+ export function unattendedStatusLine(job) {
523
+ const head = job.kind === 'long-form' ? '📖' : '🛠️';
524
+ const pct = jobPercent(job);
525
+ switch (job.status) {
526
+ case 'done':
527
+ return `${head} Job complete — ${job.progressLine ?? 'deliverable written'} (${job.batches} batch${job.batches === 1 ? '' : 'es'}).`;
528
+ case 'blocked':
529
+ return `${head} ${pct}% ${job.progressLine ?? ''}\n\n❓ ${job.pendingQuestion ?? job.stopReason ?? 'I need your input to continue.'}`.trim();
530
+ case 'failed':
531
+ return `${head} I could not finish this one — ${pct}% done${job.progressLine ? ` (${job.progressLine})` : ''}. ${job.stopReason ?? ''}`.trim();
532
+ case 'cancelled':
533
+ return `${head} Stopped — ${job.stopReason ?? 'cancelled'}.`;
534
+ default:
535
+ return (`${head} Still working — ${pct}%${job.progressLine ? ` · ${job.progressLine}` : ''} ` +
536
+ `(batch ${job.batches + 1}). No reply needed; I'll keep going and report when it's done.`);
537
+ }
538
+ }
539
+ /** How long the job may still run, in ms (0 when the budget is spent). */
540
+ export function remainingBudgetMs(job, now = Date.now()) {
541
+ return Math.max(0, job.deadline - now);
542
+ }
543
+ /** Test/reset hook. */
544
+ export function clearUnattendedJobs() {
545
+ writeJobs([]);
546
+ }
547
+ /**
548
+ * The unattended continuation loop.
549
+ *
550
+ * One instance per surface process. `drain()` is the periodic tick: it expires
551
+ * anything out of time, reports it, then runs whatever is due — looping so a
552
+ * single tick advances a long job as far as its budget allows instead of one
553
+ * chapter per tick. Drains are serialized through an internal chain, because
554
+ * two overlapping drains would run the same job twice and race on the same
555
+ * files (exactly how the first end-to-end run produced four copies of the last
556
+ * chapter).
557
+ */
558
+ export class UnattendedRunner {
559
+ deps;
560
+ chain = Promise.resolve();
561
+ active = false;
562
+ constructor(deps) {
563
+ this.deps = deps;
564
+ }
565
+ now() {
566
+ return this.deps.now ? this.deps.now() : Date.now();
567
+ }
568
+ /** Is a drain currently running? Status surfaces use this to show activity. */
569
+ get isRunning() {
570
+ return this.active;
571
+ }
572
+ /** The jobs this runner would pick up right now. */
573
+ due() {
574
+ return dueUnattendedJobs(this.now(), this.deps.owns ?? (() => true));
575
+ }
576
+ /**
577
+ * Advance every due job as far as one tick may.
578
+ *
579
+ * @returns how many batches were run.
580
+ */
581
+ async drain() {
582
+ this.chain = this.chain.then(() => this.runOnce()).catch(() => undefined);
583
+ await this.chain;
584
+ return this.lastBatches;
585
+ }
586
+ lastBatches = 0;
587
+ async runOnce() {
588
+ this.active = true;
589
+ this.lastBatches = 0;
590
+ try {
591
+ const now = this.now();
592
+ // Expiry FIRST: a user who was promised the work must hear the outcome
593
+ // even when the queue is busy with something else.
594
+ for (const job of expiredUnattendedJobs(now, this.deps.owns ?? (() => true))) {
595
+ const expired = stopUnattendedJob(job.id, 'failed', 'time budget exhausted before the work finished', now) ?? job;
596
+ await this.safeNotify(expired, unattendedStatusLine(expired));
597
+ }
598
+ const budget = Math.max(1, this.deps.maxBatchesPerDrain ?? MAX_BATCHES_PER_DRAIN);
599
+ for (let i = 0; i < budget; i++) {
600
+ const next = this.due().find((job) => !(this.deps.isBusy?.(job) ?? false));
601
+ if (!next)
602
+ break;
603
+ const claimed = claimUnattendedJob(next.id, this.now());
604
+ if (!claimed)
605
+ continue;
606
+ let outcome;
607
+ try {
608
+ outcome = await this.deps.runBatch(claimed);
609
+ }
610
+ catch (err) {
611
+ outcome = { error: err instanceof Error ? err.message : String(err) };
612
+ }
613
+ this.lastBatches += 1;
614
+ const updated = recordBatchOutcome(claimed.id, outcome, this.now());
615
+ if (updated && claimed.notify) {
616
+ await this.safeNotify(updated, unattendedStatusLine(updated));
617
+ }
618
+ }
619
+ }
620
+ finally {
621
+ this.active = false;
622
+ }
623
+ }
624
+ /** A notification must never break the run that produced it. */
625
+ async safeNotify(job, line) {
626
+ if (!this.deps.notify)
627
+ return;
628
+ try {
629
+ await this.deps.notify(job, line);
630
+ }
631
+ catch {
632
+ /* best-effort */
633
+ }
634
+ }
635
+ }
636
+ //# sourceMappingURL=unattended-job.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unattended-job.js","sourceRoot":"","sources":["../../src/learning/unattended-job.ts"],"names":[],"mappings":"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"}