@pensar/apex 2.0.0 → 2.0.1
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 +20 -0
- package/build/agent-4g69jwmq.js +19 -0
- package/build/{agent-x1tnsg7n.js → agent-6nhperp2.js} +7 -10
- package/build/{agent-z8043nrm.js → agent-x7n47c84.js} +9 -12
- package/build/{apps-gdze0s68.js → apps-2ac4vt09.js} +15 -18
- package/build/{auth-24ca1qwx.js → auth-bmt98hz0.js} +16 -19
- package/build/authentication-c0aj9zaz.js +19 -0
- package/build/blackboxAgent-sgph70e4.js +19 -0
- package/build/{blackboxPentest-xwc031xm.js → blackboxPentest-xngbtdxb.js} +13 -16
- package/build/{cli-a20jcpmp.js → cli-0yptvbbm.js} +1 -1
- package/build/{cli-pkdjamer.js → cli-1f5zzrxj.js} +15 -5
- package/build/{cli-0v9x0eby.js → cli-88bhxzr1.js} +1 -1
- package/build/{cli-948dk60p.js → cli-8g5cwvbm.js} +1 -1
- package/build/{cli-mswm4k81.js → cli-cc13ydyx.js} +11 -1
- package/build/{cli-wdmqkshz.js → cli-ddtmgbqv.js} +2 -2
- package/build/{cli-h6nw89zf.js → cli-eptabm2j.js} +1 -1
- package/build/{cli-zpvmaxem.js → cli-f93g10xk.js} +2 -2
- package/build/{cli-zvq4gy61.js → cli-fa7nrded.js} +13 -6
- package/build/{cli-sw5swz40.js → cli-fxtbkw2f.js} +3 -3
- package/build/{cli-ntd42071.js → cli-hk03x6fq.js} +1 -1
- package/build/{cli-5fr9k6m4.js → cli-mfzkhttr.js} +58 -35
- package/build/{cli-31cara07.js → cli-pyzw545d.js} +8 -6
- package/build/{cli-cb5va0cs.js → cli-w2st266h.js} +10 -1
- package/build/{cli-h825qzmd.js → cli-z1dapp7v.js} +1492 -53
- package/build/{cli-k8mvghe1.js → cli-zpdmnz8c.js} +455 -921
- package/build/cli.js +105 -45
- package/build/{config-cmq1cxz3.js → config-j0gfjhrm.js} +3 -3
- package/build/{doctor-2bkpddws.js → doctor-zn8ms7gs.js} +8 -1
- package/build/{fixes-a4qscvkx.js → fixes-d8ytvyzn.js} +15 -18
- package/build/{index-hfhkjj2g.js → index-2t2cg8x0.js} +8 -11
- package/build/{index-54ep0ery.js → index-3cbcjqw1.js} +9 -12
- package/build/{index-48pjf9d2.js → index-528cyewc.js} +94 -126
- package/build/{index-2a1x5nnv.js → index-9d2es97h.js} +3 -3
- package/build/{index-aymt8k9w.js → index-a1sy2zak.js} +2 -2
- package/build/{index-s17r2akv.js → index-hjvqqkem.js} +4 -4
- package/build/{index-0fnbx38r.js → index-k6ttkac6.js} +20 -14
- package/build/{issues-5pnrspt7.js → issues-17kdjtdg.js} +15 -18
- package/build/{logs-1mfm901x.js → logs-r4rjar4m.js} +15 -18
- package/build/{offesecAgent-mrbyc93d.js → offesecAgent-azd8ahkm.js} +8 -11
- package/build/pentest-2vsjf0j8.js +28 -0
- package/build/{pentests-htmtq66d.js → pentests-npjb5q1h.js} +15 -18
- package/build/{targetedPentest-cpbd87rc.js → targetedPentest-m24wvscc.js} +9 -12
- package/build/threatModel-7akmfzzm.js +26 -0
- package/build/{uninstall-6y9dkgyt.js → uninstall-7pm6zcah.js} +1 -1
- package/build/{upload-7wtbr768.js → upload-wg0vxmk0.js} +8 -1
- package/build/{utils-trqnyj77.js → utils-gd1y4t26.js} +6 -8
- package/package.json +1 -1
- package/build/agent-84enr6xn.js +0 -22
- package/build/authentication-0k43jay4.js +0 -22
- package/build/blackboxAgent-76tnwwg7.js +0 -22
- package/build/cli-1yavz2pb.js +0 -17
- package/build/cli-3knnkdps.js +0 -666
- package/build/cli-s1nckt4k.js +0 -20
- package/build/pentest-wy4eeagc.js +0 -31
- package/build/threatModel-9n56z6a6.js +0 -29
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
init_auth,
|
|
5
5
|
init_constants,
|
|
6
6
|
signGatewayRequest
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-8g5cwvbm.js";
|
|
8
8
|
import {
|
|
9
9
|
AISDKError,
|
|
10
10
|
APICallError,
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
delay,
|
|
33
33
|
executeTool,
|
|
34
34
|
exports_external,
|
|
35
|
+
exports_external1 as exports_external2,
|
|
35
36
|
gateway,
|
|
36
37
|
getErrorMessage,
|
|
37
38
|
getErrorMessage1 as getErrorMessage2,
|
|
@@ -42,6 +43,7 @@ import {
|
|
|
42
43
|
init_stream,
|
|
43
44
|
init_v3,
|
|
44
45
|
init_v4,
|
|
46
|
+
init_zod,
|
|
45
47
|
isAbortError,
|
|
46
48
|
isUrlSupported,
|
|
47
49
|
lazySchema,
|
|
@@ -55,17 +57,24 @@ import {
|
|
|
55
57
|
validateDownloadUrl,
|
|
56
58
|
validateTypes,
|
|
57
59
|
withUserAgentSuffix,
|
|
58
|
-
zodSchema
|
|
60
|
+
zodSchema,
|
|
61
|
+
zod_default
|
|
59
62
|
} from "./cli-e6rgwtpb.js";
|
|
60
63
|
import {
|
|
61
64
|
config,
|
|
62
65
|
init_config
|
|
63
|
-
} from "./cli-
|
|
66
|
+
} from "./cli-eptabm2j.js";
|
|
64
67
|
import {
|
|
68
|
+
getCurrentVersion,
|
|
69
|
+
init_installation
|
|
70
|
+
} from "./cli-0yptvbbm.js";
|
|
71
|
+
import {
|
|
72
|
+
__callDispose,
|
|
65
73
|
__commonJS,
|
|
66
74
|
__esm,
|
|
67
75
|
__require,
|
|
68
|
-
__toESM
|
|
76
|
+
__toESM,
|
|
77
|
+
__using
|
|
69
78
|
} from "./cli-8rxa073f.js";
|
|
70
79
|
|
|
71
80
|
// node_modules/ai/dist/index.mjs
|
|
@@ -8776,6 +8785,20 @@ var init_models = __esm(() => {
|
|
|
8776
8785
|
];
|
|
8777
8786
|
});
|
|
8778
8787
|
|
|
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
|
+
|
|
8779
8802
|
// node_modules/@ai-sdk/provider-utils/dist/index.mjs
|
|
8780
8803
|
function combineHeaders(...headers) {
|
|
8781
8804
|
return headers.reduce((combinedHeaders, currentHeaders) => ({
|
|
@@ -42434,7 +42457,7 @@ function wrapStreamWithErrorHandler(originalStream, messagesContainer, opts, mod
|
|
|
42434
42457
|
if (!isCtxError && isStreamIdleTimeoutError(error) && idleResumeCount < MAX_IDLE_RESUME_RETRIES && messagesContainer.current.length > 0) {
|
|
42435
42458
|
const nextIdleCount = idleResumeCount + 1;
|
|
42436
42459
|
if (!silent) {
|
|
42437
|
-
|
|
42460
|
+
log.warn(`Stream stalled (attempt ${nextIdleCount}/${MAX_IDLE_RESUME_RETRIES}), resuming with ${messagesContainer.current.length} messages: ${errorMessage}`);
|
|
42438
42461
|
}
|
|
42439
42462
|
const retriedStream = streamResponse({
|
|
42440
42463
|
...opts,
|
|
@@ -42450,7 +42473,7 @@ function wrapStreamWithErrorHandler(originalStream, messagesContainer, opts, mod
|
|
|
42450
42473
|
const nextRetryCount = rateLimitRetryCount + 1;
|
|
42451
42474
|
const delayMs = Math.min(1000 * nextRetryCount, 30000);
|
|
42452
42475
|
if (!silent) {
|
|
42453
|
-
|
|
42476
|
+
log.warn(`Rate limit error (attempt ${nextRetryCount}/${MAX_RATE_LIMIT_RETRIES}), waiting ${delayMs}ms: ${errorMessage}`);
|
|
42454
42477
|
}
|
|
42455
42478
|
await new Promise((resolve4) => setTimeout(resolve4, delayMs));
|
|
42456
42479
|
const retriedStream = streamResponse({
|
|
@@ -42482,7 +42505,7 @@ function wrapStreamWithErrorHandler(originalStream, messagesContainer, opts, mod
|
|
|
42482
42505
|
let postReactiveDepth = opts._restartDepth ?? 0;
|
|
42483
42506
|
if (fitted.fitsBudget && fitted.modified) {
|
|
42484
42507
|
if (!silent) {
|
|
42485
|
-
|
|
42508
|
+
log.warn(`Context length error — Layer 1+2 reduced to ~${fitted.estimatedInputTokens} tokens, retrying`);
|
|
42486
42509
|
}
|
|
42487
42510
|
try {
|
|
42488
42511
|
const retried = streamResponse({
|
|
@@ -42504,7 +42527,7 @@ function wrapStreamWithErrorHandler(originalStream, messagesContainer, opts, mod
|
|
|
42504
42527
|
}
|
|
42505
42528
|
const messagesForSummary = messagesContainer.current;
|
|
42506
42529
|
if (!silent) {
|
|
42507
|
-
|
|
42530
|
+
log.warn(`Context length error — summarizing ${messagesForSummary.length} messages`);
|
|
42508
42531
|
}
|
|
42509
42532
|
try {
|
|
42510
42533
|
const summarizationStream = createSummarizationStream(messagesForSummary, { ...opts, _restartDepth: postReactiveDepth }, model);
|
|
@@ -42517,7 +42540,7 @@ function wrapStreamWithErrorHandler(originalStream, messagesContainer, opts, mod
|
|
|
42517
42540
|
}
|
|
42518
42541
|
if (!silent) {
|
|
42519
42542
|
const sumMsg = summarizeError instanceof Error ? summarizeError.message : String(summarizeError);
|
|
42520
|
-
|
|
42543
|
+
log.warn(`Layer 3 summarization failed (${sumMsg}). Falling back to minimal-context restart.`);
|
|
42521
42544
|
}
|
|
42522
42545
|
opts.onSummarized?.("");
|
|
42523
42546
|
const minimalPrompt = typeof opts.prompt === "string" && opts.prompt.length > 0 ? opts.prompt.slice(0, 4000) : MINIMAL_RESTART_PROMPT;
|
|
@@ -42533,7 +42556,9 @@ function wrapStreamWithErrorHandler(originalStream, messagesContainer, opts, mod
|
|
|
42533
42556
|
}
|
|
42534
42557
|
} else {
|
|
42535
42558
|
if (!silent) {
|
|
42536
|
-
|
|
42559
|
+
log.error("Non-recoverable stream error, re-throwing", {
|
|
42560
|
+
error: errorMessage
|
|
42561
|
+
});
|
|
42537
42562
|
}
|
|
42538
42563
|
throw error;
|
|
42539
42564
|
}
|
|
@@ -42620,13 +42645,13 @@ function streamResponse(opts) {
|
|
|
42620
42645
|
fittedMessages = fitted.messages;
|
|
42621
42646
|
proactiveFitFailed = !fitted.fitsBudget;
|
|
42622
42647
|
if (fitted.modified && !silent) {
|
|
42623
|
-
|
|
42648
|
+
log.warn(`Proactive context fit: compacted messages to ~${fitted.estimatedInputTokens} tokens (fits=${fitted.fitsBudget})`);
|
|
42624
42649
|
}
|
|
42625
42650
|
}
|
|
42626
42651
|
const messagesContainer = { current: fittedMessages || [] };
|
|
42627
42652
|
if (proactiveFitFailed && fittedMessages) {
|
|
42628
42653
|
if (!silent) {
|
|
42629
|
-
|
|
42654
|
+
log.warn(`Proactive context fit returned fitsBudget=false on ${fittedMessages.length} messages — escalating to summarization before send`);
|
|
42630
42655
|
}
|
|
42631
42656
|
return wrapStreamWithErrorHandler(createSummarizationStream(fittedMessages, opts, providerModel), messagesContainer, opts, providerModel, silent);
|
|
42632
42657
|
}
|
|
@@ -42719,16 +42744,17 @@ function streamResponse(opts) {
|
|
|
42719
42744
|
}) => {
|
|
42720
42745
|
try {
|
|
42721
42746
|
if (!silent) {
|
|
42722
|
-
|
|
42723
|
-
|
|
42747
|
+
log.debug(`Repairing tool call: ${toolCall.toolName}`, {
|
|
42748
|
+
error: error.message || String(error)
|
|
42749
|
+
});
|
|
42724
42750
|
if (error.message && (error.message.includes("severity") || error.message.includes("riskLevel"))) {
|
|
42725
|
-
|
|
42751
|
+
log.debug("Enum validation error — tool call repair will normalize the value");
|
|
42726
42752
|
}
|
|
42727
42753
|
}
|
|
42728
42754
|
const tool6 = tools2[toolCall.toolName];
|
|
42729
42755
|
if (!tool6 || !tool6.inputSchema) {
|
|
42730
42756
|
if (!silent) {
|
|
42731
|
-
|
|
42757
|
+
log.warn(`Cannot repair tool call: ${toolCall.toolName} not found or has no schema`);
|
|
42732
42758
|
}
|
|
42733
42759
|
return null;
|
|
42734
42760
|
}
|
|
@@ -42792,14 +42818,16 @@ function streamResponse(opts) {
|
|
|
42792
42818
|
}
|
|
42793
42819
|
if (repairedArgs === undefined || repairedArgs === null) {
|
|
42794
42820
|
if (!silent) {
|
|
42795
|
-
|
|
42821
|
+
log.warn(`Tool call repair for "${toolCall.toolName}" produced no valid output`);
|
|
42796
42822
|
}
|
|
42797
42823
|
return null;
|
|
42798
42824
|
}
|
|
42799
42825
|
return { ...toolCall, input: JSON.stringify(repairedArgs) };
|
|
42800
42826
|
} catch (repairError) {
|
|
42801
42827
|
if (!silent) {
|
|
42802
|
-
|
|
42828
|
+
log.warn("Error repairing tool call", {
|
|
42829
|
+
error: String(repairError)
|
|
42830
|
+
});
|
|
42803
42831
|
}
|
|
42804
42832
|
return null;
|
|
42805
42833
|
}
|
|
@@ -42812,12 +42840,14 @@ function streamResponse(opts) {
|
|
|
42812
42840
|
const outerErrorMessage = error instanceof Error ? error.message : String(error);
|
|
42813
42841
|
if (isContextLengthError) {
|
|
42814
42842
|
if (!silent) {
|
|
42815
|
-
|
|
42843
|
+
log.warn(`Context length error, summarizing ${messagesContainer.current.length} messages`, { error: outerErrorMessage });
|
|
42816
42844
|
}
|
|
42817
42845
|
return wrapStreamWithErrorHandler(createSummarizationStream(messagesContainer.current, opts, providerModel), messagesContainer, opts, providerModel, silent);
|
|
42818
42846
|
}
|
|
42819
42847
|
if (!silent) {
|
|
42820
|
-
|
|
42848
|
+
log.error("Non-context length error, re-throwing", {
|
|
42849
|
+
error: outerErrorMessage
|
|
42850
|
+
});
|
|
42821
42851
|
}
|
|
42822
42852
|
throw error;
|
|
42823
42853
|
}
|
|
@@ -42890,14 +42920,17 @@ async function generateObjectResponse(opts) {
|
|
|
42890
42920
|
}
|
|
42891
42921
|
throw lastError;
|
|
42892
42922
|
}
|
|
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.";
|
|
42923
|
+
var log, 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.";
|
|
42894
42924
|
var init_ai = __esm(() => {
|
|
42895
42925
|
init_dist4();
|
|
42926
|
+
init_structured();
|
|
42896
42927
|
init_observability();
|
|
42928
|
+
init_lazyLogger();
|
|
42897
42929
|
init_caching();
|
|
42898
42930
|
init_contextManagement();
|
|
42899
42931
|
init_models();
|
|
42900
42932
|
init_utils();
|
|
42933
|
+
log = scopedLogger(() => createLogger("ai"));
|
|
42901
42934
|
OPENAI_REASONING_MODEL_IDS = new Set([
|
|
42902
42935
|
"gpt-5",
|
|
42903
42936
|
"gpt-5-2025-08-07",
|
|
@@ -42937,6 +42970,1407 @@ var init_ai = __esm(() => {
|
|
|
42937
42970
|
};
|
|
42938
42971
|
});
|
|
42939
42972
|
|
|
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-9d2es97h.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
|
+
|
|
42940
44374
|
// src/core/ai/providers/pensarFormatters.ts
|
|
42941
44375
|
function convertToBedrockFormat(modelId, options) {
|
|
42942
44376
|
if (modelId.includes("anthropic.claude")) {
|
|
@@ -43139,11 +44573,9 @@ async function* parseSSE(stream, options = {}) {
|
|
|
43139
44573
|
clearTimeout(timeoutId);
|
|
43140
44574
|
}
|
|
43141
44575
|
if (result.done) {
|
|
43142
|
-
|
|
43143
|
-
|
|
43144
|
-
|
|
43145
|
-
console.error(`[parseSSE] remaining buffer: ${buffer.slice(0, 500)}`);
|
|
43146
|
-
}
|
|
44576
|
+
log2.debug(`stream done: ${chunkCount} chunks, ${totalBytes} bytes, ${eventCount} events yielded, remaining buffer=${buffer.length} chars`);
|
|
44577
|
+
if (buffer.length > 0) {
|
|
44578
|
+
log2.debug(`remaining buffer: ${buffer.slice(0, 500)}`);
|
|
43147
44579
|
}
|
|
43148
44580
|
break;
|
|
43149
44581
|
}
|
|
@@ -43151,8 +44583,8 @@ async function* parseSSE(stream, options = {}) {
|
|
|
43151
44583
|
chunkCount++;
|
|
43152
44584
|
totalBytes += value.byteLength;
|
|
43153
44585
|
const decoded = decoder.decode(value, { stream: true });
|
|
43154
|
-
if (
|
|
43155
|
-
|
|
44586
|
+
if (chunkCount <= 3) {
|
|
44587
|
+
log2.debug(`chunk #${chunkCount}: ${value.byteLength} bytes, preview: ${decoded.slice(0, 200)}`);
|
|
43156
44588
|
}
|
|
43157
44589
|
buffer += decoded;
|
|
43158
44590
|
const lines = buffer.split(`
|
|
@@ -43177,34 +44609,38 @@ async function* parseSSE(stream, options = {}) {
|
|
|
43177
44609
|
}
|
|
43178
44610
|
if (currentData.length > 0) {
|
|
43179
44611
|
eventCount++;
|
|
43180
|
-
|
|
43181
|
-
console.error(`[parseSSE] flushing final event: ${currentEvent}`);
|
|
44612
|
+
log2.debug(`flushing final event: ${currentEvent}`);
|
|
43182
44613
|
yield { event: currentEvent, data: currentData.join(`
|
|
43183
44614
|
`) };
|
|
43184
44615
|
}
|
|
43185
44616
|
if (eventCount === 0) {
|
|
43186
|
-
|
|
44617
|
+
log2.warn(`stream ended with 0 events! totalBytes=${totalBytes}, chunks=${chunkCount}`);
|
|
43187
44618
|
}
|
|
43188
44619
|
} finally {
|
|
43189
44620
|
reader.releaseLock();
|
|
43190
44621
|
}
|
|
43191
44622
|
}
|
|
43192
|
-
var
|
|
44623
|
+
var log2;
|
|
43193
44624
|
var init_pensarSSE = __esm(() => {
|
|
43194
|
-
|
|
44625
|
+
init_structured();
|
|
44626
|
+
init_lazyLogger();
|
|
44627
|
+
log2 = scopedLogger(() => createLogger("pensarSSE"));
|
|
43195
44628
|
});
|
|
43196
44629
|
|
|
43197
44630
|
// src/core/ai/providers/pensar.ts
|
|
43198
|
-
function
|
|
43199
|
-
|
|
43200
|
-
|
|
44631
|
+
function fmtArgs(args) {
|
|
44632
|
+
return args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
44633
|
+
}
|
|
44634
|
+
function log3(...args) {
|
|
44635
|
+
structuredLog.debug(fmtArgs(args));
|
|
43201
44636
|
}
|
|
43202
44637
|
function logInfo(...args) {
|
|
43203
|
-
|
|
43204
|
-
console.error("[pensar]", ...args);
|
|
44638
|
+
structuredLog.debug(fmtArgs(args));
|
|
43205
44639
|
}
|
|
43206
44640
|
function logError(...args) {
|
|
43207
|
-
|
|
44641
|
+
const err = args.find((a) => a instanceof Error);
|
|
44642
|
+
const msg = fmtArgs(args.filter((a) => !(a instanceof Error)));
|
|
44643
|
+
structuredLog.error(msg, err);
|
|
43208
44644
|
}
|
|
43209
44645
|
function createPensarModel(bedrockModelId, config2) {
|
|
43210
44646
|
const modelId = `pensar:${bedrockModelId}`;
|
|
@@ -43220,14 +44656,14 @@ function createPensarModel(bedrockModelId, config2) {
|
|
|
43220
44656
|
throw new Error("Pensar authentication failed. Run /login to reconnect.");
|
|
43221
44657
|
}
|
|
43222
44658
|
headers.Authorization = `Bearer ${result.token.slice(0, 12)}…`;
|
|
43223
|
-
|
|
44659
|
+
log3(` auth: ${result.type} token (${result.token.length} chars)`);
|
|
43224
44660
|
if (config2.workspaceId) {
|
|
43225
44661
|
headers["X-Workspace-Id"] = config2.workspaceId;
|
|
43226
44662
|
}
|
|
43227
44663
|
headers.Authorization = `Bearer ${result.token}`;
|
|
43228
44664
|
} else {
|
|
43229
44665
|
headers.Authorization = `Bearer ${config2.apiKey}`;
|
|
43230
|
-
|
|
44666
|
+
log3(` auth: apiKey (${config2.apiKey.length} chars)`);
|
|
43231
44667
|
if (config2.workspaceId && !config2.apiKey.startsWith("sk-")) {
|
|
43232
44668
|
headers["X-Workspace-Id"] = config2.workspaceId;
|
|
43233
44669
|
}
|
|
@@ -43336,7 +44772,7 @@ function createPensarModel(bedrockModelId, config2) {
|
|
|
43336
44772
|
const body = convertToBedrockFormat(bedrockModelId, options);
|
|
43337
44773
|
const url = `${config2.baseUrl}/gateway/invoke`;
|
|
43338
44774
|
logInfo(`doStream → ${bedrockModelId} (${url})`);
|
|
43339
|
-
|
|
44775
|
+
log3(` messages: ${body.messages?.length ?? 0}, tools: ${body.tools?.length ?? 0}`);
|
|
43340
44776
|
const startTime = Date.now();
|
|
43341
44777
|
const serializedBody = JSON.stringify({
|
|
43342
44778
|
modelId: bedrockModelId,
|
|
@@ -43349,7 +44785,7 @@ function createPensarModel(bedrockModelId, config2) {
|
|
|
43349
44785
|
headers["X-Pensar-Timestamp"] = sig.timestamp;
|
|
43350
44786
|
headers["X-Pensar-Nonce"] = sig.nonce;
|
|
43351
44787
|
}
|
|
43352
|
-
|
|
44788
|
+
log3(` headers: ${Object.keys(headers).join(", ")}`);
|
|
43353
44789
|
const fetchSignal = buildStreamingFetchSignal(options.abortSignal);
|
|
43354
44790
|
let response;
|
|
43355
44791
|
try {
|
|
@@ -43426,10 +44862,10 @@ function createPensarModel(bedrockModelId, config2) {
|
|
|
43426
44862
|
try {
|
|
43427
44863
|
parsed = JSON.parse(sse.data);
|
|
43428
44864
|
} catch {
|
|
43429
|
-
|
|
44865
|
+
log3(` SSE event #${eventCount}: unparseable data, skipping`);
|
|
43430
44866
|
continue;
|
|
43431
44867
|
}
|
|
43432
|
-
|
|
44868
|
+
log3(` SSE event #${eventCount}: ${sse.event} (type=${parsed.type})`);
|
|
43433
44869
|
if (sse.event === "error") {
|
|
43434
44870
|
const msg = parsed.error ?? "Unknown streaming error";
|
|
43435
44871
|
logError(` SSE error event: ${msg}`);
|
|
@@ -43438,7 +44874,7 @@ function createPensarModel(bedrockModelId, config2) {
|
|
|
43438
44874
|
}
|
|
43439
44875
|
if (sse.event === "pensar:usage") {
|
|
43440
44876
|
if (parsed.totalCost != null) {
|
|
43441
|
-
|
|
44877
|
+
log3(` cost: $${Number(parsed.totalCost).toFixed(6)}`);
|
|
43442
44878
|
}
|
|
43443
44879
|
continue;
|
|
43444
44880
|
}
|
|
@@ -43625,13 +45061,15 @@ function mapStopReason(reason) {
|
|
|
43625
45061
|
return "other";
|
|
43626
45062
|
}
|
|
43627
45063
|
}
|
|
43628
|
-
var
|
|
45064
|
+
var structuredLog;
|
|
43629
45065
|
var init_pensar2 = __esm(() => {
|
|
45066
|
+
init_structured();
|
|
45067
|
+
init_lazyLogger();
|
|
43630
45068
|
init_utils();
|
|
43631
45069
|
init_pensarFormatters();
|
|
43632
45070
|
init_pensarSigning();
|
|
43633
45071
|
init_pensarSSE();
|
|
43634
|
-
|
|
45072
|
+
structuredLog = scopedLogger(() => createLogger("pensar"));
|
|
43635
45073
|
});
|
|
43636
45074
|
|
|
43637
45075
|
// src/core/ai/utils.ts
|
|
@@ -43735,9 +45173,7 @@ function getProviderModel(model, authConfig) {
|
|
|
43735
45173
|
}
|
|
43736
45174
|
const gatewayUrl = authConfig?.gatewayUrl || getPensarGatewayUrl();
|
|
43737
45175
|
const bedrockModelId = model.startsWith("pensar:") ? model.slice(7) : model;
|
|
43738
|
-
|
|
43739
|
-
console.log(`[pensar] getProviderModel: ${model} → bedrock:${bedrockModelId} via ${gatewayUrl}`);
|
|
43740
|
-
}
|
|
45176
|
+
log4.debug(`getProviderModel: ${model} → bedrock:${bedrockModelId} via ${gatewayUrl}`);
|
|
43741
45177
|
const modelConfig = {
|
|
43742
45178
|
apiKey: pensarApiKey || authConfig?.accessToken || "",
|
|
43743
45179
|
baseUrl: gatewayUrl,
|
|
@@ -43954,7 +45390,7 @@ function createSummarizationStream(messages, opts, model) {
|
|
|
43954
45390
|
}
|
|
43955
45391
|
};
|
|
43956
45392
|
}
|
|
43957
|
-
var STREAMING_FETCH_TIMEOUT_MS;
|
|
45393
|
+
var log4, STREAMING_FETCH_TIMEOUT_MS;
|
|
43958
45394
|
var init_utils = __esm(() => {
|
|
43959
45395
|
init_dist6();
|
|
43960
45396
|
init_dist7();
|
|
@@ -43966,11 +45402,14 @@ var init_utils = __esm(() => {
|
|
|
43966
45402
|
init_constants();
|
|
43967
45403
|
init_auth();
|
|
43968
45404
|
init_config();
|
|
45405
|
+
init_structured();
|
|
45406
|
+
init_lazyLogger();
|
|
43969
45407
|
init_ai();
|
|
43970
45408
|
init_contextManagement();
|
|
43971
45409
|
init_models();
|
|
43972
45410
|
init_pensar2();
|
|
45411
|
+
log4 = scopedLogger(() => createLogger("ai:utils"));
|
|
43973
45412
|
STREAMING_FETCH_TIMEOUT_MS = 15 * 60 * 1000;
|
|
43974
45413
|
});
|
|
43975
45414
|
|
|
43976
|
-
export { stepCountIs, hasToolCall, init_dist4 as init_dist,
|
|
45415
|
+
export { stepCountIs, hasToolCall, init_dist4 as init_dist, AVAILABLE_MODELS, init_models, require_tslib, scopedLogger, init_lazyLogger, buildAuthConfig, init_utils, init_ai2 as init_ai, generateRandomName, generateSessionName, init_name, CredentialManager, init_credentials, schema, descending, init_id, RateLimiter, init_rateLimiter, NotFoundError, write2 as write, createDir, writeRaw, read2 as read, update, list, init_storage, ToolsetStateSchema, init_toolset, create2 as create, list2 as list1, normalizeMessages, sessions, init_session, writeErrorLog, init_logger, createLogger, logger, init_structured, getApexTracer, init_observability, DEFAULT_OPENAI_REASONING_EFFORT, modelSupportsThinking, modelSupportsOpenAIReasoning, getOpenAIReasoningEfforts, streamResponse, generateObjectResponse, init_ai as init_ai1 };
|