Skip to content
851 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.

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.1/**
2 * The agent builder (docs.g1t.sh/guides/agents/, "Describe it"): one box
3 * for what the agent should do, the drafted agent as a card to edit, a test
4 * chat beside it, and, on an agent's profile, a box to change it in words
5 * with the change shown before it is saved.
6 */
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.7import { ArrowUp, Check, Lock, MessageSquare, Plug, RotateCcw, Shuffle, Sparkles, Users, Wand2 } from "lucide-react";
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.8import { type ReactNode, useEffect, useRef, useState } from "react";
9import { Form, Link, useFetcher, useNavigation } from "react-router";
10
11import { type AgentProposal, type AgentRedraft, type AgentTemplate, type DraftTurn, FOUNDATIONAL_SKILLS, type WorkspaceAgent } from "@g1t/contracts";
12
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.13import { TeamPicker } from "../agent-role";
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.14import { AgentAvatar } from "../agent-avatar";
15import { FaceEditor } from "./face-editor";
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.16import { Markdown } from "../markdown";
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.17import { Alert } from "../ui/alert";
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.18import { Badge } from "../ui/badge";
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.19import { Button } from "../ui/button";
20import { Card } from "../ui/card";
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.21import { Checkbox } from "../ui/checkbox";
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.22import { Hint } from "../ui/hint";
23import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../ui/select";
24import { type BuilderDefinition, type ChangeRow, changeRows, integrationHint } from "../../lib/agent-builder";
25import { PRESETS, TIER_LABELS, cleanHandle, dollarsField, microsFromDollars } from "../../lib/agent-form";
26import { cn } from "../../lib/cn";
Money is written one way. A single formatter turns millionths of a dollar into dollars, rounding half up on whole micros rather than on a float, so the same sum reads the same on every page: under a cent reads <$0.01 on a total and exactly nothing is $0.00, while the statement's lines, a session's receipt, the price book and an agent's effort costs carry up to four places where the fraction of a cent is the point; the six formatters that each rounded their own way are gone. This month is the calendar month in UTC from its first day to today everywhere, and billing counts the month's not-yet-closed usage in any range that reaches into the current month, so the top bar's pill, Spend, Home and Usage ask for the same days and get the same figure; Home now reads the usage report the others read instead of adding up statements. Usage's pending sentence says what of that usage the close will charge after the discount and included usage, which the billing API returns as pending_charged_micros. A reconciliation test holds the pill, Spend, Home and Usage to one number for one month. The usage and billing guide says how amounts are written and what this month means.27import { money } from "../../lib/money";
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.28
29const FIELD =
30 "w-full rounded-md border border-line bg-bg px-3 py-2 text-sm outline-none transition-colors placeholder:text-faint hover:border-line-strong focus:border-accent-dim";
31/** What the builder's actions answer. */
32export type BuilderAnswer =
33 | { intent: "draft"; ok: true; proposal: AgentProposal }
34 | { intent: "try"; ok: true; text: string; charged_micros: number }
35 | { intent: "redraft"; ok: true; redraft: AgentRedraft }
36 | { intent: string; ok: false; error: string };
37
38/** Things people ask agents to do, to start the box when it is empty. */
39const EXAMPLES = [
40 "Every Monday, read last week's merged pull requests and write release notes in our Releases space.",
41 "Triage new bug reports: reproduce them from the steps, label them, and ask for what's missing.",
42 "Keep me on top of my week: summarise what I'm mentioned in and what's waiting on me.",
43 "Review database migrations for locking, data loss and missing indexes before they merge.",
44];
45
46// ── Describe it ───────────────────────────────────────────────────────────
47
48/**
49 * The first thing New agent shows: one box, "What should this agent do?",
50 * the roles to start from under it, and the full form for those who want it.
51 */
52export function DescribeBox({
53 slug,
54 owner,
55 mayCreate,
56 templates,
57 fetcher,
58 initial,
59}: {
60 slug: string;
61 owner: boolean;
62 /** Whether the viewer may create an agent here at all. */
63 mayCreate: boolean;
64 templates: AgentTemplate[];
65 fetcher: ReturnType<typeof useFetcher<BuilderAnswer>>;
66 initial?: string;
67}) {
68 const [text, setText] = useState(initial ?? "");
69 const [scope, setScope] = useState<"workspace" | "personal">(owner ? "workspace" : "personal");
70 const busy = fetcher.state !== "idle";
71 const error = fetcher.state === "idle" && fetcher.data && !fetcher.data.ok && fetcher.data.intent === "draft" ? fetcher.data.error : null;
72 return (
73 <div>
74 <fetcher.Form method="post" className="relative">
75 <input type="hidden" name="intent" value="draft" />
76 <input type="hidden" name="scope" value={scope} />
77 <label htmlFor="description" className="sr-only">
78 What should this agent do?
79 </label>
80 <div
81 className={cn(
82 "rounded-2xl border border-line bg-surface p-1.5 shadow-sm transition-colors focus-within:border-accent/60 focus-within:ring-4 focus-within:ring-accent/10",
83 !mayCreate && "opacity-60",
84 )}
85 >
86 <textarea
87 id="description"
88 name="description"
89 value={text}
90 onChange={(event) => setText(event.target.value)}
91 onKeyDown={(event) => {
92 if (event.key === "Enter" && (event.metaKey || event.ctrlKey) && text.trim().length >= 3) event.currentTarget.form?.requestSubmit();
93 }}
94 disabled={!mayCreate || busy}
95 rows={4}
96 maxLength={2000}
97 placeholder="Describe the job: what it does, for whom, and what good looks like."
98 className="block w-full resize-none bg-transparent px-3 pt-2.5 pb-1 text-base leading-relaxed outline-none placeholder:text-faint sm:text-[0.9375rem]"
99 />
100 <div className="flex flex-wrap items-center gap-2 px-1.5 pb-1">
101 {owner ? (
102 <div role="radiogroup" aria-label="Who it's for" className="flex rounded-lg bg-bg p-0.5 ring-1 ring-line">
103 {(
104 [
105 ["workspace", "The workspace", <Users key="w" size={13} />],
106 ["personal", "Just me", <Lock key="p" size={13} />],
107 ] as const
108 ).map(([value, label, icon]) => (
109 <button
110 key={value}
111 type="button"
112 role="radio"
113 aria-checked={scope === value}
114 onClick={() => setScope(value)}
115 className={cn(
116 "inline-flex h-7 items-center gap-1.5 rounded-md px-2.5 text-xs font-medium transition-colors",
117 scope === value ? "bg-raised text-fg shadow-sm ring-1 ring-line-strong" : "text-muted hover:text-fg",
118 )}
119 >
120 {icon}
121 {label}
122 </button>
123 ))}
124 </div>
125 ) : (
126 <span className="inline-flex items-center gap-1.5 text-xs text-muted">
127 <Lock size={12} />
128 Your personal agent
129 </span>
130 )}
131 <span className="grow" />
132 <span className="hidden text-xs text-faint sm:inline">{busy ? "Drafting…" : "Ctrl+Enter"}</span>
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.133 <Button type="submit" disabled={!mayCreate || busy || text.trim().length < 3} variant="accent" size="sm">
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.134 <Sparkles size={14} className={busy ? "animate-pulse motion-reduce:animate-none" : ""} />
135 {busy ? "Drafting…" : "Draft it"}
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.136 </Button>
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.137 </div>
138 </div>
139 </fetcher.Form>
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.140 {error && (
141 <Alert asChild className="mt-3 px-4 py-2.5">
142 <p>{error}</p>
143 </Alert>
144 )}
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.145 <p className="mt-3 text-xs leading-relaxed text-muted">
146 {scope === "personal"
147 ? "Only you can talk to it, in your direct message with it. It spends from your own budget: $20 a month and $2 a session to start."
148 : "Everyone in the workspace can talk to it. It starts with the workspace's budget for a new agent."}{" "}
149 Drafting is a quick model call charged to you; nothing is saved until you create it.
150 </p>
151 {!text && mayCreate && (
152 <div className="mt-5">
153 <p className="text-xs font-medium text-faint">For example</p>
154 <ul className="mt-2 grid gap-2 sm:grid-cols-2">
155 {EXAMPLES.map((example) => (
156 <li key={example}>
157 <button
158 type="button"
159 onClick={() => setText(example)}
160 className="w-full rounded-lg border border-line bg-bg px-3 py-2 text-left text-[0.8125rem] leading-snug text-muted transition-colors hover:border-line-strong hover:text-fg"
161 >
162 {example}
163 </button>
164 </li>
165 ))}
166 </ul>
167 </div>
168 )}
169 {templates.length > 0 && (
170 <div className="mt-8">
171 <p className="text-xs font-medium text-faint">or start from a role</p>
172 <ul className="mt-2 flex flex-wrap gap-2">
173 {templates.map((template) => (
174 <li key={template.id}>
175 <Link
176 to={`?template=${encodeURIComponent(template.id)}`}
177 preventScrollReset
178 className="inline-flex h-8 items-center gap-2 rounded-full border border-line bg-surface pr-3 pl-1 text-[0.8125rem] text-fg/85 transition-colors hover:border-line-strong hover:text-fg"
179 >
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.180 <AgentAvatar agent={{ handle: template.handle }} size={24} />
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.181 {template.title}
182 </Link>
183 </li>
184 ))}
185 <li>
186 <Link
187 to="?template=blank"
188 preventScrollReset
189 className="inline-flex h-8 items-center gap-1.5 rounded-full border border-dashed border-line-strong px-3 text-[0.8125rem] text-muted transition-colors hover:text-fg"
190 >
191 Edit all fields
192 </Link>
193 </li>
194 </ul>
195 <p className="mt-3 text-xs text-faint">
196 <Link to={`/${slug}/-/agents/templates`} className="hover:text-fg hover:underline">
197 Read each role in full
198 </Link>
199 </p>
200 </div>
201 )}
202 </div>
203 );
204}
205
206// ── The drafted agent ─────────────────────────────────────────────────────
207
208function Label({ htmlFor, children, hint }: { htmlFor?: string; children: ReactNode; hint?: ReactNode }) {
209 return (
210 <div className="mb-1.5 flex items-baseline justify-between gap-3">
211 <label htmlFor={htmlFor} className="text-xs font-medium text-fg-soft">
212 {children}
213 </label>
214 {hint && <span className="text-xs text-faint">{hint}</span>}
215 </div>
216 );
217}
218
219function Section({ title, about, children }: { title: string; about?: ReactNode; children: ReactNode }) {
220 return (
221 <section className="border-t border-line px-4 py-4 sm:px-5">
222 <h3 className="text-xs font-semibold tracking-wide text-faint uppercase">{title}</h3>
223 {about && <p className="mt-1 text-xs text-muted">{about}</p>}
224 <div className="mt-3 space-y-3">{children}</div>
225 </section>
226 );
227}
228
229/**
230 * The drafted agent as a card to edit: who it is, its job, what it is
231 * responsible for, its voice, the skills it keeps on, what it needs
232 * connected, routines that would suit it, its model limits and budget.
233 * Only the name and the job are required.
234 */
235export function ProposalCard({
236 slug,
237 owner,
238 proposal,
239 value,
240 onChange,
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.241 joinable = [],
242 teams = [],
243 onTeams,
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.244}: {
245 slug: string;
246 owner: boolean;
247 proposal: AgentProposal;
248 value: BuilderDefinition;
249 onChange: (next: BuilderDefinition) => void;
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.250 /** The teams the person may add it to; a workspace agent only. */
251 joinable?: { slug: string; name: string }[];
252 /** The teams chosen to add it to: memberships, posted with Create, never part of the draft. */
253 teams?: string[];
254 onTeams?: (next: string[]) => void;
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.255}) {
256 const ideas = [proposal.definition.display_name, ...proposal.name_ideas];
257 const [idea, setIdea] = useState(0);
258 const [handleEdited, setHandleEdited] = useState(false);
259 const set = (patch: Partial<BuilderDefinition>) => onChange({ ...value, ...patch });
260 const rename = (name: string) => set({ display_name: name, ...(handleEdited ? {} : { handle: cleanHandle(name) }) });
261 const off = new Set(value.skills_off ?? []);
262 const suggested = new Set(proposal.skills);
263 const hints = proposal.integrations.map((s) => integrationHint(slug, s, owner)).filter((h) => h !== null);
264 const seed = value.avatar_seed || value.handle || "agent";
265 return (
266 <div className="overflow-hidden rounded-2xl border border-line bg-surface">
267 <div className="flex items-start gap-3 px-4 pt-4 pb-4 sm:px-5">
268 <div className="relative shrink-0">
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.269 <AgentAvatar agent={{ handle: value.handle, avatar_seed: seed, look: value.look ?? null }} size={56} />
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.270 </div>
271 <div className="grid min-w-0 grow gap-2 sm:grid-cols-[minmax(0,1fr)_minmax(0,0.8fr)]">
272 <div>
273 <Label htmlFor="b-name">Name</Label>
274 <div className="flex gap-1.5">
275 <input id="b-name" value={value.display_name} onChange={(e) => rename(e.target.value)} className={FIELD} autoComplete="off" data-1p-ignore required />
276 {ideas.length > 1 && (
277 <Hint label="Another name">
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.278 <Button
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.279 type="button"
280 aria-label="Another name"
281 onClick={() => {
282 const next = (idea + 1) % ideas.length;
283 setIdea(next);
284 rename(ideas[next]!);
285 }}
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.286 variant="outline" size="icon"
287 className="size-9.5 text-muted hover:bg-raised"
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.288 >
289 <Shuffle size={15} />
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.290 </Button>
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.291 </Hint>
292 )}
293 </div>
294 </div>
295 <div>
296 <Label htmlFor="b-handle">Handle</Label>
297 <div className="flex items-center rounded-md border border-line bg-bg transition-colors focus-within:border-accent-dim hover:border-line-strong">
298 <span className="pl-3 font-mono text-sm text-faint">@</span>
299 <input
300 id="b-handle"
301 value={value.handle}
302 onChange={(e) => {
303 setHandleEdited(true);
304 set({ handle: e.target.value });
305 }}
306 className="min-w-0 grow bg-transparent py-2 pr-3 pl-0.5 font-mono text-sm outline-none"
307 autoComplete="off"
308 data-1p-ignore
309 />
310 </div>
311 </div>
312 <div>
313 <Label htmlFor="b-title">Title</Label>
314 <input id="b-title" value={value.title ?? ""} onChange={(e) => set({ title: e.target.value })} placeholder="Release Manager" className={FIELD} autoComplete="off" />
315 </div>
316 </div>
317 </div>
318
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.319 {onTeams && (
320 <Section title="Add to teams" about={value.scope === "personal" ? "A personal agent is on no team." : "Optional. It joins them like anyone, and you can change them on its profile or the team's page."}>
321 {value.scope === "personal" ? null : <TeamPicker teams={joinable} value={teams} onChange={onTeams} />}
322 </Section>
323 )}
324
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.325 <Section title="Face" about="Its bot face, wherever it appears. It has one of its own already; change any part, shuffle, or give it back.">
326 <FaceEditor value={value.look ?? null} seed={seed} name={value.display_name || "Your new agent"} preset={value.personality_preset} onChange={(look) => set({ look })} />
327 </Section>
328
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.329 <Section title="Job" about="What it is responsible for and how it works. It reads this before every reply.">
330 <textarea
331 aria-label="Job"
332 value={value.instructions}
333 onChange={(e) => set({ instructions: e.target.value })}
334 rows={8}
335 required
336 className={`${FIELD} resize-y font-mono text-[0.8125rem] leading-relaxed`}
337 />
338 <div>
339 <Label htmlFor="b-duties" hint="One a line, 2 to 8">
340 Responsibilities
341 </Label>
342 <textarea
343 id="b-duties"
344 value={(value.responsibilities ?? []).join("\n")}
345 onChange={(e) => set({ responsibilities: e.target.value.split("\n").slice(0, 8) })}
346 onBlur={() => set({ responsibilities: (value.responsibilities ?? []).map((d) => d.trim()).filter(Boolean) })}
347 rows={Math.max(3, (value.responsibilities ?? []).length)}
348 className={`${FIELD} resize-y`}
349 />
350 </div>
351 </Section>
352
353 <Section title="Personality" about="Its voice only. A personality never changes what it may do.">
354 <div role="radiogroup" aria-label="Voice" className="grid grid-cols-2 gap-1 rounded-lg bg-bg p-1 ring-1 ring-line sm:grid-cols-4">
355 {PRESETS.map((option) => (
356 <button
357 key={option.value}
358 type="button"
359 role="radio"
360 aria-checked={value.personality_preset === option.value}
361 onClick={() => set({ personality_preset: option.value })}
362 className={cn(
363 "h-8 rounded-md text-[0.8125rem] font-medium transition-colors",
364 value.personality_preset === option.value ? "bg-raised text-fg shadow-sm ring-1 ring-line-strong" : "text-muted hover:text-fg",
365 )}
366 >
367 {option.label}
368 </button>
369 ))}
370 </div>
371 <input aria-label="In its own words" value={value.personality ?? ""} onChange={(e) => set({ personality: e.target.value })} placeholder="In its own words (optional)" className={FIELD} />
372 </Section>
373
374 <Section title="Skills" about="g1t's playbooks it keeps on. The suggested ones fit its job; turn any on or off.">
375 <div className="grid gap-1.5 sm:grid-cols-2">
376 {FOUNDATIONAL_SKILLS.map((skill) => {
377 const on = !off.has(skill.id);
378 return (
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.379 <Card asChild key={skill.id} tone="bg" radius="lg" className="flex min-h-10 cursor-pointer items-center gap-2.5 px-3 py-2 text-sm has-[[data-state=checked]]:border-accent/50 has-[[data-state=checked]]:bg-accent/5">
380 <label>
381 <Checkbox
382 checked={on}
383 onCheckedChange={() => {
384 const next = new Set(off);
385 if (on) next.add(skill.id);
386 else next.delete(skill.id);
387 set({ skills_off: FOUNDATIONAL_SKILLS.map((s) => s.id).filter((id) => next.has(id)) });
388 }}
389 />
390 <span className="min-w-0 grow truncate">{skill.name}</span>
391 {suggested.has(skill.id) && suggested.size < FOUNDATIONAL_SKILLS.length && (
392 <Badge tone="accent" className="shrink-0">
393 Suggested
394 </Badge>
395 )}
396 </label>
397 </Card>
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.398 );
399 })}
400 </div>
401 </Section>
402
403 {hints.length > 0 && (
404 <Section title="What it needs connected" about="Integrations its job would use. It works without them, and says so when asked for something that needs one.">
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.405 <Card asChild tone="bg" radius="lg" divided className="overflow-hidden">
406 <ul>
407 {hints.map((hint) => (
408 <li key={hint.id} className="flex flex-wrap items-center gap-x-3 gap-y-1 px-3 py-2.5">
409 <Plug size={14} className="shrink-0 text-faint" />
410 <span className="min-w-0 grow basis-40">
411 <span className="block text-sm font-medium">{hint.name}</span>
412 {hint.why && <span className="block text-xs text-muted">{hint.why}</span>}
413 </span>
414 {hint.action === "soon" ? (
415 <Badge>Soon</Badge>
416 ) : (
417 <Link to={hint.href} target="_blank" rel="noreferrer" className="text-xs font-medium text-accent hover:underline">
418 {hint.action === "connect" ? "Connect" : "Ask an owner"}
419 </Link>
420 )}
421 </li>
422 ))}
423 </ul>
424 </Card>
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.425 </Section>
426 )}
427
428 {proposal.routines.length > 0 && (
429 <Section
430 title="Routines that would suit it"
431 about={value.scope === "personal" ? "Personal agents can't run routines yet. An owner can promote it to a workspace agent, which can." : "Set them up on its Routines tab once it exists."}
432 >
433 <ul className="space-y-2">
434 {proposal.routines.map((routine) => (
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.435 <Card asChild key={routine.name} tone="bg" radius="lg" className="px-3 py-2.5">
436 <li>
437 <p className="text-sm font-medium">
438 {routine.name} <span className="font-normal text-muted">· {routine.when}</span>
439 </p>
440 {routine.instructions && <p className="mt-0.5 text-xs text-muted">{routine.instructions}</p>}
441 </li>
442 </Card>
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.443 ))}
444 </ul>
445 </Section>
446 )}
447
448 <Section title="Models and budget" about="g1t routes each step to the tier it needs; these only limit it. Budgets are checked before work starts.">
449 <div className="grid gap-3 sm:grid-cols-2">
450 {(["floor", "ceiling"] as const).map((key) => (
451 <div key={key}>
452 <Label htmlFor={`b-${key}`}>{key === "floor" ? "Floor" : "Ceiling"}</Label>
453 <Select
454 value={value.routing?.[key] ?? "none"}
455 onValueChange={(tier) =>
456 set({ routing: { floor: null, ceiling: null, providers: [], pinned: null, ...value.routing, [key]: tier === "none" ? null : (tier as "small") } })
457 }
458 >
459 <SelectTrigger id={`b-${key}`}>
460 <SelectValue />
461 </SelectTrigger>
462 <SelectContent>
463 <SelectItem value="none">{key === "floor" ? "No floor" : "No ceiling"}</SelectItem>
464 {(["small", "large", "frontier"] as const).map((tier) => (
465 <SelectItem key={tier} value={tier} description={TIER_LABELS[tier].split(": ")[1]}>
466 {TIER_LABELS[tier].split(":")[0]}
467 </SelectItem>
468 ))}
469 </SelectContent>
470 </Select>
471 </div>
472 ))}
473 {(
474 [
475 ["monthly_micros", "Monthly"],
476 ["task_micros", "Per session"],
477 ] as const
478 ).map(([key, label]) => (
479 <div key={key}>
480 <Label htmlFor={`b-${key}`} hint={key === "monthly_micros" ? "Per calendar month" : "Going over asks you"}>
481 {label}
482 </Label>
483 <div className="flex items-center rounded-md border border-line bg-bg transition-colors focus-within:border-accent-dim hover:border-line-strong">
484 <span className="pl-3 text-sm text-faint">$</span>
485 <input
486 id={`b-${key}`}
487 inputMode="decimal"
488 defaultValue={dollarsField(value.budget?.[key])}
489 onBlur={(e) => {
490 const micros = microsFromDollars(e.target.value);
491 set({ budget: { ...value.budget, [key]: micros == null || Number.isNaN(micros) ? null : micros } });
492 }}
493 placeholder="No cap"
494 className="min-w-0 grow bg-transparent px-2 py-2 text-sm tabular-nums outline-none placeholder:text-faint"
495 autoComplete="off"
496 data-1p-ignore
497 />
498 </div>
499 </div>
500 ))}
501 </div>
502 </Section>
503 </div>
504 );
505}
506
507// ── Try it ────────────────────────────────────────────────────────────────
508
509/**
510 * A test chat with the drafted agent, as it is in the card right now:
511 * charged to the person trying it, and nothing kept once they leave.
512 */
513export function TryChat({ definition, onReset }: { definition: BuilderDefinition; onReset?: () => void }) {
514 const fetcher = useFetcher<BuilderAnswer>({ key: "agent-try" });
515 const [turns, setTurns] = useState<DraftTurn[]>([]);
516 const [text, setText] = useState("");
517 const [spent, setSpent] = useState(0);
518 const handled = useRef<unknown>(null);
519 const log = useRef<HTMLDivElement>(null);
520 const busy = fetcher.state !== "idle";
521 useEffect(() => {
522 if (fetcher.state !== "idle" || !fetcher.data || handled.current === fetcher.data) return;
523 handled.current = fetcher.data;
524 if (fetcher.data.ok && fetcher.data.intent === "try") {
525 const answer = fetcher.data;
526 setTurns((now) => [...now, { role: "assistant", content: answer.text }]);
527 setSpent((n) => n + answer.charged_micros);
528 }
529 }, [fetcher.state, fetcher.data]);
530 // The newest message in view, scrolling only the conversation, never the page.
531 useEffect(() => {
532 if (log.current) log.current.scrollTop = log.current.scrollHeight;
533 }, [turns.length, busy]);
534 const error = fetcher.state === "idle" && fetcher.data && !fetcher.data.ok && fetcher.data.intent === "try" ? fetcher.data.error : null;
535 const send = () => {
536 const body = text.trim();
537 if (!body || busy) return;
538 const next: DraftTurn[] = [...turns, { role: "user", content: body }];
539 setTurns(next);
540 setText("");
541 fetcher.submit({ intent: "try", definition: JSON.stringify(definition), messages: JSON.stringify(next.slice(-24)) }, { method: "post" });
542 };
543 const name = definition.display_name || "your agent";
544 return (
545 <div className="flex h-full min-h-104 flex-col overflow-hidden rounded-2xl border border-line bg-surface">
546 <div className="flex items-center gap-2.5 border-b border-line px-4 py-3">
547 <MessageSquare size={15} className="text-faint" />
548 <div className="min-w-0 grow">
549 <p className="text-sm font-semibold">Try it</p>
550 <p className="truncate text-xs text-muted">Talk to {name} as it is drafted. Charged to you; nothing is saved.</p>
551 </div>
552 {turns.length > 0 && (
553 <Hint label="Start over">
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.554 <Button
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.555 type="button"
556 aria-label="Start over"
557 onClick={() => {
558 setTurns([]);
559 onReset?.();
560 }}
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.561 variant="ghost"
562 size="icon-sm"
563 className="text-faint"
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.564 >
565 <RotateCcw size={14} />
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.566 </Button>
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.567 </Hint>
568 )}
569 </div>
570 <div ref={log} className="min-h-0 grow space-y-3 overflow-y-auto px-4 py-4" aria-live="polite">
571 {turns.length === 0 && (
572 <div className="flex h-full flex-col items-center justify-center py-8 text-center">
573 <AgentAvatar agent={{ handle: definition.handle, avatar_seed: definition.avatar_seed || definition.handle }} size={40} />
574 <p className="mt-3 text-sm font-medium">Ask {name} something it would get asked</p>
575 <p className="mt-1 max-w-xs text-xs text-muted">It answers from its job and voice. It has no tools or memory until you create it.</p>
576 </div>
577 )}
578 {turns.map((turn, at) =>
579 turn.role === "user" ? (
580 <div key={at} className="flex justify-end">
581 <p className="max-w-[85%] rounded-2xl rounded-br-md bg-accent/15 px-3.5 py-2 text-sm whitespace-pre-wrap text-fg">{turn.content}</p>
582 </div>
583 ) : (
584 <div key={at} className="flex gap-2.5">
585 <AgentAvatar agent={{ handle: definition.handle, avatar_seed: definition.avatar_seed || definition.handle }} size={24} />
586 <div className="min-w-0 grow text-sm [&_.prose]:text-sm">
587 <Markdown source={turn.content} />
588 </div>
589 </div>
590 ),
591 )}
592 {busy && (
593 <div className="flex items-center gap-2.5 text-xs text-muted">
594 <AgentAvatar agent={{ handle: definition.handle, avatar_seed: definition.avatar_seed || definition.handle }} size={24} />
595 {name} is typing…
596 </div>
597 )}
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.598 {error && (
599 <Alert asChild className="text-xs">
600 <p>{error}</p>
601 </Alert>
602 )}
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.603 </div>
604 <form
605 className="flex items-end gap-2 border-t border-line p-2.5"
606 onSubmit={(event) => {
607 event.preventDefault();
608 send();
609 }}
610 >
611 <label htmlFor="try-message" className="sr-only">
612 Message {name}
613 </label>
614 <textarea
615 id="try-message"
616 value={text}
617 onChange={(e) => setText(e.target.value)}
618 onKeyDown={(e) => {
619 if (e.key === "Enter" && !e.shiftKey) {
620 e.preventDefault();
621 send();
622 }
623 }}
624 rows={1}
625 maxLength={4000}
626 placeholder={`Message ${name}`}
627 className="max-h-32 min-h-9 min-w-0 grow resize-none rounded-md border border-line bg-bg px-3 py-2 text-sm outline-none placeholder:text-faint focus:border-accent-dim"
628 />
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.629 <Button type="submit" aria-label="Send" disabled={busy || !text.trim()} variant="accent" size="icon">
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.630 <ArrowUp size={16} />
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.631 </Button>
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.632 </form>
633 {spent > 0 && <p className="border-t border-line px-4 py-1.5 text-[0.6875rem] text-faint tabular-nums">Trying it has cost you {money(spent)} so far.</p>}
634 </div>
635 );
636}
637
638// ── Create ────────────────────────────────────────────────────────────────
639
640/** Saves the drafted agent: its hello is waiting in a direct message. */
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.641export function CreateDraft({ definition, teams = [], onEditAll }: { definition: BuilderDefinition; teams?: string[]; onEditAll: () => void }) {
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.642 const navigation = useNavigation();
643 const busy = navigation.state !== "idle" && navigation.formData?.get("intent") === "create_draft";
644 const ready = definition.display_name.trim() && definition.instructions.trim() && definition.handle.trim();
645 return (
646 <Form method="post" className="flex flex-wrap items-center justify-end gap-2">
647 <input type="hidden" name="intent" value="create_draft" />
648 <input type="hidden" name="definition" value={JSON.stringify(definition)} />
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.649 {teams.map((slug) => (
650 <input key={slug} type="hidden" name="teams" value={slug} />
651 ))}
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.652 <Button type="button" onClick={onEditAll} variant="outline">
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.653 Edit all fields
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.654 </Button>
655 <Button type="submit" disabled={busy || !ready} variant="accent">
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.656 <Check size={15} />
657 {busy ? "Creating…" : `Create ${definition.display_name.trim() || "agent"}`}
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.658 </Button>
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.659 </Form>
660 );
661}
662
663// ── Change it in words ────────────────────────────────────────────────────
664
665/**
666 * "Tell <name> what to change": the change is drafted, shown field by
667 * field with the job as a diff, and saved as a new version only when the
668 * person says so.
669 */
670export function RedraftBox({ agent }: { agent: WorkspaceAgent }) {
671 const fetcher = useFetcher<BuilderAnswer>({ key: `redraft:${agent.id}` });
672 const save = useFetcher<{ ok?: boolean; saved?: boolean; errors?: Record<string, string> }>({ key: `redraft-save:${agent.id}` });
673 const [text, setText] = useState("");
674 const [shown, setShown] = useState<AgentRedraft | null>(null);
675 const handled = useRef<unknown>(null);
676 useEffect(() => {
677 if (fetcher.state !== "idle" || !fetcher.data || handled.current === fetcher.data) return;
678 handled.current = fetcher.data;
679 if (fetcher.data.ok && fetcher.data.intent === "redraft") setShown(fetcher.data.redraft);
680 }, [fetcher.state, fetcher.data]);
681 useEffect(() => {
682 if (save.state === "idle" && save.data?.saved) {
683 setShown(null);
684 setText("");
685 }
686 }, [save.state, save.data]);
687 const busy = fetcher.state !== "idle";
688 const error = fetcher.state === "idle" && fetcher.data && !fetcher.data.ok && fetcher.data.intent === "redraft" ? fetcher.data.error : null;
689 const saveError = save.state === "idle" && save.data && !save.data.saved ? (save.data.errors?.form ?? save.data.errors?.handle ?? null) : null;
690 const skillName = (id: string) => FOUNDATIONAL_SKILLS.find((s) => s.id === id)?.name ?? id;
691 const rows = shown ? changeRows(agent, shown.changes, skillName) : [];
692 return (
693 <section aria-labelledby="redraft" className="mb-10 rounded-2xl border border-line bg-surface">
694 <fetcher.Form method="post" className="p-4 sm:p-5">
695 <input type="hidden" name="intent" value="redraft" />
696 <h2 id="redraft" className="flex items-center gap-2 text-sm font-semibold">
697 <Wand2 size={15} className="text-accent" />
698 Tell {agent.display_name} what to change
699 </h2>
700 <p className="mt-1 text-xs text-muted">Say it in your own words. You'll see the change before it's saved as version {agent.version + 1}. Drafting it is charged to you.</p>
701 <div className="mt-3 flex flex-col gap-2 sm:flex-row sm:items-end">
702 <label htmlFor="redraft-request" className="sr-only">
703 What should change
704 </label>
705 <textarea
706 id="redraft-request"
707 name="request"
708 value={text}
709 onChange={(e) => setText(e.target.value)}
710 onKeyDown={(e) => {
711 if (e.key === "Enter" && (e.metaKey || e.ctrlKey) && text.trim().length >= 3) e.currentTarget.form?.requestSubmit();
712 }}
713 rows={2}
714 maxLength={1000}
715 placeholder={`Answer in Spanish, and keep replies under five sentences`}
716 className={`${FIELD} grow resize-y`}
717 />
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.718 <Button type="submit" disabled={busy || text.trim().length < 3} variant="accent">
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.719 <Sparkles size={14} className={busy ? "animate-pulse motion-reduce:animate-none" : ""} />
720 {busy ? "Drafting…" : "Draft the change"}
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.721 </Button>
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.722 </div>
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.723 {error && (
724 <Alert asChild className="mt-3">
725 <p>{error}</p>
726 </Alert>
727 )}
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.728 </fetcher.Form>
729 {shown && (
730 <div className="border-t border-line p-4 sm:p-5">
731 <p className="text-sm">
732 <span className="font-medium">{shown.summary}</span>{" "}
733 <span className="text-muted">
734 {rows.length} {rows.length === 1 ? "change" : "changes"} to version {shown.from_version}.
735 </span>
736 </p>
737 <ChangeList rows={rows} />
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.738 {saveError && (
739 <Alert asChild className="mt-3">
740 <p>{saveError}</p>
741 </Alert>
742 )}
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.743 <save.Form method="post" className="mt-4 flex flex-wrap items-center justify-end gap-2">
744 <input type="hidden" name="intent" value="apply" />
745 <input type="hidden" name="changes" value={JSON.stringify(shown.changes)} />
746 <input type="hidden" name="from_version" value={shown.from_version} />
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.747 <Button type="button" onClick={() => setShown(null)} variant="outline">
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.748 Discard
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.749 </Button>
750 <Button type="submit" disabled={save.state !== "idle"} variant="accent">
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.751 <Check size={15} />
752 {save.state !== "idle" ? "Saving…" : `Save as version ${agent.version + 1}`}
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.753 </Button>
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.754 </save.Form>
755 </div>
756 )}
757 </section>
758 );
759}
760
761/** Each field a change touches, before and after; the job and duties as a line diff. */
762export function ChangeList({ rows }: { rows: ChangeRow[] }) {
763 return (
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.764 <Card asChild tone="bg" radius="lg" divided className="mt-3 overflow-hidden">
765 <dl>
766 {rows.map((row) => (
767 <div key={row.field} className="px-3 py-2.5">
768 <dt className="text-xs font-medium text-faint">{row.label}</dt>
769 {row.lines ? (
770 <dd className="mt-1.5 max-h-80 overflow-auto rounded-md border border-line font-mono text-[0.75rem] leading-relaxed">
771 {row.lines.map((line, at) => (
772 <div
773 key={at}
774 className={cn(
775 "flex gap-2 px-2 whitespace-pre-wrap",
776 line.kind === "added" && "bg-success/10 text-success",
777 line.kind === "removed" && "bg-danger/10 text-danger line-through decoration-danger/40",
778 line.kind === "same" && "text-muted",
779 )}
780 >
781 <span aria-hidden="true" className="w-3 shrink-0 select-none">
782 {line.kind === "added" ? "+" : line.kind === "removed" ? "−" : " "}
783 </span>
784 <span className="sr-only">{line.kind === "added" ? "Added: " : line.kind === "removed" ? "Removed: " : ""}</span>
785 <span className="min-w-0">{line.text || " "}</span>
786 </div>
787 ))}
788 </dd>
789 ) : (
790 <dd className="mt-1 flex flex-wrap items-baseline gap-x-2 gap-y-0.5 text-sm">
791 <span className="text-muted line-through decoration-line-strong">{row.before}</span>
792 <span aria-hidden="true" className="text-faint">
793 →
794 </span>
795 <span className="sr-only">becomes</span>
796 <span className="font-medium text-fg">{row.after}</span>
797 </dd>
798 )}
799 </div>
800 ))}
801 </dl>
802 </Card>
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.803 );
804}
805
806/** Whose personal agent it is, and, for owners, making it the workspace's. */
807export function PersonalNotice({ agent, owner, mine }: { agent: WorkspaceAgent; owner: boolean; mine: boolean }) {
808 const navigation = useNavigation();
809 const [asking, setAsking] = useState(false);
810 const busy = navigation.state !== "idle" && navigation.formData?.get("intent") === "promote";
811 return (
812 <section aria-labelledby="personal" className="mb-10 rounded-2xl border border-line bg-surface p-4 sm:p-5">
813 <h2 id="personal" className="flex items-center gap-2 text-sm font-semibold">
814 <Lock size={14} className="text-faint" />
815 {mine ? "Your personal agent" : `@${agent.personal_owner ?? "a member"}'s personal agent`}
816 </h2>
817 <p className="mt-1 text-sm text-muted">
818 {mine
819 ? "Only you can talk to it, in your direct message with it, and it spends from your budget. It isn't in channels, and other agents don't hand it work."
820 : `Only @${agent.personal_owner ?? "its member"} talks to it, and it spends from their budget. As an owner you can archive it, or make it a workspace agent everyone can talk to.`}
821 </p>
822 {owner && (
823 <div className="mt-4">
824 {asking ? (
825 <Form method="post" className="space-y-3">
826 <input type="hidden" name="intent" value="promote" />
827 <p className="text-sm text-fg-soft">
828 {agent.display_name} becomes a workspace agent with the same handle, job and every version so far. What it remembers from{" "}
829 {mine ? "your" : `@${agent.personal_owner}'s`} direct messages stays behind with the personal agent, which is archived.
830 </p>
831 <div className="flex flex-wrap gap-2">
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.832 <Button type="submit" disabled={busy} variant="accent">
Anyone makes an agent by describing it: one box drafts the whole agent (name, job, responsibilities, voice, skills to keep, integrations it needs, model limits and budget) as a card to change and try in a chat beside it before creating it, and an agent changes later by saying what to change, shown as a diff before it's saved. Members can make personal agents, which only they talk to and which spend from their own budget, unless owners turn that off; owners promote one to a workspace agent. The agents guide says how.833 <Users size={14} />
834 {busy ? "Promoting…" : `Promote ${agent.display_name}`}
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.835 </Button>
836 <Button type="button" onClick={() => setAsking(false)} variant="outline">
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.837 Cancel
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.838 </Button>
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.839 </div>
840 </Form>
841 ) : (
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.842 <Button type="button" onClick={() => setAsking(true)} variant="outline">
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.843 <Users size={14} />
844 Promote to a workspace agent…
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.845 </Button>
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.846 )}
847 </div>
848 )}
849 </section>
850 );
851}