skillware 0.3.2__tar.gz → 0.3.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. {skillware-0.3.2/skillware.egg-info → skillware-0.3.5}/PKG-INFO +22 -24
  2. {skillware-0.3.2 → skillware-0.3.5}/README.md +20 -23
  3. {skillware-0.3.2 → skillware-0.3.5}/pyproject.toml +6 -1
  4. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/pii_masker/skill.py +16 -15
  5. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/tos_evaluator/skill.py +34 -13
  6. {skillware-0.3.2 → skillware-0.3.5}/skills/data_engineering/synthetic_generator/skill.py +17 -30
  7. skillware-0.3.5/skills/defi/evm_tx_handler/abis.py +136 -0
  8. skillware-0.3.5/skills/defi/evm_tx_handler/card.json +20 -0
  9. skillware-0.3.5/skills/defi/evm_tx_handler/config.yaml.example +11 -0
  10. skillware-0.3.5/skills/defi/evm_tx_handler/data/addressbook.yaml +4 -0
  11. skillware-0.3.5/skills/defi/evm_tx_handler/data/chains.yaml +18 -0
  12. skillware-0.3.5/skills/defi/evm_tx_handler/data/tokens.yaml +25 -0
  13. skillware-0.3.5/skills/defi/evm_tx_handler/instructions.md +81 -0
  14. skillware-0.3.5/skills/defi/evm_tx_handler/manifest.yaml +63 -0
  15. skillware-0.3.5/skills/defi/evm_tx_handler/skill.py +1114 -0
  16. skillware-0.3.5/skills/defi/evm_tx_handler/test_skill.py +542 -0
  17. {skillware-0.3.2 → skillware-0.3.5}/skills/dev_tools/issue_resolver/card.json +1 -1
  18. skillware-0.3.5/skills/dev_tools/issue_resolver/instructions.md +80 -0
  19. skillware-0.3.5/skills/dev_tools/issue_resolver/manifest.yaml +63 -0
  20. {skillware-0.3.2 → skillware-0.3.5}/skills/dev_tools/issue_resolver/skill.py +96 -27
  21. {skillware-0.3.2 → skillware-0.3.5}/skills/dev_tools/issue_resolver/test_skill.py +62 -1
  22. skillware-0.3.5/skills/dev_tools/issue_resolver/workflow.py +302 -0
  23. {skillware-0.3.2 → skillware-0.3.5}/skills/finance/wallet_screening/skill.py +74 -15
  24. {skillware-0.3.2 → skillware-0.3.5}/skills/optimization/prompt_rewriter/skill.py +26 -9
  25. skillware-0.3.5/skillware/__init__.py +0 -0
  26. {skillware-0.3.2 → skillware-0.3.5}/skillware/cli.py +3 -0
  27. skillware-0.3.5/skillware/core/__init__.py +0 -0
  28. {skillware-0.3.2 → skillware-0.3.5}/skillware/core/loader.py +5 -1
  29. skillware-0.3.5/skillware/version_policy.py +63 -0
  30. {skillware-0.3.2 → skillware-0.3.5/skillware.egg-info}/PKG-INFO +22 -24
  31. {skillware-0.3.2 → skillware-0.3.5}/skillware.egg-info/SOURCES.txt +16 -1
  32. {skillware-0.3.2 → skillware-0.3.5}/skillware.egg-info/requires.txt +1 -0
  33. {skillware-0.3.2 → skillware-0.3.5}/tests/test_loader.py +27 -18
  34. {skillware-0.3.2 → skillware-0.3.5}/tests/test_skill_issuer.py +18 -14
  35. skillware-0.3.5/tests/test_version_policy.py +96 -0
  36. skillware-0.3.2/skills/dev_tools/issue_resolver/instructions.md +0 -104
  37. skillware-0.3.2/skills/dev_tools/issue_resolver/manifest.yaml +0 -56
  38. {skillware-0.3.2 → skillware-0.3.5}/LICENSE +0 -0
  39. {skillware-0.3.2 → skillware-0.3.5}/MANIFEST.in +0 -0
  40. {skillware-0.3.2 → skillware-0.3.5}/setup.cfg +0 -0
  41. {skillware-0.3.2 → skillware-0.3.5}/skills/__init__.py +0 -0
  42. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/__init__.py +0 -0
  43. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/mica_module/__init__.py +0 -0
  44. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/mica_module/card.json +0 -0
  45. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/mica_module/instructions.md +0 -0
  46. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/mica_module/manifest.yaml +0 -0
  47. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/mica_module/mica_corpus.json +0 -0
  48. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/mica_module/skill.py +0 -0
  49. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/pii_masker/__init__.py +0 -0
  50. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/pii_masker/card.json +0 -0
  51. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/pii_masker/instructions.md +0 -0
  52. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/pii_masker/manifest.yaml +0 -0
  53. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/tos_evaluator/__init__.py +0 -0
  54. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/tos_evaluator/card.json +0 -0
  55. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/tos_evaluator/instructions.md +0 -0
  56. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/tos_evaluator/manifest.yaml +0 -0
  57. {skillware-0.3.2 → skillware-0.3.5}/skills/compliance/tos_evaluator/test_skill.py +0 -0
  58. {skillware-0.3.2 → skillware-0.3.5}/skills/data_engineering/__init__.py +0 -0
  59. {skillware-0.3.2 → skillware-0.3.5}/skills/data_engineering/novelty_extractor/__init__.py +0 -0
  60. {skillware-0.3.2 → skillware-0.3.5}/skills/data_engineering/novelty_extractor/card.json +0 -0
  61. {skillware-0.3.2 → skillware-0.3.5}/skills/data_engineering/novelty_extractor/instructions.md +0 -0
  62. {skillware-0.3.2 → skillware-0.3.5}/skills/data_engineering/novelty_extractor/manifest.yaml +0 -0
  63. {skillware-0.3.2 → skillware-0.3.5}/skills/data_engineering/novelty_extractor/skill.py +0 -0
  64. {skillware-0.3.2 → skillware-0.3.5}/skills/data_engineering/novelty_extractor/test_skill.py +0 -0
  65. {skillware-0.3.2 → skillware-0.3.5}/skills/data_engineering/synthetic_generator/__init__.py +0 -0
  66. {skillware-0.3.2 → skillware-0.3.5}/skills/data_engineering/synthetic_generator/card.json +0 -0
  67. {skillware-0.3.2 → skillware-0.3.5}/skills/data_engineering/synthetic_generator/instructions.md +0 -0
  68. {skillware-0.3.2 → skillware-0.3.5}/skills/data_engineering/synthetic_generator/manifest.yaml +0 -0
  69. {skillware-0.3.2/skills/finance → skillware-0.3.5/skills/defi}/__init__.py +0 -0
  70. {skillware-0.3.2/skills/office → skillware-0.3.5/skills/defi/evm_tx_handler}/__init__.py +0 -0
  71. {skillware-0.3.2 → skillware-0.3.5}/skills/dev_tools/__init__.py +0 -0
  72. {skillware-0.3.2 → skillware-0.3.5}/skills/dev_tools/issue_resolver/__init__.py +0 -0
  73. {skillware-0.3.2/skills/office/pdf_form_filler → skillware-0.3.5/skills/finance}/__init__.py +0 -0
  74. {skillware-0.3.2 → skillware-0.3.5}/skills/finance/wallet_screening/__init__.py +0 -0
  75. {skillware-0.3.2 → skillware-0.3.5}/skills/finance/wallet_screening/card.json +0 -0
  76. {skillware-0.3.2 → skillware-0.3.5}/skills/finance/wallet_screening/data/entities.ftm.json +0 -0
  77. {skillware-0.3.2 → skillware-0.3.5}/skills/finance/wallet_screening/data/malicious_scs_2025.json +0 -0
  78. {skillware-0.3.2 → skillware-0.3.5}/skills/finance/wallet_screening/data/normalized_fbi_lazarus_20250722_180019.json +0 -0
  79. {skillware-0.3.2 → skillware-0.3.5}/skills/finance/wallet_screening/data/normalized_israel_nbctf_20250722_180019.json +0 -0
  80. {skillware-0.3.2 → skillware-0.3.5}/skills/finance/wallet_screening/data/normalized_uniswap_trm.json +0 -0
  81. {skillware-0.3.2 → skillware-0.3.5}/skills/finance/wallet_screening/instructions.md +0 -0
  82. {skillware-0.3.2 → skillware-0.3.5}/skills/finance/wallet_screening/maintenance/normalization_tool.py +0 -0
  83. {skillware-0.3.2 → skillware-0.3.5}/skills/finance/wallet_screening/maintenance/normalize_uniswap_trm.py +0 -0
  84. {skillware-0.3.2 → skillware-0.3.5}/skills/finance/wallet_screening/manifest.yaml +0 -0
  85. {skillware-0.3.2/skills/optimization → skillware-0.3.5/skills/office}/__init__.py +0 -0
  86. {skillware-0.3.2/skillware → skillware-0.3.5/skills/office/pdf_form_filler}/__init__.py +0 -0
  87. {skillware-0.3.2 → skillware-0.3.5}/skills/office/pdf_form_filler/card.json +0 -0
  88. {skillware-0.3.2 → skillware-0.3.5}/skills/office/pdf_form_filler/instructions.md +0 -0
  89. {skillware-0.3.2 → skillware-0.3.5}/skills/office/pdf_form_filler/manifest.yaml +0 -0
  90. {skillware-0.3.2 → skillware-0.3.5}/skills/office/pdf_form_filler/skill.py +0 -0
  91. {skillware-0.3.2 → skillware-0.3.5}/skills/office/pdf_form_filler/utils.py +0 -0
  92. {skillware-0.3.2/skillware/core → skillware-0.3.5/skills/optimization}/__init__.py +0 -0
  93. {skillware-0.3.2 → skillware-0.3.5}/skills/optimization/prompt_rewriter/__init__.py +0 -0
  94. {skillware-0.3.2 → skillware-0.3.5}/skills/optimization/prompt_rewriter/card.json +0 -0
  95. {skillware-0.3.2 → skillware-0.3.5}/skills/optimization/prompt_rewriter/instructions.md +0 -0
  96. {skillware-0.3.2 → skillware-0.3.5}/skills/optimization/prompt_rewriter/manifest.yaml +0 -0
  97. {skillware-0.3.2 → skillware-0.3.5}/skillware/core/base_skill.py +0 -0
  98. {skillware-0.3.2 → skillware-0.3.5}/skillware/core/env.py +0 -0
  99. {skillware-0.3.2 → skillware-0.3.5}/skillware.egg-info/dependency_links.txt +0 -0
  100. {skillware-0.3.2 → skillware-0.3.5}/skillware.egg-info/entry_points.txt +0 -0
  101. {skillware-0.3.2 → skillware-0.3.5}/skillware.egg-info/top_level.txt +0 -0
  102. {skillware-0.3.2 → skillware-0.3.5}/tests/test_cli.py +0 -0
  103. {skillware-0.3.2 → skillware-0.3.5}/tests/test_mica_module.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skillware
3
- Version: 0.3.2
3
+ Version: 0.3.5
4
4
  Summary: A framework for modular, self-contained AI skills.
5
5
  Author-email: ARPA Hellenic Logical Systems <skillware-os@arpacorp.net>
6
6
  License: MIT License
@@ -37,6 +37,7 @@ Requires-Dist: requests
37
37
  Requires-Dist: pyyaml
38
38
  Requires-Dist: python-dotenv
39
39
  Requires-Dist: beautifulsoup4
40
+ Requires-Dist: packaging
40
41
  Provides-Extra: dev
41
42
  Requires-Dist: pytest; extra == "dev"
42
43
  Requires-Dist: pytest-mock; extra == "dev"
@@ -81,9 +82,9 @@ Dynamic: license-file
81
82
  <a href="#architecture">Architecture</a> •
82
83
  <a href="#quick-start">Quick Start</a> •
83
84
  <a href="#documentation">Documentation</a> •
84
- <a href="CHANGELOG.md">Changelog</a> •
85
85
  <a href="#contributing">Contributing</a> •
86
86
  <a href="#comparison">Comparison</a> •
87
+ <a href="CHANGELOG.md">Changelog</a> •
87
88
  <a href="#contact">Contact</a>
88
89
  </div>
89
90
 
@@ -95,18 +96,18 @@ Dynamic: license-file
95
96
 
96
97
  ## Mission
97
98
 
98
- The AI ecosystem is fragmented. Developers often re-invent tool definitions, system prompts, and safety rules for every project. **Skillware** supplies a standard to package capabilities into self-contained units that work across **Gemini**, **Claude**, **Ollama**, **GPT**, and **Llama**.
99
+ The AI ecosystem is fragmented. Developers often re-invent tool definitions, system prompts, and safety rules for every project. **Skillware** supplies a standard to package capabilities into self-contained, installable units that work across **Gemini**, **Claude**, **Ollama**, **GPT**, and **Llama**. For the full story and roadmap, see our **[Vision](docs/vision.md)**.
99
100
 
100
101
  A **Skill** in this framework provides everything an Agent needs to master a domain:
101
102
 
102
- 1. **Logic**: Executable Python code.
103
- 2. **Cognition**: System instructions and "cognitive maps".
104
- 3. **Governance**: Constitution and safety boundaries.
105
- 4. **Interface**: Standardized schemas for LLM tool calling.
103
+ 1. **Logic**: Executable Python so agents run real work, not guess it.
104
+ 2. **Cognition**: System instructions and cognitive maps so any logical system uses the capability as intended.
105
+ 3. **Governance**: Constitution, safety boundaries, and hard limits baked into the bundle.
106
+ 4. **Interface**: Standardized tool schemas for any LLM or agent runtime.
106
107
 
107
108
  ### Skill library
108
109
 
109
- Browse capabilities by category in the [Skill library](docs/skills/README.md).
110
+ 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>.
110
111
 
111
112
  ## Architecture
112
113
 
@@ -238,30 +239,23 @@ For other providers and shared integration patterns, see the [usage guides index
238
239
 
239
240
  ## Documentation
240
241
 
241
- | Topic | Link |
242
+ | Topic | Links |
242
243
  | :--- | :--- |
243
- | Introduction | [docs/introduction.md](docs/introduction.md) |
244
- | Changelog | [CHANGELOG.md](CHANGELOG.md) |
245
- | Testing | [docs/TESTING.md](docs/TESTING.md) |
246
- | Skill library | [docs/skills/README.md](docs/skills/README.md) |
247
- | Usage guides | [index](docs/usage/README.md) — [Gemini](docs/usage/gemini.md) · [Claude](docs/usage/claude.md) · [OpenAI](docs/usage/openai.md) · [DeepSeek](docs/usage/deepseek.md) · [Ollama](docs/usage/ollama.md); [agent loops](docs/usage/agent_loops.md); [API keys](docs/usage/api_keys.md) |
248
- | Examples index | [examples/README.md](examples/README.md) |
249
- | CLI | [docs/usage/cli.md](docs/usage/cli.md) |
250
- | Contributing | [CONTRIBUTING.md](CONTRIBUTING.md) · [agent workflow](docs/contributing/ai_native_workflow.md) |
244
+ | **Introduction** | [Introduction](docs/introduction.md) · [Vision](docs/vision.md) · [Comparison](COMPARISON.md) |
245
+ | **Usage guides** | [Skill Library](docs/skills/README.md) · [Usage Guide](docs/usage/README.md) · [Examples](examples/README.md) · [Agent Loops](docs/usage/agent_loops.md) · [API Keys](docs/usage/api_keys.md) · [CLI](docs/usage/cli.md) |
246
+ | **Contributing** | [Contributing](CONTRIBUTING.md) · [Agent Native Workflow](docs/contributing/ai_native_workflow.md) · [Testing](docs/TESTING.md) · [Changelog](CHANGELOG.md) |
251
247
 
252
248
  ## Contributing
253
249
 
254
- We are building the "App Store" for Agents and require professional, robust, and safe skills. We welcome contributions to the skill registry, documentation, tests, and core framework.
250
+ We are building the "App Store" for Agents. Skills are the main contribution, but documentation, tests, and framework fixes are welcome too. Human operators and supervised agents follow the same standards: scoped PRs, deterministic behavior, and verified tests.
255
251
 
256
- * **[CONTRIBUTING.md](CONTRIBUTING.md)** — Contribution types, skill standard, pull request process, and navigation to all contributor docs.
257
- * **[Agent Contribution Workflow](docs/contributing/ai_native_workflow.md)** — Workflow for AI agents contributing to the repository (operators supervise).
258
- * **[Agent Code of Conduct](CODE_OF_CONDUCT.md)** — Deterministic outputs, safety boundaries, and acceptable use of skills.
259
- * **[TESTING.md](docs/TESTING.md)** — Local linting and pytest before you open a PR.
260
- * **[Pull request template](.github/PULL_REQUEST_TEMPLATE.md)** — Checklists for skills, docs, and framework changes (complete only the sections that apply).
252
+ See the **Contributing** row in [Documentation](#documentation) for the full path, [Contributing](CONTRIBUTING.md) (types, skill standard, PR process), [Agent Native Workflow](docs/contributing/ai_native_workflow.md) (for autonomous and semi-autonomous agents), [Testing](docs/TESTING.md) (Black, Flake8, framework and skill pytest, pre-PR checklist), and [Changelog](CHANGELOG.md) (user-facing entries under `[Unreleased]`).
253
+
254
+ Also read the [Agent Code of Conduct](CODE_OF_CONDUCT.md). Open PRs with the [pull request template](.github/PULL_REQUEST_TEMPLATE.md) and complete only the sections that apply.
261
255
 
262
256
  ## Comparison
263
257
 
264
- Skillware differs from the Model Context Protocol (MCP) or Anthropic's Skills repository in the following ways:
258
+ Skillware differs from the Model Context Protocol (MCP), and Agent Skills (SKILL.md) in several ways:
265
259
 
266
260
  * **Model Agnostic**: Native adapters for Gemini, Claude, Ollama, and OpenAI.
267
261
  * **Code-First**: Skills are executable Python packages, not just server specs.
@@ -274,8 +268,12 @@ Skillware differs from the Model Context Protocol (MCP) or Anthropic's Skills re
274
268
  For questions, suggestions, or contributions, please open an issue or reach out to us:
275
269
 
276
270
  * **Email**: [skillware-os@arpacorp.net](mailto:skillware-os@arpacorp.net)
271
+ * **Enterprise**: [skills@arpacorp.net](mailto:skills@arpacorp.net) — enterprise skills, chaining, and forward deployed engineering
272
+ * **Security**: [security@arpacorp.net](mailto:security@arpacorp.net) — report bugs, vulnerabilities, or other sensitive issues (see [SECURITY.md](SECURITY.md))
277
273
  * **Issues**: [GitHub Issues](https://github.com/arpahls/skillware/issues)
278
274
 
275
+ For skill-specific questions or reaching a skill's maintainer, check issuer and author details on the skill card, in the repo [Skill Library](docs/skills/README.md), or on our website's <a href="https://skillware.site/skills" target="_blank" rel="noopener noreferrer">skills catalog&nbsp;↗</a>.
276
+
279
277
  ---
280
278
 
281
279
  <div align="center">
@@ -19,9 +19,9 @@
19
19
  <a href="#architecture">Architecture</a> •
20
20
  <a href="#quick-start">Quick Start</a> •
21
21
  <a href="#documentation">Documentation</a> •
22
- <a href="CHANGELOG.md">Changelog</a> •
23
22
  <a href="#contributing">Contributing</a> •
24
23
  <a href="#comparison">Comparison</a> •
24
+ <a href="CHANGELOG.md">Changelog</a> •
25
25
  <a href="#contact">Contact</a>
26
26
  </div>
27
27
 
@@ -33,18 +33,18 @@
33
33
 
34
34
  ## Mission
35
35
 
36
- The AI ecosystem is fragmented. Developers often re-invent tool definitions, system prompts, and safety rules for every project. **Skillware** supplies a standard to package capabilities into self-contained units that work across **Gemini**, **Claude**, **Ollama**, **GPT**, and **Llama**.
36
+ The AI ecosystem is fragmented. Developers often re-invent tool definitions, system prompts, and safety rules for every project. **Skillware** supplies a standard to package capabilities into self-contained, installable units that work across **Gemini**, **Claude**, **Ollama**, **GPT**, and **Llama**. For the full story and roadmap, see our **[Vision](docs/vision.md)**.
37
37
 
38
38
  A **Skill** in this framework provides everything an Agent needs to master a domain:
39
39
 
40
- 1. **Logic**: Executable Python code.
41
- 2. **Cognition**: System instructions and "cognitive maps".
42
- 3. **Governance**: Constitution and safety boundaries.
43
- 4. **Interface**: Standardized schemas for LLM tool calling.
40
+ 1. **Logic**: Executable Python so agents run real work, not guess it.
41
+ 2. **Cognition**: System instructions and cognitive maps so any logical system uses the capability as intended.
42
+ 3. **Governance**: Constitution, safety boundaries, and hard limits baked into the bundle.
43
+ 4. **Interface**: Standardized tool schemas for any LLM or agent runtime.
44
44
 
45
45
  ### Skill library
46
46
 
47
- Browse capabilities by category in the [Skill library](docs/skills/README.md).
47
+ 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>.
48
48
 
49
49
  ## Architecture
50
50
 
@@ -176,30 +176,23 @@ For other providers and shared integration patterns, see the [usage guides index
176
176
 
177
177
  ## Documentation
178
178
 
179
- | Topic | Link |
179
+ | Topic | Links |
180
180
  | :--- | :--- |
181
- | Introduction | [docs/introduction.md](docs/introduction.md) |
182
- | Changelog | [CHANGELOG.md](CHANGELOG.md) |
183
- | Testing | [docs/TESTING.md](docs/TESTING.md) |
184
- | Skill library | [docs/skills/README.md](docs/skills/README.md) |
185
- | Usage guides | [index](docs/usage/README.md) — [Gemini](docs/usage/gemini.md) · [Claude](docs/usage/claude.md) · [OpenAI](docs/usage/openai.md) · [DeepSeek](docs/usage/deepseek.md) · [Ollama](docs/usage/ollama.md); [agent loops](docs/usage/agent_loops.md); [API keys](docs/usage/api_keys.md) |
186
- | Examples index | [examples/README.md](examples/README.md) |
187
- | CLI | [docs/usage/cli.md](docs/usage/cli.md) |
188
- | Contributing | [CONTRIBUTING.md](CONTRIBUTING.md) · [agent workflow](docs/contributing/ai_native_workflow.md) |
181
+ | **Introduction** | [Introduction](docs/introduction.md) · [Vision](docs/vision.md) · [Comparison](COMPARISON.md) |
182
+ | **Usage guides** | [Skill Library](docs/skills/README.md) · [Usage Guide](docs/usage/README.md) · [Examples](examples/README.md) · [Agent Loops](docs/usage/agent_loops.md) · [API Keys](docs/usage/api_keys.md) · [CLI](docs/usage/cli.md) |
183
+ | **Contributing** | [Contributing](CONTRIBUTING.md) · [Agent Native Workflow](docs/contributing/ai_native_workflow.md) · [Testing](docs/TESTING.md) · [Changelog](CHANGELOG.md) |
189
184
 
190
185
  ## Contributing
191
186
 
192
- We are building the "App Store" for Agents and require professional, robust, and safe skills. We welcome contributions to the skill registry, documentation, tests, and core framework.
187
+ We are building the "App Store" for Agents. Skills are the main contribution, but documentation, tests, and framework fixes are welcome too. Human operators and supervised agents follow the same standards: scoped PRs, deterministic behavior, and verified tests.
193
188
 
194
- * **[CONTRIBUTING.md](CONTRIBUTING.md)** — Contribution types, skill standard, pull request process, and navigation to all contributor docs.
195
- * **[Agent Contribution Workflow](docs/contributing/ai_native_workflow.md)** — Workflow for AI agents contributing to the repository (operators supervise).
196
- * **[Agent Code of Conduct](CODE_OF_CONDUCT.md)** — Deterministic outputs, safety boundaries, and acceptable use of skills.
197
- * **[TESTING.md](docs/TESTING.md)** — Local linting and pytest before you open a PR.
198
- * **[Pull request template](.github/PULL_REQUEST_TEMPLATE.md)** — Checklists for skills, docs, and framework changes (complete only the sections that apply).
189
+ See the **Contributing** row in [Documentation](#documentation) for the full path, [Contributing](CONTRIBUTING.md) (types, skill standard, PR process), [Agent Native Workflow](docs/contributing/ai_native_workflow.md) (for autonomous and semi-autonomous agents), [Testing](docs/TESTING.md) (Black, Flake8, framework and skill pytest, pre-PR checklist), and [Changelog](CHANGELOG.md) (user-facing entries under `[Unreleased]`).
190
+
191
+ Also read the [Agent Code of Conduct](CODE_OF_CONDUCT.md). Open PRs with the [pull request template](.github/PULL_REQUEST_TEMPLATE.md) and complete only the sections that apply.
199
192
 
200
193
  ## Comparison
201
194
 
202
- Skillware differs from the Model Context Protocol (MCP) or Anthropic's Skills repository in the following ways:
195
+ Skillware differs from the Model Context Protocol (MCP), and Agent Skills (SKILL.md) in several ways:
203
196
 
204
197
  * **Model Agnostic**: Native adapters for Gemini, Claude, Ollama, and OpenAI.
205
198
  * **Code-First**: Skills are executable Python packages, not just server specs.
@@ -212,8 +205,12 @@ Skillware differs from the Model Context Protocol (MCP) or Anthropic's Skills re
212
205
  For questions, suggestions, or contributions, please open an issue or reach out to us:
213
206
 
214
207
  * **Email**: [skillware-os@arpacorp.net](mailto:skillware-os@arpacorp.net)
208
+ * **Enterprise**: [skills@arpacorp.net](mailto:skills@arpacorp.net) — enterprise skills, chaining, and forward deployed engineering
209
+ * **Security**: [security@arpacorp.net](mailto:security@arpacorp.net) — report bugs, vulnerabilities, or other sensitive issues (see [SECURITY.md](SECURITY.md))
215
210
  * **Issues**: [GitHub Issues](https://github.com/arpahls/skillware/issues)
216
211
 
212
+ For skill-specific questions or reaching a skill's maintainer, check issuer and author details on the skill card, in the repo [Skill Library](docs/skills/README.md), or on our website's <a href="https://skillware.site/skills" target="_blank" rel="noopener noreferrer">skills catalog&nbsp;↗</a>.
213
+
217
214
  ---
218
215
 
219
216
  <div align="center">
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "skillware"
7
- version = "0.3.2"
7
+ version = "0.3.5"
8
8
  description = "A framework for modular, self-contained AI skills."
9
9
  readme = "README.md"
10
10
  authors = [
@@ -22,6 +22,7 @@ dependencies = [
22
22
  "pyyaml",
23
23
  "python-dotenv",
24
24
  "beautifulsoup4",
25
+ "packaging",
25
26
  ]
26
27
  requires-python = ">=3.10"
27
28
 
@@ -68,3 +69,7 @@ include = ["skillware*", "skills*"]
68
69
  # and this wildcard. No per-skill entries needed when adding registry skills.
69
70
  [tool.setuptools.package-data]
70
71
  skills = ["**/*"]
72
+
73
+ [tool.black]
74
+ line-length = 88
75
+ target-version = ["py310"]
@@ -11,10 +11,7 @@ class PIIMaskerSkill(BaseSkill):
11
11
 
12
12
  @property
13
13
  def manifest(self) -> Dict[str, Any]:
14
- return {
15
- "name": "compliance/pii_masker",
16
- "version": "0.1.0"
17
- }
14
+ return {"name": "compliance/pii_masker", "version": "0.1.0"}
18
15
 
19
16
  def execute(self, params: Dict[str, Any]) -> Dict[str, Any]:
20
17
  text = params.get("text", "")
@@ -25,7 +22,7 @@ class PIIMaskerSkill(BaseSkill):
25
22
  sanitized_text = self._apply_mode(sanitized_text, mode)
26
23
 
27
24
  # Build unique entity types list
28
- entities = list(set([re.sub(r'_[0-9]+$', '', e) for e in detected_entities]))
25
+ entities = list(set([re.sub(r"_[0-9]+$", "", e) for e in detected_entities]))
29
26
 
30
27
  return {
31
28
  "sanitized_text": sanitized_text,
@@ -33,17 +30,21 @@ class PIIMaskerSkill(BaseSkill):
33
30
  "detected_entities": entities,
34
31
  "entity_count": len(detected_entities),
35
32
  "security_level": "local-only",
36
- "model": "arpacorp/micro-f1-mask"
37
- }
33
+ "model": "arpacorp/micro-f1-mask",
34
+ },
38
35
  }
39
36
 
40
37
  def _call_ollama(self, text: str, endpoint: str) -> Tuple[str, List[str]]:
41
38
  try:
42
- response = requests.post(f"{endpoint}/api/generate", json={
43
- "model": "arpacorp/micro-f1-mask",
44
- "prompt": text,
45
- "stream": False
46
- }, timeout=30)
39
+ response = requests.post(
40
+ f"{endpoint}/api/generate",
41
+ json={
42
+ "model": "arpacorp/micro-f1-mask",
43
+ "prompt": text,
44
+ "stream": False,
45
+ },
46
+ timeout=30,
47
+ )
47
48
  if response.status_code == 200:
48
49
  result_text = response.json().get("response", text)
49
50
  else:
@@ -56,7 +57,7 @@ class PIIMaskerSkill(BaseSkill):
56
57
  result_text = text
57
58
 
58
59
  # Detect entities in the response
59
- detected = re.findall(r'\[([A-Z_]+(?:_[0-9]+)?)\]', result_text)
60
+ detected = re.findall(r"\[([A-Z_]+(?:_[0-9]+)?)\]", result_text)
60
61
  return result_text, detected
61
62
 
62
63
  def _apply_mode(self, text: str, mode: str) -> str:
@@ -64,14 +65,14 @@ class PIIMaskerSkill(BaseSkill):
64
65
  return text
65
66
 
66
67
  # Pattern to catch [DOCUMENT], [PERSON_1], etc.
67
- pattern = r'\[[A-Z_]+(?:_[0-9]+)?\]'
68
+ pattern = r"\[[A-Z_]+(?:_[0-9]+)?\]"
68
69
  if mode == "redact":
69
70
  return re.sub(pattern, "XXXX", text)
70
71
  elif mode == "remove":
71
72
  # Replace token and any immediate preceding/following spaces safely
72
73
  # A simple sub is sufficient. Cleaning up double spaces.
73
74
  text = re.sub(pattern, "", text)
74
- text = re.sub(r'\s+', ' ', text).strip()
75
+ text = re.sub(r"\s+", " ", text).strip()
75
76
  return text
76
77
 
77
78
  return text
@@ -213,7 +213,9 @@ class TOSEvaluatorSkill(BaseSkill):
213
213
  try:
214
214
  response = self.session.get(robots_url, timeout=10)
215
215
  if response.status_code >= 400:
216
- assessment["reason"] = f"robots.txt returned HTTP {response.status_code}."
216
+ assessment["reason"] = (
217
+ f"robots.txt returned HTTP {response.status_code}."
218
+ )
217
219
  return assessment
218
220
 
219
221
  parser = RobotFileParser()
@@ -266,13 +268,20 @@ class TOSEvaluatorSkill(BaseSkill):
266
268
  else:
267
269
  candidates[item["url"]] = item
268
270
 
269
- ordered = sorted(candidates.values(), key=lambda item: item["score"], reverse=True)
271
+ ordered = sorted(
272
+ candidates.values(), key=lambda item: item["score"], reverse=True
273
+ )
270
274
  return {"candidates": ordered[:max_terms_pages]}
271
275
 
272
- def _extract_candidate_links(self, page_url: str, origin: str) -> List[Dict[str, Any]]:
276
+ def _extract_candidate_links(
277
+ self, page_url: str, origin: str
278
+ ) -> List[Dict[str, Any]]:
273
279
  links: List[Dict[str, Any]] = []
274
280
  response = self._safe_get(page_url, timeout=10)
275
- if not response or "html" not in response.headers.get("Content-Type", "").lower():
281
+ if (
282
+ not response
283
+ or "html" not in response.headers.get("Content-Type", "").lower()
284
+ ):
276
285
  return links
277
286
 
278
287
  soup = BeautifulSoup(response.text[:300000], "html.parser")
@@ -449,7 +458,10 @@ class TOSEvaluatorSkill(BaseSkill):
449
458
  return False
450
459
  if robots_assessment.get("can_fetch") is False:
451
460
  return False
452
- return bool(tos_assessment.get("matched_clauses") or tos_assessment["status"] == "caution")
461
+ return bool(
462
+ tos_assessment.get("matched_clauses")
463
+ or tos_assessment["status"] == "caution"
464
+ )
453
465
 
454
466
  def _run_llm_evaluator(
455
467
  self, normalized: Dict[str, Any], tos_assessment: Dict[str, Any]
@@ -512,26 +524,33 @@ class TOSEvaluatorSkill(BaseSkill):
512
524
  verdict = "INSUFFICIENT_EVIDENCE"
513
525
  confidence_score = 0.35
514
526
  reason = "Insufficient policy evidence to safely approve the requested action."
515
- recommended_next_step = "Review the discovered policy pages manually before proceeding."
527
+ recommended_next_step = (
528
+ "Review the discovered policy pages manually before proceeding."
529
+ )
516
530
 
517
531
  if robots_assessment.get("can_fetch") is False:
518
532
  verdict = "UNSAFE"
519
533
  confidence_score = 0.98
520
534
  reason = robots_assessment["reason"]
521
- recommended_next_step = (
522
- "Do not automate access to this path unless you have explicit permission."
523
- )
535
+ recommended_next_step = "Do not automate access to this path unless you have explicit permission."
524
536
  elif tos_assessment["status"] == "blocked":
525
537
  verdict = "UNSAFE"
526
538
  confidence_score = 0.9
527
539
  reason = tos_assessment["summary"]
528
- recommended_next_step = "Avoid the requested action or obtain explicit written permission."
540
+ recommended_next_step = (
541
+ "Avoid the requested action or obtain explicit written permission."
542
+ )
529
543
  elif tos_assessment["status"] == "caution":
530
544
  verdict = "CAUTION"
531
545
  confidence_score = 0.65
532
546
  reason = tos_assessment["summary"]
533
- recommended_next_step = "Prefer an official API or documented integration path if one exists."
534
- elif tos_assessment["status"] == "allowed" and robots_assessment.get("can_fetch") is not False:
547
+ recommended_next_step = (
548
+ "Prefer an official API or documented integration path if one exists."
549
+ )
550
+ elif (
551
+ tos_assessment["status"] == "allowed"
552
+ and robots_assessment.get("can_fetch") is not False
553
+ ):
535
554
  verdict = "SAFE"
536
555
  confidence_score = 0.72
537
556
  reason = tos_assessment["summary"]
@@ -575,7 +594,9 @@ class TOSEvaluatorSkill(BaseSkill):
575
594
  "tos_assessment": tos_assessment,
576
595
  "llm_assessment": llm_assessment or {"status": "not_used"},
577
596
  "discovered_policy_urls": {
578
- "candidates": [item["url"] for item in policy_candidates.get("candidates", [])]
597
+ "candidates": [
598
+ item["url"] for item in policy_candidates.get("candidates", [])
599
+ ]
579
600
  },
580
601
  "evidence": evidence,
581
602
  }
@@ -18,6 +18,7 @@ class SyntheticGeneratorSkill(BaseSkill):
18
18
  manifest_path = os.path.join(os.path.dirname(__file__), "manifest.yaml")
19
19
  if os.path.exists(manifest_path):
20
20
  import yaml
21
+
21
22
  with open(manifest_path, "r", encoding="utf-8") as f:
22
23
  return yaml.safe_load(f)
23
24
  return {}
@@ -35,16 +36,11 @@ class SyntheticGeneratorSkill(BaseSkill):
35
36
  # Scaled for readability
36
37
  return round(min(ratio * 1.5, 1.0), 3)
37
38
 
38
- def _call_gemini(
39
- self, prompt: str, temperature: float, model_name: str
40
- ) -> str:
39
+ def _call_gemini(self, prompt: str, temperature: float, model_name: str) -> str:
41
40
  import google.genai as genai
42
41
  from google.genai import types
43
42
 
44
- api_key = (
45
- self.config.get("GOOGLE_API_KEY")
46
- or os.environ.get("GOOGLE_API_KEY")
47
- )
43
+ api_key = self.config.get("GOOGLE_API_KEY") or os.environ.get("GOOGLE_API_KEY")
48
44
  client = genai.Client(api_key=api_key)
49
45
  response = client.models.generate_content(
50
46
  model=model_name,
@@ -53,31 +49,28 @@ class SyntheticGeneratorSkill(BaseSkill):
53
49
  )
54
50
  return response.text
55
51
 
56
- def _call_anthropic(
57
- self, prompt: str, temperature: float, model_name: str
58
- ) -> str:
52
+ def _call_anthropic(self, prompt: str, temperature: float, model_name: str) -> str:
59
53
  import anthropic
60
- api_key = (
61
- self.config.get("ANTHROPIC_API_KEY")
62
- or os.environ.get("ANTHROPIC_API_KEY")
54
+
55
+ api_key = self.config.get("ANTHROPIC_API_KEY") or os.environ.get(
56
+ "ANTHROPIC_API_KEY"
63
57
  )
64
58
  client = anthropic.Anthropic(api_key=api_key)
65
59
  message = client.messages.create(
66
60
  model=model_name,
67
61
  max_tokens=4096,
68
62
  temperature=temperature,
69
- messages=[{"role": "user", "content": prompt}]
63
+ messages=[{"role": "user", "content": prompt}],
70
64
  )
71
65
  return message.content[0].text
72
66
 
73
- def _call_ollama(
74
- self, prompt: str, temperature: float, model_name: str
75
- ) -> str:
67
+ def _call_ollama(self, prompt: str, temperature: float, model_name: str) -> str:
76
68
  import ollama
69
+
77
70
  response = ollama.chat(
78
71
  model=model_name,
79
72
  messages=[{"role": "user", "content": prompt}],
80
- options={"temperature": temperature}
73
+ options={"temperature": temperature},
81
74
  )
82
75
  return response.get("message", {}).get("content", "")
83
76
 
@@ -107,21 +100,15 @@ class SyntheticGeneratorSkill(BaseSkill):
107
100
 
108
101
  try:
109
102
  if provider == "gemini":
110
- raw_text = self._call_gemini(
111
- system_prompt, temperature, model_name
112
- )
103
+ raw_text = self._call_gemini(system_prompt, temperature, model_name)
113
104
  elif provider == "anthropic":
114
- raw_text = self._call_anthropic(
115
- system_prompt, temperature, model_name
116
- )
105
+ raw_text = self._call_anthropic(system_prompt, temperature, model_name)
117
106
  else:
118
- raw_text = self._call_ollama(
119
- system_prompt, temperature, model_name
120
- )
107
+ raw_text = self._call_ollama(system_prompt, temperature, model_name)
121
108
  except Exception as e:
122
109
  return {
123
110
  "status": "error",
124
- "message": f"LLM Call Failed via {provider}: {str(e)}"
111
+ "message": f"LLM Call Failed via {provider}: {str(e)}",
125
112
  }
126
113
 
127
114
  samples = []
@@ -141,7 +128,7 @@ class SyntheticGeneratorSkill(BaseSkill):
141
128
  return {
142
129
  "status": "error",
143
130
  "message": f"Parsing failed: {e}",
144
- "raw_output": raw_text
131
+ "raw_output": raw_text,
145
132
  }
146
133
 
147
134
  all_text = " ".join([str(s) for s in samples])
@@ -152,5 +139,5 @@ class SyntheticGeneratorSkill(BaseSkill):
152
139
  "entropy_score": score,
153
140
  "status": "success",
154
141
  "provider_used": provider,
155
- "samples_generated": len(samples)
142
+ "samples_generated": len(samples),
156
143
  }
@@ -0,0 +1,136 @@
1
+ """Minimal contract ABIs for Uniswap V2 router and ERC20."""
2
+
3
+ ROUTER_V2_ABI = [
4
+ {
5
+ "name": "getAmountsOut",
6
+ "type": "function",
7
+ "stateMutability": "view",
8
+ "inputs": [
9
+ {"name": "amountIn", "type": "uint256"},
10
+ {"name": "path", "type": "address[]"},
11
+ ],
12
+ "outputs": [{"name": "amounts", "type": "uint256[]"}],
13
+ },
14
+ {
15
+ "name": "getAmountsIn",
16
+ "type": "function",
17
+ "stateMutability": "view",
18
+ "inputs": [
19
+ {"name": "amountOut", "type": "uint256"},
20
+ {"name": "path", "type": "address[]"},
21
+ ],
22
+ "outputs": [{"name": "amounts", "type": "uint256[]"}],
23
+ },
24
+ {
25
+ "name": "swapExactTokensForTokens",
26
+ "type": "function",
27
+ "stateMutability": "nonpayable",
28
+ "inputs": [
29
+ {"name": "amountIn", "type": "uint256"},
30
+ {"name": "amountOutMin", "type": "uint256"},
31
+ {"name": "path", "type": "address[]"},
32
+ {"name": "to", "type": "address"},
33
+ {"name": "deadline", "type": "uint256"},
34
+ ],
35
+ "outputs": [{"name": "amounts", "type": "uint256[]"}],
36
+ },
37
+ {
38
+ "name": "swapTokensForExactTokens",
39
+ "type": "function",
40
+ "stateMutability": "nonpayable",
41
+ "inputs": [
42
+ {"name": "amountOut", "type": "uint256"},
43
+ {"name": "amountInMax", "type": "uint256"},
44
+ {"name": "path", "type": "address[]"},
45
+ {"name": "to", "type": "address"},
46
+ {"name": "deadline", "type": "uint256"},
47
+ ],
48
+ "outputs": [{"name": "amounts", "type": "uint256[]"}],
49
+ },
50
+ {
51
+ "name": "swapExactETHForTokens",
52
+ "type": "function",
53
+ "stateMutability": "payable",
54
+ "inputs": [
55
+ {"name": "amountOutMin", "type": "uint256"},
56
+ {"name": "path", "type": "address[]"},
57
+ {"name": "to", "type": "address"},
58
+ {"name": "deadline", "type": "uint256"},
59
+ ],
60
+ "outputs": [{"name": "amounts", "type": "uint256[]"}],
61
+ },
62
+ {
63
+ "name": "swapETHForExactTokens",
64
+ "type": "function",
65
+ "stateMutability": "payable",
66
+ "inputs": [
67
+ {"name": "amountOut", "type": "uint256"},
68
+ {"name": "path", "type": "address[]"},
69
+ {"name": "to", "type": "address"},
70
+ {"name": "deadline", "type": "uint256"},
71
+ ],
72
+ "outputs": [{"name": "amounts", "type": "uint256[]"}],
73
+ },
74
+ {
75
+ "name": "swapExactTokensForETH",
76
+ "type": "function",
77
+ "stateMutability": "nonpayable",
78
+ "inputs": [
79
+ {"name": "amountIn", "type": "uint256"},
80
+ {"name": "amountOutMin", "type": "uint256"},
81
+ {"name": "path", "type": "address[]"},
82
+ {"name": "to", "type": "address"},
83
+ {"name": "deadline", "type": "uint256"},
84
+ ],
85
+ "outputs": [{"name": "amounts", "type": "uint256[]"}],
86
+ },
87
+ ]
88
+
89
+ ERC20_ABI = [
90
+ {
91
+ "name": "balanceOf",
92
+ "type": "function",
93
+ "stateMutability": "view",
94
+ "inputs": [{"name": "account", "type": "address"}],
95
+ "outputs": [{"name": "", "type": "uint256"}],
96
+ },
97
+ {
98
+ "name": "decimals",
99
+ "type": "function",
100
+ "stateMutability": "view",
101
+ "inputs": [],
102
+ "outputs": [{"name": "", "type": "uint8"}],
103
+ },
104
+ {
105
+ "name": "allowance",
106
+ "type": "function",
107
+ "stateMutability": "view",
108
+ "inputs": [
109
+ {"name": "owner", "type": "address"},
110
+ {"name": "spender", "type": "address"},
111
+ ],
112
+ "outputs": [{"name": "", "type": "uint256"}],
113
+ },
114
+ {
115
+ "name": "approve",
116
+ "type": "function",
117
+ "stateMutability": "nonpayable",
118
+ "inputs": [
119
+ {"name": "spender", "type": "address"},
120
+ {"name": "amount", "type": "uint256"},
121
+ ],
122
+ "outputs": [{"name": "", "type": "bool"}],
123
+ },
124
+ {
125
+ "name": "transfer",
126
+ "type": "function",
127
+ "stateMutability": "nonpayable",
128
+ "inputs": [
129
+ {"name": "to", "type": "address"},
130
+ {"name": "amount", "type": "uint256"},
131
+ ],
132
+ "outputs": [{"name": "", "type": "bool"}],
133
+ },
134
+ ]
135
+
136
+ MAX_UINT256 = 2**256 - 1