Skip to content
221 linesCodeBlameRaw
1/**
2 * Agent skills (docs.g1t.sh/guides/agent-skills/): playbooks that say how an
3 * agent does a kind of work with the tools it already has. A skill never
4 * adds a tool or a permission: it names the tools it uses, and an agent
5 * without one of them (in a conversation whose people can't read code, say)
6 * is told that part isn't available there.
7 *
8 * Every agent starts with g1t's foundational skills, below. Each says,
9 * ability by ability, what works today and what is coming, and the agent is
10 * told the same, so it never claims to do what it can't. A workspace's
11 * owners can turn any foundational skill off for one agent
12 * (`WorkspaceAgent.skills_off`); turning one off takes its playbook out of
13 * the agent's instructions and leaves its tools as they were.
14 *
15 * Skills a workspace writes, adds from the Marketplace or publishes from
16 * what an agent learned are coming (`SKILL_SOURCES`).
17 *
18 * Wire shapes are snake_case.
19 */
20
21export type SkillCategory = "documents" | "research" | "data" | "code" | "communication" | "files";
22
23/** Where a skill comes from: g1t's own, written in the workspace, from the Marketplace, or learned from finished work. */
24export type SkillSource = "foundational" | "workspace" | "marketplace" | "learned";
25
26/** One thing a skill does, and whether it works today. */
27export type SkillAbility = {
28 /** Unique within its skill: `pdf`. */
29 id: string;
30 /** What it does, as the Skills tab lists it: "Make PDFs". */
31 label: string;
32 /** `ready` works today with the tools listed; `coming` is planned and the agent says so when asked. */
33 status: "ready" | "coming";
34 /** The agent's tools it uses; none for a coming ability. */
35 tools: string[];
36 /** A line on how, or what is missing: "From Markdown, as a file attached to a doc." */
37 note: string;
38};
39
40export type AgentSkill = {
41 /** `documents`, unique among skills. */
42 id: string;
43 name: string;
44 /** One line, as the Skills tab shows it. */
45 description: string;
46 category: SkillCategory;
47 source: SkillSource;
48 /** Which release of it: foundational skills change with g1t's releases. */
49 version: string;
50 /**
51 * The playbook, in the second person, as it is put in the agent's
52 * instructions while the skill is on. Coming abilities are added to it
53 * as what the agent can't do yet.
54 */
55 instructions: string;
56 abilities: SkillAbility[];
57};
58
59/** The foundational skills' release: they change together, with g1t. */
60export const FOUNDATIONAL_SKILLS_VERSION = "2026.10";
61
62/** The formats `make_file` writes. */
63export const MAKE_FILE_FORMATS = ["pdf", "docx", "xlsx", "csv", "md"] as const;
64export type MakeFileFormat = (typeof MAKE_FILE_FORMATS)[number];
65
66const V = FOUNDATIONAL_SKILLS_VERSION;
67
68/**
69 * g1t's foundational skills, in the order the Skills tab shows them. The
70 * tools named are the agent tools in services/agents (src/tools.ts); a
71 * test there fails when one is named that doesn't exist.
72 */
73export const FOUNDATIONAL_SKILLS: AgentSkill[] = [
74 {
75 id: "documents",
76 name: "Documents",
77 description: "PDFs, Word documents, spreadsheets and docs in Artifacts.",
78 category: "documents",
79 source: "foundational",
80 version: V,
81 instructions: [
82 "When someone asks for a document, give them the document, not a description of one.",
83 "- A doc to read and edit together: write it with create_artifact (Markdown: headings, lists, tables, task lists, callouts, Mermaid charts), or change one with edit_artifact.",
84 '- A file (a PDF, a Word document, a spreadsheet, a CSV): call make_file with the format. For pdf and docx, write the whole document as Markdown in content; for xlsx and csv, give the rows in sheets. Without an artifact, make_file makes a doc holding the content with the file attached; with one, it attaches the file to that doc. Link what it returns: "Here\'s the PDF: <link>".',
85 "- Write the finished thing: a title, short sections, real numbers and names from what you read. Never leave placeholders like [Company name] unless they asked for a template.",
86 "- PDFs and Word documents keep headings, paragraphs, bold, italic, code, lists, quotes and tables; images and charts don't carry into the file (they do in the doc). PDFs are in Latin script: say so if the text needs another.",
87 "- Long or many-step documents belong in a session (start_session), which reports back with the link.",
88 ].join("\n"),
89 abilities: [
90 { id: "doc", label: "Write and edit docs in Artifacts", status: "ready", tools: ["create_artifact", "edit_artifact", "read_artifact"], note: "Markdown with tables, task lists, callouts and Mermaid charts, edited live with people." },
91 { id: "pdf", label: "Make PDFs", status: "ready", tools: ["make_file"], note: "From Markdown, attached to a doc. Latin script." },
92 { id: "docx", label: "Word documents", status: "ready", tools: ["make_file"], note: "A .docx from Markdown, attached to a doc." },
93 { id: "xlsx", label: "Spreadsheets", status: "ready", tools: ["make_file"], note: "An .xlsx with one or more sheets, or a .csv." },
94 { id: "slides", label: "Slide decks", status: "coming", tools: [], note: "Comes with slides in Artifacts. Until then, an outline as a doc or a PDF." },
95 ],
96 },
97 {
98 id: "research",
99 name: "Research",
100 description: "Reports with sources, from what the workspace knows; the open web is coming.",
101 category: "research",
102 source: "foundational",
103 version: V,
104 instructions: [
105 "When someone asks you to research something, find what is known before you write, and say where each fact comes from.",
106 "- Look in the workspace first: search_artifacts and read_artifact for specs, runbooks and decisions; search_code and read_file for how the code works; search_messages and read_thread for what was said.",
107 "- Report what you found, not what you expect: lead with the answer, then the evidence, and link every source (the artifact, file or thread). Say plainly what you couldn't find.",
108 "- A report worth keeping goes in a doc (create_artifact) with a Sources section at the end. Long research is a session's job (start_session).",
109 ].join("\n"),
110 abilities: [
111 { id: "cite", label: "Reports with sources", status: "ready", tools: ["search_artifacts", "read_artifact", "search_code", "read_file", "search_messages", "read_thread", "create_artifact"], note: "From the workspace's docs, code and chat, each source linked." },
112 { id: "search", label: "Search the web", status: "coming", tools: [], note: "Comes with web access, set per team." },
113 { id: "browse", label: "Browse and read pages", status: "coming", tools: [], note: "Comes with web access, set per team." },
114 ],
115 },
116 {
117 id: "data",
118 name: "Data",
119 description: "Analyze files and tables, chart the results and hand back a spreadsheet.",
120 category: "data",
121 source: "foundational",
122 version: V,
123 instructions: [
124 "When someone asks about data, work from the data itself and show your working.",
125 "- Read it where it lives: a CSV, JSON or log file in a repository (read_file), or a table in a doc (read_artifact). Data pasted into the conversation counts too.",
126 "- You add up and compare by reasoning, not by running code, so keep tables small enough to check: count rows, say what you totalled, and round sensibly. Above a few hundred rows, say the result is an estimate, or ask for a summary.",
127 "- Charts: put a Mermaid chart in a doc. Bar or line: ```mermaid with xychart, a title, x-axis [labels], y-axis \"Unit\", then bar [values] or line [values]. Shares of a whole: pie with \"Label\" : value lines. Label axes and units.",
128 "- A table they'll work on goes back as a spreadsheet: make_file with format xlsx (or csv), header row first, numbers as numbers.",
129 ].join("\n"),
130 abilities: [
131 { id: "analyze", label: "Analyze files and tables", status: "ready", tools: ["read_file", "read_artifact"], note: "CSV, JSON and logs in repositories, tables in docs. Worked by the model, not run as code." },
132 { id: "charts", label: "Charts in docs", status: "ready", tools: ["create_artifact", "edit_artifact"], note: "Bar, line and pie charts, drawn from Mermaid in a doc." },
133 { id: "export", label: "Spreadsheets of results", status: "ready", tools: ["make_file"], note: "An .xlsx or .csv attached to a doc." },
134 { id: "dashboards", label: "Dashboards", status: "coming", tools: [], note: "Comes with dashboards in Artifacts." },
135 { id: "sql", label: "Query databases and forks", status: "coming", tools: [], note: "Comes with workspace datasets and database connections." },
136 ],
137 },
138 {
139 id: "code",
140 name: "Code",
141 description: "Read and review code, and get changes made as pull requests through issues.",
142 category: "code",
143 source: "foundational",
144 version: V,
145 instructions: [
146 "When the work is code, read before you answer, and get changes made the way the team ships them.",
147 "- Find and read it: list_repositories, search_code, read_file; for history, recent_activity, get_issue and get_pull. Quote the lines you mean, with their path.",
148 "- Review on the pull request itself with review_pull (approve, request changes or comment), and leave findings with comment. Your review is advisory.",
149 "- To get a change made, draft an issue with draft_issue: what to change, why, where in the code, and how to tell it worked (the tests to add or run). Once it's filed, assigning it to @g1t makes the pull request on a runner, with checks and revisions.",
150 "- You don't run code yourself: never say you ran, built or tested something. Say what you'd run and why.",
151 ].join("\n"),
152 abilities: [
153 { id: "read", label: "Read and explain code", status: "ready", tools: ["list_repositories", "search_code", "read_file", "recent_activity"], note: "In repositories everyone in the conversation can read." },
154 { id: "review", label: "Review pull requests", status: "ready", tools: ["get_pull", "review_pull", "comment"], note: "Advisory: people still give the approvals a merge needs." },
155 { id: "pr", label: "Open pull requests", status: "ready", tools: ["draft_issue"], note: "Through an issue assigned to @g1t, which makes the pull request on a runner." },
156 { id: "run", label: "Run code on its runner", status: "coming", tools: [], note: "Comes with agents on runners." },
157 { id: "test", label: "Write and run tests itself", status: "coming", tools: [], note: "Comes with agents on runners; @g1t runs them on issues today." },
158 ],
159 },
160 {
161 id: "communication",
162 name: "Communication",
163 description: "Draft emails and messages, and summarize threads.",
164 category: "communication",
165 source: "foundational",
166 version: V,
167 instructions: [
168 "When someone asks you to write to people, or to catch them up, do it in their voice and keep it short.",
169 "- Drafts: write the email or message ready to send, with a subject line for an email, in a fenced block or a doc they can copy. You can't send email: say they send it.",
170 "- Summaries: read the thread first (read_thread, search_messages for related ones). Lead with what was decided and what is open, then who owns each next step, with links to the messages that matter.",
171 "- Status updates: from recent_activity, issues and pull requests, say what shipped, what is in progress and what is blocked.",
172 ].join("\n"),
173 abilities: [
174 { id: "draft", label: "Draft emails and messages", status: "ready", tools: [], note: "Written ready to send; sending email is coming." },
175 { id: "summarize", label: "Summarize threads", status: "ready", tools: ["search_messages", "read_thread"], note: "Decisions, open questions and owners, with links." },
176 { id: "schedule", label: "Find times and book meetings", status: "coming", tools: [], note: "Comes with calendar integrations." },
177 ],
178 },
179 {
180 id: "files",
181 name: "Files and media",
182 description: "Convert between formats, and draw diagrams.",
183 category: "files",
184 source: "foundational",
185 version: V,
186 instructions: [
187 "When someone needs a file in another form, make it.",
188 "- Text, Markdown and tables convert to PDF, Word, Excel, CSV or Markdown with make_file. To convert a file from a repository or a doc, read it (read_file, read_artifact) and pass its content on.",
189 "- Diagrams (flows, sequences, timelines, org charts) are Mermaid fences in a doc (create_artifact).",
190 "- You can't see images or read scans, and you can't draw or edit images yet. Say so, and offer what you can do from text.",
191 ].join("\n"),
192 abilities: [
193 { id: "convert", label: "Convert between formats", status: "ready", tools: ["make_file", "read_file", "read_artifact"], note: "Markdown, text and tables to PDF, Word, Excel, CSV or Markdown." },
194 { id: "diagrams", label: "Diagrams", status: "ready", tools: ["create_artifact"], note: "Flowcharts, sequences and timelines from Mermaid in a doc." },
195 { id: "ocr", label: "Read scans and images", status: "coming", tools: [], note: "Comes with image input for agents." },
196 { id: "images", label: "Create and edit images", status: "coming", tools: [], note: "Comes with image models." },
197 ],
198 },
199];
200
201/** The ids of the foundational skills. */
202export const FOUNDATIONAL_SKILL_IDS: readonly string[] = FOUNDATIONAL_SKILLS.map((skill) => skill.id);
203
204/** Every tool a skill's ready abilities use. */
205export function skillTools(skill: AgentSkill): string[] {
206 return [...new Set(skill.abilities.filter((ability) => ability.status === "ready").flatMap((ability) => ability.tools))];
207}
208
209/** Where skills come from, and which are here yet. */
210export const SKILL_SOURCES: { source: SkillSource; label: string; status: "live" | "coming"; description: string }[] = [
211 { source: "foundational", label: "Foundational, from g1t", status: "live", description: "Every agent starts with them, updated with every release." },
212 { source: "workspace", label: "Written in your workspace", status: "coming", description: "Your own playbooks, such as how you cut a release or your brand voice." },
213 { source: "marketplace", label: "From the Marketplace", status: "coming", description: "Skills published by g1t and others, added in one step." },
214 { source: "learned", label: "Learned from work", status: "coming", description: "Proposed by an agent from finished work, published after a person reviews it." },
215];
216
217/** The foundational skills an agent has on: every one unless `off` names it. */
218export function skillsOn(off: readonly string[] | null | undefined): AgentSkill[] {
219 const skip = new Set(off ?? []);
220 return FOUNDATIONAL_SKILLS.filter((skill) => !skip.has(skill.id));
221}