From 9f5636024de8647ccfb2f783605335eecee7cb32 Mon Sep 17 00:00:00 2001 From: Meghana Pinikeshi Date: Tue, 7 Jul 2026 20:54:35 +0530 Subject: [PATCH 1/3] docs: add minimal architecture flow diagrams to README, introduction, and agent loops (#210) --- CHANGELOG.md | 4 ++++ README.md | 13 +++++++++++++ docs/introduction.md | 17 +++++++++++++++++ docs/usage/agent_loops.md | 21 +++++++++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0845bd1..596b914 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ Contributors add user-facing entries under `[Unreleased]` in the same PR. Mainta ## [Unreleased] +### Added + +- **Documentation**: Add minimal Mermaid architecture flow diagrams to README, introduction, and agent loops; add cross-links and direct-path footnotes (#210). + ### Changed - **Loader**: `SkillLoader.load_skill()` auto-discovers the single `BaseSkill` subclass in each `skill.py` and exposes it as `bundle["class"]`; `get_skill_class()` helper added. Existing `bundle["module"]` usage is unchanged (#89). diff --git a/README.md b/README.md index 236ab6e..84cccaa 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@
Mission • + How it worksArchitectureQuick StartDocumentation • @@ -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 site ↗. +## 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 diff --git a/docs/introduction.md b/docs/introduction.md index bef51dd..432748d 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -49,6 +49,23 @@ 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] + end + + Loader[SkillLoader] -->|Loads| Bundle + Loader -->|Adapts manifest| Adapters[Model Tool Schemas] + 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 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 diff --git a/docs/usage/agent_loops.md b/docs/usage/agent_loops.md index 5fb5f5f..aca4685 100644 --- a/docs/usage/agent_loops.md +++ b/docs/usage/agent_loops.md @@ -2,12 +2,33 @@ Every integration follows the same execution pattern: +```mermaid +flowchart TD + subgraph HostLoop ["Host-Centric Loop"] + direction TB + Load((1. Load)) --> Wire((2. Wire)) --> Prompt((3. Prompt)) + Prompt --> Execute((4. Execute)) --> Return((5. Return)) --> Prompt + end +``` + +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("/")` 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"]` → model | +| **prompt** | User query → model | +| **execute** | `SkillClass().execute(args)` | +| **return** | Tool result → 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. + Provider guides contain full API details. Skill pages contain copy-paste examples with skill-specific paths and sample user messages. --- From f018a9f90a368c6396fa321a88a539fc8abb9e7a Mon Sep 17 00:00:00 2001 From: Meghana Pinikeshi Date: Wed, 8 Jul 2026 13:51:53 +0530 Subject: [PATCH 2/3] docs: address review feedback on agent loop diagrams and step execution syntax --- docs/introduction.md | 1 + docs/usage/agent_loops.md | 27 ++++++++++++++++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/docs/introduction.md b/docs/introduction.md index 432748d..6246647 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -55,6 +55,7 @@ flowchart TD Manifest[manifest.yaml] Instructions[instructions.md] SkillPy[skill.py] + CardJson[card.json] end Loader[SkillLoader] -->|Loads| Bundle diff --git a/docs/usage/agent_loops.md b/docs/usage/agent_loops.md index aca4685..e07290f 100644 --- a/docs/usage/agent_loops.md +++ b/docs/usage/agent_loops.md @@ -4,11 +4,23 @@ Every integration follows the same execution pattern: ```mermaid flowchart TD - subgraph HostLoop ["Host-Centric Loop"] - direction TB - Load((1. Load)) --> Wire((2. Wire)) --> Prompt((3. Prompt)) - Prompt --> Execute((4. Execute)) --> Return((5. Return)) --> Prompt + 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). @@ -24,10 +36,15 @@ Your loop always looks like this. Skillware handles load and tool translation; y | **load** | `SkillLoader.load_skill(id)` | | **wire** | `to_*_tool(bundle)` + `bundle["instructions"]` → model | | **prompt** | User query → model | -| **execute** | `SkillClass().execute(args)` | +| **execute** | `bundle["class"]().execute(args)` | | **return** | Tool result → 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. From ba631a79f39257f6a893ba5afacf9d2afe7d7641 Mon Sep 17 00:00:00 2001 From: rosspeili Date: Wed, 8 Jul 2026 11:48:48 +0300 Subject: [PATCH 3/3] docs: polish #210 diagrams (maintainer follow-up on #217) Label optional card.json, add Step 1 mini-pipeline, fan out model adapters, move direct-path Mermaid out of blockquote, and cross-link README How it works. --- docs/introduction.md | 24 ++++++++++++++++++++---- docs/usage/agent_loops.md | 14 ++++++++------ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/docs/introduction.md b/docs/introduction.md index 80eec54..07d5a66 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -55,17 +55,26 @@ flowchart TD Manifest[manifest.yaml] Instructions[instructions.md] SkillPy[skill.py] - CardJson[card.json] + CardJson["card.json (optional)"] end Loader[SkillLoader] -->|Loads| Bundle - Loader -->|Adapts manifest| Adapters[Model Tool Schemas] + 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 code loop that hooks these adapters up, see [Agent Loops](usage/agent_loops.md). +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: @@ -73,7 +82,14 @@ When you run `SkillLoader.load_skill("category/skill_name")`, a complex orchestr 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 (`///`), the loader warns when `name` does not match the folder path; flat private layouts (`//`) 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). diff --git a/docs/usage/agent_loops.md b/docs/usage/agent_loops.md index db03b37..d987ceb 100644 --- a/docs/usage/agent_loops.md +++ b/docs/usage/agent_loops.md @@ -39,12 +39,14 @@ Your loop always looks like this. Skillware handles load and tool translation; y | **execute** | `bundle["class"]().execute(args)` | | **return** | Tool result → 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)) -> ``` +### 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.