@capybara-hq/kernel 0.1.0-rc.23 → 0.1.0-rc.25
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/bootstrap.json +25 -25
- package/dist/admin/admin.module.d.ts +2 -1
- package/dist/admin/admin.module.js +9 -3
- package/dist/admin/health.service.d.ts +2 -2
- package/dist/admin/health.service.js +6 -2
- package/dist/admin/outbox-dead.controller.d.ts +23 -0
- package/dist/admin/outbox-dead.controller.js +62 -0
- package/dist/admin/outbox-dead.schemas.d.ts +8 -0
- package/dist/admin/outbox-dead.schemas.js +18 -0
- package/dist/admin/outbox-dead.service.d.ts +66 -0
- package/dist/admin/outbox-dead.service.js +179 -0
- package/dist/admin/overview.service.d.ts +40 -5
- package/dist/admin/overview.service.js +41 -7
- package/dist/agents/agents.module.js +3 -0
- package/dist/agents/agents.service.d.ts +6 -1
- package/dist/agents/agents.service.js +11 -2
- package/dist/agents/from-template.js +1 -1
- package/dist/background/finish.d.ts +5 -2
- package/dist/background/finish.js +14 -3
- package/dist/background/launch.d.ts +2 -1
- package/dist/background/launch.js +5 -2
- package/dist/background/store.d.ts +8 -0
- package/dist/background/store.js +24 -0
- package/dist/catalog/admin-catalog.controller.d.ts +21 -2
- package/dist/catalog/admin-catalog.controller.js +45 -6
- package/dist/catalog/admin-catalog.schemas.d.ts +5 -0
- package/dist/catalog/admin-catalog.schemas.js +8 -0
- package/dist/catalog/catalog-import.module.js +0 -4
- package/dist/catalog/catalog-scope.service.d.ts +63 -26
- package/dist/catalog/catalog-scope.service.js +146 -71
- package/dist/catalog/catalog.module.d.ts +2 -1
- package/dist/catalog/catalog.module.js +9 -4
- package/dist/catalog/catalog.service.d.ts +11 -4
- package/dist/catalog/catalog.service.js +21 -5
- package/dist/catalog/cli.d.ts +4 -3
- package/dist/catalog/cli.js +8 -13
- package/dist/catalog/job-ids.d.ts +8 -20
- package/dist/catalog/job-ids.js +11 -16
- package/dist/catalog/marketplaces.service.d.ts +1 -1
- package/dist/catalog/org-plugin-uploads.d.ts +11 -4
- package/dist/catalog/org-plugin-uploads.js +21 -6
- package/dist/catalog/owned-items.d.ts +6 -13
- package/dist/catalog/owned-items.js +11 -29
- package/dist/catalog/owned-plugin-cleanup.d.ts +8 -17
- package/dist/catalog/owned-plugin-cleanup.js +12 -66
- package/dist/catalog/platform-components.d.ts +56 -34
- package/dist/catalog/platform-components.js +68 -78
- package/dist/catalog/platform-import-update.d.ts +50 -0
- package/dist/catalog/platform-import-update.js +116 -0
- package/dist/catalog/plugin-import.d.ts +64 -26
- package/dist/catalog/plugin-import.js +113 -77
- package/dist/catalog/plugin-upgrade.d.ts +22 -4
- package/dist/catalog/plugin-upgrade.js +26 -19
- package/dist/catalog/scope-jobs.d.ts +59 -0
- package/dist/catalog/scope-jobs.js +65 -0
- package/dist/catalog/scope-sync-workers.d.ts +22 -0
- package/dist/catalog/scope-sync-workers.js +58 -2
- package/dist/catalog/scope-sync.d.ts +40 -65
- package/dist/catalog/scope-sync.js +114 -122
- package/dist/channels/channels.module.d.ts +5 -2
- package/dist/channels/channels.module.js +9 -2
- package/dist/channels/deliver-job.d.ts +25 -0
- package/dist/channels/deliver-job.js +25 -0
- package/dist/channels/inbound.d.ts +1 -1
- package/dist/channels/inbound.js +4 -17
- package/dist/channels/jobs.d.ts +28 -18
- package/dist/channels/jobs.js +63 -26
- package/dist/channels/threads.d.ts +4 -3
- package/dist/channels/threads.js +4 -3
- package/dist/config/schema.d.ts +0 -3
- package/dist/config/schema.js +11 -20
- package/dist/conversations/agent-tree.d.ts +16 -0
- package/dist/conversations/agent-tree.js +36 -0
- package/dist/conversations/conversations.controller.js +4 -2
- package/dist/conversations/conversations.service.d.ts +61 -19
- package/dist/conversations/conversations.service.js +69 -43
- package/dist/conversations/event-log.d.ts +7 -10
- package/dist/conversations/event-log.js +24 -15
- package/dist/conversations/events.d.ts +21 -0
- package/dist/conversations/events.js +26 -2
- package/dist/conversations/queue.service.d.ts +8 -3
- package/dist/conversations/queue.service.js +37 -13
- package/dist/conversations/source.d.ts +10 -0
- package/dist/conversations/source.js +17 -0
- package/dist/conversations/titles.d.ts +21 -8
- package/dist/conversations/titles.js +42 -15
- package/dist/conversations/tree.d.ts +10 -0
- package/dist/conversations/tree.js +35 -0
- package/dist/db/kernel-schema.d.ts +35 -22
- package/dist/devices/devices.service.d.ts +23 -11
- package/dist/devices/devices.service.js +34 -26
- package/dist/errors.d.ts +11 -0
- package/dist/errors.js +11 -0
- package/dist/evals/run-replay.d.ts +13 -2
- package/dist/evals/run-replay.js +42 -9
- package/dist/evals/snapshot.d.ts +7 -1
- package/dist/evals/snapshot.js +2 -1
- package/dist/extensions/extensions.module.js +3 -0
- package/dist/extensions/hooks.d.ts +22 -3
- package/dist/extensions/hooks.js +15 -1
- package/dist/extensions/lifecycle-hooks.d.ts +99 -0
- package/dist/extensions/lifecycle-hooks.js +273 -0
- package/dist/extensions/lifecycle.d.ts +6 -1
- package/dist/extensions/lifecycle.js +9 -2
- package/dist/extensions/org-config.d.ts +13 -1
- package/dist/extensions/org-config.js +19 -2
- package/dist/extensions/permission-view.d.ts +9 -5
- package/dist/extensions/permission-view.js +9 -4
- package/dist/extensions/point-defaults.d.ts +28 -1
- package/dist/extensions/point-defaults.js +44 -13
- package/dist/extensions/usage-subscribers.d.ts +43 -0
- package/dist/extensions/usage-subscribers.js +108 -0
- package/dist/http/api.module.js +2 -0
- package/dist/inbox/inbox.service.d.ts +6 -20
- package/dist/inbox/inbox.service.js +0 -3
- package/dist/inbox/org-notices.d.ts +1 -1
- package/dist/inbox/platform-inbox.service.d.ts +3 -32
- package/dist/inbox/platform-inbox.service.js +5 -54
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/infra/cli/kernel-cli.module.js +5 -0
- package/dist/infra/events/kernel-events.d.ts +9 -35
- package/dist/infra/outbox/outbox-relay.module.d.ts +6 -0
- package/dist/infra/outbox/outbox-relay.module.js +18 -0
- package/dist/infra/outbox/outbox.dispatcher.d.ts +103 -0
- package/dist/infra/outbox/outbox.dispatcher.js +310 -0
- package/dist/infra/outbox/outbox.module.d.ts +24 -0
- package/dist/infra/outbox/outbox.module.js +50 -0
- package/dist/infra/outbox/outbox.relay.d.ts +31 -0
- package/dist/infra/outbox/outbox.relay.js +76 -0
- package/dist/infra/outbox/outbox.service.d.ts +51 -0
- package/dist/infra/outbox/outbox.service.js +131 -0
- package/dist/infra/outbox/registry.d.ts +244 -0
- package/dist/infra/outbox/registry.js +234 -0
- package/dist/infra/queue/queue-names.d.ts +8 -0
- package/dist/infra/queue/queue-names.js +17 -0
- package/dist/kernel.module.js +3 -0
- package/dist/local-devices/device-policy.service.d.ts +4 -0
- package/dist/local-devices/device-policy.service.js +61 -3
- package/dist/local-devices/machines.d.ts +13 -5
- package/dist/local-devices/machines.js +45 -7
- package/dist/local-devices/policy-summary.d.ts +44 -1
- package/dist/local-devices/policy-summary.js +69 -0
- package/dist/models/embeddings.d.ts +9 -9
- package/dist/models/embeddings.js +11 -18
- package/dist/models/models.module.js +3 -0
- package/dist/orgs/directory-sync.js +1 -1
- package/dist/orgs/members.service.js +1 -1
- package/dist/orgs/offboarding.d.ts +50 -57
- package/dist/orgs/offboarding.js +117 -162
- package/dist/orgs/orgs.module.js +3 -0
- package/dist/orgs/orgs.service.d.ts +11 -5
- package/dist/orgs/orgs.service.js +22 -6
- package/dist/overrides.d.ts +23 -3
- package/dist/overrides.js +12 -2
- package/dist/platform/exclusions.js +5 -0
- package/dist/platform/ops/admin.ops.js +18 -2
- package/dist/platform/ops/catalog-admin.ops.d.ts +3 -1
- package/dist/platform/ops/catalog-admin.ops.js +32 -4
- package/dist/platform/ops/inbox.ops.js +4 -20
- package/dist/platform/ops/outbox.ops.d.ts +21 -0
- package/dist/platform/ops/outbox.ops.js +125 -0
- package/dist/platform/ops/platform.ops.d.ts +1 -0
- package/dist/platform/ops/platform.ops.js +6 -3
- package/dist/platform/ops/schedules.ops.js +40 -1
- package/dist/platform/platform-ops.module.d.ts +2 -1
- package/dist/platform/platform-ops.module.js +3 -0
- package/dist/platform/route-schemas.js +3 -0
- package/dist/roles/worker-role.d.ts +10 -5
- package/dist/roles/worker-role.js +19 -9
- package/dist/roles/worker.module.js +11 -8
- package/dist/runtime/context/build.d.ts +3 -0
- package/dist/runtime/context/build.js +15 -0
- package/dist/runtime/context/plugin-context.d.ts +20 -0
- package/dist/runtime/context/plugin-context.js +30 -0
- package/dist/runtime/langgraph-loop.js +17 -5
- package/dist/runtime/limits.d.ts +15 -0
- package/dist/runtime/limits.js +25 -0
- package/dist/runtime/loop.d.ts +16 -3
- package/dist/runtime/loop.js +2 -1
- package/dist/runtime/maintenance.d.ts +7 -3
- package/dist/runtime/maintenance.js +52 -12
- package/dist/runtime/model-call.d.ts +20 -17
- package/dist/runtime/model-call.js +15 -24
- package/dist/runtime/plugin-context.service.d.ts +69 -0
- package/dist/runtime/plugin-context.service.js +208 -0
- package/dist/runtime/queue-lost-jobs.d.ts +24 -0
- package/dist/runtime/queue-lost-jobs.js +51 -0
- package/dist/runtime/run-control.d.ts +47 -5
- package/dist/runtime/run-control.js +79 -12
- package/dist/runtime/run-finish.d.ts +39 -12
- package/dist/runtime/run-finish.js +97 -14
- package/dist/runtime/run-jobs.d.ts +95 -13
- package/dist/runtime/run-jobs.js +199 -28
- package/dist/runtime/run-orphan-check.job.d.ts +142 -0
- package/dist/runtime/run-orphan-check.job.js +339 -0
- package/dist/runtime/run-processors.d.ts +16 -9
- package/dist/runtime/run-processors.js +1 -1
- package/dist/runtime/run-queue.d.ts +75 -53
- package/dist/runtime/run-queue.js +189 -263
- package/dist/runtime/run-steps.d.ts +1 -2
- package/dist/runtime/run-steps.js +8 -11
- package/dist/runtime/run-worker.d.ts +26 -16
- package/dist/runtime/run-worker.js +132 -37
- package/dist/runtime/runtime.module.d.ts +2 -3
- package/dist/runtime/runtime.module.js +7 -6
- package/dist/runtime/step-log.d.ts +16 -4
- package/dist/runtime/step-log.js +26 -6
- package/dist/runtime/stream.controller.d.ts +2 -4
- package/dist/runtime/stream.controller.js +5 -11
- package/dist/runtime/subagents/child.js +1 -1
- package/dist/runtime/subagents/definition.d.ts +2 -1
- package/dist/runtime/subagents/definition.js +4 -2
- package/dist/runtime/subagents/deliveries.d.ts +6 -3
- package/dist/runtime/subagents/deliveries.js +16 -7
- package/dist/runtime/subagents/dispatch.d.ts +12 -12
- package/dist/runtime/subagents/dispatch.js +14 -38
- package/dist/runtime/subagents/messages.d.ts +5 -1
- package/dist/runtime/subagents/messages.js +11 -3
- package/dist/runtime/subagents/skill-fork.d.ts +3 -3
- package/dist/runtime/subagents/skill-fork.js +8 -5
- package/dist/runtime/subagents/subagents.service.js +1 -1
- package/dist/runtime/subagents/tree-jobs.d.ts +61 -0
- package/dist/runtime/subagents/tree-jobs.js +86 -0
- package/dist/runtime/usage-report-jobs.d.ts +23 -48
- package/dist/runtime/usage-report-jobs.js +67 -119
- package/dist/runtime/usage-report.d.ts +28 -77
- package/dist/runtime/usage-report.js +35 -213
- package/dist/runtime/waits.d.ts +48 -198
- package/dist/runtime/waits.js +103 -805
- package/dist/sandbox/jobs.d.ts +20 -10
- package/dist/sandbox/jobs.js +23 -17
- package/dist/sandbox/sandbox.service.d.ts +17 -4
- package/dist/sandbox/sandbox.service.js +55 -14
- package/dist/schedules/calendar.d.ts +134 -0
- package/dist/schedules/calendar.js +410 -0
- package/dist/schedules/fire.d.ts +26 -7
- package/dist/schedules/fire.js +91 -22
- package/dist/schedules/job-ids.d.ts +66 -17
- package/dist/schedules/job-ids.js +81 -13
- package/dist/schedules/run-tracker.d.ts +0 -5
- package/dist/schedules/run-tracker.js +2 -14
- package/dist/schedules/scan.job.d.ts +13 -32
- package/dist/schedules/scan.job.js +50 -164
- package/dist/schedules/schedule-math.d.ts +42 -0
- package/dist/schedules/schedule-math.js +52 -0
- package/dist/schedules/scheduled-tasks.service.d.ts +22 -6
- package/dist/schedules/scheduled-tasks.service.js +70 -14
- package/dist/schedules/schedules.controller.d.ts +5 -1
- package/dist/schedules/schedules.controller.js +15 -1
- package/dist/schedules/schedules.module.js +0 -4
- package/dist/schedules/schedules.schemas.d.ts +35 -0
- package/dist/schedules/schedules.schemas.js +27 -0
- package/dist/schedules/store.d.ts +5 -0
- package/dist/schedules/store.js +20 -0
- package/dist/skills/changes.controller.d.ts +1 -1
- package/dist/skills/changes.controller.js +1 -1
- package/dist/tools/approvals.service.d.ts +41 -11
- package/dist/tools/approvals.service.js +108 -14
- package/dist/tools/builtin-names.d.ts +5 -3
- package/dist/tools/builtin-names.js +12 -4
- package/dist/tools/builtins/builtin-tools.d.ts +1 -2
- package/dist/tools/builtins/builtin-tools.js +21 -17
- package/dist/tools/builtins/sandbox/bash.js +9 -3
- package/dist/tools/builtins/sandbox/common.d.ts +18 -1
- package/dist/tools/builtins/sandbox/common.js +14 -1
- package/dist/tools/builtins/sandbox/index.d.ts +2 -1
- package/dist/tools/builtins/sandbox/index.js +4 -1
- package/dist/tools/builtins/sandbox/task-list.d.ts +12 -0
- package/dist/tools/builtins/sandbox/task-list.js +130 -0
- package/dist/tools/builtins/sandbox/task-output.d.ts +8 -1
- package/dist/tools/builtins/sandbox/task-output.js +21 -3
- package/dist/tools/builtins/web/extract.d.ts +2 -4
- package/dist/tools/builtins/web/extract.js +2 -5
- package/dist/tools/pipeline.d.ts +12 -3
- package/dist/tools/pipeline.js +6 -1
- package/dist/tools/questions.service.d.ts +30 -10
- package/dist/tools/questions.service.js +41 -27
- package/dist/tools/registry.d.ts +12 -3
- package/dist/tools/registry.js +13 -3
- package/dist/tools/tools.module.js +4 -3
- package/package.json +3 -3
- package/src/migrations/0118_device_policy_ops.sql +6 -0
- package/src/migrations/0119_outbox.sql +22 -0
- package/src/migrations/0120_drop_usage_report_sweep.sql +7 -0
- package/src/migrations/0121_drop_platform_migration_runs.sql +12 -0
- package/src/migrations/0122_drop_scheduled_task_runs_rechecked_at.sql +5 -0
- package/src/migrations/0123_pgvector.sql +27 -0
- package/src/migrations/0124_conversation_source.sql +36 -0
- package/dist/catalog/platform-migration.d.ts +0 -115
- package/dist/catalog/platform-migration.js +0 -583
- package/dist/infra/queue/add-job-once.d.ts +0 -14
- package/dist/infra/queue/add-job-once.js +0 -16
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Redis } from "ioredis";
|
|
2
|
+
/** The Redis hash of the lost-jobs canary: `count` and `lastAt` (ISO). */
|
|
3
|
+
export declare const QUEUE_LOST_JOBS_KEY = "capk:queue-lost-jobs";
|
|
4
|
+
/** How long the canary stays after its last report (then the overview drops it). */
|
|
5
|
+
export declare const QUEUE_LOST_JOBS_TTL_SECONDS: number;
|
|
6
|
+
/** What the admin overview shows: how many run jobs the queue lost, and when it last did. */
|
|
7
|
+
export interface QueueLostJobsSummary {
|
|
8
|
+
count: number;
|
|
9
|
+
lastAt: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The "queue lost jobs" canary (transactional outbox spec §8.3): the `run-orphan-check` found
|
|
13
|
+
* queued runs whose job is neither in BullMQ nor owed by the outbox, which the outbox makes
|
|
14
|
+
* impossible unless Redis lost data (its durability broke). Each report adds to a count in Redis
|
|
15
|
+
* that the admin overview shows as an attention item until a week after the last report.
|
|
16
|
+
*/
|
|
17
|
+
export declare class QueueLostJobs {
|
|
18
|
+
private readonly redis;
|
|
19
|
+
constructor(redis: Redis);
|
|
20
|
+
/** Adds `n` lost jobs to the canary (no-op for 0). */
|
|
21
|
+
report(n: number): Promise<void>;
|
|
22
|
+
/** The canary, or null when no job was lost in the last week. */
|
|
23
|
+
summary(): Promise<QueueLostJobsSummary | null>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
|
+
};
|
|
10
|
+
import { Inject, Injectable } from "@nestjs/common";
|
|
11
|
+
import { REDIS } from "../infra/tokens.js";
|
|
12
|
+
/** The Redis hash of the lost-jobs canary: `count` and `lastAt` (ISO). */
|
|
13
|
+
export const QUEUE_LOST_JOBS_KEY = "capk:queue-lost-jobs";
|
|
14
|
+
/** How long the canary stays after its last report (then the overview drops it). */
|
|
15
|
+
export const QUEUE_LOST_JOBS_TTL_SECONDS = 7 * 24 * 3600;
|
|
16
|
+
/**
|
|
17
|
+
* The "queue lost jobs" canary (transactional outbox spec §8.3): the `run-orphan-check` found
|
|
18
|
+
* queued runs whose job is neither in BullMQ nor owed by the outbox, which the outbox makes
|
|
19
|
+
* impossible unless Redis lost data (its durability broke). Each report adds to a count in Redis
|
|
20
|
+
* that the admin overview shows as an attention item until a week after the last report.
|
|
21
|
+
*/
|
|
22
|
+
let QueueLostJobs = class QueueLostJobs {
|
|
23
|
+
redis;
|
|
24
|
+
constructor(redis) {
|
|
25
|
+
this.redis = redis;
|
|
26
|
+
}
|
|
27
|
+
/** Adds `n` lost jobs to the canary (no-op for 0). */
|
|
28
|
+
async report(n) {
|
|
29
|
+
if (n <= 0)
|
|
30
|
+
return;
|
|
31
|
+
await this.redis
|
|
32
|
+
.multi()
|
|
33
|
+
.hincrby(QUEUE_LOST_JOBS_KEY, "count", n)
|
|
34
|
+
.hset(QUEUE_LOST_JOBS_KEY, "lastAt", new Date().toISOString())
|
|
35
|
+
.expire(QUEUE_LOST_JOBS_KEY, QUEUE_LOST_JOBS_TTL_SECONDS)
|
|
36
|
+
.exec();
|
|
37
|
+
}
|
|
38
|
+
/** The canary, or null when no job was lost in the last week. */
|
|
39
|
+
async summary() {
|
|
40
|
+
const h = await this.redis.hgetall(QUEUE_LOST_JOBS_KEY);
|
|
41
|
+
const count = Number(h.count ?? 0);
|
|
42
|
+
if (!(count > 0) || h.lastAt === undefined)
|
|
43
|
+
return null;
|
|
44
|
+
return { count, lastAt: h.lastAt };
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
QueueLostJobs = __decorate([
|
|
48
|
+
Injectable(),
|
|
49
|
+
__param(0, Inject(REDIS))
|
|
50
|
+
], QueueLostJobs);
|
|
51
|
+
export { QueueLostJobs };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OutboxService } from "../infra/outbox/outbox.service.js";
|
|
2
2
|
import type { KernelLogger } from "../log.js";
|
|
3
3
|
import { RunAbort } from "./abort.js";
|
|
4
|
+
import { type ResumeOutcome, RunResume } from "./run-jobs.js";
|
|
4
5
|
import { RunQueue } from "./run-queue.js";
|
|
5
6
|
import { Waits } from "./waits.js";
|
|
6
7
|
/**
|
|
@@ -11,23 +12,64 @@ export declare class RunControl {
|
|
|
11
12
|
private readonly queue;
|
|
12
13
|
private readonly waits;
|
|
13
14
|
private readonly abort;
|
|
14
|
-
|
|
15
|
+
/** The resume of a waiting run in a decision's transaction (a reply's skips). */
|
|
16
|
+
private readonly resumes;
|
|
17
|
+
/** Owes a deleted root's tree stop in the delete's transaction. */
|
|
18
|
+
private readonly outbox;
|
|
15
19
|
private readonly log;
|
|
16
|
-
constructor(queue: Pick<RunQueue, "ensureRun" | "abortIfOrphaned" | "wakeHeldTree">, waits: Pick<Waits, "abortWaiting" | "childFinished" | "stopChildren" | "stopTree">, abort: Pick<RunAbort, "request">,
|
|
20
|
+
constructor(queue: Pick<RunQueue, "ensureRun" | "oweEnsureRun" | "abortIfOrphaned" | "abortQueued" | "wakeHeldTree" | "oweHeldTreeIn">, waits: Pick<Waits, "abortWaiting" | "childFinished" | "stopChildren" | "stopTree">, abort: Pick<RunAbort, "request">,
|
|
21
|
+
/** The resume of a waiting run in a decision's transaction (a reply's skips). */
|
|
22
|
+
resumes: Pick<RunResume, "resumeIn">,
|
|
23
|
+
/** Owes a deleted root's tree stop in the delete's transaction. */
|
|
24
|
+
outbox: Pick<OutboxService, "add">, log: Pick<KernelLogger, "error">);
|
|
17
25
|
/** 有未消费的消息且没有进行中的运行时投递一轮运行;返回 runId 或 null。 */
|
|
18
26
|
ensureRun(conversationId: string): Promise<string | null>;
|
|
27
|
+
/**
|
|
28
|
+
* The direct `ensureRun` right after a commit that owes the ensure-run backstop (a message, a
|
|
29
|
+
* queue change): a failure (Redis unreachable) is logged and never thrown, since the committed
|
|
30
|
+
* write is not undone and the backstop starts the run later (transactional outbox spec §6).
|
|
31
|
+
*/
|
|
32
|
+
ensureRunAfterCommit(conversationId: string): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Owes the ensure-run backstop in the caller's transaction (transactional outbox spec §6): `seq`
|
|
35
|
+
* is the event it wrote (or the conversation's newest), `orgId` the conversation's.
|
|
36
|
+
*/
|
|
37
|
+
oweEnsureRun(conversationId: string, seq: number | string, orgId: string): Promise<boolean>;
|
|
19
38
|
/** After a root's queue was unpaused: the wakes it held for its tree ({@link RunQueue.wakeHeldTree}). */
|
|
20
39
|
wakeHeldTree(rootId: string): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Owes, in the transaction that may release a root's hold (an unpause, a "send now"), the
|
|
42
|
+
* ensure-run backstop of every sub-agent the hold kept waiting ({@link RunQueue.oweHeldTreeIn});
|
|
43
|
+
* the caller's {@link wakeHeldTree} after the commit is the direct call.
|
|
44
|
+
*/
|
|
45
|
+
oweHeldTreeIn(rootId: string): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* In the caller's transaction, after it locked the decided rows (lock order: conversations,
|
|
48
|
+
* decided rows, runs): resumes the waiting run `runId` when it waits on nothing else
|
|
49
|
+
* ({@link RunResume.resumeIn}).
|
|
50
|
+
*/
|
|
51
|
+
resumeIn(runId: string, waitId: string): Promise<ResumeOutcome>;
|
|
52
|
+
/**
|
|
53
|
+
* Owes, in a root's delete transaction, the stop of its whole sub-agent tree (`stop-tree`,
|
|
54
|
+
* transactional outbox spec §6); the caller's {@link stopTree} after the commit is the direct
|
|
55
|
+
* call.
|
|
56
|
+
*/
|
|
57
|
+
oweStopDeletedTree(conversationId: string, byAccountId: string | null, orgId: string): Promise<boolean>;
|
|
21
58
|
/**
|
|
22
59
|
* 运行是孤儿(会话锁空闲、任务已不存在,没有 worker 会收到中止广播)时直接把它写成 aborted,返回 true;
|
|
23
60
|
* 否则返回 false。A stopped sub-agent then reports to its parent at once, and a stopped parent
|
|
24
61
|
* stops its children (sub-agents spec §12).
|
|
25
62
|
*/
|
|
26
63
|
abortIfOrphaned(conversationId: string, runId: string, byAccountId: string | null): Promise<boolean>;
|
|
64
|
+
/**
|
|
65
|
+
* Ends a run still `queued` in PG ({@link RunQueue.abortQueued}; the caller wrote the stop marker
|
|
66
|
+
* first): true when it did. A stopped sub-agent then reports to its parent at once.
|
|
67
|
+
*/
|
|
68
|
+
abortQueued(conversationId: string, runId: string, byAccountId: string | null): Promise<boolean>;
|
|
27
69
|
/**
|
|
28
70
|
* 运行在等人处理(waiting)时直接中止:取消等待、写 `run_aborted`、删除 checkpoint,返回 true;
|
|
29
|
-
* 运行已不是 waiting(例如刚被续跑)→ false.
|
|
30
|
-
*
|
|
71
|
+
* 运行已不是 waiting(例如刚被续跑)→ false. The stop's transaction owes the IM delivery that
|
|
72
|
+
* updates its approval / question cards (its appends, transactional outbox spec §8.1).
|
|
31
73
|
*/
|
|
32
74
|
abortWaiting(conversationId: string, runId: string, byAccountId: string | null): Promise<boolean>;
|
|
33
75
|
/**
|
|
@@ -8,10 +8,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
10
|
import { Inject, Injectable } from "@nestjs/common";
|
|
11
|
-
import {
|
|
11
|
+
import { OutboxService } from "../infra/outbox/outbox.service.js";
|
|
12
12
|
import { KERNEL_LOGGER } from "../infra/tokens.js";
|
|
13
13
|
import { RunAbort } from "./abort.js";
|
|
14
|
+
import { RunResume } from "./run-jobs.js";
|
|
14
15
|
import { RunQueue } from "./run-queue.js";
|
|
16
|
+
import { oweStopDeletedTree } from "./subagents/tree-jobs.js";
|
|
15
17
|
import { Waits } from "./waits.js";
|
|
16
18
|
/**
|
|
17
19
|
* Starting and stopping runs from outside the run worker: the conversations API (a message, a
|
|
@@ -21,23 +23,76 @@ let RunControl = class RunControl {
|
|
|
21
23
|
queue;
|
|
22
24
|
waits;
|
|
23
25
|
abort;
|
|
24
|
-
|
|
26
|
+
resumes;
|
|
27
|
+
outbox;
|
|
25
28
|
log;
|
|
26
|
-
constructor(queue, waits, abort,
|
|
29
|
+
constructor(queue, waits, abort,
|
|
30
|
+
/** The resume of a waiting run in a decision's transaction (a reply's skips). */
|
|
31
|
+
resumes,
|
|
32
|
+
/** Owes a deleted root's tree stop in the delete's transaction. */
|
|
33
|
+
outbox, log) {
|
|
27
34
|
this.queue = queue;
|
|
28
35
|
this.waits = waits;
|
|
29
36
|
this.abort = abort;
|
|
30
|
-
this.
|
|
37
|
+
this.resumes = resumes;
|
|
38
|
+
this.outbox = outbox;
|
|
31
39
|
this.log = log;
|
|
32
40
|
}
|
|
33
41
|
/** 有未消费的消息且没有进行中的运行时投递一轮运行;返回 runId 或 null。 */
|
|
34
42
|
ensureRun(conversationId) {
|
|
35
43
|
return this.queue.ensureRun(conversationId);
|
|
36
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* The direct `ensureRun` right after a commit that owes the ensure-run backstop (a message, a
|
|
47
|
+
* queue change): a failure (Redis unreachable) is logged and never thrown, since the committed
|
|
48
|
+
* write is not undone and the backstop starts the run later (transactional outbox spec §6).
|
|
49
|
+
*/
|
|
50
|
+
async ensureRunAfterCommit(conversationId) {
|
|
51
|
+
try {
|
|
52
|
+
await this.queue.ensureRun(conversationId);
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
this.log.error("cannot start the conversation's run now; the ensure-run backstop will", {
|
|
56
|
+
conversationId,
|
|
57
|
+
err,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Owes the ensure-run backstop in the caller's transaction (transactional outbox spec §6): `seq`
|
|
63
|
+
* is the event it wrote (or the conversation's newest), `orgId` the conversation's.
|
|
64
|
+
*/
|
|
65
|
+
oweEnsureRun(conversationId, seq, orgId) {
|
|
66
|
+
return this.queue.oweEnsureRun(conversationId, seq, orgId);
|
|
67
|
+
}
|
|
37
68
|
/** After a root's queue was unpaused: the wakes it held for its tree ({@link RunQueue.wakeHeldTree}). */
|
|
38
69
|
wakeHeldTree(rootId) {
|
|
39
70
|
return this.queue.wakeHeldTree(rootId);
|
|
40
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Owes, in the transaction that may release a root's hold (an unpause, a "send now"), the
|
|
74
|
+
* ensure-run backstop of every sub-agent the hold kept waiting ({@link RunQueue.oweHeldTreeIn});
|
|
75
|
+
* the caller's {@link wakeHeldTree} after the commit is the direct call.
|
|
76
|
+
*/
|
|
77
|
+
oweHeldTreeIn(rootId) {
|
|
78
|
+
return this.queue.oweHeldTreeIn(rootId);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* In the caller's transaction, after it locked the decided rows (lock order: conversations,
|
|
82
|
+
* decided rows, runs): resumes the waiting run `runId` when it waits on nothing else
|
|
83
|
+
* ({@link RunResume.resumeIn}).
|
|
84
|
+
*/
|
|
85
|
+
resumeIn(runId, waitId) {
|
|
86
|
+
return this.resumes.resumeIn(runId, waitId);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Owes, in a root's delete transaction, the stop of its whole sub-agent tree (`stop-tree`,
|
|
90
|
+
* transactional outbox spec §6); the caller's {@link stopTree} after the commit is the direct
|
|
91
|
+
* call.
|
|
92
|
+
*/
|
|
93
|
+
oweStopDeletedTree(conversationId, byAccountId, orgId) {
|
|
94
|
+
return oweStopDeletedTree(this.outbox, conversationId, byAccountId, orgId);
|
|
95
|
+
}
|
|
41
96
|
/**
|
|
42
97
|
* 运行是孤儿(会话锁空闲、任务已不存在,没有 worker 会收到中止广播)时直接把它写成 aborted,返回 true;
|
|
43
98
|
* 否则返回 false。A stopped sub-agent then reports to its parent at once, and a stopped parent
|
|
@@ -56,15 +111,26 @@ let RunControl = class RunControl {
|
|
|
56
111
|
return r;
|
|
57
112
|
}
|
|
58
113
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* changed: `run.wait-stopped` lets the channel outbound update them.
|
|
114
|
+
* Ends a run still `queued` in PG ({@link RunQueue.abortQueued}; the caller wrote the stop marker
|
|
115
|
+
* first): true when it did. A stopped sub-agent then reports to its parent at once.
|
|
62
116
|
*/
|
|
63
|
-
async
|
|
64
|
-
const r = await this.
|
|
65
|
-
|
|
117
|
+
async abortQueued(conversationId, runId, byAccountId) {
|
|
118
|
+
const r = await this.queue.abortQueued(conversationId, runId, byAccountId);
|
|
119
|
+
if (r) {
|
|
120
|
+
await this.waits
|
|
121
|
+
.childFinished(runId)
|
|
122
|
+
.catch((err) => this.log.error("cannot report finished sub-agent run to its parent", { runId, err }));
|
|
123
|
+
}
|
|
66
124
|
return r;
|
|
67
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* 运行在等人处理(waiting)时直接中止:取消等待、写 `run_aborted`、删除 checkpoint,返回 true;
|
|
128
|
+
* 运行已不是 waiting(例如刚被续跑)→ false. The stop's transaction owes the IM delivery that
|
|
129
|
+
* updates its approval / question cards (its appends, transactional outbox spec §8.1).
|
|
130
|
+
*/
|
|
131
|
+
abortWaiting(conversationId, runId, byAccountId) {
|
|
132
|
+
return this.waits.abortWaiting(conversationId, runId, byAccountId);
|
|
133
|
+
}
|
|
68
134
|
/**
|
|
69
135
|
* Stops a sub-agent with its descendants, or with `includeSelf: false` only the sub-agent
|
|
70
136
|
* conversations below `conversationId` (agent map spec §6; {@link Waits.stopTree}). Returns
|
|
@@ -83,7 +149,8 @@ RunControl = __decorate([
|
|
|
83
149
|
__param(0, Inject(RunQueue)),
|
|
84
150
|
__param(1, Inject(Waits)),
|
|
85
151
|
__param(2, Inject(RunAbort)),
|
|
86
|
-
__param(3, Inject(
|
|
87
|
-
__param(4, Inject(
|
|
152
|
+
__param(3, Inject(RunResume)),
|
|
153
|
+
__param(4, Inject(OutboxService)),
|
|
154
|
+
__param(5, Inject(KERNEL_LOGGER))
|
|
88
155
|
], RunControl);
|
|
89
156
|
export { RunControl };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { type AppendEvent, EventLog } from "../conversations/event-log.js";
|
|
2
2
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
3
3
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
4
|
+
import { OutboxService } from "../infra/outbox/outbox.service.js";
|
|
4
5
|
import { ScheduledTaskRunTracker } from "../schedules/run-tracker.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { ApprovalsService } from "../tools/approvals.service.js";
|
|
7
|
+
import { QuestionsService } from "../tools/questions.service.js";
|
|
8
|
+
import { type TerminalStatus } from "./run-jobs.js";
|
|
8
9
|
export interface FinishRunArgs {
|
|
9
10
|
conversationId: string;
|
|
10
11
|
runId: string;
|
|
@@ -18,15 +19,10 @@ export interface FinishRunArgs {
|
|
|
18
19
|
* 超时(max_duration)传 false:loop 没吸收的消息没有被回复,必须留给下一轮(R34)。
|
|
19
20
|
*/
|
|
20
21
|
floorToTrigger?: boolean;
|
|
21
|
-
/**
|
|
22
|
-
* Runs in the transaction once the run is known not to be terminal, before the terminal event:
|
|
23
|
-
* a parent's open `Agent` calls get their results here (sub-agents spec §12, review m1).
|
|
24
|
-
*/
|
|
25
|
-
beforeTerminal?: () => Promise<void>;
|
|
26
22
|
}
|
|
27
23
|
/**
|
|
28
|
-
* Writes runs' terminal states (one instance; the run worker, the run queue's orphan
|
|
29
|
-
* waits and the eval replays finish runs through it).
|
|
24
|
+
* Writes runs' terminal states (one instance; the run worker, the run queue's orphan abort, the
|
|
25
|
+
* `run-orphan-check`, the waits and the eval replays finish runs through it).
|
|
30
26
|
*/
|
|
31
27
|
export declare class RunFinish {
|
|
32
28
|
private readonly kdb;
|
|
@@ -34,20 +30,51 @@ export declare class RunFinish {
|
|
|
34
30
|
readonly txHost: TransactionHost;
|
|
35
31
|
/** A scheduled task's run follows its kernel run's end in the same transaction (spec §6). */
|
|
36
32
|
private readonly taskRuns;
|
|
33
|
+
/** The run's end owes the conversation's ensure-run backstop (transactional outbox spec §6). */
|
|
34
|
+
private readonly outbox;
|
|
35
|
+
/** A finished run's pending approvals are cancelled in its terminal transaction. */
|
|
36
|
+
private readonly approvals;
|
|
37
|
+
/** ... and its pending input requests. */
|
|
38
|
+
private readonly questions;
|
|
37
39
|
constructor(kdb: KernelDb, eventLog: EventLog, txHost: TransactionHost,
|
|
38
40
|
/** A scheduled task's run follows its kernel run's end in the same transaction (spec §6). */
|
|
39
|
-
taskRuns: Pick<ScheduledTaskRunTracker, "onRunFinished"
|
|
41
|
+
taskRuns: Pick<ScheduledTaskRunTracker, "onRunFinished">,
|
|
42
|
+
/** The run's end owes the conversation's ensure-run backstop (transactional outbox spec §6). */
|
|
43
|
+
outbox: Pick<OutboxService, "add">,
|
|
44
|
+
/** A finished run's pending approvals are cancelled in its terminal transaction. */
|
|
45
|
+
approvals: Pick<ApprovalsService, "cancelPendingIn">,
|
|
46
|
+
/** ... and its pending input requests. */
|
|
47
|
+
questions: Pick<QuestionsService, "cancelPendingIn">);
|
|
40
48
|
/**
|
|
41
49
|
* 在调用方的事务内写运行的终态:会话行锁 → 运行仍未结束才写终态事件、推进 `consumed_seq`、更新 `runs.status`。
|
|
50
|
+
* It also owes the conversation's ensure-run backstop under the terminal event's seq.
|
|
51
|
+
*
|
|
52
|
+
* A finished run waits on nothing: its pending approvals and input requests (one asked just
|
|
53
|
+
* before the run failed, while it was still `running`) are cancelled before its terminal event
|
|
54
|
+
* (`approval_decided` / `question_answered` with `cancelled`). Lock order, as every path that
|
|
55
|
+
* writes them: the conversation row, the run's approval and input request rows, the run row.
|
|
56
|
+
*
|
|
57
|
+
* Sub-agents (transactional outbox spec §6): before the terminal event the run's open fork
|
|
58
|
+
* invocation gets its report (`pairStoppedForks`; an `Agent` call has its result from its
|
|
59
|
+
* dispatch), so no terminal path leaves an open call. After it, the stops and the delivery the
|
|
60
|
+
* run's end causes are owed here (runtime/subagents/tree-jobs.ts), the caller still doing them
|
|
61
|
+
* right after its commit: `stop-tree` when an active fork child remains or a sub-agent run a
|
|
62
|
+
* person stopped has sub-agents below it, `deliver-to-parent` for a sub-agent's run. The
|
|
63
|
+
* delivery is a job, not written here: this transaction holds the child's conversation and run
|
|
64
|
+
* rows, and the parent's conversation row comes first in the dispatch's lock order (parent
|
|
65
|
+
* conversation, parent run, budget run, child conversation).
|
|
42
66
|
* 返回终态事件的 seq;运行已是终态(例如已被其他副本标记失败)→ 返回 null,什么都不写。
|
|
43
67
|
*
|
|
44
68
|
* `consumed_seq = GREATEST(consumed_seq, consumed, runs.trigger_seq)`:不回退,且失败 / 中止 / 完成都至少
|
|
45
69
|
* 消费到触发该运行的消息——否则结束时的 ensureRun 会对同一条消息无限重试(失败)或卡住会话。
|
|
46
70
|
* 超时(`floorToTrigger: false`)只取 `GREATEST(consumed_seq, consumed)`:没吸收的消息留给下一轮(R34)。
|
|
47
|
-
*
|
|
71
|
+
* Lock order as `RunQueue.ensureRun` and the decisions take it: the conversation row, the run's
|
|
72
|
+
* approval and input request rows, the run row; they never deadlock with each other.
|
|
48
73
|
* 调用方在提交后对非 null 的返回值调用 {@link notifyFinished}。
|
|
49
74
|
*/
|
|
50
75
|
finishIn(a: FinishRunArgs): Promise<number | null>;
|
|
76
|
+
/** {@link finishIn}'s owed stops and delivery of a run's sub-agent tree. */
|
|
77
|
+
private oweTreeWork;
|
|
51
78
|
/** 自开事务写终态并在提交后发布会话通知;返回值同 {@link finishIn}。 */
|
|
52
79
|
finish(a: FinishRunArgs): Promise<number | null>;
|
|
53
80
|
private finishOwn;
|
|
@@ -14,47 +14,78 @@ import { pauseQueueIn } from "../conversations/queue.js";
|
|
|
14
14
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
15
15
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
16
16
|
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
17
|
+
import { OutboxService } from "../infra/outbox/outbox.service.js";
|
|
17
18
|
import { ScheduledTaskRunTracker } from "../schedules/run-tracker.js";
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
import { ApprovalsService } from "../tools/approvals.service.js";
|
|
20
|
+
import { QuestionsService } from "../tools/questions.service.js";
|
|
21
|
+
import { ACTIVE_RUN_STATUSES, lockWaitRowsIn, oweEnsureRun, TERMINAL_STATUSES, } from "./run-jobs.js";
|
|
22
|
+
import { pairStoppedForks } from "./subagents/skill-fork.js";
|
|
23
|
+
import { oweDeliverToParent, oweStopChildren } from "./subagents/tree-jobs.js";
|
|
23
24
|
/**
|
|
24
|
-
* Writes runs' terminal states (one instance; the run worker, the run queue's orphan
|
|
25
|
-
* waits and the eval replays finish runs through it).
|
|
25
|
+
* Writes runs' terminal states (one instance; the run worker, the run queue's orphan abort, the
|
|
26
|
+
* `run-orphan-check`, the waits and the eval replays finish runs through it).
|
|
26
27
|
*/
|
|
27
28
|
let RunFinish = class RunFinish {
|
|
28
29
|
kdb;
|
|
29
30
|
eventLog;
|
|
30
31
|
txHost;
|
|
31
32
|
taskRuns;
|
|
33
|
+
outbox;
|
|
34
|
+
approvals;
|
|
35
|
+
questions;
|
|
32
36
|
constructor(kdb, eventLog, txHost,
|
|
33
37
|
/** A scheduled task's run follows its kernel run's end in the same transaction (spec §6). */
|
|
34
|
-
taskRuns
|
|
38
|
+
taskRuns,
|
|
39
|
+
/** The run's end owes the conversation's ensure-run backstop (transactional outbox spec §6). */
|
|
40
|
+
outbox,
|
|
41
|
+
/** A finished run's pending approvals are cancelled in its terminal transaction. */
|
|
42
|
+
approvals,
|
|
43
|
+
/** ... and its pending input requests. */
|
|
44
|
+
questions) {
|
|
35
45
|
this.kdb = kdb;
|
|
36
46
|
this.eventLog = eventLog;
|
|
37
47
|
this.txHost = txHost;
|
|
38
48
|
this.taskRuns = taskRuns;
|
|
49
|
+
this.outbox = outbox;
|
|
50
|
+
this.approvals = approvals;
|
|
51
|
+
this.questions = questions;
|
|
39
52
|
}
|
|
40
53
|
/**
|
|
41
54
|
* 在调用方的事务内写运行的终态:会话行锁 → 运行仍未结束才写终态事件、推进 `consumed_seq`、更新 `runs.status`。
|
|
55
|
+
* It also owes the conversation's ensure-run backstop under the terminal event's seq.
|
|
56
|
+
*
|
|
57
|
+
* A finished run waits on nothing: its pending approvals and input requests (one asked just
|
|
58
|
+
* before the run failed, while it was still `running`) are cancelled before its terminal event
|
|
59
|
+
* (`approval_decided` / `question_answered` with `cancelled`). Lock order, as every path that
|
|
60
|
+
* writes them: the conversation row, the run's approval and input request rows, the run row.
|
|
61
|
+
*
|
|
62
|
+
* Sub-agents (transactional outbox spec §6): before the terminal event the run's open fork
|
|
63
|
+
* invocation gets its report (`pairStoppedForks`; an `Agent` call has its result from its
|
|
64
|
+
* dispatch), so no terminal path leaves an open call. After it, the stops and the delivery the
|
|
65
|
+
* run's end causes are owed here (runtime/subagents/tree-jobs.ts), the caller still doing them
|
|
66
|
+
* right after its commit: `stop-tree` when an active fork child remains or a sub-agent run a
|
|
67
|
+
* person stopped has sub-agents below it, `deliver-to-parent` for a sub-agent's run. The
|
|
68
|
+
* delivery is a job, not written here: this transaction holds the child's conversation and run
|
|
69
|
+
* rows, and the parent's conversation row comes first in the dispatch's lock order (parent
|
|
70
|
+
* conversation, parent run, budget run, child conversation).
|
|
42
71
|
* 返回终态事件的 seq;运行已是终态(例如已被其他副本标记失败)→ 返回 null,什么都不写。
|
|
43
72
|
*
|
|
44
73
|
* `consumed_seq = GREATEST(consumed_seq, consumed, runs.trigger_seq)`:不回退,且失败 / 中止 / 完成都至少
|
|
45
74
|
* 消费到触发该运行的消息——否则结束时的 ensureRun 会对同一条消息无限重试(失败)或卡住会话。
|
|
46
75
|
* 超时(`floorToTrigger: false`)只取 `GREATEST(consumed_seq, consumed)`:没吸收的消息留给下一轮(R34)。
|
|
47
|
-
*
|
|
76
|
+
* Lock order as `RunQueue.ensureRun` and the decisions take it: the conversation row, the run's
|
|
77
|
+
* approval and input request rows, the run row; they never deadlock with each other.
|
|
48
78
|
* 调用方在提交后对非 null 的返回值调用 {@link notifyFinished}。
|
|
49
79
|
*/
|
|
50
80
|
async finishIn(a) {
|
|
51
81
|
const t = this.kdb.db;
|
|
52
|
-
await t
|
|
82
|
+
const conv = await t
|
|
53
83
|
.selectFrom("conversations")
|
|
54
|
-
.select("
|
|
84
|
+
.select(["kind", "org_id"])
|
|
55
85
|
.where("id", "=", a.conversationId)
|
|
56
86
|
.forUpdate()
|
|
57
87
|
.executeTakeFirst();
|
|
88
|
+
const pending = await lockWaitRowsIn(t, a.runId);
|
|
58
89
|
const run = await t
|
|
59
90
|
.selectFrom("runs")
|
|
60
91
|
.select("status")
|
|
@@ -63,7 +94,11 @@ let RunFinish = class RunFinish {
|
|
|
63
94
|
.executeTakeFirst();
|
|
64
95
|
if (!run || TERMINAL_STATUSES.has(run.status))
|
|
65
96
|
return null;
|
|
66
|
-
|
|
97
|
+
if (pending.approvals)
|
|
98
|
+
await this.approvals.cancelPendingIn(a.runId);
|
|
99
|
+
if (pending.questions)
|
|
100
|
+
await this.questions.cancelPendingIn(a.runId);
|
|
101
|
+
await pairStoppedForks(t, this.eventLog, a.runId);
|
|
67
102
|
const [ev] = await this.eventLog.appendIn(a.conversationId, [
|
|
68
103
|
{ ...a.event, runId: a.runId, idemKey: `${a.event.type}:${a.runId}` },
|
|
69
104
|
]);
|
|
@@ -85,7 +120,42 @@ let RunFinish = class RunFinish {
|
|
|
85
120
|
// a failed or stopped run pauses the queued messages until the person resumes (spec §5.7)
|
|
86
121
|
if (a.status !== "completed")
|
|
87
122
|
await pauseQueueIn(t, a.conversationId);
|
|
88
|
-
|
|
123
|
+
const seq = ev.seq;
|
|
124
|
+
// what arrived during the run starts the next one after the commit (the run worker's post-job
|
|
125
|
+
// ensureRun); owed here too, for when that never happens (an eval's hidden conversation never
|
|
126
|
+
// starts runs)
|
|
127
|
+
if (conv && (conv.kind === "chat" || conv.kind === "subagent")) {
|
|
128
|
+
await oweEnsureRun(this.outbox, a.conversationId, seq, conv.org_id);
|
|
129
|
+
}
|
|
130
|
+
if (conv)
|
|
131
|
+
await this.oweTreeWork(a, conv.kind, conv.org_id);
|
|
132
|
+
return seq;
|
|
133
|
+
}
|
|
134
|
+
/** {@link finishIn}'s owed stops and delivery of a run's sub-agent tree. */
|
|
135
|
+
async oweTreeWork(a, kind, orgId) {
|
|
136
|
+
const t = this.kdb.db;
|
|
137
|
+
if (kind === "subagent")
|
|
138
|
+
await oweDeliverToParent(this.outbox, a.runId, orgId);
|
|
139
|
+
const forkChild = await t
|
|
140
|
+
.selectFrom("subagent_dispatches as sd")
|
|
141
|
+
.innerJoin("runs as cr", "cr.id", "sd.child_run_id")
|
|
142
|
+
.select("sd.child_run_id")
|
|
143
|
+
.where("sd.parent_run_id", "=", a.runId)
|
|
144
|
+
.where("sd.for_skill", "=", true)
|
|
145
|
+
.where("cr.status", "in", ACTIVE_RUN_STATUSES)
|
|
146
|
+
.limit(1)
|
|
147
|
+
.executeTakeFirst();
|
|
148
|
+
const stoppedWithChildren = kind === "subagent" &&
|
|
149
|
+
personStopped(a.event) &&
|
|
150
|
+
(await t
|
|
151
|
+
.selectFrom("conversations")
|
|
152
|
+
.select("id")
|
|
153
|
+
.where("parent_conversation_id", "=", a.conversationId)
|
|
154
|
+
.where("kind", "=", "subagent")
|
|
155
|
+
.limit(1)
|
|
156
|
+
.executeTakeFirst()) !== undefined;
|
|
157
|
+
if (forkChild || stoppedWithChildren)
|
|
158
|
+
await oweStopChildren(this.outbox, a.runId, orgId);
|
|
89
159
|
}
|
|
90
160
|
/** 自开事务写终态并在提交后发布会话通知;返回值同 {@link finishIn}。 */
|
|
91
161
|
async finish(a) {
|
|
@@ -109,9 +179,22 @@ RunFinish = __decorate([
|
|
|
109
179
|
__param(0, Inject(KernelDb)),
|
|
110
180
|
__param(1, Inject(EventLog)),
|
|
111
181
|
__param(2, Inject(TransactionHost)),
|
|
112
|
-
__param(3, Inject(ScheduledTaskRunTracker))
|
|
182
|
+
__param(3, Inject(ScheduledTaskRunTracker)),
|
|
183
|
+
__param(4, Inject(OutboxService)),
|
|
184
|
+
__param(5, Inject(ApprovalsService)),
|
|
185
|
+
__param(6, Inject(QuestionsService))
|
|
113
186
|
], RunFinish);
|
|
114
187
|
export { RunFinish };
|
|
188
|
+
/**
|
|
189
|
+
* A `run_aborted` a person caused (an account and no `detail`): a sub-agent run stopped that way
|
|
190
|
+
* stops its descendants (`Waits.stopDescendantsOfStopped`, agent map spec §6).
|
|
191
|
+
*/
|
|
192
|
+
function personStopped(event) {
|
|
193
|
+
if (event.type !== "run_aborted")
|
|
194
|
+
return false;
|
|
195
|
+
const p = event.payload;
|
|
196
|
+
return typeof p?.byAccountId === "string" && p.detail === undefined;
|
|
197
|
+
}
|
|
115
198
|
/** The message of a `run_failed` event's error, for the task run (undefined otherwise). */
|
|
116
199
|
function failureMessage(event) {
|
|
117
200
|
if (event.type !== "run_failed")
|