@lensmcp/node-instrumentation 1.25.21 → 1.25.22
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/index.js +1 -1
- package/lib/active-work.js +1 -1
- package/lib/ai-providers.js +9 -9
- package/lib/ai-store.js +1 -1
- package/lib/callsite.js +2 -2
- package/lib/capture-file.js +1 -1
- package/lib/emit-custom.js +1 -1
- package/lib/emit.js +3 -3
- package/lib/flood-guard.js +1 -1
- package/lib/flow-context.js +1 -1
- package/lib/http-capture.js +2 -2
- package/lib/http-store.js +1 -1
- package/lib/install.js +1 -1
- package/lib/require-hook.js +1 -1
- package/lib/sql-accounting.js +1 -1
- package/lib/sql-values.js +2 -2
- package/lib/tap-ai.js +1 -1
- package/lib/tap-bullmq.js +1 -1
- package/lib/tap-egress.js +1 -1
- package/lib/tap-event-loop.js +1 -1
- package/lib/tap-exec.js +1 -1
- package/lib/tap-fs.js +1 -1
- package/lib/tap-ingress.js +1 -1
- package/lib/tap-nest-logger.js +5 -5
- package/lib/tap-nest.js +1 -1
- package/lib/tap-pg-pool.js +2 -2
- package/lib/tap-pg.js +1 -1
- package/lib/tap-redis.js +1 -1
- package/lib/tap-stdout.js +5 -5
- package/package.json +4 -4
- package/register.js +1 -1
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var s=Object.defineProperty;var o=(t,r)=>s(t,"name",{value:r,configurable:!0});var n=Object.defineProperty,e=o((t,r)=>n(t,"name",{value:r,configurable:!0}),"e");Object.defineProperty(exports,"__esModule",{value:!0}),exports.resetActiveWorkForTests=exports.installActiveWorkProbe=exports.beginActiveWork=exports.activeWorkSnapshot=exports.installLensmcpNodeInstrumentation=exports.installChildAppBridge=exports.nestTap=exports.bullmqTap=exports.redisTap=exports.pgTap=exports.tapExec=exports.tapFs=exports.stopEventLoopTapForTests=exports.tapEventLoop=exports.EXCHANGE_ID=exports.resetIngressTapForTests=exports.tapIngress=exports.resetEgressTapForTests=exports.tapEgress=exports.installRequireHook=exports.createEventFloodGuard=exports.installCustomEmit=exports.EMIT_CUSTOM=exports.lensEmitCustom=exports.maybeRotateEventFile=exports.EVENT_MAX_FILES=exports.EVENT_MAX_BYTES=exports.EVENT_FILE=exports.PROJECT=exports.isLensWriting=exports.lensEmit=void 0;var emit_1=require("./lib/emit");Object.defineProperty(exports,"lensEmit",{enumerable:!0,get:e(function(){return emit_1.lensEmit},"get")}),Object.defineProperty(exports,"isLensWriting",{enumerable:!0,get:e(function(){return emit_1.isLensWriting},"get")}),Object.defineProperty(exports,"PROJECT",{enumerable:!0,get:e(function(){return emit_1.PROJECT},"get")}),Object.defineProperty(exports,"EVENT_FILE",{enumerable:!0,get:e(function(){return emit_1.EVENT_FILE},"get")}),Object.defineProperty(exports,"EVENT_MAX_BYTES",{enumerable:!0,get:e(function(){return emit_1.EVENT_MAX_BYTES},"get")}),Object.defineProperty(exports,"EVENT_MAX_FILES",{enumerable:!0,get:e(function(){return emit_1.EVENT_MAX_FILES},"get")}),Object.defineProperty(exports,"maybeRotateEventFile",{enumerable:!0,get:e(function(){return emit_1.maybeRotateEventFile},"get")});var emit_custom_1=require("./lib/emit-custom");Object.defineProperty(exports,"lensEmitCustom",{enumerable:!0,get:e(function(){return emit_custom_1.lensEmitCustom},"get")}),Object.defineProperty(exports,"EMIT_CUSTOM",{enumerable:!0,get:e(function(){return emit_custom_1.EMIT_CUSTOM},"get")}),Object.defineProperty(exports,"installCustomEmit",{enumerable:!0,get:e(function(){return emit_custom_1.installCustomEmit},"get")});var flood_guard_1=require("./lib/flood-guard");Object.defineProperty(exports,"createEventFloodGuard",{enumerable:!0,get:e(function(){return flood_guard_1.createEventFloodGuard},"get")});var require_hook_1=require("./lib/require-hook");Object.defineProperty(exports,"installRequireHook",{enumerable:!0,get:e(function(){return require_hook_1.installRequireHook},"get")});var tap_egress_1=require("./lib/tap-egress");Object.defineProperty(exports,"tapEgress",{enumerable:!0,get:e(function(){return tap_egress_1.tapEgress},"get")}),Object.defineProperty(exports,"resetEgressTapForTests",{enumerable:!0,get:e(function(){return tap_egress_1.resetEgressTapForTests},"get")});var tap_ingress_1=require("./lib/tap-ingress");Object.defineProperty(exports,"tapIngress",{enumerable:!0,get:e(function(){return tap_ingress_1.tapIngress},"get")}),Object.defineProperty(exports,"resetIngressTapForTests",{enumerable:!0,get:e(function(){return tap_ingress_1.resetIngressTapForTests},"get")}),Object.defineProperty(exports,"EXCHANGE_ID",{enumerable:!0,get:e(function(){return tap_ingress_1.EXCHANGE_ID},"get")});var tap_event_loop_1=require("./lib/tap-event-loop");Object.defineProperty(exports,"tapEventLoop",{enumerable:!0,get:e(function(){return tap_event_loop_1.tapEventLoop},"get")}),Object.defineProperty(exports,"stopEventLoopTapForTests",{enumerable:!0,get:e(function(){return tap_event_loop_1.stopEventLoopTapForTests},"get")});var tap_fs_1=require("./lib/tap-fs");Object.defineProperty(exports,"tapFs",{enumerable:!0,get:e(function(){return tap_fs_1.tapFs},"get")});var tap_exec_1=require("./lib/tap-exec");Object.defineProperty(exports,"tapExec",{enumerable:!0,get:e(function(){return tap_exec_1.tapExec},"get")});var tap_pg_1=require("./lib/tap-pg");Object.defineProperty(exports,"pgTap",{enumerable:!0,get:e(function(){return tap_pg_1.pgTap},"get")});var tap_redis_1=require("./lib/tap-redis");Object.defineProperty(exports,"redisTap",{enumerable:!0,get:e(function(){return tap_redis_1.redisTap},"get")});var tap_bullmq_1=require("./lib/tap-bullmq");Object.defineProperty(exports,"bullmqTap",{enumerable:!0,get:e(function(){return tap_bullmq_1.bullmqTap},"get")});var tap_nest_1=require("./lib/tap-nest");Object.defineProperty(exports,"nestTap",{enumerable:!0,get:e(function(){return tap_nest_1.nestTap},"get")}),Object.defineProperty(exports,"installChildAppBridge",{enumerable:!0,get:e(function(){return tap_nest_1.installChildAppBridge},"get")});var install_1=require("./lib/install");Object.defineProperty(exports,"installLensmcpNodeInstrumentation",{enumerable:!0,get:e(function(){return install_1.installLensmcpNodeInstrumentation},"get")});var active_work_1=require("./lib/active-work");Object.defineProperty(exports,"activeWorkSnapshot",{enumerable:!0,get:e(function(){return active_work_1.activeWorkSnapshot},"get")}),Object.defineProperty(exports,"beginActiveWork",{enumerable:!0,get:e(function(){return active_work_1.beginActiveWork},"get")}),Object.defineProperty(exports,"installActiveWorkProbe",{enumerable:!0,get:e(function(){return active_work_1.installActiveWorkProbe},"get")}),Object.defineProperty(exports,"resetActiveWorkForTests",{enumerable:!0,get:e(function(){return active_work_1.resetActiveWorkForTests},"get")});
|
package/lib/active-work.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var a=Object.defineProperty;var o=(t,e)=>a(t,"name",{value:e,configurable:!0});var i=Object.defineProperty,n=o((t,e)=>i(t,"name",{value:e,configurable:!0}),"n");Object.defineProperty(exports,"__esModule",{value:!0}),exports.beginActiveWorkGeneration=beginActiveWorkGeneration,exports.activeWorkGeneration=activeWorkGeneration,exports.beginActiveWork=beginActiveWork,exports.activeWorkSnapshot=activeWorkSnapshot,exports.installActiveWorkProbe=installActiveWorkProbe,exports.resetActiveWorkForTests=resetActiveWorkForTests;const GLOBAL_KEY="__lensmcpActiveWork",running=new Set;let currentGeneration=0;function beginActiveWorkGeneration(){return++currentGeneration}o(beginActiveWorkGeneration,"beginActiveWorkGeneration"),n(beginActiveWorkGeneration,"beginActiveWorkGeneration");function activeWorkGeneration(){return currentGeneration}o(activeWorkGeneration,"activeWorkGeneration"),n(activeWorkGeneration,"activeWorkGeneration");function beginActiveWork(t){const e={at:Date.now(),...t===void 0?{}:{gen:t}};running.add(e);let r=!1;return()=>{r||(r=!0,running.delete(e))}}o(beginActiveWork,"beginActiveWork"),n(beginActiveWork,"beginActiveWork");function activeWorkSnapshot(t){let e,r=0;for(const c of running)t!==void 0&&c.gen!==void 0&&c.gen!==t||(r+=1,(e===void 0||c.at<e)&&(e=c.at));return{count:r,...e===void 0?{}:{oldestStartedAt:e}}}o(activeWorkSnapshot,"activeWorkSnapshot"),n(activeWorkSnapshot,"activeWorkSnapshot");function installActiveWorkProbe(){globalThis[GLOBAL_KEY]=activeWorkSnapshot,globalThis.__lensmcpBeginWorkGeneration=beginActiveWorkGeneration}o(installActiveWorkProbe,"installActiveWorkProbe"),n(installActiveWorkProbe,"installActiveWorkProbe");function resetActiveWorkForTests(){running.clear(),currentGeneration=0}o(resetActiveWorkForTests,"resetActiveWorkForTests"),n(resetActiveWorkForTests,"resetActiveWorkForTests");
|
package/lib/ai-providers.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`)}
|
|
3
|
-
`:""}[tool_call ${asStr(a.name)??""} ${asStr(a.arguments)??""}]`}return{role:asStr(t.role)??"unknown",content:e}}
|
|
4
|
-
`:""}[refusal] ${
|
|
1
|
+
"use strict";var j=Object.defineProperty;var d=(t,e)=>j(t,"name",{value:e,configurable:!0});var M=Object.defineProperty,u=d((t,e)=>M(t,"name",{value:e,configurable:!0}),"u");Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseExtraHosts=parseExtraHosts,exports.matchTarget=matchTarget,exports.flattenContent=flattenContent,exports.normalizeRequest=normalizeRequest,exports.mapUsage=mapUsage,exports.normalizeResponse=normalizeResponse,exports.createStreamAccumulator=createStreamAccumulator;const isObj=u(t=>typeof t=="object"&&t!==null&&!Array.isArray(t),"isObj"),asArr=u(t=>Array.isArray(t)?t:[],"asArr"),asStr=u(t=>typeof t=="string"?t:void 0,"asStr"),asNum=u(t=>typeof t=="number"&&Number.isFinite(t)?t:void 0,"asNum"),MAX_ACCUMULATED_CHARS=512*1024,MAX_EVENT_BUFFER_CHARS=1024*1024,MAX_BLOCK_JSON_CHARS=2e3,KNOWN_HOSTS=[{test:/^api\.openai\.com$/i,provider:"openai"},{test:/\.openai\.azure\.com$/i,provider:"openai"},{test:/^api\.anthropic\.com$/i,provider:"anthropic"}],authorityOf=u(t=>t.trim().toLowerCase().replace(/^[a-z][a-z0-9+.-]*:\/\//,"").replace(/[/?#].*$/,""),"authorityOf");function parseExtraHosts(t){const e=new Map;for(const o of(t??"").split(",")){const a=o.lastIndexOf("=");if(a===-1)continue;const n=authorityOf(o.slice(0,a)),r=o.slice(a+1).trim().toLowerCase();n&&(r==="openai"||r==="anthropic")&&e.set(n,r)}return e}d(parseExtraHosts,"parseExtraHosts"),u(parseExtraHosts,"parseExtraHosts");function apiFor(t,e){const o=e.replace(/\/+$/,"").toLowerCase();if(t==="anthropic")return o.endsWith("/messages")?"messages":void 0;if(o.endsWith("/chat/completions"))return"chat";if(o.endsWith("/responses"))return"responses";if(o.endsWith("/embeddings"))return"embeddings"}d(apiFor,"apiFor"),u(apiFor,"apiFor");function matchTarget(t,e,o,a){const n=t.toLowerCase(),r=a.get(e?`${n}:${e}`:n)??a.get(n)??KNOWN_HOSTS.find(p=>p.test.test(n))?.provider;if(!r)return;const c=apiFor(r,o);return c?{provider:r,api:c}:void 0}d(matchTarget,"matchTarget"),u(matchTarget,"matchTarget");function jsonText(t,e=MAX_BLOCK_JSON_CHARS){try{const o=JSON.stringify(t);return o===void 0?"":o.length>e?`${o.slice(0,e)}\u2026`:o}catch{return""}}d(jsonText,"jsonText"),u(jsonText,"jsonText");const argsText=u(t=>typeof t=="string"?t:t==null?void 0:jsonText(t,8192),"argsText");function flattenContent(t){if(t==null)return"";if(typeof t=="string")return t;if(!Array.isArray(t))return jsonText(t);const e=[];for(const o of t){if(typeof o=="string"){e.push(o);continue}if(!isObj(o))continue;const a=asStr(o.type)??"";switch(a){case"text":case"input_text":case"output_text":e.push(asStr(o.text)??"");break;case"refusal":e.push(`[refusal] ${asStr(o.refusal)??""}`);break;case"image_url":case"image":case"input_image":e.push("[image]");break;case"input_audio":case"audio":e.push("[audio]");break;case"file":case"input_file":case"document":e.push("[file]");break;case"tool_use":e.push(`[tool_use ${asStr(o.name)??""} ${jsonText(o.input)}]`);break;case"tool_result":e.push(`[tool_result ${flattenContent(o.content)}]`);break;case"thinking":e.push(`[thinking] ${asStr(o.thinking)??""}`);break;case"redacted_thinking":e.push("[redacted_thinking]");break;default:e.push(asStr(o.text)??`[${a||"part"}]`)}}return e.filter(o=>o!=="").join(`
|
|
2
|
+
`)}d(flattenContent,"flattenContent"),u(flattenContent,"flattenContent");const SCALAR_PARAMS={chat:["temperature","top_p","max_tokens","max_completion_tokens","n","seed","presence_penalty","frequency_penalty","tool_choice","reasoning_effort","service_tier"],responses:["temperature","top_p","max_output_tokens","tool_choice","parallel_tool_calls","service_tier"],messages:["max_tokens","temperature","top_p","top_k"],embeddings:["dimensions","encoding_format"]};function scalarParams(t,e){const o={};for(const p of SCALAR_PARAMS[e]){const _=t[p];(typeof _=="string"||typeof _=="number"||typeof _=="boolean")&&(o[p]=_)}const a=t.reasoning;isObj(a)&&typeof a.effort=="string"&&(o.reasoning_effort=a.effort);const n=t.thinking;isObj(n)&&(typeof n.type=="string"&&(o.thinking=n.type),typeof n.budget_tokens=="number"&&(o.thinking_budget_tokens=n.budget_tokens));const r=t.response_format;isObj(r)&&typeof r.type=="string"&&(o.response_format=r.type);const c=t.tool_choice;return isObj(c)&&typeof c.type=="string"&&(o.tool_choice=c.type),o}d(scalarParams,"scalarParams"),u(scalarParams,"scalarParams");function toolsOf(t){const e=[];for(const o of asArr(t.tools)){if(!isObj(o))continue;const a=isObj(o.function)?o.function:void 0,n=asStr(a?.name)??asStr(o.name)??asStr(o.type);if(!n)continue;const r=asStr(a?.description)??asStr(o.description);e.push(r?{name:n,description:r}:{name:n})}return e}d(toolsOf,"toolsOf"),u(toolsOf,"toolsOf");function chatMessage(t){let e=flattenContent(t.content);for(const o of asArr(t.tool_calls)){if(!isObj(o))continue;const a=isObj(o.function)?o.function:{};e+=`${e?`
|
|
3
|
+
`:""}[tool_call ${asStr(a.name)??""} ${asStr(a.arguments)??""}]`}return{role:asStr(t.role)??"unknown",content:e}}d(chatMessage,"chatMessage"),u(chatMessage,"chatMessage");function responsesInput(t){if(typeof t=="string")return[{role:"user",content:t}];const e=[];for(const o of asArr(t)){if(!isObj(o))continue;const a=asStr(o.type);a==="function_call_output"?e.push({role:"tool",content:flattenContent(o.output)}):a==="function_call"?e.push({role:"assistant",content:`[tool_call ${asStr(o.name)??""} ${asStr(o.arguments)??""}]`}):e.push({role:asStr(o.role)??a??"user",content:flattenContent(o.content)})}return e}d(responsesInput,"responsesInput"),u(responsesInput,"responsesInput");function normalizeRequest(t,e){const o={messages:[],tools:[],params:{},stream:!1};if(!isObj(e))return o;const a={...o,...asStr(e.model)?{model:asStr(e.model)}:{},stream:e.stream===!0,params:scalarParams(e,t.api),tools:toolsOf(e)};switch(t.api){case"chat":a.messages=asArr(e.messages).filter(isObj).map(chatMessage);break;case"responses":{const n=asStr(e.instructions);n&&(a.system=n),a.messages=responsesInput(e.input);break}case"messages":{const n=e.system,r=typeof n=="string"?n:flattenContent(n);r&&(a.system=r),a.messages=asArr(e.messages).filter(isObj).map(c=>({role:asStr(c.role)??"unknown",content:flattenContent(c.content)}));break}case"embeddings":{const n=e.input;a.inputCount=Array.isArray(n)?n.length:n===void 0?0:1;break}}return a}d(normalizeRequest,"normalizeRequest"),u(normalizeRequest,"normalizeRequest");function mapUsage(t,e=!0){if(!isObj(t))return{};const o=isObj(t.prompt_tokens_details)?t.prompt_tokens_details:isObj(t.input_tokens_details)?t.input_tokens_details:{},a=isObj(t.completion_tokens_details)?t.completion_tokens_details:isObj(t.output_tokens_details)?t.output_tokens_details:{},n={},r=asNum(t.prompt_tokens)??asNum(t.input_tokens),c=asNum(t.completion_tokens)??asNum(t.output_tokens),p=asNum(o.cached_tokens)??asNum(t.cache_read_input_tokens),_=asNum(a.reasoning_tokens);r!==void 0&&(n.promptTokens=r),c!==void 0&&(n.completionTokens=c),p!==void 0&&(n.cachedTokens=p),_!==void 0&&(n.reasoningTokens=_);const f=asNum(t.total_tokens);return f!==void 0?n.totalTokens=f:e&&r!==void 0&&c!==void 0&&(n.totalTokens=r+c),n}d(mapUsage,"mapUsage"),u(mapUsage,"mapUsage");const withTotal=u(t=>t.totalTokens===void 0&&t.promptTokens!==void 0&&t.completionTokens!==void 0?{...t,totalTokens:t.promptTokens+t.completionTokens}:t,"withTotal");function errorMessage(t){const e=t.error;if(typeof e=="string")return e;if(isObj(e))return asStr(e.message)??asStr(e.type)??asStr(e.code)}d(errorMessage,"errorMessage"),u(errorMessage,"errorMessage");function normalizeResponse(t,e){const o={completion:"",toolCalls:[],usage:{}};if(!isObj(e))return o;const a=asStr(e.id),n=asStr(e.model);a&&(o.id=a),n&&(o.model=n);const r=errorMessage(e);switch(r&&(o.error=r),o.usage=mapUsage(e.usage),t.api){case"chat":{const c=asArr(e.choices).find(isObj),p=c&&isObj(c.message)?c.message:void 0;if(p){o.completion=flattenContent(p.content);const f=asStr(p.refusal);f&&(o.completion+=`${o.completion?`
|
|
4
|
+
`:""}[refusal] ${f}`);const h=asStr(p.reasoning_content)??asStr(p.reasoning);h&&(o.reasoning=h);for(const k of asArr(p.tool_calls)){if(!isObj(k))continue;const y=isObj(k.function)?k.function:{},b=argsText(y.arguments);o.toolCalls.push({...asStr(k.id)?{id:asStr(k.id)}:{},name:asStr(y.name)??"tool",...b!==void 0?{arguments:b}:{}})}const m=isObj(p.function_call)?p.function_call:void 0;if(m){const k=argsText(m.arguments);o.toolCalls.push({name:asStr(m.name)??"tool",...k!==void 0?{arguments:k}:{}})}}const _=asStr(c?.finish_reason);_&&(o.finishReason=_);break}case"responses":{const c=[],p=[];for(const m of asArr(e.output)){if(!isObj(m))continue;const k=asStr(m.type);if(k==="message")c.push(flattenContent(m.content));else if(k==="function_call")o.toolCalls.push({...asStr(m.call_id)??asStr(m.id)?{id:asStr(m.call_id)??asStr(m.id)}:{},name:asStr(m.name)??"tool",...asStr(m.arguments)!==void 0?{arguments:asStr(m.arguments)}:{}});else if(k==="reasoning")for(const y of asArr(m.summary))isObj(y)&&asStr(y.text)&&p.push(asStr(y.text))}o.completion=c.filter(Boolean).join(`
|
|
5
5
|
`),p.length&&(o.reasoning=p.join(`
|
|
6
|
-
`));const
|
|
6
|
+
`));const _=isObj(e.incomplete_details)?asStr(e.incomplete_details.reason):void 0,f=asStr(e.status),h=_??f;h&&(o.finishReason=h),!o.error&&isObj(e.error)&&(o.error=errorMessage(e));break}case"messages":{const c=[],p=[];for(const f of asArr(e.content)){if(!isObj(f))continue;const h=asStr(f.type);h==="text"?c.push(asStr(f.text)??""):h==="thinking"?p.push(asStr(f.thinking)??""):(h==="tool_use"||h==="server_tool_use"||h==="mcp_tool_use")&&o.toolCalls.push({...asStr(f.id)?{id:asStr(f.id)}:{},name:asStr(f.name)??"tool",arguments:jsonText(f.input)})}o.completion=c.filter(Boolean).join(`
|
|
7
7
|
`),p.length&&(o.reasoning=p.filter(Boolean).join(`
|
|
8
|
-
`));const
|
|
8
|
+
`));const _=asStr(e.stop_reason);_&&(o.finishReason=_);break}case"embeddings":o.vectorCount=asArr(e.data).length;break}return o}d(normalizeResponse,"normalizeResponse"),u(normalizeResponse,"normalizeResponse");function createStreamAccumulator(t){let e="",o=0,a,n,r="",c="",p="",_,f={},h,m;const k=new Map,y=u((i,s)=>{s&&(i==="text"?r.length<MAX_ACCUMULATED_CHARS&&(r+=s):i==="reasoning"?c.length<MAX_ACCUMULATED_CHARS&&(c+=s):p.length<MAX_ACCUMULATED_CHARS&&(p+=s))},"append"),b=u(i=>{let s=k.get(i);return s||(s={name:"",args:""},k.set(i,s)),s},"tool");function $(i){const s=asArr(i.choices).find(isObj),g=s&&isObj(s.delta)?s.delta:void 0;if(g){y("text",asStr(g.content)??""),y("refusal",asStr(g.refusal)??""),y("reasoning",asStr(g.reasoning_content)??asStr(g.reasoning)??"");const x=isObj(g.function_call)?g.function_call:void 0;if(x){const v=b(-1);asStr(x.name)&&(v.name+=asStr(x.name)),asStr(x.arguments)&&(v.args+=asStr(x.arguments))}for(const v of asArr(g.tool_calls)){if(!isObj(v))continue;const T=b(asNum(v.index)??0);asStr(v.id)&&(T.id=asStr(v.id));const C=isObj(v.function)?v.function:{};asStr(C.name)&&(T.name+=asStr(C.name)),asStr(C.arguments)&&(T.args+=asStr(C.arguments))}}const l=asStr(s?.finish_reason);l&&(_=l),isObj(i.usage)&&(f={...f,...mapUsage(i.usage,!1)})}d($,"R"),u($,"onChat");function O(i){const s=asStr(i.type)??"";s==="response.output_text.delta"?y("text",asStr(i.delta)??""):s==="response.completed"||s==="response.incomplete"||s==="response.failed"?m=normalizeResponse(t,i.response):s==="error"&&(h=asStr(i.message)??h)}d(O,"O"),u(O,"onResponses");function R(i){const s=asStr(i.type)??"",g=asNum(i.index)??0;if(s==="message_start"){const l=isObj(i.message)?i.message:{};a=asStr(l.id)??a,n=asStr(l.model)??n,f={...f,...mapUsage(l.usage,!1)}}else if(s==="content_block_start"){const l=isObj(i.content_block)?i.content_block:{};if(asStr(l.type)==="tool_use"||asStr(l.type)==="server_tool_use"||asStr(l.type)==="mcp_tool_use"){const x=b(g);x.id=asStr(l.id),x.name=asStr(l.name)??"tool"}else asStr(l.type)==="text"&&y("text",asStr(l.text)??"")}else if(s==="content_block_delta"){const l=isObj(i.delta)?i.delta:{},x=asStr(l.type);x==="text_delta"?y("text",asStr(l.text)??""):x==="thinking_delta"?y("reasoning",asStr(l.thinking)??""):x==="input_json_delta"&&(b(g).args+=asStr(l.partial_json)??"")}else if(s==="message_delta"){const l=isObj(i.delta)?i.delta:{};asStr(l.stop_reason)&&(_=asStr(l.stop_reason)),f={...f,...mapUsage(i.usage,!1)}}else s==="error"&&(h=errorMessage(i)??h)}d(R,"S"),u(R,"onAnthropic");function S(i){o+=1,a=asStr(i.id)??a,n=asStr(i.model)??n,t.api==="messages"?R(i):t.api==="responses"?O(i):$(i);const s=t.api==="messages"?void 0:errorMessage(i);s&&(h=s)}d(S,"b"),u(S,"onEvent");function A(i){const s=[];for(const l of i.split(`
|
|
9
9
|
`))l.startsWith("data:")&&s.push(l.slice(5).replace(/^ /,""));if(!s.length)return;const g=s.join(`
|
|
10
|
-
`);if(g!=="[DONE]")try{const l=JSON.parse(g);isObj(l)&&S(l)}catch{}}return
|
|
10
|
+
`);if(g!=="[DONE]")try{const l=JSON.parse(g);isObj(l)&&S(l)}catch{}}return d(A,"$"),u(A,"parseEvent"),{push(i){e=(e+i).replace(/\r\n/g,`
|
|
11
11
|
`);let s=e.indexOf(`
|
|
12
12
|
|
|
13
13
|
`);for(;s!==-1;)A(e.slice(0,s)),e=e.slice(s+2),s=e.indexOf(`
|
|
14
14
|
|
|
15
|
-
`);e.length>MAX_EVENT_BUFFER_CHARS&&(e="")},end(){e.trim()&&A(e),e="";const
|
|
16
|
-
`:""}[refusal] ${p}`:
|
|
15
|
+
`);e.length>MAX_EVENT_BUFFER_CHARS&&(e="")},end(){e.trim()&&A(e),e="";const i=[...k.entries()].sort((g,l)=>g[0]-l[0]).map(([,g])=>({...g.id?{id:g.id}:{},name:g.name||"tool",...g.args?{arguments:g.args}:{}})),s={...a?{id:a}:{},...n?{model:n}:{},completion:p?`${r}${r?`
|
|
16
|
+
`:""}[refusal] ${p}`:r,...c?{reasoning:c}:{},toolCalls:i,..._?{finishReason:_}:{},usage:withTotal(f),...h?{error:h}:{}};return m?{...s,...m,completion:m.completion||s.completion,toolCalls:m.toolCalls.length?m.toolCalls:s.toolCalls,usage:{...s.usage,...m.usage}}:s},get eventCount(){return o}}}d(createStreamAccumulator,"createStreamAccumulator"),u(createStreamAccumulator,"createStreamAccumulator");
|
package/lib/ai-store.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var g=Object.defineProperty;var l=(e,r)=>g(e,"name",{value:r,configurable:!0});var m=Object.defineProperty,i=l((e,r)=>m(e,"name",{value:r,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.redactAiText=void 0,exports.newAiCallId=newAiCallId,exports.fitAiContent=fitAiContent,exports.removeAiContent=removeAiContent,exports.writeAiContent=writeAiContent;const tslib_1=require("tslib"),nodeFs=tslib_1.__importStar(require("node:fs")),ai_content_1=require("@lensmcp/core/ai-content"),redact_1=require("@lensmcp/core/redact"),emit_1=require("./emit"),mkdirSync=nodeFs.mkdirSync,writeFileSync=nodeFs.writeFileSync,renameSync=nodeFs.renameSync,readdirSync=nodeFs.readdirSync,unlinkSync=nodeFs.unlinkSync;exports.redactAiText=redact_1.redactSecretText;const intEnv=i((e,r,o,t)=>{const s=Number(process.env[e]);return Number.isFinite(s)&&s>=o&&s<=t?Math.floor(s):r},"intEnv"),maxFieldChars=i(()=>intEnv("LENSMCP_AI_MAX_CHARS",32*1024,256,4*1024*1024),"maxFieldChars"),maxFileBytes=i(()=>intEnv("LENSMCP_AI_MAX_BYTES",256*1024,4*1024,16*1024*1024),"maxFileBytes"),maxFiles=i(()=>intEnv("LENSMCP_AI_MAX_FILES",200,1,1e4),"maxFiles");function newAiCallId(){const e=Date.now().toString(36).padStart(9,"0"),r=Math.random().toString(36).slice(2,8).padEnd(6,"0");return`ai_${e}${r}`}l(newAiCallId,"newAiCallId"),i(newAiCallId,"newAiCallId");const PRE_CLIP_FACTOR=4,MAX_MESSAGES=400;function sanitize(e,r){const o={cut:e.truncated===!0},t=i((n,u=r)=>{if(n===void 0)return;const a=u*PRE_CLIP_FACTOR;let d=n;return d.length>a&&(o.cut=!0,d=d.slice(0,a)),(0,exports.redactAiText)(d)},"clean"),s={...e,request:{...e.request,...e.request.system!==void 0?{system:t(e.request.system)}:{},messages:e.request.messages.slice(0,MAX_MESSAGES*4).map(n=>({role:n.role,content:t(n.content)})),...e.request.tools?{tools:e.request.tools.map(n=>({name:t(n.name,200),...n.description?{description:t(n.description,512)}:{}}))}:{}},...e.response?{response:{...e.response,...e.response.completion!==void 0?{completion:t(e.response.completion)}:{},...e.response.reasoning!==void 0?{reasoning:t(e.response.reasoning)}:{},...e.response.error!==void 0?{error:t(e.response.error,2048)}:{},...e.response.toolCalls?{toolCalls:e.response.toolCalls.map(n=>({...n.id?{id:n.id}:{},name:t(n.name,200),...n.arguments!==void 0?{arguments:t(n.arguments,8192)}:{}}))}:{}}}:{}};return e.request.messages.length>MAX_MESSAGES*4&&(o.cut=!0),o.cut&&(s.truncated=!0),s}l(sanitize,"sanitize"),i(sanitize,"sanitize");function clipTo(e,r,o){const t={cut:e.truncated===!0},s=i((c,p=r)=>{if(c!==void 0)return c.length>p&&(t.cut=!0),(0,redact_1.clip)(c,p)},"c"),n=e.request.messages;let u=n;if(n.length>o){const c=Math.min(2,o);u=[...n.slice(0,c),...n.slice(n.length-(o-c))],t.cut=!0}const a=e.response,d={...e,request:{...e.request,...e.request.system!==void 0?{system:s(e.request.system)}:{},messages:u.map(c=>({role:c.role,content:s(c.content)}))},...a?{response:{...a,...a.completion!==void 0?{completion:s(a.completion)}:{},...a.reasoning!==void 0?{reasoning:s(a.reasoning)}:{},...a.toolCalls?{toolCalls:a.toolCalls.map(c=>({...c,...c.arguments!==void 0?{arguments:s(c.arguments,Math.min(r,8192))}:{}}))}:{}}}:{}};return t.cut?d.truncated=!0:delete d.truncated,d}l(clipTo,"clipTo"),i(clipTo,"clipTo");function fitAiContent(e){const r=maxFileBytes();let o=maxFieldChars(),t=MAX_MESSAGES;const s=sanitize(e,o);let n=clipTo(s,o,t),u=JSON.stringify(n);for(;u.length>r&&(o>256||t>2);)o>256?o=Math.max(256,Math.floor(o/2)):t=Math.max(2,Math.floor(t/2)),n=clipTo(s,o,t),u=JSON.stringify(n);return{json:u,content:n}}l(fitAiContent,"fitAiContent"),i(fitAiContent,"fitAiContent");let writes=0;function prune(e){try{const r=readdirSync(e).filter(t=>/^ai_[0-9a-z]+\.json$/.test(t)).sort(),o=r.length-maxFiles();for(let t=0;t<o;t+=1)try{unlinkSync(`${e}/${r[t]}`)}catch{}}catch{}}l(prune,"prune"),i(prune,"prune");function removeAiContent(e){try{unlinkSync((0,ai_content_1.aiContentFile)(emit_1.EVENT_FILE,e))}catch{}}l(removeAiContent,"removeAiContent"),i(removeAiContent,"removeAiContent");function writeAiContent(e){try{const r=(0,ai_content_1.aiContentDir)(emit_1.EVENT_FILE);mkdirSync(r,{recursive:!0,mode:448});const{json:o,content:t}=fitAiContent(e),s=`${r}/${e.id}.json`;return writeFileSync(`${s}.tmp`,o,{mode:384}),renameSync(`${s}.tmp`,s),writes+=1,(writes===1||writes%20===0)&&prune(r),{id:e.id,truncated:t.truncated===!0}}catch{return}}l(writeAiContent,"writeAiContent"),i(writeAiContent,"writeAiContent");
|
package/lib/callsite.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`).slice(1)){const r=parseFrame(o,e,n);if(r&&(t.push(r),t.length>=exports.FRAMES_KEPT))break}if(t.length)return{frames:t,mapped:process.sourceMapsEnabled===!0}}
|
|
1
|
+
"use strict";var l=Object.defineProperty;var a=(s,e)=>l(s,"name",{value:e,configurable:!0});var f=Object.defineProperty,c=a((s,e)=>f(s,"name",{value:e,configurable:!0}),"c");Object.defineProperty(exports,"__esModule",{value:!0}),exports.SiteSampler=exports.siteKey=exports.FRAMES_KEPT=void 0,exports.captureSite=captureSite,exports.parseFrame=parseFrame,exports.appSite=appSite;const node_path_1=require("node:path"),node_url_1=require("node:url"),CAPTURE_LIMIT=40;exports.FRAMES_KEPT=3;const OFF=process.env.LENSMCP_CALLSITES==="0",OWN=__dirname,CWD=process.cwd();function captureSite(){if(OFF)return;const s={},e=Error.stackTraceLimit;try{Error.stackTraceLimit=CAPTURE_LIMIT,Error.captureStackTrace(s,captureSite)}catch{return}finally{try{Error.stackTraceLimit=e}catch{}}return s}a(captureSite,"captureSite"),c(captureSite,"captureSite");const FRAME=/^\s*at (?:async )?(?:(.+?) \((.+)\)|(.+))$/,LOCATION=/^(.*):(\d+):(\d+)$/;function parseFrame(s,e=CWD,n=OWN){const i=FRAME.exec(s);if(!i)return;const t=i[2]??i[3]??"";if(t.startsWith("eval at ")||t.includes("<anonymous>"))return;const o=LOCATION.exec(t);if(!o)return;let r=o[1];if(r.startsWith("file://"))try{r=(0,node_url_1.fileURLToPath)(r)}catch{return}if(!(0,node_path_1.isAbsolute)(r)||r.includes(`${node_path_1.sep}node_modules${node_path_1.sep}`)||r===n||r.startsWith(n+node_path_1.sep))return;const u=functionName(i[1]);return{file:r.startsWith(e+node_path_1.sep)?(0,node_path_1.relative)(e,r):r,line:Number(o[2]),column:Number(o[3]),...u?{fn:u}:{}}}a(parseFrame,"parseFrame"),c(parseFrame,"parseFrame");function functionName(s){if(!s)return;let e=s.replace(/^new /,"");const n=/ \[as ([^\]]+)\]$/.exec(e);if(n&&(e=/(?:^|\.)(?:eval|<anonymous>)$/.test(e.slice(0,n.index))?n[1]:e.slice(0,n.index)),!(e==="eval"||e.includes("<anonymous>")||e==="Object.eval"))return e}a(functionName,"functionName"),c(functionName,"functionName");function appSite(s,e=CWD,n=OWN){const i=s?.stack;if(!i)return;const t=[];for(const o of i.split(`
|
|
2
|
+
`).slice(1)){const r=parseFrame(o,e,n);if(r&&(t.push(r),t.length>=exports.FRAMES_KEPT))break}if(t.length)return{frames:t,mapped:process.sourceMapsEnabled===!0}}a(appSite,"appSite"),c(appSite,"appSite");const siteKey=c(s=>`${s.frames[0].file}:${s.frames[0].line}`,"siteKey");exports.siteKey=siteKey;const FIRST_RUNS=5,EVERY=20,RESEND_MS=10*6e4,MAX_KEYS=2e3,MAX_SITES_PER_KEY=20;class SiteSampler{static{a(this,"SiteSampler")}static{c(this,"SiteSampler")}constructor(e={}){this.opts=e,this.keys=new Map}site(e,n,i={}){if(!n&&!i.fallback)return;let t=this.keys.get(e);if(t||(t={runs:0,sent:new Map},this.keys.set(e,t),this.keys.size>MAX_KEYS&&this.keys.delete(this.keys.keys().next().value)),t.runs+=1,!i.force&&t.runs>FIRST_RUNS&&t.runs%EVERY!==0)return;const o=appSite(n,this.opts.cwd,this.opts.own)??appSite(i.fallback,this.opts.cwd,this.opts.own);if(!o)return;const r=(this.opts.now??Date.now)(),u=(0,exports.siteKey)(o),p=t.sent.get(u);if(!(!i.force&&p!==void 0&&r-p<RESEND_MS))return t.sent.delete(u),t.sent.set(u,r),t.sent.size>MAX_SITES_PER_KEY&&t.sent.delete(t.sent.keys().next().value),o}}exports.SiteSampler=SiteSampler;
|
package/lib/capture-file.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var u=Object.defineProperty;var i=(e,t)=>u(e,"name",{value:t,configurable:!0});var n=Object.defineProperty,r=i((e,t)=>n(e,"name",{value:t,configurable:!0}),"r");Object.defineProperty(exports,"__esModule",{value:!0}),exports.captureFile=void 0,exports.aiBodiesAsked=aiBodiesAsked,exports.sqlValuesAsked=sqlValuesAsked,exports.resetCaptureFileForTests=resetCaptureFileForTests;const tslib_1=require("tslib"),nodeFs=tslib_1.__importStar(require("node:fs")),node_path_1=require("node:path"),emit_1=require("./emit"),statSync=nodeFs.statSync,readFileSync=nodeFs.readFileSync,EVERY_MS=5e3;let last;const captureFile=r(()=>(0,node_path_1.join)((0,node_path_1.dirname)(emit_1.EVENT_FILE),"capture.json"),"captureFile");exports.captureFile=captureFile;function asked(e){if(last&&e-last.at<EVERY_MS)return last;let t;try{t=statSync((0,exports.captureFile)()).mtimeMs}catch{return last={at:e,mtimeMs:-1,ai:!1,sql:!0},last}if(last&&last.mtimeMs===t)return last={...last,at:e},last;let s=!1,a=!0;try{const o=JSON.parse(readFileSync((0,exports.captureFile)(),"utf8"));s=o.ai==="content",a=o.sql!=="off"}catch{}return last={at:e,mtimeMs:t,ai:s,sql:a},last}i(asked,"asked"),r(asked,"asked");function aiBodiesAsked(e=Date.now()){return asked(e).ai}i(aiBodiesAsked,"aiBodiesAsked"),r(aiBodiesAsked,"aiBodiesAsked");function sqlValuesAsked(e=Date.now(),t=process.env){const s=t.LENSMCP_SQL_VALUES?.trim().toLowerCase();return s==="0"||s==="off"||s==="false"?!1:asked(e).sql}i(sqlValuesAsked,"sqlValuesAsked"),r(sqlValuesAsked,"sqlValuesAsked");function resetCaptureFileForTests(){last=void 0}i(resetCaptureFileForTests,"resetCaptureFileForTests"),r(resetCaptureFileForTests,"resetCaptureFileForTests");
|
package/lib/emit-custom.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var O=Object.defineProperty;var d=(t,e)=>O(t,"name",{value:e,configurable:!0});var C=Object.defineProperty,c=d((t,e)=>C(t,"name",{value:e,configurable:!0}),"c");Object.defineProperty(exports,"__esModule",{value:!0}),exports.EMIT_CUSTOM=void 0,exports.emitCustomHere=emitCustomHere,exports.installCustomEmit=installCustomEmit,exports.lensEmitCustom=lensEmitCustom;const protocol_types_1=require("@lensmcp/protocol-types"),emit_1=require("./emit"),flood_guard_1=require("./flood-guard"),flow_context_1=require("./flow-context");exports.EMIT_CUSTOM=Symbol.for("lensmcp.emitCustom");const ITEM_MAX=200,ERROR_MAX=500,NAME_RE=/^[^\u0000-\u001f\u007f]{1,100}$/,customGuard=(0,flood_guard_1.createEventFloodGuard)({burst:30,perSec:5}),CHANNEL_BUCKETS_PER_SOURCE=protocol_types_1.TRAFFIC_PUSH_CHANNELS,CHANNEL_BUCKETS_MAX=1e3,channelBuckets=new Map;let channelBucketCount=0;function trafficBucket(t,e,o,f){const s=`custom:${emit_1.PROJECT}:traffic:${t}:${e}`,r=channelBuckets.get(t);return r?.has(o)?`${s}:${o}`:(r?.size??0)<CHANNEL_BUCKETS_PER_SOURCE&&channelBucketCount<CHANNEL_BUCKETS_MAX?(r?r.add(o):channelBuckets.set(t,new Set([o])),channelBucketCount++,`${s}:${o}`):(say(channelBucketCount>=CHANNEL_BUCKETS_MAX?`${f}: ${CHANNEL_BUCKETS_MAX} channels already have a flood bucket in this process \u2014 this source's further channels share one`:`${f}: more than ${CHANNEL_BUCKETS_PER_SOURCE} channels \u2014 its further channels share one flood bucket (is a channel minted per message?)`),s)}d(trafficBucket,"trafficBucket"),c(trafficBucket,"trafficBucket");const SAID_MAX=50,said=new Set;function refuse(t){return say(`${t} \u2014 not written`),!1}d(refuse,"refuse"),c(refuse,"refuse");function say(t){try{if(said.has(t)||said.size>=SAID_MAX)return;said.add(t);const e=said.size===SAID_MAX?" (further problems with lensEmitCustom are not said)":"";console.warn(`[lensmcp] lensEmitCustom: ${t}${e}`)}catch{}}d(say,"say"),c(say,"say");function shown(t){return typeof t=="string"?JSON.stringify(t.length>40?`${t.slice(0,39)}\u2026`:t):t===null?"null":typeof t}d(shown,"shown"),c(shown,"shown");const isObj=c(t=>typeof t=="object"&&t!==null&&!Array.isArray(t),"isObj"),cut=c((t,e)=>t.length>e?`${t.slice(0,e-1)}\u2026`:t,"cut");function idText(t,e){const o=typeof t=="string"?t:typeof t=="number"&&Number.isFinite(t)||typeof t=="bigint"?String(t):void 0;return o?cut(o,e):void 0}d(idText,"idText"),c(idText,"idText");function errorText(t){const e=typeof t=="string"?t:t instanceof Error?t.message:void 0;return e?cut(e,ERROR_MAX):void 0}d(errorText,"errorText"),c(errorText,"errorText");const oneLine=c((t,e)=>cut(t.replace(/\s+/g," ").trim(),e),"oneLine"),text=c((t,e)=>typeof t=="string"&&t?cut(t,e):void 0,"text");function summary(t,e,o){return`${[t,...e.filter(f=>f!==!1)].join(", ")}${o?` \u2014 ${oneLine(o,120)}`:""}`}d(summary,"summary"),c(summary,"summary");const sized=c(t=>`${String(t).replace(/\B(?=(\d{3})+(?!\d))/g,",")} byte${t===1?"":"s"}`,"sized");function emitCustomHere(t){try{if(!isObj(t))return refuse(`the event is ${shown(t)}, not { kind, name, event }`);const e=t.kind;if(!protocol_types_1.SOURCE_KINDS_READ.includes(e))return refuse(`kind ${shown(e)} is not a source kind (${protocol_types_1.SOURCE_KINDS_READ.join(", ")})`);const o=e,f=t.name;if(typeof f!="string"||!f.trim()||!NAME_RE.test(f))return refuse(`${o} name ${shown(f)} is not 1\u2013100 characters without control characters (the declared source's name)`);const s=`${o} ${JSON.stringify(f)}`,r=t.event,S=protocol_types_1.SOURCE_PUSH_EVENTS[o];if(typeof r!="string"||!S.includes(r))return refuse(`${s}: event ${shown(r)} is not a ${o} event (${S.join(", ")})`);const u={kind:"source-event",provenance:protocol_types_1.SOURCE_PROVENANCE,sourceKind:o,name:f,event:r};let $="info",p=r,_=`custom:${emit_1.PROJECT}:${o}:${f}:${r}`;if(o==="queue"){const i=idText(t.item,ITEM_MAX),n=idText(t.group,ITEM_MAX),a=errorText(t.error);i&&(u.item=i),n&&(u.group=n),a&&(u.error=a),r==="failed"&&($="warning"),p=summary(`${r}${i?` ${oneLine(i,80)}`:""}${n?` \xB7 ${oneLine(n,80)}`:""}`,[],a)}else if(o==="loop"){if(r==="run-end"){const i=t.outcome;if(!isOutcome(o,i))return refuse(`${s}: outcome ${shown(i)} is not a run outcome (${protocol_types_1.SOURCE_PUSH_OUTCOMES.loop.join(", ")})`);const n=count(t.items,s,"items",!1),a=count(t.durationMs,s,"durationMs",!0),l=errorText(t.error);i!==void 0&&(u.outcome=i),n!==void 0&&(u.items=n),a!==void 0&&(u.durationMs=a),l&&(u.error=l),i==="failed"&&($="warning"),p=summary(i?`${r} ${i}`:r,[n!==void 0&&`${n} item${n===1?"":"s"}`,a!==void 0&&`${a} ms`],l)}}else if(o==="store"){const i=idText(t.object,ITEM_MAX),n=idText(t.group,ITEM_MAX),a=r==="write"?count(t.bytes,s,"bytes",!1):void 0,l=count(t.durationMs,s,"durationMs",!0),m=errorText(t.error);i&&(u.object=i),n&&(u.group=n),a!==void 0&&(u.bytes=a),l!==void 0&&(u.durationMs=l),m&&(u.error=m),r==="error"&&($="warning"),p=summary(`${r}${i?` ${oneLine(i,80)}`:""}${n?` \xB7 ${oneLine(n,80)}`:""}`,[a!==void 0&&sized(a),l!==void 0&&`${l} ms`],m)}else{const i=t.channel;if(typeof i!="string"||!i.trim())return refuse(`${s}: channel ${shown(i)} is not a channel \u2014 every traffic event says its channel (the snapshot channel's key)`);const n=t.outcome;if(!isOutcome(o,n))return refuse(`${s}: outcome ${shown(n)} is not a message outcome (${protocol_types_1.SOURCE_PUSH_OUTCOMES.traffic.join(", ")})`);const a=cut(i,ITEM_MAX),l=text(t.counterpart,ITEM_MAX),m=count(t.durationMs,s,"durationMs",!0),y=count(t.bytes,s,"bytes",!1),v=idText(t.correlation,ITEM_MAX),h=errorText(t.error);u.channel=a,l&&(u.counterpart=l),n!==void 0&&(u.outcome=n),m!==void 0&&(u.durationMs=m),y!==void 0&&(u.bytes=y),v&&(u.correlation=v),h&&(u.error=h),(n==="failed"||n==="rate-limited")&&($="warning");const g=l?` ${r==="inbound"?"\u2190":"\u2192"} ${oneLine(l,80)}`:"";p=summary(`${r} ${oneLine(a,80)}${g}${n?` ${n}`:""}`,[y!==void 0&&sized(y),m!==void 0&&`${m} ms`],h),_=trafficBucket(f,r,a,s)}const E=(0,flow_context_1.flowContext)();return(0,emit_1.lensEmitOutcome)(protocol_types_1.CUSTOM_EVENT_SOURCE,$,`${o} ${emit_1.PROJECT}/${f} (reported): ${p}`,u,_,E?{flowId:E.flowId,requestId:E.requestId,runId:E.runId}:void 0,"backend",customGuard)==="written"}catch{return!1}}d(emitCustomHere,"emitCustomHere"),c(emitCustomHere,"emitCustomHere");function isOutcome(t,e){return e===void 0||typeof e=="string"&&protocol_types_1.SOURCE_PUSH_OUTCOMES[t].includes(e)}d(isOutcome,"isOutcome"),c(isOutcome,"isOutcome");function count(t,e,o,f){if(t===void 0)return;const s=typeof t=="number"&&f&&Number.isFinite(t)?Math.round(t):t;if(typeof s=="number"&&Number.isSafeInteger(s)&&s>=0)return s;say(`${e}: ${o} ${typeof t=="number"?String(t):shown(t)} is not a count \u2014 written without it`)}d(count,"count"),c(count,"count");function installCustomEmit(){try{const t=globalThis;if(typeof t[exports.EMIT_CUSTOM]=="function")return!1;const e=emitCustomHere;return t[exports.EMIT_CUSTOM]=e,!0}catch{return!1}}d(installCustomEmit,"installCustomEmit"),c(installCustomEmit,"installCustomEmit");function lensEmitCustom(t){try{const e=globalThis[exports.EMIT_CUSTOM];return typeof e=="function"?e(t)===!0:!1}catch{return!1}}d(lensEmitCustom,"lensEmitCustom"),c(lensEmitCustom,"lensEmitCustom");
|
package/lib/emit.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`;return maybeRotateEventFile(exports.EVENT_FILE,u.length),appendFileSync(exports.EVENT_FILE,u),"written"}catch{return"failed"}finally{writing=!1}}
|
|
3
|
-
`;return maybeRotateEventFile(exports.EVENT_FILE,
|
|
1
|
+
"use strict";var m=Object.defineProperty;var p=(r,s)=>m(r,"name",{value:s,configurable:!0});var a=Object.defineProperty,i=p((r,s)=>a(r,"name",{value:s,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.EVENT_FILE=exports.PROJECT=exports.EVENT_MAX_FILES=exports.EVENT_MAX_BYTES=void 0,exports.maybeRotateEventFile=maybeRotateEventFile,exports.isLensWriting=isLensWriting,exports.lensEmit=lensEmit,exports.lensEmitOutcome=lensEmitOutcome,exports.lensLog=lensLog;const tslib_1=require("tslib"),nodeFs=tslib_1.__importStar(require("node:fs")),node_path_1=require("node:path"),bus_rotation_1=require("@lensmcp/core/bus-rotation"),flood_guard_1=require("./flood-guard"),flow_context_1=require("./flow-context"),appendFileSync=nodeFs.appendFileSync,mkdirSync=nodeFs.mkdirSync,statSync=nodeFs.statSync,renameSync=nodeFs.renameSync,unlinkSync=nodeFs.unlinkSync,openSync=nodeFs.openSync,closeSync=nodeFs.closeSync,BUS_CAPS=(0,bus_rotation_1.busCapsFromEnv)();exports.EVENT_MAX_BYTES=BUS_CAPS.maxBytes,exports.EVENT_MAX_FILES=BUS_CAPS.maxFiles;const rotators=new Map,BUS_FS={statSync,renameSync,unlinkSync,openSync,closeSync};function maybeRotateEventFile(r,s,e){if(e!==void 0){const n=e.maxBytes??exports.EVENT_MAX_BYTES,t=e.maxFiles??exports.EVENT_MAX_FILES;(0,bus_rotation_1.createBusRotator)(r,{maxBytes:n,maxFiles:t,fs:BUS_FS,checkEveryBytes:0})(s);return}let o=rotators.get(r);o||(o=(0,bus_rotation_1.createBusRotator)(r,{maxBytes:exports.EVENT_MAX_BYTES,maxFiles:exports.EVENT_MAX_FILES,fs:BUS_FS}),rotators.set(r,o)),o(s)}p(maybeRotateEventFile,"maybeRotateEventFile"),i(maybeRotateEventFile,"maybeRotateEventFile"),exports.PROJECT=process.env.LENSMCP_PROJECT||process.env.SERVICE_NAME||"app",exports.EVENT_FILE=process.env.LENSMCP_EVENT_FILE||`${process.cwd()}/.lensmcp/events.jsonl`;let writing=!1,dirReady=!1;const emitGuard=(0,flood_guard_1.createEventFloodGuard)({burst:30,perSec:5}),logGuard=(0,flood_guard_1.createEventFloodGuard)({burst:120,perSec:20});function isLensWriting(){return writing}p(isLensWriting,"isLensWriting"),i(isLensWriting,"isLensWriting");function lensEmit(r,s,e,o,n,t,c="cluster"){return lensEmitOutcome(r,s,e,o,n,t,c)==="written"}p(lensEmit,"lensEmit"),i(lensEmit,"lensEmit");function lensEmitOutcome(r,s,e,o,n,t,c="cluster",l=emitGuard){try{writing=!0;const E=n??`${r}:${String(o.name??r)}`,d=l.admit(E);if(!d.ok)return"suppressed";dirReady||(mkdirSync((0,node_path_1.dirname)(exports.EVENT_FILE),{recursive:!0}),dirReady=!0);const u=JSON.stringify({id:Date.now().toString(36)+Math.random().toString(36).slice(2,10),sessionId:"pending",timestamp:Date.now(),source:r,category:c,severity:s,context:{sessionId:"pending",projectName:exports.PROJECT,...t?.flowId?{flowId:t.flowId}:{},...t?.requestId?{requestId:t.requestId}:{},...t?.runId?{runId:t.runId}:{},...t?.originNodeId?{originNodeId:t.originNodeId}:{},...t?.originType?{originType:t.originType}:{}},fingerprint:E,title:e,raw:{project:exports.PROJECT,...o,...d.suppressed>0?{floodSuppressed:d.suppressed}:{}}})+`
|
|
2
|
+
`;return maybeRotateEventFile(exports.EVENT_FILE,u.length),appendFileSync(exports.EVENT_FILE,u),"written"}catch{return"failed"}finally{writing=!1}}p(lensEmitOutcome,"lensEmitOutcome"),i(lensEmitOutcome,"lensEmitOutcome");function lensLog(r,s,e){try{writing=!0;const o=e?.bucket!==void 0?`log:${exports.PROJECT}:${e.bucket}`:r==="error"||r==="fatal"?`log:error:${exports.PROJECT}`:`log:${exports.PROJECT}`,n=e?.bucket!==void 0?{ok:!0,suppressed:e.suppressed??0}:logGuard.admit(o);if(!n.ok)return!1;dirReady||(mkdirSync((0,node_path_1.dirname)(exports.EVENT_FILE),{recursive:!0}),dirReady=!0);const t=(0,flow_context_1.flowContext)(),c=JSON.stringify({id:Date.now().toString(36)+Math.random().toString(36).slice(2,10),sessionId:"pending",timestamp:Date.now(),source:"nestjs",category:"runtime",severity:r,context:{sessionId:"pending",projectName:exports.PROJECT,...t?.flowId?{flowId:t.flowId}:{},...t?.requestId?{requestId:t.requestId}:{},...t?.runId?{runId:t.runId}:{}},fingerprint:o,title:s,raw:{project:exports.PROJECT,kind:"log",...e?.stack?{request:{error:{message:s,stack:e.stack}}}:{},...e?.text?{text:e.text}:{},...e?.continues?{continues:!0}:{},...e?.stream?{stream:e.stream}:{},...e?.level?{level:e.level}:{},...e?.logger?{logger:e.logger}:{},...n.suppressed>0?{floodSuppressed:n.suppressed}:{}}})+`
|
|
3
|
+
`;return maybeRotateEventFile(exports.EVENT_FILE,c.length),appendFileSync(exports.EVENT_FILE,c),!0}catch{return!1}finally{writing=!1}}p(lensLog,"lensLog"),i(lensLog,"lensLog");
|
package/lib/flood-guard.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var n=Object.defineProperty;var a=(r,t)=>n(r,"name",{value:t,configurable:!0});var o=Object.defineProperty,e=a((r,t)=>o(r,"name",{value:t,configurable:!0}),"e");Object.defineProperty(exports,"__esModule",{value:!0}),exports.createEventFloodGuard=void 0;var protocol_types_1=require("@lensmcp/protocol-types");Object.defineProperty(exports,"createEventFloodGuard",{enumerable:!0,get:e(function(){return protocol_types_1.createEventFloodGuard},"get")});
|
package/lib/flow-context.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var d=Object.defineProperty;var o=(e,t)=>d(e,"name",{value:t,configurable:!0});var l=Object.defineProperty,n=o((e,t)=>l(e,"name",{value:t,configurable:!0}),"n");Object.defineProperty(exports,"__esModule",{value:!0}),exports.CONTEXT_END=void 0,exports.flowContextStatus=flowContextStatus,exports.resetFlowContextForTests=resetFlowContextForTests,exports.isRequireEsmError=isRequireEsmError,exports.isModuleNotFoundError=isModuleNotFoundError,exports.primeFlowContext=primeFlowContext,exports.attachContextEnd=attachContextEnd,exports.contextEndOf=contextEndOf,exports.runInFlowContext=runInFlowContext,exports.liveFlowContext=liveFlowContext,exports.flowContext=flowContext;let getCtx=null,runWith=null,status={state:"not-primed"},warned=!1;function flowContextStatus(){return status}o(flowContextStatus,"flowContextStatus"),n(flowContextStatus,"flowContextStatus");function resetFlowContextForTests(){getCtx=null,runWith=null,status={state:"not-primed"},warned=!1}o(resetFlowContextForTests,"resetFlowContextForTests"),n(resetFlowContextForTests,"resetFlowContextForTests");function isRequireEsmError(e){const t=e?.code;return t==="ERR_REQUIRE_ESM"||t==="ERR_REQUIRE_ASYNC_MODULE"}o(isRequireEsmError,"isRequireEsmError"),n(isRequireEsmError,"isRequireEsmError");function isModuleNotFoundError(e){const t=e;return t?.code!=="MODULE_NOT_FOUND"&&t?.code!=="ERR_MODULE_NOT_FOUND"?!1:String(t?.message??"").includes("@lensmcp/nest-instrumentation")}o(isModuleNotFoundError,"isModuleNotFoundError"),n(isModuleNotFoundError,"isModuleNotFoundError");function requireNestInstrumentation(){return require("@lensmcp/nest-instrumentation")}o(requireNestInstrumentation,"requireNestInstrumentation"),n(requireNestInstrumentation,"requireNestInstrumentation");function primeFlowContext(e=requireNestInstrumentation){try{const t=e();getCtx=t.currentLensmcpContext,runWith=t.runInLensmcpContext,status={state:"ready"}}catch(t){if(getCtx=null,runWith=null,isModuleNotFoundError(t)){status={state:"absent"};return}const r=t instanceof Error?t.message:String(t);if(status=isRequireEsmError(t)?{state:"runtime-too-old",detail:r}:{state:"failed",detail:r},!warned){warned=!0;const s=status.state==="runtime-too-old"?`this Node (${process.version}) cannot require an ESM package; @lensmcp/node-instrumentation needs >=20.19`:r;console.warn(`[lensmcp] flow correlation is OFF \u2014 could not load @lensmcp/nest-instrumentation: ${s}`)}}}o(primeFlowContext,"primeFlowContext"),n(primeFlowContext,"primeFlowContext"),exports.CONTEXT_END=Symbol.for("lensmcp.contextEnd");function attachContextEnd(e){let t=!1;const r=[],s={get ended(){return t},onEnd(u){t?runEndListener(u):r.push(u)}};return Object.defineProperty(e,exports.CONTEXT_END,{value:s}),()=>{if(!t){t=!0;for(const u of r.splice(0))runEndListener(u)}}}o(attachContextEnd,"attachContextEnd"),n(attachContextEnd,"attachContextEnd");function runEndListener(e){try{e()}catch{}}o(runEndListener,"runEndListener"),n(runEndListener,"runEndListener");function contextEndOf(e){const t=e?.[exports.CONTEXT_END];return t&&typeof t.onEnd=="function"?t:void 0}o(contextEndOf,"contextEndOf"),n(contextEndOf,"contextEndOf");function runInFlowContext(e,t){if(!runWith)return t();const r={sessionId:"pending",requestId:e.requestId,...e.flowId?{flowId:e.flowId}:{}},s=attachContextEnd(r);let u;try{u=runWith(r,t)}catch{return s(),t()}const i=u;return i&&typeof i.then=="function"?i.then(c=>(s(),c),c=>{throw s(),c}):(s(),u)}o(runInFlowContext,"runInFlowContext"),n(runInFlowContext,"runInFlowContext");function liveFlowContext(){try{return getCtx?.()}catch{return}}o(liveFlowContext,"liveFlowContext"),n(liveFlowContext,"liveFlowContext");function flowContext(){const e=liveFlowContext();if(e)return{...e.flowId?{flowId:e.flowId}:{},...e.requestId?{requestId:e.requestId}:{},...e.runId?{runId:e.runId}:{},...e.originNodeId?{originNodeId:e.originNodeId}:{}}}o(flowContext,"flowContext"),n(flowContext,"flowContext");
|
package/lib/http-capture.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`)}:void 0}
|
|
1
|
+
"use strict";var g=Object.defineProperty;var u=(e,t)=>g(e,"name",{value:t,configurable:!0});var p=Object.defineProperty,c=u((e,t)=>p(e,"name",{value:t,configurable:!0}),"c");Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResponseSink=exports.WrittenBody=exports.headerPairs=exports.MAX_STREAM_MS=void 0,exports.takeRequest=takeRequest,exports.chunkBytes=chunkBytes,exports.unpacked=unpacked,exports.writtenRequest=writtenRequest,exports.readResponse=readResponse,exports.requestPart=requestPart;const tslib_1=require("tslib"),node_crypto_1=require("node:crypto"),zlib=tslib_1.__importStar(require("node:zlib")),ai_store_1=require("./ai-store"),http_store_1=require("./http-store"),MAX_EVENTS=2e3,MAX_EVENT_DATA=4*1024,MAX_STREAM_KEPT=256*1024;exports.MAX_STREAM_MS=300*1e3;const MAX_HASH_BYTES=1024*1024,MAX_READ=http_store_1.MAX_KEPT_BYTES*32,headerPairs=c(e=>{try{if(!e)return[];if(typeof e.forEach=="function"&&typeof e.get=="function"){const t=[];return e.forEach((n,s)=>t.push([s,n])),t}return Array.isArray(e)?e.map(([t,n])=>[String(t),String(n)]):Object.entries(e).map(([t,n])=>[t,Array.isArray(n)?n.join(", "):String(n)])}catch{return[]}},"headerPairs");exports.headerPairs=headerPairs;function takeRequest(e,t,n){const s=typeof e=="object"&&e!==null&&!(e instanceof URL)?e:void 0,o=[...(0,exports.headerPairs)(s?.headers),...(0,exports.headerPairs)(t?.headers)],a=o.find(([h])=>h.toLowerCase()==="content-type")?.[1]??"",r={headers:o,contentType:a};if(!n)return r;const i=t?.body,d=c(h=>new TextEncoder().encode(h),"enc");if(typeof i=="string")return{...r,bytes:d(i),size:Buffer.byteLength(i)};if(i instanceof URLSearchParams)return{...r,contentType:a||"application/x-www-form-urlencoded",bytes:d(i.toString())};if(i instanceof ArrayBuffer)return{...r,bytes:new Uint8Array(i),size:i.byteLength};if(ArrayBuffer.isView(i))return{...r,bytes:new Uint8Array(i.buffer,i.byteOffset,i.byteLength),size:i.byteLength};if(typeof Blob<"u"&&i instanceof Blob)return{...r,size:i.size,...i.size<=MAX_READ?{pending:i.arrayBuffer().then(h=>new Uint8Array(h)).catch(()=>{})}:{}};if(typeof FormData<"u"&&i instanceof FormData)return{...r,omitted:"form-data"};if(i!=null)return{...r,omitted:"stream"};if(s&&!s.bodyUsed&&s.body)try{return{...r,pending:s.clone().arrayBuffer().then(h=>new Uint8Array(h)).catch(()=>{})}}catch{return r}return r}u(takeRequest,"takeRequest"),c(takeRequest,"takeRequest");function chunkBytes(e,t){if(e instanceof Uint8Array)return e;if(typeof e=="string")return Buffer.from(e,typeof t=="string"&&Buffer.isEncoding(t)?t:"utf8")}u(chunkBytes,"chunkBytes"),c(chunkBytes,"chunkBytes");class WrittenBody{static{u(this,"WrittenBody")}static{c(this,"WrittenBody")}constructor(t){this.keep=t,this.chunks=[],this.read=0,this.size=0}take(t,n){if(t==null||typeof t=="function")return;const s=chunkBytes(t,n);s&&(this.size+=s.byteLength,this.keep&&this.read<MAX_READ&&(this.chunks.push(s),this.read+=s.byteLength))}get whole(){return this.read>=this.size}bytes(){return Buffer.concat(this.chunks)}}exports.WrittenBody=WrittenBody;function unpacked(e,t){try{if(e==="gzip"||e==="x-gzip")return zlib.gunzipSync(t,{maxOutputLength:MAX_READ});if(e==="br")return zlib.brotliDecompressSync(t,{maxOutputLength:MAX_READ});if(e==="deflate")return zlib.inflateSync(t,{maxOutputLength:MAX_READ})}catch{return}}u(unpacked,"unpacked"),c(unpacked,"unpacked");const encodingOf=c(e=>{const t=(e??"").trim().toLowerCase();return t==="identity"?"":t},"encodingOf");function writtenRequest(e,t){const n=(0,exports.headerPairs)(e),s=c(i=>n.find(([d])=>d.toLowerCase()===i)?.[1],"header"),o={headers:n,contentType:s("content-type")??""};if(!t||!t.size)return o;const a=encodingOf(s("content-encoding"));if(!a)return{...o,bytes:t.bytes(),size:t.size};const r=t.whole?unpacked(a,t.bytes()):void 0;return r?{...o,bytes:r,size:r.length}:{...o,size:t.size,omitted:"encoded"}}u(writtenRequest,"writtenRequest"),c(writtenRequest,"writtenRequest");function sseEvent(e){let t="message";const n=[];for(const s of e.split(/\r?\n/)){if(!s||s.startsWith(":"))continue;const o=s.indexOf(":"),a=o<0?s:s.slice(0,o),r=o<0?"":s.slice(o+1).replace(/^ /,"");a==="event"?t=r||"message":a==="data"&&n.push(r)}return n.length||t!=="message"?{event:t,data:n.join(`
|
|
2
|
+
`)}:void 0}u(sseEvent,"sseEvent"),c(sseEvent,"sseEvent");class ResponseSink{static{u(this,"ResponseSink")}static{c(this,"ResponseSink")}constructor(t,n,s){this.contentType=t,this.startedAt=n,this.opts=s,this.total=0,this.kept=[],this.keptBytes=0,this.hash=(0,node_crypto_1.createHash)("sha256"),this.events=[],this.eventTotal=0,this.eventData=0,this.cut=!1,this.pendingText="",this.decoder=new TextDecoder,this.encoding=encodingOf(s.encoding),this.sse=!this.encoding&&/text\/event-stream/i.test(t),this.parsing=this.sse,this.hashing=!/json|^text\/|xml|form/i.test(t)}get size(){return this.total}take(t){const n=sseEvent(t);if(!n)return;this.eventTotal++;const s=Date.now()-this.startedAt;if(this.firstEventMs??=s,this.events.length>=MAX_EVENTS||this.eventData>=MAX_STREAM_KEPT){this.cut=!0;return}const o=this.opts.ai?void 0:(0,ai_store_1.redactAiText)(n.data).slice(0,MAX_EVENT_DATA);o&&(this.eventData+=o.length),this.events.push({atMs:s,event:n.event,bytes:Buffer.byteLength(t),...o!==void 0?{data:o}:{}})}push(t){if(this.total+=t.byteLength,this.sse){if(!this.parsing)return this.inTime();this.pendingText+=this.decoder.decode(t,{stream:!0});let n;for(;(n=this.pendingText.search(/\r?\n\r?\n/))>=0;){const s=/\r?\n\r?\n/.exec(this.pendingText.slice(n));this.take(this.pendingText.slice(0,n)),this.pendingText=this.pendingText.slice(n+s[0].length)}this.pendingText.length>MAX_READ&&(this.pendingText="",this.parsing=!1,this.cut=!0)}else this.opts.ai||(this.keptBytes<MAX_READ&&(this.kept.push(t),this.keptBytes+=t.byteLength),this.hashing&&!this.encoding&&(this.total<=MAX_HASH_BYTES?this.hash.update(t):this.hashing=!1));return this.inTime()}inTime(){return Date.now()-this.startedAt<=exports.MAX_STREAM_MS?!0:(this.cut=!0,!1)}finish(t=!1,n=Date.now()){t?this.cut=!0:this.parsing&&this.pendingText.trim()&&this.take(this.pendingText);const s=this.total,o=this.contentType.split(";")[0].trim();if(this.sse)return{endedAt:n,stream:{protocol:"sse",...this.firstEventMs!==void 0?{firstEventMs:this.firstEventMs}:{},events:this.events,bytes:s,total:this.eventTotal,...this.cut?{cut:!0}:{}}};if(this.opts.ai)return{endedAt:n,body:{contentType:o,size:s,kept:0,truncated:!1,omitted:"ai"}};const a=Buffer.concat(this.kept);if(this.encoding){const i=s<=MAX_READ?unpacked(this.encoding,a):void 0;if(!i)return{endedAt:n,body:{contentType:o.toLowerCase(),size:s,kept:0,truncated:!1,omitted:"encoded"}};const d=this.hashing&&i.length<=MAX_HASH_BYTES?(0,node_crypto_1.createHash)("sha256").update(i).digest("hex"):void 0;return{endedAt:n,body:(0,http_store_1.keepBody)(this.contentType,i,i.length,this.opts.paths,d)}}const r=this.hashing&&s<=MAX_HASH_BYTES?this.hash.digest("hex"):void 0;return{endedAt:n,body:(0,http_store_1.keepBody)(this.contentType,a,s,this.opts.paths,r)}}}exports.ResponseSink=ResponseSink;function readResponse(e,t,n,s){const o=(()=>{try{return e.headers.get("content-type")??""}catch{return""}})(),a=t.body;if(!a)return Promise.resolve({endedAt:Date.now()});const r=a.getReader(),i=new ResponseSink(o,n,s);return(async()=>{try{for(;;){const{done:d,value:h}=await r.read();if(d)break;if(!i.push(h)){await r.cancel().catch(()=>{});break}}}catch{return i.finish(!0)}return i.finish()})()}u(readResponse,"readResponse"),c(readResponse,"readResponse");async function requestPart(e,t,n,s,o,a){const{headers:r,redacted:i}=(0,http_store_1.redactHeaders)(e.headers);a.push(...i);const d=n==="bodies"&&t.length>1?(0,http_store_1.redactQuery)(t):[];let h;if(n==="bodies"){const y=e.contentType.split(";")[0].trim().toLowerCase();if(s)h={contentType:y,size:e.size??e.bytes?.byteLength??0,kept:0,truncated:!1,omitted:"ai"};else if(e.omitted)h={contentType:y,size:e.size??0,kept:0,truncated:!1,omitted:e.omitted};else{const f=e.bytes??await e.pending;f&&f.byteLength&&(h=(0,http_store_1.keepBody)(e.contentType,f,e.size??f.byteLength,o))}}return{headers:r,...d.length?{query:d}:{},...h?{body:h}:{}}}u(requestPart,"requestPart"),c(requestPart,"requestPart");
|
package/lib/http-store.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var d=Object.defineProperty;var u=(e,t)=>d(e,"name",{value:t,configurable:!0});var f=Object.defineProperty,i=u((e,t)=>f(e,"name",{value:t,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.exchangeTime=exports.DEFAULT_HTTP_MAX_AGE_MS=exports.DEFAULT_HTTP_MAX_FILES=exports.newExchangeId=exports.MAX_KEPT_BYTES=exports.REMOVED=void 0,exports.httpCaptureMode=httpCaptureMode,exports.redactHeaders=redactHeaders,exports.redactQuery=redactQuery,exports.keepBody=keepBody,exports.pruneHttpExchanges=pruneHttpExchanges,exports.writeHttpExchange=writeHttpExchange;const tslib_1=require("tslib"),nodeFs=tslib_1.__importStar(require("node:fs")),node_crypto_1=require("node:crypto"),http_exchange_1=require("@lensmcp/core/http-exchange"),redact_1=require("@lensmcp/core/redact"),ai_store_1=require("./ai-store"),emit_1=require("./emit"),mkdirSync=nodeFs.mkdirSync,writeFileSync=nodeFs.writeFileSync,renameSync=nodeFs.renameSync,readdirSync=nodeFs.readdirSync,unlinkSync=nodeFs.unlinkSync;function httpCaptureMode(e=process.env){const t=(e.LENSMCP_HTTP_CAPTURE??"").trim().toLowerCase();return t==="off"||t==="0"||t==="false"||t==="none"?"off":t==="headers"?"headers":"bodies"}u(httpCaptureMode,"httpCaptureMode"),i(httpCaptureMode,"httpCaptureMode"),exports.REMOVED="\u2022\u2022\u2022\u2022 redacted",exports.MAX_KEPT_BYTES=64*1024;const MAX_PARSE_BYTES=2*1024*1024,newExchangeId=i(()=>`hx_${Date.now().toString(36)}${(0,node_crypto_1.randomBytes)(5).toString("hex")}`,"newExchangeId");exports.newExchangeId=newExchangeId;const CREDENTIAL_HEADERS=/^(authorization|proxy-authorization|cookie|set-cookie|x-api-key|api-key|openai-organization|openai-project|x-internal-token|x-amz-security-token)$|-api-key$|-token$|-secret$/i,CREDENTIAL_FIELD=/pass(word|wd)?|secret|token|api[-_]?key|authorization|credential|cookie|signature/i;function jwtClaims(e){const t=e.split(".");if(t.length===3)try{const r=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return`JWT \xB7 ${["iss","aud","sub","exp"].filter(n=>r[n]!==void 0).map(n=>`${n}=${n==="exp"&&typeof r[n]=="number"?new Date(r[n]*1e3).toISOString():String(r[n]).slice(0,80)}`).join(" \xB7 ")||"no claims"} \xB7 ${exports.REMOVED.split(" ")[0]} signature`}catch{return}}u(jwtClaims,"jwtClaims"),i(jwtClaims,"jwtClaims");function redactHeaders(e){const t=[],r=[];for(const[n,a]of e){const o=n.toLowerCase();if(CREDENTIAL_HEADERS.test(o)||(0,redact_1.isSecretParam)(o)){r.push(o);const s=/^bearer\s+(\S+)$/i.exec(a.trim()),c=s?jwtClaims(s[1]):void 0,p=/^(\w+)\s+\S/.exec(a.trim())?.[1];t.push([o,c?`Bearer ${c}`:p&&o.endsWith("authorization")?`${p} ${exports.REMOVED}`:exports.REMOVED])}else t.push([o,(0,ai_store_1.redactAiText)(a).slice(0,2048)])}return{headers:t,redacted:r}}u(redactHeaders,"redactHeaders"),i(redactHeaders,"redactHeaders");function redactQuery(e){const t=[];try{for(const[r,n]of new URLSearchParams(e))t.push([r,(0,redact_1.isSecretParam)(r)||CREDENTIAL_FIELD.test(r)?exports.REMOVED:(0,ai_store_1.redactAiText)(n).slice(0,1024)])}catch{}return t.slice(0,100)}u(redactQuery,"redactQuery"),i(redactQuery,"redactQuery");function redactJson(e,t,r,n=0){if(n>32||e===null||typeof e!="object")return typeof e=="string"?(0,ai_store_1.redactAiText)(e):e;if(Array.isArray(e))return e.map((o,s)=>redactJson(o,`${t}[${s}]`,r,n+1));const a={};for(const[o,s]of Object.entries(e)){const c=t?`${t}.${o}`:o,p=typeof s=="number"&&/tokens/i.test(o);CREDENTIAL_FIELD.test(o)&&s!==null&&typeof s!="object"&&!p?(a[o]=exports.REMOVED,r.length<50&&r.push(c)):a[o]=redactJson(s,c,r,n+1)}return a}u(redactJson,"redactJson"),i(redactJson,"redactJson");const textual=i(e=>/json|^text\/|x-www-form-urlencoded|xml|javascript|graphql|event-stream/i.test(e)||e==="","textual");function keepBody(e,t,r,n,a){const o=e.split(";")[0].trim().toLowerCase();if(!textual(o))return{contentType:o||"application/octet-stream",size:r,kept:0,truncated:!1,omitted:"binary",...a?{sha256:a}:{}};const s=t.byteLength>=r&&r<=MAX_PARSE_BYTES,c=Buffer.from(t.buffer,t.byteOffset,t.byteLength).toString("utf8");let p;if(s&&/json/.test(o))try{p=JSON.stringify(redactJson(JSON.parse(c),"",n))}catch{p=(0,ai_store_1.redactAiText)(c)}else s&&/x-www-form-urlencoded/.test(o)?p=new URLSearchParams(redactQuery(c)).toString():p=(0,ai_store_1.redactAiText)(c);const x=Buffer.byteLength(p)>exports.MAX_KEPT_BYTES?Buffer.from(p).subarray(0,exports.MAX_KEPT_BYTES).toString("utf8"):p;return{contentType:o,size:r,kept:Buffer.byteLength(x),text:x,truncated:r>t.byteLength||x.length<p.length}}u(keepBody,"keepBody"),i(keepBody,"keepBody"),exports.DEFAULT_HTTP_MAX_FILES=1e4,exports.DEFAULT_HTTP_MAX_AGE_MS=1440*6e4;const PRUNE_EVERY_MS=3e4,maxFiles=i(()=>{const e=Number(process.env.LENSMCP_HTTP_MAX_FILES);return Number.isInteger(e)&&e>=10?e:exports.DEFAULT_HTTP_MAX_FILES},"maxFiles"),maxAgeMs=i(()=>{const e=Number(process.env.LENSMCP_HTTP_MAX_AGE_MS);return Number.isFinite(e)&&e>=6e4?e:exports.DEFAULT_HTTP_MAX_AGE_MS},"maxAgeMs"),exchangeTime=i(e=>{const t=/^hx_([0-9a-z]{8})/.exec(e),r=t?parseInt(t[1],36):NaN;return Number.isFinite(r)?r:void 0},"exchangeTime");exports.exchangeTime=exchangeTime;const lastPrune=new Map;function pruneHttpExchanges(e,t=Date.now()){let r=0;try{const n=readdirSync(e).filter(s=>/^hx_[0-9a-z]+\.json$/.test(s)).sort(),a=n.length-maxFiles(),o=t-maxAgeMs();for(let s=0;s<n.length;s+=1){const c=(0,exports.exchangeTime)(n[s]);if(s>=a&&(c===void 0||c>=o))break;try{unlinkSync(`${e}/${n[s]}`),r+=1}catch{}}}catch{}return r}u(pruneHttpExchanges,"pruneHttpExchanges"),i(pruneHttpExchanges,"pruneHttpExchanges");function writeHttpExchange(e){try{const t=(0,http_exchange_1.exchangePlace)(e),r=(0,http_exchange_1.httpExchangeDir)(emit_1.EVENT_FILE,t);mkdirSync(r,{recursive:!0,mode:448});const n=(0,http_exchange_1.httpExchangeFile)(emit_1.EVENT_FILE,e.id,t);writeFileSync(`${n}.tmp`,JSON.stringify(e),{mode:384}),renameSync(`${n}.tmp`,n);const a=Date.now();return a-(lastPrune.get(t)??0)>=PRUNE_EVERY_MS&&(lastPrune.set(t,a),pruneHttpExchanges(r,a)),!0}catch{return!1}}u(writeHttpExchange,"writeHttpExchange"),i(writeHttpExchange,"writeHttpExchange");
|
package/lib/install.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var p=Object.defineProperty;var a=(t,r)=>p(t,"name",{value:r,configurable:!0});var s=Object.defineProperty,e=a((t,r)=>s(t,"name",{value:r,configurable:!0}),"e");Object.defineProperty(exports,"__esModule",{value:!0}),exports.installLensmcpNodeInstrumentation=installLensmcpNodeInstrumentation;const require_hook_1=require("./require-hook"),flow_context_1=require("./flow-context"),emit_custom_1=require("./emit-custom"),tap_egress_1=require("./tap-egress"),tap_ai_1=require("./tap-ai"),tap_fs_1=require("./tap-fs"),tap_exec_1=require("./tap-exec"),tap_pg_1=require("./tap-pg"),tap_redis_1=require("./tap-redis"),active_work_1=require("./active-work"),tap_bullmq_1=require("./tap-bullmq"),tap_nest_1=require("./tap-nest"),tap_nest_logger_1=require("./tap-nest-logger"),tap_event_loop_1=require("./tap-event-loop"),tap_ingress_1=require("./tap-ingress"),tap_stdout_1=require("./tap-stdout");function installLensmcpNodeInstrumentation(){const t=globalThis;if(!t.__lensmcpNodeInstrumented&&(t.__lensmcpNodeInstrumented=!0,process.env.LENSMCP_AUTO!=="0")){try{(0,active_work_1.installActiveWorkProbe)()}catch{}try{(0,flow_context_1.primeFlowContext)()}catch{}try{(0,emit_custom_1.installCustomEmit)()}catch{}try{(0,tap_egress_1.tapEgress)()}catch{}try{(0,tap_ingress_1.tapIngress)()}catch{}try{(0,tap_ai_1.tapAi)()}catch{}try{(0,tap_fs_1.tapFs)()}catch{}try{(0,tap_exec_1.tapExec)()}catch{}try{(0,tap_stdout_1.tapStdout)()}catch{}try{(0,tap_event_loop_1.tapEventLoop)()}catch{}try{(0,require_hook_1.installRequireHook)({pg:tap_pg_1.pgTap,ioredis:tap_redis_1.redisTap,bullmq:tap_bullmq_1.bullmqTap,"@nestjs/core":tap_nest_1.nestTap,"@nestjs/common":tap_nest_logger_1.nestLoggerTap})}catch{}try{(0,tap_nest_1.installChildAppBridge)()}catch{}}}a(installLensmcpNodeInstrumentation,"installLensmcpNodeInstrumentation"),e(installLensmcpNodeInstrumentation,"installLensmcpNodeInstrumentation");
|
package/lib/require-hook.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var l=Object.defineProperty;var s=(e,n)=>l(e,"name",{value:n,configurable:!0});var a=Object.defineProperty,r=s((e,n)=>a(e,"name",{value:n,configurable:!0}),"r");Object.defineProperty(exports,"__esModule",{value:!0}),exports.installRequireHook=installRequireHook;const tapped=new Set;function runTap(e,n,u){try{n(u)!==!1&&tapped.add(e)}catch{tapped.add(e)}}s(runTap,"runTap"),r(runTap,"runTap");function installRequireHook(e){const n=require("node:module"),u=n._load;n._load=function(t,...c){const i=u.call(this,t,...c),o=e[t];return o&&!tapped.has(t)&&runTap(t,o,i),i};for(const t of Object.keys(e)){if(tapped.has(t))continue;const c=e[t];if(c)try{const i=require.resolve(t),o=require.cache[i];o&&runTap(t,c,o.exports)}catch{}}}s(installRequireHook,"installRequireHook"),r(installRequireHook,"installRequireHook");
|
package/lib/sql-accounting.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var u=Object.defineProperty;var n=(t,e)=>u(t,"name",{value:e,configurable:!0});var l=Object.defineProperty,s=n((t,e)=>l(t,"name",{value:e,configurable:!0}),"s");Object.defineProperty(exports,"__esModule",{value:!0}),exports.SQL_ACCOUNT_SETTLE_MS=exports.SQL_ACCOUNT_KIND=void 0,exports.beginSqlStatement=beginSqlStatement,exports.endSqlStatement=endSqlStatement,exports.abandonSqlStatement=abandonSqlStatement;const flood_guard_1=require("./flood-guard"),emit_1=require("./emit"),flow_context_1=require("./flow-context");exports.SQL_ACCOUNT_KIND="db-request-account",exports.SQL_ACCOUNT_SETTLE_MS=1e3;const accountGuard=(0,flood_guard_1.createEventFloodGuard)({burst:120,perSec:20}),accounts=new WeakMap;let accountSeq=0;function newAccountId(){return accountSeq=(accountSeq+1)%16777215,`${Date.now().toString(36)}${accountSeq.toString(36)}${Math.random().toString(36).slice(2,6)}`}n(newAccountId,"newAccountId"),s(newAccountId,"newAccountId");function beginSqlStatement(t,e,d){if(!t||!e?.flowId||!e.requestId)return;let r=accounts.get(t);if(!r){const o=t.runId;r={accountId:newAccountId(),...typeof o=="string"&&o?{runId:o}:{},ctx:e,seq:0,inFlight:0,statements:0,failed:0,workMs:0,recorded:0,recordedWorkMs:0,suppressed:0,unwritten:0,firstStartedAt:d,lastEndedAt:d,awaitsEnd:!1,ended:!1},accounts.set(t,r);const i=(0,flow_context_1.contextEndOf)(t);if(i&&!i.ended){const a=r;a.awaitsEnd=!0,i.onEnd(()=>endSqlAccount(a))}}return r.inFlight+=1,r.timer&&(clearTimeout(r.timer),r.timer=void 0),r}n(beginSqlStatement,"beginSqlStatement"),s(beginSqlStatement,"beginSqlStatement");function endSqlStatement(t,e){t&&(t.inFlight=Math.max(0,t.inFlight-1),t.statements+=1,t.workMs+=e.durationMs,e.failed&&(t.failed+=1),e.emitted==="written"?(t.recorded+=1,t.recordedWorkMs+=e.durationMs):e.emitted==="suppressed"?t.suppressed+=1:t.unwritten+=1,t.lastEndedAt=Math.max(t.lastEndedAt,Date.now()),writeWhenDue(t))}n(endSqlStatement,"endSqlStatement"),s(endSqlStatement,"endSqlStatement");function abandonSqlStatement(t){t&&(t.inFlight=Math.max(0,t.inFlight-1),writeWhenDue(t))}n(abandonSqlStatement,"abandonSqlStatement"),s(abandonSqlStatement,"abandonSqlStatement");function endSqlAccount(t){t.ended=!0,writeWhenDue(t)}n(endSqlAccount,"endSqlAccount"),s(endSqlAccount,"endSqlAccount");function writeWhenDue(t){if(!(t.inFlight>0||t.statements===0)&&!(t.awaitsEnd&&!t.ended)){if(t.ended&&t.seq===0){writeAccount(t);return}settleLater(t)}}n(writeWhenDue,"writeWhenDue"),s(writeWhenDue,"writeWhenDue");function settleLater(t){t.timer&&clearTimeout(t.timer);const e=setTimeout(()=>writeAccount(t),exports.SQL_ACCOUNT_SETTLE_MS);e.unref?.(),t.timer=e}n(settleLater,"settleLater"),s(settleLater,"settleLater");function writeAccount(t){t.timer&&clearTimeout(t.timer),t.timer=void 0,t.seq+=1;const e=t.suppressed+t.unwritten,d=t.ended?"end":"settled";(0,emit_1.lensEmitOutcome)("lens","info",`SQL account: ${t.statements} statement${t.statements===1?"":"s"}`+(e>0?`, ${e} not on the bus`:", all on the bus"),{kind:exports.SQL_ACCOUNT_KIND,accountId:t.accountId,...t.runId?{runId:t.runId}:{},seq:t.seq,basis:d,statements:t.statements,failed:t.failed,workMs:t.workMs,recorded:t.recorded,recordedWorkMs:t.recordedWorkMs,suppressed:t.suppressed,unwritten:t.unwritten,firstStartedAt:t.firstStartedAt,lastEndedAt:t.lastEndedAt},`lens:sql-account:${emit_1.PROJECT}`,t.ctx,"db",accountGuard)}n(writeAccount,"writeAccount"),s(writeAccount,"writeAccount");
|
package/lib/sql-values.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var g=Object.defineProperty;var a=(t,l)=>g(t,"name",{value:l,configurable:!0});var y=Object.defineProperty,c=a((t,l)=>y(t,"name",{value:l,configurable:!0}),"c");Object.defineProperty(exports,"__esModule",{value:!0}),exports.SQL_VALUES_RUN_MAX_CHARS=void 0,exports.newSqlValuesId=newSqlValuesId,exports.newCacheValuesId=newCacheValuesId,exports.keepSqlValues=keepSqlValues,exports.keepCacheValues=keepCacheValues,exports.pruneSqlValues=pruneSqlValues,exports.flushSqlValuesForTests=flushSqlValuesForTests;const tslib_1=require("tslib"),nodeFs=tslib_1.__importStar(require("node:fs")),node_path_1=require("node:path"),sql_values_1=require("@lensmcp/core/sql-values"),redact_1=require("@lensmcp/core/redact"),ai_store_1=require("./ai-store"),capture_file_1=require("./capture-file"),emit_1=require("./emit"),appendFile=nodeFs.appendFile,appendFileSync=nodeFs.appendFileSync,mkdirSync=nodeFs.mkdirSync,readdirSync=nodeFs.readdirSync,statSync=nodeFs.statSync,unlinkSync=nodeFs.unlinkSync;exports.SQL_VALUES_RUN_MAX_CHARS=64*1024;const MAX_AGE_MS=1440*6e4,MAX_TOTAL_BYTES=200*1024*1024,FLUSH_MS=1e3,PRUNE_EVERY_MS=10*6e4,PRUNE_EVERY_BYTES=20*1024*1024;let seq=0,pending=[],timer,lastPrune=0,appended=0;const made=new Set;let lensDir=c(()=>(0,node_path_1.dirname)(emit_1.EVENT_FILE),"lensDir");function newSqlValuesId(t){if((0,capture_file_1.sqlValuesAsked)(t))return seq=(seq+1)%2147483647,(0,sql_values_1.sqlValuesId)(t,process.pid,seq)}a(newSqlValuesId,"newSqlValuesId"),c(newSqlValuesId,"newSqlValuesId");function newCacheValuesId(t){if((0,capture_file_1.sqlValuesAsked)(t))return seq=(seq+1)%2147483647,(0,sql_values_1.cacheValuesId)(t,process.pid,seq)}a(newCacheValuesId,"newCacheValuesId"),c(newCacheValuesId,"newCacheValuesId");const MIN_VALUE_CHARS=256;function keptParam(t,l){let s;if(t==null)s=String(t);else if(typeof t=="string")s=t;else if(t instanceof Date)s=t.toISOString();else if(t instanceof Uint8Array)s=`<${t.byteLength} bytes>`;else if(typeof t=="bigint")s=t.toString();else try{s=JSON.stringify(typeof t=="object"?(0,redact_1.redactDeep)(t):t)??String(t)}catch{s=String(t)}const n=s.length>l,r=(0,ai_store_1.redactAiText)(n?s.slice(0,l+4096):s);return r.length>l?{text:`${r.slice(0,l-1)}\u2026`,cut:!0}:{text:r,cut:n}}a(keptParam,"keptParam"),c(keptParam,"keptParam");function cells(t,l=0){if(typeof t=="string")return(0,ai_store_1.redactAiText)(t);if(typeof t=="bigint")return t.toString();if(t instanceof Date)return Number.isNaN(t.getTime())?null:t.toISOString();if(t instanceof Uint8Array)return`<${t.byteLength} bytes>`;if(l>8||t===null||typeof t!="object")return t;if(Array.isArray(t))return t.map(n=>cells(n,l+1));const s={};for(const[n,r]of Object.entries(t))s[n]=cells(r,l+1);return s}a(cells,"cells"),c(cells,"cells");function json(t){try{return JSON.stringify(t,function(l,s){const n=this[l];return n instanceof Uint8Array?`<${n.byteLength} bytes>`:typeof s=="bigint"?s.toString():s})??""}catch{return""}}a(json,"json"),c(json,"json");function keepSqlValues(t,l,s,n,r){try{const e={id:t,at:l};let i=exports.SQL_VALUES_RUN_MAX_CHARS-256;if(n?.length){const o=(0,redact_1.redactSqlParams)(s,n),u=Math.max(MIN_VALUE_CHARS,Math.floor(i/o.length)-8),f=[];for(const p of o){const S=keptParam(p,u),h=json(S.text).length+1;if(h>i){e.cut=!0;break}S.cut&&(e.cut=!0),f.push(S.text),i-=h}e.params=f,f.length<o.length&&(e.paramCount=o.length)}if(r?.length){const o=[];for(const u of r){if(json(u).length+1>i){e.cut=!0;break}const f=(0,redact_1.redactDeep)(cells(u)),p=json(f).length+1;if(p>i){e.cut=!0;break}o.push(f),i-=p}o.length&&(e.rows=o),e.rowCount=r.length}pending.push(e),timer??=setTimeout(flush,FLUSH_MS),timer.unref?.()}catch{}}a(keepSqlValues,"keepSqlValues"),c(keepSqlValues,"keepSqlValues");function keptReply(t,l){if(t==null)return;if(t instanceof Uint8Array)return{reply:`<${t.byteLength} bytes>`,size:24,cut:!1};if(typeof t=="number"||typeof t=="boolean")return{reply:t,size:16,cut:!1};if(typeof t=="string"){const n=t.trimStart();if((n.startsWith("{")||n.startsWith("["))&&t.length<=l)try{const e=(0,redact_1.redactDeep)(cells(JSON.parse(t))),i=json(e).length;if(i<=l)return{reply:e,size:i,cut:!1}}catch{}const r=keptParam(t,Math.max(MIN_VALUE_CHARS,l-8));return{reply:r.text,size:json(r.text).length,cut:r.cut}}if(Array.isArray(t)){const n=[];let r=2;for(const e of t){if(json(e).length+1>l-r)return{reply:n,size:r,cut:!0};const i=(0,redact_1.redactDeep)(cells(e));r+=json(i).length+1,n.push(i)}return{reply:n,size:r,cut:!1}}if(json(t).length>l){const n=keptParam(t,Math.max(MIN_VALUE_CHARS,l-8));return{reply:n.text,size:json(n.text).length,cut:!0}}const s=(0,redact_1.redactDeep)(cells(t));return{reply:s,size:json(s).length,cut:!1}}a(keptReply,"keptReply"),c(keptReply,"keptReply");function keepCacheValues(t,l,s,n,r,e){try{const i={id:t,at:l,op:s,key:(0,ai_store_1.redactAiText)(n.slice(0,1024))};let o=exports.SQL_VALUES_RUN_MAX_CHARS-256-i.key.length;if(r?.length){const f=Math.max(MIN_VALUE_CHARS,Math.floor(o/2/r.length)-8),p=[];for(const S of r){const h=keptParam(S,f),d=json(h.text).length+1;if(d>o){i.cut=!0;break}h.cut&&(i.cut=!0),p.push(h.text),o-=d}i.args=p,p.length<r.length&&(i.argCount=r.length)}const u=keptReply(e,o);u&&(i.reply=u.reply,u.cut&&(i.cut=!0)),pending.push(i),timer??=setTimeout(flush,FLUSH_MS),timer.unref?.()}catch{}}a(keepCacheValues,"keepCacheValues"),c(keepCacheValues,"keepCacheValues");function flush(t=!1){if(timer=void 0,!pending.length)return;const l=pending;pending=[];const s=new Map;for(const n of l){const r=(0,sql_values_1.keptValuesFile)(lensDir(),n.id);if(!r)continue;const e=s.get(r)??[];e.push(JSON.stringify(n)),s.set(r,e)}try{for(const[n,r]of s){const e=(0,node_path_1.dirname)(n);made.has(e)||(mkdirSync(e,{recursive:!0,mode:448}),made.add(e));const i=`${r.join(`
|
|
2
2
|
`)}
|
|
3
|
-
`;appended+=i.length,
|
|
3
|
+
`;appended+=i.length,t?appendFileSync(n,i,{mode:384}):appendFile(n,i,{mode:384},()=>{})}}catch{}(Date.now()-lastPrune>=PRUNE_EVERY_MS||appended>=PRUNE_EVERY_BYTES)&&(lastPrune=Date.now(),appended=0,pruneSqlValues((0,node_path_1.join)(lensDir(),sql_values_1.SQL_VALUES_DIR)),pruneSqlValues((0,node_path_1.join)(lensDir(),sql_values_1.CACHE_VALUES_DIR)))}a(flush,"flush"),c(flush,"flush");function pruneSqlValues(t,l=Date.now()){let s;try{s=readdirSync(t).filter(e=>e.endsWith(".jsonl")).map(e=>{const i=statSync((0,node_path_1.join)(t,e));return{file:(0,node_path_1.join)(t,e),mtime:i.mtimeMs,size:i.size}}).sort((e,i)=>e.mtime-i.mtime)}catch{return 0}let n=s.reduce((e,i)=>e+i.size,0),r=0;for(const e of s){if(l-e.mtime<=MAX_AGE_MS&&n<=MAX_TOTAL_BYTES)break;try{unlinkSync(e.file),n-=e.size,r+=1}catch{}}return r}a(pruneSqlValues,"pruneSqlValues"),c(pruneSqlValues,"pruneSqlValues"),process.once("exit",()=>flush(!0));function flushSqlValuesForTests(t){t&&(lensDir=c(()=>t,"lensDir"),made.clear()),timer&&clearTimeout(timer),flush(!0)}a(flushSqlValuesForTests,"flushSqlValuesForTests"),c(flushSqlValuesForTests,"flushSqlValuesForTests");
|
package/lib/tap-ai.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var R=Object.defineProperty;var c=(t,e)=>R(t,"name",{value:e,configurable:!0});var x=Object.defineProperty,d=c((t,e)=>x(t,"name",{value:e,configurable:!0}),"d");Object.defineProperty(exports,"__esModule",{value:!0}),exports.aiCaptureMode=aiCaptureMode,exports.flushAiTapForTests=flushAiTapForTests,exports.resetAiTapForTests=resetAiTapForTests,exports.tapAi=tapAi;const emit_1=require("./emit"),flow_context_1=require("./flow-context"),ai_providers_1=require("./ai-providers"),ai_store_1=require("./ai-store");function aiCaptureMode(t=process.env){const e=(t.LENSMCP_AI_CAPTURE??"").trim().toLowerCase();return e==="content"?"content":e==="metadata"||e==="1"||e==="true"||e==="on"?"metadata":"off"}c(aiCaptureMode,"aiCaptureMode"),d(aiCaptureMode,"aiCaptureMode");const MAX_REQUEST_PARSE_BYTES=2*1024*1024,MAX_RESPONSE_PARSE_BYTES=8*1024*1024,MAX_STREAM_BYTES=8*1024*1024,MAX_STREAM_MS=300*1e3,MAX_ENDPOINT_CHARS=256;function locate(t){try{const e=new URL(typeof t=="string"?t:t instanceof URL?t.href:t.url);return{host:e.hostname,port:e.port,pathname:e.pathname}}catch{return}}c(locate,"locate"),d(locate,"locate");const methodOf=d((t,e)=>{const o=typeof t=="object"&&t!==null&&!(t instanceof URL)?t.method:void 0;return String(e?.method??o??"GET").toUpperCase()},"methodOf"),decode=d(t=>({bytes:t.byteLength,...t.byteLength<=MAX_REQUEST_PARSE_BYTES?{text:Buffer.from(t.buffer,t.byteOffset,t.byteLength).toString("utf8")}:{}}),"decode");function takeRequestBody(t,e){const o=e?.body;if(typeof o=="string")return{text:o,bytes:Buffer.byteLength(o)};if(o instanceof ArrayBuffer)return decode(new Uint8Array(o));if(ArrayBuffer.isView(o))return decode(new Uint8Array(o.buffer,o.byteOffset,o.byteLength));if(typeof Blob<"u"&&o instanceof Blob)return{bytes:o.size,...o.size<=MAX_REQUEST_PARSE_BYTES?{pending:o.text().catch(()=>{})}:{}};if(o==null&&typeof t=="object"&&t!==null&&!(t instanceof URL)){const s=t;if(!s.bodyUsed&&s.body)try{return{pending:s.clone().text().catch(()=>{})}}catch{return{}}}return{}}c(takeRequestBody,"takeRequestBody"),d(takeRequestBody,"takeRequestBody");const sum=d(t=>t.reduce((e,o)=>e+o,0),"sum");function parseJson(t){if(t)try{return JSON.parse(t)}catch{return}}c(parseJson,"parseJson"),d(parseJson,"parseJson");function headerOf(t,e){try{return t?.headers?.get?.(e)??""}catch{return""}}c(headerOf,"headerOf"),d(headerOf,"headerOf");const statusOf=d(t=>typeof t?.status=="number"?t.status:void 0,"statusOf");function failureKind(t,e){const o=t?.name,s=o==="TimeoutError";return{timedOut:s,aborted:!s&&(o==="AbortError"||e?.aborted===!0)}}c(failureKind,"failureKind"),d(failureKind,"failureKind");async function readStream(t,e,o){const s=(0,ai_providers_1.createStreamAccumulator)(e);let i,r=!1;const a=t.body;if(a){const f=a.getReader(),n=new TextDecoder;let p=0;try{for(;;){const{done:m,value:g}=await f.read();if(m)break;if(p+=g.byteLength,s.push(n.decode(g,{stream:!0})),i===void 0&&s.eventCount>0&&(i=Date.now()-o),p>MAX_STREAM_BYTES||Date.now()-o>MAX_STREAM_MS){r=!0,await f.cancel().catch(()=>{});break}}}catch{r=!0}}return{response:s.end(),sse:!0,cut:r,...i!==void 0?{firstEventMs:i}:{}}}c(readStream,"readStream"),d(readStream,"readStream");async function readBody(t){const e={completion:"",toolCalls:[],usage:{}};if(!t.res||!t.clone)return{response:e,sse:!1,cut:!1};try{if(headerOf(t.res,"content-type").includes("text/event-stream"))return await readStream(t.clone,t.target,t.startedAt);const o=Number(headerOf(t.res,"content-length"));if(Number.isFinite(o)&&o>MAX_RESPONSE_PARSE_BYTES)return{response:e,sse:!1,cut:!1};const s=await t.clone.text().catch(()=>{});if(s&&/^\s*(?:event|data):/.test(s)){const i=(0,ai_providers_1.createStreamAccumulator)(t.target);return i.push(s),{response:i.end(),sse:!0,cut:!1}}return{response:(0,ai_providers_1.normalizeResponse)(t.target,parseJson(s)),sse:!1,cut:!1}}catch{return{response:e,sse:!1,cut:!1}}}c(readBody,"readBody"),d(readBody,"readBody");async function capture(t){const e=readBody(t),o=t.request.text??await t.request.pending,s=t.request.bytes??(o?Buffer.byteLength(o):void 0),i=s!==void 0&&s>MAX_REQUEST_PARSE_BYTES,r=(0,ai_providers_1.normalizeRequest)(t.target,i?void 0:parseJson(o)),a=statusOf(t.res),f=await e;let n=f.response;const p=r.stream||f.sse,m=f.firstEventMs,g=f.cut,{aborted:y,timedOut:T}=t.failure!==void 0?failureKind(t.failure,t.signal):{aborted:!1,timedOut:!1};t.failure!==void 0&&(n={...n,error:String(t.failure?.message??t.failure)});const b=y||g,A=Date.now()-t.startedAt,u=n.model??r.model,_=sum(r.messages.map(w=>w.content.length))+(r.system?.length??0);let l,h=!1;if(t.mode==="content"&&t.target.api!=="embeddings"){const w={schemaVersion:1,id:(0,ai_store_1.newAiCallId)(),capturedAt:Date.now(),...t.ctx?.flowId?{flowId:t.ctx.flowId}:{},...t.ctx?.requestId?{requestId:t.ctx.requestId}:{},provider:t.target.provider,api:t.target.api,...u?{model:u}:{},host:t.host,endpoint:t.endpoint,stream:p,...a!==void 0?{status:a}:{},request:{...r.system?{system:r.system}:{},messages:r.messages,...r.tools.length?{tools:r.tools}:{},...Object.keys(r.params).length?{params:r.params}:{}},response:{completion:n.completion,...n.reasoning?{reasoning:n.reasoning}:{},...n.toolCalls.length?{toolCalls:n.toolCalls}:{},...n.finishReason?{finishReason:n.finishReason}:{},usage:n.usage,...n.error?{error:n.error}:{}}},S=(0,ai_store_1.writeAiContent)(w);S&&(l=S.id,h=S.truncated)}const v=a!==void 0&&a>=400||t.failure!==void 0&&!y,C=u??"?";!(0,emit_1.lensEmit)("ai",t.failure!==void 0&&!y?"error":"info",a!==void 0?`ai ${t.target.provider}/${C} ${t.target.api} \u2192 ${a}`:`ai ${t.target.provider}/${C} ${t.target.api} ${y?"aborted":"failed"}`,{name:t.target.provider,kind:"ai-call",provider:t.target.provider,api:t.target.api,...u?{model:u}:{},...r.model&&u&&r.model!==u?{requestedModel:r.model}:{},host:t.host,endpoint:t.endpoint,method:t.method,...a!==void 0?{status:a}:{},stream:p,startedAt:t.startedAt,durationMs:A,...t.ttfbMs!==void 0?{ttfbMs:t.ttfbMs}:{},...m!==void 0?{firstEventMs:m}:{},...Object.keys(n.usage).length?{usage:n.usage}:{},...n.finishReason?{finishReason:n.finishReason}:{},toolCallCount:n.toolCalls.length,sizes:{messageCount:r.messages.length,toolCount:r.tools.length,promptChars:_,completionChars:n.completion.length,...s!==void 0?{requestBytes:s}:{}},...r.inputCount!==void 0?{inputCount:r.inputCount}:{},...n.vectorCount!==void 0?{vectorCount:n.vectorCount}:{},contentCaptured:l!==void 0,...l?{contentRef:l}:{},...h?{truncated:!0}:{},...b?{aborted:!0}:{},...T?{timedOut:!0}:{},...n.error?{error:(0,ai_store_1.redactAiText)(n.error).slice(0,300)}:{}},v?`ai:error:${t.target.provider}:${C}`:`ai:${t.target.provider}:${C}`,t.ctx,"ai")&&l&&(0,ai_store_1.removeAiContent)(l)}c(capture,"capture"),d(capture,"capture");let savedFetch;const pending=new Set;async function flushAiTapForTests(){await Promise.allSettled([...pending])}c(flushAiTapForTests,"flushAiTapForTests"),d(flushAiTapForTests,"flushAiTapForTests");function resetAiTapForTests(){const t=globalThis;savedFetch&&(t.fetch=savedFetch),delete t.__lensmcpAiTap,savedFetch=void 0,pending.clear()}c(resetAiTapForTests,"resetAiTapForTests"),d(resetAiTapForTests,"resetAiTapForTests");function tapAi(){const t=aiCaptureMode();if(t==="off")return;const e=globalThis;if(typeof e.fetch!="function"||e.__lensmcpAiTap)return;e.__lensmcpAiTap=!0;const o=(0,ai_providers_1.parseExtraHosts)(process.env.LENSMCP_AI_HOSTS),s=e.fetch.bind(globalThis);savedFetch=e.fetch,e.fetch=(async(i,r)=>{const a=locate(i),f=methodOf(i,r),n=a&&f==="POST"?(0,ai_providers_1.matchTarget)(a.host,a.port,a.pathname,o):void 0;if(!a||!n)return s(i,r);const p=Date.now(),m=(0,flow_context_1.flowContext)(),g=a.pathname.length>MAX_ENDPOINT_CHARS?`${a.pathname.slice(0,MAX_ENDPOINT_CHARS)}\u2026`:a.pathname,y=takeRequestBody(i,r),T=r?.signal??(typeof i=="object"&&i!==null&&!(i instanceof URL)?i.signal:void 0),b=d(h=>{const v=capture(h).catch(()=>{});pending.add(v),v.finally(()=>pending.delete(v))},"track"),A={mode:t,target:n,host:a.host,endpoint:g,method:f,startedAt:p,ctx:m,signal:T,request:y};let u;try{u=await s(i,r)}catch(h){throw b({...A,failure:h}),h}const _=Date.now()-p;let l;try{l=u.clone()}catch{l=void 0}return b({...A,ttfbMs:_,res:u,...l?{clone:l}:{}}),u})}c(tapAi,"tapAi"),d(tapAi,"tapAi");
|
package/lib/tap-bullmq.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var y=Object.defineProperty;var f=(t,e)=>y(t,"name",{value:e,configurable:!0});var b=Object.defineProperty,a=f((t,e)=>b(t,"name",{value:e,configurable:!0}),"a"),g=Object.defineProperty,i=a((t,e)=>g(t,"name",{value:e,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.bullmqTap=bullmqTap,exports.stopWorkIntake=stopWorkIntake,exports.workIntakeReport=workIntakeReport,exports.resetQueueStatePublishersForTests=resetQueueStatePublishersForTests,exports.resetWorkIntakeForTests=resetWorkIntakeForTests;const active_work_1=require("./active-work"),workerGeneration=new WeakMap,headless_flow_1=require("@lensmcp/core/headless-flow"),emit_1=require("./emit"),flow_context_1=require("./flow-context");function jobFlow(t){const e=t?.opts?.__lensmcpFlow;return e&&typeof e=="object"?e:void 0}f(jobFlow,"jobFlow"),a(jobFlow,"jobFlow"),i(jobFlow,"jobFlow");const jobLegId=i((t,e)=>`job:${t}#${e?.id??"?"}`,"jobLegId");function flowOfJob(t,e){const o=jobFlow(e)?.flowId;if(o)return{flowId:o,own:!1};if((0,headless_flow_1.headlessFlowsEnabled)())return{flowId:(0,headless_flow_1.headlessJobFlowId)(t,e?.id),own:!0}}f(flowOfJob,"flowOfJob"),a(flowOfJob,"flowOfJob"),i(flowOfJob,"flowOfJob");const publishers=new Map,sources=new Map,sourceFor=i(t=>{let e=sources.get(t);return e||sources.set(t,e={}),e},"sourceFor"),usable=i(t=>!!t&&t.closing===void 0,"usable"),currentQueue=i(t=>{const e=sources.get(t),o=e?.app?.deref();return usable(o)?o:e?.own},"currentQueue");function ownConnection(t){if(!t||typeof t!="object")return;const e=t;if(typeof e.duplicate=="function")try{return e.duplicate()}catch{return}return Object.fromEntries(Object.entries(e).filter(([,o])=>typeof o!="function"))}f(ownConnection,"ownConnection"),a(ownConnection,"ownConnection"),i(ownConnection,"ownConnection");function bullmqTap(t){const e=t;if(typeof e?.Queue!="function"||typeof e?.Worker!="function")return!1;tappedQueue=e.Queue;try{tapQueueAdd(e)}catch{}try{tapWorkerEmit(e)}catch{}try{tapWorkerProcess(e)}catch{}try{tapWorkerStamp(e)}catch{}try{tapWorkerIntake(e)}catch{}try{tapWorkerConstruct(e)}catch{}try{installWorkIntakeControl()}catch{}return!0}f(bullmqTap,"bullmqTap"),a(bullmqTap,"bullmqTap"),i(bullmqTap,"bullmqTap");function stampWorker(t){try{if(workerGeneration.has(t))return;workerGeneration.set(t,(0,active_work_1.activeWorkGeneration)()),knownWorkers.add(new WeakRef(t))}catch{}}f(stampWorker,"stampWorker"),a(stampWorker,"stampWorker"),i(stampWorker,"stampWorker");function tapWorkerConstruct(t){const e=t.Worker;if(typeof e!="function"||e.__lensmcpGen)return;const o=new Proxy(e,{construct(r,n,s){const p=Reflect.construct(r,n,s);return stampWorker(p),p}});Object.defineProperty(e,"__lensmcpGen",{value:!0,enumerable:!1}),t.Worker=o}f(tapWorkerConstruct,"tapWorkerConstruct"),a(tapWorkerConstruct,"tapWorkerConstruct"),i(tapWorkerConstruct,"tapWorkerConstruct");function tapWorkerStamp(t){const e=t.Worker?.prototype;if(e)for(const o of["createLockManager","run"]){const r=e[o];if(typeof r!="function"||r.__lensmcpStamp)continue;const n=i(function(...s){return stampWorker(this),r.apply(this,s)},"wrapped");n.__lensmcpStamp=!0,e[o]=n}}f(tapWorkerStamp,"tapWorkerStamp"),a(tapWorkerStamp,"tapWorkerStamp"),i(tapWorkerStamp,"tapWorkerStamp");const knownWorkers=new Set,stoppedWorkers=new WeakSet,intake=new Map,INTAKE_GENERATIONS_KEPT=64;function intakeOf(t){let e=intake.get(t);if(!e){intake.set(t,e={workers:0,running:0,runningAtStop:0,takenAfterStop:0,finishedAfterStop:0});for(const o of intake.keys()){if(intake.size<=INTAKE_GENERATIONS_KEPT)break;intake.delete(o)}}return e}f(intakeOf,"intakeOf"),a(intakeOf,"intakeOf"),i(intakeOf,"intakeOf");function beginIntake(t,e){if(e===void 0)return()=>{};const o=intakeOf(e);return o.running+=1,stoppedWorkers.has(t)&&(o.takenAfterStop+=1),()=>{o.running-=1,o.stoppedAt!==void 0&&(o.finishedAfterStop+=1)}}f(beginIntake,"beginIntake"),a(beginIntake,"beginIntake"),i(beginIntake,"beginIntake");function stopWorkIntake(t){const e={workers:0,running:0,runningAtStop:0,takenAfterStop:0,finishedAfterStop:0},o=Date.now();for(const r of knownWorkers){const n=r.deref();if(!n){knownWorkers.delete(r);continue}const s=workerGeneration.get(n);if(s===void 0||s>=t||stoppedWorkers.has(n))continue;const p=n.pause;if(typeof p!="function")continue;stoppedWorkers.add(n),knownWorkers.delete(r);try{Promise.resolve(p.call(n,!0)).catch(()=>{})}catch{}const u=intakeOf(s);u.stoppedAt===void 0&&(u.stoppedAt=o,u.runningAtStop=u.running,e.running+=u.running,e.runningAtStop+=u.running),u.workers+=1,e.workers+=1}return e}f(stopWorkIntake,"stopWorkIntake"),a(stopWorkIntake,"stopWorkIntake"),i(stopWorkIntake,"stopWorkIntake");function workIntakeReport(t){const e=intake.get(t);if(!(!e||e.stoppedAt===void 0))return{workers:e.workers,running:e.running,runningAtStop:e.runningAtStop,takenAfterStop:e.takenAfterStop,finishedAfterStop:e.finishedAfterStop}}f(workIntakeReport,"workIntakeReport"),a(workIntakeReport,"workIntakeReport"),i(workIntakeReport,"workIntakeReport");function tapWorkerIntake(t){const e=t.Worker?.prototype;if(!e)return;const o=e.moveToActive;if(typeof o=="function"&&!o.__lensmcpIntake){const n=i(function(...s){return stoppedWorkers.has(this)?Promise.resolve(void 0):o.apply(this,s)},"wrapped");n.__lensmcpIntake=!0,e.moveToActive=n}const r=e.resume;if(typeof r=="function"&&!r.__lensmcpIntake){const n=i(function(...s){if(!stoppedWorkers.has(this))return r.apply(this,s)},"wrapped");n.__lensmcpIntake=!0,e.resume=n}}f(tapWorkerIntake,"tapWorkerIntake"),a(tapWorkerIntake,"tapWorkerIntake"),i(tapWorkerIntake,"tapWorkerIntake");function installWorkIntakeControl(){const t=globalThis;t.__lensmcpStopWorkIntake=stopWorkIntake,t.__lensmcpWorkIntakeReport=workIntakeReport}f(installWorkIntakeControl,"installWorkIntakeControl"),a(installWorkIntakeControl,"installWorkIntakeControl"),i(installWorkIntakeControl,"installWorkIntakeControl");function tapWorkerProcess(t){const e=t.Worker?.prototype,o=e?.callProcessJob;if(!e||typeof o!="function"||o.__lensmcp)return;const r=i(async function(n,...s){const p=workerGeneration.get(this),u=(0,active_work_1.beginActiveWork)(p),l=beginIntake(this,p),c=i(()=>{u(),l()},"endWork"),d=String(this?.name??n?.queueName??"queue"),w=flowOfJob(d,n);if(!w)return o.call(this,n,...s).finally(c);const h=jobLegId(d,n),k=Date.now(),I={flowId:w.flowId,requestId:h};if(w.own){const m=`job:${d}/${n?.name??"job"}`;(0,emit_1.lensEmit)("queue","info",`job ${n?.name??""}#${n?.id??"?"} \xB7 ${d}`,{queue:d,kind:"flow-origin",job:n?.name,jobId:n?.id,originNodeId:m},`queue-origin:${d}`,{...I,originType:"job",originNodeId:m})}return(0,flow_context_1.runInFlowContext)(I,async()=>{try{const m=await o.call(this,n,...s);return(0,emit_1.lensEmit)("queue","info",`process ${n?.name}#${n?.id} (${Date.now()-k}ms)`,{queue:d,kind:"queue-process",job:n?.name,jobId:n?.id,startedAt:k,durationMs:Date.now()-k,status:"ok"},`queue:${d}`,I),m}catch(m){throw(0,emit_1.lensEmit)("queue","error",`process ${n?.name}#${n?.id} failed (${Date.now()-k}ms)`,{queue:d,kind:"queue-process",job:n?.name,jobId:n?.id,startedAt:k,durationMs:Date.now()-k,status:"error",error:String(m?.message??m)},`queue:${d}`,I),m}finally{c()}})},"wrapped");r.__lensmcp=!0,e.callProcessJob=r}f(tapWorkerProcess,"tapWorkerProcess"),a(tapWorkerProcess,"tapWorkerProcess"),i(tapWorkerProcess,"tapWorkerProcess");function tapQueueAdd(t){const e=t.Queue?.prototype,o=e?.add;if(!e||typeof o!="function"||o.__lensmcp)return;const r=i(async function(n,...s){const p=Date.now(),u=(0,flow_context_1.flowContext)();if(u?.flowId){const c=s[1]??{};s[1]={...c,__lensmcpFlow:{flowId:u.flowId,...u.requestId?{originRequestId:u.requestId}:{}}}}const l=await o.call(this,n,...s);try{const c=String(this?.name??"queue"),d=s[0];let w;try{const k=JSON.stringify(d);w=k&&k!=="undefined"?k.length>300?k.slice(0,299)+"\u2026":k:void 0}catch{}(0,emit_1.lensEmit)("queue","info",`enqueued ${n}#${l?.id} \u2192 ${c}`,{queue:c,kind:"queue-enqueued",job:n,jobId:l?.id,...w?{data:w}:{},startedAt:p,durationMs:Date.now()-p},`queue:${c}`,u);const h=sourceFor(c);h.app?.deref()!==this&&(h.app=new WeakRef(this)),ensureStatePublisher(c)}catch{}return l},"wrapped");r.__lensmcp=!0,e.add=r}f(tapQueueAdd,"tapQueueAdd"),a(tapQueueAdd,"tapQueueAdd"),i(tapQueueAdd,"tapQueueAdd");function tapWorkerEmit(t){const e=t.Worker?.prototype,o=e?.emit;if(!e||typeof o!="function"||o.__lensmcp)return;const r=i(function(n,...s){try{observeWorkerEvent(this,String(n),s)}catch{}return o.call(this,n,...s)},"wrapped");r.__lensmcp=!0,e.emit=r}f(tapWorkerEmit,"tapWorkerEmit"),a(tapWorkerEmit,"tapWorkerEmit"),i(tapWorkerEmit,"tapWorkerEmit");function observeWorkerEvent(t,e,o){if(e!=="active"&&e!=="completed"&&e!=="failed")return;const r=String(t.name??"queue"),n=o[0],s=flowOfJob(r,n),p=s?{flowId:s.flowId,requestId:jobLegId(r,n)}:void 0;if(e==="active")(0,emit_1.lensEmit)("queue","info",`processing ${n?.name}#${n?.id}`,{queue:r,kind:"queue-active",jobId:n?.id},`queue:${r}`,p);else if(e==="completed"){let u;try{const l=n?.returnvalue??o[1],c=JSON.stringify(l);u=c&&c!=="undefined"?c.length>160?c.slice(0,159)+"\u2026":c:void 0}catch{}(0,emit_1.lensEmit)("queue","info",`completed ${n?.name}#${n?.id}`,{queue:r,kind:"queue-completed",jobId:n?.id,...u?{returned:u}:{}},`queue:${r}`,p)}else{const u=o[1];(0,emit_1.lensEmit)("queue","error",`job ${n?.id} failed: ${u?.message}`,{queue:r,kind:"queue-failed",jobId:n?.id,error:String(u?.message??u)},`queue:${r}`,p)}if(!currentQueue(r))try{const u=t.opts,l=ownConnection(u?.connection);if(l){const c=snapshotQueueClass();c&&(sourceFor(r).own=new c(r,{connection:l}))}}catch{}ensureStatePublisher(r)}f(observeWorkerEvent,"observeWorkerEvent"),a(observeWorkerEvent,"observeWorkerEvent"),i(observeWorkerEvent,"observeWorkerEvent");let tappedQueue;function snapshotQueueClass(){if(tappedQueue)return tappedQueue;try{return require("bullmq").Queue}catch{return}}f(snapshotQueueClass,"snapshotQueueClass"),a(snapshotQueueClass,"snapshotQueueClass"),i(snapshotQueueClass,"snapshotQueueClass");function ensureStatePublisher(t){if(publishers.has(t))return;let e="";const o=setInterval(()=>{(async()=>{try{const r=currentQueue(t);if(!r)return;const n=await r.getJobCounts(),s=[];for(const l of["active","waiting","failed","completed","delayed"])for(const c of await r.getJobs([l],0,7)){const d=c?.data?.to;s.push({id:String(c.id),name:c.name,state:l,timestamp:c.timestamp??0,...typeof d=="string"?{to:d}:{}})}s.sort((l,c)=>Number(c.timestamp)-Number(l.timestamp));const p=s.slice(0,8),u=JSON.stringify([n,p.map(l=>`${l.id}${l.state}`)]);if(u===e)return;e=u,(0,emit_1.lensEmit)("queue","info",`queue state: ${n.active??0} active \xB7 ${n.waiting??0} waiting \xB7 ${n.failed??0} failed`,{queue:t,kind:"queue-state",counts:n,recent:p},`queue:${t}`)}catch{}})()},2e3);o.unref?.(),publishers.set(t,o)}f(ensureStatePublisher,"ensureStatePublisher"),a(ensureStatePublisher,"ensureStatePublisher"),i(ensureStatePublisher,"ensureStatePublisher");function resetQueueStatePublishersForTests(){for(const t of publishers.values())clearInterval(t);publishers.clear(),sources.clear()}f(resetQueueStatePublishersForTests,"resetQueueStatePublishersForTests"),a(resetQueueStatePublishersForTests,"resetQueueStatePublishersForTests"),i(resetQueueStatePublishersForTests,"resetQueueStatePublishersForTests");function resetWorkIntakeForTests(){knownWorkers.clear(),intake.clear()}f(resetWorkIntakeForTests,"resetWorkIntakeForTests"),a(resetWorkIntakeForTests,"resetWorkIntakeForTests"),i(resetWorkIntakeForTests,"resetWorkIntakeForTests");
|
|
1
|
+
"use strict";var b=Object.defineProperty;var a=(t,e)=>b(t,"name",{value:e,configurable:!0});var g=Object.defineProperty,i=a((t,e)=>g(t,"name",{value:e,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.bullmqTap=bullmqTap,exports.stopWorkIntake=stopWorkIntake,exports.workIntakeReport=workIntakeReport,exports.resetQueueStatePublishersForTests=resetQueueStatePublishersForTests,exports.resetWorkIntakeForTests=resetWorkIntakeForTests;const active_work_1=require("./active-work"),workerGeneration=new WeakMap,headless_flow_1=require("@lensmcp/core/headless-flow"),emit_1=require("./emit"),flow_context_1=require("./flow-context");function jobFlow(t){const e=t?.opts?.__lensmcpFlow;return e&&typeof e=="object"?e:void 0}a(jobFlow,"jobFlow"),i(jobFlow,"jobFlow");const jobLegId=i((t,e)=>`job:${t}#${e?.id??"?"}`,"jobLegId");function flowOfJob(t,e){const o=jobFlow(e)?.flowId;if(o)return{flowId:o,own:!1};if((0,headless_flow_1.headlessFlowsEnabled)())return{flowId:(0,headless_flow_1.headlessJobFlowId)(t,e?.id),own:!0}}a(flowOfJob,"flowOfJob"),i(flowOfJob,"flowOfJob");const publishers=new Map,sources=new Map,sourceFor=i(t=>{let e=sources.get(t);return e||sources.set(t,e={}),e},"sourceFor"),usable=i(t=>!!t&&t.closing===void 0,"usable"),currentQueue=i(t=>{const e=sources.get(t),o=e?.app?.deref();return usable(o)?o:e?.own},"currentQueue");function ownConnection(t){if(!t||typeof t!="object")return;const e=t;if(typeof e.duplicate=="function")try{return e.duplicate()}catch{return}return Object.fromEntries(Object.entries(e).filter(([,o])=>typeof o!="function"))}a(ownConnection,"ownConnection"),i(ownConnection,"ownConnection");function bullmqTap(t){const e=t;if(typeof e?.Queue!="function"||typeof e?.Worker!="function")return!1;tappedQueue=e.Queue;try{tapQueueAdd(e)}catch{}try{tapWorkerEmit(e)}catch{}try{tapWorkerProcess(e)}catch{}try{tapWorkerStamp(e)}catch{}try{tapWorkerIntake(e)}catch{}try{tapWorkerConstruct(e)}catch{}try{installWorkIntakeControl()}catch{}return!0}a(bullmqTap,"bullmqTap"),i(bullmqTap,"bullmqTap");function stampWorker(t){try{if(workerGeneration.has(t))return;workerGeneration.set(t,(0,active_work_1.activeWorkGeneration)()),knownWorkers.add(new WeakRef(t))}catch{}}a(stampWorker,"stampWorker"),i(stampWorker,"stampWorker");function tapWorkerConstruct(t){const e=t.Worker;if(typeof e!="function"||e.__lensmcpGen)return;const o=new Proxy(e,{construct(r,n,s){const f=Reflect.construct(r,n,s);return stampWorker(f),f}});Object.defineProperty(e,"__lensmcpGen",{value:!0,enumerable:!1}),t.Worker=o}a(tapWorkerConstruct,"tapWorkerConstruct"),i(tapWorkerConstruct,"tapWorkerConstruct");function tapWorkerStamp(t){const e=t.Worker?.prototype;if(e)for(const o of["createLockManager","run"]){const r=e[o];if(typeof r!="function"||r.__lensmcpStamp)continue;const n=i(function(...s){return stampWorker(this),r.apply(this,s)},"wrapped");n.__lensmcpStamp=!0,e[o]=n}}a(tapWorkerStamp,"tapWorkerStamp"),i(tapWorkerStamp,"tapWorkerStamp");const knownWorkers=new Set,stoppedWorkers=new WeakSet,intake=new Map,INTAKE_GENERATIONS_KEPT=64;function intakeOf(t){let e=intake.get(t);if(!e){intake.set(t,e={workers:0,running:0,runningAtStop:0,takenAfterStop:0,finishedAfterStop:0});for(const o of intake.keys()){if(intake.size<=INTAKE_GENERATIONS_KEPT)break;intake.delete(o)}}return e}a(intakeOf,"intakeOf"),i(intakeOf,"intakeOf");function beginIntake(t,e){if(e===void 0)return()=>{};const o=intakeOf(e);return o.running+=1,stoppedWorkers.has(t)&&(o.takenAfterStop+=1),()=>{o.running-=1,o.stoppedAt!==void 0&&(o.finishedAfterStop+=1)}}a(beginIntake,"beginIntake"),i(beginIntake,"beginIntake");function stopWorkIntake(t){const e={workers:0,running:0,runningAtStop:0,takenAfterStop:0,finishedAfterStop:0},o=Date.now();for(const r of knownWorkers){const n=r.deref();if(!n){knownWorkers.delete(r);continue}const s=workerGeneration.get(n);if(s===void 0||s>=t||stoppedWorkers.has(n))continue;const f=n.pause;if(typeof f!="function")continue;stoppedWorkers.add(n),knownWorkers.delete(r);try{Promise.resolve(f.call(n,!0)).catch(()=>{})}catch{}const u=intakeOf(s);u.stoppedAt===void 0&&(u.stoppedAt=o,u.runningAtStop=u.running,e.running+=u.running,e.runningAtStop+=u.running),u.workers+=1,e.workers+=1}return e}a(stopWorkIntake,"stopWorkIntake"),i(stopWorkIntake,"stopWorkIntake");function workIntakeReport(t){const e=intake.get(t);if(!(!e||e.stoppedAt===void 0))return{workers:e.workers,running:e.running,runningAtStop:e.runningAtStop,takenAfterStop:e.takenAfterStop,finishedAfterStop:e.finishedAfterStop}}a(workIntakeReport,"workIntakeReport"),i(workIntakeReport,"workIntakeReport");function tapWorkerIntake(t){const e=t.Worker?.prototype;if(!e)return;const o=e.moveToActive;if(typeof o=="function"&&!o.__lensmcpIntake){const n=i(function(...s){return stoppedWorkers.has(this)?Promise.resolve(void 0):o.apply(this,s)},"wrapped");n.__lensmcpIntake=!0,e.moveToActive=n}const r=e.resume;if(typeof r=="function"&&!r.__lensmcpIntake){const n=i(function(...s){if(!stoppedWorkers.has(this))return r.apply(this,s)},"wrapped");n.__lensmcpIntake=!0,e.resume=n}}a(tapWorkerIntake,"tapWorkerIntake"),i(tapWorkerIntake,"tapWorkerIntake");function installWorkIntakeControl(){const t=globalThis;t.__lensmcpStopWorkIntake=stopWorkIntake,t.__lensmcpWorkIntakeReport=workIntakeReport}a(installWorkIntakeControl,"installWorkIntakeControl"),i(installWorkIntakeControl,"installWorkIntakeControl");function tapWorkerProcess(t){const e=t.Worker?.prototype,o=e?.callProcessJob;if(!e||typeof o!="function"||o.__lensmcp)return;const r=i(async function(n,...s){const f=workerGeneration.get(this),u=(0,active_work_1.beginActiveWork)(f),p=beginIntake(this,f),c=i(()=>{u(),p()},"endWork"),l=String(this?.name??n?.queueName??"queue"),m=flowOfJob(l,n);if(!m)return o.call(this,n,...s).finally(c);const w=jobLegId(l,n),d=Date.now(),h={flowId:m.flowId,requestId:w};if(m.own){const k=`job:${l}/${n?.name??"job"}`;(0,emit_1.lensEmit)("queue","info",`job ${n?.name??""}#${n?.id??"?"} \xB7 ${l}`,{queue:l,kind:"flow-origin",job:n?.name,jobId:n?.id,originNodeId:k},`queue-origin:${l}`,{...h,originType:"job",originNodeId:k})}return(0,flow_context_1.runInFlowContext)(h,async()=>{try{const k=await o.call(this,n,...s);return(0,emit_1.lensEmit)("queue","info",`process ${n?.name}#${n?.id} (${Date.now()-d}ms)`,{queue:l,kind:"queue-process",job:n?.name,jobId:n?.id,startedAt:d,durationMs:Date.now()-d,status:"ok"},`queue:${l}`,h),k}catch(k){throw(0,emit_1.lensEmit)("queue","error",`process ${n?.name}#${n?.id} failed (${Date.now()-d}ms)`,{queue:l,kind:"queue-process",job:n?.name,jobId:n?.id,startedAt:d,durationMs:Date.now()-d,status:"error",error:String(k?.message??k)},`queue:${l}`,h),k}finally{c()}})},"wrapped");r.__lensmcp=!0,e.callProcessJob=r}a(tapWorkerProcess,"tapWorkerProcess"),i(tapWorkerProcess,"tapWorkerProcess");function tapQueueAdd(t){const e=t.Queue?.prototype,o=e?.add;if(!e||typeof o!="function"||o.__lensmcp)return;const r=i(async function(n,...s){const f=Date.now(),u=(0,flow_context_1.flowContext)();if(u?.flowId){const c=s[1]??{};s[1]={...c,__lensmcpFlow:{flowId:u.flowId,...u.requestId?{originRequestId:u.requestId}:{}}}}const p=await o.call(this,n,...s);try{const c=String(this?.name??"queue"),l=s[0];let m;try{const d=JSON.stringify(l);m=d&&d!=="undefined"?d.length>300?d.slice(0,299)+"\u2026":d:void 0}catch{}(0,emit_1.lensEmit)("queue","info",`enqueued ${n}#${p?.id} \u2192 ${c}`,{queue:c,kind:"queue-enqueued",job:n,jobId:p?.id,...m?{data:m}:{},startedAt:f,durationMs:Date.now()-f},`queue:${c}`,u);const w=sourceFor(c);w.app?.deref()!==this&&(w.app=new WeakRef(this)),ensureStatePublisher(c)}catch{}return p},"wrapped");r.__lensmcp=!0,e.add=r}a(tapQueueAdd,"tapQueueAdd"),i(tapQueueAdd,"tapQueueAdd");function tapWorkerEmit(t){const e=t.Worker?.prototype,o=e?.emit;if(!e||typeof o!="function"||o.__lensmcp)return;const r=i(function(n,...s){try{observeWorkerEvent(this,String(n),s)}catch{}return o.call(this,n,...s)},"wrapped");r.__lensmcp=!0,e.emit=r}a(tapWorkerEmit,"tapWorkerEmit"),i(tapWorkerEmit,"tapWorkerEmit");function observeWorkerEvent(t,e,o){if(e!=="active"&&e!=="completed"&&e!=="failed")return;const r=String(t.name??"queue"),n=o[0],s=flowOfJob(r,n),f=s?{flowId:s.flowId,requestId:jobLegId(r,n)}:void 0;if(e==="active")(0,emit_1.lensEmit)("queue","info",`processing ${n?.name}#${n?.id}`,{queue:r,kind:"queue-active",jobId:n?.id},`queue:${r}`,f);else if(e==="completed"){let u;try{const p=n?.returnvalue??o[1],c=JSON.stringify(p);u=c&&c!=="undefined"?c.length>160?c.slice(0,159)+"\u2026":c:void 0}catch{}(0,emit_1.lensEmit)("queue","info",`completed ${n?.name}#${n?.id}`,{queue:r,kind:"queue-completed",jobId:n?.id,...u?{returned:u}:{}},`queue:${r}`,f)}else{const u=o[1];(0,emit_1.lensEmit)("queue","error",`job ${n?.id} failed: ${u?.message}`,{queue:r,kind:"queue-failed",jobId:n?.id,error:String(u?.message??u)},`queue:${r}`,f)}if(!currentQueue(r))try{const u=t.opts,p=ownConnection(u?.connection);if(p){const c=snapshotQueueClass();c&&(sourceFor(r).own=new c(r,{connection:p}))}}catch{}ensureStatePublisher(r)}a(observeWorkerEvent,"observeWorkerEvent"),i(observeWorkerEvent,"observeWorkerEvent");let tappedQueue;function snapshotQueueClass(){if(tappedQueue)return tappedQueue;try{return require("bullmq").Queue}catch{return}}a(snapshotQueueClass,"snapshotQueueClass"),i(snapshotQueueClass,"snapshotQueueClass");function ensureStatePublisher(t){if(publishers.has(t))return;let e="";const o=setInterval(()=>{(async()=>{try{const r=currentQueue(t);if(!r)return;const n=await r.getJobCounts(),s=[];for(const p of["active","waiting","failed","completed","delayed"])for(const c of await r.getJobs([p],0,7)){const l=c?.data?.to;s.push({id:String(c.id),name:c.name,state:p,timestamp:c.timestamp??0,...typeof l=="string"?{to:l}:{}})}s.sort((p,c)=>Number(c.timestamp)-Number(p.timestamp));const f=s.slice(0,8),u=JSON.stringify([n,f.map(p=>`${p.id}${p.state}`)]);if(u===e)return;e=u,(0,emit_1.lensEmit)("queue","info",`queue state: ${n.active??0} active \xB7 ${n.waiting??0} waiting \xB7 ${n.failed??0} failed`,{queue:t,kind:"queue-state",counts:n,recent:f},`queue:${t}`)}catch{}})()},2e3);o.unref?.(),publishers.set(t,o)}a(ensureStatePublisher,"ensureStatePublisher"),i(ensureStatePublisher,"ensureStatePublisher");function resetQueueStatePublishersForTests(){for(const t of publishers.values())clearInterval(t);publishers.clear(),sources.clear()}a(resetQueueStatePublishersForTests,"resetQueueStatePublishersForTests"),i(resetQueueStatePublishersForTests,"resetQueueStatePublishersForTests");function resetWorkIntakeForTests(){knownWorkers.clear(),intake.clear()}a(resetWorkIntakeForTests,"resetWorkIntakeForTests"),i(resetWorkIntakeForTests,"resetWorkIntakeForTests");
|
package/lib/tap-egress.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var k=Object.defineProperty;var E=(e,t)=>k(e,"name",{value:t,configurable:!0});var P=Object.defineProperty,x=E((e,t)=>P(e,"name",{value:t,configurable:!0}),"x"),H=Object.defineProperty,c=x((e,t)=>H(e,"name",{value:t,configurable:!0}),"c");Object.defineProperty(exports,"__esModule",{value:!0}),exports.flushEgressCaptureForTests=flushEgressCaptureForTests,exports.tapEgress=tapEgress,exports.resetEgressTapForTests=resetEgressTapForTests;const redact_1=require("@lensmcp/core/redact"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),ai_providers_1=require("./ai-providers"),http_capture_1=require("./http-capture"),http_store_1=require("./http-store"),capture_file_1=require("./capture-file"),tap_ai_1=require("./tap-ai"),INTERNAL=[/\.local$/i,/\.internal$/i,/^localhost$/i,/^127\./,/^\[?::1\]?$/,/^0\.0\.0\.0$/,/^10\./,/^192\.168\./,/^172\.(1[6-9]|2\d|3[01])\./,/^169\.254\./,/^\[?[fF][cCdD][0-9a-fA-F]{2}:/,/^\[?[fF][eE]80:/],isInternal=c(e=>e===""||INTERNAL.some(t=>t.test(e)),"isInternal"),CAPTURE_QUERY=process.env.LENSMCP_EGRESS_QUERY==="1",MAX_PATH_CHARS=256,clipPath=c(e=>e.length>MAX_PATH_CHARS?`${e.slice(0,MAX_PATH_CHARS)}\u2026`:e,"clipPath");function capturePath(e,t){const r=e||"/";return!CAPTURE_QUERY||t.length<=1?clipPath(r):(0,redact_1.redactUrl)(`${r}${t}`)}E(capturePath,"capturePath"),x(capturePath,"capturePath"),c(capturePath,"capturePath");const fingerprintFor=c((e,t)=>t?`external:error:${e}`:`external:${e}`,"fingerprintFor"),pendingExchanges=new Set;async function flushEgressCaptureForTests(){await Promise.allSettled([...pendingExchanges])}E(flushEgressCaptureForTests,"flushEgressCaptureForTests"),x(flushEgressCaptureForTests,"flushEgressCaptureForTests"),c(flushEgressCaptureForTests,"flushEgressCaptureForTests");async function finishExchange(e){const t=[],r=[],u=await(0,http_capture_1.requestPart)(e.request,e.url.search,e.mode,!!e.aiOpaque,r,t),a=e.reading?await e.reading.catch(()=>{}):void 0,{headers:d,redacted:s}=(0,http_store_1.redactHeaders)(e.responseHeaders??[]);t.push(...s);const o=typeof e.status=="number"?e.status:void 0,m={schemaVersion:1,id:e.id,capturedAt:Date.now(),side:"egress",service:emit_1.PROJECT,...e.ctx?.flowId?{flowId:e.ctx.flowId}:{},...e.ctx?.requestId?{requestId:e.ctx.requestId}:{},method:e.method,url:`${e.url.protocol}//${e.url.host}${e.path}`,host:e.url.hostname,path:e.path,...o!==void 0?{status:o}:{},...e.statusText?{statusText:e.statusText}:{},...e.error?{error:e.error}:{},startedAt:e.startedAt,...e.ttfbMs!==void 0?{ttfbMs:e.ttfbMs}:{},durationMs:(a?.endedAt??Date.now())-e.startedAt,capture:e.mode==="bodies"?"bodies":"headers",request:u,response:{headers:d,...a?.body?{body:a.body}:{},...a?.stream?{stream:a.stream}:{}},redacted:{headers:[...new Set(t)],bodyFields:[...r.map(i=>`request.${i}`),...e.responseFields.map(i=>`response.${i}`)]},...e.ai?{ai:{provider:e.ai}}:{}};(0,http_store_1.writeHttpExchange)(m)}E(finishExchange,"finishExchange"),x(finishExchange,"finishExchange"),c(finishExchange,"finishExchange");function trackExchange(e){const t=(typeof e=="function"?new Promise(r=>setImmediate(r)).then(()=>finishExchange(e())):finishExchange(e)).catch(()=>{});pendingExchanges.add(t),t.finally(()=>pendingExchanges.delete(t))}E(trackExchange,"trackExchange"),x(trackExchange,"trackExchange"),c(trackExchange,"trackExchange");function tapEgress(){tapFetch(),tapHttpModule("http"),tapHttpModule("https")}E(tapEgress,"tapEgress"),x(tapEgress,"tapEgress"),c(tapEgress,"tapEgress");let savedFetch;const httpOriginals=new Map;function resetEgressTapForTests(){const e=globalThis;savedFetch&&(e.fetch=savedFetch),delete e.__lensmcpFetchTap,restoreHttp("http"),restoreHttp("https"),savedFetch=void 0}E(resetEgressTapForTests,"resetEgressTapForTests"),x(resetEgressTapForTests,"resetEgressTapForTests"),c(resetEgressTapForTests,"resetEgressTapForTests");function restoreHttp(e){const t=httpOriginals.get(e);if(!t)return;const r=require(`node:${e}`);r.request=t.request,r.get=t.get,httpOriginals.delete(e)}E(restoreHttp,"restoreHttp"),x(restoreHttp,"restoreHttp"),c(restoreHttp,"restoreHttp");function tapFetch(){const e=globalThis;if(typeof e.fetch!="function"||e.__lensmcpFetchTap)return;e.__lensmcpFetchTap=!0;const t=e.fetch.bind(globalThis);savedFetch=e.fetch;const r=(0,http_store_1.httpCaptureMode)(),u=(0,ai_providers_1.parseExtraHosts)(process.env.LENSMCP_AI_HOSTS);e.fetch=(async(a,d)=>{let s="",o="/",m=!1,i;try{const h=new URL(typeof a=="string"?a:a instanceof URL?a.href:a.url);i=h,s=h.hostname,m=h.search.length>1,o=capturePath(h.pathname,h.search)}catch{}if(isInternal(s))return t(a,d);const l=Date.now(),f=(0,flow_context_1.flowContext)(),n=(0,flow_context_1.liveFlowContext)();n&&(n.externalCallCount=(n.externalCallCount??0)+1);const T=typeof a=="object"&&a!==null&&!(a instanceof URL)?a.method:void 0,p=String(d?.method??T??"GET").toUpperCase(),w=r!=="off"&&i?(0,http_store_1.newExchangeId)():void 0,b=w?(0,http_capture_1.takeRequest)(a,d,r==="bodies"):void 0,C=w&&i&&p==="POST"?(0,ai_providers_1.matchTarget)(s,i.port,i.pathname,u)?.provider:void 0,v=!!C&&(0,tap_ai_1.aiCaptureMode)()!=="content"&&!(0,capture_file_1.aiBodiesAsked)(),$=c(h=>({id:w,mode:r,method:p,url:i,path:i.pathname.length>256?`${i.pathname.slice(0,256)}\u2026`:i.pathname,startedAt:l,ctx:f,request:b,...C?{ai:C}:{},...v?{aiOpaque:v}:{},responseFields:[],...h}),"job");try{const h=await t(a,d),_=Date.now()-l,F=h.status>=500,g=[];let y;if(w&&r==="bodies")try{y=(0,http_capture_1.readResponse)(h,h.clone(),l,{ai:v,paths:g})}catch{y=void 0}const q=(0,emit_1.lensEmit)("external","info",`egress ${p} ${s} \u2192 ${h.status}`,{name:s,kind:"egress",method:p,host:s,path:o,status:h.status,...m?{hasQuery:!0}:{},startedAt:l,durationMs:_,...w?{exchangeId:w}:{}},fingerprintFor(s,F),f);if(w&&q){const M={status:h.status,...h.statusText?{statusText:h.statusText}:{},responseHeaders:(0,http_capture_1.headerPairs)(h.headers)};trackExchange($({...M,ttfbMs:_,responseFields:g,...y?{reading:y}:{}}))}return h}catch(h){const _=String(h?.message??h),F=(0,emit_1.lensEmit)("external","error",`egress ${p} ${s} failed`,{name:s,kind:"egress",method:p,host:s,path:o,...m?{hasQuery:!0}:{},error:_,startedAt:l,durationMs:Date.now()-l,...w?{exchangeId:w}:{}},fingerprintFor(s,!0),f);throw w&&F&&trackExchange($({error:_})),h}})}E(tapFetch,"tapFetch"),x(tapFetch,"tapFetch"),c(tapFetch,"tapFetch");function tapHttpModule(e){const t=require(`node:${e}`),r=t.request;if(typeof r!="function"||r.__lensmcp)return;httpOriginals.set(e,{request:r,get:t.get});const u=(0,http_store_1.httpCaptureMode)(),a=(0,ai_providers_1.parseExtraHosts)(process.env.LENSMCP_AI_HOSTS),d=c(function(...s){const o=r.apply(this,s);try{observe(e,s,o,u,a)}catch{}return o},"wrapped");d.__lensmcp=!0,t.request=d,typeof t.get=="function"&&(t.get=function(...s){const o=d.apply(this,s);return o.end(),o})}E(tapHttpModule,"tapHttpModule"),x(tapHttpModule,"tapHttpModule"),c(tapHttpModule,"tapHttpModule");const headerOf=c((e,t)=>{const r=e?.[t];return Array.isArray(r)?r.join(", "):r??""},"headerOf");function teeRequest(e,t,r){const u=t?new http_capture_1.WrittenBody(!r):void 0,a=c(()=>{try{return e.getHeaders?.()}catch{return}},"sentHeaders");let d,s=!1;const o=e.write;u&&typeof o=="function"&&(e.write=function(i,...l){try{s||u.take(i,l[0])}catch{}return o.call(this,i,...l)});const m=e.end;return e.end=function(i,...l){try{s||(s=!0,u?.take(i,l[0]),d=a())}catch{}return m.call(this,i,...l)},()=>(0,http_capture_1.writtenRequest)(d??a(),u)}E(teeRequest,"teeRequest"),x(teeRequest,"teeRequest"),c(teeRequest,"teeRequest");function teeResponse(e,t,r){let u=!1;const a=c(o=>{if(u)return;u=!0,clearTimeout(d);const m=Date.now();r(()=>t.size?t.finish(o,m):{endedAt:m})},"finish"),d=setTimeout(()=>a(!0),http_capture_1.MAX_STREAM_MS);d.unref?.();const s=e.emit;e.emit=function(o,...m){try{return s.call(this,o,...m)}finally{try{if(o==="data"){const i=u?void 0:(0,http_capture_1.chunkBytes)(m[0],e.readableEncoding);i&&!t.push(i)&&a(!1)}else o==="end"?a(!1):(o==="aborted"||o==="error"||o==="close")&&a(!0)}catch{}}}}E(teeResponse,"teeResponse"),x(teeResponse,"teeResponse"),c(teeResponse,"teeResponse");function observe(e,t,r,u,a){const d=parseTarget(t,e),{host:s,method:o,path:m,hasQuery:i}=d;if(isInternal(s))return;const l=Date.now(),f=(0,flow_context_1.flowContext)(),n=(0,flow_context_1.liveFlowContext)();n&&(n.externalCallCount=(n.externalCallCount??0)+1);const T=u!=="off"?targetUrl(d):void 0,p=T?(0,http_store_1.newExchangeId)():void 0,w=p&&T&&o==="POST"?(0,ai_providers_1.matchTarget)(s,T.port,T.pathname,a)?.provider:void 0,b=!!w&&(0,tap_ai_1.aiCaptureMode)()!=="content"&&!(0,capture_file_1.aiBodiesAsked)(),C=p?teeRequest(r,u==="bodies",b):void 0,v=c(g=>({id:p,mode:u,method:o,url:T,path:clipPath(T.pathname),startedAt:l,ctx:f,request:C(),...w?{ai:w}:{},...b?{aiOpaque:b}:{},responseFields:[],...g}),"job");let $=!1;const h=c(g=>{if($)return;$=!0;const y=g?.statusCode,q=Date.now()-l,M=(0,emit_1.lensEmit)("external","info",`egress ${o} ${s} \u2192 ${y??"?"}`,{name:s,kind:"egress",method:o,host:s,path:m,...y!=null?{status:y}:{},...i?{hasQuery:!0}:{},startedAt:l,durationMs:q,...p?{exchangeId:p}:{}},fingerprintFor(s,y!=null&&y>=500),f);if(!p||!M||!g||typeof g.emit!="function")return;const A={...y!=null?{status:y}:{},...g.statusMessage?{statusText:g.statusMessage}:{},responseHeaders:(0,http_capture_1.headerPairs)(g.headers),ttfbMs:q};if(u!=="bodies"){trackExchange(()=>v(A));return}const R=[],S=new http_capture_1.ResponseSink(headerOf(g.headers,"content-type"),l,{ai:b,paths:R,encoding:headerOf(g.headers,"content-encoding")});teeResponse(g,S,I=>trackExchange(()=>v({...A,responseFields:R,reading:Promise.resolve(I())})))},"onResponse"),_=c(g=>{if($)return;$=!0;const y=String(g?.message??g),q=(0,emit_1.lensEmit)("external","error",`egress ${o} ${s} failed`,{name:s,kind:"egress",method:o,host:s,path:m,...i?{hasQuery:!0}:{},error:y,startedAt:l,durationMs:Date.now()-l,...p?{exchangeId:p}:{}},fingerprintFor(s,!0),f);p&&q&&trackExchange(()=>v({error:y}))},"onError"),F=r.emit;r.emit=function(g,...y){try{g==="response"?h(y[0]):g==="error"&&_(y[0])}catch{}return F.call(this,g,...y)}}E(observe,"observe"),x(observe,"observe"),c(observe,"observe");function targetUrl(e){try{const t=e.host.includes(":")&&!e.host.startsWith("[")?`[${e.host}]`:e.host,r=e.pathname.startsWith("/")?e.pathname:`/${e.pathname}`;return new URL(`${e.protocol}//${t}${e.port?`:${e.port}`:""}${r}${e.search}`)}catch{return}}E(targetUrl,"targetUrl"),x(targetUrl,"targetUrl"),c(targetUrl,"targetUrl");function parseTarget(e,t="http"){let r="",u="GET",a="/",d=!1,s=`${t}:`,o="",m="/",i="";const l=c((f,n)=>{d=n.length>1,a=capturePath(f,n),m=f||"/",i=n},"take");for(const f of e)if(typeof f=="string")try{const n=new URL(f);r=n.hostname,s=n.protocol,o=n.port,l(n.pathname,n.search)}catch{}else if(f instanceof URL)r=f.hostname,s=f.protocol,o=f.port,l(f.pathname,f.search);else if(f&&typeof f=="object"){const n=f;if(typeof n.method=="string"&&(u=n.method.toUpperCase()),typeof n.socketPath=="string")return{host:"",method:u,path:a,hasQuery:d,protocol:s,port:o,pathname:m,search:i};if(typeof n.path=="string"){const T=n.path,p=T.indexOf("?");l(p===-1?T:T.slice(0,p),p===-1?"":T.slice(p))}if(typeof n.protocol=="string"&&n.protocol&&(s=n.protocol),(typeof n.port=="number"||typeof n.port=="string"&&n.port)&&(o=String(n.port)),typeof n.hostname=="string"&&n.hostname)r=n.hostname;else if(typeof n.host=="string"&&n.host){const[T,p]=n.host.split(":");r=T??"",p&&!(typeof n.port=="number"||typeof n.port=="string")&&(o=p)}}return{host:r,method:u,path:a,hasQuery:d,protocol:s,port:o,pathname:m,search:i}}E(parseTarget,"parseTarget"),x(parseTarget,"parseTarget"),c(parseTarget,"parseTarget");
|
|
1
|
+
"use strict";var P=Object.defineProperty;var x=(t,e)=>P(t,"name",{value:e,configurable:!0});var H=Object.defineProperty,c=x((t,e)=>H(t,"name",{value:e,configurable:!0}),"c");Object.defineProperty(exports,"__esModule",{value:!0}),exports.flushEgressCaptureForTests=flushEgressCaptureForTests,exports.tapEgress=tapEgress,exports.resetEgressTapForTests=resetEgressTapForTests;const redact_1=require("@lensmcp/core/redact"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),ai_providers_1=require("./ai-providers"),http_capture_1=require("./http-capture"),http_store_1=require("./http-store"),capture_file_1=require("./capture-file"),tap_ai_1=require("./tap-ai"),INTERNAL=[/\.local$/i,/\.internal$/i,/^localhost$/i,/^127\./,/^\[?::1\]?$/,/^0\.0\.0\.0$/,/^10\./,/^192\.168\./,/^172\.(1[6-9]|2\d|3[01])\./,/^169\.254\./,/^\[?[fF][cCdD][0-9a-fA-F]{2}:/,/^\[?[fF][eE]80:/],isInternal=c(t=>t===""||INTERNAL.some(e=>e.test(t)),"isInternal"),CAPTURE_QUERY=process.env.LENSMCP_EGRESS_QUERY==="1",MAX_PATH_CHARS=256,clipPath=c(t=>t.length>MAX_PATH_CHARS?`${t.slice(0,MAX_PATH_CHARS)}\u2026`:t,"clipPath");function capturePath(t,e){const r=t||"/";return!CAPTURE_QUERY||e.length<=1?clipPath(r):(0,redact_1.redactUrl)(`${r}${e}`)}x(capturePath,"capturePath"),c(capturePath,"capturePath");const fingerprintFor=c((t,e)=>e?`external:error:${t}`:`external:${t}`,"fingerprintFor"),pendingExchanges=new Set;async function flushEgressCaptureForTests(){await Promise.allSettled([...pendingExchanges])}x(flushEgressCaptureForTests,"flushEgressCaptureForTests"),c(flushEgressCaptureForTests,"flushEgressCaptureForTests");async function finishExchange(t){const e=[],r=[],d=await(0,http_capture_1.requestPart)(t.request,t.url.search,t.mode,!!t.aiOpaque,r,e),a=t.reading?await t.reading.catch(()=>{}):void 0,{headers:u,redacted:s}=(0,http_store_1.redactHeaders)(t.responseHeaders??[]);e.push(...s);const o=typeof t.status=="number"?t.status:void 0,g={schemaVersion:1,id:t.id,capturedAt:Date.now(),side:"egress",service:emit_1.PROJECT,...t.ctx?.flowId?{flowId:t.ctx.flowId}:{},...t.ctx?.requestId?{requestId:t.ctx.requestId}:{},method:t.method,url:`${t.url.protocol}//${t.url.host}${t.path}`,host:t.url.hostname,path:t.path,...o!==void 0?{status:o}:{},...t.statusText?{statusText:t.statusText}:{},...t.error?{error:t.error}:{},startedAt:t.startedAt,...t.ttfbMs!==void 0?{ttfbMs:t.ttfbMs}:{},durationMs:(a?.endedAt??Date.now())-t.startedAt,capture:t.mode==="bodies"?"bodies":"headers",request:d,response:{headers:u,...a?.body?{body:a.body}:{},...a?.stream?{stream:a.stream}:{}},redacted:{headers:[...new Set(e)],bodyFields:[...r.map(i=>`request.${i}`),...t.responseFields.map(i=>`response.${i}`)]},...t.ai?{ai:{provider:t.ai}}:{}};(0,http_store_1.writeHttpExchange)(g)}x(finishExchange,"finishExchange"),c(finishExchange,"finishExchange");function trackExchange(t){const e=(typeof t=="function"?new Promise(r=>setImmediate(r)).then(()=>finishExchange(t())):finishExchange(t)).catch(()=>{});pendingExchanges.add(e),e.finally(()=>pendingExchanges.delete(e))}x(trackExchange,"trackExchange"),c(trackExchange,"trackExchange");function tapEgress(){tapFetch(),tapHttpModule("http"),tapHttpModule("https")}x(tapEgress,"tapEgress"),c(tapEgress,"tapEgress");let savedFetch;const httpOriginals=new Map;function resetEgressTapForTests(){const t=globalThis;savedFetch&&(t.fetch=savedFetch),delete t.__lensmcpFetchTap,restoreHttp("http"),restoreHttp("https"),savedFetch=void 0}x(resetEgressTapForTests,"resetEgressTapForTests"),c(resetEgressTapForTests,"resetEgressTapForTests");function restoreHttp(t){const e=httpOriginals.get(t);if(!e)return;const r=require(`node:${t}`);r.request=e.request,r.get=e.get,httpOriginals.delete(t)}x(restoreHttp,"restoreHttp"),c(restoreHttp,"restoreHttp");function tapFetch(){const t=globalThis;if(typeof t.fetch!="function"||t.__lensmcpFetchTap)return;t.__lensmcpFetchTap=!0;const e=t.fetch.bind(globalThis);savedFetch=t.fetch;const r=(0,http_store_1.httpCaptureMode)(),d=(0,ai_providers_1.parseExtraHosts)(process.env.LENSMCP_AI_HOSTS);t.fetch=(async(a,u)=>{let s="",o="/",g=!1,i;try{const h=new URL(typeof a=="string"?a:a instanceof URL?a.href:a.url);i=h,s=h.hostname,g=h.search.length>1,o=capturePath(h.pathname,h.search)}catch{}if(isInternal(s))return e(a,u);const l=Date.now(),f=(0,flow_context_1.flowContext)(),n=(0,flow_context_1.liveFlowContext)();n&&(n.externalCallCount=(n.externalCallCount??0)+1);const w=typeof a=="object"&&a!==null&&!(a instanceof URL)?a.method:void 0,p=String(u?.method??w??"GET").toUpperCase(),E=r!=="off"&&i?(0,http_store_1.newExchangeId)():void 0,b=E?(0,http_capture_1.takeRequest)(a,u,r==="bodies"):void 0,q=E&&i&&p==="POST"?(0,ai_providers_1.matchTarget)(s,i.port,i.pathname,d)?.provider:void 0,T=!!q&&(0,tap_ai_1.aiCaptureMode)()!=="content"&&!(0,capture_file_1.aiBodiesAsked)(),_=c(h=>({id:E,mode:r,method:p,url:i,path:i.pathname.length>256?`${i.pathname.slice(0,256)}\u2026`:i.pathname,startedAt:l,ctx:f,request:b,...q?{ai:q}:{},...T?{aiOpaque:T}:{},responseFields:[],...h}),"job");try{const h=await e(a,u),$=Date.now()-l,C=h.status>=500,m=[];let y;if(E&&r==="bodies")try{y=(0,http_capture_1.readResponse)(h,h.clone(),l,{ai:T,paths:m})}catch{y=void 0}const v=(0,emit_1.lensEmit)("external","info",`egress ${p} ${s} \u2192 ${h.status}`,{name:s,kind:"egress",method:p,host:s,path:o,status:h.status,...g?{hasQuery:!0}:{},startedAt:l,durationMs:$,...E?{exchangeId:E}:{}},fingerprintFor(s,C),f);if(E&&v){const A={status:h.status,...h.statusText?{statusText:h.statusText}:{},responseHeaders:(0,http_capture_1.headerPairs)(h.headers)};trackExchange(_({...A,ttfbMs:$,responseFields:m,...y?{reading:y}:{}}))}return h}catch(h){const $=String(h?.message??h),C=(0,emit_1.lensEmit)("external","error",`egress ${p} ${s} failed`,{name:s,kind:"egress",method:p,host:s,path:o,...g?{hasQuery:!0}:{},error:$,startedAt:l,durationMs:Date.now()-l,...E?{exchangeId:E}:{}},fingerprintFor(s,!0),f);throw E&&C&&trackExchange(_({error:$})),h}})}x(tapFetch,"tapFetch"),c(tapFetch,"tapFetch");function tapHttpModule(t){const e=require(`node:${t}`),r=e.request;if(typeof r!="function"||r.__lensmcp)return;httpOriginals.set(t,{request:r,get:e.get});const d=(0,http_store_1.httpCaptureMode)(),a=(0,ai_providers_1.parseExtraHosts)(process.env.LENSMCP_AI_HOSTS),u=c(function(...s){const o=r.apply(this,s);try{observe(t,s,o,d,a)}catch{}return o},"wrapped");u.__lensmcp=!0,e.request=u,typeof e.get=="function"&&(e.get=function(...s){const o=u.apply(this,s);return o.end(),o})}x(tapHttpModule,"tapHttpModule"),c(tapHttpModule,"tapHttpModule");const headerOf=c((t,e)=>{const r=t?.[e];return Array.isArray(r)?r.join(", "):r??""},"headerOf");function teeRequest(t,e,r){const d=e?new http_capture_1.WrittenBody(!r):void 0,a=c(()=>{try{return t.getHeaders?.()}catch{return}},"sentHeaders");let u,s=!1;const o=t.write;d&&typeof o=="function"&&(t.write=function(i,...l){try{s||d.take(i,l[0])}catch{}return o.call(this,i,...l)});const g=t.end;return t.end=function(i,...l){try{s||(s=!0,d?.take(i,l[0]),u=a())}catch{}return g.call(this,i,...l)},()=>(0,http_capture_1.writtenRequest)(u??a(),d)}x(teeRequest,"teeRequest"),c(teeRequest,"teeRequest");function teeResponse(t,e,r){let d=!1;const a=c(o=>{if(d)return;d=!0,clearTimeout(u);const g=Date.now();r(()=>e.size?e.finish(o,g):{endedAt:g})},"finish"),u=setTimeout(()=>a(!0),http_capture_1.MAX_STREAM_MS);u.unref?.();const s=t.emit;t.emit=function(o,...g){try{return s.call(this,o,...g)}finally{try{if(o==="data"){const i=d?void 0:(0,http_capture_1.chunkBytes)(g[0],t.readableEncoding);i&&!e.push(i)&&a(!1)}else o==="end"?a(!1):(o==="aborted"||o==="error"||o==="close")&&a(!0)}catch{}}}}x(teeResponse,"teeResponse"),c(teeResponse,"teeResponse");function observe(t,e,r,d,a){const u=parseTarget(e,t),{host:s,method:o,path:g,hasQuery:i}=u;if(isInternal(s))return;const l=Date.now(),f=(0,flow_context_1.flowContext)(),n=(0,flow_context_1.liveFlowContext)();n&&(n.externalCallCount=(n.externalCallCount??0)+1);const w=d!=="off"?targetUrl(u):void 0,p=w?(0,http_store_1.newExchangeId)():void 0,E=p&&w&&o==="POST"?(0,ai_providers_1.matchTarget)(s,w.port,w.pathname,a)?.provider:void 0,b=!!E&&(0,tap_ai_1.aiCaptureMode)()!=="content"&&!(0,capture_file_1.aiBodiesAsked)(),q=p?teeRequest(r,d==="bodies",b):void 0,T=c(m=>({id:p,mode:d,method:o,url:w,path:clipPath(w.pathname),startedAt:l,ctx:f,request:q(),...E?{ai:E}:{},...b?{aiOpaque:b}:{},responseFields:[],...m}),"job");let _=!1;const h=c(m=>{if(_)return;_=!0;const y=m?.statusCode,v=Date.now()-l,A=(0,emit_1.lensEmit)("external","info",`egress ${o} ${s} \u2192 ${y??"?"}`,{name:s,kind:"egress",method:o,host:s,path:g,...y!=null?{status:y}:{},...i?{hasQuery:!0}:{},startedAt:l,durationMs:v,...p?{exchangeId:p}:{}},fingerprintFor(s,y!=null&&y>=500),f);if(!p||!A||!m||typeof m.emit!="function")return;const M={...y!=null?{status:y}:{},...m.statusMessage?{statusText:m.statusMessage}:{},responseHeaders:(0,http_capture_1.headerPairs)(m.headers),ttfbMs:v};if(d!=="bodies"){trackExchange(()=>T(M));return}const F=[],R=new http_capture_1.ResponseSink(headerOf(m.headers,"content-type"),l,{ai:b,paths:F,encoding:headerOf(m.headers,"content-encoding")});teeResponse(m,R,S=>trackExchange(()=>T({...M,responseFields:F,reading:Promise.resolve(S())})))},"onResponse"),$=c(m=>{if(_)return;_=!0;const y=String(m?.message??m),v=(0,emit_1.lensEmit)("external","error",`egress ${o} ${s} failed`,{name:s,kind:"egress",method:o,host:s,path:g,...i?{hasQuery:!0}:{},error:y,startedAt:l,durationMs:Date.now()-l,...p?{exchangeId:p}:{}},fingerprintFor(s,!0),f);p&&v&&trackExchange(()=>T({error:y}))},"onError"),C=r.emit;r.emit=function(m,...y){try{m==="response"?h(y[0]):m==="error"&&$(y[0])}catch{}return C.call(this,m,...y)}}x(observe,"observe"),c(observe,"observe");function targetUrl(t){try{const e=t.host.includes(":")&&!t.host.startsWith("[")?`[${t.host}]`:t.host,r=t.pathname.startsWith("/")?t.pathname:`/${t.pathname}`;return new URL(`${t.protocol}//${e}${t.port?`:${t.port}`:""}${r}${t.search}`)}catch{return}}x(targetUrl,"targetUrl"),c(targetUrl,"targetUrl");function parseTarget(t,e="http"){let r="",d="GET",a="/",u=!1,s=`${e}:`,o="",g="/",i="";const l=c((f,n)=>{u=n.length>1,a=capturePath(f,n),g=f||"/",i=n},"take");for(const f of t)if(typeof f=="string")try{const n=new URL(f);r=n.hostname,s=n.protocol,o=n.port,l(n.pathname,n.search)}catch{}else if(f instanceof URL)r=f.hostname,s=f.protocol,o=f.port,l(f.pathname,f.search);else if(f&&typeof f=="object"){const n=f;if(typeof n.method=="string"&&(d=n.method.toUpperCase()),typeof n.socketPath=="string")return{host:"",method:d,path:a,hasQuery:u,protocol:s,port:o,pathname:g,search:i};if(typeof n.path=="string"){const w=n.path,p=w.indexOf("?");l(p===-1?w:w.slice(0,p),p===-1?"":w.slice(p))}if(typeof n.protocol=="string"&&n.protocol&&(s=n.protocol),(typeof n.port=="number"||typeof n.port=="string"&&n.port)&&(o=String(n.port)),typeof n.hostname=="string"&&n.hostname)r=n.hostname;else if(typeof n.host=="string"&&n.host){const[w,p]=n.host.split(":");r=w??"",p&&!(typeof n.port=="number"||typeof n.port=="string")&&(o=p)}}return{host:r,method:d,path:a,hasQuery:u,protocol:s,port:o,pathname:g,search:i}}x(parseTarget,"parseTarget"),c(parseTarget,"parseTarget");
|
package/lib/tap-event-loop.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var m=Object.defineProperty;var r=(e,o)=>m(e,"name",{value:o,configurable:!0});var a=Object.defineProperty,n=r((e,o)=>a(e,"name",{value:o,configurable:!0}),"n");Object.defineProperty(exports,"__esModule",{value:!0}),exports.tapEventLoop=tapEventLoop,exports.stopEventLoopTapForTests=stopEventLoopTapForTests;const node_perf_hooks_1=require("node:perf_hooks"),emit_1=require("./emit"),SAMPLE_MS=(()=>{const e=Number(process.env.LENSMCP_EVENT_LOOP_SAMPLE_MS);return Number.isFinite(e)&&e>=1e3?e:3e4})(),REPORT_ABOVE_MS=(()=>{const e=Number(process.env.LENSMCP_EVENT_LOOP_MIN_MS);return Number.isFinite(e)&&e>=0?e:50})(),RESOLUTION_MS=20;let timer,published=!1;function tapEventLoop(){if(process.env.LENSMCP_EVENT_LOOP==="0"||timer)return;const e=(0,node_perf_hooks_1.monitorEventLoopDelay)({resolution:RESOLUTION_MS});e.enable(),timer=setInterval(()=>{const o=RESOLUTION_MS,s=e.mean/1e6;if(!Number.isFinite(s))return;const i=Math.max(0,s-o),t=Math.max(0,e.max/1e6-o),p=Math.max(0,e.percentile(99)/1e6-o);e.reset(),!(published&&t<REPORT_ABOVE_MS)&&(published=!0,(0,emit_1.lensEmit)("perf",t>=1e3?"error":"info",`event loop lag ${i.toFixed(1)}ms mean / ${t.toFixed(1)}ms max`,{kind:"event-loop-lag",lagMs:Number(i.toFixed(2)),maxMs:Number(t.toFixed(2)),p99Ms:Number(p.toFixed(2)),windowMs:SAMPLE_MS},"perf:event-loop-lag",void 0,"performance"))},SAMPLE_MS),timer.unref?.()}r(tapEventLoop,"tapEventLoop"),n(tapEventLoop,"tapEventLoop");function stopEventLoopTapForTests(){timer&&clearInterval(timer),timer=void 0,published=!1}r(stopEventLoopTapForTests,"stopEventLoopTapForTests"),n(stopEventLoopTapForTests,"stopEventLoopTapForTests");
|
package/lib/tap-exec.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var m=Object.defineProperty;var p=(n,e)=>m(n,"name",{value:e,configurable:!0});var f=Object.defineProperty,d=p((n,e)=>f(n,"name",{value:e,configurable:!0}),"d");Object.defineProperty(exports,"__esModule",{value:!0}),exports.tapExec=tapExec;const redact_1=require("@lensmcp/core/redact"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),shown=d(n=>{const e=(0,redact_1.redactSecretText)(n.slice(0,4096));return e.length>200?`${e.slice(0,199)}\u2026`:e},"shown"),fmtCmd=d((n,e)=>{const r=Array.isArray(e)?e.map(String).slice(0,8).join(" "):"";return shown(`${String(n)}${r?" "+r:""}`)},"fmtCmd");function wrap(n,e,r){const t=n[e];if(typeof t!="function"||t.__lensmcp)return;const o=r(t);o.__lensmcp=!0,n[e]=o}p(wrap,"wrap"),d(wrap,"wrap");function observeChild(n,e,r,t){if(!r||typeof r.once!="function")return;const o=r;if(o.__lensmcpObserved)return;o.__lensmcpObserved=!0;const a=Date.now();r.once("exit",(...c)=>{const s=c[0],x=c[1];(0,emit_1.lensEmit)("exec",s===0?"info":x?"error":"warning",`exec ${e.split(" ")[0]} \u2192 ${s??x}`,{name:"exec",kind:"exec",cmd:e,via:n,...s!=null?{code:s}:{},...x?{signal:x}:{},durationMs:Date.now()-a,...r.pid?{pid:r.pid}:{}},void 0,t)}),r.once("error",(...c)=>{const s=c[0];(0,emit_1.lensEmit)("exec","error",`exec ${e.split(" ")[0]} failed to start`,{name:"exec",kind:"exec",cmd:e,via:n,error:(0,redact_1.clip)((0,redact_1.redactSecretText)(String(s?.message??s)),500),durationMs:Date.now()-a},void 0,t)})}p(observeChild,"observeChild"),d(observeChild,"observeChild");function tapExec(n=require("node:child_process")){for(const e of["spawn","fork"])wrap(n,e,r=>function(t,...o){const a=Array.isArray(o[0])?o[0]:[],c=(0,flow_context_1.flowContext)(),s=r.call(this,t,...o);try{observeChild(e,fmtCmd(t,a),s,c)}catch{}return s});wrap(n,"exec",e=>function(r,...t){const o=(0,flow_context_1.flowContext)(),a=e.call(this,r,...t);try{observeChild("exec",shown(String(r)),a,o)}catch{}return a}),wrap(n,"execFile",e=>function(r,...t){const o=Array.isArray(t[0])?t[0]:[],a=(0,flow_context_1.flowContext)(),c=e.call(this,r,...t);try{observeChild("execFile",fmtCmd(r,o),c,a)}catch{}return c});for(const e of["execSync","execFileSync","spawnSync"])wrap(n,e,r=>function(t,...o){const a=Array.isArray(o[0])?o[0]:[],c=e==="execSync"?shown(String(t)):fmtCmd(t,a),s=(0,flow_context_1.flowContext)(),x=Date.now();try{const l=r.call(this,t,...o),i=l&&typeof l=="object"?l:{},u=i.status??0;return i.error||i.signal?((0,emit_1.lensEmit)("exec","error",i.error?`exec ${c.split(" ")[0]} failed to start`:`exec ${c.split(" ")[0]} \u2192 ${i.signal}`,{name:"exec",kind:"exec",cmd:c,via:e,...i.error?{error:(0,redact_1.clip)((0,redact_1.redactSecretText)(String(i.error?.message??i.error)),500)}:{},...i.signal?{signal:i.signal}:{},durationMs:Date.now()-x,sync:!0},void 0,s),l):((0,emit_1.lensEmit)("exec",u===0?"info":"warning",`exec ${c.split(" ")[0]} \u2192 ${u}`,{name:"exec",kind:"exec",cmd:c,via:e,code:u,durationMs:Date.now()-x,sync:!0},void 0,s),l)}catch(l){const i=l,u=typeof i?.status=="number"&&!i.signal;throw(0,emit_1.lensEmit)("exec",u?"warning":"error",u?`exec ${c.split(" ")[0]} \u2192 ${i.status}`:`exec ${c.split(" ")[0]} failed`,{name:"exec",kind:"exec",cmd:c,via:e,...u?{code:i.status}:{error:(0,redact_1.clip)((0,redact_1.redactSecretText)(String(i?.message??l)),500)},...typeof i?.signal=="string"?{signal:i.signal}:{},durationMs:Date.now()-x,sync:!0},void 0,s),l}})}p(tapExec,"tapExec"),d(tapExec,"tapExec");
|
package/lib/tap-fs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var h=Object.defineProperty;var c=(r,n)=>h(r,"name",{value:n,configurable:!0});var d=Object.defineProperty,f=c((r,n)=>d(r,"name",{value:n,configurable:!0}),"f");Object.defineProperty(exports,"__esModule",{value:!0}),exports.FsWindow=exports.OWN_EVENTS=void 0,exports.flushFsWindowForTests=flushFsWindowForTests,exports.tapFs=tapFs;const tslib_1=require("tslib"),os=tslib_1.__importStar(require("node:os")),emit_1=require("./emit"),flow_context_1=require("./flow-context"),PATHS_KEPT=50,PATHS_SENT=20;exports.OWN_EVENTS=4;const SLICES_KEPT=64;class FsSlice{static{c(this,"FsSlice")}static{f(this,"FsSlice")}constructor(n,s){this.flowId=n,this.requestId=s,this.reads=0,this.writes=0,this.bytesRead=0,this.bytesWritten=0,this.first=1/0,this.last=0,this.counts=new Map,this.ops=new Map}absorb(n){this.reads+=n.reads,this.writes+=n.writes,this.bytesRead+=n.bytesRead,this.bytesWritten+=n.bytesWritten;for(const[s,e]of n.counts)this.counts.set(s,(this.counts.get(s)??0)+e);for(const[s,e]of n.ops)this.ops.set(s,e)}payload(n={}){const s=[...this.counts.entries()].sort((t,i)=>i[1]-t[1]).slice(0,3).map(([t])=>t),e=[...this.ops.values()].sort((t,i)=>i.at-t.at).slice(0,PATHS_SENT);return{reads:this.reads,writes:this.writes,bytesRead:this.bytesRead,bytesWritten:this.bytesWritten,top:s,paths:e,...n}}}class FsWindow{static{c(this,"FsWindow")}static{f(this,"FsWindow")}constructor(){this.slices=new Map,this.kept=0}record(n,s,e,t,i,o=!1){let l=i?.flowId?`${i.flowId}\0${i.requestId??""}`:"";l&&!this.slices.has(l)&&this.slices.size>=SLICES_KEPT&&(l="");let a=this.slices.get(l);a||(a=l?new FsSlice(i?.flowId,i?.requestId):new FsSlice,this.slices.set(l,a)),n==="read"?(a.reads+=1,a.bytesRead+=e):(a.writes+=1,a.bytesWritten+=e),a.first=Math.min(a.first,t),a.last=Math.max(a.last,t),(a.counts.size<PATHS_KEPT||a.counts.has(s))&&a.counts.set(s,(a.counts.get(s)??0)+1);const u=`${n}\0${s}\0${i?.flowId??""}`,p=a.ops.get(u);p?(p.n+=1,p.bytes+=e,p.at=t,i?.requestId&&(p.requestId=i.requestId)):this.kept<PATHS_KEPT&&(this.kept+=1,a.ops.set(u,{path:s,op:n,n:1,bytes:e,...o?{stream:!0}:{},at:t,...i?.flowId?{flowId:i.flowId}:{},...i?.requestId?{requestId:i.requestId}:{}}))}drain(){if(!this.slices.size)return[];const n=[...this.slices.entries()].filter(([o])=>o!=="").sort(([o,l],[a,u])=>u.reads+u.writes-(l.reads+l.writes)||u.last-l.last||(o<a?-1:1)),s=n.slice(0,exports.OWN_EVENTS),e=n.slice(exports.OWN_EVENTS),t=this.slices.get("")??new FsSlice;for(const[,o]of e)t.absorb(o);const i=s.map(([,o])=>({ctx:{flowId:o.flowId,...o.requestId?{requestId:o.requestId}:{}},payload:o.payload({startedAt:o.first})}));return t.reads+t.writes>0&&i.push({payload:t.payload(e.length?{merged:e.length}:{})}),this.slices.clear(),this.kept=0,i}}exports.FsWindow=FsWindow;const current=new FsWindow;let timer=null;const TMP=os.tmpdir(),CWD=process.cwd(),SKIP=["node_modules","/.nx/","/dist/","/.git/",".lensmcp"],CODE=/\.(?:[cm]?[jt]sx?|map|node)$/;let appending=0;function trackedPath(r){if((0,emit_1.isLensWriting)())return null;const n=typeof r=="string"?r:Buffer.isBuffer(r)?r.toString():r instanceof URL?r.pathname:null;return!n||n===emit_1.EVENT_FILE||n.startsWith(TMP)||SKIP.some(s=>n.includes(s))?null:n}c(trackedPath,"trackedPath"),f(trackedPath,"trackedPath");function record(r,n,s=0,e,t=!1){const i=trackedPath(n);if(!i||r==="read"&&CODE.test(i))return;const o=i.startsWith(CWD)?i.slice(CWD.length+1):i;current.record(r,o,s,Date.now(),e??(0,flow_context_1.flowContext)(),t),timer||(timer=setTimeout(flush,1e3),timer.unref?.())}c(record,"record"),f(record,"record");function flush(){timer=null;for(const{ctx:r,payload:n}of current.drain()){const s=n.paths.find(t=>t.op!=="read")??n.paths[0],e=r&&s?`fs ${s.op} ${s.path}${n.paths.length>1?` +${n.paths.length-1}`:""}`:`fs ${n.reads} reads \xB7 ${n.writes} writes`;(0,emit_1.lensEmit)("fs","info",e,{name:"fs",kind:"fs-ops",...n},`fs:${emit_1.PROJECT}`,r)}}c(flush,"flush"),f(flush,"flush");const byteLen=f(r=>typeof r=="string"?Buffer.byteLength(r):Buffer.isBuffer(r)?r.length:0,"byteLen");function wrap(r,n,s){const e=r?.[n];if(!r||typeof e!="function"||e.__lensmcp)return;const t=s(e);t.__lensmcp=!0;try{r[n]=t}catch{}}c(wrap,"wrap"),f(wrap,"wrap");function flushFsWindowForTests(){timer&&clearTimeout(timer),flush()}c(flushFsWindowForTests,"flushFsWindowForTests"),f(flushFsWindowForTests,"flushFsWindowForTests");function tapFs(r=require("node:fs")){wrap(r,"readFileSync",s=>function(e,...t){const i=s.call(this,e,...t);return record("read",e,byteLen(i)),i}),wrap(r,"writeFileSync",s=>function(e,t,...i){const o=appending>0,l=s.call(this,e,t,...i);return o||record("write",e,byteLen(t)),l}),wrap(r,"appendFileSync",s=>function(e,t,...i){appending++;let o;try{o=s.call(this,e,t,...i)}finally{appending--}return record("append",e,byteLen(t)),o}),wrap(r,"readFile",s=>function(e,...t){const i=t[t.length-1];if(typeof i=="function"){const o=(0,flow_context_1.flowContext)();t[t.length-1]=(l,a)=>{l||record("read",e,byteLen(a),o),i(l,a)}}return s.call(this,e,...t)});for(const s of["writeFile","appendFile"])wrap(r,s,e=>function(t,i,...o){const l=o[o.length-1],a=appending>0;if(typeof l=="function"){const u=(0,flow_context_1.flowContext)();o[o.length-1]=p=>{!p&&!a&&record(s==="appendFile"?"append":"write",t,byteLen(i),u),l(p)}}if(s!=="appendFile")return e.call(this,t,i,...o);appending++;try{return e.call(this,t,i,...o)}finally{appending--}});const n=r.promises;wrap(n,"readFile",s=>async function(e,...t){const i=(0,flow_context_1.flowContext)(),o=await s.call(this,e,...t);return record("read",e,byteLen(o),i),o});for(const s of["writeFile","appendFile"])wrap(n,s,e=>async function(t,i,...o){const l=(0,flow_context_1.flowContext)(),a=await e.call(this,t,i,...o);return record(s==="appendFile"?"append":"write",t,byteLen(i),l),a});wrap(r,"createReadStream",s=>function(e,...t){return record("read",e,0,(0,flow_context_1.flowContext)(),!0),s.call(this,e,...t)}),wrap(r,"createWriteStream",s=>function(e,...t){return record("write",e,0,(0,flow_context_1.flowContext)(),!0),s.call(this,e,...t)})}c(tapFs,"tapFs"),f(tapFs,"tapFs");
|
package/lib/tap-ingress.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var q=Object.defineProperty;var a=(r,e)=>q(r,"name",{value:e,configurable:!0});var _=Object.defineProperty,d=a((r,e)=>_(r,"name",{value:e,configurable:!0}),"d");Object.defineProperty(exports,"__esModule",{value:!0}),exports.EXCHANGE_ID=void 0,exports.tapIngress=tapIngress,exports.resetIngressTapForTests=resetIngressTapForTests;const tslib_1=require("tslib"),http=tslib_1.__importStar(require("node:http")),zlib=tslib_1.__importStar(require("node:zlib")),headless_flow_1=require("@lensmcp/core/headless-flow"),emit_1=require("./emit"),http_store_1=require("./http-store");exports.EXCHANGE_ID=Symbol.for("lensmcp.exchangeId");const MAX_READ=2*1024*1024,MAX_PATH_CHARS=256;let originalEmit;function tapIngress(){if(originalEmit)return;const r=(0,http_store_1.httpCaptureMode)();if(r==="off")return;const e=http.Server.prototype,s=e.emit;originalEmit=s,e.emit=function(t,...i){if(t==="request")try{watch(i[0],i[1],r)}catch{}return s.call(this,t,...i)}}a(tapIngress,"tapIngress"),d(tapIngress,"tapIngress");function resetIngressTapForTests(){originalEmit&&(http.Server.prototype.emit=originalEmit),originalEmit=void 0}a(resetIngressTapForTests,"resetIngressTapForTests"),d(resetIngressTapForTests,"resetIngressTapForTests");const one=d(r=>r===void 0?void 0:Array.isArray(r)?r.join(", "):String(r),"one"),pairs=d(r=>Object.entries(r).flatMap(([e,s])=>s===void 0?[]:[[e,one(s)]]),"pairs");class Tee{static{a(this,"Tee")}static{d(this,"Tee")}constructor(){this.chunks=[],this.read=0,this.size=0}take(e,s){if(e==null||typeof e=="function")return;const t=Buffer.isBuffer(e)?e:e instanceof Uint8Array?Buffer.from(e):typeof e=="string"?Buffer.from(e,typeof s=="string"?s:"utf8"):void 0;t&&(this.size+=t.length,this.read<MAX_READ&&(this.chunks.push(t),this.read+=t.length))}bytes(){return Buffer.concat(this.chunks)}}function watch(r,e,s){if(!r||!e||r[exports.EXCHANGE_ID])return;const t=r.url??"/",i=t.indexOf("?"),f=i<0?t:t.slice(0,i);if((0,headless_flow_1.isProbePath)(f))return;const h=(0,http_store_1.newExchangeId)();r[exports.EXCHANGE_ID]=h;const g=Date.now(),l=s==="bodies",y=new Tee,c=new Tee;if(l){const m=r.emit;r.emit=function(o,...n){return o==="data"&&y.take(n[0]),m.call(this,o,...n)};const w=e.write,b=e.end;e.write=function(o,...n){return c.take(o,n[0]),w.call(this,o,...n)},e.end=function(o,...n){return c.take(o,n[0]),b.call(this,o,...n)}}let u=!1;const p=d(()=>{if(!u){u=!0;try{(0,http_store_1.writeHttpExchange)(exchangeOf(h,r,e,{url:t,q:i,path:f,startedAt:g,bodies:l,sent:y,answered:c}))}catch{}}},"finish");e.once("finish",p),e.once("close",p)}a(watch,"watch"),d(watch,"watch");function unpacked(r,e){try{if(r==="gzip"||r==="x-gzip")return zlib.gunzipSync(e,{maxOutputLength:MAX_READ});if(r==="br")return zlib.brotliDecompressSync(e,{maxOutputLength:MAX_READ});if(r==="deflate")return zlib.inflateSync(e,{maxOutputLength:MAX_READ})}catch{return}}a(unpacked,"unpacked"),d(unpacked,"unpacked");function exchangeOf(r,e,s,t){const i=[],f=[],h=[],g=(0,http_store_1.redactHeaders)(pairs(e.headers));i.push(...g.redacted);const l=(0,http_store_1.redactHeaders)(pairs(s.getHeaders()));i.push(...l.redacted);const y=t.bodies&&t.q>=0?(0,http_store_1.redactQuery)(t.url.slice(t.q)):[];let c;t.bodies&&t.sent.size&&(c=(0,http_store_1.keepBody)(one(e.headers["content-type"])??"",t.sent.bytes(),t.sent.size,f));let u;if(t.bodies&&t.answered.size){const n=one(s.getHeader("content-type"))??"",x=(one(s.getHeader("content-encoding"))??"").trim().toLowerCase();if(!x||x==="identity")u=(0,http_store_1.keepBody)(n,t.answered.bytes(),t.answered.size,h);else{const A=t.answered.size<=MAX_READ?unpacked(x,t.answered.bytes()):void 0;u=A?(0,http_store_1.keepBody)(n,A,A.length,h):{contentType:n.split(";")[0].trim().toLowerCase(),size:t.answered.size,kept:0,truncated:!1,omitted:"encoded"}}}const p=one(e.headers.host)??"localhost",m=t.path.length>MAX_PATH_CHARS?`${t.path.slice(0,MAX_PATH_CHARS)}\u2026`:t.path,w=one(e.headers["x-lensmcp-flow-id"]),b=one(e.headers["x-request-id"]),o=!s.writableFinished;return{schemaVersion:1,id:r,capturedAt:Date.now(),side:"ingress",service:emit_1.PROJECT,...w?{flowId:w}:{},...b?{requestId:b}:{},method:(e.method??"GET").toUpperCase(),url:`http://${p}${m}`,host:p.split(":")[0]??p,path:m,status:s.statusCode,...s.statusMessage?{statusText:s.statusMessage}:{},...o?{error:"the client went away before the answer ended"}:{},startedAt:t.startedAt,durationMs:Date.now()-t.startedAt,capture:t.bodies?"bodies":"headers",request:{headers:g.headers,...y.length?{query:y}:{},...c?{body:c}:{}},response:{headers:l.headers,...u?{body:u}:{}},redacted:{headers:[...new Set(i)],bodyFields:[...f.map(n=>`request.${n}`),...h.map(n=>`response.${n}`)]}}}a(exchangeOf,"exchangeOf"),d(exchangeOf,"exchangeOf");
|
package/lib/tap-nest-logger.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`,1)[0]??"";if(r.length<ECHO_MIN_CHARS)return;const n=r.slice(0,ECHO_NEEDLE_CHARS),
|
|
1
|
+
"use strict";var T=Object.defineProperty;var s=(e,t)=>T(e,"name",{value:t,configurable:!0});var S=Object.defineProperty,o=s((e,t)=>S(e,"name",{value:t,configurable:!0}),"o");Object.defineProperty(exports,"__esModule",{value:!0}),exports.isLoggerEcho=isLoggerEcho,exports.resetNestLoggerTapForTests=resetNestLoggerTapForTests,exports.nestLoggerTap=nestLoggerTap;const redact_1=require("@lensmcp/core/redact"),flood_guard_1=require("./flood-guard"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),LEVELS=["verbose","debug","log","warn","error","fatal"],SEVERITY={verbose:"debug",debug:"debug",log:"info",warn:"warning",error:"error",fatal:"fatal"},MAX_TEXT_CHARS=4e3,TITLE_CHARS=240,shapeGuard=(0,flood_guard_1.createEventFloodGuard)({burst:30,perSec:5}),podGuard=(0,flood_guard_1.createEventFloodGuard)({burst:400,perSec:100});let depth=0;const recent=[],ECHO_WINDOW_MS=2e3,ECHO_NEEDLE_CHARS=96,ECHO_MIN_CHARS=12,MAX_RECENT=64;function isLoggerEcho(e,t=Date.now()){for(let r=recent.length-1;r>=0;r--){const n=recent[r];if(t-n.at>ECHO_WINDOW_MS)return recent.splice(0,r+1),!1;if(e.includes(n.needle)||n.escaped!==void 0&&e.includes(n.escaped))return recent.splice(r,1),!0}return!1}s(isLoggerEcho,"isLoggerEcho"),o(isLoggerEcho,"isLoggerEcho");function expectEcho(e,t){const r=e.split(`
|
|
2
|
+
`,1)[0]??"";if(r.length<ECHO_MIN_CHARS)return;const n=r.slice(0,ECHO_NEEDLE_CHARS),c=JSON.stringify(n).slice(1,-1);recent.push({needle:n,at:t,...c!==n?{escaped:c}:{}}),recent.length>MAX_RECENT&&recent.splice(0,recent.length-MAX_RECENT)}s(expectEcho,"expectEcho"),o(expectEcho,"expectEcho");function resetNestLoggerTapForTests(){recent.length=0,depth=0}s(resetNestLoggerTapForTests,"resetNestLoggerTapForTests"),o(resetNestLoggerTapForTests,"resetNestLoggerTapForTests");function textOf(e){if(typeof e=="string")return e;if(e instanceof Error)return e.stack??`${e.name}: ${e.message}`;if(e===null||typeof e!="object")return String(e);try{return JSON.stringify(e)??String(e)}catch{return Object.prototype.toString.call(e)}}s(textOf,"textOf"),o(textOf,"textOf");function openingOf(e){return typeof e=="string"?e.split(`
|
|
3
3
|
`,1)[0]??"":e instanceof Error?`${e.name}: ${e.message}`.split(`
|
|
4
|
-
`,1)[0]??"":e===null||typeof e!="object"?String(e):"{object}"}
|
|
5
|
-
`:" ")+
|
|
6
|
-
`,1)[0]??"",
|
|
4
|
+
`,1)[0]??"":e===null||typeof e!="object"?String(e):"{object}"}s(openingOf,"openingOf"),o(openingOf,"openingOf");const looksLikeStack=o(e=>typeof e=="string"&&/\n\s+at\s/.test(e),"looksLikeStack");function shapeOf(e){return e.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,"#").replace(/\b[0-9a-f]{12,}\b/gi,"#").replace(/\d+/g,"#").slice(0,80)}s(shapeOf,"shapeOf"),o(shapeOf,"shapeOf");function capture(e,t,r,n){const c=(0,flow_context_1.flowContext)();if(!c?.flowId&&!c?.requestId)return;const l=t?.context,i=n.slice();let f=typeof l=="string"&&l?l:void 0;!f&&i.length>0&&typeof i[i.length-1]=="string"&&!looksLikeStack(i[i.length-1])&&(f=i.pop());const h=openingOf(r),E=`${f??""}:${shapeOf((0,redact_1.redactText)(h.slice(0,MAX_TEXT_CHARS*2)))}`,_=Date.now(),u=shapeGuard.admit(E),L=u.ok?podGuard.admit("pod"):u;if(!u.ok||!L.ok){expectEcho(h,_);return}const y=[r,...i].filter(a=>a!==void 0).map(textOf);let d="";for(const a of y)d+=d===""?a:(looksLikeStack(a)?`
|
|
5
|
+
`:" ")+a;const p=(0,redact_1.redactText)(d.slice(0,MAX_TEXT_CHARS*2)).slice(0,MAX_TEXT_CHARS);if(!p)return;const g=p.split(`
|
|
6
|
+
`,1)[0]??"",b=looksLikeStack(p);(0,emit_1.lensLog)(SEVERITY[e],g.length>TITLE_CHARS?`${g.slice(0,TITLE_CHARS)}\u2026`:g,{...b?{stack:p}:p!==g||g.length>TITLE_CHARS?{text:p}:{},stream:"logger",level:e,...f?{logger:f}:{},bucket:E,suppressed:u.suppressed+L.suppressed});for(const a of y)expectEcho(a,_)}s(capture,"capture"),o(capture,"capture");function wrap(e,t){const r=e[t];if(typeof r!="function"||r.__lensmcpLog)return;const n=o(function(c,...l){if(depth===0)try{capture(t,this,c,l)}catch{}depth+=1;try{return r.call(this,c,...l)}finally{depth-=1}},"wrapped");n.__lensmcpLog=!0,e[t]=n}s(wrap,"wrap"),o(wrap,"wrap");function nestLoggerTap(e){if(process.env.LENSMCP_LOGS==="0")return!0;const t=e?.Logger;if(typeof t!="function"||!t.prototype)return!1;for(const r of LEVELS)wrap(t.prototype,r),wrap(t,r);return!0}s(nestLoggerTap,"nestLoggerTap"),o(nestLoggerTap,"nestLoggerTap");
|
package/lib/tap-nest.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var d=Object.defineProperty;var c=(e,t)=>d(e,"name",{value:t,configurable:!0});var f=Object.defineProperty,s=c((e,t)=>f(e,"name",{value:t,configurable:!0}),"s");Object.defineProperty(exports,"__esModule",{value:!0}),exports.installChildAppBridge=installChildAppBridge,exports.nestTap=nestTap;const emit_1=require("./emit"),WRAPPED=Symbol.for("lensmcp.wrappedRoot"),captures=[],waiters=[];function pushCapture(e){const t=waiters.shift();t?(clearTimeout(t.timer),t.resolve(e)):captures.push(e)}c(pushCapture,"pushCapture"),s(pushCapture,"pushCapture");function nextCapture(e=6e4){const t=captures.shift();return t?Promise.resolve(t):new Promise((n,r)=>{const i={resolve:n,reject:r,timer:setTimeout(()=>{const o=waiters.indexOf(i);o>=0&&waiters.splice(o,1),r(new Error("[lensmcp] no NestJS app captured within 60s \u2014 does main.ts call app.listen()? (zero-touch pods boot by running your main and intercepting listen)"))},e)};i.timer.unref?.(),waiters.push(i)})}c(nextCapture,"nextCapture"),s(nextCapture,"nextCapture");function installChildAppBridge(){if(process.env.APP_RUNNER!=="1")return;const e=global,t=s(()=>nextCapture(),"factory");e.createChildApp=t,e.__lensmcpCreateChildApp=t}c(installChildAppBridge,"installChildAppBridge"),s(installChildAppBridge,"installChildAppBridge");function nestTap(e){const t=e,n=t?.NestFactory,r=n?.create;if(!n||typeof r!="function")return!1;if(r.__lensmcp)return!0;const i=s(async function(o,...a){let p=o;const l=o,u=!!(l?.[WRAPPED]||l?.module?.[WRAPPED]);if(process.env.LENSMCP_NEST!=="0"&&!u)try{p=await buildLensmcpRoot(o)}catch{p=o}return r.call(this??n,p,...a)},"wrapped");if(i.__lensmcp=!0,n.create=i,process.env.APP_RUNNER==="1"){const o=t?.NestApplication?.prototype,a=o?.listen;if(o&&typeof a=="function"&&!a.__lensmcp){const p=s(async function(l,...u){return captureApp(this,l).catch(m=>(console.error("[lensmcp] pod capture failed, falling back to TCP listen:",m),a.call(this,l,...u)))},"listenWrapped");p.__lensmcp=!0,o.listen=p}}return!0}c(nestTap,"nestTap"),s(nestTap,"nestTap");async function buildLensmcpRoot(e){const t=await import("@lensmcp/nest-instrumentation"),n=require("@nestjs/common"),r=t.LensmcpModule.forRoot({projectName:emit_1.PROJECT,trace:{autoInstrumentMethods:!0},memory:{mode:"light",scope:"all"}});class i{static{c(this,"n")}static{s(this,"LensmcpZeroTouchRoot")}}return i[WRAPPED]=!0,n.Module({imports:[r,e]})(i),i}c(buildLensmcpRoot,"buildLensmcpRoot"),s(buildLensmcpRoot,"buildLensmcpRoot");async function captureApp(e,t){await e.init();let n=e.getHttpAdapter?.()?.getInstance?.();if(typeof n!="function"){const r=n;r?.ready&&await r.ready(),typeof r?.routing=="function"&&(n=s((i,o)=>r.routing(i,o),"handler"))}if(typeof n!="function")throw new Error("[lensmcp] cannot derive a request handler from the HTTP adapter");return pushCapture({handler:n,serviceConfig:{port:t??process.env.PORT??0},close:s(()=>Promise.resolve(e.close()).then(()=>{}),"close"),app:e}),e.getHttpServer?.()}c(captureApp,"captureApp"),s(captureApp,"captureApp");
|
package/lib/tap-pg-pool.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`).slice(1).map(r=>r.trim()).filter(r=>r.startsWith("at ")&&!/tap-pg-pool\.[cm]?[jt]s:/.test(r)),s=o.filter(r=>!r.includes("node_modules")&&!r.includes("node:"));return(s.length?s:o).slice(0,SITE_FRAMES)}
|
|
1
|
+
"use strict";var k=Object.defineProperty;var h=(e,o)=>k(e,"name",{value:o,configurable:!0});var $=Object.defineProperty,p=h((e,o)=>$(e,"name",{value:o,configurable:!0}),"p");Object.defineProperty(exports,"__esModule",{value:!0}),exports.checkoutSite=void 0,exports.pgPoolTap=pgPoolTap,exports.samplePgPoolsForTests=samplePgPoolsForTests,exports.resetPgPoolTapForTests=resetPgPoolTapForTests;const node_async_hooks_1=require("node:async_hooks"),pg_errors_1=require("@lensmcp/core/pg-errors"),active_work_1=require("./active-work"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),envMs=p((e,o,s)=>{const r=Number(process.env[e]);return Number.isFinite(r)&&r>=s?r:o},"envMs"),SAMPLE_MS=envMs("LENSMCP_PG_POOL_SAMPLE_MS",1e4,1e3),HOLD_WARN_MS=envMs("LENSMCP_PG_HOLD_WARN_MS",3e4,1e3),SLOW_WAIT_MS=250,BLOCKED_MIN_MS=1e3,WAITS_KEPT=256,SITE_FRAMES=8,stats=new WeakMap,live=[];let nextId=1,timer;const counters=p(e=>({total:e.totalCount??0,idle:e.idleCount??0,waiting:e.waitingCount??0,max:e.options?.max??10}),"counters");function whereOf(e){const o=e.options??{};let s=typeof o.host=="string"?o.host:void 0,r=typeof o.port=="number"||typeof o.port=="string"?String(o.port):void 0,t=typeof o.database=="string"?o.database:void 0;if(typeof o.connectionString=="string")try{const n=new URL(o.connectionString);s??=n.hostname||void 0,r??=n.port||void 0,t??=decodeURIComponent(n.pathname.replace(/^\//,""))||void 0}catch{}return{...t?{database:t}:{},...s?{server:`${s}:${r??5432}`}:{}}}h(whereOf,"whereOf"),p(whereOf,"whereOf");function statsOf(e){let o=stats.get(e);return o||(o={id:nextId++,gen:(0,active_work_1.activeWorkGeneration)(),ref:new WeakRef(e),createdAt:Date.now(),where:whereOf(e),out:new Map,acquires:0,waits:[],waitMax:0,peakWaiting:0,peakTotal:0,failures:0,holdMax:0},stats.set(e,o),live.push(o),startSampling()),o}h(statsOf,"statsOf"),p(statsOf,"statsOf");function siteOf(e){const o=(e.stack??"").split(`
|
|
2
|
+
`).slice(1).map(r=>r.trim()).filter(r=>r.startsWith("at ")&&!/tap-pg-pool\.[cm]?[jt]s:/.test(r)),s=o.filter(r=>!r.includes("node_modules")&&!r.includes("node:"));return(s.length?s:o).slice(0,SITE_FRAMES)}h(siteOf,"siteOf"),p(siteOf,"siteOf");const secs=p(e=>e>=1e4?`${Math.round(e/1e3)} s`:e>=1e3?`${(e/1e3).toFixed(1)} s`:`${Math.round(e)} ms`,"secs");function failed(e,o,s,r,t,n){o.failures+=1;const i=(0,pg_errors_1.pgConnectReason)(s),u=counters(e),d=n?n.total>=n.max&&n.idle===0:u.total>=u.max&&u.idle===0,l=e.options?.connectionTimeoutMillis??0,f=i==="pool-wait-timeout"||i==="connect-timeout",c=f&&l>0?Math.max(0,r-l):0,a=c>=Math.max(BLOCKED_MIN_MS,l*.2),g=`${u.total}/${u.max} open, ${u.idle} idle, ${u.waiting} waiting`,w=n?`when it asked ${n.total}/${n.max} open, ${n.idle} idle, ${n.waiting} waiting; now ${g}`:g,M=i==="pool-wait-timeout"?a?`no connection in time \u2014 waited ${secs(r)} on a ${secs(l)} limit: the process was blocked ${secs(c)} (${w})`:d?`pool full \u2014 every connection in use, none free within ${secs(l)} (${w})`:`no connection in time \u2014 the pool had room when it asked, yet the ${secs(l)} wait ran out: the process was busy or the pool's queue stalled (${w})`:i==="connect-timeout"?`opening a connection took over ${secs(l)}${a?` \u2014 the process was blocked ${secs(c)}`:""} (${g})`:i?`could not get a connection: ${pg_errors_1.PG_CONNECT_MEANING[i]}`:`could not get a connection (${secs(r)})`,m=s;(0,emit_1.lensEmitOutcome)("db","error",M,{name:"postgres",kind:"db-pool-error",...i?{reason:i}:{},waitedMs:r,...l?{timeoutMs:l}:{},...f?{lateMs:c}:{},...a?{blockedMs:c}:{},...u,...n?{asked:n}:{},fullWhenAsked:d,pool:o.id,generation:o.gen,serving:(0,active_work_1.activeWorkGeneration)(),pools:live.length,...o.where,error:String(m?.message??s),...typeof m?.code=="string"?{code:m.code}:{}},`db:pool-error:${i??"other"}`,t)}h(failed,"failed"),p(failed,"failed");function checkedOut(e,o,s,r,t,n){if(e.waits.push(n),e.waits.length>WAITS_KEPT&&e.waits.splice(0,e.waits.length-WAITS_KEPT),n>e.waitMax&&(e.waitMax=n),!o||typeof o!="object")return s;const i=o;e.out.set(i,{at:Date.now(),site:r,ctx:t});const u=p(c=>{if(!c)return;e.out.delete(i);const a=Date.now()-c.at;a>e.holdMax&&(e.holdMax=a)},"back"),d=o.release,l=p(c=>typeof c=="function"?function(...a){return u(e.out.get(i)),c.apply(this??o,a)}:c,"wrap"),f=l(d);return f&&(o.release=f),s===d?f:l(s)}h(checkedOut,"checkedOut"),p(checkedOut,"checkedOut");function percentile(e,o){if(!e.length)return 0;const s=e.slice().sort((r,t)=>r-t);return s[Math.min(s.length-1,Math.floor(s.length*o))]}h(percentile,"percentile"),p(percentile,"percentile");function sample(e=Date.now()){for(let t=live.length-1;t>=0;t--){const n=live[t],i=n.ref.deref();(!i||i.ended&&n.out.size===0)&&live.splice(t,1)}const o=(0,active_work_1.activeWorkGeneration)(),s=live.reduce((t,n)=>Math.max(t,n.gen),0),r=live.map(t=>{const n=t.ref.deref(),i=counters(n);return{pool:t.id,generation:t.gen,total:i.total,idle:i.idle,waiting:i.waiting,max:i.max,...n.ending?{ending:!0}:{}}});for(const t of live){const n=t.ref.deref();if(!n)continue;const i=[];let u=0;for(const c of t.out.values()){const a=e-c.at;if(a>u&&(u=a),a<HOLD_WARN_MS||c.warned)continue;c.warned=!0;const g=siteOf(c.site);i.push({heldMs:a,site:g}),(0,emit_1.lensEmitOutcome)("db","info",`a connection held ${secs(a)} and not given back${g[0]?` \u2014 taken ${g[0].replace(/^at /,"at ")}`:""}`,{name:"postgres",kind:"db-pool-hold",heldMs:a,site:g,pool:t.id,generation:t.gen,...counters(n),...t.where},"db:pool-hold",c.ctx)}const d=counters(n),l=t.gen<s&&d.total>0,f=t.peakWaiting>0||t.waitMax>=SLOW_WAIT_MS||t.failures>0||i.length>0;(f||l)&&(0,emit_1.lensEmit)("db","info",l&&!f?`pool of generation ${t.gen} still holds ${d.total} connection(s) \u2014 the app serving now is generation ${o}`:`pool ${d.total}/${d.max} open \xB7 ${t.acquires} checkouts \xB7 wait p95 ${secs(percentile(t.waits,.95))} max ${secs(t.waitMax)}${t.peakWaiting?` \xB7 up to ${t.peakWaiting} waiting`:""}${t.failures?` \xB7 ${t.failures} failed`:""}`,{name:"postgres",kind:"db-pool",pool:t.id,generation:t.gen,serving:o,...d,acquires:t.acquires,waitP95Ms:percentile(t.waits,.95),waitMaxMs:t.waitMax,peakWaiting:t.peakWaiting,peakTotal:t.peakTotal,failures:t.failures,holdMaxMs:t.holdMax,out:t.out.size,longestHeldMs:u,...l?{leftover:!0}:{},windowMs:SAMPLE_MS,pools:r,...t.where},"db:pool",void 0),t.acquires=0,t.waits=[],t.waitMax=0,t.failures=0,t.holdMax=0,t.peakWaiting=d.waiting,t.peakTotal=d.total}}h(sample,"sample"),p(sample,"sample");function startSampling(){timer||(timer=setInterval(()=>{try{sample()}catch{}},SAMPLE_MS),timer.unref?.())}h(startSampling,"startSampling"),p(startSampling,"startSampling");const checkoutSites=new node_async_hooks_1.AsyncLocalStorage,checkoutSite=p(()=>checkoutSites.getStore(),"checkoutSite");exports.checkoutSite=checkoutSite;function pgPoolTap(e){let o=e?.Pool?.prototype??null;for(;o&&!Object.prototype.hasOwnProperty.call(o,"connect");)o=Object.getPrototypeOf(o);const s=o?.connect;if(!o||typeof s!="function")return!1;if(s.__lensmcp)return!0;const r=p(function(t){let n;try{n=statsOf(this)}catch{return s.call(this,t)}const i=Date.now(),u=(0,flow_context_1.flowContext)();let d;try{d=counters(this)}catch{}const l=new Error("pg checkout");n.acquires+=1;const f=p(()=>{try{const a=counters(this);a.waiting>n.peakWaiting&&(n.peakWaiting=a.waiting),a.total>n.peakTotal&&(n.peakTotal=a.total)}catch{}},"note");if(typeof t=="function"){const a=s.call(this,(g,w,M)=>{let m=M;try{g?failed(this,n,g,Date.now()-i,u,d):m=checkedOut(n,w,M,l,u,Date.now()-i)}catch{}checkoutSites.run(l,()=>t(g,w,m))});return f(),a}const c=s.call(this);return f(),!c||typeof c.then!="function"?c:c.then(a=>{try{checkedOut(n,a,a?.release,l,u,Date.now()-i)}catch{}return a},a=>{try{failed(this,n,a,Date.now()-i,u,d)}catch{}throw a})},"wrapped");return r.__lensmcp=!0,o.connect=r,!0}h(pgPoolTap,"pgPoolTap"),p(pgPoolTap,"pgPoolTap");function samplePgPoolsForTests(e){sample(e)}h(samplePgPoolsForTests,"samplePgPoolsForTests"),p(samplePgPoolsForTests,"samplePgPoolsForTests");function resetPgPoolTapForTests(){timer&&clearInterval(timer),timer=void 0,live.splice(0,live.length),nextId=1}h(resetPgPoolTapForTests,"resetPgPoolTapForTests"),p(resetPgPoolTapForTests,"resetPgPoolTapForTests");
|
package/lib/tap-pg.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var B=Object.defineProperty;var p=(t,e)=>B(t,"name",{value:e,configurable:!0});var X=Object.defineProperty,r=p((t,e)=>X(t,"name",{value:e,configurable:!0}),"r");Object.defineProperty(exports,"__esModule",{value:!0}),exports.taggedAppName=taggedAppName,exports.pgTap=pgTap;const redact_1=require("@lensmcp/core/redact"),sql_shape_1=require("@lensmcp/core/sql-shape"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),sql_accounting_1=require("./sql-accounting"),tap_pg_pool_1=require("./tap-pg-pool"),callsite_1=require("./callsite"),active_work_1=require("./active-work"),emit_2=require("./emit"),sql_values_1=require("./sql-values"),SKIP_OPS=new Set(["BEGIN","START","COMMIT","END","ROLLBACK","SAVEPOINT","RELEASE","SET","RESET","SHOW","DEALLOCATE","DISCARD","LISTEN","UNLISTEN"]),STATEMENT_EVERY_MS=10*6e4,STATEMENT_MAX=64*1024,SLOW_SITE_MS=250,sites=new callsite_1.SiteSampler,statementSentAt=new Map,MAX_SHAPES_REMEMBERED=2e3,firstWord=r(t=>(/^\s*(?:(?:\/\*[\s\S]*?\*\/|--[^\n]*\n?)\s*)*(\w+)/.exec(t)?.[1]??"query").toUpperCase(),"firstWord");function parseSql(t){const e=(0,sql_shape_1.sqlShape)(t),n=(e.target??e.tables[0])?.split(".").pop();return{op:e.verb,...n?{table:n}:{},sqlId:e.id,tables:e.tables,...e.name?{name:e.name}:{}}}p(parseSql,"parseSql"),r(parseSql,"parseSql");const oneLine=r(t=>t.replace(/\s+/g," ").trim(),"oneLine"),clip=r((t,e)=>t.length>e?t.slice(0,e-1)+"\u2026":t,"clip");function paramPreview(t){if(!(!Array.isArray(t)||t.length===0))return t.slice(0,10).map(e=>{if(e==null)return String(e);const n=typeof e=="string"?e:(()=>{try{return JSON.stringify(e)}catch{return String(e)}})();return clip(n,80)})}p(paramPreview,"paramPreview"),r(paramPreview,"paramPreview");const rowsOf=r(t=>t?.rowCount??t?.rows?.length??0,"rowsOf");function resultPreview(t){const e=t?.rows;if(!(!Array.isArray(e)||e.length===0))try{return clip(JSON.stringify((0,redact_1.redactDeep)(e.slice(0,2))),240)}catch{return}}p(resultPreview,"resultPreview"),r(resultPreview,"resultPreview");function connectionOf(t){const e=t,n=e?.connectionParameters,o=typeof e?.database=="string"?e.database:typeof n?.database=="string"?n.database:void 0,s=typeof e?.host=="string"?e.host:typeof n?.host=="string"?n.host:void 0,i=typeof e?.port=="number"||typeof e?.port=="string"?e.port:typeof n?.port=="number"||typeof n?.port=="string"?n.port:5432;return{...o?{database:o}:{},...s?{server:`${s}:${i}`}:{}}}p(connectionOf,"connectionOf"),r(connectionOf,"connectionOf");const APP_NAME_MAX=63;function taggedAppName(t,e,n,o){const s=` lens:${e.replace(/[^\x21-\x7e]/g,"?").replace(/:/g,"_")}${n>0?`:g${n}`:""}${o?`:p${o}`:""}`.slice(0,APP_NAME_MAX);return`${(t??"node").replace(/[^\x20-\x7e]/g,"?").replace(/ lens:\S+$/,"").slice(0,Math.max(0,APP_NAME_MAX-s.length))}${s}`}p(taggedAppName,"taggedAppName"),r(taggedAppName,"taggedAppName");function tagApplicationName(t){if(process.env.LENSMCP_PG_APP_NAME==="0")return;const e=t.getStartupConf;if(typeof e!="function"||e.__lensmcp)return;const n=r(function(){const o=e.call(this);try{o&&typeof o=="object"&&emit_2.PROJECT&&(o.application_name=taggedAppName(typeof o.application_name=="string"?o.application_name:void 0,emit_2.PROJECT,(0,active_work_1.activeWorkGeneration)(),process.pid))}catch{}return o},"wrapped");n.__lensmcp=!0,t.getStartupConf=n}p(tagApplicationName,"tagApplicationName"),r(tagApplicationName,"tagApplicationName");function pgTap(t){const e=t?.Client?.prototype,n=e?.query;if(!e||typeof n!="function")return!1;try{(0,tap_pg_pool_1.pgPoolTap)(t)}catch{}try{tagApplicationName(e)}catch{}if(n.__lensmcp)return!0;const o=r(function(s,i,q){const m=s,d=typeof m=="string"?m:m?.text;if(!d||m&&typeof m=="object"&&typeof m.submit=="function")return n.call(this,s,i,q);if(SKIP_OPS.has(firstWord(d)))return n.call(this,s,i,q);const{op:W,table:l,sqlId:S,tables:$,name:C}=parseSql(d),J=connectionOf(this),y=W.toLowerCase(),V=`db:${y}:${l??"query"}`,u=Date.now(),A=(0,flow_context_1.flowContext)(),j=(0,callsite_1.captureSite)(),M=(0,tap_pg_pool_1.checkoutSite)(),b=(0,flow_context_1.liveFlowContext)();b&&(b.dbCallCount=(b.dbCallCount??0)+1);const w=(0,sql_accounting_1.beginSqlStatement)(b,A,u),N=clip(oneLine(d),500),O=Array.isArray(i)?i:s?.values,x=paramPreview(O),h=x&&(0,redact_1.redactSqlParams)(d,x),v=r((a,f)=>{const c=Date.now()-u,T=u-(statementSentAt.get(S)??-1/0)>=STATEMENT_EVERY_MS;let P;try{P=sites.site(S,j,{force:!!a||T||c>=SLOW_SITE_MS,...M?{fallback:M}:{}})}catch{}const L={sqlId:S,...$.length?{tables:$}:{},...C?{sqlName:C}:{},...J,...P?{site:P}:{},...T?{statement:clip(d.trim(),STATEMENT_MAX)}:{}},E=(0,sql_values_1.newSqlValuesId)(u),R=E?{valuesId:E}:{};let _;if(a)_=(0,emit_1.lensEmitOutcome)("db","error",`${y}${l?" "+l:""} failed (${c}ms)`,{name:"postgres",kind:"db-query",op:y,...l?{table:l}:{},...L,query:N,...h?{params:h}:{},...R,startedAt:u,error:String(a?.message??a),durationMs:c},`db:error:${y}:${l??"query"}`,A);else{const k=rowsOf(f),D=resultPreview(f);_=(0,emit_1.lensEmitOutcome)("db","info",`${y} ${l??"query"} (${k} rows, ${c}ms)`,{name:"postgres",kind:"db-query",op:y,...l?{table:l}:{},...L,query:N,...h?{params:h}:{},...D?{result:D}:{},...R,startedAt:u,rows:k,durationMs:c},V,A)}E&&_==="written"&&(0,sql_values_1.keepSqlValues)(E,u,d,O,a?void 0:f?.rows),T&&_==="written"&&(statementSentAt.delete(S),statementSentAt.set(S,u),statementSentAt.size>MAX_SHAPES_REMEMBERED&&statementSentAt.delete(statementSentAt.keys().next().value)),(0,sql_accounting_1.endSqlStatement)(w,{durationMs:c,failed:!!a,emitted:_})},"done"),I=typeof q=="function"?q:typeof i=="function"?i:void 0;if(I){const a=r((f,c)=>{try{v(f,c)}catch{}I(f,c)},"wrappedCb");try{return typeof i=="function"?n.call(this,s,a):n.call(this,s,i,a)}catch(f){throw(0,sql_accounting_1.abandonSqlStatement)(w),f}}let g;try{g=n.call(this,s,i)}catch(a){throw(0,sql_accounting_1.abandonSqlStatement)(w),a}return g&&typeof g.then=="function"?g.then(a=>v(void 0,a),a=>v(a,void 0)):(0,sql_accounting_1.abandonSqlStatement)(w),g},"wrapped");return o.__lensmcp=!0,e.query=o,!0}p(pgTap,"pgTap"),r(pgTap,"pgTap");
|
package/lib/tap-redis.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var $=Object.defineProperty;var d=(t,e)=>$(t,"name",{value:e,configurable:!0});var E=Object.defineProperty,p=d((t,e)=>E(t,"name",{value:e,configurable:!0}),"p");Object.defineProperty(exports,"__esModule",{value:!0}),exports.redisFingerprint=redisFingerprint,exports.redisTap=redisTap;const key_pattern_1=require("@lensmcp/core/key-pattern"),redact_1=require("@lensmcp/core/redact"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),sql_values_1=require("./sql-values"),HOUSEKEEPING=new Set(["info","ping","hello","auth","select","client","cluster","command","subscribe","psubscribe","unsubscribe","punsubscribe","echo","quit","wait","script","config","debug","memory","readonly","readwrite"]),MAX_PER_SEC=100,MAX_SHAPES=200,SHARED_BUCKET="redis:cache";let emitted=0,windowStart=0,capped=0;const shapes=new Set;function redisFingerprint(t,e){const r=`redis:${t} ${(0,key_pattern_1.foldKeyPattern)(e).slice(0,120)}`;return shapes.has(r)?r:shapes.size>=MAX_SHAPES?SHARED_BUCKET:(shapes.add(r),r)}d(redisFingerprint,"redisFingerprint"),p(redisFingerprint,"redisFingerprint");function isBullTraffic(t){const e=String(t.name??"").toLowerCase();if(e==="eval"||e==="evalsha")return!0;const r=t.args??[];for(let n=0;n<Math.min(r.length,4);n++){const i=String(r[n]??"");if(i.startsWith("bull:")||i.startsWith("{bull"))return!0}return!1}d(isBullTraffic,"isBullTraffic"),p(isBullTraffic,"isBullTraffic");function redisTap(t){const e=t,r=(e?.default??e)?.prototype,n=r?.sendCommand;if(!r||typeof n!="function")return!1;if(n.__lensmcp)return!0;const i=p(function(s,c){const a=n.call(this,s,c);try{observe(s)}catch{}return a},"wrapped");return i.__lensmcp=!0,r.sendCommand=i,!0}d(redisTap,"redisTap"),p(redisTap,"redisTap");const clip=p((t,e)=>t.length>e?t.slice(0,e-1)+"\u2026":t,"clip");function commandLine(t,e){const r=e.slice(0,6).map((n,i)=>{const s=String(n??"");return i>0&&s.length>48?`\u2026(${(s.length/1024).toFixed(1)}kb)`:clip(s,64)});return[t.toUpperCase(),...r].join(" ")}d(commandLine,"commandLine"),p(commandLine,"commandLine");function observe(t){const e=String(t?.name??"").toLowerCase();if(!e||HOUSEKEEPING.has(e)||isBullTraffic(t))return;const r=(0,flow_context_1.liveFlowContext)();r&&(r.redisCallCount=(r.redisCallCount??0)+1);const n=Date.now();if(n-windowStart>1e3&&(windowStart=n,emitted=0),++emitted>MAX_PER_SEC){capped+=1;return}const i=t?.args??[],s=String(i[0]??""),c=(0,redact_1.isSecretCacheKey)(s),a=c?(0,key_pattern_1.foldKeyPattern)(s):s,C=(0,flow_context_1.flowContext)(),y=c?`${e.toUpperCase()} ${a} \u2026`:(0,redact_1.redactSecretText)(commandLine(e,i)),g=redisFingerprint(e,s),_=capped;capped=0;const S={name:"cache",kind:"redis-op",op:e,key:a,command:y,startedAt:n,...c?{secretKey:!0}:{},..._?{capSuppressed:_}:{}},h=i.slice(1);if(e==="get"&&t.promise&&typeof t.promise.then=="function"){const l=n;t.promise.then(f=>{const o=f!=null,u=o&&!c?(0,sql_values_1.newCacheValuesId)(l):void 0,x=(0,emit_1.lensEmitOutcome)("redis","info",`cache ${o?"hit":"miss"} ${a}`,{...S,hit:o,durationMs:Date.now()-l,...o&&!c?{value:clip((0,redact_1.redactSecretText)(String(f).slice(0,4096)),120)}:{},...u?{valuesId:u}:{}},g,C);u&&x==="written"&&(0,sql_values_1.keepCacheValues)(u,l,e,s,h,f)},()=>{});return}const m=c?void 0:(0,sql_values_1.newCacheValuesId)(n),v=m?{valuesId:m}:{};let w;if(e==="set"){const l=i.map(u=>String(u)),f=l.findIndex(u=>u.toUpperCase()==="EX"),o=f>=0?Number(l[f+1]):void 0;w=(0,emit_1.lensEmitOutcome)("redis","info",o?`cache set ${a} (ttl ${o}s)`:`cache set ${a}`,{...S,...o?{ttlSec:o}:{},...v},g,C)}else w=(0,emit_1.lensEmitOutcome)("redis","info",`cache ${e} ${a}`,{...S,...v},g,C);if(!m||w!=="written")return;const b=t.promise;b&&typeof b.then=="function"?b.then(l=>(0,sql_values_1.keepCacheValues)(m,n,e,s,h,l),()=>(0,sql_values_1.keepCacheValues)(m,n,e,s,h)):(0,sql_values_1.keepCacheValues)(m,n,e,s,h)}d(observe,"observe"),p(observe,"observe");
|
package/lib/tap-stdout.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`).map(
|
|
3
|
-
`),c)){
|
|
4
|
-
`)}:{},...i.length>0&&
|
|
5
|
-
`)}:{},...
|
|
1
|
+
"use strict";var R=Object.defineProperty;var f=(t,e)=>R(t,"name",{value:e,configurable:!0});var E=Object.defineProperty,u=f((t,e)=>E(t,"name",{value:e,configurable:!0}),"u");Object.defineProperty(exports,"__esModule",{value:!0}),exports.tapStdout=tapStdout;const emit_1=require("./emit"),tap_nest_logger_1=require("./tap-nest-logger"),ANSI=new RegExp("\x1B\\[[0-9;]*m","g");function severityOf(t,e){return/\bFATAL\b/.test(t)?"fatal":/\bERROR\b/.test(t)?"error":/\bWARN\b/.test(t)?"warning":/\bDEBUG\b/.test(t)||/\bVERBOSE\b/.test(t)?"debug":/\bLOG\b/.test(t)?"info":e}f(severityOf,"severityOf"),u(severityOf,"severityOf");const STACK_FRAME=/^\s+(at\s|\.\.\.\s\d+\smore)/,CONTINUATION=/^(\s+\S|[}\])]+[,;]?$)/,CONTINUES_WITHIN_MS=1e3;function emitChunk(t,e,p,c,l){const o=t.split(`
|
|
2
|
+
`).map(r=>r.replace(ANSI,"").replace(/\s+$/,""));let s=0,n=p;for(;s<o.length;){const r=o[s];if(s+=1,!r.trim())continue;const i=[];for(;s<o.length&&o[s].trim()&&CONTINUATION.test(o[s]);)i.push(o[s]),s+=1;const g=[r,...i].filter(_=>STACK_FRAME.test(_)),a=CONTINUATION.test(r)&&n&&c-n.at<=CONTINUES_WITHIN_MS?n.severity:void 0,m=severityOf(r,e),O=m!==e||/\b(?:FATAL|ERROR|WARN|DEBUG|VERBOSE|LOG)\b/.test(r),b=a??(O?m:g.length>0?"error":e),d=[r,...i];if(!a&&(0,tap_nest_logger_1.isLoggerEcho)(d.join(`
|
|
3
|
+
`),c)){n={severity:b,at:c};continue}(0,emit_1.lensLog)(b,a?r.trim():r,{...g.length>0?{stack:d.join(`
|
|
4
|
+
`)}:{},...i.length>0&&g.length<i.length?{text:d.join(`
|
|
5
|
+
`)}:{},...a?{continues:!0}:{},stream:l}),n={severity:b,at:c}}return n}f(emitChunk,"emitChunk"),u(emitChunk,"emitChunk");function tapStdout(){if(process.env.LENSMCP_LOGS==="0"||process.env.APP_RUNNER!=="1")return;const t=[[process.stdout,"info","stdout"],[process.stderr,"error","stderr"]];for(const[e,p,c]of t){if(e.write.__lensmcp)continue;const l=e.write.bind(e);let o;const s=u(function(n,...r){try{if(!(0,emit_1.isLensWriting)()){const i=typeof n=="string"?n:Buffer.isBuffer(n)?n.toString("utf8"):"";i&&i.indexOf("[lensmcp]")===-1&&(o=emitChunk(i,p,o,Date.now(),c))}}catch{}return l(n,...r)},"wrapped");s.__lensmcp=!0,e.write=s}}f(tapStdout,"tapStdout"),u(tapStdout,"tapStdout");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lensmcp/node-instrumentation",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.22",
|
|
4
4
|
"main": "./index.js",
|
|
5
5
|
"types": "./index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@lensmcp/core": "1.25.
|
|
19
|
-
"@lensmcp/nest-instrumentation": "1.25.
|
|
20
|
-
"@lensmcp/protocol-types": "1.25.
|
|
18
|
+
"@lensmcp/core": "1.25.22",
|
|
19
|
+
"@lensmcp/nest-instrumentation": "1.25.22",
|
|
20
|
+
"@lensmcp/protocol-types": "1.25.22",
|
|
21
21
|
"tslib": "^2.3.0"
|
|
22
22
|
},
|
|
23
23
|
"optionalDependencies": {
|
package/register.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var i=Object.defineProperty;var r=(t,n)=>i(t,"name",{value:n,configurable:!0});var s=Object.defineProperty,e=r((t,n)=>s(t,"name",{value:n,configurable:!0}),"e");Object.defineProperty(exports,"__esModule",{value:!0}),exports.installLensmcpNodeInstrumentation=void 0;const install_1=require("./lib/install");Object.defineProperty(exports,"installLensmcpNodeInstrumentation",{enumerable:!0,get:e(function(){return install_1.installLensmcpNodeInstrumentation},"get")}),(0,install_1.installLensmcpNodeInstrumentation)();
|