skillware 0.2.8__tar.gz → 0.3.1__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 (87) hide show
  1. {skillware-0.2.8/skillware.egg-info → skillware-0.3.1}/PKG-INFO +97 -35
  2. {skillware-0.2.8 → skillware-0.3.1}/README.md +79 -31
  3. {skillware-0.2.8 → skillware-0.3.1}/pyproject.toml +27 -4
  4. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/mica_module/manifest.yaml +1 -1
  5. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/mica_module/skill.py +38 -6
  6. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/tos_evaluator/skill.py +12 -9
  7. skillware-0.3.1/skills/data_engineering/novelty_extractor/__init__.py +3 -0
  8. skillware-0.3.1/skills/data_engineering/novelty_extractor/card.json +37 -0
  9. skillware-0.3.1/skills/data_engineering/novelty_extractor/instructions.md +60 -0
  10. skillware-0.3.1/skills/data_engineering/novelty_extractor/manifest.yaml +45 -0
  11. skillware-0.3.1/skills/data_engineering/novelty_extractor/skill.py +111 -0
  12. skillware-0.3.1/skills/data_engineering/novelty_extractor/test_skill.py +105 -0
  13. {skillware-0.2.8 → skillware-0.3.1}/skills/data_engineering/synthetic_generator/skill.py +8 -9
  14. skillware-0.3.1/skillware/cli.py +162 -0
  15. {skillware-0.2.8 → skillware-0.3.1}/skillware/core/loader.py +16 -5
  16. {skillware-0.2.8 → skillware-0.3.1/skillware.egg-info}/PKG-INFO +97 -35
  17. {skillware-0.2.8 → skillware-0.3.1}/skillware.egg-info/SOURCES.txt +9 -0
  18. skillware-0.3.1/skillware.egg-info/entry_points.txt +2 -0
  19. skillware-0.3.1/skillware.egg-info/requires.txt +32 -0
  20. skillware-0.3.1/tests/test_cli.py +140 -0
  21. skillware-0.2.8/skillware.egg-info/requires.txt +0 -12
  22. {skillware-0.2.8 → skillware-0.3.1}/LICENSE +0 -0
  23. {skillware-0.2.8 → skillware-0.3.1}/MANIFEST.in +0 -0
  24. {skillware-0.2.8 → skillware-0.3.1}/setup.cfg +0 -0
  25. {skillware-0.2.8 → skillware-0.3.1}/skills/__init__.py +0 -0
  26. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/__init__.py +0 -0
  27. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/mica_module/__init__.py +0 -0
  28. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/mica_module/card.json +0 -0
  29. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/mica_module/instructions.md +0 -0
  30. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/mica_module/mica_corpus.json +0 -0
  31. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/pii_masker/__init__.py +0 -0
  32. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/pii_masker/card.json +0 -0
  33. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/pii_masker/instructions.md +0 -0
  34. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/pii_masker/manifest.yaml +0 -0
  35. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/pii_masker/skill.py +0 -0
  36. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/tos_evaluator/__init__.py +0 -0
  37. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/tos_evaluator/card.json +0 -0
  38. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/tos_evaluator/instructions.md +0 -0
  39. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/tos_evaluator/manifest.yaml +0 -0
  40. {skillware-0.2.8 → skillware-0.3.1}/skills/compliance/tos_evaluator/test_skill.py +0 -0
  41. {skillware-0.2.8 → skillware-0.3.1}/skills/data_engineering/__init__.py +0 -0
  42. {skillware-0.2.8 → skillware-0.3.1}/skills/data_engineering/synthetic_generator/__init__.py +0 -0
  43. {skillware-0.2.8 → skillware-0.3.1}/skills/data_engineering/synthetic_generator/card.json +0 -0
  44. {skillware-0.2.8 → skillware-0.3.1}/skills/data_engineering/synthetic_generator/instructions.md +0 -0
  45. {skillware-0.2.8 → skillware-0.3.1}/skills/data_engineering/synthetic_generator/manifest.yaml +0 -0
  46. {skillware-0.2.8 → skillware-0.3.1}/skills/dev_tools/__init__.py +0 -0
  47. {skillware-0.2.8 → skillware-0.3.1}/skills/dev_tools/issue_resolver/__init__.py +0 -0
  48. {skillware-0.2.8 → skillware-0.3.1}/skills/dev_tools/issue_resolver/card.json +0 -0
  49. {skillware-0.2.8 → skillware-0.3.1}/skills/dev_tools/issue_resolver/instructions.md +0 -0
  50. {skillware-0.2.8 → skillware-0.3.1}/skills/dev_tools/issue_resolver/manifest.yaml +0 -0
  51. {skillware-0.2.8 → skillware-0.3.1}/skills/dev_tools/issue_resolver/skill.py +0 -0
  52. {skillware-0.2.8 → skillware-0.3.1}/skills/dev_tools/issue_resolver/test_skill.py +0 -0
  53. {skillware-0.2.8 → skillware-0.3.1}/skills/finance/__init__.py +0 -0
  54. {skillware-0.2.8 → skillware-0.3.1}/skills/finance/wallet_screening/__init__.py +0 -0
  55. {skillware-0.2.8 → skillware-0.3.1}/skills/finance/wallet_screening/card.json +0 -0
  56. {skillware-0.2.8 → skillware-0.3.1}/skills/finance/wallet_screening/data/entities.ftm.json +0 -0
  57. {skillware-0.2.8 → skillware-0.3.1}/skills/finance/wallet_screening/data/malicious_scs_2025.json +0 -0
  58. {skillware-0.2.8 → skillware-0.3.1}/skills/finance/wallet_screening/data/normalized_fbi_lazarus_20250722_180019.json +0 -0
  59. {skillware-0.2.8 → skillware-0.3.1}/skills/finance/wallet_screening/data/normalized_israel_nbctf_20250722_180019.json +0 -0
  60. {skillware-0.2.8 → skillware-0.3.1}/skills/finance/wallet_screening/data/normalized_uniswap_trm.json +0 -0
  61. {skillware-0.2.8 → skillware-0.3.1}/skills/finance/wallet_screening/instructions.md +0 -0
  62. {skillware-0.2.8 → skillware-0.3.1}/skills/finance/wallet_screening/maintenance/normalization_tool.py +0 -0
  63. {skillware-0.2.8 → skillware-0.3.1}/skills/finance/wallet_screening/maintenance/normalize_uniswap_trm.py +0 -0
  64. {skillware-0.2.8 → skillware-0.3.1}/skills/finance/wallet_screening/manifest.yaml +0 -0
  65. {skillware-0.2.8 → skillware-0.3.1}/skills/finance/wallet_screening/skill.py +0 -0
  66. {skillware-0.2.8 → skillware-0.3.1}/skills/office/__init__.py +0 -0
  67. {skillware-0.2.8 → skillware-0.3.1}/skills/office/pdf_form_filler/__init__.py +0 -0
  68. {skillware-0.2.8 → skillware-0.3.1}/skills/office/pdf_form_filler/card.json +0 -0
  69. {skillware-0.2.8 → skillware-0.3.1}/skills/office/pdf_form_filler/instructions.md +0 -0
  70. {skillware-0.2.8 → skillware-0.3.1}/skills/office/pdf_form_filler/manifest.yaml +0 -0
  71. {skillware-0.2.8 → skillware-0.3.1}/skills/office/pdf_form_filler/skill.py +0 -0
  72. {skillware-0.2.8 → skillware-0.3.1}/skills/office/pdf_form_filler/utils.py +0 -0
  73. {skillware-0.2.8 → skillware-0.3.1}/skills/optimization/__init__.py +0 -0
  74. {skillware-0.2.8 → skillware-0.3.1}/skills/optimization/prompt_rewriter/__init__.py +0 -0
  75. {skillware-0.2.8 → skillware-0.3.1}/skills/optimization/prompt_rewriter/card.json +0 -0
  76. {skillware-0.2.8 → skillware-0.3.1}/skills/optimization/prompt_rewriter/instructions.md +0 -0
  77. {skillware-0.2.8 → skillware-0.3.1}/skills/optimization/prompt_rewriter/manifest.yaml +0 -0
  78. {skillware-0.2.8 → skillware-0.3.1}/skills/optimization/prompt_rewriter/skill.py +0 -0
  79. {skillware-0.2.8 → skillware-0.3.1}/skillware/__init__.py +0 -0
  80. {skillware-0.2.8 → skillware-0.3.1}/skillware/core/__init__.py +0 -0
  81. {skillware-0.2.8 → skillware-0.3.1}/skillware/core/base_skill.py +0 -0
  82. {skillware-0.2.8 → skillware-0.3.1}/skillware/core/env.py +0 -0
  83. {skillware-0.2.8 → skillware-0.3.1}/skillware.egg-info/dependency_links.txt +0 -0
  84. {skillware-0.2.8 → skillware-0.3.1}/skillware.egg-info/top_level.txt +0 -0
  85. {skillware-0.2.8 → skillware-0.3.1}/tests/test_loader.py +0 -0
  86. {skillware-0.2.8 → skillware-0.3.1}/tests/test_mica_module.py +0 -0
  87. {skillware-0.2.8 → skillware-0.3.1}/tests/test_skill_issuer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skillware
3
- Version: 0.2.8
3
+ Version: 0.3.1
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
@@ -35,15 +35,29 @@ Description-Content-Type: text/markdown
35
35
  License-File: LICENSE
36
36
  Requires-Dist: requests
37
37
  Requires-Dist: pyyaml
38
- Requires-Dist: anthropic
39
- Requires-Dist: google-generativeai
40
- Requires-Dist: pymupdf
38
+ Requires-Dist: python-dotenv
41
39
  Requires-Dist: beautifulsoup4
42
40
  Provides-Extra: dev
43
41
  Requires-Dist: pytest; extra == "dev"
44
42
  Requires-Dist: pytest-mock; extra == "dev"
45
43
  Requires-Dist: flake8; extra == "dev"
46
44
  Requires-Dist: black; extra == "dev"
45
+ Provides-Extra: cli
46
+ Requires-Dist: rich>=13.0; extra == "cli"
47
+ Provides-Extra: gemini
48
+ Requires-Dist: google-genai; extra == "gemini"
49
+ Provides-Extra: claude
50
+ Requires-Dist: anthropic; extra == "claude"
51
+ Provides-Extra: openai
52
+ Requires-Dist: openai; extra == "openai"
53
+ Provides-Extra: office
54
+ Requires-Dist: pymupdf; extra == "office"
55
+ Provides-Extra: all
56
+ Requires-Dist: rich>=13.0; extra == "all"
57
+ Requires-Dist: google-genai; extra == "all"
58
+ Requires-Dist: anthropic; extra == "all"
59
+ Requires-Dist: openai; extra == "all"
60
+ Requires-Dist: pymupdf; extra == "all"
47
61
  Dynamic: license-file
48
62
 
49
63
  <div align="center">
@@ -89,27 +103,34 @@ A **Skill** in this framework provides everything an Agent needs to master a dom
89
103
  3. **Governance**: Constitution and safety boundaries.
90
104
  4. **Interface**: Standardized schemas for LLM tool calling.
91
105
 
106
+ ### Skill library
107
+
108
+ Browse capabilities by category in the [Skill library](docs/skills/README.md).
109
+
92
110
  ## Architecture
93
111
 
94
- This repository is organized into a core framework, a registry of skills, and documentation.
112
+ This repository is organized into a core framework, a registry of skills, and
113
+ documentation. Runnable provider scripts are indexed in
114
+ [examples/README.md](examples/README.md).
95
115
 
96
116
  ```text
97
117
  Skillware/
98
- ├── docs/ # Comprehensive Documentation & Usage Guides
99
- ├── examples/ # Reference Implementations
100
- │ └── basic_agent.py # Example showing SkillLoader integration
118
+ ├── docs/ # Introduction, testing, skill catalog, usage guides (docs/usage/)
119
+ ├── examples/ # Provider reference scripts (Gemini, Claude, OpenAI, Ollama, ...)
101
120
  ├── skills/ # Skill Registry
102
121
  │ └── category/ # Domain boundaries (e.g., finance)
103
122
  │ └── skill_name/ # The Skill bundle
104
123
  │ ├── manifest.yaml # Definition, schema, and constitution
105
124
  │ ├── skill.py # Executable Python logic
106
125
  │ ├── instructions.md # Cognitive map for the LLM
107
- │ └── test_skill.py # Unit tests & schema validation
126
+ │ ├── card.json # Optional UI presentation metadata
127
+ │ └── test_skill.py # Unit tests and schema validation
108
128
  ├── skillware/ # Core Framework Package
129
+ │ ├── cli.py # Command-line interface
109
130
  │ └── core/
110
131
  │ ├── base_skill.py # Abstract Base Class for skills
111
132
  │ ├── env.py # Environment Management
112
- │ └── loader.py # Universal Skill Loader & Model Adapter
133
+ │ └── loader.py # Universal Skill Loader and Model Adapter
113
134
  ├── templates/ # Boilerplate templates for new skills
114
135
  │ └── python_skill/ # Standard template with required files
115
136
  └── tests/ # Automated test suite
@@ -135,7 +156,16 @@ pip install -e .
135
156
 
136
157
  > **Note**: Individual skills may have their own dependencies. The `SkillLoader` validates `manifest.yaml` and warns of missing packages (e.g., `requests`, `pandas`) upon loading a skill.
137
158
 
138
- ### 2. Configuration
159
+ ### 2. Verify your installation
160
+
161
+ ```bash
162
+ pip install "skillware[cli]"
163
+ skillware list
164
+ ```
165
+
166
+ This prints a table of all locally available skills and confirms the install and path resolution are working.
167
+
168
+ ### 3. Configuration
139
169
 
140
170
  Create a `.env` file with your API keys (e.g., Google Gemini API Key):
141
171
 
@@ -143,10 +173,14 @@ Create a `.env` file with your API keys (e.g., Google Gemini API Key):
143
173
  GOOGLE_API_KEY="your_key"
144
174
  ```
145
175
 
146
- ### 3. Usage Example (Gemini)
176
+ ### 4. Usage Example (Gemini)
177
+
178
+ This example requires the Google SDK optional extra: `pip install "skillware[gemini]"` (local dev: `pip install -e ".[gemini]"`). See the [Gemini usage guide](docs/usage/gemini.md) for setup details.
147
179
 
148
180
  ```python
149
- import google.generativeai as genai
181
+ import os
182
+ import google.genai as genai
183
+ from google.genai import types
150
184
  from skillware.core.loader import SkillLoader
151
185
  from skillware.core.env import load_env_file
152
186
 
@@ -155,35 +189,63 @@ load_env_file()
155
189
 
156
190
  # 1. Load the Skill from the Registry
157
191
  # The loader reads the code, manifest, and instructions automatically
158
- skill_bundle = SkillLoader.load_skill("category/skill_name") # see docs/usage/README.md for path search order
159
-
160
- # 2. Model & Chat Setup
161
- model = genai.GenerativeModel(
162
- 'gemini-2.5-flash',
163
- tools=[SkillLoader.to_gemini_tool(skill_bundle)], # The "Adapter"
164
- system_instruction=skill_bundle['instructions'] # The "Mind"
192
+ skill_bundle = SkillLoader.load_skill("finance/wallet_screening")
193
+ skill = skill_bundle["module"].WalletScreeningSkill(
194
+ config={"ETHERSCAN_API_KEY": os.environ.get("ETHERSCAN_API_KEY")}
165
195
  )
166
- chat = model.start_chat(enable_automatic_function_calling=True)
196
+
197
+ # 2. Client & Tool Setup
198
+ client = genai.Client()
199
+ tool = SkillLoader.to_gemini_tool(skill_bundle) # The "Adapter"
200
+ system_instruction = skill_bundle['instructions'] # The "Mind"
167
201
 
168
202
  # 3. Agent Loop
169
- # The SDK handles the loop: model -> tool call -> execution -> result -> model reply.
170
- response = chat.send_message("Screen wallet 0xd8dA... for risks.")
171
- print(response.text)
203
+ response = client.models.generate_content(
204
+ model="gemini-2.5-flash",
205
+ contents="Screen wallet 0xd8dA... for risks.",
206
+ config=types.GenerateContentConfig(
207
+ tools=[tool],
208
+ system_instruction=system_instruction,
209
+ ),
210
+ )
211
+
212
+ for part in response.candidates[0].content.parts:
213
+ if part.function_call:
214
+ result = skill.execute(dict(part.function_call.args))
215
+ follow_up = client.models.generate_content(
216
+ model="gemini-2.5-flash",
217
+ contents=[
218
+ "Use this tool result to answer the original request.",
219
+ {
220
+ "function_response": {
221
+ "name": part.function_call.name,
222
+ "response": {"result": result},
223
+ }
224
+ },
225
+ ],
226
+ config=types.GenerateContentConfig(
227
+ tools=[tool],
228
+ system_instruction=system_instruction,
229
+ ),
230
+ )
231
+ print(follow_up.text)
232
+ else:
233
+ print(part.text)
172
234
  ```
173
235
 
236
+ For other providers and shared integration patterns, see the [usage guides index](docs/usage/README.md), [agent loops](docs/usage/agent_loops.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), [API keys for skills](docs/usage/api_keys.md), and the [skill usage template](docs/usage/skill_usage_template.md) for contributors.
237
+
174
238
  ## Documentation
175
239
 
176
- * **[Core Logic & Philosophy](docs/introduction.md)**: Details on how Skillware decouples Logic, Cognition, and Governance.
177
- * **[Testing Guidelines](docs/TESTING.md)**: Instructions for validating skills and checking local coverage.
178
- * **[Usage guides](docs/usage/README.md)**: Provider adapters and navigation to integration docs.
179
- * **[Agent loops](docs/usage/agent_loops.md)**: Shared load, tool-call, and `execute` pattern across providers.
180
- * **[Usage Guide: Gemini](docs/usage/gemini.md)**: Integration with Google's GenAI SDK.
181
- * **[Usage Guide: Claude](docs/usage/claude.md)**: Integration with Anthropic's SDK.
182
- * **[Usage Guide: OpenAI](docs/usage/openai.md)**: Integration with OpenAI Chat Completions tool calling.
183
- * **[Usage Guide: DeepSeek](docs/usage/deepseek.md)**: Integration with the DeepSeek API via `to_deepseek_tool()`.
184
- * **[Usage Guide: Ollama](docs/usage/ollama.md)**: Native integration for local models via Ollama.
185
- * **[API Keys for Skills](docs/usage/api_keys.md)**: Environment variables, cloud/CI setup, and security for skills that call external APIs.
186
- * **[Skill Library](docs/skills/README.md)**: Available capabilities.
240
+ | Topic | Link |
241
+ | :--- | :--- |
242
+ | Introduction | [docs/introduction.md](docs/introduction.md) |
243
+ | Testing | [docs/TESTING.md](docs/TESTING.md) |
244
+ | Skill library | [docs/skills/README.md](docs/skills/README.md) |
245
+ | 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) |
246
+ | Examples index | [examples/README.md](examples/README.md) |
247
+ | CLI | [docs/usage/cli.md](docs/usage/cli.md) |
248
+ | Contributing | [CONTRIBUTING.md](CONTRIBUTING.md) · [agent workflow](docs/contributing/ai_native_workflow.md) |
187
249
 
188
250
  ## Contributing
189
251
 
@@ -41,27 +41,34 @@ A **Skill** in this framework provides everything an Agent needs to master a dom
41
41
  3. **Governance**: Constitution and safety boundaries.
42
42
  4. **Interface**: Standardized schemas for LLM tool calling.
43
43
 
44
+ ### Skill library
45
+
46
+ Browse capabilities by category in the [Skill library](docs/skills/README.md).
47
+
44
48
  ## Architecture
45
49
 
46
- This repository is organized into a core framework, a registry of skills, and documentation.
50
+ This repository is organized into a core framework, a registry of skills, and
51
+ documentation. Runnable provider scripts are indexed in
52
+ [examples/README.md](examples/README.md).
47
53
 
48
54
  ```text
49
55
  Skillware/
50
- ├── docs/ # Comprehensive Documentation & Usage Guides
51
- ├── examples/ # Reference Implementations
52
- │ └── basic_agent.py # Example showing SkillLoader integration
56
+ ├── docs/ # Introduction, testing, skill catalog, usage guides (docs/usage/)
57
+ ├── examples/ # Provider reference scripts (Gemini, Claude, OpenAI, Ollama, ...)
53
58
  ├── skills/ # Skill Registry
54
59
  │ └── category/ # Domain boundaries (e.g., finance)
55
60
  │ └── skill_name/ # The Skill bundle
56
61
  │ ├── manifest.yaml # Definition, schema, and constitution
57
62
  │ ├── skill.py # Executable Python logic
58
63
  │ ├── instructions.md # Cognitive map for the LLM
59
- │ └── test_skill.py # Unit tests & schema validation
64
+ │ ├── card.json # Optional UI presentation metadata
65
+ │ └── test_skill.py # Unit tests and schema validation
60
66
  ├── skillware/ # Core Framework Package
67
+ │ ├── cli.py # Command-line interface
61
68
  │ └── core/
62
69
  │ ├── base_skill.py # Abstract Base Class for skills
63
70
  │ ├── env.py # Environment Management
64
- │ └── loader.py # Universal Skill Loader & Model Adapter
71
+ │ └── loader.py # Universal Skill Loader and Model Adapter
65
72
  ├── templates/ # Boilerplate templates for new skills
66
73
  │ └── python_skill/ # Standard template with required files
67
74
  └── tests/ # Automated test suite
@@ -87,7 +94,16 @@ pip install -e .
87
94
 
88
95
  > **Note**: Individual skills may have their own dependencies. The `SkillLoader` validates `manifest.yaml` and warns of missing packages (e.g., `requests`, `pandas`) upon loading a skill.
89
96
 
90
- ### 2. Configuration
97
+ ### 2. Verify your installation
98
+
99
+ ```bash
100
+ pip install "skillware[cli]"
101
+ skillware list
102
+ ```
103
+
104
+ This prints a table of all locally available skills and confirms the install and path resolution are working.
105
+
106
+ ### 3. Configuration
91
107
 
92
108
  Create a `.env` file with your API keys (e.g., Google Gemini API Key):
93
109
 
@@ -95,10 +111,14 @@ Create a `.env` file with your API keys (e.g., Google Gemini API Key):
95
111
  GOOGLE_API_KEY="your_key"
96
112
  ```
97
113
 
98
- ### 3. Usage Example (Gemini)
114
+ ### 4. Usage Example (Gemini)
115
+
116
+ This example requires the Google SDK optional extra: `pip install "skillware[gemini]"` (local dev: `pip install -e ".[gemini]"`). See the [Gemini usage guide](docs/usage/gemini.md) for setup details.
99
117
 
100
118
  ```python
101
- import google.generativeai as genai
119
+ import os
120
+ import google.genai as genai
121
+ from google.genai import types
102
122
  from skillware.core.loader import SkillLoader
103
123
  from skillware.core.env import load_env_file
104
124
 
@@ -107,35 +127,63 @@ load_env_file()
107
127
 
108
128
  # 1. Load the Skill from the Registry
109
129
  # The loader reads the code, manifest, and instructions automatically
110
- skill_bundle = SkillLoader.load_skill("category/skill_name") # see docs/usage/README.md for path search order
111
-
112
- # 2. Model & Chat Setup
113
- model = genai.GenerativeModel(
114
- 'gemini-2.5-flash',
115
- tools=[SkillLoader.to_gemini_tool(skill_bundle)], # The "Adapter"
116
- system_instruction=skill_bundle['instructions'] # The "Mind"
130
+ skill_bundle = SkillLoader.load_skill("finance/wallet_screening")
131
+ skill = skill_bundle["module"].WalletScreeningSkill(
132
+ config={"ETHERSCAN_API_KEY": os.environ.get("ETHERSCAN_API_KEY")}
117
133
  )
118
- chat = model.start_chat(enable_automatic_function_calling=True)
134
+
135
+ # 2. Client & Tool Setup
136
+ client = genai.Client()
137
+ tool = SkillLoader.to_gemini_tool(skill_bundle) # The "Adapter"
138
+ system_instruction = skill_bundle['instructions'] # The "Mind"
119
139
 
120
140
  # 3. Agent Loop
121
- # The SDK handles the loop: model -> tool call -> execution -> result -> model reply.
122
- response = chat.send_message("Screen wallet 0xd8dA... for risks.")
123
- print(response.text)
141
+ response = client.models.generate_content(
142
+ model="gemini-2.5-flash",
143
+ contents="Screen wallet 0xd8dA... for risks.",
144
+ config=types.GenerateContentConfig(
145
+ tools=[tool],
146
+ system_instruction=system_instruction,
147
+ ),
148
+ )
149
+
150
+ for part in response.candidates[0].content.parts:
151
+ if part.function_call:
152
+ result = skill.execute(dict(part.function_call.args))
153
+ follow_up = client.models.generate_content(
154
+ model="gemini-2.5-flash",
155
+ contents=[
156
+ "Use this tool result to answer the original request.",
157
+ {
158
+ "function_response": {
159
+ "name": part.function_call.name,
160
+ "response": {"result": result},
161
+ }
162
+ },
163
+ ],
164
+ config=types.GenerateContentConfig(
165
+ tools=[tool],
166
+ system_instruction=system_instruction,
167
+ ),
168
+ )
169
+ print(follow_up.text)
170
+ else:
171
+ print(part.text)
124
172
  ```
125
173
 
174
+ For other providers and shared integration patterns, see the [usage guides index](docs/usage/README.md), [agent loops](docs/usage/agent_loops.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), [API keys for skills](docs/usage/api_keys.md), and the [skill usage template](docs/usage/skill_usage_template.md) for contributors.
175
+
126
176
  ## Documentation
127
177
 
128
- * **[Core Logic & Philosophy](docs/introduction.md)**: Details on how Skillware decouples Logic, Cognition, and Governance.
129
- * **[Testing Guidelines](docs/TESTING.md)**: Instructions for validating skills and checking local coverage.
130
- * **[Usage guides](docs/usage/README.md)**: Provider adapters and navigation to integration docs.
131
- * **[Agent loops](docs/usage/agent_loops.md)**: Shared load, tool-call, and `execute` pattern across providers.
132
- * **[Usage Guide: Gemini](docs/usage/gemini.md)**: Integration with Google's GenAI SDK.
133
- * **[Usage Guide: Claude](docs/usage/claude.md)**: Integration with Anthropic's SDK.
134
- * **[Usage Guide: OpenAI](docs/usage/openai.md)**: Integration with OpenAI Chat Completions tool calling.
135
- * **[Usage Guide: DeepSeek](docs/usage/deepseek.md)**: Integration with the DeepSeek API via `to_deepseek_tool()`.
136
- * **[Usage Guide: Ollama](docs/usage/ollama.md)**: Native integration for local models via Ollama.
137
- * **[API Keys for Skills](docs/usage/api_keys.md)**: Environment variables, cloud/CI setup, and security for skills that call external APIs.
138
- * **[Skill Library](docs/skills/README.md)**: Available capabilities.
178
+ | Topic | Link |
179
+ | :--- | :--- |
180
+ | Introduction | [docs/introduction.md](docs/introduction.md) |
181
+ | Testing | [docs/TESTING.md](docs/TESTING.md) |
182
+ | Skill library | [docs/skills/README.md](docs/skills/README.md) |
183
+ | 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) |
184
+ | Examples index | [examples/README.md](examples/README.md) |
185
+ | CLI | [docs/usage/cli.md](docs/usage/cli.md) |
186
+ | Contributing | [CONTRIBUTING.md](CONTRIBUTING.md) · [agent workflow](docs/contributing/ai_native_workflow.md) |
139
187
 
140
188
  ## Contributing
141
189
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "skillware"
7
- version = "0.2.8"
7
+ version = "0.3.1"
8
8
  description = "A framework for modular, self-contained AI skills."
9
9
  readme = "README.md"
10
10
  authors = [
@@ -20,13 +20,14 @@ classifiers = [
20
20
  dependencies = [
21
21
  "requests",
22
22
  "pyyaml",
23
- "anthropic",
24
- "google-generativeai",
25
- "pymupdf",
23
+ "python-dotenv",
26
24
  "beautifulsoup4",
27
25
  ]
28
26
  requires-python = ">=3.10"
29
27
 
28
+ [project.scripts]
29
+ skillware = "skillware.cli:main"
30
+
30
31
  [project.optional-dependencies]
31
32
  dev = [
32
33
  "pytest",
@@ -34,6 +35,28 @@ dev = [
34
35
  "flake8",
35
36
  "black",
36
37
  ]
38
+ cli = [
39
+ "rich>=13.0",
40
+ ]
41
+ gemini = [
42
+ "google-genai",
43
+ ]
44
+ claude = [
45
+ "anthropic",
46
+ ]
47
+ openai = [
48
+ "openai",
49
+ ]
50
+ office = [
51
+ "pymupdf",
52
+ ]
53
+ all = [
54
+ "rich>=13.0",
55
+ "google-genai",
56
+ "anthropic",
57
+ "openai",
58
+ "pymupdf",
59
+ ]
37
60
 
38
61
  [tool.setuptools]
39
62
  include-package-data = true
@@ -21,7 +21,7 @@ parameters:
21
21
  required:
22
22
  - user_prompt
23
23
  requirements:
24
- - google.generativeai
24
+ - google-genai
25
25
  constitution: |
26
26
  1. COMPLIANCE: Do not invent or hallucinate financial regulations. Base all enforcement strictly on the provided MiCA corpus blocks.
27
27
  2. FOCUS: Act exclusively as a compliance firewall and RAG engine; retrieve relevant chunks incrementally.
@@ -1,7 +1,7 @@
1
1
  import json
2
2
  import os
3
3
  from typing import Any, Dict, List
4
- import google.generativeai as genai
4
+
5
5
  from skillware.core.base_skill import BaseSkill
6
6
 
7
7
 
@@ -207,11 +207,43 @@ class MiCAModuleSkill(BaseSkill):
207
207
  """
208
208
 
209
209
  try:
210
- model = genai.GenerativeModel(model_name)
211
- resp = model.generate_content(
212
- prompt_payload,
213
- generation_config=genai.GenerationConfig(
214
- response_mime_type="application/json", temperature=0.0
210
+ import google.genai as genai
211
+ from google.genai import types
212
+ except ImportError:
213
+ return {
214
+ "policy_status": "CAUTION",
215
+ "gemini_evaluator_feedback": {
216
+ "grade": "N/A",
217
+ "holes_found": "google-genai is not installed.",
218
+ "suggestion": "Proceed manually integrating the extracted logic.",
219
+ },
220
+ "final_context_for_agent": (
221
+ f"Output your final answer seamlessly integrating and adhering to these MiCA rules:\n{context}"
222
+ ),
223
+ }
224
+
225
+ api_key = os.environ.get("GOOGLE_API_KEY")
226
+ if not api_key:
227
+ return {
228
+ "policy_status": "CAUTION",
229
+ "gemini_evaluator_feedback": {
230
+ "grade": "N/A",
231
+ "holes_found": "GOOGLE_API_KEY is not configured.",
232
+ "suggestion": "Proceed manually integrating the extracted logic.",
233
+ },
234
+ "final_context_for_agent": (
235
+ f"Output your final answer seamlessly integrating and adhering to these MiCA rules:\n{context}"
236
+ ),
237
+ }
238
+
239
+ try:
240
+ client = genai.Client(api_key=api_key)
241
+ resp = client.models.generate_content(
242
+ model=model_name,
243
+ contents=prompt_payload,
244
+ config=types.GenerateContentConfig(
245
+ response_mime_type="application/json",
246
+ temperature=0.0,
215
247
  ),
216
248
  )
217
249
  return json.loads(resp.text)
@@ -11,9 +11,11 @@ from bs4 import BeautifulSoup
11
11
  from skillware.core.base_skill import BaseSkill
12
12
 
13
13
  try:
14
- import google.generativeai as genai
14
+ import google.genai as genai
15
+ from google.genai import types
15
16
  except ImportError: # pragma: no cover - dependency is optional at runtime
16
17
  genai = None
18
+ types = None
17
19
 
18
20
 
19
21
  class TOSEvaluatorSkill(BaseSkill):
@@ -458,14 +460,13 @@ class TOSEvaluatorSkill(BaseSkill):
458
460
  "status": "skipped",
459
461
  "reason": f"Unsupported llm_provider '{normalized['llm_provider']}'.",
460
462
  }
461
- if genai is None:
462
- return {"status": "skipped", "reason": "google-generativeai is not installed."}
463
+ if genai is None or types is None:
464
+ return {"status": "skipped", "reason": "google-genai is not installed."}
463
465
 
464
466
  api_key = os.environ.get("GOOGLE_API_KEY")
465
467
  if not api_key:
466
468
  return {"status": "skipped", "reason": "GOOGLE_API_KEY is not configured."}
467
469
 
468
- genai.configure(api_key=api_key)
469
470
  prompt = {
470
471
  "target_url": normalized["target_url"],
471
472
  "intended_action": normalized["intended_action"],
@@ -479,11 +480,13 @@ class TOSEvaluatorSkill(BaseSkill):
479
480
  }
480
481
 
481
482
  try:
482
- model = genai.GenerativeModel(normalized["llm_model"])
483
- response = model.generate_content(
484
- json.dumps(prompt, ensure_ascii=True),
485
- generation_config=genai.GenerationConfig(
486
- response_mime_type="application/json", temperature=0.0
483
+ client = genai.Client(api_key=api_key)
484
+ response = client.models.generate_content(
485
+ model=normalized["llm_model"],
486
+ contents=json.dumps(prompt, ensure_ascii=True),
487
+ config=types.GenerateContentConfig(
488
+ response_mime_type="application/json",
489
+ temperature=0.0,
487
490
  ),
488
491
  )
489
492
  parsed = json.loads(response.text)
@@ -0,0 +1,3 @@
1
+ from .skill import NoveltyExtractor
2
+
3
+ __all__ = ["NoveltyExtractor"]
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "Novelty Extractor",
3
+ "description": "Filters a text dataset by semantic novelty, retaining only chunks that carry new information above a configurable threshold.",
4
+ "icon": "filter",
5
+ "ui_schema": {
6
+ "dataset_chunk": {
7
+ "ui:widget": "textarea",
8
+ "ui:placeholder": "Paste your raw text dataset here..."
9
+ },
10
+ "novelty_threshold": {
11
+ "ui:widget": "range",
12
+ "ui:options": {
13
+ "min": 0.0,
14
+ "max": 1.0,
15
+ "step": 0.05
16
+ }
17
+ },
18
+ "baseline_chunks": {
19
+ "ui:widget": "textarea",
20
+ "ui:placeholder": "Optional. Paste distilled_content from a previous call here..."
21
+ },
22
+ "chunk_strategy": {
23
+ "ui:widget": "select",
24
+ "ui:options": {
25
+ "enumOptions": [
26
+ {"value": "paragraph", "label": "Paragraph"},
27
+ {"value": "sentence", "label": "Sentence"}
28
+ ]
29
+ }
30
+ }
31
+ },
32
+ "issuer": {
33
+ "name": "Martin Rizzo Lozano",
34
+ "email": "rizzolozanomartin@gmail.com",
35
+ "github": "rizzoMartin"
36
+ }
37
+ }
@@ -0,0 +1,60 @@
1
+ # Novelty Extractor
2
+
3
+ You are an agent equipped with the Novelty Extractor skill. This skill filters
4
+ large text datasets by semantic similarity, retaining only chunks that carry
5
+ genuinely new information.
6
+
7
+ ## When to invoke this skill
8
+
9
+ Invoke `data_engineering/novelty_extractor` when:
10
+
11
+ - You need to distill a large corpus into high-signal content before passing
12
+ it to a model or storing it.
13
+ - You are processing a dataset in multiple turns and want to avoid redundancy
14
+ across turns by passing prior output as `baseline_chunks`.
15
+ - A user asks you to remove repetitive or redundant content from a document
16
+ or dataset.
17
+
18
+ ## Parameters
19
+
20
+ - `dataset_chunk` (required): The raw text to filter.
21
+ - `novelty_threshold` (required): A float between 0.0 and 1.0. Chunks with
22
+ maximum cosine similarity to already-seen content below this value are kept.
23
+ Lower values mean stricter filtering. A value of 0.85 is a sensible default
24
+ for most corpora.
25
+ - `baseline_chunks` (optional): Text from a previous call's `distilled_content`.
26
+ Pass this to filter consistently across multiple turns.
27
+ - `chunk_strategy` (optional): How to split the input. Use `"paragraph"`
28
+ (default) for documents with clear paragraph breaks, or `"sentence"` for
29
+ denser text.
30
+
31
+ ## Interpreting the output
32
+
33
+ - `distilled_content`: The filtered text. Pass this to downstream tasks or
34
+ store it as the new baseline for the next turn.
35
+ - `compression_ratio`: The percentage of input chunks that were dropped. A
36
+ high ratio (above 80%) may indicate the threshold is too strict or the
37
+ input is highly repetitive.
38
+ - `redundant_chunks_dropped`: The raw count of discarded chunks. Use this
39
+ to audit filtering behavior.
40
+
41
+ ## Handling edge cases
42
+
43
+ - If `distilled_content` is empty and no error is returned, all input chunks
44
+ were too similar to the baseline. Consider lowering `novelty_threshold`.
45
+ - If an `error` key is present in the output, the skill encountered an
46
+ unexpected failure. Inspect the value and retry with sanitized input.
47
+ - The first call without a baseline always keeps the first chunk regardless
48
+ of threshold, since there is nothing to compare against.
49
+
50
+ ## Multi-turn example
51
+
52
+ Turn 1: pass the first batch without baseline.
53
+ Turn 2: pass the next batch with `baseline_chunks` set to the previous
54
+ `distilled_content`.
55
+ Repeat until the full corpus is processed.
56
+
57
+ Note: the skill only filters each batch against the provided baseline. It does
58
+ not accumulate results across turns automatically. The caller is responsible
59
+ for concatenating `distilled_content` from each turn to build the full
60
+ distilled dataset.