Skip to content
1,184 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";
Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell.17import type { 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";
Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell.19import type { AgentConnector, ConnectorInput, ConnectorSignIn, CustomizeBundle, Marketplace, PluginAgentTemplate, PluginDetail, PluginInstall, PluginListing, SkillListing, WorkspaceConnector } from "./customize";
20import type { SkillScope } from "./skill-library";
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.21import type { AgentLook } from "./agent-look";
Every agent can have its own computer. A session that needs one wakes it: a home of its own on g1t cloud, one per agent and never shared, where it runs commands, reads and writes files and keeps what it made, with each session working in its own folder under a shared home; after ten idle minutes it sleeps, its home kept as a snapshot and restored when it wakes, and Reset wipes the home while memory and artifacts stay. Its shell and files are abilities with the usual choices, Alone, Alone when asked, Ask first or Never, offered only inside sessions and never to a chat reply; every command shows on the session with its output, and the agent's new Computer tab shows the state, the disk used of the five gigabytes included, the recent commands, and Wake, Put to sleep and Reset. Machine time counts only while it is awake, on the sandbox lines of the ledger that name the agent and who asked, held to the same spend caps as the session; the disk itself costs nothing in this version. The runner gained a long-lived supervisor that answers the computer's requests inside the container, and the runner service a computer per agent that keeps its snapshot in the agent homes bucket when one is attached, and says so when none is. The REST API and the agent tool can read a computer, wake it, put it to sleep and reset it. The agents, abilities, sessions, runners, billing and deploy guides say how it works and what an operator sets up; pinning a computer to your own runner, its browser and take-over come next.22import type { AgentComputerCommand, AgentComputerStatus } from "./runner";
Chat and workspace agents: channels, DMs and named agents you talk to23
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)24/** The built-in orchestrator's handle; nobody else's agent may take it. */
25export const BUILTIN_AGENT_HANDLE = "g1t";
26
27/** The built-in orchestrator's template id: not one a workspace can adopt. */
28export const ORCHESTRATOR_TEMPLATE = "orchestrator";
29
Chat and workspace agents: channels, DMs and named agents you talk to30/** Voice presets; free text in `personality` refines them. */
31export type PersonalityPreset = "crisp" | "friendly" | "socratic" | "terse";
32
33export type AgentRouting = {
34 /** Never route below this tier. Null: no floor. */
35 floor: ModelTier | null;
36 /** Never route above this tier. Null: no ceiling. */
37 ceiling: ModelTier | null;
38 /**
39 * Where its model calls may go. Empty: anything the workspace allows.
40 * `g1t`: g1t's hosted models. `workspace`: the workspace's own providers
41 * (Integrations), whichever they are. Any other entry: one of the
42 * workspace's own providers by integration id. Entries combine, so
43 * `["g1t", "workspace"]` is both.
44 */
45 providers: string[];
46 /** Advanced: a fixed `provider/model`, for own endpoints. Usually null. */
47 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.48 /**
49 * How hard it works (docs.g1t.sh/guides/agents/#effort): the tier its
50 * work starts on, how hard the model reasons, and how many steps a
51 * session may take. `auto` (the default; absent means it) picks per
52 * piece of work. The floor and ceiling still hold.
53 */
54 effort?: AgentEffort;
Chat and workspace agents: channels, DMs and named agents you talk to55};
56
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.57/** An agent's effort setting, cheapest first after `auto`. */
58export type AgentEffort = "auto" | "low" | "medium" | "high" | "max";
59
60export const AGENT_EFFORTS: readonly AgentEffort[] = ["auto", "low", "medium", "high", "max"];
61
62/** A level work actually ran at: what `auto` resolves to each time. */
63export type EffortLevel = Exclude<AgentEffort, "auto">;
64
65export const EFFORT_LEVELS: readonly EffortLevel[] = ["low", "medium", "high", "max"];
66
Chat and workspace agents: channels, DMs and named agents you talk to67export type AgentBudget = {
68 /** Monthly cap in micro-dollars. Null: only the workspace limit applies. */
69 monthly_micros: number | null;
70 daily_micros: number | null;
71 /** Default cap for one task. */
72 task_micros: number | null;
73};
74
75export type AgentAutonomy = {
76 open_pull_requests: "alone" | "approval";
77 merge: "alone" | "approval" | "never";
78 deploy_production: "approval" | "never";
79 edit_docs: "alone" | "suggest";
80};
81
82export type AgentStatus = "idle" | "working" | "waiting" | "out_of_budget" | "paused";
83
84export type WorkspaceAgent = {
85 id: string;
86 workspace_id: string;
87 /** Lowercase, unique in the workspace, never `g1t`. Mentioned as `@handle`. */
88 handle: string;
89 display_name: string;
90 /** Uploaded avatar hash, or null for the generated mark. */
91 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)92 /**
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.93 * What its generated face is drawn from (./agent-look.ts `lookFromSeed`),
94 * 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)95 * made; changing it gives the agent a new face.
96 */
97 avatar_seed: string;
98 /**
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.99 * Its face as its owner chose it, part by part (./agent-look.ts), or
100 * null: the face `avatar_seed` draws. Shown wherever the agent appears.
101 */
102 look: AgentLook | null;
103 /**
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.104 * 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)105 */
Chat and workspace agents: channels, DMs and named agents you talk to106 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)107 /**
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.108 * Agents are hired into roles, not tasks: a title and broad
109 * responsibilities. The teams it is on are team memberships, as a
110 * 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)111 */
112 title: string;
113 /** What it is responsible for: 2 to 8 short duties, or none yet. */
114 responsibilities: string[];
115 /**
116 * Specialised help it will use inside its own work. Never members, never
117 * wider than their agent. Stored now; they run with tasks and sessions.
118 */
119 subagents: SubagentDef[];
120 /**
Agents recall what Docs say before they answer or work, and each has required reading121 * Its required reading: Docs spaces (by id) it checks first, every time
122 * it answers or works. It still reads only what the person it acts for,
123 * and everyone reading its answer, can read.
124 */
125 reading: string[];
126 /**
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.127 * g1t's foundational skills turned off for it, by id (./skills.ts):
128 * every one is on unless named here. Off takes the skill's playbook out of
129 * its instructions; its tools stay as they are.
130 */
131 skills_off: string[];
132 /**
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.133 * What it may do (./abilities.ts, docs.g1t.sh/guides/agent-abilities/):
134 * its level and credentials for each ability it has a choice about, and
135 * the MCP servers an owner added to it. Empty means every default.
136 */
137 abilities: AgentAbilities;
138 /**
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)139 * Who it works with: `internal`, the workspace's own people (back
140 * office), or `customers` (front office). Only `internal` for now.
141 */
142 faces: AgentFaces;
Chat and workspace agents: channels, DMs and named agents you talk to143 /** The job: what it is responsible for and how it works. */
144 instructions: string;
145 personality_preset: PersonalityPreset;
146 /** Free text refining the voice. Never changes what it may do. */
147 personality: string;
148 routing: AgentRouting;
149 budget: AgentBudget;
150 autonomy: AgentAutonomy;
151 /** Tasks it works at once; more queue on its desk. */
152 capacity: number;
153 /** The template it was made from, if any. */
154 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)155 /**
156 * The workspace's built-in orchestrator, `@g1t`: every workspace has one,
157 * made the first time its agents are asked for. It cannot be archived,
158 * and its handle, name, role and job are fixed; its `instructions` are
159 * added to that job. Listed first.
160 */
161 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.162 /**
163 * Who it belongs to (docs.g1t.sh/guides/agents/, "Personal agents"):
164 * `workspace`, the workspace's own, which owners keep; or `personal`, a
165 * member's own, which only that member talks to, in their direct message
166 * with it, and whose spend counts against that member's budget.
167 */
168 scope: WorkspaceAgentScope;
169 /** For a personal agent, the member it belongs to: their user id and username. Null for a workspace agent. */
170 personal_owner_id: string | null;
171 personal_owner: string | null;
Chat and workspace agents: channels, DMs and named agents you talk to172 version: number;
173 status: AgentStatus;
174 /** Spend this calendar month, in micro-dollars. */
175 spent_month_micros: number;
176 created_by: string;
177 created_at: string;
178 updated_at: string;
179 archived_at: string | null;
An archived agent can be found, brought back, or deleted for good. The Agents page ends with Archived, folded, where owners see every archived agent and members their own personal ones, each with when and by whom it was archived and what deleting it would take; Restore brings it back, under a new handle when a live agent has taken its old one, and Delete permanently asks for the handle to be typed and then removes its sessions, replies, memories, routines, versions, drafts, skills and its computer's home, leaving its messages in chat under its saved name, the workspace's spend totals and the audit log. In Chat an archived agent is deactivated the way people expect: never offered as someone to message or mention, never woken, a conversation with it kept in the list, dimmed and marked Archived, open to read with a note in place of the composer and a way to restore it for owners; after deletion the conversation still reads, its messages marked as a deleted agent's. The agents, chat and agent budgets guides say so.180 /** Who archived it, by username; null while it is live, or for one archived before this was kept. */
181 archived_by?: string | null;
182};
183
184/**
185 * An archived agent as the Agents page's Archived section lists it
186 * (docs.g1t.sh/guides/agents/, "Archive, restore and delete"): enough to
187 * draw its row and to say what deleting it for good takes with it.
188 */
189export type ArchivedAgent = {
190 id: string;
191 handle: string;
192 display_name: string;
193 title: string;
194 role: string;
195 avatar: string | null;
196 avatar_seed: string;
197 look: AgentLook | null;
198 scope: WorkspaceAgentScope;
199 personal_owner: string | null;
200 archived_at: string;
201 archived_by: string | null;
202 /** What goes with it when it is deleted. */
203 counts: { sessions: number; replies: number; memories: number; routines: number };
Chat and workspace agents: channels, DMs and named agents you talk to204};
205
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)206/**
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.207 * Back office or front office (docs.g1t.sh/guides/agents/, "Back office
208 * 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)209 */
210export type AgentFaces = "internal" | "customers";
211
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.212/** A workspace agent, which owners keep, or a member's personal agent. */
213export type WorkspaceAgentScope = "workspace" | "personal";
214
215/** What a personal agent starts with, unless its creator gives it other caps: $20 a month and $2 a session. */
216export const PERSONAL_AGENT_BUDGET = { monthly_micros: 20_000_000, daily_micros: null, task_micros: 2_000_000 } as const;
217
218/** Most personal agents one member keeps in a workspace. */
219export const MAX_PERSONAL_AGENTS = 10;
220
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)221/**
222 * A subagent: help an agent keeps for its own work, such as Margo's
223 * `flake-hunter`. Its routing limits sit within its agent's: a floor below
224 * the agent's is raised to it, a ceiling above is lowered to it.
225 */
226export type SubagentDef = {
227 /** Lowercase letters, digits and hyphens: `flake-hunter`. Unique on the agent. */
228 name: string;
229 /** One line: what it is for. */
230 description: string;
231 instructions: string;
232 routing: { floor: ModelTier | null; ceiling: ModelTier | null };
233 /** How many of it may run at once inside one task, 1 to 8. */
234 max_parallel: number;
235};
236
Chat and workspace agents: channels, DMs and named agents you talk to237export type NewWorkspaceAgent = {
238 handle: string;
239 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.240 /** 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)241 role?: string;
242 title?: string;
243 responsibilities?: string[];
244 subagents?: SubagentDef[];
Agents recall what Docs say before they answer or work, and each has required reading245 /** Docs spaces (by id) it reads first; at most 10. */
246 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.247 /** Foundational skills to turn off, by id (./skills.ts). */
248 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.249 /**
250 * Its abilities' levels and credentials (./abilities.ts), whole: what is
251 * sent replaces what it had. MCP servers are added and removed with
252 * `addMcpServer` and `removeMcpServer`, never here.
253 */
254 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)255 /** Only `internal` for now; `customers` is refused. */
256 faces?: AgentFaces;
Chat and workspace agents: channels, DMs and named agents you talk to257 instructions: string;
258 personality_preset?: PersonalityPreset;
259 personality?: string;
260 routing?: Partial<AgentRouting>;
261 budget?: Partial<AgentBudget>;
262 autonomy?: Partial<AgentAutonomy>;
263 capacity?: number;
264 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)265 /** Its avatar's seed; left out, the handle. */
266 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.267 /** Its face, chosen part by part (./agent-look.ts); null goes back to the seed's face. */
268 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.269 /**
270 * When creating: `workspace` (owners only, and their default) or
271 * `personal` (any member, when the workspace lets members make them; a
272 * member's default). Ignored on a change: an owner promotes instead.
273 */
274 scope?: WorkspaceAgentScope;
Chat and workspace agents: channels, DMs and named agents you talk to275};
276
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)277/**
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.278 * What g1t drafted from a description (docs.g1t.sh/guides/agents/,
279 * "Describe it"): a whole definition to edit before anything is saved,
280 * and what the agent will want around it. Nothing here is saved until the
281 * agent is created.
282 */
283export type AgentProposal = {
284 /** A complete definition, ready to create as it is. */
285 definition: NewWorkspaceAgent & { scope: WorkspaceAgentScope };
286 /** Other names that suit it, for the shuffle. */
287 name_ideas: string[];
288 /** Foundational skills it should keep on, by id (./skills.ts); the rest are off in `definition.skills_off`. */
289 skills: string[];
290 /** Integrations the job needs, from the catalog (./connectors.ts), with why. */
291 integrations: { id: string; why: string }[];
292 /** Routines that would suit it, to set up on its Routines tab once it exists. */
293 routines: { name: string; when: string; instructions: string }[];
294 /** What drafting it cost, charged to the person who asked (micro-dollars). */
295 charged_micros: number;
296};
297
298/** One line of a Try it conversation, held by the page, never saved. */
299export type DraftTurn = { role: "user" | "assistant"; content: string };
300
301/** A Try it answer, and what it cost the person trying it. */
302export type DraftReply = { text: string; charged_micros: number };
303
304/** Changes drafted from "Tell <name> what to change", to review before they are saved as a new version. */
305export type AgentRedraft = {
306 /** The changes to save, as `update` takes them: only fields that differ. */
307 changes: Partial<NewWorkspaceAgent>;
308 /** One line on what changed. */
309 summary: string;
310 /** The version it was drafted from. */
311 from_version: number;
312 charged_micros: number;
313};
314
315/**
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.316 * A role to hire an agent into, by title. Agents get names, not job
317 * titles ("Margo", the QA Engineer). A template never puts an agent on a
318 * 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)319 */
Chat and workspace agents: channels, DMs and named agents you talk to320export type AgentTemplate = {
321 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)322 /** The name it suggests first. */
Chat and workspace agents: channels, DMs and named agents you talk to323 display_name: string;
324 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)325 /** Other names that suit it, for the form's shuffle. Each is also a valid handle, lowercased. */
326 name_ideas: string[];
Chat and workspace agents: channels, DMs and named agents you talk to327 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)328 title: string;
329 responsibilities: string[];
330 subagents: SubagentDef[];
Chat and workspace agents: channels, DMs and named agents you talk to331 instructions: string;
332 personality_preset: PersonalityPreset;
333 routing: AgentRouting;
334};
335
336/** What the chat service hands an agent: a message it should answer. */
337export type AgentDelivery = {
338 workspace: string;
339 workspace_id: string;
340 channel_id: string;
341 channel_kind: "channel" | "dm";
342 channel_name: string | null;
343 agent_id: string;
344 /** The message that woke it. */
345 message_id: string;
346 thread_root: string | null;
347 /** Who asked: the person's user id. */
348 asked_by: string;
349 /** Agent-to-agent hops so far in this chain. */
350 hops: number;
351 /**
352 * What the person who asked may do, from the viewer the chat service
353 * 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.354 * never does more for someone than they could do themselves. Absent
355 * from an older chat service: the agent then treats the asker as unable
356 * to change code.
Chat and workspace agents: channels, DMs and named agents you talk to357 */
358 asker?: AskerAccess | null;
359 /**
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)360 * The agents that handled this request before this one, by id, oldest
361 * first; the last sent the work here. An agent never hands back or
362 * consults the one that sent it work, and the hop limit counts every
363 * hand-off and consult along the chain. Absent: none (a person asked).
364 */
365 chain?: string[];
366 /**
Chat and workspace agents: channels, DMs and named agents you talk to367 * 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.368 * the workspace connected. The agent reads and replies through that
369 * surface; its definition, budget and replies are the same everywhere.
370 * Absent: `g1t`.
Chat and workspace agents: channels, DMs and named agents you talk to371 */
372 surface?: AgentSurface;
373};
374
375/** The chat surfaces an agent answers on. Only g1t's own today. */
376export type AgentSurface = "g1t";
377
378/** Who asked an agent, as far as its reply needs to know. */
379export type AskerAccess = {
380 username: string;
381 /** Their role in the workspace; `outside` for someone who is not a member. */
382 role: Role | "outside";
383 /**
384 * Whether they can change code in the workspace: Code is on for them
385 * and they hold write access (or more) on at least one of its
386 * repositories, through the base permission or a grant.
387 */
388 can_write: boolean;
389};
390
391const WRITING_ROLES = new Set(["write", "maintain", "admin"]);
392
393/**
394 * `user`'s access in `workspace`, for `AgentDelivery.asker`. Pure, with no
395 * imports, so the chat service computes it from its viewer for free.
396 */
397export function askerAccess(user: User, workspace: string): AskerAccess {
398 const slug = workspace.toLowerCase();
399 const membership = user.workspaces?.find((m) => m.slug.toLowerCase() === slug);
400 // Someone who uses only Chat, Docs and agents sees no repository at all.
401 const code = membership?.code_access !== false;
402 const base = membership ? membership.role === "owner" || WRITING_ROLES.has(membership.base_permission ?? "write") : false;
403 const granted = (user.grants ?? []).some((grant) => grant.workspace.toLowerCase() === slug && WRITING_ROLES.has(grant.role));
404 return {
405 username: user.username,
406 role: membership?.role ?? "outside",
407 can_write: code && (base || granted),
408 };
409}
410
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 asked411/**
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.412 * A session: one bounded piece of work an agent took on
413 * (docs.g1t.sh/guides/agent-sessions/). A conversation with an agent is
414 * not a session: talking stays cheap and quick, and when a request needs
415 * 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 asked416 * the conversation. Sessions start other sessions (one of the agent's
417 * subagents, or a colleague brought in), and everything a tree of sessions
418 * spends is charged to the agent at its root, so a chain never escapes the
419 * budget that started it.
420 */
421export type AgentSessionKind =
422 /** Spun off from a conversation: someone asked for work. */
423 | "chat"
424 /** A routine's run. */
425 | "routine"
426 /** A colleague brought in by another session. */
427 | "helper"
428 /** One of the agent's own subagents, inside another session. */
429 | "subagent";
430
431export type AgentSessionStatus =
432 | "queued"
433 | "working"
434 /** Waiting on sessions it started. */
435 | "waiting"
436 /** Stopped at its spend cap: someone who may raise it decides. */
437 | "needs_approval"
438 | "done"
439 | "failed"
440 | "stopped";
441
442/** The statuses of a session that is not over. */
443export const SESSION_LIVE: readonly AgentSessionStatus[] = ["queued", "working", "waiting", "needs_approval"];
444
445export type AgentSession = {
446 id: string;
447 workspace_id: string;
448 agent_id: string;
449 /** The agent's handle, name and face, for lists. */
450 agent_handle: string;
451 agent_name: string;
452 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.453 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 asked454 /** The subagent running it, by name, when kind is `subagent`. */
455 subagent: string | null;
456 kind: AgentSessionKind;
457 /** The session that started it, and the root of its tree. */
458 parent_id: string | null;
459 root_id: string;
460 /** Whose budget pays for it: the agent at the root of its tree. */
461 payer_agent_id: string;
462 title: string;
463 goal: string;
464 status: AgentSessionStatus;
465 /** Why it is waiting, stopped or failed, in a line. */
466 status_note: string | null;
467 /** What it found or did, once done: its report. */
468 summary: string | null;
469 /** Where it reports: the conversation it was started from. */
470 channel_id: string;
471 channel_kind: "channel" | "dm";
472 channel_name: string | null;
473 /** Its live card in that conversation; its updates go in the card's thread. */
474 card_message_id: string | null;
475 asked_by: string | null;
476 asked_by_username: string | null;
477 routine_id: string | null;
478 steps: number;
479 tool_calls: number;
480 input_tokens: number;
481 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.482 /**
483 * At list price, what it counts against budgets: the model at the
484 * provider's price with billing's model margin, plus g1t's agent rate on
485 * every token. A root session's includes everything its tree spent.
486 */
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 asked487 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.488 /** What its own steps' model answers cost at the provider's price, its tree's not included. */
489 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 asked490 /** The most it may spend before someone approves more. */
491 cap_micros: number | null;
492 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.493 /** The effort level it ran at (the highest, when `auto` raised it); null for sessions from before effort was recorded. */
494 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 asked495 /** What it produced: issues filed, sessions started. */
496 outputs: SessionOutput[];
497 created_at: string;
498 updated_at: string;
499 finished_at: string | null;
500 /**
501 * False when the viewer is not among the people of the conversation it
502 * came from: they see that it ran and what it cost, never its title,
503 * goal, report or transcript.
504 */
505 visible: boolean;
506};
507
508export type SessionOutput =
509 | { kind: "issue"; repo: string; number: number; title: string }
510 | { kind: "session"; id: string; agent_handle: string; title: string }
511 | { kind: "memory"; id: string; body: string };
512
513/** One entry of a session's transcript, as its page shows it. */
514export type SessionEvent = {
515 seq: number;
Every agent can have its own computer. A session that needs one wakes it: a home of its own on g1t cloud, one per agent and never shared, where it runs commands, reads and writes files and keeps what it made, with each session working in its own folder under a shared home; after ten idle minutes it sleeps, its home kept as a snapshot and restored when it wakes, and Reset wipes the home while memory and artifacts stay. Its shell and files are abilities with the usual choices, Alone, Alone when asked, Ask first or Never, offered only inside sessions and never to a chat reply; every command shows on the session with its output, and the agent's new Computer tab shows the state, the disk used of the five gigabytes included, the recent commands, and Wake, Put to sleep and Reset. Machine time counts only while it is awake, on the sandbox lines of the ledger that name the agent and who asked, held to the same spend caps as the session; the disk itself costs nothing in this version. The runner gained a long-lived supervisor that answers the computer's requests inside the container, and the runner service a computer per agent that keeps its snapshot in the agent homes bucket when one is attached, and says so when none is. The REST API and the agent tool can read a computer, wake it, put it to sleep and reset it. The agents, abilities, sessions, runners, billing and deploy guides say how it works and what an operator sets up; pinning a computer to your own runner, its browser and take-over come next.516 kind: "goal" | "text" | "tool" | "command" | "steer" | "update" | "child" | "result" | "note";
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 asked517 /** Who: the agent's handle, a person's username (steering), or null for g1t's notes. */
518 by: string | null;
Every agent can have its own computer. A session that needs one wakes it: a home of its own on g1t cloud, one per agent and never shared, where it runs commands, reads and writes files and keeps what it made, with each session working in its own folder under a shared home; after ten idle minutes it sleeps, its home kept as a snapshot and restored when it wakes, and Reset wipes the home while memory and artifacts stay. Its shell and files are abilities with the usual choices, Alone, Alone when asked, Ask first or Never, offered only inside sessions and never to a chat reply; every command shows on the session with its output, and the agent's new Computer tab shows the state, the disk used of the five gigabytes included, the recent commands, and Wake, Put to sleep and Reset. Machine time counts only while it is awake, on the sandbox lines of the ledger that name the agent and who asked, held to the same spend caps as the session; the disk itself costs nothing in this version. The runner gained a long-lived supervisor that answers the computer's requests inside the container, and the runner service a computer per agent that keeps its snapshot in the agent homes bucket when one is attached, and says so when none is. The REST API and the agent tool can read a computer, wake it, put it to sleep and reset it. The agents, abilities, sessions, runners, billing and deploy guides say how it works and what an operator sets up; pinning a computer to your own runner, its browser and take-over come next.519 /** For `command`: the command on its first line, then its output, cut. */
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 asked520 body: string;
Every agent can have its own computer. A session that needs one wakes it: a home of its own on g1t cloud, one per agent and never shared, where it runs commands, reads and writes files and keeps what it made, with each session working in its own folder under a shared home; after ten idle minutes it sleeps, its home kept as a snapshot and restored when it wakes, and Reset wipes the home while memory and artifacts stay. Its shell and files are abilities with the usual choices, Alone, Alone when asked, Ask first or Never, offered only inside sessions and never to a chat reply; every command shows on the session with its output, and the agent's new Computer tab shows the state, the disk used of the five gigabytes included, the recent commands, and Wake, Put to sleep and Reset. Machine time counts only while it is awake, on the sandbox lines of the ledger that name the agent and who asked, held to the same spend caps as the session; the disk itself costs nothing in this version. The runner gained a long-lived supervisor that answers the computer's requests inside the container, and the runner service a computer per agent that keeps its snapshot in the agent homes bucket when one is attached, and says so when none is. The REST API and the agent tool can read a computer, wake it, put it to sleep and reset it. The agents, abilities, sessions, runners, billing and deploy guides say how it works and what an operator sets up; pinning a computer to your own runner, its browser and take-over come next.521 /** For `tool`: the tool, and whether it read, was withheld, refused or failed. For `command`: the directory it ran 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 asked522 tool: string | null;
Every agent can have its own computer. A session that needs one wakes it: a home of its own on g1t cloud, one per agent and never shared, where it runs commands, reads and writes files and keeps what it made, with each session working in its own folder under a shared home; after ten idle minutes it sleeps, its home kept as a snapshot and restored when it wakes, and Reset wipes the home while memory and artifacts stay. Its shell and files are abilities with the usual choices, Alone, Alone when asked, Ask first or Never, offered only inside sessions and never to a chat reply; every command shows on the session with its output, and the agent's new Computer tab shows the state, the disk used of the five gigabytes included, the recent commands, and Wake, Put to sleep and Reset. Machine time counts only while it is awake, on the sandbox lines of the ledger that name the agent and who asked, held to the same spend caps as the session; the disk itself costs nothing in this version. The runner gained a long-lived supervisor that answers the computer's requests inside the container, and the runner service a computer per agent that keeps its snapshot in the agent homes bucket when one is attached, and says so when none is. The REST API and the agent tool can read a computer, wake it, put it to sleep and reset it. The agents, abilities, sessions, runners, billing and deploy guides say how it works and what an operator sets up; pinning a computer to your own runner, its browser and take-over come next.523 /** For `command`: `exit <code> · <duration>`, with `timed out` or `truncated` when so. */
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 asked524 outcome: string | null;
525 created_at: string;
526};
527
Every agent can have its own computer. A session that needs one wakes it: a home of its own on g1t cloud, one per agent and never shared, where it runs commands, reads and writes files and keeps what it made, with each session working in its own folder under a shared home; after ten idle minutes it sleeps, its home kept as a snapshot and restored when it wakes, and Reset wipes the home while memory and artifacts stay. Its shell and files are abilities with the usual choices, Alone, Alone when asked, Ask first or Never, offered only inside sessions and never to a chat reply; every command shows on the session with its output, and the agent's new Computer tab shows the state, the disk used of the five gigabytes included, the recent commands, and Wake, Put to sleep and Reset. Machine time counts only while it is awake, on the sandbox lines of the ledger that name the agent and who asked, held to the same spend caps as the session; the disk itself costs nothing in this version. The runner gained a long-lived supervisor that answers the computer's requests inside the container, and the runner service a computer per agent that keeps its snapshot in the agent homes bucket when one is attached, and says so when none is. The REST API and the agent tool can read a computer, wake it, put it to sleep and reset it. The agents, abilities, sessions, runners, billing and deploy guides say how it works and what an operator sets up; pinning a computer to your own runner, its browser and take-over come next.528/** An agent's computer as its Computer tab shows it (docs.g1t.sh/guides/agents/, "Its computer"). */
529export type AgentComputerView = {
530 status: AgentComputerStatus;
531 /** The most recent commands, newest first. */
532 commands: AgentComputerCommand[];
533 /** Whether the viewer may wake, sleep and reset it: owners, and the member of a personal agent. */
534 can_manage: boolean;
535};
536
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 asked537export type AgentSessionDetail = {
538 session: AgentSession;
539 events: SessionEvent[];
540 /** Every session in its tree, root first. */
541 tree: AgentSession[];
542 /** Whether the viewer may stop it, steer it, or approve more spend. */
543 can_stop: boolean;
544 can_steer: boolean;
545 can_approve: boolean;
546};
547
548/**
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.549 * What an agent remembers (docs.g1t.sh/guides/agent-memory/). Every fact
550 * carries where it came from, and its scope decides, in code, where it may
551 * 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 asked552 *
553 * - `workspace`: anywhere in the workspace. Owners write these, or an agent
554 * from a public channel, which every member can read already.
555 * - `channel`: only in that channel and its threads.
556 * - `person`: only in a direct message with that one person.
557 */
558export type AgentMemoryScope = "workspace" | "channel" | "person";
559
560export type AgentMemory = {
561 id: string;
562 agent_id: string;
563 scope: AgentMemoryScope;
564 /** The channel's id or the person's user id; empty for `workspace`. */
565 scope_ref: string;
566 /** The channel's name or the person's username, for display. */
567 scope_label: string | null;
568 body: string;
569 source_kind: "message" | "session" | "person";
570 /** A message id, a session id, or the username of who wrote it. */
571 source_ref: string | null;
572 source_label: string | null;
573 /** The channel the source is in, for a link. */
574 source_channel_id: string | null;
575 created_by: string;
576 created_by_kind: "agent" | "user";
577 pinned: boolean;
578 created_at: string;
579 updated_at: string;
580};
581
582/** When a routine runs, in UTC. */
583export type RoutineSchedule = {
584 every: "hour" | "day" | "weekday" | "week";
585 /** Minute of the hour, 0 to 59. */
586 minute: number;
587 /** Hour of the day (UTC), 0 to 23; not used for `hour`. */
588 hour: number;
589 /** Day of the week for `week`, 0 (Sunday) to 6. */
590 weekday: number;
591};
592
593/**
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened594 * 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.595 * (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 opened596 * thing that happened, in a repository its sponsor can read.
597 */
598export const ROUTINE_EVENTS = [
599 { key: "pull_ready", label: "A pull request is ready for review", hint: "Opened ready, or moved out of draft." },
600 { key: "pull_merged", label: "A pull request is merged", hint: "On any branch it targets." },
601 { key: "checks_failed", label: "Checks fail on a pull request", hint: "Its required checks failed or errored." },
602 { key: "issue_opened", label: "An issue is opened", hint: "By a person or an agent." },
603 { key: "deploy_failed", label: "A deploy fails", hint: "A production or preview deploy." },
604] as const;
605
606export type RoutineEvent = (typeof ROUTINE_EVENTS)[number]["key"];
607
608/**
Merge branch 'chat-sidebar' into fast-push609 * 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 asked610 * of support themes. Each run is a session posted in the routine's channel,
611 * paid from the agent's budget, and run with the access of the person who
612 * set it up (its sponsor), never more.
613 */
614export type AgentRoutine = {
615 id: string;
616 agent_id: string;
617 name: string;
618 instructions: string;
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened619 /** When it runs on a clock; null when it runs only on events. */
620 schedule: RoutineSchedule | null;
621 /** What it runs on; empty when it runs only on its schedule. */
622 events: RoutineEvent[];
623 /** Which repositories its events come from, by `workspace/name`; empty: every one its sponsor can read. */
624 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 asked625 channel_id: string;
626 channel_name: string | null;
627 sponsor: string;
628 sponsor_username: string | null;
629 enabled: boolean;
630 /** Why g1t paused it, when it did. */
631 paused_note: string | null;
632 next_run_at: string | null;
633 last_run_at: string | null;
634 last_session_id: string | null;
635 runs: number;
636 created_at: string;
637 updated_at: string;
638};
639
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened640/** A routine suggested from an agent's responsibilities, for an owner to add in one step. */
641export type RoutineSuggestion = { responsibility: string; routine: Omit<NewRoutine, "channel_id"> };
642
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 asked643export type NewRoutine = {
644 name: string;
645 instructions: string;
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened646 /** A schedule, events, or both; at least one. */
647 schedule: RoutineSchedule | null;
648 events?: RoutineEvent[];
649 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 asked650 /** A channel the agent is in, by id. */
651 channel_id: string;
652 enabled?: boolean;
653};
654
655/**
656 * The workspace's say over all its agents together, set by owners: one
657 * monthly budget across every agent, the budget a new agent starts with,
658 * and the cap a session starts with. The workspace's spend limit and AI
659 * credit (billing) sit above all of it.
660 */
661export type AgentPolicy = {
662 /** Every agent's spend together in a month. Null: only the workspace's spend limit. */
663 monthly_micros: number | null;
664 /** The monthly budget a new agent gets. Null: none. */
665 default_agent_monthly_micros: number | null;
666 /** The cap one session starts with, unless its agent's per-task cap is lower. */
667 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.668 /**
669 * What the agents working for one person (their replies and sessions,
670 * asked for by that person) may spend together in a month, unless the
671 * person has a budget of their own. Null: no budget per person.
672 */
673 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.674 /**
675 * Whether members who aren't owners may create personal agents
676 * (docs.g1t.sh/guides/agents/, "Personal agents"). On unless an owner
677 * turns it off; off, existing personal agents keep working.
678 */
679 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.680};
681
682/** One person's budget: what agents working for them may spend in a month, and what they have. */
683export type PersonBudget = {
684 username: string;
685 /** The budget that applies: their own, or the workspace's per-person default. Null: none. */
686 monthly_micros: number | null;
687 /** Whether it is their own, set by an owner, rather than the default. */
688 own: boolean;
689 /** What agents spent for them this month (UTC). */
690 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 asked691};
692
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.693/** Budgets per person: the default, and each person who has one of their own or has spent this month. */
694export type PersonBudgets = {
695 period: string;
696 default_micros: number | null;
697 /** Owners see everyone; anyone else sees only themselves. Most spent first. */
698 people: PersonBudget[];
699};
700
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 asked701export type SpendSlice = { key: string; label: string; micros: number; count: number };
702
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.703/** Which days a breakdown covers: this month (the default), last month, or the last 7 or 30 days, in UTC. */
704export type SpendPeriod = "month" | "last_month" | "7d" | "30d";
705
706/** 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 asked707export 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.708 /** `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 asked709 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.710 /** The span asked for, and its first and last day (`YYYY-MM-DD`, both included). */
711 span: SpendPeriod;
712 from: string;
713 until: string;
714 /** The one person it is about (work asked for by them), or null for everyone's. */
715 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 asked716 total_micros: number;
717 /** Chat replies, sessions, routines, helping colleagues. */
718 by_kind: SpendSlice[];
719 by_model: SpendSlice[];
720 /** Who asked: the work done for each person. */
721 by_person: SpendSlice[];
722 by_agent: SpendSlice[];
723 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.724 /**
725 * Where it was asked: a channel by id (labelled `#name`), direct
726 * messages together (`dm`), and channels the viewer can't read together
727 * (`private`).
728 */
729 by_channel: SpendSlice[];
730 /** 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 asked731 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.732 /** 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 asked733 days: { day: string; micros: number }[];
734};
735
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.736/**
737 * What each effort level has cost one agent, from its own finished
738 * sessions (docs.g1t.sh/guides/spend/#effort): measured, never estimated
739 * from other agents or list prices. A level it has not run at has no
740 * figures.
741 */
742export type EffortCost = {
743 effort: EffortLevel;
744 /** Its sessions (with everything they brought in) that finished in the window. */
745 sessions: number;
746 /** The median charged for one of them: a typical task. Null with none. */
747 typical_micros: number | null;
748 /** Of those, the share finished with nobody having to step in: no steering, not stopped or failed. Null with none. */
749 accepted_share: number | null;
750};
751
752export type AgentEffortCosts = {
753 handle: string;
754 /** Its setting now. */
755 effort: AgentEffort;
756 /** Days of history the figures cover. */
757 window_days: number;
758 levels: EffortCost[];
759};
760
761/** One side of a recommendation's evidence: the agent's sessions at one level. */
762export type EffortEvidence = {
763 effort: EffortLevel;
764 sessions: number;
765 /** Finished with nobody having to step in. */
766 accepted: number;
767 typical_micros: number;
768 mean_micros: number;
769};
770
771/**
772 * A way to spend less without losing quality, checked against the agent's
773 * own past work (docs.g1t.sh/guides/spend/#spend-less-keep-quality). The
774 * weekly check proposes one only when the cheaper level's measured
775 * outcomes hold up; when there is too little history to tell, it says so
776 * (`thin`) instead of proposing anything.
777 */
778export type AgentRecommendation = {
779 id: string;
780 agent_id: string;
781 agent_handle: string;
782 agent_name: string;
783 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.784 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.785 /** Lowering its effort setting. */
786 kind: "effort";
787 /** `thin`: not enough history to recommend anything yet. */
788 status: "open" | "applied" | "dismissed" | "thin";
789 from_effort: AgentEffort;
790 to_effort: EffortLevel;
791 /** What it says to do, in a line. */
792 title: string;
793 /** Why, from the numbers in `evidence`, in a sentence. */
794 reason: string;
795 /** What it was measured on: the level it runs at now, and the cheaper one. Null sides had no sessions. */
796 evidence: { window_days: number; current: EffortEvidence | null; cheaper: EffortEvidence | null; needed: number };
797 /** About what a month it would save at the recent pace, from the measured costs. Null when thin. */
798 saving_month_micros: number | null;
799 checked_at: string;
800 resolved_by: string | null;
801 resolved_at: string | null;
802};
803
804export type AgentRecommendations = {
805 /** When the check last ran for the workspace; null before the first. */
806 checked_at: string | null;
807 window_days: number;
808 /** To act on, largest saving first. */
809 open: AgentRecommendation[];
810 /** Agents with too little history to say. */
811 thin: AgentRecommendation[];
812 /** Applied or dismissed in the last 30 days. */
813 resolved: AgentRecommendation[];
814};
815
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 asked816/** Agents mode's front page. */
817export type AgentsOverview = {
818 policy: AgentPolicy;
819 /** Every agent's spend this month, against the policy's budget. */
820 spent_month_micros: number;
821 /** The highest alert this month: 75, 90 or 100 (% of the workspace's agent budget). */
822 alert: number | null;
823 agents: WorkspaceAgent[];
824 /** Live sessions, counted by agent id, for the roster. */
825 live_by_agent: Record<string, number>;
826 /** Sessions live now that the viewer can see. */
827 live: AgentSession[];
828 /** Sessions waiting on the viewer: spend they may approve. */
829 waiting_on_you: AgentSession[];
830 /** Recently finished sessions the viewer can see. */
831 recent: AgentSession[];
Routines run when something happens: a pull request ready for review or merged, checks or a deploy failing, an issue opened832 /** 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 asked833 upcoming: (AgentRoutine & { agent_handle: string; agent_name: string })[];
834 spend: AgentSpendBreakdown;
835 can_manage: boolean;
836};
837
838/** One thing an agent did, for its Activity tab. */
839export type AgentActivity = {
840 id: string;
841 kind: "reply" | "session";
842 status: string;
843 channel_id: string;
844 channel_name: string | null;
845 /** The session's title; null for a reply or one the viewer can't see. */
846 title: string | null;
847 asked_by_username: string | null;
848 model: string | null;
849 tools: number;
850 charged_micros: number;
851 created_at: string;
852 visible: boolean;
853 /** For a reply, the message it posted; for a session, its id. */
854 ref: string | null;
855};
856
857export type AgentVersion = { version: number; changed_by: string; created_at: string; definition: Partial<NewWorkspaceAgent> };
858
Cards you act on in chat; agents comment and review as themselves; names shown cleanly; commits on the calendar859/** A card action, as chat hands it to agents. */
860export type AgentCardAction = {
861 workspace: string;
862 channel_id: string;
863 message_id: string;
864 viewer: User;
865 card: { kind: string; ref: string | null };
866 action_id: string;
867 input: string | null;
868};
869
Chat and workspace agents: channels, DMs and named agents you talk to870export 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.871 /**
872 * The workspace's agents. Personal agents are left out unless asked
873 * for: `mine`, the viewer's own; `all`, every member's for an owner (the
874 * viewer's own for anyone else).
875 */
876 list(workspace: string, viewer: User, options?: { personal?: "mine" | "all" | null }): Promise<Result<WorkspaceAgent[]>>;
Chat and workspace agents: channels, DMs and named agents you talk to877 get(workspace: string, handle: string, viewer: User): Promise<Result<WorkspaceAgent>>;
878 /** Internal: by id, for the chat service resolving members. */
879 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.880 /**
881 * `teams`: the workspace's teams to add it to as it is made, by slug,
882 * each one the viewer manages (owners and the team's maintainers). The
883 * membership is the team's, as anyone's is; a personal agent joins none.
884 */
885 create(workspace: string, viewer: User, input: NewWorkspaceAgent, options?: { teams?: string[] }): Promise<Result<WorkspaceAgent>>;
Chat and workspace agents: channels, DMs and named agents you talk to886 update(
887 workspace: string,
888 handle: string,
889 viewer: User,
890 changes: Partial<NewWorkspaceAgent>,
891 ): Promise<Result<WorkspaceAgent>>;
892 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.893 /**
An archived agent can be found, brought back, or deleted for good. The Agents page ends with Archived, folded, where owners see every archived agent and members their own personal ones, each with when and by whom it was archived and what deleting it would take; Restore brings it back, under a new handle when a live agent has taken its old one, and Delete permanently asks for the handle to be typed and then removes its sessions, replies, memories, routines, versions, drafts, skills and its computer's home, leaving its messages in chat under its saved name, the workspace's spend totals and the audit log. In Chat an archived agent is deactivated the way people expect: never offered as someone to message or mention, never woken, a conversation with it kept in the list, dimmed and marked Archived, open to read with a note in place of the composer and a way to restore it for owners; after deletion the conversation still reads, its messages marked as a deleted agent's. The agents, chat and agent budgets guides say so.894 * The workspace's archived agents, newest archived first: every one for
895 * an owner, their own archived personal agents for anyone else.
896 */
897 listArchived(workspace: string, viewer: User): Promise<Result<ArchivedAgent[]>>;
898 /**
899 * Brings an archived agent back, under its handle or `options.handle`.
900 * `conflict` when a live agent holds the handle. Owners any agent, a
901 * member their own personal one.
902 */
903 restore(workspace: string, handle: string, viewer: User, options?: { handle?: string | null; id?: string | null }): Promise<Result<WorkspaceAgent>>;
904 /**
905 * Deletes an archived agent for good: its definition and versions,
906 * sessions, replies, memories, routines, drafts and computer, and its
907 * chat memberships. Its messages stay in chat under its last name, and
908 * its spend on the workspace's statement. `confirm` must be the handle.
909 * A live agent is archived first (`invalid`). Owners any agent, a member
910 * their own personal one; a second call is `not_found`.
911 */
912 destroy(workspace: string, handle: string, viewer: User, confirm: string, options?: { id?: string | null }): Promise<Result<null>>;
913 /**
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.914 * Drafts a whole agent from a description, with a fast model call charged
915 * to the viewer. Nothing is saved. Whoever may create the agent may draft it.
916 */
917 draft(workspace: string, viewer: User, input: { description: string; scope?: WorkspaceAgentScope | null }): Promise<Result<AgentProposal>>;
918 /**
919 * Try it: the unsaved definition answers the conversation so far, as it
920 * would in a direct message, without tools or memory. Charged to the
921 * viewer; nothing is saved.
922 */
923 tryDraft(workspace: string, viewer: User, input: { definition: NewWorkspaceAgent; messages: DraftTurn[] }): Promise<Result<DraftReply>>;
924 /** Drafts changes to an agent from a request in words; saved only through `update`. Whoever may change the agent may ask. */
925 redraft(workspace: string, handle: string, viewer: User, request: string): Promise<Result<AgentRedraft>>;
926 /**
927 * Owners make a member's personal agent a workspace agent: its definition
928 * and every version move to a workspace agent with the same handle, and
929 * the personal one is archived, with its memory and direct messages.
930 */
931 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.932 /**
933 * Adds an MCP server to an agent (docs.g1t.sh/guides/agent-abilities/,
934 * "MCP servers"): its host is checked, its tools are listed from it, and
935 * the agent gets a new version with each tool as an ability. Owners only.
936 */
937 addMcpServer(workspace: string, handle: string, viewer: User, input: { name: string; url: string }): Promise<Result<McpServer>>;
938 /** Takes an MCP server off an agent, with its abilities: a new version. Owners only. */
939 removeMcpServer(workspace: string, handle: string, viewer: User, id: string): Promise<Result<null>>;
940 /** Lists a server's tools again, for one that changed; a new version when they did. Owners only. */
941 refreshMcpServer(workspace: string, handle: string, viewer: User, id: string): Promise<Result<McpServer>>;
Chat and workspace agents: channels, DMs and named agents you talk to942 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)943 /**
944 * Internal: the workspace's built-in `@g1t` agent, made if it does not
945 * exist yet. The chat service asks for it when someone mentions @g1t in
946 * a channel it is not in yet.
947 */
948 builtin(workspace: string, workspaceId: string): Promise<Result<WorkspaceAgent>>;
Chat and workspace agents: channels, DMs and named agents you talk to949 /** The chat service hands over a message for an agent to answer. Returns at once. */
950 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 asked951 overview(workspace: string, viewer: User): Promise<Result<AgentsOverview>>;
952 sessions(
953 workspace: string,
954 viewer: User,
955 filter?: { handle?: string | null; status?: "live" | "done" | null; limit?: number | null },
956 ): Promise<Result<AgentSession[]>>;
957 session(workspace: string, id: string, viewer: User): Promise<Result<AgentSessionDetail>>;
958 /** Stops a session and every session under it. */
959 stopSession(workspace: string, id: string, viewer: User): Promise<Result<AgentSession>>;
960 /** Raises a stopped session's cap and lets it go on. Owners only. */
961 approveSession(workspace: string, id: string, viewer: User, capMicros: number): Promise<Result<AgentSession>>;
962 /** A person's message to a session, running or finished: it reads it and goes on. */
963 steerSession(workspace: string, id: string, viewer: User, body: string): Promise<Result<AgentSession>>;
Every agent can have its own computer. A session that needs one wakes it: a home of its own on g1t cloud, one per agent and never shared, where it runs commands, reads and writes files and keeps what it made, with each session working in its own folder under a shared home; after ten idle minutes it sleeps, its home kept as a snapshot and restored when it wakes, and Reset wipes the home while memory and artifacts stay. Its shell and files are abilities with the usual choices, Alone, Alone when asked, Ask first or Never, offered only inside sessions and never to a chat reply; every command shows on the session with its output, and the agent's new Computer tab shows the state, the disk used of the five gigabytes included, the recent commands, and Wake, Put to sleep and Reset. Machine time counts only while it is awake, on the sandbox lines of the ledger that name the agent and who asked, held to the same spend caps as the session; the disk itself costs nothing in this version. The runner gained a long-lived supervisor that answers the computer's requests inside the container, and the runner service a computer per agent that keeps its snapshot in the agent homes bucket when one is attached, and says so when none is. The REST API and the agent tool can read a computer, wake it, put it to sleep and reset it. The agents, abilities, sessions, runners, billing and deploy guides say how it works and what an operator sets up; pinning a computer to your own runner, its browser and take-over come next.964 /**
965 * The agent's computer: its state, disk and recent commands. Anyone who
966 * may see the agent; `can_manage` says whether the viewer may act on it.
967 */
968 computer(workspace: string, handle: string, viewer: User): Promise<Result<AgentComputerView>>;
969 /** Wakes it, restoring its home; metered until it sleeps. Owners, or a personal agent's member. */
970 wakeComputer(workspace: string, handle: string, viewer: User): Promise<Result<AgentComputerView>>;
971 /** Saves its home and stops it. Owners, or a personal agent's member. */
972 sleepComputer(workspace: string, handle: string, viewer: User): Promise<Result<AgentComputerView>>;
973 /** Wipes its home and its command history; memory and artifacts are kept. Owners, or a personal agent's member. */
974 resetComputer(workspace: string, handle: string, viewer: User): Promise<Result<AgentComputerView>>;
975 /** Its recent commands, newest first; `sessionId` narrows them to one session's. */
976 computerCommands(workspace: string, handle: string, viewer: User, sessionId?: string | null): Promise<Result<AgentComputerCommand[]>>;
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 asked977 memories(workspace: string, handle: string, viewer: User): Promise<Result<AgentMemory[]>>;
978 remember(
979 workspace: string,
980 handle: string,
981 viewer: User,
982 input: { body: string; scope: AgentMemoryScope; scope_ref?: string | null },
983 ): Promise<Result<AgentMemory>>;
984 updateMemory(
985 workspace: string,
986 handle: string,
987 viewer: User,
988 id: string,
989 changes: { body?: string; pinned?: boolean },
990 ): Promise<Result<AgentMemory>>;
991 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 opened992 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 asked993 saveRoutine(workspace: string, handle: string, viewer: User, input: NewRoutine, id?: string | null): Promise<Result<AgentRoutine>>;
994 deleteRoutine(workspace: string, handle: string, viewer: User, id: string): Promise<Result<null>>;
995 /** Runs a routine now, as a session. */
996 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.997 /**
998 * Where the spend went: one agent's, or every agent's; this month unless
999 * `period` says otherwise; for everyone, or only the work one `person`
1000 * (by username) asked for.
1001 */
1002 spend(workspace: string, viewer: User, handle?: string | null, options?: { period?: SpendPeriod | null; person?: string | null }): Promise<Result<AgentSpendBreakdown>>;
1003 /** Budgets per person this month: owners see everyone's, anyone else their own. */
1004 personBudgets(workspace: string, viewer: User): Promise<Result<PersonBudgets>>;
1005 /**
1006 * Gives one person a monthly budget of their own (`monthly_micros`; 0 for
1007 * no budget at all), or with null puts them back on the default. Owners only.
1008 */
1009 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 asked1010 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.1011 /** What each effort level has cost this agent, from its own finished sessions. Members only. */
1012 effortCosts(workspace: string, handle: string, viewer: User): Promise<Result<AgentEffortCosts>>;
1013 /** Ways to spend less, checked against past work: every agent's, or one's. Members only. */
1014 recommendations(workspace: string, viewer: User, handle?: string | null): Promise<Result<AgentRecommendations>>;
1015 /**
1016 * Owners apply one (the agent's effort changes, as a new version, and
1017 * the audit log says so) or dismiss it.
1018 */
1019 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.1020 /** What an agent is told about its teams this turn, word for word. Members only. */
1021 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 asked1022 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 calendar1023 /**
1024 * Internal, from chat: a person pressed an action on one of agents'
1025 * cards. Agents checks they may, acts, and updates the card.
1026 */
1027 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 asked1028 policy(workspace: string, viewer: User): Promise<Result<AgentPolicy>>;
1029 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.1030 /**
1031 * The Marketplace's install requests (./marketplace.ts): every one in the
1032 * workspace for an owner, a member's own for anyone else.
1033 */
1034 installRequests(workspace: string, viewer: User): Promise<Result<InstallRequests>>;
1035 /**
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.1036 * A member asks the workspace's owners to add a listing
1037 * (`extension:<id>` or `integration:<connector>`), and every owner is
1038 * 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.1039 * things themselves, so they don't ask. Asking again while a request for
1040 * the same listing is open is a conflict.
1041 */
1042 requestInstall(workspace: string, viewer: User, listing: string, note?: string | null): Promise<Result<InstallRequest>>;
1043 /** An owner marks a request added (`done`) or turns it down (`declined`); whoever asked is told. */
1044 resolveInstallRequest(workspace: string, viewer: User, id: string, status: Exclude<InstallRequestStatus, "open">): Promise<Result<InstallRequest>>;
1045 /** The extensions installed in the workspace; any member sees them. */
Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell.1046 // Customize (./customize.ts): marketplaces, plugins and connectors.
1047 marketplaces(workspace: string, viewer: User): Promise<Result<Marketplace[]>>;
1048 addMarketplace(workspace: string, viewer: User, address: string, name?: string | null): Promise<Result<Marketplace>>;
1049 removeMarketplace(workspace: string, viewer: User, name: string): Promise<Result<null>>;
1050 refreshMarketplace(workspace: string, viewer: User, name: string): Promise<Result<Marketplace>>;
1051 discover(workspace: string, viewer: User): Promise<Result<{ plugins: PluginListing[]; skills: SkillListing[]; marketplaces: Marketplace[] }>>;
1052 plugin(workspace: string, viewer: User, ref: string): Promise<Result<PluginDetail>>;
1053 pluginInstalls(workspace: string, viewer: User): Promise<Result<PluginInstall[]>>;
1054 installPlugin(workspace: string, viewer: User, ref: string): Promise<Result<PluginInstall>>;
1055 setPluginEnabled(workspace: string, viewer: User, ref: string, enabled: boolean): Promise<Result<PluginInstall>>;
1056 uninstallPlugin(workspace: string, viewer: User, ref: string): Promise<Result<null>>;
1057 /** Reads an installed plugin again at its marketplace's current listing: new skill versions, subagents and servers; attachments follow. */
1058 updatePlugin(workspace: string, viewer: User, ref: string): Promise<Result<PluginInstall>>;
1059 pluginAgents(workspace: string, viewer: User): Promise<Result<PluginAgentTemplate[]>>;
1060 connectors(workspace: string, viewer: User): Promise<Result<WorkspaceConnector[]>>;
1061 connector(workspace: string, viewer: User, id: string): Promise<Result<WorkspaceConnector>>;
1062 addConnector(workspace: string, viewer: User, input: ConnectorInput): Promise<Result<WorkspaceConnector>>;
1063 setConnectorKey(workspace: string, viewer: User, id: string, headerName: string | null, value: string): Promise<Result<WorkspaceConnector>>;
1064 removeConnector(workspace: string, viewer: User, id: string): Promise<Result<null>>;
1065 refreshConnector(workspace: string, viewer: User, id: string): Promise<Result<WorkspaceConnector>>;
1066 /** Where the browser goes to sign the connector in; `redirectUri` is this g1t's page the server sends it back to. */
1067 startConnectorSignIn(workspace: string, viewer: User, id: string, redirectUri: string): Promise<Result<ConnectorSignIn>>;
1068 finishConnectorSignIn(workspace: string, viewer: User, state: string, code: string): Promise<Result<WorkspaceConnector>>;
1069 signOutConnector(workspace: string, viewer: User, id: string): Promise<Result<WorkspaceConnector>>;
1070 /** `target`: an agent's handle or a team's slug; null for every agent. */
1071 grantConnector(workspace: string, viewer: User, id: string, scope: SkillScope, target: string | null): Promise<Result<WorkspaceConnector>>;
1072 revokeConnector(workspace: string, viewer: User, id: string, grant: string): Promise<Result<WorkspaceConnector>>;
1073 agentConnectors(workspace: string, handle: string, viewer: User): Promise<Result<AgentConnector[]>>;
1074 /** What a job's Claude Code gets, read with the job's agent token; secrets included, so only the API hands it to a runner. */
1075 customizeBundle(workspace: string, viewer: User): Promise<Result<CustomizeBundle>>;
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.1076 /** Owners install a published extension at its current version; open requests for it are answered. */
1077 /** Owners switch an install on or off: off is the kill switch. */
1078 /** Owners cap what an install spends a month; null leaves it to the workspace's limit. */
Chat and workspace agents: channels, DMs and named agents you talk to1079};
1080
1081async function rpc<T>(service: ServiceBinding, method: string, args: object): Promise<T> {
1082 const response = await service.fetch(`https://service/rpc/${method}`, {
1083 method: "POST",
1084 headers: { "content-type": "application/json" },
1085 body: JSON.stringify(args),
1086 });
1087 if (!response.ok) {
1088 throw new Error(`${method} failed with status ${response.status}`);
1089 }
1090 return (await response.json()) as T;
1091}
1092
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.1093/**
1094 * What an agent is told about its teams every turn (docs.g1t.sh/guides/people-and-teams/,
1095 * "What agents are told"): the visible teams it is on, by slug, and the text
1096 * itself; null when it is on none.
1097 */
1098export type AgentTeamContext = { handle: string; teams: string[]; text: string | null };
1099
Chat and workspace agents: channels, DMs and named agents you talk to1100export function workspaceAgentsClient(service: ServiceBinding): WorkspaceAgentsApi {
1101 const call = <T>(method: string, args: object) => rpc<T>(service, method, args);
1102 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.1103 list: (workspace, viewer, options) => call("list", { workspace, viewer, personal: options?.personal ?? null }),
Chat and workspace agents: channels, DMs and named agents you talk to1104 get: (workspace, handle, viewer) => call("get", { workspace, handle, viewer }),
1105 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.1106 create: (workspace, viewer, input, options) => call("create", { workspace, viewer, input, teams: options?.teams ?? [] }),
Chat and workspace agents: channels, DMs and named agents you talk to1107 update: (workspace, handle, viewer, changes) => call("update", { workspace, handle, viewer, changes }),
1108 archive: (workspace, handle, viewer) => call("archive", { workspace, handle, viewer }),
An archived agent can be found, brought back, or deleted for good. The Agents page ends with Archived, folded, where owners see every archived agent and members their own personal ones, each with when and by whom it was archived and what deleting it would take; Restore brings it back, under a new handle when a live agent has taken its old one, and Delete permanently asks for the handle to be typed and then removes its sessions, replies, memories, routines, versions, drafts, skills and its computer's home, leaving its messages in chat under its saved name, the workspace's spend totals and the audit log. In Chat an archived agent is deactivated the way people expect: never offered as someone to message or mention, never woken, a conversation with it kept in the list, dimmed and marked Archived, open to read with a note in place of the composer and a way to restore it for owners; after deletion the conversation still reads, its messages marked as a deleted agent's. The agents, chat and agent budgets guides say so.1109 listArchived: (workspace, viewer) => call("list_archived", { workspace, viewer }),
1110 restore: (workspace, handle, viewer, options) => call("restore", { workspace, handle, viewer, id: options?.id ?? null, new_handle: options?.handle ?? null }),
1111 destroy: (workspace, handle, viewer, confirm, options) => call("destroy", { workspace, handle, viewer, confirm, id: options?.id ?? 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.1112 draft: (workspace, viewer, input) => call("draft", { workspace, viewer, description: input.description, scope: input.scope ?? null }),
1113 tryDraft: (workspace, viewer, input) => call("try_draft", { workspace, viewer, definition: input.definition, messages: input.messages }),
1114 redraft: (workspace, handle, viewer, request) => call("redraft", { workspace, handle, viewer, request }),
1115 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.1116 addMcpServer: (workspace, handle, viewer, input) => call("add_mcp_server", { workspace, handle, viewer, name: input.name, url: input.url }),
1117 removeMcpServer: (workspace, handle, viewer, id) => call("remove_mcp_server", { workspace, handle, viewer, id }),
1118 refreshMcpServer: (workspace, handle, viewer, id) => call("refresh_mcp_server", { workspace, handle, viewer, id }),
Chat and workspace agents: channels, DMs and named agents you talk to1119 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)1120 builtin: (workspace, workspaceId) => call("builtin", { workspace, workspace_id: workspaceId }),
Chat and workspace agents: channels, DMs and named agents you talk to1121 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 asked1122 overview: (workspace, viewer) => call("overview", { workspace, viewer }),
1123 sessions: (workspace, viewer, filter) => call("sessions", { workspace, viewer, ...(filter ?? {}) }),
1124 session: (workspace, id, viewer) => call("session", { workspace, id, viewer }),
1125 stopSession: (workspace, id, viewer) => call("stop_session", { workspace, id, viewer }),
1126 approveSession: (workspace, id, viewer, capMicros) => call("approve_session", { workspace, id, viewer, cap_micros: capMicros }),
1127 steerSession: (workspace, id, viewer, body) => call("steer_session", { workspace, id, viewer, body }),
Every agent can have its own computer. A session that needs one wakes it: a home of its own on g1t cloud, one per agent and never shared, where it runs commands, reads and writes files and keeps what it made, with each session working in its own folder under a shared home; after ten idle minutes it sleeps, its home kept as a snapshot and restored when it wakes, and Reset wipes the home while memory and artifacts stay. Its shell and files are abilities with the usual choices, Alone, Alone when asked, Ask first or Never, offered only inside sessions and never to a chat reply; every command shows on the session with its output, and the agent's new Computer tab shows the state, the disk used of the five gigabytes included, the recent commands, and Wake, Put to sleep and Reset. Machine time counts only while it is awake, on the sandbox lines of the ledger that name the agent and who asked, held to the same spend caps as the session; the disk itself costs nothing in this version. The runner gained a long-lived supervisor that answers the computer's requests inside the container, and the runner service a computer per agent that keeps its snapshot in the agent homes bucket when one is attached, and says so when none is. The REST API and the agent tool can read a computer, wake it, put it to sleep and reset it. The agents, abilities, sessions, runners, billing and deploy guides say how it works and what an operator sets up; pinning a computer to your own runner, its browser and take-over come next.1128 computer: (workspace, handle, viewer) => call("computer", { workspace, handle, viewer }),
1129 wakeComputer: (workspace, handle, viewer) => call("computer_wake", { workspace, handle, viewer }),
1130 sleepComputer: (workspace, handle, viewer) => call("computer_sleep", { workspace, handle, viewer }),
1131 resetComputer: (workspace, handle, viewer) => call("computer_reset", { workspace, handle, viewer }),
1132 computerCommands: (workspace, handle, viewer, sessionId) => call("computer_commands", { workspace, handle, viewer, session_id: sessionId ?? 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 asked1133 memories: (workspace, handle, viewer) => call("memories", { workspace, handle, viewer }),
1134 remember: (workspace, handle, viewer, input) => call("remember", { workspace, handle, viewer, input }),
1135 updateMemory: (workspace, handle, viewer, id, changes) => call("update_memory", { workspace, handle, viewer, id, changes }),
1136 forget: (workspace, handle, viewer, id) => call("forget", { workspace, handle, viewer, id }),
1137 routines: (workspace, handle, viewer) => call("routines", { workspace, handle, viewer }),
1138 saveRoutine: (workspace, handle, viewer, input, id) => call("save_routine", { workspace, handle, viewer, input, id: id ?? null }),
1139 deleteRoutine: (workspace, handle, viewer, id) => call("delete_routine", { workspace, handle, viewer, id }),
1140 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.1141 spend: (workspace, viewer, handle, options) =>
1142 call("spend", { workspace, viewer, handle: handle ?? null, period: options?.period ?? null, person: options?.person ?? null }),
1143 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.1144 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.1145 setPersonBudget: (workspace, viewer, username, monthlyMicros) =>
1146 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 asked1147 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.1148 effortCosts: (workspace, handle, viewer) => call("effort_costs", { workspace, handle, viewer }),
1149 recommendations: (workspace, viewer, handle) => call("recommendations", { workspace, viewer, handle: handle ?? null }),
1150 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 asked1151 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 calendar1152 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 asked1153 policy: (workspace, viewer) => call("policy", { workspace, viewer }),
1154 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.1155 installRequests: (workspace, viewer) => call("install_requests", { workspace, viewer }),
1156 requestInstall: (workspace, viewer, listing, note) => call("request_install", { workspace, viewer, listing, note: note ?? null }),
1157 resolveInstallRequest: (workspace, viewer, id, status) => call("resolve_install_request", { workspace, viewer, id, status }),
Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell.1158 marketplaces: (workspace, viewer) => call("marketplaces", { workspace, viewer }),
1159 addMarketplace: (workspace, viewer, address, name) => call("add_marketplace", { workspace, viewer, address, name: name ?? null }),
1160 removeMarketplace: (workspace, viewer, name) => call("remove_marketplace", { workspace, viewer, name }),
1161 refreshMarketplace: (workspace, viewer, name) => call("refresh_marketplace", { workspace, viewer, name }),
1162 discover: (workspace, viewer) => call("discover", { workspace, viewer }),
1163 plugin: (workspace, viewer, ref) => call("plugin", { workspace, viewer, ref }),
1164 pluginInstalls: (workspace, viewer) => call("plugin_installs", { workspace, viewer }),
1165 installPlugin: (workspace, viewer, ref) => call("install_plugin", { workspace, viewer, ref }),
1166 setPluginEnabled: (workspace, viewer, ref, enabled) => call("set_plugin_enabled", { workspace, viewer, ref, enabled }),
1167 uninstallPlugin: (workspace, viewer, ref) => call("uninstall_plugin", { workspace, viewer, ref }),
1168 updatePlugin: (workspace, viewer, ref) => call("update_plugin", { workspace, viewer, ref }),
1169 pluginAgents: (workspace, viewer) => call("plugin_agents", { workspace, viewer }),
1170 connectors: (workspace, viewer) => call("connectors", { workspace, viewer }),
1171 connector: (workspace, viewer, id) => call("connector", { workspace, viewer, id }),
1172 addConnector: (workspace, viewer, input) => call("add_connector", { workspace, viewer, input }),
1173 setConnectorKey: (workspace, viewer, id, headerName, value) => call("set_connector_key", { workspace, viewer, id, header_name: headerName, value }),
1174 removeConnector: (workspace, viewer, id) => call("remove_connector", { workspace, viewer, id }),
1175 refreshConnector: (workspace, viewer, id) => call("refresh_connector", { workspace, viewer, id }),
1176 startConnectorSignIn: (workspace, viewer, id, redirectUri) => call("start_connector_sign_in", { workspace, viewer, id, redirect_uri: redirectUri }),
1177 finishConnectorSignIn: (workspace, viewer, state, code) => call("finish_connector_sign_in", { workspace, viewer, state, code }),
1178 signOutConnector: (workspace, viewer, id) => call("sign_out_connector", { workspace, viewer, id }),
1179 grantConnector: (workspace, viewer, id, scope, target) => call("grant_connector", { workspace, viewer, id, scope, target }),
1180 revokeConnector: (workspace, viewer, id, grant) => call("revoke_connector", { workspace, viewer, id, grant }),
1181 agentConnectors: (workspace, handle, viewer) => call("agent_connectors", { workspace, handle, viewer }),
1182 customizeBundle: (workspace, viewer) => call("customize_bundle", { workspace, viewer }),
Chat and workspace agents: channels, DMs and named agents you talk to1183 };
1184}

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