| 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 | |
| 21 | export 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. */ |
| 24 | export type SkillSource = "foundational" | "workspace" | "marketplace" | "learned"; |
| 25 | |
| 26 | /** One thing a skill does, and whether it works today. */ |
| 27 | export 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 | |
| 40 | export 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. */ |
| 60 | export const FOUNDATIONAL_SKILLS_VERSION = "2026.10"; |
| 61 | |
| 62 | /** The formats `make_file` writes. */ |
| 63 | export const MAKE_FILE_FORMATS = ["pdf", "docx", "xlsx", "csv", "md"] as const; |
| 64 | export type MakeFileFormat = (typeof MAKE_FILE_FORMATS)[number]; |
| 65 | |
| 66 | const 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 | */ |
| 73 | export 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. */ |
| 202 | export const FOUNDATIONAL_SKILL_IDS: readonly string[] = FOUNDATIONAL_SKILLS.map((skill) => skill.id); |
| 203 | |
| 204 | /** Every tool a skill's ready abilities use. */ |
| 205 | export 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. */ |
| 210 | export 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. */ |
| 218 | export 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 | } |