Skip to content

Latest commit

 

History

History
181 lines (137 loc) · 13 KB

File metadata and controls

181 lines (137 loc) · 13 KB

Agent loops with Skillware

Every integration follows the same execution pattern. Skillware loads the bundle and adapts it to your runtime's tool format; your host app calls execute() and passes JSON back to the model. The diagram below is the loop you implement in code — for bundle contents, see the Introduction. Vocabulary: glossary.

Multiple skills: use SkillContext for registry brief + tools, or skill chaining for deterministic middleware chains. Single-skill loops below are unchanged.

flowchart LR
    Load[load] --> Wire[wire]
    Wire --> Prompt[prompt]
    Prompt --> Execute[execute]
    Execute --> Return[return]
    Return --> Prompt
Loading
Role Steps
Skillware load, wire
Model prompt, return
Host execute
  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, optionally validate arguments with skill.validate_params(arguments) against manifest parameters JSON Schema (recommended before execute() in production agent loops), then 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 Optional: skill.validate_params(args); then 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. validate_params() is optional — direct scripts and many examples skip it; skills may still validate or error inside execute().

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

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

OpenAI-compatible hosts reuse to_openai_tool(); see the host guide and runnable Groq example.

Enterprise cloud (Bedrock Converse, Azure OpenAI, Vertex AI) uses the same loop with existing adapters — see enterprise_cloud.md. Runnable Bedrock example: bedrock_tos_evaluator.py.

Optional param validation: Some agent-loop examples (e.g. claude_wallet_check.py, gemini_tos_evaluator.py) call skill.validate_params(...) before execute(); others call execute() directly.

Multi-turn tool loops

After you return a tool result to the model, call the model again without a new user message when it may chain another tool call or write its answer. Only append a user turn when you need input from the person (disambiguation, missing parameters, confirmation).

Repeat until the model stops with natural-language text (not tool_use / function calls). If the skill returns needs_input, show the user the candidates or agent_hint, then continue. Skill-specific playbooks (status envelopes, pipelines, rate limits) live on each catalog page and in bundle["instructions"] — not in this guide.


Multi-skill sessions (SkillContext)

For the choice between full Directives, brief registry lines, and host-managed progressive loading, see Choose host context (Directive vs brief). SkillContext.execute() validates skill parameters; prepare() returns the Directive to the host but does not inject it into the model context.

For agents that expose many tools from the registry, replace steps 1–4 with SkillContext:

from skillware import SkillContext

ctx = SkillContext()  # or categories=, skills=, roots= — see skill_chaining.md
system = ctx.merge_system(host_system_prompt)
tools = ctx.tools("gemini")  # or claude | openai | deepseek | bedrock

# Send system + tools + user message to the model ...
# On tool_call:

result = ctx.execute(skill_id, arguments)  # auto-prepares and validates parameters
# Return result JSON to the model; loop continues
Single-skill loop Multi-skill (SkillContext)
SkillLoader.load_skill(id) SkillContext(...) discovers many IDs
to_*_tool(bundle) once ctx.tools(provider) — list of tools
bundle["instructions"] in system ctx.merge_system() — brief, directives, or empty (tools_only)
New instance per call (typical) Reused instances on one ctx

Progressive disclosure: call ctx.prepare(skill_id) when the model selects a tool if you need the full Directive in context before filling parameters. See Skill chaining — progressive disclosure.

Ollama prompt mode: use ctx.ollama_prompt instead of per-skill to_ollama_prompt() when wiring multiple skills (ollama.md).

Deterministic middleware (firewall → rewriter, scan → token gate): use a manual Python chain or a named YAML chain — the model does not pick step order in those tiers.

Hybrid: run run_chain("sanitize_input", ...) on untrusted input, then start the agent loop with sanitized text and a filtered SkillContext(categories=[...]).

Framework multi-skill examples

Pattern Script
SkillContext + optional Gemini loop skill_context_gemini_loop.py
Named chain (run_chain, local) sanitize_input_chain_demo.py
SkillContext + Ollama prompt mode ollama_skills_test.py

Tool name matching

Adapter Match tool calls using
Gemini SkillLoader._sanitize_gemini_tool_name(bundle["manifest"]["name"]) (e.g. compliance_tos_evaluator)
Claude to_claude_tool(bundle)["name"] (sanitized, e.g. compliance_tos_evaluator)
OpenAI to_openai_tool(bundle)["function"]["name"] (sanitized, e.g. compliance_tos_evaluator)
DeepSeek to_deepseek_tool(bundle)["function"]["name"] (same sanitization rules)
Bedrock Converse to_bedrock_tool(bundle)["toolSpec"]["name"] (same sanitization rules)
Ollama (prompt) "tool" field in the JSON block the model emits (same as manifest["name"] when the manifest uses the full registry ID)

Registry manifest names: Every bundled skill uses manifest["name"] = category/skill_name (for example office/pdf_form_filler, defi/evm_tx_handler). Match tool calls with sanitized adapter names on Gemini, Claude, OpenAI, DeepSeek, and Bedrock Converse (office_pdf_form_filler, optimization_prompt_rewriter), or compare against SkillLoader.to_*_tool(bundle) output rather than hardcoding. Do not hardcode legacy short names in examples. SkillLoader.load_skill() warns when name diverges from the folder path for registry-layout skills; use bundle.get("registry_id") for the path-derived ID when present.

Minimal execute (no LLM)

from skillware.core.loader import SkillLoader

bundle = SkillLoader.load_skill("compliance/tos_evaluator")
result = bundle["class"]().execute(
    {
        "target_url": "https://example.com",
        "intended_action": "crawl documentation for research",
    }
)
print(result)

Reference scripts

Full runnable loops live under examples/ where listed. See the examples index for script filenames, skill IDs, per-skill pip extras, SDK extras, and required environment variables. Install each skill with pip install "skillware[<category>_<skill>]" (see Install extras). Gemini reference scripts use the google-genai SDK (import google.genai). Bedrock Converse reference: bedrock_tos_evaluator.py (bedrock.md). All skill catalog pages include compact Usage Examples per provider.

Local execute / mixed means the checked-in script is not a single-provider agent loop. It either calls skill.execute(...) directly or loads multiple skills in one harness.

Suggested DeFi pre-trade host path: optional security/drainer_pattern_guard (when shipped) → defi/token_security_scanner → defi/evm_tx_handler preview/execute. Optional large-holder EOAs → finance/wallet_screening. Use shared EVM operator config for chains (#379); tokens in evm.tokens, not the address book.

Skill Local execute / mixed Gemini Claude OpenAI DeepSeek Ollama
compliance/tos_evaluator - gemini_tos_evaluator.py claude_tos_evaluator.py openai_tos_evaluator.py deepseek_tos_evaluator.py ollama_tos_evaluator.py
finance/wallet_screening - gemini_wallet_check.py claude_wallet_check.py (catalog page) (catalog page) ollama_skills_test.py (multi-skill)
office/gmail_handler gmail_handler_demo.py (local execute) gemini_gmail_handler.py (catalog page) (catalog page) (catalog page) (catalog page)
office/pdf_form_filler - gemini_pdf_form_filler.py claude_pdf_form_filler.py (catalog page) (catalog page) ollama_skills_test.py (multi-skill)
compliance/mica_module - mica_rag_flow.py mica_claude_flow.py (catalog page) (catalog page) mica_ollama_flow.py
compliance/pii_masker pii_guardrail_flow.py (local execute) (catalog page) (catalog page) (catalog page) (catalog page) (catalog page)
security/prompt_injection_firewall prompt_injection_firewall_demo.py, sanitize_input_chain_demo.py (local execute) (catalog page) (catalog page) (catalog page) (catalog page) (catalog page)
security/deceptive_ui_guard deceptive_ui_guard_demo.py (local execute) (catalog page) (catalog page) (catalog page) (catalog page) (catalog page)
creative/bg_remover bg_remover_demo.py (local execute) (catalog page) (catalog page) (catalog page) (catalog page) (catalog page)
creative/deck_builder deck_builder_demo.py, deck_builder_chain_demo.py (local execute) (catalog page) (catalog page) (catalog page) (catalog page) (catalog page)
optimization/prompt_rewriter prompt_compression_demo.py, sanitize_input_chain_demo.py (local execute) (catalog page) (catalog page) (catalog page) (catalog page) ollama_skills_test.py (multi-skill)
optimization/context_optimizer context_optimizer_demo.py, context_optimizer_chain_demo.py (local execute; fastembed) context_optimizer_gemini_loop.py context_optimizer_claude_loop.py (catalog page) (catalog page) (catalog page)
data_engineering/synthetic_generator build_dataset_demo.py (local execute, Gemini backend) (catalog page) (catalog page) (catalog page) (catalog page) (catalog page)
data_engineering/novelty_extractor novelty_extractor_demo.py (local execute) gemini_novelty_extractor.py (catalog page) (catalog page) (catalog page) ollama_novelty_extractor.py
data_engineering/semantic_web_proxy semantic_web_proxy_demo.py (local execute) (catalog page) (catalog page) (catalog page) (catalog page) (catalog page)
dev_tools/issue_resolver - gemini_issue_resolver.py claude_issue_resolver.py (catalog page) (catalog page) ollama_issue_resolver.py
wellness/mental_coach mental_coach_demo.py (local execute) (catalog page) (catalog page) (catalog page) (catalog page) (catalog page)
linguistics/korean_slang korean_slang_demo.py (local execute) (catalog page) (catalog page) (catalog page) (catalog page) (catalog page)
defi/evm_tx_handler - gemini_evm_tx_handler.py claude_evm_tx_handler.py - - -
defi/token_security_scanner - (catalog page) (catalog page) (catalog page) (catalog page) (catalog page)
monitoring/token_limiter token_limiter_loop.py (local execute) gemini_token_limiter.py, skill_context_gemini_loop.py (multi-skill) claude_token_limiter.py (catalog page) (catalog page) (catalog page)
monitoring/kpi_gate kpi_gate_demo.py (local execute) (catalog page) (catalog page) (catalog page) (catalog page) (catalog page)
finance/uk_companies_house_handler uk_companies_house_handler_demo.py gemini_uk_companies_house_handler.py claude_uk_companies_house_handler.py (catalog page) (catalog page) (catalog page)