@capybara-hq/kernel 0.1.0-rc.13 → 0.1.0-rc.15
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 +5 -13
- package/dist/catalog/admin-catalog.controller.d.ts +39 -5
- package/dist/catalog/admin-catalog.controller.js +75 -6
- package/dist/catalog/admin-catalog.schemas.d.ts +10 -0
- package/dist/catalog/admin-catalog.schemas.js +7 -0
- package/dist/catalog/appearance.schemas.d.ts +10 -0
- package/dist/catalog/appearance.schemas.js +20 -0
- package/dist/catalog/appearance.service.d.ts +105 -0
- package/dist/catalog/appearance.service.js +306 -0
- package/dist/catalog/catalog-content.d.ts +9 -1
- package/dist/catalog/catalog-content.js +2 -1
- package/dist/catalog/catalog-files.d.ts +3 -2
- package/dist/catalog/catalog-files.js +8 -5
- package/dist/catalog/catalog-import.module.js +3 -0
- package/dist/catalog/catalog-items.d.ts +11 -0
- package/dist/catalog/catalog-items.js +21 -0
- package/dist/catalog/catalog-scope.service.d.ts +7 -0
- package/dist/catalog/catalog-scope.service.js +55 -15
- package/dist/catalog/catalog.service.js +10 -2
- package/dist/catalog/cli.js +3 -0
- package/dist/catalog/component-scope.service.d.ts +14 -1
- package/dist/catalog/component-scope.service.js +12 -2
- package/dist/catalog/marketplaces.service.d.ts +1 -1
- package/dist/catalog/org-catalog.controller.d.ts +5 -4
- package/dist/catalog/org-catalog.controller.js +5 -4
- package/dist/catalog/org-catalog.schemas.d.ts +18 -2
- package/dist/catalog/org-catalog.schemas.js +16 -2
- package/dist/catalog/org-catalog.service.js +8 -2
- package/dist/catalog/org-extension.controller.d.ts +27 -7
- package/dist/catalog/org-extension.controller.js +48 -6
- package/dist/catalog/plugin-import.d.ts +28 -4
- package/dist/catalog/plugin-import.js +96 -20
- package/dist/catalog/plugin-package.d.ts +4 -2
- package/dist/catalog/plugin-package.js +66 -12
- package/dist/catalog/plugin-upgrade.d.ts +15 -1
- package/dist/catalog/plugin-upgrade.js +18 -5
- package/dist/channels/connections.controller.d.ts +1 -1
- package/dist/channels/connections.controller.js +1 -1
- package/dist/channels/connections.service.d.ts +22 -5
- package/dist/channels/connections.service.js +56 -10
- package/dist/channels/webhook.d.ts +21 -1
- package/dist/channels/webhook.js +39 -4
- package/dist/client/client-access.service.d.ts +101 -0
- package/dist/client/client-access.service.js +294 -0
- package/dist/client/client-builds.service.d.ts +109 -0
- package/dist/client/client-builds.service.js +229 -0
- package/dist/client/client-delivery.controller.d.ts +25 -0
- package/dist/client/client-delivery.controller.js +66 -0
- package/dist/client/client-files.d.ts +48 -0
- package/dist/client/client-files.js +136 -0
- package/dist/client/client-reports.cron.d.ts +13 -0
- package/dist/client/client-reports.cron.js +42 -0
- package/dist/client/client-reports.service.d.ts +30 -0
- package/dist/client/client-reports.service.js +102 -0
- package/dist/client/client.controller.d.ts +45 -0
- package/dist/client/client.controller.js +121 -0
- package/dist/client/client.module.d.ts +7 -0
- package/dist/client/client.module.js +26 -0
- package/dist/client/client.schemas.d.ts +55 -0
- package/dist/client/client.schemas.js +27 -0
- package/dist/ctx/create-ctx.d.ts +19 -4
- package/dist/ctx/create-ctx.js +51 -3
- package/dist/db/kernel-schema.d.ts +58 -2
- package/dist/errors.d.ts +33 -0
- package/dist/errors.js +33 -0
- package/dist/extensions/admin-ops.d.ts +4 -1
- package/dist/extensions/admin-ops.js +22 -1
- package/dist/extensions/admin-view.d.ts +8 -0
- package/dist/extensions/admin-view.js +78 -0
- package/dist/extensions/blobs.d.ts +14 -1
- package/dist/extensions/blobs.js +48 -5
- package/dist/extensions/guide-places.d.ts +66 -0
- package/dist/extensions/guide-places.js +152 -0
- package/dist/extensions/host.d.ts +6 -1
- package/dist/extensions/host.js +23 -12
- package/dist/extensions/instance.d.ts +5 -1
- package/dist/extensions/instance.js +8 -0
- package/dist/extensions/ledger.d.ts +1 -1
- package/dist/extensions/package.d.ts +4 -3
- package/dist/extensions/package.js +5 -1
- package/dist/extensions/permission-set.d.ts +35 -5
- package/dist/extensions/permission-set.js +36 -5
- package/dist/extensions/permission-view.d.ts +38 -7
- package/dist/extensions/permission-view.js +27 -8
- package/dist/extensions/plugin-guides.d.ts +207 -54
- package/dist/extensions/plugin-guides.js +436 -165
- package/dist/extensions/sources.d.ts +6 -0
- package/dist/extensions/sources.js +2 -0
- package/dist/extensions/state.module.js +9 -1
- package/dist/http/api.module.js +16 -0
- package/dist/identity/settings.d.ts +41 -26
- package/dist/identity/settings.js +87 -4
- package/dist/infra/lock/lock.service.d.ts +8 -0
- package/dist/infra/lock/lock.service.js +27 -0
- package/dist/infra/throttler/named-throttlers.d.ts +8 -1
- package/dist/infra/throttler/named-throttlers.js +30 -1
- package/dist/infra/throttler/throttler.guard.js +1 -1
- package/dist/kernel.module.js +3 -0
- package/dist/orgs/settings.service.d.ts +2 -26
- package/dist/overrides.d.ts +3 -1
- package/dist/overrides.js +2 -0
- package/dist/platform/exclusions.js +37 -6
- package/dist/platform/operation.js +4 -0
- package/dist/platform/ops/admin.ops.js +17 -2
- package/dist/platform/ops/catalog-admin.ops.d.ts +19 -1
- package/dist/platform/ops/catalog-admin.ops.js +85 -2
- package/dist/platform/ops/connectors.ops.js +2 -0
- package/dist/platform/ops/org-plugins.ops.d.ts +7 -1
- package/dist/platform/ops/org-plugins.ops.js +63 -4
- package/dist/platform/ops/org-settings.ops.js +2 -2
- package/dist/platform/ops/orgs.ops.js +1 -0
- package/dist/platform/ops/setup.ops.d.ts +24 -0
- package/dist/platform/ops/setup.ops.js +212 -0
- package/dist/platform/ops/ui.ops.js +1 -1
- package/dist/platform/platform-ops.module.d.ts +2 -1
- package/dist/platform/platform-ops.module.js +7 -0
- package/dist/platform/route-schemas.js +8 -0
- package/dist/roles/worker.module.js +4 -0
- package/dist/setup/kernel-checks.d.ts +91 -0
- package/dist/setup/kernel-checks.js +295 -0
- package/dist/setup/oauth-token-probe.d.ts +47 -0
- package/dist/setup/oauth-token-probe.js +108 -0
- package/dist/setup/redact-check.d.ts +18 -0
- package/dist/setup/redact-check.js +46 -0
- package/dist/setup/setup-check-registry.d.ts +86 -0
- package/dist/setup/setup-check-registry.js +75 -0
- package/dist/setup/setup-checks.controller.d.ts +28 -0
- package/dist/setup/setup-checks.controller.js +78 -0
- package/dist/setup/setup-checks.schemas.d.ts +38 -0
- package/dist/setup/setup-checks.schemas.js +43 -0
- package/dist/setup/setup-checks.service.d.ts +144 -0
- package/dist/setup/setup-checks.service.js +683 -0
- package/dist/setup/setup-guides.controller.d.ts +18 -0
- package/dist/setup/setup-guides.controller.js +48 -0
- package/dist/setup/setup-guides.schemas.d.ts +10 -0
- package/dist/setup/setup-guides.schemas.js +6 -0
- package/dist/setup/setup-guides.service.d.ts +126 -0
- package/dist/setup/setup-guides.service.js +315 -0
- package/dist/setup/setup.module.d.ts +8 -0
- package/dist/setup/setup.module.js +31 -0
- package/dist/themes/render-css.d.ts +2 -1
- package/dist/themes/render-css.js +5 -2
- package/dist/themes/theme-delivery.service.d.ts +4 -2
- package/dist/themes/theme-delivery.service.js +8 -3
- package/dist/themes/theme-state.d.ts +28 -7
- package/dist/themes/theme-state.js +24 -6
- package/dist/themes/themes-public.controller.d.ts +7 -2
- package/dist/themes/themes-public.controller.js +11 -5
- package/dist/themes/themes.service.js +2 -2
- package/dist/tools/connectors.controller.d.ts +28 -11
- package/dist/tools/connectors.controller.js +49 -14
- package/dist/tools/connectors.schemas.d.ts +4 -0
- package/dist/tools/connectors.schemas.js +4 -0
- package/dist/tools/connectors.service.d.ts +30 -2
- package/dist/tools/connectors.service.js +98 -3
- package/dist/tools/credentials.d.ts +20 -0
- package/dist/tools/credentials.js +90 -1
- package/dist/tools/oauth/tokens.d.ts +20 -0
- package/dist/tools/oauth/tokens.js +49 -24
- package/dist/tools/pipeline.d.ts +3 -2
- package/dist/ui/arrangement.d.ts +41 -50
- package/dist/ui/arrangement.js +88 -15
- package/dist/ui/registry.d.ts +13 -3
- package/dist/ui/registry.js +15 -4
- package/dist/ui/ui.schemas.d.ts +4 -0
- package/dist/ui/views.d.ts +36 -9
- package/dist/ui/views.js +58 -28
- package/package.json +3 -3
- package/src/migrations/0106_setup_guides_v2.sql +10 -0
- package/src/migrations/0107_extension_client_builds.sql +50 -0
|
@@ -36,6 +36,12 @@ export interface ExtensionLoadStatus {
|
|
|
36
36
|
* 省略视同 null。
|
|
37
37
|
*/
|
|
38
38
|
servingVersion?: string | null;
|
|
39
|
+
/**
|
|
40
|
+
* The package sha256 this replica serves for the plugin: the row's own `sha256` when `loaded`,
|
|
41
|
+
* the older package still running beside a failed / pending version, null when none runs.
|
|
42
|
+
* Omitted counts as null.
|
|
43
|
+
*/
|
|
44
|
+
servingSha256?: string | null;
|
|
39
45
|
}
|
|
40
46
|
/** This replica's extension load status (PG `extension_replica_status`; each replica writes only its own rows). */
|
|
41
47
|
export declare class ReplicaStatusStore {
|
|
@@ -55,6 +55,7 @@ let ReplicaStatusStore = class ReplicaStatusStore {
|
|
|
55
55
|
reason: s.reason,
|
|
56
56
|
detail: s.detail === null ? null : this.cleanDetail(s.detail),
|
|
57
57
|
serving_version: s.servingVersion ?? null,
|
|
58
|
+
serving_sha256: s.servingSha256 ?? null,
|
|
58
59
|
http_replica_id: this.httpReplicaId ?? null,
|
|
59
60
|
heartbeat_at: sql `now()`,
|
|
60
61
|
};
|
|
@@ -69,6 +70,7 @@ let ReplicaStatusStore = class ReplicaStatusStore {
|
|
|
69
70
|
reason: values.reason,
|
|
70
71
|
detail: values.detail,
|
|
71
72
|
serving_version: values.serving_version,
|
|
73
|
+
serving_sha256: values.serving_sha256,
|
|
72
74
|
http_replica_id: values.http_replica_id,
|
|
73
75
|
heartbeat_at: values.heartbeat_at,
|
|
74
76
|
}))
|
|
@@ -5,6 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
import { Module } from "@nestjs/common";
|
|
8
|
+
import { ClientModule } from "../client/client.module.js";
|
|
8
9
|
import { SuperAdminLockModule } from "../identity/super-admin.js";
|
|
9
10
|
import { OrgLockModule } from "../orgs/org-lock.js";
|
|
10
11
|
import { StorageModule } from "../storage/storage.module.js";
|
|
@@ -24,7 +25,14 @@ let ExtensionStateModule = class ExtensionStateModule {
|
|
|
24
25
|
};
|
|
25
26
|
ExtensionStateModule = __decorate([
|
|
26
27
|
Module({
|
|
27
|
-
imports: [
|
|
28
|
+
imports: [
|
|
29
|
+
ExtensionRegistryModule,
|
|
30
|
+
SuperAdminLockModule,
|
|
31
|
+
OrgLockModule,
|
|
32
|
+
StorageModule,
|
|
33
|
+
// a package with client code stores its client build (`ExtensionBlobs`)
|
|
34
|
+
ClientModule,
|
|
35
|
+
],
|
|
28
36
|
providers: [ExtensionApprovals, ExtensionBlobs, ExtensionInstalls, EffectiveConfigs],
|
|
29
37
|
exports: [
|
|
30
38
|
ExtensionRegistryModule,
|
package/dist/http/api.module.js
CHANGED
|
@@ -19,6 +19,7 @@ import { AgentSaveAsTemplateController, AgentTemplatesController, } from "../age
|
|
|
19
19
|
import { BackgroundController } from "../background/background.controller.js";
|
|
20
20
|
import { BackgroundModule } from "../background/background.module.js";
|
|
21
21
|
import { AdminCatalogController } from "../catalog/admin-catalog.controller.js";
|
|
22
|
+
import { AppearanceModule } from "../catalog/appearance.service.js";
|
|
22
23
|
import { CatalogModule } from "../catalog/catalog.module.js";
|
|
23
24
|
import { AdminComponentsController, OrgComponentsController, } from "../catalog/component-scope.controller.js";
|
|
24
25
|
import { MarketplacesController, OrgMarketplacesController, } from "../catalog/marketplaces.controller.js";
|
|
@@ -27,6 +28,9 @@ import { OrgExtensionConfigsController, OrgExtensionOverridesController, OrgExte
|
|
|
27
28
|
import { OrgOwnedPluginsController, OrgPluginUploadsController, } from "../catalog/org-plugin-uploads.controller.js";
|
|
28
29
|
import { ChannelsModule } from "../channels/channels.module.js";
|
|
29
30
|
import { ChannelConnectionsController } from "../channels/connections.controller.js";
|
|
31
|
+
import { AdminClientController, OrgClientController } from "../client/client.controller.js";
|
|
32
|
+
import { ClientModule } from "../client/client.module.js";
|
|
33
|
+
import { ClientDeliveryController } from "../client/client-delivery.controller.js";
|
|
30
34
|
import { AttachmentsController } from "../conversations/attachments.controller.js";
|
|
31
35
|
import { ConversationsController } from "../conversations/conversations.controller.js";
|
|
32
36
|
import { ConversationsModule } from "../conversations/conversations.module.js";
|
|
@@ -60,6 +64,9 @@ import { OrgsModule } from "../orgs/orgs.module.js";
|
|
|
60
64
|
import { OrgSettingsController } from "../orgs/settings.controller.js";
|
|
61
65
|
import { RuntimeModule } from "../runtime/runtime.module.js";
|
|
62
66
|
import { ConversationStreamController } from "../runtime/stream.controller.js";
|
|
67
|
+
import { SetupModule } from "../setup/setup.module.js";
|
|
68
|
+
import { SetupChecksController } from "../setup/setup-checks.controller.js";
|
|
69
|
+
import { SetupGuidesController } from "../setup/setup-guides.controller.js";
|
|
63
70
|
import { AgentSkillsController, InboxController, SkillChangesController, } from "../skills/changes.controller.js";
|
|
64
71
|
import { InvocableSkillsController } from "../skills/invocable.controller.js";
|
|
65
72
|
import { SkillsController } from "../skills/skills.controller.js";
|
|
@@ -138,6 +145,8 @@ const CONTROLLERS = [
|
|
|
138
145
|
EvalRunsController,
|
|
139
146
|
ModelPurposesController,
|
|
140
147
|
OrgCatalogController,
|
|
148
|
+
SetupChecksController,
|
|
149
|
+
SetupGuidesController,
|
|
141
150
|
OrgPluginUploadsController,
|
|
142
151
|
OrgOwnedPluginsController,
|
|
143
152
|
OrgComponentsController,
|
|
@@ -146,6 +155,9 @@ const CONTROLLERS = [
|
|
|
146
155
|
ThemeDeliveryController,
|
|
147
156
|
PlatformThemeController,
|
|
148
157
|
DeviceAuthController,
|
|
158
|
+
ClientDeliveryController,
|
|
159
|
+
OrgClientController,
|
|
160
|
+
AdminClientController,
|
|
149
161
|
];
|
|
150
162
|
/**
|
|
151
163
|
* The api role (nest kernel spec §2): the kernel API (`/api/v1/*`), imported by `KernelModule` only
|
|
@@ -166,6 +178,8 @@ ApiModule = __decorate([
|
|
|
166
178
|
AdminModule,
|
|
167
179
|
ExtensionsModule,
|
|
168
180
|
CatalogModule,
|
|
181
|
+
// a plugin's suggested appearance (its own module: it writes through the org settings)
|
|
182
|
+
AppearanceModule,
|
|
169
183
|
ToolsModule,
|
|
170
184
|
AgentsModule,
|
|
171
185
|
ConversationsModule,
|
|
@@ -179,6 +193,8 @@ ApiModule = __decorate([
|
|
|
179
193
|
UiModule,
|
|
180
194
|
InboxModule,
|
|
181
195
|
ThemesModule,
|
|
196
|
+
ClientModule,
|
|
197
|
+
SetupModule,
|
|
182
198
|
],
|
|
183
199
|
controllers: CONTROLLERS,
|
|
184
200
|
providers: [{ provide: APP_GUARD, useClass: AuthGuard }],
|
|
@@ -44,6 +44,31 @@ export declare const UiThemeSetting: z.ZodObject<{
|
|
|
44
44
|
id: z.ZodNullable<z.ZodString>;
|
|
45
45
|
}, z.core.$strip>;
|
|
46
46
|
export type UiTheme = z.infer<typeof UiThemeSetting>;
|
|
47
|
+
/** The deployment setting key of the client code kill switch (client extensions spec §10.2). */
|
|
48
|
+
export declare const CLIENT_EXTENSIONS_SETTING = "clientExtensions";
|
|
49
|
+
/** The plugins listed in `clientExtensions.disabled`: at most this many. */
|
|
50
|
+
export declare const CLIENT_DISABLED_MAX = 200;
|
|
51
|
+
/**
|
|
52
|
+
* The client code kill switch (client extensions spec §10.2): `enabled: false` stops every plugin's
|
|
53
|
+
* client code (the shell reads list nothing, delivery is 404); `disabled` names the plugins whose
|
|
54
|
+
* client code alone is stopped while their server side keeps running. Every reader goes through
|
|
55
|
+
* {@link readClientExtensions} or {@link SettingsService.get}.
|
|
56
|
+
*/
|
|
57
|
+
export declare const ClientExtensionsSetting: z.ZodObject<{
|
|
58
|
+
enabled: z.ZodBoolean;
|
|
59
|
+
disabled: z.ZodArray<z.ZodString>;
|
|
60
|
+
}, z.core.$strip>;
|
|
61
|
+
export type ClientExtensionsKillSwitch = z.infer<typeof ClientExtensionsSetting>;
|
|
62
|
+
/** The kill switch's default (and what a missing or invalid stored value reads as): everything on. */
|
|
63
|
+
export declare const clientExtensionsDefault: () => ClientExtensionsKillSwitch;
|
|
64
|
+
/**
|
|
65
|
+
* Parses a stored `clientExtensions` value (the `deployment_settings` row's `value`, undefined when
|
|
66
|
+
* the row is missing): the default when missing; when invalid the default too, with a warning naming
|
|
67
|
+
* the key (a kill switch that fails open is worth a log line, as {@link SettingsService.get} logs
|
|
68
|
+
* every other invalid key). The one parser of the setting: the settings service and every access
|
|
69
|
+
* check read through it.
|
|
70
|
+
*/
|
|
71
|
+
export declare function parseClientExtensions(value: unknown, log?: Pick<KernelLogger, "warn">): ClientExtensionsKillSwitch;
|
|
47
72
|
export declare const DEPLOYMENT_SETTINGS: z.ZodObject<{
|
|
48
73
|
orgCreation: z.ZodDefault<z.ZodEnum<{
|
|
49
74
|
anyone: "anyone";
|
|
@@ -73,19 +98,11 @@ export declare const DEPLOYMENT_SETTINGS: z.ZodObject<{
|
|
|
73
98
|
uiTheme: z.ZodDefault<z.ZodObject<{
|
|
74
99
|
id: z.ZodNullable<z.ZodString>;
|
|
75
100
|
}, z.core.$strip>>;
|
|
76
|
-
uiArrangement: z.ZodDefault<z.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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>>>;
|
|
101
|
+
uiArrangement: z.ZodDefault<z.ZodType<Partial<Record<"agent.detail.section" | "conversation.composer.frame" | "conversation.empty" | "conversation.panel" | "conversation.properties.section" | "conversation.tool-result.card" | "file.preview" | "org.page" | "org.settings.section" | "platform.page" | "shell.brand" | "shell.overlay", import("../ui/arrangement.js").UiArrangementEntry>>, unknown, z.core.$ZodTypeInternals<Partial<Record<"agent.detail.section" | "conversation.composer.frame" | "conversation.empty" | "conversation.panel" | "conversation.properties.section" | "conversation.tool-result.card" | "file.preview" | "org.page" | "org.settings.section" | "platform.page" | "shell.brand" | "shell.overlay", import("../ui/arrangement.js").UiArrangementEntry>>, unknown>>>;
|
|
102
|
+
clientExtensions: z.ZodDefault<z.ZodObject<{
|
|
103
|
+
enabled: z.ZodBoolean;
|
|
104
|
+
disabled: z.ZodArray<z.ZodString>;
|
|
105
|
+
}, z.core.$strip>>;
|
|
89
106
|
}, z.core.$strip>;
|
|
90
107
|
export type DeploymentSettings = z.infer<typeof DEPLOYMENT_SETTINGS>;
|
|
91
108
|
/**
|
|
@@ -125,19 +142,11 @@ export declare const DEPLOYMENT_SETTINGS_PATCH: z.ZodObject<{
|
|
|
125
142
|
uiTheme: z.ZodOptional<z.ZodObject<{
|
|
126
143
|
id: z.ZodNullable<z.ZodString>;
|
|
127
144
|
}, z.core.$strict>>;
|
|
128
|
-
uiArrangement: z.ZodOptional<z.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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>>>>;
|
|
145
|
+
uiArrangement: z.ZodOptional<z.ZodType<Partial<Record<"agent.detail.section" | "conversation.composer.frame" | "conversation.empty" | "conversation.panel" | "conversation.properties.section" | "conversation.tool-result.card" | "file.preview" | "org.page" | "org.settings.section" | "platform.page" | "shell.brand" | "shell.overlay", import("../ui/arrangement.js").UiArrangementEntry | null>>, unknown, z.core.$ZodTypeInternals<Partial<Record<"agent.detail.section" | "conversation.composer.frame" | "conversation.empty" | "conversation.panel" | "conversation.properties.section" | "conversation.tool-result.card" | "file.preview" | "org.page" | "org.settings.section" | "platform.page" | "shell.brand" | "shell.overlay", import("../ui/arrangement.js").UiArrangementEntry | null>>, unknown>>>;
|
|
146
|
+
clientExtensions: z.ZodOptional<z.ZodObject<{
|
|
147
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
148
|
+
disabled: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
149
|
+
}, z.core.$strict>>;
|
|
141
150
|
}, z.core.$strict>;
|
|
142
151
|
export type DeploymentSettingsPatch = z.infer<typeof DEPLOYMENT_SETTINGS_PATCH>;
|
|
143
152
|
/**
|
|
@@ -177,6 +186,12 @@ export declare function readUiTheme(db: KernelSchemaDb, opts?: {
|
|
|
177
186
|
* stored value reads as `{}` (the same fallback {@link SettingsService.get} uses).
|
|
178
187
|
*/
|
|
179
188
|
export declare function readUiArrangement(db: KernelSchemaDb): Promise<UiArrangement>;
|
|
189
|
+
/**
|
|
190
|
+
* The client code kill switch, read live from PG on every request (in the caller's transaction when
|
|
191
|
+
* there is one; never cached: every replica sees a change at once), through
|
|
192
|
+
* {@link parseClientExtensions} (missing or invalid -> everything on; invalid also warns on `log`).
|
|
193
|
+
*/
|
|
194
|
+
export declare function readClientExtensions(db: KernelSchemaDb, log?: Pick<KernelLogger, "warn">): Promise<ClientExtensionsKillSwitch>;
|
|
180
195
|
/** Deployment settings: one row per key, defaults for missing keys. */
|
|
181
196
|
export declare class SettingsService {
|
|
182
197
|
private readonly db;
|
|
@@ -7,6 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
|
+
import { EXTENSION_NAME_RE } from "@capybara-hq/plugin-sdk";
|
|
10
11
|
import { Inject, Injectable } from "@nestjs/common";
|
|
11
12
|
import { z } from "zod";
|
|
12
13
|
import { ApiError } from "../errors.js";
|
|
@@ -74,6 +75,47 @@ export const UI_THEME_SETTING = "uiTheme";
|
|
|
74
75
|
* {@link SettingsService.get}, both parsing with this schema.
|
|
75
76
|
*/
|
|
76
77
|
export const UiThemeSetting = z.object({ id: z.string().min(1).max(200).nullable() });
|
|
78
|
+
/** The deployment setting key of the client code kill switch (client extensions spec §10.2). */
|
|
79
|
+
export const CLIENT_EXTENSIONS_SETTING = "clientExtensions";
|
|
80
|
+
/** The plugins listed in `clientExtensions.disabled`: at most this many. */
|
|
81
|
+
export const CLIENT_DISABLED_MAX = 200;
|
|
82
|
+
const ClientDisabledList = z
|
|
83
|
+
.array(z.string().regex(EXTENSION_NAME_RE, "must be an extension name"))
|
|
84
|
+
.max(CLIENT_DISABLED_MAX);
|
|
85
|
+
/**
|
|
86
|
+
* The client code kill switch (client extensions spec §10.2): `enabled: false` stops every plugin's
|
|
87
|
+
* client code (the shell reads list nothing, delivery is 404); `disabled` names the plugins whose
|
|
88
|
+
* client code alone is stopped while their server side keeps running. Every reader goes through
|
|
89
|
+
* {@link readClientExtensions} or {@link SettingsService.get}.
|
|
90
|
+
*/
|
|
91
|
+
export const ClientExtensionsSetting = z.object({
|
|
92
|
+
enabled: z.boolean(),
|
|
93
|
+
disabled: ClientDisabledList,
|
|
94
|
+
});
|
|
95
|
+
/** The kill switch's default (and what a missing or invalid stored value reads as): everything on. */
|
|
96
|
+
export const clientExtensionsDefault = () => ({
|
|
97
|
+
enabled: true,
|
|
98
|
+
disabled: [],
|
|
99
|
+
});
|
|
100
|
+
/**
|
|
101
|
+
* Parses a stored `clientExtensions` value (the `deployment_settings` row's `value`, undefined when
|
|
102
|
+
* the row is missing): the default when missing; when invalid the default too, with a warning naming
|
|
103
|
+
* the key (a kill switch that fails open is worth a log line, as {@link SettingsService.get} logs
|
|
104
|
+
* every other invalid key). The one parser of the setting: the settings service and every access
|
|
105
|
+
* check read through it.
|
|
106
|
+
*/
|
|
107
|
+
export function parseClientExtensions(value, log) {
|
|
108
|
+
if (value === undefined)
|
|
109
|
+
return clientExtensionsDefault();
|
|
110
|
+
const parsed = ClientExtensionsSetting.safeParse(value);
|
|
111
|
+
if (parsed.success)
|
|
112
|
+
return parsed.data;
|
|
113
|
+
log?.warn("invalid deployment setting; using default", {
|
|
114
|
+
key: CLIENT_EXTENSIONS_SETTING,
|
|
115
|
+
issues: parsed.error.issues.map((i) => i.message),
|
|
116
|
+
});
|
|
117
|
+
return clientExtensionsDefault();
|
|
118
|
+
}
|
|
77
119
|
export const DEPLOYMENT_SETTINGS = z.object({
|
|
78
120
|
orgCreation: z.enum(["anyone", "super_admin"]).default("anyone"),
|
|
79
121
|
/** 按组织覆盖运行并发上限(orgId → 上限);未列出的组织用 `runtime.orgConcurrency`。 */
|
|
@@ -101,8 +143,13 @@ export const DEPLOYMENT_SETTINGS = z.object({
|
|
|
101
143
|
orgMarketplaceBrowse: z.boolean().default(true),
|
|
102
144
|
/** The platform default theme (themes spec §7); `{ id: null }`: the built-in theme. */
|
|
103
145
|
uiTheme: UiThemeSetting.default({ id: null }),
|
|
104
|
-
/**
|
|
146
|
+
/**
|
|
147
|
+
* The platform default arrangement of UI slots (UI slots spec §5): `{ hidden, order }` per list
|
|
148
|
+
* slot, `{ use }` per single slot (client extensions spec §6.3); orgs override per slot.
|
|
149
|
+
*/
|
|
105
150
|
uiArrangement: UiArrangementSchema.default({}),
|
|
151
|
+
/** The client code kill switch (client extensions spec §10.2). */
|
|
152
|
+
clientExtensions: ClientExtensionsSetting.default(clientExtensionsDefault),
|
|
106
153
|
});
|
|
107
154
|
const DEFAULTS = DEPLOYMENT_SETTINGS.parse({});
|
|
108
155
|
/**
|
|
@@ -134,8 +181,22 @@ export const DEPLOYMENT_SETTINGS_PATCH = z
|
|
|
134
181
|
* disabled (else 400 `theme.not_available`), or `{ id: null }` for the built-in theme.
|
|
135
182
|
*/
|
|
136
183
|
uiTheme: UiThemeSetting.strict().optional(),
|
|
137
|
-
/**
|
|
184
|
+
/**
|
|
185
|
+
* Per slot, the entry to hide / order contributions with (`{ use }` on a single slot); null
|
|
186
|
+
* removes a slot's entry.
|
|
187
|
+
*/
|
|
138
188
|
uiArrangement: UiArrangementPatchSchema.optional(),
|
|
189
|
+
/**
|
|
190
|
+
* The client code kill switch: each given field replaces the stored one (`disabled` is the
|
|
191
|
+
* whole list, stored sorted without duplicates); at least one field.
|
|
192
|
+
*/
|
|
193
|
+
clientExtensions: z
|
|
194
|
+
.object({ enabled: z.boolean().optional(), disabled: ClientDisabledList.optional() })
|
|
195
|
+
.strict()
|
|
196
|
+
.refine((o) => o.enabled !== undefined || o.disabled !== undefined, {
|
|
197
|
+
message: "give enabled, disabled or both",
|
|
198
|
+
})
|
|
199
|
+
.optional(),
|
|
139
200
|
})
|
|
140
201
|
.strict();
|
|
141
202
|
/**
|
|
@@ -258,6 +319,19 @@ export async function readUiArrangement(db) {
|
|
|
258
319
|
const parsed = UiArrangementSchema.safeParse(row?.value);
|
|
259
320
|
return parsed.success ? parsed.data : {};
|
|
260
321
|
}
|
|
322
|
+
/**
|
|
323
|
+
* The client code kill switch, read live from PG on every request (in the caller's transaction when
|
|
324
|
+
* there is one; never cached: every replica sees a change at once), through
|
|
325
|
+
* {@link parseClientExtensions} (missing or invalid -> everything on; invalid also warns on `log`).
|
|
326
|
+
*/
|
|
327
|
+
export async function readClientExtensions(db, log) {
|
|
328
|
+
const row = await db
|
|
329
|
+
.selectFrom("deployment_settings")
|
|
330
|
+
.select("value")
|
|
331
|
+
.where("key", "=", CLIENT_EXTENSIONS_SETTING)
|
|
332
|
+
.executeTakeFirst();
|
|
333
|
+
return parseClientExtensions(row?.value, log);
|
|
334
|
+
}
|
|
261
335
|
/** 按组织合并覆盖:值为 null 删除该组织,其余整项替换;未列出的组织不变。 */
|
|
262
336
|
function mergeByOrg(current, patch) {
|
|
263
337
|
const merged = { ...current };
|
|
@@ -349,12 +423,21 @@ let SettingsService = class SettingsService {
|
|
|
349
423
|
}
|
|
350
424
|
next.uiTheme = { id: patch.uiTheme.id };
|
|
351
425
|
}
|
|
352
|
-
const { runConcurrencyOverrides: runPatch, sandboxLimitOverrides: sandboxPatch, subagentLimitOverrides: subagentPatch, uiArrangement: arrangementPatch, } = patch;
|
|
426
|
+
const { runConcurrencyOverrides: runPatch, sandboxLimitOverrides: sandboxPatch, subagentLimitOverrides: subagentPatch, uiArrangement: arrangementPatch, clientExtensions: clientPatch, } = patch;
|
|
353
427
|
if (runPatch !== undefined ||
|
|
354
428
|
sandboxPatch !== undefined ||
|
|
355
429
|
subagentPatch !== undefined ||
|
|
356
|
-
arrangementPatch !== undefined
|
|
430
|
+
arrangementPatch !== undefined ||
|
|
431
|
+
clientPatch !== undefined) {
|
|
357
432
|
const current = await this.get();
|
|
433
|
+
if (clientPatch !== undefined) {
|
|
434
|
+
next.clientExtensions = {
|
|
435
|
+
enabled: clientPatch.enabled ?? current.clientExtensions.enabled,
|
|
436
|
+
disabled: clientPatch.disabled === undefined
|
|
437
|
+
? current.clientExtensions.disabled
|
|
438
|
+
: [...new Set(clientPatch.disabled)].sort(),
|
|
439
|
+
};
|
|
440
|
+
}
|
|
358
441
|
if (arrangementPatch !== undefined) {
|
|
359
442
|
next.uiArrangement = mergeArrangement(current.uiArrangement, arrangementPatch);
|
|
360
443
|
}
|
|
@@ -74,6 +74,14 @@ export declare class LockService {
|
|
|
74
74
|
holderOf(key: string): Promise<string | null>;
|
|
75
75
|
/** Deletes `key` when `holder` still owns it. */
|
|
76
76
|
releaseIf(key: string, holder: string): Promise<boolean>;
|
|
77
|
+
/**
|
|
78
|
+
* Takes one of `limit` slots of the counting semaphore `key` for `holder` (a unique token), for at
|
|
79
|
+
* most `ttlMs` (a crashed holder's slot frees itself then; no renewal). False when every slot is
|
|
80
|
+
* taken. Release with {@link releaseSlot}.
|
|
81
|
+
*/
|
|
82
|
+
takeSlot(key: string, holder: string, limit: number, ttlMs: number): Promise<boolean>;
|
|
83
|
+
/** Gives back `holder`'s slot of the semaphore `key` (nothing when it already expired). */
|
|
84
|
+
releaseSlot(key: string, holder: string): Promise<void>;
|
|
77
85
|
/**
|
|
78
86
|
* Takes `key` (no `lock:` prefix) with the caller's `holder` value for `ttlMs`, unless it is
|
|
79
87
|
* held, and renews it every TTL/3 like {@link acquire} (a run longer than the TTL keeps it, a
|
|
@@ -20,6 +20,20 @@ import { ACQUIRE_EXCLUSIVE, ACQUIRE_SHARED, COUNT_SHARED_LEASES, DOWNGRADE_SHARE
|
|
|
20
20
|
const RELEASE_IF = `if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end`;
|
|
21
21
|
/** Extends the key only while it holds our token. */
|
|
22
22
|
const RENEW_IF = `if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('pexpire', KEYS[1], tonumber(ARGV[2])) else return 0 end`;
|
|
23
|
+
/**
|
|
24
|
+
* Takes a slot of a counting semaphore: a sorted set of holder tokens scored by expiry time. Expired
|
|
25
|
+
* holders (a crashed replica's) drop out first, so a slot is never lost for longer than its TTL;
|
|
26
|
+
* then the token is added when fewer than ARGV[2] slots are taken. The set itself expires with
|
|
27
|
+
* its last slot. KEYS[1] the set; ARGV: token, limit, ttl ms. Returns 1 when taken.
|
|
28
|
+
*/
|
|
29
|
+
const TAKE_SLOT = `local now = redis.call('time')
|
|
30
|
+
local ms = tonumber(now[1]) * 1000 + math.floor(tonumber(now[2]) / 1000)
|
|
31
|
+
redis.call('zremrangebyscore', KEYS[1], '-inf', ms)
|
|
32
|
+
if redis.call('zcard', KEYS[1]) >= tonumber(ARGV[2]) then return 0 end
|
|
33
|
+
redis.call('zadd', KEYS[1], ms + tonumber(ARGV[3]), ARGV[1])
|
|
34
|
+
local last = redis.call('zrange', KEYS[1], -1, -1, 'withscores')
|
|
35
|
+
redis.call('pexpireat', KEYS[1], tonumber(last[2]))
|
|
36
|
+
return 1`;
|
|
23
37
|
/** Resolves after `ms`; rejects with the abort reason when `signal` aborts first. */
|
|
24
38
|
function sleep(ms, signal) {
|
|
25
39
|
return new Promise((resolve, reject) => {
|
|
@@ -117,6 +131,19 @@ let LockService = class LockService {
|
|
|
117
131
|
async releaseIf(key, holder) {
|
|
118
132
|
return (await this.redis.eval(RELEASE_IF, 1, key, holder)) === 1;
|
|
119
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Takes one of `limit` slots of the counting semaphore `key` for `holder` (a unique token), for at
|
|
136
|
+
* most `ttlMs` (a crashed holder's slot frees itself then; no renewal). False when every slot is
|
|
137
|
+
* taken. Release with {@link releaseSlot}.
|
|
138
|
+
*/
|
|
139
|
+
async takeSlot(key, holder, limit, ttlMs) {
|
|
140
|
+
assertNoTransaction("takeSlot");
|
|
141
|
+
return ((await this.redis.eval(TAKE_SLOT, 1, key, holder, String(limit), String(Math.ceil(ttlMs)))) === 1);
|
|
142
|
+
}
|
|
143
|
+
/** Gives back `holder`'s slot of the semaphore `key` (nothing when it already expired). */
|
|
144
|
+
async releaseSlot(key, holder) {
|
|
145
|
+
await this.redis.zrem(key, holder);
|
|
146
|
+
}
|
|
120
147
|
/**
|
|
121
148
|
* Takes `key` (no `lock:` prefix) with the caller's `holder` value for `ttlMs`, unless it is
|
|
122
149
|
* held, and renews it every TTL/3 like {@link acquire} (a run longer than the TTL keeps it, a
|
|
@@ -8,6 +8,8 @@ export interface NamedThrottler {
|
|
|
8
8
|
ttl: number;
|
|
9
9
|
/** The 429 message (today's text of the route that used the limiter). */
|
|
10
10
|
message: string;
|
|
11
|
+
/** The 429 error code; default `auth.rate_limited` (the credential routes'). */
|
|
12
|
+
code?: "auth.rate_limited" | "rate_limited";
|
|
11
13
|
/** The credential group: throttlers of one group are reserved together (one Redis hash tag). */
|
|
12
14
|
group: string;
|
|
13
15
|
/** What a successful attempt does to this counter: delete it, or give one attempt back. */
|
|
@@ -27,9 +29,14 @@ export interface NamedThrottler {
|
|
|
27
29
|
* | `POST /api/v1/invitations/:token/accept` | `invitation`, `invitation-ip` |
|
|
28
30
|
* | `GET /api/v1/device/pending/:userCode`, `POST /api/v1/device/confirm`, `POST /api/v1/device/deny` | `device-code-account` |
|
|
29
31
|
*
|
|
32
|
+
* `POST /api/v1/orgs/:orgId/ui/client/reports` and `POST /api/v1/admin/ui/client/reports` opt in to
|
|
33
|
+
* `client-reports` with `@Throttled` (20 per minute per account: a crash loop in a browser must
|
|
34
|
+
* not flood the table).
|
|
35
|
+
*
|
|
30
36
|
* `POST /api/v1/device/authorize` and `POST /api/v1/device/token` opt in to `device-authorize-ip`
|
|
31
37
|
* and `device-token-ip` with `@Throttled` (every request counts; neither checks a guessable
|
|
32
|
-
* credential: the device code is 32 random bytes).
|
|
38
|
+
* credential: the device code is 32 random bytes). `POST …/guides/:guideId/checks/:checkId/run`
|
|
39
|
+
* opts in to `setup-check` (setup guides v2 §10.3: each run may call a third party).
|
|
33
40
|
*/
|
|
34
41
|
export declare const NAMED_THROTTLERS: readonly NamedThrottler[];
|
|
35
42
|
/** The storage key of a named throttler's counter for a tracker (shared by the guard and success paths). */
|
|
@@ -30,9 +30,14 @@ const LOGIN_MSG = "Too many failed login attempts; try again later";
|
|
|
30
30
|
* | `POST /api/v1/invitations/:token/accept` | `invitation`, `invitation-ip` |
|
|
31
31
|
* | `GET /api/v1/device/pending/:userCode`, `POST /api/v1/device/confirm`, `POST /api/v1/device/deny` | `device-code-account` |
|
|
32
32
|
*
|
|
33
|
+
* `POST /api/v1/orgs/:orgId/ui/client/reports` and `POST /api/v1/admin/ui/client/reports` opt in to
|
|
34
|
+
* `client-reports` with `@Throttled` (20 per minute per account: a crash loop in a browser must
|
|
35
|
+
* not flood the table).
|
|
36
|
+
*
|
|
33
37
|
* `POST /api/v1/device/authorize` and `POST /api/v1/device/token` opt in to `device-authorize-ip`
|
|
34
38
|
* and `device-token-ip` with `@Throttled` (every request counts; neither checks a guessable
|
|
35
|
-
* credential: the device code is 32 random bytes).
|
|
39
|
+
* credential: the device code is 32 random bytes). `POST …/guides/:guideId/checks/:checkId/run`
|
|
40
|
+
* opts in to `setup-check` (setup guides v2 §10.3: each run may call a third party).
|
|
36
41
|
*/
|
|
37
42
|
export const NAMED_THROTTLERS = [
|
|
38
43
|
// (login, IP): 10; an attacker filling one login from one IP leaves the owner's other IPs alone (R25)
|
|
@@ -152,6 +157,30 @@ export const NAMED_THROTTLERS = [
|
|
|
152
157
|
message: "Too many device code attempts; try again later",
|
|
153
158
|
getTracker: (req) => sha256(principalAccountId(req)),
|
|
154
159
|
},
|
|
160
|
+
// client code crash reports per signed-in account (counted before the handler): 20 / minute
|
|
161
|
+
{
|
|
162
|
+
name: "client-reports",
|
|
163
|
+
group: "client-reports",
|
|
164
|
+
onSuccess: "clear",
|
|
165
|
+
limit: 20,
|
|
166
|
+
ttl: 60_000,
|
|
167
|
+
message: "Too many client reports; try again later",
|
|
168
|
+
getTracker: (req) => sha256(principalAccountId(req)),
|
|
169
|
+
},
|
|
170
|
+
// setup check runs per signed-in person (setup guides v2 §10.5): 30 a minute, every request
|
|
171
|
+
// counts (@Throttled); a cached answer costs no third-party call but still counts, as the page
|
|
172
|
+
// asks at most once per row and stale result. The edge of the route (with `retry-after`): the
|
|
173
|
+
// budget shared with the Platform tool's setup.check is SetupChecksService's own counter
|
|
174
|
+
{
|
|
175
|
+
name: "setup-check",
|
|
176
|
+
group: "setup-check",
|
|
177
|
+
onSuccess: "clear",
|
|
178
|
+
limit: 30,
|
|
179
|
+
ttl: 60_000,
|
|
180
|
+
message: "Too many setup check runs; try again in a minute",
|
|
181
|
+
code: "rate_limited",
|
|
182
|
+
getTracker: (req) => sha256(principalAccountId(req)),
|
|
183
|
+
},
|
|
155
184
|
];
|
|
156
185
|
/** The storage key of a named throttler's counter for a tracker (shared by the guard and success paths). */
|
|
157
186
|
export const throttlerKey = (name, tracker) => sha256(`${name}:${tracker}`);
|
|
@@ -56,7 +56,7 @@ let KernelThrottlerGuard = class KernelThrottlerGuard extends ThrottlerGuard {
|
|
|
56
56
|
const known = NAMED_THROTTLERS.find((t) => t.name === name);
|
|
57
57
|
if (!known)
|
|
58
58
|
throw new Error(`unknown throttler "${name}"`);
|
|
59
|
-
throw new ApiError("auth.rate_limited", known.message);
|
|
59
|
+
throw new ApiError(known.code ?? "auth.rate_limited", known.message);
|
|
60
60
|
}
|
|
61
61
|
};
|
|
62
62
|
KernelThrottlerGuard = __decorate([
|
package/dist/kernel.module.js
CHANGED
|
@@ -9,6 +9,7 @@ import { Global, Module } from "@nestjs/common";
|
|
|
9
9
|
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
|
+
import { ClientModule } from "./client/client.module.js";
|
|
12
13
|
import { TitlesModule } from "./conversations/titles.js";
|
|
13
14
|
import { ExtensionsModule } from "./extensions/extensions.module.js";
|
|
14
15
|
import { ApiModule } from "./http/api.module.js";
|
|
@@ -111,6 +112,8 @@ let KernelModule = KernelModule_1 = class KernelModule {
|
|
|
111
112
|
TitlesModule,
|
|
112
113
|
UsageReportModule,
|
|
113
114
|
ChannelsModule,
|
|
115
|
+
// client extensions: the client builds stored with extension packages
|
|
116
|
+
ClientModule,
|
|
114
117
|
// the @local sandbox provider, registered on every role (any replica may relay to a machine)
|
|
115
118
|
LocalDevicesModule,
|
|
116
119
|
// the Platform tool's operation registry and actor facts
|
|
@@ -87,19 +87,7 @@ export declare const OrgSettingsSchema: z.ZodObject<{
|
|
|
87
87
|
locked: "locked";
|
|
88
88
|
}>;
|
|
89
89
|
}, z.core.$strict>>>;
|
|
90
|
-
uiArrangement: z.ZodCatch<z.ZodOptional<z.
|
|
91
|
-
"agent.detail.section": "agent.detail.section";
|
|
92
|
-
"conversation.panel": "conversation.panel";
|
|
93
|
-
"conversation.properties.section": "conversation.properties.section";
|
|
94
|
-
"conversation.tool-result.card": "conversation.tool-result.card";
|
|
95
|
-
"file.preview": "file.preview";
|
|
96
|
-
"org.page": "org.page";
|
|
97
|
-
"org.settings.section": "org.settings.section";
|
|
98
|
-
"platform.page": "platform.page";
|
|
99
|
-
}> & z.core.$partial, z.ZodObject<{
|
|
100
|
-
hidden: z.ZodArray<z.ZodString>;
|
|
101
|
-
order: z.ZodArray<z.ZodString>;
|
|
102
|
-
}, z.core.$strict>>>>;
|
|
90
|
+
uiArrangement: z.ZodCatch<z.ZodOptional<z.ZodType<Partial<Record<"agent.detail.section" | "conversation.composer.frame" | "conversation.empty" | "conversation.panel" | "conversation.properties.section" | "conversation.tool-result.card" | "file.preview" | "org.page" | "org.settings.section" | "platform.page" | "shell.brand" | "shell.overlay", import("../ui/arrangement.js").UiArrangementEntry>>, unknown, z.core.$ZodTypeInternals<Partial<Record<"agent.detail.section" | "conversation.composer.frame" | "conversation.empty" | "conversation.panel" | "conversation.properties.section" | "conversation.tool-result.card" | "file.preview" | "org.page" | "org.settings.section" | "platform.page" | "shell.brand" | "shell.overlay", import("../ui/arrangement.js").UiArrangementEntry>>, unknown>>>>;
|
|
103
91
|
}, z.core.$strip>;
|
|
104
92
|
export type OrgSettings = z.infer<typeof OrgSettingsSchema>;
|
|
105
93
|
/** PATCH 体:只改给出的字段;未知字段 → 400。 */
|
|
@@ -137,19 +125,7 @@ export declare const OrgSettingsPatchSchema: z.ZodObject<{
|
|
|
137
125
|
locked: "locked";
|
|
138
126
|
}>;
|
|
139
127
|
}, z.core.$strict>>>;
|
|
140
|
-
uiArrangement: z.ZodOptional<z.
|
|
141
|
-
"agent.detail.section": "agent.detail.section";
|
|
142
|
-
"conversation.panel": "conversation.panel";
|
|
143
|
-
"conversation.properties.section": "conversation.properties.section";
|
|
144
|
-
"conversation.tool-result.card": "conversation.tool-result.card";
|
|
145
|
-
"file.preview": "file.preview";
|
|
146
|
-
"org.page": "org.page";
|
|
147
|
-
"org.settings.section": "org.settings.section";
|
|
148
|
-
"platform.page": "platform.page";
|
|
149
|
-
}> & z.core.$partial, z.ZodNullable<z.ZodObject<{
|
|
150
|
-
hidden: z.ZodArray<z.ZodString>;
|
|
151
|
-
order: z.ZodArray<z.ZodString>;
|
|
152
|
-
}, z.core.$strict>>>>;
|
|
128
|
+
uiArrangement: z.ZodOptional<z.ZodType<Partial<Record<"agent.detail.section" | "conversation.composer.frame" | "conversation.empty" | "conversation.panel" | "conversation.properties.section" | "conversation.tool-result.card" | "file.preview" | "org.page" | "org.settings.section" | "platform.page" | "shell.brand" | "shell.overlay", import("../ui/arrangement.js").UiArrangementEntry | null>>, unknown, z.core.$ZodTypeInternals<Partial<Record<"agent.detail.section" | "conversation.composer.frame" | "conversation.empty" | "conversation.panel" | "conversation.properties.section" | "conversation.tool-result.card" | "file.preview" | "org.page" | "org.settings.section" | "platform.page" | "shell.brand" | "shell.overlay", import("../ui/arrangement.js").UiArrangementEntry | null>>, unknown>>>;
|
|
153
129
|
}, z.core.$strict>;
|
|
154
130
|
export type OrgSettingsPatch = z.infer<typeof OrgSettingsPatchSchema>;
|
|
155
131
|
/** 部署的沙箱出站(`sandbox.limits.egress` + `allowHosts`)。 */
|
package/dist/overrides.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { RUN_HOOKS, type RunHooks } from "./runtime/run-worker.js";
|
|
|
12
12
|
import { SUBAGENT_MESSAGES_HOOKS, type SubagentMessagesHooks } from "./runtime/subagents/messages.js";
|
|
13
13
|
import { USAGE_REPORT_RETRY, type UsageReportRetry } from "./runtime/usage-report.js";
|
|
14
14
|
import { SANDBOX_LEASE_TIMINGS, type SandboxLeaseTimings } from "./sandbox/leases.js";
|
|
15
|
+
import { SETUP_CHECK_TIMEOUT } from "./setup/setup-checks.service.js";
|
|
15
16
|
import { TOOL_PIPELINE_HOOKS, type ToolPipelineHooks } from "./tools/pipeline.js";
|
|
16
17
|
import { EMBED_TOKEN_CLOCK } from "./ui/embed-token.js";
|
|
17
18
|
/**
|
|
@@ -24,7 +25,7 @@ import { EMBED_TOKEN_CLOCK } from "./ui/embed-token.js";
|
|
|
24
25
|
* - `TOOL_PIPELINE_HOOKS`: the tool pipeline's hooks and policy decision;
|
|
25
26
|
* - `SUBAGENT_MESSAGES_HOOKS`: the sub-agent message tools' hooks (a send raced by a run's end);
|
|
26
27
|
* - `BOOTSTRAP_LOCK_TTL`, `FILE_PREVIEW_TIMEOUT`, `LIST_MODELS_TIMEOUT`, `USAGE_REPORT_RETRY`,
|
|
27
|
-
* `SANDBOX_LEASE_TIMINGS`, `CHANNEL_WEBHOOK_TIMINGS`: shorter timings;
|
|
28
|
+
* `SANDBOX_LEASE_TIMINGS`, `CHANNEL_WEBHOOK_TIMINGS`, `SETUP_CHECK_TIMEOUT`: shorter timings;
|
|
28
29
|
* - `EMBED_TOKEN_CLOCK`: the clock embed tokens are issued and checked with;
|
|
29
30
|
* - `RUN_CONTEXT_CLOCK`: the clock run start reads the run context's date from, and the
|
|
30
31
|
* `CurrentTime` builtin the time;
|
|
@@ -42,6 +43,7 @@ interface KernelSeams {
|
|
|
42
43
|
[USAGE_REPORT_RETRY]: UsageReportRetry;
|
|
43
44
|
[SANDBOX_LEASE_TIMINGS]: Partial<SandboxLeaseTimings>;
|
|
44
45
|
[CHANNEL_WEBHOOK_TIMINGS]: Partial<ChannelWebhookTimings>;
|
|
46
|
+
[SETUP_CHECK_TIMEOUT]: number;
|
|
45
47
|
[EMBED_TOKEN_CLOCK]: () => number;
|
|
46
48
|
[RUN_CONTEXT_CLOCK]: () => number;
|
|
47
49
|
[APP_INTERCEPTOR]: NestInterceptor;
|
package/dist/overrides.js
CHANGED
|
@@ -10,6 +10,7 @@ import { RUN_HOOKS } from "./runtime/run-worker.js";
|
|
|
10
10
|
import { SUBAGENT_MESSAGES_HOOKS, } from "./runtime/subagents/messages.js";
|
|
11
11
|
import { USAGE_REPORT_RETRY } from "./runtime/usage-report.js";
|
|
12
12
|
import { SANDBOX_LEASE_TIMINGS } from "./sandbox/leases.js";
|
|
13
|
+
import { SETUP_CHECK_TIMEOUT } from "./setup/setup-checks.service.js";
|
|
13
14
|
import { TOOL_PIPELINE_HOOKS } from "./tools/pipeline.js";
|
|
14
15
|
import { EMBED_TOKEN_CLOCK } from "./ui/embed-token.js";
|
|
15
16
|
const SEAM_TOKENS = [
|
|
@@ -24,6 +25,7 @@ const SEAM_TOKENS = [
|
|
|
24
25
|
USAGE_REPORT_RETRY,
|
|
25
26
|
SANDBOX_LEASE_TIMINGS,
|
|
26
27
|
CHANNEL_WEBHOOK_TIMINGS,
|
|
28
|
+
SETUP_CHECK_TIMEOUT,
|
|
27
29
|
EMBED_TOKEN_CLOCK,
|
|
28
30
|
RUN_CONTEXT_CLOCK,
|
|
29
31
|
APP_INTERCEPTOR,
|