@midscene/cli 1.10.2 → 1.10.3
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 -15
- package/dist/es/index.mjs.map +1 -1
- package/dist/lib/index.js +196 -16
- package/dist/lib/index.js.map +1 -1
- package/package.json +8 -8
package/dist/lib/index.js
CHANGED
|
@@ -4706,16 +4706,14 @@ defineYamlBatchTest(test, testOptions);
|
|
|
4706
4706
|
},
|
|
4707
4707
|
"./src/index.ts" (__unused_rspack_module, __unused_rspack___webpack_exports__, __webpack_require__) {
|
|
4708
4708
|
"use strict";
|
|
4709
|
-
var external_node_fs_ = __webpack_require__("node:fs");
|
|
4710
|
-
var external_node_fs_namespaceObject = /*#__PURE__*/ __webpack_require__.t(external_node_fs_, 2);
|
|
4711
|
-
var external_node_path_ = __webpack_require__("node:path");
|
|
4712
4709
|
var core_ = __webpack_require__("@midscene/core");
|
|
4713
4710
|
const cli_namespaceObject = require("@midscene/shared/cli");
|
|
4714
|
-
var main = __webpack_require__("../../node_modules/.pnpm/dotenv@16.4.5/node_modules/dotenv/lib/main.js");
|
|
4715
|
-
var main_default = /*#__PURE__*/ __webpack_require__.n(main);
|
|
4716
4711
|
var package_namespaceObject = {
|
|
4717
|
-
rE: "1.10.
|
|
4712
|
+
rE: "1.10.3"
|
|
4718
4713
|
};
|
|
4714
|
+
var external_node_fs_ = __webpack_require__("node:fs");
|
|
4715
|
+
var external_node_fs_namespaceObject = /*#__PURE__*/ __webpack_require__.t(external_node_fs_, 2);
|
|
4716
|
+
var external_node_path_ = __webpack_require__("node:path");
|
|
4719
4717
|
var logger_ = __webpack_require__("@midscene/shared/logger");
|
|
4720
4718
|
var brace_expansion = __webpack_require__("../../node_modules/.pnpm/brace-expansion@2.0.1/node_modules/brace-expansion/index.js");
|
|
4721
4719
|
const MAX_PATTERN_LENGTH = 65536;
|
|
@@ -12587,7 +12585,7 @@ Usage:
|
|
|
12587
12585
|
type: 'boolean',
|
|
12588
12586
|
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}`
|
|
12589
12587
|
}
|
|
12590
|
-
}).version('version', 'Show version number', "1.10.
|
|
12588
|
+
}).version('version', 'Show version number', "1.10.3").help().epilogue(`For complete list of configuration options, please visit:
|
|
12591
12589
|
• Web options: https://midscenejs.com/automate-with-scripts-in-yaml#the-web-part
|
|
12592
12590
|
• Android options: https://midscenejs.com/automate-with-scripts-in-yaml#the-android-part
|
|
12593
12591
|
• iOS options: https://midscenejs.com/automate-with-scripts-in-yaml#the-ios-part
|
|
@@ -12635,7 +12633,188 @@ Examples:
|
|
|
12635
12633
|
});
|
|
12636
12634
|
return files.filter((file)=>file.endsWith('.yml') || file.endsWith('.yaml')).sort();
|
|
12637
12635
|
}
|
|
12636
|
+
var main = __webpack_require__("../../node_modules/.pnpm/dotenv@16.4.5/node_modules/dotenv/lib/main.js");
|
|
12637
|
+
var main_default = /*#__PURE__*/ __webpack_require__.n(main);
|
|
12638
|
+
function loadDotenvConfig(options = {}) {
|
|
12639
|
+
const dotEnvConfigFile = (0, external_node_path_.join)(options.cwd ?? process.cwd(), '.env');
|
|
12640
|
+
if (!(0, external_node_fs_.existsSync)(dotEnvConfigFile)) return;
|
|
12641
|
+
options.log?.(` Env file: ${dotEnvConfigFile}`);
|
|
12642
|
+
main_default().config({
|
|
12643
|
+
path: dotEnvConfigFile,
|
|
12644
|
+
debug: options.dotenvDebug,
|
|
12645
|
+
override: options.dotenvOverride
|
|
12646
|
+
});
|
|
12647
|
+
}
|
|
12638
12648
|
var framework = __webpack_require__("./src/framework/index.ts");
|
|
12649
|
+
const env_namespaceObject = require("@midscene/shared/env");
|
|
12650
|
+
var chalk_source = __webpack_require__("../../node_modules/.pnpm/chalk@4.1.2/node_modules/chalk/source/index.js");
|
|
12651
|
+
var source_default = /*#__PURE__*/ __webpack_require__.n(chalk_source);
|
|
12652
|
+
const DEFAULT_OPENAI_BASE_URL = 'https://api.openai.com/v1';
|
|
12653
|
+
const MODEL_VERIFY_SEPARATOR = '────────────────────────────────────────';
|
|
12654
|
+
const MODEL_COMMAND_USAGE = `Usage:
|
|
12655
|
+
midscene model verify
|
|
12656
|
+
midscene model eval
|
|
12657
|
+
`;
|
|
12658
|
+
function assertNoModelVerifyOptions(args) {
|
|
12659
|
+
for (const arg of args)throw new Error(`Unknown option for midscene model verify: ${arg}`);
|
|
12660
|
+
}
|
|
12661
|
+
function shellSingleQuote(value) {
|
|
12662
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
12663
|
+
}
|
|
12664
|
+
function buildChatCompletionsUrl(baseURL) {
|
|
12665
|
+
const normalizedBaseURL = (baseURL || DEFAULT_OPENAI_BASE_URL).replace(/\/+$/, '');
|
|
12666
|
+
if (normalizedBaseURL.endsWith('/chat/completions')) return normalizedBaseURL;
|
|
12667
|
+
return `${normalizedBaseURL}/chat/completions`;
|
|
12668
|
+
}
|
|
12669
|
+
function buildCurlCommand(modelConfig) {
|
|
12670
|
+
const payload = {
|
|
12671
|
+
model: modelConfig.modelName,
|
|
12672
|
+
messages: [
|
|
12673
|
+
{
|
|
12674
|
+
role: 'user',
|
|
12675
|
+
content: 'What is 1+1?'
|
|
12676
|
+
}
|
|
12677
|
+
]
|
|
12678
|
+
};
|
|
12679
|
+
return [
|
|
12680
|
+
`curl -X POST ${shellSingleQuote(buildChatCompletionsUrl(modelConfig.openaiBaseURL))} \\`,
|
|
12681
|
+
` -H ${shellSingleQuote(`Authorization: Bearer ${modelConfig.openaiApiKey || ''}`)} \\`,
|
|
12682
|
+
` -H ${shellSingleQuote('Content-Type: application/json')} \\`,
|
|
12683
|
+
` -d ${shellSingleQuote(JSON.stringify(payload, null, 2))}`
|
|
12684
|
+
].join('\n');
|
|
12685
|
+
}
|
|
12686
|
+
function buildCurlDedupKey(modelConfig) {
|
|
12687
|
+
return JSON.stringify({
|
|
12688
|
+
baseURL: modelConfig.openaiBaseURL || DEFAULT_OPENAI_BASE_URL,
|
|
12689
|
+
apiKey: modelConfig.openaiApiKey || '',
|
|
12690
|
+
modelName: modelConfig.modelName
|
|
12691
|
+
});
|
|
12692
|
+
}
|
|
12693
|
+
function buildModelVerifyCurlCommands(configs) {
|
|
12694
|
+
const commandMap = new Map();
|
|
12695
|
+
for (const item of configs){
|
|
12696
|
+
const key = buildCurlDedupKey(item.modelConfig);
|
|
12697
|
+
const existing = commandMap.get(key);
|
|
12698
|
+
if (existing) {
|
|
12699
|
+
existing.intents.push(item.intent);
|
|
12700
|
+
continue;
|
|
12701
|
+
}
|
|
12702
|
+
commandMap.set(key, {
|
|
12703
|
+
intents: [
|
|
12704
|
+
item.intent
|
|
12705
|
+
],
|
|
12706
|
+
curl: buildCurlCommand(item.modelConfig),
|
|
12707
|
+
usesDefaultBaseURL: !item.modelConfig.openaiBaseURL
|
|
12708
|
+
});
|
|
12709
|
+
}
|
|
12710
|
+
return [
|
|
12711
|
+
...commandMap.values()
|
|
12712
|
+
];
|
|
12713
|
+
}
|
|
12714
|
+
function formatModelVerifyFailureOutput(message, curlCommands) {
|
|
12715
|
+
const details = message?.trim() || 'No failure details were generated.';
|
|
12716
|
+
const curlSection = curlCommands.map((item)=>{
|
|
12717
|
+
const baseUrlNote = item.usesDefaultBaseURL ? ' (base URL not configured; using OpenAI SDK default)' : '';
|
|
12718
|
+
return source_default().gray(`# ${item.intents.join(', ')}${baseUrlNote}\n${item.curl}`);
|
|
12719
|
+
}).join('\n\n');
|
|
12720
|
+
return [
|
|
12721
|
+
source_default().red.bold('❌ Model verify failed with messages:'),
|
|
12722
|
+
MODEL_VERIFY_SEPARATOR,
|
|
12723
|
+
'',
|
|
12724
|
+
details,
|
|
12725
|
+
'',
|
|
12726
|
+
MODEL_VERIFY_SEPARATOR,
|
|
12727
|
+
'Generated curl requests for basic API connectivity:',
|
|
12728
|
+
'If the error is a basic connectivity issue, use these requests to test the base URL, API key, and model name directly.',
|
|
12729
|
+
'These commands contain your API key. Do not share them publicly.',
|
|
12730
|
+
'',
|
|
12731
|
+
curlSection
|
|
12732
|
+
].join('\n');
|
|
12733
|
+
}
|
|
12734
|
+
function getDefaultDeps(io) {
|
|
12735
|
+
return {
|
|
12736
|
+
loadDotenv: ()=>{
|
|
12737
|
+
loadDotenvConfig({
|
|
12738
|
+
dotenvDebug: true,
|
|
12739
|
+
dotenvOverride: true,
|
|
12740
|
+
log: io.stdout
|
|
12741
|
+
});
|
|
12742
|
+
},
|
|
12743
|
+
getModelConfig: (intent)=>env_namespaceObject.globalModelConfigManager.getModelConfig(intent),
|
|
12744
|
+
verifyModel: core_.runConnectivityTest
|
|
12745
|
+
};
|
|
12746
|
+
}
|
|
12747
|
+
async function runModelVerifyCommand(args, deps, io) {
|
|
12748
|
+
try {
|
|
12749
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
12750
|
+
io.stdout(MODEL_COMMAND_USAGE);
|
|
12751
|
+
return 0;
|
|
12752
|
+
}
|
|
12753
|
+
assertNoModelVerifyOptions(args);
|
|
12754
|
+
io.stdout('Model verify started. This usually takes about 5 seconds.\n');
|
|
12755
|
+
deps.loadDotenv();
|
|
12756
|
+
io.stdout('');
|
|
12757
|
+
const defaultModelConfig = deps.getModelConfig('default');
|
|
12758
|
+
const planningModelConfig = deps.getModelConfig('planning');
|
|
12759
|
+
const insightModelConfig = deps.getModelConfig('insight');
|
|
12760
|
+
const curlCommands = buildModelVerifyCurlCommands([
|
|
12761
|
+
{
|
|
12762
|
+
intent: 'default',
|
|
12763
|
+
modelConfig: defaultModelConfig
|
|
12764
|
+
},
|
|
12765
|
+
{
|
|
12766
|
+
intent: 'planning',
|
|
12767
|
+
modelConfig: planningModelConfig
|
|
12768
|
+
},
|
|
12769
|
+
{
|
|
12770
|
+
intent: 'insight',
|
|
12771
|
+
modelConfig: insightModelConfig
|
|
12772
|
+
}
|
|
12773
|
+
]);
|
|
12774
|
+
const result = await deps.verifyModel({
|
|
12775
|
+
defaultModelConfig,
|
|
12776
|
+
planningModelConfig,
|
|
12777
|
+
insightModelConfig
|
|
12778
|
+
});
|
|
12779
|
+
if (result.passed) {
|
|
12780
|
+
io.stdout('✅ Model verify passed.');
|
|
12781
|
+
return 0;
|
|
12782
|
+
}
|
|
12783
|
+
io.stderr(formatModelVerifyFailureOutput(result.message, curlCommands));
|
|
12784
|
+
return 1;
|
|
12785
|
+
} catch (error) {
|
|
12786
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
12787
|
+
io.stderr([
|
|
12788
|
+
MODEL_VERIFY_SEPARATOR,
|
|
12789
|
+
'❌ Model verify failed with messages:',
|
|
12790
|
+
'',
|
|
12791
|
+
message,
|
|
12792
|
+
MODEL_VERIFY_SEPARATOR
|
|
12793
|
+
].join('\n'));
|
|
12794
|
+
return 1;
|
|
12795
|
+
}
|
|
12796
|
+
}
|
|
12797
|
+
async function runModelCommand(rawArgs, deps, io = {
|
|
12798
|
+
stdout: console.log,
|
|
12799
|
+
stderr: console.error
|
|
12800
|
+
}) {
|
|
12801
|
+
const [, action, ...restArgs] = rawArgs;
|
|
12802
|
+
const mergedDeps = {
|
|
12803
|
+
...getDefaultDeps(io),
|
|
12804
|
+
...deps
|
|
12805
|
+
};
|
|
12806
|
+
if (!action || '--help' === action || '-h' === action) {
|
|
12807
|
+
io.stdout(MODEL_COMMAND_USAGE);
|
|
12808
|
+
return 0;
|
|
12809
|
+
}
|
|
12810
|
+
if ('verify' === action) return runModelVerifyCommand(restArgs, mergedDeps, io);
|
|
12811
|
+
if ('eval' === action) {
|
|
12812
|
+
io.stderr('midscene model eval is not implemented yet. It is reserved for future model evaluation suites.');
|
|
12813
|
+
return 1;
|
|
12814
|
+
}
|
|
12815
|
+
io.stderr(`Unknown midscene model command: ${action}\n\n${MODEL_COMMAND_USAGE}`);
|
|
12816
|
+
return 1;
|
|
12817
|
+
}
|
|
12639
12818
|
Promise.resolve((async ()=>{
|
|
12640
12819
|
const rawArgs = process.argv.slice(2);
|
|
12641
12820
|
const [firstArg] = rawArgs;
|
|
@@ -12648,6 +12827,11 @@ Examples:
|
|
|
12648
12827
|
version: package_namespaceObject.rE,
|
|
12649
12828
|
extraCommands: (0, core_.createReportCliCommands)()
|
|
12650
12829
|
});
|
|
12830
|
+
if ('model' === firstArg) {
|
|
12831
|
+
const exitCode = await runModelCommand(rawArgs);
|
|
12832
|
+
process.exit(exitCode);
|
|
12833
|
+
return;
|
|
12834
|
+
}
|
|
12651
12835
|
const { options, path, files: cmdFiles } = await parseProcessArgs();
|
|
12652
12836
|
const welcome = `\nWelcome to @midscene/cli v${package_namespaceObject.rE}\n`;
|
|
12653
12837
|
console.log(welcome);
|
|
@@ -12696,15 +12880,11 @@ Examples:
|
|
|
12696
12880
|
console.error('Could not create a valid configuration.');
|
|
12697
12881
|
process.exit(1);
|
|
12698
12882
|
}
|
|
12699
|
-
|
|
12700
|
-
|
|
12701
|
-
|
|
12702
|
-
|
|
12703
|
-
|
|
12704
|
-
debug: config.dotenvDebug,
|
|
12705
|
-
override: config.dotenvOverride
|
|
12706
|
-
});
|
|
12707
|
-
}
|
|
12883
|
+
loadDotenvConfig({
|
|
12884
|
+
dotenvDebug: config.dotenvDebug,
|
|
12885
|
+
dotenvOverride: config.dotenvOverride,
|
|
12886
|
+
log: console.log
|
|
12887
|
+
});
|
|
12708
12888
|
const exitCode = await (0, framework.runFrameworkTestConfig)(config);
|
|
12709
12889
|
if (config.keepWindow) setInterval(()=>{
|
|
12710
12890
|
console.log('browser is still running, use ctrl+c to stop it');
|