@hasna/testers 0.0.34 → 0.0.36

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.
@@ -4036,6 +4036,56 @@ var init_zod = __esm(() => {
4036
4036
  });
4037
4037
 
4038
4038
  // src/types/index.ts
4039
+ function isRecord(value) {
4040
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4041
+ }
4042
+ function stringValue(value) {
4043
+ return typeof value === "string" && value.trim() ? value : undefined;
4044
+ }
4045
+ function numberValue(value) {
4046
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
4047
+ }
4048
+ function stringMap(value) {
4049
+ if (!isRecord(value))
4050
+ return;
4051
+ const entries = Object.entries(value).filter((entry) => typeof entry[1] === "string");
4052
+ return entries.length > 0 ? Object.fromEntries(entries) : undefined;
4053
+ }
4054
+ function cleanupValue(value) {
4055
+ if (value === "delete" || value === "stop" || value === "keep")
4056
+ return value;
4057
+ return;
4058
+ }
4059
+ function workflowExecutionFromValue(value) {
4060
+ const input = isRecord(value) ? value : {};
4061
+ const rawTarget = stringValue(input["target"]) ?? "local";
4062
+ if (rawTarget === "local") {
4063
+ const timeoutMs2 = numberValue(input["timeoutMs"]);
4064
+ return timeoutMs2 === undefined ? { target: "local" } : { target: "local", timeoutMs: timeoutMs2 };
4065
+ }
4066
+ if (rawTarget !== "sandbox" && rawTarget !== "connector:e2b") {
4067
+ throw new Error(`Unsupported workflow execution target: ${rawTarget}`);
4068
+ }
4069
+ const provider = rawTarget === "connector:e2b" ? "e2b" : stringValue(input["provider"]) ?? stringValue(input["connector"]);
4070
+ const sandboxImage = stringValue(input["sandboxImage"]) ?? stringValue(input["sandboxTemplate"]);
4071
+ const sandboxRemoteDir = stringValue(input["sandboxRemoteDir"]);
4072
+ const sandboxCleanup = cleanupValue(input["sandboxCleanup"]);
4073
+ const setupCommand = stringValue(input["setupCommand"]);
4074
+ const packageSpec = stringValue(input["packageSpec"]);
4075
+ const timeoutMs = numberValue(input["timeoutMs"]);
4076
+ const env = stringMap(input["env"]);
4077
+ return {
4078
+ target: "sandbox",
4079
+ ...provider ? { provider } : {},
4080
+ ...sandboxImage ? { sandboxImage } : {},
4081
+ ...sandboxRemoteDir ? { sandboxRemoteDir } : {},
4082
+ ...sandboxCleanup ? { sandboxCleanup } : {},
4083
+ ...setupCommand ? { setupCommand } : {},
4084
+ ...packageSpec ? { packageSpec } : {},
4085
+ ...timeoutMs !== undefined ? { timeoutMs } : {},
4086
+ ...env ? { env } : {}
4087
+ };
4088
+ }
4039
4089
  function workflowFromRow(row) {
4040
4090
  return {
4041
4091
  id: row.id,
@@ -4045,7 +4095,7 @@ function workflowFromRow(row) {
4045
4095
  scenarioFilter: JSON.parse(row.scenario_filter || "{}"),
4046
4096
  personaIds: JSON.parse(row.persona_ids || "[]"),
4047
4097
  goal: row.goal ? JSON.parse(row.goal) : null,
4048
- execution: JSON.parse(row.execution || '{"target":"local"}'),
4098
+ execution: workflowExecutionFromValue(JSON.parse(row.execution || '{"target":"local"}')),
4049
4099
  settings: JSON.parse(row.settings || "{}"),
4050
4100
  enabled: row.enabled === 1,
4051
4101
  createdAt: row.created_at,
@@ -8582,33 +8632,33 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
8582
8632
  this.ssl = config.ssl || false;
8583
8633
  this._ending = false;
8584
8634
  this._emitMessage = false;
8585
- const self2 = this;
8635
+ const self = this;
8586
8636
  this.on("newListener", function(eventName) {
8587
8637
  if (eventName === "message") {
8588
- self2._emitMessage = true;
8638
+ self._emitMessage = true;
8589
8639
  }
8590
8640
  });
8591
8641
  }
8592
8642
  connect(port, host) {
8593
- const self2 = this;
8643
+ const self = this;
8594
8644
  this._connecting = true;
8595
8645
  this.stream.setNoDelay(true);
8596
8646
  this.stream.connect(port, host);
8597
8647
  this.stream.once("connect", function() {
8598
- if (self2._keepAlive) {
8599
- self2.stream.setKeepAlive(true, self2._keepAliveInitialDelayMillis);
8648
+ if (self._keepAlive) {
8649
+ self.stream.setKeepAlive(true, self._keepAliveInitialDelayMillis);
8600
8650
  }
8601
- self2.emit("connect");
8651
+ self.emit("connect");
8602
8652
  });
8603
8653
  const reportStreamError = function(error) {
8604
- if (self2._ending && (error.code === "ECONNRESET" || error.code === "EPIPE")) {
8654
+ if (self._ending && (error.code === "ECONNRESET" || error.code === "EPIPE")) {
8605
8655
  return;
8606
8656
  }
8607
- self2.emit("error", error);
8657
+ self.emit("error", error);
8608
8658
  };
8609
8659
  this.stream.on("error", reportStreamError);
8610
8660
  this.stream.on("close", function() {
8611
- self2.emit("end");
8661
+ self.emit("end");
8612
8662
  });
8613
8663
  if (!this.ssl) {
8614
8664
  return this.attachListeners(this.stream);
@@ -8619,19 +8669,19 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
8619
8669
  case "S":
8620
8670
  break;
8621
8671
  case "N":
8622
- self2.stream.end();
8623
- return self2.emit("error", new Error("The server does not support SSL connections"));
8672
+ self.stream.end();
8673
+ return self.emit("error", new Error("The server does not support SSL connections"));
8624
8674
  default:
8625
- self2.stream.end();
8626
- return self2.emit("error", new Error("There was an error establishing an SSL connection"));
8675
+ self.stream.end();
8676
+ return self.emit("error", new Error("There was an error establishing an SSL connection"));
8627
8677
  }
8628
8678
  const options = {
8629
- socket: self2.stream
8679
+ socket: self.stream
8630
8680
  };
8631
- if (self2.ssl !== true) {
8632
- Object.assign(options, self2.ssl);
8633
- if ("key" in self2.ssl) {
8634
- options.key = self2.ssl.key;
8681
+ if (self.ssl !== true) {
8682
+ Object.assign(options, self.ssl);
8683
+ if ("key" in self.ssl) {
8684
+ options.key = self.ssl.key;
8635
8685
  }
8636
8686
  }
8637
8687
  const net = __require2("net");
@@ -8639,13 +8689,13 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
8639
8689
  options.servername = host;
8640
8690
  }
8641
8691
  try {
8642
- self2.stream = getSecureStream(options);
8692
+ self.stream = getSecureStream(options);
8643
8693
  } catch (err) {
8644
- return self2.emit("error", err);
8694
+ return self.emit("error", err);
8645
8695
  }
8646
- self2.attachListeners(self2.stream);
8647
- self2.stream.on("error", reportStreamError);
8648
- self2.emit("sslconnect");
8696
+ self.attachListeners(self.stream);
8697
+ self.stream.on("error", reportStreamError);
8698
+ self.emit("sslconnect");
8649
8699
  });
8650
8700
  }
8651
8701
  attachListeners(stream) {
@@ -8780,9 +8830,9 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
8780
8830
  }
8781
8831
  cb();
8782
8832
  }
8783
- function push(self2, val) {
8833
+ function push(self, val) {
8784
8834
  if (val !== undefined) {
8785
- self2.push(val);
8835
+ self.push(val);
8786
8836
  }
8787
8837
  }
8788
8838
  function noop(incoming) {
@@ -9102,7 +9152,7 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
9102
9152
  this._queryQueue.length = 0;
9103
9153
  }
9104
9154
  _connect(callback) {
9105
- const self2 = this;
9155
+ const self = this;
9106
9156
  const con = this.connection;
9107
9157
  this._connectionCallback = callback;
9108
9158
  if (this._connecting || this._connected) {
@@ -9128,14 +9178,14 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
9128
9178
  con.connect(this.port, this.host);
9129
9179
  }
9130
9180
  con.on("connect", function() {
9131
- if (self2.ssl) {
9181
+ if (self.ssl) {
9132
9182
  con.requestSsl();
9133
9183
  } else {
9134
- con.startup(self2.getStartupConf());
9184
+ con.startup(self.getStartupConf());
9135
9185
  }
9136
9186
  });
9137
9187
  con.on("sslconnect", function() {
9138
- con.startup(self2.getStartupConf());
9188
+ con.startup(self.getStartupConf());
9139
9189
  });
9140
9190
  this._attachListeners(con);
9141
9191
  con.once("end", () => {
@@ -10067,34 +10117,34 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
10067
10117
  };
10068
10118
  NativeQuery.prototype.submit = function(client) {
10069
10119
  this.state = "running";
10070
- const self2 = this;
10120
+ const self = this;
10071
10121
  this.native = client.native;
10072
10122
  client.native.arrayMode = this._arrayMode;
10073
10123
  let after = function(err, rows, results) {
10074
10124
  client.native.arrayMode = false;
10075
10125
  setImmediate(function() {
10076
- self2.emit("_done");
10126
+ self.emit("_done");
10077
10127
  });
10078
10128
  if (err) {
10079
- return self2.handleError(err);
10129
+ return self.handleError(err);
10080
10130
  }
10081
- if (self2._emitRowEvents) {
10131
+ if (self._emitRowEvents) {
10082
10132
  if (results.length > 1) {
10083
10133
  rows.forEach((rowOfRows, i) => {
10084
10134
  rowOfRows.forEach((row) => {
10085
- self2.emit("row", row, results[i]);
10135
+ self.emit("row", row, results[i]);
10086
10136
  });
10087
10137
  });
10088
10138
  } else {
10089
10139
  rows.forEach(function(row) {
10090
- self2.emit("row", row, results);
10140
+ self.emit("row", row, results);
10091
10141
  });
10092
10142
  }
10093
10143
  }
10094
- self2.state = "end";
10095
- self2.emit("end", results);
10096
- if (self2.callback) {
10097
- self2.callback(null, results);
10144
+ self.state = "end";
10145
+ self.emit("end", results);
10146
+ if (self.callback) {
10147
+ self.callback(null, results);
10098
10148
  }
10099
10149
  };
10100
10150
  if (process.domain) {
@@ -10117,8 +10167,8 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
10117
10167
  return client.native.prepare(this.name, this.text, values.length, function(err) {
10118
10168
  if (err)
10119
10169
  return after(err);
10120
- client.namedQueries[self2.name] = self2.text;
10121
- return self2.native.execute(self2.name, values, after);
10170
+ client.namedQueries[self.name] = self.text;
10171
+ return self.native.execute(self.name, values, after);
10122
10172
  });
10123
10173
  } else if (this.values) {
10124
10174
  if (!Array.isArray(this.values)) {
@@ -10195,36 +10245,36 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
10195
10245
  this._queryQueue.length = 0;
10196
10246
  };
10197
10247
  Client.prototype._connect = function(cb) {
10198
- const self2 = this;
10248
+ const self = this;
10199
10249
  if (this._connecting) {
10200
10250
  process.nextTick(() => cb(new Error("Client has already been connected. You cannot reuse a client.")));
10201
10251
  return;
10202
10252
  }
10203
10253
  this._connecting = true;
10204
10254
  this.connectionParameters.getLibpqConnectionString(function(err, conString) {
10205
- if (self2.connectionParameters.nativeConnectionString)
10206
- conString = self2.connectionParameters.nativeConnectionString;
10255
+ if (self.connectionParameters.nativeConnectionString)
10256
+ conString = self.connectionParameters.nativeConnectionString;
10207
10257
  if (err)
10208
10258
  return cb(err);
10209
- self2.native.connect(conString, function(err2) {
10259
+ self.native.connect(conString, function(err2) {
10210
10260
  if (err2) {
10211
- self2.native.end();
10261
+ self.native.end();
10212
10262
  return cb(err2);
10213
10263
  }
10214
- self2._connected = true;
10215
- self2.native.on("error", function(err3) {
10216
- self2._queryable = false;
10217
- self2._errorAllQueries(err3);
10218
- self2.emit("error", err3);
10264
+ self._connected = true;
10265
+ self.native.on("error", function(err3) {
10266
+ self._queryable = false;
10267
+ self._errorAllQueries(err3);
10268
+ self.emit("error", err3);
10219
10269
  });
10220
- self2.native.on("notification", function(msg) {
10221
- self2.emit("notification", {
10270
+ self.native.on("notification", function(msg) {
10271
+ self.emit("notification", {
10222
10272
  channel: msg.relname,
10223
10273
  payload: msg.extra
10224
10274
  });
10225
10275
  });
10226
- self2.emit("connect");
10227
- self2._pulseQueryQueue(true);
10276
+ self.emit("connect");
10277
+ self._pulseQueryQueue(true);
10228
10278
  cb(null, this);
10229
10279
  });
10230
10280
  });
@@ -10315,7 +10365,7 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
10315
10365
  return result;
10316
10366
  };
10317
10367
  Client.prototype.end = function(cb) {
10318
- const self2 = this;
10368
+ const self = this;
10319
10369
  this._ending = true;
10320
10370
  if (!this._connected) {
10321
10371
  this.once("connect", this.end.bind(this, cb));
@@ -10327,10 +10377,10 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
10327
10377
  });
10328
10378
  }
10329
10379
  this.native.end(function() {
10330
- self2._connected = false;
10331
- self2._errorAllQueries(new Error("Connection terminated"));
10380
+ self._connected = false;
10381
+ self._errorAllQueries(new Error("Connection terminated"));
10332
10382
  process.nextTick(() => {
10333
- self2.emit("end");
10383
+ self.emit("end");
10334
10384
  if (cb)
10335
10385
  cb();
10336
10386
  });
@@ -10356,9 +10406,9 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
10356
10406
  }
10357
10407
  this._activeQuery = query;
10358
10408
  query.submit(this);
10359
- const self2 = this;
10409
+ const self = this;
10360
10410
  query.once("_done", function() {
10361
- self2._pulseQueryQueue();
10411
+ self._pulseQueryQueue();
10362
10412
  });
10363
10413
  };
10364
10414
  Client.prototype.cancel = function(query) {
@@ -15269,6 +15319,10 @@ function loadConfig() {
15269
15319
  if (envApiKey) {
15270
15320
  config.anthropicApiKey = envApiKey;
15271
15321
  }
15322
+ const envSelfHeal = process.env["TESTERS_SELF_HEAL"];
15323
+ if (envSelfHeal !== undefined) {
15324
+ config.selfHeal = ["1", "true", "yes", "on"].includes(envSelfHeal.toLowerCase());
15325
+ }
15272
15326
  return config;
15273
15327
  }
15274
15328
  var CONFIG_DIR3, CONFIG_PATH2;
@@ -15305,12 +15359,11 @@ Original selector that failed: "${request.failedSelector}"
15305
15359
  Please identify the correct selector from the screenshot.`;
15306
15360
  let rawResponse = "";
15307
15361
  try {
15308
- if (provider === "openai" || provider === "google") {
15309
- const baseUrl = provider === "openai" ? "https://api.openai.com/v1" : "https://generativelanguage.googleapis.com/v1beta/openai";
15310
- const apiKey = provider === "openai" ? process.env["OPENAI_API_KEY"] ?? "" : process.env["GOOGLE_API_KEY"] ?? "";
15362
+ if (provider !== "anthropic") {
15363
+ const compat = createOpenAICompatibleConfig(provider);
15311
15364
  const resp = await callOpenAICompatible({
15312
- baseUrl,
15313
- apiKey,
15365
+ baseUrl: compat.baseUrl,
15366
+ apiKey: compat.apiKey,
15314
15367
  model,
15315
15368
  system: HEAL_SYSTEM,
15316
15369
  messages: [{ role: "user", content: userMessage }],
@@ -15811,7 +15864,6 @@ async function executeTool(page, screenshotter, toolName, toolInput, context) {
15811
15864
  const assertionType = toolInput.assertion_type;
15812
15865
  const selector = toolInput.selector;
15813
15866
  const expected = toolInput.expected;
15814
- const sessionId = context.sessionId ?? "default";
15815
15867
  switch (assertionType) {
15816
15868
  case "element_exists": {
15817
15869
  if (!selector)
@@ -15876,7 +15928,6 @@ async function executeTool(page, screenshotter, toolName, toolInput, context) {
15876
15928
  case "browser_intercept": {
15877
15929
  const action = toolInput.action;
15878
15930
  const pattern = toolInput.pattern;
15879
- const interceptAction = toolInput.intercept_action;
15880
15931
  const statusCode = toolInput.status_code;
15881
15932
  const body = toolInput.body;
15882
15933
  const sessionId = context.sessionId ?? "default";
@@ -15953,7 +16004,28 @@ ${JSON.stringify(har, null, 2)}` };
15953
16004
  }
15954
16005
  case "browser_a11y": {
15955
16006
  const level = toolInput.level ?? "AA";
15956
- const snapshot = await page.accessibility.snapshot();
16007
+ const snapshot = await page.evaluate(() => {
16008
+ function readRole(el) {
16009
+ return el.getAttribute("role") ?? el.tagName.toLowerCase();
16010
+ }
16011
+ function readName(el) {
16012
+ const labelledBy = el.getAttribute("aria-labelledby");
16013
+ if (labelledBy) {
16014
+ const labelledText = labelledBy.split(/\s+/).map((id) => document.getElementById(id)?.textContent?.trim()).filter(Boolean).join(" ");
16015
+ if (labelledText)
16016
+ return labelledText;
16017
+ }
16018
+ return el.getAttribute("aria-label") ?? el.getAttribute("alt") ?? el.textContent?.trim() ?? "";
16019
+ }
16020
+ function walk(el) {
16021
+ return {
16022
+ role: readRole(el),
16023
+ name: readName(el),
16024
+ children: Array.from(el.children).map((child) => walk(child))
16025
+ };
16026
+ }
16027
+ return document.body ? walk(document.body) : null;
16028
+ });
15957
16029
  if (!snapshot)
15958
16030
  return { result: "Error: could not capture accessibility tree" };
15959
16031
  const issues = [];
@@ -15995,6 +16067,38 @@ ${filtered.join(`
15995
16067
  return { result: `Error executing ${toolName}: ${message}` };
15996
16068
  }
15997
16069
  }
16070
+ function resolveStartUrl(baseUrl, targetPath) {
16071
+ try {
16072
+ return new URL(targetPath, baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`).toString();
16073
+ } catch {
16074
+ return `${baseUrl.replace(/\/+$/, "")}/${targetPath.replace(/^\/+/, "")}`;
16075
+ }
16076
+ }
16077
+ function buildScenarioUserMessage(scenario, baseUrl) {
16078
+ const userParts = [
16079
+ `**Scenario:** ${scenario.name}`,
16080
+ `**Description:** ${scenario.description}`
16081
+ ];
16082
+ if (baseUrl) {
16083
+ const normalizedBaseUrl = baseUrl.replace(/\/+$/, "");
16084
+ userParts.push(`**Base URL:** ${normalizedBaseUrl}`);
16085
+ if (scenario.targetPath) {
16086
+ userParts.push(`**Start URL:** ${resolveStartUrl(normalizedBaseUrl, scenario.targetPath)}`);
16087
+ }
16088
+ userParts.push("**Navigation Boundary:** Treat the Base URL as the application under test. Resolve relative paths and in-app navigation against this origin. Do not navigate to another host unless a step explicitly includes an absolute external URL.");
16089
+ }
16090
+ if (scenario.targetPath) {
16091
+ userParts.push(`**Target Path:** ${scenario.targetPath}`);
16092
+ }
16093
+ if (scenario.steps.length > 0) {
16094
+ userParts.push("**Steps:**");
16095
+ for (let i = 0;i < scenario.steps.length; i++) {
16096
+ userParts.push(`${i + 1}. ${scenario.steps[i]}`);
16097
+ }
16098
+ }
16099
+ return userParts.join(`
16100
+ `);
16101
+ }
15998
16102
  async function runAgentLoop(options) {
15999
16103
  const {
16000
16104
  client,
@@ -16004,6 +16108,7 @@ async function runAgentLoop(options) {
16004
16108
  model,
16005
16109
  runId,
16006
16110
  sessionId,
16111
+ baseUrl,
16007
16112
  maxTurns = 30,
16008
16113
  onStep,
16009
16114
  persona,
@@ -16051,21 +16156,7 @@ Instructions: ${persona.instructions}` : "",
16051
16156
  "- Verify both positive and negative states"
16052
16157
  ].join(`
16053
16158
  `) + personaSection;
16054
- const userParts = [
16055
- `**Scenario:** ${scenario.name}`,
16056
- `**Description:** ${scenario.description}`
16057
- ];
16058
- if (scenario.targetPath) {
16059
- userParts.push(`**Target Path:** ${scenario.targetPath}`);
16060
- }
16061
- if (scenario.steps.length > 0) {
16062
- userParts.push("**Steps:**");
16063
- for (let i = 0;i < scenario.steps.length; i++) {
16064
- userParts.push(`${i + 1}. ${scenario.steps[i]}`);
16065
- }
16066
- }
16067
- const userMessage = userParts.join(`
16068
- `);
16159
+ const userMessage = buildScenarioUserMessage(scenario, baseUrl);
16069
16160
  const screenshots = [];
16070
16161
  let tokensUsed = 0;
16071
16162
  let stepNumber = 0;
@@ -16128,7 +16219,7 @@ Instructions: ${persona.instructions}` : "",
16128
16219
  if (onStep) {
16129
16220
  onStep({ type: "tool_call", toolName: toolBlock.name, toolInput, stepNumber });
16130
16221
  }
16131
- const execResult = await executeTool(page, screenshotter, toolBlock.name, toolInput, { runId, scenarioSlug, stepNumber, sessionId, a11y });
16222
+ const execResult = await executeTool(page, screenshotter, toolBlock.name, toolInput, { runId, scenarioSlug, stepNumber, sessionId: sessionId ?? runId, a11y });
16132
16223
  if (onStep) {
16133
16224
  onStep({ type: "tool_result", toolName: toolBlock.name, toolResult: execResult.result, stepNumber });
16134
16225
  }
@@ -16179,10 +16270,17 @@ function detectProvider(model) {
16179
16270
  return "openai";
16180
16271
  if (model.startsWith("gemini-"))
16181
16272
  return "google";
16273
+ if (model.startsWith("glm-") || model.startsWith("zai/") || model.startsWith("zai-"))
16274
+ return "zai";
16182
16275
  if (model.startsWith("llama-") || model.startsWith("qwen-") || model.includes("cerebras"))
16183
16276
  return "cerebras";
16184
16277
  return "anthropic";
16185
16278
  }
16279
+ function resolveProviderApiKeyForModel(model, explicitApiKey, configuredAnthropicApiKey) {
16280
+ if (explicitApiKey)
16281
+ return explicitApiKey;
16282
+ return detectProvider(model) === "anthropic" ? configuredAnthropicApiKey : undefined;
16283
+ }
16186
16284
  function createClient(apiKey) {
16187
16285
  const key = apiKey ?? process.env["ANTHROPIC_API_KEY"];
16188
16286
  if (!key) {
@@ -16260,26 +16358,34 @@ async function callOpenAICompatible(options) {
16260
16358
  const usage = { input_tokens: data.usage?.prompt_tokens ?? 0, output_tokens: data.usage?.completion_tokens ?? 0 };
16261
16359
  return { content, stop_reason: stopReason, usage };
16262
16360
  }
16263
- function createClientForModel(model, apiKey) {
16264
- const provider = detectProvider(model);
16361
+ function createOpenAICompatibleConfig(provider, apiKey) {
16265
16362
  if (provider === "openai") {
16266
- const key = apiKey ?? process.env["OPENAI_API_KEY"];
16267
- if (!key)
16363
+ const key2 = apiKey ?? process.env["OPENAI_API_KEY"];
16364
+ if (!key2)
16268
16365
  throw new AIClientError("No OpenAI API key. Set OPENAI_API_KEY or pass it explicitly.");
16269
- return { provider: "openai", baseUrl: "https://api.openai.com/v1", apiKey: key };
16366
+ return { provider: "openai", baseUrl: "https://api.openai.com/v1", apiKey: key2 };
16270
16367
  }
16271
16368
  if (provider === "google") {
16272
- const key = apiKey ?? process.env["GOOGLE_API_KEY"];
16273
- if (!key)
16369
+ const key2 = apiKey ?? process.env["GOOGLE_API_KEY"];
16370
+ if (!key2)
16274
16371
  throw new AIClientError("No Google API key. Set GOOGLE_API_KEY or pass it explicitly.");
16275
- return { provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai", apiKey: key };
16372
+ return { provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai", apiKey: key2 };
16276
16373
  }
16277
16374
  if (provider === "cerebras") {
16278
- const key = apiKey ?? process.env["CEREBRAS_API_KEY"];
16279
- if (!key)
16375
+ const key2 = apiKey ?? process.env["CEREBRAS_API_KEY"];
16376
+ if (!key2)
16280
16377
  throw new AIClientError("No Cerebras API key. Set CEREBRAS_API_KEY or pass it explicitly.");
16281
- return { provider: "cerebras", baseUrl: "https://api.cerebras.ai/v1", apiKey: key };
16378
+ return { provider: "cerebras", baseUrl: "https://api.cerebras.ai/v1", apiKey: key2 };
16282
16379
  }
16380
+ const key = apiKey ?? process.env["ZAI_API_KEY"];
16381
+ if (!key)
16382
+ throw new AIClientError("No Z.AI API key. Set ZAI_API_KEY or pass it explicitly.");
16383
+ return { provider: "zai", baseUrl: "https://api.z.ai/api/paas/v4", apiKey: key };
16384
+ }
16385
+ function createClientForModel(model, apiKey) {
16386
+ const provider = detectProvider(model);
16387
+ if (provider !== "anthropic")
16388
+ return createOpenAICompatibleConfig(provider, apiKey);
16283
16389
  return createClient(apiKey);
16284
16390
  }
16285
16391
  var activeHARs, activeCoverage, BROWSER_TOOLS;
@@ -28623,34 +28729,27 @@ var init_v3 = __esm(() => {
28623
28729
 
28624
28730
  // node_modules/@ai-sdk/provider-utils/node_modules/eventsource-parser/dist/index.js
28625
28731
  function noop(_arg) {}
28626
- function createParser(config2) {
28627
- if (typeof config2 == "function")
28628
- throw new TypeError("`config` must be an object, got a function instead. Did you mean `createParser({onEvent: fn})`?");
28629
- const { onEvent = noop, onError = noop, onRetry = noop, onComment, maxBufferSize } = config2, pendingFragments = [];
28630
- let pendingFragmentsLength = 0, isFirstChunk = true, id, data = "", dataLines = 0, eventType, terminated = false;
28732
+ function createParser(callbacks) {
28733
+ if (typeof callbacks == "function")
28734
+ throw new TypeError("`callbacks` must be an object, got a function instead. Did you mean `{onEvent: fn}`?");
28735
+ const { onEvent = noop, onError = noop, onRetry = noop, onComment } = callbacks, pendingFragments = [];
28736
+ let isFirstChunk = true, id, data = "", dataLines = 0, eventType;
28631
28737
  function feed(chunk) {
28632
- if (terminated)
28633
- throw new Error("Cannot feed parser: it was terminated after exceeding the configured max buffer size. Call `reset()` to resume parsing.");
28634
28738
  if (isFirstChunk && (isFirstChunk = false, chunk.charCodeAt(0) === 239 && chunk.charCodeAt(1) === 187 && chunk.charCodeAt(2) === 191 && (chunk = chunk.slice(3))), pendingFragments.length === 0) {
28635
28739
  const trailing2 = processLines(chunk);
28636
- trailing2 !== "" && (pendingFragments.push(trailing2), pendingFragmentsLength = trailing2.length), checkBufferSize();
28740
+ trailing2 !== "" && pendingFragments.push(trailing2);
28637
28741
  return;
28638
28742
  }
28639
28743
  if (chunk.indexOf(`
28640
28744
  `) === -1 && chunk.indexOf("\r") === -1) {
28641
- pendingFragments.push(chunk), pendingFragmentsLength += chunk.length, checkBufferSize();
28745
+ pendingFragments.push(chunk);
28642
28746
  return;
28643
28747
  }
28644
28748
  pendingFragments.push(chunk);
28645
28749
  const input = pendingFragments.join("");
28646
- pendingFragments.length = 0, pendingFragmentsLength = 0;
28750
+ pendingFragments.length = 0;
28647
28751
  const trailing = processLines(input);
28648
- trailing !== "" && (pendingFragments.push(trailing), pendingFragmentsLength = trailing.length), checkBufferSize();
28649
- }
28650
- function checkBufferSize() {
28651
- maxBufferSize !== undefined && (pendingFragmentsLength + data.length <= maxBufferSize || (terminated = true, pendingFragments.length = 0, pendingFragmentsLength = 0, id = undefined, data = "", dataLines = 0, eventType = undefined, onError(new ParseError(`Buffered data exceeded max buffer size of ${maxBufferSize} characters`, {
28652
- type: "max-buffer-size-exceeded"
28653
- }))));
28752
+ trailing !== "" && pendingFragments.push(trailing);
28654
28753
  }
28655
28754
  function processLines(chunk) {
28656
28755
  let searchIndex = 0;
@@ -28762,7 +28861,7 @@ ${value}`, dataLines++;
28762
28861
  const incompleteLine = pendingFragments.join("");
28763
28862
  parseLine(incompleteLine, 0, incompleteLine.length);
28764
28863
  }
28765
- isFirstChunk = true, id = undefined, data = "", dataLines = 0, eventType = undefined, pendingFragments.length = 0, pendingFragmentsLength = 0, terminated = false;
28864
+ isFirstChunk = true, id = undefined, data = "", dataLines = 0, eventType = undefined, pendingFragments.length = 0;
28766
28865
  }
28767
28866
  return { feed, reset };
28768
28867
  }
@@ -28786,7 +28885,7 @@ var EventSourceParserStream;
28786
28885
  var init_stream = __esm(() => {
28787
28886
  init_dist3();
28788
28887
  EventSourceParserStream = class EventSourceParserStream extends TransformStream {
28789
- constructor({ onError, onRetry, onComment, maxBufferSize } = {}) {
28888
+ constructor({ onError, onRetry, onComment } = {}) {
28790
28889
  let parser;
28791
28890
  super({
28792
28891
  start(controller) {
@@ -28795,11 +28894,10 @@ var init_stream = __esm(() => {
28795
28894
  controller.enqueue(event);
28796
28895
  },
28797
28896
  onError(error40) {
28798
- typeof onError == "function" && onError(error40), (onError === "terminate" || error40.type === "max-buffer-size-exceeded") && controller.error(error40);
28897
+ onError === "terminate" ? controller.error(error40) : typeof onError == "function" && onError(error40);
28799
28898
  },
28800
28899
  onRetry,
28801
- onComment,
28802
- maxBufferSize
28900
+ onComment
28803
28901
  });
28804
28902
  },
28805
28903
  transform(chunk) {
@@ -30238,7 +30336,7 @@ var DelayedPromise = class {
30238
30336
  });
30239
30337
  }
30240
30338
  return () => `${prefix}${separator}${generator()}`;
30241
- }, generateId, FETCH_FAILED_ERROR_MESSAGES, BUN_ERROR_CODES, VERSION = "4.0.27", getOriginalFetch = () => globalThis.fetch, getFromApi = async ({
30339
+ }, generateId, FETCH_FAILED_ERROR_MESSAGES, BUN_ERROR_CODES, VERSION = "4.0.26", getOriginalFetch = () => globalThis.fetch, getFromApi = async ({
30242
30340
  url: url2,
30243
30341
  headers = {},
30244
30342
  successfulResponseHandler,
@@ -32377,7 +32475,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
32377
32475
  "ai-model-id": this.modelId
32378
32476
  };
32379
32477
  }
32380
- }, gatewayRerankingResponseSchema, parallelSearchInputSchema, parallelSearchOutputSchema, parallelSearchToolFactory, parallelSearch = (config2 = {}) => parallelSearchToolFactory(config2), perplexitySearchInputSchema, perplexitySearchOutputSchema, perplexitySearchToolFactory, perplexitySearch = (config2 = {}) => perplexitySearchToolFactory(config2), gatewayTools, VERSION2 = "3.0.120", AI_GATEWAY_PROTOCOL_VERSION = "0.0.1", gateway;
32478
+ }, gatewayRerankingResponseSchema, parallelSearchInputSchema, parallelSearchOutputSchema, parallelSearchToolFactory, parallelSearch = (config2 = {}) => parallelSearchToolFactory(config2), perplexitySearchInputSchema, perplexitySearchOutputSchema, perplexitySearchToolFactory, perplexitySearch = (config2 = {}) => perplexitySearchToolFactory(config2), gatewayTools, VERSION2 = "3.0.110", AI_GATEWAY_PROTOCOL_VERSION = "0.0.1", gateway;
32381
32479
  var init_dist5 = __esm(() => {
32382
32480
  init_dist4();
32383
32481
  init_dist2();
@@ -32416,15 +32514,13 @@ var init_dist5 = __esm(() => {
32416
32514
  message,
32417
32515
  statusCode = 500,
32418
32516
  cause,
32419
- generationId,
32420
- isRetryable = statusCode != null && (statusCode === 408 || statusCode === 409 || statusCode === 429 || statusCode >= 500)
32517
+ generationId
32421
32518
  }) {
32422
32519
  super(generationId ? `${message} [${generationId}]` : message);
32423
32520
  this[_a17] = true;
32424
32521
  this.statusCode = statusCode;
32425
32522
  this.cause = cause;
32426
32523
  this.generationId = generationId;
32427
- this.isRetryable = isRetryable;
32428
32524
  }
32429
32525
  static isInstance(error40) {
32430
32526
  return _GatewayError.hasMarker(error40);
@@ -32947,11 +33043,62 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
32947
33043
  gateway = createGatewayProvider();
32948
33044
  });
32949
33045
 
33046
+ // node_modules/@opentelemetry/api/build/src/platform/node/globalThis.js
33047
+ var require_globalThis = __commonJS((exports) => {
33048
+ Object.defineProperty(exports, "__esModule", { value: true });
33049
+ exports._globalThis = undefined;
33050
+ exports._globalThis = typeof globalThis === "object" ? globalThis : global;
33051
+ });
33052
+
33053
+ // node_modules/@opentelemetry/api/build/src/platform/node/index.js
33054
+ var require_node = __commonJS((exports) => {
33055
+ var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
33056
+ if (k2 === undefined)
33057
+ k2 = k;
33058
+ Object.defineProperty(o, k2, { enumerable: true, get: function() {
33059
+ return m[k];
33060
+ } });
33061
+ } : function(o, m, k, k2) {
33062
+ if (k2 === undefined)
33063
+ k2 = k;
33064
+ o[k2] = m[k];
33065
+ });
33066
+ var __exportStar = exports && exports.__exportStar || function(m, exports2) {
33067
+ for (var p in m)
33068
+ if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
33069
+ __createBinding(exports2, m, p);
33070
+ };
33071
+ Object.defineProperty(exports, "__esModule", { value: true });
33072
+ __exportStar(require_globalThis(), exports);
33073
+ });
33074
+
33075
+ // node_modules/@opentelemetry/api/build/src/platform/index.js
33076
+ var require_platform = __commonJS((exports) => {
33077
+ var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
33078
+ if (k2 === undefined)
33079
+ k2 = k;
33080
+ Object.defineProperty(o, k2, { enumerable: true, get: function() {
33081
+ return m[k];
33082
+ } });
33083
+ } : function(o, m, k, k2) {
33084
+ if (k2 === undefined)
33085
+ k2 = k;
33086
+ o[k2] = m[k];
33087
+ });
33088
+ var __exportStar = exports && exports.__exportStar || function(m, exports2) {
33089
+ for (var p in m)
33090
+ if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
33091
+ __createBinding(exports2, m, p);
33092
+ };
33093
+ Object.defineProperty(exports, "__esModule", { value: true });
33094
+ __exportStar(require_node(), exports);
33095
+ });
33096
+
32950
33097
  // node_modules/@opentelemetry/api/build/src/version.js
32951
33098
  var require_version = __commonJS((exports) => {
32952
33099
  Object.defineProperty(exports, "__esModule", { value: true });
32953
33100
  exports.VERSION = undefined;
32954
- exports.VERSION = "1.9.1";
33101
+ exports.VERSION = "1.9.0";
32955
33102
  });
32956
33103
 
32957
33104
  // node_modules/@opentelemetry/api/build/src/internal/semver.js
@@ -33029,11 +33176,12 @@ var require_semver = __commonJS((exports) => {
33029
33176
  var require_global_utils = __commonJS((exports) => {
33030
33177
  Object.defineProperty(exports, "__esModule", { value: true });
33031
33178
  exports.unregisterGlobal = exports.getGlobal = exports.registerGlobal = undefined;
33179
+ var platform_1 = require_platform();
33032
33180
  var version_1 = require_version();
33033
33181
  var semver_1 = require_semver();
33034
33182
  var major = version_1.VERSION.split(".")[0];
33035
33183
  var GLOBAL_OPENTELEMETRY_API_KEY = Symbol.for(`opentelemetry.js.api.${major}`);
33036
- var _global = typeof globalThis === "object" ? globalThis : typeof self === "object" ? self : typeof window === "object" ? window : typeof global === "object" ? global : {};
33184
+ var _global = platform_1._globalThis;
33037
33185
  function registerGlobal(type, instance, diag, allowOverride = false) {
33038
33186
  var _a16;
33039
33187
  const api2 = _global[GLOBAL_OPENTELEMETRY_API_KEY] = (_a16 = _global[GLOBAL_OPENTELEMETRY_API_KEY]) !== null && _a16 !== undefined ? _a16 : {
@@ -33105,7 +33253,8 @@ var require_ComponentLogger = __commonJS((exports) => {
33105
33253
  if (!logger) {
33106
33254
  return;
33107
33255
  }
33108
- return logger[funcName](namespace, ...args);
33256
+ args.unshift(namespace);
33257
+ return logger[funcName](...args);
33109
33258
  }
33110
33259
  });
33111
33260
 
@@ -33166,12 +33315,6 @@ var require_diag = __commonJS((exports) => {
33166
33315
  var API_NAME = "diag";
33167
33316
 
33168
33317
  class DiagAPI {
33169
- static instance() {
33170
- if (!this._instance) {
33171
- this._instance = new DiagAPI;
33172
- }
33173
- return this._instance;
33174
- }
33175
33318
  constructor() {
33176
33319
  function _logProxy(funcName) {
33177
33320
  return function(...args) {
@@ -33181,12 +33324,12 @@ var require_diag = __commonJS((exports) => {
33181
33324
  return logger[funcName](...args);
33182
33325
  };
33183
33326
  }
33184
- const self2 = this;
33327
+ const self = this;
33185
33328
  const setLogger = (logger, optionsOrLogLevel = { logLevel: types_1.DiagLogLevel.INFO }) => {
33186
33329
  var _a16, _b16, _c;
33187
- if (logger === self2) {
33330
+ if (logger === self) {
33188
33331
  const err = new Error("Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation");
33189
- self2.error((_a16 = err.stack) !== null && _a16 !== undefined ? _a16 : err.message);
33332
+ self.error((_a16 = err.stack) !== null && _a16 !== undefined ? _a16 : err.message);
33190
33333
  return false;
33191
33334
  }
33192
33335
  if (typeof optionsOrLogLevel === "number") {
@@ -33201,20 +33344,26 @@ var require_diag = __commonJS((exports) => {
33201
33344
  oldLogger.warn(`Current logger will be overwritten from ${stack}`);
33202
33345
  newLogger.warn(`Current logger will overwrite one already registered from ${stack}`);
33203
33346
  }
33204
- return (0, global_utils_1.registerGlobal)("diag", newLogger, self2, true);
33347
+ return (0, global_utils_1.registerGlobal)("diag", newLogger, self, true);
33205
33348
  };
33206
- self2.setLogger = setLogger;
33207
- self2.disable = () => {
33208
- (0, global_utils_1.unregisterGlobal)(API_NAME, self2);
33349
+ self.setLogger = setLogger;
33350
+ self.disable = () => {
33351
+ (0, global_utils_1.unregisterGlobal)(API_NAME, self);
33209
33352
  };
33210
- self2.createComponentLogger = (options) => {
33353
+ self.createComponentLogger = (options) => {
33211
33354
  return new ComponentLogger_1.DiagComponentLogger(options);
33212
33355
  };
33213
- self2.verbose = _logProxy("verbose");
33214
- self2.debug = _logProxy("debug");
33215
- self2.info = _logProxy("info");
33216
- self2.warn = _logProxy("warn");
33217
- self2.error = _logProxy("error");
33356
+ self.verbose = _logProxy("verbose");
33357
+ self.debug = _logProxy("debug");
33358
+ self.info = _logProxy("info");
33359
+ self.warn = _logProxy("warn");
33360
+ self.error = _logProxy("error");
33361
+ }
33362
+ static instance() {
33363
+ if (!this._instance) {
33364
+ this._instance = new DiagAPI;
33365
+ }
33366
+ return this._instance;
33218
33367
  }
33219
33368
  }
33220
33369
  exports.DiagAPI = DiagAPI;
@@ -33237,7 +33386,7 @@ var require_baggage_impl = __commonJS((exports) => {
33237
33386
  return Object.assign({}, entry);
33238
33387
  }
33239
33388
  getAllEntries() {
33240
- return Array.from(this._entries.entries());
33389
+ return Array.from(this._entries.entries()).map(([k, v]) => [k, v]);
33241
33390
  }
33242
33391
  setEntry(key, entry) {
33243
33392
  const newBaggage = new BaggageImpl(this._entries);
@@ -33308,16 +33457,16 @@ var require_context = __commonJS((exports) => {
33308
33457
 
33309
33458
  class BaseContext {
33310
33459
  constructor(parentContext) {
33311
- const self2 = this;
33312
- self2._currentContext = parentContext ? new Map(parentContext) : new Map;
33313
- self2.getValue = (key) => self2._currentContext.get(key);
33314
- self2.setValue = (key, value) => {
33315
- const context = new BaseContext(self2._currentContext);
33460
+ const self = this;
33461
+ self._currentContext = parentContext ? new Map(parentContext) : new Map;
33462
+ self.getValue = (key) => self._currentContext.get(key);
33463
+ self.setValue = (key, value) => {
33464
+ const context = new BaseContext(self._currentContext);
33316
33465
  context._currentContext.set(key, value);
33317
33466
  return context;
33318
33467
  };
33319
- self2.deleteValue = (key) => {
33320
- const context = new BaseContext(self2._currentContext);
33468
+ self.deleteValue = (key) => {
33469
+ const context = new BaseContext(self._currentContext);
33321
33470
  context._currentContext.delete(key);
33322
33471
  return context;
33323
33472
  };
@@ -33329,7 +33478,7 @@ var require_context = __commonJS((exports) => {
33329
33478
  // node_modules/@opentelemetry/api/build/src/diag/consoleLogger.js
33330
33479
  var require_consoleLogger = __commonJS((exports) => {
33331
33480
  Object.defineProperty(exports, "__esModule", { value: true });
33332
- exports.DiagConsoleLogger = exports._originalConsoleMethods = undefined;
33481
+ exports.DiagConsoleLogger = undefined;
33333
33482
  var consoleMap = [
33334
33483
  { n: "error", c: "error" },
33335
33484
  { n: "warn", c: "warn" },
@@ -33337,39 +33486,19 @@ var require_consoleLogger = __commonJS((exports) => {
33337
33486
  { n: "debug", c: "debug" },
33338
33487
  { n: "verbose", c: "trace" }
33339
33488
  ];
33340
- exports._originalConsoleMethods = {};
33341
- if (typeof console !== "undefined") {
33342
- const keys = [
33343
- "error",
33344
- "warn",
33345
- "info",
33346
- "debug",
33347
- "trace",
33348
- "log"
33349
- ];
33350
- for (const key of keys) {
33351
- if (typeof console[key] === "function") {
33352
- exports._originalConsoleMethods[key] = console[key];
33353
- }
33354
- }
33355
- }
33356
33489
 
33357
33490
  class DiagConsoleLogger {
33358
33491
  constructor() {
33359
33492
  function _consoleFunc(funcName) {
33360
33493
  return function(...args) {
33361
- let theFunc = exports._originalConsoleMethods[funcName];
33362
- if (typeof theFunc !== "function") {
33363
- theFunc = exports._originalConsoleMethods["log"];
33364
- }
33365
- if (typeof theFunc !== "function" && console) {
33366
- theFunc = console[funcName];
33494
+ if (console) {
33495
+ let theFunc = console[funcName];
33367
33496
  if (typeof theFunc !== "function") {
33368
33497
  theFunc = console.log;
33369
33498
  }
33370
- }
33371
- if (typeof theFunc === "function") {
33372
- return theFunc.apply(console, args);
33499
+ if (typeof theFunc === "function") {
33500
+ return theFunc.apply(console, args);
33501
+ }
33373
33502
  }
33374
33503
  };
33375
33504
  }
@@ -33607,8 +33736,8 @@ var require_NonRecordingSpan = __commonJS((exports) => {
33607
33736
  var invalid_span_constants_1 = require_invalid_span_constants();
33608
33737
 
33609
33738
  class NonRecordingSpan {
33610
- constructor(spanContext = invalid_span_constants_1.INVALID_SPAN_CONTEXT) {
33611
- this._spanContext = spanContext;
33739
+ constructor(_spanContext = invalid_span_constants_1.INVALID_SPAN_CONTEXT) {
33740
+ this._spanContext = _spanContext;
33612
33741
  }
33613
33742
  spanContext() {
33614
33743
  return this._spanContext;
@@ -33684,126 +33813,14 @@ var require_spancontext_utils = __commonJS((exports) => {
33684
33813
  exports.wrapSpanContext = exports.isSpanContextValid = exports.isValidSpanId = exports.isValidTraceId = undefined;
33685
33814
  var invalid_span_constants_1 = require_invalid_span_constants();
33686
33815
  var NonRecordingSpan_1 = require_NonRecordingSpan();
33687
- var isHex = new Uint8Array([
33688
- 0,
33689
- 0,
33690
- 0,
33691
- 0,
33692
- 0,
33693
- 0,
33694
- 0,
33695
- 0,
33696
- 0,
33697
- 0,
33698
- 0,
33699
- 0,
33700
- 0,
33701
- 0,
33702
- 0,
33703
- 0,
33704
- 0,
33705
- 0,
33706
- 0,
33707
- 0,
33708
- 0,
33709
- 0,
33710
- 0,
33711
- 0,
33712
- 0,
33713
- 0,
33714
- 0,
33715
- 0,
33716
- 0,
33717
- 0,
33718
- 0,
33719
- 0,
33720
- 0,
33721
- 0,
33722
- 0,
33723
- 0,
33724
- 0,
33725
- 0,
33726
- 0,
33727
- 0,
33728
- 0,
33729
- 0,
33730
- 0,
33731
- 0,
33732
- 0,
33733
- 0,
33734
- 0,
33735
- 0,
33736
- 1,
33737
- 1,
33738
- 1,
33739
- 1,
33740
- 1,
33741
- 1,
33742
- 1,
33743
- 1,
33744
- 1,
33745
- 1,
33746
- 0,
33747
- 0,
33748
- 0,
33749
- 0,
33750
- 0,
33751
- 0,
33752
- 0,
33753
- 1,
33754
- 1,
33755
- 1,
33756
- 1,
33757
- 1,
33758
- 1,
33759
- 0,
33760
- 0,
33761
- 0,
33762
- 0,
33763
- 0,
33764
- 0,
33765
- 0,
33766
- 0,
33767
- 0,
33768
- 0,
33769
- 0,
33770
- 0,
33771
- 0,
33772
- 0,
33773
- 0,
33774
- 0,
33775
- 0,
33776
- 0,
33777
- 0,
33778
- 0,
33779
- 0,
33780
- 0,
33781
- 0,
33782
- 0,
33783
- 0,
33784
- 0,
33785
- 1,
33786
- 1,
33787
- 1,
33788
- 1,
33789
- 1,
33790
- 1
33791
- ]);
33792
- function isValidHex(id, length) {
33793
- if (typeof id !== "string" || id.length !== length)
33794
- return false;
33795
- let r = 0;
33796
- for (let i = 0;i < id.length; i += 4) {
33797
- r += (isHex[id.charCodeAt(i)] | 0) + (isHex[id.charCodeAt(i + 1)] | 0) + (isHex[id.charCodeAt(i + 2)] | 0) + (isHex[id.charCodeAt(i + 3)] | 0);
33798
- }
33799
- return r === length;
33800
- }
33816
+ var VALID_TRACEID_REGEX = /^([0-9a-f]{32})$/i;
33817
+ var VALID_SPANID_REGEX = /^[0-9a-f]{16}$/i;
33801
33818
  function isValidTraceId(traceId) {
33802
- return isValidHex(traceId, 32) && traceId !== invalid_span_constants_1.INVALID_TRACEID;
33819
+ return VALID_TRACEID_REGEX.test(traceId) && traceId !== invalid_span_constants_1.INVALID_TRACEID;
33803
33820
  }
33804
33821
  exports.isValidTraceId = isValidTraceId;
33805
33822
  function isValidSpanId(spanId) {
33806
- return isValidHex(spanId, 16) && spanId !== invalid_span_constants_1.INVALID_SPANID;
33823
+ return VALID_SPANID_REGEX.test(spanId) && spanId !== invalid_span_constants_1.INVALID_SPANID;
33807
33824
  }
33808
33825
  exports.isValidSpanId = isValidSpanId;
33809
33826
  function isSpanContextValid(spanContext) {
@@ -33863,7 +33880,7 @@ var require_NoopTracer = __commonJS((exports) => {
33863
33880
  }
33864
33881
  exports.NoopTracer = NoopTracer;
33865
33882
  function isSpanContext(spanContext) {
33866
- return spanContext !== null && typeof spanContext === "object" && "spanId" in spanContext && typeof spanContext["spanId"] === "string" && "traceId" in spanContext && typeof spanContext["traceId"] === "string" && "traceFlags" in spanContext && typeof spanContext["traceFlags"] === "number";
33883
+ return typeof spanContext === "object" && typeof spanContext["spanId"] === "string" && typeof spanContext["traceId"] === "string" && typeof spanContext["traceFlags"] === "number";
33867
33884
  }
33868
33885
  });
33869
33886
 
@@ -33875,8 +33892,8 @@ var require_ProxyTracer = __commonJS((exports) => {
33875
33892
  var NOOP_TRACER = new NoopTracer_1.NoopTracer;
33876
33893
 
33877
33894
  class ProxyTracer {
33878
- constructor(provider, name15, version2, options) {
33879
- this._provider = provider;
33895
+ constructor(_provider, name15, version2, options) {
33896
+ this._provider = _provider;
33880
33897
  this.name = name15;
33881
33898
  this.version = version2;
33882
33899
  this.options = options;
@@ -34036,7 +34053,7 @@ var require_tracestate_impl = __commonJS((exports) => {
34036
34053
  return this._internalState.get(key);
34037
34054
  }
34038
34055
  serialize() {
34039
- return Array.from(this._internalState.keys()).reduceRight((agg, key) => {
34056
+ return this._keys().reduce((agg, key) => {
34040
34057
  agg.push(key + LIST_MEMBER_KEY_VALUE_SPLITTER + this.get(key));
34041
34058
  return agg;
34042
34059
  }, []).join(LIST_MEMBERS_SEPARATOR);
@@ -34044,7 +34061,7 @@ var require_tracestate_impl = __commonJS((exports) => {
34044
34061
  _parse(rawTraceState) {
34045
34062
  if (rawTraceState.length > MAX_TRACE_STATE_LEN)
34046
34063
  return;
34047
- this._internalState = rawTraceState.split(LIST_MEMBERS_SEPARATOR).reduceRight((agg, part) => {
34064
+ this._internalState = rawTraceState.split(LIST_MEMBERS_SEPARATOR).reverse().reduce((agg, part) => {
34048
34065
  const listMember = part.trim();
34049
34066
  const i = listMember.indexOf(LIST_MEMBER_KEY_VALUE_SPLITTER);
34050
34067
  if (i !== -1) {
@@ -35144,10 +35161,7 @@ function convertToLanguageModelMessage({
35144
35161
  type: "tool-result",
35145
35162
  toolCallId: part.toolCallId,
35146
35163
  toolName: part.toolName,
35147
- output: mapToolResultOutput({
35148
- output: part.output,
35149
- downloadedAssets
35150
- }),
35164
+ output: mapToolResultOutput(part.output),
35151
35165
  providerOptions
35152
35166
  };
35153
35167
  }
@@ -35166,10 +35180,7 @@ function convertToLanguageModelMessage({
35166
35180
  type: "tool-result",
35167
35181
  toolCallId: part.toolCallId,
35168
35182
  toolName: part.toolName,
35169
- output: mapToolResultOutput({
35170
- output: part.output,
35171
- downloadedAssets
35172
- }),
35183
+ output: mapToolResultOutput(part.output),
35173
35184
  providerOptions: part.providerOptions
35174
35185
  };
35175
35186
  }
@@ -35193,44 +35204,15 @@ function convertToLanguageModelMessage({
35193
35204
  }
35194
35205
  }
35195
35206
  async function downloadAssets(messages, download2, supportedUrls) {
35196
- var _a21;
35197
- const downloadableFiles = [];
35198
- for (const message of messages) {
35199
- if (message.role === "user" && Array.isArray(message.content)) {
35200
- for (const part of message.content) {
35201
- if (part.type === "image" || part.type === "file") {
35202
- downloadableFiles.push({
35203
- data: part.type === "image" ? part.image : part.data,
35204
- mediaType: (_a21 = part.mediaType) != null ? _a21 : part.type === "image" ? "image/*" : undefined
35205
- });
35206
- }
35207
- }
35208
- }
35209
- if (message.role === "tool" || message.role === "assistant") {
35210
- if (!Array.isArray(message.content)) {
35211
- continue;
35212
- }
35213
- for (const part of message.content) {
35214
- if (part.type !== "tool-result") {
35215
- continue;
35216
- }
35217
- if (part.output.type !== "content") {
35218
- continue;
35219
- }
35220
- for (const contentPart of part.output.value) {
35221
- if (contentPart.type === "image-url" || contentPart.type === "file-url") {
35222
- downloadableFiles.push({
35223
- data: new URL(contentPart.url),
35224
- mediaType: contentPart.type === "image-url" ? "image/*" : undefined
35225
- });
35226
- }
35227
- }
35228
- }
35207
+ const plannedDownloads = messages.filter((message) => message.role === "user").map((message) => message.content).filter((content) => Array.isArray(content)).flat().filter((part) => part.type === "image" || part.type === "file").map((part) => {
35208
+ var _a21;
35209
+ const mediaType = (_a21 = part.mediaType) != null ? _a21 : part.type === "image" ? "image/*" : undefined;
35210
+ let data = part.type === "image" ? part.image : part.data;
35211
+ if (typeof data === "string") {
35212
+ try {
35213
+ data = new URL(data);
35214
+ } catch (ignored) {}
35229
35215
  }
35230
- }
35231
- const plannedDownloads = downloadableFiles.map((part) => {
35232
- const mediaType = part.mediaType;
35233
- const { data } = convertToLanguageModelV3DataContent(part.data);
35234
35216
  return { mediaType, data };
35235
35217
  }).filter((part) => part.data instanceof URL).map((part) => ({
35236
35218
  url: part.data,
@@ -35304,41 +35286,13 @@ function convertPartToLanguageModelPart(part, downloadedAssets) {
35304
35286
  }
35305
35287
  }
35306
35288
  }
35307
- function mapToolResultOutput({
35308
- output,
35309
- downloadedAssets
35310
- }) {
35289
+ function mapToolResultOutput(output) {
35311
35290
  if (output.type !== "content") {
35312
35291
  return output;
35313
35292
  }
35314
35293
  return {
35315
35294
  type: "content",
35316
35295
  value: output.value.map((item) => {
35317
- var _a21, _b16;
35318
- if (item.type === "image-url") {
35319
- const downloadedFile = downloadedAssets[new URL(item.url).toString()];
35320
- if (downloadedFile) {
35321
- return {
35322
- type: "image-data",
35323
- data: convertDataContentToBase64String(downloadedFile.data),
35324
- mediaType: (_a21 = downloadedFile.mediaType) != null ? _a21 : "image/*",
35325
- providerOptions: item.providerOptions
35326
- };
35327
- }
35328
- return item;
35329
- }
35330
- if (item.type === "file-url") {
35331
- const downloadedFile = downloadedAssets[new URL(item.url).toString()];
35332
- if (downloadedFile) {
35333
- return {
35334
- type: "file-data",
35335
- data: convertDataContentToBase64String(downloadedFile.data),
35336
- mediaType: (_b16 = downloadedFile.mediaType) != null ? _b16 : "application/octet-stream",
35337
- providerOptions: item.providerOptions
35338
- };
35339
- }
35340
- return item;
35341
- }
35342
35296
  if (item.type !== "media") {
35343
35297
  return item;
35344
35298
  }
@@ -35891,7 +35845,7 @@ function getRetryDelayInMs({
35891
35845
  error: error40,
35892
35846
  exponentialBackoffDelay
35893
35847
  }) {
35894
- const headers = APICallError.isInstance(error40) ? error40.responseHeaders : APICallError.isInstance(error40.cause) ? error40.cause.responseHeaders : undefined;
35848
+ const headers = error40.responseHeaders;
35895
35849
  if (!headers)
35896
35850
  return exponentialBackoffDelay;
35897
35851
  let ms;
@@ -35941,7 +35895,7 @@ async function _retryWithExponentialBackoff(f, {
35941
35895
  errors: newErrors
35942
35896
  });
35943
35897
  }
35944
- if (error40 instanceof Error && (APICallError.isInstance(error40) && error40.isRetryable === true || GatewayError.isInstance(error40) && error40.isRetryable === true) && tryNumber <= maxRetries) {
35898
+ if (error40 instanceof Error && APICallError.isInstance(error40) && error40.isRetryable === true && tryNumber <= maxRetries) {
35945
35899
  await delay(getRetryDelayInMs({
35946
35900
  error: error40,
35947
35901
  exponentialBackoffDelay: delayInMs
@@ -36159,8 +36113,7 @@ async function executeToolCall({
36159
36113
  input,
36160
36114
  error: error40,
36161
36115
  dynamic: tool2.type === "dynamic",
36162
- ...toolCall.providerMetadata != null ? { providerMetadata: toolCall.providerMetadata } : {},
36163
- ...toolCall.toolMetadata != null ? { toolMetadata: toolCall.toolMetadata } : {}
36116
+ ...toolCall.providerMetadata != null ? { providerMetadata: toolCall.providerMetadata } : {}
36164
36117
  };
36165
36118
  }
36166
36119
  const durationMs = now2() - startTime;
@@ -36190,8 +36143,7 @@ async function executeToolCall({
36190
36143
  input,
36191
36144
  output,
36192
36145
  dynamic: tool2.type === "dynamic",
36193
- ...toolCall.providerMetadata != null ? { providerMetadata: toolCall.providerMetadata } : {},
36194
- ...toolCall.toolMetadata != null ? { toolMetadata: toolCall.toolMetadata } : {}
36146
+ ...toolCall.providerMetadata != null ? { providerMetadata: toolCall.providerMetadata } : {}
36195
36147
  };
36196
36148
  }
36197
36149
  });
@@ -36556,6 +36508,15 @@ async function parsePartialJson(jsonText) {
36556
36508
  }
36557
36509
  return { value: undefined, state: "failed-parse" };
36558
36510
  }
36511
+ function mergeToolProviderMetadata(toolMetadata, callMetadata) {
36512
+ if (toolMetadata == null) {
36513
+ return callMetadata;
36514
+ }
36515
+ if (callMetadata == null) {
36516
+ return toolMetadata;
36517
+ }
36518
+ return { ...toolMetadata, ...callMetadata };
36519
+ }
36559
36520
  async function parseToolCall({
36560
36521
  toolCall,
36561
36522
  tools,
@@ -36563,6 +36524,7 @@ async function parseToolCall({
36563
36524
  system,
36564
36525
  messages
36565
36526
  }) {
36527
+ var _a21, _b16;
36566
36528
  try {
36567
36529
  if (tools == null) {
36568
36530
  if (toolCall.providerExecuted && toolCall.dynamic) {
@@ -36603,7 +36565,6 @@ async function parseToolCall({
36603
36565
  } catch (error40) {
36604
36566
  const parsedInput = await safeParseJSON({ text: toolCall.input });
36605
36567
  const input = parsedInput.success ? parsedInput.value : toolCall.input;
36606
- const tool2 = tools == null ? undefined : tools[toolCall.toolName];
36607
36568
  return {
36608
36569
  type: "tool-call",
36609
36570
  toolCallId: toolCall.toolCallId,
@@ -36612,10 +36573,9 @@ async function parseToolCall({
36612
36573
  dynamic: true,
36613
36574
  invalid: true,
36614
36575
  error: error40,
36615
- title: tool2 == null ? undefined : tool2.title,
36576
+ title: (_a21 = tools == null ? undefined : tools[toolCall.toolName]) == null ? undefined : _a21.title,
36616
36577
  providerExecuted: toolCall.providerExecuted,
36617
- providerMetadata: toolCall.providerMetadata,
36618
- ...(tool2 == null ? undefined : tool2.metadata) != null ? { toolMetadata: tool2.metadata } : {}
36578
+ providerMetadata: mergeToolProviderMetadata((_b16 = tools == null ? undefined : tools[toolCall.toolName]) == null ? undefined : _b16.providerMetadata, toolCall.providerMetadata)
36619
36579
  };
36620
36580
  }
36621
36581
  }
@@ -36662,14 +36622,14 @@ async function doParseToolCall({
36662
36622
  cause: parseResult.error
36663
36623
  });
36664
36624
  }
36625
+ const mergedProviderMetadata = mergeToolProviderMetadata(tool2.providerMetadata, toolCall.providerMetadata);
36665
36626
  return tool2.type === "dynamic" ? {
36666
36627
  type: "tool-call",
36667
36628
  toolCallId: toolCall.toolCallId,
36668
36629
  toolName: toolCall.toolName,
36669
36630
  input: parseResult.value,
36670
36631
  providerExecuted: toolCall.providerExecuted,
36671
- providerMetadata: toolCall.providerMetadata,
36672
- ...tool2.metadata != null ? { toolMetadata: tool2.metadata } : {},
36632
+ providerMetadata: mergedProviderMetadata,
36673
36633
  dynamic: true,
36674
36634
  title: tool2.title
36675
36635
  } : {
@@ -36678,8 +36638,7 @@ async function doParseToolCall({
36678
36638
  toolName,
36679
36639
  input: parseResult.value,
36680
36640
  providerExecuted: toolCall.providerExecuted,
36681
- providerMetadata: toolCall.providerMetadata,
36682
- ...tool2.metadata != null ? { toolMetadata: tool2.metadata } : {},
36641
+ providerMetadata: mergedProviderMetadata,
36683
36642
  title: tool2.title
36684
36643
  };
36685
36644
  }
@@ -37511,8 +37470,7 @@ function asContent({
37511
37470
  error: part.result,
37512
37471
  providerExecuted: true,
37513
37472
  dynamic: part.dynamic,
37514
- ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
37515
- ...(tool2 == null ? undefined : tool2.metadata) != null ? { toolMetadata: tool2.metadata } : {}
37473
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
37516
37474
  });
37517
37475
  } else {
37518
37476
  contentParts.push({
@@ -37523,8 +37481,7 @@ function asContent({
37523
37481
  output: part.result,
37524
37482
  providerExecuted: true,
37525
37483
  dynamic: part.dynamic,
37526
- ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
37527
- ...(tool2 == null ? undefined : tool2.metadata) != null ? { toolMetadata: tool2.metadata } : {}
37484
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
37528
37485
  });
37529
37486
  }
37530
37487
  break;
@@ -37538,8 +37495,7 @@ function asContent({
37538
37495
  error: part.result,
37539
37496
  providerExecuted: true,
37540
37497
  dynamic: toolCall.dynamic,
37541
- ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
37542
- ...toolCall.toolMetadata != null ? { toolMetadata: toolCall.toolMetadata } : {}
37498
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
37543
37499
  });
37544
37500
  } else {
37545
37501
  contentParts.push({
@@ -37550,8 +37506,7 @@ function asContent({
37550
37506
  output: part.result,
37551
37507
  providerExecuted: true,
37552
37508
  dynamic: toolCall.dynamic,
37553
- ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
37554
- ...toolCall.toolMetadata != null ? { toolMetadata: toolCall.toolMetadata } : {}
37509
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
37555
37510
  });
37556
37511
  }
37557
37512
  break;
@@ -37765,9 +37720,6 @@ function processUIMessageStream({
37765
37720
  if (options.title !== undefined) {
37766
37721
  anyPart.title = options.title;
37767
37722
  }
37768
- if (options.toolMetadata !== undefined) {
37769
- anyPart.toolMetadata = options.toolMetadata;
37770
- }
37771
37723
  anyPart.providerExecuted = (_a222 = anyOptions.providerExecuted) != null ? _a222 : part.providerExecuted;
37772
37724
  const providerMetadata = anyOptions.providerMetadata;
37773
37725
  if (providerMetadata != null) {
@@ -37784,7 +37736,6 @@ function processUIMessageStream({
37784
37736
  toolCallId: options.toolCallId,
37785
37737
  state: options.state,
37786
37738
  title: options.title,
37787
- ...options.toolMetadata !== undefined ? { toolMetadata: options.toolMetadata } : {},
37788
37739
  input: anyOptions.input,
37789
37740
  output: anyOptions.output,
37790
37741
  rawInput: anyOptions.rawInput,
@@ -37812,9 +37763,6 @@ function processUIMessageStream({
37812
37763
  if (options.title !== undefined) {
37813
37764
  anyPart.title = options.title;
37814
37765
  }
37815
- if (options.toolMetadata !== undefined) {
37816
- anyPart.toolMetadata = options.toolMetadata;
37817
- }
37818
37766
  anyPart.providerExecuted = (_b23 = anyOptions.providerExecuted) != null ? _b23 : part.providerExecuted;
37819
37767
  const providerMetadata = anyOptions.providerMetadata;
37820
37768
  if (providerMetadata != null) {
@@ -37837,7 +37785,6 @@ function processUIMessageStream({
37837
37785
  preliminary: anyOptions.preliminary,
37838
37786
  providerExecuted: anyOptions.providerExecuted,
37839
37787
  title: options.title,
37840
- ...options.toolMetadata !== undefined ? { toolMetadata: options.toolMetadata } : {},
37841
37788
  ...anyOptions.providerMetadata != null && (options.state === "output-available" || options.state === "output-error") ? { resultProviderMetadata: anyOptions.providerMetadata } : {},
37842
37789
  ...anyOptions.providerMetadata != null && !(options.state === "output-available" || options.state === "output-error") ? { callProviderMetadata: anyOptions.providerMetadata } : {}
37843
37790
  });
@@ -37982,8 +37929,7 @@ function processUIMessageStream({
37982
37929
  toolName: chunk.toolName,
37983
37930
  index: toolInvocations.length,
37984
37931
  dynamic: chunk.dynamic,
37985
- title: chunk.title,
37986
- toolMetadata: chunk.toolMetadata
37932
+ title: chunk.title
37987
37933
  };
37988
37934
  if (chunk.dynamic) {
37989
37935
  updateDynamicToolPart({
@@ -37993,7 +37939,6 @@ function processUIMessageStream({
37993
37939
  input: undefined,
37994
37940
  providerExecuted: chunk.providerExecuted,
37995
37941
  title: chunk.title,
37996
- toolMetadata: chunk.toolMetadata,
37997
37942
  providerMetadata: chunk.providerMetadata
37998
37943
  });
37999
37944
  } else {
@@ -38004,7 +37949,6 @@ function processUIMessageStream({
38004
37949
  input: undefined,
38005
37950
  providerExecuted: chunk.providerExecuted,
38006
37951
  title: chunk.title,
38007
- toolMetadata: chunk.toolMetadata,
38008
37952
  providerMetadata: chunk.providerMetadata
38009
37953
  });
38010
37954
  }
@@ -38028,8 +37972,7 @@ function processUIMessageStream({
38028
37972
  toolName: partialToolCall.toolName,
38029
37973
  state: "input-streaming",
38030
37974
  input: partialArgs,
38031
- title: partialToolCall.title,
38032
- toolMetadata: partialToolCall.toolMetadata
37975
+ title: partialToolCall.title
38033
37976
  });
38034
37977
  } else {
38035
37978
  updateToolPart({
@@ -38037,8 +37980,7 @@ function processUIMessageStream({
38037
37980
  toolName: partialToolCall.toolName,
38038
37981
  state: "input-streaming",
38039
37982
  input: partialArgs,
38040
- title: partialToolCall.title,
38041
- toolMetadata: partialToolCall.toolMetadata
37983
+ title: partialToolCall.title
38042
37984
  });
38043
37985
  }
38044
37986
  write();
@@ -38053,8 +37995,7 @@ function processUIMessageStream({
38053
37995
  input: chunk.input,
38054
37996
  providerExecuted: chunk.providerExecuted,
38055
37997
  providerMetadata: chunk.providerMetadata,
38056
- title: chunk.title,
38057
- toolMetadata: chunk.toolMetadata
37998
+ title: chunk.title
38058
37999
  });
38059
38000
  } else {
38060
38001
  updateToolPart({
@@ -38064,8 +38005,7 @@ function processUIMessageStream({
38064
38005
  input: chunk.input,
38065
38006
  providerExecuted: chunk.providerExecuted,
38066
38007
  providerMetadata: chunk.providerMetadata,
38067
- title: chunk.title,
38068
- toolMetadata: chunk.toolMetadata
38008
+ title: chunk.title
38069
38009
  });
38070
38010
  }
38071
38011
  write();
@@ -38087,8 +38027,7 @@ function processUIMessageStream({
38087
38027
  input: chunk.input,
38088
38028
  errorText: chunk.errorText,
38089
38029
  providerExecuted: chunk.providerExecuted,
38090
- providerMetadata: chunk.providerMetadata,
38091
- toolMetadata: chunk.toolMetadata
38030
+ providerMetadata: chunk.providerMetadata
38092
38031
  });
38093
38032
  } else {
38094
38033
  updateToolPart({
@@ -38099,8 +38038,7 @@ function processUIMessageStream({
38099
38038
  rawInput: chunk.input,
38100
38039
  errorText: chunk.errorText,
38101
38040
  providerExecuted: chunk.providerExecuted,
38102
- providerMetadata: chunk.providerMetadata,
38103
- toolMetadata: chunk.toolMetadata
38041
+ providerMetadata: chunk.providerMetadata
38104
38042
  });
38105
38043
  }
38106
38044
  write();
@@ -38131,8 +38069,7 @@ function processUIMessageStream({
38131
38069
  preliminary: chunk.preliminary,
38132
38070
  providerExecuted: chunk.providerExecuted,
38133
38071
  providerMetadata: chunk.providerMetadata,
38134
- title: toolInvocation.title,
38135
- toolMetadata: toolInvocation.toolMetadata
38072
+ title: toolInvocation.title
38136
38073
  });
38137
38074
  } else {
38138
38075
  updateToolPart({
@@ -38144,8 +38081,7 @@ function processUIMessageStream({
38144
38081
  providerExecuted: chunk.providerExecuted,
38145
38082
  preliminary: chunk.preliminary,
38146
38083
  providerMetadata: chunk.providerMetadata,
38147
- title: toolInvocation.title,
38148
- toolMetadata: toolInvocation.toolMetadata
38084
+ title: toolInvocation.title
38149
38085
  });
38150
38086
  }
38151
38087
  write();
@@ -38162,8 +38098,7 @@ function processUIMessageStream({
38162
38098
  errorText: chunk.errorText,
38163
38099
  providerExecuted: chunk.providerExecuted,
38164
38100
  providerMetadata: chunk.providerMetadata,
38165
- title: toolInvocation.title,
38166
- toolMetadata: toolInvocation.toolMetadata
38101
+ title: toolInvocation.title
38167
38102
  });
38168
38103
  } else {
38169
38104
  updateToolPart({
@@ -38175,8 +38110,7 @@ function processUIMessageStream({
38175
38110
  errorText: chunk.errorText,
38176
38111
  providerExecuted: chunk.providerExecuted,
38177
38112
  providerMetadata: chunk.providerMetadata,
38178
- title: toolInvocation.title,
38179
- toolMetadata: toolInvocation.toolMetadata
38113
+ title: toolInvocation.title
38180
38114
  });
38181
38115
  }
38182
38116
  write();
@@ -38634,8 +38568,7 @@ function runToolsTransformation({
38634
38568
  input: toolCall.input,
38635
38569
  error: getErrorMessage2(toolCall.error),
38636
38570
  dynamic: true,
38637
- title: toolCall.title,
38638
- ...toolCall.toolMetadata != null ? { toolMetadata: toolCall.toolMetadata } : {}
38571
+ title: toolCall.title
38639
38572
  });
38640
38573
  break;
38641
38574
  }
@@ -38703,7 +38636,6 @@ function runToolsTransformation({
38703
38636
  }
38704
38637
  case "tool-result": {
38705
38638
  const toolName = chunk.toolName;
38706
- const toolCall = toolCallsByToolCallId.get(chunk.toolCallId);
38707
38639
  if (chunk.isError) {
38708
38640
  toolResultsStreamController.enqueue({
38709
38641
  type: "tool-error",
@@ -38713,8 +38645,7 @@ function runToolsTransformation({
38713
38645
  providerExecuted: true,
38714
38646
  error: chunk.result,
38715
38647
  dynamic: chunk.dynamic,
38716
- ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {},
38717
- ...(toolCall == null ? undefined : toolCall.toolMetadata) != null ? { toolMetadata: toolCall.toolMetadata } : {}
38648
+ ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
38718
38649
  });
38719
38650
  } else {
38720
38651
  controller.enqueue({
@@ -38725,8 +38656,7 @@ function runToolsTransformation({
38725
38656
  output: chunk.result,
38726
38657
  providerExecuted: true,
38727
38658
  dynamic: chunk.dynamic,
38728
- ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {},
38729
- ...(toolCall == null ? undefined : toolCall.toolMetadata) != null ? { toolMetadata: toolCall.toolMetadata } : {}
38659
+ ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
38730
38660
  });
38731
38661
  }
38732
38662
  break;
@@ -39509,7 +39439,7 @@ async function embed({
39509
39439
  }),
39510
39440
  tracer,
39511
39441
  fn: async (doEmbedSpan) => {
39512
- var _a21, _b16;
39442
+ var _a21;
39513
39443
  const modelResponse = await model.doEmbed({
39514
39444
  values: [value],
39515
39445
  abortSignal,
@@ -39530,7 +39460,7 @@ async function embed({
39530
39460
  return {
39531
39461
  embedding: embedding2,
39532
39462
  usage: usage2,
39533
- warnings: (_b16 = modelResponse.warnings) != null ? _b16 : [],
39463
+ warnings: modelResponse.warnings,
39534
39464
  providerMetadata: modelResponse.providerMetadata,
39535
39465
  response: modelResponse.response
39536
39466
  };
@@ -39626,7 +39556,7 @@ async function embedMany({
39626
39556
  }),
39627
39557
  tracer,
39628
39558
  fn: async (doEmbedSpan) => {
39629
- var _a222, _b16;
39559
+ var _a222;
39630
39560
  const modelResponse = await model.doEmbed({
39631
39561
  values,
39632
39562
  abortSignal,
@@ -39647,7 +39577,7 @@ async function embedMany({
39647
39577
  return {
39648
39578
  embeddings: embeddings3,
39649
39579
  usage: usage2,
39650
- warnings: (_b16 = modelResponse.warnings) != null ? _b16 : [],
39580
+ warnings: modelResponse.warnings,
39651
39581
  providerMetadata: modelResponse.providerMetadata,
39652
39582
  response: modelResponse.response
39653
39583
  };
@@ -39704,7 +39634,7 @@ async function embedMany({
39704
39634
  }),
39705
39635
  tracer,
39706
39636
  fn: async (doEmbedSpan) => {
39707
- var _a222, _b16;
39637
+ var _a222;
39708
39638
  const modelResponse = await model.doEmbed({
39709
39639
  values: chunk,
39710
39640
  abortSignal,
@@ -39725,7 +39655,7 @@ async function embedMany({
39725
39655
  return {
39726
39656
  embeddings: embeddings2,
39727
39657
  usage,
39728
- warnings: (_b16 = modelResponse.warnings) != null ? _b16 : [],
39658
+ warnings: modelResponse.warnings,
39729
39659
  providerMetadata: modelResponse.providerMetadata,
39730
39660
  response: modelResponse.response
39731
39661
  };
@@ -41839,7 +41769,7 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
41839
41769
  const bytes = typeof data === "string" ? convertBase64ToUint8Array(data) : data;
41840
41770
  const id3Size = (bytes[6] & 127) << 21 | (bytes[7] & 127) << 14 | (bytes[8] & 127) << 7 | bytes[9] & 127;
41841
41771
  return bytes.slice(id3Size + 10);
41842
- }, VERSION3 = "6.0.191", download = async ({
41772
+ }, VERSION3 = "6.0.175", download = async ({
41843
41773
  url: url2,
41844
41774
  maxBytes,
41845
41775
  abortSignal
@@ -42347,7 +42277,7 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
42347
42277
  }
42348
42278
  return this._output;
42349
42279
  }
42350
- }, JsonToSseTransformStream, UI_MESSAGE_STREAM_HEADERS, toolMetadataSchema, uiMessageChunkSchema, isToolOrDynamicToolUIPart, getToolOrDynamicToolName, originalGenerateId2, DefaultStreamTextResult = class {
42280
+ }, JsonToSseTransformStream, UI_MESSAGE_STREAM_HEADERS, uiMessageChunkSchema, isToolOrDynamicToolUIPart, getToolOrDynamicToolName, originalGenerateId2, DefaultStreamTextResult = class {
42351
42281
  constructor({
42352
42282
  model,
42353
42283
  telemetry,
@@ -42577,18 +42507,18 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
42577
42507
  const error40 = (abortSignal == null ? undefined : abortSignal.aborted) ? abortSignal.reason : new NoOutputGeneratedError({
42578
42508
  message: "No output generated. Check the stream for errors."
42579
42509
  });
42580
- self2._finishReason.reject(error40);
42581
- self2._rawFinishReason.reject(error40);
42582
- self2._totalUsage.reject(error40);
42583
- self2._steps.reject(error40);
42510
+ self._finishReason.reject(error40);
42511
+ self._rawFinishReason.reject(error40);
42512
+ self._totalUsage.reject(error40);
42513
+ self._steps.reject(error40);
42584
42514
  return;
42585
42515
  }
42586
42516
  const finishReason = recordedFinishReason != null ? recordedFinishReason : "other";
42587
42517
  const totalUsage = recordedTotalUsage != null ? recordedTotalUsage : createNullLanguageModelUsage();
42588
- self2._finishReason.resolve(finishReason);
42589
- self2._rawFinishReason.resolve(recordedRawFinishReason);
42590
- self2._totalUsage.resolve(totalUsage);
42591
- self2._steps.resolve(recordedSteps);
42518
+ self._finishReason.resolve(finishReason);
42519
+ self._rawFinishReason.resolve(recordedRawFinishReason);
42520
+ self._totalUsage.resolve(totalUsage);
42521
+ self._steps.resolve(recordedSteps);
42592
42522
  const finalStep = recordedSteps[recordedSteps.length - 1];
42593
42523
  await notify({
42594
42524
  event: {
@@ -42719,7 +42649,7 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
42719
42649
  headers,
42720
42650
  settings: { ...callSettings, maxRetries }
42721
42651
  });
42722
- const self2 = this;
42652
+ const self = this;
42723
42653
  const modelInfo = { provider: model.provider, modelId: model.modelId };
42724
42654
  const callbackTelemetryProps = {
42725
42655
  functionId: telemetry == null ? undefined : telemetry.functionId,
@@ -42793,7 +42723,7 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
42793
42723
  toolExecutionStepStreamController = controller;
42794
42724
  }
42795
42725
  });
42796
- self2.addStream(toolExecutionStepStream);
42726
+ self.addStream(toolExecutionStepStream);
42797
42727
  try {
42798
42728
  for (const toolApproval of [
42799
42729
  ...localDeniedToolApprovals,
@@ -42877,7 +42807,7 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
42877
42807
  usage
42878
42808
  }) {
42879
42809
  var _a21, _b16, _c, _d, _e, _f, _g, _h, _i;
42880
- const includeRawChunks2 = self2.includeRawChunks;
42810
+ const includeRawChunks2 = self.includeRawChunks;
42881
42811
  const stepTimeoutId = stepTimeoutMs != null ? setTimeout(() => stepAbortController.abort(), stepTimeoutMs) : undefined;
42882
42812
  let chunkTimeoutId = undefined;
42883
42813
  function resetChunkTimeout() {
@@ -43049,7 +42979,7 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
43049
42979
  modelId: modelInfo.modelId
43050
42980
  };
43051
42981
  let activeText = "";
43052
- self2.addStream(streamWithToolResults.pipeThrough(new TransformStream({
42982
+ self.addStream(streamWithToolResults.pipeThrough(new TransformStream({
43053
42983
  async transform(chunk, controller) {
43054
42984
  var _a222, _b23, _c2, _d2, _e2;
43055
42985
  resetChunkTimeout();
@@ -43312,7 +43242,7 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
43312
43242
  type: "error",
43313
43243
  error: error40
43314
43244
  });
43315
- self2.closeStream();
43245
+ self.closeStream();
43316
43246
  }
43317
43247
  } else {
43318
43248
  controller.enqueue({
@@ -43321,7 +43251,7 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
43321
43251
  rawFinishReason: stepRawFinishReason,
43322
43252
  totalUsage: combinedUsage
43323
43253
  });
43324
- self2.closeStream();
43254
+ self.closeStream();
43325
43255
  }
43326
43256
  }
43327
43257
  })));
@@ -43337,13 +43267,13 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
43337
43267
  });
43338
43268
  }
43339
43269
  }).catch((error40) => {
43340
- self2.addStream(new ReadableStream({
43270
+ self.addStream(new ReadableStream({
43341
43271
  start(controller) {
43342
43272
  controller.enqueue({ type: "error", error: error40 });
43343
43273
  controller.close();
43344
43274
  }
43345
43275
  }));
43346
- self2.closeStream();
43276
+ self.closeStream();
43347
43277
  });
43348
43278
  }
43349
43279
  get steps() {
@@ -43595,7 +43525,6 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
43595
43525
  toolName: part.toolName,
43596
43526
  ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
43597
43527
  ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
43598
- ...part.toolMetadata != null ? { toolMetadata: part.toolMetadata } : {},
43599
43528
  ...dynamic != null ? { dynamic } : {},
43600
43529
  ...part.title != null ? { title: part.title } : {}
43601
43530
  });
@@ -43619,7 +43548,6 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
43619
43548
  input: part.input,
43620
43549
  ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
43621
43550
  ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
43622
- ...part.toolMetadata != null ? { toolMetadata: part.toolMetadata } : {},
43623
43551
  ...dynamic != null ? { dynamic } : {},
43624
43552
  errorText: onError(part.error),
43625
43553
  ...part.title != null ? { title: part.title } : {}
@@ -43632,7 +43560,6 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
43632
43560
  input: part.input,
43633
43561
  ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
43634
43562
  ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
43635
- ...part.toolMetadata != null ? { toolMetadata: part.toolMetadata } : {},
43636
43563
  ...dynamic != null ? { dynamic } : {},
43637
43564
  ...part.title != null ? { title: part.title } : {}
43638
43565
  });
@@ -43655,7 +43582,6 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
43655
43582
  output: part.output,
43656
43583
  ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
43657
43584
  ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
43658
- ...part.toolMetadata != null ? { toolMetadata: part.toolMetadata } : {},
43659
43585
  ...part.preliminary != null ? { preliminary: part.preliminary } : {},
43660
43586
  ...dynamic != null ? { dynamic } : {}
43661
43587
  });
@@ -43669,7 +43595,6 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
43669
43595
  errorText: part.providerExecuted ? typeof part.error === "string" ? part.error : JSON.stringify(part.error) : onError(part.error),
43670
43596
  ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
43671
43597
  ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
43672
- ...part.toolMetadata != null ? { toolMetadata: part.toolMetadata } : {},
43673
43598
  ...dynamic != null ? { dynamic } : {}
43674
43599
  });
43675
43600
  break;
@@ -43843,21 +43768,10 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
43843
43768
  ...options
43844
43769
  };
43845
43770
  const preparedCallArgs = (_d = await ((_c = (_b16 = this.settings).prepareCall) == null ? undefined : _c.call(_b16, baseCallArgs))) != null ? _d : baseCallArgs;
43846
- const {
43847
- instructions,
43848
- allowSystemInMessages,
43849
- messages,
43850
- prompt,
43851
- ...callArgs
43852
- } = preparedCallArgs;
43771
+ const { instructions, messages, prompt, ...callArgs } = preparedCallArgs;
43853
43772
  return {
43854
43773
  ...callArgs,
43855
- ...{
43856
- system: instructions,
43857
- allowSystemInMessages,
43858
- messages,
43859
- prompt
43860
- }
43774
+ ...{ system: instructions, messages, prompt }
43861
43775
  };
43862
43776
  }
43863
43777
  mergeOnStepFinishCallbacks(methodCallback) {
@@ -43898,7 +43812,7 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
43898
43812
  onStepFinish: this.mergeOnStepFinishCallbacks(onStepFinish)
43899
43813
  });
43900
43814
  }
43901
- }, toolMetadataSchema2, uiMessagesSchema, DefaultEmbedResult = class {
43815
+ }, uiMessagesSchema, DefaultEmbedResult = class {
43902
43816
  constructor(options) {
43903
43817
  this.value = options.value;
43904
43818
  this.embedding = options.embedding;
@@ -44214,7 +44128,7 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
44214
44128
  settings: { ...callSettings, maxRetries }
44215
44129
  });
44216
44130
  const tracer = getTracer(telemetry);
44217
- const self2 = this;
44131
+ const self = this;
44218
44132
  const stitchableStream = createStitchableStream();
44219
44133
  const eventProcessor = new TransformStream({
44220
44134
  transform(chunk, controller) {
@@ -44323,7 +44237,7 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
44323
44237
  result: await model.doStream(callOptions)
44324
44238
  })
44325
44239
  }));
44326
- self2._request.resolve(request != null ? request : {});
44240
+ self._request.resolve(request != null ? request : {});
44327
44241
  let warnings;
44328
44242
  let usage = createNullLanguageModelUsage();
44329
44243
  let finishReason;
@@ -44414,24 +44328,24 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
44414
44328
  provider: model.provider,
44415
44329
  model: model.modelId
44416
44330
  });
44417
- self2._usage.resolve(usage);
44418
- self2._providerMetadata.resolve(providerMetadata);
44419
- self2._warnings.resolve(warnings);
44420
- self2._response.resolve({
44331
+ self._usage.resolve(usage);
44332
+ self._providerMetadata.resolve(providerMetadata);
44333
+ self._warnings.resolve(warnings);
44334
+ self._response.resolve({
44421
44335
  ...fullResponse,
44422
44336
  headers: response == null ? undefined : response.headers
44423
44337
  });
44424
- self2._finishReason.resolve(finishReason != null ? finishReason : "other");
44338
+ self._finishReason.resolve(finishReason != null ? finishReason : "other");
44425
44339
  try {
44426
44340
  object22 = await parseAndValidateObjectResultWithRepair(accumulatedText, outputStrategy, repairText, {
44427
44341
  response: fullResponse,
44428
44342
  usage,
44429
44343
  finishReason
44430
44344
  });
44431
- self2._object.resolve(object22);
44345
+ self._object.resolve(object22);
44432
44346
  } catch (e) {
44433
44347
  error40 = e;
44434
- self2._object.reject(e);
44348
+ self._object.reject(e);
44435
44349
  }
44436
44350
  break;
44437
44351
  }
@@ -45406,7 +45320,6 @@ var init_dist6 = __esm(() => {
45406
45320
  init_dist5();
45407
45321
  init_dist2();
45408
45322
  init_dist2();
45409
- init_dist5();
45410
45323
  init_dist4();
45411
45324
  init_dist4();
45412
45325
  init_dist4();
@@ -46266,7 +46179,6 @@ var init_dist6 = __esm(() => {
46266
46179
  "x-vercel-ai-ui-message-stream": "v1",
46267
46180
  "x-accel-buffering": "no"
46268
46181
  };
46269
- toolMetadataSchema = exports_external3.record(exports_external3.string(), jsonValueSchema.optional());
46270
46182
  uiMessageChunkSchema = lazySchema(() => zodSchema(exports_external3.union([
46271
46183
  exports_external3.strictObject({
46272
46184
  type: exports_external3.literal("text-start"),
@@ -46294,7 +46206,6 @@ var init_dist6 = __esm(() => {
46294
46206
  toolName: exports_external3.string(),
46295
46207
  providerExecuted: exports_external3.boolean().optional(),
46296
46208
  providerMetadata: providerMetadataSchema.optional(),
46297
- toolMetadata: toolMetadataSchema.optional(),
46298
46209
  dynamic: exports_external3.boolean().optional(),
46299
46210
  title: exports_external3.string().optional()
46300
46211
  }),
@@ -46310,7 +46221,6 @@ var init_dist6 = __esm(() => {
46310
46221
  input: exports_external3.unknown(),
46311
46222
  providerExecuted: exports_external3.boolean().optional(),
46312
46223
  providerMetadata: providerMetadataSchema.optional(),
46313
- toolMetadata: toolMetadataSchema.optional(),
46314
46224
  dynamic: exports_external3.boolean().optional(),
46315
46225
  title: exports_external3.string().optional()
46316
46226
  }),
@@ -46321,7 +46231,6 @@ var init_dist6 = __esm(() => {
46321
46231
  input: exports_external3.unknown(),
46322
46232
  providerExecuted: exports_external3.boolean().optional(),
46323
46233
  providerMetadata: providerMetadataSchema.optional(),
46324
- toolMetadata: toolMetadataSchema.optional(),
46325
46234
  dynamic: exports_external3.boolean().optional(),
46326
46235
  errorText: exports_external3.string(),
46327
46236
  title: exports_external3.string().optional()
@@ -46337,7 +46246,6 @@ var init_dist6 = __esm(() => {
46337
46246
  output: exports_external3.unknown(),
46338
46247
  providerExecuted: exports_external3.boolean().optional(),
46339
46248
  providerMetadata: providerMetadataSchema.optional(),
46340
- toolMetadata: toolMetadataSchema.optional(),
46341
46249
  dynamic: exports_external3.boolean().optional(),
46342
46250
  preliminary: exports_external3.boolean().optional()
46343
46251
  }),
@@ -46347,7 +46255,6 @@ var init_dist6 = __esm(() => {
46347
46255
  errorText: exports_external3.string(),
46348
46256
  providerExecuted: exports_external3.boolean().optional(),
46349
46257
  providerMetadata: providerMetadataSchema.optional(),
46350
- toolMetadata: toolMetadataSchema.optional(),
46351
46258
  dynamic: exports_external3.boolean().optional()
46352
46259
  }),
46353
46260
  exports_external3.strictObject({
@@ -46435,7 +46342,6 @@ var init_dist6 = __esm(() => {
46435
46342
  prefix: "aitxt",
46436
46343
  size: 24
46437
46344
  });
46438
- toolMetadataSchema2 = exports_external3.record(exports_external3.string(), jsonValueSchema.optional());
46439
46345
  uiMessagesSchema = lazySchema(() => zodSchema(exports_external3.array(exports_external3.object({
46440
46346
  id: exports_external3.string(),
46441
46347
  role: exports_external3.enum(["system", "user", "assistant"]),
@@ -46487,7 +46393,6 @@ var init_dist6 = __esm(() => {
46487
46393
  type: exports_external3.literal("dynamic-tool"),
46488
46394
  toolName: exports_external3.string(),
46489
46395
  toolCallId: exports_external3.string(),
46490
- toolMetadata: toolMetadataSchema2.optional(),
46491
46396
  state: exports_external3.literal("input-streaming"),
46492
46397
  input: exports_external3.unknown().optional(),
46493
46398
  providerExecuted: exports_external3.boolean().optional(),
@@ -46500,7 +46405,6 @@ var init_dist6 = __esm(() => {
46500
46405
  type: exports_external3.literal("dynamic-tool"),
46501
46406
  toolName: exports_external3.string(),
46502
46407
  toolCallId: exports_external3.string(),
46503
- toolMetadata: toolMetadataSchema2.optional(),
46504
46408
  state: exports_external3.literal("input-available"),
46505
46409
  input: exports_external3.unknown(),
46506
46410
  providerExecuted: exports_external3.boolean().optional(),
@@ -46513,7 +46417,6 @@ var init_dist6 = __esm(() => {
46513
46417
  type: exports_external3.literal("dynamic-tool"),
46514
46418
  toolName: exports_external3.string(),
46515
46419
  toolCallId: exports_external3.string(),
46516
- toolMetadata: toolMetadataSchema2.optional(),
46517
46420
  state: exports_external3.literal("approval-requested"),
46518
46421
  input: exports_external3.unknown(),
46519
46422
  providerExecuted: exports_external3.boolean().optional(),
@@ -46530,7 +46433,6 @@ var init_dist6 = __esm(() => {
46530
46433
  type: exports_external3.literal("dynamic-tool"),
46531
46434
  toolName: exports_external3.string(),
46532
46435
  toolCallId: exports_external3.string(),
46533
- toolMetadata: toolMetadataSchema2.optional(),
46534
46436
  state: exports_external3.literal("approval-responded"),
46535
46437
  input: exports_external3.unknown(),
46536
46438
  providerExecuted: exports_external3.boolean().optional(),
@@ -46547,7 +46449,6 @@ var init_dist6 = __esm(() => {
46547
46449
  type: exports_external3.literal("dynamic-tool"),
46548
46450
  toolName: exports_external3.string(),
46549
46451
  toolCallId: exports_external3.string(),
46550
- toolMetadata: toolMetadataSchema2.optional(),
46551
46452
  state: exports_external3.literal("output-available"),
46552
46453
  input: exports_external3.unknown(),
46553
46454
  providerExecuted: exports_external3.boolean().optional(),
@@ -46566,9 +46467,8 @@ var init_dist6 = __esm(() => {
46566
46467
  type: exports_external3.literal("dynamic-tool"),
46567
46468
  toolName: exports_external3.string(),
46568
46469
  toolCallId: exports_external3.string(),
46569
- toolMetadata: toolMetadataSchema2.optional(),
46570
46470
  state: exports_external3.literal("output-error"),
46571
- input: exports_external3.unknown().optional(),
46471
+ input: exports_external3.unknown(),
46572
46472
  rawInput: exports_external3.unknown().optional(),
46573
46473
  providerExecuted: exports_external3.boolean().optional(),
46574
46474
  output: exports_external3.never().optional(),
@@ -46585,7 +46485,6 @@ var init_dist6 = __esm(() => {
46585
46485
  type: exports_external3.literal("dynamic-tool"),
46586
46486
  toolName: exports_external3.string(),
46587
46487
  toolCallId: exports_external3.string(),
46588
- toolMetadata: toolMetadataSchema2.optional(),
46589
46488
  state: exports_external3.literal("output-denied"),
46590
46489
  input: exports_external3.unknown(),
46591
46490
  providerExecuted: exports_external3.boolean().optional(),
@@ -46601,7 +46500,6 @@ var init_dist6 = __esm(() => {
46601
46500
  exports_external3.object({
46602
46501
  type: exports_external3.string().startsWith("tool-"),
46603
46502
  toolCallId: exports_external3.string(),
46604
- toolMetadata: toolMetadataSchema2.optional(),
46605
46503
  state: exports_external3.literal("input-streaming"),
46606
46504
  providerExecuted: exports_external3.boolean().optional(),
46607
46505
  callProviderMetadata: providerMetadataSchema.optional(),
@@ -46613,7 +46511,6 @@ var init_dist6 = __esm(() => {
46613
46511
  exports_external3.object({
46614
46512
  type: exports_external3.string().startsWith("tool-"),
46615
46513
  toolCallId: exports_external3.string(),
46616
- toolMetadata: toolMetadataSchema2.optional(),
46617
46514
  state: exports_external3.literal("input-available"),
46618
46515
  providerExecuted: exports_external3.boolean().optional(),
46619
46516
  input: exports_external3.unknown(),
@@ -46625,7 +46522,6 @@ var init_dist6 = __esm(() => {
46625
46522
  exports_external3.object({
46626
46523
  type: exports_external3.string().startsWith("tool-"),
46627
46524
  toolCallId: exports_external3.string(),
46628
- toolMetadata: toolMetadataSchema2.optional(),
46629
46525
  state: exports_external3.literal("approval-requested"),
46630
46526
  input: exports_external3.unknown(),
46631
46527
  providerExecuted: exports_external3.boolean().optional(),
@@ -46641,7 +46537,6 @@ var init_dist6 = __esm(() => {
46641
46537
  exports_external3.object({
46642
46538
  type: exports_external3.string().startsWith("tool-"),
46643
46539
  toolCallId: exports_external3.string(),
46644
- toolMetadata: toolMetadataSchema2.optional(),
46645
46540
  state: exports_external3.literal("approval-responded"),
46646
46541
  input: exports_external3.unknown(),
46647
46542
  providerExecuted: exports_external3.boolean().optional(),
@@ -46657,7 +46552,6 @@ var init_dist6 = __esm(() => {
46657
46552
  exports_external3.object({
46658
46553
  type: exports_external3.string().startsWith("tool-"),
46659
46554
  toolCallId: exports_external3.string(),
46660
- toolMetadata: toolMetadataSchema2.optional(),
46661
46555
  state: exports_external3.literal("output-available"),
46662
46556
  providerExecuted: exports_external3.boolean().optional(),
46663
46557
  input: exports_external3.unknown(),
@@ -46675,10 +46569,9 @@ var init_dist6 = __esm(() => {
46675
46569
  exports_external3.object({
46676
46570
  type: exports_external3.string().startsWith("tool-"),
46677
46571
  toolCallId: exports_external3.string(),
46678
- toolMetadata: toolMetadataSchema2.optional(),
46679
46572
  state: exports_external3.literal("output-error"),
46680
46573
  providerExecuted: exports_external3.boolean().optional(),
46681
- input: exports_external3.unknown().optional(),
46574
+ input: exports_external3.unknown(),
46682
46575
  rawInput: exports_external3.unknown().optional(),
46683
46576
  output: exports_external3.never().optional(),
46684
46577
  errorText: exports_external3.string(),
@@ -46693,7 +46586,6 @@ var init_dist6 = __esm(() => {
46693
46586
  exports_external3.object({
46694
46587
  type: exports_external3.string().startsWith("tool-"),
46695
46588
  toolCallId: exports_external3.string(),
46696
- toolMetadata: toolMetadataSchema2.optional(),
46697
46589
  state: exports_external3.literal("output-denied"),
46698
46590
  providerExecuted: exports_external3.boolean().optional(),
46699
46591
  input: exports_external3.unknown(),
@@ -47014,11 +46906,11 @@ var init_scan_issues = __esm(() => {
47014
46906
 
47015
46907
  // src/server/index.ts
47016
46908
  import { existsSync as existsSync10 } from "fs";
47017
- import { join as join13 } from "path";
46909
+ import { join as join14 } from "path";
47018
46910
  // package.json
47019
46911
  var package_default = {
47020
46912
  name: "@hasna/testers",
47021
- version: "0.0.33",
46913
+ version: "0.0.36",
47022
46914
  description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
47023
46915
  type: "module",
47024
46916
  main: "dist/index.js",
@@ -47042,10 +46934,10 @@ var package_default = {
47042
46934
  ],
47043
46935
  scripts: {
47044
46936
  build: "bun run build:dashboard && bun run build:cli && bun run build:mcp && bun run build:server && bun run build:lib && bun run build:types",
47045
- "build:cli": "bun build src/cli/index.tsx --outdir dist/cli --target bun --external ink --external react --external chalk --external @modelcontextprotocol/sdk --external @anthropic-ai/sdk --external playwright --external @hasna/browser",
47046
- "build:mcp": "bun build src/mcp/index.ts --outdir dist/mcp --target bun --external @modelcontextprotocol/sdk --external @anthropic-ai/sdk --external playwright --external @hasna/browser",
47047
- "build:server": "bun build src/server/index.ts --outdir dist/server --target bun --external @anthropic-ai/sdk --external playwright --external @hasna/browser",
47048
- "build:lib": "bun build src/index.ts --outdir dist --target bun --external playwright --external @anthropic-ai/sdk --external @modelcontextprotocol/sdk --external @hasna/browser",
46937
+ "build:cli": "bun build src/cli/index.tsx --outdir dist/cli --target bun --external ink --external react --external chalk --external @modelcontextprotocol/sdk --external @anthropic-ai/sdk --external playwright --external @hasna/browser --external @hasna/sandboxes",
46938
+ "build:mcp": "bun build src/mcp/index.ts --outdir dist/mcp --target bun --external @modelcontextprotocol/sdk --external @anthropic-ai/sdk --external playwright --external @hasna/browser --external @hasna/sandboxes",
46939
+ "build:server": "bun build src/server/index.ts --outdir dist/server --target bun --external @anthropic-ai/sdk --external playwright --external @hasna/browser --external @hasna/sandboxes",
46940
+ "build:lib": "bun build src/index.ts --outdir dist --target bun --external playwright --external @anthropic-ai/sdk --external @modelcontextprotocol/sdk --external @hasna/browser --external @hasna/sandboxes",
47049
46941
  "build:types": "NODE_OPTIONS='--max-old-space-size=8192' tsc --emitDeclarationOnly --outDir dist --skipLibCheck || true",
47050
46942
  "build:dashboard": "cd dashboard && bun run build",
47051
46943
  "build:ext": "cd extension && bun run build",
@@ -47059,10 +46951,11 @@ var package_default = {
47059
46951
  },
47060
46952
  dependencies: {
47061
46953
  "@anthropic-ai/sdk": "^0.52.0",
47062
- "@hasna/browser": "^0.4.5",
46954
+ "@hasna/browser": "^0.4.12",
47063
46955
  "@hasna/cloud": "^0.1.24",
47064
46956
  "@hasna/contacts": "^0.6.8",
47065
46957
  "@hasna/projects": "^0.1.42",
46958
+ "@hasna/sandboxes": "^0.1.27",
47066
46959
  "@modelcontextprotocol/sdk": "^1.12.1",
47067
46960
  ai: "^6.0.175",
47068
46961
  chalk: "^5.4.1",
@@ -47596,11 +47489,11 @@ function resolveJudgeModel(config) {
47596
47489
  apiKey = process.env["GOOGLE_API_KEY"];
47597
47490
  else if (provider === "cerebras")
47598
47491
  apiKey = process.env["CEREBRAS_API_KEY"];
47492
+ else if (provider === "zai")
47493
+ apiKey = process.env["ZAI_API_KEY"];
47599
47494
  }
47600
47495
  if (!apiKey) {
47601
- apiKey = process.env["ANTHROPIC_API_KEY"] ?? process.env["CEREBRAS_API_KEY"] ?? process.env["OPENAI_API_KEY"] ?? process.env["GOOGLE_API_KEY"] ?? globalConfig.anthropicApiKey;
47602
- if (!apiKey)
47603
- throw new AIClientError("No API key found for judge. Set ANTHROPIC_API_KEY, CEREBRAS_API_KEY, OPENAI_API_KEY, or GOOGLE_API_KEY.");
47496
+ throw new AIClientError(`No API key found for ${provider} judge provider.`);
47604
47497
  }
47605
47498
  return { model, provider, apiKey };
47606
47499
  }
@@ -47615,11 +47508,11 @@ reason: 1-2 sentences max`;
47615
47508
  async function callJudge(prompt, config) {
47616
47509
  const { model, provider, apiKey } = resolveJudgeModel(config);
47617
47510
  const threshold = 0.7;
47618
- if (provider === "openai" || provider === "google" || provider === "cerebras") {
47619
- const baseUrl = provider === "openai" ? "https://api.openai.com/v1" : provider === "cerebras" ? "https://api.cerebras.ai/v1" : "https://generativelanguage.googleapis.com/v1beta/openai";
47511
+ if (provider !== "anthropic") {
47512
+ const compat = createOpenAICompatibleConfig(provider, apiKey);
47620
47513
  const resp2 = await callOpenAICompatible({
47621
- baseUrl,
47622
- apiKey,
47514
+ baseUrl: compat.baseUrl,
47515
+ apiKey: compat.apiKey,
47623
47516
  model,
47624
47517
  system: LLM_SYSTEM,
47625
47518
  messages: [{ role: "user", content: prompt }],
@@ -49216,12 +49109,348 @@ async function notifyRunToConversations(run, results, options) {
49216
49109
  } catch {}
49217
49110
  }
49218
49111
 
49112
+ // src/lib/a11y-audit.ts
49113
+ async function runA11yAudit(page, options = {}) {
49114
+ const { level = "AA", rules, exclude = [] } = options;
49115
+ await page.addScriptTag({ url: "https://cdnjs.cloudflare.com/ajax/libs/axe-core/4.9.1/axe.min.js" });
49116
+ const config = {
49117
+ runOnly: {
49118
+ type: level === "AAA" ? "standard" : "tag",
49119
+ values: level === "AAA" ? undefined : [level, "best-practice"]
49120
+ }
49121
+ };
49122
+ if (rules && rules.length > 0) {
49123
+ config.rules = Object.fromEntries(rules.map((r) => [r, { enabled: true }]));
49124
+ }
49125
+ if (exclude.length > 0) {
49126
+ config.exclude = exclude;
49127
+ }
49128
+ const result = await page.evaluate(async (auditConfig) => {
49129
+ const axeResult = await window.axe.run(auditConfig);
49130
+ return axeResult;
49131
+ }, config);
49132
+ const violations = (result.violations ?? []).map((v) => ({
49133
+ id: v.id,
49134
+ impact: v.impact,
49135
+ description: v.description,
49136
+ help: v.help,
49137
+ helpUrl: v.helpUrl,
49138
+ nodes: (v.nodes ?? []).map((n) => ({
49139
+ html: n.html,
49140
+ target: n.target,
49141
+ failureSummary: n.failureSummary
49142
+ }))
49143
+ }));
49144
+ const passes = (result.passes ?? []).map((p) => ({
49145
+ id: p.id,
49146
+ description: p.description
49147
+ }));
49148
+ const incomplete = (result.incomplete ?? []).map((i) => ({
49149
+ id: i.id,
49150
+ description: i.description,
49151
+ impact: i.impact
49152
+ }));
49153
+ const criticalCount = violations.filter((v) => v.impact === "critical").length;
49154
+ const seriousCount = violations.filter((v) => v.impact === "serious").length;
49155
+ const moderateCount = violations.filter((v) => v.impact === "moderate").length;
49156
+ const minorCount = violations.filter((v) => v.impact === "minor").length;
49157
+ return {
49158
+ violations,
49159
+ passes,
49160
+ incomplete,
49161
+ url: page.url(),
49162
+ timestamp: new Date().toISOString(),
49163
+ totalViolations: violations.length,
49164
+ criticalCount,
49165
+ seriousCount,
49166
+ moderateCount,
49167
+ minorCount
49168
+ };
49169
+ }
49170
+
49171
+ // src/lib/assertions.ts
49172
+ async function evaluateAssertions(page, assertions, context = {}) {
49173
+ const results = [];
49174
+ for (const assertion of assertions) {
49175
+ try {
49176
+ const result = await evaluateOne(page, assertion, context);
49177
+ results.push(result);
49178
+ } catch (err) {
49179
+ results.push({
49180
+ assertion,
49181
+ passed: false,
49182
+ actual: "",
49183
+ error: err instanceof Error ? err.message : String(err)
49184
+ });
49185
+ }
49186
+ }
49187
+ return results;
49188
+ }
49189
+ async function evaluateOne(page, assertion, context) {
49190
+ switch (assertion.type) {
49191
+ case "visible": {
49192
+ const visible = await page.locator(assertion.selector).isVisible();
49193
+ return {
49194
+ assertion,
49195
+ passed: visible,
49196
+ actual: String(visible)
49197
+ };
49198
+ }
49199
+ case "not_visible": {
49200
+ const visible = await page.locator(assertion.selector).isVisible();
49201
+ return {
49202
+ assertion,
49203
+ passed: !visible,
49204
+ actual: String(visible)
49205
+ };
49206
+ }
49207
+ case "text_contains": {
49208
+ const text = await page.locator(assertion.selector).textContent() ?? "";
49209
+ const expected = String(assertion.expected ?? "");
49210
+ return {
49211
+ assertion,
49212
+ passed: text.includes(expected),
49213
+ actual: text
49214
+ };
49215
+ }
49216
+ case "text_equals": {
49217
+ const text = await page.locator(assertion.selector).textContent() ?? "";
49218
+ const expected = String(assertion.expected ?? "");
49219
+ return {
49220
+ assertion,
49221
+ passed: text.trim() === expected.trim(),
49222
+ actual: text
49223
+ };
49224
+ }
49225
+ case "element_count": {
49226
+ const count = await page.locator(assertion.selector).count();
49227
+ const expected = Number(assertion.expected ?? 0);
49228
+ return {
49229
+ assertion,
49230
+ passed: count === expected,
49231
+ actual: String(count)
49232
+ };
49233
+ }
49234
+ case "no_console_errors": {
49235
+ if (context.consoleErrors !== undefined) {
49236
+ const errors2 = context.consoleErrors.filter(Boolean);
49237
+ return {
49238
+ assertion,
49239
+ passed: errors2.length === 0,
49240
+ actual: errors2.length === 0 ? "No console errors captured" : errors2.slice(0, 3).join(" | ")
49241
+ };
49242
+ }
49243
+ const errorElements = await page.locator('[role="alert"], .error, .error-message, [data-testid="error"]').count();
49244
+ return {
49245
+ assertion,
49246
+ passed: errorElements === 0,
49247
+ actual: `${errorElements} error element(s) found`
49248
+ };
49249
+ }
49250
+ case "no_a11y_violations": {
49251
+ try {
49252
+ const auditResult = await runA11yAudit(page);
49253
+ const hasIssues = auditResult.violations.length > 0;
49254
+ return {
49255
+ assertion,
49256
+ passed: !hasIssues,
49257
+ actual: hasIssues ? `${auditResult.totalViolations} violation(s): ${auditResult.violations.map((v) => v.id).join(", ")}` : "No accessibility violations found"
49258
+ };
49259
+ } catch (err) {
49260
+ return {
49261
+ assertion,
49262
+ passed: false,
49263
+ actual: "",
49264
+ error: err instanceof Error ? err.message : String(err)
49265
+ };
49266
+ }
49267
+ }
49268
+ case "url_contains": {
49269
+ const url = page.url();
49270
+ const expected = String(assertion.expected ?? "");
49271
+ return {
49272
+ assertion,
49273
+ passed: url.includes(expected),
49274
+ actual: url
49275
+ };
49276
+ }
49277
+ case "title_contains": {
49278
+ const title = await page.title();
49279
+ const expected = String(assertion.expected ?? "");
49280
+ return {
49281
+ assertion,
49282
+ passed: title.includes(expected),
49283
+ actual: title
49284
+ };
49285
+ }
49286
+ case "cookie_exists": {
49287
+ const cookieName = assertion.expected;
49288
+ const cookies = await page.context().cookies();
49289
+ const found = cookies.some((c) => c.name === cookieName);
49290
+ return {
49291
+ assertion,
49292
+ passed: found,
49293
+ actual: found ? `Cookie "${cookieName}" exists` : `Cookie "${cookieName}" not found`
49294
+ };
49295
+ }
49296
+ case "cookie_not_exists": {
49297
+ const cookieName = assertion.expected;
49298
+ const cookies = await page.context().cookies();
49299
+ const found = cookies.some((c) => c.name === cookieName);
49300
+ return {
49301
+ assertion,
49302
+ passed: !found,
49303
+ actual: found ? `Cookie "${cookieName}" found (unexpected)` : `Cookie "${cookieName}" does not exist`
49304
+ };
49305
+ }
49306
+ case "cookie_value": {
49307
+ const [cookieName, expectedValue] = assertion.expected.split("=", 2);
49308
+ const cookies = await page.context().cookies();
49309
+ const cookie = cookies.find((c) => c.name === cookieName);
49310
+ const actualValue = cookie?.value ?? "";
49311
+ return {
49312
+ assertion,
49313
+ passed: actualValue === expectedValue,
49314
+ actual: cookie ? `${cookieName}=${actualValue}` : `Cookie "${cookieName}" not found`
49315
+ };
49316
+ }
49317
+ case "local_storage_exists": {
49318
+ const key = assertion.expected;
49319
+ const value = await page.evaluate((k) => localStorage.getItem(k), key);
49320
+ return {
49321
+ assertion,
49322
+ passed: value !== null,
49323
+ actual: value !== null ? `Key "${key}" exists with value "${value}"` : `Key "${key}" not found in localStorage`
49324
+ };
49325
+ }
49326
+ case "local_storage_not_exists": {
49327
+ const key = assertion.expected;
49328
+ const value = await page.evaluate((k) => localStorage.getItem(k), key);
49329
+ return {
49330
+ assertion,
49331
+ passed: value === null,
49332
+ actual: value !== null ? `Key "${key}" exists (unexpected)` : `Key "${key}" does not exist in localStorage`
49333
+ };
49334
+ }
49335
+ case "local_storage_value": {
49336
+ const [lsKey, expectedValue] = assertion.expected.split("=", 2);
49337
+ const value = await page.evaluate((k) => localStorage.getItem(k), lsKey ?? "");
49338
+ return {
49339
+ assertion,
49340
+ passed: value === expectedValue,
49341
+ actual: value !== null ? `${lsKey}=${value}` : `Key "${lsKey}" not found in localStorage`
49342
+ };
49343
+ }
49344
+ case "session_storage_value": {
49345
+ const [ssKey, expectedValue] = assertion.expected.split("=", 2);
49346
+ const value = await page.evaluate((k) => sessionStorage.getItem(k), ssKey ?? "");
49347
+ return {
49348
+ assertion,
49349
+ passed: value === expectedValue,
49350
+ actual: value !== null ? `${ssKey}=${value}` : `Key "${ssKey}" not found in sessionStorage`
49351
+ };
49352
+ }
49353
+ case "session_storage_not_exists": {
49354
+ const key = assertion.expected;
49355
+ const value = await page.evaluate((k) => sessionStorage.getItem(k), key);
49356
+ return {
49357
+ assertion,
49358
+ passed: value === null,
49359
+ actual: value !== null ? `Key "${key}" exists (unexpected)` : `Key "${key}" does not exist in sessionStorage`
49360
+ };
49361
+ }
49362
+ default: {
49363
+ return {
49364
+ assertion,
49365
+ passed: false,
49366
+ actual: "",
49367
+ error: `Unknown assertion type: ${assertion.type}`
49368
+ };
49369
+ }
49370
+ }
49371
+ }
49372
+ function allAssertionsPassed(results) {
49373
+ return results.every((r) => r.passed);
49374
+ }
49375
+ function formatAssertionResults(results) {
49376
+ if (results.length === 0)
49377
+ return "No assertions.";
49378
+ const lines = [];
49379
+ for (const r of results) {
49380
+ const icon = r.passed ? "PASS" : "FAIL";
49381
+ const desc = r.assertion.description || `${r.assertion.type}${r.assertion.selector ? ` ${r.assertion.selector}` : ""}`;
49382
+ let line = ` [${icon}] ${desc}`;
49383
+ if (!r.passed) {
49384
+ line += ` (actual: ${r.actual})`;
49385
+ if (r.error)
49386
+ line += ` \u2014 ${r.error}`;
49387
+ }
49388
+ lines.push(line);
49389
+ }
49390
+ const passed = results.filter((r) => r.passed).length;
49391
+ lines.push(`
49392
+ ${passed}/${results.length} assertions passed.`);
49393
+ return lines.join(`
49394
+ `);
49395
+ }
49396
+
49219
49397
  // src/lib/runner.ts
49220
49398
  var eventHandler = null;
49221
49399
  function emit(event) {
49222
49400
  if (eventHandler)
49223
49401
  eventHandler(event);
49224
49402
  }
49403
+ function resolveAgentApiKeyForModel(model, explicitApiKey, configuredAnthropicApiKey) {
49404
+ return resolveProviderApiKeyForModel(model, explicitApiKey, configuredAnthropicApiKey);
49405
+ }
49406
+ function assertionDescription(result) {
49407
+ return result.assertion.description || `${result.assertion.type}${result.assertion.selector ? ` ${result.assertion.selector}` : ""}`;
49408
+ }
49409
+ function summarizeAssertionResult(result) {
49410
+ const description = assertionDescription(result);
49411
+ if (result.passed)
49412
+ return description;
49413
+ const suffix = result.error ? `; ${result.error}` : "";
49414
+ return `${description} (actual: ${result.actual}${suffix})`;
49415
+ }
49416
+ async function applyStructuredAssertionsToResult(input) {
49417
+ const assertions = input.scenario.assertions ?? [];
49418
+ if (assertions.length === 0) {
49419
+ return {
49420
+ status: input.status,
49421
+ reasoning: input.reasoning,
49422
+ assertionsPassed: [],
49423
+ assertionsFailed: [],
49424
+ assertionResults: []
49425
+ };
49426
+ }
49427
+ const results = await evaluateAssertions(input.page, assertions, {
49428
+ consoleErrors: input.consoleErrors
49429
+ });
49430
+ const assertionsPassed = results.filter((r) => r.passed).map(summarizeAssertionResult);
49431
+ const assertionsFailed = results.filter((r) => !r.passed).map(summarizeAssertionResult);
49432
+ const assertionResults = results.map((result) => ({
49433
+ type: result.assertion.type,
49434
+ description: assertionDescription(result),
49435
+ passed: result.passed,
49436
+ actual: result.actual,
49437
+ ...result.error ? { error: result.error } : {}
49438
+ }));
49439
+ const assertionsOk = allAssertionsPassed(results);
49440
+ const status = assertionsOk || input.status !== "passed" ? input.status : "failed";
49441
+ const assertionHeading = assertionsOk ? "Structured assertions passed:" : "Structured assertions failed:";
49442
+ const reasoningParts = [input.reasoning, `${assertionHeading}
49443
+ ${formatAssertionResults(results)}`].map((part) => part.trim()).filter(Boolean);
49444
+ return {
49445
+ status,
49446
+ reasoning: reasoningParts.join(`
49447
+
49448
+ `),
49449
+ assertionsPassed,
49450
+ assertionsFailed,
49451
+ assertionResults
49452
+ };
49453
+ }
49225
49454
  function withTimeout(promise, ms, label) {
49226
49455
  return new Promise((resolve, reject) => {
49227
49456
  const warningAt = Math.floor(ms * 0.8);
@@ -49282,7 +49511,7 @@ async function runSingleScenario(scenario, runId, options) {
49282
49511
  });
49283
49512
  }
49284
49513
  }
49285
- const client = createClientForModel(model, effectiveOptions.apiKey ?? config.anthropicApiKey);
49514
+ const client = createClientForModel(model, resolveAgentApiKeyForModel(model, effectiveOptions.apiKey, config.anthropicApiKey));
49286
49515
  const screenshotter = new Screenshotter({
49287
49516
  baseDir: effectiveOptions.screenshotDir ?? config.screenshots.dir
49288
49517
  });
@@ -49392,6 +49621,7 @@ async function runSingleScenario(scenario, runId, options) {
49392
49621
  model,
49393
49622
  runId,
49394
49623
  sessionId: result.id,
49624
+ baseUrl: options.url,
49395
49625
  maxTurns: effectiveOptions.minimal ? 10 : 30,
49396
49626
  a11y: effectiveOptions.a11y,
49397
49627
  persona: persona ? {
@@ -49474,27 +49704,46 @@ async function runSingleScenario(scenario, runId, options) {
49474
49704
  closeSession(result.id);
49475
49705
  const lightpandaNote = options.engine === "lightpanda" ? " (Running with Lightpanda \u2014 no screenshots)" : options.engine === "bun" ? " (Running with Bun.WebView \u2014 native, ~11x faster)" : "";
49476
49706
  const networkMeta = networkErrors.length > 0 ? { networkErrors: networkErrors.slice(0, 20) } : {};
49477
- let updatedResult = updateResult(result.id, {
49707
+ const baseReasoning = agentResult.reasoning ? agentResult.reasoning + lightpandaNote : lightpandaNote || "";
49708
+ const assertionOutcome = await applyStructuredAssertionsToResult({
49709
+ page,
49710
+ scenario,
49711
+ consoleErrors,
49478
49712
  status: agentResult.status,
49479
- reasoning: agentResult.reasoning ? agentResult.reasoning + lightpandaNote : lightpandaNote || undefined,
49713
+ reasoning: baseReasoning
49714
+ });
49715
+ const structuredAssertionMeta = assertionOutcome.assertionResults.length > 0 ? {
49716
+ structuredAssertions: {
49717
+ passed: assertionOutcome.assertionsPassed,
49718
+ failed: assertionOutcome.assertionsFailed,
49719
+ results: assertionOutcome.assertionResults
49720
+ }
49721
+ } : {};
49722
+ let updatedResult = updateResult(result.id, {
49723
+ status: assertionOutcome.status,
49724
+ reasoning: assertionOutcome.reasoning || undefined,
49480
49725
  stepsCompleted: agentResult.stepsCompleted,
49481
49726
  durationMs: Date.now() - new Date(result.createdAt).getTime(),
49482
49727
  tokensUsed: agentResult.tokensUsed,
49483
49728
  costCents: estimateCost(model, agentResult.tokensUsed),
49484
- metadata: { consoleLogs, ...networkErrors.length > 0 ? networkMeta : {} }
49729
+ metadata: {
49730
+ consoleLogs,
49731
+ ...networkErrors.length > 0 ? networkMeta : {},
49732
+ ...structuredAssertionMeta
49733
+ }
49485
49734
  });
49486
- if (agentResult.status === "failed" || agentResult.status === "error") {
49487
- const failureAnalysis = analyzeFailure(null, agentResult.reasoning ?? null);
49735
+ if (assertionOutcome.status === "failed" || assertionOutcome.status === "error") {
49736
+ const failureAnalysis = analyzeFailure(null, assertionOutcome.reasoning ?? null);
49488
49737
  if (failureAnalysis) {
49489
49738
  updatedResult = updateResult(result.id, { failureAnalysis });
49490
49739
  }
49491
49740
  }
49492
- if (agentResult.status === "passed") {
49741
+ if (assertionOutcome.status === "passed") {
49493
49742
  try {
49494
49743
  updateScenarioPassedCache(scenario.id, options.url);
49495
49744
  } catch {}
49496
49745
  }
49497
- const eventType = agentResult.status === "passed" ? "scenario:pass" : "scenario:fail";
49746
+ const eventType = assertionOutcome.status === "passed" ? "scenario:pass" : "scenario:fail";
49498
49747
  emit({ type: eventType, scenarioId: scenario.id, scenarioName: scenario.name, resultId: result.id, runId });
49499
49748
  return updatedResult;
49500
49749
  } catch (error) {
@@ -49519,7 +49768,8 @@ async function runSingleScenario(scenario, runId, options) {
49519
49768
  } finally {
49520
49769
  if (harPath) {
49521
49770
  try {
49522
- updateResult(result.id, { metadata: { harPath } });
49771
+ const existing = getResult(result.id);
49772
+ updateResult(result.id, { metadata: { ...existing?.metadata ?? {}, harPath } });
49523
49773
  } catch {}
49524
49774
  }
49525
49775
  if (browser) {
@@ -49691,22 +49941,31 @@ async function runBatch(scenarios, options) {
49691
49941
  }
49692
49942
  return { run: finalRun, results };
49693
49943
  }
49694
- async function runByFilter(options) {
49695
- let scenarios;
49944
+ function findScenarioInList(scenarios, id) {
49945
+ return scenarios.find((scenario) => scenario.id === id || scenario.shortId === id || scenario.id.startsWith(id)) ?? null;
49946
+ }
49947
+ function resolveScenariosForRun(options) {
49696
49948
  if (options.scenarioIds && options.scenarioIds.length > 0) {
49697
- const all = listScenarios({ projectId: options.projectId });
49698
- scenarios = all.filter((s) => options.scenarioIds.includes(s.id) || options.scenarioIds.includes(s.shortId));
49699
- if (scenarios.length === 0 && options.projectId) {
49700
- const global2 = listScenarios({});
49701
- scenarios = global2.filter((s) => options.scenarioIds.includes(s.id) || options.scenarioIds.includes(s.shortId));
49949
+ const scoped = listScenarios({ projectId: options.projectId });
49950
+ const resolved = [];
49951
+ const seen = new Set;
49952
+ for (const id of options.scenarioIds) {
49953
+ const scenario = findScenarioInList(scoped, id) ?? getScenario(id);
49954
+ if (scenario && !seen.has(scenario.id)) {
49955
+ resolved.push(scenario);
49956
+ seen.add(scenario.id);
49957
+ }
49702
49958
  }
49703
- } else {
49704
- scenarios = listScenarios({
49705
- projectId: options.projectId,
49706
- tags: options.tags,
49707
- priority: options.priority
49708
- });
49959
+ return resolved;
49709
49960
  }
49961
+ return listScenarios({
49962
+ projectId: options.projectId,
49963
+ tags: options.tags,
49964
+ priority: options.priority
49965
+ });
49966
+ }
49967
+ async function runByFilter(options) {
49968
+ const scenarios = resolveScenariosForRun(options);
49710
49969
  if (scenarios.length === 0) {
49711
49970
  const config = loadConfig();
49712
49971
  const model = resolveModel(options.model ?? config.defaultModel);
@@ -50870,18 +51129,7 @@ function normalizeFilter(input) {
50870
51129
  };
50871
51130
  }
50872
51131
  function normalizeExecution(input) {
50873
- const target = input?.target ?? "local";
50874
- if (target === "connector:e2b") {
50875
- return {
50876
- target,
50877
- connector: input?.connector ?? "e2b",
50878
- operation: input?.operation ?? "run",
50879
- sandboxTemplate: input?.sandboxTemplate,
50880
- timeoutMs: input?.timeoutMs,
50881
- env: input?.env
50882
- };
50883
- }
50884
- return { ...DEFAULT_EXECUTION, timeoutMs: input?.timeoutMs };
51132
+ return input ? workflowExecutionFromValue(input) : DEFAULT_EXECUTION;
50885
51133
  }
50886
51134
  function createTestingWorkflow(input) {
50887
51135
  const db2 = getDatabase();
@@ -50980,6 +51228,10 @@ function db2() {
50980
51228
  }
50981
51229
 
50982
51230
  // src/lib/workflow-runner.ts
51231
+ init_database();
51232
+ import { mkdtempSync, rmSync, writeFileSync as writeFileSync3 } from "fs";
51233
+ import { tmpdir } from "os";
51234
+ import { join as join13 } from "path";
50983
51235
  function buildWorkflowRunPlan(workflow, options) {
50984
51236
  const runOptions = {
50985
51237
  url: options.url,
@@ -50996,10 +51248,10 @@ function buildWorkflowRunPlan(workflow, options) {
50996
51248
  return {
50997
51249
  workflow,
50998
51250
  runOptions,
50999
- connectorCommand: workflow.execution.target === "connector:e2b" ? buildConnectorCommand(workflow.execution, runOptions) : null
51251
+ sandbox: workflow.execution.target === "sandbox" ? buildSandboxPlan(workflow, workflow.execution, runOptions) : null
51000
51252
  };
51001
51253
  }
51002
- async function runTestingWorkflow(workflowId, options) {
51254
+ async function runTestingWorkflow(workflowId, options, dependencies = {}) {
51003
51255
  const workflow = getTestingWorkflow(workflowId);
51004
51256
  if (!workflow)
51005
51257
  throw new Error(`Testing workflow not found: ${workflowId}`);
@@ -51009,13 +51261,25 @@ async function runTestingWorkflow(workflowId, options) {
51009
51261
  const plan = buildWorkflowRunPlan(workflow, options);
51010
51262
  if (options.dryRun)
51011
51263
  return { run: null, results: [], plan };
51012
- if (workflow.execution.target === "connector:e2b") {
51013
- const connectorResult = await runViaConnector(plan);
51014
- return { run: null, results: [], plan, connectorResult };
51264
+ if (workflow.execution.target === "sandbox") {
51265
+ const sandboxResult = await runViaSandbox(plan, dependencies);
51266
+ return { run: null, results: [], plan, sandboxResult };
51015
51267
  }
51016
- const { run, results } = await runByFilter(plan.runOptions);
51268
+ const runLocal = dependencies.runByFilter ?? runByFilter;
51269
+ const { run, results } = await runLocal(plan.runOptions);
51017
51270
  return { run, results, plan };
51018
51271
  }
51272
+ function createWorkflowDatabaseBundle(workflow, plan) {
51273
+ if (!plan.sandbox)
51274
+ throw new Error(`Workflow is not configured for sandbox execution: ${workflow.name}`);
51275
+ const localDir = mkdtempSync(join13(tmpdir(), `testers-workflow-${workflow.id.slice(0, 8)}-`));
51276
+ writeFileSync3(join13(localDir, "testers.db"), getDatabase().serialize());
51277
+ return {
51278
+ localDir,
51279
+ remoteDir: plan.sandbox.stateRemoteDir,
51280
+ cleanup: () => rmSync(localDir, { recursive: true, force: true })
51281
+ };
51282
+ }
51019
51283
  function validatePersonaIds(workflow) {
51020
51284
  for (const personaId of workflow.personaIds) {
51021
51285
  if (!getPersona(personaId)) {
@@ -51023,46 +51287,109 @@ function validatePersonaIds(workflow) {
51023
51287
  }
51024
51288
  }
51025
51289
  }
51026
- function buildConnectorCommand(execution, runOptions) {
51027
- const connector = execution.connector ?? "e2b";
51028
- const operation = execution.operation ?? "run";
51029
- const payload = JSON.stringify({
51030
- operation,
51031
- template: execution.sandboxTemplate,
51290
+ function buildSandboxPlan(workflow, execution, runOptions) {
51291
+ const remoteDir = execution.sandboxRemoteDir ?? `/tmp/testers-workflow-${workflow.id.slice(0, 8)}`;
51292
+ const stateRemoteDir = `${remoteDir.replace(/\/+$/, "")}/.testers-state`;
51293
+ return {
51294
+ provider: execution.provider,
51295
+ image: execution.sandboxImage,
51296
+ name: `testers-${workflow.id.slice(0, 8)}`,
51297
+ remoteDir,
51298
+ stateRemoteDir,
51299
+ cleanup: execution.sandboxCleanup ?? "delete",
51032
51300
  timeoutMs: execution.timeoutMs,
51033
- env: execution.env ?? {},
51034
- command: [
51035
- "bunx",
51036
- "@hasna/testers",
51037
- "run",
51038
- runOptions.url,
51039
- ...runOptions.scenarioIds?.length ? ["--scenario", runOptions.scenarioIds.join(",")] : [],
51040
- ...runOptions.tags?.length ? runOptions.tags.flatMap((tag) => ["--tag", tag]) : [],
51041
- ...runOptions.priority ? ["--priority", runOptions.priority] : [],
51042
- ...runOptions.projectId ? ["--project", runOptions.projectId] : [],
51043
- ...runOptions.model ? ["--model", runOptions.model] : [],
51044
- "--json"
51045
- ]
51046
- });
51047
- return ["connectors", "run", connector, operation, payload];
51301
+ env: execution.env,
51302
+ command: buildSandboxCommand({
51303
+ runOptions,
51304
+ remoteDir,
51305
+ dbPath: `${stateRemoteDir}/testers.db`,
51306
+ setupCommand: execution.setupCommand,
51307
+ packageSpec: execution.packageSpec ?? "@hasna/testers"
51308
+ })
51309
+ };
51048
51310
  }
51049
- async function runViaConnector(plan) {
51050
- if (!plan.connectorCommand)
51051
- throw new Error("Workflow does not have a connector command");
51052
- const proc = Bun.spawn(plan.connectorCommand, {
51053
- stdout: "pipe",
51054
- stderr: "pipe",
51055
- env: process.env
51056
- });
51057
- const [stdout, stderr, exitCode] = await Promise.all([
51058
- new Response(proc.stdout).text(),
51059
- new Response(proc.stderr).text(),
51060
- proc.exited
51061
- ]);
51062
- if (exitCode !== 0) {
51063
- throw new Error(`Connector execution failed (${exitCode}): ${stderr || stdout}`);
51311
+ function buildSandboxCommand(input) {
51312
+ const args = [
51313
+ "bunx",
51314
+ input.packageSpec,
51315
+ "run",
51316
+ input.runOptions.url,
51317
+ ...input.runOptions.scenarioIds?.length ? ["--scenario", input.runOptions.scenarioIds.join(",")] : [],
51318
+ ...input.runOptions.tags?.length ? input.runOptions.tags.flatMap((tag) => ["--tag", tag]) : [],
51319
+ ...input.runOptions.priority ? ["--priority", input.runOptions.priority] : [],
51320
+ ...input.runOptions.projectId ? ["--project", input.runOptions.projectId] : [],
51321
+ ...input.runOptions.model ? ["--model", input.runOptions.model] : [],
51322
+ ...input.runOptions.headed ? ["--headed"] : [],
51323
+ ...input.runOptions.parallel ? ["--parallel", String(input.runOptions.parallel)] : [],
51324
+ ...input.runOptions.timeout ? ["--timeout", String(input.runOptions.timeout)] : [],
51325
+ ...input.runOptions.personaIds?.length ? ["--persona", input.runOptions.personaIds.join(",")] : [],
51326
+ "--no-auto-generate",
51327
+ "--json"
51328
+ ];
51329
+ return [
51330
+ "set -euo pipefail",
51331
+ `mkdir -p ${shellQuote(input.remoteDir)}`,
51332
+ `cd ${shellQuote(input.remoteDir)}`,
51333
+ input.setupCommand,
51334
+ `HASNA_TESTERS_DB_PATH=${shellQuote(input.dbPath)} ${args.map(shellQuote).join(" ")}`
51335
+ ].filter(Boolean).join(`
51336
+ `);
51337
+ }
51338
+ async function runViaSandbox(plan, dependencies) {
51339
+ if (!plan.sandbox)
51340
+ throw new Error("Workflow does not have a sandbox plan");
51341
+ const sandboxes = await resolveSandboxesRuntime(dependencies);
51342
+ const createBundle = dependencies.createDatabaseBundle ?? createWorkflowDatabaseBundle;
51343
+ const bundle = createBundle(plan.workflow, plan);
51344
+ try {
51345
+ const raw = await sandboxes.runCommandInSandbox({
51346
+ command: plan.sandbox.command,
51347
+ provider: plan.sandbox.provider,
51348
+ name: plan.sandbox.name,
51349
+ image: plan.sandbox.image,
51350
+ sandboxTimeout: plan.sandbox.timeoutMs,
51351
+ commandTimeoutMs: plan.sandbox.timeoutMs,
51352
+ projectId: plan.workflow.projectId ?? undefined,
51353
+ config: {
51354
+ source: "testers",
51355
+ workflowId: plan.workflow.id,
51356
+ workflowName: plan.workflow.name
51357
+ },
51358
+ sandboxEnvVars: plan.sandbox.env,
51359
+ cleanup: plan.sandbox.cleanup,
51360
+ upload: {
51361
+ localDir: bundle.localDir,
51362
+ remoteDir: bundle.remoteDir
51363
+ }
51364
+ });
51365
+ const exitCode = raw.result.exit_code ?? raw.result.exitCode ?? 0;
51366
+ const stdout = raw.result.stdout ?? "";
51367
+ const stderr = raw.result.stderr ?? "";
51368
+ if (exitCode !== 0) {
51369
+ throw new Error(`Sandbox workflow execution failed (${exitCode}): ${stderr || stdout}`);
51370
+ }
51371
+ return {
51372
+ sandboxId: raw.sandbox.id,
51373
+ sessionId: raw.session.id,
51374
+ exitCode,
51375
+ stdout,
51376
+ stderr,
51377
+ cleanup: raw.cleanup
51378
+ };
51379
+ } finally {
51380
+ bundle.cleanup?.();
51064
51381
  }
51065
- return stdout.trim();
51382
+ }
51383
+ async function resolveSandboxesRuntime(dependencies) {
51384
+ if (dependencies.sandboxes)
51385
+ return dependencies.sandboxes;
51386
+ if (dependencies.createSandboxesSDK)
51387
+ return dependencies.createSandboxesSDK();
51388
+ const mod = await import("@hasna/sandboxes");
51389
+ return mod.createSandboxesSDK();
51390
+ }
51391
+ function shellQuote(value) {
51392
+ return `'${value.replaceAll("'", `'"'"'`)}'`;
51066
51393
  }
51067
51394
 
51068
51395
  // src/lib/workflow-agent.ts
@@ -51414,10 +51741,16 @@ var WorkflowFilterSchema = exports_external.object({
51414
51741
  priority: exports_external.enum(["low", "medium", "high", "critical"]).optional()
51415
51742
  }).optional();
51416
51743
  var WorkflowExecutionSchema = exports_external.object({
51417
- target: exports_external.enum(["local", "connector:e2b"]).default("local"),
51744
+ target: exports_external.enum(["local", "sandbox", "connector:e2b"]).default("local"),
51418
51745
  connector: exports_external.string().optional(),
51419
51746
  operation: exports_external.string().optional(),
51747
+ provider: exports_external.string().optional(),
51748
+ sandboxImage: exports_external.string().optional(),
51749
+ sandboxRemoteDir: exports_external.string().optional(),
51750
+ sandboxCleanup: exports_external.enum(["delete", "stop", "keep"]).optional(),
51420
51751
  sandboxTemplate: exports_external.string().optional(),
51752
+ setupCommand: exports_external.string().optional(),
51753
+ packageSpec: exports_external.string().optional(),
51421
51754
  timeoutMs: exports_external.number().int().positive().optional(),
51422
51755
  env: exports_external.record(exports_external.string()).optional()
51423
51756
  }).optional();
@@ -51499,7 +51832,7 @@ async function handleRequest(req) {
51499
51832
  if (pathname === "/api/status" && method === "GET") {
51500
51833
  const config2 = loadConfig();
51501
51834
  getDatabase();
51502
- const dbPath = process.env["HASNA_TESTERS_DB_PATH"] ?? process.env["TESTERS_DB_PATH"] ?? join13(getTestersDir(), "testers.db");
51835
+ const dbPath = process.env["HASNA_TESTERS_DB_PATH"] ?? process.env["TESTERS_DB_PATH"] ?? join14(getTestersDir(), "testers.db");
51503
51836
  const scenarios = listScenarios();
51504
51837
  const runs = listRuns();
51505
51838
  return jsonResponse({
@@ -52229,7 +52562,7 @@ async function handleRequest(req) {
52229
52562
  return jsonResponse({ routes, apiRoutes, totalCovered: coverageMap.size });
52230
52563
  }
52231
52564
  if (!pathname.startsWith("/api")) {
52232
- const dashboardDir = join13(import.meta.dir, "..", "..", "dashboard", "dist");
52565
+ const dashboardDir = join14(import.meta.dir, "..", "..", "dashboard", "dist");
52233
52566
  if (!existsSync10(dashboardDir)) {
52234
52567
  return new Response(`<!DOCTYPE html>
52235
52568
  <html>
@@ -52248,7 +52581,7 @@ async function handleRequest(req) {
52248
52581
  }
52249
52582
  });
52250
52583
  }
52251
- const filePath = join13(dashboardDir, pathname === "/" ? "index.html" : pathname);
52584
+ const filePath = join14(dashboardDir, pathname === "/" ? "index.html" : pathname);
52252
52585
  if (existsSync10(filePath)) {
52253
52586
  const file2 = Bun.file(filePath);
52254
52587
  return new Response(file2, {
@@ -52258,7 +52591,7 @@ async function handleRequest(req) {
52258
52591
  }
52259
52592
  });
52260
52593
  }
52261
- const indexPath = join13(dashboardDir, "index.html");
52594
+ const indexPath = join14(dashboardDir, "index.html");
52262
52595
  if (existsSync10(indexPath)) {
52263
52596
  const file2 = Bun.file(indexPath);
52264
52597
  return new Response(file2, {