File size: 7,035 Bytes
8dd0d51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aba5de3
8dd0d51
 
068f05c
 
 
 
8dd0d51
 
 
 
 
 
 
 
 
e319717
 
aba5de3
34a6a12
 
4e83552
 
 
 
 
6e4bff0
98010fc
 
4a83a8e
56b95fb
 
 
7bc6f17
5b8c924
bc5f822
 
7725fd6
2848ae7
dcfbd5f
d87bc9c
3e43fab
503cc93
2fd97ff
257081e
c6c2458
34784df
d501176
18d42b7
8d35e43
e6f21d9
480d3f3
5704599
 
 
 
ddbf659
372b496
10b437c
 
8dd0d51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2848ae7
 
 
 
 
8dd0d51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10b437c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
"""Stage the Pi browser workspace for the existing static Hugging Face Space.

Run `cd app && npm ci && npm run build` first. Model weights remain in the
pinned companion model repository; only static assets and selected source
and validation files are published here.
"""
from pathlib import Path
import hashlib
import json
import shutil

root = Path(__file__).resolve().parent.parent
out = root / '.space-agent'
built = root / 'app/dist'
if not (built / 'index.html').is_file():
    raise SystemExit('Build app/ first: npm ci && npm run build')
if out.exists():
    shutil.rmtree(out)
shutil.copytree(built, out)

# Include reproducible browser source; never include environments or weights.
app_out = out / 'app'
app_out.mkdir()
for name in ['package.json', 'package-lock.json', 'index.html', 'vite.config.mjs', 'README.md']:
    shutil.copyfile(root / 'app' / name, app_out / name)
for name in ['src', 'scripts', 'public', 'tests', 'vendor']:
    shutil.copytree(root / 'app' / name, app_out / name)

modal_design = out / 'design' / 'modal-cat'
modal_design.mkdir(parents=True)
shutil.copyfile(root / 'design/modal-cat/prompt.md', modal_design / 'prompt.md')

validation = out / 'validation'
validation.mkdir()
for name in [
    'package-manifest.json', 'onnx-validation.json', 'webgpu-parity.json',
    'benchmark-summary.json', 'checksum-verification.json', 'template-tests.json',
    'control-equivalence.json', 'chinese-arithmetic-investigation.json',
    'browser-integration.json', 'space-deployment.json', 'hub-checksums.json',
    'agent-browser-hub.json', 'agent-browser-limit128.json', 'agent-browser-dev.json',
    'agent-browser-no-gpu.json', 'agent-completion.json',
    'agent-space-deployment.json', 'agent-space-embedded.json', 'agent-space-restricted.json',
    'agent-space-checksums.json',
    'agent-terminal.json', 'agent-terminal-model.json', 'agent-terminal-dev.json',
    'agent-terminal-space.json', 'agent-terminal-space-embedded.json',
    'agent-terminal-space-checksums.json',
    'agent-terminal-dark.json', 'agent-terminal-dark-dev.json',
    'agent-terminal-dark-render.json', 'agent-terminal-dark-render-dev.json',
    'agent-terminal-dark-model.json', 'agent-terminal-dark-conversation.json',
    'agent-terminal-dark-space.json', 'agent-terminal-dark-space-render.json',
    'agent-terminal-dark-space-embedded.json',
    'agent-terminal-dark-space-checksums.json',
    'agent-app-dark-render.json', 'agent-app-dark-terminal.json',
    'agent-first-message.json', 'agent-first-message-space-embedded.json',
    'agent-app-dark-space-render.json', 'agent-first-message-space-checksums.json',
    'agent-shell.json', 'agent-shell-layout.json', 'agent-shell-terminal.json',
    'agent-shell-first-message.json', 'agent-shell-space.json',
    'agent-shell-space-embedded.json',
    'agent-shell-space-checksums.json',
    'agent-rounded-header.json', 'agent-rounded-header-render.json',
    'agent-local-demo-modal.json', 'agent-compact-header.json',
    'agent-context-render.json', 'agent-context-usage.json',
    'agent-compact-shell.json', 'agent-white-action-modal.json',
    'agent-thinking-context.json', 'agent-thinking-conversation.json', 'agent-thinking-render.json',
    'agent-thinking-space.json', 'agent-thinking-space-checksums.json',
    'agent-cached-start.json', 'agent-cached-first-message.json',
    'agent-runtime-meter.json', 'agent-runtime-meter-render.json', 'agent-nested-radius.json',
    'agent-runtime-meter-adaptive.json', 'agent-adaptive-width.json',
    'agent-mascot.json', 'agent-mascot-render.json',
    'agent-modal-cat.json', 'agent-modal-cat-space.json',
    'agent-loading-paws.json', 'agent-loading-paws-webkit.json',
    'agent-credits-send.json',
    'agent-mascot-motion.json', 'agent-mascot-motion-layout.json',
    'agent-editor-focus.json',
    'agent-editor.json',
    'agent-starter-products.json', 'agent-products-mascot.json',
    'agent-products-json.json', 'agent-json-mascot.json', 'agent-safari-cat.json',
    'agent-profit-demo-review.md', 'agent-profit-demo.json', 'agent-profit-demo-guidance.json',
    'agent-profit-demo-verified.json', 'agent-profit-demo-clear.json', 'agent-profit-demo-cost-change.json',
    'agent-profit-demo-focused.json', 'agent-profit-demo-focused-cost.json', 'agent-profit-starter.json',
    'agent-profit-onboarding.json', 'agent-profit-mascot-final.json',
    'agent-sales-demo.json',
    'agent-follow-read.json', 'agent-workspace-runtime.json',
    'load-flow.json', 'column-resizer.json', 'cat-interactions.json',
    'modal-paws-open.json', 'terminal-paws.json', 'thinking-spacing.json',
]:
    source = root / 'validation' / name
    if source.is_file():
        shutil.copyfile(source, validation / name)

scripts = out / 'scripts'
scripts.mkdir()
for name in ['download_source.py', 'build.sh', 'package_model.py', 'reference.py',
             'validate_onnx.py', 'validate_webgpu.py', 'serve.py', 'prepare_space.py']:
    shutil.copyfile(root / 'scripts' / name, scripts / name)
for folder in ['browser-agent', 'download-audit']:
    report = out / 'research' / folder
    report.mkdir(parents=True)
    shutil.copyfile(root / 'research' / folder / 'REPORT.md', report / 'REPORT.md')
for name in ['pi-agent-README.md', 'pi-ai-README.md', 'just-bash-README.md']:
    shutil.copyfile(root / 'research/browser-agent' / name, out / 'research/browser-agent' / name)
audit = out / 'research/multiturn-audit'
audit.mkdir(parents=True)
for source in sorted((root / 'research/multiturn-audit').iterdir()):
    if source.is_file() and (source.name == 'REPORT.md' or source.suffix in {'.json', '.py', '.mjs'}):
        shutil.copyfile(source, audit / source.name)
shutil.copyfile(root / 'requirements-convert.txt', out / 'requirements-convert.txt')
shutil.copyfile('/usr/share/common-licenses/Apache-2.0', out / 'LICENSE')
shutil.copyfile(root / 'SPACE_README.md', out / 'README.md')
shutil.copyfile(root / 'SPACE_README.md', out / 'SPACE_README.md')
(out / 'NOTICE').write_text(
    'Base model: OpenBMB MiniCPM5-2B, Apache-2.0. Independently converted and quantized.\n'
    'Agent: Pi, earendil-works. Virtual shell: just-bash, Vercel.\n'
    'Inference: Hugging Face Transformers.js and Microsoft ONNX Runtime.\n'
    'Bundled dependency licenses and notices are in licenses/.\n'
)
(out / '.gitattributes').write_text(
    '*.onnx filter=lfs diff=lfs merge=lfs -text\n'
    '*.onnx_data* filter=lfs diff=lfs merge=lfs -text\n'
    '*.wasm filter=lfs diff=lfs merge=lfs -text\n'
)
files = {str(p.relative_to(out)): {'bytes': p.stat().st_size,
         'sha256': hashlib.sha256(p.read_bytes()).hexdigest()}
         for p in sorted(out.rglob('*')) if p.is_file()}
(out / 'deployment-manifest.json').write_text(json.dumps({'files': files}, indent=2) + '\n')
assert not any('.onnx_data' in name or 'node_modules/' in name for name in files)
print('Staged', len(files) + 1, 'files;', sum(f['bytes'] for f in files.values()), 'bytes')
print('Upload:', 'hf upload townbox/MiniCPM5-2B-WebGPU-Pi .space-agent . --type space')