@capybara-hq/kernel 0.1.0-rc.11 → 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/agents/agents.schemas.d.ts +3 -0
- package/dist/agents/agents.service.js +11 -1
- package/dist/agents/definition.d.ts +1 -0
- package/dist/agents/definition.js +7 -3
- package/dist/agents/org-templates.js +4 -0
- package/dist/agents/pending-connectors.service.js +1 -1
- 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/component-scope.controller.d.ts +18 -6
- package/dist/catalog/component-scope.controller.js +36 -13
- package/dist/catalog/component-scope.service.d.ts +11 -0
- package/dist/catalog/component-scope.service.js +4 -0
- package/dist/catalog/component-state.d.ts +8 -0
- package/dist/catalog/component-state.js +19 -11
- package/dist/catalog/marketplaces.service.d.ts +1 -1
- package/dist/catalog/plugin-import.js +4 -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 +23 -14
- package/dist/conversations/conversations.service.js +28 -21
- 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 +2 -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 +39 -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 +27 -25
- package/dist/errors.js +27 -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 +48 -3
- package/dist/platform/operation.js +6 -2
- package/dist/platform/ops/admin.ops.js +8 -2
- package/dist/platform/ops/agents.ops.js +19 -6
- 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/runtime/subagents/definition.d.ts +3 -2
- package/dist/runtime/subagents/definition.js +2 -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/connector-account-policies.d.ts +51 -0
- package/dist/tools/connector-account-policies.js +165 -0
- package/dist/tools/connectors.controller.d.ts +35 -4
- package/dist/tools/connectors.controller.js +66 -7
- package/dist/tools/connectors.schemas.d.ts +11 -0
- package/dist/tools/connectors.schemas.js +11 -0
- package/dist/tools/connectors.service.d.ts +2 -0
- package/dist/tools/connectors.service.js +1 -0
- package/dist/tools/pipeline.d.ts +1 -1
- package/dist/tools/pipeline.js +4 -3
- package/dist/tools/policy.d.ts +23 -1
- package/dist/tools/policy.js +99 -24
- package/dist/tools/registry.d.ts +2 -2
- package/dist/tools/tools.module.js +6 -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/0104_connector_tool_account_policies.sql +16 -0
- 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
|
@@ -267,14 +267,14 @@ export const PLATFORM_EXCLUSIONS = [
|
|
|
267
267
|
category: "transport",
|
|
268
268
|
reason: "Serves sandbox file bytes",
|
|
269
269
|
},
|
|
270
|
-
//
|
|
270
|
+
// devices (personal cloud devices, environments design phase 1)
|
|
271
271
|
// connected machines (environments design phase 2): device sign-in by the program and on the
|
|
272
272
|
// confirmation page, and disconnecting a machine. The machine's WebSocket (`GET /device/connect`)
|
|
273
273
|
// is a raw gateway-role route, not a Nest controller, so it is not listed (like the webhook)
|
|
274
274
|
{
|
|
275
|
-
route: "DELETE /api/v1/orgs/:orgId/
|
|
275
|
+
route: "DELETE /api/v1/orgs/:orgId/devices/:id/machine",
|
|
276
276
|
category: "human-only",
|
|
277
|
-
reason: "Disconnects a person's own machine (revokes its credential); a trust decision taken on the
|
|
277
|
+
reason: "Disconnects a person's own machine (revokes its credential); a trust decision taken on the device's page",
|
|
278
278
|
},
|
|
279
279
|
{
|
|
280
280
|
route: "POST /api/v1/device/authorize",
|
|
@@ -608,6 +608,16 @@ export const PLATFORM_EXCLUSIONS = [
|
|
|
608
608
|
category: "secret",
|
|
609
609
|
reason: "Writes the caller's connector credentials",
|
|
610
610
|
},
|
|
611
|
+
{
|
|
612
|
+
route: "GET /api/v1/orgs/:orgId/connectors/:connectorId/tool-policies/me",
|
|
613
|
+
category: "internal",
|
|
614
|
+
reason: "Display list of the connector card's 权限 sheet; connectors.get gives an agent the tools and their org defaults",
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
route: "PUT /api/v1/orgs/:orgId/connectors/:connectorId/tool-policies/me",
|
|
618
|
+
category: "human-only",
|
|
619
|
+
reason: "A member's own tool policies decide what agents may call with their connection without asking; an agent must never loosen them for itself",
|
|
620
|
+
},
|
|
611
621
|
{
|
|
612
622
|
route: "DELETE /api/v1/orgs/:orgId/connectors/:connectorId/credentials/me",
|
|
613
623
|
category: "secret",
|
|
@@ -644,6 +654,11 @@ export const PLATFORM_EXCLUSIONS = [
|
|
|
644
654
|
category: "internal",
|
|
645
655
|
reason: "Navigation entries of the web shell (panels, pages, embeds); nothing an agent acts on",
|
|
646
656
|
},
|
|
657
|
+
{
|
|
658
|
+
route: "GET /api/v1/orgs/:orgId/ui/arrangement",
|
|
659
|
+
category: "internal",
|
|
660
|
+
reason: "Listing for the 界面位置 page; the arrangement is read and written through org-settings / admin settings",
|
|
661
|
+
},
|
|
647
662
|
{
|
|
648
663
|
route: "GET /api/v1/orgs/:orgId/ui/views/:plugin/:id",
|
|
649
664
|
category: "transport",
|
|
@@ -664,6 +679,36 @@ export const PLATFORM_EXCLUSIONS = [
|
|
|
664
679
|
category: "transport",
|
|
665
680
|
reason: "Server-sent event stream of UI invalidations",
|
|
666
681
|
},
|
|
682
|
+
{
|
|
683
|
+
route: "GET /api/v1/admin/ui/contributions",
|
|
684
|
+
category: "internal",
|
|
685
|
+
reason: "Navigation entries of the admin console (platform pages)",
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
route: "GET /api/v1/admin/ui/arrangement",
|
|
689
|
+
category: "internal",
|
|
690
|
+
reason: "Listing for the 界面位置 page; the arrangement is read and written through org-settings / admin settings",
|
|
691
|
+
},
|
|
692
|
+
{
|
|
693
|
+
route: "GET /api/v1/admin/ui/views/:plugin/:id",
|
|
694
|
+
category: "transport",
|
|
695
|
+
reason: "Renders an extension UI view for the web app",
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
route: "POST /api/v1/admin/ui/actions/:plugin/:id",
|
|
699
|
+
category: "transport",
|
|
700
|
+
reason: "Runs an extension UI action from the web app",
|
|
701
|
+
},
|
|
702
|
+
{
|
|
703
|
+
route: "POST /api/v1/admin/ui/embeds/:plugin/:id/token",
|
|
704
|
+
category: "transport",
|
|
705
|
+
reason: "Issues an embed token for an iframe",
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
route: "GET /api/v1/admin/ui/stream",
|
|
709
|
+
category: "transport",
|
|
710
|
+
reason: "Server-sent event stream of UI invalidations",
|
|
711
|
+
},
|
|
667
712
|
// themes (themes spec §8-§9)
|
|
668
713
|
{
|
|
669
714
|
route: "GET /api/v1/themes/:id/:version/theme.css",
|
|
@@ -84,11 +84,15 @@ export const PLATFORM_DOMAINS = [
|
|
|
84
84
|
description: "The org's settings (tool search, language, sandbox policy, the Platform tool switch, the default theme): read and change.",
|
|
85
85
|
},
|
|
86
86
|
{
|
|
87
|
-
id: "
|
|
88
|
-
description: "Your own cloud
|
|
87
|
+
id: "devices",
|
|
88
|
+
description: "Your own cloud devices (the workspaces your conversations run in): list, read, create, rename, delete, wipe the files.",
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
91
|
id: "themes",
|
|
92
92
|
description: "The themes on in this org, the one in effect for you and the org's theme setting: list. Themes are set through your preferences, the org settings and the deployment settings.",
|
|
93
93
|
},
|
|
94
|
+
{
|
|
95
|
+
id: "ui",
|
|
96
|
+
description: "The UI slots an extension can contribute to (the catalog): list. A slot id is a ui contribution's `slot` in a plugin manifest.",
|
|
97
|
+
},
|
|
94
98
|
];
|
|
@@ -40,6 +40,7 @@ const SettingsInput = DEPLOYMENT_SETTINGS_PATCH.pick({
|
|
|
40
40
|
customSkills: true,
|
|
41
41
|
orgMarketplaceBrowse: true,
|
|
42
42
|
uiTheme: true,
|
|
43
|
+
uiArrangement: true,
|
|
43
44
|
}).strict();
|
|
44
45
|
const ProviderId = ModelProviderParams.shape.provider.describe("The model provider (models.platform-list), e.g. the plugin name of its extension.");
|
|
45
46
|
/** `provider/model` of a purpose target, or null. */
|
|
@@ -121,7 +122,7 @@ let AdminOperations = class AdminOperations {
|
|
|
121
122
|
}),
|
|
122
123
|
defineOperation({
|
|
123
124
|
id: "admin.update-settings",
|
|
124
|
-
description: "Change deployment settings (super admin); give only the keys to change: orgCreation (anyone or super_admin), priceCurrency (ISO 4217 code), customConnectors / customSkills (allow or deny: whether orgs may create their own instead of installing from the catalog), orgMarketplaceBrowse (true or false), uiTheme ({ id }: the platform default theme, a platform theme whose scope is all, or null for the built-in theme; it is what every org falls back to and what the sign-in pages show). Per-org limits are orgs.set-limits.",
|
|
125
|
+
description: "Change deployment settings (super admin); give only the keys to change: orgCreation (anyone or super_admin), priceCurrency (ISO 4217 code), customConnectors / customSkills (allow or deny: whether orgs may create their own instead of installing from the catalog), orgMarketplaceBrowse (true or false), uiTheme ({ id }: the platform default theme, a platform theme whose scope is all, or null for the built-in theme; it is what every org falls back to and what the sign-in pages show), uiArrangement ({ <slot>: { hidden, order } }: the platform default arrangement of UI slots, with contribution keys <extension>/<contribution>; hidden ones are not listed but still open by URL; null for a slot removes its entry). Per-org limits are orgs.set-limits.",
|
|
125
126
|
input: SettingsInput.refine((b) => Object.keys(b).length > 0, {
|
|
126
127
|
message: "at least one setting is required",
|
|
127
128
|
}),
|
|
@@ -148,7 +149,7 @@ let AdminOperations = class AdminOperations {
|
|
|
148
149
|
: { ok: false, code: "validation_failed", message: r.error.issues[0]?.message ?? "" };
|
|
149
150
|
},
|
|
150
151
|
summary: async (i) => {
|
|
151
|
-
const { uiTheme, ...rest } = i;
|
|
152
|
+
const { uiTheme, uiArrangement, ...rest } = i;
|
|
152
153
|
const parts = Object.entries(rest).map(([k, v]) => `${k}=${String(v)}`);
|
|
153
154
|
const zh = [...parts];
|
|
154
155
|
const en = [...parts];
|
|
@@ -158,6 +159,11 @@ let AdminOperations = class AdminOperations {
|
|
|
158
159
|
zh.push(`uiTheme=${uiTheme.id === null ? "内置主题" : (name?.zh ?? uiTheme.id)}`);
|
|
159
160
|
en.push(`uiTheme=${uiTheme.id === null ? "built-in theme" : (name?.en ?? uiTheme.id)}`);
|
|
160
161
|
}
|
|
162
|
+
if (uiArrangement !== undefined) {
|
|
163
|
+
const slots = Object.keys(uiArrangement).join(", ");
|
|
164
|
+
zh.push(`uiArrangement(${slots})`);
|
|
165
|
+
en.push(`uiArrangement (${slots})`);
|
|
166
|
+
}
|
|
161
167
|
return {
|
|
162
168
|
zh: `修改平台部署设置:${zh.join(",")}`,
|
|
163
169
|
en: `Change the deployment settings: ${en.join(", ")}`,
|
|
@@ -40,6 +40,15 @@ const RouteSkills = Def.skills.unwrap();
|
|
|
40
40
|
const Skills = RouteSkills.pick({ pinned: true })
|
|
41
41
|
.extend({ orgSkills: RouteSkills.shape.orgSkills.unwrap() })
|
|
42
42
|
.strict();
|
|
43
|
+
/**
|
|
44
|
+
* Whether `next` sets an `allow` that `current` does not have (decision 2026-11-09: `allow` on a
|
|
45
|
+
* connector tool lets an agent call it without asking). Such a change is confirmed every time and
|
|
46
|
+
* never remembered, so an agent can never loosen its own policies on a grant the person remembered
|
|
47
|
+
* for ordinary edits.
|
|
48
|
+
*/
|
|
49
|
+
function addsAllow(next, current) {
|
|
50
|
+
return Object.entries(next ?? {}).some(([k, v]) => v === "allow" && current?.[k] !== "allow");
|
|
51
|
+
}
|
|
43
52
|
/** The definition fields an agent can set through the tool; the rest keep the web's defaults. */
|
|
44
53
|
const Fields = {
|
|
45
54
|
name: Def.name,
|
|
@@ -156,8 +165,10 @@ let AgentsOperations = class AgentsOperations {
|
|
|
156
165
|
* `agents.update`'s class (spec §13): `personal` (may be remembered) only on a private agent the
|
|
157
166
|
* actor owns; any other agent the actor may edit is shared, so each change is confirmed.
|
|
158
167
|
*/
|
|
159
|
-
async updateClass(agentId, ctx) {
|
|
168
|
+
async updateClass(agentId, toolPolicies, ctx) {
|
|
160
169
|
const a = await this.agents.get(ctx.orgId, agentId, ctx.actorAccountId);
|
|
170
|
+
if (addsAllow(toolPolicies, a.definition.toolPolicies))
|
|
171
|
+
return "org";
|
|
161
172
|
return a.visibility === "private" && a.ownerAccountId === ctx.actorAccountId
|
|
162
173
|
? "personal"
|
|
163
174
|
: "org";
|
|
@@ -221,6 +232,8 @@ let AgentsOperations = class AgentsOperations {
|
|
|
221
232
|
omits: ["memberIds", "profile"],
|
|
222
233
|
loosens: { visibility: "optional: the operation creates private agents only" },
|
|
223
234
|
confirm: "personal",
|
|
235
|
+
// an `allow` loosens: never on a remembered grant
|
|
236
|
+
confirmFor: async (i) => addsAllow(i.definition.toolPolicies, undefined) ? "org" : "personal",
|
|
224
237
|
summary: (i) => ({
|
|
225
238
|
zh: `新建私有智能体「${i.definition.name}」`,
|
|
226
239
|
en: `Create private agent "${i.definition.name}"`,
|
|
@@ -246,7 +259,7 @@ let AgentsOperations = class AgentsOperations {
|
|
|
246
259
|
}),
|
|
247
260
|
defineOperation({
|
|
248
261
|
id: "agents.update",
|
|
249
|
-
description: 'Change an agent you may edit: your own, private or shared, and as an org admin any agent of the org. Send the version you read from agents.get and only the fields to change; the others keep their value. The description (one short paragraph, "" removes it) is saved with the definition; the avatar and quick actions are changed with agents.update-profile. disabledTools replaces the whole list of turned-off tools (send [] to turn every tool on). A version that is no longer current is refused, so read the agent again first. The visibility cannot be changed here (that is done on the agents page of the web app). A change to your own private agent may be remembered by the person; a change to a shared agent is confirmed every time.',
|
|
262
|
+
description: 'Change an agent you may edit: your own, private or shared, and as an org admin any agent of the org. Send the version you read from agents.get and only the fields to change; the others keep their value. The description (one short paragraph, "" removes it) is saved with the definition; the avatar and quick actions are changed with agents.update-profile. disabledTools replaces the whole list of turned-off tools (send [] to turn every tool on). A version that is no longer current is refused, so read the agent again first. The visibility cannot be changed here (that is done on the agents page of the web app). A change to your own private agent may be remembered by the person; a change to a shared agent, or one that sets a tool policy to allow, is confirmed every time.',
|
|
250
263
|
input: z
|
|
251
264
|
.object({
|
|
252
265
|
agentId: AgentId,
|
|
@@ -289,7 +302,7 @@ let AgentsOperations = class AgentsOperations {
|
|
|
289
302
|
next: "The agent changed since you read it: read it again with agents.get, then send its current version.",
|
|
290
303
|
},
|
|
291
304
|
],
|
|
292
|
-
confirmFor: (i, ctx) => this.updateClass(i.agentId, ctx),
|
|
305
|
+
confirmFor: (i, ctx) => this.updateClass(i.agentId, i.toolPolicies, ctx),
|
|
293
306
|
summary: async (i, ctx) => {
|
|
294
307
|
const a = await this.agents.get(ctx.orgId, i.agentId, ctx.actorAccountId);
|
|
295
308
|
const name = named(a.definition.name);
|
|
@@ -353,7 +366,7 @@ let AgentsOperations = class AgentsOperations {
|
|
|
353
366
|
// needs no declaration: an input that accepts less than the route passes the parity test.
|
|
354
367
|
omits: ["expectedUpdatedAt"],
|
|
355
368
|
confirm: "personal",
|
|
356
|
-
confirmFor: (i, ctx) => this.updateClass(i.agentId, ctx),
|
|
369
|
+
confirmFor: (i, ctx) => this.updateClass(i.agentId, undefined, ctx),
|
|
357
370
|
errors: [
|
|
358
371
|
{
|
|
359
372
|
code: "agent.not_found",
|
|
@@ -493,7 +506,7 @@ let AgentsOperations = class AgentsOperations {
|
|
|
493
506
|
confirm: "personal",
|
|
494
507
|
// destructive: asked every time and never remembered, a shared agent as an org write
|
|
495
508
|
rememberable: false,
|
|
496
|
-
confirmFor: (i, ctx) => this.updateClass(i.agentId, ctx),
|
|
509
|
+
confirmFor: (i, ctx) => this.updateClass(i.agentId, undefined, ctx),
|
|
497
510
|
errors: [
|
|
498
511
|
{
|
|
499
512
|
code: "agent.not_found",
|
|
@@ -578,7 +591,7 @@ let AgentsOperations = class AgentsOperations {
|
|
|
578
591
|
authz: { orgAction: "agents.create" },
|
|
579
592
|
mirrors: ["POST /api/v1/orgs/:orgId/agents/:agentId/pending-connectors/:key/bind"],
|
|
580
593
|
confirm: "personal",
|
|
581
|
-
confirmFor: (i, ctx) => this.updateClass(i.agentId, ctx),
|
|
594
|
+
confirmFor: (i, ctx) => this.updateClass(i.agentId, undefined, ctx),
|
|
582
595
|
errors: [
|
|
583
596
|
{
|
|
584
597
|
code: "agent.pending_connector_not_found",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type OnModuleInit } from "@nestjs/common";
|
|
2
2
|
import { ConversationsService } from "../../conversations/conversations.service.js";
|
|
3
|
-
import {
|
|
3
|
+
import { ConversationDeviceStatus } from "../../conversations/device-status.js";
|
|
4
4
|
import { ConversationFiles } from "../../conversations/files.js";
|
|
5
5
|
import { KernelDb } from "../../infra/database/kernel-db.js";
|
|
6
6
|
import { PlatformOperations } from "../registry.js";
|
|
@@ -14,9 +14,9 @@ export declare class ConversationsOperations implements OnModuleInit {
|
|
|
14
14
|
private readonly registry;
|
|
15
15
|
private readonly conversations;
|
|
16
16
|
private readonly files;
|
|
17
|
-
private readonly
|
|
17
|
+
private readonly device;
|
|
18
18
|
private readonly kdb;
|
|
19
|
-
constructor(registry: PlatformOperations, conversations: ConversationsService, files: ConversationFiles,
|
|
19
|
+
constructor(registry: PlatformOperations, conversations: ConversationsService, files: ConversationFiles, device: ConversationDeviceStatus, kdb: KernelDb);
|
|
20
20
|
/**
|
|
21
21
|
* Whether `id` is the conversation this run belongs to: its ROOT (the Platform tool also runs in
|
|
22
22
|
* sub-agents, whose own id is not the person's conversation). Stopping or deleting it would end
|
|
@@ -11,7 +11,7 @@ import { Inject, Injectable } from "@nestjs/common";
|
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
import { EventsQuery, FilesQuery, IdParams, ListQuery, PatchBody, SubagentsQuery, } from "../../conversations/conversations.schemas.js";
|
|
13
13
|
import { ConversationsService, } from "../../conversations/conversations.service.js";
|
|
14
|
-
import {
|
|
14
|
+
import { ConversationDeviceStatus } from "../../conversations/device-status.js";
|
|
15
15
|
import { ConversationFiles } from "../../conversations/files.js";
|
|
16
16
|
import { KernelDb } from "../../infra/database/kernel-db.js";
|
|
17
17
|
import { rootConversationOf } from "../../runtime/subagents/child.js";
|
|
@@ -41,13 +41,13 @@ let ConversationsOperations = class ConversationsOperations {
|
|
|
41
41
|
registry;
|
|
42
42
|
conversations;
|
|
43
43
|
files;
|
|
44
|
-
|
|
44
|
+
device;
|
|
45
45
|
kdb;
|
|
46
|
-
constructor(registry, conversations, files,
|
|
46
|
+
constructor(registry, conversations, files, device, kdb) {
|
|
47
47
|
this.registry = registry;
|
|
48
48
|
this.conversations = conversations;
|
|
49
49
|
this.files = files;
|
|
50
|
-
this.
|
|
50
|
+
this.device = device;
|
|
51
51
|
this.kdb = kdb;
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
@@ -348,12 +348,12 @@ let ConversationsOperations = class ConversationsOperations {
|
|
|
348
348
|
},
|
|
349
349
|
}),
|
|
350
350
|
defineOperation({
|
|
351
|
-
id: "conversations.
|
|
352
|
-
description: "Read the
|
|
351
|
+
id: "conversations.device",
|
|
352
|
+
description: "Read the device one of your conversations works in and whether its instance is running or suspended; device is null while the conversation has none. Takes the id from conversations.list.",
|
|
353
353
|
input: Id,
|
|
354
354
|
example: { conversationId: "3f2b8a40-6c1d-4e0b-9a77-5d1e2c8b9f10" },
|
|
355
355
|
authz: { orgAction: "agents.use" },
|
|
356
|
-
mirrors: ["GET /api/v1/orgs/:orgId/conversations/:id/
|
|
356
|
+
mirrors: ["GET /api/v1/orgs/:orgId/conversations/:id/device"],
|
|
357
357
|
renames: { conversationId: "id" },
|
|
358
358
|
errors: [
|
|
359
359
|
{
|
|
@@ -363,7 +363,7 @@ let ConversationsOperations = class ConversationsOperations {
|
|
|
363
363
|
],
|
|
364
364
|
confirm: "read",
|
|
365
365
|
run: async (input, ctx) => ({
|
|
366
|
-
|
|
366
|
+
device: await this.device.get(ctx.orgId, input.conversationId, ctx.actorAccountId),
|
|
367
367
|
}),
|
|
368
368
|
}),
|
|
369
369
|
defineOperation({
|
|
@@ -464,7 +464,7 @@ ConversationsOperations = __decorate([
|
|
|
464
464
|
__param(0, Inject(PlatformOperations)),
|
|
465
465
|
__param(1, Inject(ConversationsService)),
|
|
466
466
|
__param(2, Inject(ConversationFiles)),
|
|
467
|
-
__param(3, Inject(
|
|
467
|
+
__param(3, Inject(ConversationDeviceStatus)),
|
|
468
468
|
__param(4, Inject(KernelDb))
|
|
469
469
|
], ConversationsOperations);
|
|
470
470
|
export { ConversationsOperations };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type OnModuleInit } from "@nestjs/common";
|
|
2
|
+
import { DevicesService } from "../../devices/devices.service.js";
|
|
3
|
+
import { KernelDb } from "../../infra/database/kernel-db.js";
|
|
4
|
+
import { PlatformOperations } from "../registry.js";
|
|
5
|
+
/**
|
|
6
|
+
* Device operations of the `Platform` tool (environments design, phase 1): a person's own
|
|
7
|
+
* cloud devices. Phase 1 has personal devices only, visible to their owner alone, so
|
|
8
|
+
* these are `personal` writes. A cloud device carries no credentials or device connection;
|
|
9
|
+
* deleting one and wiping its files are `personal` writes that are never remembered.
|
|
10
|
+
*/
|
|
11
|
+
export declare class DevicesOperations implements OnModuleInit {
|
|
12
|
+
private readonly registry;
|
|
13
|
+
private readonly devices;
|
|
14
|
+
private readonly kdb;
|
|
15
|
+
constructor(registry: PlatformOperations, devices: DevicesService, kdb: KernelDb);
|
|
16
|
+
/**
|
|
17
|
+
* Whether `id` is the device the run works in: the one its root conversation is bound to
|
|
18
|
+
* (sub-agents use the root's). Deleting or wiping it would pull the sandbox from under the run.
|
|
19
|
+
*/
|
|
20
|
+
private isRunsDevice;
|
|
21
|
+
/** The precheck of a destructive write: never the run's own device, then the service's. */
|
|
22
|
+
private precheckDestructive;
|
|
23
|
+
/** The device's name for a card; its id when it cannot be read. */
|
|
24
|
+
private label;
|
|
25
|
+
onModuleInit(): void;
|
|
26
|
+
}
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
|
+
};
|
|
10
|
+
import { Inject, Injectable } from "@nestjs/common";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
import { DevicesService } from "../../devices/devices.service.js";
|
|
13
|
+
import { DeviceNameBody, DeviceParams } from "../../devices/dto.js";
|
|
14
|
+
import { deviceLabel } from "../../devices/label.js";
|
|
15
|
+
import { KernelDb } from "../../infra/database/kernel-db.js";
|
|
16
|
+
import { rootConversationOf } from "../../runtime/subagents/child.js";
|
|
17
|
+
import { defineOperation } from "../operation.js";
|
|
18
|
+
import { PlatformOperations } from "../registry.js";
|
|
19
|
+
import { precheckBy, viaAgent } from "./errors.js";
|
|
20
|
+
import { named, orElse } from "./summary.js";
|
|
21
|
+
const DeviceId = z.object({ deviceId: DeviceParams.shape.id }).strict();
|
|
22
|
+
const Name = z.object({ name: DeviceNameBody.shape.name }).strict();
|
|
23
|
+
/**
|
|
24
|
+
* Model-facing names are English: the default is "Personal", a default demoted by a provider
|
|
25
|
+
* switch "Personal (Docker sandbox)" (the web shows 「个人设备」 / 「个人设备(Docker 沙箱)」).
|
|
26
|
+
*/
|
|
27
|
+
const labelOf = (e) => deviceLabel(e, "en");
|
|
28
|
+
/** A row's state: why it cannot be used now, else whether its instance runs. */
|
|
29
|
+
function stateOf(e) {
|
|
30
|
+
if (!e.available) {
|
|
31
|
+
return {
|
|
32
|
+
state: "unavailable",
|
|
33
|
+
reason: "Its sandbox provider is no longer the deployment's current one.",
|
|
34
|
+
next: "Ask an org admin; use another device meanwhile.",
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (e.filesLost && e.source === "local") {
|
|
38
|
+
return {
|
|
39
|
+
state: "files_lost",
|
|
40
|
+
reason: "Its directory is gone from the connected machine.",
|
|
41
|
+
next: "Ask the person to run capybara-device logout, then capybara-device login into this device, on that machine.",
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (e.filesLost) {
|
|
45
|
+
return {
|
|
46
|
+
state: "files_lost",
|
|
47
|
+
reason: "Its file system is gone at the provider.",
|
|
48
|
+
next: "Wipe its files with devices.reset-files to use it again.",
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return { state: e.instance?.status ?? "ready" };
|
|
52
|
+
}
|
|
53
|
+
const row = (e) => ({
|
|
54
|
+
id: e.id,
|
|
55
|
+
name: labelOf(e),
|
|
56
|
+
...stateOf(e),
|
|
57
|
+
isDefault: e.isDefault,
|
|
58
|
+
source: e.source,
|
|
59
|
+
provider: e.provider,
|
|
60
|
+
online: e.online,
|
|
61
|
+
machine: e.machine && {
|
|
62
|
+
name: e.machine.name,
|
|
63
|
+
os: e.machine.os,
|
|
64
|
+
lastSeenAt: e.machine.lastSeenAt,
|
|
65
|
+
},
|
|
66
|
+
lastUsedAt: e.instance?.lastUsedAt ?? null,
|
|
67
|
+
});
|
|
68
|
+
/**
|
|
69
|
+
* Device operations of the `Platform` tool (environments design, phase 1): a person's own
|
|
70
|
+
* cloud devices. Phase 1 has personal devices only, visible to their owner alone, so
|
|
71
|
+
* these are `personal` writes. A cloud device carries no credentials or device connection;
|
|
72
|
+
* deleting one and wiping its files are `personal` writes that are never remembered.
|
|
73
|
+
*/
|
|
74
|
+
let DevicesOperations = class DevicesOperations {
|
|
75
|
+
registry;
|
|
76
|
+
devices;
|
|
77
|
+
kdb;
|
|
78
|
+
constructor(registry, devices, kdb) {
|
|
79
|
+
this.registry = registry;
|
|
80
|
+
this.devices = devices;
|
|
81
|
+
this.kdb = kdb;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Whether `id` is the device the run works in: the one its root conversation is bound to
|
|
85
|
+
* (sub-agents use the root's). Deleting or wiping it would pull the sandbox from under the run.
|
|
86
|
+
*/
|
|
87
|
+
async isRunsDevice(id, ctx) {
|
|
88
|
+
const root = await rootConversationOf(this.kdb.db, ctx.conversationId);
|
|
89
|
+
const row = await this.kdb.db
|
|
90
|
+
.selectFrom("conversations")
|
|
91
|
+
.select("device_id")
|
|
92
|
+
.where("id", "=", root)
|
|
93
|
+
.where("org_id", "=", ctx.orgId)
|
|
94
|
+
.executeTakeFirst();
|
|
95
|
+
return row?.device_id === id;
|
|
96
|
+
}
|
|
97
|
+
/** The precheck of a destructive write: never the run's own device, then the service's. */
|
|
98
|
+
async precheckDestructive(id, ctx, verb, read) {
|
|
99
|
+
if (await this.isRunsDevice(id, ctx)) {
|
|
100
|
+
return {
|
|
101
|
+
ok: false,
|
|
102
|
+
code: "device.current",
|
|
103
|
+
message: `The device you are running in cannot be ${verb} from here.`,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return precheckBy(read);
|
|
107
|
+
}
|
|
108
|
+
/** The device's name for a card; its id when it cannot be read. */
|
|
109
|
+
label(ctx, id) {
|
|
110
|
+
return orElse(async () => named(labelOf(await this.devices.get(ctx.orgId, ctx.actorAccountId, id))), id);
|
|
111
|
+
}
|
|
112
|
+
onModuleInit() {
|
|
113
|
+
this.registry.register([
|
|
114
|
+
defineOperation({
|
|
115
|
+
id: "devices.list",
|
|
116
|
+
description: "List your own devices in this org: one compact row each (name, state, whether it is the default, source: cloud or local, provider, whether a local one is online and its machine, last use), plus the default and last used ids and whether new cloud devices can be made. The default device is shown as Personal; a former default left behind by a sandbox provider switch is shown as Personal (<provider>) and becomes the default again when that provider is back.",
|
|
117
|
+
input: z.object({}).strict(),
|
|
118
|
+
example: {},
|
|
119
|
+
authz: { orgAction: "agents.use" },
|
|
120
|
+
mirrors: ["GET /api/v1/orgs/:orgId/devices"],
|
|
121
|
+
confirm: "read",
|
|
122
|
+
run: async (_input, ctx) => {
|
|
123
|
+
const l = await this.devices.list(ctx.orgId, ctx.actorAccountId);
|
|
124
|
+
return {
|
|
125
|
+
items: l.items.map(row),
|
|
126
|
+
defaultId: l.defaultId,
|
|
127
|
+
lastUsedId: l.lastUsedId,
|
|
128
|
+
cloudAvailable: l.cloudAvailable,
|
|
129
|
+
};
|
|
130
|
+
},
|
|
131
|
+
}),
|
|
132
|
+
defineOperation({
|
|
133
|
+
id: "devices.get",
|
|
134
|
+
description: "Read one of your devices with its source (cloud or local), provider, state, instance, the machine of a local one and whether it is online, limits and creation time. Takes the id from devices.list.",
|
|
135
|
+
input: DeviceId,
|
|
136
|
+
example: { deviceId: "4e8a0c1d-6b2f-4a37-8d19-3c5e7f9a1b20" },
|
|
137
|
+
authz: { orgAction: "agents.use" },
|
|
138
|
+
mirrors: ["GET /api/v1/orgs/:orgId/devices/:id"],
|
|
139
|
+
renames: { deviceId: "id" },
|
|
140
|
+
confirm: "read",
|
|
141
|
+
errors: [
|
|
142
|
+
{
|
|
143
|
+
code: "device.not_found",
|
|
144
|
+
next: "Check the id with devices.list: you only see your own devices.",
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
run: async (input, ctx) => {
|
|
148
|
+
const e = await this.devices.get(ctx.orgId, ctx.actorAccountId, input.deviceId);
|
|
149
|
+
return { device: { ...e, name: labelOf(e), ...stateOf(e) } };
|
|
150
|
+
},
|
|
151
|
+
}),
|
|
152
|
+
defineOperation({
|
|
153
|
+
id: "devices.create",
|
|
154
|
+
description: "Create a personal cloud device with a name (1-64 characters, unique among yours, case-insensitive). It is ready at once; its instance and files are made on first use. It needs a sandbox provider and is limited per person.",
|
|
155
|
+
input: Name,
|
|
156
|
+
example: { name: "Data analysis" },
|
|
157
|
+
authz: { orgAction: "agents.use" },
|
|
158
|
+
mirrors: ["POST /api/v1/orgs/:orgId/devices"],
|
|
159
|
+
confirm: "personal",
|
|
160
|
+
errors: [
|
|
161
|
+
{
|
|
162
|
+
code: "device.name_taken",
|
|
163
|
+
next: "You have a device with this name: pick another name, or read yours with devices.list.",
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
code: "device.limit_reached",
|
|
167
|
+
next: "You are at the limit: delete a device you no longer need with devices.delete, or use an existing one.",
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
code: "device.current",
|
|
171
|
+
next: "This conversation works in it: ask the person to wipe it on the web, or wipe a different one.",
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
code: "device.unavailable",
|
|
175
|
+
next: {
|
|
176
|
+
superAdmin: "No sandbox provider is current: set one up in the admin console under extensions, then call again.",
|
|
177
|
+
orgAdmin: "No sandbox provider is set up; ask the super admin.",
|
|
178
|
+
member: "No sandbox provider is set up in this deployment; ask an org admin.",
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
],
|
|
182
|
+
precheck: (i, ctx) => precheckBy(() => this.devices.checkCreate(ctx.orgId, ctx.actorAccountId, i.name)),
|
|
183
|
+
summary: (i) => ({
|
|
184
|
+
zh: `新建个人云端设备「${named(i.name)}」`,
|
|
185
|
+
en: `Create personal cloud device "${named(i.name)}"`,
|
|
186
|
+
}),
|
|
187
|
+
run: async (input, ctx) => {
|
|
188
|
+
const e = await this.devices.create(ctx.orgId, ctx.actorAccountId, { name: input.name }, undefined, viaAgent("devices.create", ctx));
|
|
189
|
+
return { device: row(e) };
|
|
190
|
+
},
|
|
191
|
+
}),
|
|
192
|
+
defineOperation({
|
|
193
|
+
id: "devices.delete",
|
|
194
|
+
description: "Delete one of your devices, the default one included: its instance and ALL its files are destroyed after the response and cannot be recovered. Conversations bound to it keep pointing at it and their sandbox tools then fail. The person confirms every delete; it is never remembered. The device this conversation works in cannot be deleted. Takes the id from devices.list.",
|
|
195
|
+
input: DeviceId,
|
|
196
|
+
example: { deviceId: "4e8a0c1d-6b2f-4a37-8d19-3c5e7f9a1b20" },
|
|
197
|
+
authz: { orgAction: "agents.use" },
|
|
198
|
+
mirrors: ["DELETE /api/v1/orgs/:orgId/devices/:id"],
|
|
199
|
+
renames: { deviceId: "id" },
|
|
200
|
+
confirm: "personal",
|
|
201
|
+
// destructive: asked every time and never remembered
|
|
202
|
+
rememberable: false,
|
|
203
|
+
errors: [
|
|
204
|
+
{
|
|
205
|
+
code: "device.not_found",
|
|
206
|
+
next: "Check the id with devices.list: you only see your own devices.",
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
code: "device.current",
|
|
210
|
+
next: "This conversation works in it: ask the person to delete it on the web, or delete a different one.",
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
precheck: (i, ctx) => this.precheckDestructive(i.deviceId, ctx, "deleted", () => this.devices.get(ctx.orgId, ctx.actorAccountId, i.deviceId)),
|
|
214
|
+
summary: async (i, ctx) => {
|
|
215
|
+
const n = await this.label(ctx, i.deviceId);
|
|
216
|
+
const c = await orElse(() => this.devices.boundConversations(ctx.orgId, ctx.actorAccountId, i.deviceId), 0);
|
|
217
|
+
return {
|
|
218
|
+
zh: `删除设备「${n}」:其中所有文件将被销毁且无法恢复;使用它的 ${c} 个对话将失去沙箱(沙箱工具会失败)`,
|
|
219
|
+
en: `Delete device "${n}": all its files are destroyed and cannot be recovered; the ${c} conversations using it lose their sandbox (their sandbox tools fail)`,
|
|
220
|
+
};
|
|
221
|
+
},
|
|
222
|
+
run: async (input, ctx) => {
|
|
223
|
+
await this.devices.remove(ctx.orgId, ctx.actorAccountId, input.deviceId, undefined, viaAgent("devices.delete", ctx));
|
|
224
|
+
return { id: input.deviceId, deleted: true };
|
|
225
|
+
},
|
|
226
|
+
}),
|
|
227
|
+
defineOperation({
|
|
228
|
+
id: "devices.reset-files",
|
|
229
|
+
description: "Wipe one of your devices' files so it starts empty: ALL its files are destroyed (after running commands finish) and cannot be recovered; the next use creates a fresh workspace. Use it when a device reports its files are lost (not for a connected machine's device: its files are on the machine). The person confirms every reset; it is never remembered. The device this conversation works in cannot be wiped. Takes the id from devices.list.",
|
|
230
|
+
input: DeviceId,
|
|
231
|
+
example: { deviceId: "4e8a0c1d-6b2f-4a37-8d19-3c5e7f9a1b20" },
|
|
232
|
+
authz: { orgAction: "agents.use" },
|
|
233
|
+
mirrors: ["POST /api/v1/orgs/:orgId/devices/:id/files/reset"],
|
|
234
|
+
renames: { deviceId: "id" },
|
|
235
|
+
confirm: "personal",
|
|
236
|
+
rememberable: false,
|
|
237
|
+
errors: [
|
|
238
|
+
{
|
|
239
|
+
code: "device.not_found",
|
|
240
|
+
next: "Check the id with devices.list: you only see your own devices.",
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
code: "device.current",
|
|
244
|
+
next: "This conversation works in it: ask the person to wipe it on the web, or wipe a different one.",
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
code: "device.files_on_device",
|
|
248
|
+
next: "Its files are on its connected machine: ask the person to run capybara-device logout, then capybara-device login into this device, on that machine.",
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
code: "device.unavailable",
|
|
252
|
+
next: {
|
|
253
|
+
orgAdmin: "Its sandbox provider is no longer the current one: use another device, or ask the super admin about the provider.",
|
|
254
|
+
member: "Its sandbox provider is no longer the current one: use another device, or ask an org admin.",
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
precheck: (i, ctx) => this.precheckDestructive(i.deviceId, ctx, "wiped", () => this.devices.checkReset(ctx.orgId, ctx.actorAccountId, i.deviceId)),
|
|
259
|
+
summary: async (i, ctx) => {
|
|
260
|
+
const n = await this.label(ctx, i.deviceId);
|
|
261
|
+
return {
|
|
262
|
+
zh: `清空设备「${n}」的文件:所有文件将被销毁且无法恢复`,
|
|
263
|
+
en: `Wipe the files of device "${n}": all files are destroyed and cannot be recovered`,
|
|
264
|
+
};
|
|
265
|
+
},
|
|
266
|
+
run: async (input, ctx) => {
|
|
267
|
+
await this.devices.resetFiles(ctx.orgId, ctx.actorAccountId, input.deviceId, undefined, viaAgent("devices.reset-files", ctx));
|
|
268
|
+
return { id: input.deviceId, reset: true };
|
|
269
|
+
},
|
|
270
|
+
}),
|
|
271
|
+
defineOperation({
|
|
272
|
+
id: "devices.rename",
|
|
273
|
+
description: "Rename one of your devices, the default one included (it then has a name). The new name is 1-64 characters and unique among yours, case-insensitive. Takes the id from devices.list.",
|
|
274
|
+
input: DeviceId.extend({ name: DeviceNameBody.shape.name }).strict(),
|
|
275
|
+
example: { deviceId: "4e8a0c1d-6b2f-4a37-8d19-3c5e7f9a1b20", name: "Reports" },
|
|
276
|
+
authz: { orgAction: "agents.use" },
|
|
277
|
+
mirrors: ["PATCH /api/v1/orgs/:orgId/devices/:id"],
|
|
278
|
+
renames: { deviceId: "id" },
|
|
279
|
+
confirm: "personal",
|
|
280
|
+
errors: [
|
|
281
|
+
{
|
|
282
|
+
code: "device.not_found",
|
|
283
|
+
next: "Check the id with devices.list: you only see your own devices.",
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
code: "device.name_taken",
|
|
287
|
+
next: "You have a device with this name: pick another name.",
|
|
288
|
+
},
|
|
289
|
+
],
|
|
290
|
+
precheck: (i, ctx) => precheckBy(() => this.devices.checkRename(ctx.orgId, ctx.actorAccountId, i.deviceId, i.name)),
|
|
291
|
+
summary: async (i, ctx) => {
|
|
292
|
+
const from = await orElse(async () => named(labelOf(await this.devices.get(ctx.orgId, ctx.actorAccountId, i.deviceId))), i.deviceId);
|
|
293
|
+
return {
|
|
294
|
+
zh: `将设备「${from}」重命名为「${named(i.name)}」`,
|
|
295
|
+
en: `Rename device "${from}" to "${named(i.name)}"`,
|
|
296
|
+
};
|
|
297
|
+
},
|
|
298
|
+
run: async (input, ctx) => ({
|
|
299
|
+
device: row(await this.devices.rename(ctx.orgId, ctx.actorAccountId, input.deviceId, input.name, undefined, viaAgent("devices.rename", ctx))),
|
|
300
|
+
}),
|
|
301
|
+
}),
|
|
302
|
+
]);
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
DevicesOperations = __decorate([
|
|
306
|
+
Injectable(),
|
|
307
|
+
__param(0, Inject(PlatformOperations)),
|
|
308
|
+
__param(1, Inject(DevicesService)),
|
|
309
|
+
__param(2, Inject(KernelDb))
|
|
310
|
+
], DevicesOperations);
|
|
311
|
+
export { DevicesOperations };
|