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.
Files changed (68) hide show
  1. vulca-0.2.0/.gitignore +254 -0
  2. vulca-0.2.0/PKG-INFO +142 -0
  3. vulca-0.2.0/README.md +103 -0
  4. vulca-0.2.0/pyproject.toml +70 -0
  5. vulca-0.2.0/src/vulca/__init__.py +42 -0
  6. vulca-0.2.0/src/vulca/__main__.py +5 -0
  7. vulca-0.2.0/src/vulca/_dimensions.py +82 -0
  8. vulca-0.2.0/src/vulca/_engine.py +200 -0
  9. vulca-0.2.0/src/vulca/_image.py +42 -0
  10. vulca-0.2.0/src/vulca/_intent.py +95 -0
  11. vulca-0.2.0/src/vulca/_parse.py +54 -0
  12. vulca-0.2.0/src/vulca/_skills.py +104 -0
  13. vulca-0.2.0/src/vulca/_version.py +1 -0
  14. vulca-0.2.0/src/vulca/_vlm.py +249 -0
  15. vulca-0.2.0/src/vulca/cli.py +278 -0
  16. vulca-0.2.0/src/vulca/create.py +223 -0
  17. vulca-0.2.0/src/vulca/cultural/__init__.py +38 -0
  18. vulca-0.2.0/src/vulca/cultural/data/traditions/_template.yaml +50 -0
  19. vulca-0.2.0/src/vulca/cultural/data/traditions/african_traditional.yaml +83 -0
  20. vulca-0.2.0/src/vulca/cultural/data/traditions/chinese_gongbi.yaml +77 -0
  21. vulca-0.2.0/src/vulca/cultural/data/traditions/chinese_xieyi.yaml +86 -0
  22. vulca-0.2.0/src/vulca/cultural/data/traditions/default.yaml +74 -0
  23. vulca-0.2.0/src/vulca/cultural/data/traditions/islamic_geometric.yaml +83 -0
  24. vulca-0.2.0/src/vulca/cultural/data/traditions/japanese_traditional.yaml +83 -0
  25. vulca-0.2.0/src/vulca/cultural/data/traditions/schema.json +134 -0
  26. vulca-0.2.0/src/vulca/cultural/data/traditions/south_asian.yaml +83 -0
  27. vulca-0.2.0/src/vulca/cultural/data/traditions/watercolor.yaml +83 -0
  28. vulca-0.2.0/src/vulca/cultural/data/traditions/western_academic.yaml +74 -0
  29. vulca-0.2.0/src/vulca/cultural/loader.py +264 -0
  30. vulca-0.2.0/src/vulca/cultural/types.py +107 -0
  31. vulca-0.2.0/src/vulca/evaluate.py +119 -0
  32. vulca-0.2.0/src/vulca/intent/__init__.py +11 -0
  33. vulca-0.2.0/src/vulca/intent/agent.py +148 -0
  34. vulca-0.2.0/src/vulca/intent/types.py +27 -0
  35. vulca-0.2.0/src/vulca/mcp_server.py +136 -0
  36. vulca-0.2.0/src/vulca/media/__init__.py +1 -0
  37. vulca-0.2.0/src/vulca/media/types.py +128 -0
  38. vulca-0.2.0/src/vulca/pipeline/__init__.py +33 -0
  39. vulca-0.2.0/src/vulca/pipeline/engine.py +362 -0
  40. vulca-0.2.0/src/vulca/pipeline/hooks.py +55 -0
  41. vulca-0.2.0/src/vulca/pipeline/node.py +54 -0
  42. vulca-0.2.0/src/vulca/pipeline/nodes/__init__.py +7 -0
  43. vulca-0.2.0/src/vulca/pipeline/nodes/decide.py +36 -0
  44. vulca-0.2.0/src/vulca/pipeline/nodes/evaluate.py +94 -0
  45. vulca-0.2.0/src/vulca/pipeline/nodes/generate.py +124 -0
  46. vulca-0.2.0/src/vulca/pipeline/templates.py +47 -0
  47. vulca-0.2.0/src/vulca/pipeline/types.py +191 -0
  48. vulca-0.2.0/src/vulca/scoring/__init__.py +28 -0
  49. vulca-0.2.0/src/vulca/scoring/config.py +8 -0
  50. vulca-0.2.0/src/vulca/scoring/model_router.py +137 -0
  51. vulca-0.2.0/src/vulca/scoring/types.py +146 -0
  52. vulca-0.2.0/src/vulca/scoring/vlm.py +10 -0
  53. vulca-0.2.0/src/vulca/session.py +111 -0
  54. vulca-0.2.0/src/vulca/storage/__init__.py +11 -0
  55. vulca-0.2.0/src/vulca/storage/jsonl.py +162 -0
  56. vulca-0.2.0/src/vulca/storage/protocol.py +56 -0
  57. vulca-0.2.0/src/vulca/types.py +148 -0
  58. vulca-0.2.0/tests/conftest.py +11 -0
  59. vulca-0.2.0/tests/test_cli.py +111 -0
  60. vulca-0.2.0/tests/test_create_hitl.py +96 -0
  61. vulca-0.2.0/tests/test_cultural_loader.py +130 -0
  62. vulca-0.2.0/tests/test_evaluate.py +332 -0
  63. vulca-0.2.0/tests/test_mcp_server.py +72 -0
  64. vulca-0.2.0/tests/test_package.py +579 -0
  65. vulca-0.2.0/tests/test_pipeline_engine.py +481 -0
  66. vulca-0.2.0/tests/test_scoring.py +88 -0
  67. vulca-0.2.0/tests/test_storage.py +178 -0
  68. 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,5 @@
1
+ """Allow running vulca as ``python -m vulca``."""
2
+
3
+ from vulca.cli import main
4
+
5
+ main()
@@ -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())