agentaudit 3.9.38 → 3.9.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/cli.mjs +49 -4
  2. package/package.json +1 -1
package/cli.mjs CHANGED
@@ -537,6 +537,22 @@ const SKIP_EXTENSIONS = new Set([
537
537
  '.woff2', '.ttf', '.eot', '.mp3', '.mp4', '.zip', '.tar', '.gz',
538
538
  '.map', '.min.js', '.min.css', '.d.ts', '.pyc', '.pyo', '.so',
539
539
  '.dylib', '.dll', '.exe', '.bin', '.dat', '.db', '.sqlite',
540
+ '.snap', '.patch', '.diff', '.log', '.csv', '.tsv', '.parquet',
541
+ ]);
542
+ // Files that are never security-relevant (config/docs/metadata)
543
+ const SKIP_FILES = new Set([
544
+ 'license', 'license.md', 'license.txt', 'licence', 'licence.md',
545
+ 'changelog.md', 'changelog', 'changes.md', 'history.md',
546
+ 'contributing.md', 'contributors.md', 'authors', 'authors.md',
547
+ 'code_of_conduct.md', 'security.md', 'funding.yml',
548
+ '.prettierrc', '.prettierrc.json', '.prettierrc.js', '.prettierignore',
549
+ '.eslintignore', '.gitignore', '.gitattributes', '.npmignore',
550
+ '.editorconfig', '.browserslistrc', '.nvmrc', '.node-version',
551
+ '.dockerignore', 'renovate.json', '.renovaterc',
552
+ 'jest.config.js', 'jest.config.ts', 'vitest.config.ts', 'vitest.config.js',
553
+ '.babelrc', 'babel.config.js', 'babel.config.json',
554
+ 'postcss.config.js', 'postcss.config.mjs', 'tailwind.config.js', 'tailwind.config.ts',
555
+ 'prettier.config.js', 'prettier.config.mjs',
540
556
  ]);
541
557
 
542
558
  function collectFiles(dir, basePath = '', collected = [], totalSize = { bytes: 0 }) {
@@ -555,6 +571,7 @@ function collectFiles(dir, basePath = '', collected = [], totalSize = { bytes: 0
555
571
  } else {
556
572
  const ext = path.extname(entry.name).toLowerCase();
557
573
  if (SKIP_EXTENSIONS.has(ext)) continue;
574
+ if (SKIP_FILES.has(entry.name.toLowerCase())) continue;
558
575
  try {
559
576
  const stat = fs.statSync(fullPath);
560
577
  if (stat.size > MAX_FILE_SIZE || stat.size === 0) continue;
@@ -1575,6 +1592,34 @@ async function auditRepo(url) {
1575
1592
  }
1576
1593
 
1577
1594
  // ── LLM call helper (reused for multi-pass) ──
1595
+ // Determine optimal max_tokens based on model context size
1596
+ // For large-context models (128k+) we can afford 8192 output tokens
1597
+ // For medium (32k-128k) use 4096, for small (<32k) use 2048
1598
+ let outputTokenBudget = 4096; // safe default
1599
+ if (resolvedProvider.id === 'openrouter') {
1600
+ try {
1601
+ const modelInfoRes = await fetch(`https://openrouter.ai/api/v1/models`, {
1602
+ signal: AbortSignal.timeout(5000),
1603
+ headers: { 'HTTP-Referer': 'https://agentaudit.dev' },
1604
+ });
1605
+ if (modelInfoRes.ok) {
1606
+ const modelData = await modelInfoRes.json();
1607
+ const modelInfo = modelData.data?.find(m => m.id === actualModel);
1608
+ if (modelInfo?.context_length) {
1609
+ const ctx = modelInfo.context_length;
1610
+ outputTokenBudget = ctx >= 128_000 ? 8192 : ctx >= 64_000 ? 4096 : ctx >= 32_000 ? 2048 : 1024;
1611
+ if (process.argv.includes('--debug')) {
1612
+ console.log(` ${c.dim} Model context: ${ctx.toLocaleString()} tokens → max_tokens: ${outputTokenBudget}${c.reset}`);
1613
+ }
1614
+ }
1615
+ }
1616
+ } catch { /* ignore — use default */ }
1617
+ } else if (resolvedProvider.id === 'anthropic') {
1618
+ outputTokenBudget = 8192; // Claude models have 200k context
1619
+ } else if (resolvedProvider.id === 'openai') {
1620
+ outputTokenBudget = 8192; // GPT-4o has 128k context
1621
+ }
1622
+
1578
1623
  async function callLLM(codeContent, passLabel) {
1579
1624
  const systemPrompt = auditPrompt || 'You are a security auditor. Analyze the code and report findings as JSON.';
1580
1625
  const userMessage = [
@@ -1605,11 +1650,11 @@ async function auditRepo(url) {
1605
1650
  },
1606
1651
  body: JSON.stringify({
1607
1652
  model: modelOverride || 'claude-sonnet-4-20250514',
1608
- max_tokens: 4096,
1653
+ max_tokens: outputTokenBudget,
1609
1654
  system: systemPrompt,
1610
1655
  messages: [{ role: 'user', content: userMessage }],
1611
1656
  }),
1612
- signal: AbortSignal.timeout(120_000),
1657
+ signal: AbortSignal.timeout(180_000),
1613
1658
  });
1614
1659
  const data = await res.json();
1615
1660
  if (data.error) {
@@ -1653,13 +1698,13 @@ async function auditRepo(url) {
1653
1698
  headers: { 'Content-Type': 'application/json', ...authHeaders },
1654
1699
  body: JSON.stringify({
1655
1700
  model: modelName,
1656
- max_tokens: 4096,
1701
+ max_tokens: outputTokenBudget,
1657
1702
  messages: [
1658
1703
  { role: 'system', content: systemPrompt },
1659
1704
  { role: 'user', content: userMessage },
1660
1705
  ],
1661
1706
  }),
1662
- signal: AbortSignal.timeout(resolvedProvider.id === 'ollama' ? 300_000 : 120_000),
1707
+ signal: AbortSignal.timeout(resolvedProvider.id === 'ollama' ? 300_000 : 180_000),
1663
1708
  });
1664
1709
  const data = await res.json();
1665
1710
  if (data.error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentaudit",
3
- "version": "3.9.38",
3
+ "version": "3.9.39",
4
4
  "description": "Security scanner for AI packages — MCP server + CLI",
5
5
  "type": "module",
6
6
  "bin": {