crosscheck-mcp 0.2.29 → 0.2.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/embed.cjs CHANGED
@@ -35,13 +35,18 @@ __export(embed_exports, {
35
35
  DEFAULT_EXCLUDED_PROVIDERS: () => DEFAULT_EXCLUDED_PROVIDERS,
36
36
  DEFAULT_FALLBACKS: () => DEFAULT_FALLBACKS,
37
37
  DEFAULT_MODELS: () => DEFAULT_MODELS,
38
+ IMAGE_MEDIA_TYPES: () => IMAGE_MEDIA_TYPES,
39
+ MAX_RUN_IMAGES: () => MAX_RUN_IMAGES,
40
+ SUPER_MODELS: () => SUPER_MODELS,
41
+ VISION_PROVIDERS: () => VISION_PROVIDERS,
38
42
  __KEY_ENV: () => KEY_ENV,
39
43
  __MODEL_ENV: () => MODEL_ENV,
40
44
  __test_internals: () => __test_internals,
41
45
  createEmbeddedEngine: () => createEmbeddedEngine,
42
46
  isAlive: () => isAlive,
43
47
  listProcesses: () => listProcesses,
44
- processRegistryPath: () => processRegistryPath
48
+ processRegistryPath: () => processRegistryPath,
49
+ withRunImages: () => withRunImages
45
50
  });
46
51
  module.exports = __toCommonJS(embed_exports);
47
52
 
@@ -50,7 +55,7 @@ var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${_
50
55
  var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
51
56
 
52
57
  // src/entrypoints/embed.ts
53
- var import_node_async_hooks2 = require("async_hooks");
58
+ var import_node_async_hooks3 = require("async_hooks");
54
59
  var import_node_fs16 = require("fs");
55
60
  var import_node_path15 = __toESM(require("path"), 1);
56
61
  var import_node_url2 = require("url");
@@ -222,6 +227,11 @@ function reasoningSharesOutputBudget(provider) {
222
227
  }
223
228
 
224
229
  // src/providers/types.ts
230
+ var IMAGE_MEDIA_TYPES = ["image/png", "image/jpeg", "image/webp", "image/gif"];
231
+ function imagesOf(m) {
232
+ if (m.role !== "user" || !Array.isArray(m.images)) return [];
233
+ return m.images.filter((i) => Boolean(i) && typeof i.data === "string" && i.data.length > 0 && IMAGE_MEDIA_TYPES.includes(i.mediaType));
234
+ }
225
235
  var ProviderError = class extends Error {
226
236
  name = "ProviderError";
227
237
  kind;
@@ -610,7 +620,12 @@ function buildAnthropicRequest(opts) {
610
620
  }
611
621
  continue;
612
622
  }
613
- convo.push({ role: m.role, content: typeof m.content === "string" ? m.content : "" });
623
+ const text = typeof m.content === "string" ? m.content : "";
624
+ const images = imagesOf(m);
625
+ convo.push(images.length ? { role: m.role, content: [
626
+ ...images.map((i) => ({ type: "image", source: { type: "base64", media_type: i.mediaType, data: i.data } })),
627
+ { type: "text", text }
628
+ ] } : { role: m.role, content: text });
614
629
  }
615
630
  const body = {
616
631
  model: opts.model,
@@ -850,7 +865,10 @@ function buildGeminiRequest(opts) {
850
865
  const role = m.role === "user" ? "user" : "model";
851
866
  contents.push({
852
867
  role,
853
- parts: [{ text: typeof m.content === "string" ? m.content : "" }]
868
+ parts: [
869
+ ...imagesOf(m).map((i) => ({ inline_data: { mime_type: i.mediaType, data: i.data } })),
870
+ { text: typeof m.content === "string" ? m.content : "" }
871
+ ]
854
872
  });
855
873
  }
856
874
  const body = {
@@ -1018,10 +1036,11 @@ function supportsNativeJsonSchema(provider, model) {
1018
1036
  return true;
1019
1037
  }
1020
1038
  function buildOpenAICompatibleRequest(opts) {
1021
- const msgs = opts.messages.map((m) => ({
1022
- role: m.role,
1023
- content: typeof m.content === "string" ? m.content : ""
1024
- }));
1039
+ const msgs = opts.messages.map((m) => {
1040
+ const text = typeof m.content === "string" ? m.content : "";
1041
+ const images = imagesOf(m);
1042
+ return images.length ? { role: m.role, content: [{ type: "text", text }, ...images.map((i) => ({ type: "image_url", image_url: { url: `data:${i.mediaType};base64,${i.data}` } }))] } : { role: m.role, content: text };
1043
+ });
1025
1044
  const body = {
1026
1045
  model: opts.model,
1027
1046
  messages: msgs
@@ -1334,7 +1353,7 @@ var import_zod = require("zod");
1334
1353
 
1335
1354
  // src/server-meta.ts
1336
1355
  var SERVER_NAME = "crosscheck-agent";
1337
- var SERVER_VERSION = true ? "0.2.29" : "0.0.0-dev";
1356
+ var SERVER_VERSION = true ? "0.2.30" : "0.0.0-dev";
1338
1357
 
1339
1358
  // src/tools/audit.ts
1340
1359
  var import_node_fs4 = require("fs");
@@ -4298,6 +4317,7 @@ async function pickAutoPanel(storage, purpose, n, providers, allowlist) {
4298
4317
  }
4299
4318
 
4300
4319
  // src/core/super-mode.ts
4320
+ var import_node_async_hooks = require("async_hooks");
4301
4321
  var SUPER_MODELS = {
4302
4322
  // Fable 5.1 verified present on the account; 5 as the fallback for accounts
4303
4323
  // that haven't been granted 5.1 yet.
@@ -4340,7 +4360,12 @@ function parseChain(v) {
4340
4360
  }
4341
4361
  return out;
4342
4362
  }
4343
- function superChainFor(provider, env = process.env) {
4363
+ var superEnvStore = new import_node_async_hooks.AsyncLocalStorage();
4364
+ function withSuperEnv(env, fn) {
4365
+ return superEnvStore.run(env, fn);
4366
+ }
4367
+ var currentEnv = () => superEnvStore.getStore() ?? process.env;
4368
+ function superChainFor(provider, env = currentEnv()) {
4344
4369
  const varName = SUPER_ENV_VARS[provider];
4345
4370
  const user = varName ? parseChain(env[varName]) : [];
4346
4371
  if (user.length > 0) {
@@ -4349,14 +4374,14 @@ function superChainFor(provider, env = process.env) {
4349
4374
  }
4350
4375
  return SUPER_MODELS[provider] ?? [];
4351
4376
  }
4352
- function superPrimary(provider, env = process.env) {
4377
+ function superPrimary(provider, env = currentEnv()) {
4353
4378
  return superChainFor(provider, env)[0];
4354
4379
  }
4355
4380
  var SUPER_PROVIDER_NAMES = Object.keys(SUPER_MODELS);
4356
4381
  function isSuperRequested(args) {
4357
4382
  return args["super"] === true;
4358
4383
  }
4359
- function retargetForSuper(p, env = process.env) {
4384
+ function retargetForSuper(p, env = currentEnv()) {
4360
4385
  const chain = superChainFor(p.name, env);
4361
4386
  if (chain.length === 0) return p;
4362
4387
  const [primary, ...fallbacks] = chain;
@@ -6427,9 +6452,9 @@ var import_node_path9 = __toESM(require("path"), 1);
6427
6452
  var import_node_perf_hooks6 = require("perf_hooks");
6428
6453
 
6429
6454
  // src/core/progress.ts
6430
- var import_node_async_hooks = require("async_hooks");
6455
+ var import_node_async_hooks2 = require("async_hooks");
6431
6456
  var import_node_perf_hooks5 = require("perf_hooks");
6432
- var progressStorage = new import_node_async_hooks.AsyncLocalStorage();
6457
+ var progressStorage = new import_node_async_hooks2.AsyncLocalStorage();
6433
6458
  async function withProgress(token, sendNotification, fn) {
6434
6459
  if (token === void 0 || token === null) {
6435
6460
  return fn();
@@ -11700,7 +11725,7 @@ var CHECK_INTERVAL_SECONDS = 3 * 24 * 60 * 60;
11700
11725
  var DEFAULT_PACKAGE = "crosscheck-cli";
11701
11726
  var FETCH_TIMEOUT_MS = 3e3;
11702
11727
  function engineVersion() {
11703
- return true ? "0.2.29" : "0.0.0-dev";
11728
+ return true ? "0.2.30" : "0.0.0-dev";
11704
11729
  }
11705
11730
  function defaultUpdateCachePath() {
11706
11731
  const base = process.env["CROSSCHECK_DATA_DIR"] || import_node_path12.default.join(import_node_os2.default.homedir() || import_node_os2.default.tmpdir(), ".crosscheck");
@@ -13493,7 +13518,33 @@ function vaultId(engineName) {
13493
13518
  }
13494
13519
  var ACTIVITY_TEXT_CAP = 8e3;
13495
13520
  var ASKED_CAP = 280;
13496
- var runContext = new import_node_async_hooks2.AsyncLocalStorage();
13521
+ var VISION_PROVIDERS = ["anthropic", "openai", "gemini", "grok"];
13522
+ var NO_IMAGE_PURPOSES = /* @__PURE__ */ new Set(["early_stop", "extract", "canary", "classify"]);
13523
+ var MAX_RUN_IMAGES = 8;
13524
+ function withRunImages(args, provider, images) {
13525
+ if (!images?.length || NO_IMAGE_PURPOSES.has(args.purpose ?? "")) return args;
13526
+ const msgs = [...args.messages];
13527
+ let idx = -1;
13528
+ for (let i = msgs.length - 1; i >= 0; i--) if (msgs[i]?.role === "user") {
13529
+ idx = i;
13530
+ break;
13531
+ }
13532
+ if (idx < 0) return args;
13533
+ const m = msgs[idx];
13534
+ if (VISION_PROVIDERS.includes(provider)) {
13535
+ msgs[idx] = { ...m, images: [...m.images ?? [], ...images] };
13536
+ } else {
13537
+ const n = images.length;
13538
+ msgs[idx] = {
13539
+ ...m,
13540
+ content: `${m.content}
13541
+
13542
+ [The user also attached ${n} image${n === 1 ? "" : "s"} that this model can't see. Don't guess at ${n === 1 ? "its" : "their"} contents \u2014 work from the text, and say so if the answer depends on ${n === 1 ? "it" : "them"}.]`
13543
+ };
13544
+ }
13545
+ return { ...args, messages: msgs };
13546
+ }
13547
+ var runContext = new import_node_async_hooks3.AsyncLocalStorage();
13497
13548
  var SYNTHESIS_PURPOSES = /* @__PURE__ */ new Set(["synth", "moderator", "recombine", "judge", "unify"]);
13498
13549
  function exemptFromSkip(ctx, provider, purpose) {
13499
13550
  return provider === ctx.moderator && SYNTHESIS_PURPOSES.has(purpose);
@@ -13548,7 +13599,7 @@ function withActivity(p) {
13548
13599
  if (!stopped && controller.signal.reason === "skip") stopped = "user";
13549
13600
  }, { once: true });
13550
13601
  try {
13551
- const res = await send({ ...args, signal: controller.signal });
13602
+ const res = await send({ ...withRunImages(args, provider, ctx.images), signal: controller.signal });
13552
13603
  const text = typeof res.text === "string" ? res.text : "";
13553
13604
  ctx.emit({
13554
13605
  type: "call.done",
@@ -13643,6 +13694,12 @@ function createEmbeddedEngine(opts) {
13643
13694
  const varName = MODEL_ENV[provider.trim().toLowerCase()];
13644
13695
  if (varName && model) env[varName] = model;
13645
13696
  }
13697
+ const superEnv = {};
13698
+ for (const [provider, model] of Object.entries(opts.superModels ?? {})) {
13699
+ const p = provider.trim().toLowerCase();
13700
+ const varName = SUPER_ENV_VARS[p === "grok" ? "xai" : p];
13701
+ if (varName && model) superEnv[varName] = model;
13702
+ }
13646
13703
  const pricingPath = [opts.pricingPath, bundledPricingPath()].find(
13647
13704
  (p) => Boolean(p) && (0, import_node_fs16.existsSync)(p)
13648
13705
  );
@@ -13683,13 +13740,14 @@ function createEmbeddedEngine(opts) {
13683
13740
  skipped: /* @__PURE__ */ new Set(),
13684
13741
  inflight: /* @__PURE__ */ new Map(),
13685
13742
  moderator: vaultId(moderator),
13686
- ...runOpts.callTimeoutMs && runOpts.callTimeoutMs > 0 ? { callTimeoutMs: runOpts.callTimeoutMs } : {}
13743
+ ...runOpts.callTimeoutMs && runOpts.callTimeoutMs > 0 ? { callTimeoutMs: runOpts.callTimeoutMs } : {},
13744
+ ...runOpts.images?.length ? { images: runOpts.images.filter((i) => IMAGE_MEDIA_TYPES.includes(i.mediaType) && typeof i.data === "string" && i.data.length > 0).slice(0, MAX_RUN_IMAGES) } : {}
13687
13745
  };
13688
13746
  liveRuns.set(runId, ctx);
13689
13747
  try {
13690
13748
  return await runContext.run(ctx, () => withProgress(runId, (n) => {
13691
13749
  if (n.params.message) emit({ type: "progress", runId, at: Date.now(), message: n.params.message });
13692
- }, () => runInner(name, args, runId, started, emit)));
13750
+ }, () => withSuperEnv(superEnv, () => runInner(name, args, runId, started, emit))));
13693
13751
  } finally {
13694
13752
  liveRuns.delete(runId);
13695
13753
  }
@@ -13848,12 +13906,17 @@ var __test_internals = { usageOf, textOf, errorOf, vaultId };
13848
13906
  DEFAULT_EXCLUDED_PROVIDERS,
13849
13907
  DEFAULT_FALLBACKS,
13850
13908
  DEFAULT_MODELS,
13909
+ IMAGE_MEDIA_TYPES,
13910
+ MAX_RUN_IMAGES,
13911
+ SUPER_MODELS,
13912
+ VISION_PROVIDERS,
13851
13913
  __KEY_ENV,
13852
13914
  __MODEL_ENV,
13853
13915
  __test_internals,
13854
13916
  createEmbeddedEngine,
13855
13917
  isAlive,
13856
13918
  listProcesses,
13857
- processRegistryPath
13919
+ processRegistryPath,
13920
+ withRunImages
13858
13921
  });
13859
13922
  //# sourceMappingURL=embed.cjs.map