flagon-io/g1t

public

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t/services/runner/src/model-env.ts

69 lines2,707 bytesCodeBlame

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Agents as a team: lifecycle, merge queue, billing and a new shell1/** The kinds of work a g1t agent does. Each is routed on its own. */
2export type AgentTask = "implement" | "review" | "update" | "plan";
Members can read a private repository's pull request forks3
Agents as a team: lifecycle, merge queue, billing and a new shell4/** Where one kind of work goes: what people see, and what is sent. */
5export type ModelRoute = {
6 /** The model's public name, e.g. `Claude Sonnet 5.5`. */
7 modelName: string;
8 /** The identifier sent to the provider. */
9 model: string;
10};
Members can read a private repository's pull request forks11
Agents as a team: lifecycle, merge queue, billing and a new shell12/**
13 * g1t's routing policy. Nobody assigning an agent picks a model; the kind
14 * of work decides, here, and the operator changes it in one place.
15 */
16export type AgentRoutes = Record<AgentTask, ModelRoute>;
17
Members can read a private repository's pull request forks18/** The settings that decide where model requests go. */
19export type ModelRouting = {
Agents as a team: lifecycle, merge queue, billing and a new shell20 /**
21 * The provider's key. Not needed when the gateway holds it and requests
22 * authenticate to the gateway instead.
23 */
Members can read a private repository's pull request forks24 ANTHROPIC_API_KEY?: string;
25 /** A Cloudflare AI Gateway id; empty sends requests to the provider directly. */
26 AI_GATEWAY_ID: string;
27 CLOUDFLARE_ACCOUNT_ID: string;
Agents as a team: lifecycle, merge queue, billing and a new shell28 /** Authenticates to the gateway, if it requires it. */
Members can read a private repository's pull request forks29 AI_GATEWAY_TOKEN?: string;
30};
31
Agents as a team: lifecycle, merge queue, billing and a new shell32/** What a run is for, attached to each of its requests at the gateway. */
33export type RunTags = { repo: string; pull: number };
34
35/** Whether there is a way to reach a model at all. */
36export function canReachModel(env: ModelRouting): boolean {
37 return Boolean(env.ANTHROPIC_API_KEY || (env.AI_GATEWAY_ID && env.AI_GATEWAY_TOKEN));
38}
39
Members can read a private repository's pull request forks40/** Where the sandbox sends model requests, and what it sends with them. */
Agents as a team: lifecycle, merge queue, billing and a new shell41export function modelEnv(
42 env: ModelRouting,
43 routes: AgentRoutes,
44 task: AgentTask,
45 tags: RunTags,
46): Record<string, string> {
47 const route = routes[task];
Members can read a private repository's pull request forks48 const vars: Record<string, string> = {
Agents as a team: lifecycle, merge queue, billing and a new shell49 ANTHROPIC_MODEL: route.model,
Members can read a private repository's pull request forks50 // Recorded at the top of the session, so anyone can see what ran.
Agents as a team: lifecycle, merge queue, billing and a new shell51 AGENT_MODEL_NAME: route.modelName,
Members can read a private repository's pull request forks52 };
Agents as a team: lifecycle, merge queue, billing and a new shell53 if (env.ANTHROPIC_API_KEY) vars.ANTHROPIC_API_KEY = env.ANTHROPIC_API_KEY;
54 if (!env.AI_GATEWAY_ID) return vars;
55
56 vars.ANTHROPIC_BASE_URL = `https://gateway.ai.cloudflare.com/v1/${env.CLOUDFLARE_ACCOUNT_ID}/${env.AI_GATEWAY_ID}/anthropic`;
57 // The gateway logs these with every request, so spend and failures can
58 // be read per kind of work, repository and pull request.
59 const headers = [`cf-aig-metadata: ${JSON.stringify({ task, ...tags })}`];
60 if (env.AI_GATEWAY_TOKEN) {
61 vars.AI_GATEWAY_TOKEN = env.AI_GATEWAY_TOKEN;
62 headers.push(`cf-aig-authorization: Bearer ${env.AI_GATEWAY_TOKEN}`);
63 // With the provider's key stored in the gateway, the sandbox never
64 // holds it. The harness still wants the variable set.
65 vars.ANTHROPIC_API_KEY ??= env.AI_GATEWAY_TOKEN;
Members can read a private repository's pull request forks66 }
Agents as a team: lifecycle, merge queue, billing and a new shell67 vars.ANTHROPIC_CUSTOM_HEADERS = headers.join("\n");
Members can read a private repository's pull request forks68 return vars;
69}