ultravisor 1.0.13 → 1.0.14
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ultravisor",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"description": "Cyclic process execution with ai integration.",
|
|
5
5
|
"main": "source/Ultravisor.cjs",
|
|
6
6
|
"bin": {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"test": "npx quack test",
|
|
12
12
|
"tests": "npx mocha -u tdd --exit -R spec --grep",
|
|
13
13
|
"coverage": "npx quack coverage",
|
|
14
|
+
"postinstall": "cd webinterface && npm install && npm run build && cd ..",
|
|
14
15
|
"build": "npx quack build && cd webinterface && npm install && npm run build && cd ..",
|
|
15
16
|
"docs": "npx quack prepare-docs ./docs -d ./modules",
|
|
16
17
|
"docs-serve": "npx quack docs-serve ./docs"
|
|
@@ -433,10 +433,32 @@ class UltravisorBeaconClient
|
|
|
433
433
|
if (tmpOutputs.ExitCode && tmpOutputs.ExitCode !== 0)
|
|
434
434
|
{
|
|
435
435
|
console.warn(`[Beacon] Work item [${pWorkItem.WorkItemHash}] completed with exit code ${tmpOutputs.ExitCode}`);
|
|
436
|
+
this._reportComplete(pWorkItem.WorkItemHash, tmpOutputs, pResult.Log || []);
|
|
437
|
+
return;
|
|
436
438
|
}
|
|
437
|
-
|
|
439
|
+
|
|
440
|
+
console.log(`[Beacon] Work item [${pWorkItem.WorkItemHash}] completed successfully.`);
|
|
441
|
+
|
|
442
|
+
// If the result contains a file, upload it to the coordinator before reporting completion
|
|
443
|
+
if (tmpOutputs.Result && tmpOutputs.OutputSize > 0)
|
|
438
444
|
{
|
|
439
|
-
|
|
445
|
+
let tmpResultPath = tmpOutputs.Result;
|
|
446
|
+
let tmpOutputFile = pWorkItem.Settings && pWorkItem.Settings.OutputFile;
|
|
447
|
+
let tmpFilename = tmpOutputFile || require('path').basename(tmpResultPath);
|
|
448
|
+
|
|
449
|
+
this._uploadResultFile(pWorkItem.WorkItemHash, tmpResultPath, tmpFilename, (pUploadError) =>
|
|
450
|
+
{
|
|
451
|
+
if (pUploadError)
|
|
452
|
+
{
|
|
453
|
+
console.warn(`[Beacon] File upload failed for [${pWorkItem.WorkItemHash}]: ${pUploadError.message} — reporting completion without file`);
|
|
454
|
+
}
|
|
455
|
+
else
|
|
456
|
+
{
|
|
457
|
+
console.log(`[Beacon] Uploaded result file [${tmpFilename}] for [${pWorkItem.WorkItemHash}]`);
|
|
458
|
+
}
|
|
459
|
+
this._reportComplete(pWorkItem.WorkItemHash, tmpOutputs, pResult.Log || []);
|
|
460
|
+
});
|
|
461
|
+
return;
|
|
440
462
|
}
|
|
441
463
|
|
|
442
464
|
this._reportComplete(pWorkItem.WorkItemHash, tmpOutputs, pResult.Log || []);
|
|
@@ -447,6 +469,58 @@ class UltravisorBeaconClient
|
|
|
447
469
|
// Reporting
|
|
448
470
|
// ================================================================
|
|
449
471
|
|
|
472
|
+
_uploadResultFile(pWorkItemHash, pFilePath, pFilename, fCallback)
|
|
473
|
+
{
|
|
474
|
+
let tmpFS = require('fs');
|
|
475
|
+
|
|
476
|
+
if (!tmpFS.existsSync(pFilePath))
|
|
477
|
+
{
|
|
478
|
+
return fCallback(new Error(`File not found: ${pFilePath}`));
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
let tmpFileBuffer = tmpFS.readFileSync(pFilePath);
|
|
482
|
+
let tmpParsedURL = new URL(this._Config.ServerURL);
|
|
483
|
+
|
|
484
|
+
let tmpOptions = {
|
|
485
|
+
hostname: tmpParsedURL.hostname,
|
|
486
|
+
port: tmpParsedURL.port || 80,
|
|
487
|
+
path: `/Beacon/Work/${pWorkItemHash}/Upload`,
|
|
488
|
+
method: 'POST',
|
|
489
|
+
headers: {
|
|
490
|
+
'Content-Type': 'application/octet-stream',
|
|
491
|
+
'Content-Length': tmpFileBuffer.length,
|
|
492
|
+
'X-Output-Filename': pFilename
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
|
|
496
|
+
if (this._SessionCookie)
|
|
497
|
+
{
|
|
498
|
+
tmpOptions.headers['Cookie'] = this._SessionCookie;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
let tmpReq = libHTTP.request(tmpOptions, (pResponse) =>
|
|
502
|
+
{
|
|
503
|
+
let tmpData = '';
|
|
504
|
+
pResponse.on('data', (pChunk) => { tmpData += pChunk; });
|
|
505
|
+
pResponse.on('end', () =>
|
|
506
|
+
{
|
|
507
|
+
if (pResponse.statusCode >= 400)
|
|
508
|
+
{
|
|
509
|
+
return fCallback(new Error(`Upload failed: HTTP ${pResponse.statusCode}`));
|
|
510
|
+
}
|
|
511
|
+
return fCallback(null);
|
|
512
|
+
});
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
tmpReq.on('error', (pError) =>
|
|
516
|
+
{
|
|
517
|
+
return fCallback(pError);
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
tmpReq.write(tmpFileBuffer);
|
|
521
|
+
tmpReq.end();
|
|
522
|
+
}
|
|
523
|
+
|
|
450
524
|
_reportComplete(pWorkItemHash, pOutputs, pLog)
|
|
451
525
|
{
|
|
452
526
|
this._httpRequest('POST', `/Beacon/Work/${pWorkItemHash}/Complete`,
|