@midscene/cli 1.10.2-beta-20260706032158.0 → 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/lib/index.js CHANGED
@@ -4706,14 +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 core_ = __webpack_require__("@midscene/core");
4710
+ const cli_namespaceObject = require("@midscene/shared/cli");
4711
+ var package_namespaceObject = {
4712
+ rE: "1.10.3"
4713
+ };
4709
4714
  var external_node_fs_ = __webpack_require__("node:fs");
4710
4715
  var external_node_fs_namespaceObject = /*#__PURE__*/ __webpack_require__.t(external_node_fs_, 2);
4711
4716
  var external_node_path_ = __webpack_require__("node:path");
4712
- var core_ = __webpack_require__("@midscene/core");
4713
- 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
- var package_namespaceObject = JSON.parse('{"rE":"1.10.2-beta-20260706032158.0"}');
4717
4717
  var logger_ = __webpack_require__("@midscene/shared/logger");
4718
4718
  var brace_expansion = __webpack_require__("../../node_modules/.pnpm/brace-expansion@2.0.1/node_modules/brace-expansion/index.js");
4719
4719
  const MAX_PATTERN_LENGTH = 65536;
@@ -12585,7 +12585,7 @@ Usage:
12585
12585
  type: 'boolean',
12586
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}`
12587
12587
  }
12588
- }).version('version', 'Show version number', "1.10.2-beta-20260706032158.0").help().epilogue(`For complete list of configuration options, please visit:
12588
+ }).version('version', 'Show version number', "1.10.3").help().epilogue(`For complete list of configuration options, please visit:
12589
12589
  • Web options: https://midscenejs.com/automate-with-scripts-in-yaml#the-web-part
12590
12590
  • Android options: https://midscenejs.com/automate-with-scripts-in-yaml#the-android-part
12591
12591
  • iOS options: https://midscenejs.com/automate-with-scripts-in-yaml#the-ios-part
@@ -12633,7 +12633,188 @@ Examples:
12633
12633
  });
12634
12634
  return files.filter((file)=>file.endsWith('.yml') || file.endsWith('.yaml')).sort();
12635
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
+ }
12636
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
+ }
12637
12818
  Promise.resolve((async ()=>{
12638
12819
  const rawArgs = process.argv.slice(2);
12639
12820
  const [firstArg] = rawArgs;
@@ -12646,6 +12827,11 @@ Examples:
12646
12827
  version: package_namespaceObject.rE,
12647
12828
  extraCommands: (0, core_.createReportCliCommands)()
12648
12829
  });
12830
+ if ('model' === firstArg) {
12831
+ const exitCode = await runModelCommand(rawArgs);
12832
+ process.exit(exitCode);
12833
+ return;
12834
+ }
12649
12835
  const { options, path, files: cmdFiles } = await parseProcessArgs();
12650
12836
  const welcome = `\nWelcome to @midscene/cli v${package_namespaceObject.rE}\n`;
12651
12837
  console.log(welcome);
@@ -12694,15 +12880,11 @@ Examples:
12694
12880
  console.error('Could not create a valid configuration.');
12695
12881
  process.exit(1);
12696
12882
  }
12697
- const dotEnvConfigFile = (0, external_node_path_.join)(process.cwd(), '.env');
12698
- if ((0, external_node_fs_.existsSync)(dotEnvConfigFile)) {
12699
- console.log(` Env file: ${dotEnvConfigFile}`);
12700
- main_default().config({
12701
- path: dotEnvConfigFile,
12702
- debug: config.dotenvDebug,
12703
- override: config.dotenvOverride
12704
- });
12705
- }
12883
+ loadDotenvConfig({
12884
+ dotenvDebug: config.dotenvDebug,
12885
+ dotenvOverride: config.dotenvOverride,
12886
+ log: console.log
12887
+ });
12706
12888
  const exitCode = await (0, framework.runFrameworkTestConfig)(config);
12707
12889
  if (config.keepWindow) setInterval(()=>{
12708
12890
  console.log('browser is still running, use ctrl+c to stop it');