Skip to content
Yash Aryan edited this page Aug 8, 2026 · 1 revision

Skills

A skill is a unit the user can enable: system-prompt instructions plus a set of tools. Skills only apply when the chat Tools toggle is on (or project default tools / overrides say so).

Mental model

Kind Where it lives Needs code?
Custom skill UI → userData/anylm-skills.json No
Builtin non-connector app/src/main/skills/builtins.ts Yes
Builtin connector builtins.ts + OAuth connector API Yes

Builtin skills are off by default until the user enables them. Tools referenced by an enabled skill can run even if those tools are globally disabled (customToolNames allowlist).

Key files

File Role
app/src/main/skills/builtins.ts Builtin definitions
app/src/main/skills/registry.ts Persist, list, toggle, instructionsBlock, ollamaTools
app/src/main/skills/exec.ts Connector tool execution (owns + token + run)
app/src/main/api/connectors.ts OAuth connect / token / disconnect
app/src/renderer/js/skills-view.ts Skills UI
app/src/types/domain.d.ts SkillDefinition, ConnectorStatus
preload.ts / api.d.ts skillsList/Save/Delete/Toggle/Connectors/Connect/Disconnect

Runtime path in chat

  1. Assemble skillsRegistry.instructionsBlock(skillOverrides) into the system prompt.
  2. Merge tool schemas: registry tools + skillsRegistry.ollamaTools(skillOverrides).
  3. On tool_call: if skillsExec.owns(name) → connector exec; else → tools/exec.

Current builtins

Web research (web-research)

  • No OAuth (connector omitted).
  • toolNames: ["web_search", "http_fetch"].
  • Instructions push the model to actually call tools for live URLs / current facts and to honor “go ahead / fetch it” follow-ups.

Google Calendar (google-calendar)

  • Connector id google-calendar.
  • Tools: gcal_list_events, gcal_create_event (writes are risky).
  • Product note: Google’s token endpoint requires a client secret even for PKCE desktop apps, so this connector is disabled in production docs. Code remains for reference / future server-backed flow.

Outlook (outlook)

  • Connector id outlook.
  • Tools: list/create events, list/send mail (writes risky).
  • Uses public client + PKCE (ANYLM_MS_CLIENT_ID in app/.env).

How to create a custom skill (no code)

  1. Create any custom tools you need in the Tools view (see Tools).
  2. Skills → New skill.
  3. Fill name, description, instructions (written to the model: when to use which tool, confirmations, constraints).
  4. Check the tools to attach.
  5. Enable the skill.
  6. In chat, turn Tools on and ask something that matches the instructions.

Instruction writing tips

  • Imperative and specific (“When the user asks for X, call tool_y with …”).
  • Say what not to invent (especially for HTTP/search).
  • Mention confirmation language if your skill proposes then executes.
  • Keep tools narrow; don’t rely on run_shell if a dedicated tool exists.

How to add a builtin non-connector skill

  1. Open app/src/main/skills/builtins.ts.
  2. Define an object:
const mySkill = {
  id: "my-skill",
  name: "My skill",
  builtin: true,
  description: "One line for the UI.",
  instructions:
    "You can … with tool_a and tool_b. When … call tool_a. Never invent …",
  tools: [] as [],
  toolNames: ["web_search", "http_fetch"], // names from tools/registry
};
  1. Append to BUILTIN_SKILLS export array.
  2. Restart the app. User must enable the skill + Tools toggle.

How to add a builtin connector skill

  1. Provider — add/adjust provider config used by api/connectors (scopes, auth URL, client id env, PKCE params). Study Outlook as the working public-client example. Prefer providers that support true public clients.
  2. Skill object in builtins.ts with connector: "<provider-id>" and tools: BuiltinTool[] where each tool has:
{
  name: "provider_action",
  description: "When to use…",
  risky: true, // for writes / side effects
  params: [{ name, description, required }],
  run: async (args, bearer) => {
    // fetch provider API with Authorization: Bearer ${bearer}
    // return a string (clip ~20k); prefix failures with "Error: "
  },
}
  1. Restart → Skills → ConnectEnable → chat Tools on.
  2. Tokens never enter the renderer; main process fetches /connectors/:provider/token.

Security checklist

  • Minimal OAuth scopes.
  • Mark mutating tools risky: true (user confirm).
  • Double opt-in: connect account + enable skill + tools on for the turn.
  • Clip large API payloads before returning to the model.

IPC surface

Method Purpose
skillsList Builtin + custom with enabled state
skillsSave / skillsDelete / skillsToggle Custom CRUD / enable
skillsConnectors Connection status per provider
skillsConnect / skillsDisconnect Start OAuth / revoke

Testing

  • Unit tests under app/src/main/skills/ and renderer skill-chip tests.
  • Manual: enable skill, send a prompt that must call a tool, confirm risky prompts, verify disconnect.

Stale comments to ignore

Some comments still say “Cloud Functions connectors.” Live path is in-process api/connectors + Firestore connectors collection. PDF skill guide may still describe NestJS — follow this wiki + TS sources.

Clone this wiki locally