@mindexec/cli 0.2.94 → 0.2.95
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 +1 -1
- package/remote-hub.js +35 -6
- package/scripts/remote-http-smoke.mjs +2 -0
- package/server.js +186 -8
- package/wwwroot/_framework/MindExecution.Core.eyl4o4qxg8.dll +0 -0
- package/wwwroot/_framework/{MindExecution.Kernel.55q6x6zeoc.dll → MindExecution.Kernel.hxyapaztgr.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Admin.peei1t6ncj.dll → MindExecution.Plugins.Admin.7kemovesa7.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Business.04t0oe4t4k.dll → MindExecution.Plugins.Business.t370in2g1b.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Concept.f4gpqdzqwj.dll → MindExecution.Plugins.Concept.oqhv1116kb.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Directory.az6m63vnll.dll → MindExecution.Plugins.Directory.0v80a0hi9m.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.o2xcmf9i46.dll → MindExecution.Plugins.PlanMaster.hn5sfx4z2l.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.YouTube.xnrrltoofq.dll → MindExecution.Plugins.YouTube.c8sc0tlc6o.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Shared.6qq547u3iu.dll → MindExecution.Shared.osv9nbh3ym.dll} +0 -0
- package/wwwroot/_framework/MindExecution.Web.cdu22y82zq.dll +0 -0
- package/wwwroot/_framework/blazor.boot.json +21 -21
- package/wwwroot/service-worker-assets.js +22 -22
- package/wwwroot/service-worker.js +1 -1
- package/wwwroot/_framework/MindExecution.Core.e31e775w23.dll +0 -0
- package/wwwroot/_framework/MindExecution.Web.nfbmmsf2rl.dll +0 -0
package/package.json
CHANGED
package/remote-hub.js
CHANGED
|
@@ -182,6 +182,19 @@ function getReachableIPv4Address() {
|
|
|
182
182
|
return candidates.find(isPrivateIPv4) || candidates[0] || '127.0.0.1';
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
function buildEndpoint(hostValue, portValue) {
|
|
186
|
+
const hostText = safeString(hostValue, 128);
|
|
187
|
+
const port = normalizePort(portValue);
|
|
188
|
+
if (!hostText || !port) {
|
|
189
|
+
return '';
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const hostPart = hostText.includes(':') && !hostText.startsWith('[')
|
|
193
|
+
? `[${hostText}]`
|
|
194
|
+
: hostText;
|
|
195
|
+
return `${hostPart}:${port}`;
|
|
196
|
+
}
|
|
197
|
+
|
|
185
198
|
function parseManagerEndpoint(value) {
|
|
186
199
|
const endpoint = safeString(value, 256);
|
|
187
200
|
const match = endpoint.match(/^(\[[^\]]+\]|[^:\s]+):(\d{1,5})$/);
|
|
@@ -486,14 +499,26 @@ export function createRemoteHub(options = {}) {
|
|
|
486
499
|
}
|
|
487
500
|
|
|
488
501
|
function getAgentEndpointRouteInfo() {
|
|
489
|
-
const
|
|
490
|
-
const
|
|
502
|
+
const includeInterfaceCandidates = !publicEndpoint && isWildcardHost(host);
|
|
503
|
+
const candidateDetails = includeInterfaceCandidates
|
|
504
|
+
? getReachableIPv4CandidateEntries()
|
|
505
|
+
: [];
|
|
506
|
+
const candidateEndpoints = candidateDetails
|
|
507
|
+
.map(candidate => ({
|
|
508
|
+
...candidate,
|
|
509
|
+
endpoint: buildEndpoint(candidate.address, boundPort || requestedPort)
|
|
510
|
+
}))
|
|
511
|
+
.filter(candidate => candidate.endpoint);
|
|
491
512
|
const endpoint = getAgentEndpoint();
|
|
513
|
+
const endpointCandidates = [
|
|
514
|
+
endpoint,
|
|
515
|
+
...candidateEndpoints.map(candidate => candidate.endpoint)
|
|
516
|
+
].filter((value, index, all) => value && all.indexOf(value) === index);
|
|
492
517
|
const wildcardWithoutReachableAddress =
|
|
493
518
|
!publicEndpoint
|
|
494
519
|
&& !publicHost
|
|
495
520
|
&& isWildcardHost(host)
|
|
496
|
-
&&
|
|
521
|
+
&& candidateDetails.length === 0;
|
|
497
522
|
const reason = getAccountRouteEndpointReason(endpoint, { wildcardWithoutReachableAddress });
|
|
498
523
|
const parsed = parseManagerEndpoint(endpoint);
|
|
499
524
|
return {
|
|
@@ -502,8 +527,8 @@ export function createRemoteHub(options = {}) {
|
|
|
502
527
|
port: parsed?.port || 0,
|
|
503
528
|
accountRouteReady: reason === 'ok',
|
|
504
529
|
reason,
|
|
505
|
-
candidates,
|
|
506
|
-
candidateDetails
|
|
530
|
+
candidates: endpointCandidates,
|
|
531
|
+
candidateDetails: candidateEndpoints
|
|
507
532
|
};
|
|
508
533
|
}
|
|
509
534
|
|
|
@@ -536,6 +561,7 @@ export function createRemoteHub(options = {}) {
|
|
|
536
561
|
leaseId: '',
|
|
537
562
|
hostInstanceId: '',
|
|
538
563
|
endpoint: '',
|
|
564
|
+
endpointCandidates: [],
|
|
539
565
|
activatedAt: '',
|
|
540
566
|
updatedAt: '',
|
|
541
567
|
expiresAt: ''
|
|
@@ -548,6 +574,7 @@ export function createRemoteHub(options = {}) {
|
|
|
548
574
|
leaseId: target.leaseId,
|
|
549
575
|
hostInstanceId: target.hostInstanceId || hostInstanceId,
|
|
550
576
|
endpoint: target.endpoint,
|
|
577
|
+
endpointCandidates: Array.isArray(target.endpointCandidates) ? [...target.endpointCandidates] : [target.endpoint].filter(Boolean),
|
|
551
578
|
activatedAt: target.activatedAt,
|
|
552
579
|
updatedAt: target.updatedAt,
|
|
553
580
|
expiresAt: target.expiresAt
|
|
@@ -609,6 +636,7 @@ export function createRemoteHub(options = {}) {
|
|
|
609
636
|
leaseId: activeSameNode && previous?.leaseId ? previous.leaseId : crypto.randomUUID(),
|
|
610
637
|
hostInstanceId,
|
|
611
638
|
endpoint: routeInfo.endpoint,
|
|
639
|
+
endpointCandidates: routeInfo.candidates,
|
|
612
640
|
activatedAt: activeSameNode && previous?.activatedAt ? previous.activatedAt : now.toISOString(),
|
|
613
641
|
updatedAt: now.toISOString(),
|
|
614
642
|
expiresAt: new Date(now.getTime() + leaseMs).toISOString()
|
|
@@ -621,7 +649,7 @@ export function createRemoteHub(options = {}) {
|
|
|
621
649
|
if (!activeSameNode || !routeInfo.accountRouteReady) {
|
|
622
650
|
logEvent(
|
|
623
651
|
'remote',
|
|
624
|
-
`host target ${routeInfo.accountRouteReady ? 'account-ready' : 'local-only'} endpoint=${routeInfo.endpoint} reason=${routeInfo.reason}`,
|
|
652
|
+
`host target ${routeInfo.accountRouteReady ? 'account-ready' : 'local-only'} endpoint=${routeInfo.endpoint} candidates=${routeInfo.candidates.length} reason=${routeInfo.reason}`,
|
|
625
653
|
'remote');
|
|
626
654
|
}
|
|
627
655
|
return {
|
|
@@ -665,6 +693,7 @@ export function createRemoteHub(options = {}) {
|
|
|
665
693
|
hostTargetLeaseId: activeHostTarget.leaseId,
|
|
666
694
|
hostTargetHostInstanceId: activeHostTarget.hostInstanceId,
|
|
667
695
|
hostTargetEndpoint: activeHostTarget.endpoint,
|
|
696
|
+
hostTargetEndpointCandidates: activeHostTarget.endpointCandidates,
|
|
668
697
|
hostTargetActivatedAt: activeHostTarget.activatedAt,
|
|
669
698
|
hostTargetUpdatedAt: activeHostTarget.updatedAt,
|
|
670
699
|
hostTargetExpiresAt: activeHostTarget.expiresAt,
|
|
@@ -217,12 +217,14 @@ async function runSyntheticEnabledSmoke() {
|
|
|
217
217
|
assert.equal(setHost.payload?.active, true);
|
|
218
218
|
assert.equal(setHost.payload?.hostTarget?.nodeId, 'remote-fleet-monitor-a');
|
|
219
219
|
assert.equal(setHost.payload?.hostTarget?.endpoint, `127.0.0.1:${remoteHubPort}`);
|
|
220
|
+
assert.deepEqual(setHost.payload?.hostTarget?.endpointCandidates, [`127.0.0.1:${remoteHubPort}`]);
|
|
220
221
|
|
|
221
222
|
const hostStatus = await fetchJson(`${baseUrl}/api/remote/status`, { token: BRIDGE_TOKEN });
|
|
222
223
|
assert.equal(hostStatus.ok, true, JSON.stringify(hostStatus.payload));
|
|
223
224
|
assert.equal(hostStatus.payload?.hostTargetActive, true);
|
|
224
225
|
assert.equal(hostStatus.payload?.hostTargetNodeId, 'remote-fleet-monitor-a');
|
|
225
226
|
assert.equal(hostStatus.payload?.hostTargetEndpoint, `127.0.0.1:${remoteHubPort}`);
|
|
227
|
+
assert.deepEqual(hostStatus.payload?.hostTargetEndpointCandidates, [`127.0.0.1:${remoteHubPort}`]);
|
|
226
228
|
|
|
227
229
|
const clearHostMismatch = await fetchJson(`${baseUrl}/api/remote/host-target`, {
|
|
228
230
|
method: 'DELETE',
|
package/server.js
CHANGED
|
@@ -2733,6 +2733,7 @@ const remoteHub = createRemoteHub({
|
|
|
2733
2733
|
|
|
2734
2734
|
const REMOTE_AGENT_STDIO_TAIL_CHARS = 12000;
|
|
2735
2735
|
const REMOTE_AGENT_EARLY_EXIT_MS = 1200;
|
|
2736
|
+
const REMOTE_AGENT_READY_TIMEOUT_MS = 5000;
|
|
2736
2737
|
const REMOTE_AGENT_DEFAULT_ENGINE = 'auto';
|
|
2737
2738
|
let remoteAgentState = createRemoteAgentIdleState();
|
|
2738
2739
|
|
|
@@ -2740,6 +2741,7 @@ function createRemoteAgentIdleState(overrides = {}) {
|
|
|
2740
2741
|
return {
|
|
2741
2742
|
status: 'idle',
|
|
2742
2743
|
manager: '',
|
|
2744
|
+
managerCandidates: [],
|
|
2743
2745
|
leaseId: '',
|
|
2744
2746
|
nodeId: '',
|
|
2745
2747
|
engine: REMOTE_AGENT_DEFAULT_ENGINE,
|
|
@@ -2748,6 +2750,8 @@ function createRemoteAgentIdleState(overrides = {}) {
|
|
|
2748
2750
|
pid: 0,
|
|
2749
2751
|
startedAt: '',
|
|
2750
2752
|
updatedAt: new Date().toISOString(),
|
|
2753
|
+
ready: false,
|
|
2754
|
+
connectedAt: '',
|
|
2751
2755
|
exitedAt: '',
|
|
2752
2756
|
exitCode: null,
|
|
2753
2757
|
signal: '',
|
|
@@ -2772,10 +2776,18 @@ function serializeRemoteAgentState() {
|
|
|
2772
2776
|
};
|
|
2773
2777
|
}
|
|
2774
2778
|
|
|
2775
|
-
function appendRemoteAgentOutput(stream, chunk) {
|
|
2779
|
+
function appendRemoteAgentOutput(stream, chunk, stateConnectionKey = '') {
|
|
2780
|
+
if (stateConnectionKey && remoteAgentState.connectionKey !== stateConnectionKey) {
|
|
2781
|
+
return;
|
|
2782
|
+
}
|
|
2783
|
+
|
|
2776
2784
|
const text = chunk.toString();
|
|
2777
2785
|
const key = stream === 'stderr' ? 'stderrTail' : 'stdoutTail';
|
|
2778
2786
|
remoteAgentState[key] = String((remoteAgentState[key] || '') + text).slice(-REMOTE_AGENT_STDIO_TAIL_CHARS);
|
|
2787
|
+
if (/Connected to RemoteHub/i.test(text)) {
|
|
2788
|
+
remoteAgentState.ready = true;
|
|
2789
|
+
remoteAgentState.connectedAt = new Date().toISOString();
|
|
2790
|
+
}
|
|
2779
2791
|
remoteAgentState.updatedAt = new Date().toISOString();
|
|
2780
2792
|
}
|
|
2781
2793
|
|
|
@@ -2844,6 +2856,53 @@ function waitForRemoteAgentEarlyExit(child, settleMs = REMOTE_AGENT_EARLY_EXIT_M
|
|
|
2844
2856
|
});
|
|
2845
2857
|
}
|
|
2846
2858
|
|
|
2859
|
+
function waitForRemoteAgentReady(child, timeoutMs = REMOTE_AGENT_READY_TIMEOUT_MS) {
|
|
2860
|
+
return new Promise(resolve => {
|
|
2861
|
+
if (!child || child.exitCode !== null || child.killed) {
|
|
2862
|
+
resolve(false);
|
|
2863
|
+
return;
|
|
2864
|
+
}
|
|
2865
|
+
|
|
2866
|
+
if (remoteAgentState.ready === true) {
|
|
2867
|
+
resolve(true);
|
|
2868
|
+
return;
|
|
2869
|
+
}
|
|
2870
|
+
|
|
2871
|
+
let settled = false;
|
|
2872
|
+
let timer = null;
|
|
2873
|
+
let poller = null;
|
|
2874
|
+
const cleanup = () => {
|
|
2875
|
+
if (timer) {
|
|
2876
|
+
clearTimeout(timer);
|
|
2877
|
+
}
|
|
2878
|
+
if (poller) {
|
|
2879
|
+
clearInterval(poller);
|
|
2880
|
+
}
|
|
2881
|
+
child.off('exit', onExit);
|
|
2882
|
+
child.off('error', onError);
|
|
2883
|
+
};
|
|
2884
|
+
const finish = value => {
|
|
2885
|
+
if (settled) {
|
|
2886
|
+
return;
|
|
2887
|
+
}
|
|
2888
|
+
settled = true;
|
|
2889
|
+
cleanup();
|
|
2890
|
+
resolve(value);
|
|
2891
|
+
};
|
|
2892
|
+
const onExit = () => finish(false);
|
|
2893
|
+
const onError = () => finish(false);
|
|
2894
|
+
|
|
2895
|
+
child.once('exit', onExit);
|
|
2896
|
+
child.once('error', onError);
|
|
2897
|
+
poller = setInterval(() => {
|
|
2898
|
+
if (remoteAgentState.ready === true) {
|
|
2899
|
+
finish(true);
|
|
2900
|
+
}
|
|
2901
|
+
}, 100);
|
|
2902
|
+
timer = setTimeout(() => finish(remoteAgentState.ready === true), timeoutMs);
|
|
2903
|
+
});
|
|
2904
|
+
}
|
|
2905
|
+
|
|
2847
2906
|
function normalizeRemoteAgentEngine(value) {
|
|
2848
2907
|
const engine = String(value || REMOTE_AGENT_DEFAULT_ENGINE).trim().toLowerCase();
|
|
2849
2908
|
if (engine === 'fast' || engine === 'csharp' || engine === 'c#') {
|
|
@@ -2871,6 +2930,34 @@ function normalizeRemoteManagerEndpoint(value) {
|
|
|
2871
2930
|
return `${match[1]}:${port}`;
|
|
2872
2931
|
}
|
|
2873
2932
|
|
|
2933
|
+
function normalizeRemoteManagerEndpointList(...values) {
|
|
2934
|
+
const rawValues = [];
|
|
2935
|
+
for (const value of values) {
|
|
2936
|
+
if (Array.isArray(value)) {
|
|
2937
|
+
rawValues.push(...value);
|
|
2938
|
+
} else if (value && typeof value[Symbol.iterator] === 'function' && typeof value !== 'string') {
|
|
2939
|
+
rawValues.push(...value);
|
|
2940
|
+
} else {
|
|
2941
|
+
rawValues.push(value);
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2944
|
+
|
|
2945
|
+
const endpoints = [];
|
|
2946
|
+
const seen = new Set();
|
|
2947
|
+
for (const value of rawValues) {
|
|
2948
|
+
const endpoint = normalizeRemoteManagerEndpoint(value);
|
|
2949
|
+
const key = endpoint.toLowerCase();
|
|
2950
|
+
if (!endpoint || seen.has(key)) {
|
|
2951
|
+
continue;
|
|
2952
|
+
}
|
|
2953
|
+
|
|
2954
|
+
seen.add(key);
|
|
2955
|
+
endpoints.push(endpoint);
|
|
2956
|
+
}
|
|
2957
|
+
|
|
2958
|
+
return endpoints;
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2874
2961
|
function safeRemoteAgentField(value, maxLength = 128) {
|
|
2875
2962
|
return String(value || '').replace(/[\r\n\t]/g, ' ').trim().slice(0, maxLength);
|
|
2876
2963
|
}
|
|
@@ -2928,6 +3015,7 @@ async function stopRemoteAgentConnection(reason = 'stopped') {
|
|
|
2928
3015
|
remoteAgentState = createRemoteAgentIdleState({
|
|
2929
3016
|
status: 'stopped',
|
|
2930
3017
|
manager: previous.manager,
|
|
3018
|
+
managerCandidates: previous.managerCandidates,
|
|
2931
3019
|
leaseId: previous.leaseId,
|
|
2932
3020
|
nodeId: previous.nodeId,
|
|
2933
3021
|
engine: previous.engine,
|
|
@@ -2946,25 +3034,31 @@ async function stopRemoteAgentConnection(reason = 'stopped') {
|
|
|
2946
3034
|
}
|
|
2947
3035
|
|
|
2948
3036
|
async function startRemoteAgentConnection(options = {}) {
|
|
2949
|
-
const manager = normalizeRemoteManagerEndpoint(options.manager || options.managerEndpoint || options.endpoint);
|
|
2950
3037
|
const pairToken = safeRemoteAgentField(options.pairToken || options.pair, 512);
|
|
2951
3038
|
const leaseId = safeRemoteAgentField(options.leaseId, 128);
|
|
2952
3039
|
const nodeId = safeRemoteAgentField(options.nodeId, 128);
|
|
2953
3040
|
const source = safeRemoteAgentField(options.source || 'registry', 64);
|
|
2954
3041
|
const engine = normalizeRemoteAgentEngine(options.engine);
|
|
3042
|
+
const managers = normalizeRemoteManagerEndpointList(
|
|
3043
|
+
options.manager || options.managerEndpoint || options.endpoint,
|
|
3044
|
+
options.managerCandidates,
|
|
3045
|
+
options.endpointCandidates,
|
|
3046
|
+
options.candidates);
|
|
2955
3047
|
|
|
2956
|
-
if (
|
|
3048
|
+
if (managers.length === 0) {
|
|
2957
3049
|
logWarn('remote', 'managed RemoteAgent connect rejected: invalid manager endpoint');
|
|
2958
3050
|
return { ok: false, error: 'invalid-manager-endpoint', agent: serializeRemoteAgentState() };
|
|
2959
3051
|
}
|
|
2960
3052
|
|
|
2961
3053
|
if (!pairToken) {
|
|
2962
|
-
logWarn('remote', `managed RemoteAgent connect rejected: missing pair token ${formatKeyValue('manager',
|
|
3054
|
+
logWarn('remote', `managed RemoteAgent connect rejected: missing pair token ${formatKeyValue('manager', managers[0])}`);
|
|
2963
3055
|
return { ok: false, error: 'missing-pair-token', agent: serializeRemoteAgentState() };
|
|
2964
3056
|
}
|
|
2965
3057
|
|
|
2966
|
-
const
|
|
2967
|
-
if (isRemoteAgentProcessRunning()
|
|
3058
|
+
const activeConnectionKeys = new Set(managers.map(manager => createRemoteAgentConnectionKey(manager, leaseId)));
|
|
3059
|
+
if (isRemoteAgentProcessRunning()
|
|
3060
|
+
&& remoteAgentState.ready === true
|
|
3061
|
+
&& activeConnectionKeys.has(remoteAgentState.connectionKey)) {
|
|
2968
3062
|
return { ok: true, alreadyRunning: true, agent: serializeRemoteAgentState() };
|
|
2969
3063
|
}
|
|
2970
3064
|
|
|
@@ -2972,6 +3066,66 @@ async function startRemoteAgentConnection(options = {}) {
|
|
|
2972
3066
|
await stopRemoteAgentConnection('replaced-by-new-target');
|
|
2973
3067
|
}
|
|
2974
3068
|
|
|
3069
|
+
let lastResult = null;
|
|
3070
|
+
for (let index = 0; index < managers.length; index += 1) {
|
|
3071
|
+
const manager = managers[index];
|
|
3072
|
+
if (managers.length > 1) {
|
|
3073
|
+
logEvent(
|
|
3074
|
+
'remote',
|
|
3075
|
+
`managed RemoteAgent candidate ${index + 1}/${managers.length} ${formatKeyValue('manager', manager)}`,
|
|
3076
|
+
'remote');
|
|
3077
|
+
}
|
|
3078
|
+
|
|
3079
|
+
const result = await startRemoteAgentConnectionAttempt({
|
|
3080
|
+
manager,
|
|
3081
|
+
managerCandidates: managers,
|
|
3082
|
+
pairToken,
|
|
3083
|
+
leaseId,
|
|
3084
|
+
nodeId,
|
|
3085
|
+
source,
|
|
3086
|
+
engine
|
|
3087
|
+
});
|
|
3088
|
+
if (result?.ok === true) {
|
|
3089
|
+
return result;
|
|
3090
|
+
}
|
|
3091
|
+
|
|
3092
|
+
lastResult = result;
|
|
3093
|
+
if (isRemoteAgentProcessRunning()) {
|
|
3094
|
+
await stopRemoteAgentConnection(`candidate-failed:${manager}`);
|
|
3095
|
+
}
|
|
3096
|
+
|
|
3097
|
+
if (index + 1 < managers.length) {
|
|
3098
|
+
logWarn(
|
|
3099
|
+
'remote',
|
|
3100
|
+
`managed RemoteAgent candidate failed; trying next ${formatKeyValue('manager', manager)} ${formatKeyValue('error', result?.error || 'unknown')}`);
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
|
|
3104
|
+
return {
|
|
3105
|
+
ok: false,
|
|
3106
|
+
error: lastResult?.error || 'all-manager-candidates-failed',
|
|
3107
|
+
agent: lastResult?.agent || serializeRemoteAgentState()
|
|
3108
|
+
};
|
|
3109
|
+
}
|
|
3110
|
+
|
|
3111
|
+
async function startRemoteAgentConnectionAttempt(options = {}) {
|
|
3112
|
+
const manager = normalizeRemoteManagerEndpoint(options.manager || options.managerEndpoint || options.endpoint);
|
|
3113
|
+
const pairToken = safeRemoteAgentField(options.pairToken || options.pair, 512);
|
|
3114
|
+
const leaseId = safeRemoteAgentField(options.leaseId, 128);
|
|
3115
|
+
const nodeId = safeRemoteAgentField(options.nodeId, 128);
|
|
3116
|
+
const source = safeRemoteAgentField(options.source || 'registry', 64);
|
|
3117
|
+
const engine = normalizeRemoteAgentEngine(options.engine);
|
|
3118
|
+
const managerCandidates = normalizeRemoteManagerEndpointList(options.managerCandidates, manager);
|
|
3119
|
+
|
|
3120
|
+
if (!manager) {
|
|
3121
|
+
return { ok: false, error: 'invalid-manager-endpoint', agent: serializeRemoteAgentState() };
|
|
3122
|
+
}
|
|
3123
|
+
|
|
3124
|
+
if (!pairToken) {
|
|
3125
|
+
return { ok: false, error: 'missing-pair-token', agent: serializeRemoteAgentState() };
|
|
3126
|
+
}
|
|
3127
|
+
|
|
3128
|
+
const connectionKey = createRemoteAgentConnectionKey(manager, leaseId);
|
|
2975
3129
|
const launcher = resolveRemoteAgentLauncher();
|
|
2976
3130
|
const args = [
|
|
2977
3131
|
...launcher.argsPrefix,
|
|
@@ -2987,12 +3141,15 @@ async function startRemoteAgentConnection(options = {}) {
|
|
|
2987
3141
|
remoteAgentState = createRemoteAgentIdleState({
|
|
2988
3142
|
status: 'starting',
|
|
2989
3143
|
manager,
|
|
3144
|
+
managerCandidates,
|
|
2990
3145
|
leaseId,
|
|
2991
3146
|
nodeId,
|
|
2992
3147
|
engine,
|
|
2993
3148
|
source,
|
|
2994
3149
|
connectionKey,
|
|
2995
3150
|
startedAt: new Date().toISOString(),
|
|
3151
|
+
ready: false,
|
|
3152
|
+
connectedAt: '',
|
|
2996
3153
|
launcher: launcher.launcher,
|
|
2997
3154
|
usingNpx: launcher.usingNpx
|
|
2998
3155
|
});
|
|
@@ -3022,10 +3179,15 @@ async function startRemoteAgentConnection(options = {}) {
|
|
|
3022
3179
|
remoteAgentState.pid = Number(child.pid || 0);
|
|
3023
3180
|
remoteAgentState.status = 'running';
|
|
3024
3181
|
remoteAgentState.updatedAt = new Date().toISOString();
|
|
3182
|
+
const stateConnectionKey = connectionKey;
|
|
3025
3183
|
|
|
3026
|
-
child.stdout.on('data', chunk => appendRemoteAgentOutput('stdout', chunk));
|
|
3027
|
-
child.stderr.on('data', chunk => appendRemoteAgentOutput('stderr', chunk));
|
|
3184
|
+
child.stdout.on('data', chunk => appendRemoteAgentOutput('stdout', chunk, stateConnectionKey));
|
|
3185
|
+
child.stderr.on('data', chunk => appendRemoteAgentOutput('stderr', chunk, stateConnectionKey));
|
|
3028
3186
|
child.once('error', err => {
|
|
3187
|
+
if (remoteAgentState.connectionKey !== stateConnectionKey) {
|
|
3188
|
+
return;
|
|
3189
|
+
}
|
|
3190
|
+
|
|
3029
3191
|
remoteAgentState.status = 'failed';
|
|
3030
3192
|
remoteAgentState.lastError = err?.message || String(err);
|
|
3031
3193
|
remoteAgentState.updatedAt = new Date().toISOString();
|
|
@@ -3033,6 +3195,10 @@ async function startRemoteAgentConnection(options = {}) {
|
|
|
3033
3195
|
emitBridgeEvent('RemoteAgentFailed', serializeRemoteAgentState());
|
|
3034
3196
|
});
|
|
3035
3197
|
child.once('exit', (code, signal) => {
|
|
3198
|
+
if (remoteAgentState.connectionKey !== stateConnectionKey) {
|
|
3199
|
+
return;
|
|
3200
|
+
}
|
|
3201
|
+
|
|
3036
3202
|
remoteAgentState.status = code === 0 ? 'exited' : 'failed';
|
|
3037
3203
|
remoteAgentState.exitCode = Number.isFinite(code) ? code : null;
|
|
3038
3204
|
remoteAgentState.signal = signal || '';
|
|
@@ -3062,6 +3228,17 @@ async function startRemoteAgentConnection(options = {}) {
|
|
|
3062
3228
|
return { ok: false, error, agent: serializeRemoteAgentState() };
|
|
3063
3229
|
}
|
|
3064
3230
|
|
|
3231
|
+
const ready = await waitForRemoteAgentReady(child);
|
|
3232
|
+
if (!ready) {
|
|
3233
|
+
const error = `remote-agent-not-ready:${manager}`;
|
|
3234
|
+
remoteAgentState.status = 'failed';
|
|
3235
|
+
remoteAgentState.lastError = error;
|
|
3236
|
+
remoteAgentState.updatedAt = new Date().toISOString();
|
|
3237
|
+
logWarn('remote', `managed RemoteAgent startup did not connect ${formatKeyValue('manager', manager)} ${formatKeyValue('error', formatRemoteAgentFailureSummary())}`);
|
|
3238
|
+
emitBridgeEvent('RemoteAgentFailed', serializeRemoteAgentState());
|
|
3239
|
+
return { ok: false, error, agent: serializeRemoteAgentState() };
|
|
3240
|
+
}
|
|
3241
|
+
|
|
3065
3242
|
return { ok: true, alreadyRunning: false, agent: serializeRemoteAgentState() };
|
|
3066
3243
|
}
|
|
3067
3244
|
|
|
@@ -7621,6 +7798,7 @@ app.post('/api/remote/agent/connect', async (req, res) => {
|
|
|
7621
7798
|
const requestedManager = normalizeRemoteManagerEndpoint(req.body?.manager || req.body?.managerEndpoint);
|
|
7622
7799
|
const result = await startRemoteAgentConnection({
|
|
7623
7800
|
manager: requestedManager,
|
|
7801
|
+
managerCandidates: req.body?.managerCandidates || req.body?.endpointCandidates || req.body?.candidates,
|
|
7624
7802
|
pairToken: req.body?.pairToken || req.body?.pair,
|
|
7625
7803
|
leaseId: req.body?.leaseId,
|
|
7626
7804
|
nodeId: req.body?.nodeId,
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"mainAssemblyName": "MindExecution.Web",
|
|
3
3
|
"resources": {
|
|
4
|
-
"hash": "sha256-
|
|
4
|
+
"hash": "sha256-5gnfR4WvV/8ivk6zDF09/vNhA5Ptgr7fb/UhdwOAmHM=",
|
|
5
5
|
"fingerprinting": {
|
|
6
6
|
"Google.Protobuf.9h59ukbel7.dll": "Google.Protobuf.dll",
|
|
7
7
|
"Markdig.d1j7v41cl1.dll": "Markdig.dll",
|
|
@@ -123,16 +123,16 @@
|
|
|
123
123
|
"System.brmz7yk5qh.dll": "System.dll",
|
|
124
124
|
"netstandard.yvr3prsx0x.dll": "netstandard.dll",
|
|
125
125
|
"System.Private.CoreLib.c1dbswx1b2.dll": "System.Private.CoreLib.dll",
|
|
126
|
-
"MindExecution.Core.
|
|
127
|
-
"MindExecution.Kernel.
|
|
128
|
-
"MindExecution.Plugins.Admin.
|
|
129
|
-
"MindExecution.Plugins.Business.
|
|
130
|
-
"MindExecution.Plugins.Concept.
|
|
131
|
-
"MindExecution.Plugins.Directory.
|
|
132
|
-
"MindExecution.Plugins.PlanMaster.
|
|
133
|
-
"MindExecution.Plugins.YouTube.
|
|
134
|
-
"MindExecution.Shared.
|
|
135
|
-
"MindExecution.Web.
|
|
126
|
+
"MindExecution.Core.eyl4o4qxg8.dll": "MindExecution.Core.dll",
|
|
127
|
+
"MindExecution.Kernel.hxyapaztgr.dll": "MindExecution.Kernel.dll",
|
|
128
|
+
"MindExecution.Plugins.Admin.7kemovesa7.dll": "MindExecution.Plugins.Admin.dll",
|
|
129
|
+
"MindExecution.Plugins.Business.t370in2g1b.dll": "MindExecution.Plugins.Business.dll",
|
|
130
|
+
"MindExecution.Plugins.Concept.oqhv1116kb.dll": "MindExecution.Plugins.Concept.dll",
|
|
131
|
+
"MindExecution.Plugins.Directory.0v80a0hi9m.dll": "MindExecution.Plugins.Directory.dll",
|
|
132
|
+
"MindExecution.Plugins.PlanMaster.hn5sfx4z2l.dll": "MindExecution.Plugins.PlanMaster.dll",
|
|
133
|
+
"MindExecution.Plugins.YouTube.c8sc0tlc6o.dll": "MindExecution.Plugins.YouTube.dll",
|
|
134
|
+
"MindExecution.Shared.osv9nbh3ym.dll": "MindExecution.Shared.dll",
|
|
135
|
+
"MindExecution.Web.cdu22y82zq.dll": "MindExecution.Web.dll",
|
|
136
136
|
"dotnet.js": "dotnet.js",
|
|
137
137
|
"dotnet.native.qc8g39g30v.js": "dotnet.native.js",
|
|
138
138
|
"dotnet.native.boem75ye5i.wasm": "dotnet.native.wasm",
|
|
@@ -278,18 +278,18 @@
|
|
|
278
278
|
"System.Xml.XDocument.sn51jas17n.dll": "sha256-GNI2kFgFmPTwzuzwUn8gxK+AzGLUWRJFdg9JzIbrybQ=",
|
|
279
279
|
"System.brmz7yk5qh.dll": "sha256-CfM2miyj1KHApFmqMdLYWio3S/jrdON2pW9Xr2nTwlo=",
|
|
280
280
|
"netstandard.yvr3prsx0x.dll": "sha256-EksNn8Luo4bOWqJ6X7dIe9qG9oOqwOVzjH2xYyMNi+E=",
|
|
281
|
-
"MindExecution.Core.
|
|
282
|
-
"MindExecution.Kernel.
|
|
283
|
-
"MindExecution.Plugins.Concept.
|
|
284
|
-
"MindExecution.Plugins.PlanMaster.
|
|
285
|
-
"MindExecution.Shared.
|
|
286
|
-
"MindExecution.Web.
|
|
281
|
+
"MindExecution.Core.eyl4o4qxg8.dll": "sha256-JtBC04XSxkMOl0cZOA2ZWvyV88yYPyU0nkIbBCF9Jtc=",
|
|
282
|
+
"MindExecution.Kernel.hxyapaztgr.dll": "sha256-q59U8/001rTsB1m+pkA4PkI9a9lvf5fijDWKXbN7uQ4=",
|
|
283
|
+
"MindExecution.Plugins.Concept.oqhv1116kb.dll": "sha256-kEAfhSpocd0AdwocZnMU2+v0W2y6HJV7TRiOB6FbmDY=",
|
|
284
|
+
"MindExecution.Plugins.PlanMaster.hn5sfx4z2l.dll": "sha256-Y2F3UYa2JgW9pCxL/YlCHo6gUohqHjQ4Z59cL/fdDBU=",
|
|
285
|
+
"MindExecution.Shared.osv9nbh3ym.dll": "sha256-yKMhEPXMN1XCDYyFMEbhio9mvn7j2JkPK/upMkWEfOE=",
|
|
286
|
+
"MindExecution.Web.cdu22y82zq.dll": "sha256-wO+wguSU+8uumbvn/I2fjxrD0N3+xXvJZZWTmE2EjKg="
|
|
287
287
|
},
|
|
288
288
|
"lazyAssembly": {
|
|
289
|
-
"MindExecution.Plugins.Admin.
|
|
290
|
-
"MindExecution.Plugins.Business.
|
|
291
|
-
"MindExecution.Plugins.Directory.
|
|
292
|
-
"MindExecution.Plugins.YouTube.
|
|
289
|
+
"MindExecution.Plugins.Admin.7kemovesa7.dll": "sha256-N8cYgaOErldVhLpnvnh4R9kf7f7fmt+16KhBWlnfG1I=",
|
|
290
|
+
"MindExecution.Plugins.Business.t370in2g1b.dll": "sha256-B66uDzMZQfzN3fDnRSM1TvWh0uZjD6AVfUvJAyuGMdI=",
|
|
291
|
+
"MindExecution.Plugins.Directory.0v80a0hi9m.dll": "sha256-JPn9UkEDTmb2CO4o/CnuG76R4RgQStGYZ6jH5pzblXk=",
|
|
292
|
+
"MindExecution.Plugins.YouTube.c8sc0tlc6o.dll": "sha256-7P2anWE7Z/EXJfm/2CSQ1SWL1qPRtZG+gMwZEeqQaKM="
|
|
293
293
|
}
|
|
294
294
|
},
|
|
295
295
|
"cacheBootResources": true,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
self.assetsManifest = {
|
|
2
|
-
"version": "
|
|
2
|
+
"version": "Gwzavwgq",
|
|
3
3
|
"assets": [
|
|
4
4
|
{
|
|
5
5
|
"hash": "sha256-+CSYMcqLNTsq3VnH11jgYyOCCdxvHzL74CBmo4sCmMU=",
|
|
@@ -410,44 +410,44 @@
|
|
|
410
410
|
"url": "_framework/MimeMapping.og9ys58ylm.dll"
|
|
411
411
|
},
|
|
412
412
|
{
|
|
413
|
-
"hash": "sha256-
|
|
414
|
-
"url": "_framework/MindExecution.Core.
|
|
413
|
+
"hash": "sha256-JtBC04XSxkMOl0cZOA2ZWvyV88yYPyU0nkIbBCF9Jtc=",
|
|
414
|
+
"url": "_framework/MindExecution.Core.eyl4o4qxg8.dll"
|
|
415
415
|
},
|
|
416
416
|
{
|
|
417
|
-
"hash": "sha256-
|
|
418
|
-
"url": "_framework/MindExecution.Kernel.
|
|
417
|
+
"hash": "sha256-q59U8/001rTsB1m+pkA4PkI9a9lvf5fijDWKXbN7uQ4=",
|
|
418
|
+
"url": "_framework/MindExecution.Kernel.hxyapaztgr.dll"
|
|
419
419
|
},
|
|
420
420
|
{
|
|
421
|
-
"hash": "sha256-
|
|
422
|
-
"url": "_framework/MindExecution.Plugins.Admin.
|
|
421
|
+
"hash": "sha256-N8cYgaOErldVhLpnvnh4R9kf7f7fmt+16KhBWlnfG1I=",
|
|
422
|
+
"url": "_framework/MindExecution.Plugins.Admin.7kemovesa7.dll"
|
|
423
423
|
},
|
|
424
424
|
{
|
|
425
|
-
"hash": "sha256-
|
|
426
|
-
"url": "_framework/MindExecution.Plugins.Business.
|
|
425
|
+
"hash": "sha256-B66uDzMZQfzN3fDnRSM1TvWh0uZjD6AVfUvJAyuGMdI=",
|
|
426
|
+
"url": "_framework/MindExecution.Plugins.Business.t370in2g1b.dll"
|
|
427
427
|
},
|
|
428
428
|
{
|
|
429
|
-
"hash": "sha256-
|
|
430
|
-
"url": "_framework/MindExecution.Plugins.Concept.
|
|
429
|
+
"hash": "sha256-kEAfhSpocd0AdwocZnMU2+v0W2y6HJV7TRiOB6FbmDY=",
|
|
430
|
+
"url": "_framework/MindExecution.Plugins.Concept.oqhv1116kb.dll"
|
|
431
431
|
},
|
|
432
432
|
{
|
|
433
|
-
"hash": "sha256-
|
|
434
|
-
"url": "_framework/MindExecution.Plugins.Directory.
|
|
433
|
+
"hash": "sha256-JPn9UkEDTmb2CO4o/CnuG76R4RgQStGYZ6jH5pzblXk=",
|
|
434
|
+
"url": "_framework/MindExecution.Plugins.Directory.0v80a0hi9m.dll"
|
|
435
435
|
},
|
|
436
436
|
{
|
|
437
|
-
"hash": "sha256-
|
|
438
|
-
"url": "_framework/MindExecution.Plugins.PlanMaster.
|
|
437
|
+
"hash": "sha256-Y2F3UYa2JgW9pCxL/YlCHo6gUohqHjQ4Z59cL/fdDBU=",
|
|
438
|
+
"url": "_framework/MindExecution.Plugins.PlanMaster.hn5sfx4z2l.dll"
|
|
439
439
|
},
|
|
440
440
|
{
|
|
441
|
-
"hash": "sha256-
|
|
442
|
-
"url": "_framework/MindExecution.Plugins.YouTube.
|
|
441
|
+
"hash": "sha256-7P2anWE7Z/EXJfm/2CSQ1SWL1qPRtZG+gMwZEeqQaKM=",
|
|
442
|
+
"url": "_framework/MindExecution.Plugins.YouTube.c8sc0tlc6o.dll"
|
|
443
443
|
},
|
|
444
444
|
{
|
|
445
|
-
"hash": "sha256-
|
|
446
|
-
"url": "_framework/MindExecution.Shared.
|
|
445
|
+
"hash": "sha256-yKMhEPXMN1XCDYyFMEbhio9mvn7j2JkPK/upMkWEfOE=",
|
|
446
|
+
"url": "_framework/MindExecution.Shared.osv9nbh3ym.dll"
|
|
447
447
|
},
|
|
448
448
|
{
|
|
449
|
-
"hash": "sha256-
|
|
450
|
-
"url": "_framework/MindExecution.Web.
|
|
449
|
+
"hash": "sha256-wO+wguSU+8uumbvn/I2fjxrD0N3+xXvJZZWTmE2EjKg=",
|
|
450
|
+
"url": "_framework/MindExecution.Web.cdu22y82zq.dll"
|
|
451
451
|
},
|
|
452
452
|
{
|
|
453
453
|
"hash": "sha256-IsZJ91/OW+fHzNqIgEc7Y072ns8z9dGritiSyvR9Wgc=",
|
|
@@ -770,7 +770,7 @@
|
|
|
770
770
|
"url": "_framework/Websocket.Client.vapounvmnl.dll"
|
|
771
771
|
},
|
|
772
772
|
{
|
|
773
|
-
"hash": "sha256-
|
|
773
|
+
"hash": "sha256-IDuQS33M39C51AcKlK3xYrMwyKOYKfuVq1o1JIS4wkw=",
|
|
774
774
|
"url": "_framework/blazor.boot.json"
|
|
775
775
|
},
|
|
776
776
|
{
|
|
Binary file
|
|
Binary file
|