feat(ui): label the System One yes / no question type noul and explain it on hover

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
kerry 2026-10-10 19:12:48 +00:00
parent 5b5187ecbd
commit a2b575d6cd
3 changed files with 21 additions and 6 deletions

View file

@ -27,7 +27,12 @@ import {
import type { SystemOnePayloadValidation } from "./lib/validatePayload";
const QUESTION_TYPES: readonly QuestionType[] = ["choice", "noul", "score"];
const TYPE_LABELS: Record<QuestionType, string> = { choice: "Choice", noul: "Yes / no", score: "Score" };
const TYPE_LABELS: Record<QuestionType, string> = { choice: "Choice", noul: "noul", score: "Score" };
const TYPE_HELP: Record<QuestionType, string | undefined> = {
choice: undefined,
noul: "noul is a yes / no question",
score: undefined,
};
const isQuestionType = (value: unknown): value is QuestionType => QUESTION_TYPES.some((type) => type === value);
@ -219,7 +224,7 @@ function QuestionCard({ name, question, taken, onChange, onRename, onRemove }: Q
</SelectTrigger>
<SelectContent>
{QUESTION_TYPES.map((type) => (
<SelectItem key={type} value={type}>
<SelectItem key={type} value={type} title={TYPE_HELP[type]}>
{TYPE_LABELS[type]}
</SelectItem>
))}

View file

@ -874,7 +874,7 @@ describe("SystemOneUI integration", () => {
fill(question("team").getByRole("textbox", { name: "Description of infra" }), "Deploys");
await user.click(screen.getByRole("button", { name: "Add question" }));
await pickAnswerType(user, "question_1", "Yes / no");
await pickAnswerType(user, "question_1", "noul");
rename(question("question_1").getByRole("textbox", { name: "Question name" }), "urgent");
fill(question("urgent").getByRole("textbox", { name: "Instructions" }), "Is this blocking users?");
fill(question("urgent").getByRole("textbox", { name: "Yes means" }), "Nobody can log in");

View file

@ -5,6 +5,7 @@ import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { SimpleTooltip } from "@/components/ui/tooltip";
import { SearchSelect } from "@/components/shared/SearchSelect";
import { DECISIONS_DOCS_URL } from "@/lib/decisionModels";
import { uiHref } from "@/utils/uiHref";
@ -35,6 +36,7 @@ interface SystemOneSendVariables {
signal: AbortSignal;
}
export const NOUL_HELP = "noul is a yes / no question. The model returns the probability that the answer is yes.";
const DECISION_MODELS_DISCUSSION_URL = "https://github.com/BerriAI/litellm/discussions/44231";
function getCustomProxyBaseUrl(): string | undefined {
@ -229,9 +231,17 @@ export default function SystemOneUI({ accessToken, disabledPersonalKeyCreation =
<Info />
<AlertTitle>{endpoint}</AlertTitle>
<AlertDescription>
{endpoint === "/v1/decisions"
? "Uses input and a questions array with predicate, choice, and score questions. Edit the form or JSON and inspect the response JSON in the OpenAI Decisions format."
: "Uses state and a questions object with noul, choice, and score questions in the System One format."}{" "}
{endpoint === "/v1/decisions" ? (
"Uses input and a questions array with predicate, choice, and score questions. Edit the form or JSON and inspect the response JSON in the OpenAI Decisions format."
) : (
<>
Uses state and a questions object with{" "}
<SimpleTooltip content={NOUL_HELP} className="underline decoration-dotted underline-offset-2">
noul
</SimpleTooltip>
, choice, and score questions in the System One format.
</>
)}{" "}
Pick a decision model under Model, or omit model to use the proxy&apos;s configured default.{" "}
<a href={DECISIONS_DOCS_URL} target="_blank" rel="noopener noreferrer" className="underline">
How to call /v1/decisions and /v1/systemone