Skip to content
1,025 linesCodeBlameRaw

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.

Chat and workspace agents: channels, DMs and named agents you talk to1/**
2 * A workspace's own agents: named members with a job, a personality,
3 * routing limits and a budget, kept by the agents service
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)4 * (`services/agents`). Every workspace also has `@g1t`, its built-in
The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were.5 * orchestrator, kept the same way (`builtin`).
Chat and workspace agents: channels, DMs and named agents you talk to6 *
7 * Wire shapes are snake_case end to end.
8 */
9import type { ServiceBinding } from "./clients";
10import type { Role, User } from "./identity";
11import type { Result } from "./result";
Cards you act on in chat; agents comment and review as themselves; names shown cleanly; commits on the calendar12import type { CardActionResult } from "./chat";
Chat and workspace agents: channels, DMs and named agents you talk to13
14// Model tiers (`ModelTier`, `MODEL_TIERS`) are integrations.ts's, the
15// same ones runs are routed between.
16import type { ModelTier } from "./integrations";
The Marketplace is where a workspace finds what to add, reached from Apps: the agent catalog of roles with who already does each job and Add to workspace; every integration with whether it's connected; g1t's own extensions, listed as Soon; and requests, where members ask and owners add or turn down, each told by a notification. Underneath, an extension is a manifest (publisher and tier, source and version from a tag, scopes, the domains its data goes to, its page on g1tusercontent.com, no price) and an install pins its version with an off switch, a budget and the audit log. Apps lists only what was added from the Marketplace, with pins; g1t's own pages stay in their sidebars, and AI Gateway joins Workspace's. The marketplace guide says how.17import type { ExtensionInstall, InstallRequest, InstallRequestStatus, InstallRequests } from "./marketplace";
Chat and workspace agents: channels, DMs and named agents you talk to18
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)19/** The built-in orchestrator's handle; nobody else's agent may take it. */
20export const BUILTIN_AGENT_HANDLE = "g1t";
21
22/** The built-in orchestrator's template id: not one a workspace can adopt. */
23export const ORCHESTRATOR_TEMPLATE = "orchestrator";
24
Chat and workspace agents: channels, DMs and named agents you talk to25/** Voice presets; free text in `personality` refines them. */
26export type PersonalityPreset = "crisp" | "friendly" | "socratic" | "terse";
27
28export type AgentRouting = {
29 /** Never route below this tier. Null: no floor. */
30 floor: ModelTier | null;
31 /** Never route above this tier. Null: no ceiling. */
32 ceiling: ModelTier | null;
33 /**
34 * Where its model calls may go. Empty: anything the workspace allows.
35 * `g1t`: g1t's hosted models. `workspace`: the workspace's own providers
36 * (Integrations), whichever they are. Any other entry: one of the
37 * workspace's own providers by integration id. Entries combine, so
38 * `["g1t", "workspace"]` is both.
39 */
40 providers: string[];
41 /** Advanced: a fixed `provider/model`, for own endpoints. Usually null. */
42 pinned: string | null;
Pricing says it plainly: models at the provider's price, the agent rate for what g1t runs around every model call (the gateway, secrets, routing, context and pass-through to your own provider, so your own keys too), everything else at cost plus 20%, your own runners free, no seats; Security and quality comes with the plan with no separate fee, and live activations end. Each agent has an effort setting, Auto to Max, with what a typical task has cost at each level, and Spend's Spend less, keep quality suggests a lower level only when the agent's own past work shows quality held, to apply or dismiss. The pricing, spend and agents guides say how.43 /**
44 * How hard it works (docs.g1t.sh/guides/agents/#effort): the tier its
45 * work starts on, how hard the model reasons, and how many steps a
46 * session may take. `auto` (the default; absent means it) picks per
47 * piece of work. The floor and ceiling still hold.
48 */
49 effort?: AgentEffort;
Chat and workspace agents: channels, DMs and named agents you talk to50};
51
Pricing says it plainly: models at the provider's price, the agent rate for what g1t runs around every model call (the gateway, secrets, routing, context and pass-through to your own provider, so your own keys too), everything else at cost plus 20%, your own runners free, no seats; Security and quality comes with the plan with no separate fee, and live activations end. Each agent has an effort setting, Auto to Max, with what a typical task has cost at each level, and Spend's Spend less, keep quality suggests a lower level only when the agent's own past work shows quality held, to apply or dismiss. The pricing, spend and agents guides say how.52/** An agent's effort setting, cheapest first after `auto`. */
53export type AgentEffort = "auto" | "low" | "medium" | "high" | "max";
54
55export const AGENT_EFFORTS: readonly AgentEffort[] = ["auto", "low", "medium", "high", "max"];
56
57/** A level work actually ran at: what `auto` resolves to each time. */
58export type EffortLevel = Exclude<AgentEffort, "auto">;
59
60export const EFFORT_LEVELS: readonly EffortLevel[] = ["low", "medium", "high", "max"];
61
Chat and workspace agents: channels, DMs and named agents you talk to62export type AgentBudget = {
63 /** Monthly cap in micro-dollars. Null: only the workspace limit applies. */
64 monthly_micros: number | null;
65 daily_micros: number | null;
66 /** Default cap for one task. */
67 task_micros: number | null;
68};
69
70export type AgentAutonomy = {
71 open_pull_requests: "alone" | "approval";
72 merge: "alone" | "approval" | "never";
73 deploy_production: "approval" | "never";
74 edit_docs: "alone" | "suggest";
75};
76
77export type AgentStatus = "idle" | "working" | "waiting" | "out_of_budget" | "paused";
78
79export type WorkspaceAgent = {
80 id: string;
81 workspace_id: string;
82 /** Lowercase, unique in the workspace, never `g1t`. Mentioned as `@handle`. */
83 handle: string;
84 display_name: string;
85 /** Uploaded avatar hash, or null for the generated mark. */
86 avatar: string | null;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)87 /**
88 * What its generated avatar is drawn from: a little pixel creature, the
89 * same for the same seed everywhere. Set from the handle when it is
90 * made; changing it gives the agent a new face.
91 */
92 avatar_seed: string;
93 /**
94 * One line, as lists show it: "QA Engineer on the QA team". Made from
95 * the title and team (or department) when not written.
96 */
Chat and workspace agents: channels, DMs and named agents you talk to97 role: string;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)98 /**
The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were.99 * Agents are hired into roles, not tasks: a title, a team, and broad
100 * responsibilities.
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)101 */
102 title: string;
103 /** The team it is on, by slug, from the workspace's teams; null for none. */
104 team: string | null;
105 /** A label for where it works when it is on no team: "QA", "Sales". */
106 department: string;
107 /** What it is responsible for: 2 to 8 short duties, or none yet. */
108 responsibilities: string[];
109 /**
110 * Specialised help it will use inside its own work. Never members, never
111 * wider than their agent. Stored now; they run with tasks and sessions.
112 */
113 subagents: SubagentDef[];
114 /**
Agents recall what Docs say before they answer or work, and each has required reading115 * Its required reading: Docs spaces (by id) it checks first, every time
116 * it answers or works. It still reads only what the person it acts for,
117 * and everyone reading its answer, can read.
118 */
119 reading: string[];
120 /**
Every agent starts with g1t's foundational skills, playbooks for documents, research, data, code, communication, and files and media, each using only tools the agent already has and saying plainly what isn't possible yet: agents make PDFs, Word documents, spreadsheets, CSV and Markdown files with make_file, kept with a doc in Artifacts and served from g1tusercontent.com; an agent's Skills tab shows what each skill can do and with which tools, and owners turn a skill off per agent; the agent skills guide says how.121 * g1t's foundational skills turned off for it, by id (./skills.ts):
122 * every one is on unless named here. Off takes the skill's playbook out of
123 * its instructions; its tools stay as they are.
124 */
125 skills_off: string[];
126 /**
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)127 * Who it works with: `internal`, the workspace's own people (back
128 * office), or `customers` (front office). Only `internal` for now.
129 */
130 faces: AgentFaces;
Chat and workspace agents: channels, DMs and named agents you talk to131 /** The job: what it is responsible for and how it works. */
132 instructions: string;
133 personality_preset: PersonalityPreset;
134 /** Free text refining the voice. Never changes what it may do. */
135 personality: string;
136 routing: AgentRouting;
137 budget: AgentBudget;
138 autonomy: AgentAutonomy;
139 /** Tasks it works at once; more queue on its desk. */
140 capacity: number;
141 /** The template it was made from, if any. */
142 template: string | null;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)143 /**
144 * The workspace's built-in orchestrator, `@g1t`: every workspace has one,
145 * made the first time its agents are asked for. It cannot be archived,
146 * and its handle, name, role and job are fixed; its `instructions` are
147 * added to that job. Listed first.
148 */
149 builtin: boolean;
Anyone makes an agent by describing it: one box drafts the whole agent (name, job, responsibilities, voice, skills to keep, integrations it needs, model limits and budget) as a card to change and try in a chat beside it before creating it, and an agent changes later by saying what to change, shown as a diff before it's saved. Members can make personal agents, which only they talk to and which spend from their own budget, unless owners turn that off; owners promote one to a workspace agent. The agents guide says how.150 /**
151 * Who it belongs to (docs.g1t.sh/guides/agents/, "Personal agents"):
152 * `workspace`, the workspace's own, which owners keep; or `personal`, a
153 * member's own, which only that member talks to, in their direct message
154 * with it, and whose spend counts against that member's budget.
155 */
156 scope: WorkspaceAgentScope;
157 /** For a personal agent, the member it belongs to: their user id and username. Null for a workspace agent. */
158 personal_owner_id: string | null;
159 personal_owner: string | null;
Chat and workspace agents: channels, DMs and named agents you talk to160 version: number;
161 status: AgentStatus;
162 /** Spend this calendar month, in micro-dollars. */
163 spent_month_micros: number;
164 created_by: string;
165 created_at: string;
166 updated_at: string;
167 archived_at: string | null;
168};
169
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)170/**
The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were.171 * Back office or front office (docs.g1t.sh/guides/agents/, "Back office
172 * and front office"). Customer-facing agents are not available yet.
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)173 */
174export type AgentFaces = "internal" | "customers";
175
Anyone makes an agent by describing it: one box drafts the whole agent (name, job, responsibilities, voice, skills to keep, integrations it needs, model limits and budget) as a card to change and try in a chat beside it before creating it, and an agent changes later by saying what to change, shown as a diff before it's saved. Members can make personal agents, which only they talk to and which spend from their own budget, unless owners turn that off; owners promote one to a workspace agent. The agents guide says how.176/** A workspace agent, which owners keep, or a member's personal agent. */
177export type WorkspaceAgentScope = "workspace" | "personal";
178
179/** What a personal agent starts with, unless its creator gives it other caps: $20 a month and $2 a session. */
180export const PERSONAL_AGENT_BUDGET = { monthly_micros: 20_000_000, daily_micros: null, task_micros: 2_000_000 } as const;
181
182/** Most personal agents one member keeps in a workspace. */
183export const MAX_PERSONAL_AGENTS = 10;
184
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)185/**
186 * A subagent: help an agent keeps for its own work, such as Margo's
187 * `flake-hunter`. Its routing limits sit within its agent's: a floor below
188 * the agent's is raised to it, a ceiling above is lowered to it.
189 */
190export type SubagentDef = {
191 /** Lowercase letters, digits and hyphens: `flake-hunter`. Unique on the agent. */
192 name: string;
193 /** One line: what it is for. */
194 description: string;
195 instructions: string;
196 routing: { floor: ModelTier | null; ceiling: ModelTier | null };
197 /** How many of it may run at once inside one task, 1 to 8. */
198 max_parallel: number;
199};
200
Chat and workspace agents: channels, DMs and named agents you talk to201export type NewWorkspaceAgent = {
202 handle: string;
203 display_name: string;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)204 /** Left out or empty: made from the title and team. */
205 role?: string;
206 title?: string;
207 team?: string | null;
208 department?: string;
209 responsibilities?: string[];
210 subagents?: SubagentDef[];
Agents recall what Docs say before they answer or work, and each has required reading211 /** Docs spaces (by id) it reads first; at most 10. */
212 reading?: string[];
Every agent starts with g1t's foundational skills, playbooks for documents, research, data, code, communication, and files and media, each using only tools the agent already has and saying plainly what isn't possible yet: agents make PDFs, Word documents, spreadsheets, CSV and Markdown files with make_file, kept with a doc in Artifacts and served from g1tusercontent.com; an agent's Skills tab shows what each skill can do and with which tools, and owners turn a skill off per agent; the agent skills guide says how.213 /** Foundational skills to turn off, by id (./skills.ts). */
214 skills_off?: string[];
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)215 /** Only `internal` for now; `customers` is refused. */
216 faces?: AgentFaces;
Chat and workspace agents: channels, DMs and named agents you talk to217 instructions: string;
218 personality_preset?: PersonalityPreset;
219 personality?: string;
220 routing?: Partial<AgentRouting>;
221 budget?: Partial<AgentBudget>;
222 autonomy?: Partial<AgentAutonomy>;
223 capacity?: number;
224 template?: string | null;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)225 /** Its avatar's seed; left out, the handle. */
226 avatar_seed?: string;
Anyone makes an agent by describing it: one box drafts the whole agent (name, job, responsibilities, voice, skills to keep, integrations it needs, model limits and budget) as a card to change and try in a chat beside it before creating it, and an agent changes later by saying what to change, shown as a diff before it's saved. Members can make personal agents, which only they talk to and which spend from their own budget, unless owners turn that off; owners promote one to a workspace agent. The agents guide says how.227 /**
228 * When creating: `workspace` (owners only, and their default) or
229 * `personal` (any member, when the workspace lets members make them; a
230 * member's default). Ignored on a change: an owner promotes instead.
231 */
232 scope?: WorkspaceAgentScope;
Chat and workspace agents: channels, DMs and named agents you talk to233};
234
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)235/**
Anyone makes an agent by describing it: one box drafts the whole agent (name, job, responsibilities, voice, skills to keep, integrations it needs, model limits and budget) as a card to change and try in a chat beside it before creating it, and an agent changes later by saying what to change, shown as a diff before it's saved. Members can make personal agents, which only they talk to and which spend from their own budget, unless owners turn that off; owners promote one to a workspace agent. The agents guide says how.236 * What g1t drafted from a description (docs.g1t.sh/guides/agents/,
237 * "Describe it"): a whole definition to edit before anything is saved,
238 * and what the agent will want around it. Nothing here is saved until the
239 * agent is created.
240 */
241export type AgentProposal = {
242 /** A complete definition, ready to create as it is. */
243 definition: NewWorkspaceAgent & { scope: WorkspaceAgentScope };
244 /** Other names that suit it, for the shuffle. */
245 name_ideas: string[];
246 /** Foundational skills it should keep on, by id (./skills.ts); the rest are off in `definition.skills_off`. */
247 skills: string[];
248 /** Integrations the job needs, from the catalog (./connectors.ts), with why. */
249 integrations: { id: string; why: string }[];
250 /** Routines that would suit it, to set up on its Routines tab once it exists. */
251 routines: { name: string; when: string; instructions: string }[];
252 /** What drafting it cost, charged to the person who asked (micro-dollars). */
253 charged_micros: number;
254};
255
256/** One line of a Try it conversation, held by the page, never saved. */
257export type DraftTurn = { role: "user" | "assistant"; content: string };
258
259/** A Try it answer, and what it cost the person trying it. */
260export type DraftReply = { text: string; charged_micros: number };
261
262/** Changes drafted from "Tell <name> what to change", to review before they are saved as a new version. */
263export type AgentRedraft = {
264 /** The changes to save, as `update` takes them: only fields that differ. */
265 changes: Partial<NewWorkspaceAgent>;
266 /** One line on what changed. */
267 summary: string;
268 /** The version it was drafted from. */
269 from_version: number;
270 charged_micros: number;
271};
272
273/**
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)274 * A role to hire an agent into, by department. Agents get names, not job
275 * titles ("Margo", the QA Engineer).
276 */
Chat and workspace agents: channels, DMs and named agents you talk to277export type AgentTemplate = {
278 id: string;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)279 /** The name it suggests first. */
Chat and workspace agents: channels, DMs and named agents you talk to280 display_name: string;
281 handle: string;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)282 /** Other names that suit it, for the form's shuffle. Each is also a valid handle, lowercased. */
283 name_ideas: string[];
Chat and workspace agents: channels, DMs and named agents you talk to284 role: string;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)285 title: string;
286 department: string;
287 responsibilities: string[];
288 subagents: SubagentDef[];
Chat and workspace agents: channels, DMs and named agents you talk to289 instructions: string;
290 personality_preset: PersonalityPreset;
291 routing: AgentRouting;
292};
293
294/** What the chat service hands an agent: a message it should answer. */
295export type AgentDelivery = {
296 workspace: string;
297 workspace_id: string;
298 channel_id: string;
299 channel_kind: "channel" | "dm";
300 channel_name: string | null;
301 agent_id: string;
302 /** The message that woke it. */
303 message_id: string;
304 thread_root: string | null;
305 /** Who asked: the person's user id. */
306 asked_by: string;
307 /** Agent-to-agent hops so far in this chain. */
308 hops: number;
309 /**
310 * What the person who asked may do, from the viewer the chat service
311 * already holds when the message is posted (`askerAccess`). An agent
The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were.312 * never does more for someone than they could do themselves. Absent
313 * from an older chat service: the agent then treats the asker as unable
314 * to change code.
Chat and workspace agents: channels, DMs and named agents you talk to315 */
316 asker?: AskerAccess | null;
317 /**
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)318 * The agents that handled this request before this one, by id, oldest
319 * first; the last sent the work here. An agent never hands back or
320 * consults the one that sent it work, and the hop limit counts every
321 * hand-off and consult along the chain. Absent: none (a person asked).
322 */
323 chain?: string[];
324 /**
Chat and workspace agents: channels, DMs and named agents you talk to325 * Where the conversation is: g1t's own chat, or later another chat app
The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were.326 * the workspace connected. The agent reads and replies through that
327 * surface; its definition, budget and replies are the same everywhere.
328 * Absent: `g1t`.
Chat and workspace agents: channels, DMs and named agents you talk to329 */
330 surface?: AgentSurface;
331};
332
333/** The chat surfaces an agent answers on. Only g1t's own today. */
334export type AgentSurface = "g1t";
335
336/** Who asked an agent, as far as its reply needs to know. */
337export type AskerAccess = {
338 username: string;
339 /** Their role in the workspace; `outside` for someone who is not a member. */
340 role: Role | "outside";
341 /**
342 * Whether they can change code in the workspace: Code is on for them
343 * and they hold write access (or more) on at least one of its
344 * repositories, through the base permission or a grant.
345 */
346 can_write: boolean;
347};
348
349const WRITING_ROLES = new Set(["write", "maintain", "admin"]);
350
351/**
352 * `user`'s access in `workspace`, for `AgentDelivery.asker`. Pure, with no
353 * imports, so the chat service computes it from its viewer for free.
354 */
355export function askerAccess(user: User, workspace: string): AskerAccess {
356 const slug = workspace.toLowerCase();
357 const membership = user.workspaces?.find((m) => m.slug.toLowerCase() === slug);
358 // Someone who uses only Chat, Docs and agents sees no repository at all.
359 const code = membership?.code_access !== false;
360 const base = membership ? membership.role === "owner" || WRITING_ROLES.has(membership.base_permission ?? "write") : false;
361 const granted = (user.grants ?? []).some((grant) => grant.workspace.toLowerCase() === slug && WRITING_ROLES.has(grant.role));
362 return {
363 username: user.username,
364 role: membership?.role ?? "outside",
365 can_write: code && (base || granted),
366 };
367}
368
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked369/**
The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were.370 * A session: one bounded piece of work an agent took on
371 * (docs.g1t.sh/guides/agent-sessions/). A conversation with an agent is
372 * not a session: talking stays cheap and quick, and when a request needs
373 * real work the agent spins off a session for it, with its own context, transcript, budget and live card in
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked374 * the conversation. Sessions start other sessions (one of the agent's
375 * subagents, or a colleague brought in), and everything a tree of sessions
376 * spends is charged to the agent at its root, so a chain never escapes the
377 * budget that started it.
378 */
379export type AgentSessionKind =
380 /** Spun off from a conversation: someone asked for work. */
381 | "chat"
382 /** A routine's run. */
383 | "routine"
384 /** A colleague brought in by another session. */
385 | "helper"
386 /** One of the agent's own subagents, inside another session. */
387 | "subagent";
388
389export type AgentSessionStatus =
390 | "queued"
391 | "working"
392 /** Waiting on sessions it started. */
393 | "waiting"
394 /** Stopped at its spend cap: someone who may raise it decides. */
395 | "needs_approval"
396 | "done"
397 | "failed"
398 | "stopped";
399
400/** The statuses of a session that is not over. */
401export const SESSION_LIVE: readonly AgentSessionStatus[] = ["queued", "working", "waiting", "needs_approval"];
402
403export type AgentSession = {
404 id: string;
405 workspace_id: string;
406 agent_id: string;
407 /** The agent's handle, name and face, for lists. */
408 agent_handle: string;
409 agent_name: string;
410 agent_avatar_seed: string;
411 /** The subagent running it, by name, when kind is `subagent`. */
412 subagent: string | null;
413 kind: AgentSessionKind;
414 /** The session that started it, and the root of its tree. */
415 parent_id: string | null;
416 root_id: string;
417 /** Whose budget pays for it: the agent at the root of its tree. */
418 payer_agent_id: string;
419 title: string;
420 goal: string;
421 status: AgentSessionStatus;
422 /** Why it is waiting, stopped or failed, in a line. */
423 status_note: string | null;
424 /** What it found or did, once done: its report. */
425 summary: string | null;
426 /** Where it reports: the conversation it was started from. */
427 channel_id: string;
428 channel_kind: "channel" | "dm";
429 channel_name: string | null;
430 /** Its live card in that conversation; its updates go in the card's thread. */
431 card_message_id: string | null;
432 asked_by: string | null;
433 asked_by_username: string | null;
434 routine_id: string | null;
435 steps: number;
436 tool_calls: number;
437 input_tokens: number;
438 output_tokens: number;
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.439 /**
440 * At list price, what it counts against budgets: the model at the
441 * provider's price with billing's model margin, plus g1t's agent rate on
442 * every token. A root session's includes everything its tree spent.
443 */
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked444 charged_micros: number;
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.445 /** What its own steps' model answers cost at the provider's price, its tree's not included. */
446 cost_micros: number;
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked447 /** The most it may spend before someone approves more. */
448 cap_micros: number | null;
449 model: string | null;
Pricing says it plainly: models at the provider's price, the agent rate for what g1t runs around every model call (the gateway, secrets, routing, context and pass-through to your own provider, so your own keys too), everything else at cost plus 20%, your own runners free, no seats; Security and quality comes with the plan with no separate fee, and live activations end. Each agent has an effort setting, Auto to Max, with what a typical task has cost at each level, and Spend's Spend less, keep quality suggests a lower level only when the agent's own past work shows quality held, to apply or dismiss. The pricing, spend and agents guides say how.450 /** The effort level it ran at (the highest, when `auto` raised it); null for sessions from before effort was recorded. */
451 effort: EffortLevel | null;
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked452 /** What it produced: issues filed, sessions started. */
453 outputs: SessionOutput[];
454 created_at: string;
455 updated_at: string;
456 finished_at: string | null;
457 /**
458 * False when the viewer is not among the people of the conversation it
459 * came from: they see that it ran and what it cost, never its title,
460 * goal, report or transcript.
461 */
462 visible: boolean;
463};
464
465export type SessionOutput =
466 | { kind: "issue"; repo: string; number: number; title: string }
467 | { kind: "session"; id: string; agent_handle: string; title: string }
468 | { kind: "memory"; id: string; body: string };
469
470/** One entry of a session's transcript, as its page shows it. */
471export type SessionEvent = {
472 seq: number;
473 kind: "goal" | "text" | "tool" | "steer" | "update" | "child" | "result" | "note";
474 /** Who: the agent's handle, a person's username (steering), or null for g1t's notes. */
475 by: string | null;
476 body: string;
477 /** For `tool`: the tool, and whether it read, was withheld, refused or failed. */
478 tool: string | null;
479 outcome: string | null;
480 created_at: string;
481};
482
483export type AgentSessionDetail = {
484 session: AgentSession;
485 events: SessionEvent[];
486 /** Every session in its tree, root first. */
487 tree: AgentSession[];
488 /** Whether the viewer may stop it, steer it, or approve more spend. */
489 can_stop: boolean;
490 can_steer: boolean;
491 can_approve: boolean;
492};
493
494/**
The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were.495 * What an agent remembers (docs.g1t.sh/guides/agent-memory/). Every fact
496 * carries where it came from, and its scope decides, in code, where it may
497 * be recalled and who may see it:
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked498 *
499 * - `workspace`: anywhere in the workspace. Owners write these, or an agent
500 * from a public channel, which every member can read already.
501 * - `channel`: only in that channel and its threads.
502 * - `person`: only in a direct message with that one person.
503 */
504export type AgentMemoryScope = "workspace" | "channel" | "person";
505
506export type AgentMemory = {
507 id: string;
508 agent_id: string;
509 scope: AgentMemoryScope;
510 /** The channel's id or the person's user id; empty for `workspace`. */
511 scope_ref: string;
512 /** The channel's name or the person's username, for display. */
513 scope_label: string | null;
514 body: string;
515 source_kind: "message" | "session" | "person";
516 /** A message id, a session id, or the username of who wrote it. */
517 source_ref: string | null;
518 source_label: string | null;
519 /** The channel the source is in, for a link. */
520 source_channel_id: string | null;
521 created_by: string;
522 created_by_kind: "agent" | "user";
523 pinned: boolean;
524 created_at: string;
525 updated_at: string;
526};
527
528/** When a routine runs, in UTC. */
529export type RoutineSchedule = {
530 every: "hour" | "day" | "weekday" | "week";
531 /** Minute of the hour, 0 to 59. */
532 minute: number;
533 /** Hour of the day (UTC), 0 to 23; not used for `hour`. */
534 hour: number;
535 /** Day of the week for `week`, 0 (Sunday) to 6. */
536 weekday: number;
537};
538
539/**
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened540 * Things that happen in the workspace a routine can run on
The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were.541 * (docs.g1t.sh/guides/agent-routines/). Each run is one session about the one
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened542 * thing that happened, in a repository its sponsor can read.
543 */
544export const ROUTINE_EVENTS = [
545 { key: "pull_ready", label: "A pull request is ready for review", hint: "Opened ready, or moved out of draft." },
546 { key: "pull_merged", label: "A pull request is merged", hint: "On any branch it targets." },
547 { key: "checks_failed", label: "Checks fail on a pull request", hint: "Its required checks failed or errored." },
548 { key: "issue_opened", label: "An issue is opened", hint: "By a person or an agent." },
549 { key: "deploy_failed", label: "A deploy fails", hint: "A production or preview deploy." },
550] as const;
551
552export type RoutineEvent = (typeof ROUTINE_EVENTS)[number]["key"];
553
554/**
Merge branch 'chat-sidebar' into fast-push555 * A routine: work an agent does on a schedule or when something happens, such as Sam's Monday digest
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked556 * of support themes. Each run is a session posted in the routine's channel,
557 * paid from the agent's budget, and run with the access of the person who
558 * set it up (its sponsor), never more.
559 */
560export type AgentRoutine = {
561 id: string;
562 agent_id: string;
563 name: string;
564 instructions: string;
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened565 /** When it runs on a clock; null when it runs only on events. */
566 schedule: RoutineSchedule | null;
567 /** What it runs on; empty when it runs only on its schedule. */
568 events: RoutineEvent[];
569 /** Which repositories its events come from, by `workspace/name`; empty: every one its sponsor can read. */
570 repos: string[];
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked571 channel_id: string;
572 channel_name: string | null;
573 sponsor: string;
574 sponsor_username: string | null;
575 enabled: boolean;
576 /** Why g1t paused it, when it did. */
577 paused_note: string | null;
578 next_run_at: string | null;
579 last_run_at: string | null;
580 last_session_id: string | null;
581 runs: number;
582 created_at: string;
583 updated_at: string;
584};
585
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened586/** A routine suggested from an agent's responsibilities, for an owner to add in one step. */
587export type RoutineSuggestion = { responsibility: string; routine: Omit<NewRoutine, "channel_id"> };
588
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked589export type NewRoutine = {
590 name: string;
591 instructions: string;
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened592 /** A schedule, events, or both; at least one. */
593 schedule: RoutineSchedule | null;
594 events?: RoutineEvent[];
595 repos?: string[];
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked596 /** A channel the agent is in, by id. */
597 channel_id: string;
598 enabled?: boolean;
599};
600
601/**
602 * The workspace's say over all its agents together, set by owners: one
603 * monthly budget across every agent, the budget a new agent starts with,
604 * and the cap a session starts with. The workspace's spend limit and AI
605 * credit (billing) sit above all of it.
606 */
607export type AgentPolicy = {
608 /** Every agent's spend together in a month. Null: only the workspace's spend limit. */
609 monthly_micros: number | null;
610 /** The monthly budget a new agent gets. Null: none. */
611 default_agent_monthly_micros: number | null;
612 /** The cap one session starts with, unless its agent's per-task cap is lower. */
613 default_session_micros: number;
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.614 /**
615 * What the agents working for one person (their replies and sessions,
616 * asked for by that person) may spend together in a month, unless the
617 * person has a budget of their own. Null: no budget per person.
618 */
619 person_monthly_micros: number | null;
Anyone makes an agent by describing it: one box drafts the whole agent (name, job, responsibilities, voice, skills to keep, integrations it needs, model limits and budget) as a card to change and try in a chat beside it before creating it, and an agent changes later by saying what to change, shown as a diff before it's saved. Members can make personal agents, which only they talk to and which spend from their own budget, unless owners turn that off; owners promote one to a workspace agent. The agents guide says how.620 /**
621 * Whether members who aren't owners may create personal agents
622 * (docs.g1t.sh/guides/agents/, "Personal agents"). On unless an owner
623 * turns it off; off, existing personal agents keep working.
624 */
625 members_create_agents: boolean;
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.626};
627
628/** One person's budget: what agents working for them may spend in a month, and what they have. */
629export type PersonBudget = {
630 username: string;
631 /** The budget that applies: their own, or the workspace's per-person default. Null: none. */
632 monthly_micros: number | null;
633 /** Whether it is their own, set by an owner, rather than the default. */
634 own: boolean;
635 /** What agents spent for them this month (UTC). */
636 spent_micros: number;
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked637};
638
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.639/** Budgets per person: the default, and each person who has one of their own or has spent this month. */
640export type PersonBudgets = {
641 period: string;
642 default_micros: number | null;
643 /** Owners see everyone; anyone else sees only themselves. Most spent first. */
644 people: PersonBudget[];
645};
646
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked647export type SpendSlice = { key: string; label: string; micros: number; count: number };
648
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.649/** Which days a breakdown covers: this month (the default), last month, or the last 7 or 30 days, in UTC. */
650export type SpendPeriod = "month" | "last_month" | "7d" | "30d";
651
652/** Where an agent's (or every agent's) spend went over a period. */
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked653export type AgentSpendBreakdown = {
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.654 /** `YYYY-MM` for a month; for a span of days, the month it ends in. */
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked655 period: string;
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.656 /** The span asked for, and its first and last day (`YYYY-MM-DD`, both included). */
657 span: SpendPeriod;
658 from: string;
659 until: string;
660 /** The one person it is about (work asked for by them), or null for everyone's. */
661 person: string | null;
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked662 total_micros: number;
663 /** Chat replies, sessions, routines, helping colleagues. */
664 by_kind: SpendSlice[];
665 by_model: SpendSlice[];
666 /** Who asked: the work done for each person. */
667 by_person: SpendSlice[];
668 by_agent: SpendSlice[];
669 by_team: SpendSlice[];
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.670 /**
671 * Where it was asked: a channel by id (labelled `#name`), direct
672 * messages together (`dm`), and channels the viewer can't read together
673 * (`private`).
674 */
675 by_channel: SpendSlice[];
676 /** The costliest sessions in the period. */
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked677 top_sessions: AgentSession[];
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.678 /** Spend by day in the period. */
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked679 days: { day: string; micros: number }[];
680};
681
Pricing says it plainly: models at the provider's price, the agent rate for what g1t runs around every model call (the gateway, secrets, routing, context and pass-through to your own provider, so your own keys too), everything else at cost plus 20%, your own runners free, no seats; Security and quality comes with the plan with no separate fee, and live activations end. Each agent has an effort setting, Auto to Max, with what a typical task has cost at each level, and Spend's Spend less, keep quality suggests a lower level only when the agent's own past work shows quality held, to apply or dismiss. The pricing, spend and agents guides say how.682/**
683 * What each effort level has cost one agent, from its own finished
684 * sessions (docs.g1t.sh/guides/spend/#effort): measured, never estimated
685 * from other agents or list prices. A level it has not run at has no
686 * figures.
687 */
688export type EffortCost = {
689 effort: EffortLevel;
690 /** Its sessions (with everything they brought in) that finished in the window. */
691 sessions: number;
692 /** The median charged for one of them: a typical task. Null with none. */
693 typical_micros: number | null;
694 /** Of those, the share finished with nobody having to step in: no steering, not stopped or failed. Null with none. */
695 accepted_share: number | null;
696};
697
698export type AgentEffortCosts = {
699 handle: string;
700 /** Its setting now. */
701 effort: AgentEffort;
702 /** Days of history the figures cover. */
703 window_days: number;
704 levels: EffortCost[];
705};
706
707/** One side of a recommendation's evidence: the agent's sessions at one level. */
708export type EffortEvidence = {
709 effort: EffortLevel;
710 sessions: number;
711 /** Finished with nobody having to step in. */
712 accepted: number;
713 typical_micros: number;
714 mean_micros: number;
715};
716
717/**
718 * A way to spend less without losing quality, checked against the agent's
719 * own past work (docs.g1t.sh/guides/spend/#spend-less-keep-quality). The
720 * weekly check proposes one only when the cheaper level's measured
721 * outcomes hold up; when there is too little history to tell, it says so
722 * (`thin`) instead of proposing anything.
723 */
724export type AgentRecommendation = {
725 id: string;
726 agent_id: string;
727 agent_handle: string;
728 agent_name: string;
729 agent_avatar_seed: string;
730 /** Lowering its effort setting. */
731 kind: "effort";
732 /** `thin`: not enough history to recommend anything yet. */
733 status: "open" | "applied" | "dismissed" | "thin";
734 from_effort: AgentEffort;
735 to_effort: EffortLevel;
736 /** What it says to do, in a line. */
737 title: string;
738 /** Why, from the numbers in `evidence`, in a sentence. */
739 reason: string;
740 /** What it was measured on: the level it runs at now, and the cheaper one. Null sides had no sessions. */
741 evidence: { window_days: number; current: EffortEvidence | null; cheaper: EffortEvidence | null; needed: number };
742 /** About what a month it would save at the recent pace, from the measured costs. Null when thin. */
743 saving_month_micros: number | null;
744 checked_at: string;
745 resolved_by: string | null;
746 resolved_at: string | null;
747};
748
749export type AgentRecommendations = {
750 /** When the check last ran for the workspace; null before the first. */
751 checked_at: string | null;
752 window_days: number;
753 /** To act on, largest saving first. */
754 open: AgentRecommendation[];
755 /** Agents with too little history to say. */
756 thin: AgentRecommendation[];
757 /** Applied or dismissed in the last 30 days. */
758 resolved: AgentRecommendation[];
759};
760
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked761/** Agents mode's front page. */
762export type AgentsOverview = {
763 policy: AgentPolicy;
764 /** Every agent's spend this month, against the policy's budget. */
765 spent_month_micros: number;
766 /** The highest alert this month: 75, 90 or 100 (% of the workspace's agent budget). */
767 alert: number | null;
768 agents: WorkspaceAgent[];
769 /** Live sessions, counted by agent id, for the roster. */
770 live_by_agent: Record<string, number>;
771 /** Sessions live now that the viewer can see. */
772 live: AgentSession[];
773 /** Sessions waiting on the viewer: spend they may approve. */
774 waiting_on_you: AgentSession[];
775 /** Recently finished sessions the viewer can see. */
776 recent: AgentSession[];
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened777 /** The next routines to run on a schedule. */
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked778 upcoming: (AgentRoutine & { agent_handle: string; agent_name: string })[];
779 spend: AgentSpendBreakdown;
780 can_manage: boolean;
781};
782
783/** One thing an agent did, for its Activity tab. */
784export type AgentActivity = {
785 id: string;
786 kind: "reply" | "session";
787 status: string;
788 channel_id: string;
789 channel_name: string | null;
790 /** The session's title; null for a reply or one the viewer can't see. */
791 title: string | null;
792 asked_by_username: string | null;
793 model: string | null;
794 tools: number;
795 charged_micros: number;
796 created_at: string;
797 visible: boolean;
798 /** For a reply, the message it posted; for a session, its id. */
799 ref: string | null;
800};
801
802export type AgentVersion = { version: number; changed_by: string; created_at: string; definition: Partial<NewWorkspaceAgent> };
803
Cards you act on in chat; agents comment and review as themselves; names shown cleanly; commits on the calendar804/** A card action, as chat hands it to agents. */
805export type AgentCardAction = {
806 workspace: string;
807 channel_id: string;
808 message_id: string;
809 viewer: User;
810 card: { kind: string; ref: string | null };
811 action_id: string;
812 input: string | null;
813};
814
Chat and workspace agents: channels, DMs and named agents you talk to815export type WorkspaceAgentsApi = {
Anyone makes an agent by describing it: one box drafts the whole agent (name, job, responsibilities, voice, skills to keep, integrations it needs, model limits and budget) as a card to change and try in a chat beside it before creating it, and an agent changes later by saying what to change, shown as a diff before it's saved. Members can make personal agents, which only they talk to and which spend from their own budget, unless owners turn that off; owners promote one to a workspace agent. The agents guide says how.816 /**
817 * The workspace's agents. Personal agents are left out unless asked
818 * for: `mine`, the viewer's own; `all`, every member's for an owner (the
819 * viewer's own for anyone else).
820 */
821 list(workspace: string, viewer: User, options?: { personal?: "mine" | "all" | null }): Promise<Result<WorkspaceAgent[]>>;
Chat and workspace agents: channels, DMs and named agents you talk to822 get(workspace: string, handle: string, viewer: User): Promise<Result<WorkspaceAgent>>;
823 /** Internal: by id, for the chat service resolving members. */
824 byIds(ids: string[]): Promise<WorkspaceAgent[]>;
825 create(workspace: string, viewer: User, input: NewWorkspaceAgent): Promise<Result<WorkspaceAgent>>;
826 update(
827 workspace: string,
828 handle: string,
829 viewer: User,
830 changes: Partial<NewWorkspaceAgent>,
831 ): Promise<Result<WorkspaceAgent>>;
832 archive(workspace: string, handle: string, viewer: User): Promise<Result<null>>;
Anyone makes an agent by describing it: one box drafts the whole agent (name, job, responsibilities, voice, skills to keep, integrations it needs, model limits and budget) as a card to change and try in a chat beside it before creating it, and an agent changes later by saying what to change, shown as a diff before it's saved. Members can make personal agents, which only they talk to and which spend from their own budget, unless owners turn that off; owners promote one to a workspace agent. The agents guide says how.833 /**
834 * Drafts a whole agent from a description, with a fast model call charged
835 * to the viewer. Nothing is saved. Whoever may create the agent may draft it.
836 */
837 draft(workspace: string, viewer: User, input: { description: string; scope?: WorkspaceAgentScope | null }): Promise<Result<AgentProposal>>;
838 /**
839 * Try it: the unsaved definition answers the conversation so far, as it
840 * would in a direct message, without tools or memory. Charged to the
841 * viewer; nothing is saved.
842 */
843 tryDraft(workspace: string, viewer: User, input: { definition: NewWorkspaceAgent; messages: DraftTurn[] }): Promise<Result<DraftReply>>;
844 /** Drafts changes to an agent from a request in words; saved only through `update`. Whoever may change the agent may ask. */
845 redraft(workspace: string, handle: string, viewer: User, request: string): Promise<Result<AgentRedraft>>;
846 /**
847 * Owners make a member's personal agent a workspace agent: its definition
848 * and every version move to a workspace agent with the same handle, and
849 * the personal one is archived, with its memory and direct messages.
850 */
851 promote(workspace: string, handle: string, viewer: User): Promise<Result<WorkspaceAgent>>;
Chat and workspace agents: channels, DMs and named agents you talk to852 templates(): Promise<AgentTemplate[]>;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)853 /**
854 * Internal: the workspace's built-in `@g1t` agent, made if it does not
855 * exist yet. The chat service asks for it when someone mentions @g1t in
856 * a channel it is not in yet.
857 */
858 builtin(workspace: string, workspaceId: string): Promise<Result<WorkspaceAgent>>;
Chat and workspace agents: channels, DMs and named agents you talk to859 /** The chat service hands over a message for an agent to answer. Returns at once. */
860 deliver(delivery: AgentDelivery): Promise<Result<null>>;
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked861 overview(workspace: string, viewer: User): Promise<Result<AgentsOverview>>;
862 sessions(
863 workspace: string,
864 viewer: User,
865 filter?: { handle?: string | null; status?: "live" | "done" | null; limit?: number | null },
866 ): Promise<Result<AgentSession[]>>;
867 session(workspace: string, id: string, viewer: User): Promise<Result<AgentSessionDetail>>;
868 /** Stops a session and every session under it. */
869 stopSession(workspace: string, id: string, viewer: User): Promise<Result<AgentSession>>;
870 /** Raises a stopped session's cap and lets it go on. Owners only. */
871 approveSession(workspace: string, id: string, viewer: User, capMicros: number): Promise<Result<AgentSession>>;
872 /** A person's message to a session, running or finished: it reads it and goes on. */
873 steerSession(workspace: string, id: string, viewer: User, body: string): Promise<Result<AgentSession>>;
874 memories(workspace: string, handle: string, viewer: User): Promise<Result<AgentMemory[]>>;
875 remember(
876 workspace: string,
877 handle: string,
878 viewer: User,
879 input: { body: string; scope: AgentMemoryScope; scope_ref?: string | null },
880 ): Promise<Result<AgentMemory>>;
881 updateMemory(
882 workspace: string,
883 handle: string,
884 viewer: User,
885 id: string,
886 changes: { body?: string; pinned?: boolean },
887 ): Promise<Result<AgentMemory>>;
888 forget(workspace: string, handle: string, viewer: User, id: string): Promise<Result<null>>;
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened889 routines(workspace: string, handle: string, viewer: User): Promise<Result<{ routines: AgentRoutine[]; suggestions: RoutineSuggestion[] }>>;
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked890 saveRoutine(workspace: string, handle: string, viewer: User, input: NewRoutine, id?: string | null): Promise<Result<AgentRoutine>>;
891 deleteRoutine(workspace: string, handle: string, viewer: User, id: string): Promise<Result<null>>;
892 /** Runs a routine now, as a session. */
893 runRoutine(workspace: string, handle: string, viewer: User, id: string): Promise<Result<AgentSession>>;
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.894 /**
895 * Where the spend went: one agent's, or every agent's; this month unless
896 * `period` says otherwise; for everyone, or only the work one `person`
897 * (by username) asked for.
898 */
899 spend(workspace: string, viewer: User, handle?: string | null, options?: { period?: SpendPeriod | null; person?: string | null }): Promise<Result<AgentSpendBreakdown>>;
900 /** Budgets per person this month: owners see everyone's, anyone else their own. */
901 personBudgets(workspace: string, viewer: User): Promise<Result<PersonBudgets>>;
902 /**
903 * Gives one person a monthly budget of their own (`monthly_micros`; 0 for
904 * no budget at all), or with null puts them back on the default. Owners only.
905 */
906 setPersonBudget(workspace: string, viewer: User, username: string, monthlyMicros: number | null): Promise<Result<PersonBudgets>>;
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked907 activity(workspace: string, handle: string, viewer: User): Promise<Result<AgentActivity[]>>;
Pricing says it plainly: models at the provider's price, the agent rate for what g1t runs around every model call (the gateway, secrets, routing, context and pass-through to your own provider, so your own keys too), everything else at cost plus 20%, your own runners free, no seats; Security and quality comes with the plan with no separate fee, and live activations end. Each agent has an effort setting, Auto to Max, with what a typical task has cost at each level, and Spend's Spend less, keep quality suggests a lower level only when the agent's own past work shows quality held, to apply or dismiss. The pricing, spend and agents guides say how.908 /** What each effort level has cost this agent, from its own finished sessions. Members only. */
909 effortCosts(workspace: string, handle: string, viewer: User): Promise<Result<AgentEffortCosts>>;
910 /** Ways to spend less, checked against past work: every agent's, or one's. Members only. */
911 recommendations(workspace: string, viewer: User, handle?: string | null): Promise<Result<AgentRecommendations>>;
912 /**
913 * Owners apply one (the agent's effort changes, as a new version, and
914 * the audit log says so) or dismiss it.
915 */
916 resolveRecommendation(workspace: string, viewer: User, id: string, action: "apply" | "dismiss"): Promise<Result<AgentRecommendation>>;
People and teams are front and centre: one directory of people and agents with presence, local time, titles, teams and what each owns; profiles with manager and reports and the agents they work with; an org chart with each team's agents beside the person who leads it; and teams of any mix, with a lead, a channel, a budget agents keep to and the agents on them. Every agent is told its teams each turn (who leads, who owns what, who's around and who to page), and the team page shows exactly what. Member management is Members and invites; the people and teams guide says how.917 /** What an agent is told about its teams this turn, word for word. Members only. */
918 teamContext(workspace: string, handle: string, viewer: User): Promise<Result<AgentTeamContext>>;
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked919 versions(workspace: string, handle: string, viewer: User): Promise<Result<AgentVersion[]>>;
Cards you act on in chat; agents comment and review as themselves; names shown cleanly; commits on the calendar920 /**
921 * Internal, from chat: a person pressed an action on one of agents'
922 * cards. Agents checks they may, acts, and updates the card.
923 */
924 cardAction(input: AgentCardAction): Promise<Result<CardActionResult>>;
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked925 policy(workspace: string, viewer: User): Promise<Result<AgentPolicy>>;
926 setPolicy(workspace: string, viewer: User, policy: Partial<AgentPolicy>): Promise<Result<AgentPolicy>>;
The Marketplace is where a workspace finds what to add, reached from Apps: the agent catalog of roles with who already does each job and Add to workspace; every integration with whether it's connected; g1t's own extensions, listed as Soon; and requests, where members ask and owners add or turn down, each told by a notification. Underneath, an extension is a manifest (publisher and tier, source and version from a tag, scopes, the domains its data goes to, its page on g1tusercontent.com, no price) and an install pins its version with an off switch, a budget and the audit log. Apps lists only what was added from the Marketplace, with pins; g1t's own pages stay in their sidebars, and AI Gateway joins Workspace's. The marketplace guide says how.927 /**
928 * The Marketplace's install requests (./marketplace.ts): every one in the
929 * workspace for an owner, a member's own for anyone else.
930 */
931 installRequests(workspace: string, viewer: User): Promise<Result<InstallRequests>>;
932 /**
The Marketplace adds what g1t doesn't do and connects what you already use: extensions (Mail, Support, CRM, Recruiting, On-call, and bridges to a helpdesk, CRM or ERP you run, all Soon), starter kits, and integrations connected by the workspace or by each person; agents aren't installed there. Agent templates live in Agents, as starting points you configure, at Agents → Templates, and the Marketplace's old agent addresses lead there. The marketplace and agents guides say how.933 * A member asks the workspace's owners to add a listing
934 * (`extension:<id>` or `integration:<connector>`), and every owner is
935 * notified. Owners add
The Marketplace is where a workspace finds what to add, reached from Apps: the agent catalog of roles with who already does each job and Add to workspace; every integration with whether it's connected; g1t's own extensions, listed as Soon; and requests, where members ask and owners add or turn down, each told by a notification. Underneath, an extension is a manifest (publisher and tier, source and version from a tag, scopes, the domains its data goes to, its page on g1tusercontent.com, no price) and an install pins its version with an off switch, a budget and the audit log. Apps lists only what was added from the Marketplace, with pins; g1t's own pages stay in their sidebars, and AI Gateway joins Workspace's. The marketplace guide says how.936 * things themselves, so they don't ask. Asking again while a request for
937 * the same listing is open is a conflict.
938 */
939 requestInstall(workspace: string, viewer: User, listing: string, note?: string | null): Promise<Result<InstallRequest>>;
940 /** An owner marks a request added (`done`) or turns it down (`declined`); whoever asked is told. */
941 resolveInstallRequest(workspace: string, viewer: User, id: string, status: Exclude<InstallRequestStatus, "open">): Promise<Result<InstallRequest>>;
942 /** The extensions installed in the workspace; any member sees them. */
943 extensionInstalls(workspace: string, viewer: User): Promise<Result<ExtensionInstall[]>>;
944 /** Owners install a published extension at its current version; open requests for it are answered. */
945 installExtension(workspace: string, viewer: User, extension: string): Promise<Result<ExtensionInstall>>;
946 /** Owners switch an install on or off: off is the kill switch. */
947 setExtensionEnabled(workspace: string, viewer: User, listing: string, enabled: boolean): Promise<Result<ExtensionInstall>>;
948 /** Owners cap what an install spends a month; null leaves it to the workspace's limit. */
949 setExtensionBudget(workspace: string, viewer: User, listing: string, monthlyMicros: number | null): Promise<Result<ExtensionInstall>>;
950 uninstallExtension(workspace: string, viewer: User, listing: string): Promise<Result<null>>;
Chat and workspace agents: channels, DMs and named agents you talk to951};
952
953async function rpc<T>(service: ServiceBinding, method: string, args: object): Promise<T> {
954 const response = await service.fetch(`https://service/rpc/${method}`, {
955 method: "POST",
956 headers: { "content-type": "application/json" },
957 body: JSON.stringify(args),
958 });
959 if (!response.ok) {
960 throw new Error(`${method} failed with status ${response.status}`);
961 }
962 return (await response.json()) as T;
963}
964
People and teams are front and centre: one directory of people and agents with presence, local time, titles, teams and what each owns; profiles with manager and reports and the agents they work with; an org chart with each team's agents beside the person who leads it; and teams of any mix, with a lead, a channel, a budget agents keep to and the agents on them. Every agent is told its teams each turn (who leads, who owns what, who's around and who to page), and the team page shows exactly what. Member management is Members and invites; the people and teams guide says how.965/**
966 * What an agent is told about its teams every turn (docs.g1t.sh/guides/people-and-teams/,
967 * "What agents are told"): the visible teams it is on, by slug, and the text
968 * itself; null when it is on none.
969 */
970export type AgentTeamContext = { handle: string; teams: string[]; text: string | null };
971
Chat and workspace agents: channels, DMs and named agents you talk to972export function workspaceAgentsClient(service: ServiceBinding): WorkspaceAgentsApi {
973 const call = <T>(method: string, args: object) => rpc<T>(service, method, args);
974 return {
Anyone makes an agent by describing it: one box drafts the whole agent (name, job, responsibilities, voice, skills to keep, integrations it needs, model limits and budget) as a card to change and try in a chat beside it before creating it, and an agent changes later by saying what to change, shown as a diff before it's saved. Members can make personal agents, which only they talk to and which spend from their own budget, unless owners turn that off; owners promote one to a workspace agent. The agents guide says how.975 list: (workspace, viewer, options) => call("list", { workspace, viewer, personal: options?.personal ?? null }),
Chat and workspace agents: channels, DMs and named agents you talk to976 get: (workspace, handle, viewer) => call("get", { workspace, handle, viewer }),
977 byIds: (ids) => call("by_ids", { ids }),
978 create: (workspace, viewer, input) => call("create", { workspace, viewer, input }),
979 update: (workspace, handle, viewer, changes) => call("update", { workspace, handle, viewer, changes }),
980 archive: (workspace, handle, viewer) => call("archive", { workspace, handle, viewer }),
Anyone makes an agent by describing it: one box drafts the whole agent (name, job, responsibilities, voice, skills to keep, integrations it needs, model limits and budget) as a card to change and try in a chat beside it before creating it, and an agent changes later by saying what to change, shown as a diff before it's saved. Members can make personal agents, which only they talk to and which spend from their own budget, unless owners turn that off; owners promote one to a workspace agent. The agents guide says how.981 draft: (workspace, viewer, input) => call("draft", { workspace, viewer, description: input.description, scope: input.scope ?? null }),
982 tryDraft: (workspace, viewer, input) => call("try_draft", { workspace, viewer, definition: input.definition, messages: input.messages }),
983 redraft: (workspace, handle, viewer, request) => call("redraft", { workspace, handle, viewer, request }),
984 promote: (workspace, handle, viewer) => call("promote", { workspace, handle, viewer }),
Chat and workspace agents: channels, DMs and named agents you talk to985 templates: () => call("templates", {}),
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)986 builtin: (workspace, workspaceId) => call("builtin", { workspace, workspace_id: workspaceId }),
Chat and workspace agents: channels, DMs and named agents you talk to987 deliver: (delivery) => call("deliver", delivery),
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked988 overview: (workspace, viewer) => call("overview", { workspace, viewer }),
989 sessions: (workspace, viewer, filter) => call("sessions", { workspace, viewer, ...(filter ?? {}) }),
990 session: (workspace, id, viewer) => call("session", { workspace, id, viewer }),
991 stopSession: (workspace, id, viewer) => call("stop_session", { workspace, id, viewer }),
992 approveSession: (workspace, id, viewer, capMicros) => call("approve_session", { workspace, id, viewer, cap_micros: capMicros }),
993 steerSession: (workspace, id, viewer, body) => call("steer_session", { workspace, id, viewer, body }),
994 memories: (workspace, handle, viewer) => call("memories", { workspace, handle, viewer }),
995 remember: (workspace, handle, viewer, input) => call("remember", { workspace, handle, viewer, input }),
996 updateMemory: (workspace, handle, viewer, id, changes) => call("update_memory", { workspace, handle, viewer, id, changes }),
997 forget: (workspace, handle, viewer, id) => call("forget", { workspace, handle, viewer, id }),
998 routines: (workspace, handle, viewer) => call("routines", { workspace, handle, viewer }),
999 saveRoutine: (workspace, handle, viewer, input, id) => call("save_routine", { workspace, handle, viewer, input, id: id ?? null }),
1000 deleteRoutine: (workspace, handle, viewer, id) => call("delete_routine", { workspace, handle, viewer, id }),
1001 runRoutine: (workspace, handle, viewer, id) => call("run_routine", { workspace, handle, viewer, id }),
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.1002 spend: (workspace, viewer, handle, options) =>
1003 call("spend", { workspace, viewer, handle: handle ?? null, period: options?.period ?? null, person: options?.person ?? null }),
1004 personBudgets: (workspace, viewer) => call("person_budgets", { workspace, viewer }),
People and teams are front and centre: one directory of people and agents with presence, local time, titles, teams and what each owns; profiles with manager and reports and the agents they work with; an org chart with each team's agents beside the person who leads it; and teams of any mix, with a lead, a channel, a budget agents keep to and the agents on them. Every agent is told its teams each turn (who leads, who owns what, who's around and who to page), and the team page shows exactly what. Member management is Members and invites; the people and teams guide says how.1005 teamContext: (workspace, handle, viewer) => call("team_context", { workspace, handle, viewer }),
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.1006 setPersonBudget: (workspace, viewer, username, monthlyMicros) =>
1007 call("set_person_budget", { workspace, viewer, username, monthly_micros: monthlyMicros }),
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked1008 activity: (workspace, handle, viewer) => call("activity", { workspace, handle, viewer }),
Pricing says it plainly: models at the provider's price, the agent rate for what g1t runs around every model call (the gateway, secrets, routing, context and pass-through to your own provider, so your own keys too), everything else at cost plus 20%, your own runners free, no seats; Security and quality comes with the plan with no separate fee, and live activations end. Each agent has an effort setting, Auto to Max, with what a typical task has cost at each level, and Spend's Spend less, keep quality suggests a lower level only when the agent's own past work shows quality held, to apply or dismiss. The pricing, spend and agents guides say how.1009 effortCosts: (workspace, handle, viewer) => call("effort_costs", { workspace, handle, viewer }),
1010 recommendations: (workspace, viewer, handle) => call("recommendations", { workspace, viewer, handle: handle ?? null }),
1011 resolveRecommendation: (workspace, viewer, id, action) => call("resolve_recommendation", { workspace, viewer, id, action }),
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked1012 versions: (workspace, handle, viewer) => call("versions", { workspace, handle, viewer }),
Cards you act on in chat; agents comment and review as themselves; names shown cleanly; commits on the calendar1013 cardAction: (input) => call("card_action", input),
Agents work in sessions: bounded, visible, steerable work spun off from chat, with subagents and colleagues in a tree paid by its root; memory with sources and scopes; routines; a workspace budget for every agent; agents file issues for whoever asked1014 policy: (workspace, viewer) => call("policy", { workspace, viewer }),
1015 setPolicy: (workspace, viewer, policy) => call("set_policy", { workspace, viewer, policy }),
The Marketplace is where a workspace finds what to add, reached from Apps: the agent catalog of roles with who already does each job and Add to workspace; every integration with whether it's connected; g1t's own extensions, listed as Soon; and requests, where members ask and owners add or turn down, each told by a notification. Underneath, an extension is a manifest (publisher and tier, source and version from a tag, scopes, the domains its data goes to, its page on g1tusercontent.com, no price) and an install pins its version with an off switch, a budget and the audit log. Apps lists only what was added from the Marketplace, with pins; g1t's own pages stay in their sidebars, and AI Gateway joins Workspace's. The marketplace guide says how.1016 installRequests: (workspace, viewer) => call("install_requests", { workspace, viewer }),
1017 requestInstall: (workspace, viewer, listing, note) => call("request_install", { workspace, viewer, listing, note: note ?? null }),
1018 resolveInstallRequest: (workspace, viewer, id, status) => call("resolve_install_request", { workspace, viewer, id, status }),
1019 extensionInstalls: (workspace, viewer) => call("extension_installs", { workspace, viewer }),
1020 installExtension: (workspace, viewer, extension) => call("install_extension", { workspace, viewer, extension }),
1021 setExtensionEnabled: (workspace, viewer, listing, enabled) => call("set_extension_enabled", { workspace, viewer, listing, enabled }),
1022 setExtensionBudget: (workspace, viewer, listing, monthlyMicros) => call("set_extension_budget", { workspace, viewer, listing, monthly_micros: monthlyMicros }),
1023 uninstallExtension: (workspace, viewer, listing) => call("uninstall_extension", { workspace, viewer, listing }),
Chat and workspace agents: channels, DMs and named agents you talk to1024 };
1025}

This file's history is long; its oldest lines are credited to the oldest commit read.