@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.
package/build/pentest.js CHANGED
@@ -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) {
@@ -40517,6 +40567,66 @@ import {
40517
40567
  } from "fs";
40518
40568
  import { join } from "path";
40519
40569
  import { homedir } from "os";
40570
+
40571
+ // src/core/services/rateLimiter/index.ts
40572
+ function sleep(ms) {
40573
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
40574
+ }
40575
+
40576
+ class RateLimiter {
40577
+ tokens;
40578
+ lastRefillTime;
40579
+ rps;
40580
+ bucketSize;
40581
+ msPerToken;
40582
+ queue;
40583
+ constructor(config2) {
40584
+ this.rps = config2?.requestsPerSecond;
40585
+ this.bucketSize = this.rps ? 1 : 0;
40586
+ this.tokens = this.bucketSize;
40587
+ this.lastRefillTime = performance.now();
40588
+ this.msPerToken = this.rps ? 1000 / this.rps : undefined;
40589
+ this.queue = Promise.resolve();
40590
+ }
40591
+ async acquireSlot() {
40592
+ if (!this.rps || !this.msPerToken)
40593
+ return;
40594
+ const previousPromise = this.queue;
40595
+ let resolveCurrentRequest;
40596
+ this.queue = new Promise((resolve2) => {
40597
+ resolveCurrentRequest = resolve2;
40598
+ });
40599
+ await previousPromise;
40600
+ try {
40601
+ const now2 = performance.now();
40602
+ this.refill(now2);
40603
+ if (this.tokens < 1) {
40604
+ const waitTime = (1 - this.tokens) * this.msPerToken;
40605
+ await sleep(waitTime);
40606
+ const nowAfterSleep = performance.now();
40607
+ this.refill(nowAfterSleep);
40608
+ }
40609
+ this.tokens -= 1;
40610
+ } finally {
40611
+ resolveCurrentRequest();
40612
+ }
40613
+ }
40614
+ refill(now2) {
40615
+ if (this.tokens >= this.bucketSize) {
40616
+ this.lastRefillTime = now2;
40617
+ return;
40618
+ }
40619
+ const elapsed = now2 - this.lastRefillTime;
40620
+ const tokensToAdd = elapsed / this.msPerToken;
40621
+ this.tokens = Math.min(this.bucketSize, this.tokens + tokensToAdd);
40622
+ this.lastRefillTime = now2;
40623
+ }
40624
+ isEnabled() {
40625
+ return this.rps !== undefined;
40626
+ }
40627
+ }
40628
+
40629
+ // src/core/agent/sessions/index.ts
40520
40630
  var DEFAULT_OFFENSIVE_HEADERS = {
40521
40631
  "User-Agent": "pensar-apex"
40522
40632
  };
@@ -40551,6 +40661,9 @@ function createSession(target, objective, prefix, config2) {
40551
40661
  startTime: new Date().toISOString(),
40552
40662
  config: config2
40553
40663
  };
40664
+ if (config2?.rateLimiter) {
40665
+ session._rateLimiter = new RateLimiter(config2.rateLimiter);
40666
+ }
40554
40667
  const metadataPath = join(rootPath, "session.json");
40555
40668
  writeFileSync(metadataPath, JSON.stringify(session, null, 2));
40556
40669
  const readmePath = join(rootPath, "README.md");
@@ -46747,6 +46860,7 @@ function wrapCommandWithHeaders(command, headers) {
46747
46860
  }
46748
46861
  function createPentestTools(session, model, toolOverride) {
46749
46862
  const offensiveHeaders = getOffensiveHeaders(session);
46863
+ const rateLimiter = session._rateLimiter;
46750
46864
  const executeCommand = tool({
46751
46865
  name: "execute_command",
46752
46866
  description: `Execute a shell command for penetration testing activities.
@@ -46791,6 +46905,9 @@ IMPORTANT: Always analyze results and adjust your approach based on findings.`,
46791
46905
  inputSchema: ExecuteCommandInput,
46792
46906
  execute: async ({ command, timeout = 30000, toolCallDescription }) => {
46793
46907
  try {
46908
+ if (rateLimiter) {
46909
+ await rateLimiter.acquireSlot();
46910
+ }
46794
46911
  if (toolOverride?.execute_command) {
46795
46912
  return toolOverride.execute_command({
46796
46913
  command,
@@ -46847,6 +46964,9 @@ COMMON TESTING PATTERNS:
46847
46964
  inputSchema: HttpRequestInput,
46848
46965
  execute: async ({ url: url2, method, headers, body, followRedirects, timeout, toolCallDescription }) => {
46849
46966
  try {
46967
+ if (rateLimiter) {
46968
+ await rateLimiter.acquireSlot();
46969
+ }
46850
46970
  if (toolOverride?.http_request) {
46851
46971
  return toolOverride.http_request({
46852
46972
  url: url2,
@@ -47084,6 +47204,125 @@ You MUST provide the details final report using create_attack_surface_report too
47084
47204
 
47085
47205
  // src/core/messages/index.ts
47086
47206
  import fs from "fs";
47207
+
47208
+ // src/core/messages/types.ts
47209
+ var ToolMessageObject = exports_external.object({
47210
+ role: exports_external.literal("tool"),
47211
+ status: exports_external.enum(["pending", "completed"]),
47212
+ toolCallId: exports_external.string(),
47213
+ content: exports_external.string(),
47214
+ args: exports_external.record(exports_external.string(), exports_external.any()),
47215
+ toolName: exports_external.string(),
47216
+ createdAt: exports_external.coerce.date()
47217
+ });
47218
+ var SystemModelMessageObject = exports_external.object({
47219
+ role: exports_external.literal("system"),
47220
+ content: exports_external.string(),
47221
+ createdAt: exports_external.coerce.date(),
47222
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional()
47223
+ });
47224
+ var TextPartObject = exports_external.object({
47225
+ type: exports_external.literal("text"),
47226
+ text: exports_external.string(),
47227
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional()
47228
+ });
47229
+ var FilePartObject = exports_external.object({
47230
+ type: exports_external.literal("file"),
47231
+ data: exports_external.union([
47232
+ exports_external.string(),
47233
+ exports_external.instanceof(Uint8Array),
47234
+ exports_external.instanceof(ArrayBuffer),
47235
+ exports_external.instanceof(Buffer),
47236
+ exports_external.url()
47237
+ ]),
47238
+ filename: exports_external.string().optional(),
47239
+ mediaType: exports_external.string(),
47240
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional()
47241
+ });
47242
+ var ReasoningPartObject = exports_external.object({
47243
+ type: exports_external.literal("reasoning"),
47244
+ text: exports_external.string(),
47245
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional()
47246
+ });
47247
+ var ToolCallPartObject = exports_external.object({
47248
+ type: exports_external.literal("tool-call"),
47249
+ toolCallId: exports_external.string(),
47250
+ toolName: exports_external.string(),
47251
+ input: exports_external.unknown(),
47252
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional(),
47253
+ providerExecuted: exports_external.boolean().optional()
47254
+ });
47255
+ var ToolResultOutputObject = exports_external.discriminatedUnion("type", [
47256
+ exports_external.object({
47257
+ type: exports_external.literal("text"),
47258
+ value: exports_external.string()
47259
+ }),
47260
+ exports_external.object({
47261
+ type: exports_external.literal("json"),
47262
+ value: exports_external.any()
47263
+ }),
47264
+ exports_external.object({
47265
+ type: exports_external.literal("error-text"),
47266
+ value: exports_external.string()
47267
+ }),
47268
+ exports_external.object({
47269
+ type: exports_external.literal("error-json"),
47270
+ value: exports_external.any()
47271
+ }),
47272
+ exports_external.object({
47273
+ type: exports_external.literal("content"),
47274
+ value: exports_external.array(exports_external.discriminatedUnion("type", [
47275
+ exports_external.object({
47276
+ type: exports_external.literal("text"),
47277
+ text: exports_external.string()
47278
+ }),
47279
+ exports_external.object({
47280
+ type: exports_external.literal("media"),
47281
+ data: exports_external.string(),
47282
+ mediaType: exports_external.string()
47283
+ })
47284
+ ]))
47285
+ })
47286
+ ]);
47287
+ var ToolResultPartObject = exports_external.object({
47288
+ type: exports_external.literal("tool-result"),
47289
+ toolCallId: exports_external.string(),
47290
+ toolName: exports_external.string(),
47291
+ output: ToolResultOutputObject,
47292
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional()
47293
+ });
47294
+ var AssistantModelMessageObject = exports_external.object({
47295
+ role: exports_external.literal("assistant"),
47296
+ content: exports_external.union([
47297
+ exports_external.string(),
47298
+ exports_external.array(exports_external.discriminatedUnion("type", [
47299
+ TextPartObject,
47300
+ FilePartObject,
47301
+ ReasoningPartObject,
47302
+ ToolCallPartObject,
47303
+ ToolResultPartObject
47304
+ ]))
47305
+ ]),
47306
+ createdAt: exports_external.coerce.date(),
47307
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional()
47308
+ });
47309
+ var UserModelMessageObject = exports_external.object({
47310
+ role: exports_external.literal("user"),
47311
+ content: exports_external.union([
47312
+ exports_external.string(),
47313
+ exports_external.array(exports_external.discriminatedUnion("type", [TextPartObject, FilePartObject]))
47314
+ ]),
47315
+ createdAt: exports_external.coerce.date(),
47316
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional()
47317
+ });
47318
+ var ModelMessageObject = exports_external.discriminatedUnion("role", [
47319
+ SystemModelMessageObject,
47320
+ UserModelMessageObject,
47321
+ AssistantModelMessageObject,
47322
+ ToolMessageObject
47323
+ ]);
47324
+
47325
+ // src/core/messages/index.ts
47087
47326
  function saveSubagentMessages(orchestratorSession, subagentId, messages) {
47088
47327
  const subagentDir = `${orchestratorSession.rootPath}/subagents/${subagentId}`;
47089
47328
  if (!fs.existsSync(`${orchestratorSession.rootPath}/subagents`)) {
@@ -47805,13 +48044,15 @@ async function runPentest(options) {
47805
48044
  target,
47806
48045
  model = "claude-sonnet-4-5",
47807
48046
  headerMode = "default",
47808
- customHeaders
48047
+ customHeaders,
48048
+ rps
47809
48049
  } = options;
47810
48050
  console.log("=".repeat(80));
47811
48051
  console.log("PENSAR COMPREHENSIVE PENTEST");
47812
48052
  console.log("=".repeat(80));
47813
48053
  console.log(`Target: ${target}`);
47814
48054
  console.log(`Model: ${model}`);
48055
+ console.log(`Rate Limit: ${rps ? `${rps} req/s` : "Unlimited"}`);
47815
48056
  console.log(`Headers: ${headerMode === "none" ? "None" : headerMode === "default" ? "Default (pensar-apex)" : "Custom"}`);
47816
48057
  if (headerMode === "custom" && customHeaders) {
47817
48058
  for (const [key, value] of Object.entries(customHeaders)) {
@@ -47829,6 +48070,11 @@ async function runPentest(options) {
47829
48070
  offensiveHeaders: {
47830
48071
  mode: headerMode,
47831
48072
  headers: headerMode === "custom" ? customHeaders : undefined
48073
+ },
48074
+ ...rps && {
48075
+ rateLimiter: {
48076
+ requestsPerSecond: rps
48077
+ }
47832
48078
  }
47833
48079
  };
47834
48080
  const { streamResult, session } = runAgent3({
@@ -47882,6 +48128,7 @@ async function main() {
47882
48128
  console.error();
47883
48129
  console.error("Options:");
47884
48130
  console.error(" --model <model> AI model to use (default: claude-sonnet-4-5)");
48131
+ console.error(" --rps <number> Rate limit: requests per second (default: unlimited)");
47885
48132
  console.error(" --headers <mode> Header mode: none, default, or custom (default: default)");
47886
48133
  console.error(" --header <name:value> Add custom header (requires --headers custom, can be repeated)");
47887
48134
  console.error();
@@ -47899,7 +48146,7 @@ async function main() {
47899
48146
  console.error("Examples:");
47900
48147
  console.error(" pensar pentest --target example.com");
47901
48148
  console.error(" pensar pentest --target api.example.com --headers none");
47902
- console.error(" pensar pentest --target example.com --headers custom \\");
48149
+ console.error(" pensar pentest --target example.com --rps 5 --headers custom \\");
47903
48150
  console.error(" --header 'User-Agent: pensar_client123' --header 'X-Bug-Bounty: researcher'");
47904
48151
  console.error();
47905
48152
  process.exit(1);
@@ -47924,6 +48171,21 @@ async function main() {
47924
48171
  }
47925
48172
  model = modelArg;
47926
48173
  }
48174
+ const rpsIndex = args.indexOf("--rps");
48175
+ let rps;
48176
+ if (rpsIndex !== -1) {
48177
+ const rpsArg = args[rpsIndex + 1];
48178
+ if (!rpsArg) {
48179
+ console.error("Error: --rps must be followed by a number");
48180
+ process.exit(1);
48181
+ }
48182
+ const parsedRps = parseInt(rpsArg, 10);
48183
+ if (isNaN(parsedRps) || parsedRps <= 0) {
48184
+ console.error("Error: --rps must be a positive number");
48185
+ process.exit(1);
48186
+ }
48187
+ rps = parsedRps;
48188
+ }
47927
48189
  const headersIndex = args.indexOf("--headers");
47928
48190
  let headerMode = "default";
47929
48191
  if (headersIndex !== -1) {
@@ -47969,7 +48231,8 @@ async function main() {
47969
48231
  target,
47970
48232
  ...model && { model },
47971
48233
  headerMode,
47972
- ...headerMode === "custom" && { customHeaders }
48234
+ ...headerMode === "custom" && { customHeaders },
48235
+ ...rps && { rps }
47973
48236
  });
47974
48237
  } catch (error46) {
47975
48238
  console.error("Fatal error:", error46.message);