@browserbasehq/browse-cli 0.4.1 → 0.4.2

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.
Files changed (2) hide show
  1. package/dist/index.js +53 -21
  2. package/package.json +3 -2
package/dist/index.js CHANGED
@@ -119791,10 +119791,13 @@ var AISdkClient2 = class extends LLMClient {
119791
119791
  type = "aisdk";
119792
119792
  model;
119793
119793
  logger;
119794
- constructor({ model, logger }) {
119794
+ constructor({ model, logger, clientOptions }) {
119795
119795
  super(model.modelId);
119796
119796
  this.model = model;
119797
119797
  this.logger = logger;
119798
+ if (clientOptions) {
119799
+ this.clientOptions = clientOptions;
119800
+ }
119798
119801
  }
119799
119802
  getLanguageModel() {
119800
119803
  return this.model;
@@ -119872,9 +119875,11 @@ var AISdkClient2 = class extends LLMClient {
119872
119875
  let objectResponse;
119873
119876
  const isGPT5 = this.model.modelId.includes("gpt-5");
119874
119877
  const isCodex = this.model.modelId.includes("codex");
119875
- const usesLowReasoningEffort = (this.model.modelId.includes("gpt-5.1") || this.model.modelId.includes("gpt-5.2")) && !isCodex;
119876
119878
  const isKimi = this.model.modelId.includes("kimi");
119877
119879
  const temperature = isKimi ? 1 : options.temperature;
119880
+ const isGPT5SubModel = this.model.modelId.includes("gpt-5.") && !isCodex;
119881
+ const userReasoningEffort = this.clientOptions?.reasoningEffort;
119882
+ const resolvedReasoningEffort = userReasoningEffort ?? (isGPT5SubModel ? "none" : void 0);
119878
119883
  const PROMPT_JSON_FALLBACK_PATTERNS = ["deepseek", "kimi", "glm"];
119879
119884
  const needsPromptJsonFallback = PROMPT_JSON_FALLBACK_PATTERNS.some((p2) => this.model.modelId.includes(p2));
119880
119885
  if (options.response_model) {
@@ -119903,11 +119908,10 @@ You must respond in JSON format. respond WITH JSON. Do not include any other tex
119903
119908
  messages: formattedMessages,
119904
119909
  schema: options.response_model.schema,
119905
119910
  temperature,
119906
- providerOptions: isGPT5 ? {
119911
+ providerOptions: resolvedReasoningEffort ? {
119907
119912
  openai: {
119908
- textVerbosity: isCodex ? "medium" : "low",
119909
- // codex models only support 'medium'
119910
- reasoningEffort: isCodex ? "medium" : usesLowReasoningEffort ? "low" : "minimal"
119913
+ ...isGPT5 ? { textVerbosity: isCodex ? "medium" : "low" } : {},
119914
+ reasoningEffort: resolvedReasoningEffort
119911
119915
  }
119912
119916
  } : void 0
119913
119917
  });
@@ -152796,27 +152800,34 @@ var modelToProviderMap = {
152796
152800
  "gemini-2.5-flash-preview-04-17": "google",
152797
152801
  "gemini-2.5-pro-preview-03-25": "google"
152798
152802
  };
152799
- function getAISDKLanguageModel(subProvider, subModelName, clientOptions) {
152803
+ function getAISDKLanguageModel(subProvider, subModelName, clientOptions, middleware) {
152800
152804
  const hasValidOptions = clientOptions && Object.values(clientOptions).some((v2) => v2 !== void 0 && v2 !== null);
152805
+ let model;
152801
152806
  if (hasValidOptions) {
152802
152807
  const creator = AISDKProvidersWithAPIKey[subProvider];
152803
152808
  if (!creator) {
152804
152809
  throw new UnsupportedAISDKModelProviderError(subProvider, Object.keys(AISDKProvidersWithAPIKey));
152805
152810
  }
152806
152811
  const provider = creator(clientOptions);
152807
- return provider(subModelName);
152812
+ model = provider(subModelName);
152808
152813
  } else {
152809
152814
  const provider = AISDKProviders[subProvider];
152810
152815
  if (!provider) {
152811
152816
  throw new UnsupportedAISDKModelProviderError(subProvider, Object.keys(AISDKProviders));
152812
152817
  }
152813
- return provider(subModelName);
152818
+ model = provider(subModelName);
152819
+ }
152820
+ if (middleware) {
152821
+ return wrapLanguageModel({ model, middleware });
152814
152822
  }
152823
+ return model;
152815
152824
  }
152816
152825
  var LLMProvider = class {
152817
152826
  logger;
152818
- constructor(logger) {
152827
+ middleware;
152828
+ constructor(logger, middleware) {
152819
152829
  this.logger = logger;
152830
+ this.middleware = middleware;
152820
152831
  }
152821
152832
  getClient(modelName, clientOptions, options) {
152822
152833
  if (modelName.includes("/")) {
@@ -152826,10 +152837,12 @@ var LLMProvider = class {
152826
152837
  if (subProvider === "vertex" && !options?.disableAPI && !options?.experimental) {
152827
152838
  throw new ExperimentalNotConfiguredError("Vertex provider");
152828
152839
  }
152829
- const languageModel = getAISDKLanguageModel(subProvider, subModelName, clientOptions);
152840
+ const effectiveMiddleware = options?.middleware ?? this.middleware;
152841
+ const languageModel = getAISDKLanguageModel(subProvider, subModelName, clientOptions, effectiveMiddleware);
152830
152842
  return new AISdkClient2({
152831
152843
  model: languageModel,
152832
- logger: this.logger
152844
+ logger: this.logger,
152845
+ clientOptions
152833
152846
  });
152834
152847
  }
152835
152848
  const provider = modelToProviderMap[modelName];
@@ -162834,13 +162847,14 @@ function resolveModelConfiguration(model) {
162834
162847
  return { modelName: model };
162835
162848
  }
162836
162849
  if (model && typeof model === "object") {
162837
- const { modelName, ...clientOptions } = model;
162850
+ const { modelName, middleware, ...clientOptions } = model;
162838
162851
  if (!modelName) {
162839
162852
  throw new StagehandInvalidArgumentError("model.modelName is required when providing client options.");
162840
162853
  }
162841
162854
  return {
162842
162855
  modelName,
162843
- clientOptions
162856
+ clientOptions,
162857
+ middleware
162844
162858
  };
162845
162859
  }
162846
162860
  return { modelName: DEFAULT_MODEL_NAME };
@@ -163015,11 +163029,11 @@ var V3 = (() => {
163015
163029
  }
163016
163030
  } catch {
163017
163031
  }
163018
- const { modelName, clientOptions } = resolveModelConfiguration(opts.model);
163032
+ const { modelName, clientOptions, middleware } = resolveModelConfiguration(opts.model);
163019
163033
  this.modelName = modelName;
163020
163034
  this.experimental = opts.experimental ?? false;
163021
163035
  this.logInferenceToFile = opts.logInferenceToFile ?? false;
163022
- this.llmProvider = new LLMProvider(this.logger);
163036
+ this.llmProvider = new LLMProvider(this.logger, middleware);
163023
163037
  this.domSettleTimeoutMs = opts.domSettleTimeout;
163024
163038
  this.disableAPI = opts.disableAPI ?? false;
163025
163039
  const baseClientOptions = clientOptions ? { ...clientOptions } : {};
@@ -163101,14 +163115,16 @@ var V3 = (() => {
163101
163115
  }
163102
163116
  let modelName;
163103
163117
  let clientOptions;
163118
+ let perCallMiddleware;
163104
163119
  if (typeof model === "string") {
163105
163120
  modelName = model;
163106
163121
  } else {
163107
- const { modelName: overrideModelName, ...rest } = model;
163122
+ const { modelName: overrideModelName, middleware, ...rest } = model;
163108
163123
  modelName = overrideModelName;
163109
163124
  clientOptions = rest;
163125
+ perCallMiddleware = middleware;
163110
163126
  }
163111
- if (modelName === this.modelName && (!clientOptions || Object.keys(clientOptions).length === 0)) {
163127
+ if (modelName === this.modelName && !perCallMiddleware && (!clientOptions || Object.keys(clientOptions).length === 0)) {
163112
163128
  return this.llmClient;
163113
163129
  }
163114
163130
  const overrideProvider = String(modelName).split("/")[0];
@@ -163124,6 +163140,13 @@ var V3 = (() => {
163124
163140
  mergedOptions.apiKey = apiKey;
163125
163141
  }
163126
163142
  }
163143
+ if (perCallMiddleware) {
163144
+ return this.llmProvider.getClient(modelName, mergedOptions, {
163145
+ experimental: this.experimental,
163146
+ disableAPI: this.disableAPI,
163147
+ middleware: perCallMiddleware
163148
+ });
163149
+ }
163127
163150
  const cacheKey = JSON.stringify({
163128
163151
  modelName,
163129
163152
  clientOptions: mergedOptions
@@ -163132,7 +163155,10 @@ var V3 = (() => {
163132
163155
  if (cached2) {
163133
163156
  return cached2;
163134
163157
  }
163135
- const client = this.llmProvider.getClient(modelName, mergedOptions, { experimental: this.experimental, disableAPI: this.disableAPI });
163158
+ const client = this.llmProvider.getClient(modelName, mergedOptions, {
163159
+ experimental: this.experimental,
163160
+ disableAPI: this.disableAPI
163161
+ });
163136
163162
  this.overrideLlmClients.set(cacheKey, client);
163137
163163
  return client;
163138
163164
  }
@@ -164626,7 +164652,7 @@ var import_child_process4 = require("child_process");
164626
164652
  var readline = __toESM(require("readline"));
164627
164653
 
164628
164654
  // package.json
164629
- var version3 = "0.4.1";
164655
+ var version3 = "0.4.2";
164630
164656
 
164631
164657
  // src/resolve-ws.ts
164632
164658
  init_cjs_shims();
@@ -164651,6 +164677,7 @@ async function resolveWsTarget(input) {
164651
164677
  }
164652
164678
 
164653
164679
  // src/index.ts
164680
+ var import_node_html_markdown = require("node-html-markdown");
164654
164681
  var program = new import_commander.Command();
164655
164682
  var SOCKET_DIR = os3.tmpdir();
164656
164683
  function getSocketPath(session) {
@@ -165472,6 +165499,11 @@ async function executeCommand(context, command, args, stagehand) {
165472
165499
  return {
165473
165500
  checked: await page.deepLocator(resolveSelector(selector)).isChecked()
165474
165501
  };
165502
+ case "markdown": {
165503
+ const target = selector ? resolveSelector(selector) : "body";
165504
+ const html = await page.deepLocator(target).innerHtml();
165505
+ return { markdown: import_node_html_markdown.NodeHtmlMarkdown.translate(html) };
165506
+ }
165475
165507
  default:
165476
165508
  throw new Error(`Unknown get type: ${what}`);
165477
165509
  }
@@ -166401,7 +166433,7 @@ program.command("highlight <selector>").description("Highlight element").option(
166401
166433
  }
166402
166434
  });
166403
166435
  program.command("get <what> [selector]").description(
166404
- "Get page info: url, title, text, html, value, box, visible, checked"
166436
+ "Get page info: url, title, text, html, markdown, value, box, visible, checked"
166405
166437
  ).action(async (what, selector) => {
166406
166438
  const opts = program.opts();
166407
166439
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@browserbasehq/browse-cli",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Browser automation CLI for AI agents, built on Stagehand",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",
@@ -44,10 +44,11 @@
44
44
  "dependencies": {
45
45
  "commander": "^12.0.0",
46
46
  "dotenv": "^16.4.5",
47
+ "node-html-markdown": "^1.3.0",
47
48
  "pino": "^9.6.0",
48
49
  "pino-pretty": "^13.0.0",
49
50
  "ws": "^8.18.0",
50
- "@browserbasehq/stagehand": "3.2.1-alpha-ad055f91530a84bd5d0735f7d5be82912580914b"
51
+ "@browserbasehq/stagehand": "3.2.0"
51
52
  },
52
53
  "devDependencies": {
53
54
  "@types/node": "^20.11.30",