Skip to main content

Skills

What skills are

A skill is a saved, replayable artifact that AI Partner can reuse without re-reasoning from scratch. When a goal matches a skill, the executor runs the stored sequence directly — skipping the LLM reasoning step entirely.

Why it matters: the first time you ask for something, the agent takes 30–90 seconds to reason, plan, and execute. The second time, it runs 3–5× faster.

Two kinds (one library, one UI)

KindWhat it isWhere it's capturedUI
Code skillsParameterized Python / Node scripts with {{PLACEHOLDER}} substitutions. Reused for repeatable script work (stock fetches, CSV transforms, document generation).SkillLearner after a successful goal that ran a scriptSettings → Learned Skills (top section)
Browser interaction skillsRecorded CDP action sequences (navigate / fill / click / extract) with {{PLACEHOLDER}} substitutions. Reused for repeatable browser work (directory submissions, form fills, login flows).T3SkillRecorder after a successful partner-mode goal that used browser toolsSettings → Learned Skills (Browser Interaction Skills section)

Both kinds appear in the same Learned Skills sidebar item (GraduationCap icon). They share the same matching mechanism (hybrid semantic + keyword), the same versioning, the same success/failure tracking. The only difference is the artifact format and where they capture from.

Storage:

  • Code skills: learned_skills SQLite table + workspace/skills/learned/*.py|*.js files (the file copy is for human-inspection and version control — you can browse / edit / version-control these as plain files)
  • Browser interaction skills: t3_browser_skills SQLite table only (no file copy — the action sequence isn't meaningful as a flat file)

API:

  • GET /api/skills/learned — code skills
  • GET /api/skills/browser — browser interaction skills
  • DELETE /api/skills/learned/:name and DELETE /api/skills/browser/:id — remove a skill

Auto-learned skills

After every successful goal, the executor runs SkillLearner:

  1. Examines the successful script
  2. Extracts parameterizable variables (TICKER, COMPANY, FILENAME, etc.) and replaces them with {{PLACEHOLDER}} syntax
  3. Computes an embedding of the skill's description
  4. Checks for near-duplicates in the skill library (cosine similarity > 0.9)
  5. If no duplicate: saves as a new skill
  6. If a better version: saves as v2 and marks the old one superseded

Example — auto-learned skill:

After running "Get the current price of RELIANCE.NS from Yahoo Finance", the skill saved looks like:

# Skill: fetch_stock_price (v1)
# Keywords: stock price, Yahoo Finance, NSE, ticker
import yfinance as yf
import os

ticker = os.environ.get('TICKER', '{{TICKER}}')
stock = yf.Ticker(ticker)
info = stock.fast_info
print(f"{ticker}: ₹{info.last_price:.2f} ({info.day_change_percent:+.1f}%)")

Next time you ask "What's the HDFC Bank share price?", the executor:

  1. Detects keyword match: "share price" → fetch_stock_price
  2. Checks embedding similarity: 0.91 (above 0.75 threshold)
  3. Runs the skill with TICKER=HDFCBANK.NS
  4. Returns the result in ~3 seconds

Browsing the skill library

Go to sidebar → Learned Skills:

┌──────────────────────────────────────────────────────────────────┐
│ Learned Skills [+ New] │
├──────────────────────────────────────────────────────────────────┤
│ fetch_stock_price Python v2 ⭐ 19/20 auto [View] [Test] │
│ github_trending Python v1 ⭐ 8/10 auto [View] [Test] │
│ competitor_research Python v2 ⭐ 5/6 auto [View] [Test] │
│ weekly_news_digest Python v1 ⭐ 3/4 auto [View] [Test] │
│ daily_portfolio_check Python v1 ⭐ 0/0 manual [View] [Test] │
└──────────────────────────────────────────────────────────────────┘

Click View to see the stored script template, keywords, version history, and match statistics.

Click Test to run the skill immediately with test parameters.


Writing a manual skill

You don't have to wait for a goal to succeed. Write a skill in advance and it's available immediately.

Go to Learned Skills → + New Skill.

The modal has a Generate with AI panel (Wand icon, expands at the top of the form). Enter a description of what the skill should do — at least 10 characters — choose Python or Node.js, and click Suggest:

Description: Fetch the current stock price of any NSE ticker using yfinance
Runtime: Python

The AI returns a pre-filled draft: name, keywords, strategy hint, and a complete script template with {{PLACEHOLDERS}}. Review and edit before saving — nothing is saved until you click Save.

The generator runs a security scan on the draft before returning it. If the model produces code that matches a restricted pattern, the request is rejected with a reason message — rephrase and try again.

Manual authoring

  1. 1
    Fill in the skill metadata
    Name: daily_portfolio_check
    Keywords: portfolio, my stocks, stock prices, watchlist, check holdings
    Runtime: Python (or Node.js)
    Tags: finance, stocks, daily

    Keywords are what the executor matches against incoming goals. Be specific — "check stocks" is too broad; "check my portfolio stocks" matches more precisely.

  2. 2
    Write the strategy hint (important)

    The Strategy Hint is 2–3 plain-English sentences describing the approach — what library to use, what sequence to follow, any key gotchas. This is NOT code. It's injected into the agent's context at iteration 1 when the skill is matched, so the agent starts knowing the plan instead of figuring it out from scratch.

    Use yfinance to fetch ticker data. Always use the .fast_info property for
    speed — it avoids a full .info call. Handle TickerNotFound exceptions
    per ticker so one bad symbol doesn't abort the whole list.

    A skill without a strategy hint still works, but the agent starts cold and may take an extra iteration to pick the right approach.

  3. 3
    Write the script template

    Use {{PLACEHOLDER}} for any variable that should be substituted from the goal:

    import yfinance as yf
    import os

    # TICKERS can be overridden by the goal; defaults to a sensible list
    tickers = os.environ.get('TICKERS', 'RELIANCE.NS,INFY.NS,TCS.NS,HDFC.NS').split(',')

    print("📈 Portfolio Check\n")
    for ticker in tickers:
    try:
    stock = yf.Ticker(ticker)
    info = stock.fast_info
    emoji = "🟢" if info.day_change_percent >= 0 else "🔴"
    print(f"{emoji} {ticker}: ₹{info.last_price:.2f} ({info.day_change_percent:+.1f}%)")
    except Exception as e:
    print(f"⚠️ {ticker}: error ({e})")

    The script is scanned for restricted patterns (shell injection, network backdoors, filesystem escapes) before saving. Scripts that fail the scan are rejected with a reason.

  4. 4
    Save and test

    Click Save. The skill is immediately active — the next goal that matches the keywords will use it.

    Click Test to run it right now and verify the output.


Skill promotion to MCP tools

A skill that proves itself gets promoted to a first-class MCP tool:

  • Threshold: ≥5 successful uses AND ≥80% success rate
  • Effect: the skill becomes callable as a tool in any ReAct reasoning step — not just matched from the keyword library
✅ Skill "fetch_stock_price" promoted to MCP tool
Available as: fetch_stock_price
Visible in: Tool Marketplace → Learned Skills category

Promoted skills appear in the Tool Marketplace and can be called by any agent profile that has them in its tool whitelist.


Skill versioning

When the agent generates a solution that outperforms the existing skill, it saves a new version:

fetch_stock_price v1: 6 successes, 60% rate — superseded
fetch_stock_price v2: 19 successes, 95% rate — current ✓

Versions are never deleted — you can view the history and manually roll back if needed.


The matching pipeline

When a goal arrives, the executor runs this check before generating anything:

Goal: "What's the HDFC share price today?"

1. Keyword scan
Goal tokens: ["HDFC", "share", "price", "today"]
Skill keywords: ["stock price", "Yahoo Finance", "ticker"]
Overlap score: 0.72

2. Embedding similarity
embed("HDFC share price today") vs embed("fetch_stock_price description")
Cosine similarity: 0.91

3. Combined score: 0.87 → above threshold (0.75)
→ Match: "fetch_stock_price" (v2)
→ Run stored script with TICKER=HDFCBANK.NS

If the combined score is below threshold, no match. The full ReAct loop runs, generates a solution, and — if it succeeds — that solution potentially becomes a new skill.


Sharing skills with the org (multi-user)

On multi-user deployments, skills are private by default — your learned skills are recalled only for your goals. To make a skill available to every member:

  1. Click the Share icon on the skill in Learned Skills → it gets a pending review badge.
  2. An admin reviews the full template in Admin Console → Skill Governance. Approval re-runs the code security scan — a template with restricted patterns is auto-rejected.
  3. Once approved, the skill shows an org badge and is recalled for every member's matching goals (alongside their own private skills).
  4. A rejected request shows a share rejected badge with the admin's reason on hover.

The flow is deliberately two-sided: nothing is shared without both the owner's request and an admin's approval. Admins can later deprecate an org skill, reverting it to the owner's private library. System seed skills (shipped with AI Partner) remain visible to everyone as before.

POST /api/skills/learned/:id/share # member: request org sharing
GET /api/admin/skills/pending # admin: review queue
POST /api/admin/skills/:id/approve|reject|deprecate

Tips for writing effective skills

Be specific with keywords

Avoid single-word keywords like "stocks" or "email". Use 2–4 word phrases that describe the exact task: "fetch stock price", "check gmail inbox", "create excel report".

Use environment variables for parameters

Put all variable values in os.environ.get('PARAM', 'default'). The executor automatically maps goal entities (ticker names, company names, file paths) to env vars.

Handle errors gracefully

Wrap each operation in try/except and print a meaningful error. The self-corrector can fix code errors, but unhandled exceptions with no output are harder to debug.

Print your output

The executor reads the script's stdout as the result. Always print the output you want the agent to see — don't just compute silently.