@pensar/apex 0.0.28 → 0.0.29

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.
@@ -39333,8 +39333,8 @@ function createAnthropic(options = {}) {
39333
39333
  }
39334
39334
  var anthropic = createAnthropic();
39335
39335
 
39336
- // src/core/ai/models.ts
39337
- var AVAILABLE_MODELS = [
39336
+ // src/core/ai/models/anthropic.ts
39337
+ var ANTHROPIC_MODELS = [
39338
39338
  {
39339
39339
  id: "claude-haiku-4-5",
39340
39340
  name: "Claude Haiku 4.5",
@@ -39418,55 +39418,11 @@ var AVAILABLE_MODELS = [
39418
39418
  name: "Claude 3 Haiku (2024-03-07)",
39419
39419
  provider: "anthropic",
39420
39420
  contextLength: 200000
39421
- },
39422
- {
39423
- id: "gpt-4.5-turbo",
39424
- name: "GPT-4.5 Turbo",
39425
- provider: "openai",
39426
- contextLength: 128000
39427
- },
39428
- {
39429
- id: "gpt-4o",
39430
- name: "GPT-4o",
39431
- provider: "openai",
39432
- contextLength: 128000
39433
- },
39434
- {
39435
- id: "gpt-4o-mini",
39436
- name: "GPT-4o Mini",
39437
- provider: "openai",
39438
- contextLength: 128000
39439
- },
39440
- {
39441
- id: "gpt-4-turbo",
39442
- name: "GPT-4 Turbo",
39443
- provider: "openai",
39444
- contextLength: 128000
39445
- },
39446
- {
39447
- id: "gpt-4",
39448
- name: "GPT-4",
39449
- provider: "openai",
39450
- contextLength: 8192
39451
- },
39452
- {
39453
- id: "gpt-3.5-turbo",
39454
- name: "GPT-3.5 Turbo",
39455
- provider: "openai",
39456
- contextLength: 16385
39457
- },
39458
- {
39459
- id: "o1",
39460
- name: "O1",
39461
- provider: "openai",
39462
- contextLength: 200000
39463
- },
39464
- {
39465
- id: "o1-mini",
39466
- name: "O1 Mini",
39467
- provider: "openai",
39468
- contextLength: 128000
39469
- },
39421
+ }
39422
+ ];
39423
+
39424
+ // src/core/ai/models/openrouter.ts
39425
+ var OPENROUTER_MODELS = [
39470
39426
  {
39471
39427
  id: "anthropic/claude-haiku-4.5",
39472
39428
  name: "Claude Haiku 4.5 (OpenRouter)",
@@ -39586,28 +39542,62 @@ var AVAILABLE_MODELS = [
39586
39542
  name: "Qwen 3 32B Instruct",
39587
39543
  provider: "openrouter",
39588
39544
  contextLength: 256000
39545
+ }
39546
+ ];
39547
+
39548
+ // src/core/ai/models/bedrock.ts
39549
+ var BEDROCK_MODELS = [
39550
+ {
39551
+ id: "anthropic.claude-3-haiku-20240307-v1:0",
39552
+ name: "Claude 3 Haiku (Bedrock)",
39553
+ provider: "bedrock",
39554
+ contextLength: 200000
39589
39555
  },
39590
39556
  {
39591
- id: "anthropic.claude-3-5-sonnet-20240620-v1:0",
39592
- name: "Claude 3.5 Sonnet (Bedrock)",
39557
+ id: "anthropic.claude-3-5-haiku-20241022-v1:0",
39558
+ name: "Claude 3.5 Haiku (Bedrock)",
39593
39559
  provider: "bedrock",
39594
39560
  contextLength: 200000
39595
39561
  },
39596
39562
  {
39597
- id: "anthropic.claude-3-opus-20240229-v1:0",
39598
- name: "Claude 3 Opus (Bedrock)",
39563
+ id: "anthropic.claude-3-7-sonnet-20250219-v1:0",
39564
+ name: "Claude 3.7 Sonnet (Bedrock)",
39599
39565
  provider: "bedrock",
39600
39566
  contextLength: 200000
39601
39567
  },
39602
39568
  {
39603
- id: "anthropic.claude-3-sonnet-20240229-v1:0",
39604
- name: "Claude 3 Sonnet (Bedrock)",
39569
+ id: "anthropic.claude-haiku-4-5-20251001-v1:0",
39570
+ name: "Claude Haiku 4.5 (Bedrock)",
39605
39571
  provider: "bedrock",
39606
39572
  contextLength: 200000
39607
39573
  },
39608
39574
  {
39609
- id: "anthropic.claude-3-haiku-20240307-v1:0",
39610
- name: "Claude 3 Haiku (Bedrock)",
39575
+ id: "anthropic.claude-opus-4-1-20250805-v1:0",
39576
+ name: "Claude Opus 4.1 (Bedrock)",
39577
+ provider: "bedrock",
39578
+ contextLength: 200000
39579
+ },
39580
+ {
39581
+ id: "anthropic.claude-opus-4-5-20251101-v1:0",
39582
+ name: "Claude Opus 4.5 (Bedrock)",
39583
+ provider: "bedrock",
39584
+ contextLength: 200000
39585
+ },
39586
+ {
39587
+ id: "anthropic.claude-opus-4-20250514-v1:0",
39588
+ name: "Claude Opus 4 (Bedrock)",
39589
+ provider: "bedrock",
39590
+ contextLength: 200000
39591
+ },
39592
+ {
39593
+ id: "anthropic.claude-sonnet-4-5-20250929-v1:0",
39594
+ name: "Claude Sonnet 4.5 (Bedrock)",
39595
+ provider: "bedrock",
39596
+ contextLength: 200000
39597
+ },
39598
+ {
39599
+ id: "anthropic.claude-sonnet-4-20250514-v1:0",
39600
+ name: "Claude Sonnet 4 (Bedrock)",
39611
39601
  provider: "bedrock",
39612
39602
  contextLength: 200000
39613
39603
  },
@@ -39648,6 +39638,66 @@ var AVAILABLE_MODELS = [
39648
39638
  contextLength: 128000
39649
39639
  }
39650
39640
  ];
39641
+
39642
+ // src/core/ai/models/openai.ts
39643
+ var OPENAI_MODELS = [
39644
+ {
39645
+ id: "gpt-4.5-turbo",
39646
+ name: "GPT-4.5 Turbo",
39647
+ provider: "openai",
39648
+ contextLength: 128000
39649
+ },
39650
+ {
39651
+ id: "gpt-4o",
39652
+ name: "GPT-4o",
39653
+ provider: "openai",
39654
+ contextLength: 128000
39655
+ },
39656
+ {
39657
+ id: "gpt-4o-mini",
39658
+ name: "GPT-4o Mini",
39659
+ provider: "openai",
39660
+ contextLength: 128000
39661
+ },
39662
+ {
39663
+ id: "gpt-4-turbo",
39664
+ name: "GPT-4 Turbo",
39665
+ provider: "openai",
39666
+ contextLength: 128000
39667
+ },
39668
+ {
39669
+ id: "gpt-4",
39670
+ name: "GPT-4",
39671
+ provider: "openai",
39672
+ contextLength: 8192
39673
+ },
39674
+ {
39675
+ id: "gpt-3.5-turbo",
39676
+ name: "GPT-3.5 Turbo",
39677
+ provider: "openai",
39678
+ contextLength: 16385
39679
+ },
39680
+ {
39681
+ id: "o1",
39682
+ name: "O1",
39683
+ provider: "openai",
39684
+ contextLength: 200000
39685
+ },
39686
+ {
39687
+ id: "o1-mini",
39688
+ name: "O1 Mini",
39689
+ provider: "openai",
39690
+ contextLength: 128000
39691
+ }
39692
+ ];
39693
+
39694
+ // src/core/ai/models/index.ts
39695
+ var AVAILABLE_MODELS = [
39696
+ ...ANTHROPIC_MODELS,
39697
+ ...OPENROUTER_MODELS,
39698
+ ...BEDROCK_MODELS,
39699
+ ...OPENAI_MODELS
39700
+ ];
39651
39701
  function getModelInfo(model) {
39652
39702
  return AVAILABLE_MODELS.find((m) => m.id === model) ?? {
39653
39703
  id: model,
@@ -39664,7 +39714,7 @@ function getProviderModel(model, authConfig) {
39664
39714
  const openRouterAPIKey = authConfig?.openRouterAPIKey || process.env.OPENROUTER_API_KEY;
39665
39715
  const bedrockAccessKeyId = authConfig?.bedrock?.accessKeyId || process.env.AWS_ACCESS_KEY_ID;
39666
39716
  const bedrockSecretAccessKey = authConfig?.bedrock?.secretAccessKey || process.env.AWS_SECRET_ACCESS_KEY;
39667
- const bedrockRegion = authConfig?.bedrock?.region || process.env.AWS_REGION || "us-east-1";
39717
+ const bedrockRegion = authConfig?.bedrock?.region || process.env.AWS_REGION;
39668
39718
  const localBaseURL = authConfig?.local?.baseURL || process.env.LOCAL_MODEL_URL || "http://127.0.0.1:1234/v1";
39669
39719
  let providerModel;
39670
39720
  switch (provider) {
@@ -41505,6 +41555,66 @@ import {
41505
41555
  } from "fs";
41506
41556
  import { join } from "path";
41507
41557
  import { homedir } from "os";
41558
+
41559
+ // src/core/services/rateLimiter/index.ts
41560
+ function sleep(ms) {
41561
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
41562
+ }
41563
+
41564
+ class RateLimiter {
41565
+ tokens;
41566
+ lastRefillTime;
41567
+ rps;
41568
+ bucketSize;
41569
+ msPerToken;
41570
+ queue;
41571
+ constructor(config2) {
41572
+ this.rps = config2?.requestsPerSecond;
41573
+ this.bucketSize = this.rps ? 1 : 0;
41574
+ this.tokens = this.bucketSize;
41575
+ this.lastRefillTime = performance.now();
41576
+ this.msPerToken = this.rps ? 1000 / this.rps : undefined;
41577
+ this.queue = Promise.resolve();
41578
+ }
41579
+ async acquireSlot() {
41580
+ if (!this.rps || !this.msPerToken)
41581
+ return;
41582
+ const previousPromise = this.queue;
41583
+ let resolveCurrentRequest;
41584
+ this.queue = new Promise((resolve2) => {
41585
+ resolveCurrentRequest = resolve2;
41586
+ });
41587
+ await previousPromise;
41588
+ try {
41589
+ const now2 = performance.now();
41590
+ this.refill(now2);
41591
+ if (this.tokens < 1) {
41592
+ const waitTime = (1 - this.tokens) * this.msPerToken;
41593
+ await sleep(waitTime);
41594
+ const nowAfterSleep = performance.now();
41595
+ this.refill(nowAfterSleep);
41596
+ }
41597
+ this.tokens -= 1;
41598
+ } finally {
41599
+ resolveCurrentRequest();
41600
+ }
41601
+ }
41602
+ refill(now2) {
41603
+ if (this.tokens >= this.bucketSize) {
41604
+ this.lastRefillTime = now2;
41605
+ return;
41606
+ }
41607
+ const elapsed = now2 - this.lastRefillTime;
41608
+ const tokensToAdd = elapsed / this.msPerToken;
41609
+ this.tokens = Math.min(this.bucketSize, this.tokens + tokensToAdd);
41610
+ this.lastRefillTime = now2;
41611
+ }
41612
+ isEnabled() {
41613
+ return this.rps !== undefined;
41614
+ }
41615
+ }
41616
+
41617
+ // src/core/agent/sessions/index.ts
41508
41618
  var DEFAULT_OFFENSIVE_HEADERS = {
41509
41619
  "User-Agent": "pensar-apex"
41510
41620
  };
@@ -41539,6 +41649,9 @@ function createSession(target, objective, prefix, config2) {
41539
41649
  startTime: new Date().toISOString(),
41540
41650
  config: config2
41541
41651
  };
41652
+ if (config2?.rateLimiter) {
41653
+ session._rateLimiter = new RateLimiter(config2.rateLimiter);
41654
+ }
41542
41655
  const metadataPath = join(rootPath, "session.json");
41543
41656
  writeFileSync(metadataPath, JSON.stringify(session, null, 2));
41544
41657
  const readmePath = join(rootPath, "README.md");
@@ -43942,6 +44055,7 @@ function wrapCommandWithHeaders(command, headers) {
43942
44055
  }
43943
44056
  function createPentestTools(session, model, toolOverride) {
43944
44057
  const offensiveHeaders = getOffensiveHeaders(session);
44058
+ const rateLimiter = session._rateLimiter;
43945
44059
  const executeCommand = tool({
43946
44060
  name: "execute_command",
43947
44061
  description: `Execute a shell command for penetration testing activities.
@@ -43986,6 +44100,9 @@ IMPORTANT: Always analyze results and adjust your approach based on findings.`,
43986
44100
  inputSchema: ExecuteCommandInput,
43987
44101
  execute: async ({ command, timeout = 30000, toolCallDescription }) => {
43988
44102
  try {
44103
+ if (rateLimiter) {
44104
+ await rateLimiter.acquireSlot();
44105
+ }
43989
44106
  if (toolOverride?.execute_command) {
43990
44107
  return toolOverride.execute_command({
43991
44108
  command,
@@ -44042,6 +44159,9 @@ COMMON TESTING PATTERNS:
44042
44159
  inputSchema: HttpRequestInput,
44043
44160
  execute: async ({ url: url2, method, headers, body, followRedirects, timeout, toolCallDescription }) => {
44044
44161
  try {
44162
+ if (rateLimiter) {
44163
+ await rateLimiter.acquireSlot();
44164
+ }
44045
44165
  if (toolOverride?.http_request) {
44046
44166
  return toolOverride.http_request({
44047
44167
  url: url2,
@@ -45105,7 +45225,8 @@ async function runQuicktest(options) {
45105
45225
  objective,
45106
45226
  model = "claude-sonnet-4-5",
45107
45227
  headerMode = "default",
45108
- customHeaders
45228
+ customHeaders,
45229
+ rps
45109
45230
  } = options;
45110
45231
  console.log("=".repeat(80));
45111
45232
  console.log("PENSAR QUICK PENTEST");
@@ -45113,6 +45234,7 @@ async function runQuicktest(options) {
45113
45234
  console.log(`Target: ${target}`);
45114
45235
  console.log(`Objective: ${objective}`);
45115
45236
  console.log(`Model: ${model}`);
45237
+ console.log(`Rate Limit: ${rps ? `${rps} req/s` : "Unlimited"}`);
45116
45238
  console.log(`Headers: ${headerMode === "none" ? "None" : headerMode === "default" ? "Default (pensar-apex)" : "Custom"}`);
45117
45239
  if (headerMode === "custom" && customHeaders) {
45118
45240
  for (const [key, value] of Object.entries(customHeaders)) {
@@ -45125,6 +45247,11 @@ async function runQuicktest(options) {
45125
45247
  offensiveHeaders: {
45126
45248
  mode: headerMode,
45127
45249
  headers: headerMode === "custom" ? customHeaders : undefined
45250
+ },
45251
+ ...rps && {
45252
+ rateLimiter: {
45253
+ requestsPerSecond: rps
45254
+ }
45128
45255
  }
45129
45256
  };
45130
45257
  const { streamResult, session } = runAgent({
@@ -45180,6 +45307,7 @@ async function main() {
45180
45307
  console.error();
45181
45308
  console.error("Options:");
45182
45309
  console.error(" --model <model> AI model to use (default: claude-sonnet-4-5)");
45310
+ console.error(" --rps <number> Rate limit: requests per second (default: unlimited)");
45183
45311
  console.error(" --headers <mode> Header mode: none, default, or custom (default: default)");
45184
45312
  console.error(" --header <name:value> Add custom header (requires --headers custom, can be repeated)");
45185
45313
  console.error();
@@ -45191,7 +45319,7 @@ async function main() {
45191
45319
  console.error("Examples:");
45192
45320
  console.error(" pensar quicktest --target http://localhost:3000 --objective 'Find SQL injection'");
45193
45321
  console.error(" pensar quicktest --target 192.168.1.100 --objective 'Test auth bypass' --headers none");
45194
- console.error(" pensar quicktest --target api.example.com --objective 'API testing' \\");
45322
+ console.error(" pensar quicktest --target api.example.com --objective 'API testing' --rps 5 \\");
45195
45323
  console.error(" --headers custom --header 'User-Agent: pensar_client123' --header 'X-Bug-Bounty: researcher'");
45196
45324
  console.error();
45197
45325
  process.exit(1);
@@ -45226,6 +45354,21 @@ async function main() {
45226
45354
  }
45227
45355
  model = modelArg;
45228
45356
  }
45357
+ const rpsIndex = args.indexOf("--rps");
45358
+ let rps;
45359
+ if (rpsIndex !== -1) {
45360
+ const rpsArg = args[rpsIndex + 1];
45361
+ if (!rpsArg) {
45362
+ console.error("Error: --rps must be followed by a number");
45363
+ process.exit(1);
45364
+ }
45365
+ const parsedRps = parseInt(rpsArg, 10);
45366
+ if (isNaN(parsedRps) || parsedRps <= 0) {
45367
+ console.error("Error: --rps must be a positive number");
45368
+ process.exit(1);
45369
+ }
45370
+ rps = parsedRps;
45371
+ }
45229
45372
  const headersIndex = args.indexOf("--headers");
45230
45373
  let headerMode = "default";
45231
45374
  if (headersIndex !== -1) {
@@ -45272,7 +45415,8 @@ async function main() {
45272
45415
  objective,
45273
45416
  ...model && { model },
45274
45417
  headerMode,
45275
- ...headerMode === "custom" && { customHeaders }
45418
+ ...headerMode === "custom" && { customHeaders },
45419
+ ...rps && { rps }
45276
45420
  });
45277
45421
  } catch (error46) {
45278
45422
  console.error("Fatal error:", error46.message);