droid-patch 0.13.0 → 0.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as removeAlias, d as listAllMetadata, f as loadAliasMetadata, i as listAliases, l as createMetadata, m as patchDroid, n as createAlias, o as removeAliasesByFilter, p as saveAliasMetadata, r as createAliasForWrapper, t as clearAllAliases, u as formatPatches } from "./alias-hvk8y5gC.mjs";
2
+ import { a as removeAlias, d as listAllMetadata, f as loadAliasMetadata, i as listAliases, l as createMetadata, m as patchDroid, n as createAlias, o as removeAliasesByFilter, p as saveAliasMetadata, r as createAliasForWrapper, t as clearAllAliases, u as formatPatches } from "./alias-12JqnRQZ.mjs";
3
3
  import bin from "tiny-bin";
4
4
  import { styleText } from "node:util";
5
5
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
@@ -14,12 +14,12 @@ import { createInterface } from "node:readline/promises";
14
14
  /**
15
15
  * WebSearch External Providers Mode (--websearch)
16
16
  *
17
- * Priority: Smithery Exa > Google PSE > Serper > Brave > SearXNG > DuckDuckGo
17
+ * Priority: Smithery Exa > Google PSE > Tavily > Serper > Brave > SearXNG > DuckDuckGo
18
18
  */
19
19
  function generateSearchProxyServerCode() {
20
20
  return `#!/usr/bin/env node
21
21
  // Droid WebSearch Proxy Server (External Providers Mode)
22
- // Priority: Smithery Exa > Google PSE > Serper > Brave > SearXNG > DuckDuckGo
22
+ // Priority: Smithery Exa > Google PSE > Tavily > Serper > Brave > SearXNG > DuckDuckGo
23
23
 
24
24
  const http = require('http');
25
25
  const https = require('https');
@@ -75,6 +75,30 @@ async function searchGooglePSE(query, numResults) {
75
75
  return null;
76
76
  }
77
77
 
78
+ async function searchTavily(query, numResults) {
79
+ const apiKey = process.env.TAVILY_API_KEY;
80
+ if (!apiKey) return null;
81
+ try {
82
+ const bodyStr = JSON.stringify({
83
+ api_key: apiKey,
84
+ query: query,
85
+ max_results: numResults,
86
+ search_depth: 'basic',
87
+ include_answer: false,
88
+ include_images: false,
89
+ include_raw_content: false
90
+ }).replace(/'/g, "'\\\\''");
91
+ const curlCmd = 'curl -s "https://api.tavily.com/search" -H "Content-Type: application/json" -d \\'' + bodyStr + "\\'";
92
+ const data = JSON.parse(execSync(curlCmd, { encoding: 'utf-8', timeout: 15000 }));
93
+ if (data && Array.isArray(data.results) && data.results.length > 0) {
94
+ return data.results.slice(0, numResults).map(function(item) {
95
+ return { title: item.title || '', url: item.url || '', content: item.content || item.snippet || item.raw_content || '' };
96
+ });
97
+ }
98
+ } catch (e) { log('Tavily failed:', e.message); }
99
+ return null;
100
+ }
101
+
78
102
  async function searchSerper(query, numResults) {
79
103
  const apiKey = process.env.SERPER_API_KEY;
80
104
  if (!apiKey) return null;
@@ -144,13 +168,16 @@ async function search(query, numResults) {
144
168
  numResults = numResults || 10;
145
169
  log('Search:', query);
146
170
 
147
- // Priority: Smithery > Google PSE > Serper > Brave > SearXNG > DuckDuckGo
171
+ // Priority: Smithery > Google PSE > Tavily > Serper > Brave > SearXNG > DuckDuckGo
148
172
  var results = await searchSmitheryExa(query, numResults);
149
173
  if (results && results.length > 0) return { results: results, source: 'smithery-exa' };
150
174
 
151
175
  results = await searchGooglePSE(query, numResults);
152
176
  if (results && results.length > 0) return { results: results, source: 'google-pse' };
153
177
 
178
+ results = await searchTavily(query, numResults);
179
+ if (results && results.length > 0) return { results: results, source: 'tavily' };
180
+
154
181
  results = await searchSerper(query, numResults);
155
182
  if (results && results.length > 0) return { results: results, source: 'serper' };
156
183
 
@@ -1057,7 +1084,7 @@ function findDefaultDroidPath() {
1057
1084
  for (const p of paths) if (existsSync(p)) return p;
1058
1085
  return join(home, ".droid", "bin", "droid");
1059
1086
  }
1060
- bin("droid-patch", "CLI tool to patch droid binary with various modifications").package("droid-patch", version).option("--is-custom", "Patch isCustom:!0 to isCustom:!1 (enable context compression for custom models)").option("--skip-login", "Inject a fake FACTORY_API_KEY to bypass login requirement (no real key needed)").option("--api-base <url>", "Replace API URL (standalone: binary patch, max 22 chars; with --websearch: proxy forward target, no limit)").option("--websearch", "Enable local WebSearch proxy with external providers (Smithery, Google PSE, etc.)").option("--websearch-proxy", "Enable native provider websearch (requires proxy plugin, reads ~/.factory/settings.json)").option("--standalone", "Standalone mode: mock non-LLM Factory APIs (use with --websearch)").option("--reasoning-effort", "Enable reasoning effort for custom models (set to high, enable UI selector)").option("--disable-telemetry", "Disable telemetry and Sentry error reporting (block data uploads)").option("--spec-model-custom", "Enable custom models as spec model (show in UI selector + bypass validation)").option("--dry-run", "Verify patches without actually modifying the binary").option("-p, --path <path>", "Path to the droid binary").option("-o, --output <dir>", "Output directory for patched binary").option("--no-backup", "Do not create backup of original binary").option("-v, --verbose", "Enable verbose output").argument("[alias]", "Alias name for the patched binary").action(async (options, args) => {
1087
+ bin("droid-patch", "CLI tool to patch droid binary with various modifications").package("droid-patch", version).option("--is-custom", "Patch isCustom:!0 to isCustom:!1 (enable context compression for custom models)").option("--skip-login", "Inject a fake FACTORY_API_KEY to bypass login requirement (no real key needed)").option("--api-base <url>", "Replace API URL (standalone: binary patch, max 22 chars; with --websearch: proxy forward target, no limit)").option("--websearch", "Enable local WebSearch proxy with external providers (Smithery, Google PSE, etc.)").option("--websearch-proxy", "Enable native provider websearch (requires proxy plugin, reads ~/.factory/settings.json)").option("--standalone", "Standalone mode: mock non-LLM Factory APIs (use with --websearch)").option("--reasoning-effort", "Enable reasoning effort for custom models (set to high, enable UI selector)").option("--disable-telemetry", "Disable telemetry and Sentry error reporting (block data uploads)").option("--dry-run", "Verify patches without actually modifying the binary").option("-p, --path <path>", "Path to the droid binary").option("-o, --output <dir>", "Output directory for patched binary").option("--no-backup", "Do not create backup of original binary").option("-v, --verbose", "Enable verbose output").argument("[alias]", "Alias name for the patched binary").action(async (options, args) => {
1061
1088
  const alias = args?.[0];
1062
1089
  const isCustom = options["is-custom"];
1063
1090
  const skipLogin = options["skip-login"];
@@ -1068,14 +1095,13 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1068
1095
  const websearchTarget = websearch ? apiBase || "https://api.factory.ai" : void 0;
1069
1096
  const reasoningEffort = options["reasoning-effort"];
1070
1097
  const noTelemetry = options["disable-telemetry"];
1071
- const specModelCustom = options["spec-model-custom"];
1072
1098
  const dryRun = options["dry-run"];
1073
1099
  const path = options.path || findDefaultDroidPath();
1074
1100
  const outputDir = options.output;
1075
1101
  const backup = options.backup !== false;
1076
1102
  const verbose = options.verbose;
1077
1103
  const outputPath = outputDir && alias ? join(outputDir, alias) : void 0;
1078
- const needsBinaryPatch = !!isCustom || !!skipLogin || !!reasoningEffort || !!noTelemetry || !!specModelCustom || !!apiBase && !websearch && !websearchProxy;
1104
+ const needsBinaryPatch = !!isCustom || !!skipLogin || !!reasoningEffort || !!noTelemetry || !!apiBase && !websearch && !websearchProxy;
1079
1105
  if (websearch && websearchProxy) {
1080
1106
  console.log(styleText("red", "Error: Cannot use --websearch and --websearch-proxy together"));
1081
1107
  console.log(styleText("gray", "Choose one:"));
@@ -1157,14 +1183,16 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1157
1183
  console.log(styleText("gray", " 2. Google PSE:"));
1158
1184
  console.log(styleText("gray", " export GOOGLE_PSE_API_KEY=your_api_key"));
1159
1185
  console.log(styleText("gray", " export GOOGLE_PSE_CX=your_search_engine_id"));
1160
- console.log(styleText("gray", " 3-6. Serper, Brave, SearXNG, DuckDuckGo (fallbacks)"));
1186
+ console.log(styleText("gray", " 3. Tavily:"));
1187
+ console.log(styleText("gray", " export TAVILY_API_KEY=your_api_key"));
1188
+ console.log(styleText("gray", " 4-7. Serper, Brave, SearXNG, DuckDuckGo (fallbacks)"));
1161
1189
  console.log();
1162
1190
  console.log("Debug mode:");
1163
1191
  console.log(styleText("gray", " export DROID_SEARCH_DEBUG=1"));
1164
1192
  }
1165
1193
  return;
1166
1194
  }
1167
- if (!isCustom && !skipLogin && !apiBase && !websearch && !reasoningEffort && !noTelemetry && !specModelCustom) {
1195
+ if (!isCustom && !skipLogin && !apiBase && !websearch && !reasoningEffort && !noTelemetry) {
1168
1196
  console.log(styleText("yellow", "No patch flags specified. Available patches:"));
1169
1197
  console.log(styleText("gray", " --is-custom Patch isCustom for custom models"));
1170
1198
  console.log(styleText("gray", " --skip-login Bypass login by injecting a fake API key"));
@@ -1172,7 +1200,6 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1172
1200
  console.log(styleText("gray", " --websearch Enable local WebSearch proxy"));
1173
1201
  console.log(styleText("gray", " --reasoning-effort Set reasoning effort level for custom models"));
1174
1202
  console.log(styleText("gray", " --disable-telemetry Disable telemetry and Sentry error reporting"));
1175
- console.log(styleText("gray", " --spec-model-custom Enable custom models as spec model"));
1176
1203
  console.log(styleText("gray", " --standalone Standalone mode: mock non-LLM Factory APIs"));
1177
1204
  console.log();
1178
1205
  console.log("Usage examples:");
@@ -1284,24 +1311,6 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1284
1311
  replacement: Buffer.from("!0||this.webEvents.length")
1285
1312
  });
1286
1313
  }
1287
- if (specModelCustom) {
1288
- patches.push({
1289
- name: "specModelCustomUIShow",
1290
- description: "Show all custom models in spec model selector (bypass filter)",
1291
- pattern: Buffer.from(""),
1292
- replacement: Buffer.from(""),
1293
- regexPattern: /([A-Za-z_$])=([A-Za-z_$])\?([A-Za-z_$])\.filter\(\(([A-Za-z_$])\)=>\2\.includes\(\4\.id\)\):\3/g,
1294
- regexReplacement: "$1=0?$3.filter(($4)=>$2.includes($4.id)):$3"
1295
- });
1296
- patches.push({
1297
- name: "specModelCustomValidation",
1298
- description: "Bypass compatibilityGroup check for custom spec models",
1299
- pattern: Buffer.from(""),
1300
- replacement: Buffer.from(""),
1301
- regexPattern: /([A-Z])=([a-zA-Z_$][a-zA-Z0-9_$]*)\(A\),([A-Z])=\2\(R\);if\(\1&&\1!==\3\)\{/g,
1302
- regexReplacement: "$1=$2(A),$3=$2(R);if($3&&$1!==$3){"
1303
- });
1304
- }
1305
1314
  try {
1306
1315
  const result = await patchDroid({
1307
1316
  inputPath: path,
@@ -1359,8 +1368,7 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1359
1368
  websearchProxy: !!websearchProxy,
1360
1369
  reasoningEffort: !!reasoningEffort,
1361
1370
  noTelemetry: !!noTelemetry,
1362
- standalone: !!standalone,
1363
- specModelCustom: !!specModelCustom
1371
+ standalone: !!standalone
1364
1372
  }, {
1365
1373
  droidPatchVersion: version,
1366
1374
  droidVersion,
@@ -1381,7 +1389,7 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1381
1389
  }
1382
1390
  }).command("list", "List all droid-patch aliases").action(async () => {
1383
1391
  await listAliases();
1384
- }).command("remove", "Remove alias(es) by name or filter").argument("[alias-or-path]", "Alias name or file path to remove").option("--patch-version <version>", "Remove aliases created by this droid-patch version").option("--droid-version <version>", "Remove aliases for this droid version").option("--flag <flag>", "Remove aliases with this flag (is-custom, skip-login, websearch, api-base, reasoning-effort, disable-telemetry, standalone, spec-model-custom)").action(async (options, args) => {
1392
+ }).command("remove", "Remove alias(es) by name or filter").argument("[alias-or-path]", "Alias name or file path to remove").option("--patch-version <version>", "Remove aliases created by this droid-patch version").option("--droid-version <version>", "Remove aliases for this droid version").option("--flag <flag>", "Remove aliases with this flag (is-custom, skip-login, websearch, api-base, reasoning-effort, disable-telemetry, standalone)").action(async (options, args) => {
1385
1393
  const target = args?.[0];
1386
1394
  const patchVersion = options["patch-version"];
1387
1395
  const droidVersion = options["droid-version"];
@@ -1395,8 +1403,7 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1395
1403
  "api-base",
1396
1404
  "reasoning-effort",
1397
1405
  "disable-telemetry",
1398
- "standalone",
1399
- "spec-model-custom"
1406
+ "standalone"
1400
1407
  ];
1401
1408
  if (!allowedFlags.includes(flagRaw)) {
1402
1409
  console.error(styleText("red", `Error: Invalid --flag value: ${flagRaw}`));
@@ -1557,24 +1564,6 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1557
1564
  replacement: Buffer.from("!0||this.webEvents.length")
1558
1565
  });
1559
1566
  }
1560
- if (meta.patches.specModelCustom) {
1561
- patches.push({
1562
- name: "specModelCustomUIShow",
1563
- description: "Show all custom models in spec model selector (bypass filter)",
1564
- pattern: Buffer.from(""),
1565
- replacement: Buffer.from(""),
1566
- regexPattern: /([A-Za-z_$])=([A-Za-z_$])\?([A-Za-z_$])\.filter\(\(([A-Za-z_$])\)=>\2\.includes\(\4\.id\)\):\3/g,
1567
- regexReplacement: "$1=0?$3.filter(($4)=>$2.includes($4.id)):$3"
1568
- });
1569
- patches.push({
1570
- name: "specModelCustomValidation",
1571
- description: "Bypass compatibilityGroup check for custom spec models",
1572
- pattern: Buffer.from(""),
1573
- replacement: Buffer.from(""),
1574
- regexPattern: /([A-Z])=([a-zA-Z_$][a-zA-Z0-9_$]*)\(A\),([A-Z])=\2\(R\);if\(\1&&\1!==\3\)\{/g,
1575
- regexReplacement: "$1=$2(A),$3=$2(R);if($3&&$1!==$3){"
1576
- });
1577
- }
1578
1567
  const outputPath = join(join(homedir(), ".droid-patch", "bins"), `${meta.name}-patched`);
1579
1568
  if (patches.length > 0) {
1580
1569
  if (!(await patchDroid({