Let a bot and a workspace set their own envs
Envs had three scopes, general, workspace and computer. A bot had no
scope of its own, so the only way to give one worker a key was to set it
on a computer it happened to share.
The envs table gets a bot_id, and resolution now layers bot over
computer over workspace over general, so a bot's own key wins wherever it
runs. Every computer call site passes the run's bot_id, and grabRunEnvs
does the same for the {{env.KEY}} a custom tool or an MCP server's headers
read.
A bot's and a workspace's settings page can now edit their own envs, in
place, through the same save-env and delete-env routes: sending `scoped`
makes them answer with just that scope instead of the whole install's
overview. Super admins only, like the Environment page.
This commit is contained in:
@@ -2,6 +2,7 @@ import { useContext, useState } from "react";
|
||||
import EmptyContent from "@moduletrace/twui/elements/EmptyContent";
|
||||
import { AppContext } from "@/src/pages/__root";
|
||||
import canManageCrew from "@/src/utils/rbac/can-manage-crew";
|
||||
import ScopedEnvsGroup from "../../../(partials)/envs/scoped-envs-group";
|
||||
import ExtensionsGroup from "../../../(partials)/extensions-group";
|
||||
import SettingsSectionHeading from "../../../(partials)/settings-section-heading";
|
||||
import SettingsShell from "../../../(partials)/settings-shell";
|
||||
@@ -70,6 +71,7 @@ export default function WorkspaceOverview() {
|
||||
description="Every bot working here gets these, the coordinator too, on top of its own, only while it works here."
|
||||
initial={pageProps?.workspace_extensions}
|
||||
/>
|
||||
<ScopedEnvsGroup initial={pageProps?.workspace_envs} />
|
||||
{harnesses?.length ? (
|
||||
<>
|
||||
<SettingsSectionHeading
|
||||
|
||||
@@ -2,6 +2,9 @@ import type { PagePropsType, PageQueryObject } from "@/src/types";
|
||||
import type { BunextPageServerFn } from "@moduletrace/bunext/types";
|
||||
import grabBots from "@/src/functions/backend/db/bots/grab-bots";
|
||||
import grabUserComputers from "@/src/functions/backend/db/computers/grab-user-computers";
|
||||
import grabScopedEnvs from "@/src/functions/backend/db/envs/grab-scoped-envs";
|
||||
import userAuth from "@/src/functions/backend/auth/user-auth";
|
||||
import isPassThroughUser from "@/src/utils/rbac/is-pass-through-user";
|
||||
import grabWorkspaceExtensionsOverview from "@/src/functions/backend/db/extensions/grab-workspace-extensions-overview";
|
||||
import grabBotHarnessOverview from "@/src/functions/backend/db/harness/grab-bot-harness-overview";
|
||||
import grabUserWorkspaces from "@/src/functions/backend/db/workspaces/grab-user-workspaces";
|
||||
@@ -45,6 +48,7 @@ export const server: BunextPageServerFn<PagePropsType> = async (params) => {
|
||||
computers,
|
||||
workspace_harness_overview,
|
||||
workspace_extensions,
|
||||
workspace_envs,
|
||||
] = await Promise.all([
|
||||
grabWorkspaceBots({ user_id, workspace_id }),
|
||||
grabBots({ user_id }),
|
||||
@@ -52,6 +56,14 @@ export const server: BunextPageServerFn<PagePropsType> = async (params) => {
|
||||
grabUserComputers({ user_id }),
|
||||
grabBotHarnessOverview({ workspace_id }).catch(() => null),
|
||||
grabWorkspaceExtensionsOverview({ user_id, workspace_id }),
|
||||
grabScopedEnvs({
|
||||
paradigm: "workspace",
|
||||
owner_id: workspace_id,
|
||||
user_id,
|
||||
can_manage: isPassThroughUser({
|
||||
user_types: (await userAuth({ req: params.req })).user_types,
|
||||
}),
|
||||
}),
|
||||
]);
|
||||
|
||||
const crew = railBots({ bots: workspace_bots });
|
||||
@@ -68,6 +80,7 @@ export const server: BunextPageServerFn<PagePropsType> = async (params) => {
|
||||
computers,
|
||||
workspace_harness_overview,
|
||||
workspace_extensions,
|
||||
workspace_envs,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user