@pensar/apex 0.0.36-canary.0 → 0.0.39-canary.2f181ec5
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/README.md +29 -1
- package/build/benchmark.js +128 -23
- package/build/index.js +186 -62
- package/build/pentest.js +127 -22
- package/build/quicktest.js +96 -16
- package/build/swarm.js +96 -16
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -27321,6 +27321,12 @@ var OPENROUTER_MODELS = [
|
|
|
27321
27321
|
provider: "openrouter",
|
|
27322
27322
|
contextLength: 64000
|
|
27323
27323
|
},
|
|
27324
|
+
{
|
|
27325
|
+
id: "mistralai/mistral-large-2512",
|
|
27326
|
+
name: "Mistral Large 3 2512",
|
|
27327
|
+
provider: "openrouter",
|
|
27328
|
+
contextLength: 262144
|
|
27329
|
+
},
|
|
27324
27330
|
{
|
|
27325
27331
|
id: "moonshotai/kimi-k2-thinking",
|
|
27326
27332
|
name: "Kimi K2 Thinking",
|
|
@@ -27843,24 +27849,40 @@ function useAgent() {
|
|
|
27843
27849
|
}
|
|
27844
27850
|
function AgentProvider({ children }) {
|
|
27845
27851
|
const [model, setModel] = import_react10.useState(AVAILABLE_MODELS[0]);
|
|
27846
|
-
const [
|
|
27852
|
+
const [tokenUsage, setTokenUsage] = import_react10.useState({
|
|
27853
|
+
inputTokens: 0,
|
|
27854
|
+
outputTokens: 0,
|
|
27855
|
+
totalTokens: 0
|
|
27856
|
+
});
|
|
27857
|
+
const [hasExecuted, setHasExecuted] = import_react10.useState(false);
|
|
27847
27858
|
const [thinking, setThinking] = import_react10.useState(false);
|
|
27848
27859
|
const [isExecuting, setIsExecuting] = import_react10.useState(false);
|
|
27849
|
-
const
|
|
27850
|
-
|
|
27851
|
-
|
|
27860
|
+
const addTokenUsage = import_react10.useCallback((input, output) => {
|
|
27861
|
+
setHasExecuted(true);
|
|
27862
|
+
setTokenUsage((prev) => ({
|
|
27863
|
+
inputTokens: prev.inputTokens + input,
|
|
27864
|
+
outputTokens: prev.outputTokens + output,
|
|
27865
|
+
totalTokens: prev.totalTokens + input + output
|
|
27866
|
+
}));
|
|
27867
|
+
}, []);
|
|
27868
|
+
const resetTokenUsage = import_react10.useCallback(() => {
|
|
27869
|
+
setHasExecuted(false);
|
|
27870
|
+
setTokenUsage({ inputTokens: 0, outputTokens: 0, totalTokens: 0 });
|
|
27871
|
+
}, []);
|
|
27872
|
+
const contextValue = import_react10.useMemo(() => ({
|
|
27873
|
+
model,
|
|
27874
|
+
setModel,
|
|
27875
|
+
tokenUsage,
|
|
27876
|
+
addTokenUsage,
|
|
27877
|
+
resetTokenUsage,
|
|
27878
|
+
hasExecuted,
|
|
27879
|
+
thinking,
|
|
27880
|
+
setThinking,
|
|
27881
|
+
isExecuting,
|
|
27882
|
+
setIsExecuting
|
|
27883
|
+
}), [model, tokenUsage, hasExecuted, thinking, isExecuting, addTokenUsage, resetTokenUsage]);
|
|
27852
27884
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(AgentContext.Provider, {
|
|
27853
|
-
value:
|
|
27854
|
-
model,
|
|
27855
|
-
setModel,
|
|
27856
|
-
tokenCount,
|
|
27857
|
-
setTokenCount,
|
|
27858
|
-
addTokens,
|
|
27859
|
-
thinking,
|
|
27860
|
-
setThinking,
|
|
27861
|
-
isExecuting,
|
|
27862
|
-
setIsExecuting
|
|
27863
|
-
},
|
|
27885
|
+
value: contextValue,
|
|
27864
27886
|
children
|
|
27865
27887
|
}, undefined, false, undefined, this);
|
|
27866
27888
|
}
|
|
@@ -27934,7 +27956,7 @@ function Footer({
|
|
|
27934
27956
|
showExitWarning = false
|
|
27935
27957
|
}) {
|
|
27936
27958
|
cwd = "~" + cwd.split(os2.homedir()).pop() || "";
|
|
27937
|
-
const { model,
|
|
27959
|
+
const { model, tokenUsage, hasExecuted, thinking, isExecuting } = useAgent();
|
|
27938
27960
|
const hotkeys = isExecuting ? [{ key: "Ctrl+C", label: "Stop Execution" }] : [{ key: "Ctrl+C", label: "Clear/Exit" }];
|
|
27939
27961
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
27940
27962
|
flexDirection: "row",
|
|
@@ -28000,27 +28022,21 @@ function Footer({
|
|
|
28000
28022
|
}, undefined, true, undefined, this);
|
|
28001
28023
|
}
|
|
28002
28024
|
function AgentStatus() {
|
|
28003
|
-
const {
|
|
28025
|
+
const { tokenUsage, hasExecuted, thinking, isExecuting } = useAgent();
|
|
28004
28026
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
28005
28027
|
flexDirection: "row",
|
|
28006
28028
|
gap: 1,
|
|
28007
28029
|
children: [
|
|
28008
|
-
|
|
28030
|
+
hasExecuted && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(import_jsx_dev_runtime2.Fragment, {
|
|
28009
28031
|
children: [
|
|
28010
28032
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
28011
28033
|
border: ["right"],
|
|
28012
28034
|
borderColor: "green"
|
|
28013
28035
|
}, undefined, false, undefined, this),
|
|
28014
28036
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
28015
|
-
fg: "
|
|
28016
|
-
children:
|
|
28017
|
-
|
|
28018
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
28019
|
-
fg: "white",
|
|
28020
|
-
children: formatTokenCount(tokenCount)
|
|
28021
|
-
}, undefined, false, undefined, this)
|
|
28022
|
-
]
|
|
28023
|
-
}, undefined, true, undefined, this),
|
|
28037
|
+
fg: "white",
|
|
28038
|
+
children: `↓${formatTokenCount(tokenUsage.inputTokens)} ↑${formatTokenCount(tokenUsage.outputTokens)} Σ${formatTokenCount(tokenUsage.totalTokens)}`
|
|
28039
|
+
}, undefined, false, undefined, this),
|
|
28024
28040
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ContextProgress, {
|
|
28025
28041
|
width: 10
|
|
28026
28042
|
}, undefined, false, undefined, this)
|
|
@@ -28042,10 +28058,11 @@ function AgentStatus() {
|
|
|
28042
28058
|
}, undefined, true, undefined, this);
|
|
28043
28059
|
}
|
|
28044
28060
|
function ContextProgress({ width }) {
|
|
28045
|
-
const { model,
|
|
28046
|
-
|
|
28047
|
-
if (!thinking)
|
|
28061
|
+
const { model, tokenUsage, thinking } = useAgent();
|
|
28062
|
+
if (!thinking || tokenUsage.totalTokens === 0)
|
|
28048
28063
|
return null;
|
|
28064
|
+
const contextLength = model.contextLength ?? 200000;
|
|
28065
|
+
const contextProgress = Math.max(0, Math.min(100, Number((tokenUsage.totalTokens / contextLength * 100).toFixed(2))));
|
|
28049
28066
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ProgressBar, {
|
|
28050
28067
|
value: contextProgress,
|
|
28051
28068
|
width
|
|
@@ -65011,11 +65028,38 @@ async function summarizeConversation(messages, opts, model) {
|
|
|
65011
65028
|
content: `Summarize this conversation to pass to another agent. This was the system prompt: ${opts.system} `
|
|
65012
65029
|
}
|
|
65013
65030
|
];
|
|
65014
|
-
const { text: summary } = await generateText({
|
|
65031
|
+
const { text: summary, usage: summaryUsage } = await generateText({
|
|
65015
65032
|
model,
|
|
65016
65033
|
system: `You are a helpful assistant that summarizes conversations to pass to another agent. Review the conversation and system prompt at the end provided by the user.`,
|
|
65017
65034
|
messages: summarizedMessages
|
|
65018
65035
|
});
|
|
65036
|
+
if (opts.onStepFinish && summaryUsage) {
|
|
65037
|
+
opts.onStepFinish({
|
|
65038
|
+
text: "",
|
|
65039
|
+
reasoning: undefined,
|
|
65040
|
+
reasoningDetails: [],
|
|
65041
|
+
files: [],
|
|
65042
|
+
sources: [],
|
|
65043
|
+
toolCalls: [],
|
|
65044
|
+
toolResults: [],
|
|
65045
|
+
finishReason: "stop",
|
|
65046
|
+
usage: {
|
|
65047
|
+
inputTokens: summaryUsage.inputTokens ?? 0,
|
|
65048
|
+
outputTokens: summaryUsage.outputTokens ?? 0,
|
|
65049
|
+
totalTokens: summaryUsage.totalTokens ?? 0
|
|
65050
|
+
},
|
|
65051
|
+
warnings: [],
|
|
65052
|
+
request: {},
|
|
65053
|
+
response: {
|
|
65054
|
+
id: "summarization",
|
|
65055
|
+
timestamp: new Date,
|
|
65056
|
+
modelId: ""
|
|
65057
|
+
},
|
|
65058
|
+
providerMetadata: undefined,
|
|
65059
|
+
stepType: "initial",
|
|
65060
|
+
isContinued: false
|
|
65061
|
+
});
|
|
65062
|
+
}
|
|
65019
65063
|
const originalLength = typeof opts.prompt === "string" ? opts.prompt.length : 0;
|
|
65020
65064
|
const enhancedPrompt = originalLength > 1e5 ? `Context: The previous conversation contained very long content that was summarized.
|
|
65021
65065
|
|
|
@@ -65178,6 +65222,7 @@ function streamResponse(opts) {
|
|
|
65178
65222
|
} = opts;
|
|
65179
65223
|
const messagesContainer = { current: messages || [] };
|
|
65180
65224
|
const providerModel = getProviderModel(model, authConfig);
|
|
65225
|
+
let rateLimitRetryCount = 0;
|
|
65181
65226
|
try {
|
|
65182
65227
|
const response = streamText({
|
|
65183
65228
|
model: providerModel,
|
|
@@ -65191,6 +65236,16 @@ function streamResponse(opts) {
|
|
|
65191
65236
|
messagesContainer.current = opts2.messages;
|
|
65192
65237
|
return;
|
|
65193
65238
|
},
|
|
65239
|
+
onError: async ({ error: error46 }) => {
|
|
65240
|
+
if (error46.message.toLowerCase().includes("too many tokens") || error46.message.toLowerCase().includes("overloaded")) {
|
|
65241
|
+
rateLimitRetryCount++;
|
|
65242
|
+
await new Promise((resolve4) => setTimeout(resolve4, 1000 * rateLimitRetryCount));
|
|
65243
|
+
if (rateLimitRetryCount < 20) {
|
|
65244
|
+
return;
|
|
65245
|
+
}
|
|
65246
|
+
}
|
|
65247
|
+
throw error46;
|
|
65248
|
+
},
|
|
65194
65249
|
onStepFinish,
|
|
65195
65250
|
abortSignal,
|
|
65196
65251
|
activeTools,
|
|
@@ -65209,7 +65264,7 @@ function streamResponse(opts) {
|
|
|
65209
65264
|
throw new Error(`Tool ${toolCall.toolName} not found or has no schema`);
|
|
65210
65265
|
}
|
|
65211
65266
|
const jsonSchema2 = inputSchema({ toolName: toolCall.toolName });
|
|
65212
|
-
const { object: repairedArgs } = await generateObject({
|
|
65267
|
+
const { object: repairedArgs, usage: repairUsage } = await generateObject({
|
|
65213
65268
|
model: providerModel,
|
|
65214
65269
|
schema: tool2.inputSchema,
|
|
65215
65270
|
prompt: [
|
|
@@ -65222,6 +65277,33 @@ function streamResponse(opts) {
|
|
|
65222
65277
|
].join(`
|
|
65223
65278
|
`)
|
|
65224
65279
|
});
|
|
65280
|
+
if (onStepFinish && repairUsage) {
|
|
65281
|
+
onStepFinish({
|
|
65282
|
+
text: "",
|
|
65283
|
+
reasoning: undefined,
|
|
65284
|
+
reasoningDetails: [],
|
|
65285
|
+
files: [],
|
|
65286
|
+
sources: [],
|
|
65287
|
+
toolCalls: [],
|
|
65288
|
+
toolResults: [],
|
|
65289
|
+
finishReason: "stop",
|
|
65290
|
+
usage: {
|
|
65291
|
+
inputTokens: repairUsage.inputTokens ?? 0,
|
|
65292
|
+
outputTokens: repairUsage.outputTokens ?? 0,
|
|
65293
|
+
totalTokens: repairUsage.totalTokens ?? 0
|
|
65294
|
+
},
|
|
65295
|
+
warnings: [],
|
|
65296
|
+
request: {},
|
|
65297
|
+
response: {
|
|
65298
|
+
id: "tool-repair",
|
|
65299
|
+
timestamp: new Date,
|
|
65300
|
+
modelId: ""
|
|
65301
|
+
},
|
|
65302
|
+
providerMetadata: undefined,
|
|
65303
|
+
stepType: "initial",
|
|
65304
|
+
isContinued: false
|
|
65305
|
+
});
|
|
65306
|
+
}
|
|
65225
65307
|
return { ...toolCall, input: JSON.stringify(repairedArgs) };
|
|
65226
65308
|
} catch (repairError) {
|
|
65227
65309
|
if (!silent) {
|
|
@@ -65248,9 +65330,9 @@ function streamResponse(opts) {
|
|
|
65248
65330
|
}
|
|
65249
65331
|
}
|
|
65250
65332
|
async function generateObjectResponse(opts) {
|
|
65251
|
-
const { model, schema, prompt, system, maxTokens, temperature, authConfig } = opts;
|
|
65333
|
+
const { model, schema, prompt, system, maxTokens, temperature, authConfig, onTokenUsage } = opts;
|
|
65252
65334
|
const providerModel = getProviderModel(model, authConfig);
|
|
65253
|
-
const { object: object3 } = await generateObject({
|
|
65335
|
+
const { object: object3, usage } = await generateObject({
|
|
65254
65336
|
model: providerModel,
|
|
65255
65337
|
schema,
|
|
65256
65338
|
prompt,
|
|
@@ -65258,6 +65340,9 @@ async function generateObjectResponse(opts) {
|
|
|
65258
65340
|
maxTokens,
|
|
65259
65341
|
temperature
|
|
65260
65342
|
});
|
|
65343
|
+
if (onTokenUsage && usage) {
|
|
65344
|
+
onTokenUsage(usage.inputTokens ?? 0, usage.outputTokens ?? 0);
|
|
65345
|
+
}
|
|
65261
65346
|
return object3;
|
|
65262
65347
|
}
|
|
65263
65348
|
// src/core/agent/pentestAgent/prompts.ts
|
|
@@ -68639,7 +68724,7 @@ Example workflow:
|
|
|
68639
68724
|
execute: async (params) => recordTestResultCore(session, params)
|
|
68640
68725
|
});
|
|
68641
68726
|
}
|
|
68642
|
-
async function generateTestStrategy(params, model) {
|
|
68727
|
+
async function generateTestStrategy(params, model, onTokenUsage) {
|
|
68643
68728
|
const prompt = `You are a penetration testing expert. Generate a concise testing strategy:
|
|
68644
68729
|
|
|
68645
68730
|
Attack Type: ${params.knowledge.name}
|
|
@@ -68665,12 +68750,15 @@ Be tactical and specific.`;
|
|
|
68665
68750
|
model: providerModel,
|
|
68666
68751
|
prompt
|
|
68667
68752
|
});
|
|
68753
|
+
if (onTokenUsage && result.usage) {
|
|
68754
|
+
onTokenUsage(result.usage.inputTokens ?? 0, result.usage.outputTokens ?? 0);
|
|
68755
|
+
}
|
|
68668
68756
|
return result.text;
|
|
68669
68757
|
} catch (error46) {
|
|
68670
68758
|
return params.knowledge.adaptiveStrategy;
|
|
68671
68759
|
}
|
|
68672
68760
|
}
|
|
68673
|
-
async function generatePayload(params, model) {
|
|
68761
|
+
async function generatePayload(params, model, onTokenUsage) {
|
|
68674
68762
|
const prompt = `Generate ONE ${params.knowledge.name} payload for testing.
|
|
68675
68763
|
|
|
68676
68764
|
Techniques:
|
|
@@ -68694,7 +68782,8 @@ Generate ONE specific payload. Return ONLY JSON:
|
|
|
68694
68782
|
const result = await generateObjectResponse({
|
|
68695
68783
|
model,
|
|
68696
68784
|
schema: PayloadSchema,
|
|
68697
|
-
prompt
|
|
68785
|
+
prompt,
|
|
68786
|
+
onTokenUsage
|
|
68698
68787
|
});
|
|
68699
68788
|
return result;
|
|
68700
68789
|
} catch (error46) {
|
|
@@ -68707,7 +68796,7 @@ Generate ONE specific payload. Return ONLY JSON:
|
|
|
68707
68796
|
technique: technique.name
|
|
68708
68797
|
};
|
|
68709
68798
|
}
|
|
68710
|
-
async function analyzeResponse(params, model) {
|
|
68799
|
+
async function analyzeResponse(params, model, onTokenUsage) {
|
|
68711
68800
|
const prompt = `Analyze this security test response:
|
|
68712
68801
|
|
|
68713
68802
|
Attack: ${params.knowledge.name}
|
|
@@ -68735,7 +68824,8 @@ Analyze: Is this vulnerable? Return ONLY JSON:
|
|
|
68735
68824
|
const result = await generateObjectResponse({
|
|
68736
68825
|
model,
|
|
68737
68826
|
schema: AnalysisSchema,
|
|
68738
|
-
prompt
|
|
68827
|
+
prompt,
|
|
68828
|
+
onTokenUsage
|
|
68739
68829
|
});
|
|
68740
68830
|
return result;
|
|
68741
68831
|
} catch (error46) {
|
|
@@ -68754,7 +68844,7 @@ Analyze: Is this vulnerable? Return ONLY JSON:
|
|
|
68754
68844
|
suggestedNextTest: "Try alternative payload or technique"
|
|
68755
68845
|
};
|
|
68756
68846
|
}
|
|
68757
|
-
function createSmartTestTool(session, model) {
|
|
68847
|
+
function createSmartTestTool(session, model, onTokenUsage) {
|
|
68758
68848
|
return tool({
|
|
68759
68849
|
name: "test_parameter",
|
|
68760
68850
|
description: `Intelligently test a parameter for a vulnerability using AI-powered adaptive testing.
|
|
@@ -68824,7 +68914,7 @@ test_parameter({
|
|
|
68824
68914
|
parameter,
|
|
68825
68915
|
endpoint,
|
|
68826
68916
|
context
|
|
68827
|
-
}, model);
|
|
68917
|
+
}, model, onTokenUsage);
|
|
68828
68918
|
console.log(`Strategy: ${strategy}`);
|
|
68829
68919
|
const results = [];
|
|
68830
68920
|
let vulnerable = false;
|
|
@@ -68837,7 +68927,7 @@ test_parameter({
|
|
|
68837
68927
|
context: { ...context, parameter, endpoint },
|
|
68838
68928
|
previousResults: results,
|
|
68839
68929
|
round
|
|
68840
|
-
}, model);
|
|
68930
|
+
}, model, onTokenUsage);
|
|
68841
68931
|
console.log(` Payload: ${payloadData.payload}`);
|
|
68842
68932
|
console.log(` Reasoning: ${payloadData.reasoning}`);
|
|
68843
68933
|
let response;
|
|
@@ -68866,7 +68956,7 @@ test_parameter({
|
|
|
68866
68956
|
attackType,
|
|
68867
68957
|
knowledge,
|
|
68868
68958
|
previousResults: results
|
|
68869
|
-
}, model);
|
|
68959
|
+
}, model, onTokenUsage);
|
|
68870
68960
|
console.log(` Analysis: ${analysis.reasoning}`);
|
|
68871
68961
|
console.log(` Vulnerable: ${analysis.vulnerable} (confidence: ${analysis.confidence})`);
|
|
68872
68962
|
results.push({
|
|
@@ -69316,7 +69406,7 @@ function wrapCommandWithHeaders(command, headers) {
|
|
|
69316
69406
|
}
|
|
69317
69407
|
return wrapped;
|
|
69318
69408
|
}
|
|
69319
|
-
function createPentestTools(session, model, toolOverride) {
|
|
69409
|
+
function createPentestTools(session, model, toolOverride, onTokenUsage) {
|
|
69320
69410
|
const offensiveHeaders = getOffensiveHeaders(session);
|
|
69321
69411
|
const rateLimiter = session._rateLimiter;
|
|
69322
69412
|
const executeCommand = tool({
|
|
@@ -69490,7 +69580,7 @@ COMMON TESTING PATTERNS:
|
|
|
69490
69580
|
http_request: httpRequest,
|
|
69491
69581
|
document_finding: createDocumentFindingTool(session),
|
|
69492
69582
|
record_test_result: createRecordTestResultTool(session),
|
|
69493
|
-
test_parameter: createSmartTestTool(session, model || "claude-sonnet-4-20250514"),
|
|
69583
|
+
test_parameter: createSmartTestTool(session, model || "claude-sonnet-4-20250514", onTokenUsage),
|
|
69494
69584
|
check_testing_coverage: createCheckTestingCoverageTool(session),
|
|
69495
69585
|
validate_completeness: createValidateCompletenessTool(session),
|
|
69496
69586
|
enumerate_endpoints: createEnumerateEndpointsTool(session),
|
|
@@ -70549,6 +70639,7 @@ function runAgent(opts) {
|
|
|
70549
70639
|
objective,
|
|
70550
70640
|
model,
|
|
70551
70641
|
onStepFinish,
|
|
70642
|
+
onToolTokenUsage,
|
|
70552
70643
|
abortSignal,
|
|
70553
70644
|
silent,
|
|
70554
70645
|
authConfig,
|
|
@@ -70568,7 +70659,7 @@ function runAgent(opts) {
|
|
|
70568
70659
|
analyze_scan,
|
|
70569
70660
|
scratchpad,
|
|
70570
70661
|
generate_report
|
|
70571
|
-
} = createPentestTools(session, undefined, toolOverride);
|
|
70662
|
+
} = createPentestTools(session, undefined, toolOverride, onToolTokenUsage);
|
|
70572
70663
|
const document_finding = tool({
|
|
70573
70664
|
name: "document_finding",
|
|
70574
70665
|
description: `Document a security finding with severity, impact, and remediation guidance.
|
|
@@ -72334,8 +72425,8 @@ function PentestAgentDisplay() {
|
|
|
72334
72425
|
const { closePentest } = useCommand();
|
|
72335
72426
|
const {
|
|
72336
72427
|
model,
|
|
72337
|
-
|
|
72338
|
-
|
|
72428
|
+
addTokenUsage,
|
|
72429
|
+
resetTokenUsage,
|
|
72339
72430
|
setThinking,
|
|
72340
72431
|
isExecuting,
|
|
72341
72432
|
setIsExecuting
|
|
@@ -72500,6 +72591,7 @@ function PentestAgentDisplay() {
|
|
|
72500
72591
|
setHasStarted(true);
|
|
72501
72592
|
setThinking(true);
|
|
72502
72593
|
setIsExecuting(true);
|
|
72594
|
+
resetTokenUsage();
|
|
72503
72595
|
const controller = new AbortController;
|
|
72504
72596
|
setAbortController(controller);
|
|
72505
72597
|
try {
|
|
@@ -72510,8 +72602,12 @@ function PentestAgentDisplay() {
|
|
|
72510
72602
|
abortSignal: controller.signal,
|
|
72511
72603
|
sessionConfig,
|
|
72512
72604
|
onStepFinish: ({ usage }) => {
|
|
72513
|
-
const
|
|
72514
|
-
|
|
72605
|
+
const inputTokens = usage.inputTokens ?? 0;
|
|
72606
|
+
const outputTokens = usage.outputTokens ?? 0;
|
|
72607
|
+
addTokenUsage(inputTokens, outputTokens);
|
|
72608
|
+
},
|
|
72609
|
+
onToolTokenUsage: (inputTokens, outputTokens) => {
|
|
72610
|
+
addTokenUsage(inputTokens, outputTokens);
|
|
72515
72611
|
}
|
|
72516
72612
|
});
|
|
72517
72613
|
setSessionPath(result.session.rootPath);
|
|
@@ -72529,7 +72625,6 @@ Path: ${result.session.rootPath}`,
|
|
|
72529
72625
|
for await (const delta of result.fullStream) {
|
|
72530
72626
|
if (delta.type === "text-delta") {
|
|
72531
72627
|
currentAssistantText += delta.text;
|
|
72532
|
-
addTokens(1);
|
|
72533
72628
|
const lastMessage = allMessages[allMessages.length - 1];
|
|
72534
72629
|
if (lastMessage && lastMessage.role === "assistant") {
|
|
72535
72630
|
lastMessage.content = currentAssistantText;
|
|
@@ -74821,7 +74916,7 @@ If resuming from summarization, review the assets in the session assets folder a
|
|
|
74821
74916
|
import { join as join5 } from "path";
|
|
74822
74917
|
import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync10 } from "fs";
|
|
74823
74918
|
function runAgent2(opts) {
|
|
74824
|
-
const { target, model, onStepFinish, abortSignal } = opts;
|
|
74919
|
+
const { target, model, onStepFinish, onToolTokenUsage, abortSignal } = opts;
|
|
74825
74920
|
const session = opts.session || createSession(target);
|
|
74826
74921
|
const subagentId = `attack-surface-${nanoid3(6)}`;
|
|
74827
74922
|
console.log(`Created attack surface session: ${session.id}`);
|
|
@@ -74830,7 +74925,7 @@ function runAgent2(opts) {
|
|
|
74830
74925
|
if (!existsSync10(assetsPath)) {
|
|
74831
74926
|
mkdirSync5(assetsPath, { recursive: true });
|
|
74832
74927
|
}
|
|
74833
|
-
const { analyze_scan, execute_command, http_request } = createPentestTools(session, model);
|
|
74928
|
+
const { analyze_scan, execute_command, http_request } = createPentestTools(session, model, undefined, onToolTokenUsage);
|
|
74834
74929
|
const document_asset = tool({
|
|
74835
74930
|
name: "document_asset",
|
|
74836
74931
|
description: `Document a discovered asset during attack surface analysis.
|
|
@@ -75127,13 +75222,14 @@ function runAgent3(opts) {
|
|
|
75127
75222
|
onSubagentSpawn,
|
|
75128
75223
|
onSubagentMessage,
|
|
75129
75224
|
onSubagentComplete,
|
|
75225
|
+
onSubagentTokenUsage,
|
|
75130
75226
|
session: sessionProp
|
|
75131
75227
|
} = opts;
|
|
75132
75228
|
const session = sessionProp || createSession(target, undefined, undefined, sessionConfig);
|
|
75133
75229
|
const logger = new Logger(session);
|
|
75134
75230
|
logger.log(`Created thorough pentest session: ${session.id}`);
|
|
75135
75231
|
logger.log(`Session path: ${session.rootPath}`);
|
|
75136
|
-
const tools2 = createOrchestratorTools(session, model, abortSignal, onSubagentSpawn, onSubagentMessage, onSubagentComplete, logger);
|
|
75232
|
+
const tools2 = createOrchestratorTools(session, model, abortSignal, onSubagentSpawn, onSubagentMessage, onSubagentComplete, onSubagentTokenUsage, logger);
|
|
75137
75233
|
const enhancedPrompt = `
|
|
75138
75234
|
TARGET: ${target}
|
|
75139
75235
|
|
|
@@ -75169,7 +75265,7 @@ Begin by using the get_attack_surface tool to map the complete attack surface of
|
|
|
75169
75265
|
streamResult.session = session;
|
|
75170
75266
|
return { streamResult, session };
|
|
75171
75267
|
}
|
|
75172
|
-
function createOrchestratorTools(session, model, abortSignal, onSubagentSpawn, onSubagentMessage, onSubagentComplete, logger) {
|
|
75268
|
+
function createOrchestratorTools(session, model, abortSignal, onSubagentSpawn, onSubagentMessage, onSubagentComplete, onSubagentTokenUsage, logger) {
|
|
75173
75269
|
const getAttackSurface = tool({
|
|
75174
75270
|
name: "get_attack_surface",
|
|
75175
75271
|
description: `Run the attack surface analysis agent to discover all assets and identify targets.
|
|
@@ -75201,7 +75297,19 @@ Use this as the FIRST step in your thorough penetration test.`,
|
|
|
75201
75297
|
target,
|
|
75202
75298
|
objective,
|
|
75203
75299
|
model,
|
|
75204
|
-
abortSignal
|
|
75300
|
+
abortSignal,
|
|
75301
|
+
onStepFinish: ({ usage }) => {
|
|
75302
|
+
if (onSubagentTokenUsage) {
|
|
75303
|
+
const inputTokens = usage.inputTokens ?? 0;
|
|
75304
|
+
const outputTokens = usage.outputTokens ?? 0;
|
|
75305
|
+
onSubagentTokenUsage(subagentId, inputTokens, outputTokens);
|
|
75306
|
+
}
|
|
75307
|
+
},
|
|
75308
|
+
onToolTokenUsage: (inputTokens, outputTokens) => {
|
|
75309
|
+
if (onSubagentTokenUsage) {
|
|
75310
|
+
onSubagentTokenUsage(subagentId, inputTokens, outputTokens);
|
|
75311
|
+
}
|
|
75312
|
+
}
|
|
75205
75313
|
});
|
|
75206
75314
|
const allMessages = [];
|
|
75207
75315
|
let currentAssistantText = "";
|
|
@@ -75376,7 +75484,19 @@ You can spawn multiple agents in parallel - they will run concurrently.`,
|
|
|
75376
75484
|
target: targetInfo.target,
|
|
75377
75485
|
objective: targetInfo.objective,
|
|
75378
75486
|
model,
|
|
75379
|
-
abortSignal
|
|
75487
|
+
abortSignal,
|
|
75488
|
+
onStepFinish: ({ usage }) => {
|
|
75489
|
+
if (onSubagentTokenUsage) {
|
|
75490
|
+
const inputTokens = usage.inputTokens ?? 0;
|
|
75491
|
+
const outputTokens = usage.outputTokens ?? 0;
|
|
75492
|
+
onSubagentTokenUsage(subagentId, inputTokens, outputTokens);
|
|
75493
|
+
}
|
|
75494
|
+
},
|
|
75495
|
+
onToolTokenUsage: (inputTokens, outputTokens) => {
|
|
75496
|
+
if (onSubagentTokenUsage) {
|
|
75497
|
+
onSubagentTokenUsage(subagentId, inputTokens, outputTokens);
|
|
75498
|
+
}
|
|
75499
|
+
}
|
|
75380
75500
|
});
|
|
75381
75501
|
const allMessages = [];
|
|
75382
75502
|
let currentAssistantText = "";
|
|
@@ -75703,8 +75823,8 @@ function useThoroughPentestAgent() {
|
|
|
75703
75823
|
const [abortController, setAbortController] = import_react22.useState(null);
|
|
75704
75824
|
const {
|
|
75705
75825
|
model,
|
|
75706
|
-
|
|
75707
|
-
|
|
75826
|
+
addTokenUsage,
|
|
75827
|
+
resetTokenUsage,
|
|
75708
75828
|
setThinking,
|
|
75709
75829
|
isExecuting,
|
|
75710
75830
|
setIsExecuting
|
|
@@ -75732,6 +75852,7 @@ function useThoroughPentestAgent() {
|
|
|
75732
75852
|
setHasStarted(true);
|
|
75733
75853
|
setThinking(true);
|
|
75734
75854
|
setIsExecuting(true);
|
|
75855
|
+
resetTokenUsage();
|
|
75735
75856
|
const controller = new AbortController;
|
|
75736
75857
|
setAbortController(controller);
|
|
75737
75858
|
try {
|
|
@@ -75741,8 +75862,12 @@ function useThoroughPentestAgent() {
|
|
|
75741
75862
|
abortSignal: controller.signal,
|
|
75742
75863
|
sessionConfig,
|
|
75743
75864
|
onStepFinish: ({ usage }) => {
|
|
75744
|
-
const
|
|
75745
|
-
|
|
75865
|
+
const inputTokens = usage.inputTokens ?? 0;
|
|
75866
|
+
const outputTokens = usage.outputTokens ?? 0;
|
|
75867
|
+
addTokenUsage(inputTokens, outputTokens);
|
|
75868
|
+
},
|
|
75869
|
+
onSubagentTokenUsage: (subagentId, input, output) => {
|
|
75870
|
+
addTokenUsage(input, output);
|
|
75746
75871
|
},
|
|
75747
75872
|
onSubagentSpawn: (subagentInfo) => {
|
|
75748
75873
|
setSubagents((prev) => [
|
|
@@ -75853,7 +75978,6 @@ Mode: Pentest (Orchestrator)`,
|
|
|
75853
75978
|
await consumeStream2(result, {
|
|
75854
75979
|
onTextDelta: (delta) => {
|
|
75855
75980
|
currentAssistantText += delta.text;
|
|
75856
|
-
addTokens(1);
|
|
75857
75981
|
const lastMessage = allMessages[allMessages.length - 1];
|
|
75858
75982
|
if (lastMessage && lastMessage.role === "assistant") {
|
|
75859
75983
|
lastMessage.content = currentAssistantText;
|