context-lens 0.3.2 → 0.4.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 +52 -16
- package/dist/analysis/ingest.d.ts +13 -0
- package/dist/analysis/ingest.d.ts.map +1 -0
- package/dist/analysis/ingest.js +75 -0
- package/dist/analysis/ingest.js.map +1 -0
- package/dist/analysis/server.d.ts +10 -0
- package/dist/analysis/server.d.ts.map +1 -0
- package/dist/analysis/server.js +95 -0
- package/dist/analysis/server.js.map +1 -0
- package/dist/analysis/watcher.d.ts +55 -0
- package/dist/analysis/watcher.d.ts.map +1 -0
- package/dist/analysis/watcher.js +170 -0
- package/dist/analysis/watcher.js.map +1 -0
- package/dist/cli-utils.d.ts +16 -0
- package/dist/cli-utils.d.ts.map +1 -1
- package/dist/cli-utils.js +185 -3
- package/dist/cli-utils.js.map +1 -1
- package/dist/cli.js +629 -88
- package/dist/cli.js.map +1 -1
- package/dist/core/conversation.d.ts +8 -1
- package/dist/core/conversation.d.ts.map +1 -1
- package/dist/core/conversation.js +38 -12
- package/dist/core/conversation.js.map +1 -1
- package/dist/core/parse.d.ts.map +1 -1
- package/dist/core/parse.js +17 -1
- package/dist/core/parse.js.map +1 -1
- package/dist/core/session-analysis.d.ts +100 -0
- package/dist/core/session-analysis.d.ts.map +1 -0
- package/dist/core/session-analysis.js +435 -0
- package/dist/core/session-analysis.js.map +1 -0
- package/dist/core/session-format.d.ts +20 -0
- package/dist/core/session-format.d.ts.map +1 -0
- package/dist/core/session-format.js +298 -0
- package/dist/core/session-format.js.map +1 -0
- package/dist/core.d.ts +4 -0
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +2 -0
- package/dist/core.js.map +1 -1
- package/dist/lhar/reader.d.ts +22 -0
- package/dist/lhar/reader.d.ts.map +1 -0
- package/dist/lhar/reader.js +43 -0
- package/dist/lhar/reader.js.map +1 -0
- package/dist/lhar/record.d.ts.map +1 -1
- package/dist/lhar/record.js +3 -0
- package/dist/lhar/record.js.map +1 -1
- package/dist/lhar/response.d.ts +8 -0
- package/dist/lhar/response.d.ts.map +1 -1
- package/dist/lhar/response.js +44 -0
- package/dist/lhar/response.js.map +1 -1
- package/dist/lhar/tools.d.ts +17 -0
- package/dist/lhar/tools.d.ts.map +1 -0
- package/dist/lhar/tools.js +48 -0
- package/dist/lhar/tools.js.map +1 -0
- package/dist/lhar-types.generated.d.ts +34 -0
- package/dist/lhar-types.generated.d.ts.map +1 -1
- package/dist/lhar.d.ts +4 -1
- package/dist/lhar.d.ts.map +1 -1
- package/dist/lhar.js +5 -1
- package/dist/lhar.js.map +1 -1
- package/dist/proxy/capture.d.ts +40 -0
- package/dist/proxy/capture.d.ts.map +1 -0
- package/dist/proxy/capture.js +56 -0
- package/dist/proxy/capture.js.map +1 -0
- package/dist/proxy/config.d.ts +16 -0
- package/dist/proxy/config.d.ts.map +1 -0
- package/dist/proxy/config.js +34 -0
- package/dist/proxy/config.js.map +1 -0
- package/dist/proxy/forward.d.ts +20 -0
- package/dist/proxy/forward.d.ts.map +1 -0
- package/dist/proxy/forward.js +210 -0
- package/dist/proxy/forward.js.map +1 -0
- package/dist/proxy/headers.d.ts +16 -0
- package/dist/proxy/headers.d.ts.map +1 -0
- package/dist/proxy/headers.js +37 -0
- package/dist/proxy/headers.js.map +1 -0
- package/dist/proxy/routing.d.ts +44 -0
- package/dist/proxy/routing.d.ts.map +1 -0
- package/dist/proxy/routing.js +114 -0
- package/dist/proxy/routing.js.map +1 -0
- package/dist/proxy/server.d.ts +27 -0
- package/dist/proxy/server.d.ts.map +1 -0
- package/dist/proxy/server.js +55 -0
- package/dist/proxy/server.js.map +1 -0
- package/dist/schemas.d.ts +328 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +249 -0
- package/dist/schemas.js.map +1 -0
- package/dist/server/api.d.ts +3 -4
- package/dist/server/api.d.ts.map +1 -1
- package/dist/server/api.js +195 -220
- package/dist/server/api.js.map +1 -1
- package/dist/server/store.d.ts +23 -7
- package/dist/server/store.d.ts.map +1 -1
- package/dist/server/store.js +141 -50
- package/dist/server/store.js.map +1 -1
- package/dist/server/webui.d.ts +5 -2
- package/dist/server/webui.d.ts.map +1 -1
- package/dist/server/webui.js +32 -13
- package/dist/server/webui.js.map +1 -1
- package/dist/server-utils.d.ts +1 -2
- package/dist/server-utils.d.ts.map +1 -1
- package/dist/server-utils.js +0 -2
- package/dist/server-utils.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +1 -1
- package/mitm_addon.py +99 -28
- package/package.json +12 -5
- package/schema/lhar.schema.json +50 -0
- package/dist/server/config.d.ts +0 -13
- package/dist/server/config.d.ts.map +0 -1
- package/dist/server/config.js +0 -36
- package/dist/server/config.js.map +0 -1
- package/dist/server/proxy.d.ts +0 -13
- package/dist/server/proxy.d.ts.map +0 -1
- package/dist/server/proxy.js +0 -218
- package/dist/server/proxy.js.map +0 -1
- package/dist/server/static.d.ts +0 -9
- package/dist/server/static.d.ts.map +0 -1
- package/dist/server/static.js +0 -78
- package/dist/server/static.js.map +0 -1
- package/dist/server.d.ts +0 -3
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -43
- package/dist/server.js.map +0 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract structured tool definition summaries from a ContextInfo.
|
|
3
|
+
*
|
|
4
|
+
* Returns one entry per tool schema available to the model, with name and
|
|
5
|
+
* description only (no full input_schema, keeping the LHAR lightweight).
|
|
6
|
+
*/
|
|
7
|
+
export function extractToolDefinitions(contextInfo) {
|
|
8
|
+
return contextInfo.tools.map((tool) => {
|
|
9
|
+
if ("function" in tool) {
|
|
10
|
+
// OpenAI format: { type: "function", function: { name, description } }
|
|
11
|
+
const fn = tool.function;
|
|
12
|
+
return {
|
|
13
|
+
name: fn.name,
|
|
14
|
+
description: fn.description ?? null,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
// Anthropic format: { name, description } or Gemini functionDeclarations
|
|
18
|
+
const t = tool;
|
|
19
|
+
return {
|
|
20
|
+
name: t.name,
|
|
21
|
+
description: t.description ?? null,
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Extract structured tool call entries from a ContextInfo's parsed messages.
|
|
27
|
+
*
|
|
28
|
+
* Scans contentBlocks for tool_use blocks and returns each invocation with
|
|
29
|
+
* its name, call ID, and arguments.
|
|
30
|
+
*/
|
|
31
|
+
export function extractToolCalls(contextInfo) {
|
|
32
|
+
const calls = [];
|
|
33
|
+
for (const msg of contextInfo.messages) {
|
|
34
|
+
if (!msg.contentBlocks)
|
|
35
|
+
continue;
|
|
36
|
+
for (const block of msg.contentBlocks) {
|
|
37
|
+
if (block.type === "tool_use" && "name" in block) {
|
|
38
|
+
calls.push({
|
|
39
|
+
name: block.name,
|
|
40
|
+
call_id: block.id || null,
|
|
41
|
+
arguments: block.input ?? null,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return calls;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/lhar/tools.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACpC,WAAwB;IAExB,OAAO,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACpC,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;YACvB,uEAAuE;YACvE,MAAM,EAAE,GAAI,IAAmB,CAAC,QAAQ,CAAC;YACzC,OAAO;gBACL,IAAI,EAAE,EAAE,CAAC,IAAI;gBACb,WAAW,EAAE,EAAE,CAAC,WAAW,IAAI,IAAI;aACpC,CAAC;QACJ,CAAC;QACD,yEAAyE;QACzE,MAAM,CAAC,GAAG,IAAqB,CAAC;QAChC,OAAO;YACL,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,IAAI;SACnC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAwB;IACvD,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;QACvC,IAAI,CAAC,GAAG,CAAC,aAAa;YAAE,SAAS;QACjC,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC;YACtC,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;gBACjD,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,OAAO,EAAE,KAAK,CAAC,EAAE,IAAI,IAAI;oBACzB,SAAS,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI;iBAC/B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -14,6 +14,32 @@ export type CompositionCategory = "system_prompt" | "tool_definitions" | "tool_r
|
|
|
14
14
|
export interface LHARLLMHTTPArchiveFormat {
|
|
15
15
|
[k: string]: unknown;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* A tool/function available to the model in this request.
|
|
19
|
+
*
|
|
20
|
+
* This interface was referenced by `LHARLLMHTTPArchiveFormat`'s JSON-Schema
|
|
21
|
+
* via the `definition` "ToolDefinitionEntry".
|
|
22
|
+
*/
|
|
23
|
+
export interface ToolDefinitionEntry {
|
|
24
|
+
name: string;
|
|
25
|
+
description: string | null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A tool invocation found in the conversation history of this request.
|
|
29
|
+
*
|
|
30
|
+
* This interface was referenced by `LHARLLMHTTPArchiveFormat`'s JSON-Schema
|
|
31
|
+
* via the `definition` "ToolCallEntry".
|
|
32
|
+
*/
|
|
33
|
+
export interface ToolCallEntry {
|
|
34
|
+
name: string;
|
|
35
|
+
call_id: string | null;
|
|
36
|
+
/**
|
|
37
|
+
* The arguments passed to the tool. Object when parsed, string when raw/unparsed.
|
|
38
|
+
*/
|
|
39
|
+
arguments: {
|
|
40
|
+
[k: string]: unknown;
|
|
41
|
+
} | string | null;
|
|
42
|
+
}
|
|
17
43
|
/**
|
|
18
44
|
* This interface was referenced by `LHARLLMHTTPArchiveFormat`'s JSON-Schema
|
|
19
45
|
* via the `definition` "CompositionEntry".
|
|
@@ -120,6 +146,14 @@ export interface LharRecord {
|
|
|
120
146
|
cumulative_tokens: number;
|
|
121
147
|
compaction_detected: boolean;
|
|
122
148
|
};
|
|
149
|
+
/**
|
|
150
|
+
* Tool/function schemas available to the model in this request.
|
|
151
|
+
*/
|
|
152
|
+
tool_definitions?: ToolDefinitionEntry[];
|
|
153
|
+
/**
|
|
154
|
+
* Tool invocations found in the conversation history of this request.
|
|
155
|
+
*/
|
|
156
|
+
tool_calls?: ToolCallEntry[];
|
|
123
157
|
security: {
|
|
124
158
|
alerts: {
|
|
125
159
|
message_index: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lhar-types.generated.d.ts","sourceRoot":"","sources":["../src/lhar-types.generated.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lhar-types.generated.d.ts","sourceRoot":"","sources":["../src/lhar-types.generated.ts"],"names":[],"mappings":"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"}
|
package/dist/lhar.d.ts
CHANGED
|
@@ -7,7 +7,10 @@
|
|
|
7
7
|
export { redactHeaders, SENSITIVE_HEADERS } from "./http/headers.js";
|
|
8
8
|
export { analyzeComposition, normalizeComposition, } from "./lhar/composition.js";
|
|
9
9
|
export { toLharJson, toLharJsonl } from "./lhar/export.js";
|
|
10
|
+
export type { ParsedLhar } from "./lhar/reader.js";
|
|
11
|
+
export { parseLharContent, readLharFile } from "./lhar/reader.js";
|
|
10
12
|
export { buildLharRecord, buildSessionLine } from "./lhar/record.js";
|
|
11
13
|
export type { ParsedResponseUsage } from "./lhar/response.js";
|
|
12
|
-
export { parseResponseUsage } from "./lhar/response.js";
|
|
14
|
+
export { extractResponseId, parseResponseUsage } from "./lhar/response.js";
|
|
15
|
+
export { extractToolCalls, extractToolDefinitions } from "./lhar/tools.js";
|
|
13
16
|
//# sourceMappingURL=lhar.d.ts.map
|
package/dist/lhar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lhar.d.ts","sourceRoot":"","sources":["../src/lhar.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAErE,OAAO,EACL,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"lhar.d.ts","sourceRoot":"","sources":["../src/lhar.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAErE,OAAO,EACL,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC3D,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAElE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACrE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE3E,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/lhar.js
CHANGED
|
@@ -10,8 +10,12 @@ export { redactHeaders, SENSITIVE_HEADERS } from "./http/headers.js";
|
|
|
10
10
|
export { analyzeComposition, normalizeComposition, } from "./lhar/composition.js";
|
|
11
11
|
// Export serialization (JSONL / JSON)
|
|
12
12
|
export { toLharJson, toLharJsonl } from "./lhar/export.js";
|
|
13
|
+
// LHAR file reader
|
|
14
|
+
export { parseLharContent, readLharFile } from "./lhar/reader.js";
|
|
13
15
|
// Record & session builders
|
|
14
16
|
export { buildLharRecord, buildSessionLine } from "./lhar/record.js";
|
|
15
17
|
// Response usage parsing
|
|
16
|
-
export { parseResponseUsage } from "./lhar/response.js";
|
|
18
|
+
export { extractResponseId, parseResponseUsage } from "./lhar/response.js";
|
|
19
|
+
// Tool extraction
|
|
20
|
+
export { extractToolCalls, extractToolDefinitions } from "./lhar/tools.js";
|
|
17
21
|
//# sourceMappingURL=lhar.js.map
|
package/dist/lhar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lhar.js","sourceRoot":"","sources":["../src/lhar.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,4DAA4D;AAC5D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACrE,uBAAuB;AACvB,OAAO,EACL,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,sCAAsC;AACtC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE3D,4BAA4B;AAC5B,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAErE,yBAAyB;AACzB,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"lhar.js","sourceRoot":"","sources":["../src/lhar.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,4DAA4D;AAC5D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACrE,uBAAuB;AACvB,OAAO,EACL,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,sCAAsC;AACtC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE3D,mBAAmB;AACnB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAClE,4BAA4B;AAC5B,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAErE,yBAAyB;AACzB,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,kBAAkB;AAClB,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capture writer for the proxy.
|
|
3
|
+
*
|
|
4
|
+
* Writes raw request/response pairs as JSON files to the capture directory.
|
|
5
|
+
* Uses atomic writes (write to .tmp, then rename) so readers never see
|
|
6
|
+
* partial files. Zero external dependencies.
|
|
7
|
+
*/
|
|
8
|
+
export interface CaptureData {
|
|
9
|
+
timestamp: string;
|
|
10
|
+
method: string;
|
|
11
|
+
path: string;
|
|
12
|
+
source: string | null;
|
|
13
|
+
provider: string;
|
|
14
|
+
apiFormat: string;
|
|
15
|
+
targetUrl: string;
|
|
16
|
+
requestHeaders: Record<string, string>;
|
|
17
|
+
requestBody: Record<string, any> | null;
|
|
18
|
+
requestBytes: number;
|
|
19
|
+
responseStatus: number;
|
|
20
|
+
responseHeaders: Record<string, string>;
|
|
21
|
+
responseBody: string;
|
|
22
|
+
responseIsStreaming: boolean;
|
|
23
|
+
responseBytes: number;
|
|
24
|
+
timings: {
|
|
25
|
+
send_ms: number;
|
|
26
|
+
wait_ms: number;
|
|
27
|
+
receive_ms: number;
|
|
28
|
+
total_ms: number;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create a capture writer for a given directory.
|
|
33
|
+
*
|
|
34
|
+
* Ensures the directory exists on first use. File names are
|
|
35
|
+
* `{timestamp}-{counter}.json` for natural sort order and uniqueness.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createCaptureWriter(captureDir: string): {
|
|
38
|
+
write: (capture: CaptureData) => string | null;
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=capture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/proxy/capture.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE;QACP,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM;qBAe5B,WAAW,KAAG,MAAM,GAAG,IAAI;EA4BpD"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capture writer for the proxy.
|
|
3
|
+
*
|
|
4
|
+
* Writes raw request/response pairs as JSON files to the capture directory.
|
|
5
|
+
* Uses atomic writes (write to .tmp, then rename) so readers never see
|
|
6
|
+
* partial files. Zero external dependencies.
|
|
7
|
+
*/
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
/**
|
|
11
|
+
* Create a capture writer for a given directory.
|
|
12
|
+
*
|
|
13
|
+
* Ensures the directory exists on first use. File names are
|
|
14
|
+
* `{timestamp}-{counter}.json` for natural sort order and uniqueness.
|
|
15
|
+
*/
|
|
16
|
+
export function createCaptureWriter(captureDir) {
|
|
17
|
+
let dirReady = false;
|
|
18
|
+
let counter = 0;
|
|
19
|
+
function ensureDir() {
|
|
20
|
+
if (dirReady)
|
|
21
|
+
return;
|
|
22
|
+
fs.mkdirSync(captureDir, { recursive: true });
|
|
23
|
+
dirReady = true;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Write a capture to disk atomically.
|
|
27
|
+
*
|
|
28
|
+
* Returns the filename (without directory) on success, or null on error.
|
|
29
|
+
*/
|
|
30
|
+
function write(capture) {
|
|
31
|
+
ensureDir();
|
|
32
|
+
const seq = String(counter++).padStart(6, "0");
|
|
33
|
+
const ts = Date.now();
|
|
34
|
+
const filename = `${ts}-${seq}.json`;
|
|
35
|
+
const filePath = join(captureDir, filename);
|
|
36
|
+
const tmpPath = `${filePath}.tmp`;
|
|
37
|
+
try {
|
|
38
|
+
fs.writeFileSync(tmpPath, JSON.stringify(capture));
|
|
39
|
+
fs.renameSync(tmpPath, filePath);
|
|
40
|
+
return filename;
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
console.error("Capture write error:", err instanceof Error ? err.message : String(err));
|
|
44
|
+
// Clean up temp file if rename failed
|
|
45
|
+
try {
|
|
46
|
+
fs.unlinkSync(tmpPath);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
/* may not exist */
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return { write };
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/proxy/capture.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AA0BjC;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAAkB;IACpD,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,SAAS,SAAS;QAChB,IAAI,QAAQ;YAAE,OAAO;QACrB,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IAED;;;;OAIG;IACH,SAAS,KAAK,CAAC,OAAoB;QACjC,SAAS,EAAE,CAAC;QACZ,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC/C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,GAAG,QAAQ,MAAM,CAAC;QAElC,IAAI,CAAC;YACH,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;YACnD,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACjC,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CACX,sBAAsB,EACtB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACjD,CAAC;YACF,sCAAsC;YACtC,IAAI,CAAC;gBACH,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACzB,CAAC;YAAC,MAAM,CAAC;gBACP,mBAAmB;YACrB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proxy configuration.
|
|
3
|
+
*
|
|
4
|
+
* Reads from environment variables with safe defaults.
|
|
5
|
+
* Zero external dependencies.
|
|
6
|
+
*/
|
|
7
|
+
import type { Upstreams } from "./routing.js";
|
|
8
|
+
export interface ProxyConfig {
|
|
9
|
+
upstreams: Upstreams;
|
|
10
|
+
bindHost: string;
|
|
11
|
+
port: number;
|
|
12
|
+
allowTargetOverride: boolean;
|
|
13
|
+
captureDir: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function loadProxyConfig(): ProxyConfig;
|
|
16
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/proxy/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB,EAAE,OAAO,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,eAAe,IAAI,WAAW,CAiC7C"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proxy configuration.
|
|
3
|
+
*
|
|
4
|
+
* Reads from environment variables with safe defaults.
|
|
5
|
+
* Zero external dependencies.
|
|
6
|
+
*/
|
|
7
|
+
import { homedir } from "node:os";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
export function loadProxyConfig() {
|
|
10
|
+
const upstreams = {
|
|
11
|
+
openai: process.env.UPSTREAM_OPENAI_URL || "https://api.openai.com/v1",
|
|
12
|
+
anthropic: process.env.UPSTREAM_ANTHROPIC_URL || "https://api.anthropic.com",
|
|
13
|
+
chatgpt: process.env.UPSTREAM_CHATGPT_URL || "https://chatgpt.com",
|
|
14
|
+
gemini: process.env.UPSTREAM_GEMINI_URL ||
|
|
15
|
+
"https://generativelanguage.googleapis.com",
|
|
16
|
+
geminiCodeAssist: process.env.UPSTREAM_GEMINI_CODE_ASSIST_URL ||
|
|
17
|
+
"https://cloudcode-pa.googleapis.com",
|
|
18
|
+
};
|
|
19
|
+
// Bind only to localhost unless explicitly overridden.
|
|
20
|
+
const bindHost = process.env.CONTEXT_LENS_BIND_HOST || "127.0.0.1";
|
|
21
|
+
const port = parseInt(process.env.CONTEXT_LENS_PROXY_PORT || "4040", 10);
|
|
22
|
+
// Do not honor `x-target-url` unless explicitly enabled.
|
|
23
|
+
const allowTargetOverride = process.env.CONTEXT_LENS_ALLOW_TARGET_OVERRIDE === "1";
|
|
24
|
+
const captureDir = process.env.CONTEXT_LENS_CAPTURE_DIR ||
|
|
25
|
+
join(homedir(), ".context-lens", "captures");
|
|
26
|
+
return {
|
|
27
|
+
upstreams,
|
|
28
|
+
bindHost,
|
|
29
|
+
port,
|
|
30
|
+
allowTargetOverride,
|
|
31
|
+
captureDir,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/proxy/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAYjC,MAAM,UAAU,eAAe;IAC7B,MAAM,SAAS,GAAc;QAC3B,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,2BAA2B;QACtE,SAAS,EACP,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,2BAA2B;QACnE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,qBAAqB;QAClE,MAAM,EACJ,OAAO,CAAC,GAAG,CAAC,mBAAmB;YAC/B,2CAA2C;QAC7C,gBAAgB,EACd,OAAO,CAAC,GAAG,CAAC,+BAA+B;YAC3C,qCAAqC;KACxC,CAAC;IAEF,uDAAuD;IACvD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,WAAW,CAAC;IACnE,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;IAEzE,yDAAyD;IACzD,MAAM,mBAAmB,GACvB,OAAO,CAAC,GAAG,CAAC,kCAAkC,KAAK,GAAG,CAAC;IAEzD,MAAM,UAAU,GACd,OAAO,CAAC,GAAG,CAAC,wBAAwB;QACpC,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC;IAE/C,OAAO;QACL,SAAS;QACT,QAAQ;QACR,IAAI;QACJ,mBAAmB;QACnB,UAAU;KACX,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP forwarding logic for the proxy.
|
|
3
|
+
*
|
|
4
|
+
* Receives incoming requests, forwards them to the appropriate LLM upstream,
|
|
5
|
+
* captures the raw request/response pair to disk, and pipes the response
|
|
6
|
+
* back to the client. Zero external dependencies.
|
|
7
|
+
*/
|
|
8
|
+
import http from "node:http";
|
|
9
|
+
import type { CaptureData } from "./capture.js";
|
|
10
|
+
import { type Upstreams } from "./routing.js";
|
|
11
|
+
export interface ForwardOptions {
|
|
12
|
+
upstreams: Upstreams;
|
|
13
|
+
allowTargetOverride: boolean;
|
|
14
|
+
onCapture: (capture: CaptureData) => void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create the main proxy request handler.
|
|
18
|
+
*/
|
|
19
|
+
export declare function createProxyHandler(opts: ForwardOptions): (req: http.IncomingMessage, res: http.ServerResponse) => void;
|
|
20
|
+
//# sourceMappingURL=forward.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forward.d.ts","sourceRoot":"","sources":["../../src/proxy/forward.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,SAAS,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;CAC3C;AAgHD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,cAAc,GACnB,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,KAAK,IAAI,CAuJ/D"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP forwarding logic for the proxy.
|
|
3
|
+
*
|
|
4
|
+
* Receives incoming requests, forwards them to the appropriate LLM upstream,
|
|
5
|
+
* captures the raw request/response pair to disk, and pipes the response
|
|
6
|
+
* back to the client. Zero external dependencies.
|
|
7
|
+
*/
|
|
8
|
+
import http from "node:http";
|
|
9
|
+
import https from "node:https";
|
|
10
|
+
import url from "node:url";
|
|
11
|
+
import { selectHeaders } from "./headers.js";
|
|
12
|
+
import { classifyRequest, extractSource, resolveTargetUrl, } from "./routing.js";
|
|
13
|
+
/**
|
|
14
|
+
* Build headers to send to the upstream, stripping proxy-internal ones.
|
|
15
|
+
*/
|
|
16
|
+
function buildForwardHeaders(reqHeaders, targetHost, bodyLength) {
|
|
17
|
+
const forwardHeaders = { ...reqHeaders };
|
|
18
|
+
delete forwardHeaders["x-target-url"];
|
|
19
|
+
delete forwardHeaders.host;
|
|
20
|
+
if (targetHost) {
|
|
21
|
+
forwardHeaders.host = targetHost;
|
|
22
|
+
}
|
|
23
|
+
if (bodyLength != null) {
|
|
24
|
+
delete forwardHeaders["transfer-encoding"];
|
|
25
|
+
forwardHeaders["content-length"] = bodyLength;
|
|
26
|
+
}
|
|
27
|
+
return forwardHeaders;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Wire up error/close handlers between client response and upstream request.
|
|
31
|
+
*/
|
|
32
|
+
function attachLifecycleHandlers(res, proxyReq) {
|
|
33
|
+
res.on("close", () => {
|
|
34
|
+
if (!proxyReq.destroyed)
|
|
35
|
+
proxyReq.destroy();
|
|
36
|
+
});
|
|
37
|
+
proxyReq.on("error", (err) => {
|
|
38
|
+
if (res.destroyed)
|
|
39
|
+
return;
|
|
40
|
+
const detail = err.message || ("code" in err ? err.code : "unknown");
|
|
41
|
+
console.error("Proxy error:", detail);
|
|
42
|
+
if (!res.headersSent) {
|
|
43
|
+
res.writeHead(502, { "Content-Type": "application/json" });
|
|
44
|
+
}
|
|
45
|
+
if (!res.destroyed) {
|
|
46
|
+
res.end(JSON.stringify({ error: "Proxy error", details: err.message }));
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Resolve headers for routing, filtering x-target-url when not allowed.
|
|
52
|
+
*/
|
|
53
|
+
function headersForResolution(headers, remoteAddr, allowTargetOverride) {
|
|
54
|
+
const h = headers;
|
|
55
|
+
if (h["x-target-url"] &&
|
|
56
|
+
!(allowTargetOverride && isLocalRemote(remoteAddr))) {
|
|
57
|
+
const { "x-target-url": _drop, ...rest } = h;
|
|
58
|
+
return rest;
|
|
59
|
+
}
|
|
60
|
+
return h;
|
|
61
|
+
}
|
|
62
|
+
function isLocalRemote(addr) {
|
|
63
|
+
if (!addr)
|
|
64
|
+
return false;
|
|
65
|
+
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Forward a non-POST request (GET /v1/models, OPTIONS, etc.) without capturing.
|
|
69
|
+
*/
|
|
70
|
+
function forwardPassthrough(req, res, targetUrl, body) {
|
|
71
|
+
const targetParsed = url.parse(targetUrl);
|
|
72
|
+
const forwardHeaders = buildForwardHeaders(req.headers, targetParsed.host, body ? body.length : undefined);
|
|
73
|
+
const protocol = targetParsed.protocol === "https:" ? https : http;
|
|
74
|
+
const proxyReq = protocol.request({
|
|
75
|
+
hostname: targetParsed.hostname,
|
|
76
|
+
port: targetParsed.port,
|
|
77
|
+
path: targetParsed.path,
|
|
78
|
+
method: req.method,
|
|
79
|
+
headers: forwardHeaders,
|
|
80
|
+
}, (proxyRes) => {
|
|
81
|
+
if (!res.headersSent)
|
|
82
|
+
res.writeHead(proxyRes.statusCode, proxyRes.headers);
|
|
83
|
+
proxyRes.pipe(res);
|
|
84
|
+
proxyRes.on("error", (err) => {
|
|
85
|
+
console.error("Upstream response error (forward):", err.message);
|
|
86
|
+
if (!res.destroyed)
|
|
87
|
+
res.end();
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
attachLifecycleHandlers(res, proxyReq);
|
|
91
|
+
if (body)
|
|
92
|
+
proxyReq.write(body);
|
|
93
|
+
proxyReq.end();
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Create the main proxy request handler.
|
|
97
|
+
*/
|
|
98
|
+
export function createProxyHandler(opts) {
|
|
99
|
+
return function handleProxy(req, res) {
|
|
100
|
+
const parsedUrl = url.parse(req.url);
|
|
101
|
+
const { source, cleanPath } = extractSource(parsedUrl.pathname);
|
|
102
|
+
const search = parsedUrl.search || null;
|
|
103
|
+
const routingHeaders = headersForResolution(req.headers, req.socket.remoteAddress, opts.allowTargetOverride);
|
|
104
|
+
const { targetUrl, provider } = resolveTargetUrl(cleanPath, search, routingHeaders, opts.upstreams);
|
|
105
|
+
const { apiFormat } = classifyRequest(cleanPath, routingHeaders);
|
|
106
|
+
const hasAuth = !!req.headers.authorization;
|
|
107
|
+
const sourceTag = source ? `[${source}]` : "";
|
|
108
|
+
console.log(`${req.method} ${req.url} → ${targetUrl} [${provider}] ${sourceTag} auth=${hasAuth}`);
|
|
109
|
+
// Non-POST requests: pass through without capturing
|
|
110
|
+
if (req.method !== "POST") {
|
|
111
|
+
forwardPassthrough(req, res, targetUrl, null);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
// Buffer the request body
|
|
115
|
+
const chunks = [];
|
|
116
|
+
let clientAborted = false;
|
|
117
|
+
req.on("data", (chunk) => {
|
|
118
|
+
chunks.push(chunk);
|
|
119
|
+
});
|
|
120
|
+
req.on("error", () => {
|
|
121
|
+
clientAborted = true;
|
|
122
|
+
});
|
|
123
|
+
req.on("end", () => {
|
|
124
|
+
if (clientAborted)
|
|
125
|
+
return;
|
|
126
|
+
const bodyBuffer = Buffer.concat(chunks);
|
|
127
|
+
const bodyText = bodyBuffer.toString("utf8");
|
|
128
|
+
// Try to parse as JSON (for the capture file), but forward regardless
|
|
129
|
+
let bodyJson = null;
|
|
130
|
+
try {
|
|
131
|
+
bodyJson = JSON.parse(bodyText);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// Not JSON; capture as null, forward the raw bytes
|
|
135
|
+
}
|
|
136
|
+
const targetParsed = url.parse(targetUrl);
|
|
137
|
+
const forwardHeaders = buildForwardHeaders(req.headers, targetParsed.host, bodyBuffer.length);
|
|
138
|
+
const protocol = targetParsed.protocol === "https:" ? https : http;
|
|
139
|
+
const startTime = performance.now();
|
|
140
|
+
let firstByteTime = 0;
|
|
141
|
+
let requestSentTime = 0;
|
|
142
|
+
const reqBytes = bodyBuffer.length;
|
|
143
|
+
const proxyReq = protocol.request({
|
|
144
|
+
hostname: targetParsed.hostname,
|
|
145
|
+
port: targetParsed.port,
|
|
146
|
+
path: targetParsed.path,
|
|
147
|
+
method: req.method,
|
|
148
|
+
headers: forwardHeaders,
|
|
149
|
+
}, (proxyRes) => {
|
|
150
|
+
console.log(` ← ${proxyRes.statusCode} ${proxyRes.statusMessage}`);
|
|
151
|
+
res.writeHead(proxyRes.statusCode, proxyRes.headers);
|
|
152
|
+
const isStreaming = proxyRes.headers["content-type"]?.includes("text/event-stream");
|
|
153
|
+
let respBytes = 0;
|
|
154
|
+
const respChunks = [];
|
|
155
|
+
proxyRes.on("data", (chunk) => {
|
|
156
|
+
if (!firstByteTime)
|
|
157
|
+
firstByteTime = performance.now();
|
|
158
|
+
respBytes += chunk.length;
|
|
159
|
+
respChunks.push(chunk);
|
|
160
|
+
if (!res.destroyed)
|
|
161
|
+
res.write(chunk);
|
|
162
|
+
});
|
|
163
|
+
proxyRes.on("end", () => {
|
|
164
|
+
const endTime = performance.now();
|
|
165
|
+
if (!firstByteTime)
|
|
166
|
+
firstByteTime = endTime;
|
|
167
|
+
const respBody = Buffer.concat(respChunks).toString("utf8");
|
|
168
|
+
const capture = {
|
|
169
|
+
timestamp: new Date().toISOString(),
|
|
170
|
+
method: req.method,
|
|
171
|
+
path: cleanPath,
|
|
172
|
+
source,
|
|
173
|
+
provider,
|
|
174
|
+
apiFormat,
|
|
175
|
+
targetUrl,
|
|
176
|
+
requestHeaders: selectHeaders(req.headers),
|
|
177
|
+
requestBody: bodyJson,
|
|
178
|
+
requestBytes: reqBytes,
|
|
179
|
+
responseStatus: proxyRes.statusCode || 0,
|
|
180
|
+
responseHeaders: selectHeaders(proxyRes.headers),
|
|
181
|
+
responseBody: respBody,
|
|
182
|
+
responseIsStreaming: !!isStreaming,
|
|
183
|
+
responseBytes: respBytes,
|
|
184
|
+
timings: {
|
|
185
|
+
send_ms: Math.round(Math.max(0, (requestSentTime || firstByteTime) - startTime)),
|
|
186
|
+
wait_ms: Math.round(Math.max(0, firstByteTime - (requestSentTime || startTime))),
|
|
187
|
+
receive_ms: Math.round(endTime - firstByteTime),
|
|
188
|
+
total_ms: Math.round(endTime - startTime),
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
opts.onCapture(capture);
|
|
192
|
+
if (!res.destroyed)
|
|
193
|
+
res.end();
|
|
194
|
+
});
|
|
195
|
+
proxyRes.on("error", (err) => {
|
|
196
|
+
console.error("Upstream response error:", err.message);
|
|
197
|
+
if (!res.destroyed)
|
|
198
|
+
res.end();
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
attachLifecycleHandlers(res, proxyReq);
|
|
202
|
+
proxyReq.on("finish", () => {
|
|
203
|
+
requestSentTime = performance.now();
|
|
204
|
+
});
|
|
205
|
+
proxyReq.write(bodyBuffer);
|
|
206
|
+
proxyReq.end();
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=forward.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forward.js","sourceRoot":"","sources":["../../src/proxy/forward.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Header redaction for the proxy.
|
|
3
|
+
*
|
|
4
|
+
* The proxy captures headers for debugging but must never persist secrets.
|
|
5
|
+
* This is the single source of truth for what gets stripped.
|
|
6
|
+
*/
|
|
7
|
+
/** Case-insensitive set of header names that must never be persisted. */
|
|
8
|
+
export declare const SENSITIVE_HEADERS: Set<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Select a safe subset of headers for capture.
|
|
11
|
+
*
|
|
12
|
+
* Drops sensitive headers and keeps only string-valued entries
|
|
13
|
+
* (Node can represent multi-valued headers as arrays).
|
|
14
|
+
*/
|
|
15
|
+
export declare function selectHeaders(headers: Record<string, any>): Record<string, string>;
|
|
16
|
+
//# sourceMappingURL=headers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../src/proxy/headers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,yEAAyE;AACzE,eAAO,MAAM,iBAAiB,aAY5B,CAAC;AAEH;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC3B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Header redaction for the proxy.
|
|
3
|
+
*
|
|
4
|
+
* The proxy captures headers for debugging but must never persist secrets.
|
|
5
|
+
* This is the single source of truth for what gets stripped.
|
|
6
|
+
*/
|
|
7
|
+
/** Case-insensitive set of header names that must never be persisted. */
|
|
8
|
+
export const SENSITIVE_HEADERS = new Set([
|
|
9
|
+
"authorization",
|
|
10
|
+
"x-api-key",
|
|
11
|
+
"cookie",
|
|
12
|
+
"set-cookie",
|
|
13
|
+
"x-target-url",
|
|
14
|
+
"proxy-authorization",
|
|
15
|
+
"x-auth-token",
|
|
16
|
+
"x-forwarded-authorization",
|
|
17
|
+
"www-authenticate",
|
|
18
|
+
"proxy-authenticate",
|
|
19
|
+
"x-goog-api-key",
|
|
20
|
+
]);
|
|
21
|
+
/**
|
|
22
|
+
* Select a safe subset of headers for capture.
|
|
23
|
+
*
|
|
24
|
+
* Drops sensitive headers and keeps only string-valued entries
|
|
25
|
+
* (Node can represent multi-valued headers as arrays).
|
|
26
|
+
*/
|
|
27
|
+
export function selectHeaders(headers) {
|
|
28
|
+
const result = {};
|
|
29
|
+
for (const [key, val] of Object.entries(headers)) {
|
|
30
|
+
if (SENSITIVE_HEADERS.has(key.toLowerCase()))
|
|
31
|
+
continue;
|
|
32
|
+
if (typeof val === "string")
|
|
33
|
+
result[key] = val;
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headers.js","sourceRoot":"","sources":["../../src/proxy/headers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,yEAAyE;AACzE,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IACvC,eAAe;IACf,WAAW;IACX,QAAQ;IACR,YAAY;IACZ,cAAc;IACd,qBAAqB;IACrB,cAAc;IACd,2BAA2B;IAC3B,kBAAkB;IAClB,oBAAoB;IACpB,gBAAgB;CACjB,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAC3B,OAA4B;IAE5B,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACjD,IAAI,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;YAAE,SAAS;QACvD,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACjD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|