@capybara-hq/kernel 0.1.0-rc.12 → 0.1.0-rc.13
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/dist/admin/admin.schemas.d.ts +13 -0
- package/dist/agents/agent-lookup.d.ts +5 -0
- package/dist/agents/agent-lookup.js +15 -0
- package/dist/background/background.module.js +2 -2
- package/dist/background/launch-lock.d.ts +1 -1
- package/dist/background/launch-lock.js +1 -1
- package/dist/background/poll.job.d.ts +2 -2
- package/dist/background/poll.job.js +10 -10
- package/dist/background/stop.d.ts +1 -1
- package/dist/background/stop.js +3 -3
- package/dist/background/store.d.ts +5 -5
- package/dist/background/store.js +5 -5
- package/dist/background/tasks.service.d.ts +6 -6
- package/dist/background/tasks.service.js +13 -13
- package/dist/catalog/marketplaces.service.d.ts +1 -1
- package/dist/channels/channels.module.js +2 -2
- package/dist/channels/inbound.d.ts +8 -8
- package/dist/channels/inbound.js +31 -31
- package/dist/channels/phrases.d.ts +27 -27
- package/dist/channels/phrases.js +27 -27
- package/dist/config/docs.js +1 -1
- package/dist/config/schema.d.ts +2 -2
- package/dist/config/schema.js +21 -21
- package/dist/conversations/conversations.controller.d.ts +11 -11
- package/dist/conversations/conversations.controller.js +15 -15
- package/dist/conversations/conversations.module.d.ts +1 -1
- package/dist/conversations/conversations.module.js +7 -7
- package/dist/conversations/conversations.schemas.js +1 -1
- package/dist/conversations/conversations.service.d.ts +14 -14
- package/dist/conversations/conversations.service.js +19 -19
- package/dist/conversations/{environment-status.d.ts → device-status.d.ts} +9 -9
- package/dist/conversations/{environment-status.js → device-status.js} +18 -18
- package/dist/conversations/event-log.d.ts +1 -1
- package/dist/conversations/event-log.js +1 -1
- package/dist/conversations/events.d.ts +1 -1
- package/dist/conversations/events.js +2 -2
- package/dist/ctx/create-ctx.d.ts +10 -1
- package/dist/ctx/create-ctx.js +86 -25
- package/dist/db/kernel-schema.d.ts +26 -23
- package/dist/{environments → devices}/access.d.ts +19 -19
- package/dist/{environments → devices}/access.js +28 -28
- package/dist/devices/conversation-devices.d.ts +75 -0
- package/dist/{environments/conversation-environments.js → devices/conversation-devices.js} +71 -72
- package/dist/devices/devices.controller.d.ts +36 -0
- package/dist/{environments/environments.controller.js → devices/devices.controller.js} +37 -37
- package/dist/devices/devices.module.d.ts +5 -13
- package/dist/devices/devices.module.js +16 -29
- package/dist/devices/devices.schemas.d.ts +3 -0
- package/dist/devices/devices.schemas.js +14 -0
- package/dist/{environments/environments.service.d.ts → devices/devices.service.d.ts} +70 -70
- package/dist/{environments/environments.service.js → devices/devices.service.js} +122 -122
- package/dist/devices/dto.d.ts +13 -54
- package/dist/devices/dto.js +7 -39
- package/dist/devices/label.d.ts +11 -0
- package/dist/{environments → devices}/label.js +7 -7
- package/dist/{environments → devices}/legacy-cleanup.job.d.ts +3 -3
- package/dist/{environments → devices}/legacy-cleanup.job.js +3 -3
- package/dist/errors.d.ts +25 -25
- package/dist/errors.js +25 -25
- package/dist/evals/recorded-tools.d.ts +2 -2
- package/dist/evals/recorded-tools.js +6 -6
- package/dist/extensions/admin-ops.js +1 -0
- package/dist/extensions/admin-view.js +2 -0
- package/dist/extensions/effective-config.d.ts +6 -0
- package/dist/extensions/effective-config.js +18 -7
- package/dist/extensions/host.d.ts +13 -2
- package/dist/extensions/host.js +24 -3
- package/dist/extensions/instance.d.ts +12 -1
- package/dist/extensions/instance.js +13 -0
- package/dist/extensions/permission-view.d.ts +10 -1
- package/dist/files/previewers.d.ts +1 -1
- package/dist/files/previewers.js +1 -1
- package/dist/http/api.module.js +10 -6
- package/dist/http/gateway-routes.d.ts +1 -1
- package/dist/http/gateway-routes.js +1 -1
- package/dist/identity/settings.d.ts +32 -0
- package/dist/identity/settings.js +26 -2
- package/dist/infra/config/kernel-config.service.js +4 -4
- package/dist/kernel.module.js +3 -3
- package/dist/{devices → local-devices}/device-auth.controller.d.ts +6 -6
- package/dist/{devices → local-devices}/device-auth.controller.js +5 -5
- package/dist/{devices → local-devices}/device-auth.d.ts +20 -20
- package/dist/{devices → local-devices}/device-auth.js +51 -53
- package/dist/local-devices/device-auth.module.d.ts +7 -0
- package/dist/{devices → local-devices}/device-auth.module.js +5 -5
- package/dist/{devices → local-devices}/device-routes.d.ts +3 -3
- package/dist/{devices → local-devices}/device-routes.js +2 -2
- package/dist/local-devices/dto.d.ts +66 -0
- package/dist/local-devices/dto.js +44 -0
- package/dist/{devices → local-devices}/keys.d.ts +11 -11
- package/dist/{devices → local-devices}/keys.js +11 -11
- package/dist/{devices/device-gateway.d.ts → local-devices/local-device-gateway.d.ts} +14 -14
- package/dist/{devices/device-gateway.js → local-devices/local-device-gateway.js} +44 -44
- package/dist/{devices/device-provider.d.ts → local-devices/local-device-provider.d.ts} +15 -15
- package/dist/{devices/device-provider.js → local-devices/local-device-provider.js} +23 -23
- package/dist/local-devices/local-devices.module.d.ts +16 -0
- package/dist/local-devices/local-devices.module.js +44 -0
- package/dist/{devices → local-devices}/machines.d.ts +26 -26
- package/dist/{devices → local-devices}/machines.js +71 -71
- package/dist/{devices → local-devices}/relay.d.ts +15 -15
- package/dist/{devices → local-devices}/relay.js +55 -55
- package/dist/{devices → local-devices}/targets.d.ts +8 -8
- package/dist/{devices → local-devices}/targets.js +14 -14
- package/dist/orgs/offboarding.d.ts +6 -6
- package/dist/orgs/offboarding.js +12 -12
- package/dist/orgs/settings.service.d.ts +28 -0
- package/dist/orgs/settings.service.js +20 -1
- package/dist/platform/exclusions.js +38 -3
- package/dist/platform/operation.js +6 -2
- package/dist/platform/ops/admin.ops.js +8 -2
- package/dist/platform/ops/conversations.ops.d.ts +3 -3
- package/dist/platform/ops/conversations.ops.js +9 -9
- package/dist/platform/ops/devices.ops.d.ts +26 -0
- package/dist/platform/ops/devices.ops.js +311 -0
- package/dist/platform/ops/org-settings.ops.js +2 -2
- package/dist/platform/ops/orgs.ops.js +1 -0
- package/dist/platform/ops/ui.ops.d.ts +8 -0
- package/dist/platform/ops/ui.ops.js +41 -0
- package/dist/platform/platform-ops.module.d.ts +3 -2
- package/dist/platform/platform-ops.module.js +8 -5
- package/dist/platform/route-schemas.js +6 -3
- package/dist/roles/gateway-role.d.ts +3 -3
- package/dist/roles/gateway-role.js +4 -4
- package/dist/roles/gateway.module.d.ts +1 -1
- package/dist/roles/gateway.module.js +5 -5
- package/dist/roles/worker.module.js +1 -1
- package/dist/runtime/context/build.d.ts +1 -1
- package/dist/runtime/context/build.js +6 -6
- package/dist/runtime/context/compaction.js +1 -1
- package/dist/runtime/context/{environment-paths.d.ts → device-paths.d.ts} +11 -11
- package/dist/runtime/context/{environment-paths.js → device-paths.js} +13 -13
- package/dist/runtime/maintenance.d.ts +1 -1
- package/dist/sandbox/jobs.d.ts +13 -13
- package/dist/sandbox/jobs.js +20 -20
- package/dist/sandbox/leases.d.ts +9 -9
- package/dist/sandbox/leases.js +14 -14
- package/dist/sandbox/providers.d.ts +8 -8
- package/dist/sandbox/providers.js +8 -8
- package/dist/sandbox/sandbox.module.d.ts +1 -1
- package/dist/sandbox/sandbox.module.js +1 -1
- package/dist/sandbox/sandbox.service.d.ts +76 -76
- package/dist/sandbox/sandbox.service.js +230 -230
- package/dist/tools/builtins/builtin-tools.d.ts +2 -2
- package/dist/tools/builtins/builtin-tools.js +5 -5
- package/dist/tools/builtins/platform.js +1 -1
- package/dist/tools/builtins/sandbox/bash.js +6 -6
- package/dist/tools/builtins/sandbox/common.d.ts +25 -25
- package/dist/tools/builtins/sandbox/common.js +51 -51
- package/dist/tools/builtins/sandbox/edit.js +2 -2
- package/dist/tools/builtins/sandbox/index.d.ts +1 -1
- package/dist/tools/builtins/sandbox/index.js +1 -1
- package/dist/tools/builtins/sandbox/task-output.d.ts +6 -6
- package/dist/tools/builtins/sandbox/task-output.js +10 -10
- package/dist/tools/builtins/sandbox/task-stop.js +2 -2
- package/dist/tools/builtins/sandbox/write.js +2 -2
- package/dist/tools/builtins/skill-load.d.ts +1 -1
- package/dist/tools/builtins/skill-load.js +2 -2
- package/dist/tools/pipeline.js +4 -3
- package/dist/tools/registry.d.ts +2 -2
- package/dist/tools/tools.module.js +3 -3
- package/dist/ui/admin-ui.controller.d.ts +56 -0
- package/dist/ui/admin-ui.controller.js +192 -0
- package/dist/ui/arrangement.d.ts +74 -0
- package/dist/ui/arrangement.js +98 -0
- package/dist/ui/embed-token.d.ts +2 -2
- package/dist/ui/embed-token.js +30 -5
- package/dist/ui/registry.d.ts +29 -14
- package/dist/ui/registry.js +31 -10
- package/dist/ui/slots.controller.d.ts +11 -0
- package/dist/ui/slots.controller.js +25 -0
- package/dist/ui/ui-stream.d.ts +20 -3
- package/dist/ui/ui-stream.js +25 -7
- package/dist/ui/ui.schemas.d.ts +66 -0
- package/dist/ui/ui.schemas.js +65 -0
- package/dist/ui/views.controller.d.ts +35 -49
- package/dist/ui/views.controller.js +48 -70
- package/dist/ui/views.d.ts +84 -18
- package/dist/ui/views.js +201 -38
- package/package.json +3 -3
- package/src/migrations/0105_devices_rename.sql +136 -0
- package/dist/devices/device-auth.module.d.ts +0 -7
- package/dist/environments/conversation-environments.d.ts +0 -75
- package/dist/environments/dto.d.ts +0 -25
- package/dist/environments/dto.js +0 -12
- package/dist/environments/environments.controller.d.ts +0 -36
- package/dist/environments/environments.module.d.ts +0 -8
- package/dist/environments/environments.module.js +0 -31
- package/dist/environments/environments.schemas.d.ts +0 -3
- package/dist/environments/environments.schemas.js +0 -14
- package/dist/environments/label.d.ts +0 -11
- package/dist/platform/ops/environments.ops.d.ts +0 -26
- package/dist/platform/ops/environments.ops.js +0 -311
|
@@ -60,6 +60,14 @@ export class ExtensionInstance {
|
|
|
60
60
|
generation;
|
|
61
61
|
manifest;
|
|
62
62
|
permissions;
|
|
63
|
+
/** The manifest's UI contributions whose slot the catalog knows (UI slots spec §3.2), in manifest order. */
|
|
64
|
+
ui;
|
|
65
|
+
/** The manifest's UI contributions left out at load (unknown slot or slot version). */
|
|
66
|
+
uiDropped;
|
|
67
|
+
/** `after` values that are not anchors of their slot (the contribution keeps the default position). */
|
|
68
|
+
uiUnknownAnchors;
|
|
69
|
+
/** Ids of contributions that still name the deprecated `place`. */
|
|
70
|
+
uiDeprecatedPlace;
|
|
63
71
|
hash;
|
|
64
72
|
live;
|
|
65
73
|
entryUrl;
|
|
@@ -77,6 +85,11 @@ export class ExtensionInstance {
|
|
|
77
85
|
this.source = init.source;
|
|
78
86
|
this.generation = init.generation;
|
|
79
87
|
this.permissions = init.permissions;
|
|
88
|
+
const ui = init.ctx.uiResolution;
|
|
89
|
+
this.ui = ui.resolved;
|
|
90
|
+
this.uiDropped = ui.dropped;
|
|
91
|
+
this.uiUnknownAnchors = ui.unknownAnchors;
|
|
92
|
+
this.uiDeprecatedPlace = ui.deprecatedPlace;
|
|
80
93
|
this.hash = init.configHash;
|
|
81
94
|
this.live = init.config;
|
|
82
95
|
this.entryUrl = init.entryUrl;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LocalizedName } from "@capybara-hq/plugin-sdk";
|
|
1
|
+
import type { LocalizedName, UiDropReason } from "@capybara-hq/plugin-sdk";
|
|
2
2
|
import type { PluginScope } from "../catalog/scope.js";
|
|
3
3
|
import { type PermissionSet } from "./permission-set.js";
|
|
4
4
|
import type { ExtensionSource } from "./sources.js";
|
|
@@ -142,6 +142,15 @@ export interface AdminExtensionView {
|
|
|
142
142
|
builtin: boolean;
|
|
143
143
|
/** Where the install record came from (`bootstrap` for the bootstrap step); null for config-declared. */
|
|
144
144
|
installSource: "npm" | "file" | "catalog" | "bootstrap" | null;
|
|
145
|
+
/**
|
|
146
|
+
* UI contributions this replica's loaded instance left out at load (UI slots spec §3.2): a slot the
|
|
147
|
+
* catalog does not know, or not at that version. `[]` when the extension is not loaded here.
|
|
148
|
+
*/
|
|
149
|
+
uiDropped: {
|
|
150
|
+
id: string;
|
|
151
|
+
ref: string;
|
|
152
|
+
reason: UiDropReason;
|
|
153
|
+
}[];
|
|
145
154
|
/**
|
|
146
155
|
* Only with status `conflict`: the single-provider extension point and the other extensions that
|
|
147
156
|
* provide it (they keep this one from loading; disabling them loads it, no restart).
|
|
@@ -87,7 +87,7 @@ export declare class PreviewerRegistry {
|
|
|
87
87
|
locale: "zh" | "en";
|
|
88
88
|
}): Promise<UiView>;
|
|
89
89
|
/**
|
|
90
|
-
* Whether an embed token for a `file
|
|
90
|
+
* Whether an embed token for a `file.preview` contribution may be issued for this file: the
|
|
91
91
|
* viewer reads the conversation, the file is in it, and an enabled previewer of that extension
|
|
92
92
|
* with `embed: contribution` takes it. Conversation / file not found throws 404.
|
|
93
93
|
*/
|
package/dist/files/previewers.js
CHANGED
|
@@ -299,7 +299,7 @@ let PreviewerRegistry = class PreviewerRegistry {
|
|
|
299
299
|
return view;
|
|
300
300
|
}
|
|
301
301
|
/**
|
|
302
|
-
* Whether an embed token for a `file
|
|
302
|
+
* Whether an embed token for a `file.preview` contribution may be issued for this file: the
|
|
303
303
|
* viewer reads the conversation, the file is in it, and an enabled previewer of that extension
|
|
304
304
|
* with `embed: contribution` takes it. Conversation / file not found throws 404.
|
|
305
305
|
*/
|
package/dist/http/api.module.js
CHANGED
|
@@ -30,10 +30,8 @@ import { ChannelConnectionsController } from "../channels/connections.controller
|
|
|
30
30
|
import { AttachmentsController } from "../conversations/attachments.controller.js";
|
|
31
31
|
import { ConversationsController } from "../conversations/conversations.controller.js";
|
|
32
32
|
import { ConversationsModule } from "../conversations/conversations.module.js";
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import { EnvironmentsController } from "../environments/environments.controller.js";
|
|
36
|
-
import { EnvironmentsModule } from "../environments/environments.module.js";
|
|
33
|
+
import { DevicesController } from "../devices/devices.controller.js";
|
|
34
|
+
import { DevicesModule } from "../devices/devices.module.js";
|
|
37
35
|
import { EvalsModule } from "../evals/evals.module.js";
|
|
38
36
|
import { EvalRunsController } from "../evals/runs.controller.js";
|
|
39
37
|
import { EvalSetsController } from "../evals/sets.controller.js";
|
|
@@ -50,6 +48,8 @@ import { MeController } from "../identity/me.controller.js";
|
|
|
50
48
|
import { BindController, MeIdentitiesController, SsoController, } from "../identity/sso.controller.js";
|
|
51
49
|
import { InboxModule } from "../inbox/inbox.module.js";
|
|
52
50
|
import { PlatformInboxController } from "../inbox/platform-inbox.controller.js";
|
|
51
|
+
import { DeviceAuthController } from "../local-devices/device-auth.controller.js";
|
|
52
|
+
import { DeviceAuthModule } from "../local-devices/device-auth.module.js";
|
|
53
53
|
import { ModelEnablementController } from "../models/enablement.controller.js";
|
|
54
54
|
import { ModelsModule } from "../models/models.module.js";
|
|
55
55
|
import { ModelPurposesController } from "../models/purposes.controller.js";
|
|
@@ -75,6 +75,8 @@ import { ExtensionToolsController } from "../tools/extension-tools.controller.js
|
|
|
75
75
|
import { OAuthCallbackController, OAuthConnectController, } from "../tools/oauth/oauth.controller.js";
|
|
76
76
|
import { QuestionsController } from "../tools/questions.controller.js";
|
|
77
77
|
import { ToolsModule } from "../tools/tools.module.js";
|
|
78
|
+
import { AdminUiController } from "../ui/admin-ui.controller.js";
|
|
79
|
+
import { SlotsController } from "../ui/slots.controller.js";
|
|
78
80
|
import { UiModule } from "../ui/ui.module.js";
|
|
79
81
|
import { UiController } from "../ui/views.controller.js";
|
|
80
82
|
/** Every controller of the kernel API. */
|
|
@@ -104,7 +106,7 @@ const CONTROLLERS = [
|
|
|
104
106
|
ReadinessController,
|
|
105
107
|
ConversationsController,
|
|
106
108
|
BackgroundController,
|
|
107
|
-
|
|
109
|
+
DevicesController,
|
|
108
110
|
AttachmentsController,
|
|
109
111
|
SkillsController,
|
|
110
112
|
SkillChangesController,
|
|
@@ -127,6 +129,8 @@ const CONTROLLERS = [
|
|
|
127
129
|
ChannelConnectionsController,
|
|
128
130
|
DirectorySyncController,
|
|
129
131
|
UiController,
|
|
132
|
+
AdminUiController,
|
|
133
|
+
SlotsController,
|
|
130
134
|
FilePreviewersController,
|
|
131
135
|
ExtensionPointDefaultsController,
|
|
132
136
|
TrajectoryController,
|
|
@@ -166,7 +170,7 @@ ApiModule = __decorate([
|
|
|
166
170
|
AgentsModule,
|
|
167
171
|
ConversationsModule,
|
|
168
172
|
BackgroundModule,
|
|
169
|
-
|
|
173
|
+
DevicesModule,
|
|
170
174
|
DeviceAuthModule,
|
|
171
175
|
RuntimeModule,
|
|
172
176
|
ChannelsModule,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Logger } from "@capybara-hq/plugin-sdk";
|
|
2
2
|
import type { FastifyInstance } from "fastify";
|
|
3
3
|
import type { ChannelWebhooks } from "../channels/webhook.js";
|
|
4
|
-
import { type DeviceRoutesOptions } from "../devices/device-routes.js";
|
|
4
|
+
import { type DeviceRoutesOptions } from "../local-devices/device-routes.js";
|
|
5
5
|
/** What the gateway role serves over HTTP besides health and plugin routes. */
|
|
6
6
|
export interface GatewayRoutes {
|
|
7
7
|
webhooks: Pick<ChannelWebhooks, "handle">;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { registerChannelWebhookRoute } from "../channels/webhook.controller.js";
|
|
2
|
-
import { registerDeviceConnectRoute } from "../devices/device-routes.js";
|
|
2
|
+
import { registerDeviceConnectRoute, } from "../local-devices/device-routes.js";
|
|
3
3
|
/**
|
|
4
4
|
* Registers the gateway role's HTTP routes (`serveGateway = roles.includes("gateway")`): the
|
|
5
5
|
* channel webhook and the device connection WebSocket. These are raw Fastify routes, not a Nest
|
|
@@ -3,6 +3,7 @@ import type { KernelSchemaDb } from "../db/kernel-schema.js";
|
|
|
3
3
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
4
4
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
5
5
|
import type { KernelLogger } from "../log.js";
|
|
6
|
+
import { type UiArrangement } from "../ui/arrangement.js";
|
|
6
7
|
import { SuperAdminLock } from "./super-admin.js";
|
|
7
8
|
/** 沙箱 cpu(核)与内存(MB)覆盖的范围(C19)。 */
|
|
8
9
|
export declare const SANDBOX_CPU_RANGE: {
|
|
@@ -72,6 +73,19 @@ export declare const DEPLOYMENT_SETTINGS: z.ZodObject<{
|
|
|
72
73
|
uiTheme: z.ZodDefault<z.ZodObject<{
|
|
73
74
|
id: z.ZodNullable<z.ZodString>;
|
|
74
75
|
}, z.core.$strip>>;
|
|
76
|
+
uiArrangement: z.ZodDefault<z.ZodRecord<z.ZodEnum<{
|
|
77
|
+
"agent.detail.section": "agent.detail.section";
|
|
78
|
+
"conversation.panel": "conversation.panel";
|
|
79
|
+
"conversation.properties.section": "conversation.properties.section";
|
|
80
|
+
"conversation.tool-result.card": "conversation.tool-result.card";
|
|
81
|
+
"file.preview": "file.preview";
|
|
82
|
+
"org.page": "org.page";
|
|
83
|
+
"org.settings.section": "org.settings.section";
|
|
84
|
+
"platform.page": "platform.page";
|
|
85
|
+
}> & z.core.$partial, z.ZodObject<{
|
|
86
|
+
hidden: z.ZodArray<z.ZodString>;
|
|
87
|
+
order: z.ZodArray<z.ZodString>;
|
|
88
|
+
}, z.core.$strict>>>;
|
|
75
89
|
}, z.core.$strip>;
|
|
76
90
|
export type DeploymentSettings = z.infer<typeof DEPLOYMENT_SETTINGS>;
|
|
77
91
|
/**
|
|
@@ -111,6 +125,19 @@ export declare const DEPLOYMENT_SETTINGS_PATCH: z.ZodObject<{
|
|
|
111
125
|
uiTheme: z.ZodOptional<z.ZodObject<{
|
|
112
126
|
id: z.ZodNullable<z.ZodString>;
|
|
113
127
|
}, z.core.$strict>>;
|
|
128
|
+
uiArrangement: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
129
|
+
"agent.detail.section": "agent.detail.section";
|
|
130
|
+
"conversation.panel": "conversation.panel";
|
|
131
|
+
"conversation.properties.section": "conversation.properties.section";
|
|
132
|
+
"conversation.tool-result.card": "conversation.tool-result.card";
|
|
133
|
+
"file.preview": "file.preview";
|
|
134
|
+
"org.page": "org.page";
|
|
135
|
+
"org.settings.section": "org.settings.section";
|
|
136
|
+
"platform.page": "platform.page";
|
|
137
|
+
}> & z.core.$partial, z.ZodNullable<z.ZodObject<{
|
|
138
|
+
hidden: z.ZodArray<z.ZodString>;
|
|
139
|
+
order: z.ZodArray<z.ZodString>;
|
|
140
|
+
}, z.core.$strict>>>>;
|
|
114
141
|
}, z.core.$strict>;
|
|
115
142
|
export type DeploymentSettingsPatch = z.infer<typeof DEPLOYMENT_SETTINGS_PATCH>;
|
|
116
143
|
/**
|
|
@@ -145,6 +172,11 @@ export declare function readOrgMarketplaceBrowse(db: KernelSchemaDb): Promise<bo
|
|
|
145
172
|
export declare function readUiTheme(db: KernelSchemaDb, opts?: {
|
|
146
173
|
lock?: boolean;
|
|
147
174
|
}): Promise<UiTheme>;
|
|
175
|
+
/**
|
|
176
|
+
* The platform default arrangement of UI slots, read live (the lists apply it). An invalid
|
|
177
|
+
* stored value reads as `{}` (the same fallback {@link SettingsService.get} uses).
|
|
178
|
+
*/
|
|
179
|
+
export declare function readUiArrangement(db: KernelSchemaDb): Promise<UiArrangement>;
|
|
148
180
|
/** Deployment settings: one row per key, defaults for missing keys. */
|
|
149
181
|
export declare class SettingsService {
|
|
150
182
|
private readonly db;
|
|
@@ -15,6 +15,7 @@ import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
|
15
15
|
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
16
16
|
import { KERNEL_LOGGER } from "../infra/tokens.js";
|
|
17
17
|
import { assertPlatformDefaultEligible, lockThemeShared } from "../themes/theme-state.js";
|
|
18
|
+
import { mergeArrangement, UiArrangementPatchSchema, UiArrangementSchema, } from "../ui/arrangement.js";
|
|
18
19
|
import { audit } from "./audit.js";
|
|
19
20
|
import { SuperAdminLock } from "./super-admin.js";
|
|
20
21
|
/** 币种代码:ISO 4217 的三位大写字母(如 USD、CNY)。 */
|
|
@@ -100,6 +101,8 @@ export const DEPLOYMENT_SETTINGS = z.object({
|
|
|
100
101
|
orgMarketplaceBrowse: z.boolean().default(true),
|
|
101
102
|
/** The platform default theme (themes spec §7); `{ id: null }`: the built-in theme. */
|
|
102
103
|
uiTheme: UiThemeSetting.default({ id: null }),
|
|
104
|
+
/** The platform default arrangement of UI slots (UI slots spec §5); orgs override per slot. */
|
|
105
|
+
uiArrangement: UiArrangementSchema.default({}),
|
|
103
106
|
});
|
|
104
107
|
const DEFAULTS = DEPLOYMENT_SETTINGS.parse({});
|
|
105
108
|
/**
|
|
@@ -131,6 +134,8 @@ export const DEPLOYMENT_SETTINGS_PATCH = z
|
|
|
131
134
|
* disabled (else 400 `theme.not_available`), or `{ id: null }` for the built-in theme.
|
|
132
135
|
*/
|
|
133
136
|
uiTheme: UiThemeSetting.strict().optional(),
|
|
137
|
+
/** Per slot, the entry to hide / order contributions with; null removes a slot's entry. */
|
|
138
|
+
uiArrangement: UiArrangementPatchSchema.optional(),
|
|
134
139
|
})
|
|
135
140
|
.strict();
|
|
136
141
|
/**
|
|
@@ -240,6 +245,19 @@ async function lockUiThemeRow(db) {
|
|
|
240
245
|
.forUpdate()
|
|
241
246
|
.execute();
|
|
242
247
|
}
|
|
248
|
+
/**
|
|
249
|
+
* The platform default arrangement of UI slots, read live (the lists apply it). An invalid
|
|
250
|
+
* stored value reads as `{}` (the same fallback {@link SettingsService.get} uses).
|
|
251
|
+
*/
|
|
252
|
+
export async function readUiArrangement(db) {
|
|
253
|
+
const row = await db
|
|
254
|
+
.selectFrom("deployment_settings")
|
|
255
|
+
.select("value")
|
|
256
|
+
.where("key", "=", "uiArrangement")
|
|
257
|
+
.executeTakeFirst();
|
|
258
|
+
const parsed = UiArrangementSchema.safeParse(row?.value);
|
|
259
|
+
return parsed.success ? parsed.data : {};
|
|
260
|
+
}
|
|
243
261
|
/** 按组织合并覆盖:值为 null 删除该组织,其余整项替换;未列出的组织不变。 */
|
|
244
262
|
function mergeByOrg(current, patch) {
|
|
245
263
|
const merged = { ...current };
|
|
@@ -331,9 +349,15 @@ let SettingsService = class SettingsService {
|
|
|
331
349
|
}
|
|
332
350
|
next.uiTheme = { id: patch.uiTheme.id };
|
|
333
351
|
}
|
|
334
|
-
const { runConcurrencyOverrides: runPatch, sandboxLimitOverrides: sandboxPatch, subagentLimitOverrides: subagentPatch, } = patch;
|
|
335
|
-
if (runPatch !== undefined ||
|
|
352
|
+
const { runConcurrencyOverrides: runPatch, sandboxLimitOverrides: sandboxPatch, subagentLimitOverrides: subagentPatch, uiArrangement: arrangementPatch, } = patch;
|
|
353
|
+
if (runPatch !== undefined ||
|
|
354
|
+
sandboxPatch !== undefined ||
|
|
355
|
+
subagentPatch !== undefined ||
|
|
356
|
+
arrangementPatch !== undefined) {
|
|
336
357
|
const current = await this.get();
|
|
358
|
+
if (arrangementPatch !== undefined) {
|
|
359
|
+
next.uiArrangement = mergeArrangement(current.uiArrangement, arrangementPatch);
|
|
360
|
+
}
|
|
337
361
|
if (runPatch !== undefined) {
|
|
338
362
|
next.runConcurrencyOverrides = mergeByOrg(current.runConcurrencyOverrides, runPatch);
|
|
339
363
|
}
|
|
@@ -33,10 +33,10 @@ const HOT_APPLIERS = {
|
|
|
33
33
|
"models.embedTimeoutMs": () => { },
|
|
34
34
|
// SandboxService reads the shared-lease cap at every acquisition.
|
|
35
35
|
"sandbox.maxConcurrentCommands": () => { },
|
|
36
|
-
// The
|
|
37
|
-
"
|
|
38
|
-
// The device relay reads the reconnect grace at every disconnect and token response.
|
|
39
|
-
"
|
|
36
|
+
// The devices service reads the personal limit at every create.
|
|
37
|
+
"devices.maxPersonal": () => { },
|
|
38
|
+
// The local device relay reads the reconnect grace at every disconnect and token response.
|
|
39
|
+
"devices.local.reconnectGraceSeconds": () => { },
|
|
40
40
|
// Sub-agent limits are read at every dispatch, child step and tool resolution.
|
|
41
41
|
"subagents.maxDepth": () => { },
|
|
42
42
|
"subagents.maxConcurrentPerConversation": () => { },
|
package/dist/kernel.module.js
CHANGED
|
@@ -10,7 +10,6 @@ import { APP_INTERCEPTOR } from "@nestjs/core";
|
|
|
10
10
|
import { CatalogModule } from "./catalog/catalog.module.js";
|
|
11
11
|
import { ChannelsModule } from "./channels/channels.module.js";
|
|
12
12
|
import { TitlesModule } from "./conversations/titles.js";
|
|
13
|
-
import { DevicesModule } from "./devices/devices.module.js";
|
|
14
13
|
import { ExtensionsModule } from "./extensions/extensions.module.js";
|
|
15
14
|
import { ApiModule } from "./http/api.module.js";
|
|
16
15
|
import { ErrorFilterModule } from "./http/error-filter.module.js";
|
|
@@ -32,6 +31,7 @@ import { KERNEL_POOL, REDIS } from "./infra/tokens.js";
|
|
|
32
31
|
import { ValidationModule } from "./infra/validation/validation.module.js";
|
|
33
32
|
import { KernelLifecycle } from "./lifecycle/kernel-lifecycle.js";
|
|
34
33
|
import { KERNEL_APP_OPTIONS } from "./lifecycle/tokens.js";
|
|
34
|
+
import { LocalDevicesModule } from "./local-devices/local-devices.module.js";
|
|
35
35
|
import { createConfiguredLogger } from "./log-config.js";
|
|
36
36
|
import { KERNEL_OVERRIDE_TOKENS } from "./overrides.js";
|
|
37
37
|
import { PlatformModule } from "./platform/platform.module.js";
|
|
@@ -111,8 +111,8 @@ let KernelModule = KernelModule_1 = class KernelModule {
|
|
|
111
111
|
TitlesModule,
|
|
112
112
|
UsageReportModule,
|
|
113
113
|
ChannelsModule,
|
|
114
|
-
// the @
|
|
115
|
-
|
|
114
|
+
// the @local sandbox provider, registered on every role (any replica may relay to a machine)
|
|
115
|
+
LocalDevicesModule,
|
|
116
116
|
// the Platform tool's operation registry and actor facts
|
|
117
117
|
PlatformModule,
|
|
118
118
|
// its operations (skills, agents, ...), registered at start on every role
|
|
@@ -11,15 +11,15 @@ import { type DeviceAuthorizeBody, type DeviceConfirmBody, type DeviceTokenBody,
|
|
|
11
11
|
* they need `X-Capybara-Csrf: 1`, which `capybara-device` sends:
|
|
12
12
|
* - `POST /authorize { name, os, arch, programVersion }` → `{ deviceCode, userCode,
|
|
13
13
|
* verificationUri, verificationUriComplete, interval, expiresIn }` (`device-authorize-ip`);
|
|
14
|
-
* - `POST /token { deviceCode }` → `{ credential, orgId,
|
|
15
|
-
* reconnectGraceSeconds, maxFrameBytes }` once, else `
|
|
16
|
-
* `
|
|
14
|
+
* - `POST /token { deviceCode }` → `{ credential, orgId, deviceId, connectUrl,
|
|
15
|
+
* reconnectGraceSeconds, maxFrameBytes }` once, else `device_sign_in.authorization_pending` / `device_sign_in.slow_down` /
|
|
16
|
+
* `device_sign_in.denied` / `device_sign_in.expired` (`device-token-ip`).
|
|
17
17
|
*
|
|
18
18
|
* The person's routes need a web session (the confirmation page `/device`); each try of a user
|
|
19
19
|
* code counts on `device-code-account` (refunded on success):
|
|
20
20
|
* - `GET /pending/:userCode` → `{ machine, expiresAt }`;
|
|
21
|
-
* - `POST /confirm { userCode, orgId,
|
|
22
|
-
* (`
|
|
21
|
+
* - `POST /confirm { userCode, orgId, deviceId | name }` → `{ deviceId }`
|
|
22
|
+
* (`device_sign_in.expired` / `device_sign_in.unavailable` when the credential could not be handed over: the
|
|
23
23
|
* machine is revoked again and the person runs login again);
|
|
24
24
|
* - `POST /deny { userCode }` → 204.
|
|
25
25
|
*/
|
|
@@ -34,7 +34,7 @@ export declare class DeviceAuthController {
|
|
|
34
34
|
expiresAt: string;
|
|
35
35
|
}>;
|
|
36
36
|
confirm(principal: Principal, body: z.infer<typeof DeviceConfirmBody>, req: FastifyRequest, reply: FastifyReply): Promise<{
|
|
37
|
-
|
|
37
|
+
deviceId: string;
|
|
38
38
|
}>;
|
|
39
39
|
deny(principal: Principal, body: z.infer<typeof DeviceUserCodeBody>, req: FastifyRequest, reply: FastifyReply): Promise<void>;
|
|
40
40
|
/** Runs `fn` as one counted try of a user code; a success gives the try back. */
|
|
@@ -23,15 +23,15 @@ const CODE_THROTTLER = ["device-code-account"];
|
|
|
23
23
|
* they need `X-Capybara-Csrf: 1`, which `capybara-device` sends:
|
|
24
24
|
* - `POST /authorize { name, os, arch, programVersion }` → `{ deviceCode, userCode,
|
|
25
25
|
* verificationUri, verificationUriComplete, interval, expiresIn }` (`device-authorize-ip`);
|
|
26
|
-
* - `POST /token { deviceCode }` → `{ credential, orgId,
|
|
27
|
-
* reconnectGraceSeconds, maxFrameBytes }` once, else `
|
|
28
|
-
* `
|
|
26
|
+
* - `POST /token { deviceCode }` → `{ credential, orgId, deviceId, connectUrl,
|
|
27
|
+
* reconnectGraceSeconds, maxFrameBytes }` once, else `device_sign_in.authorization_pending` / `device_sign_in.slow_down` /
|
|
28
|
+
* `device_sign_in.denied` / `device_sign_in.expired` (`device-token-ip`).
|
|
29
29
|
*
|
|
30
30
|
* The person's routes need a web session (the confirmation page `/device`); each try of a user
|
|
31
31
|
* code counts on `device-code-account` (refunded on success):
|
|
32
32
|
* - `GET /pending/:userCode` → `{ machine, expiresAt }`;
|
|
33
|
-
* - `POST /confirm { userCode, orgId,
|
|
34
|
-
* (`
|
|
33
|
+
* - `POST /confirm { userCode, orgId, deviceId | name }` → `{ deviceId }`
|
|
34
|
+
* (`device_sign_in.expired` / `device_sign_in.unavailable` when the credential could not be handed over: the
|
|
35
35
|
* machine is revoked again and the person runs login again);
|
|
36
36
|
* - `POST /deny { userCode }` → 204.
|
|
37
37
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Redis } from "ioredis";
|
|
2
|
-
import {
|
|
2
|
+
import { DevicesService } from "../devices/devices.service.js";
|
|
3
3
|
import type { UserPrincipal } from "../identity/principal.js";
|
|
4
4
|
import { KernelConfigService } from "../infra/config/kernel-config.service.js";
|
|
5
5
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
@@ -10,8 +10,8 @@ import { MachinesService } from "./machines.js";
|
|
|
10
10
|
export declare const USER_CODE_ALPHABET = "BCDFGHJKLMNPQRSTVWXZ";
|
|
11
11
|
/** What `slow_down` adds to the poll interval (RFC 8628 §3.5). */
|
|
12
12
|
export declare const SLOW_DOWN_STEP_SECONDS = 5;
|
|
13
|
-
/** The web page that confirms a code: `<http.publicUrl>/
|
|
14
|
-
export declare const DEVICE_PAGE_PATH = "/
|
|
13
|
+
/** The web page that confirms a code: `<http.publicUrl>/devices/link`. */
|
|
14
|
+
export declare const DEVICE_PAGE_PATH = "/devices/link";
|
|
15
15
|
/** The machine's WebSocket route: `ws(s)://<http.publicUrl host>/device/connect`. */
|
|
16
16
|
export declare const DEVICE_CONNECT_PATH = "/device/connect";
|
|
17
17
|
/** The sign-in state of one device code: `capk:device-auth:<sha256(deviceCode)>` (a hash). */
|
|
@@ -28,7 +28,7 @@ export interface DeviceMachineInfo {
|
|
|
28
28
|
interface Grant {
|
|
29
29
|
credential: string;
|
|
30
30
|
orgId: string;
|
|
31
|
-
|
|
31
|
+
deviceId: string;
|
|
32
32
|
}
|
|
33
33
|
export interface DeviceAuthorization {
|
|
34
34
|
deviceCode: string;
|
|
@@ -41,7 +41,7 @@ export interface DeviceAuthorization {
|
|
|
41
41
|
export interface DeviceGrant extends Grant {
|
|
42
42
|
connectUrl: string;
|
|
43
43
|
reconnectGraceSeconds: number;
|
|
44
|
-
/** `
|
|
44
|
+
/** `devices.local.maxFrameBytes`: the program never sends a larger frame (ruling R26). */
|
|
45
45
|
maxFrameBytes: number;
|
|
46
46
|
}
|
|
47
47
|
/** A user code as typed → `XXXX-XXXX`, or null when it cannot be one. */
|
|
@@ -51,7 +51,7 @@ export declare function normalizeUserCode(input: string): string | null;
|
|
|
51
51
|
* for a code pair (`authorize`), the signed-in person confirms the user code on the web page
|
|
52
52
|
* `/device` (`pending`, `confirm` or `deny`), and the program polls `token` until it gets the
|
|
53
53
|
* machine credential, once. State lives only in Redis, both keys with the code's TTL
|
|
54
|
-
* (`
|
|
54
|
+
* (`devices.local.authCodeTtlSeconds`): `capk:device-auth:<sha256(deviceCode)>` (a hash:
|
|
55
55
|
* `info` JSON, `status`, `interval`, `lastPollAt`, the parked `grant`) and
|
|
56
56
|
* `capk:device-user:<userCode>` → the device code's hash. The device code itself is never stored.
|
|
57
57
|
*/
|
|
@@ -60,16 +60,16 @@ export declare class DeviceAuthService {
|
|
|
60
60
|
readonly txHost: TransactionHost;
|
|
61
61
|
private readonly redis;
|
|
62
62
|
private readonly config;
|
|
63
|
-
private readonly
|
|
63
|
+
private readonly devices;
|
|
64
64
|
private readonly machines;
|
|
65
65
|
private readonly log;
|
|
66
|
-
constructor(db: KernelDb, txHost: TransactionHost, redis: Redis, config: Pick<KernelConfigService, "get">,
|
|
66
|
+
constructor(db: KernelDb, txHost: TransactionHost, redis: Redis, config: Pick<KernelConfigService, "get">, devices: Pick<DevicesService, "createLocal">, machines: Pick<MachinesService, "issue" | "revokeMachine">, log: Pick<KernelLogger, "warn">);
|
|
67
67
|
/** A new code pair for a machine. Needs `http.publicUrl` (the page and the connection URL). */
|
|
68
68
|
authorize(machine: DeviceMachineInfo): Promise<DeviceAuthorization>;
|
|
69
69
|
/**
|
|
70
70
|
* The program's poll: the grant once the person confirmed (the code is consumed), else
|
|
71
|
-
* `
|
|
72
|
-
* interval), `
|
|
71
|
+
* `device_sign_in.authorization_pending`, `device_sign_in.slow_down` (details `[{ interval }]`, the grown
|
|
72
|
+
* interval), `device_sign_in.denied` or `device_sign_in.expired` (also for an unknown code).
|
|
73
73
|
*/
|
|
74
74
|
token(deviceCode: string): Promise<DeviceGrant>;
|
|
75
75
|
/** The machine waiting behind a user code, for the confirmation page. */
|
|
@@ -79,10 +79,10 @@ export declare class DeviceAuthService {
|
|
|
79
79
|
}>;
|
|
80
80
|
/**
|
|
81
81
|
* The person confirms a user code: in an org where they may use agents (`agents.use`), into
|
|
82
|
-
* one of their own live
|
|
83
|
-
* while the name is taken). One transaction creates the
|
|
84
|
-
* machine (revoking the
|
|
85
|
-
* `
|
|
82
|
+
* one of their own live local devices or a new one named `name` (` 2`, ` 3`, … appended
|
|
83
|
+
* while the name is taken). One transaction creates the device if needed, issues the
|
|
84
|
+
* machine (revoking the device's previous one) and audits
|
|
85
|
+
* `device.machine_connected` (retried once when a concurrent confirmation took the new
|
|
86
86
|
* name); after the commit the credential is parked for the poll ({@link park}). The code is
|
|
87
87
|
* claimed first, so two confirmations of one code cannot both issue a machine; a confirmation
|
|
88
88
|
* that fails before the commit leaves it pending.
|
|
@@ -90,28 +90,28 @@ export declare class DeviceAuthService {
|
|
|
90
90
|
confirm(principal: UserPrincipal, input: {
|
|
91
91
|
userCode: string;
|
|
92
92
|
orgId: string;
|
|
93
|
-
|
|
93
|
+
deviceId?: string | undefined;
|
|
94
94
|
name?: string | undefined;
|
|
95
95
|
}): Promise<{
|
|
96
|
-
|
|
96
|
+
deviceId: string;
|
|
97
97
|
}>;
|
|
98
98
|
/**
|
|
99
99
|
* Parks the committed machine's credential for the poll. When that fails (the code expired
|
|
100
100
|
* meanwhile, or Redis failed) the machine is revoked again, so no credential nobody holds stays
|
|
101
|
-
* valid, and the person is told to start over: `
|
|
101
|
+
* valid, and the person is told to start over: `device_sign_in.expired` / `device_sign_in.unavailable`.
|
|
102
102
|
*/
|
|
103
103
|
private park;
|
|
104
104
|
/** Revokes a machine whose credential never reached the program (see {@link park}). */
|
|
105
105
|
private abandon;
|
|
106
|
-
/** The person refuses a user code: the program's next poll gets `
|
|
106
|
+
/** The person refuses a user code: the program's next poll gets `device_sign_in.denied`. */
|
|
107
107
|
deny(userCode: string): Promise<void>;
|
|
108
108
|
private confirmIn;
|
|
109
109
|
/** `name`, or `name 2`, `name 3`, … : the first that is none of the person's live names. */
|
|
110
110
|
private freeName;
|
|
111
|
-
/** The code behind a user code with status `status`, else `
|
|
111
|
+
/** The code behind a user code with status `status`, else `device_sign_in.code_invalid`. */
|
|
112
112
|
private lookup;
|
|
113
113
|
private transition;
|
|
114
|
-
/** `http.publicUrl` without trailing slashes; unset → `
|
|
114
|
+
/** `http.publicUrl` without trailing slashes; unset → `device.unavailable`. */
|
|
115
115
|
private publicUrl;
|
|
116
116
|
/** The machine's WebSocket URL: the public URL with `ws` / `wss` and `/device/connect`. */
|
|
117
117
|
private connectUrl;
|