vulca 0.2.0__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.
- vulca-0.2.0/.gitignore +254 -0
- vulca-0.2.0/PKG-INFO +142 -0
- vulca-0.2.0/README.md +103 -0
- vulca-0.2.0/pyproject.toml +70 -0
- vulca-0.2.0/src/vulca/__init__.py +42 -0
- vulca-0.2.0/src/vulca/__main__.py +5 -0
- vulca-0.2.0/src/vulca/_dimensions.py +82 -0
- vulca-0.2.0/src/vulca/_engine.py +200 -0
- vulca-0.2.0/src/vulca/_image.py +42 -0
- vulca-0.2.0/src/vulca/_intent.py +95 -0
- vulca-0.2.0/src/vulca/_parse.py +54 -0
- vulca-0.2.0/src/vulca/_skills.py +104 -0
- vulca-0.2.0/src/vulca/_version.py +1 -0
- vulca-0.2.0/src/vulca/_vlm.py +249 -0
- vulca-0.2.0/src/vulca/cli.py +278 -0
- vulca-0.2.0/src/vulca/create.py +223 -0
- vulca-0.2.0/src/vulca/cultural/__init__.py +38 -0
- vulca-0.2.0/src/vulca/cultural/data/traditions/_template.yaml +50 -0
- vulca-0.2.0/src/vulca/cultural/data/traditions/african_traditional.yaml +83 -0
- vulca-0.2.0/src/vulca/cultural/data/traditions/chinese_gongbi.yaml +77 -0
- vulca-0.2.0/src/vulca/cultural/data/traditions/chinese_xieyi.yaml +86 -0
- vulca-0.2.0/src/vulca/cultural/data/traditions/default.yaml +74 -0
- vulca-0.2.0/src/vulca/cultural/data/traditions/islamic_geometric.yaml +83 -0
- vulca-0.2.0/src/vulca/cultural/data/traditions/japanese_traditional.yaml +83 -0
- vulca-0.2.0/src/vulca/cultural/data/traditions/schema.json +134 -0
- vulca-0.2.0/src/vulca/cultural/data/traditions/south_asian.yaml +83 -0
- vulca-0.2.0/src/vulca/cultural/data/traditions/watercolor.yaml +83 -0
- vulca-0.2.0/src/vulca/cultural/data/traditions/western_academic.yaml +74 -0
- vulca-0.2.0/src/vulca/cultural/loader.py +264 -0
- vulca-0.2.0/src/vulca/cultural/types.py +107 -0
- vulca-0.2.0/src/vulca/evaluate.py +119 -0
- vulca-0.2.0/src/vulca/intent/__init__.py +11 -0
- vulca-0.2.0/src/vulca/intent/agent.py +148 -0
- vulca-0.2.0/src/vulca/intent/types.py +27 -0
- vulca-0.2.0/src/vulca/mcp_server.py +136 -0
- vulca-0.2.0/src/vulca/media/__init__.py +1 -0
- vulca-0.2.0/src/vulca/media/types.py +128 -0
- vulca-0.2.0/src/vulca/pipeline/__init__.py +33 -0
- vulca-0.2.0/src/vulca/pipeline/engine.py +362 -0
- vulca-0.2.0/src/vulca/pipeline/hooks.py +55 -0
- vulca-0.2.0/src/vulca/pipeline/node.py +54 -0
- vulca-0.2.0/src/vulca/pipeline/nodes/__init__.py +7 -0
- vulca-0.2.0/src/vulca/pipeline/nodes/decide.py +36 -0
- vulca-0.2.0/src/vulca/pipeline/nodes/evaluate.py +94 -0
- vulca-0.2.0/src/vulca/pipeline/nodes/generate.py +124 -0
- vulca-0.2.0/src/vulca/pipeline/templates.py +47 -0
- vulca-0.2.0/src/vulca/pipeline/types.py +191 -0
- vulca-0.2.0/src/vulca/scoring/__init__.py +28 -0
- vulca-0.2.0/src/vulca/scoring/config.py +8 -0
- vulca-0.2.0/src/vulca/scoring/model_router.py +137 -0
- vulca-0.2.0/src/vulca/scoring/types.py +146 -0
- vulca-0.2.0/src/vulca/scoring/vlm.py +10 -0
- vulca-0.2.0/src/vulca/session.py +111 -0
- vulca-0.2.0/src/vulca/storage/__init__.py +11 -0
- vulca-0.2.0/src/vulca/storage/jsonl.py +162 -0
- vulca-0.2.0/src/vulca/storage/protocol.py +56 -0
- vulca-0.2.0/src/vulca/types.py +148 -0
- vulca-0.2.0/tests/conftest.py +11 -0
- vulca-0.2.0/tests/test_cli.py +111 -0
- vulca-0.2.0/tests/test_create_hitl.py +96 -0
- vulca-0.2.0/tests/test_cultural_loader.py +130 -0
- vulca-0.2.0/tests/test_evaluate.py +332 -0
- vulca-0.2.0/tests/test_mcp_server.py +72 -0
- vulca-0.2.0/tests/test_package.py +579 -0
- vulca-0.2.0/tests/test_pipeline_engine.py +481 -0
- vulca-0.2.0/tests/test_scoring.py +88 -0
- vulca-0.2.0/tests/test_storage.py +178 -0
- vulca-0.2.0/tests/test_types_unified.py +300 -0
vulca-0.2.0/.gitignore
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
env/
|
|
8
|
+
venv/
|
|
9
|
+
ENV/
|
|
10
|
+
build/
|
|
11
|
+
develop-eggs/
|
|
12
|
+
dist/
|
|
13
|
+
downloads/
|
|
14
|
+
eggs/
|
|
15
|
+
.eggs/
|
|
16
|
+
lib/
|
|
17
|
+
lib64/
|
|
18
|
+
parts/
|
|
19
|
+
sdist/
|
|
20
|
+
var/
|
|
21
|
+
wheels/
|
|
22
|
+
*.egg-info/
|
|
23
|
+
.installed.cfg
|
|
24
|
+
*.egg
|
|
25
|
+
.pytest_cache/
|
|
26
|
+
.coverage
|
|
27
|
+
htmlcov/
|
|
28
|
+
|
|
29
|
+
# Node.js
|
|
30
|
+
node_modules/
|
|
31
|
+
npm-debug.log*
|
|
32
|
+
yarn-debug.log*
|
|
33
|
+
yarn-error.log*
|
|
34
|
+
.pnpm-debug.log*
|
|
35
|
+
|
|
36
|
+
# Environment variables
|
|
37
|
+
.env
|
|
38
|
+
.env.local
|
|
39
|
+
.env.production
|
|
40
|
+
.env.production.local
|
|
41
|
+
.env.development.local
|
|
42
|
+
.env.test.local
|
|
43
|
+
.claude/settings.local.json
|
|
44
|
+
|
|
45
|
+
# IDE
|
|
46
|
+
.vscode/
|
|
47
|
+
.idea/
|
|
48
|
+
*.swp
|
|
49
|
+
*.swo
|
|
50
|
+
*~
|
|
51
|
+
.DS_Store
|
|
52
|
+
|
|
53
|
+
# Database
|
|
54
|
+
*.db
|
|
55
|
+
*.sqlite
|
|
56
|
+
*.sqlite3
|
|
57
|
+
wenxin.db
|
|
58
|
+
|
|
59
|
+
# Logs
|
|
60
|
+
*.log
|
|
61
|
+
logs/
|
|
62
|
+
|
|
63
|
+
# Build outputs
|
|
64
|
+
wenxin-moyun/dist/
|
|
65
|
+
wenxin-moyun/.vite/
|
|
66
|
+
|
|
67
|
+
# Uploads
|
|
68
|
+
uploads/
|
|
69
|
+
*.upload
|
|
70
|
+
|
|
71
|
+
# Docker
|
|
72
|
+
.docker/
|
|
73
|
+
|
|
74
|
+
# Temporary files
|
|
75
|
+
*.tmp
|
|
76
|
+
~$*
|
|
77
|
+
.temp/
|
|
78
|
+
|
|
79
|
+
# Test coverage
|
|
80
|
+
coverage/
|
|
81
|
+
.nyc_output/
|
|
82
|
+
|
|
83
|
+
# Redis
|
|
84
|
+
dump.rdb
|
|
85
|
+
|
|
86
|
+
# Celery
|
|
87
|
+
celerybeat-schedule
|
|
88
|
+
celerybeat.pid
|
|
89
|
+
|
|
90
|
+
# Python virtual environments
|
|
91
|
+
bin/
|
|
92
|
+
include/
|
|
93
|
+
Scripts/
|
|
94
|
+
pyvenv.cfg
|
|
95
|
+
|
|
96
|
+
# Windows reserved names (cannot be used as files)
|
|
97
|
+
nul
|
|
98
|
+
con
|
|
99
|
+
prn
|
|
100
|
+
aux
|
|
101
|
+
com[1-9]
|
|
102
|
+
lpt[1-9]
|
|
103
|
+
**/nul
|
|
104
|
+
**/con
|
|
105
|
+
**/prn
|
|
106
|
+
**/aux
|
|
107
|
+
|
|
108
|
+
# Playwright E2E Testing
|
|
109
|
+
playwright-report/
|
|
110
|
+
test-results/
|
|
111
|
+
test-results.json
|
|
112
|
+
*.trace.zip
|
|
113
|
+
videos/
|
|
114
|
+
screenshots/
|
|
115
|
+
wenxin-moyun/playwright-report/
|
|
116
|
+
wenxin-moyun/test-results/
|
|
117
|
+
wenxin-moyun/test-results.json
|
|
118
|
+
wenxin-moyun/tests/e2e/playwright-report/
|
|
119
|
+
wenxin-moyun/tests/e2e/test-results/
|
|
120
|
+
wenxin-moyun/tests/e2e/test-results.json
|
|
121
|
+
ios26_figma_data.json
|
|
122
|
+
|
|
123
|
+
# Playwright MCP screenshots (debug artifacts)
|
|
124
|
+
.playwright-mcp/
|
|
125
|
+
|
|
126
|
+
# Root-level temporary/binary files
|
|
127
|
+
*.png
|
|
128
|
+
*.jpg
|
|
129
|
+
*.jpeg
|
|
130
|
+
*.exe
|
|
131
|
+
*.msi
|
|
132
|
+
*.zip
|
|
133
|
+
*.docx
|
|
134
|
+
*.aux
|
|
135
|
+
# Allow specific image assets in subdirectories
|
|
136
|
+
!wenxin-moyun/public/**/*.png
|
|
137
|
+
!wenxin-moyun/public/**/*.jpg
|
|
138
|
+
!wenxin-moyun/public/**/*.svg
|
|
139
|
+
!wenxin-moyun/src/**/*.png
|
|
140
|
+
!wenxin-moyun/src/**/*.jpg
|
|
141
|
+
!wenxin-moyun/marketing/**/*.png
|
|
142
|
+
|
|
143
|
+
# Root-level one-off files
|
|
144
|
+
*.html
|
|
145
|
+
!wenxin-moyun/**/*.html
|
|
146
|
+
gmail-*.md
|
|
147
|
+
gmail-*.png
|
|
148
|
+
|
|
149
|
+
# Build/installer artifacts
|
|
150
|
+
*.whl
|
|
151
|
+
cloud_sql_proxy*
|
|
152
|
+
gh.zip
|
|
153
|
+
gh_installer.msi
|
|
154
|
+
|
|
155
|
+
# Prototype temporary outputs
|
|
156
|
+
wenxin-backend/tmp/
|
|
157
|
+
wenxin-backend/venv/
|
|
158
|
+
wenxin-backend/vulca
|
|
159
|
+
wenxin-backend/=*
|
|
160
|
+
|
|
161
|
+
# Prototype runtime artifacts (images + checkpoints + data)
|
|
162
|
+
wenxin-backend/app/prototype/checkpoints/
|
|
163
|
+
wenxin-backend/app/prototype/data/*.jsonl
|
|
164
|
+
wenxin-backend/app/prototype/data/evolved_context.json
|
|
165
|
+
wenxin-backend/app/prototype/data/trajectories/
|
|
166
|
+
wenxin-backend/app/prototype/data/generated/
|
|
167
|
+
wenxin-backend/app/prototype/blind_eval/results/
|
|
168
|
+
|
|
169
|
+
# VULCA unified package virtual environment
|
|
170
|
+
.venv/
|
|
171
|
+
vulca/.venv/
|
|
172
|
+
|
|
173
|
+
# LaTeX artifacts
|
|
174
|
+
*.aux
|
|
175
|
+
*.synctex.gz
|
|
176
|
+
|
|
177
|
+
# Design files
|
|
178
|
+
*.pen
|
|
179
|
+
|
|
180
|
+
# VULCA intro materials (binary)
|
|
181
|
+
wenxin-moyun/docs/*.pdf
|
|
182
|
+
wenxin-moyun/docs/*.docx
|
|
183
|
+
wenxin-moyun/docs/*.zip
|
|
184
|
+
Didot_exhibition_Dec/*.pdf
|
|
185
|
+
network-log.txt
|
|
186
|
+
wenxin-moyun/marketing/exports/
|
|
187
|
+
|
|
188
|
+
# Video production scripts (personal tooling)
|
|
189
|
+
add-audio.sh
|
|
190
|
+
cut-demo-b.sh
|
|
191
|
+
make-video.sh
|
|
192
|
+
produce-demo.sh
|
|
193
|
+
finalize-demo-v3.sh
|
|
194
|
+
finalize-demo-v4.sh
|
|
195
|
+
|
|
196
|
+
# Non-product directories
|
|
197
|
+
Didot_exhibition_Dec/
|
|
198
|
+
EMNLP2025-VULCA/
|
|
199
|
+
ACMMM2026-AgentLoop/
|
|
200
|
+
ios26_assets/
|
|
201
|
+
specs/
|
|
202
|
+
tasks/
|
|
203
|
+
.playwright-mcp/
|
|
204
|
+
wenxinmoyun/
|
|
205
|
+
references/
|
|
206
|
+
benchmark_results/
|
|
207
|
+
huggingface-space/
|
|
208
|
+
monitoring/
|
|
209
|
+
vulca-pkg/
|
|
210
|
+
render.yaml
|
|
211
|
+
AGENTS.md
|
|
212
|
+
.gcloudignore
|
|
213
|
+
.claude/hooks/
|
|
214
|
+
.claude/skills/prospect-manager/
|
|
215
|
+
.claude/skills/northeast-review/
|
|
216
|
+
.github/DEPLOYMENT_LOG.md
|
|
217
|
+
|
|
218
|
+
# Internal deployment scripts
|
|
219
|
+
wenxin-backend/PRODUCTION_INIT.md
|
|
220
|
+
wenxin-backend/cloud_shell_import.md
|
|
221
|
+
wenxin-backend/cloud_shell_upload.sh
|
|
222
|
+
wenxin-backend/cloudbuild-import.yaml
|
|
223
|
+
wenxin-backend/deploy_import.sh
|
|
224
|
+
wenxin-backend/deploy_with_gcloud.bat
|
|
225
|
+
wenxin-backend/fix_import_script.py
|
|
226
|
+
wenxin-backend/run_import_on_cloud.sh
|
|
227
|
+
wenxin-backend/simple_import.sql
|
|
228
|
+
wenxin-backend/start_proxy.bat
|
|
229
|
+
wenxin-backend/.gcloudignore
|
|
230
|
+
wenxin-backend/Dockerfile.import
|
|
231
|
+
wenxin-backend/cloud_sql_proxy*
|
|
232
|
+
wenxin-backend/tests/smoke/test_import_chain.py
|
|
233
|
+
wenxin-moyun/DEPLOYMENT.md
|
|
234
|
+
wenxin-moyun/gcp-alerts.json
|
|
235
|
+
wenxin-moyun/.firebase/
|
|
236
|
+
wenxin-moyun/docs/
|
|
237
|
+
wenxin-moyun/marketing/
|
|
238
|
+
wenxin-moyun/.playwright-mcp/
|
|
239
|
+
wenxin-moyun/gcp-automation.cjs
|
|
240
|
+
wenxin-moyun/manual_test.spec.js
|
|
241
|
+
wenxin-moyun/view_button_test.spec.js
|
|
242
|
+
wenxin-moyun/PERFORMANCE_REPORT.md
|
|
243
|
+
wenxin-moyun/PLAYWRIGHT_TEST_REPORT.md
|
|
244
|
+
wenxin-moyun/FRONTEND_OVERVIEW.md
|
|
245
|
+
wenxin-moyun/README_BROWSER_WARNINGS.md
|
|
246
|
+
wenxin-moyun/nginx.cloud.conf
|
|
247
|
+
wenxin-moyun/Dockerfile.cloud
|
|
248
|
+
wenxin-moyun/Dockerfile.dev
|
|
249
|
+
wenxin-moyun/*.png
|
|
250
|
+
wenxin-moyun/*.txt
|
|
251
|
+
wenxin-backend/OPENAI_BENCHMARK_SUMMARY.md
|
|
252
|
+
wenxin-backend/OPTIMIZATION_SUCCESS_REPORT.md
|
|
253
|
+
wenxin-moyun/tsconfig.app.tsbuildinfo
|
|
254
|
+
wenxin-moyun/vulca_test_results.json
|
vulca-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vulca
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: AI-native creation organism. Create, critique, and evolve cultural art.
|
|
5
|
+
Project-URL: Homepage, https://vulcaart.art
|
|
6
|
+
Project-URL: Documentation, https://github.com/vulca-org/vulca
|
|
7
|
+
Project-URL: Repository, https://github.com/vulca-org/vulca
|
|
8
|
+
Project-URL: Issues, https://github.com/vulca-org/vulca/issues
|
|
9
|
+
Author-email: Yu Haorui <yuhaorui48@gmail.com>
|
|
10
|
+
License-Expression: Apache-2.0
|
|
11
|
+
Keywords: ai,art,creation,cultural,evaluation,pipeline,vlm
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Requires-Dist: httpx>=0.25.0
|
|
25
|
+
Requires-Dist: litellm>=1.0.0
|
|
26
|
+
Requires-Dist: pyyaml>=6.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
30
|
+
Provides-Extra: graph
|
|
31
|
+
Requires-Dist: langgraph>=0.2.0; extra == 'graph'
|
|
32
|
+
Provides-Extra: mcp
|
|
33
|
+
Requires-Dist: fastmcp>=3.0; extra == 'mcp'
|
|
34
|
+
Provides-Extra: pipeline
|
|
35
|
+
Provides-Extra: scout
|
|
36
|
+
Requires-Dist: faiss-cpu>=1.7.0; extra == 'scout'
|
|
37
|
+
Requires-Dist: sentence-transformers>=2.2.2; extra == 'scout'
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
|
|
40
|
+
# VULCA SDK
|
|
41
|
+
|
|
42
|
+
AI-native creation organism. Create, critique, and evolve cultural art.
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install -e vulca/ # From repo root
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
import vulca
|
|
54
|
+
|
|
55
|
+
# Evaluate an artwork (mock mode — no API key needed)
|
|
56
|
+
result = vulca.evaluate("painting.jpg", tradition="chinese_xieyi", mock=True)
|
|
57
|
+
print(result.scores) # {"L1": 0.85, "L2": 0.78, ...}
|
|
58
|
+
print(result.weighted_total) # 0.82
|
|
59
|
+
|
|
60
|
+
# Create through the full pipeline
|
|
61
|
+
result = vulca.create("Misty mountains in ink wash", provider="mock")
|
|
62
|
+
print(result.status) # "completed"
|
|
63
|
+
|
|
64
|
+
# Human-in-the-loop with custom weights
|
|
65
|
+
result = vulca.create(
|
|
66
|
+
"水墨山水",
|
|
67
|
+
provider="mock",
|
|
68
|
+
hitl=True,
|
|
69
|
+
weights={"L1": 0.3, "L2": 0.2, "L3": 0.2, "L4": 0.15, "L5": 0.15},
|
|
70
|
+
)
|
|
71
|
+
# result.status == "waiting_human"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## CLI
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
vulca evaluate painting.jpg --tradition watercolor
|
|
78
|
+
vulca create "Garden scene" --provider mock
|
|
79
|
+
vulca create "水墨山水" --hitl --weights "L1=0.3,L2=0.2,L3=0.2,L4=0.15,L5=0.15"
|
|
80
|
+
vulca traditions # List all 9 cultural traditions
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## MCP Server
|
|
84
|
+
|
|
85
|
+
For AI agents (Claude Code, OpenClaw, etc.):
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
vulca-mcp # Exposes 3 tools: create_artwork, evaluate_artwork, list_traditions
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Architecture
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
vulca/src/vulca/
|
|
95
|
+
├── pipeline/ # Execution engine + 3 built-in nodes + 3 templates
|
|
96
|
+
├── cultural/ # 9 YAML tradition configs with L1-L5 weights
|
|
97
|
+
├── scoring/ # VLM model routing + L1-L5 evaluation types
|
|
98
|
+
├── storage/ # Session/Feedback protocol + JSONL backend
|
|
99
|
+
├── intent/ # Natural language → tradition resolution
|
|
100
|
+
├── media/ # MediaType enum + creation recipe types
|
|
101
|
+
├── _vlm.py # Gemini Vision L1-L5 scoring (core)
|
|
102
|
+
├── _engine.py # Evaluation engine singleton
|
|
103
|
+
├── cli.py # CLI entry point
|
|
104
|
+
└── mcp.py # MCP server entry point
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Cultural Traditions
|
|
108
|
+
|
|
109
|
+
9 traditions with YAML-defined weights, terminology, and taboos:
|
|
110
|
+
|
|
111
|
+
| Tradition | L1 | L2 | L3 | L4 | L5 |
|
|
112
|
+
|-----------|----|----|----|----|-----|
|
|
113
|
+
| Chinese Xieyi | 0.10 | 0.15 | 0.25 | 0.20 | 0.30 |
|
|
114
|
+
| Chinese Gongbi | 0.15 | 0.30 | 0.25 | 0.15 | 0.15 |
|
|
115
|
+
| Japanese Traditional | 0.15 | 0.20 | 0.20 | 0.20 | 0.25 |
|
|
116
|
+
| Western Academic | 0.20 | 0.25 | 0.15 | 0.25 | 0.15 |
|
|
117
|
+
| Islamic Geometric | 0.25 | 0.30 | 0.20 | 0.15 | 0.10 |
|
|
118
|
+
| Watercolor | 0.20 | 0.25 | 0.15 | 0.20 | 0.20 |
|
|
119
|
+
| African Traditional | 0.15 | 0.20 | 0.30 | 0.20 | 0.15 |
|
|
120
|
+
| South Asian | 0.15 | 0.20 | 0.25 | 0.15 | 0.25 |
|
|
121
|
+
| Default | 0.20 | 0.20 | 0.20 | 0.20 | 0.20 |
|
|
122
|
+
|
|
123
|
+
Weights evolve automatically through the self-evolution system.
|
|
124
|
+
|
|
125
|
+
## Self-Evolution
|
|
126
|
+
|
|
127
|
+
The system learns from every evaluation session:
|
|
128
|
+
|
|
129
|
+
1. **ContextEvolver** adjusts L1-L5 weights per tradition based on scoring patterns
|
|
130
|
+
2. **FewShotUpdater** selects high-scoring examples (≥0.75) as reference benchmarks
|
|
131
|
+
3. **VLM prompt** receives evolved weights, few-shot calibration, and tradition insights
|
|
132
|
+
4. `get_weights()` returns evolved weights when available, falling back to YAML defaults
|
|
133
|
+
|
|
134
|
+
## Tests
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
cd vulca && .venv/bin/python -m pytest tests/ -v # 218 tests
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## License
|
|
141
|
+
|
|
142
|
+
Apache 2.0
|
vulca-0.2.0/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# VULCA SDK
|
|
2
|
+
|
|
3
|
+
AI-native creation organism. Create, critique, and evolve cultural art.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install -e vulca/ # From repo root
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
import vulca
|
|
15
|
+
|
|
16
|
+
# Evaluate an artwork (mock mode — no API key needed)
|
|
17
|
+
result = vulca.evaluate("painting.jpg", tradition="chinese_xieyi", mock=True)
|
|
18
|
+
print(result.scores) # {"L1": 0.85, "L2": 0.78, ...}
|
|
19
|
+
print(result.weighted_total) # 0.82
|
|
20
|
+
|
|
21
|
+
# Create through the full pipeline
|
|
22
|
+
result = vulca.create("Misty mountains in ink wash", provider="mock")
|
|
23
|
+
print(result.status) # "completed"
|
|
24
|
+
|
|
25
|
+
# Human-in-the-loop with custom weights
|
|
26
|
+
result = vulca.create(
|
|
27
|
+
"水墨山水",
|
|
28
|
+
provider="mock",
|
|
29
|
+
hitl=True,
|
|
30
|
+
weights={"L1": 0.3, "L2": 0.2, "L3": 0.2, "L4": 0.15, "L5": 0.15},
|
|
31
|
+
)
|
|
32
|
+
# result.status == "waiting_human"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## CLI
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
vulca evaluate painting.jpg --tradition watercolor
|
|
39
|
+
vulca create "Garden scene" --provider mock
|
|
40
|
+
vulca create "水墨山水" --hitl --weights "L1=0.3,L2=0.2,L3=0.2,L4=0.15,L5=0.15"
|
|
41
|
+
vulca traditions # List all 9 cultural traditions
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## MCP Server
|
|
45
|
+
|
|
46
|
+
For AI agents (Claude Code, OpenClaw, etc.):
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
vulca-mcp # Exposes 3 tools: create_artwork, evaluate_artwork, list_traditions
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Architecture
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
vulca/src/vulca/
|
|
56
|
+
├── pipeline/ # Execution engine + 3 built-in nodes + 3 templates
|
|
57
|
+
├── cultural/ # 9 YAML tradition configs with L1-L5 weights
|
|
58
|
+
├── scoring/ # VLM model routing + L1-L5 evaluation types
|
|
59
|
+
├── storage/ # Session/Feedback protocol + JSONL backend
|
|
60
|
+
├── intent/ # Natural language → tradition resolution
|
|
61
|
+
├── media/ # MediaType enum + creation recipe types
|
|
62
|
+
├── _vlm.py # Gemini Vision L1-L5 scoring (core)
|
|
63
|
+
├── _engine.py # Evaluation engine singleton
|
|
64
|
+
├── cli.py # CLI entry point
|
|
65
|
+
└── mcp.py # MCP server entry point
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Cultural Traditions
|
|
69
|
+
|
|
70
|
+
9 traditions with YAML-defined weights, terminology, and taboos:
|
|
71
|
+
|
|
72
|
+
| Tradition | L1 | L2 | L3 | L4 | L5 |
|
|
73
|
+
|-----------|----|----|----|----|-----|
|
|
74
|
+
| Chinese Xieyi | 0.10 | 0.15 | 0.25 | 0.20 | 0.30 |
|
|
75
|
+
| Chinese Gongbi | 0.15 | 0.30 | 0.25 | 0.15 | 0.15 |
|
|
76
|
+
| Japanese Traditional | 0.15 | 0.20 | 0.20 | 0.20 | 0.25 |
|
|
77
|
+
| Western Academic | 0.20 | 0.25 | 0.15 | 0.25 | 0.15 |
|
|
78
|
+
| Islamic Geometric | 0.25 | 0.30 | 0.20 | 0.15 | 0.10 |
|
|
79
|
+
| Watercolor | 0.20 | 0.25 | 0.15 | 0.20 | 0.20 |
|
|
80
|
+
| African Traditional | 0.15 | 0.20 | 0.30 | 0.20 | 0.15 |
|
|
81
|
+
| South Asian | 0.15 | 0.20 | 0.25 | 0.15 | 0.25 |
|
|
82
|
+
| Default | 0.20 | 0.20 | 0.20 | 0.20 | 0.20 |
|
|
83
|
+
|
|
84
|
+
Weights evolve automatically through the self-evolution system.
|
|
85
|
+
|
|
86
|
+
## Self-Evolution
|
|
87
|
+
|
|
88
|
+
The system learns from every evaluation session:
|
|
89
|
+
|
|
90
|
+
1. **ContextEvolver** adjusts L1-L5 weights per tradition based on scoring patterns
|
|
91
|
+
2. **FewShotUpdater** selects high-scoring examples (≥0.75) as reference benchmarks
|
|
92
|
+
3. **VLM prompt** receives evolved weights, few-shot calibration, and tradition insights
|
|
93
|
+
4. `get_weights()` returns evolved weights when available, falling back to YAML defaults
|
|
94
|
+
|
|
95
|
+
## Tests
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
cd vulca && .venv/bin/python -m pytest tests/ -v # 218 tests
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## License
|
|
102
|
+
|
|
103
|
+
Apache 2.0
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "vulca"
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "AI-native creation organism. Create, critique, and evolve cultural art."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "Apache-2.0"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Yu Haorui", email = "yuhaorui48@gmail.com" },
|
|
14
|
+
]
|
|
15
|
+
keywords = ["ai", "art", "evaluation", "cultural", "vlm", "pipeline", "creation"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Intended Audience :: Science/Research",
|
|
20
|
+
"License :: OSI Approved :: Apache Software License",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
27
|
+
"Topic :: Multimedia :: Graphics",
|
|
28
|
+
]
|
|
29
|
+
dependencies = [
|
|
30
|
+
"litellm>=1.0.0",
|
|
31
|
+
"httpx>=0.25.0",
|
|
32
|
+
"pyyaml>=6.0",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
pipeline = []
|
|
37
|
+
scout = [
|
|
38
|
+
"sentence-transformers>=2.2.2",
|
|
39
|
+
"faiss-cpu>=1.7.0",
|
|
40
|
+
]
|
|
41
|
+
graph = [
|
|
42
|
+
"langgraph>=0.2.0",
|
|
43
|
+
]
|
|
44
|
+
mcp = [
|
|
45
|
+
"fastmcp>=3.0",
|
|
46
|
+
]
|
|
47
|
+
dev = [
|
|
48
|
+
"pytest>=8.0",
|
|
49
|
+
"pytest-asyncio>=0.23",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
[project.urls]
|
|
53
|
+
Homepage = "https://vulcaart.art"
|
|
54
|
+
Documentation = "https://github.com/vulca-org/vulca"
|
|
55
|
+
Repository = "https://github.com/vulca-org/vulca"
|
|
56
|
+
Issues = "https://github.com/vulca-org/vulca/issues"
|
|
57
|
+
|
|
58
|
+
[project.scripts]
|
|
59
|
+
vulca = "vulca.cli:main"
|
|
60
|
+
vulca-mcp = "vulca.mcp_server:mcp.run"
|
|
61
|
+
|
|
62
|
+
[tool.hatch.build.targets.wheel]
|
|
63
|
+
packages = ["src/vulca"]
|
|
64
|
+
|
|
65
|
+
[tool.hatch.build]
|
|
66
|
+
artifacts = ["src/vulca/cultural/data/**"]
|
|
67
|
+
|
|
68
|
+
[tool.pytest.ini_options]
|
|
69
|
+
asyncio_mode = "auto"
|
|
70
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""VULCA -- AI-native creation organism.
|
|
2
|
+
|
|
3
|
+
Create, critique, and evolve cultural art through multi-agent AI pipelines.
|
|
4
|
+
|
|
5
|
+
Usage::
|
|
6
|
+
|
|
7
|
+
import vulca
|
|
8
|
+
|
|
9
|
+
# Evaluate an artwork
|
|
10
|
+
result = vulca.evaluate("painting.jpg")
|
|
11
|
+
print(result.score) # 0.82
|
|
12
|
+
print(result.tradition) # "chinese_xieyi"
|
|
13
|
+
print(result.dimensions) # {"L1": 0.75, "L2": 0.82, ...}
|
|
14
|
+
|
|
15
|
+
# With intent
|
|
16
|
+
result = vulca.evaluate("painting.jpg", intent="check ink wash style")
|
|
17
|
+
|
|
18
|
+
# With explicit tradition
|
|
19
|
+
result = vulca.evaluate("painting.jpg", tradition="chinese_xieyi")
|
|
20
|
+
|
|
21
|
+
# Async
|
|
22
|
+
result = await vulca.aevaluate("painting.jpg", intent="...")
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from vulca._version import __version__
|
|
26
|
+
from vulca.create import acreate, create
|
|
27
|
+
from vulca.evaluate import aevaluate, evaluate
|
|
28
|
+
from vulca.session import asession, session
|
|
29
|
+
from vulca.types import CreateResult, EvalResult, SkillResult
|
|
30
|
+
|
|
31
|
+
__all__ = [
|
|
32
|
+
"__version__",
|
|
33
|
+
"evaluate",
|
|
34
|
+
"aevaluate",
|
|
35
|
+
"create",
|
|
36
|
+
"acreate",
|
|
37
|
+
"session",
|
|
38
|
+
"asession",
|
|
39
|
+
"EvalResult",
|
|
40
|
+
"CreateResult",
|
|
41
|
+
"SkillResult",
|
|
42
|
+
]
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""L1-L5 dimension name normalization and bidirectional mapping.
|
|
2
|
+
|
|
3
|
+
Provides canonical mapping between short names (L1-L5) and full descriptive names,
|
|
4
|
+
plus utilities for converting between various naming formats (snake_case, camelCase, spaced).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
# Canonical L1-L5 definitions
|
|
10
|
+
DIMENSION_NAMES: dict[str, str] = {
|
|
11
|
+
"L1": "Visual Perception",
|
|
12
|
+
"L2": "Technical Execution",
|
|
13
|
+
"L3": "Cultural Context",
|
|
14
|
+
"L4": "Critical Interpretation",
|
|
15
|
+
"L5": "Philosophical Aesthetics",
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
# Reverse mapping: full name -> L-code
|
|
19
|
+
_FULL_TO_CODE: dict[str, str] = {v.lower(): k for k, v in DIMENSION_NAMES.items()}
|
|
20
|
+
|
|
21
|
+
# Snake case variants — includes both paper names and prototype names
|
|
22
|
+
_SNAKE_TO_CODE: dict[str, str] = {
|
|
23
|
+
# Paper terminology (VULCA-Bench / EMNLP 2025)
|
|
24
|
+
"visual_perception": "L1",
|
|
25
|
+
"technical_execution": "L2",
|
|
26
|
+
"cultural_context": "L3",
|
|
27
|
+
"critical_interpretation": "L4",
|
|
28
|
+
"philosophical_aesthetics": "L5",
|
|
29
|
+
# Prototype terminology (wenxin-backend)
|
|
30
|
+
"technical_analysis": "L2",
|
|
31
|
+
"philosophical_aesthetic": "L5",
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def to_code(name: str) -> str:
|
|
36
|
+
"""Convert any dimension name format to L-code (L1-L5).
|
|
37
|
+
|
|
38
|
+
Accepts: "L1", "Visual Perception", "visual_perception", "VisualPerception"
|
|
39
|
+
Returns: "L1" (or the original string if unrecognized)
|
|
40
|
+
"""
|
|
41
|
+
# Already an L-code
|
|
42
|
+
if name in DIMENSION_NAMES:
|
|
43
|
+
return name
|
|
44
|
+
|
|
45
|
+
# Full name match (case-insensitive)
|
|
46
|
+
lower = name.lower().strip()
|
|
47
|
+
if lower in _FULL_TO_CODE:
|
|
48
|
+
return _FULL_TO_CODE[lower]
|
|
49
|
+
|
|
50
|
+
# Snake case match
|
|
51
|
+
if lower in _SNAKE_TO_CODE:
|
|
52
|
+
return _SNAKE_TO_CODE[lower]
|
|
53
|
+
|
|
54
|
+
# CamelCase -> spaced -> try again
|
|
55
|
+
import re
|
|
56
|
+
spaced = re.sub(r"([a-z])([A-Z])", r"\1 \2", name).lower()
|
|
57
|
+
if spaced in _FULL_TO_CODE:
|
|
58
|
+
return _FULL_TO_CODE[spaced]
|
|
59
|
+
|
|
60
|
+
return name
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def to_full_name(code: str) -> str:
|
|
64
|
+
"""Convert L-code to full descriptive name.
|
|
65
|
+
|
|
66
|
+
"L1" -> "Visual Perception"
|
|
67
|
+
"""
|
|
68
|
+
return DIMENSION_NAMES.get(code, code)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def to_snake(code: str) -> str:
|
|
72
|
+
"""Convert L-code to snake_case name.
|
|
73
|
+
|
|
74
|
+
"L1" -> "visual_perception"
|
|
75
|
+
"""
|
|
76
|
+
full = DIMENSION_NAMES.get(code, code)
|
|
77
|
+
return full.lower().replace(" ", "_")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def all_codes() -> list[str]:
|
|
81
|
+
"""Return all L-codes: ["L1", "L2", "L3", "L4", "L5"]."""
|
|
82
|
+
return list(DIMENSION_NAMES.keys())
|