Skip to content
1,060 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";
Each agent has an Abilities tab: g1t's built-ins, always on within the asker's access; its computer, coming; each connected integration's actions one row each, read, import, comment or resolve, with a level for each, alone, alone when the person asked for it, ask first or never, and whose connection it runs on; and MCP servers an owner adds. Reading is alone, writing inside g1t follows today's choices, anything that leaves g1t asks first, and production deploys can't go above ask. The agents service enforces every level: ask first posts a card to allow or deny and parks a session until it's answered, a refusal names its rule in the transcript and the audit log, and a missing ability posts a request to owners. The agent abilities guide says how.18import type { AgentAbilities, AgentAbilitiesChange, McpServer } from "./abilities";
Agents have faces, and are never mistaken for people. Every agent wears a little bot face drawn from a look it owns, shape, colour, eyes, mouth, antenna, accessory and pattern, chosen in its builder and on its Profile tab with a live preview, Shuffle and a way back to the face its seed gives it; the face blinks on its own time, breathes, narrows its eyes while the agent works, shuts them asleep and bounces when it finishes, all of it still for anyone who asked for less motion. Wherever an agent shows, in chat, in a list, on a mention, on a review or a commit, its avatar carries an agent marker, and the people reading it are told so. In Chat, direct messages are two lists: People, and Agents, which also holds the agents you haven't talked to yet; a conversation with both a person and an agent in it is marked in the list, named in the conversation's header, spelled out by the composer and explained once the first time it opens. Agents keep their look in the agents service, which every service passes along. The chat and agents guides say so, and CONTRIBUTING makes the shared avatar the only way to draw an agent.19import type { AgentLook } from "./agent-look";
Chat and workspace agents: channels, DMs and named agents you talk to20
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)21/** The built-in orchestrator's handle; nobody else's agent may take it. */
22export const BUILTIN_AGENT_HANDLE = "g1t";
23
24/** The built-in orchestrator's template id: not one a workspace can adopt. */
25export const ORCHESTRATOR_TEMPLATE = "orchestrator";
26
Chat and workspace agents: channels, DMs and named agents you talk to27/** Voice presets; free text in `personality` refines them. */
28export type PersonalityPreset = "crisp" | "friendly" | "socratic" | "terse";
29
30export type AgentRouting = {
31 /** Never route below this tier. Null: no floor. */
32 floor: ModelTier | null;
33 /** Never route above this tier. Null: no ceiling. */
34 ceiling: ModelTier | null;
35 /**
36 * Where its model calls may go. Empty: anything the workspace allows.
37 * `g1t`: g1t's hosted models. `workspace`: the workspace's own providers
38 * (Integrations), whichever they are. Any other entry: one of the
39 * workspace's own providers by integration id. Entries combine, so
40 * `["g1t", "workspace"]` is both.
41 */
42 providers: string[];
43 /** Advanced: a fixed `provider/model`, for own endpoints. Usually null. */
44 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.45 /**
46 * How hard it works (docs.g1t.sh/guides/agents/#effort): the tier its
47 * work starts on, how hard the model reasons, and how many steps a
48 * session may take. `auto` (the default; absent means it) picks per
49 * piece of work. The floor and ceiling still hold.
50 */
51 effort?: AgentEffort;
Chat and workspace agents: channels, DMs and named agents you talk to52};
53
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.54/** An agent's effort setting, cheapest first after `auto`. */
55export type AgentEffort = "auto" | "low" | "medium" | "high" | "max";
56
57export const AGENT_EFFORTS: readonly AgentEffort[] = ["auto", "low", "medium", "high", "max"];
58
59/** A level work actually ran at: what `auto` resolves to each time. */
60export type EffortLevel = Exclude<AgentEffort, "auto">;
61
62export const EFFORT_LEVELS: readonly EffortLevel[] = ["low", "medium", "high", "max"];
63
Chat and workspace agents: channels, DMs and named agents you talk to64export type AgentBudget = {
65 /** Monthly cap in micro-dollars. Null: only the workspace limit applies. */
66 monthly_micros: number | null;
67 daily_micros: number | null;
68 /** Default cap for one task. */
69 task_micros: number | null;
70};
71
72export type AgentAutonomy = {
73 open_pull_requests: "alone" | "approval";
74 merge: "alone" | "approval" | "never";
75 deploy_production: "approval" | "never";
76 edit_docs: "alone" | "suggest";
77};
78
79export type AgentStatus = "idle" | "working" | "waiting" | "out_of_budget" | "paused";
80
81export type WorkspaceAgent = {
82 id: string;
83 workspace_id: string;
84 /** Lowercase, unique in the workspace, never `g1t`. Mentioned as `@handle`. */
85 handle: string;
86 display_name: string;
87 /** Uploaded avatar hash, or null for the generated mark. */
88 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)89 /**
Agents have faces, and are never mistaken for people. Every agent wears a little bot face drawn from a look it owns, shape, colour, eyes, mouth, antenna, accessory and pattern, chosen in its builder and on its Profile tab with a live preview, Shuffle and a way back to the face its seed gives it; the face blinks on its own time, breathes, narrows its eyes while the agent works, shuts them asleep and bounces when it finishes, all of it still for anyone who asked for less motion. Wherever an agent shows, in chat, in a list, on a mention, on a review or a commit, its avatar carries an agent marker, and the people reading it are told so. In Chat, direct messages are two lists: People, and Agents, which also holds the agents you haven't talked to yet; a conversation with both a person and an agent in it is marked in the list, named in the conversation's header, spelled out by the composer and explained once the first time it opens. Agents keep their look in the agents service, which every service passes along. The chat and agents guides say so, and CONTRIBUTING makes the shared avatar the only way to draw an agent.90 * What its generated face is drawn from (./agent-look.ts `lookFromSeed`),
91 * the same for the same seed everywhere. Set from the handle when it is
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)92 * made; changing it gives the agent a new face.
93 */
94 avatar_seed: string;
95 /**
Agents have faces, and are never mistaken for people. Every agent wears a little bot face drawn from a look it owns, shape, colour, eyes, mouth, antenna, accessory and pattern, chosen in its builder and on its Profile tab with a live preview, Shuffle and a way back to the face its seed gives it; the face blinks on its own time, breathes, narrows its eyes while the agent works, shuts them asleep and bounces when it finishes, all of it still for anyone who asked for less motion. Wherever an agent shows, in chat, in a list, on a mention, on a review or a commit, its avatar carries an agent marker, and the people reading it are told so. In Chat, direct messages are two lists: People, and Agents, which also holds the agents you haven't talked to yet; a conversation with both a person and an agent in it is marked in the list, named in the conversation's header, spelled out by the composer and explained once the first time it opens. Agents keep their look in the agents service, which every service passes along. The chat and agents guides say so, and CONTRIBUTING makes the shared avatar the only way to draw an agent.96 * Its face as its owner chose it, part by part (./agent-look.ts), or
97 * null: the face `avatar_seed` draws. Shown wherever the agent appears.
98 */
99 look: AgentLook | null;
100 /**
An agent is on teams the way a person is: through team membership, with no team or department of its own. Add it to teams when you create it, from its profile or from the team's page; the Agents sidebar groups agents by the teams they're on, with those on none last; what an agent is told about its teammates, team budgets, skills reach, Spend's By team and the People pages all read memberships. Agents with an old team name matching a team are moved onto it once; the rest are left off a team. Templates name a role only. The agents, teams and people guides say how.101 * One line, as lists show it: "QA Engineer". Its title when not written.
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)102 */
Chat and workspace agents: channels, DMs and named agents you talk to103 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)104 /**
An agent is on teams the way a person is: through team membership, with no team or department of its own. Add it to teams when you create it, from its profile or from the team's page; the Agents sidebar groups agents by the teams they're on, with those on none last; what an agent is told about its teammates, team budgets, skills reach, Spend's By team and the People pages all read memberships. Agents with an old team name matching a team are moved onto it once; the rest are left off a team. Templates name a role only. The agents, teams and people guides say how.105 * Agents are hired into roles, not tasks: a title and broad
106 * responsibilities. The teams it is on are team memberships, as a
107 * person's are (identity `team_agents`), never part of the agent.
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)108 */
109 title: string;
110 /** What it is responsible for: 2 to 8 short duties, or none yet. */
111 responsibilities: string[];
112 /**
113 * Specialised help it will use inside its own work. Never members, never
114 * wider than their agent. Stored now; they run with tasks and sessions.
115 */
116 subagents: SubagentDef[];
117 /**
Agents recall what Docs say before they answer or work, and each has required reading118 * Its required reading: Docs spaces (by id) it checks first, every time
119 * it answers or works. It still reads only what the person it acts for,
120 * and everyone reading its answer, can read.
121 */
122 reading: string[];
123 /**
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.124 * g1t's foundational skills turned off for it, by id (./skills.ts):
125 * every one is on unless named here. Off takes the skill's playbook out of
126 * its instructions; its tools stay as they are.
127 */
128 skills_off: string[];
129 /**
Each agent has an Abilities tab: g1t's built-ins, always on within the asker's access; its computer, coming; each connected integration's actions one row each, read, import, comment or resolve, with a level for each, alone, alone when the person asked for it, ask first or never, and whose connection it runs on; and MCP servers an owner adds. Reading is alone, writing inside g1t follows today's choices, anything that leaves g1t asks first, and production deploys can't go above ask. The agents service enforces every level: ask first posts a card to allow or deny and parks a session until it's answered, a refusal names its rule in the transcript and the audit log, and a missing ability posts a request to owners. The agent abilities guide says how.130 * What it may do (./abilities.ts, docs.g1t.sh/guides/agent-abilities/):
131 * its level and credentials for each ability it has a choice about, and
132 * the MCP servers an owner added to it. Empty means every default.
133 */
134 abilities: AgentAbilities;
135 /**
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)136 * Who it works with: `internal`, the workspace's own people (back
137 * office), or `customers` (front office). Only `internal` for now.
138 */
139 faces: AgentFaces;
Chat and workspace agents: channels, DMs and named agents you talk to140 /** The job: what it is responsible for and how it works. */
141 instructions: string;
142 personality_preset: PersonalityPreset;
143 /** Free text refining the voice. Never changes what it may do. */
144 personality: string;
145 routing: AgentRouting;
146 budget: AgentBudget;
147 autonomy: AgentAutonomy;
148 /** Tasks it works at once; more queue on its desk. */
149 capacity: number;
150 /** The template it was made from, if any. */
151 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)152 /**
153 * The workspace's built-in orchestrator, `@g1t`: every workspace has one,
154 * made the first time its agents are asked for. It cannot be archived,
155 * and its handle, name, role and job are fixed; its `instructions` are
156 * added to that job. Listed first.
157 */
158 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.159 /**
160 * Who it belongs to (docs.g1t.sh/guides/agents/, "Personal agents"):
161 * `workspace`, the workspace's own, which owners keep; or `personal`, a
162 * member's own, which only that member talks to, in their direct message
163 * with it, and whose spend counts against that member's budget.
164 */
165 scope: WorkspaceAgentScope;
166 /** For a personal agent, the member it belongs to: their user id and username. Null for a workspace agent. */
167 personal_owner_id: string | null;
168 personal_owner: string | null;
Chat and workspace agents: channels, DMs and named agents you talk to169 version: number;
170 status: AgentStatus;
171 /** Spend this calendar month, in micro-dollars. */
172 spent_month_micros: number;
173 created_by: string;
174 created_at: string;
175 updated_at: string;
176 archived_at: string | null;
177};
178
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)179/**
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.180 * Back office or front office (docs.g1t.sh/guides/agents/, "Back office
181 * 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)182 */
183export type AgentFaces = "internal" | "customers";
184
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.185/** A workspace agent, which owners keep, or a member's personal agent. */
186export type WorkspaceAgentScope = "workspace" | "personal";
187
188/** What a personal agent starts with, unless its creator gives it other caps: $20 a month and $2 a session. */
189export const PERSONAL_AGENT_BUDGET = { monthly_micros: 20_000_000, daily_micros: null, task_micros: 2_000_000 } as const;
190
191/** Most personal agents one member keeps in a workspace. */
192export const MAX_PERSONAL_AGENTS = 10;
193
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)194/**
195 * A subagent: help an agent keeps for its own work, such as Margo's
196 * `flake-hunter`. Its routing limits sit within its agent's: a floor below
197 * the agent's is raised to it, a ceiling above is lowered to it.
198 */
199export type SubagentDef = {
200 /** Lowercase letters, digits and hyphens: `flake-hunter`. Unique on the agent. */
201 name: string;
202 /** One line: what it is for. */
203 description: string;
204 instructions: string;
205 routing: { floor: ModelTier | null; ceiling: ModelTier | null };
206 /** How many of it may run at once inside one task, 1 to 8. */
207 max_parallel: number;
208};
209
Chat and workspace agents: channels, DMs and named agents you talk to210export type NewWorkspaceAgent = {
211 handle: string;
212 display_name: string;
An agent is on teams the way a person is: through team membership, with no team or department of its own. Add it to teams when you create it, from its profile or from the team's page; the Agents sidebar groups agents by the teams they're on, with those on none last; what an agent is told about its teammates, team budgets, skills reach, Spend's By team and the People pages all read memberships. Agents with an old team name matching a team are moved onto it once; the rest are left off a team. Templates name a role only. The agents, teams and people guides say how.213 /** Left out or empty: its title. */
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)214 role?: string;
215 title?: string;
216 responsibilities?: string[];
217 subagents?: SubagentDef[];
Agents recall what Docs say before they answer or work, and each has required reading218 /** Docs spaces (by id) it reads first; at most 10. */
219 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.220 /** Foundational skills to turn off, by id (./skills.ts). */
221 skills_off?: string[];
Each agent has an Abilities tab: g1t's built-ins, always on within the asker's access; its computer, coming; each connected integration's actions one row each, read, import, comment or resolve, with a level for each, alone, alone when the person asked for it, ask first or never, and whose connection it runs on; and MCP servers an owner adds. Reading is alone, writing inside g1t follows today's choices, anything that leaves g1t asks first, and production deploys can't go above ask. The agents service enforces every level: ask first posts a card to allow or deny and parks a session until it's answered, a refusal names its rule in the transcript and the audit log, and a missing ability posts a request to owners. The agent abilities guide says how.222 /**
223 * Its abilities' levels and credentials (./abilities.ts), whole: what is
224 * sent replaces what it had. MCP servers are added and removed with
225 * `addMcpServer` and `removeMcpServer`, never here.
226 */
227 abilities?: AgentAbilitiesChange;
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)228 /** Only `internal` for now; `customers` is refused. */
229 faces?: AgentFaces;
Chat and workspace agents: channels, DMs and named agents you talk to230 instructions: string;
231 personality_preset?: PersonalityPreset;
232 personality?: string;
233 routing?: Partial<AgentRouting>;
234 budget?: Partial<AgentBudget>;
235 autonomy?: Partial<AgentAutonomy>;
236 capacity?: number;
237 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)238 /** Its avatar's seed; left out, the handle. */
239 avatar_seed?: string;
Agents have faces, and are never mistaken for people. Every agent wears a little bot face drawn from a look it owns, shape, colour, eyes, mouth, antenna, accessory and pattern, chosen in its builder and on its Profile tab with a live preview, Shuffle and a way back to the face its seed gives it; the face blinks on its own time, breathes, narrows its eyes while the agent works, shuts them asleep and bounces when it finishes, all of it still for anyone who asked for less motion. Wherever an agent shows, in chat, in a list, on a mention, on a review or a commit, its avatar carries an agent marker, and the people reading it are told so. In Chat, direct messages are two lists: People, and Agents, which also holds the agents you haven't talked to yet; a conversation with both a person and an agent in it is marked in the list, named in the conversation's header, spelled out by the composer and explained once the first time it opens. Agents keep their look in the agents service, which every service passes along. The chat and agents guides say so, and CONTRIBUTING makes the shared avatar the only way to draw an agent.240 /** Its face, chosen part by part (./agent-look.ts); null goes back to the seed's face. */
241 look?: AgentLook | 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.242 /**
243 * When creating: `workspace` (owners only, and their default) or
244 * `personal` (any member, when the workspace lets members make them; a
245 * member's default). Ignored on a change: an owner promotes instead.
246 */
247 scope?: WorkspaceAgentScope;
Chat and workspace agents: channels, DMs and named agents you talk to248};
249
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)250/**
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.251 * What g1t drafted from a description (docs.g1t.sh/guides/agents/,
252 * "Describe it"): a whole definition to edit before anything is saved,
253 * and what the agent will want around it. Nothing here is saved until the
254 * agent is created.
255 */
256export type AgentProposal = {
257 /** A complete definition, ready to create as it is. */
258 definition: NewWorkspaceAgent & { scope: WorkspaceAgentScope };
259 /** Other names that suit it, for the shuffle. */
260 name_ideas: string[];
261 /** Foundational skills it should keep on, by id (./skills.ts); the rest are off in `definition.skills_off`. */
262 skills: string[];
263 /** Integrations the job needs, from the catalog (./connectors.ts), with why. */
264 integrations: { id: string; why: string }[];
265 /** Routines that would suit it, to set up on its Routines tab once it exists. */
266 routines: { name: string; when: string; instructions: string }[];
267 /** What drafting it cost, charged to the person who asked (micro-dollars). */
268 charged_micros: number;
269};
270
271/** One line of a Try it conversation, held by the page, never saved. */
272export type DraftTurn = { role: "user" | "assistant"; content: string };
273
274/** A Try it answer, and what it cost the person trying it. */
275export type DraftReply = { text: string; charged_micros: number };
276
277/** Changes drafted from "Tell <name> what to change", to review before they are saved as a new version. */
278export type AgentRedraft = {
279 /** The changes to save, as `update` takes them: only fields that differ. */
280 changes: Partial<NewWorkspaceAgent>;
281 /** One line on what changed. */
282 summary: string;
283 /** The version it was drafted from. */
284 from_version: number;
285 charged_micros: number;
286};
287
288/**
An agent is on teams the way a person is: through team membership, with no team or department of its own. Add it to teams when you create it, from its profile or from the team's page; the Agents sidebar groups agents by the teams they're on, with those on none last; what an agent is told about its teammates, team budgets, skills reach, Spend's By team and the People pages all read memberships. Agents with an old team name matching a team are moved onto it once; the rest are left off a team. Templates name a role only. The agents, teams and people guides say how.289 * A role to hire an agent into, by title. Agents get names, not job
290 * titles ("Margo", the QA Engineer). A template never puts an agent on a
291 * team.
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)292 */
Chat and workspace agents: channels, DMs and named agents you talk to293export type AgentTemplate = {
294 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)295 /** The name it suggests first. */
Chat and workspace agents: channels, DMs and named agents you talk to296 display_name: string;
297 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)298 /** Other names that suit it, for the form's shuffle. Each is also a valid handle, lowercased. */
299 name_ideas: string[];
Chat and workspace agents: channels, DMs and named agents you talk to300 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)301 title: string;
302 responsibilities: string[];
303 subagents: SubagentDef[];
Chat and workspace agents: channels, DMs and named agents you talk to304 instructions: string;
305 personality_preset: PersonalityPreset;
306 routing: AgentRouting;
307};
308
309/** What the chat service hands an agent: a message it should answer. */
310export type AgentDelivery = {
311 workspace: string;
312 workspace_id: string;
313 channel_id: string;
314 channel_kind: "channel" | "dm";
315 channel_name: string | null;
316 agent_id: string;
317 /** The message that woke it. */
318 message_id: string;
319 thread_root: string | null;
320 /** Who asked: the person's user id. */
321 asked_by: string;
322 /** Agent-to-agent hops so far in this chain. */
323 hops: number;
324 /**
325 * What the person who asked may do, from the viewer the chat service
326 * 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.327 * never does more for someone than they could do themselves. Absent
328 * from an older chat service: the agent then treats the asker as unable
329 * to change code.
Chat and workspace agents: channels, DMs and named agents you talk to330 */
331 asker?: AskerAccess | null;
332 /**
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)333 * The agents that handled this request before this one, by id, oldest
334 * first; the last sent the work here. An agent never hands back or
335 * consults the one that sent it work, and the hop limit counts every
336 * hand-off and consult along the chain. Absent: none (a person asked).
337 */
338 chain?: string[];
339 /**
Chat and workspace agents: channels, DMs and named agents you talk to340 * 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.341 * the workspace connected. The agent reads and replies through that
342 * surface; its definition, budget and replies are the same everywhere.
343 * Absent: `g1t`.
Chat and workspace agents: channels, DMs and named agents you talk to344 */
345 surface?: AgentSurface;
346};
347
348/** The chat surfaces an agent answers on. Only g1t's own today. */
349export type AgentSurface = "g1t";
350
351/** Who asked an agent, as far as its reply needs to know. */
352export type AskerAccess = {
353 username: string;
354 /** Their role in the workspace; `outside` for someone who is not a member. */
355 role: Role | "outside";
356 /**
357 * Whether they can change code in the workspace: Code is on for them
358 * and they hold write access (or more) on at least one of its
359 * repositories, through the base permission or a grant.
360 */
361 can_write: boolean;
362};
363
364const WRITING_ROLES = new Set(["write", "maintain", "admin"]);
365
366/**
367 * `user`'s access in `workspace`, for `AgentDelivery.asker`. Pure, with no
368 * imports, so the chat service computes it from its viewer for free.
369 */
370export function askerAccess(user: User, workspace: string): AskerAccess {
371 const slug = workspace.toLowerCase();
372 const membership = user.workspaces?.find((m) => m.slug.toLowerCase() === slug);
373 // Someone who uses only Chat, Docs and agents sees no repository at all.
374 const code = membership?.code_access !== false;
375 const base = membership ? membership.role === "owner" || WRITING_ROLES.has(membership.base_permission ?? "write") : false;
376 const granted = (user.grants ?? []).some((grant) => grant.workspace.toLowerCase() === slug && WRITING_ROLES.has(grant.role));
377 return {
378 username: user.username,
379 role: membership?.role ?? "outside",
380 can_write: code && (base || granted),
381 };
382}
383
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 asked384/**
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.385 * A session: one bounded piece of work an agent took on
386 * (docs.g1t.sh/guides/agent-sessions/). A conversation with an agent is
387 * not a session: talking stays cheap and quick, and when a request needs
388 * 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 asked389 * the conversation. Sessions start other sessions (one of the agent's
390 * subagents, or a colleague brought in), and everything a tree of sessions
391 * spends is charged to the agent at its root, so a chain never escapes the
392 * budget that started it.
393 */
394export type AgentSessionKind =
395 /** Spun off from a conversation: someone asked for work. */
396 | "chat"
397 /** A routine's run. */
398 | "routine"
399 /** A colleague brought in by another session. */
400 | "helper"
401 /** One of the agent's own subagents, inside another session. */
402 | "subagent";
403
404export type AgentSessionStatus =
405 | "queued"
406 | "working"
407 /** Waiting on sessions it started. */
408 | "waiting"
409 /** Stopped at its spend cap: someone who may raise it decides. */
410 | "needs_approval"
411 | "done"
412 | "failed"
413 | "stopped";
414
415/** The statuses of a session that is not over. */
416export const SESSION_LIVE: readonly AgentSessionStatus[] = ["queued", "working", "waiting", "needs_approval"];
417
418export type AgentSession = {
419 id: string;
420 workspace_id: string;
421 agent_id: string;
422 /** The agent's handle, name and face, for lists. */
423 agent_handle: string;
424 agent_name: string;
425 agent_avatar_seed: string;
Agents have faces, and are never mistaken for people. Every agent wears a little bot face drawn from a look it owns, shape, colour, eyes, mouth, antenna, accessory and pattern, chosen in its builder and on its Profile tab with a live preview, Shuffle and a way back to the face its seed gives it; the face blinks on its own time, breathes, narrows its eyes while the agent works, shuts them asleep and bounces when it finishes, all of it still for anyone who asked for less motion. Wherever an agent shows, in chat, in a list, on a mention, on a review or a commit, its avatar carries an agent marker, and the people reading it are told so. In Chat, direct messages are two lists: People, and Agents, which also holds the agents you haven't talked to yet; a conversation with both a person and an agent in it is marked in the list, named in the conversation's header, spelled out by the composer and explained once the first time it opens. Agents keep their look in the agents service, which every service passes along. The chat and agents guides say so, and CONTRIBUTING makes the shared avatar the only way to draw an agent.426 agent_look: AgentLook | 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 asked427 /** The subagent running it, by name, when kind is `subagent`. */
428 subagent: string | null;
429 kind: AgentSessionKind;
430 /** The session that started it, and the root of its tree. */
431 parent_id: string | null;
432 root_id: string;
433 /** Whose budget pays for it: the agent at the root of its tree. */
434 payer_agent_id: string;
435 title: string;
436 goal: string;
437 status: AgentSessionStatus;
438 /** Why it is waiting, stopped or failed, in a line. */
439 status_note: string | null;
440 /** What it found or did, once done: its report. */
441 summary: string | null;
442 /** Where it reports: the conversation it was started from. */
443 channel_id: string;
444 channel_kind: "channel" | "dm";
445 channel_name: string | null;
446 /** Its live card in that conversation; its updates go in the card's thread. */
447 card_message_id: string | null;
448 asked_by: string | null;
449 asked_by_username: string | null;
450 routine_id: string | null;
451 steps: number;
452 tool_calls: number;
453 input_tokens: number;
454 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.455 /**
456 * At list price, what it counts against budgets: the model at the
457 * provider's price with billing's model margin, plus g1t's agent rate on
458 * every token. A root session's includes everything its tree spent.
459 */
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 asked460 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.461 /** What its own steps' model answers cost at the provider's price, its tree's not included. */
462 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 asked463 /** The most it may spend before someone approves more. */
464 cap_micros: number | null;
465 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.466 /** The effort level it ran at (the highest, when `auto` raised it); null for sessions from before effort was recorded. */
467 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 asked468 /** What it produced: issues filed, sessions started. */
469 outputs: SessionOutput[];
470 created_at: string;
471 updated_at: string;
472 finished_at: string | null;
473 /**
474 * False when the viewer is not among the people of the conversation it
475 * came from: they see that it ran and what it cost, never its title,
476 * goal, report or transcript.
477 */
478 visible: boolean;
479};
480
481export type SessionOutput =
482 | { kind: "issue"; repo: string; number: number; title: string }
483 | { kind: "session"; id: string; agent_handle: string; title: string }
484 | { kind: "memory"; id: string; body: string };
485
486/** One entry of a session's transcript, as its page shows it. */
487export type SessionEvent = {
488 seq: number;
489 kind: "goal" | "text" | "tool" | "steer" | "update" | "child" | "result" | "note";
490 /** Who: the agent's handle, a person's username (steering), or null for g1t's notes. */
491 by: string | null;
492 body: string;
493 /** For `tool`: the tool, and whether it read, was withheld, refused or failed. */
494 tool: string | null;
495 outcome: string | null;
496 created_at: string;
497};
498
499export type AgentSessionDetail = {
500 session: AgentSession;
501 events: SessionEvent[];
502 /** Every session in its tree, root first. */
503 tree: AgentSession[];
504 /** Whether the viewer may stop it, steer it, or approve more spend. */
505 can_stop: boolean;
506 can_steer: boolean;
507 can_approve: boolean;
508};
509
510/**
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.511 * What an agent remembers (docs.g1t.sh/guides/agent-memory/). Every fact
512 * carries where it came from, and its scope decides, in code, where it may
513 * 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 asked514 *
515 * - `workspace`: anywhere in the workspace. Owners write these, or an agent
516 * from a public channel, which every member can read already.
517 * - `channel`: only in that channel and its threads.
518 * - `person`: only in a direct message with that one person.
519 */
520export type AgentMemoryScope = "workspace" | "channel" | "person";
521
522export type AgentMemory = {
523 id: string;
524 agent_id: string;
525 scope: AgentMemoryScope;
526 /** The channel's id or the person's user id; empty for `workspace`. */
527 scope_ref: string;
528 /** The channel's name or the person's username, for display. */
529 scope_label: string | null;
530 body: string;
531 source_kind: "message" | "session" | "person";
532 /** A message id, a session id, or the username of who wrote it. */
533 source_ref: string | null;
534 source_label: string | null;
535 /** The channel the source is in, for a link. */
536 source_channel_id: string | null;
537 created_by: string;
538 created_by_kind: "agent" | "user";
539 pinned: boolean;
540 created_at: string;
541 updated_at: string;
542};
543
544/** When a routine runs, in UTC. */
545export type RoutineSchedule = {
546 every: "hour" | "day" | "weekday" | "week";
547 /** Minute of the hour, 0 to 59. */
548 minute: number;
549 /** Hour of the day (UTC), 0 to 23; not used for `hour`. */
550 hour: number;
551 /** Day of the week for `week`, 0 (Sunday) to 6. */
552 weekday: number;
553};
554
555/**
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened556 * 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.557 * (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 opened558 * thing that happened, in a repository its sponsor can read.
559 */
560export const ROUTINE_EVENTS = [
561 { key: "pull_ready", label: "A pull request is ready for review", hint: "Opened ready, or moved out of draft." },
562 { key: "pull_merged", label: "A pull request is merged", hint: "On any branch it targets." },
563 { key: "checks_failed", label: "Checks fail on a pull request", hint: "Its required checks failed or errored." },
564 { key: "issue_opened", label: "An issue is opened", hint: "By a person or an agent." },
565 { key: "deploy_failed", label: "A deploy fails", hint: "A production or preview deploy." },
566] as const;
567
568export type RoutineEvent = (typeof ROUTINE_EVENTS)[number]["key"];
569
570/**
Merge branch 'chat-sidebar' into fast-push571 * 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 asked572 * of support themes. Each run is a session posted in the routine's channel,
573 * paid from the agent's budget, and run with the access of the person who
574 * set it up (its sponsor), never more.
575 */
576export type AgentRoutine = {
577 id: string;
578 agent_id: string;
579 name: string;
580 instructions: string;
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened581 /** When it runs on a clock; null when it runs only on events. */
582 schedule: RoutineSchedule | null;
583 /** What it runs on; empty when it runs only on its schedule. */
584 events: RoutineEvent[];
585 /** Which repositories its events come from, by `workspace/name`; empty: every one its sponsor can read. */
586 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 asked587 channel_id: string;
588 channel_name: string | null;
589 sponsor: string;
590 sponsor_username: string | null;
591 enabled: boolean;
592 /** Why g1t paused it, when it did. */
593 paused_note: string | null;
594 next_run_at: string | null;
595 last_run_at: string | null;
596 last_session_id: string | null;
597 runs: number;
598 created_at: string;
599 updated_at: string;
600};
601
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened602/** A routine suggested from an agent's responsibilities, for an owner to add in one step. */
603export type RoutineSuggestion = { responsibility: string; routine: Omit<NewRoutine, "channel_id"> };
604
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 asked605export type NewRoutine = {
606 name: string;
607 instructions: string;
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened608 /** A schedule, events, or both; at least one. */
609 schedule: RoutineSchedule | null;
610 events?: RoutineEvent[];
611 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 asked612 /** A channel the agent is in, by id. */
613 channel_id: string;
614 enabled?: boolean;
615};
616
617/**
618 * The workspace's say over all its agents together, set by owners: one
619 * monthly budget across every agent, the budget a new agent starts with,
620 * and the cap a session starts with. The workspace's spend limit and AI
621 * credit (billing) sit above all of it.
622 */
623export type AgentPolicy = {
624 /** Every agent's spend together in a month. Null: only the workspace's spend limit. */
625 monthly_micros: number | null;
626 /** The monthly budget a new agent gets. Null: none. */
627 default_agent_monthly_micros: number | null;
628 /** The cap one session starts with, unless its agent's per-task cap is lower. */
629 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.630 /**
631 * What the agents working for one person (their replies and sessions,
632 * asked for by that person) may spend together in a month, unless the
633 * person has a budget of their own. Null: no budget per person.
634 */
635 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.636 /**
637 * Whether members who aren't owners may create personal agents
638 * (docs.g1t.sh/guides/agents/, "Personal agents"). On unless an owner
639 * turns it off; off, existing personal agents keep working.
640 */
641 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.642};
643
644/** One person's budget: what agents working for them may spend in a month, and what they have. */
645export type PersonBudget = {
646 username: string;
647 /** The budget that applies: their own, or the workspace's per-person default. Null: none. */
648 monthly_micros: number | null;
649 /** Whether it is their own, set by an owner, rather than the default. */
650 own: boolean;
651 /** What agents spent for them this month (UTC). */
652 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 asked653};
654
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.655/** Budgets per person: the default, and each person who has one of their own or has spent this month. */
656export type PersonBudgets = {
657 period: string;
658 default_micros: number | null;
659 /** Owners see everyone; anyone else sees only themselves. Most spent first. */
660 people: PersonBudget[];
661};
662
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 asked663export type SpendSlice = { key: string; label: string; micros: number; count: number };
664
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.665/** Which days a breakdown covers: this month (the default), last month, or the last 7 or 30 days, in UTC. */
666export type SpendPeriod = "month" | "last_month" | "7d" | "30d";
667
668/** 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 asked669export 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.670 /** `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 asked671 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.672 /** The span asked for, and its first and last day (`YYYY-MM-DD`, both included). */
673 span: SpendPeriod;
674 from: string;
675 until: string;
676 /** The one person it is about (work asked for by them), or null for everyone's. */
677 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 asked678 total_micros: number;
679 /** Chat replies, sessions, routines, helping colleagues. */
680 by_kind: SpendSlice[];
681 by_model: SpendSlice[];
682 /** Who asked: the work done for each person. */
683 by_person: SpendSlice[];
684 by_agent: SpendSlice[];
685 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.686 /**
687 * Where it was asked: a channel by id (labelled `#name`), direct
688 * messages together (`dm`), and channels the viewer can't read together
689 * (`private`).
690 */
691 by_channel: SpendSlice[];
692 /** 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 asked693 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.694 /** 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 asked695 days: { day: string; micros: number }[];
696};
697
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.698/**
699 * What each effort level has cost one agent, from its own finished
700 * sessions (docs.g1t.sh/guides/spend/#effort): measured, never estimated
701 * from other agents or list prices. A level it has not run at has no
702 * figures.
703 */
704export type EffortCost = {
705 effort: EffortLevel;
706 /** Its sessions (with everything they brought in) that finished in the window. */
707 sessions: number;
708 /** The median charged for one of them: a typical task. Null with none. */
709 typical_micros: number | null;
710 /** Of those, the share finished with nobody having to step in: no steering, not stopped or failed. Null with none. */
711 accepted_share: number | null;
712};
713
714export type AgentEffortCosts = {
715 handle: string;
716 /** Its setting now. */
717 effort: AgentEffort;
718 /** Days of history the figures cover. */
719 window_days: number;
720 levels: EffortCost[];
721};
722
723/** One side of a recommendation's evidence: the agent's sessions at one level. */
724export type EffortEvidence = {
725 effort: EffortLevel;
726 sessions: number;
727 /** Finished with nobody having to step in. */
728 accepted: number;
729 typical_micros: number;
730 mean_micros: number;
731};
732
733/**
734 * A way to spend less without losing quality, checked against the agent's
735 * own past work (docs.g1t.sh/guides/spend/#spend-less-keep-quality). The
736 * weekly check proposes one only when the cheaper level's measured
737 * outcomes hold up; when there is too little history to tell, it says so
738 * (`thin`) instead of proposing anything.
739 */
740export type AgentRecommendation = {
741 id: string;
742 agent_id: string;
743 agent_handle: string;
744 agent_name: string;
745 agent_avatar_seed: string;
Agents have faces, and are never mistaken for people. Every agent wears a little bot face drawn from a look it owns, shape, colour, eyes, mouth, antenna, accessory and pattern, chosen in its builder and on its Profile tab with a live preview, Shuffle and a way back to the face its seed gives it; the face blinks on its own time, breathes, narrows its eyes while the agent works, shuts them asleep and bounces when it finishes, all of it still for anyone who asked for less motion. Wherever an agent shows, in chat, in a list, on a mention, on a review or a commit, its avatar carries an agent marker, and the people reading it are told so. In Chat, direct messages are two lists: People, and Agents, which also holds the agents you haven't talked to yet; a conversation with both a person and an agent in it is marked in the list, named in the conversation's header, spelled out by the composer and explained once the first time it opens. Agents keep their look in the agents service, which every service passes along. The chat and agents guides say so, and CONTRIBUTING makes the shared avatar the only way to draw an agent.746 agent_look: AgentLook | 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.747 /** Lowering its effort setting. */
748 kind: "effort";
749 /** `thin`: not enough history to recommend anything yet. */
750 status: "open" | "applied" | "dismissed" | "thin";
751 from_effort: AgentEffort;
752 to_effort: EffortLevel;
753 /** What it says to do, in a line. */
754 title: string;
755 /** Why, from the numbers in `evidence`, in a sentence. */
756 reason: string;
757 /** What it was measured on: the level it runs at now, and the cheaper one. Null sides had no sessions. */
758 evidence: { window_days: number; current: EffortEvidence | null; cheaper: EffortEvidence | null; needed: number };
759 /** About what a month it would save at the recent pace, from the measured costs. Null when thin. */
760 saving_month_micros: number | null;
761 checked_at: string;
762 resolved_by: string | null;
763 resolved_at: string | null;
764};
765
766export type AgentRecommendations = {
767 /** When the check last ran for the workspace; null before the first. */
768 checked_at: string | null;
769 window_days: number;
770 /** To act on, largest saving first. */
771 open: AgentRecommendation[];
772 /** Agents with too little history to say. */
773 thin: AgentRecommendation[];
774 /** Applied or dismissed in the last 30 days. */
775 resolved: AgentRecommendation[];
776};
777
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/** Agents mode's front page. */
779export type AgentsOverview = {
780 policy: AgentPolicy;
781 /** Every agent's spend this month, against the policy's budget. */
782 spent_month_micros: number;
783 /** The highest alert this month: 75, 90 or 100 (% of the workspace's agent budget). */
784 alert: number | null;
785 agents: WorkspaceAgent[];
786 /** Live sessions, counted by agent id, for the roster. */
787 live_by_agent: Record<string, number>;
788 /** Sessions live now that the viewer can see. */
789 live: AgentSession[];
790 /** Sessions waiting on the viewer: spend they may approve. */
791 waiting_on_you: AgentSession[];
792 /** Recently finished sessions the viewer can see. */
793 recent: AgentSession[];
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened794 /** 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 asked795 upcoming: (AgentRoutine & { agent_handle: string; agent_name: string })[];
796 spend: AgentSpendBreakdown;
797 can_manage: boolean;
798};
799
800/** One thing an agent did, for its Activity tab. */
801export type AgentActivity = {
802 id: string;
803 kind: "reply" | "session";
804 status: string;
805 channel_id: string;
806 channel_name: string | null;
807 /** The session's title; null for a reply or one the viewer can't see. */
808 title: string | null;
809 asked_by_username: string | null;
810 model: string | null;
811 tools: number;
812 charged_micros: number;
813 created_at: string;
814 visible: boolean;
815 /** For a reply, the message it posted; for a session, its id. */
816 ref: string | null;
817};
818
819export type AgentVersion = { version: number; changed_by: string; created_at: string; definition: Partial<NewWorkspaceAgent> };
820
Cards you act on in chat; agents comment and review as themselves; names shown cleanly; commits on the calendar821/** A card action, as chat hands it to agents. */
822export type AgentCardAction = {
823 workspace: string;
824 channel_id: string;
825 message_id: string;
826 viewer: User;
827 card: { kind: string; ref: string | null };
828 action_id: string;
829 input: string | null;
830};
831
Chat and workspace agents: channels, DMs and named agents you talk to832export 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.833 /**
834 * The workspace's agents. Personal agents are left out unless asked
835 * for: `mine`, the viewer's own; `all`, every member's for an owner (the
836 * viewer's own for anyone else).
837 */
838 list(workspace: string, viewer: User, options?: { personal?: "mine" | "all" | null }): Promise<Result<WorkspaceAgent[]>>;
Chat and workspace agents: channels, DMs and named agents you talk to839 get(workspace: string, handle: string, viewer: User): Promise<Result<WorkspaceAgent>>;
840 /** Internal: by id, for the chat service resolving members. */
841 byIds(ids: string[]): Promise<WorkspaceAgent[]>;
An agent is on teams the way a person is: through team membership, with no team or department of its own. Add it to teams when you create it, from its profile or from the team's page; the Agents sidebar groups agents by the teams they're on, with those on none last; what an agent is told about its teammates, team budgets, skills reach, Spend's By team and the People pages all read memberships. Agents with an old team name matching a team are moved onto it once; the rest are left off a team. Templates name a role only. The agents, teams and people guides say how.842 /**
843 * `teams`: the workspace's teams to add it to as it is made, by slug,
844 * each one the viewer manages (owners and the team's maintainers). The
845 * membership is the team's, as anyone's is; a personal agent joins none.
846 */
847 create(workspace: string, viewer: User, input: NewWorkspaceAgent, options?: { teams?: string[] }): Promise<Result<WorkspaceAgent>>;
Chat and workspace agents: channels, DMs and named agents you talk to848 update(
849 workspace: string,
850 handle: string,
851 viewer: User,
852 changes: Partial<NewWorkspaceAgent>,
853 ): Promise<Result<WorkspaceAgent>>;
854 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.855 /**
856 * Drafts a whole agent from a description, with a fast model call charged
857 * to the viewer. Nothing is saved. Whoever may create the agent may draft it.
858 */
859 draft(workspace: string, viewer: User, input: { description: string; scope?: WorkspaceAgentScope | null }): Promise<Result<AgentProposal>>;
860 /**
861 * Try it: the unsaved definition answers the conversation so far, as it
862 * would in a direct message, without tools or memory. Charged to the
863 * viewer; nothing is saved.
864 */
865 tryDraft(workspace: string, viewer: User, input: { definition: NewWorkspaceAgent; messages: DraftTurn[] }): Promise<Result<DraftReply>>;
866 /** Drafts changes to an agent from a request in words; saved only through `update`. Whoever may change the agent may ask. */
867 redraft(workspace: string, handle: string, viewer: User, request: string): Promise<Result<AgentRedraft>>;
868 /**
869 * Owners make a member's personal agent a workspace agent: its definition
870 * and every version move to a workspace agent with the same handle, and
871 * the personal one is archived, with its memory and direct messages.
872 */
873 promote(workspace: string, handle: string, viewer: User): Promise<Result<WorkspaceAgent>>;
Each agent has an Abilities tab: g1t's built-ins, always on within the asker's access; its computer, coming; each connected integration's actions one row each, read, import, comment or resolve, with a level for each, alone, alone when the person asked for it, ask first or never, and whose connection it runs on; and MCP servers an owner adds. Reading is alone, writing inside g1t follows today's choices, anything that leaves g1t asks first, and production deploys can't go above ask. The agents service enforces every level: ask first posts a card to allow or deny and parks a session until it's answered, a refusal names its rule in the transcript and the audit log, and a missing ability posts a request to owners. The agent abilities guide says how.874 /**
875 * Adds an MCP server to an agent (docs.g1t.sh/guides/agent-abilities/,
876 * "MCP servers"): its host is checked, its tools are listed from it, and
877 * the agent gets a new version with each tool as an ability. Owners only.
878 */
879 addMcpServer(workspace: string, handle: string, viewer: User, input: { name: string; url: string }): Promise<Result<McpServer>>;
880 /** Takes an MCP server off an agent, with its abilities: a new version. Owners only. */
881 removeMcpServer(workspace: string, handle: string, viewer: User, id: string): Promise<Result<null>>;
882 /** Lists a server's tools again, for one that changed; a new version when they did. Owners only. */
883 refreshMcpServer(workspace: string, handle: string, viewer: User, id: string): Promise<Result<McpServer>>;
Chat and workspace agents: channels, DMs and named agents you talk to884 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)885 /**
886 * Internal: the workspace's built-in `@g1t` agent, made if it does not
887 * exist yet. The chat service asks for it when someone mentions @g1t in
888 * a channel it is not in yet.
889 */
890 builtin(workspace: string, workspaceId: string): Promise<Result<WorkspaceAgent>>;
Chat and workspace agents: channels, DMs and named agents you talk to891 /** The chat service hands over a message for an agent to answer. Returns at once. */
892 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 asked893 overview(workspace: string, viewer: User): Promise<Result<AgentsOverview>>;
894 sessions(
895 workspace: string,
896 viewer: User,
897 filter?: { handle?: string | null; status?: "live" | "done" | null; limit?: number | null },
898 ): Promise<Result<AgentSession[]>>;
899 session(workspace: string, id: string, viewer: User): Promise<Result<AgentSessionDetail>>;
900 /** Stops a session and every session under it. */
901 stopSession(workspace: string, id: string, viewer: User): Promise<Result<AgentSession>>;
902 /** Raises a stopped session's cap and lets it go on. Owners only. */
903 approveSession(workspace: string, id: string, viewer: User, capMicros: number): Promise<Result<AgentSession>>;
904 /** A person's message to a session, running or finished: it reads it and goes on. */
905 steerSession(workspace: string, id: string, viewer: User, body: string): Promise<Result<AgentSession>>;
906 memories(workspace: string, handle: string, viewer: User): Promise<Result<AgentMemory[]>>;
907 remember(
908 workspace: string,
909 handle: string,
910 viewer: User,
911 input: { body: string; scope: AgentMemoryScope; scope_ref?: string | null },
912 ): Promise<Result<AgentMemory>>;
913 updateMemory(
914 workspace: string,
915 handle: string,
916 viewer: User,
917 id: string,
918 changes: { body?: string; pinned?: boolean },
919 ): Promise<Result<AgentMemory>>;
920 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 opened921 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 asked922 saveRoutine(workspace: string, handle: string, viewer: User, input: NewRoutine, id?: string | null): Promise<Result<AgentRoutine>>;
923 deleteRoutine(workspace: string, handle: string, viewer: User, id: string): Promise<Result<null>>;
924 /** Runs a routine now, as a session. */
925 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.926 /**
927 * Where the spend went: one agent's, or every agent's; this month unless
928 * `period` says otherwise; for everyone, or only the work one `person`
929 * (by username) asked for.
930 */
931 spend(workspace: string, viewer: User, handle?: string | null, options?: { period?: SpendPeriod | null; person?: string | null }): Promise<Result<AgentSpendBreakdown>>;
932 /** Budgets per person this month: owners see everyone's, anyone else their own. */
933 personBudgets(workspace: string, viewer: User): Promise<Result<PersonBudgets>>;
934 /**
935 * Gives one person a monthly budget of their own (`monthly_micros`; 0 for
936 * no budget at all), or with null puts them back on the default. Owners only.
937 */
938 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 asked939 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.940 /** What each effort level has cost this agent, from its own finished sessions. Members only. */
941 effortCosts(workspace: string, handle: string, viewer: User): Promise<Result<AgentEffortCosts>>;
942 /** Ways to spend less, checked against past work: every agent's, or one's. Members only. */
943 recommendations(workspace: string, viewer: User, handle?: string | null): Promise<Result<AgentRecommendations>>;
944 /**
945 * Owners apply one (the agent's effort changes, as a new version, and
946 * the audit log says so) or dismiss it.
947 */
948 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.949 /** What an agent is told about its teams this turn, word for word. Members only. */
950 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 asked951 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 calendar952 /**
953 * Internal, from chat: a person pressed an action on one of agents'
954 * cards. Agents checks they may, acts, and updates the card.
955 */
956 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 asked957 policy(workspace: string, viewer: User): Promise<Result<AgentPolicy>>;
958 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.959 /**
960 * The Marketplace's install requests (./marketplace.ts): every one in the
961 * workspace for an owner, a member's own for anyone else.
962 */
963 installRequests(workspace: string, viewer: User): Promise<Result<InstallRequests>>;
964 /**
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.965 * A member asks the workspace's owners to add a listing
966 * (`extension:<id>` or `integration:<connector>`), and every owner is
967 * 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.968 * things themselves, so they don't ask. Asking again while a request for
969 * the same listing is open is a conflict.
970 */
971 requestInstall(workspace: string, viewer: User, listing: string, note?: string | null): Promise<Result<InstallRequest>>;
972 /** An owner marks a request added (`done`) or turns it down (`declined`); whoever asked is told. */
973 resolveInstallRequest(workspace: string, viewer: User, id: string, status: Exclude<InstallRequestStatus, "open">): Promise<Result<InstallRequest>>;
974 /** The extensions installed in the workspace; any member sees them. */
975 extensionInstalls(workspace: string, viewer: User): Promise<Result<ExtensionInstall[]>>;
976 /** Owners install a published extension at its current version; open requests for it are answered. */
977 installExtension(workspace: string, viewer: User, extension: string): Promise<Result<ExtensionInstall>>;
978 /** Owners switch an install on or off: off is the kill switch. */
979 setExtensionEnabled(workspace: string, viewer: User, listing: string, enabled: boolean): Promise<Result<ExtensionInstall>>;
980 /** Owners cap what an install spends a month; null leaves it to the workspace's limit. */
981 setExtensionBudget(workspace: string, viewer: User, listing: string, monthlyMicros: number | null): Promise<Result<ExtensionInstall>>;
982 uninstallExtension(workspace: string, viewer: User, listing: string): Promise<Result<null>>;
Chat and workspace agents: channels, DMs and named agents you talk to983};
984
985async function rpc<T>(service: ServiceBinding, method: string, args: object): Promise<T> {
986 const response = await service.fetch(`https://service/rpc/${method}`, {
987 method: "POST",
988 headers: { "content-type": "application/json" },
989 body: JSON.stringify(args),
990 });
991 if (!response.ok) {
992 throw new Error(`${method} failed with status ${response.status}`);
993 }
994 return (await response.json()) as T;
995}
996
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.997/**
998 * What an agent is told about its teams every turn (docs.g1t.sh/guides/people-and-teams/,
999 * "What agents are told"): the visible teams it is on, by slug, and the text
1000 * itself; null when it is on none.
1001 */
1002export type AgentTeamContext = { handle: string; teams: string[]; text: string | null };
1003
Chat and workspace agents: channels, DMs and named agents you talk to1004export function workspaceAgentsClient(service: ServiceBinding): WorkspaceAgentsApi {
1005 const call = <T>(method: string, args: object) => rpc<T>(service, method, args);
1006 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.1007 list: (workspace, viewer, options) => call("list", { workspace, viewer, personal: options?.personal ?? null }),
Chat and workspace agents: channels, DMs and named agents you talk to1008 get: (workspace, handle, viewer) => call("get", { workspace, handle, viewer }),
1009 byIds: (ids) => call("by_ids", { ids }),
An agent is on teams the way a person is: through team membership, with no team or department of its own. Add it to teams when you create it, from its profile or from the team's page; the Agents sidebar groups agents by the teams they're on, with those on none last; what an agent is told about its teammates, team budgets, skills reach, Spend's By team and the People pages all read memberships. Agents with an old team name matching a team are moved onto it once; the rest are left off a team. Templates name a role only. The agents, teams and people guides say how.1010 create: (workspace, viewer, input, options) => call("create", { workspace, viewer, input, teams: options?.teams ?? [] }),
Chat and workspace agents: channels, DMs and named agents you talk to1011 update: (workspace, handle, viewer, changes) => call("update", { workspace, handle, viewer, changes }),
1012 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.1013 draft: (workspace, viewer, input) => call("draft", { workspace, viewer, description: input.description, scope: input.scope ?? null }),
1014 tryDraft: (workspace, viewer, input) => call("try_draft", { workspace, viewer, definition: input.definition, messages: input.messages }),
1015 redraft: (workspace, handle, viewer, request) => call("redraft", { workspace, handle, viewer, request }),
1016 promote: (workspace, handle, viewer) => call("promote", { workspace, handle, viewer }),
Each agent has an Abilities tab: g1t's built-ins, always on within the asker's access; its computer, coming; each connected integration's actions one row each, read, import, comment or resolve, with a level for each, alone, alone when the person asked for it, ask first or never, and whose connection it runs on; and MCP servers an owner adds. Reading is alone, writing inside g1t follows today's choices, anything that leaves g1t asks first, and production deploys can't go above ask. The agents service enforces every level: ask first posts a card to allow or deny and parks a session until it's answered, a refusal names its rule in the transcript and the audit log, and a missing ability posts a request to owners. The agent abilities guide says how.1017 addMcpServer: (workspace, handle, viewer, input) => call("add_mcp_server", { workspace, handle, viewer, name: input.name, url: input.url }),
1018 removeMcpServer: (workspace, handle, viewer, id) => call("remove_mcp_server", { workspace, handle, viewer, id }),
1019 refreshMcpServer: (workspace, handle, viewer, id) => call("refresh_mcp_server", { workspace, handle, viewer, id }),
Chat and workspace agents: channels, DMs and named agents you talk to1020 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)1021 builtin: (workspace, workspaceId) => call("builtin", { workspace, workspace_id: workspaceId }),
Chat and workspace agents: channels, DMs and named agents you talk to1022 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 asked1023 overview: (workspace, viewer) => call("overview", { workspace, viewer }),
1024 sessions: (workspace, viewer, filter) => call("sessions", { workspace, viewer, ...(filter ?? {}) }),
1025 session: (workspace, id, viewer) => call("session", { workspace, id, viewer }),
1026 stopSession: (workspace, id, viewer) => call("stop_session", { workspace, id, viewer }),
1027 approveSession: (workspace, id, viewer, capMicros) => call("approve_session", { workspace, id, viewer, cap_micros: capMicros }),
1028 steerSession: (workspace, id, viewer, body) => call("steer_session", { workspace, id, viewer, body }),
1029 memories: (workspace, handle, viewer) => call("memories", { workspace, handle, viewer }),
1030 remember: (workspace, handle, viewer, input) => call("remember", { workspace, handle, viewer, input }),
1031 updateMemory: (workspace, handle, viewer, id, changes) => call("update_memory", { workspace, handle, viewer, id, changes }),
1032 forget: (workspace, handle, viewer, id) => call("forget", { workspace, handle, viewer, id }),
1033 routines: (workspace, handle, viewer) => call("routines", { workspace, handle, viewer }),
1034 saveRoutine: (workspace, handle, viewer, input, id) => call("save_routine", { workspace, handle, viewer, input, id: id ?? null }),
1035 deleteRoutine: (workspace, handle, viewer, id) => call("delete_routine", { workspace, handle, viewer, id }),
1036 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.1037 spend: (workspace, viewer, handle, options) =>
1038 call("spend", { workspace, viewer, handle: handle ?? null, period: options?.period ?? null, person: options?.person ?? null }),
1039 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.1040 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.1041 setPersonBudget: (workspace, viewer, username, monthlyMicros) =>
1042 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 asked1043 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.1044 effortCosts: (workspace, handle, viewer) => call("effort_costs", { workspace, handle, viewer }),
1045 recommendations: (workspace, viewer, handle) => call("recommendations", { workspace, viewer, handle: handle ?? null }),
1046 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 asked1047 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 calendar1048 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 asked1049 policy: (workspace, viewer) => call("policy", { workspace, viewer }),
1050 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.1051 installRequests: (workspace, viewer) => call("install_requests", { workspace, viewer }),
1052 requestInstall: (workspace, viewer, listing, note) => call("request_install", { workspace, viewer, listing, note: note ?? null }),
1053 resolveInstallRequest: (workspace, viewer, id, status) => call("resolve_install_request", { workspace, viewer, id, status }),
1054 extensionInstalls: (workspace, viewer) => call("extension_installs", { workspace, viewer }),
1055 installExtension: (workspace, viewer, extension) => call("install_extension", { workspace, viewer, extension }),
1056 setExtensionEnabled: (workspace, viewer, listing, enabled) => call("set_extension_enabled", { workspace, viewer, listing, enabled }),
1057 setExtensionBudget: (workspace, viewer, listing, monthlyMicros) => call("set_extension_budget", { workspace, viewer, listing, monthly_micros: monthlyMicros }),
1058 uninstallExtension: (workspace, viewer, listing) => call("uninstall_extension", { workspace, viewer, listing }),
Chat and workspace agents: channels, DMs and named agents you talk to1059 };
1060}

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