@midscene/cli 1.10.2 → 1.10.4-beta-20260707113337.0
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/es/index.mjs +193 -17
- package/dist/es/index.mjs.map +1 -1
- package/dist/lib/index.js +195 -17
- package/dist/lib/index.js.map +1 -1
- package/package.json +8 -8
package/dist/es/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*! For license information please see index.mjs.LICENSE.txt */
|
|
2
|
-
import
|
|
3
|
-
import { ReportMergingTool, createReportCliCommands } from "@midscene/core";
|
|
2
|
+
import { ReportMergingTool, createReportCliCommands, runConnectivityTest } from "@midscene/core";
|
|
4
3
|
import { runToolsCLI } from "@midscene/shared/cli";
|
|
4
|
+
import node_path, { basename, dirname as external_node_path_dirname, extname, join, posix, relative as external_node_path_relative, resolve as external_node_path_resolve, sep as external_node_path_sep, win32 } from "node:path";
|
|
5
5
|
import { getDebug } from "@midscene/shared/logger";
|
|
6
6
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
7
|
import { lstat, readdir, readlink, realpath } from "node:fs/promises";
|
|
@@ -23,6 +23,7 @@ import { processCacheConfig } from "@midscene/core/utils";
|
|
|
23
23
|
import { AgentOverChromeBridge } from "@midscene/web/bridge-mode";
|
|
24
24
|
import { stripVTControlCharacters } from "node:util";
|
|
25
25
|
import { createRequire } from "node:module";
|
|
26
|
+
import { globalModelConfigManager } from "@midscene/shared/env";
|
|
26
27
|
import * as __rspack_external_assert from "assert";
|
|
27
28
|
import * as __rspack_external_crypto from "crypto";
|
|
28
29
|
import * as __rspack_external_fs from "fs";
|
|
@@ -3024,11 +3025,7 @@ var __webpack_modules__ = {
|
|
|
3024
3025
|
module.exports = (string, columns, options)=>String(string).normalize().replace(/\r\n/g, '\n').split('\n').map((line)=>exec(line, columns, options)).join('\n');
|
|
3025
3026
|
},
|
|
3026
3027
|
"./src/index.ts" (__unused_rspack_module, __unused_rspack___webpack_exports__, __webpack_require__) {
|
|
3027
|
-
var
|
|
3028
|
-
var main_default = /*#__PURE__*/ __webpack_require__.n(main);
|
|
3029
|
-
var package_namespaceObject = {
|
|
3030
|
-
rE: "1.10.2"
|
|
3031
|
-
};
|
|
3028
|
+
var package_namespaceObject = JSON.parse('{"rE":"1.10.4-beta-20260707113337.0"}');
|
|
3032
3029
|
var brace_expansion = __webpack_require__("../../node_modules/.pnpm/brace-expansion@2.0.1/node_modules/brace-expansion/index.js");
|
|
3033
3030
|
const MAX_PATTERN_LENGTH = 65536;
|
|
3034
3031
|
const assertValidPattern = (pattern)=>{
|
|
@@ -10889,7 +10886,7 @@ Usage:
|
|
|
10889
10886
|
type: 'boolean',
|
|
10890
10887
|
description: `Turn on logging to help debug why certain keys or values are not being set as you expect, default is ${config_factory_defaultConfig.dotenvDebug}`
|
|
10891
10888
|
}
|
|
10892
|
-
}).version('version', 'Show version number', "1.10.
|
|
10889
|
+
}).version('version', 'Show version number', "1.10.4-beta-20260707113337.0").help().epilogue(`For complete list of configuration options, please visit:
|
|
10893
10890
|
• Web options: https://midscenejs.com/automate-with-scripts-in-yaml#the-web-part
|
|
10894
10891
|
• Android options: https://midscenejs.com/automate-with-scripts-in-yaml#the-android-part
|
|
10895
10892
|
• iOS options: https://midscenejs.com/automate-with-scripts-in-yaml#the-ios-part
|
|
@@ -10937,6 +10934,18 @@ Examples:
|
|
|
10937
10934
|
});
|
|
10938
10935
|
return files.filter((file)=>file.endsWith('.yml') || file.endsWith('.yaml')).sort();
|
|
10939
10936
|
}
|
|
10937
|
+
var main = __webpack_require__("../../node_modules/.pnpm/dotenv@16.4.5/node_modules/dotenv/lib/main.js");
|
|
10938
|
+
var main_default = /*#__PURE__*/ __webpack_require__.n(main);
|
|
10939
|
+
function loadDotenvConfig(options = {}) {
|
|
10940
|
+
const dotEnvConfigFile = join(options.cwd ?? process.cwd(), '.env');
|
|
10941
|
+
if (!(0, __rspack_external_node_fs_5ea92f0c.existsSync)(dotEnvConfigFile)) return;
|
|
10942
|
+
options.log?.(` Env file: ${dotEnvConfigFile}`);
|
|
10943
|
+
main_default().config({
|
|
10944
|
+
path: dotEnvConfigFile,
|
|
10945
|
+
debug: options.dotenvDebug,
|
|
10946
|
+
override: options.dotenvOverride
|
|
10947
|
+
});
|
|
10948
|
+
}
|
|
10940
10949
|
const warnRetryReport = getDebug('execution-summary', {
|
|
10941
10950
|
console: true
|
|
10942
10951
|
});
|
|
@@ -12609,6 +12618,172 @@ defineYamlBatchTest(test, testOptions);
|
|
|
12609
12618
|
const success = printExecutionSummary(results, summaryPath);
|
|
12610
12619
|
return success ? exitCode : 1;
|
|
12611
12620
|
}
|
|
12621
|
+
const DEFAULT_OPENAI_BASE_URL = 'https://api.openai.com/v1';
|
|
12622
|
+
const MODEL_VERIFY_SEPARATOR = '────────────────────────────────────────';
|
|
12623
|
+
const MODEL_COMMAND_USAGE = `Usage:
|
|
12624
|
+
midscene model verify
|
|
12625
|
+
midscene model eval
|
|
12626
|
+
`;
|
|
12627
|
+
function assertNoModelVerifyOptions(args) {
|
|
12628
|
+
for (const arg of args)throw new Error(`Unknown option for midscene model verify: ${arg}`);
|
|
12629
|
+
}
|
|
12630
|
+
function shellSingleQuote(value) {
|
|
12631
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
12632
|
+
}
|
|
12633
|
+
function buildChatCompletionsUrl(baseURL) {
|
|
12634
|
+
const normalizedBaseURL = (baseURL || DEFAULT_OPENAI_BASE_URL).replace(/\/+$/, '');
|
|
12635
|
+
if (normalizedBaseURL.endsWith('/chat/completions')) return normalizedBaseURL;
|
|
12636
|
+
return `${normalizedBaseURL}/chat/completions`;
|
|
12637
|
+
}
|
|
12638
|
+
function buildCurlCommand(modelConfig) {
|
|
12639
|
+
const payload = {
|
|
12640
|
+
model: modelConfig.modelName,
|
|
12641
|
+
messages: [
|
|
12642
|
+
{
|
|
12643
|
+
role: 'user',
|
|
12644
|
+
content: 'What is 1+1?'
|
|
12645
|
+
}
|
|
12646
|
+
]
|
|
12647
|
+
};
|
|
12648
|
+
return [
|
|
12649
|
+
`curl -X POST ${shellSingleQuote(buildChatCompletionsUrl(modelConfig.openaiBaseURL))} \\`,
|
|
12650
|
+
` -H ${shellSingleQuote(`Authorization: Bearer ${modelConfig.openaiApiKey || ''}`)} \\`,
|
|
12651
|
+
` -H ${shellSingleQuote('Content-Type: application/json')} \\`,
|
|
12652
|
+
` -d ${shellSingleQuote(JSON.stringify(payload, null, 2))}`
|
|
12653
|
+
].join('\n');
|
|
12654
|
+
}
|
|
12655
|
+
function buildCurlDedupKey(modelConfig) {
|
|
12656
|
+
return JSON.stringify({
|
|
12657
|
+
baseURL: modelConfig.openaiBaseURL || DEFAULT_OPENAI_BASE_URL,
|
|
12658
|
+
apiKey: modelConfig.openaiApiKey || '',
|
|
12659
|
+
modelName: modelConfig.modelName
|
|
12660
|
+
});
|
|
12661
|
+
}
|
|
12662
|
+
function buildModelVerifyCurlCommands(configs) {
|
|
12663
|
+
const commandMap = new Map();
|
|
12664
|
+
for (const item of configs){
|
|
12665
|
+
const key = buildCurlDedupKey(item.modelConfig);
|
|
12666
|
+
const existing = commandMap.get(key);
|
|
12667
|
+
if (existing) {
|
|
12668
|
+
existing.intents.push(item.intent);
|
|
12669
|
+
continue;
|
|
12670
|
+
}
|
|
12671
|
+
commandMap.set(key, {
|
|
12672
|
+
intents: [
|
|
12673
|
+
item.intent
|
|
12674
|
+
],
|
|
12675
|
+
curl: buildCurlCommand(item.modelConfig),
|
|
12676
|
+
usesDefaultBaseURL: !item.modelConfig.openaiBaseURL
|
|
12677
|
+
});
|
|
12678
|
+
}
|
|
12679
|
+
return [
|
|
12680
|
+
...commandMap.values()
|
|
12681
|
+
];
|
|
12682
|
+
}
|
|
12683
|
+
function formatModelVerifyFailureOutput(message, curlCommands) {
|
|
12684
|
+
const details = message?.trim() || 'No failure details were generated.';
|
|
12685
|
+
const curlSection = curlCommands.map((item)=>{
|
|
12686
|
+
const baseUrlNote = item.usesDefaultBaseURL ? ' (base URL not configured; using OpenAI SDK default)' : '';
|
|
12687
|
+
return source_default().gray(`# ${item.intents.join(', ')}${baseUrlNote}\n${item.curl}`);
|
|
12688
|
+
}).join('\n\n');
|
|
12689
|
+
return [
|
|
12690
|
+
source_default().red.bold('❌ Model verify failed with messages:'),
|
|
12691
|
+
MODEL_VERIFY_SEPARATOR,
|
|
12692
|
+
'',
|
|
12693
|
+
details,
|
|
12694
|
+
'',
|
|
12695
|
+
MODEL_VERIFY_SEPARATOR,
|
|
12696
|
+
'Generated curl requests for basic API connectivity:',
|
|
12697
|
+
'If the error is a basic connectivity issue, use these requests to test the base URL, API key, and model name directly.',
|
|
12698
|
+
'These commands contain your API key. Do not share them publicly.',
|
|
12699
|
+
'',
|
|
12700
|
+
curlSection
|
|
12701
|
+
].join('\n');
|
|
12702
|
+
}
|
|
12703
|
+
function getDefaultDeps(io) {
|
|
12704
|
+
return {
|
|
12705
|
+
loadDotenv: ()=>{
|
|
12706
|
+
loadDotenvConfig({
|
|
12707
|
+
dotenvDebug: true,
|
|
12708
|
+
dotenvOverride: true,
|
|
12709
|
+
log: io.stdout
|
|
12710
|
+
});
|
|
12711
|
+
},
|
|
12712
|
+
getModelConfig: (intent)=>globalModelConfigManager.getModelConfig(intent),
|
|
12713
|
+
verifyModel: runConnectivityTest
|
|
12714
|
+
};
|
|
12715
|
+
}
|
|
12716
|
+
async function runModelVerifyCommand(args, deps, io) {
|
|
12717
|
+
try {
|
|
12718
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
12719
|
+
io.stdout(MODEL_COMMAND_USAGE);
|
|
12720
|
+
return 0;
|
|
12721
|
+
}
|
|
12722
|
+
assertNoModelVerifyOptions(args);
|
|
12723
|
+
io.stdout('Model verify started. This usually takes about 5 seconds.\n');
|
|
12724
|
+
deps.loadDotenv();
|
|
12725
|
+
io.stdout('');
|
|
12726
|
+
const defaultModelConfig = deps.getModelConfig('default');
|
|
12727
|
+
const planningModelConfig = deps.getModelConfig('planning');
|
|
12728
|
+
const insightModelConfig = deps.getModelConfig('insight');
|
|
12729
|
+
const curlCommands = buildModelVerifyCurlCommands([
|
|
12730
|
+
{
|
|
12731
|
+
intent: 'default',
|
|
12732
|
+
modelConfig: defaultModelConfig
|
|
12733
|
+
},
|
|
12734
|
+
{
|
|
12735
|
+
intent: 'planning',
|
|
12736
|
+
modelConfig: planningModelConfig
|
|
12737
|
+
},
|
|
12738
|
+
{
|
|
12739
|
+
intent: 'insight',
|
|
12740
|
+
modelConfig: insightModelConfig
|
|
12741
|
+
}
|
|
12742
|
+
]);
|
|
12743
|
+
const result = await deps.verifyModel({
|
|
12744
|
+
defaultModelConfig,
|
|
12745
|
+
planningModelConfig,
|
|
12746
|
+
insightModelConfig
|
|
12747
|
+
});
|
|
12748
|
+
if (result.passed) {
|
|
12749
|
+
io.stdout('✅ Model verify passed.');
|
|
12750
|
+
return 0;
|
|
12751
|
+
}
|
|
12752
|
+
io.stderr(formatModelVerifyFailureOutput(result.message, curlCommands));
|
|
12753
|
+
return 1;
|
|
12754
|
+
} catch (error) {
|
|
12755
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
12756
|
+
io.stderr([
|
|
12757
|
+
MODEL_VERIFY_SEPARATOR,
|
|
12758
|
+
'❌ Model verify failed with messages:',
|
|
12759
|
+
'',
|
|
12760
|
+
message,
|
|
12761
|
+
MODEL_VERIFY_SEPARATOR
|
|
12762
|
+
].join('\n'));
|
|
12763
|
+
return 1;
|
|
12764
|
+
}
|
|
12765
|
+
}
|
|
12766
|
+
async function runModelCommand(rawArgs, deps, io = {
|
|
12767
|
+
stdout: console.log,
|
|
12768
|
+
stderr: console.error
|
|
12769
|
+
}) {
|
|
12770
|
+
const [, action, ...restArgs] = rawArgs;
|
|
12771
|
+
const mergedDeps = {
|
|
12772
|
+
...getDefaultDeps(io),
|
|
12773
|
+
...deps
|
|
12774
|
+
};
|
|
12775
|
+
if (!action || '--help' === action || '-h' === action) {
|
|
12776
|
+
io.stdout(MODEL_COMMAND_USAGE);
|
|
12777
|
+
return 0;
|
|
12778
|
+
}
|
|
12779
|
+
if ('verify' === action) return runModelVerifyCommand(restArgs, mergedDeps, io);
|
|
12780
|
+
if ('eval' === action) {
|
|
12781
|
+
io.stderr('midscene model eval is not implemented yet. It is reserved for future model evaluation suites.');
|
|
12782
|
+
return 1;
|
|
12783
|
+
}
|
|
12784
|
+
io.stderr(`Unknown midscene model command: ${action}\n\n${MODEL_COMMAND_USAGE}`);
|
|
12785
|
+
return 1;
|
|
12786
|
+
}
|
|
12612
12787
|
Promise.resolve((async ()=>{
|
|
12613
12788
|
const rawArgs = process.argv.slice(2);
|
|
12614
12789
|
const [firstArg] = rawArgs;
|
|
@@ -12621,6 +12796,11 @@ defineYamlBatchTest(test, testOptions);
|
|
|
12621
12796
|
version: package_namespaceObject.rE,
|
|
12622
12797
|
extraCommands: createReportCliCommands()
|
|
12623
12798
|
});
|
|
12799
|
+
if ('model' === firstArg) {
|
|
12800
|
+
const exitCode = await runModelCommand(rawArgs);
|
|
12801
|
+
process.exit(exitCode);
|
|
12802
|
+
return;
|
|
12803
|
+
}
|
|
12624
12804
|
const { options, path, files: cmdFiles } = await parseProcessArgs();
|
|
12625
12805
|
const welcome = `\nWelcome to @midscene/cli v${package_namespaceObject.rE}\n`;
|
|
12626
12806
|
console.log(welcome);
|
|
@@ -12669,15 +12849,11 @@ defineYamlBatchTest(test, testOptions);
|
|
|
12669
12849
|
console.error('Could not create a valid configuration.');
|
|
12670
12850
|
process.exit(1);
|
|
12671
12851
|
}
|
|
12672
|
-
|
|
12673
|
-
|
|
12674
|
-
|
|
12675
|
-
|
|
12676
|
-
|
|
12677
|
-
debug: config.dotenvDebug,
|
|
12678
|
-
override: config.dotenvOverride
|
|
12679
|
-
});
|
|
12680
|
-
}
|
|
12852
|
+
loadDotenvConfig({
|
|
12853
|
+
dotenvDebug: config.dotenvDebug,
|
|
12854
|
+
dotenvOverride: config.dotenvOverride,
|
|
12855
|
+
log: console.log
|
|
12856
|
+
});
|
|
12681
12857
|
const exitCode = await runFrameworkTestConfig(config);
|
|
12682
12858
|
if (config.keepWindow) setInterval(()=>{
|
|
12683
12859
|
console.log('browser is still running, use ctrl+c to stop it');
|