@pensar/apex 2.0.0-canary.241920ad → 2.0.0
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 +0 -20
- package/build/agent-84enr6xn.js +22 -0
- package/build/{agent-7866ka7b.js → agent-x1tnsg7n.js} +10 -7
- package/build/{agent-aj7jpehp.js → agent-z8043nrm.js} +12 -9
- package/build/{apps-hse35c2d.js → apps-gdze0s68.js} +18 -15
- package/build/{auth-15rkvgam.js → auth-24ca1qwx.js} +19 -16
- package/build/authentication-0k43jay4.js +22 -0
- package/build/blackboxAgent-76tnwwg7.js +22 -0
- package/build/{blackboxPentest-vmtnnp5d.js → blackboxPentest-xwc031xm.js} +16 -13
- package/build/{cli-23xtyah8.js → cli-0v9x0eby.js} +1 -1
- package/build/cli-1yavz2pb.js +17 -0
- package/build/{cli-6gge86w5.js → cli-31cara07.js} +6 -8
- package/build/cli-3knnkdps.js +666 -0
- package/build/{cli-cbw2rmv7.js → cli-5fr9k6m4.js} +35 -58
- package/build/{cli-78s9w64j.js → cli-948dk60p.js} +1 -1
- package/build/{cli-k1vsv3qh.js → cli-a20jcpmp.js} +1 -1
- package/build/{cli-0svsmc2c.js → cli-cb5va0cs.js} +1 -10
- package/build/{cli-rtbry75t.js → cli-h6nw89zf.js} +1 -1
- package/build/{cli-5h1kv0v4.js → cli-h825qzmd.js} +53 -1492
- package/build/{cli-gtepvg8s.js → cli-k8mvghe1.js} +921 -444
- package/build/{cli-4dpc999m.js → cli-mswm4k81.js} +1 -11
- package/build/{cli-zyk3xsth.js → cli-ntd42071.js} +1 -1
- package/build/{cli-mb837pv4.js → cli-pkdjamer.js} +5 -15
- package/build/cli-s1nckt4k.js +20 -0
- package/build/{cli-4ez6yssj.js → cli-sw5swz40.js} +3 -3
- package/build/{cli-ft17f9nh.js → cli-wdmqkshz.js} +2 -2
- package/build/{cli-demg7sj2.js → cli-zpvmaxem.js} +2 -2
- package/build/{cli-r0s5br0a.js → cli-zvq4gy61.js} +6 -13
- package/build/cli.js +45 -105
- package/build/{config-bb6q79q0.js → config-cmq1cxz3.js} +3 -3
- package/build/{doctor-tkz0a0g4.js → doctor-2bkpddws.js} +1 -8
- package/build/{fixes-krvbkbey.js → fixes-a4qscvkx.js} +18 -15
- package/build/{index-pamhzcx3.js → index-0fnbx38r.js} +14 -20
- package/build/{index-ah3cm7hf.js → index-2a1x5nnv.js} +3 -3
- package/build/{index-v4sz6cee.js → index-48pjf9d2.js} +124 -76
- package/build/{index-tknvj68q.js → index-54ep0ery.js} +12 -9
- package/build/{index-wsp4kqtm.js → index-aymt8k9w.js} +2 -2
- package/build/{index-a9ea9c1q.js → index-hfhkjj2g.js} +11 -8
- package/build/{index-4gk224ac.js → index-s17r2akv.js} +4 -4
- package/build/{issues-m2me70rs.js → issues-5pnrspt7.js} +18 -15
- package/build/{logs-rxf1a0be.js → logs-1mfm901x.js} +18 -15
- package/build/{offesecAgent-hmxcpch7.js → offesecAgent-mrbyc93d.js} +11 -8
- package/build/pentest-wy4eeagc.js +31 -0
- package/build/{pentests-201vfsn6.js → pentests-htmtq66d.js} +18 -15
- package/build/{targetedPentest-85b1dndy.js → targetedPentest-cpbd87rc.js} +12 -9
- package/build/threatModel-9n56z6a6.js +29 -0
- package/build/{uninstall-qa8jvrj1.js → uninstall-6y9dkgyt.js} +1 -1
- package/build/{upload-p58nxxvf.js → upload-7wtbr768.js} +1 -8
- package/build/{utils-hsde107p.js → utils-trqnyj77.js} +8 -6
- package/package.json +1 -1
- package/build/agent-mjyx1amj.js +0 -19
- package/build/authentication-b8p1afqq.js +0 -19
- package/build/blackboxAgent-z1h2cgyg.js +0 -19
- package/build/pentest-r6hfzf8n.js +0 -28
- package/build/threatModel-hbpz15y7.js +0 -26
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
init_auth,
|
|
5
5
|
init_constants,
|
|
6
6
|
signGatewayRequest
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-948dk60p.js";
|
|
8
8
|
import {
|
|
9
9
|
AISDKError,
|
|
10
10
|
APICallError,
|
|
@@ -32,7 +32,6 @@ import {
|
|
|
32
32
|
delay,
|
|
33
33
|
executeTool,
|
|
34
34
|
exports_external,
|
|
35
|
-
exports_external1 as exports_external2,
|
|
36
35
|
gateway,
|
|
37
36
|
getErrorMessage,
|
|
38
37
|
getErrorMessage1 as getErrorMessage2,
|
|
@@ -43,7 +42,6 @@ import {
|
|
|
43
42
|
init_stream,
|
|
44
43
|
init_v3,
|
|
45
44
|
init_v4,
|
|
46
|
-
init_zod,
|
|
47
45
|
isAbortError,
|
|
48
46
|
isUrlSupported,
|
|
49
47
|
lazySchema,
|
|
@@ -57,24 +55,17 @@ import {
|
|
|
57
55
|
validateDownloadUrl,
|
|
58
56
|
validateTypes,
|
|
59
57
|
withUserAgentSuffix,
|
|
60
|
-
zodSchema
|
|
61
|
-
zod_default
|
|
58
|
+
zodSchema
|
|
62
59
|
} from "./cli-e6rgwtpb.js";
|
|
63
60
|
import {
|
|
64
61
|
config,
|
|
65
62
|
init_config
|
|
66
|
-
} from "./cli-
|
|
63
|
+
} from "./cli-h6nw89zf.js";
|
|
67
64
|
import {
|
|
68
|
-
getCurrentVersion,
|
|
69
|
-
init_installation
|
|
70
|
-
} from "./cli-k1vsv3qh.js";
|
|
71
|
-
import {
|
|
72
|
-
__callDispose,
|
|
73
65
|
__commonJS,
|
|
74
66
|
__esm,
|
|
75
67
|
__require,
|
|
76
|
-
__toESM
|
|
77
|
-
__using
|
|
68
|
+
__toESM
|
|
78
69
|
} from "./cli-8rxa073f.js";
|
|
79
70
|
|
|
80
71
|
// node_modules/ai/dist/index.mjs
|
|
@@ -8785,20 +8776,6 @@ var init_models = __esm(() => {
|
|
|
8785
8776
|
];
|
|
8786
8777
|
});
|
|
8787
8778
|
|
|
8788
|
-
// src/core/util/lazyLogger.ts
|
|
8789
|
-
function scopedLogger(factory) {
|
|
8790
|
-
let instance;
|
|
8791
|
-
const get = () => instance ??= factory();
|
|
8792
|
-
return new Proxy({}, {
|
|
8793
|
-
get(_target, prop) {
|
|
8794
|
-
const inst = get();
|
|
8795
|
-
const value = inst[prop];
|
|
8796
|
-
return typeof value === "function" ? value.bind(inst) : value;
|
|
8797
|
-
}
|
|
8798
|
-
});
|
|
8799
|
-
}
|
|
8800
|
-
var init_lazyLogger = () => {};
|
|
8801
|
-
|
|
8802
8779
|
// node_modules/@ai-sdk/provider-utils/dist/index.mjs
|
|
8803
8780
|
function combineHeaders(...headers) {
|
|
8804
8781
|
return headers.reduce((combinedHeaders, currentHeaders) => ({
|
|
@@ -42457,7 +42434,7 @@ function wrapStreamWithErrorHandler(originalStream, messagesContainer, opts, mod
|
|
|
42457
42434
|
if (!isCtxError && isStreamIdleTimeoutError(error) && idleResumeCount < MAX_IDLE_RESUME_RETRIES && messagesContainer.current.length > 0) {
|
|
42458
42435
|
const nextIdleCount = idleResumeCount + 1;
|
|
42459
42436
|
if (!silent) {
|
|
42460
|
-
|
|
42437
|
+
console.warn(`Stream stalled (attempt ${nextIdleCount}/${MAX_IDLE_RESUME_RETRIES}), resuming with ${messagesContainer.current.length} messages: ${errorMessage}`);
|
|
42461
42438
|
}
|
|
42462
42439
|
const retriedStream = streamResponse({
|
|
42463
42440
|
...opts,
|
|
@@ -42473,7 +42450,7 @@ function wrapStreamWithErrorHandler(originalStream, messagesContainer, opts, mod
|
|
|
42473
42450
|
const nextRetryCount = rateLimitRetryCount + 1;
|
|
42474
42451
|
const delayMs = Math.min(1000 * nextRetryCount, 30000);
|
|
42475
42452
|
if (!silent) {
|
|
42476
|
-
|
|
42453
|
+
console.warn(`Rate limit error (attempt ${nextRetryCount}/${MAX_RATE_LIMIT_RETRIES}), waiting ${delayMs}ms: ${errorMessage}`);
|
|
42477
42454
|
}
|
|
42478
42455
|
await new Promise((resolve4) => setTimeout(resolve4, delayMs));
|
|
42479
42456
|
const retriedStream = streamResponse({
|
|
@@ -42505,7 +42482,7 @@ function wrapStreamWithErrorHandler(originalStream, messagesContainer, opts, mod
|
|
|
42505
42482
|
let postReactiveDepth = opts._restartDepth ?? 0;
|
|
42506
42483
|
if (fitted.fitsBudget && fitted.modified) {
|
|
42507
42484
|
if (!silent) {
|
|
42508
|
-
|
|
42485
|
+
console.warn(`Context length error — Layer 1+2 reduced to ~${fitted.estimatedInputTokens} tokens, retrying`);
|
|
42509
42486
|
}
|
|
42510
42487
|
try {
|
|
42511
42488
|
const retried = streamResponse({
|
|
@@ -42527,7 +42504,7 @@ function wrapStreamWithErrorHandler(originalStream, messagesContainer, opts, mod
|
|
|
42527
42504
|
}
|
|
42528
42505
|
const messagesForSummary = messagesContainer.current;
|
|
42529
42506
|
if (!silent) {
|
|
42530
|
-
|
|
42507
|
+
console.warn(`Context length error — summarizing ${messagesForSummary.length} messages`);
|
|
42531
42508
|
}
|
|
42532
42509
|
try {
|
|
42533
42510
|
const summarizationStream = createSummarizationStream(messagesForSummary, { ...opts, _restartDepth: postReactiveDepth }, model);
|
|
@@ -42540,7 +42517,7 @@ function wrapStreamWithErrorHandler(originalStream, messagesContainer, opts, mod
|
|
|
42540
42517
|
}
|
|
42541
42518
|
if (!silent) {
|
|
42542
42519
|
const sumMsg = summarizeError instanceof Error ? summarizeError.message : String(summarizeError);
|
|
42543
|
-
|
|
42520
|
+
console.error(`Layer 3 summarization failed (${sumMsg}). Falling back to minimal-context restart.`);
|
|
42544
42521
|
}
|
|
42545
42522
|
opts.onSummarized?.("");
|
|
42546
42523
|
const minimalPrompt = typeof opts.prompt === "string" && opts.prompt.length > 0 ? opts.prompt.slice(0, 4000) : MINIMAL_RESTART_PROMPT;
|
|
@@ -42556,9 +42533,7 @@ function wrapStreamWithErrorHandler(originalStream, messagesContainer, opts, mod
|
|
|
42556
42533
|
}
|
|
42557
42534
|
} else {
|
|
42558
42535
|
if (!silent) {
|
|
42559
|
-
|
|
42560
|
-
error: errorMessage
|
|
42561
|
-
});
|
|
42536
|
+
console.error("Non-recoverable stream error, re-throwing:", errorMessage);
|
|
42562
42537
|
}
|
|
42563
42538
|
throw error;
|
|
42564
42539
|
}
|
|
@@ -42645,13 +42620,13 @@ function streamResponse(opts) {
|
|
|
42645
42620
|
fittedMessages = fitted.messages;
|
|
42646
42621
|
proactiveFitFailed = !fitted.fitsBudget;
|
|
42647
42622
|
if (fitted.modified && !silent) {
|
|
42648
|
-
|
|
42623
|
+
console.warn(`Proactive context fit: compacted messages to ~${fitted.estimatedInputTokens} tokens (fits=${fitted.fitsBudget})`);
|
|
42649
42624
|
}
|
|
42650
42625
|
}
|
|
42651
42626
|
const messagesContainer = { current: fittedMessages || [] };
|
|
42652
42627
|
if (proactiveFitFailed && fittedMessages) {
|
|
42653
42628
|
if (!silent) {
|
|
42654
|
-
|
|
42629
|
+
console.warn(`Proactive context fit returned fitsBudget=false on ${fittedMessages.length} messages — escalating to summarization before send`);
|
|
42655
42630
|
}
|
|
42656
42631
|
return wrapStreamWithErrorHandler(createSummarizationStream(fittedMessages, opts, providerModel), messagesContainer, opts, providerModel, silent);
|
|
42657
42632
|
}
|
|
@@ -42744,17 +42719,16 @@ function streamResponse(opts) {
|
|
|
42744
42719
|
}) => {
|
|
42745
42720
|
try {
|
|
42746
42721
|
if (!silent) {
|
|
42747
|
-
log
|
|
42748
|
-
|
|
42749
|
-
});
|
|
42722
|
+
console.log(`\uD83D\uDD27 Repairing tool call: ${toolCall.toolName}`);
|
|
42723
|
+
console.log(` Error: ${error.message || error}`);
|
|
42750
42724
|
if (error.message && (error.message.includes("severity") || error.message.includes("riskLevel"))) {
|
|
42751
|
-
log
|
|
42725
|
+
console.log(` Note: This appears to be an enum validation error. Tool call repair will normalize the value.`);
|
|
42752
42726
|
}
|
|
42753
42727
|
}
|
|
42754
42728
|
const tool6 = tools2[toolCall.toolName];
|
|
42755
42729
|
if (!tool6 || !tool6.inputSchema) {
|
|
42756
42730
|
if (!silent) {
|
|
42757
|
-
|
|
42731
|
+
console.error(`Cannot repair tool call: ${toolCall.toolName} not found or has no schema`);
|
|
42758
42732
|
}
|
|
42759
42733
|
return null;
|
|
42760
42734
|
}
|
|
@@ -42818,16 +42792,14 @@ function streamResponse(opts) {
|
|
|
42818
42792
|
}
|
|
42819
42793
|
if (repairedArgs === undefined || repairedArgs === null) {
|
|
42820
42794
|
if (!silent) {
|
|
42821
|
-
|
|
42795
|
+
console.error(`Tool call repair for "${toolCall.toolName}" produced no valid output`);
|
|
42822
42796
|
}
|
|
42823
42797
|
return null;
|
|
42824
42798
|
}
|
|
42825
42799
|
return { ...toolCall, input: JSON.stringify(repairedArgs) };
|
|
42826
42800
|
} catch (repairError) {
|
|
42827
42801
|
if (!silent) {
|
|
42828
|
-
|
|
42829
|
-
error: String(repairError)
|
|
42830
|
-
});
|
|
42802
|
+
console.error("Error repairing tool call:", repairError instanceof Error ? repairError.message : String(repairError));
|
|
42831
42803
|
}
|
|
42832
42804
|
return null;
|
|
42833
42805
|
}
|
|
@@ -42840,14 +42812,12 @@ function streamResponse(opts) {
|
|
|
42840
42812
|
const outerErrorMessage = error instanceof Error ? error.message : String(error);
|
|
42841
42813
|
if (isContextLengthError) {
|
|
42842
42814
|
if (!silent) {
|
|
42843
|
-
|
|
42815
|
+
console.warn(`Context length error, summarizing ${messagesContainer.current.length} messages: `, outerErrorMessage);
|
|
42844
42816
|
}
|
|
42845
42817
|
return wrapStreamWithErrorHandler(createSummarizationStream(messagesContainer.current, opts, providerModel), messagesContainer, opts, providerModel, silent);
|
|
42846
42818
|
}
|
|
42847
42819
|
if (!silent) {
|
|
42848
|
-
|
|
42849
|
-
error: outerErrorMessage
|
|
42850
|
-
});
|
|
42820
|
+
console.error("Non-context length error, re-throwing", outerErrorMessage);
|
|
42851
42821
|
}
|
|
42852
42822
|
throw error;
|
|
42853
42823
|
}
|
|
@@ -42920,17 +42890,14 @@ async function generateObjectResponse(opts) {
|
|
|
42920
42890
|
}
|
|
42921
42891
|
throw lastError;
|
|
42922
42892
|
}
|
|
42923
|
-
var
|
|
42893
|
+
var DEFAULT_OPENAI_REASONING_EFFORT = "medium", OPENAI_REASONING_MODEL_IDS, _usageCallback = null, MAX_RATE_LIMIT_RETRIES = 20, MAX_IDLE_RESUME_RETRIES = 3, STREAM_IDLE_TIMEOUT_MS, StreamIdleTimeoutError, MAX_OBJECT_RATE_LIMIT_RETRIES = 8, ContextLengthError, ContextLengthExhaustedError, MAX_RESTART_DEPTH = 3, MAX_TOOL_INPUT_CHARS = 8000, MAX_SCHEMA_CHARS = 6000, MINIMAL_RESTART_PROMPT = "Continue the previous task. Earlier context was discarded due to repeated context-length errors.";
|
|
42924
42894
|
var init_ai = __esm(() => {
|
|
42925
42895
|
init_dist4();
|
|
42926
|
-
init_structured();
|
|
42927
42896
|
init_observability();
|
|
42928
|
-
init_lazyLogger();
|
|
42929
42897
|
init_caching();
|
|
42930
42898
|
init_contextManagement();
|
|
42931
42899
|
init_models();
|
|
42932
42900
|
init_utils();
|
|
42933
|
-
log = scopedLogger(() => createLogger("ai"));
|
|
42934
42901
|
OPENAI_REASONING_MODEL_IDS = new Set([
|
|
42935
42902
|
"gpt-5",
|
|
42936
42903
|
"gpt-5-2025-08-07",
|
|
@@ -42970,1407 +42937,6 @@ var init_ai = __esm(() => {
|
|
|
42970
42937
|
};
|
|
42971
42938
|
});
|
|
42972
42939
|
|
|
42973
|
-
// src/core/ai/index.ts
|
|
42974
|
-
var init_ai2 = __esm(() => {
|
|
42975
|
-
init_ai();
|
|
42976
|
-
init_models();
|
|
42977
|
-
init_utils();
|
|
42978
|
-
});
|
|
42979
|
-
|
|
42980
|
-
// src/util/name.ts
|
|
42981
|
-
function generateRandomName() {
|
|
42982
|
-
const adj = adjectives[Math.floor(Math.random() * adjectives.length)] ?? "swift";
|
|
42983
|
-
const noun = nouns[Math.floor(Math.random() * nouns.length)] ?? "falcon";
|
|
42984
|
-
return `${adj}-${noun}`;
|
|
42985
|
-
}
|
|
42986
|
-
async function generateSessionName(opts) {
|
|
42987
|
-
const { targets, userMessage, model, authConfig, abortSignal } = opts;
|
|
42988
|
-
const contextParts = [];
|
|
42989
|
-
if (targets.length > 0) {
|
|
42990
|
-
contextParts.push(`Target(s): ${targets.join(", ")}`);
|
|
42991
|
-
}
|
|
42992
|
-
if (userMessage) {
|
|
42993
|
-
contextParts.push(`User objective: ${userMessage}`);
|
|
42994
|
-
}
|
|
42995
|
-
if (contextParts.length === 0)
|
|
42996
|
-
return null;
|
|
42997
|
-
const prompt = [
|
|
42998
|
-
"Generate a short, descriptive name for a penetration testing session.",
|
|
42999
|
-
"The name should be 2-4 lowercase words separated by hyphens.",
|
|
43000
|
-
"It should capture the key aspect of the target or task — e.g. 'acme-api-pentest', 'login-auth-bypass', 'ecommerce-checkout-test'.",
|
|
43001
|
-
"",
|
|
43002
|
-
...contextParts
|
|
43003
|
-
].join(`
|
|
43004
|
-
`);
|
|
43005
|
-
try {
|
|
43006
|
-
const result = await generateObjectResponse({
|
|
43007
|
-
model,
|
|
43008
|
-
schema: sessionNameSchema,
|
|
43009
|
-
prompt,
|
|
43010
|
-
maxTokens: 50,
|
|
43011
|
-
temperature: 0.7,
|
|
43012
|
-
authConfig,
|
|
43013
|
-
abortSignal
|
|
43014
|
-
});
|
|
43015
|
-
if (!result?.name)
|
|
43016
|
-
return null;
|
|
43017
|
-
const name29 = result.name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 50);
|
|
43018
|
-
return name29 || null;
|
|
43019
|
-
} catch {
|
|
43020
|
-
return null;
|
|
43021
|
-
}
|
|
43022
|
-
}
|
|
43023
|
-
var adjectives, nouns, sessionNameSchema;
|
|
43024
|
-
var init_name = __esm(() => {
|
|
43025
|
-
init_zod();
|
|
43026
|
-
init_ai2();
|
|
43027
|
-
adjectives = [
|
|
43028
|
-
"swift",
|
|
43029
|
-
"bright",
|
|
43030
|
-
"calm",
|
|
43031
|
-
"bold",
|
|
43032
|
-
"keen",
|
|
43033
|
-
"noble",
|
|
43034
|
-
"quick",
|
|
43035
|
-
"sharp",
|
|
43036
|
-
"vivid",
|
|
43037
|
-
"warm",
|
|
43038
|
-
"agile",
|
|
43039
|
-
"brave",
|
|
43040
|
-
"clever",
|
|
43041
|
-
"daring",
|
|
43042
|
-
"eager",
|
|
43043
|
-
"fierce",
|
|
43044
|
-
"gentle",
|
|
43045
|
-
"humble",
|
|
43046
|
-
"jolly",
|
|
43047
|
-
"lively",
|
|
43048
|
-
"merry",
|
|
43049
|
-
"nimble",
|
|
43050
|
-
"proud",
|
|
43051
|
-
"quiet",
|
|
43052
|
-
"rapid",
|
|
43053
|
-
"serene",
|
|
43054
|
-
"sturdy",
|
|
43055
|
-
"tender",
|
|
43056
|
-
"valiant",
|
|
43057
|
-
"witty",
|
|
43058
|
-
"zealous"
|
|
43059
|
-
];
|
|
43060
|
-
nouns = [
|
|
43061
|
-
"falcon",
|
|
43062
|
-
"wolf",
|
|
43063
|
-
"hawk",
|
|
43064
|
-
"bear",
|
|
43065
|
-
"lion",
|
|
43066
|
-
"tiger",
|
|
43067
|
-
"eagle",
|
|
43068
|
-
"raven",
|
|
43069
|
-
"phoenix",
|
|
43070
|
-
"dragon",
|
|
43071
|
-
"panther",
|
|
43072
|
-
"cobra",
|
|
43073
|
-
"viper",
|
|
43074
|
-
"shark",
|
|
43075
|
-
"orca",
|
|
43076
|
-
"mantis",
|
|
43077
|
-
"spider",
|
|
43078
|
-
"scorpion",
|
|
43079
|
-
"hydra",
|
|
43080
|
-
"griffin",
|
|
43081
|
-
"sphinx",
|
|
43082
|
-
"kraken",
|
|
43083
|
-
"cipher",
|
|
43084
|
-
"nexus",
|
|
43085
|
-
"prism",
|
|
43086
|
-
"vector",
|
|
43087
|
-
"matrix",
|
|
43088
|
-
"pulse",
|
|
43089
|
-
"surge",
|
|
43090
|
-
"flux"
|
|
43091
|
-
];
|
|
43092
|
-
sessionNameSchema = exports_external2.object({
|
|
43093
|
-
name: exports_external2.string().describe("A short, descriptive session name (2-4 words, lowercase, hyphenated)")
|
|
43094
|
-
});
|
|
43095
|
-
});
|
|
43096
|
-
|
|
43097
|
-
// src/core/credentials/manager.ts
|
|
43098
|
-
import { randomBytes } from "crypto";
|
|
43099
|
-
function generateCredentialId() {
|
|
43100
|
-
return `cred_${randomBytes(8).toString("hex")}`;
|
|
43101
|
-
}
|
|
43102
|
-
function inferType(cred) {
|
|
43103
|
-
const hasPwd = !!cred.password;
|
|
43104
|
-
const hasApiKey = !!cred.apiKey;
|
|
43105
|
-
const hasBearer = !!cred.tokens?.bearerToken;
|
|
43106
|
-
const hasHeaders = !!cred.tokens?.customHeaders && Object.keys(cred.tokens.customHeaders).length > 0;
|
|
43107
|
-
const hasCookies = !!cred.tokens?.cookies;
|
|
43108
|
-
const count = (hasPwd ? 1 : 0) + (hasApiKey ? 1 : 0) + (hasBearer ? 1 : 0) + (hasHeaders ? 1 : 0) + (hasCookies ? 1 : 0);
|
|
43109
|
-
if (count > 1)
|
|
43110
|
-
return "composite";
|
|
43111
|
-
if (hasPwd)
|
|
43112
|
-
return "username-password";
|
|
43113
|
-
if (hasApiKey)
|
|
43114
|
-
return "api-key";
|
|
43115
|
-
if (hasBearer)
|
|
43116
|
-
return "bearer-token";
|
|
43117
|
-
if (hasHeaders)
|
|
43118
|
-
return "custom-headers";
|
|
43119
|
-
if (hasCookies)
|
|
43120
|
-
return "cookies";
|
|
43121
|
-
return "username-password";
|
|
43122
|
-
}
|
|
43123
|
-
function toReference(stored) {
|
|
43124
|
-
const ref = {
|
|
43125
|
-
id: stored.id,
|
|
43126
|
-
type: stored.type
|
|
43127
|
-
};
|
|
43128
|
-
if (stored.label)
|
|
43129
|
-
ref.label = stored.label;
|
|
43130
|
-
if (stored.role)
|
|
43131
|
-
ref.role = stored.role;
|
|
43132
|
-
if (stored.username)
|
|
43133
|
-
ref.username = stored.username;
|
|
43134
|
-
if (stored.loginUrl)
|
|
43135
|
-
ref.loginUrl = stored.loginUrl;
|
|
43136
|
-
if (stored.tokens?.customHeaders) {
|
|
43137
|
-
ref.customHeaderKeys = Object.keys(stored.tokens.customHeaders);
|
|
43138
|
-
}
|
|
43139
|
-
const ctx = stored.metadata?.context;
|
|
43140
|
-
if (typeof ctx === "string" && ctx)
|
|
43141
|
-
ref.context = ctx;
|
|
43142
|
-
return ref;
|
|
43143
|
-
}
|
|
43144
|
-
|
|
43145
|
-
class CredentialManager {
|
|
43146
|
-
store = new Map;
|
|
43147
|
-
findDuplicate(candidate) {
|
|
43148
|
-
for (const [id, existing] of this.store) {
|
|
43149
|
-
if (existing.username === candidate.username && existing.password === candidate.password && existing.apiKey === candidate.apiKey && existing.loginUrl === candidate.loginUrl && existing.tokens?.bearerToken === candidate.tokens?.bearerToken && existing.tokens?.cookies === candidate.tokens?.cookies && existing.tokens?.sessionToken === candidate.tokens?.sessionToken && JSON.stringify(existing.tokens?.customHeaders) === JSON.stringify(candidate.tokens?.customHeaders)) {
|
|
43150
|
-
return id;
|
|
43151
|
-
}
|
|
43152
|
-
}
|
|
43153
|
-
return;
|
|
43154
|
-
}
|
|
43155
|
-
add(input) {
|
|
43156
|
-
const id = input.id ?? generateCredentialId();
|
|
43157
|
-
const type = input.type ?? inferType(input);
|
|
43158
|
-
const stored = { ...input, id, type };
|
|
43159
|
-
this.store.set(id, stored);
|
|
43160
|
-
return id;
|
|
43161
|
-
}
|
|
43162
|
-
addFromAuthCredentials(creds, extra) {
|
|
43163
|
-
const candidate = {
|
|
43164
|
-
username: creds.username,
|
|
43165
|
-
password: creds.password,
|
|
43166
|
-
apiKey: creds.apiKey,
|
|
43167
|
-
loginUrl: creds.loginUrl,
|
|
43168
|
-
additionalFields: creds.additionalFields,
|
|
43169
|
-
tokens: creds.tokens,
|
|
43170
|
-
label: extra?.label,
|
|
43171
|
-
role: extra?.role ?? creds.role,
|
|
43172
|
-
metadata: creds.context ? { context: creds.context } : undefined
|
|
43173
|
-
};
|
|
43174
|
-
const existingId = this.findDuplicate(candidate);
|
|
43175
|
-
if (existingId)
|
|
43176
|
-
return existingId;
|
|
43177
|
-
return this.add(candidate);
|
|
43178
|
-
}
|
|
43179
|
-
resolve(credentialId) {
|
|
43180
|
-
return this.store.get(credentialId);
|
|
43181
|
-
}
|
|
43182
|
-
getReference(credentialId) {
|
|
43183
|
-
const stored = this.store.get(credentialId);
|
|
43184
|
-
if (!stored)
|
|
43185
|
-
return;
|
|
43186
|
-
return toReference(stored);
|
|
43187
|
-
}
|
|
43188
|
-
listReferences() {
|
|
43189
|
-
return Array.from(this.store.values()).map(toReference);
|
|
43190
|
-
}
|
|
43191
|
-
listCredentialsWithHeaders() {
|
|
43192
|
-
const out = [];
|
|
43193
|
-
for (const stored of this.store.values()) {
|
|
43194
|
-
const headers = stored.tokens?.customHeaders;
|
|
43195
|
-
if (headers && Object.keys(headers).length > 0) {
|
|
43196
|
-
out.push({ tokens: { customHeaders: { ...headers } } });
|
|
43197
|
-
}
|
|
43198
|
-
}
|
|
43199
|
-
return out;
|
|
43200
|
-
}
|
|
43201
|
-
remove(credentialId) {
|
|
43202
|
-
return this.store.delete(credentialId);
|
|
43203
|
-
}
|
|
43204
|
-
get size() {
|
|
43205
|
-
return this.store.size;
|
|
43206
|
-
}
|
|
43207
|
-
clear() {
|
|
43208
|
-
this.store.clear();
|
|
43209
|
-
}
|
|
43210
|
-
toAuthCredentials(credentialId) {
|
|
43211
|
-
const stored = this.resolve(credentialId);
|
|
43212
|
-
if (!stored)
|
|
43213
|
-
return;
|
|
43214
|
-
const result = {};
|
|
43215
|
-
if (stored.username)
|
|
43216
|
-
result.username = stored.username;
|
|
43217
|
-
if (stored.password)
|
|
43218
|
-
result.password = stored.password;
|
|
43219
|
-
if (stored.apiKey)
|
|
43220
|
-
result.apiKey = stored.apiKey;
|
|
43221
|
-
if (stored.loginUrl)
|
|
43222
|
-
result.loginUrl = stored.loginUrl;
|
|
43223
|
-
if (stored.additionalFields)
|
|
43224
|
-
result.additionalFields = stored.additionalFields;
|
|
43225
|
-
if (stored.tokens)
|
|
43226
|
-
result.tokens = { ...stored.tokens };
|
|
43227
|
-
return result;
|
|
43228
|
-
}
|
|
43229
|
-
formatForPrompt() {
|
|
43230
|
-
const refs = this.listReferences();
|
|
43231
|
-
if (refs.length === 0)
|
|
43232
|
-
return "";
|
|
43233
|
-
const lines = refs.map((ref) => {
|
|
43234
|
-
const parts = [`- Credential ID: ${ref.id}`];
|
|
43235
|
-
if (ref.label)
|
|
43236
|
-
parts.push(` Label: ${ref.label}`);
|
|
43237
|
-
parts.push(` Type: ${ref.type}`);
|
|
43238
|
-
if (ref.role)
|
|
43239
|
-
parts.push(` Role: ${ref.role}`);
|
|
43240
|
-
if (ref.username)
|
|
43241
|
-
parts.push(` Username: ${ref.username}`);
|
|
43242
|
-
if (ref.loginUrl)
|
|
43243
|
-
parts.push(` Login URL: ${ref.loginUrl}`);
|
|
43244
|
-
if (ref.customHeaderKeys?.length) {
|
|
43245
|
-
parts.push(` Header keys: ${ref.customHeaderKeys.join(", ")}`);
|
|
43246
|
-
}
|
|
43247
|
-
if (ref.context)
|
|
43248
|
-
parts.push(` Context: ${ref.context}`);
|
|
43249
|
-
return parts.join(`
|
|
43250
|
-
`);
|
|
43251
|
-
});
|
|
43252
|
-
return `<available_credentials>
|
|
43253
|
-
The following credentials are available. To use a credential, pass its ID to the appropriate tool.
|
|
43254
|
-
Do NOT ask the user for passwords or secrets — they are resolved automatically from the credential ID.
|
|
43255
|
-
|
|
43256
|
-
${lines.join(`
|
|
43257
|
-
|
|
43258
|
-
`)}
|
|
43259
|
-
</available_credentials>`;
|
|
43260
|
-
}
|
|
43261
|
-
}
|
|
43262
|
-
var init_manager = () => {};
|
|
43263
|
-
|
|
43264
|
-
// src/core/credentials/index.ts
|
|
43265
|
-
var init_credentials = __esm(() => {
|
|
43266
|
-
init_manager();
|
|
43267
|
-
});
|
|
43268
|
-
|
|
43269
|
-
// src/core/id/id.ts
|
|
43270
|
-
import { randomBytes as randomBytes2 } from "crypto";
|
|
43271
|
-
function schema(prefix) {
|
|
43272
|
-
return zod_default.string().startsWith(prefixes[prefix]);
|
|
43273
|
-
}
|
|
43274
|
-
function descending(prefix, given) {
|
|
43275
|
-
return generateID(prefix, true, given);
|
|
43276
|
-
}
|
|
43277
|
-
function generateID(prefix, descending2, given) {
|
|
43278
|
-
if (!given) {
|
|
43279
|
-
return create(prefix, descending2);
|
|
43280
|
-
}
|
|
43281
|
-
if (!given.startsWith(prefixes[prefix])) {
|
|
43282
|
-
throw new Error(`ID ${given} does not start with ${prefixes[prefix]}`);
|
|
43283
|
-
}
|
|
43284
|
-
return given;
|
|
43285
|
-
}
|
|
43286
|
-
function randomBase62(length) {
|
|
43287
|
-
const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
43288
|
-
let result = "";
|
|
43289
|
-
const bytes = randomBytes2(length);
|
|
43290
|
-
for (let i = 0;i < length; i++) {
|
|
43291
|
-
result += chars[bytes[i] % 62];
|
|
43292
|
-
}
|
|
43293
|
-
return result;
|
|
43294
|
-
}
|
|
43295
|
-
function create(prefix, descending2, timestamp) {
|
|
43296
|
-
const currentTimestamp = timestamp ?? Date.now();
|
|
43297
|
-
if (currentTimestamp !== lastTimestamp) {
|
|
43298
|
-
lastTimestamp = currentTimestamp;
|
|
43299
|
-
counter = 0;
|
|
43300
|
-
}
|
|
43301
|
-
counter++;
|
|
43302
|
-
let now2 = BigInt(currentTimestamp) * BigInt(4096) + BigInt(counter);
|
|
43303
|
-
now2 = descending2 ? ~now2 : now2;
|
|
43304
|
-
const timeBytes = Buffer.alloc(6);
|
|
43305
|
-
for (let i = 0;i < 6; i++) {
|
|
43306
|
-
timeBytes[i] = Number(now2 >> BigInt(40 - 8 * i) & BigInt(255));
|
|
43307
|
-
}
|
|
43308
|
-
return prefixes[prefix] + "_" + timeBytes.toString("hex") + randomBase62(LENGTH - 12);
|
|
43309
|
-
}
|
|
43310
|
-
var prefixes, LENGTH = 26, lastTimestamp = 0, counter = 0;
|
|
43311
|
-
var init_id = __esm(() => {
|
|
43312
|
-
init_zod();
|
|
43313
|
-
prefixes = {
|
|
43314
|
-
session: "ses",
|
|
43315
|
-
message: "msg",
|
|
43316
|
-
permission: "per",
|
|
43317
|
-
user: "usr",
|
|
43318
|
-
part: "prt"
|
|
43319
|
-
};
|
|
43320
|
-
});
|
|
43321
|
-
|
|
43322
|
-
// src/core/services/rateLimiter/index.ts
|
|
43323
|
-
function sleep(ms) {
|
|
43324
|
-
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
43325
|
-
}
|
|
43326
|
-
|
|
43327
|
-
class RateLimiter {
|
|
43328
|
-
tokens;
|
|
43329
|
-
lastRefillTime;
|
|
43330
|
-
rps;
|
|
43331
|
-
bucketSize;
|
|
43332
|
-
msPerToken;
|
|
43333
|
-
queue;
|
|
43334
|
-
constructor(config2) {
|
|
43335
|
-
this.rps = config2?.requestsPerSecond;
|
|
43336
|
-
this.bucketSize = this.rps ? 1 : 0;
|
|
43337
|
-
this.tokens = this.bucketSize;
|
|
43338
|
-
this.lastRefillTime = performance.now();
|
|
43339
|
-
this.msPerToken = this.rps ? 1000 / this.rps : undefined;
|
|
43340
|
-
this.queue = Promise.resolve();
|
|
43341
|
-
}
|
|
43342
|
-
async acquireSlot() {
|
|
43343
|
-
if (!this.rps || !this.msPerToken)
|
|
43344
|
-
return;
|
|
43345
|
-
const previousPromise = this.queue;
|
|
43346
|
-
let resolveCurrentRequest;
|
|
43347
|
-
this.queue = new Promise((resolve4) => {
|
|
43348
|
-
resolveCurrentRequest = resolve4;
|
|
43349
|
-
});
|
|
43350
|
-
await previousPromise;
|
|
43351
|
-
try {
|
|
43352
|
-
const now2 = performance.now();
|
|
43353
|
-
this.refill(now2);
|
|
43354
|
-
if (this.tokens < 1) {
|
|
43355
|
-
const waitTime = (1 - this.tokens) * this.msPerToken;
|
|
43356
|
-
await sleep(waitTime);
|
|
43357
|
-
const nowAfterSleep = performance.now();
|
|
43358
|
-
this.refill(nowAfterSleep);
|
|
43359
|
-
}
|
|
43360
|
-
this.tokens -= 1;
|
|
43361
|
-
} finally {
|
|
43362
|
-
resolveCurrentRequest();
|
|
43363
|
-
}
|
|
43364
|
-
}
|
|
43365
|
-
refill(now2) {
|
|
43366
|
-
if (this.tokens >= this.bucketSize) {
|
|
43367
|
-
this.lastRefillTime = now2;
|
|
43368
|
-
return;
|
|
43369
|
-
}
|
|
43370
|
-
const elapsed = now2 - this.lastRefillTime;
|
|
43371
|
-
const tokensToAdd = elapsed / this.msPerToken;
|
|
43372
|
-
this.tokens = Math.min(this.bucketSize, this.tokens + tokensToAdd);
|
|
43373
|
-
this.lastRefillTime = now2;
|
|
43374
|
-
}
|
|
43375
|
-
isEnabled() {
|
|
43376
|
-
return this.rps !== undefined;
|
|
43377
|
-
}
|
|
43378
|
-
}
|
|
43379
|
-
var init_rateLimiter = () => {};
|
|
43380
|
-
|
|
43381
|
-
// src/util/errors.ts
|
|
43382
|
-
var NamedError;
|
|
43383
|
-
var init_errors = __esm(() => {
|
|
43384
|
-
init_zod();
|
|
43385
|
-
NamedError = class NamedError extends Error {
|
|
43386
|
-
static create(name29, data) {
|
|
43387
|
-
const schema2 = zod_default.object({
|
|
43388
|
-
name: zod_default.literal(name29),
|
|
43389
|
-
data
|
|
43390
|
-
});
|
|
43391
|
-
const result = class extends NamedError {
|
|
43392
|
-
data;
|
|
43393
|
-
static Schema = schema2;
|
|
43394
|
-
name = name29;
|
|
43395
|
-
constructor(data2, options) {
|
|
43396
|
-
super(name29, options);
|
|
43397
|
-
this.data = data2;
|
|
43398
|
-
this.name = name29;
|
|
43399
|
-
}
|
|
43400
|
-
static isInstance(input) {
|
|
43401
|
-
return typeof input === "object" && input !== null && "name" in input && input.name === name29;
|
|
43402
|
-
}
|
|
43403
|
-
schema() {
|
|
43404
|
-
return schema2;
|
|
43405
|
-
}
|
|
43406
|
-
toObject() {
|
|
43407
|
-
return {
|
|
43408
|
-
name: name29,
|
|
43409
|
-
data: this.data
|
|
43410
|
-
};
|
|
43411
|
-
}
|
|
43412
|
-
};
|
|
43413
|
-
Object.defineProperty(result, "name", { value: name29 });
|
|
43414
|
-
return result;
|
|
43415
|
-
}
|
|
43416
|
-
static Unknown = NamedError.create("UnknownError", zod_default.object({
|
|
43417
|
-
message: zod_default.string()
|
|
43418
|
-
}));
|
|
43419
|
-
};
|
|
43420
|
-
});
|
|
43421
|
-
|
|
43422
|
-
// src/util/lock.ts
|
|
43423
|
-
function getLock(key) {
|
|
43424
|
-
let lock = locks.get(key);
|
|
43425
|
-
if (!lock) {
|
|
43426
|
-
lock = {
|
|
43427
|
-
readers: 0,
|
|
43428
|
-
writer: false,
|
|
43429
|
-
waitingReaders: [],
|
|
43430
|
-
waitingWriters: []
|
|
43431
|
-
};
|
|
43432
|
-
locks.set(key, lock);
|
|
43433
|
-
}
|
|
43434
|
-
return lock;
|
|
43435
|
-
}
|
|
43436
|
-
function processQueue(key) {
|
|
43437
|
-
const lock = locks.get(key);
|
|
43438
|
-
if (!lock || lock.writer || lock.readers > 0)
|
|
43439
|
-
return;
|
|
43440
|
-
if (lock.waitingWriters.length > 0) {
|
|
43441
|
-
const nextWriter = lock.waitingWriters.shift();
|
|
43442
|
-
nextWriter?.();
|
|
43443
|
-
return;
|
|
43444
|
-
}
|
|
43445
|
-
while (lock.waitingReaders.length > 0) {
|
|
43446
|
-
const nextReader = lock.waitingReaders.shift();
|
|
43447
|
-
nextReader?.();
|
|
43448
|
-
}
|
|
43449
|
-
if (lock.readers === 0 && !lock.writer && lock.waitingReaders.length === 0 && lock.waitingWriters.length === 0) {
|
|
43450
|
-
locks.delete(key);
|
|
43451
|
-
}
|
|
43452
|
-
}
|
|
43453
|
-
async function read(key) {
|
|
43454
|
-
const lock = getLock(key);
|
|
43455
|
-
return new Promise((resolve4) => {
|
|
43456
|
-
if (!lock.writer && lock.waitingWriters.length === 0) {
|
|
43457
|
-
lock.readers++;
|
|
43458
|
-
resolve4({
|
|
43459
|
-
[Symbol.dispose]: () => {
|
|
43460
|
-
lock.readers--;
|
|
43461
|
-
processQueue(key);
|
|
43462
|
-
}
|
|
43463
|
-
});
|
|
43464
|
-
} else {
|
|
43465
|
-
lock.waitingReaders.push(() => {
|
|
43466
|
-
lock.readers++;
|
|
43467
|
-
resolve4({
|
|
43468
|
-
[Symbol.dispose]: () => {
|
|
43469
|
-
lock.readers--;
|
|
43470
|
-
processQueue(key);
|
|
43471
|
-
}
|
|
43472
|
-
});
|
|
43473
|
-
});
|
|
43474
|
-
}
|
|
43475
|
-
});
|
|
43476
|
-
}
|
|
43477
|
-
async function write(key) {
|
|
43478
|
-
const lock = getLock(key);
|
|
43479
|
-
return new Promise((resolve4) => {
|
|
43480
|
-
if (!lock.writer && lock.readers === 0) {
|
|
43481
|
-
lock.writer = true;
|
|
43482
|
-
resolve4({
|
|
43483
|
-
[Symbol.dispose]: () => {
|
|
43484
|
-
lock.writer = false;
|
|
43485
|
-
processQueue(key);
|
|
43486
|
-
}
|
|
43487
|
-
});
|
|
43488
|
-
} else {
|
|
43489
|
-
lock.waitingWriters.push(() => {
|
|
43490
|
-
lock.writer = true;
|
|
43491
|
-
resolve4({
|
|
43492
|
-
[Symbol.dispose]: () => {
|
|
43493
|
-
lock.writer = false;
|
|
43494
|
-
processQueue(key);
|
|
43495
|
-
}
|
|
43496
|
-
});
|
|
43497
|
-
});
|
|
43498
|
-
}
|
|
43499
|
-
});
|
|
43500
|
-
}
|
|
43501
|
-
var locks;
|
|
43502
|
-
var init_lock = __esm(() => {
|
|
43503
|
-
locks = new Map;
|
|
43504
|
-
});
|
|
43505
|
-
|
|
43506
|
-
// src/core/storage/index.ts
|
|
43507
|
-
import fs, { readdir } from "fs/promises";
|
|
43508
|
-
import os from "os";
|
|
43509
|
-
import path from "path";
|
|
43510
|
-
function getBaseDir() {
|
|
43511
|
-
return process.env.PENSAR_DATA_DIR ?? path.join(os.homedir(), ".pensar");
|
|
43512
|
-
}
|
|
43513
|
-
async function write2(key, content, ext) {
|
|
43514
|
-
const dir = getBaseDir();
|
|
43515
|
-
const target = path.join(dir, ...key) + (ext ? ext : ".json");
|
|
43516
|
-
return withErrorHandling(async () => {
|
|
43517
|
-
let __stack = [];
|
|
43518
|
-
try {
|
|
43519
|
-
const _ = __using(__stack, await write(target), 0);
|
|
43520
|
-
await fs.mkdir(path.dirname(target), { recursive: true });
|
|
43521
|
-
await fs.writeFile(target, JSON.stringify(content, null, 2), "utf-8");
|
|
43522
|
-
} catch (_catch) {
|
|
43523
|
-
var _err = _catch, _hasErr = 1;
|
|
43524
|
-
} finally {
|
|
43525
|
-
__callDispose(__stack, _err, _hasErr);
|
|
43526
|
-
}
|
|
43527
|
-
});
|
|
43528
|
-
}
|
|
43529
|
-
async function createDir(key) {
|
|
43530
|
-
const dir = getBaseDir();
|
|
43531
|
-
const target = path.join(dir, ...key);
|
|
43532
|
-
return withErrorHandling(async () => {
|
|
43533
|
-
let __stack = [];
|
|
43534
|
-
try {
|
|
43535
|
-
const _ = __using(__stack, await write(target), 0);
|
|
43536
|
-
await fs.mkdir(target, { recursive: true });
|
|
43537
|
-
} catch (_catch) {
|
|
43538
|
-
var _err = _catch, _hasErr = 1;
|
|
43539
|
-
} finally {
|
|
43540
|
-
__callDispose(__stack, _err, _hasErr);
|
|
43541
|
-
}
|
|
43542
|
-
});
|
|
43543
|
-
}
|
|
43544
|
-
async function writeRaw(key, content) {
|
|
43545
|
-
const dir = getBaseDir();
|
|
43546
|
-
const target = path.join(dir, ...key);
|
|
43547
|
-
return withErrorHandling(async () => {
|
|
43548
|
-
let __stack = [];
|
|
43549
|
-
try {
|
|
43550
|
-
const _ = __using(__stack, await write(target), 0);
|
|
43551
|
-
const parentDir = path.dirname(target);
|
|
43552
|
-
await fs.mkdir(parentDir, { recursive: true });
|
|
43553
|
-
await fs.writeFile(target, content, "utf-8");
|
|
43554
|
-
} catch (_catch) {
|
|
43555
|
-
var _err = _catch, _hasErr = 1;
|
|
43556
|
-
} finally {
|
|
43557
|
-
__callDispose(__stack, _err, _hasErr);
|
|
43558
|
-
}
|
|
43559
|
-
});
|
|
43560
|
-
}
|
|
43561
|
-
async function read2(key, ext) {
|
|
43562
|
-
const dir = getBaseDir();
|
|
43563
|
-
const target = path.join(dir, ...key) + (ext ? ext : ".json");
|
|
43564
|
-
return withErrorHandling(async () => {
|
|
43565
|
-
let __stack = [];
|
|
43566
|
-
try {
|
|
43567
|
-
const _ = __using(__stack, await read(target), 0);
|
|
43568
|
-
const text2 = await fs.readFile(target, "utf-8");
|
|
43569
|
-
const result = ext ? text2 : JSON.parse(text2);
|
|
43570
|
-
return result;
|
|
43571
|
-
} catch (_catch) {
|
|
43572
|
-
var _err = _catch, _hasErr = 1;
|
|
43573
|
-
} finally {
|
|
43574
|
-
__callDispose(__stack, _err, _hasErr);
|
|
43575
|
-
}
|
|
43576
|
-
});
|
|
43577
|
-
}
|
|
43578
|
-
async function update(key, fn, ext) {
|
|
43579
|
-
const dir = getBaseDir();
|
|
43580
|
-
const target = path.join(dir, ...key) + (ext ? ext : ".json");
|
|
43581
|
-
return withErrorHandling(async () => {
|
|
43582
|
-
let __stack = [];
|
|
43583
|
-
try {
|
|
43584
|
-
const _ = __using(__stack, await write(target), 0);
|
|
43585
|
-
const text2 = await fs.readFile(target, "utf-8");
|
|
43586
|
-
const content = ext ? text2 : JSON.parse(text2);
|
|
43587
|
-
fn(content);
|
|
43588
|
-
await fs.writeFile(target, JSON.stringify(content, null, 2), "utf-8");
|
|
43589
|
-
return content;
|
|
43590
|
-
} catch (_catch) {
|
|
43591
|
-
var _err = _catch, _hasErr = 1;
|
|
43592
|
-
} finally {
|
|
43593
|
-
__callDispose(__stack, _err, _hasErr);
|
|
43594
|
-
}
|
|
43595
|
-
});
|
|
43596
|
-
}
|
|
43597
|
-
async function withErrorHandling(body) {
|
|
43598
|
-
return body().catch((e) => {
|
|
43599
|
-
if (!(e instanceof Error))
|
|
43600
|
-
throw e;
|
|
43601
|
-
const errnoExcpetion = e;
|
|
43602
|
-
if (errnoExcpetion.code === "ENOENT") {
|
|
43603
|
-
throw new NotFoundError({
|
|
43604
|
-
message: `Resource not found: ${errnoExcpetion.path}`
|
|
43605
|
-
});
|
|
43606
|
-
}
|
|
43607
|
-
throw e;
|
|
43608
|
-
});
|
|
43609
|
-
}
|
|
43610
|
-
async function listFilesRecursively(dir) {
|
|
43611
|
-
const entries = await readdir(dir, { withFileTypes: true });
|
|
43612
|
-
const files = [];
|
|
43613
|
-
for (const entry of entries) {
|
|
43614
|
-
const fullPath = path.join(dir, entry.name);
|
|
43615
|
-
if (entry.isDirectory()) {
|
|
43616
|
-
files.push(...await listFilesRecursively(fullPath));
|
|
43617
|
-
} else {
|
|
43618
|
-
files.push(fullPath);
|
|
43619
|
-
}
|
|
43620
|
-
}
|
|
43621
|
-
return files;
|
|
43622
|
-
}
|
|
43623
|
-
async function list(prefix) {
|
|
43624
|
-
const dir = getBaseDir();
|
|
43625
|
-
const targetDir = path.join(dir, ...prefix);
|
|
43626
|
-
try {
|
|
43627
|
-
const files = await listFilesRecursively(targetDir);
|
|
43628
|
-
const result = files.map((filePath) => {
|
|
43629
|
-
const relativePath = path.relative(targetDir, filePath);
|
|
43630
|
-
return [...prefix, ...relativePath.slice(0, -5).split(path.sep)];
|
|
43631
|
-
});
|
|
43632
|
-
result.sort();
|
|
43633
|
-
return result;
|
|
43634
|
-
} catch {
|
|
43635
|
-
return [];
|
|
43636
|
-
}
|
|
43637
|
-
}
|
|
43638
|
-
var NotFoundError;
|
|
43639
|
-
var init_storage = __esm(() => {
|
|
43640
|
-
init_zod();
|
|
43641
|
-
init_errors();
|
|
43642
|
-
init_lock();
|
|
43643
|
-
NotFoundError = NamedError.create("NotFoundError", zod_default.object({
|
|
43644
|
-
message: zod_default.string()
|
|
43645
|
-
}));
|
|
43646
|
-
});
|
|
43647
|
-
|
|
43648
|
-
// src/core/toolset/index.ts
|
|
43649
|
-
var ToolsetStateSchema;
|
|
43650
|
-
var init_toolset = __esm(() => {
|
|
43651
|
-
init_zod();
|
|
43652
|
-
ToolsetStateSchema = exports_external2.object({
|
|
43653
|
-
baseToolsetId: exports_external2.string(),
|
|
43654
|
-
enabledTools: exports_external2.record(exports_external2.string(), exports_external2.boolean()),
|
|
43655
|
-
lastModified: exports_external2.number()
|
|
43656
|
-
});
|
|
43657
|
-
});
|
|
43658
|
-
|
|
43659
|
-
// src/core/session/index.ts
|
|
43660
|
-
import { existsSync, readFileSync } from "fs";
|
|
43661
|
-
import os2 from "os";
|
|
43662
|
-
import path2 from "path";
|
|
43663
|
-
function resolveSmtpConfig(explicit) {
|
|
43664
|
-
if (explicit)
|
|
43665
|
-
return explicit;
|
|
43666
|
-
const fromAddress = process.env.OUTBOUND_EMAIL;
|
|
43667
|
-
const resendKey = process.env.RESEND_API_KEY;
|
|
43668
|
-
if (resendKey) {
|
|
43669
|
-
return {
|
|
43670
|
-
host: "smtp.resend.com",
|
|
43671
|
-
port: 465,
|
|
43672
|
-
username: "resend",
|
|
43673
|
-
password: resendKey,
|
|
43674
|
-
tls: true,
|
|
43675
|
-
fromAddress
|
|
43676
|
-
};
|
|
43677
|
-
}
|
|
43678
|
-
const host = process.env.SMTP_HOST;
|
|
43679
|
-
const port = process.env.SMTP_PORT;
|
|
43680
|
-
const username = process.env.SMTP_USERNAME;
|
|
43681
|
-
const password = process.env.SMTP_PASSWORD;
|
|
43682
|
-
if (host && port && username && password) {
|
|
43683
|
-
return {
|
|
43684
|
-
host,
|
|
43685
|
-
port: parseInt(port, 10),
|
|
43686
|
-
username,
|
|
43687
|
-
password,
|
|
43688
|
-
tls: process.env.SMTP_TLS !== "false",
|
|
43689
|
-
fromAddress
|
|
43690
|
-
};
|
|
43691
|
-
}
|
|
43692
|
-
return;
|
|
43693
|
-
}
|
|
43694
|
-
function getPensarDir() {
|
|
43695
|
-
return path2.join(os2.homedir(), ".pensar");
|
|
43696
|
-
}
|
|
43697
|
-
function getSessionsDir() {
|
|
43698
|
-
return path2.join(getPensarDir(), "sessions");
|
|
43699
|
-
}
|
|
43700
|
-
function getSessionRoot(id) {
|
|
43701
|
-
return path2.join(getSessionsDir(), id);
|
|
43702
|
-
}
|
|
43703
|
-
async function createSessionDirs(input) {
|
|
43704
|
-
const { session } = input;
|
|
43705
|
-
await createDir(["sessions", session.id]);
|
|
43706
|
-
await createDir(["sessions", session.id, "findings"]);
|
|
43707
|
-
await createDir(["sessions", session.id, "scratchpad"]);
|
|
43708
|
-
await createDir(["sessions", session.id, "logs"]);
|
|
43709
|
-
await createDir(["sessions", session.id, "pocs"]);
|
|
43710
|
-
const startTime = new Date().toISOString();
|
|
43711
|
-
const readme = generateSessionReadme(session);
|
|
43712
|
-
await writeRaw(["sessions", session.id, "README.md"], readme);
|
|
43713
|
-
console.info("created session", session.id);
|
|
43714
|
-
}
|
|
43715
|
-
function generateSessionReadme(session) {
|
|
43716
|
-
return `# Penetration Test Session
|
|
43717
|
-
|
|
43718
|
-
**Session ID:** ${session.id}
|
|
43719
|
-
**Target:** ${session.targets}
|
|
43720
|
-
**Objective:** ${session.config?.outcomeGuidance}
|
|
43721
|
-
**Started:** ${session.time.created}
|
|
43722
|
-
|
|
43723
|
-
## Directory Structure
|
|
43724
|
-
|
|
43725
|
-
- \`findings/\` - Security findings and vulnerabilities
|
|
43726
|
-
- \`scratchpad/\` - Notes and temporary data during testing
|
|
43727
|
-
- \`logs/\` - Execution logs and command outputs
|
|
43728
|
-
- \`pocs/\` - Proof-of-concept exploit scripts
|
|
43729
|
-
- \`session.json\` - Session metadata
|
|
43730
|
-
|
|
43731
|
-
## Findings
|
|
43732
|
-
|
|
43733
|
-
Security findings will be documented in the \`findings/\` directory as individual files.
|
|
43734
|
-
|
|
43735
|
-
## Status
|
|
43736
|
-
|
|
43737
|
-
Testing in progress...
|
|
43738
|
-
`;
|
|
43739
|
-
}
|
|
43740
|
-
function normalizeDeprecatedHeaders(config2) {
|
|
43741
|
-
if (!config2)
|
|
43742
|
-
return config2;
|
|
43743
|
-
if (config2.offensiveHeaders == null) {
|
|
43744
|
-
const { offensiveHeaders: _drop, ...rest2 } = config2;
|
|
43745
|
-
return rest2;
|
|
43746
|
-
}
|
|
43747
|
-
const { offensiveHeaders, ...rest } = config2;
|
|
43748
|
-
const restWithHeaders = rest;
|
|
43749
|
-
if (restWithHeaders.headers !== undefined) {
|
|
43750
|
-
return restWithHeaders;
|
|
43751
|
-
}
|
|
43752
|
-
const oh = offensiveHeaders;
|
|
43753
|
-
if (oh.mode === "none") {
|
|
43754
|
-
return { ...restWithHeaders, headers: {} };
|
|
43755
|
-
}
|
|
43756
|
-
let headers = {};
|
|
43757
|
-
if (oh.mode === "default")
|
|
43758
|
-
headers = { ...DEFAULT_HEADER_RECORD };
|
|
43759
|
-
if (oh.headers)
|
|
43760
|
-
headers = { ...headers, ...oh.headers };
|
|
43761
|
-
return { ...restWithHeaders, headers };
|
|
43762
|
-
}
|
|
43763
|
-
function migrateLegacySessionData(input) {
|
|
43764
|
-
if (!input || typeof input !== "object")
|
|
43765
|
-
return input;
|
|
43766
|
-
const root = input;
|
|
43767
|
-
const config2 = root.config;
|
|
43768
|
-
if (!config2 || typeof config2 !== "object")
|
|
43769
|
-
return input;
|
|
43770
|
-
const cfg = config2;
|
|
43771
|
-
if (!("offensiveHeaders" in cfg))
|
|
43772
|
-
return input;
|
|
43773
|
-
return { ...root, config: normalizeDeprecatedHeaders(cfg) };
|
|
43774
|
-
}
|
|
43775
|
-
async function create2(input) {
|
|
43776
|
-
const name29 = input.name ?? generateRandomName();
|
|
43777
|
-
const normalizedConfig = normalizeDeprecatedHeaders(input.config);
|
|
43778
|
-
const id = `${input.prefix ? input.prefix : ""}` + descending("session", input.id);
|
|
43779
|
-
const rootPath = getSessionRoot(id);
|
|
43780
|
-
const findingsPath = path2.join(rootPath, "findings");
|
|
43781
|
-
const scratchpadPath = path2.join(rootPath, "scratchpad");
|
|
43782
|
-
const logsPath = path2.join(rootPath, "logs");
|
|
43783
|
-
const pocsPath = path2.join(rootPath, "pocs");
|
|
43784
|
-
const rateLimiter = new RateLimiter({
|
|
43785
|
-
requestsPerSecond: normalizedConfig?.requestsPerSecond
|
|
43786
|
-
});
|
|
43787
|
-
let credentialManager;
|
|
43788
|
-
if (normalizedConfig?.authCredentials) {
|
|
43789
|
-
credentialManager = new CredentialManager;
|
|
43790
|
-
const creds = Array.isArray(normalizedConfig.authCredentials) ? normalizedConfig.authCredentials : [normalizedConfig.authCredentials];
|
|
43791
|
-
for (const cred of creds) {
|
|
43792
|
-
credentialManager.addFromAuthCredentials(cred);
|
|
43793
|
-
}
|
|
43794
|
-
}
|
|
43795
|
-
const smtpConfig = resolveSmtpConfig(normalizedConfig?.smtpConfig);
|
|
43796
|
-
let snapshotHeaders;
|
|
43797
|
-
if (normalizedConfig?.headers !== undefined) {
|
|
43798
|
-
snapshotHeaders = { ...normalizedConfig.headers };
|
|
43799
|
-
} else {
|
|
43800
|
-
const { config: appConfig } = await import("./index-ah3cm7hf.js");
|
|
43801
|
-
const cfg = await appConfig.get();
|
|
43802
|
-
snapshotHeaders = cfg.defaultHeaders ? { ...cfg.defaultHeaders } : { ...DEFAULT_HEADER_RECORD };
|
|
43803
|
-
}
|
|
43804
|
-
const result = {
|
|
43805
|
-
id,
|
|
43806
|
-
version: getCurrentVersion(),
|
|
43807
|
-
targets: input.targets,
|
|
43808
|
-
name: name29,
|
|
43809
|
-
time: {
|
|
43810
|
-
created: Date.now(),
|
|
43811
|
-
updated: Date.now()
|
|
43812
|
-
},
|
|
43813
|
-
config: {
|
|
43814
|
-
...normalizedConfig,
|
|
43815
|
-
mode: normalizedConfig?.mode || "auto",
|
|
43816
|
-
headers: snapshotHeaders,
|
|
43817
|
-
outcomeGuidance: normalizedConfig?.outcomeGuidance || (normalizedConfig?.exfilMode ? EXFIL_OUTCOME_GUIDANCE : DEFAULT_OUTCOME_GUIDANCE),
|
|
43818
|
-
smtpConfig
|
|
43819
|
-
},
|
|
43820
|
-
_rateLimiter: rateLimiter,
|
|
43821
|
-
credentialManager,
|
|
43822
|
-
rootPath,
|
|
43823
|
-
logsPath,
|
|
43824
|
-
pocsPath,
|
|
43825
|
-
scratchpadPath,
|
|
43826
|
-
findingsPath
|
|
43827
|
-
};
|
|
43828
|
-
const { _rateLimiter, credentialManager: _cm, ...sessionData } = result;
|
|
43829
|
-
await createSessionDirs({ session: result });
|
|
43830
|
-
await write2(["sessions", result.id, "session"], sessionData);
|
|
43831
|
-
if (!input.name && input.model) {
|
|
43832
|
-
generateSessionName({
|
|
43833
|
-
targets: input.targets,
|
|
43834
|
-
userMessage: input.userMessage,
|
|
43835
|
-
model: input.model,
|
|
43836
|
-
authConfig: input.authConfig
|
|
43837
|
-
}).then((aiName) => {
|
|
43838
|
-
if (aiName) {
|
|
43839
|
-
result.name = aiName;
|
|
43840
|
-
update2(result.id, (s) => {
|
|
43841
|
-
s.name = aiName;
|
|
43842
|
-
}).catch(() => {});
|
|
43843
|
-
input.onNameGenerated?.(aiName);
|
|
43844
|
-
}
|
|
43845
|
-
});
|
|
43846
|
-
}
|
|
43847
|
-
return result;
|
|
43848
|
-
}
|
|
43849
|
-
async function update2(id, editor) {
|
|
43850
|
-
const result = await update(["sessions", id, "session"], (draft) => {
|
|
43851
|
-
editor(draft);
|
|
43852
|
-
draft.time.updated = Date.now();
|
|
43853
|
-
});
|
|
43854
|
-
return result;
|
|
43855
|
-
}
|
|
43856
|
-
async function* list2() {
|
|
43857
|
-
const sessionsDir = getSessionsDir();
|
|
43858
|
-
let entries;
|
|
43859
|
-
try {
|
|
43860
|
-
entries = await import("fs/promises").then((fsp) => fsp.readdir(sessionsDir, { withFileTypes: true }));
|
|
43861
|
-
} catch {
|
|
43862
|
-
return;
|
|
43863
|
-
}
|
|
43864
|
-
for (const entry of entries) {
|
|
43865
|
-
if (!entry.isDirectory())
|
|
43866
|
-
continue;
|
|
43867
|
-
try {
|
|
43868
|
-
yield await read2([
|
|
43869
|
-
"sessions",
|
|
43870
|
-
entry.name,
|
|
43871
|
-
"session"
|
|
43872
|
-
]);
|
|
43873
|
-
} catch {}
|
|
43874
|
-
}
|
|
43875
|
-
}
|
|
43876
|
-
async function loadOperatorState(sessionId) {
|
|
43877
|
-
try {
|
|
43878
|
-
const session = await get(sessionId);
|
|
43879
|
-
const statePath = path2.join(session.rootPath, "messages.json");
|
|
43880
|
-
if (!existsSync(statePath))
|
|
43881
|
-
return null;
|
|
43882
|
-
const data = readFileSync(statePath, "utf-8");
|
|
43883
|
-
const parsed = JSON.parse(data);
|
|
43884
|
-
if (Array.isArray(parsed)) {
|
|
43885
|
-
return {
|
|
43886
|
-
mode: session.config?.operatorSettings?.initialMode ?? "manual",
|
|
43887
|
-
requireApproval: session.config?.operatorSettings?.requireApproval ?? true,
|
|
43888
|
-
currentStage: "recon",
|
|
43889
|
-
messages: parsed,
|
|
43890
|
-
attackSurface: [],
|
|
43891
|
-
credentials: [],
|
|
43892
|
-
verifiedVulns: [],
|
|
43893
|
-
targetState: null,
|
|
43894
|
-
hypotheses: [],
|
|
43895
|
-
evidence: [],
|
|
43896
|
-
actionHistory: [],
|
|
43897
|
-
pausedAt: new Date().toISOString(),
|
|
43898
|
-
lastRunId: ""
|
|
43899
|
-
};
|
|
43900
|
-
}
|
|
43901
|
-
return parsed;
|
|
43902
|
-
} catch (error) {
|
|
43903
|
-
console.error("Error loading operator state:", error);
|
|
43904
|
-
return null;
|
|
43905
|
-
}
|
|
43906
|
-
}
|
|
43907
|
-
function hasOperatorState(session) {
|
|
43908
|
-
const statePath = path2.join(session.rootPath, "messages.json");
|
|
43909
|
-
return existsSync(statePath);
|
|
43910
|
-
}
|
|
43911
|
-
function getResumeMessages(messages, limit = MAX_RESUME_MESSAGES) {
|
|
43912
|
-
if (messages.length <= limit)
|
|
43913
|
-
return messages;
|
|
43914
|
-
let cutIndex = messages.length - limit;
|
|
43915
|
-
while (cutIndex < messages.length) {
|
|
43916
|
-
if (messages[cutIndex].role === "user")
|
|
43917
|
-
break;
|
|
43918
|
-
cutIndex++;
|
|
43919
|
-
}
|
|
43920
|
-
if (cutIndex >= messages.length) {
|
|
43921
|
-
cutIndex = messages.length - limit;
|
|
43922
|
-
}
|
|
43923
|
-
return messages.slice(cutIndex);
|
|
43924
|
-
}
|
|
43925
|
-
function normalizeMessages(messages) {
|
|
43926
|
-
if (messages.length <= 1)
|
|
43927
|
-
return fixToolOutputs(messages);
|
|
43928
|
-
const result = [];
|
|
43929
|
-
for (const msg of messages) {
|
|
43930
|
-
const prev = result[result.length - 1];
|
|
43931
|
-
if (prev && prev.role === "user" && msg.role === "user" && typeof prev.content === "string" && typeof msg.content === "string") {
|
|
43932
|
-
result[result.length - 1] = {
|
|
43933
|
-
...prev,
|
|
43934
|
-
content: `${prev.content}
|
|
43935
|
-
|
|
43936
|
-
${msg.content}`
|
|
43937
|
-
};
|
|
43938
|
-
} else if (prev && prev.role === "user" && msg.role === "user") {
|
|
43939
|
-
result[result.length - 1] = msg;
|
|
43940
|
-
} else {
|
|
43941
|
-
result.push(msg);
|
|
43942
|
-
}
|
|
43943
|
-
}
|
|
43944
|
-
return fixToolOutputs(result);
|
|
43945
|
-
}
|
|
43946
|
-
function fixToolOutputs(messages) {
|
|
43947
|
-
let changed = false;
|
|
43948
|
-
const fixed = messages.map((msg) => {
|
|
43949
|
-
if (msg.role !== "tool" || !Array.isArray(msg.content))
|
|
43950
|
-
return msg;
|
|
43951
|
-
let partChanged = false;
|
|
43952
|
-
const fixedContent = msg.content.map((part) => {
|
|
43953
|
-
if (part.type === "tool-result" && typeof part.output === "string") {
|
|
43954
|
-
partChanged = true;
|
|
43955
|
-
return { ...part, output: { type: "text", value: part.output } };
|
|
43956
|
-
}
|
|
43957
|
-
return part;
|
|
43958
|
-
});
|
|
43959
|
-
if (partChanged) {
|
|
43960
|
-
changed = true;
|
|
43961
|
-
return { ...msg, content: fixedContent };
|
|
43962
|
-
}
|
|
43963
|
-
return msg;
|
|
43964
|
-
});
|
|
43965
|
-
return changed ? fixed : messages;
|
|
43966
|
-
}
|
|
43967
|
-
async function updateOperatorSettings(sessionId, settings) {
|
|
43968
|
-
return await update2(sessionId, (session) => {
|
|
43969
|
-
if (!session.config) {
|
|
43970
|
-
session.config = {};
|
|
43971
|
-
}
|
|
43972
|
-
if (!session.config.operatorSettings) {
|
|
43973
|
-
session.config.operatorSettings = {
|
|
43974
|
-
initialMode: "manual",
|
|
43975
|
-
requireApproval: true,
|
|
43976
|
-
enableSuggestions: true
|
|
43977
|
-
};
|
|
43978
|
-
}
|
|
43979
|
-
if (settings.initialMode !== undefined) {
|
|
43980
|
-
session.config.operatorSettings.initialMode = settings.initialMode;
|
|
43981
|
-
}
|
|
43982
|
-
if (settings.requireApproval !== undefined) {
|
|
43983
|
-
session.config.operatorSettings.requireApproval = settings.requireApproval;
|
|
43984
|
-
}
|
|
43985
|
-
if (settings.enableSuggestions !== undefined) {
|
|
43986
|
-
session.config.operatorSettings.enableSuggestions = settings.enableSuggestions;
|
|
43987
|
-
}
|
|
43988
|
-
});
|
|
43989
|
-
}
|
|
43990
|
-
async function updateSessionHeaders(sessionId, headers) {
|
|
43991
|
-
return await update2(sessionId, (session) => {
|
|
43992
|
-
if (!session.config) {
|
|
43993
|
-
session.config = {};
|
|
43994
|
-
}
|
|
43995
|
-
session.config.headers = { ...headers };
|
|
43996
|
-
});
|
|
43997
|
-
}
|
|
43998
|
-
var DEFAULT_OUTCOME_GUIDANCE, EXFIL_OUTCOME_GUIDANCE, DEFAULT_HEADER_RECORD, AuthCredentialsObject, ScopeConstraintsObject, SessionHeadersRecord, OffensiveHeadersConfigObject, OperatorSettingsObject, EmailInboxConfigObject, EmailIntegrationConfigObject, SmtpConfigObject, SessionConfigObject, SessionInfoObject, get = async (id) => {
|
|
43999
|
-
const raw = await read2(["sessions", id, "session"]);
|
|
44000
|
-
const read3 = migrateLegacySessionData(raw);
|
|
44001
|
-
if (read3.config?.requestsPerSecond) {
|
|
44002
|
-
read3._rateLimiter = new RateLimiter({
|
|
44003
|
-
requestsPerSecond: read3.config.requestsPerSecond
|
|
44004
|
-
});
|
|
44005
|
-
} else {
|
|
44006
|
-
delete read3._rateLimiter;
|
|
44007
|
-
}
|
|
44008
|
-
return read3;
|
|
44009
|
-
}, RemoveInput, remove2 = async (input) => {
|
|
44010
|
-
try {
|
|
44011
|
-
const sessionDir = getSessionRoot(input.sessionId);
|
|
44012
|
-
const fsp = await import("fs/promises");
|
|
44013
|
-
await fsp.rm(sessionDir, { recursive: true, force: true });
|
|
44014
|
-
} catch (e) {
|
|
44015
|
-
console.error(e);
|
|
44016
|
-
}
|
|
44017
|
-
}, RemoveMsgInput, MAX_RESUME_MESSAGES = 200, sessions;
|
|
44018
|
-
var init_session = __esm(() => {
|
|
44019
|
-
init_zod();
|
|
44020
|
-
init_name();
|
|
44021
|
-
init_credentials();
|
|
44022
|
-
init_id();
|
|
44023
|
-
init_installation();
|
|
44024
|
-
init_rateLimiter();
|
|
44025
|
-
init_storage();
|
|
44026
|
-
init_toolset();
|
|
44027
|
-
DEFAULT_OUTCOME_GUIDANCE = "Prove the exploit can be run but do not exfiltrate data or cause any harm to the system. " + "Create proof-of-concept exploits that demonstrate the vulnerability exists without causing damage.";
|
|
44028
|
-
EXFIL_OUTCOME_GUIDANCE = "Exfiltrate data to extract the flag value. " + "Create proof-of-concept exploits that successfully extract the flag from the target system.";
|
|
44029
|
-
DEFAULT_HEADER_RECORD = {
|
|
44030
|
-
"User-Agent": "pensar-apex"
|
|
44031
|
-
};
|
|
44032
|
-
AuthCredentialsObject = zod_default.object({
|
|
44033
|
-
username: zod_default.string().optional(),
|
|
44034
|
-
password: zod_default.string().optional(),
|
|
44035
|
-
loginUrl: zod_default.string().optional(),
|
|
44036
|
-
additionalFields: zod_default.record(zod_default.string(), zod_default.string()).optional(),
|
|
44037
|
-
apiKey: zod_default.string().optional(),
|
|
44038
|
-
role: zod_default.string().optional(),
|
|
44039
|
-
context: zod_default.string().optional(),
|
|
44040
|
-
tokens: zod_default.object({
|
|
44041
|
-
bearerToken: zod_default.string().optional(),
|
|
44042
|
-
cookies: zod_default.string().optional(),
|
|
44043
|
-
sessionToken: zod_default.string().optional(),
|
|
44044
|
-
customHeaders: zod_default.record(zod_default.string(), zod_default.string()).optional()
|
|
44045
|
-
}).optional()
|
|
44046
|
-
});
|
|
44047
|
-
ScopeConstraintsObject = zod_default.object({
|
|
44048
|
-
allowedHosts: zod_default.string().array().optional(),
|
|
44049
|
-
allowedPorts: zod_default.number().array().optional(),
|
|
44050
|
-
strictScope: zod_default.boolean().optional()
|
|
44051
|
-
});
|
|
44052
|
-
SessionHeadersRecord = zod_default.record(zod_default.string(), zod_default.string());
|
|
44053
|
-
OffensiveHeadersConfigObject = zod_default.object({
|
|
44054
|
-
mode: zod_default.enum(["none", "default", "custom"]).optional(),
|
|
44055
|
-
headers: SessionHeadersRecord.optional()
|
|
44056
|
-
});
|
|
44057
|
-
OperatorSettingsObject = zod_default.object({
|
|
44058
|
-
initialMode: zod_default.enum(["plan", "manual", "auto"]).default("manual"),
|
|
44059
|
-
requireApproval: zod_default.boolean().default(true),
|
|
44060
|
-
enableSuggestions: zod_default.boolean().default(true)
|
|
44061
|
-
});
|
|
44062
|
-
EmailInboxConfigObject = zod_default.discriminatedUnion("provider", [
|
|
44063
|
-
zod_default.object({
|
|
44064
|
-
provider: zod_default.literal("gmail"),
|
|
44065
|
-
id: zod_default.string(),
|
|
44066
|
-
name: zod_default.string(),
|
|
44067
|
-
emailAddress: zod_default.string(),
|
|
44068
|
-
accessToken: zod_default.string(),
|
|
44069
|
-
refreshToken: zod_default.string(),
|
|
44070
|
-
clientId: zod_default.string().optional(),
|
|
44071
|
-
clientSecret: zod_default.string().optional(),
|
|
44072
|
-
tokenExpiry: zod_default.number().optional()
|
|
44073
|
-
}),
|
|
44074
|
-
zod_default.object({
|
|
44075
|
-
provider: zod_default.literal("outlook"),
|
|
44076
|
-
id: zod_default.string(),
|
|
44077
|
-
name: zod_default.string(),
|
|
44078
|
-
emailAddress: zod_default.string(),
|
|
44079
|
-
accessToken: zod_default.string(),
|
|
44080
|
-
refreshToken: zod_default.string(),
|
|
44081
|
-
clientId: zod_default.string().optional(),
|
|
44082
|
-
clientSecret: zod_default.string().optional(),
|
|
44083
|
-
tokenExpiry: zod_default.number().optional()
|
|
44084
|
-
}),
|
|
44085
|
-
zod_default.object({
|
|
44086
|
-
provider: zod_default.literal("imap"),
|
|
44087
|
-
id: zod_default.string(),
|
|
44088
|
-
name: zod_default.string(),
|
|
44089
|
-
emailAddress: zod_default.string(),
|
|
44090
|
-
imapHost: zod_default.string(),
|
|
44091
|
-
imapPort: zod_default.number(),
|
|
44092
|
-
username: zod_default.string(),
|
|
44093
|
-
password: zod_default.string(),
|
|
44094
|
-
tls: zod_default.boolean()
|
|
44095
|
-
})
|
|
44096
|
-
]);
|
|
44097
|
-
EmailIntegrationConfigObject = zod_default.object({
|
|
44098
|
-
inboxes: zod_default.array(EmailInboxConfigObject)
|
|
44099
|
-
});
|
|
44100
|
-
SmtpConfigObject = zod_default.object({
|
|
44101
|
-
host: zod_default.string(),
|
|
44102
|
-
port: zod_default.number(),
|
|
44103
|
-
username: zod_default.string(),
|
|
44104
|
-
password: zod_default.string(),
|
|
44105
|
-
tls: zod_default.boolean().default(true),
|
|
44106
|
-
fromAddress: zod_default.string().optional()
|
|
44107
|
-
});
|
|
44108
|
-
SessionConfigObject = zod_default.object({
|
|
44109
|
-
headers: SessionHeadersRecord.optional(),
|
|
44110
|
-
offensiveHeaders: OffensiveHeadersConfigObject.optional(),
|
|
44111
|
-
sessionType: zod_default.enum(["web-app"]).optional(),
|
|
44112
|
-
mode: zod_default.enum(["auto", "driver", "operator"]).optional(),
|
|
44113
|
-
outcomeGuidance: zod_default.string().optional(),
|
|
44114
|
-
scopeConstraints: ScopeConstraintsObject.optional(),
|
|
44115
|
-
authCredentials: zod_default.union([AuthCredentialsObject, zod_default.array(AuthCredentialsObject)]).optional(),
|
|
44116
|
-
authenticationInstructions: zod_default.string().optional(),
|
|
44117
|
-
requestsPerSecond: zod_default.number().optional(),
|
|
44118
|
-
operatorSettings: OperatorSettingsObject.optional(),
|
|
44119
|
-
toolsetState: ToolsetStateSchema.optional(),
|
|
44120
|
-
enumerateSubdomains: zod_default.boolean().optional(),
|
|
44121
|
-
codebasePath: zod_default.string().optional(),
|
|
44122
|
-
emailIntegration: EmailIntegrationConfigObject.optional(),
|
|
44123
|
-
smtpConfig: SmtpConfigObject.optional(),
|
|
44124
|
-
exfilMode: zod_default.boolean().optional(),
|
|
44125
|
-
agentCwd: zod_default.string().optional(),
|
|
44126
|
-
prompt: zod_default.string().optional(),
|
|
44127
|
-
taskDriven: zod_default.boolean().optional(),
|
|
44128
|
-
requirePlan: zod_default.boolean().optional()
|
|
44129
|
-
});
|
|
44130
|
-
SessionInfoObject = zod_default.object({
|
|
44131
|
-
id: schema("session"),
|
|
44132
|
-
name: zod_default.string().optional(),
|
|
44133
|
-
version: zod_default.string(),
|
|
44134
|
-
targets: zod_default.array(zod_default.string()),
|
|
44135
|
-
config: SessionConfigObject.optional(),
|
|
44136
|
-
time: zod_default.object({
|
|
44137
|
-
created: zod_default.number(),
|
|
44138
|
-
updated: zod_default.number()
|
|
44139
|
-
}),
|
|
44140
|
-
rootPath: zod_default.string(),
|
|
44141
|
-
logsPath: zod_default.string(),
|
|
44142
|
-
findingsPath: zod_default.string(),
|
|
44143
|
-
scratchpadPath: zod_default.string(),
|
|
44144
|
-
pocsPath: zod_default.string()
|
|
44145
|
-
});
|
|
44146
|
-
RemoveInput = zod_default.object({
|
|
44147
|
-
sessionId: schema("session")
|
|
44148
|
-
});
|
|
44149
|
-
RemoveMsgInput = zod_default.object({
|
|
44150
|
-
sessionId: schema("session"),
|
|
44151
|
-
messageId: schema("message")
|
|
44152
|
-
});
|
|
44153
|
-
sessions = {
|
|
44154
|
-
getSessionRoot,
|
|
44155
|
-
EXFIL_OUTCOME_GUIDANCE,
|
|
44156
|
-
create: create2,
|
|
44157
|
-
get,
|
|
44158
|
-
remove: remove2,
|
|
44159
|
-
loadOperatorState,
|
|
44160
|
-
hasOperatorState,
|
|
44161
|
-
getResumeMessages,
|
|
44162
|
-
updateOperatorSettings,
|
|
44163
|
-
updateSessionHeaders
|
|
44164
|
-
};
|
|
44165
|
-
});
|
|
44166
|
-
|
|
44167
|
-
// src/core/logger/index.ts
|
|
44168
|
-
import {
|
|
44169
|
-
appendFileSync,
|
|
44170
|
-
existsSync as existsSync2,
|
|
44171
|
-
mkdirSync as mkdirSync2,
|
|
44172
|
-
readFileSync as readFileSync2,
|
|
44173
|
-
writeFileSync as writeFileSync2
|
|
44174
|
-
} from "fs";
|
|
44175
|
-
import os3 from "os";
|
|
44176
|
-
import path3 from "path";
|
|
44177
|
-
function pruneErrorLog() {
|
|
44178
|
-
if (hasPruned)
|
|
44179
|
-
return;
|
|
44180
|
-
hasPruned = true;
|
|
44181
|
-
try {
|
|
44182
|
-
if (!existsSync2(ERROR_LOG_PATH))
|
|
44183
|
-
return;
|
|
44184
|
-
const cutoff = Date.now() - RETENTION_DAYS * 86400000;
|
|
44185
|
-
const raw = readFileSync2(ERROR_LOG_PATH, "utf8");
|
|
44186
|
-
const lines = raw.split(`
|
|
44187
|
-
`);
|
|
44188
|
-
const kept = [];
|
|
44189
|
-
let keeping = true;
|
|
44190
|
-
for (const line of lines) {
|
|
44191
|
-
const match = TIMESTAMP_RE.exec(line);
|
|
44192
|
-
if (match) {
|
|
44193
|
-
keeping = new Date(match[1]).getTime() >= cutoff;
|
|
44194
|
-
}
|
|
44195
|
-
if (keeping) {
|
|
44196
|
-
kept.push(line);
|
|
44197
|
-
}
|
|
44198
|
-
}
|
|
44199
|
-
writeFileSync2(ERROR_LOG_PATH, kept.join(`
|
|
44200
|
-
`), "utf8");
|
|
44201
|
-
} catch {}
|
|
44202
|
-
}
|
|
44203
|
-
function writeErrorLog(error, source, fields) {
|
|
44204
|
-
try {
|
|
44205
|
-
pruneErrorLog();
|
|
44206
|
-
const dir = path3.dirname(ERROR_LOG_PATH);
|
|
44207
|
-
if (!existsSync2(dir)) {
|
|
44208
|
-
mkdirSync2(dir, { recursive: true });
|
|
44209
|
-
}
|
|
44210
|
-
const timestamp = new Date().toISOString();
|
|
44211
|
-
const tag = source ? `[${source}] ` : "";
|
|
44212
|
-
const message = error instanceof Error ? `${error.message}
|
|
44213
|
-
${error.stack ?? ""}` : String(error);
|
|
44214
|
-
let fieldsStr = "";
|
|
44215
|
-
if (fields && Object.keys(fields).length > 0) {
|
|
44216
|
-
try {
|
|
44217
|
-
fieldsStr = ` ${JSON.stringify(fields)}`;
|
|
44218
|
-
} catch {}
|
|
44219
|
-
}
|
|
44220
|
-
const entry = `${timestamp} - [ERROR] ${tag}${message}${fieldsStr}
|
|
44221
|
-
`;
|
|
44222
|
-
appendFileSync(ERROR_LOG_PATH, entry, "utf8");
|
|
44223
|
-
} catch {}
|
|
44224
|
-
}
|
|
44225
|
-
var ERROR_LOG_PATH, RETENTION_DAYS = 7, TIMESTAMP_RE, hasPruned = false;
|
|
44226
|
-
var init_logger = __esm(() => {
|
|
44227
|
-
init_session();
|
|
44228
|
-
init_structured();
|
|
44229
|
-
ERROR_LOG_PATH = path3.join(os3.homedir(), ".pensar", "error.log");
|
|
44230
|
-
TIMESTAMP_RE = /^(\d{4}-\d{2}-\d{2}T[\d:.]+Z) - /;
|
|
44231
|
-
});
|
|
44232
|
-
|
|
44233
|
-
// src/core/logger/structured.ts
|
|
44234
|
-
function isLevel(v) {
|
|
44235
|
-
return typeof v === "string" && VALID_LEVELS.has(v);
|
|
44236
|
-
}
|
|
44237
|
-
function resolveInitialLevel(env) {
|
|
44238
|
-
const explicit = env.PENSAR_LOG_LEVEL?.trim().toUpperCase();
|
|
44239
|
-
if (isLevel(explicit))
|
|
44240
|
-
return explicit;
|
|
44241
|
-
const debug = env.PENSAR_DEBUG?.toLowerCase();
|
|
44242
|
-
if (debug === "1" || debug === "true")
|
|
44243
|
-
return "DEBUG";
|
|
44244
|
-
return "INFO";
|
|
44245
|
-
}
|
|
44246
|
-
function resolveFormat(env) {
|
|
44247
|
-
const forced = env.PENSAR_LOG_FORMAT?.toLowerCase();
|
|
44248
|
-
if (forced === "json" || forced === "pretty")
|
|
44249
|
-
return forced;
|
|
44250
|
-
return process.stderr.isTTY ? "pretty" : "json";
|
|
44251
|
-
}
|
|
44252
|
-
|
|
44253
|
-
class Logger {
|
|
44254
|
-
level;
|
|
44255
|
-
explicit = false;
|
|
44256
|
-
scope;
|
|
44257
|
-
constructor(scope, level) {
|
|
44258
|
-
this.scope = scope;
|
|
44259
|
-
this.level = level ?? resolveInitialLevel(process.env);
|
|
44260
|
-
}
|
|
44261
|
-
setLevel(level) {
|
|
44262
|
-
this.level = level;
|
|
44263
|
-
this.explicit = true;
|
|
44264
|
-
}
|
|
44265
|
-
getLevel() {
|
|
44266
|
-
return this.level;
|
|
44267
|
-
}
|
|
44268
|
-
child(scope) {
|
|
44269
|
-
const next = this.scope ? `${this.scope}:${scope}` : scope;
|
|
44270
|
-
const child = new Logger(next, this.level);
|
|
44271
|
-
if (this.explicit)
|
|
44272
|
-
child.setLevel(this.level);
|
|
44273
|
-
return child;
|
|
44274
|
-
}
|
|
44275
|
-
debug(msg, fields) {
|
|
44276
|
-
this.emit("DEBUG", msg, fields);
|
|
44277
|
-
}
|
|
44278
|
-
info(msg, fields) {
|
|
44279
|
-
this.emit("INFO", msg, fields);
|
|
44280
|
-
}
|
|
44281
|
-
warn(msg, fields) {
|
|
44282
|
-
this.emit("WARN", msg, fields);
|
|
44283
|
-
}
|
|
44284
|
-
error(msg, errOrFields, fields) {
|
|
44285
|
-
let err;
|
|
44286
|
-
let extra;
|
|
44287
|
-
if (errOrFields instanceof Error) {
|
|
44288
|
-
err = errOrFields;
|
|
44289
|
-
extra = fields;
|
|
44290
|
-
} else if (errOrFields && typeof errOrFields === "object") {
|
|
44291
|
-
extra = errOrFields;
|
|
44292
|
-
}
|
|
44293
|
-
const merged = { ...extra };
|
|
44294
|
-
if (err) {
|
|
44295
|
-
merged.error = err.message;
|
|
44296
|
-
if (err.stack)
|
|
44297
|
-
merged.stack = err.stack;
|
|
44298
|
-
}
|
|
44299
|
-
this.emit("ERROR", msg, merged);
|
|
44300
|
-
if (this.level !== "SILENT") {
|
|
44301
|
-
writeErrorLog(err ?? msg, this.scope, extra);
|
|
44302
|
-
}
|
|
44303
|
-
}
|
|
44304
|
-
emit(level, msg, fields) {
|
|
44305
|
-
if (SEVERITY[level] < SEVERITY[this.level])
|
|
44306
|
-
return;
|
|
44307
|
-
const ts = new Date().toISOString();
|
|
44308
|
-
const format = resolveFormat(process.env);
|
|
44309
|
-
const line = format === "json" ? this.formatJson(ts, level, msg, fields) : this.formatPretty(ts, level, msg, fields);
|
|
44310
|
-
process.stderr.write(`${line}
|
|
44311
|
-
`);
|
|
44312
|
-
}
|
|
44313
|
-
formatJson(ts, level, msg, fields) {
|
|
44314
|
-
const record = { ts, level, msg };
|
|
44315
|
-
if (this.scope)
|
|
44316
|
-
record.scope = this.scope;
|
|
44317
|
-
if (fields) {
|
|
44318
|
-
for (const [k, v] of Object.entries(fields)) {
|
|
44319
|
-
if (k !== "ts" && k !== "level" && k !== "msg" && k !== "scope") {
|
|
44320
|
-
record[k] = v;
|
|
44321
|
-
}
|
|
44322
|
-
}
|
|
44323
|
-
}
|
|
44324
|
-
return safeStringify(record);
|
|
44325
|
-
}
|
|
44326
|
-
formatPretty(ts, level, msg, fields) {
|
|
44327
|
-
const color = COLORS[level];
|
|
44328
|
-
const tag = `${color}${level.padEnd(5)}${RESET}`;
|
|
44329
|
-
const scope = this.scope ? ` ${DIM}[${this.scope}]${RESET}` : "";
|
|
44330
|
-
let rest = "";
|
|
44331
|
-
if (fields && Object.keys(fields).length > 0) {
|
|
44332
|
-
rest = ` ${DIM}${safeStringify(fields)}${RESET}`;
|
|
44333
|
-
}
|
|
44334
|
-
return `${DIM}${ts}${RESET} ${tag}${scope} ${msg}${rest}`;
|
|
44335
|
-
}
|
|
44336
|
-
}
|
|
44337
|
-
function safeStringify(value) {
|
|
44338
|
-
try {
|
|
44339
|
-
return JSON.stringify(value);
|
|
44340
|
-
} catch {
|
|
44341
|
-
return JSON.stringify({ msg: "[unserializable log payload]" });
|
|
44342
|
-
}
|
|
44343
|
-
}
|
|
44344
|
-
function createLogger(scope) {
|
|
44345
|
-
return new Logger(scope);
|
|
44346
|
-
}
|
|
44347
|
-
var SEVERITY, VALID_LEVELS, COLORS, RESET = "\x1B[0m", DIM = "\x1B[2m", logger;
|
|
44348
|
-
var init_structured = __esm(() => {
|
|
44349
|
-
init_logger();
|
|
44350
|
-
SEVERITY = {
|
|
44351
|
-
DEBUG: 10,
|
|
44352
|
-
INFO: 20,
|
|
44353
|
-
WARN: 30,
|
|
44354
|
-
ERROR: 40,
|
|
44355
|
-
SILENT: 50
|
|
44356
|
-
};
|
|
44357
|
-
VALID_LEVELS = new Set([
|
|
44358
|
-
"DEBUG",
|
|
44359
|
-
"INFO",
|
|
44360
|
-
"WARN",
|
|
44361
|
-
"ERROR",
|
|
44362
|
-
"SILENT"
|
|
44363
|
-
]);
|
|
44364
|
-
COLORS = {
|
|
44365
|
-
DEBUG: "\x1B[90m",
|
|
44366
|
-
INFO: "\x1B[36m",
|
|
44367
|
-
WARN: "\x1B[33m",
|
|
44368
|
-
ERROR: "\x1B[31m",
|
|
44369
|
-
SILENT: ""
|
|
44370
|
-
};
|
|
44371
|
-
logger = new Logger;
|
|
44372
|
-
});
|
|
44373
|
-
|
|
44374
42940
|
// src/core/ai/providers/pensarFormatters.ts
|
|
44375
42941
|
function convertToBedrockFormat(modelId, options) {
|
|
44376
42942
|
if (modelId.includes("anthropic.claude")) {
|
|
@@ -44573,9 +43139,11 @@ async function* parseSSE(stream, options = {}) {
|
|
|
44573
43139
|
clearTimeout(timeoutId);
|
|
44574
43140
|
}
|
|
44575
43141
|
if (result.done) {
|
|
44576
|
-
|
|
44577
|
-
|
|
44578
|
-
|
|
43142
|
+
if (DEBUG) {
|
|
43143
|
+
console.error(`[parseSSE] stream done: ${chunkCount} chunks, ${totalBytes} bytes, ${eventCount} events yielded, remaining buffer=${buffer.length} chars`);
|
|
43144
|
+
if (buffer.length > 0) {
|
|
43145
|
+
console.error(`[parseSSE] remaining buffer: ${buffer.slice(0, 500)}`);
|
|
43146
|
+
}
|
|
44579
43147
|
}
|
|
44580
43148
|
break;
|
|
44581
43149
|
}
|
|
@@ -44583,8 +43151,8 @@ async function* parseSSE(stream, options = {}) {
|
|
|
44583
43151
|
chunkCount++;
|
|
44584
43152
|
totalBytes += value.byteLength;
|
|
44585
43153
|
const decoded = decoder.decode(value, { stream: true });
|
|
44586
|
-
if (chunkCount <= 3) {
|
|
44587
|
-
|
|
43154
|
+
if (DEBUG && chunkCount <= 3) {
|
|
43155
|
+
console.error(`[parseSSE] chunk #${chunkCount}: ${value.byteLength} bytes, preview: ${decoded.slice(0, 200)}`);
|
|
44588
43156
|
}
|
|
44589
43157
|
buffer += decoded;
|
|
44590
43158
|
const lines = buffer.split(`
|
|
@@ -44609,38 +43177,34 @@ async function* parseSSE(stream, options = {}) {
|
|
|
44609
43177
|
}
|
|
44610
43178
|
if (currentData.length > 0) {
|
|
44611
43179
|
eventCount++;
|
|
44612
|
-
|
|
43180
|
+
if (DEBUG)
|
|
43181
|
+
console.error(`[parseSSE] flushing final event: ${currentEvent}`);
|
|
44613
43182
|
yield { event: currentEvent, data: currentData.join(`
|
|
44614
43183
|
`) };
|
|
44615
43184
|
}
|
|
44616
43185
|
if (eventCount === 0) {
|
|
44617
|
-
|
|
43186
|
+
console.error(`[parseSSE] WARNING: stream ended with 0 events! totalBytes=${totalBytes}, chunks=${chunkCount}`);
|
|
44618
43187
|
}
|
|
44619
43188
|
} finally {
|
|
44620
43189
|
reader.releaseLock();
|
|
44621
43190
|
}
|
|
44622
43191
|
}
|
|
44623
|
-
var
|
|
43192
|
+
var DEBUG;
|
|
44624
43193
|
var init_pensarSSE = __esm(() => {
|
|
44625
|
-
|
|
44626
|
-
init_lazyLogger();
|
|
44627
|
-
log2 = scopedLogger(() => createLogger("pensarSSE"));
|
|
43194
|
+
DEBUG = process.env.PENSAR_DEBUG === "1" || process.env.PENSAR_DEBUG === "true";
|
|
44628
43195
|
});
|
|
44629
43196
|
|
|
44630
43197
|
// src/core/ai/providers/pensar.ts
|
|
44631
|
-
function
|
|
44632
|
-
|
|
44633
|
-
|
|
44634
|
-
function log3(...args) {
|
|
44635
|
-
structuredLog.debug(fmtArgs(args));
|
|
43198
|
+
function log(...args) {
|
|
43199
|
+
if (DEBUG2)
|
|
43200
|
+
console.error("[pensar:debug]", ...args);
|
|
44636
43201
|
}
|
|
44637
43202
|
function logInfo(...args) {
|
|
44638
|
-
|
|
43203
|
+
if (DEBUG2)
|
|
43204
|
+
console.error("[pensar]", ...args);
|
|
44639
43205
|
}
|
|
44640
43206
|
function logError(...args) {
|
|
44641
|
-
|
|
44642
|
-
const msg = fmtArgs(args.filter((a) => !(a instanceof Error)));
|
|
44643
|
-
structuredLog.error(msg, err);
|
|
43207
|
+
console.error("[pensar:error]", ...args);
|
|
44644
43208
|
}
|
|
44645
43209
|
function createPensarModel(bedrockModelId, config2) {
|
|
44646
43210
|
const modelId = `pensar:${bedrockModelId}`;
|
|
@@ -44656,14 +43220,14 @@ function createPensarModel(bedrockModelId, config2) {
|
|
|
44656
43220
|
throw new Error("Pensar authentication failed. Run /login to reconnect.");
|
|
44657
43221
|
}
|
|
44658
43222
|
headers.Authorization = `Bearer ${result.token.slice(0, 12)}…`;
|
|
44659
|
-
|
|
43223
|
+
log(` auth: ${result.type} token (${result.token.length} chars)`);
|
|
44660
43224
|
if (config2.workspaceId) {
|
|
44661
43225
|
headers["X-Workspace-Id"] = config2.workspaceId;
|
|
44662
43226
|
}
|
|
44663
43227
|
headers.Authorization = `Bearer ${result.token}`;
|
|
44664
43228
|
} else {
|
|
44665
43229
|
headers.Authorization = `Bearer ${config2.apiKey}`;
|
|
44666
|
-
|
|
43230
|
+
log(` auth: apiKey (${config2.apiKey.length} chars)`);
|
|
44667
43231
|
if (config2.workspaceId && !config2.apiKey.startsWith("sk-")) {
|
|
44668
43232
|
headers["X-Workspace-Id"] = config2.workspaceId;
|
|
44669
43233
|
}
|
|
@@ -44772,7 +43336,7 @@ function createPensarModel(bedrockModelId, config2) {
|
|
|
44772
43336
|
const body = convertToBedrockFormat(bedrockModelId, options);
|
|
44773
43337
|
const url = `${config2.baseUrl}/gateway/invoke`;
|
|
44774
43338
|
logInfo(`doStream → ${bedrockModelId} (${url})`);
|
|
44775
|
-
|
|
43339
|
+
log(` messages: ${body.messages?.length ?? 0}, tools: ${body.tools?.length ?? 0}`);
|
|
44776
43340
|
const startTime = Date.now();
|
|
44777
43341
|
const serializedBody = JSON.stringify({
|
|
44778
43342
|
modelId: bedrockModelId,
|
|
@@ -44785,7 +43349,7 @@ function createPensarModel(bedrockModelId, config2) {
|
|
|
44785
43349
|
headers["X-Pensar-Timestamp"] = sig.timestamp;
|
|
44786
43350
|
headers["X-Pensar-Nonce"] = sig.nonce;
|
|
44787
43351
|
}
|
|
44788
|
-
|
|
43352
|
+
log(` headers: ${Object.keys(headers).join(", ")}`);
|
|
44789
43353
|
const fetchSignal = buildStreamingFetchSignal(options.abortSignal);
|
|
44790
43354
|
let response;
|
|
44791
43355
|
try {
|
|
@@ -44862,10 +43426,10 @@ function createPensarModel(bedrockModelId, config2) {
|
|
|
44862
43426
|
try {
|
|
44863
43427
|
parsed = JSON.parse(sse.data);
|
|
44864
43428
|
} catch {
|
|
44865
|
-
|
|
43429
|
+
log(` SSE event #${eventCount}: unparseable data, skipping`);
|
|
44866
43430
|
continue;
|
|
44867
43431
|
}
|
|
44868
|
-
|
|
43432
|
+
log(` SSE event #${eventCount}: ${sse.event} (type=${parsed.type})`);
|
|
44869
43433
|
if (sse.event === "error") {
|
|
44870
43434
|
const msg = parsed.error ?? "Unknown streaming error";
|
|
44871
43435
|
logError(` SSE error event: ${msg}`);
|
|
@@ -44874,7 +43438,7 @@ function createPensarModel(bedrockModelId, config2) {
|
|
|
44874
43438
|
}
|
|
44875
43439
|
if (sse.event === "pensar:usage") {
|
|
44876
43440
|
if (parsed.totalCost != null) {
|
|
44877
|
-
|
|
43441
|
+
log(` cost: $${Number(parsed.totalCost).toFixed(6)}`);
|
|
44878
43442
|
}
|
|
44879
43443
|
continue;
|
|
44880
43444
|
}
|
|
@@ -45061,15 +43625,13 @@ function mapStopReason(reason) {
|
|
|
45061
43625
|
return "other";
|
|
45062
43626
|
}
|
|
45063
43627
|
}
|
|
45064
|
-
var
|
|
43628
|
+
var DEBUG2;
|
|
45065
43629
|
var init_pensar2 = __esm(() => {
|
|
45066
|
-
init_structured();
|
|
45067
|
-
init_lazyLogger();
|
|
45068
43630
|
init_utils();
|
|
45069
43631
|
init_pensarFormatters();
|
|
45070
43632
|
init_pensarSigning();
|
|
45071
43633
|
init_pensarSSE();
|
|
45072
|
-
|
|
43634
|
+
DEBUG2 = process.env.PENSAR_DEBUG === "1" || process.env.PENSAR_DEBUG === "true";
|
|
45073
43635
|
});
|
|
45074
43636
|
|
|
45075
43637
|
// src/core/ai/utils.ts
|
|
@@ -45173,7 +43735,9 @@ function getProviderModel(model, authConfig) {
|
|
|
45173
43735
|
}
|
|
45174
43736
|
const gatewayUrl = authConfig?.gatewayUrl || getPensarGatewayUrl();
|
|
45175
43737
|
const bedrockModelId = model.startsWith("pensar:") ? model.slice(7) : model;
|
|
45176
|
-
|
|
43738
|
+
if (process.env.PENSAR_DEBUG === "1" || process.env.PENSAR_DEBUG === "true") {
|
|
43739
|
+
console.log(`[pensar] getProviderModel: ${model} → bedrock:${bedrockModelId} via ${gatewayUrl}`);
|
|
43740
|
+
}
|
|
45177
43741
|
const modelConfig = {
|
|
45178
43742
|
apiKey: pensarApiKey || authConfig?.accessToken || "",
|
|
45179
43743
|
baseUrl: gatewayUrl,
|
|
@@ -45390,7 +43954,7 @@ function createSummarizationStream(messages, opts, model) {
|
|
|
45390
43954
|
}
|
|
45391
43955
|
};
|
|
45392
43956
|
}
|
|
45393
|
-
var
|
|
43957
|
+
var STREAMING_FETCH_TIMEOUT_MS;
|
|
45394
43958
|
var init_utils = __esm(() => {
|
|
45395
43959
|
init_dist6();
|
|
45396
43960
|
init_dist7();
|
|
@@ -45402,14 +43966,11 @@ var init_utils = __esm(() => {
|
|
|
45402
43966
|
init_constants();
|
|
45403
43967
|
init_auth();
|
|
45404
43968
|
init_config();
|
|
45405
|
-
init_structured();
|
|
45406
|
-
init_lazyLogger();
|
|
45407
43969
|
init_ai();
|
|
45408
43970
|
init_contextManagement();
|
|
45409
43971
|
init_models();
|
|
45410
43972
|
init_pensar2();
|
|
45411
|
-
log4 = scopedLogger(() => createLogger("ai:utils"));
|
|
45412
43973
|
STREAMING_FETCH_TIMEOUT_MS = 15 * 60 * 1000;
|
|
45413
43974
|
});
|
|
45414
43975
|
|
|
45415
|
-
export { stepCountIs, hasToolCall, init_dist4 as init_dist,
|
|
43976
|
+
export { stepCountIs, hasToolCall, init_dist4 as init_dist, getApexTracer, init_observability, AVAILABLE_MODELS, init_models, require_tslib, buildAuthConfig, init_utils, DEFAULT_OPENAI_REASONING_EFFORT, modelSupportsThinking, modelSupportsOpenAIReasoning, getOpenAIReasoningEfforts, streamResponse, generateObjectResponse, init_ai };
|