+54
-21
lines changedFilter options
+54
-21
lines changed Original file line number Diff line number Diff line change
@@ -972,7 +972,7 @@ func New(options *Options) *API {
972
972
})
973
973
r.Route("/experiments", func(r chi.Router) {
974
974
r.Use(apiKeyMiddleware)
975
-
r.Get("/available", handleExperimentsSafe)
975
+
r.Get("/available", handleExperimentsAvailable)
976
976
r.Get("/", api.handleExperimentsGet)
977
977
})
978
978
r.Get("/updatecheck", api.updateCheck)
@@ -1895,7 +1895,9 @@ func ReadExperiments(log slog.Logger, raw []string) codersdk.Experiments {
1895
1895
exps = append(exps, codersdk.ExperimentsSafe...)
1896
1896
default:
1897
1897
ex := codersdk.Experiment(strings.ToLower(v))
1898
-
if !slice.Contains(codersdk.ExperimentsSafe, ex) {
1898
+
if !slice.Contains(codersdk.ExperimentsKnown, ex) {
1899
+
log.Warn(context.Background(), "ignoring unknown experiment", slog.F("experiment", ex))
1900
+
} else if !slice.Contains(codersdk.ExperimentsSafe, ex) {
1899
1901
log.Warn(context.Background(), "🐉 HERE BE DRAGONS: opting into hidden experiment", slog.F("experiment", ex))
1900
1902
}
1901
1903
exps = append(exps, ex)
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ func (api *API) handleExperimentsGet(rw http.ResponseWriter, r *http.Request) {
26
26
// @Tags General
27
27
// @Success 200 {array} codersdk.Experiment
28
28
// @Router /experiments/available [get]
29
-
func handleExperimentsSafe(rw http.ResponseWriter, r *http.Request) {
29
+
func handleExperimentsAvailable(rw http.ResponseWriter, r *http.Request) {
30
30
ctx := r.Context()
31
31
httpapi.Write(ctx, rw, http.StatusOK, codersdk.AvailableExperiments{
32
32
Safe: codersdk.ExperimentsSafe,
Original file line number Diff line number Diff line change
@@ -3372,6 +3372,18 @@ const (
3372
3372
ExperimentAITasks Experiment = "ai-tasks" // Enables the new AI tasks feature.
3373
3373
)
3374
3374
3375
+
// ExperimentsKnown should include all experiments defined above.
3376
+
var ExperimentsKnown = Experiments{
3377
+
ExperimentExample,
3378
+
ExperimentAutoFillParameters,
3379
+
ExperimentNotifications,
3380
+
ExperimentWorkspaceUsage,
3381
+
ExperimentWebPush,
3382
+
ExperimentWorkspacePrebuilds,
3383
+
ExperimentAgenticChat,
3384
+
ExperimentAITasks,
3385
+
}
3386
+
3375
3387
// ExperimentsSafe should include all experiments that are safe for
3376
3388
// users to opt-in to via --experimental='*'.
3377
3389
// Experiments that are not ready for consumption by all users should
@@ -3384,6 +3396,9 @@ var ExperimentsSafe = Experiments{
3384
3396
// Multiple experiments may be enabled at the same time.
3385
3397
// Experiments are not safe for production use, and are not guaranteed to
3386
3398
// be backwards compatible. They may be removed or renamed at any time.
3399
+
// The below typescript-ignore annotation allows our typescript generator
3400
+
// to generate an enum list, which is used in the frontend.
3401
+
// @typescript-ignore Experiments
3387
3402
type Experiments []Experiment
3388
3403
3389
3404
// Returns a list of experiments that are enabled for the deployment.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
1
1
import { API } from "api/api";
2
-
import type { Experiments } from "api/typesGenerated";
2
+
import { type Experiment, Experiments } from "api/typesGenerated";
3
3
import type { MetadataState } from "hooks/useEmbeddedMetadata";
4
4
import { cachedQuery } from "./util";
5
5
6
6
const experimentsKey = ["experiments"] as const;
7
7
8
-
export const experiments = (metadata: MetadataState<Experiments>) => {
8
+
export const experiments = (metadata: MetadataState<Experiment[]>) => {
9
9
return cachedQuery({
10
10
metadata,
11
11
queryKey: experimentsKey,
@@ -19,3 +19,7 @@ export const availableExperiments = () => {
19
19
queryFn: async () => API.getAvailableExperiments(),
20
20
};
21
21
};
22
+
23
+
export const isKnownExperiment = (experiment: string): boolean => {
24
+
return Experiments.includes(experiment as Experiment);
25
+
};
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import type {
2
2
AppearanceConfig,
3
3
BuildInfoResponse,
4
4
Entitlements,
5
-
Experiments,
5
+
Experiment,
6
6
Region,
7
7
User,
8
8
UserAppearanceSettings,
@@ -24,7 +24,7 @@ export const DEFAULT_METADATA_KEY = "property";
24
24
*/
25
25
type AvailableMetadata = Readonly<{
26
26
user: User;
27
-
experiments: Experiments;
27
+
experiments: Experiment[];
28
28
appearance: AppearanceConfig;
29
29
userAppearance: UserAppearanceSettings;
30
30
entitlements: Entitlements;
@@ -89,7 +89,7 @@ export class MetadataManager implements MetadataManagerApi {
89
89
userAppearance:
90
90
this.registerValue<UserAppearanceSettings>("userAppearance"),
91
91
entitlements: this.registerValue<Entitlements>("entitlements"),
92
-
experiments: this.registerValue<Experiments>("experiments"),
92
+
experiments: this.registerValue<Experiment[]>("experiments"),
93
93
"build-info": this.registerValue<BuildInfoResponse>("build-info"),
94
94
regions: this.registerRegionValue(),
95
95
tasksTabVisible: this.registerValue<boolean>("tasksTabVisible"),
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ import { organizations } from "api/queries/organizations";
5
5
import type {
6
6
AppearanceConfig,
7
7
Entitlements,
8
-
Experiments,
8
+
Experiment,
9
9
Organization,
10
10
} from "api/typesGenerated";
11
11
import { ErrorAlert } from "components/Alert/ErrorAlert";
@@ -19,7 +19,7 @@ import { selectFeatureVisibility } from "./entitlements";
19
19
20
20
export interface DashboardValue {
21
21
entitlements: Entitlements;
22
-
experiments: Experiments;
22
+
experiments: Experiment[];
23
23
appearance: AppearanceConfig;
24
24
organizations: readonly Organization[];
25
25
showOrganizations: boolean;
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
1
1
import { deploymentDAUs } from "api/queries/deployment";
2
-
import { availableExperiments, experiments } from "api/queries/experiments";
2
+
import {
3
+
availableExperiments,
4
+
experiments,
5
+
isKnownExperiment,
6
+
} from "api/queries/experiments";
3
7
import { useEmbeddedMetadata } from "hooks/useEmbeddedMetadata";
4
8
import { useDeploymentConfig } from "modules/management/DeploymentConfigProvider";
5
9
import type { FC } from "react";
@@ -18,7 +22,7 @@ const OverviewPage: FC = () => {
18
22
const safeExperiments = safeExperimentsQuery.data?.safe ?? [];
19
23
const invalidExperiments =
20
24
enabledExperimentsQuery.data?.filter((exp) => {
21
-
return !safeExperiments.includes(exp);
25
+
return !isKnownExperiment(exp);
22
26
}) ?? [];
23
27
24
28
const { data: dailyActiveUsers } = useQuery(deploymentDAUs());
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ const meta: Meta<typeof OverviewPageView> = {
30
30
description:
31
31
"Enable one or more experiments. These are not ready for production. Separate multiple experiments with commas, or enter '*' to opt-in to all available experiments.",
32
32
flag: "experiments",
33
-
value: ["workspace_actions"],
33
+
value: ["example"],
34
34
flag_shorthand: "",
35
35
hidden: false,
36
36
},
@@ -82,8 +82,8 @@ export const allExperimentsEnabled: Story = {
82
82
hidden: false,
83
83
},
84
84
],
85
-
safeExperiments: ["shared-ports"],
86
-
invalidExperiments: ["invalid"],
85
+
safeExperiments: ["example"],
86
+
invalidExperiments: [],
87
87
},
88
88
};
89
89
@@ -118,7 +118,7 @@ export const invalidExperimentsEnabled: Story = {
118
118
hidden: false,
119
119
},
120
120
],
121
-
safeExperiments: ["shared-ports"],
121
+
safeExperiments: ["example"],
122
122
invalidExperiments: ["invalid"],
123
123
},
124
124
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
1
1
import AlertTitle from "@mui/material/AlertTitle";
2
2
import type {
3
3
DAUsResponse,
4
-
Experiments,
4
+
Experiment,
5
5
SerpentOption,
6
6
} from "api/typesGenerated";
7
7
import { Link } from "components/Link/Link";
@@ -22,8 +22,8 @@ import { UserEngagementChart } from "./UserEngagementChart";
22
22
type OverviewPageViewProps = {
23
23
deploymentOptions: SerpentOption[];
24
24
dailyActiveUsers: DAUsResponse | undefined;
25
-
readonly invalidExperiments: Experiments | string[];
26
-
readonly safeExperiments: Experiments | string[];
25
+
readonly invalidExperiments: readonly string[];
26
+
readonly safeExperiments: readonly Experiment[];
27
27
};
28
28
29
29
export const OverviewPageView: FC<OverviewPageViewProps> = ({
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4