infinicode 2.8.49 β 2.8.51
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.
- package/dist/kernel/federation/dashboard-html.d.ts +1 -1
- package/dist/kernel/federation/dashboard-html.js +7 -2
- package/dist/robopark/enroll.js +3 -3
- package/dist/robopark/preview-agent-launcher.js +3 -3
- package/dist/robopark/python-env.d.ts +6 -0
- package/dist/robopark/python-env.js +50 -1
- package/dist/robopark/vision-agent-launcher.js +4 -3
- package/package.json +1 -1
|
@@ -5867,7 +5867,7 @@ button.act:disabled{opacity:0.5;cursor:default;}
|
|
|
5867
5867
|
var effPresetOptions='', effVoiceOptions='';
|
|
5868
5868
|
for(var ci=0;ci<characterPresets.length;ci++){ var cp=characterPresets[ci]; effPresetOptions += '<option value="'+esc(cp.id||'')+'"'+((cp.id===n.id)?' selected':'')+'>'+esc(cp.name||cp.id||'')+'</option>'; }
|
|
5869
5869
|
for(var vi=0;vi<voiceStacks.length;vi++){ var vs=voiceStacks[vi]; effVoiceOptions += '<option value="'+esc(vs.id||'')+'">'+esc(vs.name||vs.id||'')+'</option>'; }
|
|
5870
|
-
var devForPm=schedulerDevice(n)||{};
|
|
5870
|
+
var devForPm=schedulerDevice(n)||{};
|
|
5871
5871
|
b.innerHTML =
|
|
5872
5872
|
sect('π camera feed',
|
|
5873
5873
|
'<div class="pk-cam" id="pk-cam"><canvas id="pk-camcv" width="384" height="216"></canvas>'
|
|
@@ -5895,7 +5895,12 @@ button.act:disabled{opacity:0.5;cursor:default;}
|
|
|
5895
5895
|
+ buildShellSection(schedId(n))
|
|
5896
5896
|
+ sect('π character / voice','<div class="pk-note" id="pk-eff-note" style="margin-bottom:0.45rem;">loading effective configβ¦</div><div class="rp-field"><label>Character preset</label><select class="rp-char" id="pk-eff-char" data-robot="'+esc(schedId(n))+'">'+effPresetOptions+'</select></div><div class="rp-field"><label>Voice stack</label><select class="rp-voice" id="pk-eff-voice" data-robot="'+esc(schedId(n))+'">'+effVoiceOptions+'</select></div><button class="rp-btn" id="pk-eff-save" data-robot="'+esc(schedId(n))+'" style="margin-top:0.35rem;">Set up on this robot</button>');
|
|
5897
5897
|
b.innerHTML += sect('Camera + audio devices','<div class="rp-field"><label>Search devices</label><input id="pk-device-search" placeholder="camera, USB, microphone, HDMI..." autocomplete="off"></div><div class="rp-field"><label>Camera input</label><select id="pk-video-device"></select></div><div class="rp-field"><label>Microphone input</label><select id="pk-audio-input"></select></div><div class="rp-field"><label>Speaker / output inventory</label><select id="pk-audio-output"></select></div><div class="rp-field"><label>Preset greeting phrases <span class="pk-note">one per line, cached per voice</span></label><textarea id="pk-greeting-phrases" rows="3" placeholder="Hi, I am Jaguar! / Welcome to RoboPark."></textarea></div><button class="rp-btn" id="pk-device-save" style="margin-top:0.35rem">Save device selection + greetings</button><div class="pk-note" id="pk-device-note">waiting for robot heartbeat inventory</div>');
|
|
5898
|
-
|
|
5898
|
+
// Put live hardware selection beside the camera and audio tests,
|
|
5899
|
+
// ahead of persona and service administration in the Park drawer.
|
|
5900
|
+
var deviceInput=$('pk-device-search'), deviceSection=deviceInput&&deviceInput.closest('.pk-sect');
|
|
5901
|
+
var speakerTest=$('pk-spk-test'), speakerSection=speakerTest&&speakerTest.closest('.pk-sect');
|
|
5902
|
+
if(deviceSection && speakerSection) speakerSection.after(deviceSection);
|
|
5903
|
+
refreshDeviceSelectors(n);
|
|
5899
5904
|
b.innerHTML += '<div class="pk-ctl" style="margin-top:0.5rem"><button class="rp-btn danger" id="pk-recover" data-robot="'+esc(n.name)+'">Recover robot</button><span class="pk-note" style="margin:0">clears stale sessions and queued triggers for this robot</span></div>';
|
|
5900
5905
|
var deviceSearch=$('pk-device-search'); if(deviceSearch) deviceSearch.addEventListener('input', function(){ refreshDeviceSelectors(n); });
|
|
5901
5906
|
var deviceSave=$('pk-device-save'); if(deviceSave) deviceSave.addEventListener('click', function(){ saveDeviceSelectors(n); });
|
package/dist/robopark/enroll.js
CHANGED
|
@@ -9,7 +9,7 @@ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
|
9
9
|
import { homedir, hostname } from 'node:os';
|
|
10
10
|
import { join } from 'node:path';
|
|
11
11
|
import chalk from 'chalk';
|
|
12
|
-
import { findPython, findSchedulerPath,
|
|
12
|
+
import { findPython, findSchedulerPath, prepareRobotPython } from './python-env.js';
|
|
13
13
|
const ROBOPARK_DIR = join(homedir(), '.robopark');
|
|
14
14
|
const ENROLLMENT_FILE = join(ROBOPARK_DIR, 'enrollment_token');
|
|
15
15
|
function ensureDir() {
|
|
@@ -39,8 +39,8 @@ export async function roboparkEnroll(opts) {
|
|
|
39
39
|
console.log(chalk.red(' β could not find preview_agent.py'));
|
|
40
40
|
process.exit(1);
|
|
41
41
|
}
|
|
42
|
-
const python = findPython();
|
|
43
|
-
if (!
|
|
42
|
+
const python = prepareRobotPython(findPython(), script);
|
|
43
|
+
if (!python)
|
|
44
44
|
process.exit(1);
|
|
45
45
|
const args = [
|
|
46
46
|
script,
|
|
@@ -8,7 +8,7 @@ import { spawn } from 'node:child_process';
|
|
|
8
8
|
import { hostname } from 'node:os';
|
|
9
9
|
import chalk from 'chalk';
|
|
10
10
|
import { discoverContext } from './discovery.js';
|
|
11
|
-
import { findPython, findSchedulerPath,
|
|
11
|
+
import { findPython, findSchedulerPath, prepareRobotPython } from './python-env.js';
|
|
12
12
|
const DEFAULT_SCHEDULER_PORT = 8080;
|
|
13
13
|
export async function roboparkPreviewAgent(opts) {
|
|
14
14
|
const ctx = await discoverContext();
|
|
@@ -24,8 +24,8 @@ export async function roboparkPreviewAgent(opts) {
|
|
|
24
24
|
console.log(chalk.red(' β could not find preview_agent.py'));
|
|
25
25
|
process.exit(1);
|
|
26
26
|
}
|
|
27
|
-
const python = findPython();
|
|
28
|
-
if (!
|
|
27
|
+
const python = prepareRobotPython(findPython(), script);
|
|
28
|
+
if (!python)
|
|
29
29
|
process.exit(1);
|
|
30
30
|
const args = [
|
|
31
31
|
script,
|
|
@@ -13,3 +13,9 @@ export declare function findPython(): string;
|
|
|
13
13
|
* (e.g. app_pi_clean.py + requirements_pi_unified.txt).
|
|
14
14
|
*/
|
|
15
15
|
export declare function ensurePythonDeps(python: string, scriptPath: string, modules?: string[], reqFile?: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Create and maintain the isolated robot runtime at ~/.robopark/venv.
|
|
18
|
+
* System site packages stay visible so Pi apt packages such as OpenCV,
|
|
19
|
+
* PyAudio and Picamera2 do not need to be rebuilt by pip on ARM.
|
|
20
|
+
*/
|
|
21
|
+
export declare function prepareRobotPython(basePython: string, scriptPath: string, modules?: string[], reqFile?: string): string | null;
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
* and `vision-agent`, which spawn preview_agent.py / app_pi_clean.py.
|
|
4
4
|
*/
|
|
5
5
|
import { execSync, spawnSync } from 'node:child_process';
|
|
6
|
-
import { existsSync } from 'node:fs';
|
|
6
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
7
|
+
import { homedir } from 'node:os';
|
|
7
8
|
import { join } from 'node:path';
|
|
9
|
+
import { createHash } from 'node:crypto';
|
|
8
10
|
import chalk from 'chalk';
|
|
9
11
|
/** Modules preview_agent.py imports β kept in sync with requirements-robot.txt. */
|
|
10
12
|
const REQUIRED_MODULES = ['httpx', 'cv2', 'pyaudio', 'livekit'];
|
|
@@ -52,6 +54,12 @@ export function findPython() {
|
|
|
52
54
|
}
|
|
53
55
|
return process.platform === 'win32' ? 'python' : 'python3';
|
|
54
56
|
}
|
|
57
|
+
const ROBOPARK_VENV = join(homedir(), '.robopark', 'venv');
|
|
58
|
+
function venvPythonPath() {
|
|
59
|
+
return process.platform === 'win32'
|
|
60
|
+
? join(ROBOPARK_VENV, 'Scripts', 'python.exe')
|
|
61
|
+
: join(ROBOPARK_VENV, 'bin', 'python');
|
|
62
|
+
}
|
|
55
63
|
function missingModules(python, modules) {
|
|
56
64
|
return modules.filter(mod => {
|
|
57
65
|
const res = spawnSync(python, ['-c', `import ${mod}`], { stdio: 'ignore' });
|
|
@@ -89,3 +97,44 @@ export function ensurePythonDeps(python, scriptPath, modules = REQUIRED_MODULES,
|
|
|
89
97
|
}
|
|
90
98
|
return true;
|
|
91
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Create and maintain the isolated robot runtime at ~/.robopark/venv.
|
|
102
|
+
* System site packages stay visible so Pi apt packages such as OpenCV,
|
|
103
|
+
* PyAudio and Picamera2 do not need to be rebuilt by pip on ARM.
|
|
104
|
+
*/
|
|
105
|
+
export function prepareRobotPython(basePython, scriptPath, modules = REQUIRED_MODULES, reqFile = 'requirements-robot.txt') {
|
|
106
|
+
const reqPath = join(scriptPath, '..', reqFile);
|
|
107
|
+
if (!existsSync(reqPath)) {
|
|
108
|
+
console.log(chalk.red(` β ${reqFile} not found next to ${scriptPath}`));
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
const python = venvPythonPath();
|
|
112
|
+
if (!existsSync(python)) {
|
|
113
|
+
console.log(chalk.dim(` creating RoboPark Python environment: ${ROBOPARK_VENV}`));
|
|
114
|
+
mkdirSync(join(homedir(), '.robopark'), { recursive: true });
|
|
115
|
+
const created = spawnSync(basePython, ['-m', 'venv', '--system-site-packages', ROBOPARK_VENV], { stdio: 'inherit' });
|
|
116
|
+
if (created.status !== 0 || !existsSync(python)) {
|
|
117
|
+
console.log(chalk.red(' β could not create ~/.robopark/venv. On Debian/Raspberry Pi install python3-venv, then retry.'));
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const requirements = readFileSync(reqPath, 'utf8');
|
|
122
|
+
const fingerprint = createHash('sha256').update(requirements).digest('hex');
|
|
123
|
+
const marker = join(ROBOPARK_VENV, `.robopark-${reqFile}.sha256`);
|
|
124
|
+
const installedFingerprint = existsSync(marker) ? readFileSync(marker, 'utf8').trim() : '';
|
|
125
|
+
if (installedFingerprint !== fingerprint || missingModules(python, modules).length > 0) {
|
|
126
|
+
console.log(chalk.dim(` syncing RoboPark Python dependencies from ${reqFile}β¦`));
|
|
127
|
+
const install = spawnSync(python, ['-m', 'pip', 'install', '--upgrade', '-r', reqPath], { stdio: 'inherit' });
|
|
128
|
+
if (install.status !== 0) {
|
|
129
|
+
console.log(chalk.red(` β dependency install failed in ${ROBOPARK_VENV}`));
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
writeFileSync(marker, `${fingerprint}\n`);
|
|
133
|
+
}
|
|
134
|
+
const stillMissing = missingModules(python, modules);
|
|
135
|
+
if (stillMissing.length) {
|
|
136
|
+
console.log(chalk.red(` β venv is still missing: ${stillMissing.join(', ')}`));
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
return python;
|
|
140
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { spawn } from 'node:child_process';
|
|
9
9
|
import chalk from 'chalk';
|
|
10
|
-
import { findPython, findVisionPath,
|
|
10
|
+
import { findPython, findVisionPath, prepareRobotPython, VISION_REQUIRED_MODULES } from './python-env.js';
|
|
11
11
|
const DEFAULT_VISION_PORT = 5000;
|
|
12
12
|
const DEFAULT_MOTION_WEBHOOK_PORT = 5057; // must match preview-agent's --vision-webhook-port default
|
|
13
13
|
function isPiArm() {
|
|
@@ -19,12 +19,13 @@ export async function roboparkVisionAgent(opts) {
|
|
|
19
19
|
console.log(chalk.red(' β could not find app_pi_clean.py'));
|
|
20
20
|
process.exit(1);
|
|
21
21
|
}
|
|
22
|
-
const
|
|
22
|
+
const basePython = findPython();
|
|
23
23
|
// Real Pi: opencv comes from `apt install python3-opencv`, not pip (see
|
|
24
24
|
// requirements_pi_unified.txt) β pip-installing it here would fight the
|
|
25
25
|
// ARM-optimized system build. Everywhere else: plain pip install works.
|
|
26
26
|
const reqFile = isPiArm() ? 'requirements_pi_unified.txt' : 'requirements-demo.txt';
|
|
27
|
-
|
|
27
|
+
const python = prepareRobotPython(basePython, script, VISION_REQUIRED_MODULES, reqFile);
|
|
28
|
+
if (!python)
|
|
28
29
|
process.exit(1);
|
|
29
30
|
const port = opts.port ?? String(DEFAULT_VISION_PORT);
|
|
30
31
|
const webhookUrl = opts.motionWebhookUrl ?? `http://127.0.0.1:${DEFAULT_MOTION_WEBHOOK_PORT}/`;
|
package/package.json
CHANGED