Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Contributors add user-facing entries under `[Unreleased]` in the same PR. Mainta
### Added

- **`finance/uk_companies_house_handler`**: New skill for UK Companies House REST API — deterministic company search, profile, officers, PSC, filing history, and intent-to-operation mapping with UK corporate terminology translation; bundled endpoint index and terminology map; status-based response envelope (ready/needs_input/error) with disambiguation support.
- **Documentation**: Add minimal Mermaid architecture flow diagrams to README, introduction, and agent loops; add cross-links and direct-path footnotes (#210).

### Changed

Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

<div align="center">
<a href="#mission">Mission</a> •
<a href="#how-it-works">How it works</a> •
<a href="#architecture">Architecture</a> •
<a href="#quick-start">Quick Start</a> •
<a href="#documentation">Documentation</a> •
Expand Down Expand Up @@ -48,6 +49,18 @@ A **Skill** in this framework provides everything an Agent needs to master a dom

Browse capabilities by category in the [Skill library](docs/skills/README.md) or on our <a href="https://skillware.site/skills" target="_blank" rel="noopener noreferrer">site&nbsp;↗</a>.

## How it works

```mermaid
flowchart LR
Registry[(Registry / Disk)] -->|Load| Skillware[Skillware Loader]
Skillware -->|Adapt| Host[Host App]
Host -->|Prompt + Tools| Model([AI Model])
Model -->|Tool Call| Host
```

Install the registry once. Skillware loads a bundle and adapts it to your model's tool format — you run the loop. For details on how the loader turns the manifest into a tool, see the [Introduction](docs/introduction.md).

## Architecture

This repository is organized into a core framework, a registry of skills, and
Expand Down
36 changes: 35 additions & 1 deletion docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,47 @@ Skillware/
└── loader.py # The engine that bridges the skill to the LLM
```

```mermaid
flowchart TD
subgraph Bundle["Skill Bundle Folder"]
Manifest[manifest.yaml]
Instructions[instructions.md]
SkillPy[skill.py]
CardJson["card.json (optional)"]
end

Loader[SkillLoader] -->|Loads| Bundle
Loader --> Adapters

subgraph Adapters["Model adapters"]
direction LR
G[Gemini]
C[Claude]
O[OpenAI]
OL[Ollama]
end

Host[Host App] -.->|Directly calls execute| SkillPy

style Host stroke-width:2px,stroke-dasharray: 5 5
```

A skill is a folder on disk. The loader turns the manifest into whatever tool schema your runtime expects. For the high-level picture, see [How it works](../README.md#how-it-works); for the code loop that hooks these adapters up, see [Agent Loops](usage/agent_loops.md).

When you run `SkillLoader.load_skill("category/skill_name")`, a complex orchestration happens behind the scenes:

### Step 1: Discovery & Loading
The loader resolves `category/skill_name` to a skill directory by checking, in order: an existing path on disk, roots in `SKILLWARE_SKILL_PATH`, a `skills/` folder in the current working directory (or its parents), then bundled skills installed with the package. Each bundle is a directory containing `manifest.yaml` and `skill.py`.
* It dynamically imports the `skill.py` module and auto-discovers the single `BaseSkill` subclass as `bundle["class"]` (no hardcoded class names required).
* It parses the `manifest.yaml` (including `issuer` for attribution, separate from tool-calling fields). Registry skills set `name` to the full ID (`category/skill_name`), which Gemini and Claude use as the tool name; OpenAI and DeepSeek receive a sanitized variant (slashes → underscores). For registry-layout paths (`<skill_root>/<category>/<skill_name>/`), the loader warns when `name` does not match the folder path; flat private layouts (`<skill_root>/<skill_name>/`) skip this check. Loaded bundles expose `registry_id` when validation applies.
* It reads `instructions.md` and `card.json`.
* It reads `instructions.md` and, when present, optional `card.json`.

```mermaid
flowchart LR
ID[category/name] --> FIND[resolve]
FIND --> PACK[bundle]
PACK --> ADAPT[adapt]
```

For how skills are resolved on disk, the provenance tiers, and what to check before loading skills you did not write, see [Skill trust model & operator security](security/skill-trust-model.md).

Expand Down
40 changes: 40 additions & 0 deletions docs/usage/agent_loops.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,52 @@

Every integration follows the same execution pattern:

```mermaid
flowchart TD
subgraph Skillware
Load((1. Load)) --> Adapt((2. Wire / Adapt))
end

subgraph Model
Prompt((3. Prompt))
Return((5. Return))
end

subgraph Host ["Host App"]
Execute((4. Execute))
end

Adapt -->|Inject tools/instructions| Prompt
Prompt -->|Tool call request| Execute
Execute -->|Tool result JSON| Return
Return -->|Loop next iteration| Prompt
```

Your loop always looks like this. Skillware handles load and tool translation; you call execute and pass JSON back. To see what files a skill contains, see the [Introduction](../introduction.md).

1. `bundle = SkillLoader.load_skill("<category>/<skill_name>")`
2. `skill = bundle["class"]()` — or `SkillLoader.get_skill_class(bundle)()`; `bundle["module"]` remains available for backward compatibility.
3. Adapt `bundle` for the model (`to_gemini_tool`, `to_claude_tool`, etc.).
4. Pass `bundle["instructions"]` as system context.
5. On tool call, `result = skill.execute(arguments)` and return JSON to the model.

| Step | Call |
| :--- | :--- |
| **load** | `SkillLoader.load_skill(id)` |
| **wire** | `to_*_tool(bundle)` + `bundle["instructions"]` &rarr; model |
| **prompt** | User query &rarr; model |
| **execute** | `bundle["class"]().execute(args)` |
| **return** | Tool result &rarr; model |

### Direct path (no model)

You can also run skills directly without an LLM or agent loop (e.g., `examples/token_limiter_loop.py`): load the skill, call `execute(args)` directly, and process the returned JSON.

```mermaid
flowchart LR
Load((1. Load)) --> Execute((2. Execute)) --> JSON((3. JSON))
```

Provider guides contain full API details. Skill pages contain copy-paste examples with skill-specific paths and sample user messages.

---
Expand Down
Loading