Skip to content

Commit

Merge branch 'browser-pass' into fast-push

syntaqxcommitted Parents4647f252553782Browse files
9 files+57−170/9 viewed
+1−1
6363 | **Active branches** | Branches other than the default, newest first. See [active branches](#active-branches). |
6464 | **Recent changes**, **Latest on main**, **Activity**, **Previews** | What landed, the default branch's latest commits, what happened (pull requests opened, readied and merged, issues opened and closed, checks, reviews, comments, pushes to the default branch and production deploys), and the previews that are up. |
6565 | **About** | Its description, its [links](#links), what it is, and its latest release (its newest tag). People who can change its settings edit the description and links from here. |
66−| **Health**, **Clone** | How often checks pass, recent builds and open issues by age; the clone address. |
66+| **Health**, **Clone** | How often checks pass (on pull requests, or the project's workflow runs when it ships without them), recent builds and open issues by age; the clone address. |
6767
6868 ### The checklist
6969
+13−0
2828 nextSeen,
2929 pipelineStage,
3030 queuedNumbers,
31+ runHealth,
3132 rankNeeds,
3233 readCookie,
3334 sparkPoints,
179180 ]);
180181 assert.deepEqual(rate, { rate: 0.5, of: 2 });
181182 assert.deepEqual(firstPassRate([]), { rate: null, of: 0 });
183+ // Workflow runs: cancelled, skipped and unfinished ones don't count; a pass on a second attempt isn't a first-try pass.
184+ const runs = runHealth([
185+ { attempt: 1, status: "completed", conclusion: "success" },
186+ { attempt: 2, status: "completed", conclusion: "success" },
187+ { attempt: 1, status: "completed", conclusion: "failure" },
188+ { attempt: 1, status: "completed", conclusion: "cancelled" },
189+ { attempt: 1, status: "in_progress", conclusion: null },
190+ ]);
191+ assert.equal(runs.checkRuns, 3);
192+ assert.equal(runs.passRate, 2 / 3);
193+ assert.deepEqual(runs.firstPass, { rate: 1 / 3, of: 3 });
194+ assert.deepEqual(runHealth([]), { passRate: null, firstPass: { rate: null, of: 0 }, checkRuns: 0 });
182195 assert.equal(formatSpan(null), "—");
183196 assert.equal(formatSpan(30 * MIN), "30m");
184197 assert.equal(formatSpan(5 * HOUR), "5h");
+14−0
417417 return results.filter(Boolean).length / results.length;
418418 }
419419
420+/**
421+ * A project's health from its recent workflow runs, for one that ships
422+ * without pull requests (whose checks are what `checks.completed` counts).
423+ * Only runs that finished and passed or failed count: cancelled and skipped
424+ * say nothing about the code. A run passed on the first try when its first
425+ * attempt is the one that passed.
426+ */
427+export function runHealth(runs: { attempt: number; status: string; conclusion: string | null }[]): { passRate: number | null; firstPass: { rate: number | null; of: number }; checkRuns: number } {
428+ const decided = runs.filter((run) => run.status === "completed" && (run.conclusion === "success" || run.conclusion === "failure"));
429+ const passed = decided.map((run) => run.conclusion === "success");
430+ const first = decided.filter((run) => run.conclusion === "success" && run.attempt <= 1).length;
431+ return { passRate: passRate(passed), firstPass: { rate: decided.length ? first / decided.length : null, of: decided.length }, checkRuns: decided.length };
432+}
433+
420434 /** How long from an issue being opened to its change landing, for each that did, in ms. */
421435 export function issueToMerge(
422436 opened: { repo: string; number: number; at: number }[],
+9−3
7171 projectFeed,
7272 queuedNumbers,
7373 rankNeeds,
74+ runHealth,
7475 stuckMinutes,
7576 } from "../../lib/mission";
7677 import { agentWasAssigned, checklistPlan, hasInstructions, productionChecklist, releaseChecklist, startChecklist } from "../../lib/checklist";
160161 const libraryRepoP = Promise.all([planP, repoP]).then(([plan, repo]) => (plan === "release" && repo?.ok ? repo.value : null));
161162 const packagesP = libraryRepoP.then((repo) => (repo ? soft(packages.list(params.owner, viewer, { repoId: repo.id })) : null));
162163 const workflowsP = planP.then((plan) => (plan && plan !== "production" ? forMembers(() => actions.workflows(path, viewer)) : null));
164+ // Recent workflow runs, for Health when no pull request's checks have finished lately.
165+ const workflowRunsP = soft(actions.runs(path, viewer, { limit: 30 }));
163166 // Only the kinds the feed shows: the newest events are mostly session
164167 // steps and merge checks, which would otherwise crowd out everything.
165168 const eventsP = repoP.then((repo) =>
231234 // The latest release, for About.
232235 soft(repos.tags(path, viewer)),
233236 ]);
237+ const workflowRuns = await workflowRunsP;
234238 const ok = <T,>(result: { ok: true; value: T } | { ok: false } | null): T | null => (result?.ok ? result.value : null);
235239
236240 const openPulls = ok(open) ?? [];
458462 groups: groupActivity(items).slice(0, 30),
459463 eventsLoaded: recent != null,
460464 health: {
461− passRate: passRate(checkEvents.map((c) => c.passed)),
462− firstPass: firstPassRate(checkEvents),
463− checkRuns: checkEvents.length,
465+ // A pull request's checks when any finished lately; otherwise the
466+ // project's workflow runs, for one that ships straight to its branch.
467+ ...(checkEvents.length > 0 || !workflowRuns?.ok
468+ ? { passRate: passRate(checkEvents.map((c) => c.passed)), firstPass: firstPassRate(checkEvents), checkRuns: checkEvents.length }
469+ : runHealth(workflowRuns.value)),
464470 ages: openIssues ? ageBuckets(openIssues.map((issue) => issue.createdAt), now) : null,
465471 },
466472 knows: knows as Memory[],
+4−3
1616 import { page } from "../../lib/meta";
1717 import { useRefreshWhile } from "../../lib/refresh";
1818 import { workspaceAgents } from "../../lib/services.server";
19−import { getViewer, roleIn } from "../../lib/session.server";
19+import { requireUser, roleIn } from "../../lib/session.server";
2020 import { money } from "../../lib/usage";
2121
2222 export function meta({ params, ...args }: Route.MetaArgs) {
2424 }
2525
2626 /** Agents mode's front page: the budget, what is waiting and working, the roster, and where the month went. */
27−export async function loader({ params, context }: Route.LoaderArgs): Promise<{ overview: AgentsOverview | null }> {
28− const viewer = getViewer(context);
27+export async function loader({ params, context, request }: Route.LoaderArgs): Promise<{ overview: AgentsOverview | null }> {
28+ // Signed out, sign in first (as Chat and Docs do), rather than a 404.
29+ const viewer = requireUser(context, request);
2930 if (!viewer || !roleIn(viewer, params.owner)) throw data(null, { status: 404 });
3031 return { overview: await readOrNull(workspaceAgents.overview(params.owner.toLowerCase(), viewer)) };
3132 }
+4−3
66
77 import type { Route } from "./+types/layout";
88 import { workspaceAgents } from "../../../lib/services.server";
9−import { getViewer, roleIn } from "../../../lib/session.server";
9+import { requireUser, roleIn } from "../../../lib/session.server";
1010
1111 /**
1212 * Agents mode: the workspace's agents, for its sidebar, and how many live
1414 */
1515 export type AgentsLayoutData = { slug: string; agents: WorkspaceAgent[] | null; live: Record<string, number> };
1616
17−export async function loader({ params, context }: Route.LoaderArgs): Promise<AgentsLayoutData> {
18− const viewer = getViewer(context);
17+export async function loader({ params, context, request }: Route.LoaderArgs): Promise<AgentsLayoutData> {
18+ // Signed out, sign in first (as Chat and Docs do), rather than a 404.
19+ const viewer = requireUser(context, request);
1920 if (!roleIn(viewer, params.owner)) throw data(null, { status: 404 });
2021 const slug = params.owner.toLowerCase();
2122 const [listed, live] = await Promise.all([
+3−2
1010 import { integrationsSection } from "../../lib/integration-sections";
1111 import { page } from "../../lib/meta";
1212 import { integrations, webhooks } from "../../lib/services.server";
13−import { getViewer, roleIn } from "../../lib/session.server";
13+import { requireUser, roleIn } from "../../lib/session.server";
1414
1515 export function meta({ params, ...args }: Route.MetaArgs) {
1616 return page(args, { title: `Integrations · ${params.owner} · g1t` });
2323 * GitHub import, webhooks); this page only finds them.
2424 */
2525 export async function loader({ params, context, request }: Route.LoaderArgs) {
26− const viewer = getViewer(context);
26+ // Signed out, sign in first (as Chat and Docs do), rather than a 404.
27+ const viewer = requireUser(context, request);
2728 const role = roleIn(viewer, params.owner);
2829 if (!role || !viewer) throw new Response(null, { status: 404 });
2930 const slug = params.owner.toLowerCase();
+1−1
4646 });
4747
4848 test("required spaces come first, then the rest", () => {
49− const picked = pickPassages([c("a:0", "s1", 0.9), c("b:0", "s2", 0.65), c("c:0", "s1", 0.85)], { allowed: new Set(["s1", "s2"]), required: ["s2"], limit: 2 });
49+ const picked = pickPassages([c("a:0", "s1", 0.9), c("b:0", "s2", 0.75), c("c:0", "s1", 0.85)], { allowed: new Set(["s1", "s2"]), required: ["s2"], limit: 2 });
5050 assert.deepEqual(
5151 picked.map((p) => p.id),
5252 ["b:0", "a:0"],
+8−4
88
99 /**
1010 * The least cosine similarity a passage needs to count as being about the
11− * query. bge-base-en-v1.5 scores unrelated English around 0.4 to 0.55 and
12− * a passage on the asked-about topic from about 0.65; 0.6 keeps recall
13− * quiet when the docs say nothing about it.
11+ * query. Measured on g1t's own docs folder (606 passages, chunked and
12+ * embedded as here, bge-base-en-v1.5 with Workers AI's mean pooling): the
13+ * best passage for 16 questions the docs answer scored 0.72 to 0.84, while
14+ * the best for 16 they don't ("hello", a recipe, Postgres tuning, a
15+ * vacation policy, SSO with Okta) scored 0.54 to 0.67. At 0.6, 11 of those
16+ * 16 pulled in passages (up to 89 above it); 0.7 keeps every answer and
17+ * keeps recall quiet when the docs say nothing about the question.
1418 */
15−export const MEANING_FLOOR = 0.6;
19+export const MEANING_FLOOR = 0.7;
1620 /** The score a passage found only by its words carries: below the floor, so callers can tell. */
1721 export const WORDS_SCORE = 0.5;
1822 /** Nearest passages asked of the index. */