@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/benchmark.js +301 -62
- package/build/index.js +353 -74
- package/build/pentest.js +326 -63
- package/build/quicktest.js +207 -63
- package/build/swarm.js +180 -60
- package/package.json +1 -1
package/build/quicktest.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
|
|
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
|
-
|
|
39424
|
-
|
|
39425
|
-
|
|
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-
|
|
39592
|
-
name: "Claude 3.5
|
|
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-
|
|
39598
|
-
name: "Claude 3
|
|
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-
|
|
39604
|
-
name: "Claude
|
|
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-
|
|
39610
|
-
name: "Claude
|
|
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
|
|
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);
|