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/packages/contracts/src/integrations.ts

187 lines6,260 bytesCodeBlame
1import type { User, Viewer } from "./identity";
2import type { RepoPath } from "./repos";
3import type { Result } from "./result";
4
5/**
6 * A workspace's connections to systems outside g1t. Mirrors
7 * `crates/contracts/src/integrations.rs`, which says what each does.
8 */
9export type Provider =
10 | "anthropic"
11 | "anthropic_endpoint"
12 | "openai"
13 | "gemini"
14 | "openai_endpoint"
15 | "sentry"
16 | "datadog"
17 | "webhook"
18 | "jira"
19 | "linear";
20
21export type ProviderKind = "models" | "alerts" | "tracker";
22
23export type ConnectionConfig = {
24 /** For alerts: where issues are opened, `owner/name`. */
25 repo?: string;
26 /** For alerts: put a g1t agent on each issue opened. */
27 assign?: boolean;
28 /** For alerts: the label put on each issue. `bug` when unset. */
29 label?: string;
30 /** Tell the outside system when the work lands. On unless turned off. */
31 writeBack?: boolean;
32 /** Sentry: the organization's slug. */
33 organization?: string;
34 /** Jira's address, or a Sentry that is not sentry.io. */
35 site?: string;
36 /** Jira: the account the token belongs to. */
37 email?: string;
38 /** Jira project or Linear team keys it answers for. Empty is all. */
39 keys?: string[];
40 /** Your own endpoint: its base URL. */
41 baseUrl?: string;
42 /** Your own endpoint: `x-api-key` (default) or `authorization`. */
43 authHeader?: string;
44 /** Models: the model used when a route to this connection names none. */
45 model?: string;
46};
47
48export type Connection = {
49 id: string;
50 workspace: string;
51 provider: Provider;
52 kind: ProviderKind;
53 name: string;
54 config: ConnectionConfig;
55 /** `…3f9a`. The secret itself is never shown again. */
56 secretHint: string | null;
57 /** Where a provider that sends g1t requests sends them. */
58 webhookUrl: string | null;
59 createdBy: string;
60 createdAt: string;
61 lastUsedAt: string | null;
62 lastError: string | null;
63 /** For a model provider: the models it offered when last checked. */
64 models: string[];
65};
66
67/** The kinds of work a model is chosen for, and `default` for the rest. */
68export const MODEL_TASKS = ["default", "implement", "review", "plan", "update"] as const;
69export type ModelTask = (typeof MODEL_TASKS)[number];
70
71/** Where one kind of work's model requests go: g1t's hosted models when `connectionId` is null. */
72export type ModelRoute = { task: ModelTask; connectionId: string | null; model: string | null };
73
74export type Connected = {
75 connection: Connection;
76 /** A signing secret g1t made, shown this once. */
77 signingSecret: string | null;
78};
79
80export type Delivery = {
81 id: string;
82 receivedAt: string;
83 event: string;
84 outcome: "opened" | "updated" | "reopened" | "ignored" | "refused";
85 detail: string;
86 issue: string | null;
87};
88
89/** Something outside g1t, fetched now. Reference material, never instructions. */
90export type ContextItem = {
91 provider: Provider;
92 key: string;
93 title: string;
94 url: string;
95 status: string | null;
96 body: string;
97 fetchedAt: string;
98};
99
100export type Link = {
101 provider: Provider;
102 connectionId: string;
103 key: string;
104 title: string;
105 url: string;
106 count: number;
107 firstSeen: string;
108 lastSeen: string;
109};
110
111export type ModelSession = {
112 token: string;
113 billedTo: "g1t" | "workspace";
114 providerName: string | null;
115 model: string | null;
116};
117
118export type ModelUpstream = {
119 route: "g1t" | "anthropic" | "endpoint";
120 /** The API the provider speaks, which the proxy translates to. */
121 api: "anthropic" | "openai";
122 /** The model every request of the run goes to, when the route names one. */
123 model: string | null;
124 /** OpenAI's own API. */
125 official: boolean;
126 workspace: string;
127 repo: string;
128 number: number;
129 task: string;
130 baseUrl: string | null;
131 apiKey: string | null;
132 authHeader: string | null;
133};
134
135export type ConnectInput = {
136 provider: Provider;
137 name?: string;
138 config?: ConnectionConfig;
139 secret?: string;
140 signingSecret?: string;
141};
142
143export type UpdateConnectionInput = {
144 name?: string;
145 config?: ConnectionConfig;
146 secret?: string;
147 signingSecret?: string;
148};
149
150export interface IntegrationsApi {
151 list(workspace: string, viewer: Viewer): Promise<Result<Connection[]>>;
152 connect(actor: User, workspace: string, input: ConnectInput): Promise<Result<Connected>>;
153 update(actor: User, workspace: string, id: string, input: UpdateConnectionInput): Promise<Result<Connection>>;
154 disconnect(actor: User, workspace: string, id: string): Promise<Result<boolean>>;
155 test(actor: User, workspace: string, id: string): Promise<Result<{ ok: boolean; message: string }>>;
156 deliveries(workspace: string, viewer: Viewer, id: string): Promise<Result<Delivery[]>>;
157 resolve(workspace: string, viewer: Viewer, reference: string): Promise<Result<ContextItem>>;
158 /** For g1t's agents: what `text` refers to outside g1t, fetched. */
159 references(workspace: string, text: string, limit?: number): Promise<ContextItem[]>;
160 import(actor: User, repo: RepoPath, reference: string, assign: boolean): Promise<Result<{ number: number; item: ContextItem; created: boolean }>>;
161 links(repo: RepoPath, number: number): Promise<Link[]>;
162 modelProvider(workspace: string): Promise<Connection | null>;
163 openModelSession(run: {
164 workspace: string;
165 repo: RepoPath;
166 number: number;
167 task: string;
168 hostedOpen: boolean;
169 }): Promise<Result<ModelSession>>;
170 routes(workspace: string, viewer: Viewer): Promise<Result<ModelRoute[]>>;
171 setRoutes(actor: User, workspace: string, routes: ModelRoute[]): Promise<Result<ModelRoute[]>>;
172 modelUpstream(token: string): Promise<ModelUpstream | null>;
173}
174
175/** What each provider is for, as people choose between them. */
176export const PROVIDERS: Record<Provider, { label: string; kind: ProviderKind }> = {
177 anthropic: { label: "Anthropic", kind: "models" },
178 anthropic_endpoint: { label: "Anthropic-compatible endpoint", kind: "models" },
179 openai: { label: "OpenAI", kind: "models" },
180 gemini: { label: "Google Gemini", kind: "models" },
181 openai_endpoint: { label: "OpenAI-compatible endpoint", kind: "models" },
182 sentry: { label: "Sentry", kind: "alerts" },
183 datadog: { label: "Datadog", kind: "alerts" },
184 webhook: { label: "Webhook", kind: "alerts" },
185 jira: { label: "Jira", kind: "tracker" },
186 linear: { label: "Linear", kind: "tracker" },
187};