@capybara-hq/kernel 0.1.0-rc.19 → 0.1.0-rc.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/bootstrap.json +25 -25
  2. package/dist/admin/admin-agents.controller.d.ts +28 -0
  3. package/dist/admin/admin-agents.controller.js +79 -0
  4. package/dist/admin/admin-connectors.controller.d.ts +29 -0
  5. package/dist/admin/admin-connectors.controller.js +79 -0
  6. package/dist/admin/admin-items.schemas.d.ts +42 -0
  7. package/dist/admin/admin-items.schemas.js +48 -0
  8. package/dist/admin/admin.controller.d.ts +11 -20
  9. package/dist/admin/admin.controller.js +28 -34
  10. package/dist/admin/admin.module.d.ts +4 -1
  11. package/dist/admin/admin.module.js +50 -4
  12. package/dist/admin/admin.schemas.d.ts +4 -0
  13. package/dist/admin/admin.schemas.js +4 -1
  14. package/dist/admin/audit.controller.d.ts +14 -0
  15. package/dist/admin/audit.controller.js +42 -0
  16. package/dist/admin/audit.schemas.d.ts +8 -0
  17. package/dist/admin/audit.schemas.js +17 -0
  18. package/dist/admin/health.service.d.ts +104 -0
  19. package/dist/admin/health.service.js +246 -0
  20. package/dist/admin/overview.controller.d.ts +31 -0
  21. package/dist/admin/overview.controller.js +78 -0
  22. package/dist/admin/overview.schemas.d.ts +8 -0
  23. package/dist/admin/overview.schemas.js +13 -0
  24. package/dist/admin/overview.service.d.ts +112 -0
  25. package/dist/admin/overview.service.js +223 -0
  26. package/dist/admin/platform-audit.service.d.ts +41 -0
  27. package/dist/admin/platform-audit.service.js +70 -0
  28. package/dist/admin/usage.service.d.ts +149 -0
  29. package/dist/admin/usage.service.js +321 -0
  30. package/dist/agents/admin-agents.d.ts +92 -0
  31. package/dist/agents/admin-agents.js +170 -0
  32. package/dist/agents/agents.module.d.ts +4 -3
  33. package/dist/agents/agents.module.js +7 -3
  34. package/dist/agents/agents.service.d.ts +41 -3
  35. package/dist/agents/agents.service.js +113 -27
  36. package/dist/agents/definition.d.ts +16 -0
  37. package/dist/agents/definition.js +32 -2
  38. package/dist/agents/org-templates.js +4 -0
  39. package/dist/background/launch.d.ts +1 -1
  40. package/dist/background/launch.js +3 -3
  41. package/dist/background/tasks.service.d.ts +35 -3
  42. package/dist/background/tasks.service.js +91 -36
  43. package/dist/catalog/catalog.module.js +8 -2
  44. package/dist/channels/channels.module.js +11 -2
  45. package/dist/channels/supervisor.d.ts +2 -0
  46. package/dist/channels/supervisor.js +4 -0
  47. package/dist/conversations/events.js +1 -1
  48. package/dist/conversations/titles.js +4 -8
  49. package/dist/db/kernel-schema.d.ts +8 -1
  50. package/dist/devices/devices.module.js +5 -2
  51. package/dist/errors.d.ts +22 -2
  52. package/dist/errors.js +22 -2
  53. package/dist/evals/evals.module.js +11 -2
  54. package/dist/extensions/permission-view.js +3 -3
  55. package/dist/http/api.module.js +10 -1
  56. package/dist/identity/settings.js +3 -2
  57. package/dist/identity/write-actor.d.ts +11 -0
  58. package/dist/identity/write-actor.js +7 -0
  59. package/dist/inbox/inbox.service.d.ts +2 -1
  60. package/dist/inbox/platform-inbox.service.d.ts +7 -1
  61. package/dist/inbox/platform-inbox.service.js +20 -2
  62. package/dist/infra/presence/presence.module.d.ts +6 -0
  63. package/dist/infra/presence/presence.module.js +22 -0
  64. package/dist/infra/presence/replica-presence.d.ts +87 -0
  65. package/dist/infra/presence/replica-presence.js +189 -0
  66. package/dist/kernel.module.js +3 -0
  67. package/dist/lifecycle/kernel-lifecycle.d.ts +3 -1
  68. package/dist/lifecycle/kernel-lifecycle.js +17 -3
  69. package/dist/local-devices/local-device-gateway.d.ts +6 -0
  70. package/dist/local-devices/local-device-gateway.js +12 -0
  71. package/dist/overrides.d.ts +7 -1
  72. package/dist/overrides.js +4 -0
  73. package/dist/platform/exclusions.js +15 -0
  74. package/dist/platform/operation.d.ts +1 -1
  75. package/dist/platform/operation.js +1 -1
  76. package/dist/platform/ops/admin-items.ops.d.ts +37 -0
  77. package/dist/platform/ops/admin-items.ops.js +278 -0
  78. package/dist/platform/ops/admin.ops.d.ts +10 -10
  79. package/dist/platform/ops/admin.ops.js +111 -42
  80. package/dist/platform/ops/agent-skills.ops.d.ts +29 -3
  81. package/dist/platform/ops/agent-skills.ops.js +290 -7
  82. package/dist/platform/ops/inbox.ops.js +7 -4
  83. package/dist/platform/ops/platform.ops.js +1 -1
  84. package/dist/platform/ops/skills.ops.js +1 -57
  85. package/dist/platform/platform-ops.module.d.ts +2 -1
  86. package/dist/platform/platform-ops.module.js +5 -0
  87. package/dist/platform/route-schemas.js +8 -0
  88. package/dist/roles/gateway-role.d.ts +4 -0
  89. package/dist/roles/gateway-role.js +8 -0
  90. package/dist/runtime/run-jobs.js +4 -2
  91. package/dist/sandbox/sandbox-file-reader.d.ts +35 -0
  92. package/dist/sandbox/sandbox-file-reader.js +98 -0
  93. package/dist/skills/agent-skills.controller.d.ts +48 -0
  94. package/dist/skills/agent-skills.controller.js +131 -0
  95. package/dist/skills/agent-skills.service.d.ts +262 -0
  96. package/dist/skills/agent-skills.service.js +996 -0
  97. package/dist/skills/catalog.d.ts +8 -6
  98. package/dist/skills/catalog.js +8 -4
  99. package/dist/skills/changes.controller.d.ts +5 -22
  100. package/dist/skills/changes.controller.js +7 -55
  101. package/dist/skills/changes.service.d.ts +69 -115
  102. package/dist/skills/changes.service.js +249 -599
  103. package/dist/skills/conversation-catalog.d.ts +53 -0
  104. package/dist/skills/conversation-catalog.js +149 -0
  105. package/dist/skills/invocation-keys.d.ts +1 -1
  106. package/dist/skills/invocation-keys.js +1 -1
  107. package/dist/skills/package.d.ts +0 -5
  108. package/dist/skills/package.js +0 -14
  109. package/dist/skills/skills.controller.js +1 -10
  110. package/dist/skills/skills.module.js +15 -2
  111. package/dist/skills/skills.schemas.d.ts +11 -15
  112. package/dist/skills/skills.schemas.js +27 -20
  113. package/dist/skills/skills.service.d.ts +37 -30
  114. package/dist/skills/skills.service.js +107 -59
  115. package/dist/skills/usable.d.ts +4 -3
  116. package/dist/skills/usable.js +13 -4
  117. package/dist/tools/admin-connectors.d.ts +69 -0
  118. package/dist/tools/admin-connectors.js +135 -0
  119. package/dist/tools/builtin-names.d.ts +9 -14
  120. package/dist/tools/builtin-names.js +13 -22
  121. package/dist/tools/builtins/builtin-tools.d.ts +2 -3
  122. package/dist/tools/builtins/builtin-tools.js +21 -26
  123. package/dist/tools/builtins/sandbox/bash.js +2 -2
  124. package/dist/tools/builtins/skill-load.js +1 -0
  125. package/dist/tools/connectors.controller.d.ts +5 -1
  126. package/dist/tools/connectors.controller.js +17 -3
  127. package/dist/tools/connectors.service.d.ts +20 -1
  128. package/dist/tools/connectors.service.js +61 -0
  129. package/dist/tools/legacy-keys.js +0 -1
  130. package/dist/tools/org-tool-switches.d.ts +3 -2
  131. package/dist/tools/org-tool-switches.js +4 -4
  132. package/dist/tools/policy.d.ts +7 -9
  133. package/dist/tools/policy.js +11 -22
  134. package/dist/tools/tools.module.js +3 -0
  135. package/package.json +1 -1
  136. package/src/migrations/0109_audit_platform_idx.sql +5 -0
  137. package/src/migrations/0110_usage_time_idx.sql +8 -0
  138. package/src/migrations/0111_agent_skill_sharing.sql +22 -0
  139. package/src/migrations/0112_skill_share_requests.sql +4 -0
  140. package/dist/tools/builtins/skill-write.d.ts +0 -59
  141. package/dist/tools/builtins/skill-write.js +0 -244
@@ -0,0 +1,278 @@
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 { ToolError } from "@capybara-hq/plugin-sdk";
11
+ import { Inject, Injectable } from "@nestjs/common";
12
+ import { z } from "zod";
13
+ import { AdminAgentListQuery, AdminConnectorListQuery, AgentIdParams, ConnectorIdParams, ConnectorStatusBody, } from "../../admin/admin-items.schemas.js";
14
+ import { AdminAgents } from "../../agents/admin-agents.js";
15
+ import { AgentsService } from "../../agents/agents.service.js";
16
+ import { ApiError } from "../../errors.js";
17
+ import { KernelDb } from "../../infra/database/kernel-db.js";
18
+ import { MembersService } from "../../orgs/members.service.js";
19
+ import { rootConversationOf } from "../../runtime/subagents/child.js";
20
+ import { AdminConnectors } from "../../tools/admin-connectors.js";
21
+ import { ConnectorsService } from "../../tools/connectors.service.js";
22
+ import { defineOperation } from "../operation.js";
23
+ import { PlatformOperations } from "../registry.js";
24
+ import { viaAgent } from "./errors.js";
25
+ import { named, orElse } from "./summary.js";
26
+ /**
27
+ * Refusal of an item another org owns: the tool's results enter this org's event log, where
28
+ * another org's items do not belong (Platform tool spec §6.1, §14.5 item 1).
29
+ */
30
+ export const OTHER_ORG_ITEM = "This belongs to another organization; the Platform tool acts only on this conversation's organization. Use the admin console.";
31
+ const AgentIdInput = AgentIdParams.strict();
32
+ const ConnectorIdInput = ConnectorIdParams.strict();
33
+ /**
34
+ * The super admin's agent and connector operations of the `Platform` tool (admin agents and
35
+ * connectors spec §4.5): the admin console's views and writes, run through the same services as
36
+ * the routes. Unlike the console they cover only the conversation's org: lists filter to it, and
37
+ * reads and writes of another org's item are refused (Platform tool spec §6.1). The owner transfer
38
+ * is excluded (human-only, as the org's own transfer route).
39
+ */
40
+ let AdminItemsOperations = class AdminItemsOperations {
41
+ registry;
42
+ adminAgents;
43
+ agents;
44
+ adminConnectors;
45
+ connectors;
46
+ members;
47
+ kdb;
48
+ constructor(registry, adminAgents, agents, adminConnectors, connectors, members, kdb) {
49
+ this.registry = registry;
50
+ this.adminAgents = adminAgents;
51
+ this.agents = agents;
52
+ this.adminConnectors = adminConnectors;
53
+ this.connectors = connectors;
54
+ this.members = members;
55
+ this.kdb = kdb;
56
+ }
57
+ /** The agent's admin detail when it is the conversation org's; else {@link OTHER_ORG_ITEM}. */
58
+ async agentOf(agentId, ctx) {
59
+ const agent = await this.adminAgents.get(agentId);
60
+ if (agent.orgId !== ctx.orgId)
61
+ throw new ToolError(OTHER_ORG_ITEM);
62
+ return agent;
63
+ }
64
+ /** The connector's admin detail when it is the conversation org's; else {@link OTHER_ORG_ITEM}. */
65
+ async connectorOf(connectorId, ctx) {
66
+ const connector = await this.adminConnectors.get(connectorId);
67
+ if (connector.orgId !== ctx.orgId)
68
+ throw new ToolError(OTHER_ORG_ITEM);
69
+ return connector;
70
+ }
71
+ /** A precheck from a read: its `ApiError` code, or `notFound` for another org's item. */
72
+ async precheck(read, notFound) {
73
+ try {
74
+ await read();
75
+ return { ok: true };
76
+ }
77
+ catch (e) {
78
+ if (e instanceof ToolError)
79
+ return { ok: false, code: notFound, message: e.message };
80
+ if (e instanceof ApiError)
81
+ return { ok: false, code: e.code, message: e.message };
82
+ throw e;
83
+ }
84
+ }
85
+ onModuleInit() {
86
+ this.registry.register([
87
+ defineOperation({
88
+ id: "admin.agents-list",
89
+ description: "List this org's agents as the admin console shows them (super admin): private ones too, with owner, visibility, whether the agent needs a new owner and the template it was created from. q searches the name; pages by limit (default 50), pass the returned next as after. Other orgs' agents are only in the admin console.",
90
+ input: AdminAgentListQuery.pick({ q: true, after: true, limit: true }).strict(),
91
+ example: { limit: 50 },
92
+ authz: { superAdmin: true },
93
+ mirrors: ["GET /api/v1/admin/agents"],
94
+ confirm: "read",
95
+ run: (input, ctx) => this.adminAgents.list({ ...input, orgId: ctx.orgId }),
96
+ }),
97
+ defineOperation({
98
+ id: "admin.agent-get",
99
+ description: "Read one agent of this org as the admin console shows it (super admin): its definition with the instructions in full, members, profile with quick action labels, versions count, the skills and connectors it uses by name. Never its conversations or credentials.",
100
+ input: AgentIdInput,
101
+ example: { agentId: "7c1a5b0e-9a53-4c6b-8d64-2f5a1b0c3e77" },
102
+ authz: { superAdmin: true },
103
+ mirrors: ["GET /api/v1/admin/agents/:agentId"],
104
+ confirm: "read",
105
+ errors: [{ code: "agent.not_found", next: "Check the agent id with admin.agents-list." }],
106
+ run: async (input, ctx) => ({ agent: await this.agentOf(input.agentId, ctx) }),
107
+ }),
108
+ defineOperation({
109
+ id: "admin.agent-delete",
110
+ description: "Delete an agent of this org on the platform's behalf (super admin), whoever owns it: its conversations stay readable but it can no longer be used, its eval runs stop and its pending skill changes are cancelled. The org's audit log records that the platform acted. The agent you are running as cannot be deleted.",
111
+ input: AgentIdInput,
112
+ example: { agentId: "7c1a5b0e-9a53-4c6b-8d64-2f5a1b0c3e77" },
113
+ authz: { superAdmin: true },
114
+ mirrors: ["DELETE /api/v1/admin/agents/:agentId"],
115
+ confirm: "platform",
116
+ errors: [
117
+ { code: "agent.not_found", next: "Check the agent id with admin.agents-list." },
118
+ {
119
+ code: "agent.delete_current",
120
+ next: "This is the agent you are running as: ask the person to delete it in the admin console, or delete a different agent.",
121
+ },
122
+ ],
123
+ precheck: async (i, ctx) => {
124
+ // the run's agent is the root conversation's: a sub-agent runs under its parent's agent
125
+ const rootId = await rootConversationOf(this.kdb.db, ctx.conversationId);
126
+ const root = await this.kdb.db
127
+ .selectFrom("conversations")
128
+ .select("agent_id")
129
+ .where("id", "=", rootId)
130
+ .executeTakeFirst();
131
+ if (i.agentId === ctx.agentId || i.agentId === root?.agent_id) {
132
+ return {
133
+ ok: false,
134
+ code: "agent.delete_current",
135
+ message: "The agent you are running as cannot be deleted from here.",
136
+ };
137
+ }
138
+ return this.precheck(() => this.agentOf(i.agentId, ctx), "agent.not_found");
139
+ },
140
+ summary: async (i, ctx) => {
141
+ const n = await orElse(async () => named((await this.agentOf(i.agentId, ctx)).name), i.agentId);
142
+ return {
143
+ zh: `以平台身份删除智能体「${n}」;它的对话仍可查看,但不能再使用`,
144
+ en: `Delete agent "${n}" on the platform's behalf; its conversations stay readable but it can no longer be used`,
145
+ };
146
+ },
147
+ run: async (input, ctx) => {
148
+ await this.agentOf(input.agentId, ctx);
149
+ await this.agents.softDeleteAsPlatform(input.agentId, { accountId: ctx.actorAccountId }, viaAgent("admin.agent-delete", ctx));
150
+ return { id: input.agentId, deleted: true };
151
+ },
152
+ }),
153
+ defineOperation({
154
+ id: "admin.connectors-list",
155
+ description: "List this org's connectors as the admin console shows them (super admin): name, protocol, status, tool count, who created it and from which template. Never an endpoint, credential or whether anyone has one. status and q (name search) filter; pages by limit (default 50), pass the returned next as after. Other orgs' connectors are only in the admin console.",
156
+ input: AdminConnectorListQuery.pick({
157
+ status: true,
158
+ q: true,
159
+ after: true,
160
+ limit: true,
161
+ }).strict(),
162
+ example: { limit: 50 },
163
+ authz: { superAdmin: true },
164
+ mirrors: ["GET /api/v1/admin/connectors"],
165
+ confirm: "read",
166
+ run: (input, ctx) => this.adminConnectors.list({ ...input, orgId: ctx.orgId }),
167
+ }),
168
+ defineOperation({
169
+ id: "admin.connector-get",
170
+ description: "Read one connector of this org as the admin console shows it (super admin): its endpoint with large fields as size and hash only, the auth type and who holds the credential (the org or each person), and its tools with their state and default policy. Never a credential, token or secret, nor whether any member has one.",
171
+ input: ConnectorIdInput,
172
+ example: { connectorId: "5d2e8f1a-0b3c-4d5e-8f9a-1b2c3d4e5f60" },
173
+ authz: { superAdmin: true },
174
+ mirrors: ["GET /api/v1/admin/connectors/:connectorId"],
175
+ confirm: "read",
176
+ errors: [
177
+ {
178
+ code: "connector.not_found",
179
+ next: "Check the connector id with admin.connectors-list.",
180
+ },
181
+ ],
182
+ run: async (input, ctx) => ({
183
+ connector: await this.connectorOf(input.connectorId, ctx),
184
+ }),
185
+ }),
186
+ defineOperation({
187
+ id: "admin.connector-set-status",
188
+ description: "Disable or enable a connector of this org on the platform's behalf (super admin): status disabled takes its tools away from every agent until it is enabled again. Its endpoint and auth stay the org's to edit. The org's audit log records that the platform acted.",
189
+ input: z
190
+ .object({
191
+ connectorId: ConnectorIdParams.shape.connectorId,
192
+ status: ConnectorStatusBody.shape.status,
193
+ })
194
+ .strict(),
195
+ example: {
196
+ connectorId: "5d2e8f1a-0b3c-4d5e-8f9a-1b2c3d4e5f60",
197
+ status: "disabled",
198
+ },
199
+ authz: { superAdmin: true },
200
+ mirrors: ["PATCH /api/v1/admin/connectors/:connectorId"],
201
+ confirm: "platform",
202
+ errors: [
203
+ {
204
+ code: "connector.not_found",
205
+ next: "Check the connector id with admin.connectors-list.",
206
+ },
207
+ ],
208
+ precheck: (i, ctx) => this.precheck(() => this.connectorOf(i.connectorId, ctx), "connector.not_found"),
209
+ summary: async (i, ctx) => {
210
+ const n = await orElse(async () => named((await this.connectorOf(i.connectorId, ctx)).name), i.connectorId);
211
+ return i.status === "disabled"
212
+ ? {
213
+ zh: `以平台身份停用连接器「${n}」;智能体将失去其工具,直到重新启用`,
214
+ en: `Disable connector "${n}" on the platform's behalf; agents lose its tools until it is enabled again`,
215
+ }
216
+ : {
217
+ zh: `以平台身份启用连接器「${n}」`,
218
+ en: `Enable connector "${n}" on the platform's behalf`,
219
+ };
220
+ },
221
+ run: async (input, ctx) => {
222
+ await this.connectorOf(input.connectorId, ctx);
223
+ await this.connectors.setStatusAsPlatform(input.connectorId, input.status, { accountId: ctx.actorAccountId }, viaAgent("admin.connector-set-status", ctx));
224
+ return { connector: await this.adminConnectors.get(input.connectorId) };
225
+ },
226
+ }),
227
+ defineOperation({
228
+ id: "admin.connector-delete",
229
+ description: "Delete a connector of this org on the platform's behalf (super admin): its credentials are deleted too and agents that use it lose its tools. Creating it again needs its credentials entered on the web. The org's audit log records that the platform acted.",
230
+ input: ConnectorIdInput,
231
+ example: { connectorId: "5d2e8f1a-0b3c-4d5e-8f9a-1b2c3d4e5f60" },
232
+ authz: { superAdmin: true },
233
+ mirrors: ["DELETE /api/v1/admin/connectors/:connectorId"],
234
+ confirm: "platform",
235
+ errors: [
236
+ {
237
+ code: "connector.not_found",
238
+ next: "Check the connector id with admin.connectors-list.",
239
+ },
240
+ ],
241
+ precheck: (i, ctx) => this.precheck(() => this.connectorOf(i.connectorId, ctx), "connector.not_found"),
242
+ summary: async (i, ctx) => {
243
+ const n = await orElse(async () => named((await this.connectorOf(i.connectorId, ctx)).name), i.connectorId);
244
+ return {
245
+ zh: `以平台身份删除连接器「${n}」及其全部凭据;使用它的智能体将失去其工具`,
246
+ en: `Delete connector "${n}" and all its credentials on the platform's behalf; agents that use it lose its tools`,
247
+ };
248
+ },
249
+ run: async (input, ctx) => {
250
+ await this.connectorOf(input.connectorId, ctx);
251
+ await this.connectors.removeAsPlatform(input.connectorId, { accountId: ctx.actorAccountId }, viaAgent("admin.connector-delete", ctx));
252
+ return { id: input.connectorId, deleted: true };
253
+ },
254
+ }),
255
+ defineOperation({
256
+ id: "admin.org-members",
257
+ description: "List the members of this conversation's org as the admin console reads them (super admin): account id, display name, email, role, when they joined and whether the account is the org's anonymous guest.",
258
+ input: z.object({}).strict(),
259
+ example: {},
260
+ authz: { superAdmin: true },
261
+ mirrors: ["GET /api/v1/admin/orgs/:orgId/members"],
262
+ confirm: "read",
263
+ run: async (_input, ctx) => ({ members: await this.members.list(ctx.orgId) }),
264
+ }),
265
+ ]);
266
+ }
267
+ };
268
+ AdminItemsOperations = __decorate([
269
+ Injectable(),
270
+ __param(0, Inject(PlatformOperations)),
271
+ __param(1, Inject(AdminAgents)),
272
+ __param(2, Inject(AgentsService)),
273
+ __param(3, Inject(AdminConnectors)),
274
+ __param(4, Inject(ConnectorsService)),
275
+ __param(5, Inject(MembersService)),
276
+ __param(6, Inject(KernelDb))
277
+ ], AdminItemsOperations);
278
+ export { AdminItemsOperations };
@@ -1,29 +1,25 @@
1
1
  import { type OnModuleInit } from "@nestjs/common";
2
- import { CatalogRequestsService } from "../../catalog/requests.service.js";
3
- import { ExtensionAdmin } from "../../extensions/admin-view.js";
2
+ import { AdminHealthService } from "../../admin/health.service.js";
3
+ import { AdminOverviewService } from "../../admin/overview.service.js";
4
+ import { PlatformAuditService } from "../../admin/platform-audit.service.js";
5
+ import { AdminUsageService } from "../../admin/usage.service.js";
4
6
  import { ExtensionDisplayNames } from "../../extensions/display-name.js";
5
7
  import { ExtensionRegistry } from "../../extensions/registry.js";
6
- import { AccountsService } from "../../identity/accounts.js";
7
8
  import { SettingsService } from "../../identity/settings.js";
8
9
  import { ModelEnablement } from "../../models/enablement.js";
9
10
  import { PricesService } from "../../models/prices.js";
10
11
  import { ModelPurposesService } from "../../models/purposes.js";
11
- import { OrgsService } from "../../orgs/orgs.service.js";
12
12
  import { ProviderRegistry } from "../../runtime/providers.js";
13
13
  import { ThemesService } from "../../themes/themes.service.js";
14
14
  import { PlatformOperations } from "../registry.js";
15
15
  /**
16
- * Admin console operations of the `Platform` tool (spec §14.2): the dashboard totals, the
16
+ * Admin console operations of the `Platform` tool (spec §14.2): the dashboard numbers and attention lists, the platform audit log, the
17
17
  * deployment settings, and the platform's models (the model catalog with the platform's disabled
18
18
  * list, the price table, the default model per purpose). Super admin only, through their own
19
19
  * private agent. The per-org overrides of models and purposes are the org's own pages.
20
20
  */
21
21
  export declare class AdminOperations implements OnModuleInit {
22
22
  private readonly registry;
23
- private readonly extensions;
24
- private readonly orgs;
25
- private readonly accounts;
26
- private readonly catalogRequests;
27
23
  private readonly settings;
28
24
  private readonly providers;
29
25
  private readonly displayNames;
@@ -32,7 +28,11 @@ export declare class AdminOperations implements OnModuleInit {
32
28
  private readonly prices;
33
29
  private readonly purposes;
34
30
  private readonly themes;
35
- constructor(registry: PlatformOperations, extensions: ExtensionAdmin, orgs: OrgsService, accounts: AccountsService, catalogRequests: CatalogRequestsService, settings: SettingsService, providers: ProviderRegistry, displayNames: ExtensionDisplayNames, extensionRegistry: ExtensionRegistry, enablement: ModelEnablement, prices: PricesService, purposes: ModelPurposesService, themes: ThemesService);
31
+ private readonly audit;
32
+ private readonly overview;
33
+ private readonly health;
34
+ private readonly usage;
35
+ constructor(registry: PlatformOperations, settings: SettingsService, providers: ProviderRegistry, displayNames: ExtensionDisplayNames, extensionRegistry: ExtensionRegistry, enablement: ModelEnablement, prices: PricesService, purposes: ModelPurposesService, themes: ThemesService, audit: PlatformAuditService, overview: AdminOverviewService, health: AdminHealthService, usage: AdminUsageService);
36
36
  private assertProvider;
37
37
  onModuleInit(): void;
38
38
  }
@@ -10,20 +10,21 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
10
10
  import { Inject, Injectable } from "@nestjs/common";
11
11
  import { z } from "zod";
12
12
  import { DeploymentSettingsBody, PurposeParams } from "../../admin/admin.schemas.js";
13
- import { CatalogRequestsService } from "../../catalog/requests.service.js";
13
+ import { AuditListQuery } from "../../admin/audit.schemas.js";
14
+ import { AdminHealthService } from "../../admin/health.service.js";
15
+ import { UsageQuery } from "../../admin/overview.schemas.js";
16
+ import { AdminOverviewService } from "../../admin/overview.service.js";
17
+ import { PlatformAuditService } from "../../admin/platform-audit.service.js";
18
+ import { AdminUsageService } from "../../admin/usage.service.js";
14
19
  import { ApiError } from "../../errors.js";
15
- import { ExtensionAdmin } from "../../extensions/admin-view.js";
16
20
  import { ExtensionDisplayNames } from "../../extensions/display-name.js";
17
- import { extensionNeedsAction } from "../../extensions/permission-view.js";
18
21
  import { ExtensionRegistry } from "../../extensions/registry.js";
19
- import { AccountsService } from "../../identity/accounts.js";
20
22
  import { DEPLOYMENT_SETTINGS_PATCH, SettingsService } from "../../identity/settings.js";
21
23
  import { ModelDisabledPatch, ModelProviderParams } from "../../models/enablement.controller.js";
22
24
  import { ModelEnablement } from "../../models/enablement.js";
23
25
  import { MODEL_PRICE_PUT, PricesService } from "../../models/prices.js";
24
26
  import { purposeTargetOf } from "../../models/purposes.controller.js";
25
27
  import { ModelPurposesService, PURPOSE_PUT, withDeclaredByNames } from "../../models/purposes.js";
26
- import { OrgsService } from "../../orgs/orgs.service.js";
27
28
  import { ProviderRegistry } from "../../runtime/providers.js";
28
29
  import { ThemesService } from "../../themes/themes.service.js";
29
30
  import { defineOperation } from "../operation.js";
@@ -46,18 +47,49 @@ const SettingsInput = DEPLOYMENT_SETTINGS_PATCH.pick({
46
47
  const ProviderId = ModelProviderParams.shape.provider.describe("The model provider (models.platform-list), e.g. the plugin name of its extension.");
47
48
  /** `provider/model` of a purpose target, or null. */
48
49
  const refOf = (t) => t === null ? null : `${t.model.provider}/${t.model.model}`;
50
+ /** The attention lists as compact rows (`next`: the admin console page that fixes it). */
51
+ function attentionRows(a) {
52
+ return {
53
+ items: [
54
+ ...a.extensions.map((e) => ({
55
+ kind: "extension",
56
+ id: e.name,
57
+ name: localized(e.displayName, e.name).en,
58
+ state: e.status,
59
+ reason: e.reason,
60
+ next: `Fix it on the extension's page in the admin console (/admin/extensions/${e.name}).`,
61
+ })),
62
+ ...a.updates.map((u) => ({
63
+ kind: "update",
64
+ id: u.itemId,
65
+ name: localized(u.displayName, u.name).en,
66
+ state: "newer_in_marketplace",
67
+ reason: `${u.version} -> ${u.marketplaceVersion}`,
68
+ next: `Upgrade it on the plugin's page in the admin console (/admin/plugins/${u.itemId}); a newer version is never imported automatically.`,
69
+ })),
70
+ ...a.providers.map((p) => ({
71
+ kind: "provider",
72
+ id: p.plugin,
73
+ name: localized(p.displayName, p.plugin).en,
74
+ state: p.problem === "list_failed" ? "error" : "ok",
75
+ reason: p.problem,
76
+ next: p.problem === "list_failed"
77
+ ? `Check the provider's deployment config and connection on its extension page (/admin/extensions/${p.plugin}); the models page (/admin/models) shows the list.`
78
+ : "The provider lists no chat model that is switched on: switch one on in the admin console (/admin/models) or check the provider's config.",
79
+ })),
80
+ ],
81
+ more: a.more,
82
+ unavailable: a.unavailable,
83
+ };
84
+ }
49
85
  /**
50
- * Admin console operations of the `Platform` tool (spec §14.2): the dashboard totals, the
86
+ * Admin console operations of the `Platform` tool (spec §14.2): the dashboard numbers and attention lists, the platform audit log, the
51
87
  * deployment settings, and the platform's models (the model catalog with the platform's disabled
52
88
  * list, the price table, the default model per purpose). Super admin only, through their own
53
89
  * private agent. The per-org overrides of models and purposes are the org's own pages.
54
90
  */
55
91
  let AdminOperations = class AdminOperations {
56
92
  registry;
57
- extensions;
58
- orgs;
59
- accounts;
60
- catalogRequests;
61
93
  settings;
62
94
  providers;
63
95
  displayNames;
@@ -66,12 +98,12 @@ let AdminOperations = class AdminOperations {
66
98
  prices;
67
99
  purposes;
68
100
  themes;
69
- constructor(registry, extensions, orgs, accounts, catalogRequests, settings, providers, displayNames, extensionRegistry, enablement, prices, purposes, themes) {
101
+ audit;
102
+ overview;
103
+ health;
104
+ usage;
105
+ constructor(registry, settings, providers, displayNames, extensionRegistry, enablement, prices, purposes, themes, audit, overview, health, usage) {
70
106
  this.registry = registry;
71
- this.extensions = extensions;
72
- this.orgs = orgs;
73
- this.accounts = accounts;
74
- this.catalogRequests = catalogRequests;
75
107
  this.settings = settings;
76
108
  this.providers = providers;
77
109
  this.displayNames = displayNames;
@@ -80,6 +112,10 @@ let AdminOperations = class AdminOperations {
80
112
  this.prices = prices;
81
113
  this.purposes = purposes;
82
114
  this.themes = themes;
115
+ this.audit = audit;
116
+ this.overview = overview;
117
+ this.health = health;
118
+ this.usage = usage;
83
119
  }
84
120
  assertProvider(provider) {
85
121
  if (!this.extensionRegistry.list("model-provider").some((e) => e.plugin === provider)) {
@@ -90,26 +126,59 @@ let AdminOperations = class AdminOperations {
90
126
  this.registry.register([
91
127
  defineOperation({
92
128
  id: "admin.overview",
93
- description: "The admin console's dashboard totals (super admin): extensions that need the super admin's action, catalog requests waiting for deployment, and the numbers of orgs and accounts.",
129
+ description: "The admin console's dashboard numbers (super admin): orgs, accounts and attentionTotal, everything waiting for a super admin (the platform inbox total plus the extensions, plugin updates and model providers admin.attention lists); partial is true when one of those lists could not be read right now (attentionTotal then leaves it out).",
94
130
  input: z.object({}).strict(),
95
131
  example: {},
96
132
  authz: { superAdmin: true },
97
133
  mirrors: ["GET /api/v1/admin/overview"],
98
134
  confirm: "read",
99
- run: async () => {
100
- const [plugins, orgs, accounts, catalogRequestsPending] = await Promise.all([
101
- this.extensions.list(),
102
- this.orgs.listAll(),
103
- this.accounts.count(),
104
- this.catalogRequests.countPendingDeployment(),
105
- ]);
106
- return {
107
- extensionsNeedingAction: plugins.filter((p) => extensionNeedsAction(p.status)).length,
108
- catalogRequestsPending,
109
- orgs: orgs.length,
110
- accounts,
111
- };
112
- },
135
+ run: () => this.overview.stats(),
136
+ }),
137
+ defineOperation({
138
+ id: "admin.attention",
139
+ description: "What needs the super admin besides the platform inbox (super admin), one compact row each (kind, id, name, state, reason, next step): extensions (reason config, load_failed, approval, dependency, conflict, converging or legacy_format), platform plugins with a newer marketplace version (reason names both versions) and model providers (reason list_failed or no_chat_model). Each kind lists at most 20 rows; more counts the rest per kind. unavailable names a kind that could not be read right now (try again later). The platform inbox itself is inbox.platform-list.",
140
+ input: z.object({}).strict(),
141
+ example: {},
142
+ authz: { superAdmin: true },
143
+ mirrors: ["GET /api/v1/admin/overview/attention"],
144
+ confirm: "read",
145
+ run: async () => attentionRows(await this.overview.attention()),
146
+ }),
147
+ defineOperation({
148
+ id: "admin.health",
149
+ description: 'How the platform runs right now (super admin), to answer "is the worker up, is the run queue backing up": kernel.version; replicas (live kernel processes: id, roles, version, startedAt) and roles (live replicas per role: api serves requests, worker runs conversations and jobs, gateway holds channel and device connections; 0 workers means no run starts); queues (per kernel queue, e.g. cap-kernel-runs: waiting, active, delayed, failed and failedLastDay, counts only); channels (online, offline: active long connections no replica holds, webhook, disabled, error); devices (online / local); sandboxes (running, suspended, running per provider). unavailable names a source that did not answer (redis or database); its numbers are then null. Failure details are in the kernel logs, not here.',
150
+ input: z.object({}).strict(),
151
+ example: {},
152
+ authz: { superAdmin: true },
153
+ mirrors: ["GET /api/v1/admin/overview/health"],
154
+ confirm: "read",
155
+ run: () => this.health.read(),
156
+ }),
157
+ defineOperation({
158
+ id: "admin.usage",
159
+ description: "What the platform used over the last 7 days (super admin): today and the 6 days before, as calendar days in tz (an IANA zone such as Asia/Shanghai; use the person's own zone). days has one entry per day, oldest first: runs (every run, sub-agent and eval replay runs included), tokens (input, output, cacheRead, cacheWrite of every model call, and embedding) and cost. cost is an estimate from the model prices the super admin entered (models.prices), in currency; it is null when tokens were used and none of them had a price, and costPartial is true when some tokens had no price (the costs then count only the priced ones). orgs lists the 10 orgs that used the most tokens (runs, tokens, cost each); otherOrgs sums the rest (count, runs, tokens, cost). Totals only: never per account, agent or conversation. The answer may be up to 5 minutes old. admin.usage_unavailable means the database took too long: try again later.",
160
+ input: UsageQuery.strict(),
161
+ example: { tz: "Asia/Shanghai" },
162
+ authz: { superAdmin: true },
163
+ mirrors: ["GET /api/v1/admin/overview/usage"],
164
+ confirm: "read",
165
+ errors: [
166
+ {
167
+ code: "admin.usage_unavailable",
168
+ next: "The usage numbers took too long to compute; try again in a few minutes.",
169
+ },
170
+ ],
171
+ run: (input) => this.usage.week(input.tz),
172
+ }),
173
+ defineOperation({
174
+ id: "admin.audit",
175
+ description: "The platform-level audit log (super admin), newest first: deployment settings, accounts, marketplaces, catalog imports and scope, extensions, model prices and purposes, setup. Each event has its id, time, actor (id, name, email; null for the kernel itself), viaToken (done with a personal access token), viaAgent (done through the Platform tool), action and target; never the event's details, and never an org's own events. limit is 1 to 100 (default 20); pages by keyset: pass the returned next as params.after (null: no more).",
176
+ input: AuditListQuery.strict(),
177
+ example: { limit: 20 },
178
+ authz: { superAdmin: true },
179
+ mirrors: ["GET /api/v1/admin/audit"],
180
+ confirm: "read",
181
+ run: (input) => this.audit.list(input),
113
182
  }),
114
183
  defineOperation({
115
184
  id: "admin.settings",
@@ -412,17 +481,17 @@ let AdminOperations = class AdminOperations {
412
481
  AdminOperations = __decorate([
413
482
  Injectable(),
414
483
  __param(0, Inject(PlatformOperations)),
415
- __param(1, Inject(ExtensionAdmin)),
416
- __param(2, Inject(OrgsService)),
417
- __param(3, Inject(AccountsService)),
418
- __param(4, Inject(CatalogRequestsService)),
419
- __param(5, Inject(SettingsService)),
420
- __param(6, Inject(ProviderRegistry)),
421
- __param(7, Inject(ExtensionDisplayNames)),
422
- __param(8, Inject(ExtensionRegistry)),
423
- __param(9, Inject(ModelEnablement)),
424
- __param(10, Inject(PricesService)),
425
- __param(11, Inject(ModelPurposesService)),
426
- __param(12, Inject(ThemesService))
484
+ __param(1, Inject(SettingsService)),
485
+ __param(2, Inject(ProviderRegistry)),
486
+ __param(3, Inject(ExtensionDisplayNames)),
487
+ __param(4, Inject(ExtensionRegistry)),
488
+ __param(5, Inject(ModelEnablement)),
489
+ __param(6, Inject(PricesService)),
490
+ __param(7, Inject(ModelPurposesService)),
491
+ __param(8, Inject(ThemesService)),
492
+ __param(9, Inject(PlatformAuditService)),
493
+ __param(10, Inject(AdminOverviewService)),
494
+ __param(11, Inject(AdminHealthService)),
495
+ __param(12, Inject(AdminUsageService))
427
496
  ], AdminOperations);
428
497
  export { AdminOperations };
@@ -1,21 +1,47 @@
1
1
  import { type OnModuleInit } from "@nestjs/common";
2
2
  import { AgentsService } from "../../agents/agents.service.js";
3
+ import { KernelDb } from "../../infra/database/kernel-db.js";
4
+ import { SandboxFileReader } from "../../sandbox/sandbox-file-reader.js";
5
+ import { AgentSkillsService } from "../../skills/agent-skills.service.js";
3
6
  import { SkillChangesService } from "../../skills/changes.service.js";
4
7
  import { SkillInvoker } from "../../skills/invoke.js";
5
8
  import { SkillsService } from "../../skills/skills.service.js";
6
9
  import { PlatformOperations } from "../registry.js";
7
10
  /**
8
11
  * The skills of one agent and the skill change inbox detail (`Platform` tool, spec §14): reads of
9
- * the agent's own skills and of the invocable ones, detaching a skill, and the detail of a pending
10
- * skill change as the inbox shows it. Deciding a change stays `human-only`.
12
+ * the agent's own skills and of the invocable ones, registering, deleting and sharing a skill,
13
+ * and the detail of a skill change request as the inbox shows it. Deciding a request stays
14
+ * `human-only` (org admins on the web).
11
15
  */
12
16
  export declare class AgentSkillsOperations implements OnModuleInit {
13
17
  private readonly registry;
14
18
  private readonly agents;
15
19
  private readonly skills;
16
20
  private readonly changes;
21
+ private readonly agentSkills;
17
22
  private readonly invoker;
18
- constructor(registry: PlatformOperations, agents: AgentsService, skills: SkillsService, changes: SkillChangesService, invoker: SkillInvoker);
23
+ private readonly files;
24
+ private readonly db;
25
+ constructor(registry: PlatformOperations, agents: AgentsService, skills: SkillsService, changes: SkillChangesService, agentSkills: AgentSkillsService, invoker: SkillInvoker, files: SandboxFileReader, db: KernelDb);
26
+ /**
27
+ * Class of registering a skill on the run's agent: `personal` on a private agent the actor owns
28
+ * whose `skills.writePolicy` is not `ask`; otherwise `org` (asked every time, never remembered).
29
+ * Also `org` when the registration may apply a version to a shared org skill at once (the actor
30
+ * is an org admin maintaining one; the package name is not known before the card).
31
+ */
32
+ private registerClass;
33
+ /**
34
+ * The refusals read before anything touches the sandbox (the reader checks only the device):
35
+ * a sub-agent conversation, then an actor who is not the agent's current owner.
36
+ */
37
+ private registerCheck;
38
+ /**
39
+ * The refusals of sharing read before the card: a sub-agent conversation, an actor who is not
40
+ * the agent's current owner, a skill that is not one of the agent's own.
41
+ */
42
+ private shareCheck;
43
+ /** The file count of a registered version (null for a proposal or when the row is gone). */
44
+ private filesOf;
19
45
  /** Class of deleting a skill: your own private agent is personal; a shared agent is the org's. */
20
46
  private deleteClass;
21
47
  /** The route's refusals, read before the card: a visible agent, owned by the actor, with the skill. */