@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
|
@@ -9,6 +9,8 @@ import { AccountsService } from "../identity/accounts.js";
|
|
|
9
9
|
import { PlatformInboxService } from "../inbox/platform-inbox.service.js";
|
|
10
10
|
import { OrgsService } from "../orgs/orgs.service.js";
|
|
11
11
|
import { ProviderRegistry, type ProviderStatus } from "../runtime/providers.js";
|
|
12
|
+
import { QueueLostJobs } from "../runtime/queue-lost-jobs.js";
|
|
13
|
+
import { OutboxDeadService } from "./outbox-dead.service.js";
|
|
12
14
|
/** The most rows each attention list returns; the rest are counted in `more`. */
|
|
13
15
|
export declare const ATTENTION_LIST_MAX = 20;
|
|
14
16
|
/** The admin overview's numbers (`GET /api/v1/admin/overview`): counts only. */
|
|
@@ -17,7 +19,8 @@ export interface AdminOverviewStats {
|
|
|
17
19
|
accounts: number;
|
|
18
20
|
/**
|
|
19
21
|
* What waits for a super admin: the platform inbox total plus the extensions, plugin updates and
|
|
20
|
-
* model providers of {@link AdminAttention} (each counted in full, not capped)
|
|
22
|
+
* model providers of {@link AdminAttention} (each counted in full, not capped), every dead
|
|
23
|
+
* outbox row and the run queue's lost-jobs item.
|
|
21
24
|
*/
|
|
22
25
|
attentionTotal: number;
|
|
23
26
|
/** An attention source could not be read: `attentionTotal` leaves its items out. */
|
|
@@ -33,7 +36,7 @@ export type AttentionExtensionReason = "config" | "load_failed" | "approval" | "
|
|
|
33
36
|
/** What is wrong with a model provider: its model list failed, or it lists no usable chat model. */
|
|
34
37
|
export type AttentionProviderProblem = "list_failed" | "no_chat_model";
|
|
35
38
|
/** An attention list a source failed to read (it is then empty, the others intact). */
|
|
36
|
-
export type AttentionSource = "extensions" | "updates" | "providers";
|
|
39
|
+
export type AttentionSource = "extensions" | "updates" | "providers" | "outbox" | "queue";
|
|
37
40
|
export interface AttentionExtension {
|
|
38
41
|
name: string;
|
|
39
42
|
displayName: LocalizedName | null;
|
|
@@ -61,6 +64,27 @@ export interface AttentionProvider {
|
|
|
61
64
|
icon: string | null;
|
|
62
65
|
problem: AttentionProviderProblem;
|
|
63
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Background work the kernel could not queue (transactional outbox spec §3.4): how many outbox
|
|
69
|
+
* rows are dead and the oldest one's `dead_at`. One item for all of them; the rows themselves are
|
|
70
|
+
* `GET /api/v1/admin/outbox/dead`.
|
|
71
|
+
*/
|
|
72
|
+
export interface AttentionOutboxDead {
|
|
73
|
+
kind: "outbox_dead";
|
|
74
|
+
count: number;
|
|
75
|
+
oldestAt: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The run queue lost background jobs (transactional outbox spec §8.3): the `run-orphan-check`
|
|
79
|
+
* found queued runs whose job was neither in the queue nor owed, which only Redis losing data
|
|
80
|
+
* explains. Their jobs were added again; the item says Redis durability needs a look, how many
|
|
81
|
+
* jobs were lost and when last (it stays a week after the last loss).
|
|
82
|
+
*/
|
|
83
|
+
export interface AttentionQueueLostJobs {
|
|
84
|
+
kind: "queue_lost_jobs";
|
|
85
|
+
count: number;
|
|
86
|
+
lastAt: string;
|
|
87
|
+
}
|
|
64
88
|
/**
|
|
65
89
|
* `GET /api/v1/admin/overview/attention` (spec §5.2, §9): what needs a super admin besides the
|
|
66
90
|
* inbox, each list at most {@link ATTENTION_LIST_MAX} rows with the rest counted in `more`, and
|
|
@@ -71,6 +95,10 @@ export interface AdminAttention {
|
|
|
71
95
|
extensions: AttentionExtension[];
|
|
72
96
|
updates: AttentionUpdate[];
|
|
73
97
|
providers: AttentionProvider[];
|
|
98
|
+
/** System items: at most one, `outbox_dead`, when some outbox rows are dead. */
|
|
99
|
+
outbox: AttentionOutboxDead[];
|
|
100
|
+
/** System items: at most one, `queue_lost_jobs`, when the run queue lost jobs this week. */
|
|
101
|
+
queue: AttentionQueueLostJobs[];
|
|
74
102
|
more: Record<AttentionSource, number>;
|
|
75
103
|
unavailable: AttentionSource[];
|
|
76
104
|
}
|
|
@@ -81,8 +109,9 @@ export declare function providerProblem(p: ProviderStatus): AttentionProviderPro
|
|
|
81
109
|
/**
|
|
82
110
|
* The admin overview (spec §4.1, §5.2): its numbers and the 待处理 lists, read live from the
|
|
83
111
|
* sources the admin pages read (`ExtensionAdmin`, the catalog, the provider registry's cached
|
|
84
|
-
* lists). Each source is read on its own: a failing one is reported in
|
|
85
|
-
* audited (decision D5) and not cached further (every source is PG
|
|
112
|
+
* lists, the dead outbox rows, the run queue's lost-jobs canary). Each source is read on its own: a failing one is reported in
|
|
113
|
+
* `unavailable`. Reads are not audited (decision D5) and not cached further (every source is PG
|
|
114
|
+
* or already Redis-cached).
|
|
86
115
|
*/
|
|
87
116
|
export declare class AdminOverviewService {
|
|
88
117
|
private readonly extensions;
|
|
@@ -94,10 +123,16 @@ export declare class AdminOverviewService {
|
|
|
94
123
|
private readonly orgs;
|
|
95
124
|
private readonly accounts;
|
|
96
125
|
private readonly marketplaces;
|
|
126
|
+
private readonly outboxDead;
|
|
127
|
+
private readonly lostJobs;
|
|
97
128
|
private readonly log;
|
|
98
|
-
constructor(extensions: ExtensionAdmin, catalog: CatalogService, registry: ProviderRegistry, displayNames: ExtensionDisplayNames, icons: PluginIcons, inbox: PlatformInboxService, orgs: OrgsService, accounts: AccountsService, marketplaces: MarketplacesService, log: Logger);
|
|
129
|
+
constructor(extensions: ExtensionAdmin, catalog: CatalogService, registry: ProviderRegistry, displayNames: ExtensionDisplayNames, icons: PluginIcons, inbox: PlatformInboxService, orgs: OrgsService, accounts: AccountsService, marketplaces: MarketplacesService, outboxDead: OutboxDeadService, lostJobs: Pick<QueueLostJobs, "summary">, log: Logger);
|
|
99
130
|
stats(): Promise<AdminOverviewStats>;
|
|
100
131
|
attention(): Promise<AdminAttention>;
|
|
132
|
+
/** The `queue_lost_jobs` item when the run queue lost jobs this week, else none. */
|
|
133
|
+
private queueRows;
|
|
134
|
+
/** The `outbox_dead` item when some outbox rows are dead, else none. */
|
|
135
|
+
private outboxRows;
|
|
101
136
|
/**
|
|
102
137
|
* The extensions needing a look, but not one pending approval whose plugin waits in the platform
|
|
103
138
|
* inbox (a permission confirmation or an org upload: the inbox already lists and counts it). A
|
|
@@ -18,6 +18,8 @@ import { PlatformInboxService } from "../inbox/platform-inbox.service.js";
|
|
|
18
18
|
import { KERNEL_LOGGER } from "../infra/tokens.js";
|
|
19
19
|
import { OrgsService } from "../orgs/orgs.service.js";
|
|
20
20
|
import { ProviderRegistry } from "../runtime/providers.js";
|
|
21
|
+
import { QueueLostJobs } from "../runtime/queue-lost-jobs.js";
|
|
22
|
+
import { OutboxDeadService } from "./outbox-dead.service.js";
|
|
21
23
|
/** The most rows each attention list returns; the rest are counted in `more`. */
|
|
22
24
|
export const ATTENTION_LIST_MAX = 20;
|
|
23
25
|
/** The reason an extension is listed, or null when it needs nothing. */
|
|
@@ -53,8 +55,9 @@ export function providerProblem(p) {
|
|
|
53
55
|
/**
|
|
54
56
|
* The admin overview (spec §4.1, §5.2): its numbers and the 待处理 lists, read live from the
|
|
55
57
|
* sources the admin pages read (`ExtensionAdmin`, the catalog, the provider registry's cached
|
|
56
|
-
* lists). Each source is read on its own: a failing one is reported in
|
|
57
|
-
* audited (decision D5) and not cached further (every source is PG
|
|
58
|
+
* lists, the dead outbox rows, the run queue's lost-jobs canary). Each source is read on its own: a failing one is reported in
|
|
59
|
+
* `unavailable`. Reads are not audited (decision D5) and not cached further (every source is PG
|
|
60
|
+
* or already Redis-cached).
|
|
58
61
|
*/
|
|
59
62
|
let AdminOverviewService = class AdminOverviewService {
|
|
60
63
|
extensions;
|
|
@@ -66,8 +69,10 @@ let AdminOverviewService = class AdminOverviewService {
|
|
|
66
69
|
orgs;
|
|
67
70
|
accounts;
|
|
68
71
|
marketplaces;
|
|
72
|
+
outboxDead;
|
|
73
|
+
lostJobs;
|
|
69
74
|
log;
|
|
70
|
-
constructor(extensions, catalog, registry, displayNames, icons, inbox, orgs, accounts, marketplaces, log) {
|
|
75
|
+
constructor(extensions, catalog, registry, displayNames, icons, inbox, orgs, accounts, marketplaces, outboxDead, lostJobs, log) {
|
|
71
76
|
this.extensions = extensions;
|
|
72
77
|
this.catalog = catalog;
|
|
73
78
|
this.registry = registry;
|
|
@@ -77,6 +82,8 @@ let AdminOverviewService = class AdminOverviewService {
|
|
|
77
82
|
this.orgs = orgs;
|
|
78
83
|
this.accounts = accounts;
|
|
79
84
|
this.marketplaces = marketplaces;
|
|
85
|
+
this.outboxDead = outboxDead;
|
|
86
|
+
this.lostJobs = lostJobs;
|
|
80
87
|
this.log = log;
|
|
81
88
|
}
|
|
82
89
|
async stats() {
|
|
@@ -87,10 +94,17 @@ let AdminOverviewService = class AdminOverviewService {
|
|
|
87
94
|
this.attention(),
|
|
88
95
|
]);
|
|
89
96
|
const listed = (s) => attention[s].length + attention.more[s];
|
|
97
|
+
// each dead row waits for a super admin, not the one item that counts them
|
|
98
|
+
const dead = attention.outbox.reduce((n, o) => n + o.count, 0);
|
|
90
99
|
return {
|
|
91
100
|
orgs: orgs.length,
|
|
92
101
|
accounts,
|
|
93
|
-
attentionTotal: inbox +
|
|
102
|
+
attentionTotal: inbox +
|
|
103
|
+
listed("extensions") +
|
|
104
|
+
listed("updates") +
|
|
105
|
+
listed("providers") +
|
|
106
|
+
dead +
|
|
107
|
+
attention.queue.length,
|
|
94
108
|
partial: attention.unavailable.length > 0,
|
|
95
109
|
};
|
|
96
110
|
}
|
|
@@ -98,16 +112,20 @@ let AdminOverviewService = class AdminOverviewService {
|
|
|
98
112
|
// the catalog is read once: the update rows, and the plugins the inbox already lists
|
|
99
113
|
const items = this.catalogItems();
|
|
100
114
|
items.catch(() => { }); // awaited (and reported) by updateRows
|
|
101
|
-
const [extensions, updates, providers] = await Promise.allSettled([
|
|
115
|
+
const [extensions, updates, providers, outbox, queue] = await Promise.allSettled([
|
|
102
116
|
this.extensionRows(items),
|
|
103
117
|
this.updateRows(items),
|
|
104
118
|
this.providerRows(),
|
|
119
|
+
this.outboxRows(),
|
|
120
|
+
this.queueRows(),
|
|
105
121
|
]);
|
|
106
122
|
const out = {
|
|
107
123
|
extensions: [],
|
|
108
124
|
updates: [],
|
|
109
125
|
providers: [],
|
|
110
|
-
|
|
126
|
+
outbox: [],
|
|
127
|
+
queue: [],
|
|
128
|
+
more: { extensions: 0, updates: 0, providers: 0, outbox: 0, queue: 0 },
|
|
111
129
|
unavailable: [],
|
|
112
130
|
};
|
|
113
131
|
/** The rows of a source that answered (capped), or none and its name in `unavailable`. */
|
|
@@ -127,8 +145,22 @@ let AdminOverviewService = class AdminOverviewService {
|
|
|
127
145
|
out.extensions = take("extensions", extensions);
|
|
128
146
|
out.updates = take("updates", updates);
|
|
129
147
|
out.providers = take("providers", providers);
|
|
148
|
+
out.outbox = take("outbox", outbox);
|
|
149
|
+
out.queue = take("queue", queue);
|
|
130
150
|
return out;
|
|
131
151
|
}
|
|
152
|
+
/** The `queue_lost_jobs` item when the run queue lost jobs this week, else none. */
|
|
153
|
+
async queueRows() {
|
|
154
|
+
const lost = await this.lostJobs.summary();
|
|
155
|
+
return lost === null ? [] : [{ kind: "queue_lost_jobs", ...lost }];
|
|
156
|
+
}
|
|
157
|
+
/** The `outbox_dead` item when some outbox rows are dead, else none. */
|
|
158
|
+
async outboxRows() {
|
|
159
|
+
const { count, oldestAt } = await this.outboxDead.summary();
|
|
160
|
+
if (count === 0 || oldestAt === null)
|
|
161
|
+
return [];
|
|
162
|
+
return [{ kind: "outbox_dead", count, oldestAt: oldestAt.toISOString() }];
|
|
163
|
+
}
|
|
132
164
|
/**
|
|
133
165
|
* The extensions needing a look, but not one pending approval whose plugin waits in the platform
|
|
134
166
|
* inbox (a permission confirmation or an org upload: the inbox already lists and counts it). A
|
|
@@ -218,6 +250,8 @@ AdminOverviewService = __decorate([
|
|
|
218
250
|
__param(6, Inject(OrgsService)),
|
|
219
251
|
__param(7, Inject(AccountsService)),
|
|
220
252
|
__param(8, Inject(MarketplacesService)),
|
|
221
|
-
__param(9, Inject(
|
|
253
|
+
__param(9, Inject(OutboxDeadService)),
|
|
254
|
+
__param(10, Inject(QueueLostJobs)),
|
|
255
|
+
__param(11, Inject(KERNEL_LOGGER))
|
|
222
256
|
], AdminOverviewService);
|
|
223
257
|
export { AdminOverviewService };
|
|
@@ -8,6 +8,7 @@ import { Module } from "@nestjs/common";
|
|
|
8
8
|
import { AttachmentsModule } from "../conversations/attachments.module.js";
|
|
9
9
|
import { EvalBudgetModule } from "../evals/budget.js";
|
|
10
10
|
import { ExtensionsModule } from "../extensions/extensions.module.js";
|
|
11
|
+
import { LifecycleHooksModule } from "../extensions/lifecycle-hooks.js";
|
|
11
12
|
import { ModelsModule } from "../models/models.module.js";
|
|
12
13
|
import { OrgLockModule } from "../orgs/org-lock.js";
|
|
13
14
|
import { ProvidersModule } from "../runtime/providers.js";
|
|
@@ -48,6 +49,8 @@ AgentsModule = __decorate([
|
|
|
48
49
|
// creating from a template: the extension tools and the tier purposes (rulings P4-4, P4-5)
|
|
49
50
|
ExtensionsModule,
|
|
50
51
|
ModelsModule,
|
|
52
|
+
// the agent delete records `agent.deleted` deliveries
|
|
53
|
+
LifecycleHooksModule,
|
|
51
54
|
],
|
|
52
55
|
providers: [
|
|
53
56
|
AgentsService,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { KernelSchemaDb } from "../db/kernel-schema.js";
|
|
2
2
|
import { EvalBudget } from "../evals/budget.js";
|
|
3
|
+
import { LifecycleHooks } from "../extensions/lifecycle-hooks.js";
|
|
3
4
|
import type { WriteActor } from "../identity/write-actor.js";
|
|
4
5
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
5
6
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
@@ -92,6 +93,8 @@ export declare class AgentsService {
|
|
|
92
93
|
private readonly evalBudget;
|
|
93
94
|
/** Settles the agent's connector setup request when its pending connectors change (P4-7). */
|
|
94
95
|
private readonly setupRequests;
|
|
96
|
+
/** Records `agent.deleted` for the subscribing plugins in the delete's transaction. */
|
|
97
|
+
private readonly lifecycle;
|
|
95
98
|
constructor(db: KernelDb, lookup: AgentLookup, tools: Pick<ToolRegistry, "checkDisabled">,
|
|
96
99
|
/**
|
|
97
100
|
* Cancels the agent's pending skill requests: all of them when it is deleted, share requests
|
|
@@ -105,7 +108,9 @@ export declare class AgentsService {
|
|
|
105
108
|
/** Cancels the deleted agent's running eval runs (in the delete's transaction). */
|
|
106
109
|
evalBudget: Pick<EvalBudget, "cancelRuns">,
|
|
107
110
|
/** Settles the agent's connector setup request when its pending connectors change (P4-7). */
|
|
108
|
-
setupRequests: Pick<PendingConnectorRequests, "settleIn" | "retargetIn"
|
|
111
|
+
setupRequests: Pick<PendingConnectorRequests, "settleIn" | "retargetIn">,
|
|
112
|
+
/** Records `agent.deleted` for the subscribing plugins in the delete's transaction. */
|
|
113
|
+
lifecycle: Pick<LifecycleHooks, "recordIn">);
|
|
109
114
|
/**
|
|
110
115
|
* Checks the turned-off tools and the policies (tools default-on spec §2): `disabledTools` must
|
|
111
116
|
* name existing builtins, extensions and connectors (`ToolRegistry.checkDisabled`); `toolPolicies`
|
|
@@ -13,7 +13,9 @@ import { Inject, Injectable } from "@nestjs/common";
|
|
|
13
13
|
import { sql } from "kysely";
|
|
14
14
|
import { ApiError } from "../errors.js";
|
|
15
15
|
import { EvalBudget } from "../evals/budget.js";
|
|
16
|
+
import { LifecycleHooks } from "../extensions/lifecycle-hooks.js";
|
|
16
17
|
import { audit } from "../identity/audit.js";
|
|
18
|
+
import { afterCommit } from "../infra/database/after-commit.js";
|
|
17
19
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
18
20
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
19
21
|
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
@@ -279,6 +281,7 @@ let AgentsService = class AgentsService {
|
|
|
279
281
|
txHost;
|
|
280
282
|
evalBudget;
|
|
281
283
|
setupRequests;
|
|
284
|
+
lifecycle;
|
|
282
285
|
constructor(db, lookup, tools,
|
|
283
286
|
/**
|
|
284
287
|
* Cancels the agent's pending skill requests: all of them when it is deleted, share requests
|
|
@@ -292,7 +295,9 @@ let AgentsService = class AgentsService {
|
|
|
292
295
|
/** Cancels the deleted agent's running eval runs (in the delete's transaction). */
|
|
293
296
|
evalBudget,
|
|
294
297
|
/** Settles the agent's connector setup request when its pending connectors change (P4-7). */
|
|
295
|
-
setupRequests
|
|
298
|
+
setupRequests,
|
|
299
|
+
/** Records `agent.deleted` for the subscribing plugins in the delete's transaction. */
|
|
300
|
+
lifecycle) {
|
|
296
301
|
this.db = db;
|
|
297
302
|
this.lookup = lookup;
|
|
298
303
|
this.tools = tools;
|
|
@@ -302,6 +307,7 @@ let AgentsService = class AgentsService {
|
|
|
302
307
|
this.txHost = txHost;
|
|
303
308
|
this.evalBudget = evalBudget;
|
|
304
309
|
this.setupRequests = setupRequests;
|
|
310
|
+
this.lifecycle = lifecycle;
|
|
305
311
|
}
|
|
306
312
|
/**
|
|
307
313
|
* Checks the turned-off tools and the policies (tools default-on spec §2): `disabledTools` must
|
|
@@ -746,6 +752,8 @@ let AgentsService = class AgentsService {
|
|
|
746
752
|
});
|
|
747
753
|
// 评测集的 agent 删除后其评测运行不再花钱:显式取消(审计带原因)
|
|
748
754
|
await this.evalBudget.cancelRuns({ orgId, agentId }, { accountId: actorAccountId, ...(actorTokenId !== undefined && { tokenId: actorTokenId }) }, "agent_deleted");
|
|
755
|
+
// plugins learn of the delete durably: owed here, delivered by the outbox after the commit
|
|
756
|
+
await this.lifecycle.recordIn("agent.deleted", { orgId, agentId });
|
|
749
757
|
// joins this transaction (mandatory: it relies on the agent row lock taken above)
|
|
750
758
|
return this.skillChanges.cancelPendingForAgent(orgId, agentId, actorAccountId, "agent_deleted", actorTokenId);
|
|
751
759
|
}
|
|
@@ -907,6 +915,7 @@ AgentsService = __decorate([
|
|
|
907
915
|
__param(5, Inject(ProviderRegistry)),
|
|
908
916
|
__param(6, Inject(TransactionHost)),
|
|
909
917
|
__param(7, Inject(EvalBudget)),
|
|
910
|
-
__param(8, Inject(PendingConnectorRequests))
|
|
918
|
+
__param(8, Inject(PendingConnectorRequests)),
|
|
919
|
+
__param(9, Inject(LifecycleHooks))
|
|
911
920
|
], AgentsService);
|
|
912
921
|
export { AgentsService };
|
|
@@ -329,7 +329,7 @@ export async function planFromTemplate(db, orgId, row, opts) {
|
|
|
329
329
|
}
|
|
330
330
|
if (describesSubagents)
|
|
331
331
|
listed.add(AGENT_TOOL);
|
|
332
|
-
// `TaskOutput` / `TaskStop` follow `Bash`
|
|
332
|
+
// `TaskOutput` / `TaskStop` / `TaskList` follow `Bash`
|
|
333
333
|
for (const name of AGENT_BUILTIN_NAMES)
|
|
334
334
|
if (!listed.has(name))
|
|
335
335
|
offBuiltin(name);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EventLog } from "../conversations/event-log.js";
|
|
2
2
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
3
3
|
import { KernelEvents } from "../infra/events/kernel-events.js";
|
|
4
|
+
import { OutboxService } from "../infra/outbox/outbox.service.js";
|
|
4
5
|
import { type BackgroundTaskRow, BackgroundTaskStore } from "./store.js";
|
|
5
6
|
/** Where a task ends (as {@link BackgroundTaskStore.finish} takes it). */
|
|
6
7
|
export type BackgroundFinish = Parameters<BackgroundTaskStore["finish"]>[1];
|
|
@@ -19,7 +20,8 @@ export declare const finishedEventKey: (taskId: string) => string;
|
|
|
19
20
|
* task (two pollers, a poll and a stop) exactly one writes it. After the commit: the log's notify,
|
|
20
21
|
* the `changed: "background"` frame (to the owner and, for a sub-agent's task, the conversation
|
|
21
22
|
* that owns the sandbox, whose panel lists it too) and the `background_task.finished` domain event
|
|
22
|
-
* (`BackgroundWake` wakes an idle conversation; it lives in the runtime, above this module).
|
|
23
|
+
* (`BackgroundWake` wakes an idle conversation; it lives in the runtime, above this module). A
|
|
24
|
+
* finish that may wake the conversation also owes the ensure-run backstop in the transaction.
|
|
23
25
|
*
|
|
24
26
|
* Holds no lock and runs no sandbox command: the caller reads `lastLines` before.
|
|
25
27
|
*/
|
|
@@ -28,7 +30,8 @@ export declare class BackgroundTaskFinisher {
|
|
|
28
30
|
private readonly eventLog;
|
|
29
31
|
private readonly events;
|
|
30
32
|
readonly txHost: TransactionHost;
|
|
31
|
-
|
|
33
|
+
private readonly outbox;
|
|
34
|
+
constructor(store: Pick<BackgroundTaskStore, "finish">, eventLog: EventLog, events: KernelEvents, txHost: TransactionHost, outbox: Pick<OutboxService, "add">);
|
|
32
35
|
/**
|
|
33
36
|
* Finishes `task` as `to` with its last output lines (cut to their last 4 000 characters);
|
|
34
37
|
* `reported` when a tool call already told the model in its run. False (nothing written) when the
|
|
@@ -13,6 +13,8 @@ import { afterCommit } from "../infra/database/after-commit.js";
|
|
|
13
13
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
14
14
|
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
15
15
|
import { KernelEvents } from "../infra/events/kernel-events.js";
|
|
16
|
+
import { OutboxService } from "../infra/outbox/outbox.service.js";
|
|
17
|
+
import { oweEnsureRun } from "../runtime/run-jobs.js";
|
|
16
18
|
import { taskOutputFile } from "./launch.js";
|
|
17
19
|
import { LAST_LINES_MAX_CHARS } from "./session.js";
|
|
18
20
|
import { BackgroundTaskStore } from "./store.js";
|
|
@@ -25,7 +27,8 @@ export const finishedEventKey = (taskId) => `background_task_finished:${taskId}`
|
|
|
25
27
|
* task (two pollers, a poll and a stop) exactly one writes it. After the commit: the log's notify,
|
|
26
28
|
* the `changed: "background"` frame (to the owner and, for a sub-agent's task, the conversation
|
|
27
29
|
* that owns the sandbox, whose panel lists it too) and the `background_task.finished` domain event
|
|
28
|
-
* (`BackgroundWake` wakes an idle conversation; it lives in the runtime, above this module).
|
|
30
|
+
* (`BackgroundWake` wakes an idle conversation; it lives in the runtime, above this module). A
|
|
31
|
+
* finish that may wake the conversation also owes the ensure-run backstop in the transaction.
|
|
29
32
|
*
|
|
30
33
|
* Holds no lock and runs no sandbox command: the caller reads `lastLines` before.
|
|
31
34
|
*/
|
|
@@ -34,11 +37,13 @@ let BackgroundTaskFinisher = class BackgroundTaskFinisher {
|
|
|
34
37
|
eventLog;
|
|
35
38
|
events;
|
|
36
39
|
txHost;
|
|
37
|
-
|
|
40
|
+
outbox;
|
|
41
|
+
constructor(store, eventLog, events, txHost, outbox) {
|
|
38
42
|
this.store = store;
|
|
39
43
|
this.eventLog = eventLog;
|
|
40
44
|
this.events = events;
|
|
41
45
|
this.txHost = txHost;
|
|
46
|
+
this.outbox = outbox;
|
|
42
47
|
}
|
|
43
48
|
/**
|
|
44
49
|
* Finishes `task` as `to` with its last output lines (cut to their last 4 000 characters);
|
|
@@ -71,6 +76,11 @@ let BackgroundTaskFinisher = class BackgroundTaskFinisher {
|
|
|
71
76
|
},
|
|
72
77
|
},
|
|
73
78
|
]);
|
|
79
|
+
// a finish that may wake the conversation owes the ensure-run backstop with its event: the
|
|
80
|
+
// wake after the commit (`BackgroundWake`) may never happen (transactional outbox spec §6)
|
|
81
|
+
if (event && !reported && opts.stoppedBy === undefined) {
|
|
82
|
+
await oweEnsureRun(this.outbox, task.conversationId, event.seq, task.orgId);
|
|
83
|
+
}
|
|
74
84
|
const conversations = [...new Set([task.conversationId, task.sandboxConversationId])];
|
|
75
85
|
afterCommit(async () => {
|
|
76
86
|
if (event)
|
|
@@ -90,6 +100,7 @@ BackgroundTaskFinisher = __decorate([
|
|
|
90
100
|
__param(0, Inject(BackgroundTaskStore)),
|
|
91
101
|
__param(1, Inject(EventLog)),
|
|
92
102
|
__param(2, Inject(KernelEvents)),
|
|
93
|
-
__param(3, Inject(TransactionHost))
|
|
103
|
+
__param(3, Inject(TransactionHost)),
|
|
104
|
+
__param(4, Inject(OutboxService))
|
|
94
105
|
], BackgroundTaskFinisher);
|
|
95
106
|
export { BackgroundTaskFinisher };
|
|
@@ -70,7 +70,8 @@ export declare const GROUP_LAUNCHER: string;
|
|
|
70
70
|
* `setsid nohup sh -c 'timeout -s KILL <seconds> …'` and the sid is `$!`, the pid `setsid` started;
|
|
71
71
|
* elsewhere (macOS: no `setsid`, no `timeout`, no `pgrep -s`) {@link GROUP_LAUNCHER} runs it in a
|
|
72
72
|
* process group of its own, watched by the launcher, and writes the sid (the group id) itself,
|
|
73
|
-
* which the launch waits for (up to 10 s).
|
|
73
|
+
* which the launch waits for (up to 10 s). The script starts with `BACKGROUND_LAUNCH_LINE`, so a
|
|
74
|
+
* local device, which kills what any other exec leaves running, leaves the task alone. An
|
|
74
75
|
* environment without one of the needed programs fails with a readable error on stderr and exit
|
|
75
76
|
* code 127, before anything starts. `id` must be a task id and `seconds` a positive integer (both
|
|
76
77
|
* go into the script unquoted).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
|
-
import { DEFAULT_SANDBOX_ROOTS } from "@capybara-hq/plugin-sdk";
|
|
2
|
+
import { BACKGROUND_LAUNCH_LINE, DEFAULT_SANDBOX_ROOTS } from "@capybara-hq/plugin-sdk";
|
|
3
3
|
/**
|
|
4
4
|
* Launching a background Bash task (spec 2026-11-05-background-bash-design §4.2): the task id, the
|
|
5
5
|
* one short exec that starts the command detached from the exec, and the model-visible result.
|
|
@@ -112,7 +112,8 @@ export const GROUP_LAUNCHER = [
|
|
|
112
112
|
* `setsid nohup sh -c 'timeout -s KILL <seconds> …'` and the sid is `$!`, the pid `setsid` started;
|
|
113
113
|
* elsewhere (macOS: no `setsid`, no `timeout`, no `pgrep -s`) {@link GROUP_LAUNCHER} runs it in a
|
|
114
114
|
* process group of its own, watched by the launcher, and writes the sid (the group id) itself,
|
|
115
|
-
* which the launch waits for (up to 10 s).
|
|
115
|
+
* which the launch waits for (up to 10 s). The script starts with `BACKGROUND_LAUNCH_LINE`, so a
|
|
116
|
+
* local device, which kills what any other exec leaves running, leaves the task alone. An
|
|
116
117
|
* environment without one of the needed programs fails with a readable error on stderr and exit
|
|
117
118
|
* code 127, before anything starts. `id` must be a task id and `seconds` a positive integer (both
|
|
118
119
|
* go into the script unquoted).
|
|
@@ -127,6 +128,8 @@ export function launchScript(id, command, seconds) {
|
|
|
127
128
|
const t = `${TASKS_DIR}/${id}`;
|
|
128
129
|
const need = (list) => `for c in ${list.join(" ")}; do command -v "$c" >/dev/null 2>&1 || { echo "Background tasks need ${list.join(", ")} in this environment; $c is missing." >&2; exit 127; }; done`;
|
|
129
130
|
return [
|
|
131
|
+
// first: a local device kills what an exec leaves running, except a launch's detached task
|
|
132
|
+
BACKGROUND_LAUNCH_LINE,
|
|
130
133
|
"set -e",
|
|
131
134
|
SESSION_MODE_SCRIPT,
|
|
132
135
|
`if [ "$pg" = -s ]; then ${need(REQUIRED_SESSION)}; else ${need(REQUIRED_GROUP)}; fi`,
|
|
@@ -137,6 +137,14 @@ export declare class BackgroundTaskStore {
|
|
|
137
137
|
runningStarted(): Promise<BackgroundTaskRow[]>;
|
|
138
138
|
/** The running tasks one conversation owns (not those of its sub-agents), oldest first. */
|
|
139
139
|
runningOwnedBy(conversationId: string): Promise<BackgroundTaskRow[]>;
|
|
140
|
+
/**
|
|
141
|
+
* The finished tasks one conversation owns (not those of its sub-agents), the most recently
|
|
142
|
+
* finished first, at most `limit` of them, with how many it owns in all (`TaskList`).
|
|
143
|
+
*/
|
|
144
|
+
finishedOwnedBy(conversationId: string, limit: number): Promise<{
|
|
145
|
+
rows: BackgroundTaskRow[];
|
|
146
|
+
total: number;
|
|
147
|
+
}>;
|
|
140
148
|
/** The running tasks of one root conversation's tree (what `maxTasks` limits). */
|
|
141
149
|
countRunning(sandboxConversationId: string): Promise<number>;
|
|
142
150
|
/** The tasks owned by any of the conversations, newest first. */
|
package/dist/background/store.js
CHANGED
|
@@ -258,6 +258,30 @@ let BackgroundTaskStore = class BackgroundTaskStore {
|
|
|
258
258
|
.execute();
|
|
259
259
|
return rows.map(toRow);
|
|
260
260
|
}
|
|
261
|
+
/**
|
|
262
|
+
* The finished tasks one conversation owns (not those of its sub-agents), the most recently
|
|
263
|
+
* finished first, at most `limit` of them, with how many it owns in all (`TaskList`).
|
|
264
|
+
*/
|
|
265
|
+
async finishedOwnedBy(conversationId, limit) {
|
|
266
|
+
const [rows, count] = await Promise.all([
|
|
267
|
+
this.db
|
|
268
|
+
.selectFrom("background_tasks")
|
|
269
|
+
.selectAll()
|
|
270
|
+
.where("conversation_id", "=", conversationId)
|
|
271
|
+
.where("status", "<>", "running")
|
|
272
|
+
.orderBy("finished_at", "desc")
|
|
273
|
+
.orderBy("id", "desc")
|
|
274
|
+
.limit(limit)
|
|
275
|
+
.execute(),
|
|
276
|
+
this.db
|
|
277
|
+
.selectFrom("background_tasks")
|
|
278
|
+
.select((eb) => eb.fn.countAll().as("n"))
|
|
279
|
+
.where("conversation_id", "=", conversationId)
|
|
280
|
+
.where("status", "<>", "running")
|
|
281
|
+
.executeTakeFirstOrThrow(),
|
|
282
|
+
]);
|
|
283
|
+
return { rows: rows.map(toRow), total: Number(count.n) };
|
|
284
|
+
}
|
|
261
285
|
/** The running tasks of one root conversation's tree (what `maxTasks` limits). */
|
|
262
286
|
async countRunning(sandboxConversationId) {
|
|
263
287
|
const r = await this.db
|
|
@@ -5,12 +5,13 @@ import { type ClientBuildSummary, ClientBuilds } from "../client/client-builds.s
|
|
|
5
5
|
import { PluginGuides, type RenderedSetupGuide } from "../extensions/plugin-guides.js";
|
|
6
6
|
import { PluginIcons } from "../extensions/plugin-icons.js";
|
|
7
7
|
import { type Principal } from "../identity/principal.js";
|
|
8
|
-
import { AdminCatalogGuideQuery, CatalogItemsQuery, CatalogUpdateBody, CatalogUpdatePreviewBody, CatalogDisabledBody as DisabledBody, CatalogGitImportBody as GitBody, CatalogNpmImportBody as NpmBody, CatalogScopeBody as ScopeBody, CatalogScopePreviewBody as ScopePreviewBody, CatalogShownBody as ShownBody } from "./admin-catalog.schemas.js";
|
|
8
|
+
import { AdminCatalogGuideQuery, CatalogImportUpdateBody, CatalogItemsQuery, CatalogUpdateBody, CatalogUpdatePreviewBody, CatalogDisabledBody as DisabledBody, CatalogGitImportBody as GitBody, CatalogNpmImportBody as NpmBody, CatalogScopeBody as ScopeBody, CatalogScopePreviewBody as ScopePreviewBody, CatalogShownBody as ShownBody } from "./admin-catalog.schemas.js";
|
|
9
9
|
import { AppearanceApplyBody } from "./appearance.schemas.js";
|
|
10
10
|
import { type AppearanceResult, AppearanceService } from "./appearance.service.js";
|
|
11
11
|
import { type CatalogItemDetail, type CatalogItemView, CatalogService, type PermissionsMismatch } from "./catalog.service.js";
|
|
12
12
|
import { CatalogScopeService, type ScopePreview } from "./catalog-scope.service.js";
|
|
13
13
|
import { OrgCatalogService } from "./org-catalog.service.js";
|
|
14
|
+
import { PlatformImportUpdate, type PlatformImportUpdateResult } from "./platform-import-update.js";
|
|
14
15
|
import { type PluginConfirmResult, PluginImport, type PluginReview } from "./plugin-import.js";
|
|
15
16
|
import { PlatformPluginUpdater, type PlatformUpdatePreview, type PlatformUpdateResult } from "./plugin-upgrade.js";
|
|
16
17
|
declare const ConfirmBody: z.ZodObject<{
|
|
@@ -41,11 +42,12 @@ export declare class AdminCatalogController {
|
|
|
41
42
|
private readonly orgCatalog;
|
|
42
43
|
private readonly scope;
|
|
43
44
|
private readonly updater;
|
|
45
|
+
private readonly importUpdate;
|
|
44
46
|
private readonly icons;
|
|
45
47
|
private readonly appearance;
|
|
46
48
|
private readonly clientBuilds;
|
|
47
49
|
private readonly guides;
|
|
48
|
-
constructor(catalog: CatalogService, pluginImport: PluginImport, orgCatalog: OrgCatalogService, scope: CatalogScopeService, updater: PlatformPluginUpdater, icons: PluginIcons, appearance: AppearanceService, clientBuilds: ClientBuilds, guides: PluginGuides);
|
|
50
|
+
constructor(catalog: CatalogService, pluginImport: PluginImport, orgCatalog: OrgCatalogService, scope: CatalogScopeService, updater: PlatformPluginUpdater, importUpdate: PlatformImportUpdate, icons: PluginIcons, appearance: AppearanceService, clientBuilds: ClientBuilds, guides: PluginGuides);
|
|
49
51
|
/**
|
|
50
52
|
* Prepares the import of an uploaded plugin (an npm-pack tgz as the raw body,
|
|
51
53
|
* `application/octet-stream`, at most `packages.maxBytes`): reads and checks the whole plugin
|
|
@@ -108,6 +110,23 @@ export declare class AdminCatalogController {
|
|
|
108
110
|
* is an unknown field (400 `validation_failed`).
|
|
109
111
|
*/
|
|
110
112
|
confirm(principal: Principal, stagingId: string, body: z.infer<typeof ConfirmBody>): Promise<PluginConfirmResult>;
|
|
113
|
+
/**
|
|
114
|
+
* What confirming a staged new version of an installed platform plugin would do as the platform
|
|
115
|
+
* update (`PlatformImportUpdate`, the one 更新到 wizard): the update preview of the staged
|
|
116
|
+
* version, nothing written (cancelling the wizard leaves only the staging row). Not a platform
|
|
117
|
+
* plugin yet -> 409 `plugin.upgrade_target_invalid` (reason `not_installed`); staging missing ->
|
|
118
|
+
* 404 `plugin.staging_not_found`; otherwise as `items/:id/update/preview`.
|
|
119
|
+
*/
|
|
120
|
+
importUpdatePreview(stagingId: string): Promise<PlatformUpdatePreview>;
|
|
121
|
+
/**
|
|
122
|
+
* Imports the staged version and updates the platform plugin to it, confirmed with the import
|
|
123
|
+
* review's `reviewHash` and the update preview's `diffHash` (201 `{ item, update }`). Stale review
|
|
124
|
+
* -> 409 `plugin.review_stale`, stale preview -> 409 `plugin.upgrade_stale`, another update
|
|
125
|
+
* running -> 409 `plugin.install_in_progress`: nothing written. The update failing after the
|
|
126
|
+
* import -> 409 `plugin.imported_not_updated` (the version stays in the catalog, the platform on
|
|
127
|
+
* its version, the extension's approval put back; details name the cause).
|
|
128
|
+
*/
|
|
129
|
+
importAndUpdate(principal: Principal, stagingId: string, body: z.infer<typeof CatalogImportUpdateBody>): Promise<PlatformImportUpdateResult>;
|
|
111
130
|
/**
|
|
112
131
|
* The item list (`includeDeleted=true` includes deleted items). Paging: `limit` (default 200, at
|
|
113
132
|
* most 1000) and `offset`; `nextOffset` is the next page's offset, null when there is none.
|
|
@@ -16,13 +16,14 @@ import { PluginIcons } from "../extensions/plugin-icons.js";
|
|
|
16
16
|
import { CurrentPrincipal, patTokenId, requireUser, SuperAdmin, } from "../identity/principal.js";
|
|
17
17
|
import { createZodDto } from "../infra/validation/create-zod-dto.js";
|
|
18
18
|
import { ZBody, ZQuery } from "../infra/validation/zod-params.js";
|
|
19
|
-
import { AdminCatalogGuideQuery, CatalogItemsQuery, CatalogUpdateBody, CatalogUpdatePreviewBody, CatalogDisabledBody as DisabledBody, CatalogGitImportBody as GitBody, CatalogHash as Hash, CatalogNpmImportBody as NpmBody, CatalogScopeOrgs as Orgs, CatalogScope as Scope, CatalogScopeBody as ScopeBody, CatalogScopePreviewBody as ScopePreviewBody, CatalogShownBody as ShownBody, } from "./admin-catalog.schemas.js";
|
|
19
|
+
import { AdminCatalogGuideQuery, CatalogImportUpdateBody, CatalogItemsQuery, CatalogUpdateBody, CatalogUpdatePreviewBody, CatalogDisabledBody as DisabledBody, CatalogGitImportBody as GitBody, CatalogHash as Hash, CatalogNpmImportBody as NpmBody, CatalogScopeOrgs as Orgs, CatalogScope as Scope, CatalogScopeBody as ScopeBody, CatalogScopePreviewBody as ScopePreviewBody, CatalogShownBody as ShownBody, } from "./admin-catalog.schemas.js";
|
|
20
20
|
import { AppearanceApplyBody } from "./appearance.schemas.js";
|
|
21
21
|
import { AppearanceService, suggestedAppearanceOf, } from "./appearance.service.js";
|
|
22
22
|
import { CatalogService, } from "./catalog.service.js";
|
|
23
23
|
import { CatalogScopeService } from "./catalog-scope.service.js";
|
|
24
24
|
import { sendCatalogIcon } from "./org-catalog.controller.js";
|
|
25
25
|
import { OrgCatalogService } from "./org-catalog.service.js";
|
|
26
|
+
import { PlatformImportUpdate } from "./platform-import-update.js";
|
|
26
27
|
import { PluginImport } from "./plugin-import.js";
|
|
27
28
|
import { PlatformPluginUpdater, } from "./plugin-upgrade.js";
|
|
28
29
|
const ConfirmBody = z
|
|
@@ -66,6 +67,8 @@ class CatalogUpdatePreviewBodyDto extends createZodDto(CatalogUpdatePreviewBody,
|
|
|
66
67
|
}
|
|
67
68
|
class CatalogUpdateBodyDto extends createZodDto(CatalogUpdateBody, "CatalogUpdateBody") {
|
|
68
69
|
}
|
|
70
|
+
class CatalogImportUpdateBodyDto extends createZodDto(CatalogImportUpdateBody, "CatalogImportUpdateBody") {
|
|
71
|
+
}
|
|
69
72
|
class AppearanceApplyBodyDto extends createZodDto(AppearanceApplyBody, "AppearanceApplyBody") {
|
|
70
73
|
}
|
|
71
74
|
/**
|
|
@@ -80,16 +83,18 @@ let AdminCatalogController = class AdminCatalogController {
|
|
|
80
83
|
orgCatalog;
|
|
81
84
|
scope;
|
|
82
85
|
updater;
|
|
86
|
+
importUpdate;
|
|
83
87
|
icons;
|
|
84
88
|
appearance;
|
|
85
89
|
clientBuilds;
|
|
86
90
|
guides;
|
|
87
|
-
constructor(catalog, pluginImport, orgCatalog, scope, updater, icons, appearance, clientBuilds, guides) {
|
|
91
|
+
constructor(catalog, pluginImport, orgCatalog, scope, updater, importUpdate, icons, appearance, clientBuilds, guides) {
|
|
88
92
|
this.catalog = catalog;
|
|
89
93
|
this.pluginImport = pluginImport;
|
|
90
94
|
this.orgCatalog = orgCatalog;
|
|
91
95
|
this.scope = scope;
|
|
92
96
|
this.updater = updater;
|
|
97
|
+
this.importUpdate = importUpdate;
|
|
93
98
|
this.icons = icons;
|
|
94
99
|
this.appearance = appearance;
|
|
95
100
|
this.clientBuilds = clientBuilds;
|
|
@@ -169,6 +174,28 @@ let AdminCatalogController = class AdminCatalogController {
|
|
|
169
174
|
...(body.orgs !== undefined && { orgs: body.orgs }),
|
|
170
175
|
}, actorOpts(actor));
|
|
171
176
|
}
|
|
177
|
+
/**
|
|
178
|
+
* What confirming a staged new version of an installed platform plugin would do as the platform
|
|
179
|
+
* update (`PlatformImportUpdate`, the one 更新到 wizard): the update preview of the staged
|
|
180
|
+
* version, nothing written (cancelling the wizard leaves only the staging row). Not a platform
|
|
181
|
+
* plugin yet -> 409 `plugin.upgrade_target_invalid` (reason `not_installed`); staging missing ->
|
|
182
|
+
* 404 `plugin.staging_not_found`; otherwise as `items/:id/update/preview`.
|
|
183
|
+
*/
|
|
184
|
+
importUpdatePreview(stagingId) {
|
|
185
|
+
return this.importUpdate.preview(stagingId);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Imports the staged version and updates the platform plugin to it, confirmed with the import
|
|
189
|
+
* review's `reviewHash` and the update preview's `diffHash` (201 `{ item, update }`). Stale review
|
|
190
|
+
* -> 409 `plugin.review_stale`, stale preview -> 409 `plugin.upgrade_stale`, another update
|
|
191
|
+
* running -> 409 `plugin.install_in_progress`: nothing written. The update failing after the
|
|
192
|
+
* import -> 409 `plugin.imported_not_updated` (the version stays in the catalog, the platform on
|
|
193
|
+
* its version, the extension's approval put back; details name the cause).
|
|
194
|
+
*/
|
|
195
|
+
importAndUpdate(principal, stagingId, body) {
|
|
196
|
+
const actor = requireUser(principal);
|
|
197
|
+
return this.importUpdate.confirm(actor.account.id, stagingId, body, actorOpts(actor));
|
|
198
|
+
}
|
|
172
199
|
/**
|
|
173
200
|
* The item list (`includeDeleted=true` includes deleted items). Paging: `limit` (default 200, at
|
|
174
201
|
* most 1000) and `offset`; `nextOffset` is the next page's offset, null when there is none.
|
|
@@ -367,6 +394,17 @@ __decorate([
|
|
|
367
394
|
__param(1, Param("stagingId")),
|
|
368
395
|
__param(2, ZBody(CatalogImportConfirmBody))
|
|
369
396
|
], AdminCatalogController.prototype, "confirm", null);
|
|
397
|
+
__decorate([
|
|
398
|
+
Get("imports/:stagingId/update-preview"),
|
|
399
|
+
__param(0, Param("stagingId"))
|
|
400
|
+
], AdminCatalogController.prototype, "importUpdatePreview", null);
|
|
401
|
+
__decorate([
|
|
402
|
+
Post("imports/:stagingId/update"),
|
|
403
|
+
HttpCode(201),
|
|
404
|
+
__param(0, CurrentPrincipal()),
|
|
405
|
+
__param(1, Param("stagingId")),
|
|
406
|
+
__param(2, ZBody(CatalogImportUpdateBodyDto))
|
|
407
|
+
], AdminCatalogController.prototype, "importAndUpdate", null);
|
|
370
408
|
__decorate([
|
|
371
409
|
Get("items"),
|
|
372
410
|
__param(0, ZQuery(CatalogItemsQueryDto))
|
|
@@ -457,9 +495,10 @@ AdminCatalogController = __decorate([
|
|
|
457
495
|
__param(2, Inject(OrgCatalogService)),
|
|
458
496
|
__param(3, Inject(CatalogScopeService)),
|
|
459
497
|
__param(4, Inject(PlatformPluginUpdater)),
|
|
460
|
-
__param(5, Inject(
|
|
461
|
-
__param(6, Inject(
|
|
462
|
-
__param(7, Inject(
|
|
463
|
-
__param(8, Inject(
|
|
498
|
+
__param(5, Inject(PlatformImportUpdate)),
|
|
499
|
+
__param(6, Inject(PluginIcons)),
|
|
500
|
+
__param(7, Inject(AppearanceService)),
|
|
501
|
+
__param(8, Inject(ClientBuilds)),
|
|
502
|
+
__param(9, Inject(PluginGuides))
|
|
464
503
|
], AdminCatalogController);
|
|
465
504
|
export { AdminCatalogController };
|