Skill Invocation

Run agent skills via /slash commands, $ARGUMENTS substitution, and inline shell

Skills can be invoked three ways: auto-triggered by the LLM from the system-prompt listing, manually via /skill-name slash commands (browse them by typing / at the praisonai code prompt), or programmatically through SkillManager.invoke().

python
from praisonaiagents import Agent

agent = Agent(
    name="assistant",
    skills=["./skills/deploy"],
)
agent.start("/deploy staging prod")

The user sends a slash command or normal prompt; the agent routes to skill invoke or LLM handling.

Diagram

Skill Invocation

/skill args

normal prompt

👤 User

Route

🔧 invoke

🤖 LLM

📤 Response

Quick Start

  1. Slash command
    python
    from praisonaiagents import Agent
    
    agent = Agent(
        name="assistant",
        skills=["./skills/deploy"],
    )
    agent.start("/deploy staging prod")
    # Renders the skill body with $ARGUMENTS substituted, then continues the turn
  2. Auto-trigger
    python
    from praisonaiagents import Agent
    
    agent = Agent(
        name="assistant",
        skills=["./skills/csv-summary"],
    )
    agent.start("Summarise this CSV for me")
    # LLM sees skill descriptions in the system prompt and activates the matching skill

How It Works

Diagram
Agent LLMSkillManagerSlash RouterUserAgent LLMSkillManagerSlash RouterUseralt[Starts with /][Normal prompt]“/deploy staging” or normal promptinvoke(name, args)rendered body ($ARGUMENTS substituted)prompt (skills listed in system prompt)Response
ModeWhen to use
Auto-triggerSkill description is in the system prompt; the LLM decides when to follow it
Slash commandUser types /deploy staging; body is rendered with $ARGUMENTS substituted

Discover skills in the interactive menu

Inside praisonai code (the REPL and the async TUI), type / at the prompt to see every installed skill listed alongside built-ins and your custom .praisonai/commands/*.md files. Each entry uses the skill’s description from SKILL.md frontmatter, so a well-written description doubles as menu help. Editing a SKILL.md body or adding a new skill under any discovered skill root takes effect on the next prompt in praisonai code — the registry re-scans when the definition roots change.

text
> /
  /help
  /clear
  /deploy               Deploy the current branch
  /pr-summary           Summarise a pull request
  /csv-summary          Summarise a CSV file

> /deploy staging prod

Pressing Enter on /deploy staging prod runs the same code path as agent.skill_manager.invoke("deploy", raw_args="staging prod") — the SKILL.md body is rendered with $ARGUMENTS substituted and passed as the next turn’s prompt.


Argument Substitution

Inside SKILL.md bodies you can reference arguments passed after the skill name:

$ARGUMENTS

markdown
Deploy $ARGUMENTS now.

/deploy staging prod becomes Deploy staging prod now.

Indexed

markdown
Migrate $ARGUMENTS[0] from $ARGUMENTS[1] to $ARGUMENTS[2].

/migrate SearchBar React Vue expands each positional argument.

Shorthand

markdown
Hello $0, meet $1.

$N is shorthand for $ARGUMENTS[N]. Quotes group tokens: /greet "hello world" friend sets $0 = "hello world".

Context vars

markdown
Working inside ${PRAISON_SKILL_DIR}. Session ${PRAISON_SESSION_ID}.

${CLAUDE_SKILL_DIR} / ${CLAUDE_SESSION_ID} are supported as aliases so existing Claude Code skills work unchanged.


Inline Shell Substitution

python
from praisonaiagents import SkillManager

mgr = SkillManager()
mgr.add_skill("./skills/pr-summary")
rendered = mgr.invoke("pr-summary", raw_args="42", shell_exec=True)
Inline backtick form
markdown
Current branch: !`git rev-parse --abbrev-ref HEAD`
Fenced block form
markdown
```!
node --version
npm --version
```

Invocation Policy

disable-model-invocation boolean

When true the skill is hidden from the system-prompt listing, so the LLM cannot auto-trigger it. Users can still invoke it via /skill-name. Use for side-effecting commands like /deploy.

user-invocable boolean

When false, the skill is hidden from the interactive / menu in praisonai code (REPL and async TUI) and from praisonai "/name" --skills …. It stays in the system-prompt listing so the LLM can still auto-trigger it. Use for background knowledge or model-only helpers that should never surface as a user command.

Where each skill shows up

Two independent flags decide where a skill appears — one axis for the LLM, one for the user.

SKILL.md frontmatterSystem-prompt listing (LLM auto-triggers)Interactive / menu (user runs)
default (both flags omitted)✅✅
disable-model-invocation: true❌✅
user-invocable: false✅❌
disable-model-invocation: true + user-invocable: false❌❌ (never triggered — usually a mistake)

The interactive / menu is the completion list you see when you type / inside praisonai code (REPL or async TUI). “Absent from the / menu” means both completion and dispatch — typing the name falls through to “Unknown command”.

Diagram

🧩 Installed skill

false

true

true

false

disable-model-invocation
(default: false)

user-invocable
(default: true)

🤖 System-prompt listing
LLM can auto-trigger

🚫 Hidden from LLM

⚡ Interactive Unsupported markdown: codespan menu
User can run

🚫 Hidden from Unsupported markdown: codespan menu

A /deploy skill (both flags default) and a model-only pricing-lookup skill (user-invocable: false) live side by side. Type / in praisonai code and only one shows:

text
> /
/deploy        Deploy to an environment
# pricing-lookup is absent — the LLM still reads it from the system prompt,
# but typing /pricing-lookup falls through to "Unknown command".

Flip the flag back off and the same list gains the model-only skill:

text
> /            # with user-invocable omitted on pricing-lookup
/deploy          Deploy to an environment
/pricing-lookup  Look up current pricing

Allowed Tools Pre-approval

allowed-tools string | list[str]

Space-separated string (Read Grep) or YAML list. When a user invokes the skill, those tool names are pre-approved via the approval registry for the current agent so the LLM can run them without the interactive confirmation prompt.


Common Patterns

Programmatic invoke

python
from praisonaiagents import Agent

agent = Agent(name="assistant", skills=["./skills/deploy"])
rendered = agent.skill_manager.invoke("deploy", raw_args="staging prod")

YAML

yaml
# agents.yaml
agents:
  assistant:
    role: Helper
    goal: Help the user
    backstory: You are helpful.
    skills:
      - ./skills/deploy
      - ~/.praisonai/skills/csv-summary

CLI

List installed
praisonai skills list
Invoke from CLI
praisonai "/deploy staging" --skills ./skills/deploy
Install
# Either verb works — pick whichever reads more naturally.
praisonai skills add https://github.com/acme/my-skill
praisonai skills install ./local-skill --dest ~/.praisonai/skills
Sync remote
praisonai skills sync https://github.com/acme/skills-repo
praisonai skills sync                       # uses skills.urls from config

Precedence

Skills are discovered in this order (first wins on name collision):

  1. Project

    ./.praisonai/skills/ or ./.claude/skills/

  2. Ancestors

    Every .praisonai/skills or .claude/skills in a parent directory (monorepo support)

  3. User

    ~/.praisonai/skills/

  4. Remote cache

    ~/.praisonai/cache/remote-skills/<source>/current/ — populated by praisonai skills sync (see Remote Skill Sources)

  5. System

    /etc/praison/skills/


Best Practices

Use slash commands for side effects

Set disable-model-invocation: true on deploy, restart, or delete skills so the LLM cannot trigger them accidentally — users invoke them explicitly with /skill-name.

Keep user-invocable false for background knowledge

Set user-invocable: false when a skill should only auto-activate from the system prompt. It stays available to the LLM but never appears in the / menu inside praisonai code, so users cannot run it by mistake.

Opt in to shell blocks deliberately

Leave shell_exec=False (default) in production. Pass shell_exec=True only in trusted environments where inline `!cmd ` blocks are required.

Validate encoding before deploy

Save SKILL.md as UTF-8. Run praisonai skills validate --path ./my-skill to catch Windows encoding issues early.


Related