@warlock.js/core 4.5.0 → 4.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.
- package/CHANGELOG.md +33 -0
- package/esm/ai/src/agent/agent.mjs +126 -7
- package/esm/ai/src/agent/agent.mjs.map +1 -1
- package/esm/ai/src/agent/signature.mjs +57 -0
- package/esm/ai/src/agent/signature.mjs.map +1 -0
- package/esm/ai/src/agent/snapshot.mjs +101 -0
- package/esm/ai/src/agent/snapshot.mjs.map +1 -0
- package/esm/ai/src/ai.mjs +37 -1
- package/esm/ai/src/ai.mjs.map +1 -1
- package/esm/ai/src/errors/agent-drift-error.mjs +31 -0
- package/esm/ai/src/errors/agent-drift-error.mjs.map +1 -0
- package/esm/ai/src/errors/index.mjs +2 -0
- package/esm/ai/src/errors/planner-drift-error.mjs +33 -0
- package/esm/ai/src/errors/planner-drift-error.mjs.map +1 -0
- package/esm/ai/src/image/image-cost.mjs +55 -0
- package/esm/ai/src/image/image-cost.mjs.map +1 -0
- package/esm/ai/src/image/image.mjs +112 -0
- package/esm/ai/src/image/image.mjs.map +1 -0
- package/esm/ai/src/image/index.mjs +4 -0
- package/esm/ai/src/index.mjs +20 -0
- package/esm/ai/src/planner/planner-run.mjs +161 -6
- package/esm/ai/src/planner/planner-run.mjs.map +1 -1
- package/esm/ai/src/planner/planner.mjs +25 -1
- package/esm/ai/src/planner/planner.mjs.map +1 -1
- package/esm/ai/src/planner/snapshot.mjs +95 -0
- package/esm/ai/src/planner/snapshot.mjs.map +1 -0
- package/esm/ai/src/rag/hybrid/bm25.mjs +51 -0
- package/esm/ai/src/rag/hybrid/bm25.mjs.map +1 -0
- package/esm/ai/src/rag/hybrid/hybrid-rank.mjs +29 -0
- package/esm/ai/src/rag/hybrid/hybrid-rank.mjs.map +1 -0
- package/esm/ai/src/rag/hybrid/rrf.mjs +30 -0
- package/esm/ai/src/rag/hybrid/rrf.mjs.map +1 -0
- package/esm/ai/src/rag/index.mjs +11 -0
- package/esm/ai/src/rag/loaders/errors.mjs +25 -0
- package/esm/ai/src/rag/loaders/errors.mjs.map +1 -0
- package/esm/ai/src/rag/loaders/index.mjs +7 -0
- package/esm/ai/src/rag/loaders/load-html.mjs +138 -0
- package/esm/ai/src/rag/loaders/load-html.mjs.map +1 -0
- package/esm/ai/src/rag/loaders/load-pdf.mjs +150 -0
- package/esm/ai/src/rag/loaders/load-pdf.mjs.map +1 -0
- package/esm/ai/src/rag/loaders/load-text.mjs +60 -0
- package/esm/ai/src/rag/loaders/load-text.mjs.map +1 -0
- package/esm/ai/src/rag/loaders/load-web.mjs +89 -0
- package/esm/ai/src/rag/loaders/load-web.mjs.map +1 -0
- package/esm/ai/src/rag/store/pg-vector-store.mjs +328 -0
- package/esm/ai/src/rag/store/pg-vector-store.mjs.map +1 -0
- package/esm/ai/src/rag/transforms/multi-query.mjs +41 -0
- package/esm/ai/src/rag/transforms/multi-query.mjs.map +1 -0
- package/esm/ai/src/speech/index.mjs +3 -0
- package/esm/ai/src/speech/speech.mjs +122 -0
- package/esm/ai/src/speech/speech.mjs.map +1 -0
- package/esm/ai/src/supervisor/entries.mjs +2 -2
- package/esm/ai/src/supervisor/entries.mjs.map +1 -1
- package/esm/ai/src/transcribe/audio-input.mjs +84 -0
- package/esm/ai/src/transcribe/audio-input.mjs.map +1 -0
- package/esm/ai/src/transcribe/index.mjs +4 -0
- package/esm/ai/src/transcribe/transcribe.mjs +127 -0
- package/esm/ai/src/transcribe/transcribe.mjs.map +1 -0
- package/esm/ai-openai/src/image.mjs +5 -0
- package/esm/ai-openai/src/index.mjs +3 -0
- package/esm/ai-openai/src/sdk.mjs +3 -0
- package/esm/ai-openai/src/speech.mjs +5 -0
- package/esm/ai-openai/src/transcription.mjs +6 -0
- package/esm/ai-openai/src/utils/index.mjs +1 -0
- package/esm/ai-openai/src/utils/to-openai-messages.mjs +3 -0
- package/esm/bootstrap.d.mts.map +1 -1
- package/esm/bootstrap.mjs +3 -1
- package/esm/bootstrap.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/config.check.mjs +42 -0
- package/esm/cli/commands/doctor/checks/config.check.mjs.map +1 -0
- package/esm/cli/commands/doctor/checks/connectors.check.mjs +28 -0
- package/esm/cli/commands/doctor/checks/connectors.check.mjs.map +1 -0
- package/esm/cli/commands/doctor/checks/health.check.mjs +35 -0
- package/esm/cli/commands/doctor/checks/health.check.mjs.map +1 -0
- package/esm/cli/commands/doctor/checks/index.mjs +25 -0
- package/esm/cli/commands/doctor/checks/index.mjs.map +1 -0
- package/esm/cli/commands/doctor/checks/optional-peers.check.mjs +90 -0
- package/esm/cli/commands/doctor/checks/optional-peers.check.mjs.map +1 -0
- package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs +69 -0
- package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs.map +1 -0
- package/esm/cli/commands/doctor/checks/routes.check.mjs +30 -0
- package/esm/cli/commands/doctor/checks/routes.check.mjs.map +1 -0
- package/esm/cli/commands/doctor/doctor-command.action.mjs +28 -0
- package/esm/cli/commands/doctor/doctor-command.action.mjs.map +1 -0
- package/esm/cli/commands/doctor/format-report.mjs +44 -0
- package/esm/cli/commands/doctor/format-report.mjs.map +1 -0
- package/esm/cli/commands/doctor/run-checks.mjs +50 -0
- package/esm/cli/commands/doctor/run-checks.mjs.map +1 -0
- package/esm/cli/commands/doctor.command.mjs +29 -0
- package/esm/cli/commands/doctor.command.mjs.map +1 -0
- package/esm/cli/commands/generate/templates/stubs.mjs +6 -8
- package/esm/cli/commands/generate/templates/stubs.mjs.map +1 -1
- package/esm/cli/commands/routes/format-routes-table.mjs +129 -0
- package/esm/cli/commands/routes/format-routes-table.mjs.map +1 -0
- package/esm/cli/commands/routes/route-row.mjs +92 -0
- package/esm/cli/commands/routes/route-row.mjs.map +1 -0
- package/esm/cli/commands/routes/routes-command.action.mjs +43 -0
- package/esm/cli/commands/routes/routes-command.action.mjs.map +1 -0
- package/esm/cli/commands/routes.command.mjs +51 -0
- package/esm/cli/commands/routes.command.mjs.map +1 -0
- package/esm/cli/commands/seed.command.mjs +5 -0
- package/esm/cli/commands/seed.command.mjs.map +1 -1
- package/esm/cli/framework-cli-commands.mjs +4 -0
- package/esm/cli/framework-cli-commands.mjs.map +1 -1
- package/esm/config/config-getter.mjs +5 -5
- package/esm/config/config-getter.mjs.map +1 -1
- package/esm/config/config-loader.mjs +2 -2
- package/esm/config/config-loader.mjs.map +1 -1
- package/esm/connectors/access-connector.mjs +2 -2
- package/esm/connectors/access-connector.mjs.map +1 -1
- package/esm/connectors/ai-connector.mjs +2 -2
- package/esm/connectors/ai-connector.mjs.map +1 -1
- package/esm/connectors/cache-connector.mjs +2 -2
- package/esm/connectors/cache-connector.mjs.map +1 -1
- package/esm/connectors/database-connector.mjs +2 -2
- package/esm/connectors/database-connector.mjs.map +1 -1
- package/esm/connectors/herald-connector.mjs +2 -2
- package/esm/connectors/herald-connector.mjs.map +1 -1
- package/esm/connectors/http-connector.d.mts.map +1 -1
- package/esm/connectors/http-connector.mjs +9 -7
- package/esm/connectors/http-connector.mjs.map +1 -1
- package/esm/connectors/logger-connector.mjs +2 -2
- package/esm/connectors/logger-connector.mjs.map +1 -1
- package/esm/connectors/mail-connector.mjs +2 -2
- package/esm/connectors/mail-connector.mjs.map +1 -1
- package/esm/connectors/notifications-connector.mjs +2 -2
- package/esm/connectors/notifications-connector.mjs.map +1 -1
- package/esm/connectors/socket-connector.mjs +3 -3
- package/esm/connectors/socket-connector.mjs.map +1 -1
- package/esm/database/index.d.mts +2 -1
- package/esm/database/index.mjs +1 -0
- package/esm/database/seed-command-action.mjs +44 -4
- package/esm/database/seed-command-action.mjs.map +1 -1
- package/esm/database/seeds/seed-records-table-migration.mjs +36 -0
- package/esm/database/seeds/seed-records-table-migration.mjs.map +1 -0
- package/esm/database/seeds/seeder.d.mts +22 -5
- package/esm/database/seeds/seeder.d.mts.map +1 -1
- package/esm/database/seeds/seeder.errors.d.mts +22 -0
- package/esm/database/seeds/seeder.errors.d.mts.map +1 -0
- package/esm/database/seeds/seeder.errors.mjs +29 -0
- package/esm/database/seeds/seeder.errors.mjs.map +1 -0
- package/esm/database/seeds/seeder.mjs.map +1 -1
- package/esm/database/seeds/seeders.manager.mjs +90 -11
- package/esm/database/seeds/seeders.manager.mjs.map +1 -1
- package/esm/database/seeds/types.d.mts +117 -1
- package/esm/database/seeds/types.d.mts.map +1 -1
- package/esm/database/seeds/utils.mjs +6 -1
- package/esm/database/seeds/utils.mjs.map +1 -1
- package/esm/dev-server/module-loader.d.mts +12 -0
- package/esm/dev-server/module-loader.d.mts.map +1 -1
- package/esm/dev-server/module-loader.mjs +30 -2
- package/esm/dev-server/module-loader.mjs.map +1 -1
- package/esm/http/config.mjs +2 -2
- package/esm/http/config.mjs.map +1 -1
- package/esm/http/createHttpApplication.mjs +2 -2
- package/esm/http/createHttpApplication.mjs.map +1 -1
- package/esm/http/health.d.mts +14 -0
- package/esm/http/health.d.mts.map +1 -1
- package/esm/http/health.mjs +16 -0
- package/esm/http/health.mjs.map +1 -1
- package/esm/http/middleware/idempotency.middleware.mjs +5 -5
- package/esm/http/middleware/idempotency.middleware.mjs.map +1 -1
- package/esm/http/middleware/inject-request-context.mjs +2 -2
- package/esm/http/middleware/inject-request-context.mjs.map +1 -1
- package/esm/http/middleware/maintenance.middleware.mjs +4 -4
- package/esm/http/middleware/maintenance.middleware.mjs.map +1 -1
- package/esm/http/plugins.mjs +9 -9
- package/esm/http/plugins.mjs.map +1 -1
- package/esm/http/response.mjs +5 -5
- package/esm/http/response.mjs.map +1 -1
- package/esm/http/server.mjs +4 -4
- package/esm/http/server.mjs.map +1 -1
- package/esm/index.d.mts +4 -3
- package/esm/index.mjs +2 -1
- package/esm/repositories/adapters/cascade/cascade-query-builder.d.mts +28 -1
- package/esm/repositories/adapters/cascade/cascade-query-builder.d.mts.map +1 -1
- package/esm/repositories/adapters/cascade/cascade-query-builder.mjs +39 -0
- package/esm/repositories/adapters/cascade/cascade-query-builder.mjs.map +1 -1
- package/esm/repositories/contracts/index.d.mts +1 -1
- package/esm/repositories/contracts/query-builder.contract.d.mts +87 -1
- package/esm/repositories/contracts/query-builder.contract.d.mts.map +1 -1
- package/esm/repositories/index.d.mts +1 -1
- package/esm/repositories/repository.manager.d.mts +99 -1
- package/esm/repositories/repository.manager.d.mts.map +1 -1
- package/esm/repositories/repository.manager.mjs +128 -0
- package/esm/repositories/repository.manager.mjs.map +1 -1
- package/esm/router/router.d.mts +9 -0
- package/esm/router/router.d.mts.map +1 -1
- package/esm/router/router.mjs +21 -1
- package/esm/router/router.mjs.map +1 -1
- package/esm/utils/paths.mjs +2 -2
- package/esm/utils/paths.mjs.map +1 -1
- package/esm/validation/validateAll.mjs +2 -2
- package/esm/validation/validateAll.mjs.map +1 -1
- package/llms-full.txt +427 -45
- package/llms.txt +4 -2
- package/package.json +9 -9
- package/skills/README.md +65 -0
- package/skills/health-checks/SKILL.md +13 -0
- package/skills/use-repository/SKILL.md +38 -1
- package/skills/warlock-doctor/SKILL.md +135 -0
- package/skills/warlock-routes/SKILL.md +91 -0
- package/skills/write-seeder/SKILL.md +143 -45
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,39 @@ All notable changes to `@warlock.js/core` are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
|
|
6
6
|
|
|
7
|
+
## 4.6.1
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- a fatal `uncaughtException` at production boot (e.g. a config file that throws) is no longer swallowed into a silent `exit 0` — bootstrap now wires the crash handler to exit non-zero in production so `warlock start` surfaces the failure; the dev server still logs-and-continues for HMR
|
|
12
|
+
|
|
13
|
+
## 4.6.0
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- release-hygiene tests: version↔changelog invariant + generator-stub import check
|
|
18
|
+
- `router.routeCount()` exposes the number of registered routes as a boot/readiness signal
|
|
19
|
+
- `health.addRoutesRegisteredCheck(getRouteCount)` registers a readiness check that reports not-ready when a booted HTTP app has zero routes
|
|
20
|
+
- seeders now receive a `{ track }` context — `track(model)`, `track(models[])`, and `track(table, id)` register created records (each call returns its argument so it can be chained inline); `recordsCreated` is auto-derived from the track count
|
|
21
|
+
- `seed_records` table (created via the new `SeedRecordsTableMigration`) records every tracked seed reference within the same transaction the seed runs in; only the last run's refs are kept per seeder
|
|
22
|
+
- `warlock seed --drop [name]` undoes a seed: deletes its tracked records in reverse run/insertion order inside a transaction, then resets the matching seeds-log rows so `once: true` seeds re-run; scope to one seeder with `--drop=<name>`
|
|
23
|
+
- `Seeder.dependsOn` is now resolved — seeders are topologically sorted so dependencies run before dependents, layered over the numeric `order` tie-break; throws `UnknownSeederDependencyError` for a missing dependency and `SeederDependencyCycleError` for a cycle
|
|
24
|
+
- seeders receive an injectable clock and a meaningful batch size — `run({ track, now, batchSize })`; `now()` (default `() => new Date()`) drives both seed data and the seeds-log timestamps so historical/back-fill runs are deterministic, and `batchSize` surfaces the seeder's own `batchSize` for `Model.createMany(rows, { batchSize })`
|
|
25
|
+
- repository-level aggregation — `aggregate()`, `sum()`, `avg()`, `min()`, `max()`, and `groupBy()` on `RepositoryManager`, each reusing `filterBy` (and its operator-injection guard), `where`, and scopes before the aggregate, exactly like `count()`
|
|
26
|
+
- `warlock doctor` — a read-only diagnostics command that runs routes / config / connectors / optional-peers / health / release-hygiene checks and prints a pass/warn/fail report (exits non-zero on any failure, never opens a DB/cache/socket connection)
|
|
27
|
+
- `warlock routes` — a read-only command that lists the registered HTTP routes as a verb-colored table (method / path / name / action / middleware-count / source); filter with `--method` / `--path` / `--name`, or emit the normalized rows as JSON with `--json`. Boots app code to register routes but starts no connectors
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- `Seeder.run` now receives a `SeedContext` (`run(ctx)`) — backward compatible, an existing zero-arg `run()` keeps working unchanged
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- route-module load/registration failures are no longer swallowed: a route file that throws on import or registration now surfaces loudly instead of silently 404'ing the whole surface
|
|
36
|
+
- `ModuleLoader.loadModule` rethrows after logging (wrapped in a new `ModuleLoadError` carrying the failing file + cause), so a broken module aborts boot and is caught loudly by the HMR batch-reload handler in dev
|
|
37
|
+
- `ModuleLoader.loadAll` aggregates per-file failures and throws an `AggregateError` at the end, so one broken module no longer hides the others
|
|
38
|
+
- `router.withSourceFile` rethrows the callback error after logging instead of consuming it with a bare `console.log` (the `try/finally` source-file stack cleanup is preserved)
|
|
39
|
+
|
|
7
40
|
## 4.5.0
|
|
8
41
|
|
|
9
42
|
### Changed
|
|
@@ -24,6 +24,8 @@ import { logAgentEvent } from "./agent-log-event.mjs";
|
|
|
24
24
|
import { createAgentStream } from "./agent-stream.mjs";
|
|
25
25
|
import { agentEventToStreamEvent } from "./agent-to-stream-event.mjs";
|
|
26
26
|
import { JsonStreamGuard } from "./json-stream-guard.mjs";
|
|
27
|
+
import { computeAgentSignature } from "./signature.mjs";
|
|
28
|
+
import { deleteAgentSnapshot, loadAgentSnapshotForResume, persistAgentSnapshot } from "./snapshot.mjs";
|
|
27
29
|
import { log } from "@warlock.js/logger";
|
|
28
30
|
|
|
29
31
|
//#region ../@warlock.js/ai/src/agent/agent.ts
|
|
@@ -154,11 +156,23 @@ function agent(config) {
|
|
|
154
156
|
tools
|
|
155
157
|
}) : config.name;
|
|
156
158
|
const skillsLib = config.skills ? isSkillsContract(config.skills) ? config.skills : skills(config.skills) : void 0;
|
|
159
|
+
const signature = computeAgentSignature({
|
|
160
|
+
name: isAnonymous ? void 0 : name,
|
|
161
|
+
version: config.version,
|
|
162
|
+
model: {
|
|
163
|
+
name: config.model?.name,
|
|
164
|
+
provider: config.model?.provider
|
|
165
|
+
},
|
|
166
|
+
tools,
|
|
167
|
+
maxTrips: config.maxTrips,
|
|
168
|
+
output: config.output
|
|
169
|
+
});
|
|
157
170
|
const resolvedConfig = {
|
|
158
171
|
...config,
|
|
159
172
|
name,
|
|
160
173
|
tools,
|
|
161
|
-
skillsLib
|
|
174
|
+
skillsLib,
|
|
175
|
+
signature
|
|
162
176
|
};
|
|
163
177
|
const instanceHandlers = /* @__PURE__ */ new Map();
|
|
164
178
|
function on(event, handler) {
|
|
@@ -178,6 +192,7 @@ function agent(config) {
|
|
|
178
192
|
name,
|
|
179
193
|
isAnonymous,
|
|
180
194
|
description: config.description,
|
|
195
|
+
signature,
|
|
181
196
|
async execute(input, options) {
|
|
182
197
|
return new Execution(resolvedConfig, input, options, void 0, instanceHandlers).run();
|
|
183
198
|
},
|
|
@@ -186,6 +201,19 @@ function agent(config) {
|
|
|
186
201
|
new Execution(resolvedConfig, input, options, controller, instanceHandlers).run();
|
|
187
202
|
return stream;
|
|
188
203
|
},
|
|
204
|
+
async resume(runId, options) {
|
|
205
|
+
const snapshot = await loadAgentSnapshotForResume({
|
|
206
|
+
durable: resolvedConfig.durable,
|
|
207
|
+
agentName: name,
|
|
208
|
+
signature,
|
|
209
|
+
runId,
|
|
210
|
+
options
|
|
211
|
+
});
|
|
212
|
+
return new Execution(resolvedConfig, snapshot.input, {
|
|
213
|
+
...options,
|
|
214
|
+
runId
|
|
215
|
+
}, void 0, instanceHandlers, snapshot).run();
|
|
216
|
+
},
|
|
189
217
|
on,
|
|
190
218
|
off,
|
|
191
219
|
eval(options) {
|
|
@@ -272,12 +300,13 @@ agent.judge = judgeAgent;
|
|
|
272
300
|
* return stream;
|
|
273
301
|
*/
|
|
274
302
|
var Execution = class {
|
|
275
|
-
constructor(config, input, options, streamController, instanceHandlers) {
|
|
303
|
+
constructor(config, input, options, streamController, instanceHandlers, resumeFrom) {
|
|
276
304
|
this.config = config;
|
|
277
305
|
this.input = input;
|
|
278
306
|
this.options = options;
|
|
279
307
|
this.streamController = streamController;
|
|
280
308
|
this.instanceHandlers = instanceHandlers;
|
|
309
|
+
this.resumeFrom = resumeFrom;
|
|
281
310
|
this.trips = [];
|
|
282
311
|
this.toolCalls = [];
|
|
283
312
|
this.usage = {
|
|
@@ -286,15 +315,25 @@ var Execution = class {
|
|
|
286
315
|
total: 0
|
|
287
316
|
};
|
|
288
317
|
this.messages = [];
|
|
289
|
-
this.startedAt = /* @__PURE__ */ new Date();
|
|
290
318
|
this.start = performance.now();
|
|
291
|
-
this.runId = generateRunId("agent");
|
|
292
319
|
this.logger = log;
|
|
293
320
|
this.warnedHandlerEvents = /* @__PURE__ */ new Set();
|
|
294
321
|
this.middlewareState = /* @__PURE__ */ new Map();
|
|
295
322
|
this.maxTrips = config.maxTrips ?? 10;
|
|
296
323
|
this.middleware = config.middleware ?? [];
|
|
297
324
|
this.judgeConfig = resolveJudgeConfig(config.judge);
|
|
325
|
+
this.runId = resumeFrom?.runId ?? options?.runId ?? generateRunId("agent");
|
|
326
|
+
this.startedAt = resumeFrom ? new Date(resumeFrom.startedAt) : /* @__PURE__ */ new Date();
|
|
327
|
+
if (resumeFrom) {
|
|
328
|
+
this.messages.push(...resumeFrom.messages);
|
|
329
|
+
this.trips.push(...resumeFrom.trips);
|
|
330
|
+
this.toolCalls.push(...resumeFrom.toolCalls);
|
|
331
|
+
mergeUsage(this.usage, resumeFrom.usage);
|
|
332
|
+
this.systemPrompt = resumeFrom.systemPrompt;
|
|
333
|
+
this.responseSchema = resumeFrom.responseSchema;
|
|
334
|
+
this.promptName = resumeFrom.promptName;
|
|
335
|
+
this.promptVersion = resumeFrom.promptVersion;
|
|
336
|
+
}
|
|
298
337
|
const skillTools = config.skillsLib ? normalizeAgentTools(config.skillsLib.tools(this.runId)) ?? [] : [];
|
|
299
338
|
this.effectiveTools = [...config.tools ?? [], ...skillTools];
|
|
300
339
|
}
|
|
@@ -358,14 +397,28 @@ var Execution = class {
|
|
|
358
397
|
* with `error` populated when things went wrong.
|
|
359
398
|
*/
|
|
360
399
|
async runCore() {
|
|
400
|
+
if (this.resumeFrom && this.resumeFrom.status === "completed") return this.rebuildResumedResult(this.resumeFrom);
|
|
361
401
|
try {
|
|
362
|
-
|
|
363
|
-
|
|
402
|
+
if (!this.resumeFrom) {
|
|
403
|
+
await this.buildInitialMessages();
|
|
404
|
+
this.emit("agent.starting", { input: this.input });
|
|
405
|
+
}
|
|
364
406
|
await this.runTripLoop();
|
|
365
407
|
if (await this.parseOutput() === "failed" && this.resolveRepairAttempts() > 0) await this.runRepairLoop();
|
|
366
408
|
} catch (thrown) {
|
|
367
409
|
this.error = this.toAIError(thrown);
|
|
368
410
|
}
|
|
411
|
+
await this.checkpoint(this.resolveSnapshotStatus());
|
|
412
|
+
if (!this.error && this.config.durable?.deleteOnComplete) {
|
|
413
|
+
const outcome = await deleteAgentSnapshot({
|
|
414
|
+
durable: this.config.durable,
|
|
415
|
+
runId: this.runId
|
|
416
|
+
});
|
|
417
|
+
if (!outcome.ok) this.logger.warn(LOG_MODULE, "snapshot.delete.failed", "durable snapshot delete failed", {
|
|
418
|
+
runId: this.runId,
|
|
419
|
+
error: outcome.error instanceof Error ? outcome.error.message : String(outcome.error)
|
|
420
|
+
});
|
|
421
|
+
}
|
|
369
422
|
return this.buildResult();
|
|
370
423
|
}
|
|
371
424
|
/**
|
|
@@ -430,7 +483,7 @@ var Execution = class {
|
|
|
430
483
|
* error so the caller can distinguish runaway tool loops from a real result.
|
|
431
484
|
*/
|
|
432
485
|
async runTripLoop() {
|
|
433
|
-
for (let tripIndex =
|
|
486
|
+
for (let tripIndex = this.trips.length; tripIndex < this.maxTrips; tripIndex++) {
|
|
434
487
|
if (this.options?.signal?.aborted) {
|
|
435
488
|
this.error = this.makeCancelledError();
|
|
436
489
|
return;
|
|
@@ -478,6 +531,7 @@ var Execution = class {
|
|
|
478
531
|
this.trips.push(failedTrip);
|
|
479
532
|
this.emit("agent.trip.completed", { trip: failedTrip });
|
|
480
533
|
this.emit("agent.error", { error: this.error });
|
|
534
|
+
await this.checkpoint("failed");
|
|
481
535
|
return "error";
|
|
482
536
|
}
|
|
483
537
|
if (response.usage.cost === void 0) response.usage.cost = computeCost(response.usage, this.config.model.pricing);
|
|
@@ -509,6 +563,7 @@ var Execution = class {
|
|
|
509
563
|
};
|
|
510
564
|
this.trips.push(trip);
|
|
511
565
|
this.emit("agent.trip.completed", { trip });
|
|
566
|
+
await this.checkpoint("running");
|
|
512
567
|
if (!isToolCallTrip) return "stop";
|
|
513
568
|
return response.toolCalls.every((request) => {
|
|
514
569
|
return this.effectiveTools.find((tool) => tool.name === request.name)?.mode === "silent";
|
|
@@ -919,6 +974,70 @@ var Execution = class {
|
|
|
919
974
|
};
|
|
920
975
|
}
|
|
921
976
|
/**
|
|
977
|
+
* Map the run's terminal outcome to the persisted snapshot status.
|
|
978
|
+
* A cancelled error reads as `"cancelled"`, any other error as
|
|
979
|
+
* `"failed"`, otherwise `"completed"`. Mirrors the report-status
|
|
980
|
+
* mapping in {@link buildResult}.
|
|
981
|
+
*/
|
|
982
|
+
resolveSnapshotStatus() {
|
|
983
|
+
if (!this.error) return "completed";
|
|
984
|
+
return this.error instanceof AgentCancelledError ? "cancelled" : "failed";
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* Build and persist an {@link AgentSnapshot} from the current
|
|
988
|
+
* accumulators. The per-trip and terminal checkpoints both route
|
|
989
|
+
* through here. Reuses {@link captureMessages} to normalize the live
|
|
990
|
+
* `Message[]` into JSON-safe form so the snapshot round-trips through
|
|
991
|
+
* any store backend.
|
|
992
|
+
*
|
|
993
|
+
* No-op (returns immediately) when `durable` is absent — the common
|
|
994
|
+
* non-durable path stays free. A failed persist is logged and
|
|
995
|
+
* swallowed (never aborts the run), matching the supervisor / workflow
|
|
996
|
+
* checkpoint policy.
|
|
997
|
+
*/
|
|
998
|
+
async checkpoint(status) {
|
|
999
|
+
if (!this.config.durable) return;
|
|
1000
|
+
const outcome = await persistAgentSnapshot({
|
|
1001
|
+
durable: this.config.durable,
|
|
1002
|
+
runId: this.runId,
|
|
1003
|
+
agentName: this.config.name ?? this.config.model.name,
|
|
1004
|
+
signature: this.config.signature,
|
|
1005
|
+
version: this.config.version,
|
|
1006
|
+
input: this.input,
|
|
1007
|
+
systemPrompt: this.systemPrompt,
|
|
1008
|
+
responseSchema: this.responseSchema,
|
|
1009
|
+
promptName: this.promptName,
|
|
1010
|
+
promptVersion: this.promptVersion,
|
|
1011
|
+
messages: this.captureMessages(),
|
|
1012
|
+
trips: this.trips,
|
|
1013
|
+
toolCalls: this.toolCalls,
|
|
1014
|
+
usage: this.usage,
|
|
1015
|
+
status,
|
|
1016
|
+
startedAt: this.startedAt.toISOString()
|
|
1017
|
+
});
|
|
1018
|
+
if (!outcome.ok) this.logger.warn(LOG_MODULE, "snapshot.persist.failed", "durable snapshot persist failed", {
|
|
1019
|
+
runId: this.runId,
|
|
1020
|
+
status,
|
|
1021
|
+
error: outcome.error instanceof Error ? outcome.error.message : String(outcome.error)
|
|
1022
|
+
});
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Rebuild the final {@link AgentResult} from a COMPLETED snapshot
|
|
1026
|
+
* WITHOUT re-running anything. Used by the completed-run resume
|
|
1027
|
+
* short-circuit: the persisted trips / tool calls / usage are the
|
|
1028
|
+
* authoritative outcome, so a resume of a settled run re-returns that
|
|
1029
|
+
* outcome idempotently. Re-derives `this.data` from the final trip
|
|
1030
|
+
* output against the schema (cheap, no model call) so the rebuilt
|
|
1031
|
+
* result carries the same structured payload the original produced.
|
|
1032
|
+
*
|
|
1033
|
+
* Only reached for a `completed` snapshot — `failed` / `cancelled`
|
|
1034
|
+
* snapshots re-enter the trip loop to retry the remaining work instead.
|
|
1035
|
+
*/
|
|
1036
|
+
async rebuildResumedResult(_snapshot) {
|
|
1037
|
+
await this.parseOutput();
|
|
1038
|
+
return this.buildResult();
|
|
1039
|
+
}
|
|
1040
|
+
/**
|
|
922
1041
|
* Normalize the accumulated runtime `Message[]` into the JSON-safe
|
|
923
1042
|
* {@link CapturedMessage}[] persisted on `AgentReport.messages` (F2).
|
|
924
1043
|
* Flattens `ContentPart[]` content to a string, and forwards
|